Module: MetricStats

Extended by:
ActiveSupport::Concern
Included in:
Watchdog::Dashboard::DashboardController
Defined in:
app/controllers/concerns/metric_stats.rb

Instance Method Summary collapse

Instance Method Details

#average_timeObject



4
5
6
# File 'app/controllers/concerns/metric_stats.rb', line 4

def average_time
  Watchdog::Dashboard::Metric.all.average(:run_time)
end

#avg_execution_time_by_file(days = 30) ⇒ Object



184
185
186
187
188
189
190
191
192
# File 'app/controllers/concerns/metric_stats.rb', line 184

def avg_execution_time_by_file(days = 30)
  Watchdog::Dashboard::Metric
    .select("file_path, AVG(run_time) as average_run_time")
    .where(created_at: days.days.ago..Time.current.end_of_day)
    .where("run_time IS NOT NULL") # Filtrar nulos si es necesario
    .group("file_path")
    .order("average_run_time DESC")
    .map { |m| { file_path: m.file_path, average_run_time: m.average_run_time.to_f.round(2) } } # Asegurarse de que sea flotante
end

#execution_time_varianceObject



84
85
86
87
88
89
90
91
92
93
94
95
# File 'app/controllers/concerns/metric_stats.rb', line 84

def execution_time_variance
  run_times = Watchdog::Dashboard::Metric.pluck(:run_time)
  mean = run_times.sum / run_times.size
  variance = run_times.map { |time| (time - mean) ** 2 }.sum / run_times.size
  std_dev = Math.sqrt(variance)

  {
    mean: mean,
    variance: variance,
    standard_deviation: std_dev
  }
end

#failed_testsObject



30
31
32
# File 'app/controllers/concerns/metric_stats.rb', line 30

def failed_tests
  Watchdog::Dashboard::Metric.where(status: 'failed')
end

#failed_tests_trend_by_file(days = 30) ⇒ Object



175
176
177
178
179
180
181
182
# File 'app/controllers/concerns/metric_stats.rb', line 175

def failed_tests_trend_by_file(days = 30)
  Watchdog::Dashboard::Metric
    .select("DATE(created_at) as test_date, file_path, COUNT(*) as failed_count")
    .where(status: 'failed', created_at: days.days.ago..Time.current.end_of_day)
    .group("DATE(created_at), file_path")
    .order("DATE(created_at), failed_count DESC")
    .map { |m| { test_date: m.test_date.to_s, file_path: m.file_path, failed_count: m.failed_count } }
end

#fastest_testObject



8
9
10
# File 'app/controllers/concerns/metric_stats.rb', line 8

def fastest_test
  Watchdog::Dashboard::Metric.order(:run_time).first
end

#longest_tests_by_day(days = 30) ⇒ Object



147
148
149
150
151
152
153
154
# File 'app/controllers/concerns/metric_stats.rb', line 147

def longest_tests_by_day(days = 30)
  Watchdog::Dashboard::Metric
    .select("DATE(created_at) as test_date, description, run_time")
    .where(created_at: days.days.ago..Time.current.end_of_day)
    .where("run_time = (SELECT MAX(run_time) FROM watchdog_dashboard_metrics AS m2 WHERE DATE(m2.created_at) = DATE(watchdog_dashboard_metrics.created_at))")
    .order("test_date DESC") # Ordenamos por fecha
    .map { |m| { test_date: m.test_date.to_s, description: m.description, run_time: m.run_time.to_f } }
end

#percentilesObject



16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'app/controllers/concerns/metric_stats.rb', line 16

def percentiles
  total = Watchdog::Dashboard::Metric.count
  [0.25, 0.5, 0.75].map do |p|
    index = (total * p).round - 1
    example = Watchdog::Dashboard::Metric.order(:run_time).limit(1).offset(index).first
    {
      percentile: (p * 100).to_i,
      description: example.description,
      file_path: example.file_path,
      run_time: example.run_time
    }
  end
end

#performance_trend(days = 30) ⇒ Object



129
130
131
132
133
134
135
136
# File 'app/controllers/concerns/metric_stats.rb', line 129

def performance_trend(days = 30)
  Watchdog::Dashboard::Metric
    .select("DATE(created_at) as test_date, AVG(run_time) as average_run_time")
    .where(created_at: days.days.ago..Time.current.end_of_day) # ← INCLUYE HOY COMPLETO
    .group("DATE(created_at)")
    .order("DATE(created_at)")
    .map { |m| { test_date: m.test_date.to_s, average_run_time: m.average_run_time.to_f } }
end

#run_time_distribution(bin_size = 1.0) ⇒ Object

HISTORIC DATA



122
123
124
125
126
127
# File 'app/controllers/concerns/metric_stats.rb', line 122

