test-prof 1.0.0.rc1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b43e971bbd8c55a38c657e3338dc625d5860bd067e96385f310885024a1c5cc5
4
- data.tar.gz: 6d4b767d0ed366be1b27521e986785b6ddfa9f2008eb9640c76baae55084bb34
3
+ metadata.gz: c3ea5b7078b12209f32a60554f25acffccd184bdf852ebfe14cad161ded2c180
4
+ data.tar.gz: 34e61ec6d58e5688b441ea09c1be524ae563f9ca82f334541c3f2c3197787cbd
5
5
  SHA512:
6
- metadata.gz: 1b490801a31def008b6e8c77dff834e67c4c27a96d9d09fbe626dbed0009cb541da48acc7308905f3f8b722e8fc6f6bde39ebce5362e928abb0c2d319f259248
7
- data.tar.gz: 825b2ca0cd5f0c4ea235c5df11686a39799a70685a1ae0911facceb383facec815bed04322336ec67867b51e3a0152d150ed9fe7db9f01bb1acea520fd095258
6
+ metadata.gz: d866bfe03650d81cb2dd5b698b5de5703a8fa505c7c8d0b0e4283b8130eb774ac43c5cca6a750fef6f8342acdec7e518613489e898fd354f133e1793df833e45
7
+ data.tar.gz: cf92cef8973837d2e09ff3bcc4449fb0675ebfca3f10fc75a314f10d885ad92aaae2f6fac0cd99e7250eb57985208e6d6f53b88d101f177709a172b8fcae1815
data/CHANGELOG.md CHANGED
@@ -2,6 +2,30 @@
2
2
 
3
3
  ## master (unrealeased)
4
4
 
5
+ ## 1.0.3 (2021-04-30)
6
+
7
+ - Minor fixes.
8
+
9
+ ## 1.0.2 (2021-02-26)
10
+
11
+ - Make `before_all(setup_fixtures: true)` compatible with Rails 6.1. ([@palkan][])
12
+
13
+ ## 1.0.1 (2021-02-12)
14
+
15
+ - Fixed AnyFixture deprecation warning.
16
+
17
+ ## 1.0.0 (2021-01-21)
18
+
19
+ ## 1.0.0.rc2 (2021-01-06)
20
+
21
+ - Make Rails fixtures accesible in `before_all`. ([@palkan][])
22
+
23
+ You can load and access fixtures when explicitly enabling them via `before_all(setup_fixtures: true, &block)`.
24
+
25
+ - Minitest's `before_all` is not longer experimental. ([@palkan][])
26
+
27
+ - Add `after_all` to Minitest in addition to `before_all`. ([@palkan][])
28
+
5
29
  ## 1.0.0.rc1 (2020-12-30)
6
30
 
7
31
  - Remove deprecated `AggregateFailures` cop. ([@palkan][])
