diff_matcher 2.3.3 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
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
+