minitest-holdify 1.0.1 → 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: e52a7f895ae3023c767178f3b678fbb7daa0da3f0253ee83a4428cccfa23cce0
4
- data.tar.gz: 56f7bf3e4903f8506053b7fecb3be01c3ac642f6b2d9f490cdcdbb0fc303dfa3
3
+ metadata.gz: 06f80be32b494ec786f8d873556a8046d6e051854ce38051c1f9a41ecce91fe7
4
+ data.tar.gz: 95efd3e040696f2eacdbcf61b378db9c51bb33889f73b54c418d8bb0417e6244
5
5
  SHA512:
6
- metadata.gz: 26522a5a41ee3ff122d748a0536f830d9d7c7d1b376ae3d3f42fe8df46ad2852f4aad48239df5bd0a70ba29af127a51da5efdf565fbeea5700f65833f455cd88
7
- data.tar.gz: add1f22c79883b79477340aa077921b981916fbeb36807944b2d6d85d00720baefa76241bdfcd59fa120c0e1b403b0fee381a7db04adf2e09a9a51dca65e764a
6
+ metadata.gz: 3174aad64ba870444147f629ca38dddbbafce4b57d94d72d32febc1c32afdc56c6f2415337e43fab7be44a45a7d7edae7197aabc06f5ea82504bc868ca3ab123
7
+ data.tar.gz: a336655be1c76832e50c00b919bbb7ecc8a735b1b49e8067a8df3506fa7a6ef2f7b1553b10356bca2fd54025a0fb22a936bdc70f390eaaa124e244f978407df9
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Holdify
4
+ # The *_hold statement (Assertion/Expectation)
5
+ class Hold
6
+ attr_reader :forced
7
+
8
+ def initialize(test)
9
+ @test = test
10
+ @path, = test.method(test.name).source_location
11
+ @store = Holdify.stores[@path] ||= Store.new(@path)
12
+ @session = Hash.new { |h, k| h[k] = [] }
13
+ @forced = []
14
+ @added = []
15
+ end
16
+
17
+ def call(actual, force: false)
18
+ location = find_location
19
+ id = @store.id_at(location.lineno)
20
+ raise "Could not find holdify statement at line #{location.lineno}" unless id
21
+
22
+ @session[id] << actual
23
+ @forced << "#{location.path}:#{location.lineno}" if force
24
+
25
+ return actual if force || Holdify.reconcile
26
+
27
+ stored = @store.stored(id)
28
+ index = @session[id].size - 1
29
+ return stored[index] if stored && index < stored.size
30
+
31
+ @added << "#{location.path}:#{location.lineno}"
32
+ actual
33
+ end
34
+
35
+ def save
36
+ return unless @test.failures.empty?
37
+
38
+ @added.each { |loc| warn "[holdify] Held new value for #{loc}" } unless Holdify.quiet
39
+ @session.each { |id, values| @store.update(id, values) }
40
+ @store.save
41
+ end
42
+
43
+ def find_location
44
+ caller_locations.find do |location|
45
+ next unless location.path == @path
46
+
47
+ label = location.base_label
48
+ label == @test.name || label == '<top (required)>' || label == '<main>' || label.start_with?('<class:', '<module:')
49
+ end
50
+ end
51
+ end
52
+ end
data/lib/holdify/store.rb CHANGED
@@ -2,13 +2,14 @@
2
2
 
3
3
  require 'yaml'
4
4
  require 'fileutils'
5
+ require 'digest/sha1'
5
6
 
6
- class Holdify
7
+ module Holdify
7
8
  # A simple Hash-based store that syncs with a static source map
8
9
  class Store
9
10
  def initialize(source_path)
10
11
  @path = "#{source_path}#{CONFIG[:ext]}"
11
- File.delete(@path) if Holdify.rebuild && File.exist?(@path)
12
+ File.delete(@path) if Holdify.reconcile && File.exist?(@path)
12
13
 
13
14
  @source = {} # { lineno => id }
14
15
  File.foreach(source_path).with_index(1) do |line, lineno|
data/lib/holdify.rb CHANGED
@@ -1,69 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'digest/sha1'
4
3
  require_relative 'holdify/store'
4
+ require_relative 'holdify/hold'
5
5
 
6
6
  # Add description
7
- class Holdify
8
- VERSION = '1.0.1'
7
+ module Holdify
8
+ VERSION = '1.0.3'
9
9
  CONFIG = { ext: '.yaml' }.freeze
10
10
 
11
11
  class << self
12
- attr_accessor :rebuild, :quiet
12
+ attr_accessor :reconcile, :quiet
13
13
 
14
14
  def stores = @stores ||= {}
15
15
  end
16
-
17
- attr_reader :forced
18
-
19
- def initialize(test)
20
- @test = test
21
- @path, = test.method(test.name).source_location
22
- @store = self.class.stores[@path] ||= Store.new(@path)
23
- @session = Hash.new { |h, k| h[k] = [] }
24
- @forced = []
25
- end
26
-
27
- def hold(actual, force: false)
28
- location = find_location
29
- id = @store.id_at(location.lineno)
30
- raise "Could not find holdify statement at line #{location.lineno}" unless id
31
-
32
- @session[id] << actual
33
- @forced << "#{location.path}:#{location.lineno}" if force
34
-
35
- return actual if force || self.class.rebuild
36
-
37
- stored = @store.stored(id)
38
- index = @session[id].size - 1
39
- return stored[index] if stored && index < stored.size
40
-
41
- # :nocov:
42
- warn "[holdify] Held new value for #{location.path}:#{location.lineno}" unless self.class.quiet
43
- # :nocov:
44
- actual
45
- end
46
-
47
- def save
48
- return unless @test.failures.empty?
49
-
50
- @session.each { |id, values| @store.update(id, values) }
51
- @store.save
52
- end
53
-
54
- def find_location
55
- caller_locations.find do |location|
56
- next unless location.path == @path
57
-
58
- label = location.base_label
59
- # :nocov:
60
- label = ::Regexp.last_match(1) if label.start_with?('block ') && label =~ / in (.+)$/
61
- # :nocov:
62
-
63
- label == @test.name ||
64
- label == '<top (required)>' ||
65
- label == '<main>' ||
66
- label.start_with?('<class:', '<module:')
67
- end
68
- end
69
16
  end
