rspec-hal 1.2.0 → 1.2.1
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.
- checksums.yaml +4 -4
- data/README.md +3 -1
- data/lib/rspec/hal/matchers.rb +32 -84
- data/lib/rspec/hal/matchers/hal_matcher_helpers.rb +65 -0
- data/lib/rspec/hal/matchers/have_property_matcher.rb +69 -0
- data/lib/rspec/hal/matchers/relation_matcher.rb +69 -0
- data/lib/rspec/hal/matchers/templated_relation_matcher.rb +5 -30
- data/lib/rspec/hal/version.rb +1 -1
- data/spec/rspec/hal/matchers/have_property_matcher_spec.rb +126 -0
- data/spec/rspec/hal/matchers/relation_matcher_spec.rb +173 -0
- data/spec/rspec/hal/matchers/templated_relation_matcher_spec.rb +4 -4
- data/spec/rspec/hal/matchers_spec.rb +1 -45
- metadata +9 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 5db7232aae0766a25700b98a53d8c343c0eb8f91
         | 
| 4 | 
            +
              data.tar.gz: 560a463c6967e2c0f060aec76c688d007cf08756
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: dfe7e6f2a41a4dce154256da82f2789d40db8509e5be62f7658a9db46ec97a3bdfdaa25e88669300158008dddb4aa1b320b0bae52aac65975646c02e11841231
         | 
| 7 | 
            +
              data.tar.gz: f48fead8ad5405d19646fe6c01b5d07518978f475f6683089d8ce0a65e09b46ba41d4246cb4244a9aa2bcdd1a2e2d0aa6953990a64ae18a7aae61c94b78868f0
         | 
    
        data/README.md
    CHANGED
    
    | @@ -35,6 +35,8 @@ Once you have the matchers included you can use it like this | |
| 35 35 | 
             
                  .including(a_hash_including('type' => 'sport'))
         | 
| 36 36 |  | 
| 37 37 | 
             
                expect(a_user_doc).to have_relation('tag')
         | 
| 38 | 
            +
                expect(a_user_doc).to have_templated_relation("search")
         | 
| 39 | 
            +
                expect(a_user_doc).to have_templated_relation("search", matching("{?q}"))
         | 
