check_please 0.5.1 → 0.5.6
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/Gemfile.lock +1 -1
- data/README.md +32 -0
- data/lib/check_please.rb +50 -11
- data/lib/check_please/comparison.rb +94 -6
- data/lib/check_please/diffs.rb +18 -2
- data/lib/check_please/error.rb +4 -0
- data/lib/check_please/flags.rb +3 -0
- data/lib/check_please/path.rb +18 -16
- data/lib/check_please/path_segment.rb +9 -23
- data/lib/check_please/path_segment_matcher.rb +44 -0
- data/lib/check_please/printers.rb +3 -2
- data/lib/check_please/printers/long.rb +31 -0
- data/lib/check_please/version.rb +1 -1
- metadata +4 -3
- data/lib/check_please/refinements.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c5a664d82f1f1d267e0e45d5e259f6443e23f19d2d53aafdeca8a908984d6fe
|
4
|
+
data.tar.gz: 9296b3b4c859c7e07d96991dbaaaaf48ae005ac9c4c09d9be9353b85f668f33b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5e0293242c66c30aa1f093d78427183263e9be492577e081a8daa810e16250827401c7ee81e1764dcade73fd7934932430595f14ea9aecb5bf67219d2422124
|
7
|
+
data.tar.gz: 4bbe14148472e8c49d0af0a6b7eaf2ee3acd7f29ec26af23fd6f2fd23181ce5510886773a835474d0e53102d9c360702a3a5de90311ccb38bb552e0982055ced
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -22,6 +22,7 @@ structures parsed from either of those.
|
|
22
22
|
* [Repeatable Flags](#repeatable-flags)
|
23
23
|
* [Expanded Documentation for Specific Flags](#expanded-documentation-for-specific-flags)
|
24
24
|
* [Flag: match_by_key](#flag-match_by_key)
|
25
|
+
* [Flag: normalize_values](#flag-normalize_values)
|
25
26
|
* [TODO (maybe)](#todo-maybe)
|
26
27
|
* [Development](#development)
|
27
28
|
* [Contributing](#contributing)
|
@@ -420,6 +421,37 @@ the following path expression: `/authors/id=1/books/isbn=12345`
|
|
420
421
|
**This syntax is intended to be readable by humans first.** If you need to
|
421
422
|
build tooling that consumes it... well, I'm open to suggestions. :)
|
422
423
|
|
424
|
+
#### Flag: `normalize_values`
|
425
|
+
|
426
|
+
NOTE: This flag is only accessible via the Ruby API.
|
427
|
+
(I have no idea how to reasonably express it in a CLI flag.)
|
428
|
+
|
429
|
+
Before comparing values at specified paths, normalize both values using
|
430
|
+
the provided message or Proc.
|
431
|
+
|
432
|
+
To use an example from the tests, the following reference/candidate pair would
|
433
|
+
normally create three "mismatch" diffs:
|
434
|
+
|
435
|
+
```ruby
|
436
|
+
ref = { list: [ "foo", "bar", "yak" ] }
|
437
|
+
can = { list: [ :foo, :bar, :yak ] }
|
438
|
+
```
|
439
|
+
|
440
|
+
However, the values can be converted to String before comparison via any of the following:
|
441
|
+
|
442
|
+
```ruby
|
443
|
+
CheckPlease.diff(ref, can, normalize_values: { "/list/*" => ->(v) { v.to_s } })
|
444
|
+
CheckPlease.diff(ref, can, normalize_values: { "/list/*" => :to_s })
|
445
|
+
CheckPlease.diff(ref, can, normalize_values: { "/list/*" => "to_s" })
|
446
|
+
```
|
447
|
+
|
448
|
+
Note that the value of the flag is a Hash.
|
449
|
+
* Its keys must be strings representing path expressions.
|
450
|
+
* If the value associated with a given path is a lambda/proc, it will be
|
451
|
+
called with both the reference value and the candidate value.
|
452
|
+
* If the value is a String or Symbol, it will be sent as a message to
|
453
|
+
both the reference and candidate values using Object#send.
|
454
|
+
|
423
455
|
-----
|
424
456
|
|
425
457
|
# TODO (maybe)
|
data/lib/check_please.rb
CHANGED
@@ -7,17 +7,17 @@ require "check_please/error"
|
|
7
7
|
require "check_please/version"
|
8
8
|
|
9
9
|
module CheckPlease
|
10
|
-
autoload :Reification,
|
11
|
-
autoload :CLI,
|
12
|
-
autoload :Comparison,
|
13
|
-
autoload :Diff,
|
14
|
-
autoload :Diffs,
|
15
|
-
autoload :Flag,
|
16
|
-
autoload :Flags,
|
17
|
-
autoload :Path,
|
18
|
-
autoload :PathSegment,
|
19
|
-
autoload :
|
20
|
-
autoload :
|
10
|
+
autoload :Reification, "check_please/reification"
|
11
|
+
autoload :CLI, "check_please/cli"
|
12
|
+
autoload :Comparison, "check_please/comparison"
|
13
|
+
autoload :Diff, "check_please/diff"
|
14
|
+
autoload :Diffs, "check_please/diffs"
|
15
|
+
autoload :Flag, "check_please/flag"
|
16
|
+
autoload :Flags, "check_please/flags"
|
17
|
+
autoload :Path, "check_please/path"
|
18
|
+
autoload :PathSegment, "check_please/path_segment"
|
19
|
+
autoload :PathSegmentMatcher, "check_please/path_segment_matcher"
|
20
|
+
autoload :Printers, "check_please/printers"
|
21
21
|
end
|
22
22
|
|
23
23
|
|
@@ -143,4 +143,43 @@ module CheckPlease
|
|
143
143
|
EOF
|
144
144
|
end
|
145
145
|
|
146
|
+
Flags.define :match_by_value do |flag|
|
147
|
+
flag.repeatable
|
148
|
+
flag.coerce { |value| CheckPlease::Path.reify(value) }
|
149
|
+
|
150
|
+
flag.cli_long = "--match-by-value FOO"
|
151
|
+
flag.description = <<~EOF
|
152
|
+
When comparing two arrays that match a specified path, the candidate
|
153
|
+
array will be scanned for each element in the reference array.
|
154
|
+
May be repeated; values will be treated as an 'OR' list.
|
155
|
+
NOTE: explodes if either array at a given path contains other collections.
|
156
|
+
NOTE: paths of 'extra' diffs use the index in the candidate array.
|
157
|
+
EOF
|
158
|
+
end
|
159
|
+
|
160
|
+
Flags.define :indifferent_keys do |flag|
|
161
|
+
flag.default = false
|
162
|
+
flag.coerce { |value| !!value }
|
163
|
+
|
164
|
+
flag.cli_long = "--indifferent-keys"
|
165
|
+
flag.description = <<~EOF
|
166
|
+
When comparing hashes, convert symbol keys to strings
|
167
|
+
EOF
|
168
|
+
end
|
169
|
+
|
170
|
+
Flags.define :indifferent_values do |flag|
|
171
|
+
flag.default = false
|
172
|
+
flag.coerce { |value| !!value }
|
173
|
+
|
174
|
+
flag.cli_long = "--indifferent-values"
|
175
|
+
flag.description = <<~EOF
|
176
|
+
When comparing values (that aren't arrays or hashes), convert symbols to strings
|
177
|
+
EOF
|
178
|
+
end
|
179
|
+
|
180
|
+
Flags.define :normalize_values do |flag|
|
181
|
+
# NOTE: This flag is only accessible via the Ruby API.
|
182
|
+
# See the README for documentation.
|
183
|
+
end
|
184
|
+
|
146
185
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module CheckPlease
|
2
|
-
using Refinements
|
3
2
|
|
4
3
|
class Comparison
|
5
4
|
def self.perform(reference, candidate, flags = {})
|
@@ -7,13 +6,13 @@ module CheckPlease
|
|
7
6
|
end
|
8
7
|
|
9
8
|
def perform(reference, candidate, flags = {})
|
10
|
-
@flags = Flags(flags)
|
9
|
+
@flags = Flags.reify(flags)
|
11
10
|
@diffs = Diffs.new(flags: @flags)
|
12
11
|
|
13
12
|
catch(:max_diffs_reached) do
|
14
13
|
compare reference, candidate, CheckPlease::Path.root
|
15
14
|
end
|
16
|
-
diffs
|
15
|
+
diffs.filter_by_flags(@flags)
|
17
16
|
end
|
18
17
|
|
19
18
|
private
|
@@ -22,7 +21,7 @@ module CheckPlease
|
|
22
21
|
def compare(ref, can, path)
|
23
22
|
return if path.excluded?(flags)
|
24
23
|
|
25
|
-
case
|
24
|
+
case types_for_compare(ref, can)
|
26
25
|
when [ :array, :array ] ; compare_arrays ref, can, path
|
27
26
|
when [ :hash, :hash ] ; compare_hashes ref, can, path
|
28
27
|
when [ :other, :other ] ; compare_others ref, can, path
|
@@ -31,7 +30,7 @@ module CheckPlease
|
|
31
30
|
end
|
32
31
|
end
|
33
32
|
|
34
|
-
def
|
33
|
+
def types_for_compare(*list)
|
35
34
|
list.map { |e|
|
36
35
|
case e
|
37
36
|
when Array ; :array
|
@@ -42,8 +41,11 @@ module CheckPlease
|
|
42
41
|
end
|
43
42
|
|
44
43
|
def compare_arrays(ref_array, can_array, path)
|
45
|
-
|
44
|
+
case
|
45
|
+
when ( key = path.key_to_match_by(flags) )
|
46
46
|
compare_arrays_by_key ref_array, can_array, path, key
|
47
|
+
when path.match_by_value?(flags)
|
48
|
+
compare_arrays_by_value ref_array, can_array, path
|
47
49
|
else
|
48
50
|
compare_arrays_by_index ref_array, can_array, path
|
49
51
|
end
|
@@ -52,6 +54,7 @@ module CheckPlease
|
|
52
54
|
def compare_arrays_by_key(ref_array, can_array, path, key_name)
|
53
55
|
refs_by_key = index_array!(ref_array, path, key_name, "reference")
|
54
56
|
cans_by_key = index_array!(can_array, path, key_name, "candidate")
|
57
|
+
|
55
58
|
key_values = (refs_by_key.keys | cans_by_key.keys)
|
56
59
|
|
57
60
|
key_values.compact! # NOTE: will break if nil is ever used as a key (but WHO WOULD DO THAT?!)
|
@@ -79,6 +82,10 @@ module CheckPlease
|
|
79
82
|
"The element at position #{i} in the #{ref_or_can} array is not a hash."
|
80
83
|
end
|
81
84
|
|
85
|
+
if flags.indifferent_keys
|
86
|
+
h = stringify_symbol_keys(h)
|
87
|
+
end
|
88
|
+
|
82
89
|
# try to get the value of the attribute identified by key_name
|
83
90
|
key_value = h.fetch(key_name) {
|
84
91
|
raise CheckPlease::NoSuchKeyError, \
|
@@ -102,6 +109,45 @@ module CheckPlease
|
|
102
109
|
elements_by_key
|
103
110
|
end
|
104
111
|
|
112
|
+
# FIXME: this can generate duplicate paths.
|
113
|
+
# Time to introduce lft_path, rgt_path ?
|
114
|
+
def compare_arrays_by_value(ref_array, can_array, path)
|
115
|
+
assert_can_match_by_value! ref_array
|
116
|
+
assert_can_match_by_value! can_array
|
117
|
+
|
118
|
+
matches = can_array.map { false }
|
119
|
+
|
120
|
+
# Look for missing values
|
121
|
+
ref_array.each.with_index do |ref, i|
|
122
|
+
new_path = path + (i+1) # count in human pls
|
123
|
+
|
124
|
+
# Weird, but necessary to handle duplicates properly
|
125
|
+
j = can_array.index.with_index { |can, j|
|
126
|
+
matches[j] == false && can == ref
|
127
|
+
}
|
128
|
+
|
129
|
+
if j
|
130
|
+
matches[j] = true
|
131
|
+
else
|
132
|
+
record_diff ref, nil, new_path, :missing
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Look for extra values
|
137
|
+
can_array.zip(matches).each.with_index do |(can, match), i|
|
138
|
+
next if match
|
139
|
+
new_path = path + (i+1) # count in human pls
|
140
|
+
record_diff nil, can, new_path, :extra
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def assert_can_match_by_value!(array)
|
145
|
+
if array.any? { |e| Array === e || Hash === e }
|
146
|
+
raise CheckPlease::BehaviorUndefined,
|
147
|
+
"match_by_value behavior is not defined for collections!"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
105
151
|
def compare_arrays_by_index(ref_array, can_array, path)
|
106
152
|
max_len = [ ref_array, can_array ].map(&:length).max
|
107
153
|
(0...max_len).each do |i|
|
@@ -121,11 +167,27 @@ module CheckPlease
|
|
121
167
|
end
|
122
168
|
|
123
169
|
def compare_hashes(ref_hash, can_hash, path)
|
170
|
+
if flags.indifferent_keys
|
171
|
+
ref_hash = stringify_symbol_keys(ref_hash)
|
172
|
+
can_hash = stringify_symbol_keys(can_hash)
|
173
|
+
end
|
124
174
|
record_missing_keys ref_hash, can_hash, path
|
125
175
|
compare_common_keys ref_hash, can_hash, path
|
126
176
|
record_extra_keys ref_hash, can_hash, path
|
127
177
|
end
|
128
178
|
|
179
|
+
def stringify_symbol_keys(h)
|
180
|
+
Hash[
|
181
|
+
h.map { |k,v|
|
182
|
+
[ stringify_symbol(k), v ]
|
183
|
+
}
|
184
|
+
]
|
185
|
+
end
|
186
|
+
|
187
|
+
def stringify_symbol(x)
|
188
|
+
Symbol === x ? x.to_s : x
|
189
|
+
end
|
190
|
+
|
129
191
|
def record_missing_keys(ref_hash, can_hash, path)
|
130
192
|
keys = ref_hash.keys - can_hash.keys
|
131
193
|
keys.each do |k|
|
@@ -148,10 +210,36 @@ module CheckPlease
|
|
148
210
|
end
|
149
211
|
|
150
212
|
def compare_others(ref, can, path)
|
213
|
+
ref = normalize_value(path, ref)
|
214
|
+
can = normalize_value(path, can)
|
215
|
+
|
151
216
|
return if ref == can
|
152
217
|
record_diff ref, can, path, :mismatch
|
153
218
|
end
|
154
219
|
|
220
|
+
def normalize_value(path, value)
|
221
|
+
if flags.indifferent_values
|
222
|
+
value = stringify_symbol(value)
|
223
|
+
end
|
224
|
+
|
225
|
+
if flags.normalize_values
|
226
|
+
# We assume that normalize_values is a hash of path expression strings to a proc, string, or symbol that will be used to normalize the value
|
227
|
+
_, normalizer = flags.normalize_values.detect { |path_string, a_proc|
|
228
|
+
path.match?(path_string)
|
229
|
+
}
|
230
|
+
|
231
|
+
case normalizer
|
232
|
+
when nil ; value
|
233
|
+
when Proc ; normalizer.call(value)
|
234
|
+
when String, Symbol ; value.send(normalizer)
|
235
|
+
else ; raise ArgumentError, "Not sure how to use #{normalizer.inspect} to normalize #{value.inspect}"
|
236
|
+
end
|
237
|
+
else
|
238
|
+
return value
|
239
|
+
end
|
240
|
+
|
241
|
+
end
|
242
|
+
|
155
243
|
def record_diff(ref, can, path, type)
|
156
244
|
diff = Diff.new(type, path, ref, can)
|
157
245
|
diffs << diff
|
data/lib/check_please/diffs.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
|
3
3
|
module CheckPlease
|
4
|
-
using Refinements
|
5
4
|
|
6
5
|
# Custom collection class for Diff instances.
|
7
6
|
# Can retrieve members using indexes or paths.
|
8
7
|
class Diffs
|
9
8
|
attr_reader :flags
|
10
9
|
def initialize(diff_list = nil, flags: {})
|
11
|
-
@flags = Flags(flags)
|
10
|
+
@flags = Flags.reify(flags)
|
12
11
|
@list = []
|
13
12
|
@hash = {}
|
14
13
|
Array(diff_list).each do |diff|
|
@@ -47,10 +46,27 @@ module CheckPlease
|
|
47
46
|
@list.map(&:attributes)
|
48
47
|
end
|
49
48
|
|
49
|
+
def filter_by_flags(flags)
|
50
|
+
new_list = @list.reject { |diff| Path.new(diff.path).excluded?(flags) }
|
51
|
+
self.class.new(new_list, flags: flags)
|
52
|
+
end
|
53
|
+
|
50
54
|
def to_s(flags = {})
|
51
55
|
CheckPlease::Printers.render(self, flags)
|
52
56
|
end
|
53
57
|
|
58
|
+
def method_missing(meth, *args, &blk)
|
59
|
+
if formats.include?(meth.to_sym)
|
60
|
+
CheckPlease::Printers.render(self, format: meth)
|
61
|
+
else
|
62
|
+
super
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def formats
|
67
|
+
CheckPlease::Printers::FORMATS
|
68
|
+
end
|
69
|
+
|
54
70
|
extend Forwardable
|
55
71
|
def_delegators :@list, *%i[
|
56
72
|
each
|
data/lib/check_please/error.rb
CHANGED
data/lib/check_please/flags.rb
CHANGED
data/lib/check_please/path.rb
CHANGED
@@ -17,7 +17,12 @@ module CheckPlease
|
|
17
17
|
def initialize(name_or_segments = [])
|
18
18
|
case name_or_segments
|
19
19
|
when String, Symbol, Numeric, nil
|
20
|
-
|
20
|
+
string = name_or_segments.to_s
|
21
|
+
if string =~ %r(//)
|
22
|
+
raise InvalidPath, "paths cannot have empty segments"
|
23
|
+
end
|
24
|
+
|
25
|
+
names = string.split(SEPARATOR)
|
21
26
|
names.shift until names.empty? || names.first =~ /\S/
|
22
27
|
segments = PathSegment.reify(names)
|
23
28
|
when Array
|
@@ -26,10 +31,6 @@ module CheckPlease
|
|
26
31
|
raise InvalidPath, "not sure what to do with #{name_or_segments.inspect}"
|
27
32
|
end
|
28
33
|
|
29
|
-
if segments.any?(&:empty?)
|
30
|
-
raise InvalidPath, "#{self.class.name} cannot contain empty segments"
|
31
|
-
end
|
32
|
-
|
33
34
|
@segments = Array(segments)
|
34
35
|
|
35
36
|
@to_s = SEPARATOR + @segments.join(SEPARATOR)
|
@@ -81,13 +82,10 @@ module CheckPlease
|
|
81
82
|
"<#{self.class.name} '#{to_s}'>"
|
82
83
|
end
|
83
84
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
matches =
|
88
|
-
# NOTE: matching on parent because MBK '/foo/:id' should return 'id' for path '/foo'
|
89
|
-
mbk_expr.parent.match?(self)
|
90
|
-
}
|
85
|
+
def key_to_match_by(flags)
|
86
|
+
key_exprs = unpack_key_exprs(flags.match_by_key)
|
87
|
+
# NOTE: match on parent because if self.to_s == '/foo', MBK '/foo/:id' should return 'id'
|
88
|
+
matches = key_exprs.select { |e| e.parent.match?(self) }
|
91
89
|
|
92
90
|
case matches.length
|
93
91
|
when 0 ; nil
|
@@ -96,6 +94,10 @@ module CheckPlease
|
|
96
94
|
end
|
97
95
|
end
|
98
96
|
|
97
|
+
def match_by_value?(flags)
|
98
|
+
flags.match_by_value.any? { |e| e.match?(self) }
|
99
|
+
end
|
100
|
+
|
99
101
|
def match?(path_or_string)
|
100
102
|
# If the strings are literally equal, we're good..
|
101
103
|
return true if self == path_or_string
|
@@ -123,7 +125,7 @@ module CheckPlease
|
|
123
125
|
# (as of this writing, this should never actually happen, but I'm being thorough)
|
124
126
|
def ancestor_on_list?(paths)
|
125
127
|
paths.any? { |path|
|
126
|
-
ancestors.any? { |ancestor| ancestor
|
128
|
+
ancestors.any? { |ancestor| ancestor.match?(path) }
|
127
129
|
}
|
128
130
|
end
|
129
131
|
|
@@ -152,7 +154,7 @@ module CheckPlease
|
|
152
154
|
|
153
155
|
# O(n) check to see if the path itself is on a list
|
154
156
|
def self_on_list?(paths)
|
155
|
-
paths.any? { |path| self
|
157
|
+
paths.any? { |path| self.match?(path) }
|
156
158
|
end
|
157
159
|
|
158
160
|
def too_deep?(flags)
|
@@ -160,8 +162,8 @@ module CheckPlease
|
|
160
162
|
depth > flags.max_depth
|
161
163
|
end
|
162
164
|
|
163
|
-
def
|
164
|
-
|
165
|
+
def unpack_key_exprs(path_list)
|
166
|
+
path_list
|
165
167
|
.map { |path| path.send(:key_exprs) }
|
166
168
|
.flatten
|
167
169
|
.uniq { |e| e.to_s } # use the block form so we don't have to implement #hash and #eql? in horrible ways
|
@@ -30,19 +30,16 @@ module CheckPlease
|
|
30
30
|
|
31
31
|
def initialize(name = nil)
|
32
32
|
@name = name.to_s.strip
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
|
34
|
+
case @name
|
35
|
+
when "", /\s/ # blank or has any whitespace
|
36
|
+
raise InvalidPathSegment, "#{name.inspect} is not a valid #{self.class} name"
|
37
37
|
end
|
38
|
+
|
38
39
|
parse_key_and_value
|
39
40
|
freeze
|
40
41
|
end
|
41
42
|
|
42
|
-
def empty?
|
43
|
-
name.empty?
|
44
|
-
end
|
45
|
-
|
46
43
|
def key_expr?
|
47
44
|
name.match?(KEY_EXPR)
|
48
45
|
end
|
@@ -52,23 +49,12 @@ module CheckPlease
|
|
52
49
|
end
|
53
50
|
|
54
51
|
def match?(other_segment_or_string)
|
55
|
-
other =
|
56
|
-
|
57
|
-
match_types = [ self.match_type, other.match_type ]
|
58
|
-
case match_types
|
59
|
-
when [ :plain, :plain ] ; self.name == other.name
|
60
|
-
when [ :key, :key_value ] ; self.key == other.key
|
61
|
-
when [ :key_value, :key ] ; self.key == other.key
|
62
|
-
else ; false
|
63
|
-
end
|
52
|
+
other = reify(other_segment_or_string)
|
53
|
+
PathSegmentMatcher.call(self, other)
|
64
54
|
end
|
65
55
|
|
66
|
-
|
67
|
-
|
68
|
-
def match_type
|
69
|
-
return :key if key_expr?
|
70
|
-
return :key_value if key_val_expr?
|
71
|
-
:plain
|
56
|
+
def splat?
|
57
|
+
name == '*'
|
72
58
|
end
|
73
59
|
|
74
60
|
private
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module CheckPlease
|
2
|
+
|
3
|
+
class PathSegmentMatcher
|
4
|
+
def self.call(a,b)
|
5
|
+
new(a,b).call
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :a, :b, :types
|
9
|
+
def initialize(a, b)
|
10
|
+
@a, @b = a, b
|
11
|
+
@types = [ _type(a), _type(b) ].sort
|
12
|
+
end
|
13
|
+
|
14
|
+
def call
|
15
|
+
return true if either?(:splat)
|
16
|
+
return a.name == b.name if both?(:plain)
|
17
|
+
return a.key == b.key if key_and_key_value?
|
18
|
+
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def _type(x)
|
25
|
+
return :splat if x.splat?
|
26
|
+
return :key if x.key_expr?
|
27
|
+
return :key_value if x.key_val_expr?
|
28
|
+
:plain
|
29
|
+
end
|
30
|
+
|
31
|
+
def both?(type)
|
32
|
+
types.uniq == [type]
|
33
|
+
end
|
34
|
+
|
35
|
+
def either?(type)
|
36
|
+
types.include?(type)
|
37
|
+
end
|
38
|
+
|
39
|
+
def key_and_key_value?
|
40
|
+
types == [ :key, :key_value ]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -1,20 +1,21 @@
|
|
1
1
|
module CheckPlease
|
2
|
-
using Refinements
|
3
2
|
|
4
3
|
module Printers
|
5
4
|
autoload :Base, "check_please/printers/base"
|
6
5
|
autoload :JSON, "check_please/printers/json"
|
6
|
+
autoload :Long, "check_please/printers/long"
|
7
7
|
autoload :TablePrint, "check_please/printers/table_print"
|
8
8
|
|
9
9
|
PRINTERS_BY_FORMAT = {
|
10
10
|
table: Printers::TablePrint,
|
11
11
|
json: Printers::JSON,
|
12
|
+
long: Printers::Long,
|
12
13
|
}
|
13
14
|
FORMATS = PRINTERS_BY_FORMAT.keys.sort
|
14
15
|
DEFAULT_FORMAT = :table
|
15
16
|
|
16
17
|
def self.render(diffs, flags = {})
|
17
|
-
flags = Flags(flags)
|
18
|
+
flags = Flags.reify(flags)
|
18
19
|
printer = PRINTERS_BY_FORMAT[flags.format]
|
19
20
|
printer.render(diffs)
|
20
21
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module CheckPlease
|
2
|
+
module Printers
|
3
|
+
|
4
|
+
class Long < Base
|
5
|
+
def to_s
|
6
|
+
return "" if diffs.empty?
|
7
|
+
|
8
|
+
out = build_string do |io|
|
9
|
+
diffs.each do |diff|
|
10
|
+
t = diff.type.to_sym
|
11
|
+
ref, can = *[ diff.reference, diff.candidate ].map(&:inspect)
|
12
|
+
diff_string = <<~EOF.strip
|
13
|
+
#{diff.path} [#{diff.type}]
|
14
|
+
reference: #{( t == :extra ) ? "[no value]" : ref}
|
15
|
+
candidate: #{( t == :missing ) ? "[no value]" : can}
|
16
|
+
EOF
|
17
|
+
|
18
|
+
io.puts diff_string
|
19
|
+
io.puts
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
out.strip
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
data/lib/check_please/version.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module CheckPlease
|
2
2
|
# NOTE: 'check_please_rspec_matcher' depends on this,
|
3
3
|
# so try to keep them roughly in sync
|
4
|
-
VERSION = "0.5.
|
4
|
+
VERSION = "0.5.6" # about to release? rerun `bundle lock` to update Gemfile.lock
|
5
5
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: check_please
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Livingston-Gray
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: table_print
|
@@ -87,11 +87,12 @@ files:
|
|
87
87
|
- lib/check_please/flags.rb
|
88
88
|
- lib/check_please/path.rb
|
89
89
|
- lib/check_please/path_segment.rb
|
90
|
+
- lib/check_please/path_segment_matcher.rb
|
90
91
|
- lib/check_please/printers.rb
|
91
92
|
- lib/check_please/printers/base.rb
|
92
93
|
- lib/check_please/printers/json.rb
|
94
|
+
- lib/check_please/printers/long.rb
|
93
95
|
- lib/check_please/printers/table_print.rb
|
94
|
-
- lib/check_please/refinements.rb
|
95
96
|
- lib/check_please/reification.rb
|
96
97
|
- lib/check_please/version.rb
|
97
98
|
- usage_examples.rb
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module CheckPlease
|
2
|
-
|
3
|
-
module Refinements
|
4
|
-
refine Kernel do
|
5
|
-
def Flags(flags_or_hash)
|
6
|
-
case flags_or_hash
|
7
|
-
when Flags ; return flags_or_hash
|
8
|
-
when Hash ; return Flags.new(flags_or_hash)
|
9
|
-
else
|
10
|
-
raise ArgumentError, "Expected either a CheckPlease::Flags or a Hash; got #{flags_or_hash.inspect}"
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|