@@ -6,34 +6,26 @@ require 'holdify'
6
6
  module Minitest
7
7
  # Set the Holdify options
8
8
  def self.plugin_holdify_options(opts, _options)
9
- opts.on '--holdify-rebuild', 'Rebuild the stores with the current entries/values' do
10
- Holdify.rebuild = true
11
- Holdify.quiet = true
9
+ opts.on '--holdify-reconcile', 'Reconcile the held values with the new ones' do
10
+ Holdify.reconcile = true
11
+ Holdify.quiet = true
12
12
  end
13
- # :nocov:
14
13
  opts.on '--holdify-quiet', 'Skip the warning on storing a new value' do
15
14
  Holdify.quiet = true
16
15
  end
17
- # :nocov:
18
16
  end
19
17
 
20
18
  # Reopen the minitest class
21
19
  class Test
22
- # Create the @holdify instance for each test
23
- def after_setup
24
- super
25
- @holdify ||= Holdify.new(self) # rubocop:disable Naming/MemoizedInstanceVariableName
26
- end
27
-
28
20
  # Ensure store is tidied and saved after the test runs
29
21
  def before_teardown
30
22
  super
31
- @holdify&.save
32
- return unless @holdify&.forced&.any? && failures.empty?
23
+ @hold&.save
24
+ return unless @hold&.forced&.any? && failures.empty?
33
25
 
34
26
  msg = <<~MSG.chomp
35
27
  [holdify] the value has been stored: remove the "!" suffix to pass the test
36
- #{@holdify.forced.uniq.map { |l| " #{l}" }.join("\n")}
28
+ #{@hold.forced.uniq.map { |l| " #{l}" }.join("\n")}
37
29
  MSG
38
30
  raise Minitest::Assertion, msg
39
31
  end
@@ -42,38 +34,37 @@ module Minitest
42
34
  # Reopen the minitest module
43
35
  module Assertions
44
36
  # Main assertion
45
- def assert_hold(actual, *args)
46
- @holdify ||= Holdify.new(self)
37
+ def assert_hold(actual, *args, inspect: false, **)
38
+ @hold ||= Holdify::Hold.new(self)
47
39
  assertion, message = args
48
40
  assertion, message = message, assertion unless assertion.nil? || assertion.is_a?(Symbol)
41
+ expected = @hold.(actual, **)
49
42
 
50
- expected = @holdify.hold(actual)
51
43
  if actual.nil?
52
44
  assert_nil expected, message
53
45
  else
54
46
  send(assertion || :assert_equal, expected, actual, message)
55
47
  end
48
+
49
+ if inspect
50
+ location = @hold.find_location
51
+ warn "[holdify] The value from #{location.path}:#{location.lineno} is:\n[holdify] => #{actual.inspect}"
52
+ end
53
+
54
+ expected
56
55
  end
57
56
 
58
57
  # Temporarily used to store the actual value, useful for reconciliation of expected changed values
59
- def assert_hold!(actual, *)
60
- @holdify ||= Holdify.new(self)
61
- @holdify.hold(actual, force: true)
62
- end
58
+ def assert_hold!(*, **) = assert_hold(*, **, force: true)
63
59
 
64
60
  # Temporarily used for development feedback to print to STDERR the actual value
65
- def assert_hold_?(actual, *)
66
- @holdify ||= Holdify.new(self)
67
- location = @holdify.find_location
68
- warn "[holdify] Actual value dumped from: #{location.path}:#{location.lineno}\n=> #{actual.inspect}"
69
- @holdify.hold(actual)
70
- end
61
+ def assert_hold?(*, **) = assert_hold(*, **, inspect: true)
71
62
  end
72
63
 
73
64
  # Register expectations only if minitest/spec is loaded; ensure the right class in 6.0 and < 6.0
74
65
  # :nocov:
75
66
  if (expectation_class = defined?(Spec) && (defined?(Expectation) ? Expectation : Expectations))
76
- %w[hold hold! hold_?].each do |suffix|
67
+ %w[hold hold! hold?].each do |suffix|
77
68
  expectation_class.infect_an_assertion :"assert_#{suffix}", :"must_#{suffix}", :reverse
78
69
  expectation_class.alias_method :"to_#{suffix}", :"must_#{suffix}"
79
70
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minitest-holdify
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Domizio Demichelis
@@ -33,6 +33,7 @@ extra_rdoc_files: []
33
33
  files:
34
34
  - LICENSE.txt
35
35
  - lib/holdify.rb
36
+ - lib/holdify/hold.rb
36
37
  - lib/holdify/store.rb
37
38
  - lib/minitest-holdify.rb
38
39
  - lib/minitest/holdify_plugin.rb