| 38 40 | 
             
            ```
         | 
| 39 41 |  | 
| 40 42 | 
             
            ## Installation
         | 
| @@ -60,4 +62,4 @@ Or install it yourself as: | |
| 60 62 | 
             
            5. Push to the branch (`git push origin my-new-feature`)
         | 
| 61 63 | 
             
            6. Create new Pull Request
         | 
| 62 64 |  | 
| 63 | 
            -
            [semver]: http://semver.org
         | 
| 65 | 
            +
            [semver]: http://semver.org
         | 
    
        data/lib/rspec/hal/matchers.rb
    CHANGED
    
    | @@ -4,7 +4,10 @@ require 'hal-client' | |
| 4 4 | 
             
            module RSpec
         | 
| 5 5 | 
             
              module Hal
         | 
| 6 6 | 
             
                module Matchers
         | 
| 7 | 
            +
                  autoload :HalMatcherHelpers, "rspec/hal/matchers/hal_matcher_helpers"
         | 
| 8 | 
            +
                  require "rspec/hal/matchers/relation_matcher"
         | 
| 7 9 | 
             
                  require "rspec/hal/matchers/templated_relation_matcher"
         | 
| 10 | 
            +
                  require "rspec/hal/matchers/have_property_matcher"
         | 
| 8 11 |  | 
| 9 12 | 
             
                  # Examples
         | 
| 10 13 | 
             
                  #
         | 
| @@ -15,6 +18,35 @@ module RSpec | |
| 15 18 | 
             
                    TemplatedRelationMatcher.new(*args)
         | 
| 16 19 | 
             
                  end
         | 
| 17 20 |  | 
| 21 | 
            +
                  # Signature
         | 
| 22 | 
            +
                  #
         | 
| 23 | 
            +
                  #     expect(doc).to have_relation(link_rel)
         | 
| 24 | 
            +
                  #     expect(doc).to have_relation(link_rel, href_matcher)
         | 
| 25 | 
            +
                  #     expect(doc).to have_relation(link_rel, template_variables)
         | 
| 26 | 
            +
                  #     expect(doc).to have_relation(link_rel, template_variables, href_matcher)
         | 
| 27 | 
            +
                  #
         | 
| 28 | 
            +
                  # Examples
         | 
| 29 | 
            +
                  #
         | 
| 30 | 
            +
                  #     expect(authors_doc).to have_relation("search",
         | 
| 31 | 
            +
                  #                                          {q: "Alice"},
         | 
| 32 | 
            +
                  #                                          match(%r|users/42|))
         | 
| 33 | 
            +
                  def have_relation(*args)
         | 
| 34 | 
            +
                    RelationMatcher.new(*args)
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  # Signature
         | 
| 38 | 
            +
                  #
         | 
| 39 | 
            +
                  #     expect(a_doc).to have_property "name"
         | 
| 40 | 
            +
                  #     expect(a_doc).to have_property "name, matching(/alice/i)
         | 
| 41 | 
            +
                  #
         | 
| 42 | 
            +
                  #     expect(a_doc).to have_property("name").matching(/alice/i)
         | 
| 43 | 
            +
                  #     expect(a_doc).to have_property("hobbies").including(matching("golf"))
         | 
| 44 | 
            +
                  #     expect(a_doc).to have_property("name").that_is("Bob")
         | 
| 45 | 
            +
                  #     expect(a_doc).to have_property("age").that_is kind_of Numeric
         | 
| 46 | 
            +
                  def have_property(*args)
         | 
| 47 | 
            +
                    HavePropertyMatcher.new(*args)
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
             | 
| 18 50 | 
             
                  module Document
         | 
| 19 51 | 
             
                    extend RSpec::Matchers::DSL
         | 
| 20 52 |  | 
| @@ -74,91 +106,7 @@ module RSpec | |
| 74 106 | 
             
                        "Expected `$._embedded.item` to exist in:\n" + a_doc
         | 
| 75 107 | 
             
                      end
         | 
| 76 108 | 
             
                    end
         | 
| 77 | 
            -
             | 
| 78 | 
            -
                    # Check that the document has the specified property.
         | 
| 79 | 
            -
                    #
         | 
| 80 | 
            -
                    # Signature
         | 
| 81 | 
            -
                    #
         | 
| 82 | 
            -
                    #     expect(a_user_doc).to have_property "name"
         | 
| 83 | 
            -
                    #     expect(a_user_doc).to have_property("name").that_is("Bob")
         | 
| 84 | 
            -
                    #     expect(a_user_doc).to have_property("age").that_is kind_of Numeric
         | 
| 85 | 
            -
                    #     expect(a_user_doc).to have_property("name").matching(/bob/i)
         | 
| 86 | 
            -
                    #     expect(a_user_doc).to have_property("hobbies").including(matching("golf"))
         | 
| 87 | 
            -
                    matcher :have_property do |prop_name|
         | 
| 88 | 
            -
                      match do |a_doc|
         | 
| 89 | 
            -
                        a_doc = JSON.load(a_doc) rescue a_doc
         | 
| 90 | 
            -
             | 
| 91 | 
            -
             | 
| 92 | 
            -
                        next false unless a_doc.key? prop_name
         | 
| 93 | 
            -
             | 
| 94 | 
            -
                        __value_matcher === a_doc.fetch(prop_name)
         | 
| 95 | 
            -
                      end
         | 
| 96 | 
            -
             | 
| 97 | 
            -
                      chain :that_is do |expected_val|
         | 
| 98 | 
            -
                        @value_matcher = expected_val
         | 
| 99 | 
            -
                      end
         | 
| 100 | 
            -
             | 
| 101 | 
            -
                      chain :matching do |val_pat|
         | 
| 102 | 
            -
                        @value_matcher = if Regexp === val_pat
         | 
| 103 | 
            -
                                           RSpec::Matchers::BuiltIn::Match.new val_pat
         | 
| 104 | 
            -
                                         else
         | 
| 105 | 
            -
                                           val_pat
         | 
| 106 | 
            -
                                         end
         | 
| 107 | 
            -
                      end
         | 
| 108 | 
            -
             | 
| 109 | 
            -
                      chain :including do |val_pat|
         | 
| 110 | 
            -
                        @value_matcher = RSpec::Matchers::BuiltIn::Include.new val_pat
         | 
| 111 | 
            -
                      end
         | 
| 112 | 
            -
             | 
| 113 | 
            -
                      failure_message do
         | 
| 114 | 
            -
                        msg = super()
         | 
| 115 | 
            -
                        if @value_matcher
         | 
| 116 | 
            -
                          msg + " " + @value_matcher.description.gsub(/^match /, "matching ")
         | 
| 117 | 
            -
                        end
         | 
| 118 | 
            -
                      end
         | 
| 119 | 
            -
             | 
| 120 | 
            -
                      define_method(:__value_matcher) do
         | 
| 121 | 
            -
                        @value_matcher || ->(*_){ true }
         | 
| 122 | 
            -
                      end
         | 
| 123 | 
            -
                    end
         | 
| 124 | 
            -
             | 
| 125 | 
            -
                    # Check that the document has the specified relation (in
         | 
| 126 | 
            -
                    # either the _links or _embedded sections.
         | 
| 127 | 
            -
                    #
         | 
| 128 | 
            -
                    # Signature
         | 
| 129 | 
            -
                    #
         | 
| 130 | 
            -
                    #     expect(a_user_doc).to have_relation "tag"
         | 
| 131 | 
            -
                    matcher :have_relation do |link_rel|
         | 
| 132 | 
            -
                      match do |a_doc|
         | 
| 133 | 
            -
                        a_doc = JSON.load(a_doc) rescue a_doc
         | 
| 134 | 
            -
                        repr = HalClient::Representation.new(parsed_json: a_doc)
         | 
| 135 | 
            -
             | 
| 136 | 
            -
                        begin
         | 
| 137 | 
            -
                          repr.related_hrefs(link_rel) .any?{|an_href|
         | 
| 138 | 
            -
                            next true if !defined? @href_matcher
         | 
| 139 | 
            -
                            @href_matcher === an_href
         | 
| 140 | 
            -
                          }
         | 
| 141 | 
            -
                        rescue KeyError
         | 
| 142 | 
            -
                          false
         | 
| 143 | 
            -
                        end
         | 
| 144 | 
            -
                      end
         | 
| 145 | 
            -
             | 
| 146 | 
            -
                      chain :with_href do |expected_href|
         | 
| 147 | 
            -
                        (fail ArgumentError, "#{expected_href.inspect} must be a matcher") unless expected_href.respond_to? :matches?
         | 
| 148 | 
            -
             | 
| 149 | 
            -
                        @href_matcher = expected_href
         | 
| 150 | 
            -
                      end
         | 
| 151 | 
            -
             | 
| 152 | 
            -
                      failure_message do
         | 
| 153 | 
            -
                        msg = super()
         | 
| 154 | 
            -
                        if @href_matcher
         | 
| 155 | 
            -
                          msg + " with href " + @href_matcher.description.gsub(/^match /, "matching ")
         | 
| 156 | 
            -
                        end
         | 
| 157 | 
            -
                      end
         | 
| 158 | 
            -
             | 
| 159 | 
            -
                    end
         | 
| 160 109 | 
             
                  end
         | 
| 161 | 
            -
             | 
| 162 110 | 
             
                  include Document
         | 
| 163 111 | 
             
                end
         | 
| 164 112 | 
             
              end
         | 
| @@ -0,0 +1,65 @@ | |
| 1 | 
            +
            module RSpec
         | 
| 2 | 
            +
              module Hal
         | 
| 3 | 
            +
                module Matchers
         | 
| 4 | 
            +
                  module HalMatcherHelpers
         | 
| 5 | 
            +
                    NullMatcher = Class.new do
         | 
| 6 | 
            +
                      def matches(*args)
         | 
| 7 | 
            +
                        true
         | 
| 8 | 
            +
                      end
         | 
| 9 | 
            +
                      def ===(*args)
         | 
| 10 | 
            +
                        true
         | 
| 11 | 
            +
                      end
         | 
| 12 | 
            +
                      def description
         | 
| 13 | 
            +
                        ""
         | 
| 14 | 
            +
                      end
         | 
| 15 | 
            +
                    end.new
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                    # Returns string composed of the specified clauses with proper
         | 
| 18 | 
            +
                    # spacing between them. Empty and nil clauses are ignored.
         | 
| 19 | 
            +
                    def sentencize(*clauses)
         | 
| 20 | 
            +
                      clauses
         | 
| 21 | 
            +
                        .flatten
         | 
| 22 | 
            +
                        .compact
         | 
| 23 | 
            +
                        .reject(&:empty?)
         | 
| 24 | 
            +
                        .map(&:strip)
         | 
| 25 | 
            +
                        .join(" ")
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    # Returns HalClient::Representation of the provided jsonish
         | 
| 29 | 
            +
                    # thing.
         | 
| 30 | 
            +
                    #
         | 
| 31 | 
            +
                    # jsonish - A HAL document (as a string or pre-parsed hash) or
         | 
| 32 | 
            +
                    #   an object that can be converted into one via its `#to_hal`
         | 