def run_time_distribution(bin_size = 1.0)
  Watchdog::Dashboard::Metric.select("FLOOR(run_time / #{bin_size}) as run_time_bin,
                                  COUNT(*) as test_count")
                          .group("run_time_bin")
                          .order("run_time_bin")
end

#slowest_testObject



12
13
14
# File 'app/controllers/concerns/metric_stats.rb', line 12

def slowest_test
  Watchdog::Dashboard::Metric.order(run_time: :desc).first
end

#stability_trend(days = 30) ⇒ Object



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'app/controllers/concerns/metric_stats.rb', line 195

def stability_trend(days = 30)
  Watchdog::Dashboard::Metric
    .select("DATE(created_at) as test_date,
            SUM(CASE WHEN status = 'passed' THEN 1 ELSE 0 END) as passed_count,
            SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed_count,
            SUM(CASE WHEN status = 'skipped' THEN 1 ELSE 0 END) as skipped_count,
            SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending_count,
            SUM(CASE WHEN status = 'error' THEN 1 ELSE 0 END) as error_count")
    .where(created_at: days.days.ago..Time.current.end_of_day)
    .group("DATE(created_at)") # Asegúrate de que solo agrupas por la fecha, no por otros campos
    .order("DATE(created_at)")
    .map { |m|
      {
        test_date: m.test_date.to_s,
        passed_count: m.passed_count,
        failed_count: m.failed_count,
        skipped_count: m.skipped_count,
        pending_count: m.pending_count,
        error_count: m.error_count
      }
    }
end

#temporal_complexity_analysisObject



97
98
99
100
101
102
103
104
105
106
107
# File 'app/controllers/concerns/metric_stats.rb', line 97

def temporal_complexity_analysis
  sorted_by_complexity = Watchdog::Dashboard::Metric.order(:run_time)

  sorted_by_complexity.first(3).map do |ex|
    {
      description: ex.description,
      file_path: ex.file_path,
      execution_time: ex.run_time
    }
  end
end

#test_count_trend(days = 30) ⇒ Object



138
139
140
141
142
143
144
145
# File 'app/controllers/concerns/metric_stats.rb', line 138

def test_count_trend(days = 30)
  Watchdog::Dashboard::Metric
    .select("DATE(created_at) as test_date, COUNT(*) as test_count")
    .where(created_at: days.days.ago..Time.current.end_of_day)
    .group("DATE(created_at)")
    .order("DATE(created_at)")
    .map { |m| { test_date: m.test_date.to_s, test_count: m.test_count } }
end

#test_dependency_analysisObject



109
110
111
112
113
114
115
116
117
118
119
# File 'app/controllers/concerns/metric_stats.rb', line 109

def test_dependency_analysis
  file_dependencies = Watchdog::Dashboard::Metric.group(:file_path).having("count(*) > 1").count

  file_dependencies.map do |file, count|
    {
      file: file,
      number_of_tests: count,
      average_execution_time: Watchdog::Dashboard::Metric.where(file_path: file).average(:run_time)
    }
  end
end

#test_stability_analysisObject



70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'app/controllers/concerns/metric_stats.rb', line 70

def test_stability_analysis
  total_tests = Watchdog::Dashboard::Metric.count
  passed = Watchdog::Dashboard::Metric.where(status: 'passed').count
  failed = Watchdog::Dashboard::Metric.where(status: 'failed').count
  pending = Watchdog::Dashboard::Metric.where(status: 'pending').count

  {
    total_tests: total_tests,
    passed_percentage: (passed.to_f / total_tests * 100).round(2),
    failed_percentage: (failed.to_f / total_tests * 100).round(2),
    pending_percentage: (pending.to_f / total_tests * 100).round(2)
  }
end

#tests_exceeding_time_threshold(threshold = 1.0, days = 30) ⇒ Object



165
166
167
168
169
170
171
172
173
# File 'app/controllers/concerns/metric_stats.rb', line 165

def tests_exceeding_time_threshold(threshold = 1.0, days = 30)
  Watchdog::Dashboard::Metric
    .select("DATE(created_at) as test_date, COUNT(*) as test_count")
    .where('run_time > ?', threshold)
    .where(created_at: days.days.ago..Time.current.end_of_day)
    .group("DATE(created_at)")
    .order("DATE(created_at)")
    .map { |m| { test_date: m.test_date.to_s, test_count: m.test_count } }
end

#tests_grouped_by_fileObject



34
35
36
# File 'app/controllers/concerns/metric_stats.rb', line 34

def tests_grouped_by_file
  Watchdog::Dashboard::Metric.group(:file_path).order(:file_path)
end

#tests_that_took_longer_than(threshold) ⇒ Object



38
39
40
# File 'app/controllers/concerns/metric_stats.rb', line 38

def tests_that_took_longer_than(threshold)
  Watchdog::Dashboard::Metric.where('run_time > ?', threshold)
end

#time_distribution_analysisObject



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'app/controllers/concerns/metric_stats.rb', line 42

def time_distribution_analysis
  total_tests = Watchdog::Dashboard::Metric.count
  categories = {
    "⚡ Ultra Fast (< 0.01s)" => 0,
    "🚀 Fast (0.01s - 0.1s)" => 0,
    "🏃 Normal (0.1s - 0.5s)" => 0,
    "🚶 Slow (0.5s - 1s)" => 0,
    "🐢 Very Slow (> 1s)" => 0
  }

  Watchdog::Dashboard::Metric.find_each do |ex|
    case ex.run_time
    when 0...0.01
      categories["⚡ Ultra Fast (< 0.01s)"] += 1
    when 0.01...0.1
      categories["🚀 Fast (0.01s - 0.1s)"] += 1
    when 0.1...0.5
      categories["🏃 Normal (0.1s - 0.5s)"] += 1
    when 0.5...1.0
      categories["🚶 Slow (0.5s - 1s)"] += 1
    else
      categories["🐢 Very Slow (> 1s)"] += 1
    end
  end

  categories
end

#total_execution_time_by_day(days = 30) ⇒ Object



156
157
158
159
160
161
162
163
# File 'app/controllers/concerns/metric_stats.rb', line 156

def total_execution_time_by_day(days = 30)
  Watchdog::Dashboard::Metric
    .select("DATE(created_at) as test_date, SUM(run_time) as total_run_time")
    .where(created_at: days.days.ago..Time.current.end_of_day)
    .group("DATE(created_at)")
    .order("DATE(created_at)")
    .map { |m| { test_date: m.test_date.to_s, total_run_time: m.total_run_time } }
end