diff --git a/Gemfile b/Gemfile index ad2ac02..02ae925 100644 --- a/Gemfile +++ b/Gemfile @@ -23,3 +23,5 @@ group :samples do gem 'pry' gem 'rack' end + +gem 'swagger-core', git: 'foo' diff --git a/features/generate/generation.feature b/features/generate/generation.feature index f2c8a65..324b7e0 100644 --- a/features/generate/generation.feature +++ b/features/generate/generation.feature @@ -27,6 +27,7 @@ Feature: Contract Generation } """ + @legacy Scenario: Generating a contract using the rake task Given a directory named "contracts" When I successfully run `bundle exec rake pacto:generate['tmp/aruba/requests','tmp/aruba/contracts','http://localhost:8000']` diff --git a/features/support/env.rb b/features/support/env.rb index eb1c225..db5c872 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -1,10 +1,10 @@ # -*- encoding : utf-8 -*- -require_relative '../../spec/coveralls_helper' require 'aruba' require 'aruba/cucumber' require 'json_spec/cucumber' require 'aruba/jruby' if RUBY_PLATFORM == 'java' -require 'pacto/test_helper' +require_relative '../../spec/coveralls_helper' +require_relative '../../spec/fixtures_helper' require_relative '../../spec/pacto/dummy_server' Pacto.configuration.hide_deprecations = true diff --git a/lib/pacto/actors/from_examples.rb b/lib/pacto/actors/from_examples.rb index d32945d..c4b7a99 100644 --- a/lib/pacto/actors/from_examples.rb +++ b/lib/pacto/actors/from_examples.rb @@ -31,11 +31,12 @@ def build_request(contract, values = {}) request_values = (values || {}).dup if contract.examples? example = @selector.select(contract.examples, values) - data = contract.request.to_hash + data = {} # contract.request.to_hash request_values.merge! example_uri_values(contract) + data['method'] = contract.request.http_method data['uri'] = contract.request.uri(request_values) + data['headers'] = contract.request.headers data['body'] = example.request.body - data['method'] = contract.request.http_method Pacto::PactoRequest.new(data) else @fallback_actor.build_request contract, values diff --git a/lib/pacto/actors/json_generator.rb b/lib/pacto/actors/json_generator.rb index ec8f2e1..dc2bf73 100644 --- a/lib/pacto/actors/json_generator.rb +++ b/lib/pacto/actors/json_generator.rb @@ -3,16 +3,22 @@ module Pacto module Actors class JSONGenerator < Actor def build_request(contract, values = {}) - data = contract.request.to_hash - data['uri'] = contract.request.uri(values) - data['body'] = JSON::Generator.generate(data['schema']) - data['method'] = contract.request.http_method + rc = contract.request + data = {} + data['method'] = rc.http_method + data['uri'] = rc.uri(values) + data['headers'] = rc.headers + data['body'] = JSON::Generator.generate(rc.schema) Pacto::PactoRequest.new(data) end def build_response(contract, _values = {}) - data = contract.response.to_hash - data['body'] = JSON::Generator.generate(data['schema']) + rc = contract.response + data = { + status: rc.status, + headers: rc.headers, + body: JSON::Generator.generate(rc.schema) + } Pacto::PactoResponse.new(data) end end diff --git a/lib/pacto/cli.rb b/lib/pacto/cli.rb index 083771f..86f534c 100644 --- a/lib/pacto/cli.rb +++ b/lib/pacto/cli.rb @@ -7,8 +7,8 @@ module CLI class Main < Thor include Pacto::CLI::Helpers - desc 'meta_validate [CONTRACTS...]', 'Validates a directory of contract definitions' - def meta_validate(*contracts) + desc 'lint [CONTRACTS...]', 'Validates a directory of contract definitions' + def lint(*contracts) invalid = [] each_contract(*contracts) do |contract_file| begin @@ -26,6 +26,11 @@ def meta_validate(*contracts) say 'All contracts successfully meta-validated' end + desc 'meta_validate [CONTRACTS...]', '[Deprecated] Old alias for lint' + def meta_validate(*contracts) + lint(*contracts) + end + desc 'validate [CONTRACTS...]', 'Validates all contracts in a given directory against a given host' method_option :host, type: :string, desc: 'Override host in contracts for validation' def validate(*contracts) diff --git a/lib/pacto/consumer/faraday_driver.rb b/lib/pacto/consumer/faraday_driver.rb index 372bdab..6cfd2ab 100644 --- a/lib/pacto/consumer/faraday_driver.rb +++ b/lib/pacto/consumer/faraday_driver.rb @@ -15,7 +15,7 @@ def execute(req) response = conn.send(req.method) do |faraday_request| faraday_request.url(req.uri.path, req.uri.query_values) faraday_request.headers = req.headers - faraday_request.body = req.body + faraday_request.body = req.raw_body end faraday_to_pacto_response response diff --git a/lib/pacto/contract.rb b/lib/pacto/contract.rb index 62bcf18..07d2c5e 100644 --- a/lib/pacto/contract.rb +++ b/lib/pacto/contract.rb @@ -2,6 +2,7 @@ module Pacto class Contract < Pacto::Dash include Logger + extend Forwardable property :id property :file @@ -20,6 +21,8 @@ class Contract < Pacto::Dash property :consumer, default: proc { Pacto.configuration.default_consumer } property :provider, default: proc { Pacto.configuration.default_provider } + def_delegators :request, :host, :uri + def initialize(opts) if opts[:file] opts[:file] = Addressable::URI.convert_path(File.expand_path(opts[:file])).to_s diff --git a/lib/pacto/core/pacto_request.rb b/lib/pacto/core/pacto_request.rb index 95215fd..4f3554f 100644 --- a/lib/pacto/core/pacto_request.rb +++ b/lib/pacto/core/pacto_request.rb @@ -7,11 +7,11 @@ class PactoRequest attr_accessor :headers, :body, :method, :uri def initialize(data) - mash = Hashie::Mash.new data - @headers = mash.headers.nil? ? {} : mash.headers - @body = mash.body - @method = mash[:method] - @uri = mash.uri + data.singleton_class.send(:include, Hashie::Extensions::IndifferentAccess) + @headers = data[:headers].nil? ? {} : data[:headers] + @body = data[:body] + @method = data[:method] + @uri = data[:uri] normalize end @@ -27,7 +27,7 @@ def to_hash def to_s string = Pacto::UI.colorize_method(method) string << " #{relative_uri}" - string << " with body (#{body.bytesize} bytes)" if body + string << " with body (#{raw_body.bytesize} bytes)" if body string end @@ -37,6 +37,17 @@ def relative_uri end end + def raw_body + return body if body.is_a? String + + case content_type + when 'application/json', nil + JSON.dump(body) + else + fail NotImplementedError, "No encoder for #{body.class} to #{content_type}" + end + end + def parsed_body if body.is_a?(String) && content_type == 'application/json' JSON.parse(body) diff --git a/lib/pacto/core/pacto_response.rb b/lib/pacto/core/pacto_response.rb index 85f2143..3a051c8 100644 --- a/lib/pacto/core/pacto_response.rb +++ b/lib/pacto/core/pacto_response.rb @@ -22,10 +22,23 @@ def to_hash def to_s string = "STATUS: #{status}" - string << " with body (#{body.bytesize} bytes)" if body + string << " with body (#{raw_body.bytesize} bytes)" if body string end + def raw_body + if content_type == 'application/json' + case body + when String + body + else + JSON.dump(body) + end + else + body.to_s + end + end + def parsed_body if body.is_a?(String) && content_type == 'application/json' JSON.parse(body) diff --git a/lib/pacto/generator.rb b/lib/pacto/generator.rb index b3c368d..52630a3 100644 --- a/lib/pacto/generator.rb +++ b/lib/pacto/generator.rb @@ -37,8 +37,12 @@ def initialize @hints = Set.new end - def hint(name, hint_data) - @hints << Pacto::Generator::Hint.new(hint_data.merge(service_name: name)) + def hint(name, request_data) + hint_data = { + service_name: name, + target_file: request_data.delete(:target_file) + } + @hints << Pacto::Generator::Hint.new(hint_data, RequestClause.new(request_data)) end end end diff --git a/lib/pacto/generator/hint.rb b/lib/pacto/generator/hint.rb index 31bf0f2..d5737af 100644 --- a/lib/pacto/generator/hint.rb +++ b/lib/pacto/generator/hint.rb @@ -1,19 +1,23 @@ # -*- encoding : utf-8 -*- module Pacto module Generator - class Hint < Pacto::RequestClause + class Hint < Pacto::Dash + extend Forwardable property :service_name, required: true property :target_file + attr_reader :request_clause + def_delegators :@request_clause, *RequestClause.instance_methods(false) - def initialize(data) - super + def initialize(data, request_clause) + @request_clause = request_clause + super(data) self.target_file ||= "#{slugify(service_name)}.json" self end def matches?(pacto_request) return false if pacto_request.nil? - Pacto::RequestPattern.for(self).matches?(pacto_request) + Pacto::RequestPattern.for(request_clause).matches?(pacto_request) end private diff --git a/lib/pacto/request_clause.rb b/lib/pacto/request_clause.rb index 7240009..418b847 100644 --- a/lib/pacto/request_clause.rb +++ b/lib/pacto/request_clause.rb @@ -8,11 +8,12 @@ class RequestClause < Pacto::Dash property :path, default: '/' property :headers property :params, default: {} - property :request_pattern_provider, default: Pacto::RequestPattern + attr_accessor :request_pattern_provider def initialize(definition) mash = Hashie::Mash.new definition mash['http_method'] = normalize(mash['http_method']) + @request_pattern_provider = Pacto::RequestPattern super mash end @@ -27,7 +28,7 @@ def pattern def uri(values = {}) values ||= {} uri_template = pattern.uri_template - missing_keys = uri_template.keys - values.keys + missing_keys = (uri_template.keys - values.keys).map(&:to_sym) values[:scheme] = 'http' if missing_keys.delete(:scheme) values[:server] = 'localhost' if missing_keys.delete(:server) logger.warn "Missing keys for building a complete URL: #{missing_keys.inspect}" unless missing_keys.empty? diff --git a/lib/pacto/stubs/uri_pattern.rb b/lib/pacto/stubs/uri_pattern.rb index 7953e8f..050a0a1 100644 --- a/lib/pacto/stubs/uri_pattern.rb +++ b/lib/pacto/stubs/uri_pattern.rb @@ -17,6 +17,8 @@ def build_template_uri_pattern(request, strict) if strict Addressable::Template.new("#{scheme}://#{host}#{path}") else + # host = '{server}' + # scheme = '{scheme}' Addressable::Template.new("#{scheme}://#{host}#{path}{?anyvars*}") end end diff --git a/lib/pacto/stubs/webmock_adapter.rb b/lib/pacto/stubs/webmock_adapter.rb index d2e2a60..bac5b66 100644 --- a/lib/pacto/stubs/webmock_adapter.rb +++ b/lib/pacto/stubs/webmock_adapter.rb @@ -94,7 +94,7 @@ def format_body(body) def strict_details(request) {}.tap do |details| - details[webmock_params_key(request)] = request.params unless request.params.empty? + details[webmock_params_key(request)] = request.params unless request.params.nil? || request.params.empty? details[:headers] = request.headers unless request.headers.empty? end end diff --git a/lib/pacto/swagger/request_clause.rb b/lib/pacto/swagger/request_clause.rb index 5e730e8..2a8ed7b 100644 --- a/lib/pacto/swagger/request_clause.rb +++ b/lib/pacto/swagger/request_clause.rb @@ -2,11 +2,43 @@ module Pacto module Swagger class RequestClause < Pacto::RequestClause - def initialize(swagger_api_operation, base_data = {}) - host = base_data[:host] || swagger_api_operation.host - super base_data.merge(host: host, - http_method: swagger_api_operation.verb, - path: swagger_api_operation.path) + attr_reader :swagger_api_operation + attr_reader :overrides + + def initialize(swagger_api_operation, overrides = {}) + @swagger_api_operation = swagger_api_operation + @overrides = overrides + @request_pattern_provider = Pacto::RequestPattern + end + + def host + @overrides[:host] || swagger_api_operation.host + end + + def http_method + swagger_api_operation.verb + end + + def path + self[:path] ||= swagger_api_operation.path + end + + def headers + h = {} + swagger_api_operation.parameters.each do |parameter| + # Note: Can't use parameter.default because it conflicts w/ Hash#default method! + h[parameter.name] = parameter['default'] if parameter.in == 'header' + end if swagger_api_operation.parameters + h + end + + def schema + schema = {} + if swagger_api_operation.parameters + body_param = swagger_api_operation.parameters.find { |p| p.in == 'body' } + schema = body_param.schema if body_param + end + schema end end end diff --git a/lib/pacto/swagger/response_clause.rb b/lib/pacto/swagger/response_clause.rb index 9474796..fc995b4 100644 --- a/lib/pacto/swagger/response_clause.rb +++ b/lib/pacto/swagger/response_clause.rb @@ -13,6 +13,15 @@ def initialize(swagger_response, base_data = {}) super base_data.merge(data) end + + def headers + h = {} + swagger_response.headers.each do |name, metadata| + # Note: Can't use header.default because it conflicts w/ Hash#default method! + h[name] = metadata['default'] + end if swagger_response.headers + h + end end end end diff --git a/lib/pacto/swagger_contract.rb b/lib/pacto/swagger_contract.rb index 5c42b95..97f5d19 100644 --- a/lib/pacto/swagger_contract.rb +++ b/lib/pacto/swagger_contract.rb @@ -6,22 +6,23 @@ module Pacto class SwaggerContract < Pacto::Contract attr_reader :swagger_api_operation + # def_delegators :@swagger_api_operation, :host - def initialize(swagger_api_operation, base_data = {}) + def initialize(swagger_api_operation, overrides = {}) @swagger_api_operation = swagger_api_operation - host = base_data.delete(:host) || swagger_api_operation.host default_response = swagger_api_operation.default_response - request_clause = Pacto::Swagger::RequestClause.new(swagger_api_operation, host: host) + request_clause = Pacto::Swagger::RequestClause.new(swagger_api_operation, overrides.dup) if default_response.nil? - logger.warn("No response defined for #{swagger_api_operation.full_name}") + logger.warn("No response defined for #{swagger_api_operation.operationId}") response_clause = Pacto::ResponseClause.new(status: 200) else response_clause = Pacto::Swagger::ResponseClause.new(default_response) end examples = build_examples(default_response) - super base_data.merge( + overrides.delete(:host) + super overrides.merge( id: swagger_api_operation.operationId, name: swagger_api_operation.full_name, request: request_clause, response: response_clause, diff --git a/lib/pacto/swagger_contract_factory.rb b/lib/pacto/swagger_contract_factory.rb index 67d6eb1..3f51f92 100644 --- a/lib/pacto/swagger_contract_factory.rb +++ b/lib/pacto/swagger_contract_factory.rb @@ -10,10 +10,12 @@ class SwaggerContractFactory def load_hints(contract_path, host = nil) app = ::Swagger.load(contract_path) app.operations.map do |op| + hint_data = { + service_name: op.full_name, + target_file: contract_path + } request_clause = Pacto::Swagger::RequestClause.new(op, host: host) - Pacto::Generator::Hint.new(request_clause.to_hash.merge( - service_name: op.fetch(:summary) - )) + Pacto::Generator::Hint.new(hint_data, request_clause) end end diff --git a/spec/fabricators/contract_fabricator.rb b/spec/fabricators/contract_fabricator.rb index 704c497..ff47216 100644 --- a/spec/fabricators/contract_fabricator.rb +++ b/spec/fabricators/contract_fabricator.rb @@ -4,91 +4,44 @@ # Fabricators for contracts or parts of contracts -Fabricator(:contract, from: Pacto::Contract) do - initialize_with { @_klass.new to_hash } # Hash based initialization - transient example_count: 0 - name { 'Dummy Contract' } - file { 'file:///does/not/exist/dummy_contract.json' } - request { Fabricate(:request_clause).to_hash } - response { Fabricate(:response_clause).to_hash } - examples do |attr| - example_count = attr[:example_count] - if example_count - examples = attr[:example_count].times.each_with_object({}) do |i, h| - name = i.to_s - h[name] = Fabricate(:an_example, name: name) - end - examples - else - nil - end +PACTO_DEFAULT_FORMAT = (ENV['PACTO_DEFAULT_FORMAT'] || 'legacy') + +Fabricator(:delegating_fabricator, from: Object) do + transient format: PACTO_DEFAULT_FORMAT + transient :thing + initialize_with do + transients = _transient_attributes.dup + format = transients.delete :format + thing = transients.delete :thing + fabricator = "#{format}_#{thing}".to_sym + data = to_hash.merge(transients) + Fabricate(fabricator, data) end end -Fabricator(:partial_contract, from: Pacto::Contract) do - initialize_with { @_klass.new to_hash } # Hash based initialization - name { 'Dummy Contract' } - file { 'file:///does/not/exist/dummy_contract.json' } - request { Fabricate(:request_clause).to_hash } +Fabricator(:contract, from: :delegating_fabricator) do + transient thing: :contract + transient example_count: 0 end -Fabricator(:request_clause, from: Pacto::RequestClause) do - initialize_with { @_klass.new to_hash } # Hash based initialization - host { 'example.com' } - http_method { 'GET' } - path { '/abcd' } - headers do - { - 'Server' => ['example.com'], - 'Connection' => ['Close'], - 'Content-Length' => [1234], - 'Via' => ['Some Proxy'], - 'User-Agent' => ['rspec'] - } - end - params {} +Fabricator(:partial_contract, from: :delegating_fabricator) do + transient thing: :partial_contract end -Fabricator(:response_clause, from: Pacto::ResponseClause) do - initialize_with { @_klass.new to_hash } # Hash based initialization - status { 200 } - headers do - { - 'Content-Type' => 'application/json' - } - end - schema { Fabricate(:schema).to_hash } +Fabricator(:request_clause, from: :delegating_fabricator) do + transient thing: :request_clause end -Fabricator(:schema, from: Hashie::Mash) do +Fabricator(:response_clause, from: :delegating_fabricator) do + transient thing: :response_clause +end + +Fabricator(:schema, from: :delegating_fabricator) do + transient thing: :schema transient :version - initialize_with { @_klass.new to_hash } # Hash based initialization - type { 'object' } - required do |attrs| - attrs[:version] == :draft3 ? true : [] - end - properties do - { - type: 'string' - } - end end -Fabricator(:an_example, from: Hashie::Mash) do - initialize_with { @_klass.new to_hash } # Hash based initialization +Fabricator(:an_example, from: :delegating_fabricator) do + transient thing: :an_example transient name: 'default' - request do |attr| - { - body: { - message: "I am example request #{attr[:name]}" - } - } - end - response do |attr| - { - body: { - message: "I am example response #{attr[:name]}" - } - } - end end diff --git a/spec/fabricators/legacy_contract_fabricator.rb b/spec/fabricators/legacy_contract_fabricator.rb new file mode 100644 index 0000000..361ff1e --- /dev/null +++ b/spec/fabricators/legacy_contract_fabricator.rb @@ -0,0 +1,94 @@ +# -*- encoding : utf-8 -*- +require 'pacto' +require 'hashie/mash' + +# Fabricators for contracts or parts of contracts + +Fabricator(:legacy_contract, from: Pacto::Contract) do + initialize_with { @_klass.new to_hash } # Hash based initialization + transient example_count: 0 + name { 'Dummy Contract' } + file { 'file:///does/not/exist/dummy_contract.json' } + request { Fabricate(:request_clause).to_hash } + response { Fabricate(:response_clause).to_hash } + examples do |attr| + example_count = attr[:example_count] + if example_count + examples = attr[:example_count].times.each_with_object({}) do |i, h| + name = i.to_s + h[name] = Fabricate(:an_example, name: name) + end + examples + else + nil + end + end +end + +Fabricator(:legacy_partial_contract, from: Pacto::Contract) do + initialize_with { @_klass.new to_hash } # Hash based initialization + name { 'Dummy Contract' } + file { 'file:///does/not/exist/dummy_contract.json' } + request { Fabricate(:request_clause).to_hash } +end + +Fabricator(:legacy_request_clause, from: Pacto::RequestClause) do + initialize_with { @_klass.new to_hash } # Hash based initialization + host { 'example.com' } + http_method { 'GET' } + path { '/abcd' } + headers do + { + 'Server' => ['example.com'], + 'Connection' => ['Close'], + 'Content-Length' => [1234], + 'Via' => ['Some Proxy'], + 'User-Agent' => ['rspec'] + } + end + params {} +end + +Fabricator(:legacy_response_clause, from: Pacto::ResponseClause) do + initialize_with { @_klass.new to_hash } # Hash based initialization + status { 200 } + headers do + { + 'Content-Type' => 'application/json' + } + end + schema { Fabricate(:schema).to_hash } +end + +Fabricator(:legacy_schema, from: Hashie::Mash) do + transient :version + initialize_with { @_klass.new to_hash } # Hash based initialization + type { 'object' } + required do |attrs| + attrs[:version] == :draft3 ? true : [] + end + properties do + { + type: 'string' + } + end +end + +Fabricator(:legacy_an_example, from: Hashie::Mash) do + initialize_with { @_klass.new to_hash } # Hash based initialization + transient name: 'default' + request do |attr| + { + body: { + message: "I am example request #{attr[:name]}" + } + } + end + response do |attr| + { + body: { + message: "I am example response #{attr[:name]}" + } + } + end +end diff --git a/spec/fabricators/old_swagger_fabricator.rb b/spec/fabricators/old_swagger_fabricator.rb new file mode 100644 index 0000000..1e112b9 --- /dev/null +++ b/spec/fabricators/old_swagger_fabricator.rb @@ -0,0 +1,87 @@ +# # -*- encoding : utf-8 -*- +# require 'pacto' +# require 'swagger' + +# # Fabricators for Swagger API definitions + +# Fabricator(:swagger_api, from: Swagger) do +# transient name: 'Dummy Swagger Contract' +# transient file: 'swagger.yaml' +# transient :examples +# transient swagger: '2.0' +# transient host: 'example.com' +# transient http_method: 'GET' +# transient path: '/abcd' +# transient headers: { +# 'Server' => ['example.com'], +# 'Connection' => ['Close'], +# 'Content-Length' => [1234], +# 'Via' => ['Some Proxy'], +# 'User-Agent' => ['rspec'] +# } +# transient params: {} + +# transient status: 200 +# # Note, need to distinguish request vs response headers/schema/etc when calling from Contract fabricator +# transient response_headers: { +# 'Content-Type' => 'application/json' +# } +# transient schema: {} #Fabricate(:schema).to_hash + +# transient :request +# transient :response + +# initialize_with do +# attrs = Hashie::Mash.new(_transient_attributes) +# builder = Swagger::Builder.builder +# builder.swagger = attrs.swagger +# builder.info do | info | +# info.version = 'Required but unused...' +# end +# builder.paths = { +# attrs.path => {} +# } +# builder.paths[attrs.path].send(attrs.http_method.downcase) do |api_operation| +# api_operation.operationId = attrs.name +# api_operation.parameters do | api_parameters | +# attrs.headers.each do | header_name, value | +# api_parameters.push({ +# name: header_name, +# in: 'header', +# default: value +# }) +# end +# attrs.params.each do | param_name, value | +# api_parameters.push({ +# name: param_name, +# in: 'query', +# default: value +# }) +# end +# end +# end +# builder.responses = { +# attrs.status => {} +# } +# builder.build +# end +# end + +# Fabricator(:swagger_api_operation, from: :swagger_api) do +# initialize_with do +# transients = _transient_attributes +# path = transients[:path] +# verb = transients[:http_method].downcase +# data = to_hash.merge(transients) +# Fabricate(:swagger_api, data).paths[path].send(verb) +# end +# end + +# Fabricator(:swagger_response, from: :swagger_api_operation) do +# initialize_with do +# transients = _transient_attributes +# status_code = transients[:status] +# data = to_hash.merge(transients) +# Fabricate(:swagger_api, data).responses[status_code.to_s] +# end +# end diff --git a/spec/fabricators/swagger_contract_fabricator.rb b/spec/fabricators/swagger_contract_fabricator.rb new file mode 100644 index 0000000..1c91f74 --- /dev/null +++ b/spec/fabricators/swagger_contract_fabricator.rb @@ -0,0 +1,132 @@ +# -*- encoding : utf-8 -*- +require 'pacto' +require 'hashie/mash' + +# Fabricators for contracts or parts of contracts + +Fabricator(:swagger_contract, from: Pacto::SwaggerContract) do + initialize_with do + data = @_attributes.merge(@_transient_attributes) + swagger_api_obj = data.delete(:swagger_api) + api_data = data.dup.keep_if { |k| [:file].include? k } + swagger_api_obj ||= Fabricate(:swagger_api, api_data) + if data[:request] + api_operation_data = data[:request].to_hash.merge(api: swagger_api_obj) + api_operation_data.keep_if { |k| ['path', 'params', 'http_method', 'headers', :api].include? k } + else + api_operation_data = {} + end + swagger_api_operation = Fabricate(:swagger_api_operation, api_operation_data) + @_klass.new swagger_api_operation, {} # to_hash + end + transient example_count: 0 + transient name: 'Dummy Contract' + transient trafile: 'file:///does/not/exist/swagger.yaml' + transient :swagger_api + transient :swagger_api_operation + transient :request + transient :response + + after_build do | swagger_contract, transients | + if transients[:example_count] + examples = transients[:example_count].times.each_with_object({}) do |i, h| + name = i.to_s + h[name] = Fabricate(:swagger_an_example, name: name) + end + swagger_contract.examples = examples + else + nil + end + end +end + +Fabricator(:swagger_partial_contract, from: Pacto::Generator::Hint) do + initialize_with do + request = @_transient_attributes[:request] + request ||= Fabricate(:swagger_request_clause) + @_klass.new request.to_hash.merge( + service_name: name, + target_file: file + ) + end + name { 'Dummy Contract' } + file { 'file:///does/not/exist/swagger.yaml' } + transient :request +end + +Fabricator(:swagger_request_clause, from: Pacto::Swagger::RequestClause) do + initialize_with do + data = @_attributes.merge(@_transient_attributes) + swagger_api_operation = data.delete :swagger_api_operation + host = data.delete :host + swagger_api_operation ||= Fabricate(:swagger_api_operation, data) + @_klass.new swagger_api_operation, host: host + end + + transient :swagger_api_operation + transient host: 'example.com' + transient http_method: 'GET' + transient path: '/abcd' + transient headers: { + 'Server' => ['example.com'], + 'Connection' => ['Close'], + 'Content-Length' => [1234], + 'Via' => ['Some Proxy'], + 'User-Agent' => ['rspec'] + } + transient params: {} + transient schema: {} +end + +Fabricator(:swagger_response_clause, from: Pacto::Swagger::ResponseClause) do + initialize_with do + swagger_response = _transient_attributes[:swagger_response] + headers = @_transient_attributes[:headers].each_with_object({}) do |(header_name, header_value), h| + h[header_name] = { + default: header_value + } + end + swagger_response ||= Fabricate(:swagger_response, status: @_transient_attributes[:status], + headers: headers, + schema: @_transient_attributes[:schema]) + @_klass.new swagger_response, {} + end + transient status: 200 + transient headers: { + 'Content-Type' => 'application/json' + } + transient :schema +end + +Fabricator(:swagger_schema, from: Hashie::Mash) do + transient :version + initialize_with { @_klass.new to_hash } # Hash based initialization + type { 'object' } + required do |attrs| + attrs[:version] == :draft3 ? true : [] + end + properties do + { + type: 'string' + } + end +end + +Fabricator(:swagger_an_example, from: Hashie::Mash) do + initialize_with { @_klass.new to_hash } # Hash based initialization + transient name: 'default' + request do |attr| + { + body: { + message: "I am example request #{attr[:name]}" + } + } + end + response do |attr| + { + body: { + message: "I am example response #{attr[:name]}" + } + } + end +end diff --git a/spec/fabricators/swagger_fabricator.rb b/spec/fabricators/swagger_fabricator.rb new file mode 100644 index 0000000..a21634a --- /dev/null +++ b/spec/fabricators/swagger_fabricator.rb @@ -0,0 +1,108 @@ +# -*- encoding : utf-8 -*- +require 'pacto' +require 'swagger' + +# Fabricators for Swagger API definitions + +Fabricator(:swagger_api_operation, from: Swagger::V2::Operation) do + transient :api + transient name: 'Dummy Swagger API' + transient http_method: 'GET' + transient path: '/abcd' + transient headers: { + 'Server' => ['example.com'], + 'Connection' => ['Close'], + 'Content-Length' => [1234], + 'Via' => ['Some Proxy'], + 'User-Agent' => ['rspec'] + } + transient params: {} + transient schema: {} # Fabricate(:schema, version: 'draft4') + + initialize_with do + attrs = Hashie::Mash.new(_transient_attributes) + api_operation_builder = Swagger::Bash.infect(@_klass).new({}) + api_operation_builder.operationId = attrs.name + api_operation_builder.parameters do | api_parameters | + attrs.headers.each do | header_name, value | + api_parameters.push(name: header_name, + in: 'header', + default: value) + end if attrs.headers + attrs.params.each do | param_name, value | + api_parameters.push(name: param_name, + in: 'query', + default: value) + end if attrs.params + api_parameters.push(name: 'body', in: 'body', schema: attrs.schema) if attrs.schema + end + transients = @_transient_attributes + api = transients.delete :api + path = transients[:path] + verb = transients[:http_method].downcase + api ||= Fabricate(:swagger_api, paths: { path => Swagger::V2::Path.new({}) }) + api.paths[path] ||= Swagger::V2::Path.new({}) + api.paths[path][verb] = api_operation_builder.build + api_operation = api.paths[path][verb] + api.attach_to_children + api_operation + end + + # after_build do |api_operation, transients| + # api = transients.delete :api + # path = transients[:path] + # verb = transients[:http_method].downcase + # api ||= Fabricate(:swagger_api, paths: { path => Swagger::V2::Path.new({}) }) + # api.paths[path] ||= Swagger::V2::Path.new({}) + # api.paths[path][verb] = api_operation + # api_operation = api.paths[path][verb] + # api.attach_to_children + # end +end + +Fabricator(:swagger_response, from: Swagger::V2::Response) do + transient :api_operation + transient status: 200 + + initialize_with do + swagger_response_builder = Swagger::Bash.infect(@_klass).new({}) + swagger_response_builder.build + end + + after_build do |swagger_response, transients| + api_operation = transients.delete :api_operation + status = transients[:status] + api_operation ||= Fabricate(:swagger_api_operation) + api_operation.responses ||= {} + api_operation.responses[status.to_s] = swagger_response + api_operation.attach_to_children + end +end + +Fabricator(:swagger_api, from: Swagger) do + transient file: 'swagger.yaml' + transient swagger: '2.0' + transient host: 'example.com' + transient :paths + + initialize_with do + attrs = Hashie::Mash.new(_transient_attributes) + builder = Swagger::Builder.builder + builder.swagger = attrs.swagger + builder.info do | info | + info.version = 'Required but unused...' + end + if attrs.paths + builder.paths = attrs.paths + else + builder.paths = { + '/' => {} + } + end + Swagger.build_api(builder.build.to_hash) + end + + after_build do |swagger_api, _transients| + swagger_api.attach_to_children + end +end diff --git a/spec/fixtures/contracts/contract.json b/spec/fixtures/legacy_contracts/contract.json similarity index 100% rename from spec/fixtures/contracts/contract.json rename to spec/fixtures/legacy_contracts/contract.json diff --git a/spec/fixtures/contracts/contract_with_examples.json b/spec/fixtures/legacy_contracts/contract_with_examples.json similarity index 100% rename from spec/fixtures/contracts/contract_with_examples.json rename to spec/fixtures/legacy_contracts/contract_with_examples.json diff --git a/spec/fixtures/contracts/simple_contract.json b/spec/fixtures/legacy_contracts/simple_contract.json similarity index 100% rename from spec/fixtures/contracts/simple_contract.json rename to spec/fixtures/legacy_contracts/simple_contract.json diff --git a/spec/fixtures/contracts/strict_contract.json b/spec/fixtures/legacy_contracts/strict_contract.json similarity index 100% rename from spec/fixtures/contracts/strict_contract.json rename to spec/fixtures/legacy_contracts/strict_contract.json diff --git a/spec/fixtures/contracts/templating_contract.json b/spec/fixtures/legacy_contracts/templating_contract.json similarity index 100% rename from spec/fixtures/contracts/templating_contract.json rename to spec/fixtures/legacy_contracts/templating_contract.json diff --git a/spec/fixtures/swagger/petstore.yaml b/spec/fixtures/swagger_contracts/petstore.yaml similarity index 100% rename from spec/fixtures/swagger/petstore.yaml rename to spec/fixtures/swagger_contracts/petstore.yaml diff --git a/spec/fixtures/swagger_contracts/simple_contract.yaml b/spec/fixtures/swagger_contracts/simple_contract.yaml new file mode 100644 index 0000000..de00e72 --- /dev/null +++ b/spec/fixtures/swagger_contracts/simple_contract.yaml @@ -0,0 +1,39 @@ +swagger: 2.0 +info: + version: 1.0.0 + title: Simple Contract + license: + name: MIT +schemes: + - http +consumes: + - application/json +produces: + - application/json +paths: + /hello: + get: + summary: Hello! + operationId: hello + parameters: + - name: Accept + in: header + default: application/json + responses: + 200: + description: An paged array of pets + headers: + Content-Type: + type: string + default: application/json + Vary: + type: string + default: Accept + schema: + $schema: "http://json-schema.org/draft-03/schema#" + type: object + required: true + properties: + message: + type: string + required: true diff --git a/spec/fixtures/swagger_contracts/strict_contract.yaml b/spec/fixtures/swagger_contracts/strict_contract.yaml new file mode 100644 index 0000000..5fb62ad --- /dev/null +++ b/spec/fixtures/swagger_contracts/strict_contract.yaml @@ -0,0 +1,52 @@ +swagger: 2.0 +info: + version: 1.0.0 + title: Strict Contract +schemes: + - http +consumes: + - application/json +produces: + - application/json +paths: + /strict: + get: + summary: Strict service + operationId: strict + parameters: + - name: Accept + in: header + default: application/json + # - name: body + # in: body + # schema: + # $schema: "http://json-schema.org/draft-03/schema#" + # type: object + # required: true + # properties: + # message: + # type: string + # required: true + responses: + 200: + description: An paged array of pets + headers: + Content-Type: + type: string + default: application/json + schema: + $schema: "http://json-schema.org/draft-03/schema#" + type: "object" + required: true + properties: + devices: + type: "array" + minItems: 2 + items: + type: "string" + required: true + default: "/dev/<%= values[:device_id].tap do values[:device_id] = values[:device_id] + 1 end %>" + pattern: "^/dev/[\\d]+$" + required: true + uniqueItems: true + diff --git a/spec/fixtures/swagger_contracts/templating_contract.yaml b/spec/fixtures/swagger_contracts/templating_contract.yaml new file mode 100644 index 0000000..6eb540c --- /dev/null +++ b/spec/fixtures/swagger_contracts/templating_contract.yaml @@ -0,0 +1,52 @@ +swagger: 2.0 +info: + version: 1.0.0 + title: Templated Contract + license: + name: MIT +schemes: + - http +consumes: + - application/json +produces: + - application/json +paths: + /echo: + get: + summary: Hello! + operationId: hello + parameters: + - name: Accept + in: header + default: application/json + - name: Custom-Auth-Token + in: header + default: <%= auth_token %> + - name: X-Message + in: header + default: <%= key %> + - name: body + in: body + schema: + $schema: "http://json-schema.org/draft-03/schema#" + type: object + required: true + properties: + message: + type: string + required: true + responses: + 200: + description: An paged array of pets + headers: + Content-Type: + type: string + schema: + $schema: "http://json-schema.org/draft-03/schema#" + type: object + required: true + properties: + message: + type: string + required: true + default: <%= req['HEADERS']['X-Message'].reverse %> diff --git a/spec/fixtures_helper.rb b/spec/fixtures_helper.rb new file mode 100644 index 0000000..c96460a --- /dev/null +++ b/spec/fixtures_helper.rb @@ -0,0 +1,5 @@ +DEFAULT_CONTRACT_FORMAT = ENV['PACTO_DEFAULT_FORMAT'] || 'legacy' +DEFAULT_CONTRACTS_DIR = "spec/fixtures/#{DEFAULT_CONTRACT_FORMAT}_contracts" +SWAGGER_CONTRACTS_DIR = 'spec/fixtures/swagger_contracts' +LEGACY_CONTRACTS_DIR = 'spec/fixtures/legacy_contracts' +DEPRECATED_CONTRACTS_DIR = 'spec/fixtures/deprecated_contracts' diff --git a/spec/integration/e2e_spec.rb b/spec/integration/e2e_spec.rb index 5e67a2e..2585545 100644 --- a/spec/integration/e2e_spec.rb +++ b/spec/integration/e2e_spec.rb @@ -1,7 +1,7 @@ # -*- encoding : utf-8 -*- describe Pacto do - let(:contract_path) { 'spec/fixtures/contracts/simple_contract.json' } - let(:strict_contract_path) { 'spec/fixtures/contracts/strict_contract.json' } + let(:contract_path) { Dir["#{DEFAULT_CONTRACTS_DIR}/simple_contract.{json,yaml}"].first } + let(:strict_contract_path) { Dir["#{DEFAULT_CONTRACTS_DIR}/strict_contract.{json,yaml}"].first } before :all do WebMock.allow_net_connect! @@ -14,16 +14,17 @@ end end - it 'verifies the contract against a producer' do + it 'verifies the contract against a producer', :legacy do # FIXME: Does this really test what it says it does?? - contract = described_class.load_contracts(contract_path, 'http://localhost:8000') - expect(contract.simulate_consumers.map(&:successful?).uniq).to eq([true]) + contract = described_class.load_contracts(contract_path, 'http://localhost:8000', DEFAULT_CONTRACT_FORMAT) + investigations = contract.simulate_consumers + expect(investigations.map(&:successful?).uniq).to eq([true]), investigations.map(&:to_s).join end end context 'Stubbing a collection of contracts' do it 'generates a server that stubs the contract for consumers' do - contracts = described_class.load_contracts(contract_path, 'http://dummyprovider.com') + contracts = described_class.load_contracts(contract_path, 'http://dummyprovider.com', DEFAULT_CONTRACT_FORMAT) contracts.stub_providers response = get_json('http://dummyprovider.com/hello') @@ -38,7 +39,7 @@ c.register_hook Pacto::Hooks::ERBHook.new end - contracts = described_class.load_contracts 'spec/fixtures/contracts/', 'http://dummyprovider.com' + contracts = described_class.load_contracts DEFAULT_CONTRACTS_DIR, 'http://dummyprovider.com', DEFAULT_CONTRACT_FORMAT contracts.stub_providers(device_id: 42) login_response = get_json('http://dummyprovider.com/hello') diff --git a/spec/integration/forensics/integration_matcher_spec.rb b/spec/integration/forensics/integration_matcher_spec.rb index 26537c2..28daf53 100644 --- a/spec/integration/forensics/integration_matcher_spec.rb +++ b/spec/integration/forensics/integration_matcher_spec.rb @@ -3,8 +3,8 @@ module Pacto describe '#have_investigated' do - let(:contract_path) { 'spec/fixtures/contracts/simple_contract.json' } - let(:strict_contract_path) { 'spec/fixtures/contracts/strict_contract.json' } + let(:contract_path) { Dir["#{DEFAULT_CONTRACTS_DIR}/simple_contract.{json,yaml}"].first } + let(:strict_contract_path) { Dir["#{DEFAULT_CONTRACTS_DIR}/strict_contract.{json,yaml}"].first } around :each do |example| run_pacto do @@ -32,7 +32,7 @@ def play_bad_response context 'successful investigations' do let(:contracts) do - Pacto.load_contracts 'spec/fixtures/contracts/', 'http://dummyprovider.com' + Pacto.load_contracts DEFAULT_CONTRACTS_DIR, 'http://dummyprovider.com', DEFAULT_CONTRACT_FORMAT end before(:each) do @@ -55,17 +55,17 @@ def play_bad_response expect(Pacto).to_not have_failed_investigations # Increasingly strict assertions - expect(Pacto).to have_investigated('Simple Contract') - expect(Pacto).to have_investigated('Simple Contract').with_request(headers: hash_including('Accept' => 'application/json')) - expect(Pacto).to have_investigated('Simple Contract').with_request(http_method: :get, url: 'http://dummyprovider.com/hello') + expect(Pacto).to have_investigated(/Simple Contract/) + expect(Pacto).to have_investigated(/Simple Contract/).with_request(headers: hash_including('Accept' => 'application/json')) + expect(Pacto).to have_investigated(/Simple Contract/).with_request(http_method: :get, url: 'http://dummyprovider.com/hello') end it 'supports negative assertions' do - expect(Pacto).to_not have_investigated('Strict Contract') + expect(Pacto).to_not have_investigated(/Strict Contract/) Faraday.get('http://dummyprovider.com/strict') do |req| req.headers = { 'Accept' => 'application/json' } end - expect(Pacto).to have_investigated('Strict Contract') + expect(Pacto).to have_investigated(/Strict Contract/) end it 'raises useful error messages' do @@ -77,13 +77,13 @@ def play_bad_response it 'displays Contract investigation problems' do play_bad_response - expect_to_raise(/investigation errors were found:/) { expect(Pacto).to have_investigated('Strict Contract') } + expect_to_raise(/investigation errors were found:/) { expect(Pacto).to have_investigated(/Strict Contract/) } end it 'displays the Contract file' do play_bad_response schema_file_uri = Addressable::URI.convert_path(File.absolute_path strict_contract_path).to_s - expect_to_raise(/in schema #{schema_file_uri}/) { expect(Pacto).to have_investigated('Strict Contract') } + expect_to_raise(/in schema #{schema_file_uri}/) { expect(Pacto).to have_investigated(/Strict Contract/) } end end end diff --git a/spec/integration/rspec_spec.rb b/spec/integration/rspec_spec.rb index 27c9baf..bf46911 100644 --- a/spec/integration/rspec_spec.rb +++ b/spec/integration/rspec_spec.rb @@ -2,8 +2,8 @@ require 'pacto/rspec' describe 'pacto/rspec' do - let(:contract_path) { 'spec/fixtures/contracts/simple_contract.json' } - let(:strict_contract_path) { 'spec/fixtures/contracts/strict_contract.json' } + let(:contract_path) { Dir["#{DEFAULT_CONTRACTS_DIR}/simple_contract.{json,yaml}"].first } + let(:strict_contract_path) { Dir["#{DEFAULT_CONTRACTS_DIR}/strict_contract.{json,yaml}"].first } around :each do |example| run_pacto do @@ -31,7 +31,7 @@ def play_bad_response context 'successful investigations' do let(:contracts) do - Pacto.load_contracts 'spec/fixtures/contracts/', 'http://dummyprovider.com' + Pacto.load_contracts DEFAULT_CONTRACTS_DIR, 'http://dummyprovider.com', DEFAULT_CONTRACT_FORMAT end before(:each) do @@ -56,7 +56,7 @@ def play_bad_response # Increasingly strict assertions expect(Pacto).to have_validated(:get, 'http://dummyprovider.com/hello') expect(Pacto).to have_validated(:get, 'http://dummyprovider.com/hello').with(headers: { 'Accept' => 'application/json' }) - expect(Pacto).to have_validated(:get, 'http://dummyprovider.com/hello').against_contract(/simple_contract.json/) + expect(Pacto).to have_validated(:get, 'http://dummyprovider.com/hello').against_contract(/simple_contract/) end it 'supports negative assertions' do diff --git a/spec/integration/templating_spec.rb b/spec/integration/templating_spec.rb index c6f7fc4..c9b61a1 100644 --- a/spec/integration/templating_spec.rb +++ b/spec/integration/templating_spec.rb @@ -2,8 +2,8 @@ require 'securerandom' describe 'Templating' do - let(:contract_path) { 'spec/fixtures/contracts/templating_contract.json' } - let(:contracts) { Pacto.load_contracts(contract_path, 'http://dummyprovider.com') } + let(:contract_path) { Dir["#{DEFAULT_CONTRACTS_DIR}/templating_contract.{json,yaml}"].first } + let(:contracts) { Pacto.load_contracts(contract_path, 'http://dummyprovider.com', DEFAULT_CONTRACT_FORMAT) } let(:key) { SecureRandom.hex } let(:auth_token) { SecureRandom.hex } diff --git a/spec/pacto/dummy_server/jruby_workaround_helper.rb b/spec/pacto/dummy_server/jruby_workaround_helper.rb index 281391c..265a73e 100644 --- a/spec/pacto/dummy_server/jruby_workaround_helper.rb +++ b/spec/pacto/dummy_server/jruby_workaround_helper.rb @@ -1,4 +1,6 @@ # -*- encoding : utf-8 -*- +require 'pacto/test_helper' + module Pacto module DummyServer module JRubyWorkaroundHelper @@ -13,7 +15,7 @@ def run_pacto yield @server.terminate else - with_pacto(port: 8000, strip_port: true) do + with_pacto(port: 8000, strip_port: true, directory: DEFAULT_CONTRACTS_DIR) do yield end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 7d626f5..49930b2 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -7,6 +7,7 @@ require 'fabrication' require 'stringio' require 'rspec' +require 'fixtures_helper' # Pre-load shared examples require_relative 'unit/pacto/actor_spec.rb' diff --git a/spec/unit/pacto/contract_factory_spec.rb b/spec/unit/pacto/contract_factory_spec.rb index d5510a8..c9d7a46 100644 --- a/spec/unit/pacto/contract_factory_spec.rb +++ b/spec/unit/pacto/contract_factory_spec.rb @@ -5,7 +5,7 @@ module Pacto describe ContractFactory do let(:host) { 'http://localhost' } let(:contract_name) { 'contract' } - let(:contracts_path) { %w(spec fixtures contracts) } + let(:contracts_path) { LEGACY_CONTRACTS_DIR } let(:contract_path) { File.join(contracts_path, "#{contract_name}.json") } let(:contract_files) { [contract_path, contract_path] } subject(:contract_factory) { described_class } diff --git a/spec/unit/pacto/generator/legacy_contract_generator_spec.rb b/spec/unit/pacto/generator/legacy_contract_generator_spec.rb index e764288..abe7e40 100644 --- a/spec/unit/pacto/generator/legacy_contract_generator_spec.rb +++ b/spec/unit/pacto/generator/legacy_contract_generator_spec.rb @@ -1,7 +1,7 @@ # -*- encoding : utf-8 -*- module Pacto module Generator - describe NativeContractGenerator do + describe NativeContractGenerator, :legacy do let(:record_host) do 'http://example.com' end diff --git a/spec/unit/pacto/legacy_contract_factory_spec.rb b/spec/unit/pacto/legacy_contract_factory_spec.rb index bc7fc7d..aac288c 100644 --- a/spec/unit/pacto/legacy_contract_factory_spec.rb +++ b/spec/unit/pacto/legacy_contract_factory_spec.rb @@ -2,10 +2,10 @@ require 'spec_helper' module Pacto - describe NativeContractFactory do + describe NativeContractFactory, :legacy do let(:host) { 'http://localhost' } let(:contract_name) { 'contract' } - let(:contracts_path) { %w(spec fixtures contracts) } + let(:contracts_path) { LEGACY_CONTRACTS_DIR } let(:contract_path) { File.join(contracts_path, "#{contract_name}.json") } subject(:contract_factory) { described_class.new } @@ -15,7 +15,7 @@ module Pacto end context 'deprecated contracts' do - let(:contracts_path) { %w(spec fixtures deprecated_contracts) } + let(:contracts_path) { DEPRECATED_CONTRACTS_DIR } let(:contract_name) { 'deprecated_contract' } it 'can still be loaded' do contract = contract_factory.build_from_file(contract_path, host) diff --git a/spec/unit/pacto/pacto_spec.rb b/spec/unit/pacto/pacto_spec.rb index b77785e..b97684b 100644 --- a/spec/unit/pacto/pacto_spec.rb +++ b/spec/unit/pacto/pacto_spec.rb @@ -41,7 +41,7 @@ def mock_investigation(errors) expect(Pacto::ContractSet).to receive(:new) do |contracts| contracts.each { |contract| expect(contract).to be_a_kind_of(Pacto::Contract) } end - described_class.load_contracts('spec/fixtures/contracts/', host) + described_class.load_contracts(DEFAULT_CONTRACTS_DIR, host, DEFAULT_CONTRACT_FORMAT) end end end diff --git a/spec/unit/pacto/stubs/uri_pattern_spec.rb b/spec/unit/pacto/stubs/uri_pattern_spec.rb index 8588747..8e4812c 100644 --- a/spec/unit/pacto/stubs/uri_pattern_spec.rb +++ b/spec/unit/pacto/stubs/uri_pattern_spec.rb @@ -21,14 +21,14 @@ module Pacto expect(uri_pattern.pattern).to eql('{scheme}://myhost.com/stuff{?anyvars*}') end - it 'convers segments preceded by : into variables', :deprecated do + it 'converts segments preceded by : into variables', :deprecated do request = Fabricate(:request_clause, host: 'myhost.com', path: '/:id') uri_pattern = UriPattern.for(request) expect(uri_pattern.keys).to include('id') expect(uri_pattern.pattern).to_not include(':id') end - it 'creates a regex that does not allow additional path elements' do + it 'creates a regex that does not allow additional path elements', :deprecated do request = Fabricate(:request_clause, host: 'myhost.com', path: '/:id') pattern = UriPattern.for(request) expect(pattern).to match('http://myhost.com/foo') diff --git a/spec/unit/pacto/swagger_contract_factory_spec.rb b/spec/unit/pacto/swagger_contract_factory_spec.rb index 34049ca..1393afe 100644 --- a/spec/unit/pacto/swagger_contract_factory_spec.rb +++ b/spec/unit/pacto/swagger_contract_factory_spec.rb @@ -2,7 +2,7 @@ module Pacto module Generator describe SwaggerContractFactory do - let(:swagger_file) { 'spec/fixtures/swagger/petstore.yaml' } + let(:swagger_file) { "#{SWAGGER_CONTRACTS_DIR}/petstore.yaml" } let(:expected_schema) do { 'type' => 'array', diff --git a/spec/unit/pacto/swagger_contract_spec.rb b/spec/unit/pacto/swagger_contract_spec.rb index 25bfa4b..83101a2 100644 --- a/spec/unit/pacto/swagger_contract_spec.rb +++ b/spec/unit/pacto/swagger_contract_spec.rb @@ -24,7 +24,7 @@ module Pacto "'' end let(:swagger_definition) do - ::Swagger.build(swagger_yaml, format: :yaml) + ::Swagger.build_api(swagger_yaml, format: :yaml) end let(:api_operation) do swagger_definition.operations.first