| 33 | 
            +
                    #   or `#to_json` methods.
         | 
| 34 | 
            +
                    def parse(jsonish)
         | 
| 35 | 
            +
                      json = if jsonish.kind_of? String
         | 
| 36 | 
            +
                               jsonish
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                             elsif jsonish.respond_to? :to_hal
         | 
| 39 | 
            +
                               jsonish.to_hal
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                             else jsonish.respond_to? :to_json
         | 
| 42 | 
            +
                               jsonish.to_json
         | 
| 43 | 
            +
                             end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                      HalClient::Representation.new(parsed_json: MultiJson.load(json))
         | 
| 46 | 
            +
                    end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                    def matcherize(expected)
         | 
| 49 | 
            +
                      if matcher? expected
         | 
| 50 | 
            +
                        expected
         | 
| 51 | 
            +
                      elsif expected.kind_of? Regexp
         | 
| 52 | 
            +
                        RSpec::Matchers::BuiltIn::Match.new(expected)
         | 
| 53 | 
            +
                      else
         | 
| 54 | 
            +
                        RSpec::Matchers::BuiltIn::Eq.new(expected)
         | 
| 55 | 
            +
                      end
         | 
| 56 | 
            +
                    end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                    def matcher?(obj)
         | 
| 59 | 
            +
                      obj.respond_to?(:matches?) and (obj.respond_to?(:failure_message) or
         | 
| 60 | 
            +
                                                      obj.respond_to?(:failure_message_for_should))
         | 
| 61 | 
            +
                    end
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
              end
         | 
| 65 | 
            +
            end
         | 
| @@ -0,0 +1,69 @@ | |
| 1 | 
            +
            module RSpec
         | 
| 2 | 
            +
              module Hal
         | 
| 3 | 
            +
                module Matchers
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                  # Example
         | 
| 6 | 
            +
                  #
         | 
| 7 | 
            +
                  #     expect(doc).to have_property("name")
         | 
| 8 | 
            +
                  #     expect(doc).to have_property("search", matching("Alice"))
         | 
| 9 | 
            +
                  #
         | 
| 10 | 
            +
                  class HavePropertyMatcher
         | 
| 11 | 
            +
                    include HalMatcherHelpers
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                    def initialize(property_name, expected=NullMatcher)
         | 
| 14 | 
            +
                      @prop_name = property_name
         | 
| 15 | 
            +
                      @expected = expected
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    def matches?(jsonish)
         | 
| 19 | 
            +
                      repr = parse(jsonish)
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                      repr.property?(prop_name) &&
         | 
| 22 | 
            +
                        expected === repr.property(prop_name){ nil }
         | 
| 23 | 
            +
                    end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    def failure_message
         | 
| 26 | 
            +
                      but_clause = if outcome == :no_templates
         | 
| 27 | 
            +
                                     "found only non-templated links"
         | 
| 28 | 
            +
                                   else
         | 
| 29 | 
            +
                                     "found none"
         | 
| 30 | 
            +
                                   end
         | 
| 31 | 
            +
                      expected_clause = if expected != NullMatcher && expected.respond_to?(:description)
         | 
| 32 | 
            +
                                          expected.description
         | 
| 33 | 
            +
                                        elsif expected != NullMatcher
         | 
| 34 | 
            +
                                          "matching #{expected}"
         | 
| 35 | 
            +
                                        else
         | 
| 36 | 
            +
                                          "to exist"
         | 
| 37 | 
            +
                                        end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                      "Expected templated `#{link_rel}` link #{expected_clause} but #{but_clause}"
         | 
| 40 | 
            +
                    end
         | 
| 41 | 
            +
                    alias_method :failure_message_for_should, :failure_message
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                    def failure_message_when_negated
         | 
| 44 | 
            +
                      "Expected `#{link_rel}` link to be absent or not templated"
         | 
| 45 | 
            +
                    end
         | 
| 46 | 
            +
                    alias_method :failure_message_for_should_not, :failure_message_when_negated
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                    def description
         | 
| 49 | 
            +
                      "have property `#{prop_name}` #{@expected.description}"
         | 
| 50 | 
            +
                    end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
             | 
| 53 | 
            +
                    def matching(expected)
         | 
| 54 | 
            +
                      self.class.new(prop_name, matcherize(expected))
         | 
| 55 | 
            +
                    end
         | 
| 56 | 
            +
                    alias_method :that_is, :matching
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                    def including(expected)
         | 
| 59 | 
            +
                      self.class.new(prop_name, RSpec::Matchers::BuiltIn::Include.new(expected))
         | 
| 60 | 
            +
                    end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    protected
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    attr_reader :prop_name, :outcome, :expected
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
              end
         | 
| 69 | 
            +
            end
         | 
| @@ -0,0 +1,69 @@ | |
| 1 | 
            +
            module RSpec
         | 
| 2 | 
            +
              module Hal
         | 
| 3 | 
            +
                module Matchers
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                  # Example
         | 
| 6 | 
            +
                  #
         | 
| 7 | 
            +
                  #     expect(doc).to have_relation("search")
         | 
| 8 | 
            +
                  #     expect(doc).to have_relation("search", matching("{?q}"))
         | 
| 9 | 
            +
                  #
         | 
| 10 | 
            +
                  class RelationMatcher
         | 
| 11 | 
            +
                    include HalMatcherHelpers
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                    # Signature
         | 
| 14 | 
            +
                    #
         | 
| 15 | 
            +
                    #     expect(doc).to have_relation link_rel
         | 
| 16 | 
            +
                    #     expect(doc).to have_relation link_rel, href_matcher
         | 
| 17 | 
            +
                    #     expect(doc).to have_relation link_rel, template_variables
         | 
| 18 | 
            +
                    #     expect(doc).to have_relation link_rel, template_variables, href_matcher
         | 
