json_spec 0.5.0 → 0.6.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/.travis.yml CHANGED
@@ -3,3 +3,9 @@ rvm:
3
3
  - 1.8.7
4
4
  - 1.9.2
5
5
  - ruby-head
6
+ - rbx
7
+ - jruby
8
+ only:
9
+ - master
10
+ notifications:
11
+ disabled: true
data/README.md CHANGED
@@ -22,9 +22,10 @@ Continuous Integration
22
22
 
23
23
  RSpec
24
24
  --------------
25
- json_spec defines four new RSpec matchers:
25
+ json_spec defines five new RSpec matchers:
26
26
 
27
27
  * `be_json_eql`
28
+ * `include_json`
28
29
  * `have_json_path`
29
30
  * `have_json_type`
30
31
  * `have_json_size`
@@ -50,6 +51,7 @@ The new matchers could be used in RSpec as follows:
50
51
  json.should have_json_size(0).at_path("friends")
51
52
  user.friends << User.create!(:first_name => "Catie", :last_name => "Richert")
52
53
  json.should have_json_size(1).at_path("friends")
54
+ json.should include_json(%({"first_name":"Catie","last_name":"Richert"}))
53
55
  end
54
56
  end
55
57
  end
@@ -170,6 +172,39 @@ different formats:
170
172
  Then the JSON at "path" should be false
171
173
  Then the JSON at "path" should be null
172
174
 
175
+ Then the JSON should include:
176
+ """
177
+ {
178
+ "key": "value"
179
+ }
180
+ """
181
+ Then the JSON at "path" should include:
182
+ """
183
+ [
184
+ "entry",
185
+ "entry"
186
+ ]
187
+ """
188
+
189
+ Then the JSON should include {"key":"value"}
190
+ Then the JSON at "path" should include {"key":"value"}
191
+ Then the JSON should include ["entry","entry"]
192
+ Then the JSON at "path" should include ["entry","entry"]
193
+ Then the JSON should include "string"
194
+ Then the JSON at "path" should include "string"
195
+ Then the JSON should include 10
196
+ Then the JSON at "path" should include 10
197
+ Then the JSON should include 10.0
198
+ Then the JSON at "path" should include 10.0
199
+ Then the JSON should include 1e+1
200
+ Then the JSON at "path" should include 1e+1
201
+ Then the JSON should include true
202
+ Then the JSON at "path" should include true
203
+ Then the JSON should include false
204
+ Then the JSON at "path" should include false
205
+ Then the JSON should include null
206
+ Then the JSON at "path" should include null
207
+
173
208
  Then the JSON should have "path"
174
209
 
175
210
  Then the JSON should be a hash
