minitest-holdify 1.1.2 → 1.1.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 +18 -18
- data/lib/holdify/ledger.rb +17 -19
- data/lib/holdify/source.rb +10 -10
- data/lib/holdify/store.rb +2 -2
- data/lib/holdify.rb +14 -2
- data/lib/minitest/holdify_plugin.rb +11 -3
- metadata +7 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7560a67982ab6acf747a90307f0fc5fca6ff30c4675aefaf92c973afaa01fe65
|
|
4
|
+
data.tar.gz: 928f88bd3d8711d13817c924a5c587117e9e61d1cb3a7301b2a097f7cfafb95a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b2cb240ed6c9d90797003b00508b4640d694617b78661fd8ff59a7533eb771a58e12d1f24024cf09d71224c490446c92f325b3bc4b0217ee2c2774d3f78ab4f9
|
|
7
|
+
data.tar.gz: aa038a10daa87f5d4700d7778dd86e75049d06036f2435b769c455b2f4f37e08fac5a21a91d7a375f06a53dda9a5c2ac50858f4e26cdde27e4d2a6732976fa7c
|
data/lib/holdify/hold.rb
CHANGED
|
@@ -8,37 +8,37 @@ module Holdify
|
|
|
8
8
|
def initialize(test)
|
|
9
9
|
@test = test
|
|
10
10
|
@path, = test.method(test.name).source_location
|
|
11
|
-
@store = Holdify.stores
|
|
11
|
+
@store = Holdify.stores(@path)
|
|
12
12
|
@session = Hash.new { |h, k| h[k] = [] } # { line => [values] }
|
|
13
|
-
@forced = [] # [
|
|
14
|
-
@added = [] # [
|
|
13
|
+
@forced = [] # [ line ]
|
|
14
|
+
@added = [] # [ line ]
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def call(actual, force: false)
|
|
18
18
|
location = find_location
|
|
19
19
|
line = location.lineno
|
|
20
|
-
raise "Could not find holdify statement at line #{line}" unless @store.
|
|
20
|
+
raise "Could not find holdify statement at line #{line}" unless @store.xxh(line)
|
|
21
21
|
|
|
22
|
-
@
|
|
23
|
-
@forced << "#{@path}:#{line}" if force
|
|
22
|
+
@forced << line if force
|
|
24
23
|
|
|
25
|
-
return actual if force || Holdify.reconcile
|
|
26
|
-
|
|
27
|
-
# Expected value
|
|
28
24
|
values = @store.get(line)
|
|
29
|
-
index = @session[line].size
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
25
|
+
index = @session[line].size
|
|
26
|
+
value = if force || Holdify.reconcile
|
|
27
|
+
actual
|
|
28
|
+
elsif values && index < values.size
|
|
29
|
+
values[index]
|
|
30
|
+
else
|
|
31
|
+
@added << line
|
|
32
|
+
actual
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
@session[line] << value
|
|
36
|
+
value
|
|
34
37
|
end
|
|
35
38
|
|
|
36
39
|
def save
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
@added.each { |loc| warn "[holdify] Held new value for #{loc}" } unless Holdify.quiet
|
|
40
|
+
@added.each { |line| warn "[holdify] Held new value for #{@path}:#{line}" } unless Holdify.quiet
|
|
40
41
|
@session.each { |line, values| @store.set(line, values) }
|
|
41
|
-
@store.save
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
# Find the location in the test that triggered the hold
|
data/lib/holdify/ledger.rb
CHANGED
|
@@ -9,28 +9,26 @@ module Holdify
|
|
|
9
9
|
def initialize(path, source)
|
|
10
10
|
@path = "#{path}#{CONFIG[:ext]}"
|
|
11
11
|
@source = source
|
|
12
|
-
|
|
13
|
-
@data = load_and_align
|
|
12
|
+
FileUtils.rm_f(@path) if Holdify.reconcile
|
|
13
|
+
@data = File.exist?(@path) ? load_and_align : {}
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def get(line) = @data[line]
|
|
17
17
|
|
|
18
18
|
def set(line, values) = (@data[line] = values)
|
|
19
19
|
|
|
20
|
-
def
|
|
20
|
+
def persist
|
|
21
21
|
return FileUtils.rm_f(@path) if @data.empty?
|
|
22
22
|
|
|
23
23
|
output = {}
|
|
24
24
|
@data.keys.sort.each do |line|
|
|
25
|
-
|
|
26
|
-
next unless
|
|
25
|
+
xxh = @source.xxh(line)
|
|
26
|
+
next unless xxh
|
|
27
27
|
|
|
28
|
-
output["L#{line} #{
|
|
28
|
+
output["L#{line} #{xxh}"] = @data[line]
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
content = YAML.dump(output, line_width: 78) # Ensure 80 columns (including pretty gutter)
|
|
32
|
-
return if File.exist?(@path) && File.read(@path) == content
|
|
33
|
-
|
|
34
32
|
File.write(@path, content)
|
|
35
33
|
end
|
|
36
34
|
|
|
@@ -38,19 +36,19 @@ module Holdify
|
|
|
38
36
|
|
|
39
37
|
def load_and_align
|
|
40
38
|
{}.tap do |aligned|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
next if
|
|
45
|
-
|
|
46
|
-
#
|
|
47
|
-
|
|
48
|
-
|
|
39
|
+
data = YAML.unsafe_load_file(@path) || {}
|
|
40
|
+
data.group_by { |k, _| k.split.last }.each do |xxh, entries|
|
|
41
|
+
lines = @source.lines(xxh)
|
|
42
|
+
next if lines.empty?
|
|
43
|
+
|
|
44
|
+
# Position of the held lines compared to the source lines
|
|
45
|
+
stayed, moved = entries.map { |key, values| { line: key[/\d+/].to_i, values: values } }
|
|
46
|
+
.partition { |c| lines.include?(c[:line]) }
|
|
49
47
|
moved.sort_by! { |c| c[:line] }
|
|
50
48
|
|
|
51
|
-
#
|
|
52
|
-
|
|
53
|
-
match
|
|
49
|
+
# Align lines
|
|
50
|
+
lines.each do |line|
|
|
51
|
+
match = stayed.find { |c| c[:line] == line } || moved.shift
|
|
54
52
|
aligned[line] = match[:values] if match
|
|
55
53
|
end
|
|
56
54
|
end
|
data/lib/holdify/source.rb
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'xxhash'
|
|
3
|
+
require 'digest/xxhash'
|
|
4
4
|
|
|
5
5
|
module Holdify
|
|
6
6
|
# Represents the current state of the source file
|
|
7
7
|
class Source
|
|
8
|
-
def initialize(path) = (@
|
|
8
|
+
def initialize(path) = (@line_xxh, @xxh_lines = parse(path))
|
|
9
9
|
|
|
10
|
-
def
|
|
10
|
+
def xxh(line) = @line_xxh[line]
|
|
11
11
|
|
|
12
|
-
def
|
|
12
|
+
def lines(xxh) = @xxh_lines[xxh]
|
|
13
13
|
|
|
14
14
|
private
|
|
15
15
|
|
|
16
16
|
def parse(path)
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
line_xxh = {}
|
|
18
|
+
xxh_lines = Hash.new { |h, k| h[k] = [] }
|
|
19
19
|
|
|
20
20
|
File.foreach(path).with_index(1) do |text, line|
|
|
21
21
|
content = text.strip
|
|
22
22
|
next if content.empty?
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
xxh = Digest::XXH3_64bits.hexdigest(content)
|
|
25
|
+
line_xxh[line] = xxh
|
|
26
|
+
xxh_lines[xxh] << line
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
[
|
|
29
|
+
[line_xxh, xxh_lines]
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
end
|
data/lib/holdify/store.rb
CHANGED
data/lib/holdify.rb
CHANGED
|
@@ -5,14 +5,24 @@ require_relative 'holdify/hold'
|
|
|
5
5
|
|
|
6
6
|
# The container module
|
|
7
7
|
module Holdify
|
|
8
|
-
VERSION = '1.1.
|
|
8
|
+
VERSION = '1.1.3'
|
|
9
9
|
CONFIG = { ext: '.yaml' }.freeze
|
|
10
10
|
|
|
11
11
|
class << self
|
|
12
12
|
attr_accessor :reconcile, :quiet
|
|
13
13
|
attr_writer :pretty
|
|
14
14
|
|
|
15
|
-
def stores =
|
|
15
|
+
def stores(path = nil)
|
|
16
|
+
return @stores unless path
|
|
17
|
+
|
|
18
|
+
@mutex.synchronize do
|
|
19
|
+
@stores[path] ||= Store.new(path)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def persist_all!
|
|
24
|
+
@stores&.each_value(&:persist)
|
|
25
|
+
end
|
|
16
26
|
|
|
17
27
|
def pretty
|
|
18
28
|
return @pretty unless @pretty.nil?
|
|
@@ -21,4 +31,6 @@ module Holdify
|
|
|
21
31
|
system('git --version', out: File::NULL, err: File::NULL)
|
|
22
32
|
end
|
|
23
33
|
end
|
|
34
|
+
@mutex = Mutex.new
|
|
35
|
+
@stores = {}
|
|
24
36
|
end
|
|
@@ -5,6 +5,11 @@ require 'holdify/pretty'
|
|
|
5
5
|
|
|
6
6
|
# Implement the minitest plugin
|
|
7
7
|
module Minitest
|
|
8
|
+
# Register the after_run hook to persist all data
|
|
9
|
+
def self.plugin_holdify_init(_options)
|
|
10
|
+
Minitest.after_run { Holdify.persist_all! }
|
|
11
|
+
end
|
|
12
|
+
|
|
8
13
|
# Set the Holdify options
|
|
9
14
|
def self.plugin_holdify_options(opts, _options)
|
|
10
15
|
opts.on '--holdify-reconcile', 'Reconcile the held values with the new ones' do
|
|
@@ -26,12 +31,15 @@ module Minitest
|
|
|
26
31
|
# Ensure store is tidied and saved after the test runs
|
|
27
32
|
def before_teardown
|
|
28
33
|
super
|
|
29
|
-
@hold
|
|
30
|
-
|
|
34
|
+
return unless failures.empty? && @hold
|
|
35
|
+
|
|
36
|
+
@hold.save
|
|
37
|
+
return unless @hold.forced.any?
|
|
31
38
|
|
|
39
|
+
path, = method(name).source_location
|
|
32
40
|
msg = <<~MSG.chomp
|
|
33
41
|
[holdify] the value has been stored: remove the "!" suffix to pass the test
|
|
34
|
-
#{@hold.forced.uniq.map { |l| " #{l}" }.join("\n")}
|
|
42
|
+
#{@hold.forced.uniq.map { |l| " #{path}:#{l}" }.join("\n")}
|
|
35
43
|
MSG
|
|
36
44
|
raise Minitest::Assertion, msg
|
|
37
45
|
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.1.
|
|
4
|
+
version: 1.1.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Domizio Demichelis
|
|
@@ -10,33 +10,33 @@ cert_chain: []
|
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
|
-
name:
|
|
13
|
+
name: digest-xxhash
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
16
|
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version:
|
|
18
|
+
version: 0.2.9
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version:
|
|
25
|
+
version: 0.2.9
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
|
-
name:
|
|
27
|
+
name: minitest
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
30
|
- - ">="
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: 0.
|
|
32
|
+
version: 5.0.0
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - ">="
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: 0.
|
|
39
|
+
version: 5.0.0
|
|
40
40
|
description: Stop maintaining large expected values in your test/fixture files! Hold
|
|
41
41
|
them automatically. Update them effortlessly.
|
|
42
42
|
email:
|