| 19 | 
            +
                    def initialize(link_rel, *args)
         | 
| 20 | 
            +
                      @link_rel = link_rel
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                      @tmpl_vars, @expected = *if args.empty?
         | 
| 23 | 
            +
                                                 [{},NullMatcher]
         | 
| 24 | 
            +
                                               elsif args.size > 1
         | 
| 25 | 
            +
                                                 args
         | 
| 26 | 
            +
                                               elsif hashish? args.first
         | 
| 27 | 
            +
                                                 [args.first, NullMatcher]
         | 
| 28 | 
            +
                                               else
         | 
| 29 | 
            +
                                                 [{}, args.first]
         | 
| 30 | 
            +
                                               end
         | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                    def matches?(jsonish)
         | 
| 34 | 
            +
                      repr = parse(jsonish)
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                      repr.related_hrefs(link_rel, tmpl_vars){[]}
         | 
| 37 | 
            +
                        .select{|it| expected === it }
         | 
| 38 | 
            +
                        .any?
         | 
| 39 | 
            +
                    end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                    def failure_message
         | 
| 42 | 
            +
                      sentencize "Expected `#{link_rel}` link or embedded", expected.description, "but found none"
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
                    alias_method :failure_message_for_should, :failure_message
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                    def failure_message_when_negated
         | 
| 47 | 
            +
                      "Expected `#{link_rel}` link to be absent"
         | 
| 48 | 
            +
                    end
         | 
| 49 | 
            +
                    alias_method :failure_message_for_should_not, :failure_message_when_negated
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                    def description
         | 
| 52 | 
            +
                      "have #{link_rel} link or embedded"
         | 
| 53 | 
            +
                    end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                    def with_href(expected)
         | 
| 56 | 
            +
                      self.class.new(link_rel, tmpl_vars, matcherize(expected))
         | 
| 57 | 
            +
                    end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                    protected
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                    attr_reader :link_rel, :expected, :tmpl_vars
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                    def hashish?(obj)
         | 
| 64 | 
            +
                      obj.respond_to?(:key?) && obj.respond_to?(:[])
         | 
| 65 | 
            +
                    end
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
              end
         | 
| 69 | 
            +
            end
         | 
| @@ -8,7 +8,9 @@ module RSpec | |
| 8 8 | 
             
                  #     expect(doc).to have_templated_relation("search", matching("{?q}"))
         | 
| 9 9 | 
             
                  #
         | 
| 10 10 | 
             
                  class TemplatedRelationMatcher
         | 
| 11 | 
            -
                     | 
| 11 | 
            +
                    include HalMatcherHelpers
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                    def initialize(link_rel, expected=NullMatcher)
         | 
| 12 14 | 
             
                      @link_rel = link_rel
         | 
| 13 15 | 
             
                      @expected = expected
         | 
| 14 16 | 
             
                    end
         | 
| @@ -37,15 +39,8 @@ module RSpec | |
| 37 39 | 
             
                                   else
         | 
| 38 40 | 
             
                                     "found none"
         | 
| 39 41 | 
             
                                   end
         | 
| 40 | 
            -
                      expected_clause = if expected != NullMatcher && expected.respond_to?(:description)
         | 
| 41 | 
            -
                                          expected.description
         | 
| 42 | 
            -
                                        elsif expected != NullMatcher
         | 
| 43 | 
            -
                                          "matching #{expected}"
         | 
| 44 | 
            -
                                        else
         | 
| 45 | 
            -
                                          "to exist"
         | 
| 46 | 
            -
                                        end
         | 
| 47 42 |  | 
| 48 | 
            -
                      "Expected templated `#{link_rel}` link  | 
| 43 | 
            +
                      sentencize "Expected templated `#{link_rel}` link", expected.description, "but #{but_clause}"
         | 
| 49 44 | 
             
                    end
         | 
| 50 45 | 
             
                    alias_method :failure_message_for_should, :failure_message
         | 
| 51 46 |  | 
| @@ -60,27 +55,7 @@ module RSpec | |
| 60 55 |  | 
| 61 56 | 
             
                    protected
         | 
| 62 57 |  | 
| 63 | 
            -
                    attr_reader :link_rel, :outcome
         | 
| 64 | 
            -
             | 
| 65 | 
            -
                    NullMatcher = ->(_url_template){ true }
         | 
| 66 | 
            -
             | 
| 67 | 
            -
                    def expected
         | 
| 68 | 
            -
                      @expected ||= NullMatcher
         | 
| 69 | 
            -
                    end
         | 
| 70 | 
            -
             | 
| 71 | 
            -
                    def parse(jsonish)
         | 
| 72 | 
            -
                      json = if jsonish.kind_of? String
         | 
| 73 | 
            -
                               jsonish
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                             elsif jsonish.respond_to? :to_hal
         | 
| 76 | 
            -
                               jsonish.to_hal
         | 
| 77 | 
            -
             | 
| 78 | 
            -
                             else jsonish.respond_to? :to_json
         | 
| 79 | 
            -
                               jsonish.to_json
         | 
| 80 | 
            -
                             end
         | 
| 81 | 
            -
             | 
| 82 | 
            -
                      HalClient::Representation.new(parsed_json: MultiJson.load(json))
         | 
| 83 | 
            -
                    end
         | 
| 58 | 
            +
                    attr_reader :link_rel, :outcome, :expected
         | 
| 84 59 | 
             
                  end
         | 
| 85 60 | 
             
                end
         | 
| 86 61 | 
             
              end
         | 
    
        data/lib/rspec/hal/version.rb
    CHANGED
    
    
| @@ -0,0 +1,126 @@ | |
| 1 | 
            +
            require_relative "../../../spec_helper"
         | 
| 2 | 
            +
            require "rspec/version"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe RSpec::Hal::Matchers::HavePropertyMatcher do
         | 
| 5 | 
            +
              describe "creation" do
         | 
| 6 | 
            +
                specify { expect{ described_class.new(a_prop_name) }.not_to raise_error }
         | 
| 7 | 
            +
                specify { expect{ described_class.new(a_prop_name, any_matcher) }.not_to raise_error }
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              subject(:matcher) { described_class.new(a_prop_name) }
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              specify { expect(matcher.matches?(json_str_w_property)).to be_truthy}
         | 
| 13 | 
            +
              specify { expect(matcher.matches?(json_str_wo_property)).to be_falsey}
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              specify { expect(matcher.matches?(parsed_json_w_property)).to be_truthy}
         | 
| 16 | 
            +
              specify { expect(matcher.matches?(parsed_json_wo_property)).to be_falsey}
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              specify { expect(matcher.matches?(to_halable_w_property)).to be_truthy}
         | 
| 19 | 
            +
              specify { expect(matcher.matches?(to_halable_wo_property)).to be_falsey}
         | 
| 20 | 
            +
             | 
| 21 | 
            +
             | 
| 22 | 
            +
              describe "value expectation set via #matching(regexp)" do
         | 
| 23 | 
            +
                subject(:matcher) {  described_class.new(a_prop_name).matching(/ice$/) }
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                specify { expect(matcher.description).to match /have property `name`/ }
         | 
| 26 | 
            +
                specify { expect(matcher.description).to match /match.*ice/ }
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                specify { expect(matcher.matches?(json_str_w_property)).to be_truthy}
         | 
| 29 | 
            +
                specify { expect(matcher.matches?(json_str_wo_property)).to be_falsey}
         | 
| 30 | 
            +
                specify { expect(matcher.matches?(json_str_w_nonmatching_property)).to be_falsey}
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              describe "value expectation set via #matching(another_matcher)" do
         | 
| 34 | 
            +
                subject(:matcher) { described_class.new(a_prop_name)
         | 
| 35 | 
            +
                    .matching(RSpec::Matchers::BuiltIn::EndWith.new("ice")) }
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                specify { expect(matcher.description).to match /have property `name`/ }
         | 
| 38 | 
            +
                specify { expect(matcher.description).to match /end with.*/ }
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                specify { expect(matcher.matches?(json_str_w_property)).to be_truthy}
         | 
| 41 | 
            +
                specify { expect(matcher.matches?(json_str_wo_property)).to be_falsey}
         | 
| 42 | 
            +
                specify { expect(matcher.matches?(json_str_w_nonmatching_property)).to be_falsey}
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              describe "value expectation set via #including(another_matcher)" do
         | 
| 46 | 
            +
                subject(:matcher) {  described_class.new('hobbies')
         | 
| 47 | 
            +
                    .including(RSpec::Matchers::BuiltIn::Include.new('type' => 'sport')) }
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                specify { expect(matcher.description).to match /have property `hobbies`/ }
         | 
| 50 | 
            +
                specify { expect(matcher.description).to match /include.*sport/ }
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                specify { expect(matcher.matches?(json_str_w_property)).to be_truthy}
         | 
| 53 | 
            +
                specify { expect(matcher.matches?(json_str_wo_property)).to be_falsey}
         | 
| 54 | 
            +
                specify { expect(matcher.matches?(json_str_w_nonmatching_property)).to be_falsey}
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              describe "value expectation set via #that_is(another_matcher)" do
         | 
| 58 | 
            +
                subject(:matcher) { described_class.new(a_prop_name)
         | 
| 59 | 
            +
                    .that_is(RSpec::Matchers::BuiltIn::EndWith.new("ice")) }
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                specify { expect(matcher.description).to match /have property `name`/ }
         | 
| 62 | 
            +
                specify { expect(matcher.description).to match /end with.*/ }
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                specify { expect(matcher.matches?(json_str_w_property)).to be_truthy}
         | 
| 65 | 
            +
                specify { expect(matcher.matches?(json_str_wo_property)).to be_falsey}
         | 
| 66 | 
            +
                specify { expect(matcher.matches?(json_str_w_nonmatching_property)).to be_falsey}
         | 
| 67 | 
            +
              end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
              describe "value expectation set via #that_is(exact_value)" do
         | 
| 70 | 
            +
                subject(:matcher) { described_class.new(a_prop_name)
         | 
| 71 | 
            +
                    .that_is("Alice") }
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                specify { expect(matcher.description).to match /have property `name`/ }
         | 
| 74 | 
            +
                specify { expect(matcher.description).to match /Alice/ }
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                specify { expect(matcher.matches?(json_str_w_property)).to be_truthy}
         | 
| 77 | 
            +
                specify { expect(matcher.matches?(json_str_wo_property)).to be_falsey}
         | 
| 78 | 
            +
                specify { expect(matcher.matches?(json_str_w_nonmatching_property)).to be_falsey}
         | 
| 79 | 
            +
              end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
             | 
| 82 | 
            +
              specify { expect(matcher.description).to match "have property `#{a_prop_name}`" }
         | 
| 83 | 
            +
             | 
| 84 | 
            +
             | 
| 85 | 
            +
             | 
| 86 | 
            +
              # Background
         | 
| 87 | 
            +
              # ---
         | 
| 88 | 
            +
             | 
| 89 | 
            +
              let(:json_str_w_property) { <<-HAL }
         | 
| 90 | 
            +
                { "name": "Alice"
         | 
| 91 | 
            +
                  ,"hobbies": [{"name": "soccer", "type": "sport"}]
         | 
| 92 | 
            +
                }
         | 
| 93 | 
            +
              HAL
         | 
| 94 | 
            +
             | 
| 95 | 
            +
              let(:json_str_wo_property) { <<-HAL }
         | 
| 96 | 
            +
                { }
         | 
| 97 | 
            +
              HAL
         | 
| 98 | 
            +
             | 
| 99 | 
            +
              let(:json_str_w_nonmatching_property) { <<-HAL }
         | 
| 100 | 
            +
                { "name": "Bob"
         | 
| 101 | 
            +
                  ,"hobbies": [{"name": "trumpet", "type": "music"}] }
         | 
| 102 | 
            +
              HAL
         | 
| 103 | 
            +
             | 
| 104 | 
            +
             | 
| 105 | 
            +
              let(:parsed_json_w_property) { MultiJson.load json_str_w_property }
         | 
| 106 | 
            +
              let(:parsed_json_wo_property) { MultiJson.load json_str_wo_property }
         | 
| 107 | 
            +
             | 
| 108 | 
            +
              let(:to_halable_w_property) { halable.new json_str_w_property}
         | 
| 109 | 
            +
              let(:to_halable_wo_property) { halable.new json_str_wo_property }
         | 
| 110 | 
            +
             | 
| 111 | 
            +
              let(:halable) { Class.new do
         | 
| 112 | 
            +
                  def initialize(json)
         | 
| 113 | 
            +
                    @json = json
         | 
| 114 | 
            +
                  end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                  def to_hal
         | 
| 117 | 
            +
                    return @json
         | 
| 118 | 
            +
                  end
         | 
| 119 | 
            +
                end }
         | 
