rspec-activerecord-formatter 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 573d9da6bd2d49e858ad2598ecf931c7b9909cc4d53881ed84d27b9e071310c5
4
- data.tar.gz: a4f40473db9a50e226ba87b5512b031a1adacf5694f1872ef1571763e997f212
3
+ metadata.gz: db1b2dbddfb326ac8143998c1b7cc204d90d84f83ccfabe9f3cc022d435a49d8
4
+ data.tar.gz: 7f29a63684b8e1ce6614e99cbf6ad978739f2f08357d14abc7a4209f2fd866ea
5
5
  SHA512:
6
- metadata.gz: 87e83e43deaad1f964e3cc88264ab51779a0362c789f18a5ea3d33d1116059866f7f3df0c8946f936462215b94a8f4440bafb1f11143bf5a7d5a2f964a62f433
7
- data.tar.gz: '068fbce81ae37fe58c1e0d97d61f4024cab3cd233618f870d8e4b842d25291810872504dc53c21e702379a92a4aca472dde66fbdb7869a7d57a6ef1524dac255'
6
+ metadata.gz: 9f7f871268d7ce2c007d1bede488b073e443ee5e93ae6ed9f07ca7e787811b2bd38d373ca5843c34403dc877942c1b7908f83ed9729f6c5010f71801dbced20d
7
+ data.tar.gz: 5dc551ee718ce1fdd0e5ce8997f105750b2295d2e7a9b14e399acce10ee5a17be8a07b76bd51c8d21c30b8c2278337b224cb0d8dda5916977f8082040e72a07a
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  .DS_Store
2
2
  Gemfile.lock
3
3
  coverage
4
+ *.gem
@@ -4,7 +4,8 @@ class ActiveRecordFormatter < ::RSpec::Core::Formatters::DocumentationFormatter
4
4
  attr_reader :collector, :colorizer, :configuration
5
5
 
6
6
  ::RSpec::Core::Formatters.register self, :start, :dump_summary,
7
- :example_started, :example_passed, :example_failed
7
+ :example_started, :example_group_started,
8
+ :example_group_finished
8
9
 
9
10
  def initialize(output)
10
11
  super
@@ -17,8 +18,18 @@ class ActiveRecordFormatter < ::RSpec::Core::Formatters::DocumentationFormatter
17
18
  output.puts "Recording and reporting ActiveRecord select and creation counts."
18
19
  end
19
20
 
21
+ def example_group_started(example_group)
22
+ collector.group_started(example_group.group)
23
+ super
24
+ end
25
+
26
+ def example_group_finished(example_group)
27
+ collector.group_finished(example_group.group)
28
+ super
29
+ end
30
+
20
31
  def example_started(example)
21
- collector.reset_example
32
+ collector.reset_example(example)
22
33
  end
23
34
 
24
35
  def dump_summary(summary)
@@ -35,15 +46,25 @@ class ActiveRecordFormatter < ::RSpec::Core::Formatters::DocumentationFormatter
35
46
  end
36
47
 
37
48
  def write_profile_summary
38
- output_report_filename = Time.now.strftime("rspec_activerecord_result_%Y_%m_%d_%H_%m_%S.txt")
39
- output_report_path = Rails.root.join("tmp", output_report_filename)
49
+ output_report_filename = Time.now.strftime("ar_%Y_%m_%d_%H_%m_%S.txt")
50
+ report_dir = Rails.root.join("tmp", "profile")
51
+ output_report_path = report_dir.join(output_report_filename)
40
52
 
41
- puts "\nOutputting Detailed Profile Data to #{output_report_path}"
53
+ output.puts "\nOutputting Detailed Profile Data to #{output_report_path}"
54
+ Dir.mkdir(report_dir) unless File.exists?(report_dir)
42
55
  File.open(output_report_path, "wb") do |f|