data/README.md CHANGED
@@ -32,7 +32,7 @@ TestProf toolbox aims to help you identify bottlenecks in your test suite. It co
32
32
  📑 [Documentation](https://test-prof.evilmartians.io)
33
33
 
34
34
  <p align="center">
35
- <a href="http://bit.ly/test-prof-map">
35
+ <a href="http://bit.ly/test-prof-map-v1">
36
36
  <img src="./docs/assets/images/coggle.png" alt="TestProf map" width="738">
37
37
  </a>
38
38
  </p>
@@ -75,7 +75,7 @@ Add `test-prof` gem to your application:
75
75
 
76
76
  ```ruby
77
77
  group :test do
78
- gem "test-prof"
78
+ gem "test-prof", "~> 1.0"
79
79
  end
80
80
  ```
81
81
 
data/lib/test_prof.rb CHANGED
@@ -161,5 +161,5 @@ require "test_prof/factory_doctor"
161
161
  require "test_prof/factory_prof"
162
162
  require "test_prof/rspec_stamp"
163
163
  require "test_prof/tag_prof"
164
- require "test_prof/rspec_dissect"
164
+ require "test_prof/rspec_dissect" if TestProf.rspec?
165
165
  require "test_prof/factory_all_stub"
@@ -6,7 +6,7 @@ require "test_prof/any_fixture/dump"
6
6
  module TestProf
7
7
  # Make DB fixtures from blocks.
8
8
  module AnyFixture
9
- INSERT_RXP = /^INSERT INTO ([\S]+)/.freeze
9
+ INSERT_RXP = /^INSERT INTO (\S+)/.freeze
10
10
 
11
11
  using FloatDuration
12
12
 
@@ -16,8 +16,8 @@ module TestProf
16
16
  :import_dump_via_cli, :dump_matching_queries, :force_matching_dumps
17
17
  attr_reader :default_dump_watch_paths
18
18
 
19
- alias reporting_enabled? reporting_enabled
20
- alias import_dump_via_cli? import_dump_via_cli
19
+ alias_method :reporting_enabled?, :reporting_enabled
20
+ alias_method :import_dump_via_cli?, :import_dump_via_cli
21
21
 
22
22
  def initialize
23
23
  @reporting_enabled = ENV["ANYFIXTURE_REPORT"] == "1"
@@ -42,7 +42,7 @@ module TestProf
42
42
  end
43
43
 
44
44
  def before_dump(&block)
45
- if block_given?
45
+ if block
46
46
  @before_dump << block
47
47
  else
48
48
  @before_dump
@@ -50,7 +50,7 @@ module TestProf
50
50
  end
51
51
 
52
52
  def after_dump(&block)
53
- if block_given?
53
+ if block
54
54
  @after_dump << block
55
55
  else
56
56
  @after_dump
@@ -112,7 +112,7 @@ module TestProf
112
112
  config.reporting_enabled
113
113
  end
114
114
 
115
- alias reporting_enabled? reporting_enabled
115
+ alias_method :reporting_enabled?, :reporting_enabled
116
116
 
117
117
  # Register a block of code as a fixture,
118
118
  # returns the result of the block execution
@@ -6,9 +6,9 @@ require "set"
6
6
 
7
7
  module TestProf
8
8
  module AnyFixture
9
- MODIFY_RXP = /^(INSERT INTO|UPDATE|DELETE FROM) ([\S]+)/i.freeze
10
- ANY_FIXTURE_RXP = /(\/\*|\-\-).*\bany_fixture:dump/.freeze
11
- ANY_FIXTURE_IGNORE_RXP = /(\/\*|\-\-).*\bany_fixture:ignore/.freeze
9
+ MODIFY_RXP = /^(INSERT INTO|UPDATE|DELETE FROM) (\S+)/i.freeze
10
+ ANY_FIXTURE_RXP = /(\/\*|--).*\bany_fixture:dump/.freeze
11
+ ANY_FIXTURE_IGNORE_RXP = /(\/\*|--).*\bany_fixture:ignore/.freeze
12
12
 
13
13
  using(Module.new do
14
14
  refine Object do
@@ -45,7 +45,6 @@ module TestProf
45
45
  @adapter = adapter
46
46
  @tmp_path = path + ".tmp"
47
47
  @reset_pk = Set.new
48
- @file = File.open(tmp_path, "w")
49
48
  end
50
49
 
51
50
  def start(_event, _id, payload)
@@ -70,6 +69,8 @@ module TestProf
70
69
  end
71
70
 
72
71
  def commit
72
+ return unless defined?(:@file)
73
+
73
74
  file.close
74
75
 
75
76
  FileUtils.mv(tmp_path, path)
@@ -77,7 +78,11 @@ module TestProf
77
78
 
78
79
  private
79
80
 
80
- attr_reader :file, :reset_pk, :adapter
81
+ attr_reader :reset_pk, :adapter
82
+
83
+ def file
84
+ @file ||= File.open(tmp_path, "w")
85
+ end
81
86
 
82
87
  def reset_pk!(table_name)
83
88
  return if /sqlite_sequence/.match?(table_name)
@@ -106,7 +111,7 @@ module TestProf
106
111
  end
107
112
 
108
113
  attr_reader :name, :digest, :path, :subscriber, :success
109
- alias success? success
114
+ alias_method :success?, :success
110
115
 
111
116
  def initialize(name, watch: [], cache_key: nil)
112
117
  @name = name
@@ -32,6 +32,12 @@ module TestProf
32
32
  end
33
33
  end
34
34
 
35
+ def setup_fixtures(test_object)
36
+ raise ArgumentError, "Current adapter doesn't support #setup_fixtures" unless adapter.respond_to?(:setup_fixtures)
37
+
38
+ adapter.setup_fixtures(test_object)
39
+ end
40
+
35
41
  def config
36
42
  @config ||= Configuration.new
37
43
  end
@@ -60,8 +66,11 @@ module TestProf
60
66
  class Configuration
61
67
  HOOKS = %i[begin rollback].freeze
62
68
 
69
+ attr_accessor :setup_fixtures
70
+
63
71
  def initialize
64
72
  @hooks = Hash.new { |h, k| h[k] = HooksChain.new(k) }
73
+ @setup_fixtures = false
65
74
  end
66
75
 
67
76
  # Add `before` hook for `begin` or
@@ -70,7 +79,7 @@ module TestProf
70
79
  # config.before(:rollback) { ... }
71
80
  def before(type, &block)
72
81
  validate_hook_type!(type)
73
- hooks[type].before << block if block_given?
82
+ hooks[type].before << block if block
74
83
  end
75
84
 
76
85
  # Add `after` hook for `begin` or
@@ -79,7 +88,7 @@ module TestProf
79
88
  # config.after(:begin) { ... }
80
89
  def after(type, &block)
81
90
  validate_hook_type!(type)
82
- hooks[type].after << block if block_given?
91
+ hooks[type].after << block if block
83
92
  end
84
93
 
85
94
  def run_hooks(type) # :nodoc:
@@ -18,6 +18,21 @@ module TestProf
18
18
  end
19
19
  ::ActiveRecord::Base.connection.rollback_transaction
20
20
  end
21
+
22
+ def setup_fixtures(test_object)
23
+ test_object.instance_eval do
24
+ @@already_loaded_fixtures ||= {}
25
+ @fixture_cache ||= {}
26
+ config = ::ActiveRecord::Base
27
+
28
+ if @@already_loaded_fixtures[self.class]
29
+ @loaded_fixtures = @@already_loaded_fixtures[self.class]
30
+ else
31
+ @loaded_fixtures = load_fixtures(config)
32
+ @@already_loaded_fixtures[self.class] = @loaded_fixtures
33
+ end
34
+ end
35
+ end
21
36
  end
22
37
  end
23
38
  end
@@ -6,7 +6,7 @@ module TestProf
6
6
  module CustomEvents
7
7
  class << self
8
8
  def register(event, &block)
9
- raise ArgumentError, "Block is required!" unless block_given?
9
+ raise ArgumentError, "Block is required!" unless block
10
10
  registrations[event] = block
11
11
  end
12
12
 
@@ -26,7 +26,7 @@ module TestProf::EventProf
26
26
 
27
27
  class << self
28
28
  def subscribe(event, &block)
29
- raise ArgumentError, "Block is required!" unless block_given?
29
+ raise ArgumentError, "Block is required!" unless block
30
30
 
31
31
  ::ActiveSupport::Notifications.subscribe(event, Subscriber.new(block))
32
32
  end
@@ -6,7 +6,7 @@ module TestProf
6
6
  attr_reader :event, :total_count, :total_time, :rank_by, :top_count, :per_example,
7
7
  :time, :count, :example_time, :example_count, :absolute_run_time
8
8
 
9
- alias per_example? per_example
9
+ alias_method :per_example?, :per_example
10
10
 
11
11
  def initialize(event:, instrumenter:, rank_by: :time, top_count: 5, per_example: false)
12
12
  @event = event
@@ -88,14 +88,13 @@ module TestProf
88
88
  end
89
89
 
90
90
  def results
91
- results = {
91
+ {
92
92
  groups: @groups.to_a
93
93
  }.tap do |data|
94
94
  next unless per_example?
95
95
 
96
96
  data[:examples] = @examples.to_a
97
97
  end
98
- results
99
98
  end
100
99
 
101
100
  def take_time(start_ts)
@@ -130,7 +129,7 @@ module TestProf
130
129
  end
131
130
 
132
131
  def each(&block)
133
- if block_given?
132
+ if block
134
133
  @profilers.each(&block)
135
134
  else
136
135
  @profilers.each
@@ -10,7 +10,7 @@ module TestProf
10
10
  # flamegraphs or detect most popular factories
11
11
  module FactoryProf
12
12
  FACTORY_BUILDERS = [FactoryBuilders::FactoryBot,
13
- FactoryBuilders::Fabrication].freeze
13
+ FactoryBuilders::Fabrication].freeze
14
14
 
15
15
  # FactoryProf configuration
16
16
  class Configuration
@@ -12,7 +12,7 @@ module TestProf
12
12
  def logger
13
13
  return @logger if instance_variable_defined?(:@logger)
14
14
 
15
- @logger = Logger.new(STDOUT)
15
+ @logger = Logger.new($stdout)
16
16
  end
17
17
 
18
18
  def ar_loggables
@@ -8,33 +8,45 @@ module TestProf
8
8
  # store instance variables
9
9
  module Minitest # :nodoc: all
10
10
  class Executor
11
- attr_reader :active, :block, :captured_ivars
11
+ attr_reader :active, :block, :captured_ivars, :teardown_block, :current_test_object,
12
+ :setup_fixtures
12
13
 
13
- alias active? active
14
+ alias_method :active?, :active
15
+ alias_method :setup_fixtures?, :setup_fixtures
14
16
 
15
- def initialize(&block)
17
+ def initialize(setup_fixtures: false, &block)
18
+ @setup_fixtures = setup_fixtures
16
19
  @block = block
17
20
  @captured_ivars = []
18
21
  end
19
22
 
23
+ def teardown(&block)
24
+ @teardown_block = block
25
+ end
26
+
20
27
  def activate!(test_object)
28
+ @current_test_object = test_object
29
+
21
30
  return restore_ivars(test_object) if active?
22
31
  @active = true
23
- @examples_left = test_object.class.runnable_methods.size
32
+ BeforeAll.setup_fixtures(test_object) if setup_fixtures?
24
33
  BeforeAll.begin_transaction do
25
34
  capture!(test_object)
26
35
  end
27
36
  end
28
37
 
29
- def try_deactivate!
30
- @examples_left -= 1
31
- return unless @examples_left.zero?
32
-
38
+ def deactivate!
33
39
  @active = false
40
+
41
+ current_test_object&.instance_eval(&teardown_block) if teardown_block
42
+
43
+ @current_test_object = nil
34
44
  BeforeAll.rollback_transaction
35
45
  end
36
46
 
37
47
  def capture!(test_object)
48
+ return unless block
49
+
38
50
  before_ivars = test_object.instance_variables
39
51
 
40
52
  test_object.instance_eval(&block)
@@ -63,21 +75,29 @@ module TestProf
63
75
  module ClassMethods
64
76
  attr_accessor :before_all_executor
65
77
 
66
- def before_all(&block)
67
- self.before_all_executor = Executor.new(&block)
78
+ def before_all(setup_fixtures: BeforeAll.config.setup_fixtures, &block)
79
+ self.before_all_executor = Executor.new(setup_fixtures: setup_fixtures, &block)
68
80
 
69
81
  prepend(Module.new do
70
- def setup
82
+ def before_setup
71
83
  self.class.before_all_executor.activate!(self)
72
84
  super
73
85
  end
86
+ end)
74
87
 
75
- def teardown
88
+ singleton_class.prepend(Module.new do
89
+ def run(*)
76
90
  super
77
- self.class.before_all_executor.try_deactivate!
91
+ ensure
92
+ before_all_executor&.deactivate!
78
93
  end
79
94
  end)
80
95
  end
96
+
97
+ def after_all(&block)
98
+ self.before_all_executor ||= Executor.new
99
+ before_all_executor.teardown(&block)
100
+ end
81
101
  end
82
102
  end
83
103
  end
@@ -15,7 +15,7 @@ RSpec.configure do |config|
15
15
  config.include_context "any_fixture:clean", with_clean_fixture: true
16
16
 
17
17
  config.after(:suite) do
18
- TestProf::AnyFixture.report_stats if TestProf::AnyFixture.reporting_enabled?
18
+ TestProf::AnyFixture.report_stats if TestProf::AnyFixture.config.reporting_enabled?
19
19
  TestProf::AnyFixture.reset
20
20
  end
21
21
  end
@@ -6,14 +6,22 @@ module TestProf
6
6
  module BeforeAll
7
7
  # Helper to wrap the whole example group into a transaction
8
8
  module RSpec
9
- def before_all(&block)
10
- raise ArgumentError, "Block is required!" unless block_given?
9
+ def before_all(setup_fixtures: BeforeAll.config.setup_fixtures, &block)
10
+ raise ArgumentError, "Block is required!" unless block
11
11
 
12
- return before(:all, &block) if within_before_all?
12
+ if within_before_all?
13
+ before(:all) do
14
+ @__inspect_output = "before_all hook"
15
+ instance_eval(&block)
16
+ end
17
+ return
18
+ end
13
19
 
14
20
  @__before_all_activated__ = true
15
21
 
16
22
  before(:all) do
23
+ @__inspect_output = "before_all hook"
24
+ BeforeAll.setup_fixtures(self) if setup_fixtures
17
25
  BeforeAll.begin_transaction do
18
26
  instance_eval(&block)
19
27
  end
@@ -55,9 +55,7 @@ module TestProf
55
55
  end
56
56
 
57
57
  def module_for(group)
58
- modules[group] ||= begin
59
- Module.new.tap { |mod| group.prepend(mod) }
60
- end
58
+ modules[group] ||= Module.new.tap { |mod| group.prepend(mod) }
61
59
  end
62
60
 
63
61
  private
@@ -91,8 +89,7 @@ module TestProf
91
89
  initializer = proc do
92
90
  instance_variable_set(:"#{TestProf::LetItBe::PREFIX}#{identifier}", instance_exec(&block))
93
91
  rescue FrozenError => e
94
- e.message << TestProf::LetItBe::FROZEN_ERROR_HINT
95
- raise
92
+ raise e.exception("#{e.message}#{TestProf::LetItBe::FROZEN_ERROR_HINT}")
96
93
  end
97
94
 
98
95
  default_options = LetItBe.config.default_modifiers.dup
@@ -108,8 +105,9 @@ module TestProf
108
105
 
109
106
  LetItBe.module_for(self).module_eval do
110
107
  define_method(identifier) do
111
- # Trying to detect the context (couldn't find other way so far)
112
- if /\(:context\)/.match?(@__inspect_output)
108
+ # Trying to detect the context
109
+ # Based on https://github.com/rspec/rspec-rails/commit/7cb796db064f58da7790a92e73ab906ef50b1f34
110
+ if @__inspect_output.include?("before(:context)") || @__inspect_output.include?("before_all")
113
111
  instance_variable_get(:"#{PREFIX}#{identifier}")
114
112
  else
115
113
  # Fallback to let definition
@@ -242,7 +240,7 @@ end
242
240
  RSpec.configure do |config|
243
241
  config.after(:example) do |example|
244
242
  if example.exception&.is_a?(FrozenError)
245
- example.exception.message << TestProf::LetItBe::FROZEN_ERROR_HINT
243
+ example.exception.message << TestProf::LetItBe::FROZEN_ERROR_HINT unless example.exception.message.frozen?
246
244
  end
247
245
  end
248
246
  end
@@ -38,7 +38,7 @@ module TestProf
38
38
  attr_accessor :top_count, :let_stats_enabled,
39
39
  :let_top_count
40
40
 
41
- alias let_stats_enabled? let_stats_enabled
41
+ alias_method :let_stats_enabled?, :let_stats_enabled
42
42
 
43
43
  attr_reader :mode
44
44
 
@@ -139,7 +139,7 @@ end
139
139
 
140
140
  require "test_prof/rspec_dissect/collectors/let"
141
141
  require "test_prof/rspec_dissect/collectors/before"
142
- require "test_prof/rspec_dissect/rspec" if TestProf.rspec?
142
+ require "test_prof/rspec_dissect/rspec"
143
143
 
144
144
  TestProf.activate("RD_PROF") do
145
145
  TestProf::RSpecDissect.init
@@ -239,16 +239,18 @@ module TestProf
239
239
  end
240
240
 
241
241
  def exclude_common_methods(profiler)
242
- profiler.exclude_methods!(
243
- TSort,
244
- :tsort_each
245
- )
242
+ if defined?(TSort)
243
+ profiler.exclude_methods!(
244
+ TSort,
245
+ :tsort_each
246
+ )
246
247
 
247
- profiler.exclude_methods!(
248
- TSort.singleton_class,
249
- :tsort_each, :each_strongly_connected_component,
250
- :each_strongly_connected_component_from
251
- )
248
+ profiler.exclude_methods!(
249
+ TSort.singleton_class,
250
+ :tsort_each, :each_strongly_connected_component,
251
+ :each_strongly_connected_component_from
252
+ )
253
+ end
252
254
 
253
255
  profiler.exclude_methods!(
254
256
  BasicObject,
@@ -14,7 +14,7 @@ module TestProf
14
14
  def initialize(max_size, sort_by: nil, &block)
15
15
  @max_size = max_size
16
16
  @comparator =
17
- if block_given?
17
+ if block
18
18
  block
19
19
  elsif !sort_by.nil?
20
20
  ->(x, y) { x[sort_by] >= y[sort_by] }
@@ -42,7 +42,7 @@ module TestProf
42
42
  end
43
43
 
44
44
  def each(&block)
45
- if block_given?
45
+ if block
46
46
  data.each(&block)
47
47
  else
48
48
  data.each
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TestProf
4
- VERSION = "1.0.0.rc1"
4
+ VERSION = "1.0.3"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: test-prof
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc1
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-30 00:00:00.000000000 Z
11
+ date: 2021-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -219,7 +219,7 @@ metadata:
219
219
  documentation_uri: https://test-prof.evilmartians.io/
220
220
  homepage_uri: https://test-prof.evilmartians.io/
221
221
  source_code_uri: http://github.com/test-prof/test-prof
222
- post_install_message:
222
+ post_install_message:
223
223
  rdoc_options: []
224
224
  require_paths:
225
225
  - lib
@@ -230,12 +230,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
230
230
  version: 2.5.0
231
231
  required_rubygems_version: !ruby/object:Gem::Requirement
232
232
  requirements:
233
- - - ">"
233
+ - - ">="
234
234
  - !ruby/object:Gem::Version
235
- version: 1.3.1
235
+ version: '0'
236
236
  requirements: []
237
- rubygems_version: 3.0.6
238
- signing_key:
237
+ rubygems_version: 3.2.15
238
+ signing_key:
239
239
  specification_version: 4
240
240
  summary: Ruby applications tests profiling tools
241
241
  test_files: []