@@ -0,0 +1,154 @@
1
+ Feature: Inclusion
2
+ Background:
3
+ Given the JSON is:
4
+ """
5
+ {
6
+ "array": [
7
+ "json",
8
+ "spec"
9
+ ],
10
+ "created_at": "2011-07-08 02:27:34",
11
+ "empty_array": [
12
+
13
+ ],
14
+ "empty_hash": {
15
+ },
16
+ "false": false,
17
+ "float": 10.0,
18
+ "hash": {
19
+ "json": "spec"
20
+ },
21
+ "id": 1,
22
+ "integer": 10,
23
+ "negative": -10,
24
+ "null": null,
25
+ "string": "json_spec",
26
+ "true": true,
27
+ "updated_at": "2011-07-08 02:28:50",
28
+ "nested": {
29
+ "id": 2,
30
+ "key": "value"
31
+ }
32
+ }
33
+ """
34
+
35
+ Scenario: String
36
+ When I get the JSON
37
+ Then the JSON should include "json_spec"
38
+ And the JSON should include:
39
+ """
40
+ "json_spec"
41
+ """
42
+
43
+ Scenario: Integer
44
+ When I get the JSON
45
+ Then the JSON should include 10
46
+ And the JSON should include:
47
+ """
48
+ 10
49
+ """
50
+
51
+ Scenario: Negative integer
52
+ When I get the JSON
53
+ Then the JSON should include -10
54
+ And the JSON should include:
55
+ """
56
+ -10
57
+ """
58
+
59
+ Scenario: Float
60
+ When I get the JSON
61
+ Then the JSON should include 10.0
62
+ And the JSON should include 10.0e0
63
+ And the JSON should include 10.0e+0
64
+ And the JSON should include 10.0e-0
65
+ And the JSON should include 10e0
66
+ And the JSON should include 10e+0
67
+ And the JSON should include 10e-0
68
+ And the JSON should include 1.0e1
69
+ And the JSON should include 1.0e+1
70
+ And the JSON should include 1e1
71
+ And the JSON should include 1e+1
72
+ And the JSON should include 100.0e-1
73
+ And the JSON should include 100e-1
74
+ And the JSON should include:
75
+ """
76
+ 10.0
77
+ """
78
+
79
+ Scenario: Array
80
+ When I get the JSON
81
+ Then the JSON should include ["json","spec"]
82
+ And the JSON at "array" should include "json"
83
+ And the JSON at "array" should include "spec"
84
+ And the JSON should include:
85
+ """
86
+ [
87
+ "json",
88
+ "spec"
89
+ ]
90
+ """
91
+
92
+ Scenario: Empty array
93
+ When I get the JSON
94
+ Then the JSON should include []
95
+ And the JSON should include:
96
+ """
97
+ [
98
+
99
+ ]
100
+ """
101
+
102
+ Scenario: Hash
103
+ When I get the JSON
104
+ Then the JSON should include {"json":"spec"}
105
+ And the JSON at "hash" should include "spec"
106
+ And the JSON should include:
107
+ """
108
+ {
109
+ "json": "spec"
110
+ }
111
+ """
112
+
113
+ Scenario: Empty hash
114
+ When I get the JSON
115
+ Then the JSON should include {}
116
+ And the JSON should include:
117
+ """
118
+ {
119
+ }
120
+ """
121
+
122
+ Scenario: True
123
+ When I get the JSON
124
+ Then the JSON should include true
125
+ And the JSON should include:
126
+ """
127
+ true
128
+ """
129
+
130
+ Scenario: False
131
+ When I get the JSON
132
+ Then the JSON should include false
133
+ And the JSON should include:
134
+ """
135
+ false
136
+ """
137
+
138
+ Scenario: Null
139
+ When I get the JSON
140
+ Then the JSON should include null
141
+ And the JSON should include:
142
+ """
143
+ null
144
+ """
145
+
146
+ Scenario: Excluded value
147
+ When I get the JSON
148
+ Then the JSON should include "2011-07-08 02:27:34"
149
+ And the JSON should include 1
150
+ And the JSON should include "2011-07-08 02:28:50"
151
+
152
+ Scenario: Nested exclusions
153
+ When I get the JSON
154
+ Then the JSON should include {"key":"value"}
@@ -182,3 +182,40 @@ Feature: Memory
182
182
  "true": true
183
183
  }
