diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..005119b --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.4.1 diff --git a/README.md b/README.md index 5a09c63..c94fa52 100644 --- a/README.md +++ b/README.md @@ -9,19 +9,20 @@ Easily handle JSON in RSpec and Cucumber ## RSpec -json_spec defines five new RSpec matchers: +json_spec defines six new RSpec matchers: * `be_json_eql` * `include_json` * `have_json_path` * `have_json_type` * `have_json_size` +* `have_json_value` The new matchers could be used in RSpec as follows: ```ruby describe User do - let(:user){ User.create!(first_name: "Steve", last_name: "Richert") } + let(:user) { User.create!(first_name: "Steve", last_name: "Richert") } context "#to_json" do it "includes names" do @@ -34,6 +35,10 @@ describe User do user.to_json.should have_json_type(Integer).at_path("id") end + it "includes a generated friendly ID" do + user.to_json.should have_json_value(user.friendly_id).at_path("external_id") + end + it "includes friends" do user.to_json.should have_json_size(0).at_path("friends") diff --git a/lib/json_spec/matchers.rb b/lib/json_spec/matchers.rb index cf58e89..2500806 100644 --- a/lib/json_spec/matchers.rb +++ b/lib/json_spec/matchers.rb @@ -2,6 +2,7 @@ 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_value" require "json_spec/matchers/have_json_size" module JsonSpec @@ -22,6 +23,10 @@ def have_json_type(type) JsonSpec::Matchers::HaveJsonType.new(type) end + def have_json_value(value) + JsonSpec::Matchers::HaveJsonValue.new(value) + end + def have_json_size(size) JsonSpec::Matchers::HaveJsonSize.new(size) end diff --git a/lib/json_spec/matchers/have_json_value.rb b/lib/json_spec/matchers/have_json_value.rb new file mode 100644 index 0000000..de75fbc --- /dev/null +++ b/lib/json_spec/matchers/have_json_value.rb @@ -0,0 +1,36 @@ +module JsonSpec + module Matchers + class HaveJsonValue + include JsonSpec::Helpers + include JsonSpec::Messages + + def initialize(value) + @value = value + end + + def matches?(json) + @ruby = parse_json(json, @path) + @value == @ruby + end + + def at_path(path) + @path = path + self + end + + def failure_message + message_with_path("Expected JSON value to be \"#{@value}\", got \"#{@ruby}\"") + end + alias :failure_message_for_should :failure_message + + def failure_message_when_negated + message_with_path("Expected JSON value to not be \"#{@value}\", got \"#{@ruby}\"") + end + alias :failure_message_for_should_not :failure_message_when_negated + + def description + message_with_path(%(have JSON value "#{@value}")) + end + end + end +end diff --git a/spec/json_spec/matchers/have_json_value_spec.rb b/spec/json_spec/matchers/have_json_value_spec.rb new file mode 100644 index 0000000..92dbad7 --- /dev/null +++ b/spec/json_spec/matchers/have_json_value_spec.rb @@ -0,0 +1,41 @@ +require "spec_helper" + +describe JsonSpec::Matchers::HaveJsonValue do + it "matches value at root path" do + %("bar").should have_json_value("bar") + end + + it "matches value at path" do + %({"foo": "bar"}).should have_json_value("bar").at_path("foo") + end + + it "matches value at deep path" do + %({"foo": {"pipe": "bar"}}).should have_json_value("bar").at_path("foo/pipe") + end + + it "provides a failure message" do + matcher = have_json_value("pipe") + matcher.matches?(%("bar")) + matcher.failure_message.should == "Expected JSON value to be \"pipe\", got \"bar\"" + matcher.failure_message_for_should.should == "Expected JSON value to be \"pipe\", got \"bar\"" # RSpec 2 interface + end + + it "provides a failure message for negation" do + matcher = have_json_value("pipe") + matcher.matches?(%("bar")) + matcher.failure_message_when_negated.should == "Expected JSON value to not be \"pipe\", got \"bar\"" + matcher.failure_message_for_should_not.should == "Expected JSON value to not be \"pipe\", got \"bar\"" # RSpec 2 interface + end + + it "provides a description message" do + matcher = have_json_value("pipe") + matcher.matches?(%("pipe")) + matcher.description.should == %(have JSON value "pipe") + end + + it "provides a description message with path" do + matcher = have_json_value("pipe").at_path("json") + matcher.matches?(%({"id":1,"json":"pipe"})) + matcher.description.should == %(have JSON value "pipe" at path "json") + end +end