| 120 | 
            +
             | 
| 121 | 
            +
              let(:a_prop_name) { "name" }
         | 
| 122 | 
            +
             | 
| 123 | 
            +
              let(:any_matcher) { matching_prop_value_matcher }
         | 
| 124 | 
            +
              let(:matching_prop_value_matcher) { match "Alice" }
         | 
| 125 | 
            +
              # let(:nonmatching_template_str_matcher) { match "hello" }
         | 
| 126 | 
            +
            end
         | 
| @@ -0,0 +1,173 @@ | |
| 1 | 
            +
            require_relative "../../../spec_helper"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe RSpec::Hal::Matchers::RelationMatcher do
         | 
| 4 | 
            +
              describe "creation" do
         | 
| 5 | 
            +
                specify { expect{ described_class.new(a_link_rel) }.not_to raise_error }
         | 
| 6 | 
            +
                specify { expect{ described_class.new(a_link_rel, any_href_matcher) }.not_to raise_error }
         | 
| 7 | 
            +
                specify { expect{ described_class.new(a_link_rel, template_variables, any_href_matcher) }
         | 
| 8 | 
            +
                    .not_to raise_error }
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              subject(:matcher) { described_class.new(a_link_rel) }
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              specify{ expect(matcher.matches?(json_str_w_link)).to be_truthy }
         | 
| 14 | 
            +
              specify{ expect(matcher.matches?(json_str_wo_link)).to be_falsey }
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              context "curries" do
         | 
| 17 | 
            +
                let(:a_link_rel) { "http://example.com/rels/foo" }
         | 
| 18 | 
            +
                specify{ expect(matcher.matches?(json_str_w_curied_link)).to be_truthy }
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                context "trying to match unexpanded rel" do
         | 
| 21 | 
            +
                  let(:a_link_rel) { "ex:foo" }
         | 
| 22 | 
            +
                  specify{ expect(matcher.matches? json_str_w_curied_link).to be_falsey }
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              context "templated links" do
         | 
| 27 | 
            +
                subject(:matcher) { described_class.new(a_link_rel, which: "mother") }
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                specify{ expect(matcher.matches? json_str_w_templated_link).to be_truthy }
         | 
| 30 | 
            +
                specify{ expect(matcher.matches? json_str_w_link).to be_truthy }
         | 
| 31 | 
            +
                specify{ expect(matcher.matches? json_str_wo_link).to be_falsey }
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              context "templated links with href matcher" do
         | 
| 35 | 
            +
                subject(:matcher) { described_class.new(a_link_rel, {which: "mother"}, match(/parent/)) }
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                specify{ expect(matcher.matches? json_str_w_templated_link).to be_truthy }
         | 
| 38 | 
            +
                specify{ expect(matcher.matches? json_str_w_link).to be_truthy }
         | 
| 39 | 
            +
                specify{ expect(matcher.matches? json_str_wo_link).to be_falsey }
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
              specify{ expect(matcher.matches?(parsed_json_w_link)).to be_truthy }
         | 
| 43 | 
            +
              specify{ expect(matcher.matches?(parsed_json_wo_link)).to be_falsey }
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              specify{ expect(matcher.matches?(to_halable_w_link)).to be_truthy }
         | 
| 46 | 
            +
              specify{ expect(matcher.matches?(to_halable_wo_link)).to be_falsey }
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              specify { expect(matcher.description).to match "have #{a_link_rel} link" }
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              context "exact expected href specified via #with_href" do
         | 
| 51 | 
            +
                subject(:matcher) { described_class.new(a_link_rel)
         | 
| 52 | 
            +
                    .with_href("http://example.com/parent") }
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                specify{ expect(matcher.matches? json_str_w_link).to be_truthy }
         | 
| 55 | 
            +
                specify{ expect(matcher.matches? json_str_wo_link).to be_falsey }
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
              context "regexp expected href specified via #with_href" do
         | 
| 59 | 
            +
                subject(:matcher) { described_class.new(a_link_rel)
         | 
| 60 | 
            +
                    .with_href(%r(/parent)) }
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                specify{ expect(matcher.matches? json_str_w_link).to be_truthy }
         | 
| 63 | 
            +
                specify{ expect(matcher.matches? json_str_wo_link).to be_falsey }
         | 
| 64 | 
            +
              end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
              context "matcher for expected href specified via #with_href" do
         | 
| 67 | 
            +
                subject(:matcher) { described_class.new(a_link_rel)
         | 
| 68 | 
            +
                    .with_href(end_with("parent")) }
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                specify{ expect(matcher.matches? json_str_w_link).to be_truthy }
         | 
| 71 | 
            +
                specify{ expect(matcher.matches? json_str_wo_link).to be_falsey }
         | 
| 72 | 
            +
              end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
              context "non-matching expected href specified via #with_href" do
         | 
| 75 | 
            +
                subject(:matcher) { described_class.new(a_link_rel)
         | 
| 76 | 
            +
                    .with_href("Malory") }
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                specify{ expect(matcher.matches? json_str_w_link).to be_falsy }
         | 
| 79 | 
            +
              end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
             | 
| 82 | 
            +
              context "failed due to missing relation matcher" do
         | 
| 83 | 
            +
                before do
         | 
| 84 | 
            +
                  matcher.matches? json_str_wo_link
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                specify { expect(matcher.failure_message)
         | 
| 88 | 
            +
                    .to match "Expected `#{a_link_rel}` link or embedded but found none" }
         | 
| 89 | 
            +
                specify { expect(matcher.failure_message_for_should)
         | 
| 90 | 
            +
                    .to match matcher.failure_message }
         | 
| 91 | 
            +
              end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
              context "failed due to unexpected existing relation" do
         | 
| 94 | 
            +
                before do
         | 
| 95 | 
            +
                  matcher.matches? json_str_w_link
         | 
| 96 | 
            +
                end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                specify { expect(matcher.failure_message_when_negated)
         | 
| 99 | 
            +
                    .to match "Expected `#{a_link_rel}` link to be absent" }
         | 
| 100 | 
            +
                specify { expect(matcher.failure_message_for_should_not)
         | 
| 101 | 
            +
                    .to match matcher.failure_message_when_negated }
         | 
| 102 | 
            +
              end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
              context "failed due to sub-matcher failure matcher" do
         | 
