rspec_api_blueprint_matchers 0.1.2
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 +7 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Dockerfile +24 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +77 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/codeship-services.yml +7 -0
- data/codeship-steps.yml +4 -0
- data/lib/rspec_api_blueprint_matchers.rb +1 -0
- data/lib/rspec_apib.rb +41 -0
- data/lib/rspec_apib/config.rb +17 -0
- data/lib/rspec_apib/elements.rb +20 -0
- data/lib/rspec_apib/elements/annotation.rb +7 -0
- data/lib/rspec_apib/elements/array.rb +9 -0
- data/lib/rspec_apib/elements/asset.rb +7 -0
- data/lib/rspec_apib/elements/base.rb +97 -0
- data/lib/rspec_apib/elements/category.rb +7 -0
- data/lib/rspec_apib/elements/copy.rb +7 -0
- data/lib/rspec_apib/elements/data_structure.rb +7 -0
- data/lib/rspec_apib/elements/href_variables.rb +13 -0
- data/lib/rspec_apib/elements/http_headers.rb +27 -0
- data/lib/rspec_apib/elements/http_message_payload.rb +45 -0
- data/lib/rspec_apib/elements/http_request.rb +59 -0
- data/lib/rspec_apib/elements/http_response.rb +35 -0
- data/lib/rspec_apib/elements/http_transaction.rb +58 -0
- data/lib/rspec_apib/elements/member.rb +21 -0
- data/lib/rspec_apib/elements/object.rb +7 -0
- data/lib/rspec_apib/elements/parse_result.rb +7 -0
- data/lib/rspec_apib/elements/resource.rb +24 -0
- data/lib/rspec_apib/elements/source_map.rb +7 -0
- data/lib/rspec_apib/elements/string.rb +9 -0
- data/lib/rspec_apib/elements/templated_href.rb +43 -0
- data/lib/rspec_apib/elements/transition.rb +22 -0
- data/lib/rspec_apib/engine.rb +0 -0
- data/lib/rspec_apib/extractors.rb +2 -0
- data/lib/rspec_apib/extractors/http_transaction.rb +23 -0
- data/lib/rspec_apib/extractors/resource.rb +23 -0
- data/lib/rspec_apib/parser.rb +79 -0
- data/lib/rspec_apib/request.rb +44 -0
- data/lib/rspec_apib/response.rb +39 -0
- data/lib/rspec_apib/rspec.rb +40 -0
- data/lib/rspec_apib/transaction_coverage_report.rb +36 -0
- data/lib/rspec_apib/transaction_coverage_validator.rb +49 -0
- data/lib/rspec_apib/transaction_validator.rb +44 -0
- data/lib/rspec_apib/transcluder.rb +30 -0
- data/lib/rspec_apib/version.rb +3 -0
- data/lib/transcluder.rb +3 -0
- data/rspec_api_blueprint_matchers.gemspec +29 -0
- metadata +182 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
require "rspec_apib/transcluder"
|
2
|
+
require "rspec_apib/extractors"
|
3
|
+
require "rspec_apib/elements"
|
4
|
+
require "open3"
|
5
|
+
require "json"
|
6
|
+
module RSpecApib
|
7
|
+
class Parser
|
8
|
+
|
9
|
+
def initialize(transcluder: Transcluder, base_element: Element::Base)
|
10
|
+
self.transcluder = transcluder
|
11
|
+
self.base_element = base_element
|
12
|
+
end
|
13
|
+
|
14
|
+
def parse_file(file)
|
15
|
+
self.parsed_file = call_parser(file)
|
16
|
+
document, index = parse_document
|
17
|
+
self.document = document
|
18
|
+
self.index = index
|
19
|
+
document
|
20
|
+
end
|
21
|
+
|
22
|
+
def resources
|
23
|
+
index[Element::Resource]
|
24
|
+
end
|
25
|
+
|
26
|
+
def categories
|
27
|
+
index[Element::Category]
|
28
|
+
end
|
29
|
+
|
30
|
+
def copies
|
31
|
+
index[Element::Copy]
|
32
|
+
end
|
33
|
+
|
34
|
+
def transitions
|
35
|
+
index[Element::Transition]
|
36
|
+
end
|
37
|
+
|
38
|
+
def http_transactions
|
39
|
+
index[Element::HttpTransaction]
|
40
|
+
end
|
41
|
+
|
42
|
+
def http_requests
|
43
|
+
index[Element::HttpRequest]
|
44
|
+
end
|
45
|
+
|
46
|
+
def http_responses
|
47
|
+
index[Element::HttpResponse]
|
48
|
+
end
|
49
|
+
|
50
|
+
def asset
|
51
|
+
index[Element::Asset]
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
attr_accessor :transcluder, :parsed_file, :document, :base_element, :index
|
57
|
+
|
58
|
+
def parse_document
|
59
|
+
base_element.parse_root(parsed_file)
|
60
|
+
end
|
61
|
+
|
62
|
+
def bin_path
|
63
|
+
"drafter"
|
64
|
+
end
|
65
|
+
|
66
|
+
def call_parser(file)
|
67
|
+
op = nil
|
68
|
+
Open3.popen3("#{bin_path} -f json") do |stdin, stdout, stderr, wait_thr|
|
69
|
+
transcluder.each_line(file) do |line|
|
70
|
+
stdin.write line
|
71
|
+
end
|
72
|
+
stdin.close
|
73
|
+
op = stdout.read
|
74
|
+
exit_status = wait_thr.value
|
75
|
+
end
|
76
|
+
JSON.parse op
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module RSpecApib
|
2
|
+
class Request
|
3
|
+
def initialize(request)
|
4
|
+
self.raw_request = request
|
5
|
+
end
|
6
|
+
|
7
|
+
def request_method
|
8
|
+
raw_request.method
|
9
|
+
end
|
10
|
+
|
11
|
+
def url
|
12
|
+
raw_request.url
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate_body_with_json_schema?
|
16
|
+
request_method != :get && is_json?
|
17
|
+
end
|
18
|
+
|
19
|
+
# The request body
|
20
|
+
# @return [String] The request body - always as a string
|
21
|
+
def body
|
22
|
+
raw_request.body
|
23
|
+
end
|
24
|
+
|
25
|
+
def content_type
|
26
|
+
headers["Content-Type"]
|
27
|
+
end
|
28
|
+
|
29
|
+
def headers
|
30
|
+
raw_request.request_headers
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
attr_accessor :raw_request
|
37
|
+
|
38
|
+
def is_json?
|
39
|
+
content_type =~ /json/
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "json"
|
2
|
+
module RSpecApib
|
3
|
+
class Response
|
4
|
+
def initialize(response)
|
5
|
+
self.raw_response = response
|
6
|
+
end
|
7
|
+
|
8
|
+
def status
|
9
|
+
raw_response.status.to_s
|
10
|
+
end
|
11
|
+
|
12
|
+
# The response body
|
13
|
+
# @return [String] The response body - always as a string
|
14
|
+
def body
|
15
|
+
JSON.generate raw_response.body
|
16
|
+
end
|
17
|
+
|
18
|
+
def validate_body_with_json_schema?
|
19
|
+
is_json?
|
20
|
+
end
|
21
|
+
|
22
|
+
def content_type
|
23
|
+
headers["Content-Type"]
|
24
|
+
end
|
25
|
+
|
26
|
+
def headers
|
27
|
+
raw_response.response_headers
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
attr_accessor :raw_response
|
34
|
+
|
35
|
+
def is_json?
|
36
|
+
content_type=~/json/
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "rspec/matchers"
|
2
|
+
require "rspec_apib/transaction_validator"
|
3
|
+
require "rspec_apib/transaction_coverage_validator"
|
4
|
+
RSpec::Matchers.define :match_api_docs_for do |path:, request_method:, content_type:, parser: RSpecApib.config.default_parser|
|
5
|
+
error_messages = []
|
6
|
+
match do |actual|
|
7
|
+
if actual.nil?
|
8
|
+
error_messages << "Expected the transaction to match api docs for #{method}:#{path} but it was nil"
|
9
|
+
false
|
10
|
+
elsif !parser.is_a?(RSpecApib::Parser)
|
11
|
+
error_messages << "Expected the transaction to match api docs for #{method}:#{path} but the provided parser was invalid"
|
12
|
+
false
|
13
|
+
else
|
14
|
+
::RSpecApib::TransactionValidator.new(path: path, request_method: request_method, content_type: content_type, parser: parser).validate(request: ::RSpecApib.normalize_request(actual.request), response: ::RSpecApib.normalize_response(actual.response), error_messages: error_messages)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
failure_message do |actual|
|
20
|
+
error_messages.join("\n")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
RSpec::Matchers.define :have_covered_all_api_documentation do | parser: RSpecApib.config.default_parser |
|
25
|
+
error_messages = []
|
26
|
+
Transaction = Struct.new(:request, :response)
|
27
|
+
match do |actual|
|
28
|
+
error_messages << "No API calls were made" if actual.empty?
|
29
|
+
|
30
|
+
normalized_transactions = actual.map do |tx|
|
31
|
+
Transaction.new(RSpecApib.normalize_request(tx.request), RSpecApib.normalize_response(tx.response))
|
32
|
+
end
|
33
|
+
::RSpecApib::TransactionCoverageValidator.new(parser: parser).validate(transactions: normalized_transactions, error_messages: error_messages)
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
failure_message do |actual|
|
38
|
+
error_messages.join("\n")
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module RSpecApib
|
2
|
+
class TransactionCoverageReport
|
3
|
+
def initialize(transactions:, parser: RSpecApib.config.default_parser)
|
4
|
+
self.transactions = transactions
|
5
|
+
self.parser = parser
|
6
|
+
end
|
7
|
+
|
8
|
+
def uncovered_transactions
|
9
|
+
documented_transaction_tracker = parser.http_transactions.inject({}) do |acc, t|
|
10
|
+
acc[t]=false
|
11
|
+
acc
|
12
|
+
end
|
13
|
+
transactions.each do |requested_tx|
|
14
|
+
matching_transactions = documented_transaction_tracker.keys.each do |dtx|
|
15
|
+
documented_transaction_tracker[dtx] = true if dtx.matches?(requested_tx.request, requested_tx.response)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
documented_transaction_tracker.reject {|k,v| v}.keys
|
19
|
+
end
|
20
|
+
|
21
|
+
def undocumented_transactions
|
22
|
+
results = []
|
23
|
+
transactions.each do |requested_tx|
|
24
|
+
match = parser.http_transactions.find do |doc_txn|
|
25
|
+
doc_txn.matches?(requested_tx.request, requested_tx.response)
|
26
|
+
end
|
27
|
+
results << requested_tx if match.nil?
|
28
|
+
end
|
29
|
+
results
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
attr_accessor :transactions, :parser
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "rspec_apib/transaction_coverage_report"
|
2
|
+
module RSpecApib
|
3
|
+
class TransactionCoverageValidator
|
4
|
+
def initialize(parser: RSpecApib.config.default_parser)
|
5
|
+
self.parser = parser
|
6
|
+
end
|
7
|
+
|
8
|
+
def validate(transactions:, error_messages:)
|
9
|
+
errors = []
|
10
|
+
reporter = TransactionCoverageReport.new(transactions: transactions, parser: parser)
|
11
|
+
uncovered = reporter.uncovered_transactions
|
12
|
+
if uncovered.length > 0
|
13
|
+
uncovered.each do |tx|
|
14
|
+
errors << self.class.uncovered_tx_message(tx)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
undocumented = reporter.undocumented_transactions
|
18
|
+
if undocumented.length > 0
|
19
|
+
undocumented.each do |tx|
|
20
|
+
errors << self.class.undocumented_tx_message(tx)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
if errors.length > 0
|
24
|
+
error_messages.concat errors
|
25
|
+
error_messages << "Coverage Summary: #{uncovered.length} uncovered and #{undocumented.length} undocumented transactions"
|
26
|
+
false
|
27
|
+
else
|
28
|
+
true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
attr_accessor :parser
|
35
|
+
|
36
|
+
def matched_transaction(request:, response:)
|
37
|
+
parser.http_transactions.find { |t| t.matches?(request, response, options: {validate_request_schema: :never, validate_response_schema: :never}) }
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.uncovered_tx_message(tx)
|
41
|
+
"#{tx.request.request_method.to_s.upcase} #{tx.request.url} with response (#{tx.response.content_type}) status #{tx.response.status}- Not covered"
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.undocumented_tx_message(tx)
|
45
|
+
"#{tx.request.request_method.upcase} #{tx.request.url} with response (#{tx.response.content_type}) status #{tx.response.status} - Not documented"
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module RSpecApib
|
2
|
+
class TransactionValidator
|
3
|
+
# validate_request_schema can be :always, :never, :when_defined
|
4
|
+
def initialize(path:, request_method:, content_type:, validate_request_schema: :always, validate_response_schema: :always, parser: RSpecApib.config.default_parser)
|
5
|
+
self.path = path
|
6
|
+
self.request_method = request_method
|
7
|
+
self.content_type = content_type
|
8
|
+
self.parser = parser
|
9
|
+
self.validate_request_schema = validate_request_schema
|
10
|
+
self.validate_response_schema = validate_response_schema
|
11
|
+
end
|
12
|
+
|
13
|
+
def validate(request:, response:, error_messages:, options: {})
|
14
|
+
candidates = transaction_candidates(request: request, response: response, options: options)
|
15
|
+
results = candidates.map do |candidate|
|
16
|
+
candidate.validate_schema(request, response, validate_request_schema: validate_request_schema, validate_response_schema: validate_response_schema)
|
17
|
+
end
|
18
|
+
|
19
|
+
if results.empty?
|
20
|
+
error_messages << "No candidates for #{request.inspect} with response #{response.inspect}"
|
21
|
+
return false
|
22
|
+
end
|
23
|
+
|
24
|
+
return true unless results.flatten.find {|r| !r[:request_errors].empty? || !r[:response_errors].empty?}
|
25
|
+
results.each do |result|
|
26
|
+
error_messages << "The request validation failed - reasons #{result[:request_errors].join("\n")}" unless result[:request_errors].empty?
|
27
|
+
error_messages << "The response validation failed - reasons #{result[:response_errors].join("\n")}" unless result[:response_errors].empty?
|
28
|
+
end
|
29
|
+
false
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def transaction_candidates(request:, response:, options: {})
|
35
|
+
transactions = parser.http_transactions.select do |t|
|
36
|
+
t.potential_match?(path: path, request_method: request_method, content_type: content_type)
|
37
|
+
end
|
38
|
+
transactions.select { |t| t.matches?(request, response, options: options) }
|
39
|
+
end
|
40
|
+
|
41
|
+
attr_accessor :path, :request_method, :content_type, :parser, :validate_request_schema, :validate_response_schema
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module RSpecApib::Transcluder
|
2
|
+
REGEX = /:\[[^\]]*\]\(([^\)]*)\)/
|
3
|
+
def self.each_line(file, &block)
|
4
|
+
File.readlines(file, encoding: "UTF-8").each do |line|
|
5
|
+
if needs_transclude?(line)
|
6
|
+
transclude(file, line, &block)
|
7
|
+
else
|
8
|
+
yield line
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.needs_transclude?(line)
|
14
|
+
line =~ REGEX
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.transclude(file, line, &block)
|
18
|
+
line.gsub!(REGEX) do |match|
|
19
|
+
transclude_file = $1
|
20
|
+
unless transclude_file =~ /^\//
|
21
|
+
transclude_file = File.expand_path(transclude_file, File.dirname(file))
|
22
|
+
end
|
23
|
+
each_line(transclude_file, &block)
|
24
|
+
""
|
25
|
+
end
|
26
|
+
yield line
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
end
|
data/lib/transcluder.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rspec_apib/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rspec_api_blueprint_matchers"
|
8
|
+
spec.version = RSpecApib::VERSION
|
9
|
+
spec.authors = ["Shift Commerce Ltd"]
|
10
|
+
spec.email = ["team@shiftcommerce.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{API Blueprint Tools For RSpec}
|
13
|
+
spec.description = %q{API Blueprint Tools For RSpec - Matching http transactions against an API Blueprint document to ensure the API that you are implementing matches the API that is documented which your clients will expect to be the case.}
|
14
|
+
spec.homepage = "https://github.com/shiftcommerce/rspec_api_blueprint_matchers"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
spec.add_dependency "addressable", ">= 2.5.0"
|
24
|
+
spec.add_dependency "json-schema", ">= 2.8.0"
|
25
|
+
spec.add_dependency "rspec", ">= 3.0"
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
27
|
+
spec.add_development_dependency "byebug"
|
28
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rspec_api_blueprint_matchers
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Shift Commerce Ltd
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-05-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: addressable
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.5.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.5.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: json-schema
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.8.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.8.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.14'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.14'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: byebug
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '10.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '10.0'
|
97
|
+
description: API Blueprint Tools For RSpec - Matching http transactions against an
|
98
|
+
API Blueprint document to ensure the API that you are implementing matches the API
|
99
|
+
that is documented which your clients will expect to be the case.
|
100
|
+
email:
|
101
|
+
- team@shiftcommerce.com
|
102
|
+
executables: []
|
103
|
+
extensions: []
|
104
|
+
extra_rdoc_files: []
|
105
|
+
files:
|
106
|
+
- ".gitignore"
|
107
|
+
- ".rspec"
|
108
|
+
- ".travis.yml"
|
109
|
+
- Dockerfile
|
110
|
+
- Gemfile
|
111
|
+
- LICENSE.txt
|
112
|
+
- README.md
|
113
|
+
- Rakefile
|
114
|
+
- bin/console
|
115
|
+
- bin/setup
|
116
|
+
- codeship-services.yml
|
117
|
+
- codeship-steps.yml
|
118
|
+
- lib/rspec_api_blueprint_matchers.rb
|
119
|
+
- lib/rspec_apib.rb
|
120
|
+
- lib/rspec_apib/config.rb
|
121
|
+
- lib/rspec_apib/elements.rb
|
122
|
+
- lib/rspec_apib/elements/annotation.rb
|
123
|
+
- lib/rspec_apib/elements/array.rb
|
124
|
+
- lib/rspec_apib/elements/asset.rb
|
125
|
+
- lib/rspec_apib/elements/base.rb
|
126
|
+
- lib/rspec_apib/elements/category.rb
|
127
|
+
- lib/rspec_apib/elements/copy.rb
|
128
|
+
- lib/rspec_apib/elements/data_structure.rb
|
129
|
+
- lib/rspec_apib/elements/href_variables.rb
|
130
|
+
- lib/rspec_apib/elements/http_headers.rb
|
131
|
+
- lib/rspec_apib/elements/http_message_payload.rb
|
132
|
+
- lib/rspec_apib/elements/http_request.rb
|
133
|
+
- lib/rspec_apib/elements/http_response.rb
|
134
|
+
- lib/rspec_apib/elements/http_transaction.rb
|
135
|
+
- lib/rspec_apib/elements/member.rb
|
136
|
+
- lib/rspec_apib/elements/object.rb
|
137
|
+
- lib/rspec_apib/elements/parse_result.rb
|
138
|
+
- lib/rspec_apib/elements/resource.rb
|
139
|
+
- lib/rspec_apib/elements/source_map.rb
|
140
|
+
- lib/rspec_apib/elements/string.rb
|
141
|
+
- lib/rspec_apib/elements/templated_href.rb
|
142
|
+
- lib/rspec_apib/elements/transition.rb
|
143
|
+
- lib/rspec_apib/engine.rb
|
144
|
+
- lib/rspec_apib/extractors.rb
|
145
|
+
- lib/rspec_apib/extractors/http_transaction.rb
|
146
|
+
- lib/rspec_apib/extractors/resource.rb
|
147
|
+
- lib/rspec_apib/parser.rb
|
148
|
+
- lib/rspec_apib/request.rb
|
149
|
+
- lib/rspec_apib/response.rb
|
150
|
+
- lib/rspec_apib/rspec.rb
|
151
|
+
- lib/rspec_apib/transaction_coverage_report.rb
|
152
|
+
- lib/rspec_apib/transaction_coverage_validator.rb
|
153
|
+
- lib/rspec_apib/transaction_validator.rb
|
154
|
+
- lib/rspec_apib/transcluder.rb
|
155
|
+
- lib/rspec_apib/version.rb
|
156
|
+
- lib/transcluder.rb
|
157
|
+
- rspec_api_blueprint_matchers.gemspec
|
158
|
+
homepage: https://github.com/shiftcommerce/rspec_api_blueprint_matchers
|
159
|
+
licenses:
|
160
|
+
- MIT
|
161
|
+
metadata: {}
|
162
|
+
post_install_message:
|
163
|
+
rdoc_options: []
|
164
|
+
require_paths:
|
165
|
+
- lib
|
166
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
167
|
+
requirements:
|
168
|
+
- - ">="
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: '0'
|
171
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
172
|
+
requirements:
|
173
|
+
- - ">="
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: '0'
|
176
|
+
requirements: []
|
177
|
+
rubyforge_project:
|
178
|
+
rubygems_version: 2.6.10
|
179
|
+
signing_key:
|
180
|
+
specification_version: 4
|
181
|
+
summary: API Blueprint Tools For RSpec
|
182
|
+
test_files: []
|