rspec-api-matchers 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/README.md +10 -3
 - data/lib/rspec-api/dsl/be_a_jsonp.rb +24 -0
 - data/lib/rspec-api/dsl/be_filtered.rb +24 -0
 - data/lib/rspec-api/dsl/be_sorted.rb +24 -0
 - data/lib/rspec-api/dsl/be_valid_json.rb +29 -0
 - data/lib/rspec-api/dsl/have_attributes.rb +37 -0
 - data/lib/rspec-api/dsl/have_prev_page_link.rb +20 -0
 - data/lib/rspec-api/dsl/have_status.rb +20 -0
 - data/lib/rspec-api/dsl/include_content_type.rb +23 -0
 - data/lib/rspec-api/dsl/run_if.rb +24 -0
 - data/lib/rspec-api/matchers.rb +28 -3
 - data/lib/rspec-api/matchers/attributes.rb +171 -0
 - data/lib/rspec-api/matchers/content_type.rb +30 -0
 - data/lib/rspec-api/matchers/filter.rb +54 -0
 - data/lib/rspec-api/matchers/json.rb +46 -0
 - data/lib/rspec-api/matchers/jsonp.rb +27 -0
 - data/lib/rspec-api/matchers/prev_page_link.rb +27 -0
 - data/lib/rspec-api/matchers/run_if.rb +39 -0
 - data/lib/rspec-api/matchers/sort.rb +65 -0
 - data/lib/rspec-api/matchers/{match_status.rb → status.rb} +11 -11
 - data/lib/rspec-api/matchers/version.rb +1 -1
 - metadata +34 -4
 - data/lib/rspec-api/matchers/matchers.rb +0 -26
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 480e18da2657efd7c3645a753ce1cc105c8bd4d4
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: fb4600f19714aa5eb6f0a49b4e45bcc05be3d1ca
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: dfc14d736db8c6d4f9c059d32ab0012c579c585a2b903ae2cf8920211be1ed95f5b42c07e4d56a710c8357df97d50fb7539ee8ea97d05bc030f2c8846adca79b
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 12d82522d32fb0154b6e5e7c20464a2c01e47b4adb863a2475db3aa0ca8a584db430afb1ba84556240b8ab76398bf2b1a911f88d9b2196578f5a42137e7850a7
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -3,11 +3,11 @@ RSpec API Matchers 
     | 
|
| 
       3 
3 
     | 
    
         | 
| 
       4 
