json_spec 0.5.0 → 0.6.0

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