184
184
  """
185
+
186
+ Scenario: Table format
187
+ When I keep the JSON at "string" as "STRING"
188
+ And I keep the JSON at "integer" as "INTEGER"
189
+ And I keep the JSON at "float" as "FLOAT"
190
+ And I keep the JSON at "array" as "ARRAY"
191
+ And I keep the JSON at "hash" as "HASH"
192
+ And I keep the JSON at "true" as "TRUE"
193
+ And I keep the JSON at "false" as "FALSE"
194
+ And I keep the JSON at "null" as "NULL"
195
+ Then the JSON should have the following:
196
+ | string | %{STRING} |
197
+ | integer | %{INTEGER} |
198
+ | float | %{FLOAT} |
199
+ | array | %{ARRAY} |
200
+ | hash | %{HASH} |
201
+ | true | %{TRUE} |
202
+ | false | %{FALSE} |
203
+ | null | %{NULL} |
204
+
205
+ Scenario: Inclusion
206
+ When I keep the JSON at "string" as "STRING"
207
+ And I keep the JSON at "integer" as "INTEGER"
208
+ And I keep the JSON at "float" as "FLOAT"
209
+ And I keep the JSON at "array" as "ARRAY"
210
+ And I keep the JSON at "hash" as "HASH"
211
+ And I keep the JSON at "true" as "TRUE"
212
+ And I keep the JSON at "false" as "FALSE"
213
+ And I keep the JSON at "null" as "NULL"
214
+ Then the JSON should include %{STRING}
215
+ And the JSON should include %{INTEGER}
216
+ And the JSON should include %{FLOAT}
217
+ And the JSON should include %{ARRAY}
218
+ And the JSON should include %{HASH}
219
+ And the JSON should include %{TRUE}
220
+ And the JSON should include %{FALSE}
221
+ And the JSON should include %{NULL}
data/lib/json_spec.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "json_spec/version"
2
2
  require "json_spec/errors"
3
3
  require "json_spec/configuration"
4
+ require "json_spec/exclusion"
4
5
  require "json_spec/matchers"
5
6
  require "json_spec/helpers"
6
7
  require "json_spec/memory"
@@ -26,6 +26,22 @@ Then /^the (?:JSON|json)(?: response)?(?: at "(.*)")? should( not)? be (".*"|\-?
26
26
  end
27
27
  end
28
28
 
29
+ Then /^the (?:JSON|json)(?: response)?(?: at "(.*)")? should( not)? include:$/ do |path, negative, json|
30
+ if negative
31
+ last_json.should_not include_json(JsonSpec.remember(json)).at_path(path)
32
+ else
33
+ last_json.should include_json(JsonSpec.remember(json)).at_path(path)
34
+ end
35
+ end
36
+
37
+ Then /^the (?:JSON|json)(?: response)?(?: at "(.*)")? should( not)? include (".*"|\-?\d+(?:\.\d+)?(?:[eE][\+\-]?\d+)?|\[.*\]|%?\{.*\}|true|false|null)$/ do |path, negative, value|
38
+ if negative
39
+ last_json.should_not include_json(JsonSpec.remember(value)).at_path(path)
40
+ else
41
+ last_json.should include_json(JsonSpec.remember(value)).at_path(path)
42
+ end
43
+ end
44
+
29
45
  Then /^the (?:JSON|json)(?: response)?(?: at "(.*)")? should have the following:$/ do |base, table|
30
46
  table.rows.each do |path, value|
31
47
  path = [base, path].compact.join("/")
@@ -0,0 +1,26 @@
1
+ module JsonSpec
2
+ module Exclusion
3
+ extend self
4
+
5
+ def exclude_keys(ruby)
6
+ case ruby
7
+ when Hash
8
+ ruby.sort.inject({}) do |hash, (key, value)|
9
+ hash[key] = exclude_keys(value) unless exclude_key?(key)
10
+ hash
11
+ end
12
+ when Array
13
+ ruby.map{|v| exclude_keys(v) }
14
+ else ruby
15
+ end
16
+ end
17
+
18
+ def exclude_key?(key)
19
+ excluded_keys.include?(key)
20
+ end
21
+
22
+ def excluded_keys
23
+ @excluded_keys ||= Set.new(JsonSpec.excluded_keys)
24
+ end
25
+ end
26
+ end
@@ -3,6 +3,7 @@ require "rspec"
3
3
 
4
4
  RSpec::Matchers.define :be_json_eql do |expected_json|
5
5
  include JsonSpec::Helpers
6
+ include JsonSpec::Exclusion
6
7
 
7
8
  diffable
8
9
 
@@ -38,26 +39,44 @@ RSpec::Matchers.define :be_json_eql do |expected_json|
38
39
  def scrub(json, path = nil)
39
40
  generate_normalized_json(exclude_keys(parse_json(json, path))).chomp + "\n"
40
41
  end
42
+ end
43
+
44
+ RSpec::Matchers.define :include_json do |expected_json|
45
+ include JsonSpec::Helpers
46
+ include JsonSpec::Exclusion
41
47
 
42
- def exclude_keys(ruby)
43
- case ruby
44
- when Hash
45
- ruby.sort.inject({}) do |hash, (key, value)|
46
- hash[key] = exclude_keys(value) unless exclude_key?(key)
47
- hash
48
- end
49
- when Array
50
- ruby.map{|v| exclude_keys(v) }
51
- else ruby
48
+ match do |actual_json|
49
+ actual = parse_json(actual_json, @path)
50
+ expected = exclude_keys(parse_json(expected_json))
51
+ case actual
52
+ when Hash then actual.values.map{|v| exclude_keys(v) }.include?(expected)
53
+ when Array then actual.map{|e| exclude_keys(e) }.include?(expected)
54
+ else false
52
55
  end
53
56
  end
54
57
 
55
- def exclude_key?(key)
56
- excluded_keys.include?(key)
58
+ chain :at_path do |path|
59
+ @path = path
60
+ end
61
+
62
+ chain :excluding do |*keys|
63
+ excluded_keys.add(*keys.map{|k| k.to_s })
64
+ end
65
+
66
+ chain :including do |*keys|
67
+ excluded_keys.subtract(keys.map{|k| k.to_s })
57
68
  end
58
69
 
59
- def excluded_keys
60
- @excluded_keys ||= Set.new(JsonSpec.excluded_keys)
70
+ failure_message_for_should do
71
+ message = "Expected included JSON"
72
+ message << %( at path "#{@path}") if @path
73
+ message
74
+ end
75
+
76
+ failure_message_for_should_not do
77
+ message = "Expected excluded JSON"
78
+ message << %( at path "#{@path}") if @path
79
+ message
61
80
  end
62
81
  end
63
82
 
@@ -1,3 +1,3 @@
1
1
  module JsonSpec
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -78,6 +78,60 @@ describe "Matchers:" do
78
78
  end
79
79
  end
80
80
 
81
+ context "include_json" do
82
+ it "matches included array elements" do
83
+ json = %(["one",1,1.0,true,false,null])
84
+ json.should include_json(%("one"))
85
+ json.should include_json(%(1))
86
+ json.should include_json(%(1.0))
87
+ json.should include_json(%(true))
88
+ json.should include_json(%(false))
89
+ json.should include_json(%(null))
90
+ end
91
+
92
+ it "matches an array included in an array" do
93
+ json = %([[1,2,3],[4,5,6]])
94
+ json.should include_json(%([1,2,3]))
95
+ json.should include_json(%([4,5,6]))
96
+ end
97
+
98
+ it "matches a hash included in an array" do
99
+ json = %([{"one":1},{"two":2}])
100
+ json.should include_json(%({"one":1}))
101
+ json.should include_json(%({"two":2}))
102
+ end
103
+
104
+ it "matches include hash values" do
105
+ json = %({"string":"one","integer":1,"float":1.0,"true":true,"false":false,"null":null})
106
+ json.should include_json(%("one"))
107
+ json.should include_json(%(1))
108
+ json.should include_json(%(1.0))
109
+ json.should include_json(%(true))
110
+ json.should include_json(%(false))
111
+ json.should include_json(%(null))
112
+ end
113
+
114
+ it "matches a hash included in a hash" do
115
+ json = %({"one":{"two":3},"four":{"five":6}})
116
+ json.should include_json(%({"two":3}))
117
+ json.should include_json(%({"five":6}))
118
+ end
119
+
120
+ it "matches an array included in a hash" do
121
+ json = %({"one":[2,3],"four":[5,6]})
122
+ json.should include_json(%([2,3]))
123
+ json.should include_json(%([5,6]))
124
+ end
125
+
126
+ it "matches at a path" do
127
+ %({"one":{"two":[3,4]}}).should include_json(%([3,4])).at_path("one")
128
+ end
129
+
130
+ it "ignores excluded keys" do
131
+ %([{"id":1,"two":3}]).should include_json(%({"two":3}))
132
+ end
133
+ end
134
+
81
135
  context "have_json_size" do
82
136
  it "counts array entries" do
83
137
  %([1,2,3]).should have_json_size(3)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json_spec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-07-10 00:00:00.000000000 -04:00
12
+ date: 2011-07-20 00:00:00.000000000 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json
17
- requirement: &2156046080 !ruby/object:Gem::Requirement
17
+ requirement: &70202465651180 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '1.0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *2156046080
25
+ version_requirements: *70202465651180
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rspec
28
- requirement: &2156045580 !ruby/object:Gem::Requirement
28
+ requirement: &70202465650680 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ~>
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '2.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *2156045580
36
+ version_requirements: *70202465650680
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: rake
39
- requirement: &2156045120 !ruby/object:Gem::Requirement
39
+ requirement: &70202465650220 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ~>
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: '0.9'
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *2156045120
47
+ version_requirements: *70202465650220
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: cucumber
50
- requirement: &2156044660 !ruby/object:Gem::Requirement
50
+ requirement: &70202465649760 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ~>
@@ -55,7 +55,7 @@ dependencies:
55
55
  version: '1.0'
56
56
  type: :development
57
57
  prerelease: false
58
- version_requirements: *2156044660
58
+ version_requirements: *70202465649760
59
59
  description: Easily handle JSON in RSpec and Cucumber
60
60
  email:
61
61
  - steve.richert@gmail.com
@@ -70,6 +70,7 @@ files:
70
70
  - README.md
71
71
  - Rakefile
72
72
  - features/equivalence.feature
73
+ - features/inclusion.feature
73
74
  - features/memory.feature
74
75
  - features/paths.feature
75
76
  - features/sizes.feature
@@ -81,6 +82,7 @@ files:
81
82
  - lib/json_spec/configuration.rb
82
83
  - lib/json_spec/cucumber.rb
83
84
  - lib/json_spec/errors.rb
85
+ - lib/json_spec/exclusion.rb
84
86
  - lib/json_spec/helpers.rb
85
87
  - lib/json_spec/matchers.rb
86
88
  - lib/json_spec/memory.rb
@@ -117,6 +119,7 @@ specification_version: 3
117
119
  summary: Easily handle JSON in RSpec and Cucumber
118
120
  test_files:
119
121
  - features/equivalence.feature
122
+ - features/inclusion.feature
120
123
  - features/memory.feature
121
124
  - features/paths.feature
122
125
  - features/sizes.feature