4 
     | 
    
         
             
            RSpecApi::Matchers lets you express outcomes on the response of web APIs.
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
                expect( 
     | 
| 
      
 6 
     | 
    
         
            +
                expect(response).to have_status(:not_found)
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
            More documentation and examples about RSpec Api are available at [http://rspec-api.github.io](http://rspec-api.github.io)
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
            [](https://travis-ci.org/rspec-api/rspec-api-matchers)
         
     | 
| 
      
 10 
     | 
    
         
            +
            [](https://travis-ci.org/rspec-api/rspec-api-matchers)
         
     | 
| 
       11 
11 
     | 
    
         
             
            [](https://codeclimate.com/github/rspec-api/rspec-api-matchers)
         
     | 
| 
       12 
12 
     | 
    
         
             
            [](https://coveralls.io/r/rspec-api/rspec-api-matchers)
         
     | 
| 
       13 
13 
     | 
    
         
             
            [](https://gemnasium.com/rspec-api/rspec-api-matchers)
         
     | 
| 
         @@ -21,7 +21,14 @@ Or install yourself by running `gem install rspec-api-matchers`. 
     | 
|
| 
       21 
21 
     | 
    
         
             
            Available matchers
         
     | 
| 
       22 
22 
     | 
    
         
             
            ------------------
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
                expect( 
     | 
| 
      
 24 
     | 
    
         
            +
                expect(response).to have_status(:ok)
         
     | 
| 
      
 25 
     | 
    
         
            +
                expect(response).to include_content_type(:json)
         
     | 
| 
      
 26 
     | 
    
         
            +
                expect(response).to have_prev_page_link
         
     | 
| 
      
 27 
     | 
    
         
            +
                expect(response).to be_valid_json(Array)
         
     | 
| 
      
 28 
     | 
    
         
            +
                expect(response).to be_a_jsonp('alert')
         
     | 
| 
      
 29 
     | 
    
         
            +
                expect(response).to be_sorted(by: :id, verse: :desc)
         
     | 
| 
      
 30 
     | 
    
         
            +
                expect(response).to be_filtered(10, by: :id)
         
     | 
| 
      
 31 
     | 
    
         
            +
                expect(response).to have_attributes(id: {value: 1.2}, url: {type: {string: :url}})
         
     | 
| 
       25 
32 
     | 
    
         | 
| 
       26 
33 
     | 
    
         
             
            How to contribute
         
     | 
| 
       27 
34 
     | 
    
         
             
            =================
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rspec-api/matchers/jsonp'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RSpecApi
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 5 
     | 
    
         
            +
                # Convert RSpecAPI::Matchers classes into RSpec-compatible matchers, e.g.:
         
     | 
| 
      
 6 
     | 
    
         
            +
                # makes RSpecApi::Matchers::Status available as expect(...).to match_status
         
     | 
| 
      
 7 
     | 
    
         
            +
                module DSL
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # Passes if response body is in JSONP format
         
     | 
| 
      
 9 
     | 
    
         
            +
                  #
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # @note
         
     | 
| 
      
 11 
     | 
    
         
            +
                  #
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # A JSONP should actually return application/javascript...
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #
         
     | 
| 
      
 14 
     | 
    
         
            +
                  # @example
         
     | 
| 
      
 15 
     | 
    
         
            +
                  #
         
     | 
| 
      
 16 
     | 
    
         
            +
                  #   # Passes if the body is a JSON wrapped in a callback
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #   body = 'alert([{"website":"http://www.example.com","flag":null}])'
         
     | 
| 
      
 18 
     | 
    
         
            +
                  #   expect(OpenStruct.new body: body).to be_a_jsonp(:alert)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  def be_a_jsonp(callback = nil)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    RSpecApi::Matchers::Jsonp.new(callback)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rspec-api/matchers/filter'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RSpecApi
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 5 
     | 
    
         
            +
                # Convert RSpecAPI::Matchers classes into RSpec-compatible matchers, e.g.:
         
     | 
| 
      
 6 
     | 
    
         
            +
                # makes RSpecApi::Matchers::Status available as expect(...).to match_status
         
     | 
| 
      
 7 
     | 
    
         
            +
                module DSL
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # Passes if response body is filtered by +options[:by]+ comparing with +options[:comparing_with]+
         
     | 
| 
      
 9 
     | 
    
         
            +
                  #
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # @example
         
     | 
| 
      
 11 
     | 
    
         
            +
                  #
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #   # Passes if the body only contains ID = 1
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #   body = '[{"id": 1}, {"id": 1}, {"id": 1}]'
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #   expect(OpenStruct.new body: body).to be_filtered(1, by: :id)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  #
         
     | 
| 
      
 16 
     | 
    
         
            +
                  #   # Passes if the body only contains ID < 10
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #   body = '[{"id": 1}, {"id": 6}, {"id": 3}]'
         
     | 
| 
      
 18 
     | 
    
         
            +
                  #   expect(OpenStruct.new body: body).to be_filtered(10, by: :id, comparing_with: :<)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  def be_filtered(value = nil, options = {})
         
     | 
| 
      
 20 
     | 
    
         
            +
                    RSpecApi::Matchers::Filter.new value, options
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rspec-api/matchers/sort'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RSpecApi
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 5 
     | 
    
         
            +
                # Convert RSpecAPI::Matchers classes into RSpec-compatible matchers, e.g.:
         
     | 
| 
      
 6 
     | 
    
         
            +
                # makes RSpecApi::Matchers::Status available as expect(...).to match_status
         
     | 
| 
      
 7 
     | 
    
         
            +
                module DSL
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # Passes if response body is sorted by +options[:by]+ with +options[:verse]+
         
     | 
| 
      
 9 
     | 
    
         
            +
                  #
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # @example
         
     | 
| 
      
 11 
     | 
    
         
            +
                  #
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #   # Passes if the body is sorted by ascending IDs
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #   body = '[{"id": 1}, {"id": 2}, {"id": 3}]'
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #   expect(OpenStruct.new body: body).to be_sorted(by: :id)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  #
         
     | 
| 
      
 16 
     | 
    
         
            +
                  #   # Passes if the body is sorted by descending timestamps
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #   body = '[{"t": "2013-10-29T18:09:43Z"}, {"t": "2009-01-12T18:09:43Z"}]'
         
     | 
| 
      
 18 
     | 
    
         
            +
                  #   expect(OpenStruct.new body: body).to be_sorted(by: :t, verse: :desc)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  def be_sorted(options = {})
         
     | 
| 
      
 20 
     | 
    
         
            +
                    RSpecApi::Matchers::Sort.new options
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,29 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rspec-api/matchers/json'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RSpecApi
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 5 
     | 
    
         
            +
                # Convert RSpecAPI::Matchers classes into RSpec-compatible matchers, e.g.:
         
     | 
| 
      
 6 
     | 
    
         
            +
                # makes RSpecApi::Matchers::Status available as expect(...).to match_status
         
     | 
| 
      
 7 
     | 
    
         
            +
                module DSL
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # Passes if response body is JSON. Optionally check if Array or Hash.
         
     | 
| 
      
 9 
     | 
    
         
            +
                  # Skips if  if response body is JSON. Optionally check if Array or Hash.
         
     | 
| 
      
 10 
     | 
    
         
            +
                  #
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # @example
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #   # Passes if the body is valid JSON
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #   body = '{"id": 1}'
         
     | 
| 
      
 15 
     | 
    
         
            +
                  #   expect(OpenStruct.new body: body).to be_valid_json
         
     | 
| 
      
 16 
     | 
    
         
            +
                  #
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #   # Passes if the body is a valid JSON-marshalled Hash
         
     | 
| 
      
 18 
     | 
    
         
            +
                  #   body = '{"id": 1}'
         
     | 
| 
      
 19 
     | 
    
         
            +
                  #   expect(OpenStruct.new body: body).to be_valid_json(Hash)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  #
         
     | 
| 
      
 21 
     | 
    
         
            +
                  #   # Passes if the body is a valid JSON-marshalled Array
         
     | 
| 
      
 22 
     | 
    
         
            +
                  #   body = '[{"id": 1}, {"id": 2}]'
         
     | 
| 
      
 23 
     | 
    
         
            +
                  #   expect(OpenStruct.new body: body).to be_valid_json(Array)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  def be_valid_json(type = nil)
         
     | 
| 
      
 25 
     | 
    
         
            +
                    RSpecApi::Matchers::Json.new(type)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,37 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rspec-api/matchers/attributes'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RSpecApi
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 5 
     | 
    
         
            +
                # Convert RSpecAPI::Matchers classes into RSpec-compatible matchers, e.g.:
         
     | 
| 
      
 6 
     | 
    
         
            +
                # makes RSpecApi::Matchers::Status available as expect(...).to match_status
         
     | 
| 
      
 7 
     | 
    
         
            +
                module DSL
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # Passes if response body is an object or array of objects with +key+.
         
     | 
| 
      
 9 
     | 
    
         
            +
                  #
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # @example
         
     | 
| 
      
 11 
     | 
    
         
            +
                  #
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #   # Passes if the body is an object with key :id
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #   body = '{"id": 1, "url": "http://www.example.com"}'
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #   expect(OpenStruct.new body: body).to have_attributes(:id)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  #
         
     | 
| 
      
 16 
     | 
    
         
            +
                  #   # Passes if the body is an object with key :id and value 1
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #   body = '{"id": 1, "url": "http://www.example.com"}'
         
     | 
| 
      
 18 
     | 
    
         
            +
                  #   expect(OpenStruct.new body: body).to have_attributes(id: {value: 1})
         
     | 
| 
      
 19 
     | 
    
         
            +
                  #
         
     | 
| 
      
 20 
     | 
    
         
            +
                  #   # Passes if the body is an array of objects, all with key :id
         
     | 
| 
      
 21 
     | 
    
         
            +
                  #   body = '{"id": 1, "name": ""}, {"id": 2}]'
         
     | 
| 
      
 22 
     | 
    
         
            +
                  #   expect(OpenStruct.new body: body).to have_attributes(:id)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  #
         
     | 
| 
      
 24 
     | 
    
         
            +
                  #   # Passes if the body is an array of object with key :id and odd values
         
     | 
| 
      
 25 
     | 
    
         
            +
                  #   body = '{"id": 1, "name": ""}, {"id": 3}], {"id": 5}]'
         
     | 
| 
      
 26 
     | 
    
         
            +
                  #   expect(OpenStruct.new body: body).to have_attributes(id: {value: -> v {v.odd?}})
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                  # TODO: add &block options
         
     | 
| 
      
 29 
     | 
    
         
            +
                  def have_attributes(attributes = {})
         
     | 
| 
      
 30 
     | 
    
         
            +
                    RSpecApi::Matchers::Attributes.new attributes
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
                  # alias have_attribute have_attributes
         
     | 
| 
      
 33 
     | 
    
         
            +
                  # alias have_keys have_attributes
         
     | 
| 
      
 34 
     | 
    
         
            +
                  # alias have_key have_attributes
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rspec-api/matchers/prev_page_link'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RSpecApi
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 5 
     | 
    
         
            +
                # Convert RSpecAPI::Matchers classes into RSpec-compatible matchers, e.g.:
         
     | 
| 
      
 6 
     | 
    
         
            +
                # makes RSpecApi::Matchers::Status available as expect(...).to match_status
         
     | 
| 
      
 7 
     | 
    
         
            +
                module DSL
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # Passes if response includes the pagination Link rel=prev in the headers
         
     | 
| 
      
 9 
     | 
    
         
            +
                  #
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # @example
         
     | 
| 
      
 11 
     | 
    
         
            +
                  #
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #   # Passes if the headers specify the pagination link for Prev
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #   headers = {'Link' => '<https://example.com/1>; rel="prev"'}
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #   expect(OpenStruct.new headers: headers).to have_prev_page_link
         
     | 
| 
      
 15 
     | 
    
         
            +
                  def have_prev_page_link
         
     | 
| 
      
 16 
     | 
    
         
            +
                    RSpecApi::Matchers::PrevPageLink.new
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rspec-api/matchers/status'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RSpecApi
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 5 
     | 
    
         
            +
                module DSL
         
     | 
| 
      
 6 
     | 
    
         
            +
                  # Passes if response has the given HTTP status code.
         
     | 
| 
      
 7 
     | 
    
         
            +
                  #
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # @example
         
     | 
| 
      
 9 
     | 
    
         
            +
                  #
         
     | 
| 
      
 10 
     | 
    
         
            +
                  #   # Passes if the status is 200 OK (passed as a symbol)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  #   expect(OpenStruct.new status: 200).to match_status :ok
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #   # Passes if the status is 200 OK (passed as a number)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #   expect(OpenStruct.new status: 200).to match_status 200
         
     | 
| 
      
 15 
     | 
    
         
            +
                  def have_status(status)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    RSpecApi::Matchers::Status.new status
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rspec-api/matchers/content_type'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RSpecApi
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 5 
     | 
    
         
            +
                # Convert RSpecAPI::Matchers classes into RSpec-compatible matchers, e.g.:
         
     | 
| 
      
 6 
     | 
    
         
            +
                # makes RSpecApi::Matchers::Status available as expect(...).to match_status
         
     | 
| 
      
 7 
     | 
    
         
            +
                module DSL
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # Passes if response includes the given Content-Type JSON in the headers
         
     | 
| 
      
 9 
     | 
    
         
            +
                  #
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # @example
         
     | 
| 
      
 11 
     | 
    
         
            +
                  #
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #   # Passes if the headers specify that Content-Type is JSON
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #   headers ={'Content-Type' => 'application/json; charset=utf-8'}
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #   expect(OpenStruct.new headers: headers).to include_content_type(:json)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  def include_content_type(type = nil)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    content_type = case type
         
     | 
| 
      
 17 
     | 
    
         
            +
                    when :json then 'application/json; charset=utf-8'
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
                    RSpecApi::Matchers::ContentType.new(content_type)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rspec-api/matchers/run_if'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RSpecApi
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 5 
     | 
    
         
            +
                module DSL
         
     | 
| 
      
 6 
     | 
    
         
            +
                  # Creates a +method_name+_if method for each DSL method
         
     | 
| 
      
 7 
     | 
    
         
            +
                  #
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # @example
         
     | 
| 
      
 9 
     | 
    
         
            +
                  #
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # def have_prev_page_link_if(condition, *args)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  #   RSpecApi::Matchers::RunIf.new condition, have_prev_page_link(*args)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # end
         
     | 
| 
      
 13 
     | 
    
         
            +
                  RSpecApi::Matchers::DSL.instance_methods.each do |method|
         
     | 
| 
      
 14 
     | 
    
         
            +
                    define_method("#{method}_if") do |condition, *args|
         
     | 
| 
      
 15 
     | 
    
         
            +
                      run_if condition, send(method, *args)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    end
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  def run_if(run, matcher)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    RSpecApi::Matchers::RunIf.new run, matcher
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/rspec-api/matchers.rb
    CHANGED
    
    | 
         @@ -1,3 +1,28 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'rspec-api/ 
     | 
| 
       2 
     | 
    
         
            -
            require 'rspec-api/ 
     | 
| 
       3 
     | 
    
         
            -
            require 'rspec-api/ 
     | 
| 
      
 1 
     | 
    
         
            +
            require 'rspec-api/dsl/have_status'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'rspec-api/dsl/include_content_type'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'rspec-api/dsl/have_prev_page_link'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'rspec-api/dsl/be_a_jsonp'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'rspec-api/dsl/be_sorted'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'rspec-api/dsl/be_valid_json'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'rspec-api/dsl/be_filtered'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require 'rspec-api/dsl/have_attributes'
         
     | 
| 
      
 9 
     | 
    
         
            +
            require 'rspec-api/dsl/run_if' # should be the last, for metaprogramming
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            require 'rspec/matchers'
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            # Convert RSpecAPI::Matchers classes into RSpec-compatible matchers, e.g.:
         
     | 
| 
      
 14 
     | 
    
         
            +
            # makes RSpecApi::Matchers::Status available as expect(...).to match_status
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            module RSpecApi
         
     | 
| 
      
 17 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 18 
     | 
    
         
            +
                module DSL
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            module RSpec
         
     | 
| 
      
 24 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 25 
     | 
    
         
            +
                # Make RSpecApi::Matchers::DSL methods available inside RSpec
         
     | 
| 
      
 26 
     | 
    
         
            +
                include ::RSpecApi::Matchers::DSL
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,171 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'json'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'active_support/core_ext/array/wrap'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'active_support/core_ext/hash/keys'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'active_support/core_ext/array/conversions'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module RSpecApi
         
     | 
| 
      
 7 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 8 
     | 
    
         
            +
                class Attributes
         
     | 
| 
      
 9 
     | 
    
         
            +
                  def initialize(attributes = {})
         
     | 
| 
      
 10 
     | 
    
         
            +
                    @attributes = as_hash(attributes)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  def matches?(response)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @body = response.body
         
     | 
| 
      
 15 
     | 
    
         
            +
                    json = extract_symbolized_json_from @body
         
     | 
| 
      
 16 
     | 
    
         
            +
                    # NOTE: Might add this... but might be too strict. For instance, if I
         
     | 
| 
      
 17 
     | 
    
         
            +
                    # ask for ?page=2, I might get an empty array. Maybe in that case I
         
     | 
| 
      
 18 
     | 
    
         
            +
                    # should not even check for attributes? Maybe it can be another best
         
     | 
| 
      
 19 
     | 
    
         
            +
                    # practice: adding query params will not affect the attributes (so I
         
     | 
| 
      
 20 
     | 
    
         
            +
                    # can just check them when there are no query params)... of course
         
     | 
| 
      
 21 
     | 
    
         
            +
                    # unless the query params is ?fields=id,name
         
     | 
| 
      
 22 
     | 
    
         
            +
                    # if json.is_a?(Array) and json.empty?
         
     | 
| 
      
 23 
     | 
    
         
            +
                    #   raise RSpec::Core::Pending::PendingDeclaredInExample.new "You are testing if an array is sorted, but the array is empty. Try with more fixtures"
         
     | 
| 
      
 24 
     | 
    
         
            +
                    # end
         
     | 
| 
      
 25 
     | 
    
         
            +
                    has_attributes? json, @attributes
         
     | 
| 
      
 26 
     | 
    
         
            +
                  rescue JSON::ParserError, JSON::GeneratorError
         
     | 
| 
      
 27 
     | 
    
         
            +
                    false
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
                  alias == matches?
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  def failure_message_for_should
         
     | 
| 
      
 32 
     | 
    
         
            +
                    "expected body to #{description}, but got #{@body}"
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  def failure_message_for_should_not
         
     | 
| 
      
 36 
     | 
    
         
            +
                    "expected body not to #{description}, but it did"
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  def description
         
     | 
| 
      
 40 
     | 
    
         
            +
                    desc = @attributes.map do |name, options|
         
     | 
| 
      
 41 
     | 
    
         
            +
                      text = "#{name}"
         
     | 
| 
      
 42 
     | 
    
         
            +
                      if options.key?(:value)
         
     | 
| 
      
 43 
     | 
    
         
            +
                        text << "="
         
     | 
| 
      
 44 
     | 
    
         
            +
                        text << case options[:value]
         
     | 
| 
      
 45 
     | 
    
         
            +
                          when NilClass then 'nil'
         
     | 
| 
      
 46 
     | 
    
         
            +
                          when Proc then '[Proc value]'
         
     | 
| 
      
 47 
     | 
    
         
            +
                          else "#{options[:value]}"
         
     | 
| 
      
 48 
     | 
    
         
            +
                        end
         
     | 
| 
      
 49 
     | 
    
         
            +
                      end
         
     | 
| 
      
 50 
     | 
    
         
            +
                      if options.key?(:type)
         
     | 
| 
      
 51 
     | 
    
         
            +
                        expected_types = Array.wrap(options.fetch :type, :any)
         
     | 
| 
      
 52 
     | 
    
         
            +
                        types = expected_types.map do |type|
         
     | 
| 
      
 53 
     | 
    
         
            +
                          case type
         
     | 
| 
      
 54 
     | 
    
         
            +
                          when Hash
         
     | 
| 
      
 55 
     | 
    
         
            +
                            type.map do |k, format|
         
     | 
| 
      
 56 
     | 
    
         
            +
                              case format
         
     | 
| 
      
 57 
     | 
    
         
            +
                              when Hash, Array
         
     | 
| 
      
 58 
     | 
    
         
            +
                                "#{k} with attributes"
         
     | 
| 
      
 59 
     | 
    
         
            +
                              else # Symbol
         
     | 
| 
      
 60 
     | 
    
         
            +
                                "#{format} #{k}"
         
     | 
| 
      
 61 
     | 
    
         
            +
                              end
         
     | 
| 
      
 62 
     | 
    
         
            +
                            end.to_sentence(two_words_connector: ' or ', last_word_connector: ', or ')
         
     | 
| 
      
 63 
     | 
    
         
            +
                          else "#{type}"
         
     | 
| 
      
 64 
     | 
    
         
            +
                          end
         
     | 
| 
      
 65 
     | 
    
         
            +
                        end
         
     | 
| 
      
 66 
     | 
    
         
            +
                        text << " (#{types.to_sentence(two_words_connector: ' or ', last_word_connector: ', or ')})" if types.any?
         
     | 
| 
      
 67 
     | 
    
         
            +
                      end
         
     | 
| 
      
 68 
     | 
    
         
            +
                      text
         
     | 
| 
      
 69 
     | 
    
         
            +
                    end.to_sentence
         
     | 
| 
      
 70 
     | 
    
         
            +
                    ['have attributes', desc].join(' ').strip
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                private
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                  def has_attributes?(item_or_items, attributes)
         
     | 
| 
      
 76 
     | 
    
         
            +
                    attributes.deep_symbolize_keys!
         
     | 
| 
      
 77 
     | 
    
         
            +
                    items = Array.wrap item_or_items
         
     | 
| 
      
 78 
     | 
    
         
            +
                    attributes.all? do |name, options|
         
     | 
| 
      
 79 
     | 
    
         
            +
                      has_attribute? items, name, options
         
     | 
| 
      
 80 
     | 
    
         
            +
                    end
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                  def has_attribute?(items, name, options)
         
     | 
| 
      
 84 
     | 
    
         
            +
                    if items.all?{|item| has_key? item, name}
         
     | 
| 
      
 85 
     | 
    
         
            +
                      values = items.map{|item| item[name]}
         
     | 
| 
      
 86 
     | 
    
         
            +
                      expected_types = Array.wrap(options.fetch :type, :any)
         
     | 
| 
      
 87 
     | 
    
         
            +
                      expected_value = options.fetch :value, :any
         
     | 
| 
      
 88 
     | 
    
         
            +
                      values.all? do |value|
         
     | 
| 
      
 89 
     | 
    
         
            +
                        matches_value?(value, expected_value) && matches_types?(value, expected_types)
         
     | 
| 
      
 90 
     | 
    
         
            +
                      end
         
     | 
| 
      
 91 
     | 
    
         
            +
                    end
         
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                  def has_key?(item, name)
         
     | 
| 
      
 95 
     | 
    
         
            +
                    item.key? name
         
     | 
| 
      
 96 
     | 
    
         
            +
                  end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                  def matches_value?(value, expected_value)
         
     | 
| 
      
 100 
     | 
    
         
            +
                    case expected_value
         
     | 
| 
      
 101 
     | 
    
         
            +
                    when :any then true
         
     | 
| 
      
 102 
     | 
    
         
            +
                    when Proc then expected_value.call value
         
     | 
| 
      
 103 
     | 
    
         
            +
                    else value == expected_value
         
     | 
| 
      
 104 
     | 
    
         
            +
                    end
         
     | 
| 
      
 105 
     | 
    
         
            +
                  end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                  def matches_types?(value, expected_types)
         
     | 
| 
      
 108 
     | 
    
         
            +
                    expected_types.any? do |type|
         
     | 
| 
      
 109 
     | 
    
         
            +
                      matches_type_and_format? value, type
         
     | 
| 
      
 110 
     | 
    
         
            +
                    end
         
     | 
| 
      
 111 
     | 
    
         
            +
                  end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                  def matches_type_and_format?(value, type)
         
     | 
| 
      
 114 
     | 
    
         
            +
                    type = Hash[type, :any] unless type.is_a?(Hash)
         
     | 
| 
      
 115 
     | 
    
         
            +
                    type.any? do |type, format|
         
     | 
| 
      
 116 
     | 
    
         
            +
                      matches_type?(value, type) && matches_format?(value, format)
         
     | 
| 
      
 117 
     | 
    
         
            +
                    end
         
     | 
| 
      
 118 
     | 
    
         
            +
                  end
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
                  def matches_type?(value, type)
         
     | 
| 
      
 121 
     | 
    
         
            +
                    type_to_classes(type).any?{|klass| value.is_a? klass}
         
     | 
| 
      
 122 
     | 
    
         
            +
                  end
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                  def matches_format?(value, format)
         
     | 
| 
      
 125 
     | 
    
         
            +
                    case format
         
     | 
| 
      
 126 
     | 
    
         
            +
                    when :url then value =~ URI::regexp
         
     | 
| 
      
 127 
     | 
    
         
            +
                    when :integer then value.is_a? Integer
         
     | 
| 
      
 128 
     | 
    
         
            +
                    when :timestamp then DateTime.iso8601 value rescue false
         
     | 
| 
      
 129 
     | 
    
         
            +
                    when :email then value =~ %r{(?<name>.+?)@(?<host>.+?)\.(?<domain>.+?)}
         
     | 
| 
      
 130 
     | 
    
         
            +
                    when Hash, Array then value.any? ?has_attributes?(value, as_hash(format)) : true
         
     | 
| 
      
 131 
     | 
    
         
            +
                    when String then matches_format?(value, format.to_sym)
         
     | 
| 
      
 132 
     | 
    
         
            +
                    when :any then true
         
     | 
| 
      
 133 
     | 
    
         
            +
                    end
         
     | 
| 
      
 134 
     | 
    
         
            +
                  end
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                  def type_to_classes(type)
         
     | 
| 
      
 137 
     | 
    
         
            +
                    Array.wrap case type
         
     | 
| 
      
 138 
     | 
    
         
            +
                      when :string then String
         
     | 
| 
      
 139 
     | 
    
         
            +
                      when :array then Array
         
     | 
| 
      
 140 
     | 
    
         
            +
                      when :object then Hash
         
     | 
| 
      
 141 
     | 
    
         
            +
                      when :null then NilClass
         
     | 
| 
      
 142 
     | 
    
         
            +
                      when :boolean then [TrueClass, FalseClass]
         
     | 
| 
      
 143 
     | 
    
         
            +
                      when :number then Numeric
         
     | 
| 
      
 144 
     | 
    
         
            +
                      when String then type_to_classes(type.to_sym)
         
     | 
| 
      
 145 
     | 
    
         
            +
                      when :any then Object
         
     | 
| 
      
 146 
     | 
    
         
            +
                    end
         
     | 
| 
      
 147 
     | 
    
         
            +
                  end
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
                  # These go elsewhere
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                  def as_hash(anything)
         
     | 
| 
      
 152 
     | 
    
         
            +
                    if anything.is_a? Hash
         
     | 
| 
      
 153 
     | 
    
         
            +
                      anything
         
     | 
| 
      
 154 
     | 
    
         
            +
                    elsif anything.nil?
         
     | 
| 
      
 155 
     | 
    
         
            +
                      {}
         
     | 
| 
      
 156 
     | 
    
         
            +
                    else
         
     | 
| 
      
 157 
     | 
    
         
            +
                      Hash[*Array.wrap(anything).map{|x| x.is_a?(Hash) ? [x.keys.first, x.values.first] : [x, {}]}.flatten]
         
     | 
| 
      
 158 
     | 
    
         
            +
                    end
         
     | 
| 
      
 159 
     | 
    
         
            +
                  end
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
                  def extract_symbolized_json_from(something)
         
     | 
| 
      
 162 
     | 
    
         
            +
                    JSON without_callbacks(something), symbolize_names: true
         
     | 
| 
      
 163 
     | 
    
         
            +
                  end
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
                  def without_callbacks(something)
         
     | 
| 
      
 166 
     | 
    
         
            +
                    callback_pattern = %r[^.+?\((.*?)\)$]
         
     | 
| 
      
 167 
     | 
    
         
            +
                    something =~ callback_pattern ? something.match(callback_pattern)[1] : something
         
     | 
| 
      
 168 
     | 
    
         
            +
                  end
         
     | 
| 
      
 169 
     | 
    
         
            +
                end
         
     | 
| 
      
 170 
     | 
    
         
            +
              end
         
     | 
| 
      
 171 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module RSpecApi
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 3 
     | 
    
         
            +
                class ContentType
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def initialize(content_type)
         
     | 
| 
      
 5 
     | 
    
         
            +
                    @content_type = content_type
         
     | 
| 
      
 6 
     | 
    
         
            +
                  end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  def matches?(response)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    @headers = response.headers
         
     | 
| 
      
 10 
     | 
    
         
            +
                    @headers['Content-Type'] == @content_type if @headers.key? 'Content-Type'
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  def failure_message_for_should
         
     | 
| 
      
 14 
     | 
    
         
            +
                    "expected headers to #{description}, but got #{@headers}"
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  def failure_message_for_should_not
         
     | 
| 
      
 18 
     | 
    
         
            +
                    "expected headers not to #{description}, but got #{@headers}"
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  def description
         
     | 
| 
      
 22 
     | 
    
         
            +
                    %Q{include 'Content-Type': '#{@content_type}'}
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  def description_for_run_if
         
     | 
| 
      
 26 
     | 
    
         
            +
                    %Q{include any specific 'Content-Type'}
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,54 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'json'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RSpecApi
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 5 
     | 
    
         
            +
                class Filter
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def initialize(value, options = {})
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @value = value
         
     | 
| 
      
 8 
     | 
    
         
            +
                    @field = options[:by]
         
     | 
| 
      
 9 
     | 
    
         
            +
                    @comparing_with = options.fetch :comparing_with, Proc.new{|x,y| x == y}
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  def matches?(response)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @desc = " by #{@field}#{@comparing_with}#{@value}"
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @body = response.body
         
     | 
| 
      
 15 
     | 
    
         
            +
                    array = extract_json_from @body
         
     | 
| 
      
 16 
     | 
    
         
            +
                    array.all? do |item| # TODO: Don't always use string
         
     | 
| 
      
 17 
     | 
    
         
            +
                      @comparing_with.call @value, item[@field.to_s].to_s
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
                  alias == matches?
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  def failure_message_for_should
         
     | 
| 
      
 23 
     | 
    
         
            +
                    "expected body to #{description}, but got #{@body}"
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  def failure_message_for_should_not
         
     | 
| 
      
 27 
     | 
    
         
            +
                    "expected body not to #{description}, but it was"
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  def description
         
     | 
| 
      
 31 
     | 
    
         
            +
                    %Q(be filtered#{@desc})
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                private
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  # These go elsewhere
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  def extract_json_from(something)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    array = JSON without_callbacks(something)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    if array.is_a?(Array) and array.empty?
         
     | 
| 
      
 41 
     | 
    
         
            +
                      raise RSpec::Core::Pending::PendingDeclaredInExample.new "You are testing if an array is sorted, but the array is empty. Try with more fixtures"
         
     | 
| 
      
 42 
     | 
    
         
            +
                    end
         
     | 
| 
      
 43 
     | 
    
         
            +
                    array
         
     | 
| 
      
 44 
     | 
    
         
            +
                  rescue JSON::ParserError, JSON::GeneratorError
         
     | 
| 
      
 45 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  def without_callbacks(something)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    callback_pattern = %r[^.+?\((.*?)\)$]
         
     | 
| 
      
 50 
     | 
    
         
            +
                    something =~ callback_pattern ? something.match(callback_pattern)[1] : something
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,46 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'json'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RSpecApi
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 5 
     | 
    
         
            +
                class Json
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def initialize(type)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @type = type
         
     | 
| 
      
 8 
     | 
    
         
            +
                    @desc = " #{@type}" if @type
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def matches?(response)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @body = response.body
         
     | 
| 
      
 13 
     | 
    
         
            +
                    json = parse_json_of @body
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @type ? json.is_a?(@type) : true
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  alias == matches?
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def failure_message_for_should
         
     | 
| 
      
 19 
     | 
    
         
            +
                    "expected body to #{description}, but got #{@body}"
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  def failure_message_for_should_not
         
     | 
| 
      
 23 
     | 
    
         
            +
                    "expected body not to #{description}, but it was"
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  def description
         
     | 
| 
      
 27 
     | 
    
         
            +
                    %Q(be a valid JSON#{@desc})
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                private
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  # These go elsewhere
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  def parse_json_of(something)
         
     | 
| 
      
 35 
     | 
    
         
            +
                    JSON without_callbacks(something)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  rescue JSON::ParserError, JSON::GeneratorError
         
     | 
| 
      
 37 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  def without_callbacks(something)
         
     | 
| 
      
 41 
     | 
    
         
            +
                    callback_pattern = %r[^.+?\((.*?)\)$]
         
     | 
| 
      
 42 
     | 
    
         
            +
                    something =~ callback_pattern ? something.match(callback_pattern)[1] : something
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module RSpecApi
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Jsonp
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def initialize(callback)
         
     | 
| 
      
 5 
     | 
    
         
            +
                    @callback = callback
         
     | 
| 
      
 6 
     | 
    
         
            +
                  end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  def matches?(response)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    @body = response.body
         
     | 
| 
      
 10 
     | 
    
         
            +
                    @body =~ %r{^#{@callback || '.+?'}\((.*?)\)$}
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
                  alias == matches?
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def failure_message_for_should
         
     | 
| 
      
 15 
     | 
    
         
            +
                    "expected body to #{description}, but got #{@body}"
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def failure_message_for_should_not
         
     | 
| 
      
 19 
     | 
    
         
            +
                    "expected body not to #{description}, but it was"
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  def description
         
     | 
| 
      
 23 
     | 
    
         
            +
                    %Q(be wrapped in a JSONP callback #{@callback}).rstrip
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module RSpecApi
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 3 
     | 
    
         
            +
                class PrevPageLink
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def matches?(response)
         
     | 
| 
      
 5 
     | 
    
         
            +
                    @headers = response.headers
         
     | 
| 
      
 6 
     | 
    
         
            +
                    links = @headers['Link'] || '' # not fetch, see http://git.io/CUz3-Q
         
     | 
| 
      
 7 
     | 
    
         
            +
                    links =~ %r{<.+?>. rel\="prev"}
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def failure_message_for_should
         
     | 
| 
      
 11 
     | 
    
         
            +
                    "expected headers to #{description}, but got #{@headers}"
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def failure_message_for_should_not
         
     | 
| 
      
 15 
     | 
    
         
            +
                    "expected headers not to #{description}, but got #{@headers}"
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def description
         
     | 
| 
      
 19 
     | 
    
         
            +
                    %Q{include a 'Link' to the previous page}
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  def description_for_run_if
         
     | 
| 
      
 23 
     | 
    
         
            +
                    %Q{include any specific pagination 'Link'}
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,39 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module RSpecApi
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 3 
     | 
    
         
            +
                class RunIf
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def initialize(run, matcher)
         
     | 
| 
      
 5 
     | 
    
         
            +
                    @run = run
         
     | 
| 
      
 6 
     | 
    
         
            +
                    @matcher = matcher
         
     | 
| 
      
 7 
     | 
    
         
            +
                  end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  def matches?(response)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    !@run || @matcher.matches?(response)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
                  alias == matches?
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def does_not_match?(response)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    !@run || !matches?(response)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def failure_message_for_should
         
     | 
| 
      
 19 
     | 
    
         
            +
                    @matcher.failure_message_for_should
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  def failure_message_for_should_not
         
     | 
| 
      
 23 
     | 
    
         
            +
                    @matcher.failure_message_for_should_not
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  def description
         
     | 
| 
      
 27 
     | 
    
         
            +
                    if @run
         
     | 
| 
      
 28 
     | 
    
         
            +
                      @matcher.description
         
     | 
| 
      
 29 
     | 
    
         
            +
                    else
         
     | 
| 
      
 30 
     | 
    
         
            +
                      if @matcher.respond_to? :description_for_run_if
         
     | 
| 
      
 31 
     | 
    
         
            +
                        %Q{not be expected to #{@matcher.description_for_run_if}}
         
     | 
| 
      
 32 
     | 
    
         
            +
                      else
         
     | 
| 
      
 33 
     | 
    
         
            +
                        %Q{not be expected to #{@matcher.description}}
         
     | 
| 
      
 34 
     | 
    
         
            +
                      end
         
     | 
| 
      
 35 
     | 
    
         
            +
                    end
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,65 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'json'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RSpecApi
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Matchers
         
     | 
| 
      
 5 
     | 
    
         
            +
                class Sort
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def initialize(options = {})
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @field = options[:by]
         
     | 
| 
      
 8 
     | 
    
         
            +
                    @reverse = options[:verse].to_s == 'desc' || options[:verse].to_s == 'descending' || options[:reverse] == true || options[:ascending] == true || options[:asc] == true || options[:descending] == false || options[:desc] == false
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def matches?(response)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    # If we don't get which field the body should be sorted by, then we
         
     | 
| 
      
 13 
     | 
    
         
            +
                    # say that it's sorted. For instance sort by random... no expectations
         
     | 
| 
      
 14 
     | 
    
         
            +
                    # We might still want to do some check about being a JSON array, though
         
     | 
| 
      
 15 
     | 
    
         
            +
                    if @field.nil?
         
     | 
| 
      
 16 
     | 
    
         
            +
                      true
         
     | 
| 
      
 17 
     | 
    
         
            +
                    else
         
     | 
| 
      
 18 
     | 
    
         
            +
                      @desc = " by #{'descending ' if @reverse}#{@field}"
         
     | 
| 
      
 19 
     | 
    
         
            +
                      @body = response.body
         
     | 
| 
      
 20 
     | 
    
         
            +
                      array = extract_array of: @field, from: @body # what if this fails?
         
     | 
| 
      
 21 
     | 
    
         
            +
                      is_sorted? array, @reverse
         
     | 
| 
      
 22 
     | 
    
         
            +
                    end
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
                  alias == matches?
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  def failure_message_for_should
         
     | 
| 
      
 27 
     | 
    
         
            +
                    # NOTE: might just print the (unsorted) fields, not the whole @body
         
     | 
| 
      
 28 
     | 
    
         
            +
                    "expected body to #{description}, but got #{@body}"
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  def failure_message_for_should_not
         
     | 
| 
      
 32 
     | 
    
         
            +
                    "expected body not to #{description}, but it was"
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  def description
         
     | 
| 
      
 36 
     | 
    
         
            +
                    %Q(be sorted#{@desc})
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                private
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  def is_sorted?(array, reverse)
         
     | 
| 
      
 42 
     | 
    
         
            +
                    return false unless array.is_a?(Array)
         
     | 
| 
      
 43 
     | 
    
         
            +
                    array.reverse! if reverse
         
     | 
| 
      
 44 
     | 
    
         
            +
                    array == array.sort
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  # These go elsewhere
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  def extract_array(options = {})
         
     | 
| 
      
 50 
     | 
    
         
            +
                    array = JSON without_callbacks(options[:from])
         
     | 
| 
      
 51 
     | 
    
         
            +
                    if array.is_a?(Array) and array.empty?
         
     | 
| 
      
 52 
     | 
    
         
            +
                      raise RSpec::Core::Pending::PendingDeclaredInExample.new "You are testing if an array is sorted, but the array is empty. Try with more fixtures"
         
     | 
| 
      
 53 
     | 
    
         
            +
                    end
         
     | 
| 
      
 54 
     | 
    
         
            +
                    array.map{|item| item[options[:of].to_s]} # what if it's not an array of hashes?
         
     | 
| 
      
 55 
     | 
    
         
            +
                  rescue JSON::ParserError, JSON::GeneratorError
         
     | 
| 
      
 56 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  def without_callbacks(something)
         
     | 
| 
      
 60 
     | 
    
         
            +
                    callback_pattern = %r[^.+?\((.*?)\)$]
         
     | 
| 
      
 61 
     | 
    
         
            +
                    something =~ callback_pattern ? something.match(callback_pattern)[1] : something
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -2,27 +2,27 @@ require 'rack/utils' 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module RSpecApi
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Matchers
         
     | 
| 
       5 
     | 
    
         
            -
                class  
     | 
| 
       6 
     | 
    
         
            -
                  def initialize( 
     | 
| 
       7 
     | 
    
         
            -
                    @expected_status =  
     | 
| 
      
 5 
     | 
    
         
            +
                class Status
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def initialize(status)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @expected_status = status
         
     | 
| 
       8 
8 
     | 
    
         
             
                  end
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                  def matches?( 
     | 
| 
       11 
     | 
    
         
            -
                    @ 
     | 
| 
       12 
     | 
    
         
            -
                     
     | 
| 
      
 10 
     | 
    
         
            +
                  def matches?(response)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @status = response.status
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @status == expected_code
         
     | 
| 
       13 
13 
     | 
    
         
             
                  end
         
     | 
| 
       14 
14 
     | 
    
         
             
                  alias == matches?
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
16 
     | 
    
         
             
                  def failure_message_for_should
         
     | 
| 
       17 
     | 
    
         
            -
                    "expected #{ 
     | 
| 
      
 17 
     | 
    
         
            +
                    "expected HTTP status code #{expected_code}, got #{@status}"
         
     | 
| 
       18 
18 
     | 
    
         
             
                  end
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
                  def failure_message_for_should_not
         
     | 
| 
       21 
     | 
    
         
            -
                    "expected  
     | 
| 
      
 21 
     | 
    
         
            +
                    "expected HTTP status code not to be #{expected_code}, but it was"
         
     | 
| 
       22 
22 
     | 
    
         
             
                  end
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
       24 
24 
     | 
    
         
             
                  def description
         
     | 
| 
       25 
     | 
    
         
            -
                    "be #{ 
     | 
| 
      
 25 
     | 
    
         
            +
                    "be HTTP status code #{expected_code}"
         
     | 
| 
       26 
26 
     | 
    
         
             
                  end
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         
             
                private
         
     | 
| 
         @@ -36,7 +36,7 @@ module RSpecApi 
     | 
|
| 
       36 
36 
     | 
    
         
             
                  # @example
         
     | 
| 
       37 
37 
     | 
    
         
             
                  # status_to_code(:ok) # => 200
         
     | 
| 
       38 
38 
     | 
    
         
             
                  # status_to_code(200) # => 200
         
     | 
| 
       39 
     | 
    
         
            -
                  # status_to_code(987) # => raise
         
     | 
| 
      
 39 
     | 
    
         
            +
                  # status_to_code(987) # => raise ArgumentError
         
     | 
| 
       40 
40 
     | 
    
         
             
                  def status_to_numeric_code(status)
         
     | 
| 
       41 
41 
     | 
    
         
             
                    code = status.is_a?(Symbol) ? Rack::Utils.status_code(status) : status
         
     | 
| 
       42 
42 
     | 
    
         
             
                    validate_status_code! code
         
     | 
| 
         @@ -47,7 +47,7 @@ module RSpecApi 
     | 
|
| 
       47 
47 
     | 
    
         
             
                  #
         
     | 
| 
       48 
48 
     | 
    
         
             
                  # @example
         
     | 
| 
       49 
49 
     | 
    
         
             
                  # validate_status_code!(200) # => (no error)
         
     | 
| 
       50 
     | 
    
         
            -
                  # validate_status_code!(999) # => raise
         
     | 
| 
      
 50 
     | 
    
         
            +
                  # validate_status_code!(999) # => raise ArgumentError
         
     | 
| 
       51 
51 
     | 
    
         
             
                  def validate_status_code!(code)
         
     | 
| 
       52 
52 
     | 
    
         
             
                    valid_codes = Rack::Utils::SYMBOL_TO_STATUS_CODE.values
         
     | 
| 
       53 
53 
     | 
    
         
             
                    message = "#{code} must be a valid HTTP status code: #{valid_codes}"
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: rspec-api-matchers
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0.0 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.1.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - claudiob
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2013- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2013-11-03 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: rspec
         
     | 
| 
         @@ -38,6 +38,20 @@ dependencies: 
     | 
|
| 
       38 
38 
     | 
    
         
             
                - - '>='
         
     | 
| 
       39 
39 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       40 
40 
     | 
    
         
             
                    version: '0'
         
     | 
| 
      
 41 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 42 
     | 
    
         
            +
              name: activesupport
         
     | 
| 
      
 43 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 44 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 45 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 46 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 47 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 48 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 49 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 50 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 51 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 52 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 53 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 54 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
       41 
55 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       42 
56 
     | 
    
         
             
              name: bundler
         
     | 
| 
       43 
57 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -87,8 +101,24 @@ executables: [] 
     | 
|
| 
       87 
101 
     | 
    
         
             
            extensions: []
         
     | 
| 
       88 
102 
     | 
    
         
             
            extra_rdoc_files: []
         
     | 
| 
       89 
103 
     | 
    
         
             
            files:
         
     | 
| 
       90 
     | 
    
         
            -
            - lib/rspec-api/ 
     | 
| 
       91 
     | 
    
         
            -
            - lib/rspec-api/ 
     | 
| 
      
 104 
     | 
    
         
            +
            - lib/rspec-api/dsl/be_a_jsonp.rb
         
     | 
| 
      
 105 
     | 
    
         
            +
            - lib/rspec-api/dsl/be_filtered.rb
         
     | 
| 
      
 106 
     | 
    
         
            +
            - lib/rspec-api/dsl/be_sorted.rb
         
     | 
| 
      
 107 
     | 
    
         
            +
            - lib/rspec-api/dsl/be_valid_json.rb
         
     | 
| 
      
 108 
     | 
    
         
            +
            - lib/rspec-api/dsl/have_attributes.rb
         
     | 
| 
      
 109 
     | 
    
         
            +
            - lib/rspec-api/dsl/have_prev_page_link.rb
         
     | 
| 
      
 110 
     | 
    
         
            +
            - lib/rspec-api/dsl/have_status.rb
         
     | 
| 
      
 111 
     | 
    
         
            +
            - lib/rspec-api/dsl/include_content_type.rb
         
     | 
| 
      
 112 
     | 
    
         
            +
            - lib/rspec-api/dsl/run_if.rb
         
     | 
| 
      
 113 
     | 
    
         
            +
            - lib/rspec-api/matchers/attributes.rb
         
     | 
| 
      
 114 
     | 
    
         
            +
            - lib/rspec-api/matchers/content_type.rb
         
     | 
| 
      
 115 
     | 
    
         
            +
            - lib/rspec-api/matchers/filter.rb
         
     | 
| 
      
 116 
     | 
    
         
            +
            - lib/rspec-api/matchers/json.rb
         
     | 
| 
      
 117 
     | 
    
         
            +
            - lib/rspec-api/matchers/jsonp.rb
         
     | 
| 
      
 118 
     | 
    
         
            +
            - lib/rspec-api/matchers/prev_page_link.rb
         
     | 
| 
      
 119 
     | 
    
         
            +
            - lib/rspec-api/matchers/run_if.rb
         
     | 
| 
      
 120 
     | 
    
         
            +
            - lib/rspec-api/matchers/sort.rb
         
     | 
| 
      
 121 
     | 
    
         
            +
            - lib/rspec-api/matchers/status.rb
         
     | 
| 
       92 
122 
     | 
    
         
             
            - lib/rspec-api/matchers/version.rb
         
     | 
| 
       93 
123 
     | 
    
         
             
            - lib/rspec-api/matchers.rb
         
     | 
| 
       94 
124 
     | 
    
         
             
            - lib/rspec-api-matchers.rb
         
     | 
| 
         @@ -1,26 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'rspec/matchers'
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            module RSpecApi
         
     | 
| 
       4 
     | 
    
         
            -
              module Matchers
         
     | 
| 
       5 
     | 
    
         
            -
                # Passes if receiver is the same HTTP status code as the argument.
         
     | 
| 
       6 
     | 
    
         
            -
                # The receiver can either be in a symbolic or numeric form.
         
     | 
| 
       7 
     | 
    
         
            -
                #
         
     | 
| 
       8 
     | 
    
         
            -
                # @example
         
     | 
| 
       9 
     | 
    
         
            -
                #
         
     | 
| 
       10 
     | 
    
         
            -
                #   # Passes if 200 corresponds to 200
         
     | 
| 
       11 
     | 
    
         
            -
                #   expect(200).to match_status(200)
         
     | 
| 
       12 
     | 
    
         
            -
                #
         
     | 
| 
       13 
     | 
    
         
            -
                #   # Passes if :ok corresponds to :ok
         
     | 
| 
       14 
     | 
    
         
            -
                #   expect(:ok).to match_status(200)
         
     | 
| 
       15 
     | 
    
         
            -
                def match_status(expected_status)
         
     | 
| 
       16 
     | 
    
         
            -
                  RSpecApi::Matchers::MatchStatus.new(expected_status)
         
     | 
| 
       17 
     | 
    
         
            -
                end
         
     | 
| 
       18 
     | 
    
         
            -
              end
         
     | 
| 
       19 
     | 
    
         
            -
            end
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
            module RSpec
         
     | 
| 
       22 
     | 
    
         
            -
              module Matchers
         
     | 
| 
       23 
     | 
    
         
            -
                # Make RSpecApi::Matchers available inside RSpec
         
     | 
| 
       24 
     | 
    
         
            -
                include ::RSpecApi::Matchers
         
     | 
| 
       25 
     | 
    
         
            -
              end
         
     | 
| 
       26 
     | 
    
         
            -
            end
         
     |