json_expressions 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +23 -37
- data/lib/json_expressions/matcher.rb +1 -17
- metadata +1 -1
data/README.md
CHANGED
@@ -82,20 +82,20 @@ class UsersControllerTest < MiniTest::Unit::TestCase
|
|
82
82
|
# This is what we expect the returned JSON to look like
|
83
83
|
pattern = {
|
84
84
|
user: {
|
85
|
-
id: :user_id,
|
86
|
-
username: 'chancancode',
|
85
|
+
id: :user_id, # "Capture" this value for later
|
86
|
+
username: 'chancancode', # Match this exact string
|
87
87
|
full_name: 'Godfrey Chan',
|
88
88
|
email: 'godfrey@example.com',
|
89
89
|
type: 'Administrator',
|
90
|
-
points: Fixnum,
|
91
|
-
homepage: /\Ahttps?\:\/\/.*\z/i,
|
92
|
-
created_at: WILDCARD_MATCHER,
|
90
|
+
points: Fixnum, # Any integer value
|
91
|
+
homepage: /\Ahttps?\:\/\/.*\z/i, # Let's get serious
|
92
|
+
created_at: WILDCARD_MATCHER, # Don't care as long as it exists
|
93
93
|
updated_at: WILDCARD_MATCHER,
|
94
94
|
posts: [
|
95
95
|
{
|
96
96
|
id: Fixnum,
|
97
97
|
subject: 'Hello world!',
|
98
|
-
user_id: :user_id,
|
98
|
+
user_id: :user_id, # Match against the captured value
|
99
99
|
tags: [
|
100
100
|
'announcement',
|
101
101
|
'welcome',
|
@@ -180,10 +180,24 @@ Furthermore, because the pattern is just plain old Ruby code, you can also write
|
|
180
180
|
[ WILDCARD_MATCHER ] * 7
|
181
181
|
```
|
182
182
|
|
183
|
-
###
|
183
|
+
### Object Equality
|
184
184
|
|
185
|
-
|
185
|
+
By default, json_expressions uses `Object#===` to match against the corresponding value in the target JSON. In most cases, this method behaves exactly the same as `Object#==`. However, certain classes override this method to provide specialized behavior (notably `Regexp` and `Module`, see below). If you find this undesirable for certain classes, you can explicitly opt them out and json_expressions will call `Object#==` instead:
|
186
186
|
|
187
|
+
```ruby
|
188
|
+
# This is the default setting
|
189
|
+
JsonExpressions::Matcher.skip_triple_equal_on = [ ]
|
190
|
+
|
191
|
+
# To add more modules/classes
|
192
|
+
# JsonExpressions::Matcher.skip_triple_equal_on << MyClass
|
193
|
+
|
194
|
+
# To turn this off completely
|
195
|
+
# JsonExpressions::Matcher.skip_triple_equal_on = [ BasicObject ]
|
196
|
+
```
|
197
|
+
|
198
|
+
### Regular Expressions
|
199
|
+
|
200
|
+
Since `Regexp` overrides `Object#===` to mean "matches", you can use them in your patterns and json_expressions will do the right thing:
|
187
201
|
```ruby
|
188
202
|
{ hex: /\A0x[0-9a-f]+\z/i }
|
189
203
|
```
|
@@ -196,24 +210,9 @@ but not
|
|
196
210
|
{ "hex": "Hello world!" }
|
197
211
|
```
|
198
212
|
|
199
|
-
Sometimes this behavior is undesirable. For instance, String#match(other) converts `other` into a `Regexp` and use that to match against itself, which is probably not what you want (`''.match 'Hello world!' # => nil` but `'Hello world!'.match '' # => #<MatchData "">`!).
|
200
|
-
|
201
|
-
You can specific a list of classes/modules with undesirable `match` behavior, and json_expression will fall back to calling `===` on these objects instead (see the section below for `===` vs `==`).
|
202
|
-
|
203
|
-
```ruby
|
204
|
-
# This is the default setting
|
205
|
-
JsonExpressions::Matcher.skip_match_on = [ String ]
|
206
|
-
|
207
|
-
# To add more modules/classes
|
208
|
-
# JsonExpressions::Matcher.skip_match_on << MyClass
|
209
|
-
|
210
|
-
# To turn this off completely
|
211
|
-
# JsonExpressions::Matcher.skip_match_on = [ BasicObject ]
|
212
|
-
```
|
213
|
-
|
214
213
|
### Type Matching
|
215
214
|
|
216
|
-
|
215
|
+
`Module` (and by inheritance, `Class`) overrides `===` to mean `instance of`. You can exploit this behavior to do type matching:
|
217
216
|
```ruby
|
218
217
|
{
|
219
218
|
integer: Fixnum,
|
@@ -238,19 +237,6 @@ matches the JSON object
|
|
238
237
|
}
|
239
238
|
```
|
240
239
|
|
241
|
-
You can specific a list of classes/modules with undesirable `===` behavior, and json_expression will fall back to calling `==` on them instead.
|
242
|
-
|
243
|
-
```ruby
|
244
|
-
# This is the default setting
|
245
|
-
JsonExpressions::Matcher.skip_triple_equal_on = [ ]
|
246
|
-
|
247
|
-
# To add more modules/classes
|
248
|
-
# JsonExpressions::Matcher.skip_triple_equal_on << MyClass
|
249
|
-
|
250
|
-
# To turn this off completely
|
251
|
-
# JsonExpressions::Matcher.skip_triple_equal_on = [ BasicObject ]
|
252
|
-
```
|
253
|
-
|
254
240
|
### Capturing
|
255
241
|
|
256
242
|
Similar to how "captures" work in Regexp, you can capture the value of certain keys for later use:
|
@@ -4,12 +4,6 @@ require 'json_expressions/core_extensions'
|
|
4
4
|
module JsonExpressions
|
5
5
|
class Matcher
|
6
6
|
class << self
|
7
|
-
# JsonExpressions::Matcher.skip_match_on (Array)
|
8
|
-
# An array of classes and modules with undesirable `match` behavior
|
9
|
-
# Default: [ String ]
|
10
|
-
attr_accessor :skip_match_on
|
11
|
-
JsonExpressions::Matcher.skip_match_on = [ String ]
|
12
|
-
|
13
7
|
# JsonExpressions::Matcher.skip_triple_equal_on (Array)
|
14
8
|
# An array of classes and modules with undesirable `===` behavior
|
15
9
|
# Default: []
|
@@ -20,7 +14,7 @@ module JsonExpressions
|
|
20
14
|
# By default, assume arrays are unordered when not specified
|
21
15
|
# Default: true
|
22
16
|
attr_accessor :assume_unordered_arrays
|
23
|
-
JsonExpressions::Matcher.assume_unordered_arrays =
|
17
|
+
JsonExpressions::Matcher.assume_unordered_arrays = false
|
24
18
|
|
25
19
|
# JsonExpressions::Matcher.assume_strict_arrays (Boolean)
|
26
20
|
# By default, reject arrays with extra elements when not specified
|
@@ -78,8 +72,6 @@ module JsonExpressions
|
|
78
72
|
match_array path, matcher, other
|
79
73
|
elsif matcher.is_a? Hash
|
80
74
|
match_hash path, matcher, other
|
81
|
-
elsif matcher.respond_to?(:match) && matchable?(matcher)
|
82
|
-
match_obj path, matcher, other, :match
|
83
75
|
elsif triple_equable?(matcher)
|
84
76
|
match_obj path, matcher, other, :===
|
85
77
|
else
|
@@ -204,14 +196,6 @@ module JsonExpressions
|
|
204
196
|
end
|
205
197
|
end
|
206
198
|
|
207
|
-
def matchable?(obj)
|
208
|
-
if self.class.skip_match_on.include? obj.class
|
209
|
-
false
|
210
|
-
else
|
211
|
-
self.class.skip_match_on.none? { |klass| obj.is_a? klass }
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
199
|
def triple_equable?(obj)
|
216
200
|
if self.class.skip_triple_equal_on.include? obj.class
|
217
201
|
false
|