43
- f.puts "#{collector.total_objects} AR objects, #{collector.total_queries} AR queries\n"
44
- f.puts "Query Summary"
45
- collector.most_common_query_names.each do |name, count|
46
- f.puts "%-4s %s" % [count, name]
56
+ f.puts "#{collector.total_objects} AR objects, #{collector.total_queries} AR queries"
57
+
58
+ f.puts ""
59
+ f.puts "Worst Example Groups by Object Creation"
60
+ collector.most_expensive_groups.first(50).each do |name, count|
61
+ f.puts "%-5s %s" % [count, name]
62
+ end
63
+
64
+ f.puts ""
65
+ f.puts "Most Common Queries"
66
+ collector.most_common_query_names.first(50).each do |name, count|
67
+ f.puts "%-5s %s" % [count, name]
47
68
  end
48
69
  end
49
70
  end
@@ -2,7 +2,9 @@ require 'active_support/notifications'
2
2
 
3
3
  module ActiveRecordFormatterHelpers
4
4
  class Collector
5
- attr_reader :query_count, :objects_count, :total_queries, :total_objects, :query_names
5
+ attr_reader :query_count, :objects_count, :total_queries, :total_objects,
6
+ :query_names, :active_groups, :group_counts
7
+
6
8
  SKIP_QUERIES = ["SELECT tablename FROM pg_tables", "select sum(ct) from (select count(*) ct from"]
7
9
 
8
10
  def initialize
@@ -11,6 +13,8 @@ module ActiveRecordFormatterHelpers
11
13
  @total_queries = 0
12
14
  @total_objects = 0
13
15
  @query_names = Hash.new(0)
16
+ @group_counts = Hash.new(0)
17
+ @active_groups = []
14
18
 
15
19
  ActiveSupport::Notifications.subscribe("sql.active_record", method(:record_query))
16
20
  end
@@ -18,29 +22,60 @@ module ActiveRecordFormatterHelpers
18
22
  def record_query(*_unused, data)
19
23
  return if SKIP_QUERIES.any? { |q| data[:sql].index(q) == 0 }
20
24
 
21
- @query_count += 1
22
- @total_queries += 1
23
-
24
- if query_is_an_insert?(data[:sql])
25
- @objects_count += 1
26
- @total_objects += 1
27
- end
28
-
29
- name = data[:name] || "Unnamed"
30
- @query_names[name] += 1
25
+ inc_query
26
+ inc_object if query_is_an_insert?(data[:sql])
27
+ inc_query_name(data)
31
28
  end
32
29
 
33
30
  def most_common_query_names
34
- @query_names.sort_by(&:last).reverse
31
+ query_names.sort_by(&:last).reverse
35
32
  end
36
33
 
37
- def reset_example
34
+ def most_expensive_groups
35
+ group_counts.sort_by(&:last).reverse
36
+ end
37
+
38
+ def reset_example(_)
38
39
  @query_count = 0
39
40
  @objects_count = 0
40
41
  end
41
42
 
43
+ def group_started(group)
44
+ return unless group.parent_groups.length > 1
45
+
46
+ active_groups.push(group_path(group))
47
+ end
48
+
49
+ def group_finished(group)
50
+ active_groups.delete(group_path(group))
51
+ end
52
+
42
53
  protected
43
54
 
55
+ def inc_object
56
+ @objects_count += 1
57
+ @total_objects += 1
58
+
59
+ active_groups.each do |group|
60
+ @group_counts[group] += 1
61
+ end
62
+ end
63
+
64
+ def inc_query
65
+ @query_count += 1
66
+ @total_queries += 1
67
+ end
68
+
69
+ def inc_query_name(data)
70
+ name = data[:name] || "Unnamed"
71
+
72
+ query_names[name] += 1
73
+ end
74
+
75
+ def group_path(group)
76
+ group.parent_groups.reverse.map(&:description).join(' ')
77
+ end
78
+
44
79
  # TODO: what happens if we try to create many records at once?
45
80
  # TODO: are there any false positives we need to worry about? false negatives?
46
81
  def query_is_an_insert?(query)
@@ -6,7 +6,7 @@ $LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
6
6
  Gem::Specification.new do |gem|
7
7
 
8
8
  gem.name = "rspec-activerecord-formatter"
9
- gem.version = "1.1.0"
9
+ gem.version = "1.2.0"
10
10
 
11
11
  gem.summary = "Adds object creations and queries to Rspec output."
12
12
  gem.description = "Creates a new formatter for ActiveRecord that can help you diagnose performance issues in RSpec"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-activerecord-formatter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joseph Mastey