Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Break matchers out into their own files for better organization

  • Loading branch information...
commit 633546e51dbaa1ec35fd1f748b7a19eecb6ed7b8 1 parent 36d08d0
@laserlemon laserlemon authored
View
2  lib/json_spec.rb
@@ -1,3 +1,5 @@
+require "json"
+require "rspec"
require "json_spec/version"
require "json_spec/errors"
require "json_spec/configuration"
View
233 lib/json_spec/matchers.rb
@@ -1,234 +1,11 @@
-require "json"
-require "rspec"
+require "json_spec/matchers/be_json_eql"
+require "json_spec/matchers/include_json"
+require "json_spec/matchers/have_json_path"
+require "json_spec/matchers/have_json_type"
+require "json_spec/matchers/have_json_size"
module JsonSpec
module Matchers
- class BeJsonEql
- include JsonSpec::Helpers
- include JsonSpec::Exclusion
-
- attr_reader :expected, :actual
-
- def diffable?
- true
- end
-
- def initialize(expected_json = nil)
- @expected_json = expected_json
- end
-
- def matches?(actual_json)
- raise "Expected equivalent JSON not provided" if @expected_json.nil?
-
- @actual, @expected = scrub(actual_json, @path), scrub(@expected_json)
- @actual == @expected
- end
-
- def at_path(path)
- @path = path
- self
- end
-
- def to_file(path)
- @expected_json = load_json(path)
- self
- end
-
- def excluding(*keys)
- excluded_keys.merge(keys.map{|k| k.to_s })
- self
- end
-
- def including(*keys)
- excluded_keys.subtract(keys.map{|k| k.to_s })
- self
- end
-
- def failure_message_for_should
- message = "Expected equivalent JSON"
- message << %( at path "#{@path}") if @path
- message
- end
-
- def failure_message_for_should_not
- message = "Expected inequivalent JSON"
- message << %( at path "#{@path}") if @path
- message
- end
-
- def description
- message = "equal JSON"
- message << %( at path "#{@path}") if @path
- message
- end
-
- private
- def scrub(json, path = nil)
- generate_normalized_json(exclude_keys(parse_json(json, path))).chomp + "\n"
- end
- end
-
- class IncludeJson
- include JsonSpec::Helpers
- include JsonSpec::Exclusion
-
- def initialize(expected_json = nil)
- @expected_json = expected_json
- end
-
- def matches?(actual_json)
- raise "Expected included JSON not provided" if @expected_json.nil?
-
- actual = parse_json(actual_json, @path)
- expected = exclude_keys(parse_json(@expected_json))
- case actual
- when Hash then actual.values.map{|v| exclude_keys(v) }.include?(expected)
- when Array then actual.map{|e| exclude_keys(e) }.include?(expected)
- else false
- end
- end
-
- def at_path(path)
- @path = path
- self
- end
-
- def from_file(path)
- @expected_json = load_json(path)
- self
- end
-
- def excluding(*keys)
- excluded_keys.merge(keys.map{|k| k.to_s })
- self
- end
-
- def including(*keys)
- excluded_keys.subtract(keys.map{|k| k.to_s })
- self
- end
-
- def failure_message_for_should
- message = "Expected included JSON"
- message << %( at path "#{@path}") if @path
- message
- end
-
- def failure_message_for_should_not
- message = "Expected excluded JSON"
- message << %( at path "#{@path}") if @path
- message
- end
-
- def description
- message = "include JSON"
- message << %( at path "#{@path}") if @path
- message
- end
- end
-
- class HaveJsonPath
- include JsonSpec::Helpers
-
- def initialize(path)
- @path = path
- end
-
- def matches?(json)
- begin
- parse_json(json, @path)
- true
- rescue JsonSpec::MissingPathError
- false
- end
- end
-
- def failure_message_for_should
- %(Expected JSON path "#{@path}")
- end
-
- def failure_message_for_should_not
- %(Expected no JSON path "#{@path}")
- end
-
- def description
- %(have JSON path "#{@path}")
- end
- end
-
- class HaveJsonType
- include JsonSpec::Helpers
-
- def initialize(klass)
- @klass = klass
- end
-
- def matches?(json)
- @ruby = parse_json(json, @path)
- @ruby.is_a?(@klass)
- end
-
- def at_path(path)
- @path = path
- self
- end
-
- def failure_message_for_should
- message = "Expected JSON value type to be #{@klass}, got #{@ruby.class}"
- message << %( at path "#{@path}") if @path
- message
- end
-
- def failure_message_for_should_not
- message = "Expected JSON value type to not be #{@klass}, got #{@ruby.class}"
- message << %( at path "#{@path}") if @path
- message
- end
-
- def description
- message = %(have JSON type "#{@klass.to_s}")
- message << %( at path "#{@path}") if @path
- message
- end
- end
-
- class HaveJsonSize
- include JsonSpec::Helpers
-
- def initialize(size)
- @expected = size
- end
-
- def matches?(json)
- ruby = parse_json(json, @path)
- @actual = ruby.is_a?(Enumerable) ? ruby.size : 1
- @actual == @expected
- end
-
- def at_path(path)
- @path = path
- self
- end
-
- def failure_message_for_should
- message = "Expected JSON value size to be #{@expected}, got #{@actual}"
- message << %( at path "#{@path}") if @path
- message
- end
-
- def failure_message_for_should_not
- message = "Expected JSON value size to not be #{@expected}, got #{@actual}"
- message << %( at path "#{@path}") if @path
- message
- end
-
- def description
- message = %(have JSON size "#{@expected}")
- message << %( at path "#{@path}") if @path
- message
- end
- end
-
def be_json_eql(json = nil)
JsonSpec::Matchers::BeJsonEql.new(json)
end
View
68 lib/json_spec/matchers/be_json_eql.rb
@@ -0,0 +1,68 @@
+module JsonSpec
+ module Matchers
+ class BeJsonEql
+ include JsonSpec::Helpers
+ include JsonSpec::Exclusion
+
+ attr_reader :expected, :actual
+
+ def diffable?
+ true
+ end
+
+ def initialize(expected_json = nil)
+ @expected_json = expected_json
+ end
+
+ def matches?(actual_json)
+ raise "Expected equivalent JSON not provided" if @expected_json.nil?
+
+ @actual, @expected = scrub(actual_json, @path), scrub(@expected_json)
+ @actual == @expected
+ end
+
+ def at_path(path)
+ @path = path
+ self
+ end
+
+ def to_file(path)
+ @expected_json = load_json(path)
+ self
+ end
+
+ def excluding(*keys)
+ excluded_keys.merge(keys.map{|k| k.to_s })
+ self
+ end
+
+ def including(*keys)
+ excluded_keys.subtract(keys.map{|k| k.to_s })
+ self
+ end
+
+ def failure_message_for_should
+ message = "Expected equivalent JSON"
+ message << %( at path "#{@path}") if @path
+ message
+ end
+
+ def failure_message_for_should_not
+ message = "Expected inequivalent JSON"
+ message << %( at path "#{@path}") if @path
+ message
+ end
+
+ def description
+ message = "equal JSON"
+ message << %( at path "#{@path}") if @path
+ message
+ end
+
+ private
+ def scrub(json, path = nil)
+ generate_normalized_json(exclude_keys(parse_json(json, path))).chomp + "\n"
+ end
+ end
+ end
+end
View
32 lib/json_spec/matchers/have_json_path.rb
@@ -0,0 +1,32 @@
+module JsonSpec
+ module Matchers
+ class HaveJsonPath
+ include JsonSpec::Helpers
+
+ def initialize(path)
+ @path = path
+ end
+
+ def matches?(json)
+ begin
+ parse_json(json, @path)
+ true
+ rescue JsonSpec::MissingPathError
+ false
+ end
+ end
+
+ def failure_message_for_should
+ %(Expected JSON path "#{@path}")
+ end
+
+ def failure_message_for_should_not
+ %(Expected no JSON path "#{@path}")
+ end
+
+ def description
+ %(have JSON path "#{@path}")
+ end
+ end
+ end
+end
View
40 lib/json_spec/matchers/have_json_size.rb
@@ -0,0 +1,40 @@
+module JsonSpec
+ module Matchers
+ class HaveJsonSize
+ include JsonSpec::Helpers
+
+ def initialize(size)
+ @expected = size
+ end
+
+ def matches?(json)
+ ruby = parse_json(json, @path)
+ @actual = ruby.is_a?(Enumerable) ? ruby.size : 1
+ @actual == @expected
+ end
+
+ def at_path(path)
+ @path = path
+ self
+ end
+
+ def failure_message_for_should
+ message = "Expected JSON value size to be #{@expected}, got #{@actual}"
+ message << %( at path "#{@path}") if @path
+ message
+ end
+
+ def failure_message_for_should_not
+ message = "Expected JSON value size to not be #{@expected}, got #{@actual}"
+ message << %( at path "#{@path}") if @path
+ message
+ end
+
+ def description
+ message = %(have JSON size "#{@expected}")
+ message << %( at path "#{@path}") if @path
+ message
+ end
+ end
+ end
+end
View
39 lib/json_spec/matchers/have_json_type.rb
@@ -0,0 +1,39 @@
+module JsonSpec
+ module Matchers
+ class HaveJsonType
+ include JsonSpec::Helpers
+
+ def initialize(klass)
+ @klass = klass
+ end
+
+ def matches?(json)
+ @ruby = parse_json(json, @path)
+ @ruby.is_a?(@klass)
+ end
+
+ def at_path(path)
+ @path = path
+ self
+ end
+
+ def failure_message_for_should
+ message = "Expected JSON value type to be #{@klass}, got #{@ruby.class}"
+ message << %( at path "#{@path}") if @path
+ message
+ end
+
+ def failure_message_for_should_not
+ message = "Expected JSON value type to not be #{@klass}, got #{@ruby.class}"
+ message << %( at path "#{@path}") if @path
+ message
+ end
+
+ def description
+ message = %(have JSON type "#{@klass.to_s}")
+ message << %( at path "#{@path}") if @path
+ message
+ end
+ end
+ end
+end
View
62 lib/json_spec/matchers/include_json.rb
@@ -0,0 +1,62 @@
+module JsonSpec
+ module Matchers
+ class IncludeJson
+ include JsonSpec::Helpers
+ include JsonSpec::Exclusion
+
+ def initialize(expected_json = nil)
+ @expected_json = expected_json
+ end
+
+ def matches?(actual_json)
+ raise "Expected included JSON not provided" if @expected_json.nil?
+
+ actual = parse_json(actual_json, @path)
+ expected = exclude_keys(parse_json(@expected_json))
+ case actual
+ when Hash then actual.values.map{|v| exclude_keys(v) }.include?(expected)
+ when Array then actual.map{|e| exclude_keys(e) }.include?(expected)
+ else false
+ end
+ end
+
+ def at_path(path)
+ @path = path
+ self
+ end
+
+ def from_file(path)
+ @expected_json = load_json(path)
+ self
+ end
+
+ def excluding(*keys)
+ excluded_keys.merge(keys.map{|k| k.to_s })
+ self
+ end
+
+ def including(*keys)
+ excluded_keys.subtract(keys.map{|k| k.to_s })
+ self
+ end
+
+ def failure_message_for_should
+ message = "Expected included JSON"
+ message << %( at path "#{@path}") if @path
+ message
+ end
+
+ def failure_message_for_should_not
+ message = "Expected excluded JSON"
+ message << %( at path "#{@path}") if @path
+ message
+ end
+
+ def description
+ message = "include JSON"
+ message << %( at path "#{@path}") if @path
+ message
+ end
+ end
+ end
+end
View
109 spec/json_spec/matchers/be_json_eql_spec.rb
@@ -0,0 +1,109 @@
+require "spec_helper"
+
+describe JsonSpec::Matchers::BeJsonEql do
+ it "matches identical JSON" do
+ %({"json":"spec"}).should be_json_eql(%({"json":"spec"}))
+ end
+
+ it "matches differently-formatted JSON" do
+ %({"json": "spec"}).should be_json_eql(%({"json":"spec"}))
+ end
+
+ it "matches out-of-order hashes" do
+ %({"laser":"lemon","json":"spec"}).should be_json_eql(%({"json":"spec","laser":"lemon"}))
+ end
+
+ it "doesn't match out-of-order arrays" do
+ %(["json","spec"]).should_not be_json_eql(%(["spec","json"]))
+ end
+
+ it "matches valid JSON values, yet invalid JSON documents" do
+ %("json_spec").should be_json_eql(%("json_spec"))
+ end
+
+ it "matches at a path" do
+ %({"json":["spec"]}).should be_json_eql(%("spec")).at_path("json/0")
+ end
+
+ it "ignores excluded-by-default hash keys" do
+ JsonSpec.excluded_keys.should_not be_empty
+
+ actual = expected = {"json" => "spec"}
+ JsonSpec.excluded_keys.each{|k| actual[k] = k }
+ actual.to_json.should be_json_eql(expected.to_json)
+ end
+
+ it "ignores custom excluded hash keys" do
+ JsonSpec.exclude_keys("ignore")
+ %({"json":"spec","ignore":"please"}).should be_json_eql(%({"json":"spec"}))
+ end
+
+ it "ignores nested, excluded hash keys" do
+ JsonSpec.exclude_keys("ignore")
+ %({"json":"spec","please":{"ignore":"this"}}).should be_json_eql(%({"json":"spec","please":{}}))
+ end
+
+ it "ignores hash keys when included in the expected value" do
+ JsonSpec.exclude_keys("ignore")
+ %({"json":"spec","ignore":"please"}).should be_json_eql(%({"json":"spec","ignore":"this"}))
+ end
+
+ it "doesn't match Ruby-equivalent, JSON-inequivalent values" do
+ %({"one":1}).should_not be_json_eql(%({"one":1.0}))
+ end
+
+ it "matches different looking, JSON-equivalent values" do
+ %({"ten":10.0}).should be_json_eql(%({"ten":1e+1}))
+ end
+
+ it "excludes extra hash keys per matcher" do
+ JsonSpec.excluded_keys = %w(ignore)
+ %({"id":1,"json":"spec","ignore":"please"}).should be_json_eql(%({"id":2,"json":"spec","ignore":"this"})).excluding("id")
+ end
+
+ it "excludes extra hash keys given as symbols" do
+ JsonSpec.excluded_keys = []
+ %({"id":1,"json":"spec"}).should be_json_eql(%({"id":2,"json":"spec"})).excluding(:id)
+ end
+
+ it "excludes multiple keys" do
+ JsonSpec.excluded_keys = []
+ %({"id":1,"json":"spec"}).should be_json_eql(%({"id":2,"json":"different"})).excluding(:id, :json)
+ end
+
+ it "includes globally-excluded hash keys per matcher" do
+ JsonSpec.excluded_keys = %w(id ignore)
+ %({"id":1,"json":"spec","ignore":"please"}).should_not be_json_eql(%({"id":2,"json":"spec","ignore":"this"})).including("id")
+ end
+
+ it "includes globally-included hash keys given as symbols" do
+ JsonSpec.excluded_keys = %w(id)
+ %({"id":1,"json":"spec"}).should_not be_json_eql(%({"id":2,"json":"spec"})).including(:id)
+ end
+
+ it "includes multiple keys" do
+ JsonSpec.excluded_keys = %w(id json)
+ %({"id":1,"json":"spec"}).should_not be_json_eql(%({"id":2,"json":"different"})).including(:id, :json)
+ end
+
+ it "provide a description message" do
+ matcher = be_json_eql(%({"id":2,"json":"spec"}))
+ matcher.matches?(%({"id":1,"json":"spec"}))
+ matcher.description.should == "equal JSON"
+ end
+
+ it "provide a description message with path" do
+ matcher = be_json_eql(%({"id":1,"json":["spec"]})).at_path("json/0")
+ matcher.matches?(%({"id":1,"json":["spec"]}))
+ matcher.description.should == %(equal JSON at path "json/0")
+ end
+
+ it "raises an error when not given expected JSON" do
+ expect{ %({"id":1,"json":"spec"}).should be_json_eql }.to raise_error
+ end
+
+ it "matches file contents" do
+ JsonSpec.directory = files_path
+ %({ "value" : "from_file" }).should be_json_eql.to_file("one.json")
+ end
+end
View
29 spec/json_spec/matchers/have_json_path_spec.rb
@@ -0,0 +1,29 @@
+require "spec_helper"
+
+describe JsonSpec::Matchers::HaveJsonPath do
+ it "matches hash keys" do
+ %({"one":{"two":{"three":4}}}).should have_json_path("one/two/three")
+ end
+
+ it "doesn't match values" do
+ %({"one":{"two":{"three":4}}}).should_not have_json_path("one/two/three/4")
+ end
+
+ it "matches array indexes" do
+ %([1,[1,2,[1,2,3,4]]]).should have_json_path("1/2/3")
+ end
+
+ it "respects null array values" do
+ %([null,[null,null,[null,null,null,null]]]).should have_json_path("1/2/3")
+ end
+
+ it "matches hash keys and array indexes" do
+ %({"one":[1,2,{"three":4}]}).should have_json_path("one/2/three")
+ end
+
+ it "provide a description message" do
+ matcher = have_json_path("json")
+ matcher.matches?(%({"id":1,"json":"spec"}))
+ matcher.description.should == %(have JSON path "json")
+ end
+end
View
47 spec/json_spec/matchers/have_json_size_spec.rb
@@ -0,0 +1,47 @@
+require "spec_helper"
+
+describe JsonSpec::Matchers::HaveJsonSize do
+ it "counts array entries" do
+ %([1,2,3]).should have_json_size(3)
+ end
+
+ it "counts null array entries" do
+ %([1,null,3]).should have_json_size(3)
+ end
+
+ it "counts hash key/value pairs" do
+ %({"one":1,"two":2,"three":3}).should have_json_size(3)
+ end
+
+ it "counts null hash values" do
+ %({"one":1,"two":null,"three":3}).should have_json_size(3)
+ end
+
+ it "matches at a path" do
+ %({"one":[1,2,3]}).should have_json_size(3).at_path("one")
+ end
+
+ it "provides a failure message for should" do
+ matcher = have_json_size(3)
+ matcher.matches?(%([1,2]))
+ matcher.failure_message_for_should.should == "Expected JSON value size to be 3, got 2"
+ end
+
+ it "provides a failure message for should not" do
+ matcher = have_json_size(3)
+ matcher.matches?(%([1,2,3]))
+ matcher.failure_message_for_should_not.should == "Expected JSON value size to not be 3, got 3"
+ end
+
+ it "provide a description message" do
+ matcher = have_json_size(1)
+ matcher.matches?(%({"id":1,"json":["spec"]}))
+ matcher.description.should == %(have JSON size "1")
+ end
+
+ it "provide a description message with path" do
+ matcher = have_json_size(1).at_path("json")
+ matcher.matches?(%({"id":1,"json":["spec"]}))
+ matcher.description.should == %(have JSON size "1" at path "json")
+ end
+end
View
79 spec/json_spec/matchers/have_json_type_spec.rb
@@ -0,0 +1,79 @@
+require "spec_helper"
+
+describe JsonSpec::Matchers::HaveJsonType do
+ it "matches hashes" do
+ %({}).should have_json_type(Hash)
+ end
+
+ it "matches arrays" do
+ %([]).should have_json_type(Array)
+ end
+
+ it "matches at a path" do
+ %({"root":[]}).should have_json_type(Array).at_path("root")
+ end
+
+ it "matches strings" do
+ %(["json_spec"]).should have_json_type(String).at_path("0")
+ end
+
+ it "matches a valid JSON value, yet invalid JSON document" do
+ %("json_spec").should have_json_type(String)
+ end
+
+ it "matches empty strings" do
+ %("").should have_json_type(String)
+ end
+
+ it "matches integers" do
+ %(10).should have_json_type(Integer)
+ end
+
+ it "matches floats" do
+ %(10.0).should have_json_type(Float)
+ %(1e+1).should have_json_type(Float)
+ end
+
+ it "matches ancestor classes" do
+ %(10).should have_json_type(Numeric)
+ %(10.0).should have_json_type(Numeric)
+ end
+
+ it "provides a failure message for should" do
+ matcher = have_json_type(Numeric)
+ matcher.matches?(%("foo"))
+ matcher.failure_message_for_should.should == "Expected JSON value type to be Numeric, got String"
+ end
+
+ it "provides a failure message for should not" do
+ matcher = have_json_type(Numeric)
+ matcher.matches?(%(10))
+ matcher.failure_message_for_should_not.should == "Expected JSON value type to not be Numeric, got Fixnum"
+ end
+
+ it "provide a description message" do
+ matcher = have_json_type(String)
+ matcher.matches?(%({"id":1,"json":"spec"}))
+ matcher.description.should == %(have JSON type "String")
+ end
+
+ it "provide a description message with path" do
+ matcher = have_json_type(String).at_path("json")
+ matcher.matches?(%({"id":1,"json":"spec"}))
+ matcher.description.should == %(have JSON type "String" at path "json")
+ end
+
+ context "somewhat uselessly" do
+ it "matches true" do
+ %(true).should have_json_type(TrueClass)
+ end
+
+ it "matches false" do
+ %(false).should have_json_type(FalseClass)
+ end
+
+ it "matches null" do
+ %(null).should have_json_type(NilClass)
+ end
+ end
+end
View
76 spec/json_spec/matchers/include_json_spec.rb
@@ -0,0 +1,76 @@
+require "spec_helper"
+
+describe JsonSpec::Matchers::IncludeJson do
+ it "matches included array elements" do
+ json = %(["one",1,1.0,true,false,null])
+ json.should include_json(%("one"))
+ json.should include_json(%(1))
+ json.should include_json(%(1.0))
+ json.should include_json(%(true))
+ json.should include_json(%(false))
+ json.should include_json(%(null))
+ end
+
+ it "matches an array included in an array" do
+ json = %([[1,2,3],[4,5,6]])
+ json.should include_json(%([1,2,3]))
+ json.should include_json(%([4,5,6]))
+ end
+
+ it "matches a hash included in an array" do
+ json = %([{"one":1},{"two":2}])
+ json.should include_json(%({"one":1}))
+ json.should include_json(%({"two":2}))
+ end
+
+ it "matches include hash values" do
+ json = %({"string":"one","integer":1,"float":1.0,"true":true,"false":false,"null":null})
+ json.should include_json(%("one"))
+ json.should include_json(%(1))
+ json.should include_json(%(1.0))
+ json.should include_json(%(true))
+ json.should include_json(%(false))
+ json.should include_json(%(null))
+ end
+
+ it "matches a hash included in a hash" do
+ json = %({"one":{"two":3},"four":{"five":6}})
+ json.should include_json(%({"two":3}))
+ json.should include_json(%({"five":6}))
+ end
+
+ it "matches an array included in a hash" do
+ json = %({"one":[2,3],"four":[5,6]})
+ json.should include_json(%([2,3]))
+ json.should include_json(%([5,6]))
+ end
+
+ it "matches at a path" do
+ %({"one":{"two":[3,4]}}).should include_json(%([3,4])).at_path("one")
+ end
+
+ it "ignores excluded keys" do
+ %([{"id":1,"two":3}]).should include_json(%({"two":3}))
+ end
+
+ it "provide a description message" do
+ matcher = include_json(%({"json":"spec"}))
+ matcher.matches?(%({"id":1,"json":"spec"}))
+ matcher.description.should == "include JSON"
+ end
+
+ it "provide a description message with path" do
+ matcher = include_json(%("spec")).at_path("json/0")
+ matcher.matches?(%({"id":1,"json":["spec"]}))
+ matcher.description.should == %(include JSON at path "json/0")
+ end
+
+ it "raises an error when not given expected JSON" do
+ expect{ %([{"id":1,"two":3}]).should include_json }.to raise_error
+ end
+
+ it "matches file contents" do
+ JsonSpec.directory = files_path
+ %({"one":{"value":"from_file"},"four":{"five":6}}).should include_json.from_file("one.json")
+ end
+end
View
348 spec/json_spec/matchers_spec.rb
@@ -1,339 +1,77 @@
require "spec_helper"
-describe "Matchers:" do
- context "be_json_eql" do
- it "matches identical JSON" do
- %({"json":"spec"}).should be_json_eql(%({"json":"spec"}))
- end
-
- it "matches differently-formatted JSON" do
- %({"json": "spec"}).should be_json_eql(%({"json":"spec"}))
- end
-
- it "matches out-of-order hashes" do
- %({"laser":"lemon","json":"spec"}).should be_json_eql(%({"json":"spec","laser":"lemon"}))
- end
-
- it "doesn't match out-of-order arrays" do
- %(["json","spec"]).should_not be_json_eql(%(["spec","json"]))
- end
-
- it "matches valid JSON values, yet invalid JSON documents" do
- %("json_spec").should be_json_eql(%("json_spec"))
- end
-
- it "matches at a path" do
- %({"json":["spec"]}).should be_json_eql(%("spec")).at_path("json/0")
- end
-
- it "ignores excluded-by-default hash keys" do
- JsonSpec.excluded_keys.should_not be_empty
-
- actual = expected = {"json" => "spec"}
- JsonSpec.excluded_keys.each{|k| actual[k] = k }
- actual.to_json.should be_json_eql(expected.to_json)
- end
-
- it "ignores custom excluded hash keys" do
- JsonSpec.exclude_keys("ignore")
- %({"json":"spec","ignore":"please"}).should be_json_eql(%({"json":"spec"}))
- end
-
- it "ignores nested, excluded hash keys" do
- JsonSpec.exclude_keys("ignore")
- %({"json":"spec","please":{"ignore":"this"}}).should be_json_eql(%({"json":"spec","please":{}}))
- end
-
- it "ignores hash keys when included in the expected value" do
- JsonSpec.exclude_keys("ignore")
- %({"json":"spec","ignore":"please"}).should be_json_eql(%({"json":"spec","ignore":"this"}))
- end
-
- it "doesn't match Ruby-equivalent, JSON-inequivalent values" do
- %({"one":1}).should_not be_json_eql(%({"one":1.0}))
- end
-
- it "matches different looking, JSON-equivalent values" do
- %({"ten":10.0}).should be_json_eql(%({"ten":1e+1}))
- end
-
- it "excludes extra hash keys per matcher" do
- JsonSpec.excluded_keys = %w(ignore)
- %({"id":1,"json":"spec","ignore":"please"}).should be_json_eql(%({"id":2,"json":"spec","ignore":"this"})).excluding("id")
- end
-
- it "excludes extra hash keys given as symbols" do
- JsonSpec.excluded_keys = []
- %({"id":1,"json":"spec"}).should be_json_eql(%({"id":2,"json":"spec"})).excluding(:id)
- end
-
- it "excludes multiple keys" do
- JsonSpec.excluded_keys = []
- %({"id":1,"json":"spec"}).should be_json_eql(%({"id":2,"json":"different"})).excluding(:id, :json)
- end
-
- it "includes globally-excluded hash keys per matcher" do
- JsonSpec.excluded_keys = %w(id ignore)
- %({"id":1,"json":"spec","ignore":"please"}).should_not be_json_eql(%({"id":2,"json":"spec","ignore":"this"})).including("id")
- end
-
- it "includes globally-included hash keys given as symbols" do
- JsonSpec.excluded_keys = %w(id)
- %({"id":1,"json":"spec"}).should_not be_json_eql(%({"id":2,"json":"spec"})).including(:id)
- end
-
- it "includes multiple keys" do
- JsonSpec.excluded_keys = %w(id json)
- %({"id":1,"json":"spec"}).should_not be_json_eql(%({"id":2,"json":"different"})).including(:id, :json)
- end
-
- it "provide a description message" do
- matcher = be_json_eql(%({"id":2,"json":"spec"}))
- matcher.matches?(%({"id":1,"json":"spec"}))
- matcher.description.should == "equal JSON"
- end
-
- it "provide a description message with path" do
- matcher = be_json_eql(%({"id":1,"json":["spec"]})).at_path("json/0")
- matcher.matches?(%({"id":1,"json":["spec"]}))
- matcher.description.should == %(equal JSON at path "json/0")
- end
-
- it "raises an error when not given expected JSON" do
- expect{ %({"id":1,"json":"spec"}).should be_json_eql }.to raise_error
- end
-
- it "matches file contents" do
- JsonSpec.directory = files_path
- %({ "value" : "from_file" }).should be_json_eql.to_file("one.json")
- end
+describe JsonSpec::Matchers do
+ let(:environment) do
+ klass = Class.new
+ klass.send(:include, JsonSpec::Matchers)
+ klass.new
end
- context "include_json" do
- it "matches included array elements" do
- json = %(["one",1,1.0,true,false,null])
- json.should include_json(%("one"))
- json.should include_json(%(1))
- json.should include_json(%(1.0))
- json.should include_json(%(true))
- json.should include_json(%(false))
- json.should include_json(%(null))
- end
-
- it "matches an array included in an array" do
- json = %([[1,2,3],[4,5,6]])
- json.should include_json(%([1,2,3]))
- json.should include_json(%([4,5,6]))
- end
-
- it "matches a hash included in an array" do
- json = %([{"one":1},{"two":2}])
- json.should include_json(%({"one":1}))
- json.should include_json(%({"two":2}))
- end
-
- it "matches include hash values" do
- json = %({"string":"one","integer":1,"float":1.0,"true":true,"false":false,"null":null})
- json.should include_json(%("one"))
- json.should include_json(%(1))
- json.should include_json(%(1.0))
- json.should include_json(%(true))
- json.should include_json(%(false))
- json.should include_json(%(null))
- end
-
- it "matches a hash included in a hash" do
- json = %({"one":{"two":3},"four":{"five":6}})
- json.should include_json(%({"two":3}))
- json.should include_json(%({"five":6}))
- end
-
- it "matches an array included in a hash" do
- json = %({"one":[2,3],"four":[5,6]})
- json.should include_json(%([2,3]))
- json.should include_json(%([5,6]))
- end
-
- it "matches at a path" do
- %({"one":{"two":[3,4]}}).should include_json(%([3,4])).at_path("one")
- end
-
- it "ignores excluded keys" do
- %([{"id":1,"two":3}]).should include_json(%({"two":3}))
- end
-
- it "provide a description message" do
- matcher = include_json(%({"json":"spec"}))
- matcher.matches?(%({"id":1,"json":"spec"}))
- matcher.description.should == "include JSON"
- end
+ let(:json){ %({"json":"spec"}) }
- it "provide a description message with path" do
- matcher = include_json(%("spec")).at_path("json/0")
- matcher.matches?(%({"id":1,"json":["spec"]}))
- matcher.description.should == %(include JSON at path "json/0")
- end
-
- it "raises an error when not given expected JSON" do
- expect{ %([{"id":1,"two":3}]).should include_json }.to raise_error
+ context "be_json_eql" do
+ it "instantiates its matcher" do
+ JsonSpec::Matchers::BeJsonEql.should_receive(:new).with(json)
+ environment.be_json_eql(json)
end
- it "matches file contents" do
- JsonSpec.directory = files_path
- %({"one":{"value":"from_file"},"four":{"five":6}}).should include_json.from_file("one.json")
+ it "returns its matcher" do
+ matcher = environment.be_json_eql(json)
+ matcher.should be_a(JsonSpec::Matchers::BeJsonEql)
end
end
- context "have_json_size" do
- it "counts array entries" do
- %([1,2,3]).should have_json_size(3)
- end
-
- it "counts null array entries" do
- %([1,null,3]).should have_json_size(3)
- end
-
- it "counts hash key/value pairs" do
- %({"one":1,"two":2,"three":3}).should have_json_size(3)
- end
-
- it "counts null hash values" do
- %({"one":1,"two":null,"three":3}).should have_json_size(3)
- end
-
- it "matches at a path" do
- %({"one":[1,2,3]}).should have_json_size(3).at_path("one")
- end
-
- it "provides a failure message for should" do
- matcher = have_json_size(3)
- matcher.matches?(%([1,2]))
- matcher.failure_message_for_should.should == "Expected JSON value size to be 3, got 2"
- end
-
- it "provides a failure message for should not" do
- matcher = have_json_size(3)
- matcher.matches?(%([1,2,3]))
- matcher.failure_message_for_should_not.should == "Expected JSON value size to not be 3, got 3"
- end
-
- it "provide a description message" do
- matcher = have_json_size(1)
- matcher.matches?(%({"id":1,"json":["spec"]}))
- matcher.description.should == %(have JSON size "1")
+ context "include_json" do
+ it "instantiates its matcher" do
+ JsonSpec::Matchers::IncludeJson.should_receive(:new).with(json)
+ environment.include_json(json)
end
- it "provide a description message with path" do
- matcher = have_json_size(1).at_path("json")
- matcher.matches?(%({"id":1,"json":["spec"]}))
- matcher.description.should == %(have JSON size "1" at path "json")
+ it "returns its matcher" do
+ matcher = environment.include_json(json)
+ matcher.should be_a(JsonSpec::Matchers::IncludeJson)
end
end
context "have_json_path" do
- it "matches hash keys" do
- %({"one":{"two":{"three":4}}}).should have_json_path("one/two/three")
- end
-
- it "doesn't match values" do
- %({"one":{"two":{"three":4}}}).should_not have_json_path("one/two/three/4")
- end
-
- it "matches array indexes" do
- %([1,[1,2,[1,2,3,4]]]).should have_json_path("1/2/3")
- end
+ let(:path){ "json" }
- it "respects null array values" do
- %([null,[null,null,[null,null,null,null]]]).should have_json_path("1/2/3")
+ it "instantiates its matcher" do
+ JsonSpec::Matchers::HaveJsonPath.should_receive(:new).with(path)
+ environment.have_json_path(path)
end
- it "matches hash keys and array indexes" do
- %({"one":[1,2,{"three":4}]}).should have_json_path("one/2/three")
+ it "returns its matcher" do
+ matcher = environment.have_json_path(path)
+ matcher.should be_a(JsonSpec::Matchers::HaveJsonPath)
end
-
- it "provide a description message" do
- matcher = have_json_path("json")
- matcher.matches?(%({"id":1,"json":"spec"}))
- matcher.description.should == %(have JSON path "json")
- end
-
end
context "have_json_type" do
- it "matches hashes" do
- %({}).should have_json_type(Hash)
- end
-
- it "matches arrays" do
- %([]).should have_json_type(Array)
- end
-
- it "matches at a path" do
- %({"root":[]}).should have_json_type(Array).at_path("root")
- end
-
- it "matches strings" do
- %(["json_spec"]).should have_json_type(String).at_path("0")
- end
-
- it "matches a valid JSON value, yet invalid JSON document" do
- %("json_spec").should have_json_type(String)
- end
-
- it "matches empty strings" do
- %("").should have_json_type(String)
- end
-
- it "matches integers" do
- %(10).should have_json_type(Integer)
- end
-
- it "matches floats" do
- %(10.0).should have_json_type(Float)
- %(1e+1).should have_json_type(Float)
- end
+ let(:type){ Hash }
- it "matches ancestor classes" do
- %(10).should have_json_type(Numeric)
- %(10.0).should have_json_type(Numeric)
+ it "instantiates its matcher" do
+ JsonSpec::Matchers::HaveJsonType.should_receive(:new).with(type)
+ environment.have_json_type(type)
end
- it "provides a failure message for should" do
- matcher = have_json_type(Numeric)
- matcher.matches?(%("foo"))
- matcher.failure_message_for_should.should == "Expected JSON value type to be Numeric, got String"
- end
-
- it "provides a failure message for should not" do
- matcher = have_json_type(Numeric)
- matcher.matches?(%(10))
- matcher.failure_message_for_should_not.should == "Expected JSON value type to not be Numeric, got Fixnum"
+ it "returns its matcher" do
+ matcher = environment.have_json_type(type)
+ matcher.should be_a(JsonSpec::Matchers::HaveJsonType)
end
+ end
- it "provide a description message" do
- matcher = have_json_type(String)
- matcher.matches?(%({"id":1,"json":"spec"}))
- matcher.description.should == %(have JSON type "String")
- end
+ context "have_json_size" do
+ let(:size){ 1 }
- it "provide a description message with path" do
- matcher = have_json_type(String).at_path("json")
- matcher.matches?(%({"id":1,"json":"spec"}))
- matcher.description.should == %(have JSON type "String" at path "json")
+ it "instantiates its matcher" do
+ JsonSpec::Matchers::HaveJsonSize.should_receive(:new).with(size)
+ environment.have_json_size(size)
end
- context "somewhat uselessly" do
- it "matches true" do
- %(true).should have_json_type(TrueClass)
- end
-
- it "matches false" do
- %(false).should have_json_type(FalseClass)
- end
-
- it "matches null" do
- %(null).should have_json_type(NilClass)
- end
+ it "returns its matcher" do
+ matcher = environment.have_json_size(size)
+ matcher.should be_a(JsonSpec::Matchers::HaveJsonSize)
end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.