json_spec 0.3.0 → 0.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/README.md CHANGED
@@ -18,7 +18,7 @@ Please help write documentation!
18
18
 
19
19
  Continuous Integration
20
20
  ----------------------
21
- [![Build Status](https://travis-ci.org/collectiveidea/json_spec.png)](http://travis-ci.org/collectiveidea/json_spec)
21
+ [![Build Status](https://secure.travis-ci.org/collectiveidea/json_spec.png)](http://travis-ci.org/collectiveidea/json_spec)
22
22
 
23
23
  RSpec
24
24
  --------------
@@ -7,7 +7,7 @@ After do
7
7
  end
8
8
 
9
9
  When /^(?:I )?keep the (?:JSON|json)(?: response)?(?: at "(.*)")? as "(.*)"$/ do |path, key|
10
- JsonSpec.memorize(key, path ? json_at_path(last_json, path) : last_json)
10
+ JsonSpec.memorize(key, normalize_json(last_json, path))
11
11
  end
12
12
 
13
13
  Then /^the (?:JSON|json)(?: response)?(?: at "(.*)")? should( not)? be:$/ do |path, negative, json|
@@ -2,39 +2,43 @@ module JsonSpec
2
2
  module Helpers
3
3
  extend self
4
4
 
5
- def json_at_path(json, path)
6
- pretty_json_value(ruby_at_json_path(json, path))
5
+ def parse_json(json, path = nil)
6
+ ruby = JSON.parse(%([#{json}])).first
7
+ value_at_json_path(ruby, path)
8
+ rescue JSON::ParserError
9
+ JSON.parse(json)
10
+ end
11
+
12
+ def normalize_json(json, path = nil)
13
+ ruby = parse_json(json, path)
14
+ generate_normalized_json(ruby)
7
15
  end
8
16
 
9
- def pretty_json_value(ruby)
17
+ def generate_normalized_json(ruby)
10
18
  case ruby
11
19
  when Hash, Array then JSON.pretty_generate(ruby)
12
20
  else ruby.to_json
13
21
  end
14
22
  end
15
23
 
16
- def ruby_at_json_path(json, path)
17
- json_path_to_keys(path).inject(parse_json_value(json)) do |value, key|
18
- case value
19
- when Hash, Array then value.fetch(key){ missing_json_path!(path) }
20
- else missing_json_path!(path)
24
+ private
25
+ def value_at_json_path(ruby, path)
26
+ return ruby unless path
27
+
28
+ json_path_to_keys(path).inject(ruby) do |value, key|
29
+ case value
30
+ when Hash, Array then value.fetch(key){ missing_json_path!(path) }
31
+ else missing_json_path!(path)
32
+ end
21
33
  end
22
34
  end
23
- end
24
-
25
- def json_path_to_keys(path)
26
- path.to_s.gsub(/(?:^\/|\/$)/, "").split("/").map{|k| k =~ /^\d+$/ ? k.to_i : k }
27
- end
28
35
 
29
- def parse_json_value(json)
30
- JSON.parse(%({"root":#{json}}))["root"]
31
- rescue JSON::ParserError
32
- # Re-raise more appropriate parsing error
33
- JSON.parse(json)
34
- end
36
+ def json_path_to_keys(path)
37
+ path.split("/").map{|k| k =~ /^\d+$/ ? k.to_i : k }
38
+ end
35
39
 
36
- def missing_json_path!(path)
37
- raise JsonSpec::MissingPathError.new(path)
38
- end
40
+ def missing_json_path!(path)
41
+ raise JsonSpec::MissingPathError.new(path)
42
+ end
39
43
  end
40
44
  end
@@ -36,8 +36,7 @@ RSpec::Matchers.define :be_json_eql do |expected_json|
36
36
  end
37
37
 
38
38
  def scrub(json, path = nil)
39
- ruby = path ? ruby_at_json_path(json, path) : parse_json_value(json)
40
- pretty_json_value(exclude_keys(ruby)).chomp + "\n"
39
+ generate_normalized_json(exclude_keys(parse_json(json, path))).chomp + "\n"
41
40
  end
42
41
 
43
42
  def exclude_keys(ruby)
@@ -67,7 +66,7 @@ RSpec::Matchers.define :have_json_path do |path|
67
66
 
68
67
  match do |json|
69
68
  begin
70
- ruby_at_json_path(json, path)
69
+ parse_json(json, path)
71
70
  true
72
71
  rescue JsonSpec::MissingPathError
73
72
  false
@@ -87,8 +86,7 @@ RSpec::Matchers.define :have_json_type do |klass|
87
86
  include JsonSpec::Helpers
88
87
 
89
88
  match do |json|
90
- ruby = @path ? ruby_at_json_path(json, @path) : parse_json_value(json)
91
- ruby.is_a?(klass)
89
+ parse_json(json, @path).is_a?(klass)
92
90
  end
93
91
 
94
92
  chain :at_path do |path|
@@ -112,7 +110,7 @@ RSpec::Matchers.define :have_json_size do |expected_size|
112
110
  include JsonSpec::Helpers
113
111
 
114
112
  match do |json|
115
- ruby = @path ? ruby_at_json_path(json, @path) : parse_json_value(json)
113
+ ruby = parse_json(json, @path)
116
114
  actual_size = ruby.is_a?(Enumerable) ? ruby.size : 1
117
115
  actual_size == expected_size
118
116
  end
@@ -1,3 +1,3 @@
1
1
  module JsonSpec
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -0,0 +1,74 @@
1
+ require "spec_helper"
2
+
3
+ describe JsonSpec::Helpers do
4
+ include described_class
5
+
6
+ context "parse_json" do
7
+ it "parses JSON documents" do
8
+ parse_json(%({"json":["spec"]})).should == {"json" => ["spec"]}
9
+ end
10
+
11
+ it "parses JSON values" do
12
+ parse_json(%("json_spec")).should == "json_spec"
13
+ end
14
+
15
+ it "raises a parser error for invalid JSON" do
16
+ expect{ parse_json("json_spec") }.to raise_error(JSON::ParserError)
17
+ end
18
+
19
+ it "parses at a path if given" do
20
+ json = %({"json":["spec"]})
21
+ parse_json(json, "json").should == ["spec"]
22
+ parse_json(json, "json/0").should == "spec"
23
+ end
24
+
25
+ it "raises an error for a missing path" do
26
+ json = %({"json":["spec"]})
27
+ %w(spec json/1).each do |path|
28
+ expect{ parse_json(json, path) }.to raise_error(JsonSpec::MissingPathError)
29
+ end
30
+ end
31
+ end
32
+
33
+ context "normalize_json" do
34
+ it "normalizes a JSON document" do
35
+ normalized = <<-JSON
36
+ {
37
+ "json": [
38
+ "spec"
39
+ ]
40
+ }
41
+ JSON
42
+ normalize_json(%({"json":["spec"]})).should == normalized.chomp
43
+ end
44
+
45
+ it "normalizes at a path" do
46
+ normalize_json(%({"json":["spec"]}), "json/0").should == %("spec")
47
+ end
48
+
49
+ it "accepts a JSON value" do
50
+ normalize_json(%("json_spec")).should == %("json_spec")
51
+ end
52
+
53
+ it "normalizes JSON values" do
54
+ normalize_json(%(1e+1)).should == %(10.0)
55
+ end
56
+ end
57
+
58
+ context "generate_normalized_json" do
59
+ it "generates a normalized JSON document" do
60
+ normalized = <<-JSON
61
+ {
62
+ "json": [
63
+ "spec"
64
+ ]
65
+ }
66
+ JSON
67
+ generate_normalized_json({"json" => ["spec"]}).should == normalized.chomp
68
+ end
69
+
70
+ it "generates a normalized JSON value" do
71
+ generate_normalized_json(nil).should == %(null)
72
+ end
73
+ end
74
+ end
@@ -18,6 +18,14 @@ describe "Matchers:" do
18
18
  %(["json","spec"]).should_not be_json_eql(%(["spec","json"]))
19
19
  end
20
20
 
21
+ it "matches valid JSON values, yet invalid JSON documents" do
22
+ %("json_spec").should be_json_eql(%("json_spec"))
23
+ end
24
+
25
+ it "matches at a path" do
26
+ %({"json":["spec"]}).should be_json_eql(%("spec")).at_path("json/0")
27
+ end
28
+
21
29
  it "ignores excluded-by-default hash keys" do
22
30
  JsonSpec.excluded_keys.should_not be_empty
23
31
 
@@ -45,9 +53,13 @@ describe "Matchers:" do
45
53
  %({"one":1}).should_not be_json_eql(%({"one":1.0}))
46
54
  end
47
55
 
56
+ it "matches different looking, JSON-equivalent values" do
57
+ %({"ten":10.0}).should be_json_eql(%({"ten":1e+1}))
58
+ end
59
+
48
60
  it "excludes extra hash keys per matcher" do
49
61
  JsonSpec.excluded_keys = %w(ignore)
50
- %({"id":1,"json":"spec","ignore":"please"}).should be_json_eql(%({"id":"2","json":"spec","ignore":"this"})).excluding("id")
62
+ %({"id":1,"json":"spec","ignore":"please"}).should be_json_eql(%({"id":2,"json":"spec","ignore":"this"})).excluding("id")
51
63
  end
52
64
 
53
65
  it "excludes extra hash keys given as symbols" do
@@ -57,7 +69,7 @@ describe "Matchers:" do
57
69
 
58
70
  it "includes globally-excluded hash keys per matcher" do
59
71
  JsonSpec.excluded_keys = %w(id ignore)
60
- %({"id":1,"json":"spec","ignore":"please"}).should_not be_json_eql(%({"id":"2","json":"spec","ignore":"this"})).including("id")
72
+ %({"id":1,"json":"spec","ignore":"please"}).should_not be_json_eql(%({"id":2,"json":"spec","ignore":"this"})).including("id")
61
73
  end
62
74
 
63
75
  it "includes globally-included hash keys given as symbols" do
@@ -82,6 +94,10 @@ describe "Matchers:" do
82
94
  it "counts null hash values" do
83
95
  %({"one":1,"two":null,"three":3}).should have_json_size(3)
84
96
  end
97
+
98
+ it "matches at a path" do
99
+ %({"one":[1,2,3]}).should have_json_size(3).at_path("one")
100
+ end
85
101
  end
86
102
 
87
103
  context "have_json_path" do
@@ -105,4 +121,58 @@ describe "Matchers:" do
105
121
  %({"one":[1,2,{"three":4}]}).should have_json_path("one/2/three")
106
122
  end
107
123
  end
124
+
125
+ context "have_json_type" do
126
+ it "matches hashes" do
127
+ %({}).should have_json_type(Hash)
128
+ end
129
+
130
+ it "matches arrays" do
131
+ %([]).should have_json_type(Array)
132
+ end
133
+
134
+ it "matches at a path" do
135
+ %({"root":[]}).should have_json_type(Array).at_path("root")
136
+ end
137
+
138
+ it "matches strings" do
139
+ %(["json_spec"]).should have_json_type(String).at_path("0")
140
+ end
141
+
142
+ it "matches a valid JSON value, yet invalid JSON document" do
143
+ %("json_spec").should have_json_type(String)
144
+ end
145
+
146
+ it "matches empty strings" do
147
+ %("").should have_json_type(String)
148
+ end
149
+
150
+ it "matches integers" do
151
+ %(10).should have_json_type(Integer)
152
+ end
153
+
154
+ it "matches floats" do
155
+ %(10.0).should have_json_type(Float)
156
+ %(1e+1).should have_json_type(Float)
157
+ end
158
+
159
+ it "matches ancestor classes" do
160
+ %(10).should have_json_type(Numeric)
161
+ %(10.0).should have_json_type(Numeric)
162
+ end
163
+
164
+ context "somewhat uselessly" do
165
+ it "matches true" do
166
+ %(true).should have_json_type(TrueClass)
167
+ end
168
+
169
+ it "matches false" do
170
+ %(false).should have_json_type(FalseClass)
171
+ end
172
+
173
+ it "matches null" do
174
+ %(null).should have_json_type(NilClass)
175
+ end
176
+ end
177
+ end
108
178
  end
@@ -0,0 +1,27 @@
1
+ require "spec_helper"
2
+
3
+ describe JsonSpec::Memory do
4
+ it "has a memory" do
5
+ JsonSpec.memory.should == {}
6
+ end
7
+
8
+ it "memorizes strings" do
9
+ JsonSpec.memorize("key", "value")
10
+ JsonSpec.memory.should == {"key" => "value"}
11
+ end
12
+
13
+ it "regurgitates unremembered strings" do
14
+ JsonSpec.remember("foo%{bar}").should == "foo%{bar}"
15
+ end
16
+
17
+ it "remembers strings" do
18
+ JsonSpec.memorize("bar", "baz")
19
+ JsonSpec.remember("foo%{bar}").should == "foobaz"
20
+ end
21
+
22
+ it "forgets" do
23
+ JsonSpec.memorize("key", "value")
24
+ JsonSpec.forget
25
+ JsonSpec.memory.should == {}
26
+ end
27
+ end
metadata CHANGED
@@ -1,93 +1,68 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: json_spec
3
- version: !ruby/object:Gem::Version
4
- hash: 19
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 3
9
- - 0
10
- version: 0.3.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Steve Richert
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-07-08 00:00:00 -04:00
12
+ date: 2011-07-09 00:00:00.000000000 -04:00
19
13
  default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
22
16
  name: json
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
17
+ requirement: &2155974100 !ruby/object:Gem::Requirement
25
18
  none: false
26
- requirements:
19
+ requirements:
27
20
  - - ~>
28
- - !ruby/object:Gem::Version
29
- hash: 15
30
- segments:
31
- - 1
32
- - 0
33
- version: "1.0"
21
+ - !ruby/object:Gem::Version
22
+ version: '1.0'
34
23
  type: :runtime
35
- version_requirements: *id001
36
- - !ruby/object:Gem::Dependency
37
- name: rspec
38
24
  prerelease: false
39
- requirement: &id002 !ruby/object:Gem::Requirement
25
+ version_requirements: *2155974100
26
+ - !ruby/object:Gem::Dependency
27
+ name: rspec
28
+ requirement: &2155973600 !ruby/object:Gem::Requirement
40
29
  none: false
41
- requirements:
30
+ requirements:
42
31
  - - ~>
43
- - !ruby/object:Gem::Version
44
- hash: 3
45
- segments:
46
- - 2
47
- - 0
48
- version: "2.0"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
49
34
  type: :runtime
50
- version_requirements: *id002
51
- - !ruby/object:Gem::Dependency
52
- name: rake
53
35
  prerelease: false
54
- requirement: &id003 !ruby/object:Gem::Requirement
36
+ version_requirements: *2155973600
37
+ - !ruby/object:Gem::Dependency
38
+ name: rake
39
+ requirement: &2155973140 !ruby/object:Gem::Requirement
55
40
  none: false
56
- requirements:
41
+ requirements:
57
42
  - - ~>
58
- - !ruby/object:Gem::Version
59
- hash: 25
60
- segments:
61
- - 0
62
- - 9
63
- version: "0.9"
43
+ - !ruby/object:Gem::Version
44
+ version: '0.9'
64
45
  type: :development
65
- version_requirements: *id003
66
- - !ruby/object:Gem::Dependency
67
- name: cucumber
68
46
  prerelease: false
69
- requirement: &id004 !ruby/object:Gem::Requirement
47
+ version_requirements: *2155973140
48
+ - !ruby/object:Gem::Dependency
49
+ name: cucumber
50
+ requirement: &2155972680 !ruby/object:Gem::Requirement
70
51
  none: false
71
- requirements:
52
+ requirements:
72
53
  - - ~>
73
- - !ruby/object:Gem::Version
74
- hash: 15
75
- segments:
76
- - 1
77
- - 0
78
- version: "1.0"
54
+ - !ruby/object:Gem::Version
55
+ version: '1.0'
79
56
  type: :development
80
- version_requirements: *id004
57
+ prerelease: false
58
+ version_requirements: *2155972680
81
59
  description: Easily handle JSON in RSpec and Cucumber
82
- email:
60
+ email:
83
61
  - steve.richert@gmail.com
84
62
  executables: []
85
-
86
63
  extensions: []
87
-
88
64
  extra_rdoc_files: []
89
-
90
- files:
65
+ files:
91
66
  - .gitignore
92
67
  - .travis.yml
93
68
  - Gemfile
@@ -111,44 +86,36 @@ files:
111
86
  - lib/json_spec/memory.rb
112
87
  - lib/json_spec/version.rb
113
88
  - spec/json_spec/configuration_spec.rb
89
+ - spec/json_spec/helpers_spec.rb
114
90
  - spec/json_spec/matchers_spec.rb
115
- - spec/json_spec_spec.rb
91
+ - spec/json_spec/memory_spec.rb
116
92
  - spec/spec_helper.rb
117
93
  has_rdoc: true
118
94
  homepage: https://github.com/collectiveidea/json_spec
119
95
  licenses: []
120
-
121
96
  post_install_message:
122
97
  rdoc_options: []
123
-
124
- require_paths:
98
+ require_paths:
125
99
  - lib
126
- required_ruby_version: !ruby/object:Gem::Requirement
100
+ required_ruby_version: !ruby/object:Gem::Requirement
127
101
  none: false
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- hash: 3
132
- segments:
133
- - 0
134
- version: "0"
135
- required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
107
  none: false
137
- requirements:
138
- - - ">="
139
- - !ruby/object:Gem::Version
140
- hash: 3
141
- segments:
142
- - 0
143
- version: "0"
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
144
112
  requirements: []
145
-
146
113
  rubyforge_project: json_spec
147
- rubygems_version: 1.3.7
114
+ rubygems_version: 1.6.2
148
115
  signing_key:
149
116
  specification_version: 3
150
117
  summary: Easily handle JSON in RSpec and Cucumber
151
- test_files:
118
+ test_files:
152
119
  - features/equivalence.feature
153
120
  - features/memory.feature
154
121
  - features/paths.feature
@@ -157,6 +124,7 @@ test_files:
157
124
  - features/support/env.rb
158
125
  - features/types.feature
159
126
  - spec/json_spec/configuration_spec.rb
127
+ - spec/json_spec/helpers_spec.rb
160
128
  - spec/json_spec/matchers_spec.rb
161
- - spec/json_spec_spec.rb
129
+ - spec/json_spec/memory_spec.rb
162
130
  - spec/spec_helper.rb
@@ -1,5 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe JsonSpec do
4
- it "is awesome"
5
- end