diff_matcher 2.7.1 → 2.8.0

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
- SHA1:
3
- metadata.gz: 269ffc7ffb370219902eab20adbb33123e12de62
4
- data.tar.gz: eeae047d47e866671da62f7fb2f6c5723cf9e935
2
+ SHA256:
3
+ metadata.gz: ae30490620e0407789851f3b58ecdbf8c0de16b4ec6695b19a77d1809cadfe59
4
+ data.tar.gz: a00b708d6ded4b931c75858c41040e10fc4362d3fbeb55c2f6f63ee8eaf20164
5
5
  SHA512:
6
- metadata.gz: 826869c482e6c5a60b9b6132e19dd64296be1d7aafa12d66e580d309f624806ee43724bc3cebc2ff78039eca8362e6cde7fe798eba9b351f570b26240ca206cd
7
- data.tar.gz: b76a7c7ceec440089b683436969a73b88730a28e670ce0e4565dd79d0f0192f116fae79c4f3bcf1d7dd0a48a5648b29a24b247c66cce5ae1f144601d954a42b3
6
+ metadata.gz: 35619bf1f55bdb50a50f69e90483c233236cec6bce7f721dcf8e007533653cadec5b492499d795de648af323d31c4d4142a60daac2386d37641ee41a354c7fa9
7
+ data.tar.gz: 47a9e874d8da2f0d5b623b5077487d1b07138a6d74d04eae2ee32c873f841332cc4ffc26e9cc61c36402176a6636ba2c0b14b56985a24136475261b709b3a9af
@@ -1,5 +1,9 @@
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
+
3
7
  ### v2.7.1
4
8
 
5
9
  * Use `failure_message` from RSpec matchers in diff output. (denyago)
data/README.md CHANGED
@@ -34,7 +34,7 @@ actual = { :a=>{ :a1=>10, :a2=>12 }, :b=>[ 21 ], :c=>'3' , :d=>4 , :e=
34
34
  puts DiffMatcher::difference(expected, actual, :color_scheme=>:white_background)
35
35
  ```
36
36
 
37
- ![example output](https://raw.github.com/playup/diff_matcher/master/doc/diff_matcher.gif)
37
+ ![example output](https://raw.github.com/diff-matcher/diff_matcher/master/doc/diff_matcher.gif)
38
38
 
39
39
 
40
40
  Installation
@@ -437,6 +437,75 @@ Finished in 0.00601 seconds
437
437
  ```
438
438
 
439
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
+
440
509
  Contributing
441
510
  ---
442
511
 
data/TODO.txt CHANGED
@@ -12,3 +12,7 @@ ie. by matching `actual` against an `expected` value/pattern/class/proc.
12
12
  Wed Dec 14 2011
13
13
  - underline
14
14
  - string diff
15
+
16
+
17
+ Sat Nov 14 2020
18
+ - add tests for exe/diff-* executables
@@ -22,4 +22,6 @@ EOF
22
22
  s.files = `git ls-files`.split("\n")
23
23
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
24
  s.require_paths = ["lib"]
25
+ s.bindir = "exe"
26
+ s.executables = s.files.grep(%r{^#{s.bindir}/}) { |f| File.basename(f) }
25
27
  end
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
@@ -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
@@ -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
@@ -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}:[${color}m $msg" 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
@@ -1,3 +1,3 @@
1
1
  module DiffMatcher
2
- VERSION = "2.7.1"
2
+ VERSION = "2.8.0"
3
3
  end
metadata CHANGED
@@ -1,21 +1,24 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: diff_matcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.1
4
+ version: 2.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - locochris
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2016-03-02 00:00:00.000000000 Z
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:
@@ -28,8 +31,15 @@ files:
28
31
  - Rakefile
29
32
  - TODO.txt
30
33
  - diff_matcher.gemspec
34
+ - doc/builtin_complex_matcher.png
31
35
  - doc/diff_matcher.gif
36
+ - doc/diff_matcher.png
37
+ - doc/even_more_tapas_spec.rb
32
38
  - doc/example_output.png
39
+ - doc/more_tapas_spec.rb
40
+ - exe/diff-csv
41
+ - exe/diff-json
42
+ - exe/diff-mysql
33
43
  - lib/diff_matcher.rb
34
44
  - lib/diff_matcher/difference.rb
35
45
  - lib/diff_matcher/escape_to_html.rb
@@ -66,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
66
76
  version: '0'
67
77
  requirements: []
68
78
  rubyforge_project:
69
- rubygems_version: 2.2.5
79
+ rubygems_version: 2.7.6
70
80
  signing_key:
71
81
  specification_version: 4
72
82
  summary: Generates a diff by matching against user-defined matchers written in ruby.
@@ -74,4 +84,3 @@ test_files:
74
84
  - spec/diff_matcher/difference_spec.rb
75
85
  - spec/diff_matcher/rspec/matchers/diff_matcher_spec.rb
76
86
  - spec/spec_helper.rb
77
- has_rdoc: