Skip to content

Instantly share code, notes, and snippets.

@maxlinc
Created October 29, 2013 00:20
Show Gist options
  • Save maxlinc/7207170 to your computer and use it in GitHub Desktop.
Save maxlinc/7207170 to your computer and use it in GitHub Desktop.
VCR to Pacto
def vcr_to_pacto_request vcr_request
uri = URI(vcr_request.uri)
definition = {
'method' => vcr_request.method,
'path' => uri.path,
# How do we get params from VCR?
'params' => {},
'headers' => vcr_request.headers
}
Pacto::Request.new uri.host, definition
end
def vcr_to_pacto_response vcr_response
OpenStruct.new(
'status' => vcr_response.status.code,
'headers' => vcr_response.headers,
'body' => vcr_response.body
)
end
Pacto.configure do |c|
c.contracts_path = 'contracts'
end
VCR.configure do |c|
# ...
if ENV['PACTO'] == 'generate'
c.before_playback do | interaction |
uri = URI(interaction.request.uri)
basename = File.basename(uri.path, '.json') + '.json'
# contract_file = File.expand_path(Pacto.configuration.contracts_path, File.dirname(uri.path), basename)
contract_file = File.join(Pacto.configuration.contracts_path, File.dirname(uri.path), basename)
unless File.exists? contract_file
pacto_request = vcr_to_pacto_request(interaction.request)
pacto_response = vcr_to_pacto_response(interaction.response)
generator = Pacto::Generator.new
FileUtils.mkdir_p(File.dirname contract_file)
File.write(contract_file, generator.save('vcr', pacto_request, pacto_response))
end
end
end
end
@marcosccm
Copy link

wow! that's really cool! Can you post a generated contract?

@maxlinc
Copy link
Author

maxlinc commented Oct 30, 2013

I asked @fernando-alves if he can work on a PR that makes the generator only record request headers that appear in the Vary. That's exactly what Vary is supposed to tell us, right? We'd still need a way to clean up response headers, though.

Also, the schema generator doesn't request default values right now, but that should be a pretty easy enhancement.

I'd also prefer the description ("Generated from ...") at the top of the Contract, instead of in the body.

The generated contract (with the extra request headers dropped), would look like this:

{
  "request": {
    "headers": {
      "X-Auth-Token": [
        "_ONE-TIME-TOKEN_"
      ]
    },
    "method": "get",
    "params": {
    },
    "path": "/v1.0/000000/flavors/1.json"
  },
  "response": {
    "headers": {
      "vary": [
        "Accept, Accept-Encoding, X-Auth-Token"
      ],
      "Last-Modified": [
        "Wed, 19 Sep 2007 18:24:59 GMT"
      ],
      "X-PURGE-KEY": [
        "/flavors"
      ],
      "Cache-Control": [
        "s-maxage=1800"
      ],
      "Content-Type": [
        "application/json"
      ],
      "X-Varnish": [
        "_VARNISH-REQUEST-ID_"
      ],
      "Age": [
        "0"
      ],
      "Via": [
        "1.1 varnish"
      ]
    },
    "status": 200,
    "body": {
      "$schema": "http://json-schema.org/draft-03/schema#",
      "description": "Generated from vcr with shasum 8bc264c0741af280ceabf118834194374ab86bc4",
      "type": "object",
      "required": true,
      "properties": {
        "flavor": {
          "type": "object",
          "required": true,
          "properties": {
            "id": {
              "type": "integer",
              "required": true
            },
            "ram": {
              "type": "integer",
              "required": true
            },
            "disk": {
              "type": "integer",
              "required": true
            },
            "name": {
              "type": "string",
              "required": true
            }
          }
        }
      }
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment