json_spec 0.3.0 → 0.4.0

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