| 105 | 
            +
                subject(:matcher) { described_class.new(a_link_rel, match("absent")) }
         | 
| 106 | 
            +
                before do
         | 
| 107 | 
            +
                  matcher.matches? json_str_wo_link
         | 
| 108 | 
            +
                end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                specify { expect(matcher.failure_message)
         | 
| 111 | 
            +
                    .to match %r(Expected `#{a_link_rel}` link or embedded match(?:ing)? "absent" but found none) }
         | 
| 112 | 
            +
              end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
             | 
| 115 | 
            +
              # Background
         | 
| 116 | 
            +
              # ---
         | 
| 117 | 
            +
             | 
| 118 | 
            +
              let(:json_str_w_link) { <<-HAL }
         | 
| 119 | 
            +
                { "_links": {
         | 
| 120 | 
            +
                  "up": {"href": "http://example.com/parent"}
         | 
| 121 | 
            +
                }}
         | 
| 122 | 
            +
              HAL
         | 
| 123 | 
            +
             | 
| 124 | 
            +
              let(:json_str_wo_link) { <<-HAL }
         | 
| 125 | 
            +
                { "_links": {
         | 
| 126 | 
            +
                }}
         | 
| 127 | 
            +
              HAL
         | 
| 128 | 
            +
             | 
| 129 | 
            +
              let(:json_str_w_curied_link) { <<-HAL }
         | 
| 130 | 
            +
                { "_links": {
         | 
| 131 | 
            +
                  "ex:foo": {"href": "http://example.com/parent"},
         | 
| 132 | 
            +
                  "curies": [
         | 
| 133 | 
            +
                    {"name": "ex", "href": "http://example.com/rels/{rel}", "templated": true }
         | 
| 134 | 
            +
                  ]
         | 
| 135 | 
            +
                }}
         | 
| 136 | 
            +
              HAL
         | 
| 137 | 
            +
             | 
| 138 | 
            +
              let(:json_str_w_templated_link) { <<-HAL }
         | 
| 139 | 
            +
                { "_links": {
         | 
| 140 | 
            +
                  "up": {"href": "http://example.com/parent{?which}", "templated": true}
         | 
| 141 | 
            +
                }}
         | 
| 142 | 
            +
              HAL
         | 
| 143 | 
            +
             | 
| 144 | 
            +
             | 
| 145 | 
            +
              # let(:json_str_w_nontemplate_link) { <<-HAL }
         | 
| 146 | 
            +
              #   { "_links": {
         | 
| 147 | 
            +
              #     "up": {"href": "http://example.com/parent"}
         | 
| 148 | 
            +
              #   }}
         | 
| 149 | 
            +
              # HAL
         | 
| 150 | 
            +
             | 
| 151 | 
            +
             | 
| 152 | 
            +
              let(:parsed_json_w_link) { MultiJson.load json_str_w_link }
         | 
| 153 | 
            +
              let(:parsed_json_wo_link) { MultiJson.load json_str_wo_link }
         | 
| 154 | 
            +
             | 
| 155 | 
            +
              let(:to_halable_w_link) { halable.new json_str_w_link}
         | 
| 156 | 
            +
              let(:to_halable_wo_link) { halable.new json_str_wo_link }
         | 
| 157 | 
            +
             | 
| 158 | 
            +
              let(:halable) { Class.new do
         | 
| 159 | 
            +
                  def initialize(json)
         | 
| 160 | 
            +
                    @json = json
         | 
| 161 | 
            +
                  end
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                  def to_hal
         | 
| 164 | 
            +
                    return @json
         | 
| 165 | 
            +
                  end
         | 
| 166 | 
            +
                end }
         | 
| 167 | 
            +
             | 
| 168 | 
            +
              let(:a_link_rel) { "up" }
         | 
| 169 | 
            +
              let(:any_href_matcher) { matching_href_matcher }
         | 
| 170 | 
            +
              let(:matching_href_matcher) { match /example.com/ }
         | 
| 171 | 
            +
              let(:nonmatching_href_matcher) { match "hello" }
         | 
| 172 | 
            +
              let(:template_variables) { {q: "search terms"} }
         | 
| 173 | 
            +
            end
         | 
| @@ -28,7 +28,7 @@ describe RSpec::Hal::Matchers::TemplatedRelationMatcher do | |
| 28 28 | 
             
                end
         | 
| 29 29 |  | 
| 30 30 | 
             
                specify { expect(matcher.failure_message)
         | 
| 31 | 
            -
                    .to match "Expected templated `#{a_link_rel}` link  | 
| 31 | 
            +
                    .to match "Expected templated `#{a_link_rel}` link but found none" }
         | 
| 32 32 | 
             
                specify { expect(matcher.failure_message_for_should)
         | 
| 33 33 | 
             
                    .to match matcher.failure_message }
         | 
| 34 34 | 
             
              end
         | 
| @@ -50,17 +50,17 @@ describe RSpec::Hal::Matchers::TemplatedRelationMatcher do | |
| 50 50 | 
             
                end
         | 
| 51 51 |  | 
| 52 52 | 
             
                specify { expect(matcher.failure_message)
         | 
| 53 | 
            -
                    .to match "Expected templated `#{a_link_rel}` link  | 
| 53 | 
            +
                    .to match "Expected templated `#{a_link_rel}` link but found only non-templated links" }
         | 
| 54 54 | 
             
              end
         | 
| 55 55 |  | 
| 56 56 | 
             
              context "failed due to sub-matcher failure matcher" do
         | 
