test-prof 1.0.0.rc1 → 1.0.3

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: 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: []