minitest-holdify 1.0.2 → 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 +4 -4
- data/lib/holdify/hold.rb +52 -0
- data/lib/holdify/store.rb +2 -1
- data/lib/holdify.rb +3 -56
- data/lib/minitest/holdify_plugin.rb +16 -25
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 06f80be32b494ec786f8d873556a8046d6e051854ce38051c1f9a41ecce91fe7
|
|
4
|
+
data.tar.gz: 95efd3e040696f2eacdbcf61b378db9c51bb33889f73b54c418d8bb0417e6244
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3174aad64ba870444147f629ca38dddbbafce4b57d94d72d32febc1c32afdc56c6f2415337e43fab7be44a45a7d7edae7197aabc06f5ea82504bc868ca3ab123
|
|
7
|
+
data.tar.gz: a336655be1c76832e50c00b919bbb7ecc8a735b1b49e8067a8df3506fa7a6ef2f7b1553b10356bca2fd54025a0fb22a936bdc70f390eaaa124e244f978407df9
|
data/lib/holdify/hold.rb
ADDED
|
@@ -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
data/lib/holdify.rb
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
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
|
-
|
|
8
|
-
VERSION = '1.0.
|
|
7
|
+
module Holdify
|
|
8
|
+
VERSION = '1.0.3'
|
|
9
9
|
CONFIG = { ext: '.yaml' }.freeze
|
|
10
10
|
|
|
11
11
|
class << self
|
|
@@ -13,57 +13,4 @@ class Holdify
|
|
|
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.reconcile
|
|
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
|
|
@@ -10,30 +10,22 @@ module Minitest
|
|
|
10
10
|
Holdify.reconcile = true
|
|
11
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
|
-
@
|
|
32
|
-
return unless @
|
|
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
|
-
#{@
|
|
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
|
-
@
|
|
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!(
|
|
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
|
|
66
|
-
@holdify ||= Holdify.new(self)
|
|
67
|
-
location = @holdify.find_location
|
|
68
|
-
warn "[holdify] Actual value 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!
|
|
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.
|
|
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
|