| 57 | 
            -
                subject(:matcher) { described_class.new(a_link_rel,  | 
| 57 | 
            +
                subject(:matcher) { described_class.new(a_link_rel, match("absent")) }
         | 
| 58 58 | 
             
                before do
         | 
| 59 59 | 
             
                  matcher.matches? json_str_wo_link
         | 
| 60 60 | 
             
                end
         | 
| 61 61 |  | 
| 62 62 | 
             
                specify { expect(matcher.failure_message)
         | 
| 63 | 
            -
                    .to match %(Expected templated `#{a_link_rel}` link  | 
| 63 | 
            +
                    .to match %r(Expected templated `#{a_link_rel}` link match(?:ing)? "absent" but found none) }
         | 
| 64 64 | 
             
              end
         | 
| 65 65 |  | 
| 66 66 |  | 
| @@ -17,7 +17,7 @@ describe RSpec::Hal::Matchers do | |
| 17 17 |  | 
| 18 18 | 
             
              matcher :be_a_matcher do
         | 
| 19 19 | 
             
                match do |actual|
         | 
| 20 | 
            -
                  respond_to?(:matches?) && respond_to?(:failure_message)
         | 
| 20 | 
            +
                  actual.respond_to?(:matches?) && actual.respond_to?(:failure_message)
         | 
| 21 21 | 
             
                end
         | 
| 22 22 | 
             
              end
         | 
| 23 23 | 
             
            end
         | 
| @@ -38,50 +38,6 @@ describe RSpec::Hal::Matchers::Document do | |
| 38 38 | 
             
                specify { expect(matcher.matches?(hal_doc)).to be_falsey }
         | 
| 39 39 | 
             
              end
         | 
| 40 40 |  | 
| 41 | 
            -
              describe "have_property('name')" do
         | 
| 42 | 
            -
                subject(:matcher) { have_property('name') }
         | 
| 43 | 
            -
             | 
| 44 | 
            -
                specify { expect(matcher.matches?(hal_doc)).to be_truthy}
         | 
| 45 | 
            -
                specify { expect(matcher.matches?("{}")).to be_falsey}
         | 
| 46 | 
            -
              end
         | 
| 47 | 
            -
             | 
| 48 | 
            -
              describe "have_property('name').matching(/ice$/)" do
         | 
| 49 | 
            -
                subject(:matcher) { have_property('name').matching(/ice$/) }
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                specify { expect(matcher.matches?(hal_doc)).to be_truthy}
         | 
| 52 | 
            -
                specify { expect(matcher.matches?("{}")).to be_falsey}
         | 
| 53 | 
            -
                specify { expect(matcher.matches?(bob)).to be_falsey}
         | 
| 54 | 
            -
              end
         | 
| 55 | 
            -
             | 
| 56 | 
            -
              describe "have_property('name').matching(end_with('ice'))" do
         | 
| 57 | 
            -
                before do skip("RSpec 3 feature") unless /3\./ === RSpec::Version::STRING end
         | 
| 58 | 
            -
                subject(:matcher) { have_property('name')
         | 
| 59 | 
            -
                    .matching(RSpec::Matchers::BuiltIn::EndWith.new("ice")) }
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                specify { expect(matcher.matches?(hal_doc)).to be_truthy}
         | 
| 62 | 
            -
                specify { expect(matcher.matches?("{}")).to be_falsey}
         | 
| 63 | 
            -
                specify { expect(matcher.matches?(bob)).to be_falsey}
         | 
| 64 | 
            -
              end
         | 
| 65 | 
            -
             | 
| 66 | 
            -
              describe "have_property('hobbies').including(a_hash_including('type' => 'sport'))" do
         | 
| 67 | 
            -
                subject(:matcher) { have_property('hobbies')
         | 
| 68 | 
            -
                    .including(RSpec::Matchers::BuiltIn::Include.new('type' => 'sport')) }
         | 
| 69 | 
            -
                before do extend described_class end
         | 
| 70 | 
            -
             | 
| 71 | 
            -
                specify { expect(matcher.matches?(hal_doc)).to be_truthy}
         | 
| 72 | 
            -
                specify { expect(matcher.matches?("{}")).to be_falsey}
         | 
| 73 | 
            -
                specify { expect(matcher.matches?(bob)).to be_falsey}
         | 
| 74 | 
            -
              end
         | 
| 75 | 
            -
             | 
| 76 | 
            -
              describe "have_relation('tag')" do
         | 
| 77 | 
            -
                subject(:matcher) { have_relation('tag') }
         | 
| 78 | 
            -
             | 
| 79 | 
            -
                specify { expect(matcher.matches?(hal_doc)).to be_truthy}
         | 
| 80 | 
            -
                specify { expect(matcher.matches?("{}")).to be_falsey}
         | 
| 81 | 
            -
                specify { expect(matcher.matches?(bob)).to be_falsey}
         | 
| 82 | 
            -
              end
         | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 85 41 | 
             
              before do
         | 
| 86 42 | 
             
                extend RSpec::Hal::Matchers::Document
         | 
| 87 43 | 
             
              end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: rspec-hal
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.2. | 
| 4 | 
            +
              version: 1.2.1
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Peter Williams
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2014-04- | 
| 11 | 
            +
            date: 2014-04-03 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         | 
| @@ -88,9 +88,14 @@ files: | |
| 88 88 | 
             
            - lib/rspec-hal.rb
         | 
| 89 89 | 
             
            - lib/rspec/hal.rb
         | 
| 90 90 | 
             
            - lib/rspec/hal/matchers.rb
         | 
| 91 | 
            +
            - lib/rspec/hal/matchers/hal_matcher_helpers.rb
         | 
| 92 | 
            +
            - lib/rspec/hal/matchers/have_property_matcher.rb
         | 
| 93 | 
            +
            - lib/rspec/hal/matchers/relation_matcher.rb
         | 
| 91 94 | 
             
            - lib/rspec/hal/matchers/templated_relation_matcher.rb
         | 
| 92 95 | 
             
            - lib/rspec/hal/version.rb
         | 
| 93 96 | 
             
            - rspec-hal.gemspec
         | 
| 97 | 
            +
            - spec/rspec/hal/matchers/have_property_matcher_spec.rb
         | 
| 98 | 
            +
            - spec/rspec/hal/matchers/relation_matcher_spec.rb
         | 
| 94 99 | 
             
            - spec/rspec/hal/matchers/templated_relation_matcher_spec.rb
         | 
| 95 100 | 
             
            - spec/rspec/hal/matchers_spec.rb
         | 
| 96 101 | 
             
            - spec/spec_helper.rb
         | 
| @@ -119,6 +124,8 @@ signing_key: | |
| 119 124 | 
             
            specification_version: 4
         | 
| 120 125 | 
             
            summary: Matchers and helpers for specing HAL documents.
         | 
| 121 126 | 
             
            test_files:
         | 
| 127 | 
            +
            - spec/rspec/hal/matchers/have_property_matcher_spec.rb
         | 
| 128 | 
            +
            - spec/rspec/hal/matchers/relation_matcher_spec.rb
         | 
| 122 129 | 
             
            - spec/rspec/hal/matchers/templated_relation_matcher_spec.rb
         | 
| 123 130 | 
             
            - spec/rspec/hal/matchers_spec.rb
         | 
| 124 131 | 
             
            - spec/spec_helper.rb
         |