diff_matcher 2.3.3 → 2.4.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.
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  coverage
2
2
  pkg
3
3
  Gemfile.lock
4
+ .rvmrc
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ### v2.4.0
4
+
5
+ Add class configuration of Difference from a block
6
+
3
7
  ### v2.3.3
4
8
 
5
9
  Allow HTML output using `:html_output=>true` option
data/README.md CHANGED
@@ -4,27 +4,30 @@ DiffMatcher
4
4
  [![build status](http://travis-ci.org/playup/diff_matcher.png)](http://travis-ci.org/playup/diff_matcher)
5
5
  [![still maintained](http://stillmaintained.com/playupchris/diff_matcher.png)](http://stillmaintained.com/playupchris/diff_matcher)
6
6
 
7
- Generates a diff by matching against expected values, classes, regexes and/or procs.
7
+ Generates a diff by matching against user-defined matchers written in ruby.
8
8
 
9
- DiffMatcher performs recursive matches on values contained in hashes, arrays and combinations thereof.
9
+ DiffMatcher matches input data (eg. from a JSON API) against values,
10
+ ranges, classes, regexes, procs, custom matchers and/or easily composed,
11
+ nested combinations thereof to produce an easy to read diff string.
10
12
 
11
- Values in a containing object match when:
13
+ Actual input values are matched against expected matchers in the following way:
12
14
 
13
15
  ``` ruby
14
16
  actual.is_a? expected # when expected is a class
15
17
  expected.match actual # when expected is a regexp
16
18
  expected.call actual # when expected is a proc
17
19
  actual == expected # when expected is anything else
20
+ expected.diff actual # when expected is a built-in DiffMatcher
18
21
  ```
19
22
 
20
- Example:
23
+ Using these building blocks, more complicated nested matchers can be
24
+ composed.
25
+ eg.
21
26
 
22
27
  ``` ruby
23
- puts DiffMatcher::difference(
24
- { :a=>{ :a1=>11 }, :b=>[ 21, 22 ], :c=>/\d/, :d=>Fixnum, :e=>lambda { |x| (4..6).include? x } },
25
- { :a=>{ :a1=>10, :a2=>12 }, :b=>[ 21 ], :c=>'3' , :d=>4 , :e=>5 },
26
- :color_scheme=>:white_background
27
- )
28
+ expected = { :a=>{ :a1=>11 }, :b=>[ 21, 22 ], :c=>/\d/, :d=>Fixnum, :e=>lambda { |x| (4..6).include? x } },
29
+ actual = { :a=>{ :a1=>10, :a2=>12 }, :b=>[ 21 ], :c=>'3' , :d=>4 , :e=>5 },
30
+ puts DiffMatcher::difference(expected, actual, :color_scheme=>:white_background)
28
31
  ```
29
32
 
30
33
  ![example output](https://raw.github.com/playup/diff_matcher/master/doc/diff_matcher.gif)
@@ -42,191 +45,234 @@ Usage
42
45
  ``` ruby
43
46
  require 'diff_matcher'
44
47
 
45
- DiffMatcher::difference(actual, expected, opts={})
48
+ DiffMatcher::difference(expected, actual, opts={})
46
49
  ```
47
50
 
48
- When `expected` != `actual`
51
+ #### Simple matchers
49
52
 
50
- ``` ruby
51
- puts DiffMatcher::difference(1, 2)
52
- # => - 1+ 2
53
- # => Where, - 1 missing, + 1 additional
53
+ Using plain ruby objects produces the following diffs:
54
+ ```
55
+ +-------------+--------+-------------+
56
+ | expected | actual | diff |
57
+ +-------------+--------+-------------+
58
+ | 1 | 2 | - 1+ 2 |
59
+ | 1 | 1 | |
60
+ | String | 1 | - String+ 1 |
61
+ | String | "1" | |
62
+ | /[a-z]/ | 1 | -/[a-z]/+ 1 |
63
+ | /[a-z]/ | "a" | |
64
+ | 1..3 | 4 | - 1..3+ 4 |
65
+ | 1..3 | 3 | |
66
+ | is_boolean | true | |
67
+ +-------------+--------+-------------+
68
+
69
+ Where:
70
+ is_boolean = lambda { |x| [FalseClass, TrueClass].include? x.class }
54
71
  ```
55
72
 
56
- When `expected` == `actual`
73
+ When `actual` is missing one of the `expected` values
57
74
 
58
75
  ``` ruby
59
- p DiffMatcher::difference(1, 1)
60
- # => nil
76
+ expected = [1, 2]
77
+ puts DiffMatcher::difference(expected, [1])
78
+ # => [
79
+ # => 1
80
+ # => - 2
81
+ # => ]
82
+ # => Where, - 1 missing
61
83
  ```
62
84
 
63
- When `actual` is an instance of the `expected`
85
+ When `actual` has additional values to the `expected`
64
86
 
65
87
  ``` ruby
66
- p DiffMatcher::difference(String, '1')
67
- # => nil
88
+ expected = [1]
89
+ puts DiffMatcher::difference(expected, [1, 2])
90
+ # => [
91
+ # => 1
92
+ # => + 2
93
+ # => ]
94
+ # => Where, + 1 additional
68
95
  ```
69
96
 
70
- When `actual` is a string that matches the `expected` regex
97
+
98
+ #### More complicated matchers
99
+
100
+ Sometimes you'll need to wrap plain ruby objects with DiffMatcher's
101
+ built-in matchers, to provide extra matching abilities.
102
+
103
+ When `expected` is a `Hash`, but has optional keys, wrap the `Hash` with
104
+ a built-in `Matcher`
71
105
 
72
106
  ``` ruby
73
- p DiffMatcher::difference(/[a-z]/, "a")
74
- # => nil
107
+ exp = {:name=>String, :age=>Fixnum}
108
+ expected = DiffMatcher::Matcher.new(exp, :optional_keys=>[:age])
109
+ puts DiffMatcher::difference(expected, {:name=>0})
110
+ # => {
111
+ # => :name=>- String+ 0
112
+ # => }
113
+ # => Where, - 1 missing, + 1 additional
75
114
  ```
76
115
 
77
- When `actual` is a fixnum that matches the `expected` range
116
+ When multiple `expected` values can be matched against, simply wrap them
117
+ in `Matcher`s and `||` them together
78
118
 
79
119
  ``` ruby
80
- p DiffMatcher::difference(1..3, 3)
81
- # => nil
120
+ exp1 = Fixnum
121
+ exp2 = Float
122
+ expected = DiffMatcher::Matcher.new(exp1) || DiffMatcher::Matcher.new(exp2)
123
+ puts DiffMatcher::difference(expected, "3")
124
+ # => - Float+ "3"
125
+ # => Where, - 1 missing, + 1 additional
82
126
  ```
83
127
 
84
- When `actual` is passed to an `expected` proc and it returns true
128
+ Or to do the same thing using a shorter syntax
85
129
 
86
130
  ``` ruby
87
- is_boolean = lambda { |x| [FalseClass, TrueClass].include? x.class }
88
- p DiffMatcher::difference(is_boolean, true)
89
- # => nil
131
+ exp1 = Fixnum
132
+ exp2 = Float
133
+ expected = DiffMatcher::Matcher[exp1, exp2]
134
+ puts DiffMatcher::difference(expected, "3")
135
+ # => - Float+ "3"
136
+ # => Where, - 1 missing, + 1 additional
90
137
  ```
91
138
 
92
- When `actual` is missing one of the `expected` values
139
+ When `actual` is an array of *unknown* size use an `AllMatcher` to match
140
+ against *all* the elements in the array
93
141
 
94
142
  ``` ruby
95
- puts DiffMatcher::difference([1, 2], [1])
143
+ exp = Fixnum
144
+ expected = DiffMatcher::AllMatcher.new(exp)
145
+ puts DiffMatcher::difference(expected, [1, 2, "3"])
96
146
  # => [
97
- # => 1
98
- # => - 2
147
+ # => : 1,
148
+ # => : 2,
149
+ # => - Fixnum+ "3"
99
150
  # => ]
100
- # => Where, - 1 missing
151
+ # => Where, - 1 missing, + 1 additional, : 2 match_class
101
152
  ```
102
153
 
103
- When `actual` has additional values to the `expected`
154
+
155
+ When `actual` is an array with a *limited* size use an `AllMatcher` to match
156
+ against *all* the elements in the array adhering to the limits of `:min`
157
+ and or `:max` or `:size` (where `:size` is a Fixnum or range of Fixnum).
104
158
 
105
159
  ``` ruby
106
- puts DiffMatcher::difference([1], [1, 2])
160
+ exp = Fixnum
161
+ expected = DiffMatcher::AllMatcher.new(exp, :min=>3)
162
+ puts DiffMatcher::difference(expected, [1, 2])
107
163
  # => [
108
- # => 1
109
- # => + 2
164
+ # => : 1,
165
+ # => : 2,
166
+ # => - Fixnum
110
167
  # => ]
111
- # => Where, + 1 additional
168
+ # => Where, - 1 missing, : 2 match_class
112
169
  ```
113
170
 
114
-
115
- When `expected` is a `Hash` with optional keys use a `Matcher`.
116
-
117
171
  ``` ruby
118
- puts DiffMatcher::difference(
119
- DiffMatcher::Matcher.new({:name=>String, :age=>Fixnum}, :optional_keys=>[:age]),
120
- {:name=>0}
121
- )
122
- {
123
- :name=>- String+ 0
124
- }
125
- Where, - 1 missing, + 1 additional
172
+ exp = Fixnum
173
+ expected = DiffMatcher::AllMatcher.new(exp, :size=>3..5)
174
+ puts DiffMatcher::difference(expected, [1, 2])
175
+ # => [
176
+ # => : 1,
177
+ # => : 2,
178
+ # => - Fixnum
179
+ # => ]
180
+ # => Where, - 1 missing, : 2 match_class
126
181
  ```
127
182
 
128
-
129
- When `expected` can take multiple forms use some `Matcher`s `||`ed together.
183
+ When `actual` is an array of unknown size *and* `expected` can take
184
+ multiple forms use a `Matcher` to `||` them together, then wrap that
185
+ with an `AllMatcher` to match against *all* the elements in the array in
186
+ any of the forms.
130
187
 
131
188
  ``` ruby
132
- puts DiffMatcher::difference(DiffMatcher::Matcher.new(Fixnum) || DiffMatcher.new(Float), "3")
133
- - Float+ "3"
134
- Where, - 1 missing, + 1 additional
189
+ exp1 = Fixnum
190
+ exp2 = Float
191
+ expected = DiffMatcher::AllMatcher.new( DiffMatcher::Matcher[Fixnum, Float] )
192
+ puts DiffMatcher::difference(expected, [1, 2.00, "3"])
193
+ # => [
194
+ # => | 1,
195
+ # => | 2.0,
196
+ # => - Float+ "3"
197
+ # => ]
198
+ # => Where, - 1 missing, + 1 additional, | 2 match_matcher
135
199
  ```
136
- (NB. `DiffMatcher::Matcher[Fixnum, Float]` can be used as a shortcut for
137
- `DiffMatcher::Matcher.new(Fixnum) || DiffMatcher.new(Float)`
138
- )
139
200
 
201
+ ### Matcher options
140
202
 
141
- When `actual` is an array of *unknown* size use an `AllMatcher` to match
142
- against *all* the elements in the array.
203
+ Matcher options can be passed to `DiffMatcher::difference` or `DiffMatcher::Matcher#diff`
204
+ or instances of `DiffMatcher::Matcher`
205
+
206
+ First consider:
143
207
 
144
208
  ``` ruby
145
- puts DiffMatcher::difference(DiffMatcher::AllMatcher.new(Fixnum), [1, 2, "3"])
146
- [
147
- : 1,
148
- : 2,
149
- - Fixnum+ "3"
150
- ]
151
- Where, - 1 missing, + 1 additional, : 2 match_class
209
+ expected = DiffMatcher::Matcher.new([1])
210
+ puts expected.diff([1, 2])
211
+ # => [
212
+ # => 1,
213
+ # => + 2
214
+ # => ]
152
215
  ```
153
216
 
217
+ Using `:ignore_additional=>true` will now match even though `actual` has additional items.
154
218
 
155
- When `actual` is an array with a *limited* size use an `AllMatcher` to match
156
- against *all* the elements in the array adhering to the limits of `:min`
157
- and or `:max` or `:size` (where `:size` is a Fixnum or range of Fixnum).
219
+ It can be used in the following ways:
158
220
 
159
221
  ``` ruby
160
- puts DiffMatcher::difference(DiffMatcher::AllMatcher.new(Fixnum, :min=>3), [1, 2])
161
- [
162
- : 1,
163
- : 2,
164
- - Fixnum
165
- ]
166
- Where, - 1 missing, : 2 match_class
222
+ expected = DiffMatcher::Matcher.new([1])
223
+ puts expected.diff([1, 2], :ignore_additional=>true)
224
+ # => nil
167
225
  ```
168
226
 
227
+ or
228
+
169
229
  ``` ruby
170
- puts DiffMatcher::difference(DiffMatcher::AllMatcher.new(Fixnum, :size=>3..5), [1, 2])
171
- [
172
- : 1,
173
- : 2,
174
- - Fixnum
175
- ]
176
- Where, - 1 missing, : 2 match_class
230
+ expected = DiffMatcher::Matcher.new([1])
231
+ puts DiffMatcher::difference(expected, [1, 2], :ignore_additional=>true)
232
+ # => nil
177
233
  ```
178
234
 
179
- When `actual` is an array of unknown size *and* `expected` can take
180
- multiple forms use a `Matcher` inside of an `AllMatcher` to match
181
- against *all* the elements in the array in any of the forms.
235
+ or
182
236
 
183
237
  ``` ruby
184
- puts DiffMatcher::difference(
185
- DiffMatcher::AllMatcher.new(
186
- DiffMatcher::Matcher[Fixnum, Float]
187
- ),
188
- [1, 2.00, "3"]
189
- )
190
- [
191
- | 1,
192
- | 2.0,
193
- - Float+ "3"
194
- ]
195
- Where, - 1 missing, + 1 additional, | 2 match_matcher
238
+ expected = DiffMatcher::Matcher.new([1], :ignore_additional=>true)
239
+ puts expected.diff([1, 2])
240
+ # => nil
196
241
  ```
197
242
 
198
- ### Options
199
-
200
- `:ignore_additional=>true` will match even if `actual` has additional items
243
+ Now consider:
201
244
 
202
245
  ``` ruby
203
- p DiffMatcher::difference([1], [1, 2], :ignore_additional=>true)
204
- # => nil
246
+ puts DiffMatcher::Matcher.new([Fixnum, 2]).diff([1])
247
+ # => [
248
+ # => : 1,
249
+ # => - 2
250
+ # => ]
205
251
  ```
206
252
 
207
- `:quiet=>true` shows only missing and additional items in the output
208
-
253
+ Using `:quiet=>true` will only show missing and additional items in the output
209
254
  ``` ruby
210
- puts DiffMatcher::difference([Fixnum, 2], [1], :quiet=>true)
255
+ puts DiffMatcher::Matcher.new([Fixnum, 2]).diff([1], :quiet=>true)
211
256
  # => [
212
257
  # => - 2
213
258
  # => ]
214
- # => Where, - 1 missing
215
259
  ```
216
260
 
217
- `:html_output=>true` will convert ansii escape codes to html spans
261
+ `:html_output=>true` will convert ansii escape colour codes to html spans
218
262
 
219
263
  ``` ruby
220
264
  puts DiffMatcher::difference(1, 2, :html_output=>true)
221
- <pre>
222
- <span style="color:red">- <b>1</b></span><span style="color:yellow">+ <b>2</b></span>
223
- Where, <span style="color:red">- <b>1 missing</b></span>, <span style="color:yellow">+ <b>1 additional</b></span>
224
- </pre>
265
+ # => <pre>
266
+ # => <span style="color:red">- <b>1</b></span><span style="color:yellow">+ <b>2</b></span>
267
+ # => Where, <span style="color:red">- <b>1 missing</b></span>, <span style="color:yellow">+ <b>1 additional</b></span>
268
+ # => </pre>
225
269
  ```
226
270
 
227
271
  #### Prefixes
228
272
 
229
- The items shown in a difference are prefixed as follows:
273
+ A difference string is similar in appereance to the `.inspect` of plain
274
+ ruby objects, however the matched elements it contains are prefixed
275
+ in the following way:
230
276
 
231
277
  missing => "- "
232
278
  additional => "+ "
@@ -376,13 +422,14 @@ Finished in 0.00601 seconds
376
422
  Contributing
377
423
  ---
378
424
 
379
- Fork, write some tests and send a pull request (bonus points for topic branches).
425
+ Think up something DiffMatcher *can't* do! :)
426
+ Fork, write some tests and send a pull request (bonus points for topic branches), or just submit an issue.
380
427
 
381
428
 
382
429
  Status
383
430
  ---
384
431
 
385
- Our company is using this gem to test our JSON API which has got it to a stable v1.0.0 release.
432
+ Our company is using this gem to test our JSON API which has got above and beyond a stable v1.0.0 release.
386
433
 
387
434
  There's a [pull request](http://github.com/rspec/rspec-expectations/pull/79) to use this gem in a `be_hash_matching`
388
435
  [rspec matcher](https://www.relishapp.com/rspec/rspec-expectations).
@@ -11,16 +11,11 @@ Gem::Specification.new do |s|
11
11
  s.email = "chris@playup.com"
12
12
  s.homepage = "http://github.com/playup/diff_matcher"
13
13
 
14
- s.summary = %q{Generates a diff by matching against expected values, classes, regexes and/or procs.}
14
+ s.summary = %q{Generates a diff by matching against user-defined matchers written in ruby.}
15
15
  s.description = <<EOF
16
- DiffMatcher performs recursive matches on values contained in hashes, arrays and combinations thereof.
17
-
18
- Values in a containing object match when:
19
-
20
- - actual == expected
21
- - actual.is_a? expected # when expected is a class
22
- - expected.match actual # when expected is a regexp
23
- - expected.call actual # when expected is a proc
16
+ DiffMatcher matches input data (eg. from a JSON API) against values,
17
+ ranges, classes, regexes, procs, custom matchers and/or easily composed,
18
+ nested combinations thereof to produce an easy to read diff string.
24
19
  EOF
25
20
 
26
21
  s.files = `git ls-files`.split("\n")
@@ -48,7 +48,6 @@ module DiffMatcher
48
48
  end
49
49
  end
50
50
 
51
- class NotAnArray < Exception; end
52
51
  class AllMatcher < Matcher
53
52
  def expected(e, actual)
54
53
  opts = expected_opts(e)
@@ -109,9 +108,17 @@ module DiffMatcher
109
108
  @color_scheme = color_schemes[value]
110
109
  end
111
110
 
111
+ def color_enabled=(value)
112
+ @color_enabled = value
113
+ end
114
+
112
115
  def color_enabled
113
116
  @color_enabled.nil? ? !!@color_scheme : @color_enabled
114
117
  end
118
+
119
+ def configure(&block)
120
+ block.call(self)
121
+ end
115
122
  end
116
123
 
117
124
  def initialize(expected, actual, opts={})
@@ -1,3 +1,3 @@
1
1
  module DiffMatcher
2
- VERSION = "2.3.3"
2
+ VERSION = "2.4.0"
3
3
  end
@@ -751,6 +751,27 @@ describe "DiffMatcher::difference(expected, actual, opts)" do
751
751
  end
752
752
  end
753
753
 
754
+ describe "it shows matches in color when color is configured in Difference" do
755
+ before do
756
+ DiffMatcher::Difference.configure do |config|
757
+ config.color_enabled = true
758
+ end
759
+ end
760
+
761
+ it_behaves_like "a diff matcher", expected, same, different,
762
+ <<-EOF
763
+ \e[0m[
764
+ \e[0m \e[31m- \e[1m1\e[0m\e[35m+ \e[1m0\e[0m,
765
+ \e[0m 2,
766
+ \e[0m \e[32m~ \e[0m"\e[32m(\e[1m3\e[0m\e[32m)\e[0m"\e[0m,
767
+ \e[0m \e[34m: \e[1m4\e[0m,
768
+ \e[0m \e[36m. \e[1m5\e[0m,
769
+ \e[0m \e[36m{ \e[1m6\e[0m
770
+ \e[0m]
771
+ 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
772
+ EOF
773
+ end
774
+
754
775
  describe "it shows matches in html" do
755
776
  it_behaves_like "a diff matcher", expected, same, different,
756
777
  <<-EOF , :color_scheme => :white_background, :html_output=>true
metadata CHANGED
@@ -1,27 +1,31 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: diff_matcher
3
- version: !ruby/object:Gem::Version
4
- version: 2.3.3
3
+ version: !ruby/object:Gem::Version
5
4
  prerelease:
5
+ version: 2.4.0
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Playup
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-03 00:00:00.000000000 +10:00
13
- default_executable:
12
+
13
+ date: 2012-08-05 00:00:00 Z
14
14
  dependencies: []
15
- description: ! "DiffMatcher performs recursive matches on values contained in hashes,
16
- arrays and combinations thereof.\n\nValues in a containing object match when:\n\n
17
- \ - actual == expected\n - actual.is_a? expected # when expected is a class\n
18
- \ - expected.match actual # when expected is a regexp\n - expected.call actual
19
- \ # when expected is a proc\n"
15
+
16
+ description: |
17
+ DiffMatcher matches input data (eg. from a JSON API) against values,
18
+ ranges, classes, regexes, procs, custom matchers and/or easily composed,
19
+ nested combinations thereof to produce an easy to read diff string.
20
+
20
21
  email: chris@playup.com
21
22
  executables: []
23
+
22
24
  extensions: []
25
+
23
26
  extra_rdoc_files: []
24
- files:
27
+
28
+ files:
25
29
  - .gitignore
26
30
  - .rspec
27
31
  - .travis.yml
@@ -40,33 +44,35 @@ files:
40
44
  - lib/diff_matcher/version.rb
41
45
  - spec/diff_matcher/difference_spec.rb
42
46
  - spec/spec_helper.rb
43
- has_rdoc: true
44
47
  homepage: http://github.com/playup/diff_matcher
45
48
  licenses: []
49
+
46
50
  post_install_message:
47
51
  rdoc_options: []
48
- require_paths:
52
+
53
+ require_paths:
49
54
  - lib
50
- required_ruby_version: !ruby/object:Gem::Requirement
55
+ required_ruby_version: !ruby/object:Gem::Requirement
51
56
  none: false
52
- requirements:
53
- - - ! '>='
54
- - !ruby/object:Gem::Version
55
- version: '0'
56
- segments:
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: -1395308355013142327
61
+ segments:
57
62
  - 0
58
- hash: 1047575201
59
- required_rubygems_version: !ruby/object:Gem::Requirement
63
+ version: "0"
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
65
  none: false
61
- requirements:
62
- - - ! '>='
63
- - !ruby/object:Gem::Version
64
- version: '0'
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
65
70
  requirements: []
71
+
66
72
  rubyforge_project:
67
- rubygems_version: 1.6.2
73
+ rubygems_version: 1.8.21
68
74
  signing_key:
69
75
  specification_version: 3
70
- summary: Generates a diff by matching against expected values, classes, regexes and/or
71
- procs.
76
+ summary: Generates a diff by matching against user-defined matchers written in ruby.
72
77
  test_files: []
78
+