diff_matcher 2.4.1 → 2.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +16 -2
- data/CHANGELOG.md +20 -0
- data/README.md +120 -41
- data/TODO.txt +4 -0
- data/diff_matcher.gemspec +3 -0
- data/doc/builtin_complex_matcher.png +0 -0
- data/doc/diff_matcher.png +0 -0
- data/doc/even_more_tapas_spec.rb +13 -0
- data/doc/more_tapas_spec.rb +11 -0
- data/exe/diff-csv +89 -0
- data/exe/diff-json +14 -0
- data/exe/diff-mysql +93 -0
- data/lib/diff_matcher/difference.rb +22 -3
- data/lib/diff_matcher/rspec.rb +3 -0
- data/lib/diff_matcher/rspec/matchers.rb +3 -0
- data/lib/diff_matcher/rspec/matchers/diff_json_matcher.rb +31 -0
- data/lib/diff_matcher/rspec/matchers/diff_matcher.rb +31 -0
- data/lib/diff_matcher/rspec_3.rb +3 -0
- data/lib/diff_matcher/rspec_3/matchers.rb +2 -0
- data/lib/diff_matcher/rspec_3/matchers/diff_json_matcher.rb +31 -0
- data/lib/diff_matcher/rspec_3/matchers/diff_matcher.rb +31 -0
- data/lib/diff_matcher/version.rb +1 -1
- data/spec/diff_matcher/difference_spec.rb +71 -20
- data/spec/diff_matcher/rspec/matchers/diff_matcher_spec.rb +13 -0
- metadata +33 -12
- data/License.txt +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ae30490620e0407789851f3b58ecdbf8c0de16b4ec6695b19a77d1809cadfe59
|
4
|
+
data.tar.gz: a00b708d6ded4b931c75858c41040e10fc4362d3fbeb55c2f6f63ee8eaf20164
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35619bf1f55bdb50a50f69e90483c233236cec6bce7f721dcf8e007533653cadec5b492499d795de648af323d31c4d4142a60daac2386d37641ee41a354c7fa9
|
7
|
+
data.tar.gz: 47a9e874d8da2f0d5b623b5077487d1b07138a6d74d04eae2ee32c873f841332cc4ffc26e9cc61c36402176a6636ba2c0b14b56985a24136475261b709b3a9af
|
data/.travis.yml
CHANGED
@@ -5,8 +5,22 @@ rvm:
|
|
5
5
|
- 1.9.2
|
6
6
|
- 1.9.3
|
7
7
|
- rbx
|
8
|
-
|
8
|
+
- rbx-19mode
|
9
|
+
- rbx-2
|
9
10
|
- jruby
|
10
11
|
- ree
|
11
|
-
# - ruby-head
|
12
12
|
- 2.0.0
|
13
|
+
- 2.1
|
14
|
+
- 2.2
|
15
|
+
- 2.3.0
|
16
|
+
- ruby-head
|
17
|
+
|
18
|
+
before_install:
|
19
|
+
- gem install bundler -v '1.11.2'
|
20
|
+
|
21
|
+
matrix:
|
22
|
+
fast_finish: true
|
23
|
+
allow_failures:
|
24
|
+
- rvm: rbx
|
25
|
+
- rvm: rbx-19mode
|
26
|
+
- rvm: rbx-2
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
### v2.8.0
|
4
|
+
|
5
|
+
* Add new diff-* executables for matching JSON & CSV files on the command line
|
6
|
+
|
7
|
+
### v2.7.1
|
8
|
+
|
9
|
+
* Use `failure_message` from RSpec matchers in diff output. (denyago)
|
10
|
+
|
11
|
+
### v2.7.0
|
12
|
+
|
13
|
+
* Add rspec custom matcher `be_json_matching` for Rspec v2.x & v3.x
|
14
|
+
|
15
|
+
### v2.6.0
|
16
|
+
|
17
|
+
* Add rspec custom matcher `be_matching` for RSpec v3.x
|
18
|
+
|
19
|
+
### v2.5.0
|
20
|
+
|
21
|
+
* Add rspec custom matcher `be_matching`
|
22
|
+
|
3
23
|
### v2.4.1
|
4
24
|
|
5
25
|
* BUGFIX match values where their classes are different but one is a subclass of the other
|
data/README.md
CHANGED
@@ -5,21 +5,23 @@ DiffMatcher
|
|
5
5
|
[![Gem Version](https://badge.fury.io/rb/diff_matcher.png)](http://badge.fury.io/rb/diff_matcher)
|
6
6
|
[![Dependency Status](https://gemnasium.com/diff-matcher/diff_matcher.png)](https://gemnasium.com/diff-matcher/diff_matcher)
|
7
7
|
[![still maintained](http://stillmaintained.com/diff-matcher/diff_matcher.png)](http://stillmaintained.com/diff-matcher/diff_matcher)
|
8
|
+
[![diff_matcher API Documentation](https://www.omniref.com/ruby/gems/diff_matcher.png)](https://www.omniref.com/ruby/gems/diff_matcher)
|
8
9
|
|
9
10
|
Generates a diff by matching against user-defined matchers written in ruby.
|
10
11
|
|
11
12
|
DiffMatcher matches input data (eg. from a JSON API) against values,
|
12
|
-
ranges, classes, regexes, procs, custom matchers and/or easily composed,
|
13
|
+
ranges, classes, regexes, procs, custom matchers, RSpec matchers and/or easily composed,
|
13
14
|
nested combinations thereof to produce an easy to read diff string.
|
14
15
|
|
15
16
|
Actual input values are matched against expected matchers in the following way:
|
16
17
|
|
17
18
|
``` ruby
|
18
|
-
actual.is_a? expected
|
19
|
-
expected.match actual
|
20
|
-
expected.call actual
|
21
|
-
actual
|
22
|
-
expected
|
19
|
+
actual.is_a? expected # when expected is a class
|
20
|
+
expected.match actual # when expected is a regexp
|
21
|
+
expected.call actual # when expected is a proc
|
22
|
+
expected.matches? actual # when expected implements an RSpec Matcher interface
|
23
|
+
actual == expected # when expected is anything else
|
24
|
+
expected.diff actual # when expected is a built-in DiffMatcher
|
23
25
|
```
|
24
26
|
|
25
27
|
Using these building blocks, more complicated nested matchers can be
|
@@ -32,7 +34,7 @@ actual = { :a=>{ :a1=>10, :a2=>12 }, :b=>[ 21 ], :c=>'3' , :d=>4 , :e=
|
|
32
34
|
puts DiffMatcher::difference(expected, actual, :color_scheme=>:white_background)
|
33
35
|
```
|
34
36
|
|
35
|
-
![example output](https://raw.github.com/
|
37
|
+
![example output](https://raw.github.com/diff-matcher/diff_matcher/master/doc/diff_matcher.gif)
|
36
38
|
|
37
39
|
|
38
40
|
Installation
|
@@ -200,6 +202,43 @@ puts DiffMatcher::difference(expected, [1, 2.00, "3"])
|
|
200
202
|
# => Where, - 1 missing, + 1 additional, | 2 match_matcher
|
201
203
|
```
|
202
204
|
|
205
|
+
When `actual` is matched against some custom logic, an object with an RSpec Matcher
|
206
|
+
interface can be used. (NB. `#mathches?(actual)`, `#description` and `#failure_message`
|
207
|
+
methods must be implemented.)
|
208
|
+
|
209
|
+
So you can use one of the RSpec matchers or you can implement your own.
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
class BeAWeekend
|
213
|
+
def matches?(day)
|
214
|
+
@day = day
|
215
|
+
%w{Sat Sun}.include?(day)
|
216
|
+
end
|
217
|
+
|
218
|
+
def description
|
219
|
+
'be a weekend day'
|
220
|
+
end
|
221
|
+
|
222
|
+
def failure_message
|
223
|
+
"expected #{@day} to #{description}"
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
be_a_weekend = BeAWeekend.new
|
228
|
+
puts DiffMatcher::difference(be_a_weekend, 'Mon')
|
229
|
+
# => - expected Mon to be a weekend day+ "Mon"
|
230
|
+
# => Where, - 1 missing, + 1 additional
|
231
|
+
|
232
|
+
|
233
|
+
all_be_weekends = DiffMatcher::AllMatcher.new(be_a_weekend)
|
234
|
+
puts DiffMatcher::difference(all_be_weekends, ['Sat', 'Mon'])
|
235
|
+
# => [
|
236
|
+
# => R "Sat" be a weekend day,
|
237
|
+
# => - expected Mon to be a weekend day+ "Mon"
|
238
|
+
# => ]
|
239
|
+
# => Where, - 1 missing, + 1 additional, R 1 match_rspec
|
240
|
+
```
|
241
|
+
|
203
242
|
### Matcher options
|
204
243
|
|
205
244
|
Matcher options can be passed to `DiffMatcher::difference` or `DiffMatcher::Matcher#diff`
|
@@ -284,6 +323,7 @@ in the following way:
|
|
284
323
|
match matcher => "| "
|
285
324
|
match range => ". "
|
286
325
|
match proc => "{ "
|
326
|
+
match rspec => "R "
|
287
327
|
|
288
328
|
|
289
329
|
#### Colours
|
@@ -300,6 +340,7 @@ Using the `:default` colour scheme items shown in a difference are coloured as f
|
|
300
340
|
match matcher => blue
|
301
341
|
match range => cyan
|
302
342
|
match proc => cyan
|
343
|
+
match rspec => cyan
|
303
344
|
|
304
345
|
Other colour schemes, eg. `:color_scheme=>:white_background` will use different colour mappings.
|
305
346
|
|
@@ -355,42 +396,11 @@ do pattern matching and also looks like a good alternative to diff_matcher, it h
|
|
355
396
|
|
356
397
|
Use with rspec
|
357
398
|
---
|
358
|
-
To use with rspec,
|
399
|
+
To use with rspec, require it in `spec_helper.rb`
|
359
400
|
|
360
401
|
``` ruby
|
361
|
-
require 'diff_matcher'
|
362
|
-
|
363
|
-
# Uses the diff_matcher gem to provide advanced matching abilities, along with nice visual representation of the
|
364
|
-
# diff between actual and expected. The functionality set is very helpful for comparing hashes.
|
365
|
-
#
|
366
|
-
# Usage examples:
|
367
|
-
# it { should be_matching(my_var) }
|
368
|
-
# it { should be_matching(my_var).with_options(ignore_additional: true) }
|
369
|
-
#
|
370
|
-
# Options: by default, color_enabled is controlled by Rspec, and quiet is set to true.
|
371
|
-
RSpec::Matchers.define :be_matching do |expected|
|
372
|
-
match do |actual|
|
373
|
-
options = { :color_enabled => RSpec::configuration.color_enabled?, :quiet => true }.merge(@options || {})
|
374
|
-
@difference = DiffMatcher::Difference.new(expected, actual, options)
|
375
|
-
@difference.matching?
|
376
|
-
end
|
377
|
-
|
378
|
-
chain :with_options do |options|
|
379
|
-
@options = options
|
380
|
-
end
|
381
|
-
|
382
|
-
failure_message_for_should do |actual|
|
383
|
-
"diff is:\n" + @difference.to_s
|
384
|
-
end
|
385
|
-
|
386
|
-
failure_message_for_should_not do |actual|
|
387
|
-
"diff is:\n" + @difference.to_s
|
388
|
-
end
|
389
|
-
|
390
|
-
description do
|
391
|
-
"match via DiffMatcher #{expected}" + (@options.blank? ? '' : " with options: #{@options}")
|
392
|
-
end
|
393
|
-
end
|
402
|
+
require 'diff_matcher/rspec' # for RSpec version < 3.0
|
403
|
+
require 'diff_matcher/rspec_3' # for RSpec version >= 3.x
|
394
404
|
```
|
395
405
|
|
396
406
|
And use it with:
|
@@ -427,6 +437,75 @@ Finished in 0.00601 seconds
|
|
427
437
|
```
|
428
438
|
|
429
439
|
|
440
|
+
Comparing to built-in rspec matcher
|
441
|
+
---
|
442
|
+
RSpec 3 now has a built-in complex matcher:
|
443
|
+
``` ruby
|
444
|
+
RSpec.describe "a complex example" do
|
445
|
+
let(:response) {{person: {first_name: "Noel", last_name: "Rappin"},
|
446
|
+
company: {name: "Table XI", url: "www.tablexi.com"}}}
|
447
|
+
|
448
|
+
it "gets the right response" do
|
449
|
+
expect(response).to match({
|
450
|
+
person: {first_name: "Avdi", last_name: "Grim"},
|
451
|
+
company: {name: "ShipRise", url: a_string_matching(/tablexi/)}
|
452
|
+
})
|
453
|
+
end
|
454
|
+
end
|
455
|
+
```
|
456
|
+
|
457
|
+
With `--color` set, will result in:
|
458
|
+
|
459
|
+
![built-in complex matcher](https://raw.github.com/diff-matcher/diff_matcher/master/doc/builtin_complex_matcher.png)
|
460
|
+
|
461
|
+
|
462
|
+
But using `diff_matcher`:
|
463
|
+
``` ruby
|
464
|
+
require "diff_matcher/rspec_3"
|
465
|
+
|
466
|
+
RSpec.describe "a complex example" do
|
467
|
+
let(:response) {{person: {first_name: "Noel", last_name: "Rappin"},
|
468
|
+
company: {name: "Table XI", url: "www.tablexi.com"}}}
|
469
|
+
|
470
|
+
it "gets the right response" do
|
471
|
+
expect(response).to be_matching({
|
472
|
+
person: {first_name: "Avdi", last_name: "Grim"},
|
473
|
+
company: {name: "ShipRise", url: /tablexi/}
|
474
|
+
}).with_options(quiet: false)
|
475
|
+
end
|
476
|
+
end
|
477
|
+
```
|
478
|
+
|
479
|
+
With `--color` set, will result in:
|
480
|
+
|
481
|
+
![diff-matcher](https://raw.github.com/diff-matcher/diff_matcher/master/doc/diff_matcher.png)
|
482
|
+
|
483
|
+
ie. by making these changes:
|
484
|
+
``` diff
|
485
|
+
--- more_tapas_spec.rb 2017-03-02 19:51:26.000000000 +1100
|
486
|
+
+++ even_more_tapas_spec.rb 2017-03-02 20:41:52.000000000 +1100
|
487
|
+
@@ -1,11 +1,13 @@
|
488
|
+
+require "diff_matcher/rspec_3"
|
489
|
+
+
|
490
|
+
RSpec.describe "a complex example" do
|
491
|
+
let(:response) {{person: {first_name: "Noel", last_name: "Rappin"},
|
492
|
+
company: {name: "Table XI", url: "www.tablexi.com"}}}
|
493
|
+
|
494
|
+
it "gets the right response" do
|
495
|
+
- expect(response).to match({
|
496
|
+
+ expect(response).to be_matching({
|
497
|
+
person: {first_name: "Avdi", last_name: "Grim"},
|
498
|
+
- company: {name: "ShipRise", url: a_string_matching(/tablexi/)}
|
499
|
+
- })
|
500
|
+
+ company: {name: "ShipRise", url: /tablexi/}
|
501
|
+
+ }).with_options(quiet: false)
|
502
|
+
end
|
503
|
+
end
|
504
|
+
```
|
505
|
+
|
506
|
+
NB. Its not as easy to see with RSpec's built-in complex matcher that the url actually matched in the above example.
|
507
|
+
|
508
|
+
|
430
509
|
Contributing
|
431
510
|
---
|
432
511
|
|
data/TODO.txt
CHANGED
data/diff_matcher.gemspec
CHANGED
@@ -10,6 +10,7 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.authors = ["locochris"]
|
11
11
|
s.email = "chris@locomote.com.au"
|
12
12
|
s.homepage = "http://github.com/diff-matcher/diff_matcher"
|
13
|
+
s.licenses = %w{ BSD MIT }
|
13
14
|
|
14
15
|
s.summary = %q{Generates a diff by matching against user-defined matchers written in ruby.}
|
15
16
|
s.description = <<EOF
|
@@ -21,4 +22,6 @@ EOF
|
|
21
22
|
s.files = `git ls-files`.split("\n")
|
22
23
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
23
24
|
s.require_paths = ["lib"]
|
25
|
+
s.bindir = "exe"
|
26
|
+
s.executables = s.files.grep(%r{^#{s.bindir}/}) { |f| File.basename(f) }
|
24
27
|
end
|
Binary file
|
Binary file
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "diff_matcher/rspec_3"
|
2
|
+
|
3
|
+
RSpec.describe "a complex example" do
|
4
|
+
let(:response) {{person: {first_name: "Noel", last_name: "Rappin"},
|
5
|
+
company: {name: "Table XI", url: "www.tablexi.com"}}}
|
6
|
+
|
7
|
+
it "gets the right response" do
|
8
|
+
expect(response).to be_matching({
|
9
|
+
person: {first_name: "Avdi", last_name: "Grim"},
|
10
|
+
company: {name: "ShipRise", url: /tablexi/}
|
11
|
+
}).with_options(quiet: false)
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
RSpec.describe "a complex example" do
|
2
|
+
let(:response) {{person: {first_name: "Noel", last_name: "Rappin"},
|
3
|
+
company: {name: "Table XI", url: "www.tablexi.com"}}}
|
4
|
+
|
5
|
+
it "gets the right response" do
|
6
|
+
expect(response).to match({
|
7
|
+
person: {first_name: "Avdi", last_name: "Grim"},
|
8
|
+
company: {name: "ShipRise", url: a_string_matching(/tablexi/)}
|
9
|
+
})
|
10
|
+
end
|
11
|
+
end
|
data/exe/diff-csv
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Given:
|
3
|
+
# --- languages-v1.tsv ---
|
4
|
+
# id name author first_appeared stable_release
|
5
|
+
# 1 ruby Yukihiro Matsumoto 1995 2.7.1
|
6
|
+
# 2 python Guido van Rossum 1991 3.9.0
|
7
|
+
# 3 jq Stephen Dolan 2013 1.6
|
8
|
+
# --- languages-v1.tsv ---
|
9
|
+
#
|
10
|
+
# --- languages-v2.tsv ---
|
11
|
+
# id name author first_appeared stable_release
|
12
|
+
# 1 ruby Yukihiro Matsumoto 1995 2.7.2
|
13
|
+
# 2 python Guido van Rossum 1991 3.9.0
|
14
|
+
# 3 jq Stephen Dolan 2013 1.6
|
15
|
+
# --- languages-v2.tsv ---
|
16
|
+
#
|
17
|
+
# Examples:
|
18
|
+
# > diff-csv languages-v1.tsv languages-v2.tsv
|
19
|
+
# {
|
20
|
+
# 1=>{
|
21
|
+
# "stable_release"=>- "2.7.1"+ "2.7.2"
|
22
|
+
# }
|
23
|
+
# }
|
24
|
+
# Where, - 1 missing, + 1 additional
|
25
|
+
#
|
26
|
+
# > VERBOSE=1 diff-csv languages-v{1,2}.tsv
|
27
|
+
# {
|
28
|
+
# 1=>{
|
29
|
+
# "name"=>"ruby",
|
30
|
+
# "author"=>"Yukihiro Matsumoto",
|
31
|
+
# "first_appeared"=>1995,
|
32
|
+
# "stable_release"=>- "2.7.1"+ "2.7.2"
|
33
|
+
# },
|
34
|
+
# 2=>{
|
35
|
+
# "name"=>"python",
|
36
|
+
# "author"=>"Guido van Rossum",
|
37
|
+
# "first_appeared"=>1991,
|
38
|
+
# "stable_release"=>"3.9.0"
|
39
|
+
# },
|
40
|
+
# 3=>{
|
41
|
+
# "name"=>"jq",
|
42
|
+
# "author"=>"Stephen Dolan",
|
43
|
+
# "first_appeared"=>2013,
|
44
|
+
# "stable_release"=>1.6
|
45
|
+
# }
|
46
|
+
# }
|
47
|
+
# Where, - 1 missing, + 1 additional
|
48
|
+
#
|
49
|
+
# > KEY=name diff-csv languages-v{1,2}.tsv
|
50
|
+
# {
|
51
|
+
# "ruby"=>{
|
52
|
+
# "stable_release"=>- "2.7.1"+ "2.7.2"
|
53
|
+
# }
|
54
|
+
# }
|
55
|
+
# Where, - 1 missing, + 1 additional
|
56
|
+
|
57
|
+
require 'csv'
|
58
|
+
require 'diff_matcher'
|
59
|
+
|
60
|
+
COL_SEP=ENV.fetch("COL_SEP", "\t")
|
61
|
+
KEY=ENV.fetch("KEY", "id")
|
62
|
+
|
63
|
+
|
64
|
+
def fix_nulls(h)
|
65
|
+
h.each { |k, v| h[k] = (v == 'NULL' ? nil : v) }
|
66
|
+
end
|
67
|
+
|
68
|
+
def records(file, key=KEY, col_sep=COL_SEP)
|
69
|
+
CSV(file, col_sep: COL_SEP, headers: true, converters: :all).inject({}) do |h, row|
|
70
|
+
data = fix_nulls(row.to_hash)
|
71
|
+
h.update(data.delete(key)=> data)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
data0 = records(File.open(ARGV[0]))
|
76
|
+
data1 = records(File.open(ARGV[1]))
|
77
|
+
|
78
|
+
diff_opts = {
|
79
|
+
color_enabled: true,
|
80
|
+
ignore_additional: ENV['IGNORE_ADDITIONAL'],
|
81
|
+
quiet: !ENV['VERBOSE']
|
82
|
+
}
|
83
|
+
|
84
|
+
diff=DiffMatcher.difference(data0, data1, diff_opts)
|
85
|
+
|
86
|
+
if diff
|
87
|
+
puts diff
|
88
|
+
exit 1
|
89
|
+
end
|
data/exe/diff-json
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'diff_matcher'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
expected, actual = ARGV.first(2).map do |f|
|
6
|
+
JSON.parse(File.read(f))
|
7
|
+
end
|
8
|
+
|
9
|
+
diff=DiffMatcher.difference(expected, actual, color_scheme: :default)
|
10
|
+
|
11
|
+
if diff
|
12
|
+
puts diff
|
13
|
+
exit 1
|
14
|
+
end
|
data/exe/diff-mysql
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
#!/bin/bash -e
|
2
|
+
# Examples:
|
3
|
+
# # Show diff between the TABLES in two databases
|
4
|
+
# TABLES="languages" diff-mysql database1 database2
|
5
|
+
#
|
6
|
+
# # Show diff between languages TABLES skipping any output containing 'python'
|
7
|
+
# FILTER_CMD='grep -v python' TABLES=languages diff-mysql database{1,2}
|
8
|
+
#
|
9
|
+
# # Filter at the database level instead
|
10
|
+
# FILTER_SQL="WHERE languages.name = 'python'" TABLES=languages diff-mysql database{1,2}
|
11
|
+
#
|
12
|
+
set -eo pipefail
|
13
|
+
|
14
|
+
DB_USERNAME=${DB_USERNAME:-root}
|
15
|
+
DB_PASSWORD=${DB_PASSWORD:-password}
|
16
|
+
DB_HOST=${DB_HOST:-localhost}
|
17
|
+
|
18
|
+
MAX_ROW_COUNT=${MAX_ROW_COUNT:-100}
|
19
|
+
SKIP=${SKIP:-messages}
|
20
|
+
|
21
|
+
DB_NAME1=$1
|
22
|
+
DB_NAME2=$2
|
23
|
+
|
24
|
+
puts() { local color=$1; local prefix=$2; local msg=$3
|
25
|
+
echo -e "[$(date +%Y%m%d%H%M%S)] [${color};1m${prefix}:[0m[${color}m $msg[0m" 1>&2
|
26
|
+
}
|
27
|
+
|
28
|
+
info() { local msg=$*; puts 34 INFO "$msg" ; }
|
29
|
+
success() { local msg=$*; puts 32 SUCCESS "$msg"; }
|
30
|
+
error() { local msg=$*; puts 31 ERROR "$msg" ; }
|
31
|
+
|
32
|
+
skip() { local name=$1
|
33
|
+
for skip_name in $SKIP; do
|
34
|
+
[ "$skip_name" == "$name" ] && return 0
|
35
|
+
done
|
36
|
+
return 1
|
37
|
+
}
|
38
|
+
|
39
|
+
do_mysql() { local db_name="$1"; shift
|
40
|
+
mysql "$@" --user="$DB_USERNAME" --password="$DB_PASSWORD" --host="$DB_HOST" "$db_name" 2> /dev/null
|
41
|
+
}
|
42
|
+
|
43
|
+
do_mysql_silent() { local db_name=$1
|
44
|
+
do_mysql "$db_name" --silent
|
45
|
+
}
|
46
|
+
|
47
|
+
tables() { local db_name=$1
|
48
|
+
info "Fetching table names from database $db_name (host '$DB_HOST') ..."
|
49
|
+
echo "show tables" |
|
50
|
+
do_mysql_silent "$db_name"
|
51
|
+
}
|
52
|
+
TABLES=${TABLES:-$(tables "$DB_NAME1")}
|
53
|
+
|
54
|
+
count_rows() { local table=$1; local db_name=$2
|
55
|
+
echo "select count(id) from $table" |
|
56
|
+
do_mysql_silent "$db_name"
|
57
|
+
}
|
58
|
+
|
59
|
+
diff_cmd() {
|
60
|
+
#diff -u $@
|
61
|
+
COLOR_ENABLED=1 ${DIFF_CMD:-diff-csv} "$@"
|
62
|
+
}
|
63
|
+
|
64
|
+
filter_cmd() {
|
65
|
+
${FILTER_CMD:-cat}
|
66
|
+
}
|
67
|
+
|
68
|
+
dump_table() { local table=$1; local db_name=$2
|
69
|
+
echo "$(echo 'SELECT *') FROM $table ${FILTER_SQL}" |
|
70
|
+
do_mysql "$db_name" |
|
71
|
+
filter_cmd
|
72
|
+
}
|
73
|
+
|
74
|
+
table_diff() { local table="$1"
|
75
|
+
info "Diffing $table ($DB_NAME1 vs $DB_NAME2)"
|
76
|
+
diff_cmd <(dump_table "$table" {"$DB_NAME1","$DB_NAME2"})
|
77
|
+
}
|
78
|
+
|
79
|
+
|
80
|
+
exit_code=0
|
81
|
+
for table in $TABLES; do
|
82
|
+
row_count=$(count_rows "$table" "$DB_NAME1")
|
83
|
+
if [ $row_count -lt $MAX_ROW_COUNT ]; then
|
84
|
+
if skip "$table"; then
|
85
|
+
info "Skipping $table (as it was referenced in SKIP)"
|
86
|
+
else
|
87
|
+
table_diff "$table" || exit_code=$?
|
88
|
+
fi
|
89
|
+
else
|
90
|
+
info "Skipping $table (as row count exceeds MAX_ROW_COUNT, $row_count > $MAX_ROW_COUNT)"
|
91
|
+
fi
|
92
|
+
done
|
93
|
+
exit $exit_code
|
@@ -88,7 +88,8 @@ module DiffMatcher
|
|
88
88
|
:match_class => [BLUE , ":"],
|
89
89
|
:match_matcher => [BLUE , "|"],
|
90
90
|
:match_range => [CYAN , "."],
|
91
|
-
:match_proc => [CYAN , "{"]
|
91
|
+
:match_proc => [CYAN , "{"],
|
92
|
+
:match_rspec => [CYAN , "R"]
|
92
93
|
}
|
93
94
|
|
94
95
|
class << self
|
@@ -186,7 +187,7 @@ module DiffMatcher
|
|
186
187
|
@matches_shown ||= lambda {
|
187
188
|
ret = []
|
188
189
|
unless @quiet
|
189
|
-
ret += [:match_matcher, :match_class, :match_range, :match_proc, :match_regexp]
|
190
|
+
ret += [:match_matcher, :match_class, :match_range, :match_proc, :match_regexp, :match_rspec]
|
190
191
|
ret += [:match_value]
|
191
192
|
end
|
192
193
|
ret
|
@@ -273,7 +274,12 @@ module DiffMatcher
|
|
273
274
|
when Range ; [expected.include?(actual) , :match_range ]
|
274
275
|
when Proc ; [expected.call(actual) , :match_proc ]
|
275
276
|
when Regexp ; [actual.is_a?(String) && actual.match(expected) , :match_regexp ]
|
276
|
-
else
|
277
|
+
else
|
278
|
+
if expected.respond_to?(:matches?)
|
279
|
+
[expected.matches?(actual), :match_rspec]
|
280
|
+
else
|
281
|
+
[actual == expected, :match_value]
|
282
|
+
end
|
277
283
|
end
|
278
284
|
end
|
279
285
|
|
@@ -294,6 +300,7 @@ module DiffMatcher
|
|
294
300
|
|
295
301
|
def match_to_s(expected, actual, match_type)
|
296
302
|
actual = match_regexp_to_s(expected, actual) if match_type == :match_regexp
|
303
|
+
actual = "#{actual} #{expected.description}" if match_type == :match_rspec
|
297
304
|
markup(match_type, actual) if matches_shown.include?(match_type)
|
298
305
|
end
|
299
306
|
|
@@ -308,6 +315,16 @@ module DiffMatcher
|
|
308
315
|
end
|
309
316
|
end
|
310
317
|
|
318
|
+
def summarize_rspec_matcher(matcher)
|
319
|
+
if matcher.respond_to?(:failure_message)
|
320
|
+
matcher.failure_message
|
321
|
+
elsif matcher.respond_to?(:failure_message_for_should)
|
322
|
+
matcher.failure_message_for_should
|
323
|
+
else
|
324
|
+
summarize_item(matcher)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
311
328
|
def difference_to_s(expected, actual)
|
312
329
|
match, match_type, d = match?(expected, actual)
|
313
330
|
if match
|
@@ -316,6 +333,8 @@ module DiffMatcher
|
|
316
333
|
case match_type
|
317
334
|
when :match_matcher
|
318
335
|
d
|
336
|
+
when :match_rspec
|
337
|
+
"#{markup(:missing, summarize_rspec_matcher(expected))}#{markup(:additional, summarize_item(actual))}"
|
319
338
|
else
|
320
339
|
exp, act = if [expected, actual].any? { |item| item.is_a?(Proc) }
|
321
340
|
[expected, actual].map { |item| item.inspect }
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Uses the diff_matcher gem to provide advanced matching abilities, along with nice visual representation of the
|
2
|
+
# diff between JSON.parse(actual) and expected. The functionality set is very helpful for comparing hashes.
|
3
|
+
#
|
4
|
+
# Usage examples:
|
5
|
+
# it { should be_matching(my_var) }
|
6
|
+
# it { should be_matching(my_var).with_options(ignore_additional: true) }
|
7
|
+
#
|
8
|
+
# Options: by default, color_enabled is controlled by Rspec, and quiet is set to true.
|
9
|
+
RSpec::Matchers.define :be_json_matching do |expected|
|
10
|
+
match do |actual|
|
11
|
+
options = { :color_enabled => RSpec::configuration.color_enabled?, :quiet => true }.merge(@options || {})
|
12
|
+
@difference = DiffMatcher::Difference.new(expected, JSON.parse(actual), options)
|
13
|
+
@difference.matching?
|
14
|
+
end
|
15
|
+
|
16
|
+
chain :with_options do |options|
|
17
|
+
@options = options
|
18
|
+
end
|
19
|
+
|
20
|
+
failure_message_for_should do |actual|
|
21
|
+
"diff is:\n" + @difference.to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
failure_message_for_should_not do |actual|
|
25
|
+
"diff is:\n" + @difference.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
description do
|
29
|
+
"match via DiffMatcher #{expected}" + (@options.blank? ? '' : " with options: #{@options}")
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Uses the diff_matcher gem to provide advanced matching abilities, along with nice visual representation of the
|
2
|
+
# diff between JSON.parse(actual) and expected. The functionality set is very helpful for comparing hashes.
|
3
|
+
#
|
4
|
+
# Usage examples:
|
5
|
+
# it { should be_matching(my_var) }
|
6
|
+
# it { should be_matching(my_var).with_options(ignore_additional: true) }
|
7
|
+
#
|
8
|
+
# Options: by default, color_enabled is controlled by Rspec, and quiet is set to true.
|
9
|
+
RSpec::Matchers.define :be_json_matching do |expected|
|
10
|
+
match do |actual|
|
11
|
+
options = { :color_enabled => RSpec::configuration.color_enabled?, :quiet => true }.merge(@options || {})
|
12
|
+
@difference = DiffMatcher::Difference.new(expected, JSON.parse(actual), options)
|
13
|
+
@difference.matching?
|
14
|
+
end
|
15
|
+
|
16
|
+
chain :with_options do |options|
|
17
|
+
@options = options
|
18
|
+
end
|
19
|
+
|
20
|
+
failure_message_for_should do |actual|
|
21
|
+
"diff is:\n" + @difference.to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
failure_message_for_should_not do |actual|
|
25
|
+
"diff is:\n" + @difference.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
description do
|
29
|
+
"match via DiffMatcher #{expected}" + (@options.blank? ? '' : " with options: #{@options}")
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Uses the diff_matcher gem to provide advanced matching abilities, along with nice visual representation of the
|
2
|
+
# diff between JSON.parse(actual) and expected. The functionality set is very helpful for comparing hashes.
|
3
|
+
#
|
4
|
+
# Usage examples:
|
5
|
+
# it { should be_matching(my_var) }
|
6
|
+
# it { should be_matching(my_var).with_options(ignore_additional: true) }
|
7
|
+
#
|
8
|
+
# Options: by default, color_enabled is controlled by Rspec, and quiet is set to true.
|
9
|
+
RSpec::Matchers.define :be_json_matching do |expected|
|
10
|
+
match do |actual|
|
11
|
+
options = { :color_enabled => RSpec::configuration.color_enabled?, :quiet => true }.merge(@options || {})
|
12
|
+
@difference = DiffMatcher::Difference.new(expected, JSON.parse(actual), options)
|
13
|
+
@difference.matching?
|
14
|
+
end
|
15
|
+
|
16
|
+
chain :with_options do |options|
|
17
|
+
@options = options
|
18
|
+
end
|
19
|
+
|
20
|
+
failure_message do |actual|
|
21
|
+
"diff is:\n" + @difference.to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
failure_message_when_negated do |actual|
|
25
|
+
"diff is:\n" + @difference.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
description do
|
29
|
+
"match via DiffMatcher #{expected}" + (@options.blank? ? '' : " with options: #{@options}")
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Uses the diff_matcher gem to provide advanced matching abilities, along with nice visual representation of the
|
2
|
+
# diff between actual and expected. The functionality set is very helpful for comparing hashes.
|
3
|
+
#
|
4
|
+
# Usage examples:
|
5
|
+
# it { should be_matching(my_var) }
|
6
|
+
# it { should be_matching(my_var).with_options(ignore_additional: true) }
|
7
|
+
#
|
8
|
+
# Options: by default, color_enabled is controlled by Rspec, and quiet is set to true.
|
9
|
+
RSpec::Matchers.define :be_matching do |expected|
|
10
|
+
match do |actual|
|
11
|
+
options = { :color_enabled => RSpec::configuration.color_enabled?, :quiet => true }.merge(@options || {})
|
12
|
+
@difference = DiffMatcher::Difference.new(expected, actual, options)
|
13
|
+
@difference.matching?
|
14
|
+
end
|
15
|
+
|
16
|
+
chain :with_options do |options|
|
17
|
+
@options = options
|
18
|
+
end
|
19
|
+
|
20
|
+
failure_message do |actual|
|
21
|
+
"diff is:\n" + @difference.to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
failure_message_when_negated do |actual|
|
25
|
+
"diff is:\n" + @difference.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
description do
|
29
|
+
"match via DiffMatcher #{expected}" + (@options.blank? ? '' : " with options: #{@options}")
|
30
|
+
end
|
31
|
+
end
|
data/lib/diff_matcher/version.rb
CHANGED
@@ -470,6 +470,36 @@ describe "DiffMatcher::difference(expected, actual, opts)" do
|
|
470
470
|
end
|
471
471
|
end
|
472
472
|
|
473
|
+
context 'a duck-type responding to #matches?' do
|
474
|
+
matchable = Class.new do
|
475
|
+
def initialize(expected)
|
476
|
+
@expected = expected
|
477
|
+
end
|
478
|
+
|
479
|
+
def matches?(actual)
|
480
|
+
actual == @expected
|
481
|
+
end
|
482
|
+
|
483
|
+
def failure_message
|
484
|
+
"the matcher should be eq '#{@expected}'"
|
485
|
+
end
|
486
|
+
|
487
|
+
def description
|
488
|
+
"be eq #{@expected}"
|
489
|
+
end
|
490
|
+
end
|
491
|
+
expected, same, different =
|
492
|
+
matchable.new('foo'),
|
493
|
+
'foo',
|
494
|
+
'bar'
|
495
|
+
|
496
|
+
it_behaves_like "a diff matcher", expected, same, different,
|
497
|
+
<<-EOF
|
498
|
+
- the matcher should be eq 'foo'+ "bar"
|
499
|
+
Where, - 1 missing, + 1 additional
|
500
|
+
EOF
|
501
|
+
end
|
502
|
+
|
473
503
|
context "a proc," do
|
474
504
|
expected, same, different =
|
475
505
|
lambda { |x| [FalseClass, TrueClass].include? x.class },
|
@@ -654,12 +684,25 @@ describe "DiffMatcher::difference(expected, actual, opts)" do
|
|
654
684
|
end
|
655
685
|
|
656
686
|
context "when expected has multiple items," do
|
687
|
+
matchable = Class.new do
|
688
|
+
def initialize(expected)
|
689
|
+
@expected = expected
|
690
|
+
end
|
691
|
+
|
692
|
+
def matches?(actual)
|
693
|
+
actual == @expected
|
694
|
+
end
|
695
|
+
|
696
|
+
def description
|
697
|
+
"be == #{@expected}"
|
698
|
+
end
|
699
|
+
end
|
657
700
|
expected, same, different =
|
658
|
-
[ 1, 2, /\d/, Fixnum, 4..6 , lambda { |x| x % 6 == 0 } ],
|
659
|
-
[ 1, 2, "3" , 4 , 5 , 6
|
660
|
-
[ 0, 2, "3" , 4 , 5 , 6
|
701
|
+
[ 1, 2, /\d/, Fixnum, 4..6 , lambda { |x| x % 6 == 0 }, matchable.new(7)],
|
702
|
+
[ 1, 2, "3" , 4 , 5 , 6 , 7 ],
|
703
|
+
[ 0, 2, "3" , 4 , 5 , 6 , 7 ]
|
661
704
|
|
662
|
-
describe "it shows regex, class, range, proc matches and
|
705
|
+
describe "it shows regex, class, range, proc matches, matches and RSpec matcher" do
|
663
706
|
it_behaves_like "a diff matcher", expected, same, different,
|
664
707
|
<<-EOF
|
665
708
|
[
|
@@ -668,9 +711,10 @@ describe "DiffMatcher::difference(expected, actual, opts)" do
|
|
668
711
|
~ "(3)",
|
669
712
|
: 4,
|
670
713
|
. 5,
|
671
|
-
{ 6
|
714
|
+
{ 6,
|
715
|
+
R 7 be == 7
|
672
716
|
]
|
673
|
-
Where, - 1 missing, + 1 additional, ~ 1 match_regexp, : 1 match_class, . 1 match_range, { 1 match_proc
|
717
|
+
Where, - 1 missing, + 1 additional, ~ 1 match_regexp, : 1 match_class, . 1 match_range, { 1 match_proc, R 1 match_rspec
|
674
718
|
EOF
|
675
719
|
end
|
676
720
|
|
@@ -693,9 +737,10 @@ describe "DiffMatcher::difference(expected, actual, opts)" do
|
|
693
737
|
~ "(3)",
|
694
738
|
: 4,
|
695
739
|
. 5,
|
696
|
-
{ 6
|
740
|
+
{ 6,
|
741
|
+
R 7 be == 7
|
697
742
|
]
|
698
|
-
Where, - 1 missing, + 1 additional, ~ 1 match_regexp, : 1 match_class, . 1 match_range, { 1 match_proc
|
743
|
+
Where, - 1 missing, + 1 additional, ~ 1 match_regexp, : 1 match_class, . 1 match_range, { 1 match_proc, R 1 match_rspec
|
699
744
|
EOF
|
700
745
|
end
|
701
746
|
|
@@ -708,9 +753,10 @@ describe "DiffMatcher::difference(expected, actual, opts)" do
|
|
708
753
|
\e[0m \e[32m~ \e[0m"\e[32m(\e[1m3\e[0m\e[32m)\e[0m"\e[0m,
|
709
754
|
\e[0m \e[34m: \e[1m4\e[0m,
|
710
755
|
\e[0m \e[36m. \e[1m5\e[0m,
|
711
|
-
\e[0m \e[36m{ \e[1m6\e[0m
|
756
|
+
\e[0m \e[36m{ \e[1m6\e[0m,
|
757
|
+
\e[0m \e[36mR \e[1m7 be == 7\e[0m
|
712
758
|
\e[0m]
|
713
|
-
Where, \e[31m- \e[1m1 missing\e[0m, \e[33m+ \e[1m1 additional\e[0m, \e[32m~ \e[1m1 match_regexp\e[0m, \e[34m: \e[1m1 match_class\e[0m, \e[36m. \e[1m1 match_range\e[0m, \e[36m{ \e[1m1 match_proc\e[0m
|
759
|
+
Where, \e[31m- \e[1m1 missing\e[0m, \e[33m+ \e[1m1 additional\e[0m, \e[32m~ \e[1m1 match_regexp\e[0m, \e[34m: \e[1m1 match_class\e[0m, \e[36m. \e[1m1 match_range\e[0m, \e[36m{ \e[1m1 match_proc\e[0m, \e[36mR \e[1m1 match_rspec\e[0m
|
714
760
|
EOF
|
715
761
|
|
716
762
|
context "on a white background" do
|
@@ -722,9 +768,10 @@ describe "DiffMatcher::difference(expected, actual, opts)" do
|
|
722
768
|
\e[0m \e[32m~ \e[0m"\e[32m(\e[1m3\e[0m\e[32m)\e[0m"\e[0m,
|
723
769
|
\e[0m \e[34m: \e[1m4\e[0m,
|
724
770
|
\e[0m \e[36m. \e[1m5\e[0m,
|
725
|
-
\e[0m \e[36m{ \e[1m6\e[0m
|
771
|
+
\e[0m \e[36m{ \e[1m6\e[0m,
|
772
|
+
\e[0m \e[36mR \e[1m7 be == 7\e[0m
|
726
773
|
\e[0m]
|
727
|
-
Where, \e[31m- \e[1m1 missing\e[0m, \e[35m+ \e[1m1 additional\e[0m, \e[32m~ \e[1m1 match_regexp\e[0m, \e[34m: \e[1m1 match_class\e[0m, \e[36m. \e[1m1 match_range\e[0m, \e[36m{ \e[1m1 match_proc\e[0m
|
774
|
+
Where, \e[31m- \e[1m1 missing\e[0m, \e[35m+ \e[1m1 additional\e[0m, \e[32m~ \e[1m1 match_regexp\e[0m, \e[34m: \e[1m1 match_class\e[0m, \e[36m. \e[1m1 match_range\e[0m, \e[36m{ \e[1m1 match_proc\e[0m, \e[36mR \e[1m1 match_rspec\e[0m
|
728
775
|
EOF
|
729
776
|
end
|
730
777
|
|
@@ -739,9 +786,10 @@ describe "DiffMatcher::difference(expected, actual, opts)" do
|
|
739
786
|
\e[0m \e[32m~ \e[0m"\e[32m(\e[1m3\e[0m\e[32m)\e[0m"\e[0m,
|
740
787
|
\e[0m \e[34m: \e[1m4\e[0m,
|
741
788
|
\e[0m \e[36m. \e[1m5\e[0m,
|
742
|
-
\e[0m \e[36m{ \e[1m6\e[0m
|
789
|
+
\e[0m \e[36m{ \e[1m6\e[0m,
|
790
|
+
\e[0m \e[36mR \e[1m7 be == 7\e[0m
|
743
791
|
\e[0m]
|
744
|
-
Where, \e[31m- \e[1m1 missing\e[0m, \e[33m+ \e[1m1 additional\e[0m, \e[32m~ \e[1m1 match_regexp\e[0m, \e[34m: \e[1m1 match_class\e[0m, \e[36m. \e[1m1 match_range\e[0m, \e[36m{ \e[1m1 match_proc\e[0m
|
792
|
+
Where, \e[31m- \e[1m1 missing\e[0m, \e[33m+ \e[1m1 additional\e[0m, \e[32m~ \e[1m1 match_regexp\e[0m, \e[34m: \e[1m1 match_class\e[0m, \e[36m. \e[1m1 match_range\e[0m, \e[36m{ \e[1m1 match_proc\e[0m, \e[36mR \e[1m1 match_rspec\e[0m
|
745
793
|
EOF
|
746
794
|
end
|
747
795
|
|
@@ -756,9 +804,10 @@ describe "DiffMatcher::difference(expected, actual, opts)" do
|
|
756
804
|
\e[0m \e[32m~ \e[0m"\e[32m(\e[1m3\e[0m\e[32m)\e[0m"\e[0m,
|
757
805
|
\e[0m \e[34m: \e[1m4\e[0m,
|
758
806
|
\e[0m \e[36m. \e[1m5\e[0m,
|
759
|
-
\e[0m \e[36m{ \e[1m6\e[0m
|
807
|
+
\e[0m \e[36m{ \e[1m6\e[0m,
|
808
|
+
\e[0m \e[36mR \e[1m7 be == 7\e[0m
|
760
809
|
\e[0m]
|
761
|
-
Where, \e[31m- \e[1m1 missing\e[0m, \e[35m+ \e[1m1 additional\e[0m, \e[32m~ \e[1m1 match_regexp\e[0m, \e[34m: \e[1m1 match_class\e[0m, \e[36m. \e[1m1 match_range\e[0m, \e[36m{ \e[1m1 match_proc\e[0m
|
810
|
+
Where, \e[31m- \e[1m1 missing\e[0m, \e[35m+ \e[1m1 additional\e[0m, \e[32m~ \e[1m1 match_regexp\e[0m, \e[34m: \e[1m1 match_class\e[0m, \e[36m. \e[1m1 match_range\e[0m, \e[36m{ \e[1m1 match_proc\e[0m, \e[36mR \e[1m1 match_rspec\e[0m
|
762
811
|
EOF
|
763
812
|
end
|
764
813
|
end
|
@@ -778,9 +827,10 @@ describe "DiffMatcher::difference(expected, actual, opts)" do
|
|
778
827
|
\e[0m \e[32m~ \e[0m"\e[32m(\e[1m3\e[0m\e[32m)\e[0m"\e[0m,
|
779
828
|
\e[0m \e[34m: \e[1m4\e[0m,
|
780
829
|
\e[0m \e[36m. \e[1m5\e[0m,
|
781
|
-
\e[0m \e[36m{ \e[1m6\e[0m
|
830
|
+
\e[0m \e[36m{ \e[1m6\e[0m,
|
831
|
+
\e[0m \e[36mR \e[1m7 be == 7\e[0m
|
782
832
|
\e[0m]
|
783
|
-
Where, \e[31m- \e[1m1 missing\e[0m, \e[35m+ \e[1m1 additional\e[0m, \e[32m~ \e[1m1 match_regexp\e[0m, \e[34m: \e[1m1 match_class\e[0m, \e[36m. \e[1m1 match_range\e[0m, \e[36m{ \e[1m1 match_proc\e[0m
|
833
|
+
Where, \e[31m- \e[1m1 missing\e[0m, \e[35m+ \e[1m1 additional\e[0m, \e[32m~ \e[1m1 match_regexp\e[0m, \e[34m: \e[1m1 match_class\e[0m, \e[36m. \e[1m1 match_range\e[0m, \e[36m{ \e[1m1 match_proc\e[0m, \e[36mR \e[1m1 match_rspec\e[0m
|
784
834
|
EOF
|
785
835
|
end
|
786
836
|
|
@@ -794,9 +844,10 @@ describe "DiffMatcher::difference(expected, actual, opts)" do
|
|
794
844
|
<span style=\"color:green\">~ </b></span>\"<span style=\"color:green\">(<b>3</b></span><span style=\"color:green\">)</b></span>\"</b></span>,
|
795
845
|
<span style=\"color:blue\">: <b>4</b></span>,
|
796
846
|
<span style=\"color:cyan\">. <b>5</b></span>,
|
797
|
-
<span style=\"color:cyan\">{ <b>6</b></span
|
847
|
+
<span style=\"color:cyan\">{ <b>6</b></span>,
|
848
|
+
<span style=\"color:cyan\">R <b>7 be == 7</b></span>
|
798
849
|
]
|
799
|
-
Where, <span style=\"color:red\">- <b>1 missing</b></span>, <span style=\"color:magenta\">+ <b>1 additional</b></span>, <span style=\"color:green\">~ <b>1 match_regexp</b></span>, <span style=\"color:blue\">: <b>1 match_class</b></span>, <span style=\"color:cyan\">. <b>1 match_range</b></span>, <span style=\"color:cyan\">{ <b>1 match_proc</b></span>
|
850
|
+
Where, <span style=\"color:red\">- <b>1 missing</b></span>, <span style=\"color:magenta\">+ <b>1 additional</b></span>, <span style=\"color:green\">~ <b>1 match_regexp</b></span>, <span style=\"color:blue\">: <b>1 match_class</b></span>, <span style=\"color:cyan\">. <b>1 match_range</b></span>, <span style=\"color:cyan\">{ <b>1 match_proc</b></span>, <span style=\"color:cyan\">R <b>1 match_rspec</b></span>
|
800
851
|
</pre>
|
801
852
|
EOF
|
802
853
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'diff_matcher/rspec'
|
3
|
+
|
4
|
+
describe :be_matching do
|
5
|
+
it "should call DiffMatcher::Difference" do
|
6
|
+
pending 'how are custom matchers tested now?'
|
7
|
+
DiffMatcher::Difference.should_receive(:new).with(
|
8
|
+
:expected, :actual, { :color_enabled => RSpec::configuration.color_enabled?, :quiet => true }.merge({ :foo => 'bar' })
|
9
|
+
).and_return(double(:matching? => true))
|
10
|
+
|
11
|
+
:actual.should be_matching(:expected).with_options :foo => 'bar'
|
12
|
+
end
|
13
|
+
end
|
metadata
CHANGED
@@ -1,44 +1,64 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: diff_matcher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- locochris
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-11-14 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
DiffMatcher matches input data (eg. from a JSON API) against values,
|
15
15
|
ranges, classes, regexes, procs, custom matchers and/or easily composed,
|
16
16
|
nested combinations thereof to produce an easy to read diff string.
|
17
17
|
email: chris@locomote.com.au
|
18
|
-
executables:
|
18
|
+
executables:
|
19
|
+
- diff-csv
|
20
|
+
- diff-json
|
21
|
+
- diff-mysql
|
19
22
|
extensions: []
|
20
23
|
extra_rdoc_files: []
|
21
24
|
files:
|
22
|
-
- .gitignore
|
23
|
-
- .rspec
|
24
|
-
- .travis.yml
|
25
|
+
- ".gitignore"
|
26
|
+
- ".rspec"
|
27
|
+
- ".travis.yml"
|
25
28
|
- CHANGELOG.md
|
26
29
|
- Gemfile
|
27
|
-
- License.txt
|
28
30
|
- README.md
|
29
31
|
- Rakefile
|
30
32
|
- TODO.txt
|
31
33
|
- diff_matcher.gemspec
|
34
|
+
- doc/builtin_complex_matcher.png
|
32
35
|
- doc/diff_matcher.gif
|
36
|
+
- doc/diff_matcher.png
|
37
|
+
- doc/even_more_tapas_spec.rb
|
33
38
|
- doc/example_output.png
|
39
|
+
- doc/more_tapas_spec.rb
|
40
|
+
- exe/diff-csv
|
41
|
+
- exe/diff-json
|
42
|
+
- exe/diff-mysql
|
34
43
|
- lib/diff_matcher.rb
|
35
44
|
- lib/diff_matcher/difference.rb
|
36
45
|
- lib/diff_matcher/escape_to_html.rb
|
46
|
+
- lib/diff_matcher/rspec.rb
|
47
|
+
- lib/diff_matcher/rspec/matchers.rb
|
48
|
+
- lib/diff_matcher/rspec/matchers/diff_json_matcher.rb
|
49
|
+
- lib/diff_matcher/rspec/matchers/diff_matcher.rb
|
50
|
+
- lib/diff_matcher/rspec_3.rb
|
51
|
+
- lib/diff_matcher/rspec_3/matchers.rb
|
52
|
+
- lib/diff_matcher/rspec_3/matchers/diff_json_matcher.rb
|
53
|
+
- lib/diff_matcher/rspec_3/matchers/diff_matcher.rb
|
37
54
|
- lib/diff_matcher/version.rb
|
38
55
|
- spec/diff_matcher/difference_spec.rb
|
56
|
+
- spec/diff_matcher/rspec/matchers/diff_matcher_spec.rb
|
39
57
|
- spec/spec_helper.rb
|
40
58
|
homepage: http://github.com/diff-matcher/diff_matcher
|
41
|
-
licenses:
|
59
|
+
licenses:
|
60
|
+
- BSD
|
61
|
+
- MIT
|
42
62
|
metadata: {}
|
43
63
|
post_install_message:
|
44
64
|
rdoc_options: []
|
@@ -46,20 +66,21 @@ require_paths:
|
|
46
66
|
- lib
|
47
67
|
required_ruby_version: !ruby/object:Gem::Requirement
|
48
68
|
requirements:
|
49
|
-
- -
|
69
|
+
- - ">="
|
50
70
|
- !ruby/object:Gem::Version
|
51
71
|
version: '0'
|
52
72
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
73
|
requirements:
|
54
|
-
- -
|
74
|
+
- - ">="
|
55
75
|
- !ruby/object:Gem::Version
|
56
76
|
version: '0'
|
57
77
|
requirements: []
|
58
78
|
rubyforge_project:
|
59
|
-
rubygems_version: 2.
|
79
|
+
rubygems_version: 2.7.6
|
60
80
|
signing_key:
|
61
81
|
specification_version: 4
|
62
82
|
summary: Generates a diff by matching against user-defined matchers written in ruby.
|
63
83
|
test_files:
|
64
84
|
- spec/diff_matcher/difference_spec.rb
|
85
|
+
- spec/diff_matcher/rspec/matchers/diff_matcher_spec.rb
|
65
86
|
- spec/spec_helper.rb
|
data/License.txt
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
(The MIT License)
|
2
|
-
|
3
|
-
Copyright (c) 2011 PlayUp
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
a copy of this software and associated documentation files (the
|
7
|
-
"Software"), to deal in the Software without restriction, including
|
8
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
-
permit persons to whom the Software is furnished to do so, subject to
|
11
|
-
the following conditions:
|
12
|
-
|
13
|
-
The above copyright notice and this permission notice shall be
|
14
|
-
included in all copies or substantial portions of the Software.
|
15
|
-
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
-
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|