cucumber-blinkbox 0.3.3

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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ Y2MyODE2NDZjYTE4Y2VhNjNhN2VmNmM4MDhkY2EzMmU0MTIyYzNiNQ==
5
+ data.tar.gz: !binary |-
6
+ NmNkZGExNjNkNTcyYWJlZmUxZTVlMjM2YTdiZTVmNzZlYTIwNjQzMQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZDI5MTIwZGJlOTQ2NzkyZDU5YzczYzFhNDczYWJiNjU1M2I0MjM4NzNkYjc4
10
+ ZjkyNGU1MTIwZjM1OTVmNTM0YjA3NjMzOTIzZjIzNzNiNTY5Y2NiOGMyMDEy
11
+ Mzg2MmE1MTgwOWVmNjZjZmMzMTYyNGQxZmY4NWE2MDQyNGJlOWU=
12
+ data.tar.gz: !binary |-
13
+ YjU4ZGI4YzhkYjZmMDlhNmMxM2YwNTdhYmQzNDRjZjJhZTk2MTMxNDVhYjI4
14
+ OTY5MWI3ZjM5YjQ1MTFhYzViYzNlYmQ4M2E3NWVhYWNmMTIzZTE2Y2Y3MGYy
15
+ ZGY5ZThjMzBlYWJjOGI2MjI2M2NkY2IyMDQ3ODgzYTdmMDRkMzU=
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.3
@@ -0,0 +1,6 @@
1
+ require "cucumber/blinkbox/environment"
2
+ require "cucumber/blinkbox/data_dependencies"
3
+ require "cucumber/blinkbox/subjects"
4
+ require "cucumber/blinkbox/requests"
5
+ require "cucumber/blinkbox/responses"
6
+ require "cucumber/blinkbox/response_validation"
@@ -0,0 +1,31 @@
1
+ module KnowsAboutDataDependencies
2
+ ::TEST_CONFIG ||= {}
3
+
4
+ def self.extended(base)
5
+ base.instance_eval do
6
+ path = TEST_CONFIG["data.yml"] || "config/data.yml"
7
+ raise "The data dependencies file does not exist at #{path}" unless File.exist?(path)
8
+ @data_dependencies = YAML.load_file(path)
9
+ end
10
+ end
11
+
12
+ def data_for_a(object, which: nil, but_isnt: nil, instances: nil)
13
+ raise ArgumentError, "Please specify a condition using `which:`" if which.nil?
14
+ data = @data_dependencies[object.to_s][which] rescue nil
15
+
16
+ if data.respond_to? :sample
17
+ data.delete_if { |item| item == but_isnt } if but_isnt
18
+ if instances
19
+ pending "Test error: There are not enough examples defined for a #{object} which #{which}" unless data.size >= instances
20
+ data = data.sample(instances)
21
+ else
22
+ data = data.sample
23
+ end
24
+ end
25
+
26
+ pending "Test error: There is no data dependency defined for a #{object} which #{which}" unless data
27
+ data
28
+ end
29
+ end
30
+
31
+ World(KnowsAboutDataDependencies)
@@ -0,0 +1,35 @@
1
+ module KnowsAboutTheEnvironment
2
+ ::TEST_CONFIG ||= {}
3
+
4
+ class EnvStruct
5
+ def initialize(env)
6
+ @env = env
7
+ end
8
+ def [](key)
9
+ value = @env[key.to_s]
10
+ value.is_a?(Hash) ? EnvStruct.new(value) : value
11
+ end
12
+ def method_missing(name, *args)
13
+ key = name.to_s.tr("_", " ").downcase
14
+ self[key]
15
+ end
16
+ def inspect
17
+ @env.inspect
18
+ end
19
+ end
20
+
21
+ def self.extended(base)
22
+ base.instance_eval do
23
+ path = TEST_CONFIG["environments.yml"] || "config/environments.yml"
24
+ raise "The environments file does not exist at #{path}" unless File.exist?(path)
25
+ env = YAML.load_file(path)[TEST_CONFIG["server"].downcase]
26
+ raise "Environment '#{TEST_CONFIG["server"]}' is not defined in environments.yml" if env.nil?
27
+ @test_env = EnvStruct.new(env)
28
+ end
29
+ end
30
+
31
+ def test_env
32
+ @test_env
33
+ end
34
+ end
35
+ World(KnowsAboutTheEnvironment)
@@ -0,0 +1,124 @@
1
+ require 'cucumber/formatter/html'
2
+
3
+ module Cucumber
4
+ module Blinkbox
5
+ module Formatter
6
+ class Html < Cucumber::Formatter::Html
7
+
8
+ def timestamp
9
+ Time.now.strftime("%b %e %H:%M:%S")
10
+ end
11
+
12
+ def append_timestamp_to(name)
13
+ "#{name} [#{timestamp}]"
14
+ end
15
+
16
+ def prefix_with_timestamp(name)
17
+ "#{timestamp} #{name}"
18
+ end
19
+
20
+ #override inline JS in the default html formatter to always show cucumber tags regardless expand/collapse state of the scenarios
21
+ #also make all scenarios collapsed on page load
22
+ def inline_js_content
23
+ <<-EOF
24
+
25
+ SCENARIOS = "h3[id^='scenario_'],h3[id^=background_]";
26
+
27
+ $(document).ready(function() {
28
+ $(SCENARIOS).css('cursor', 'pointer');
29
+ $(SCENARIOS).click(function() {
30
+ $(this).siblings().toggle(250, function(){
31
+ $(this).siblings(".tag").show();
32
+ $(this).siblings(".examples").show();
33
+ $(this).siblings(".examples").children().show();
34
+ });
35
+ });
36
+
37
+ $("#collapser").css('cursor', 'pointer');
38
+ $("#collapser").click(function() {
39
+ $(SCENARIOS).siblings().hide();
40
+ $(SCENARIOS).siblings(".tag").show();
41
+ });
42
+
43
+ $("#expander").css('cursor', 'pointer');
44
+ $("#expander").click(function() {
45
+ $(SCENARIOS).siblings().show();
46
+ });
47
+
48
+ $(SCENARIOS).siblings().hide();
49
+ $(SCENARIOS).siblings(".tag").show();
50
+ })
51
+
52
+ function moveProgressBar(percentDone) {
53
+ $("cucumber-header").css('width', percentDone +"%");
54
+ }
55
+ function makeRed(element_id) {
56
+ $('#'+element_id).css('background', '#C40D0D');
57
+ $('#'+element_id).css('color', '#FFFFFF');
58
+ }
59
+ function makeYellow(element_id) {
60
+ $('#'+element_id).css('background', '#FAF834');
61
+ $('#'+element_id).css('color', '#000000');
62
+ }
63
+
64
+ EOF
65
+ end
66
+
67
+ #log scenario name so that console log is more readable
68
+ #also track the position in the all logs array from which out for current scenario starts
69
+ def scenario_name(keyword, name, file_colon_line, source_indent)
70
+ name = append_timestamp_to(name)
71
+ super(keyword, name, file_colon_line, source_indent)
72
+ end
73
+
74
+ def step_name(keyword, step_match, status, source_indent, background, file_colon_line)
75
+ name = super
76
+ append_timestamp_to(name)
77
+ end
78
+
79
+ def build_step(keyword, step_match, status)
80
+ super
81
+ @builder.div(:class => 'step_file') do |div|
82
+ @builder.span do
83
+ @builder << append_timestamp_to("")
84
+ end
85
+ end
86
+ end
87
+
88
+ #override to set color of pending exceptions backtraces to Yellow instead of Red (and thus not make the whole scenario Red)
89
+ def after_table_row(table_row)
90
+ return if @hide_this_step
91
+ print_table_row_messages
92
+ @builder << '</tr>'
93
+ if table_row.exception
94
+ if table_row.exception.instance_of?(Cucumber::Pending)
95
+ @builder.tr do
96
+ @builder.td(:colspan => @col_index.to_s, :class => 'pending') do
97
+ @builder.pre do |pre|
98
+ pre << h(format_exception(table_row.exception))
99
+ end
100
+ end
101
+ end
102
+ set_scenario_color_pending
103
+ else
104
+ @builder.tr do
105
+ @builder.td(:colspan => @col_index.to_s, :class => 'failed') do
106
+ @builder.pre do |pre|
107
+ pre << h(format_exception(table_row.exception))
108
+ end
109
+ end
110
+ end
111
+ set_scenario_color_failed
112
+ end
113
+ end
114
+ if @outline_row
115
+ @outline_row += 1
116
+ end
117
+ @step_number += 1
118
+ move_progress
119
+ end
120
+
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,92 @@
1
+ module KnowsAboutApiRequests
2
+ CONTENT_TYPE = "application/vnd.blinkboxbooks.data.v1+json"
3
+
4
+ def http_client
5
+ @http ||= HTTPClient.new(TEST_CONFIG["proxy"])
6
+ # Ensure we're using the system SSL certs, as per other libraries (like HTTParty)
7
+ @http.ssl_config.set_trust_ca(OpenSSL::X509::DEFAULT_CERT_FILE)
8
+ @http.debug_dev = STDOUT if TEST_CONFIG["debug"]
9
+ #@http.reset_all
10
+ @http
11
+ end
12
+
13
+ def query
14
+ @query ||= {}
15
+ end
16
+
17
+ def request_headers(header = {})
18
+ @request_headers ||= {
19
+ "Accept" => CONTENT_TYPE
20
+ }
21
+ if @access_token
22
+ @request_headers["Authorization"] = "Bearer #{@access_token}"
23
+ else
24
+ @request_headers.delete("Authorization")
25
+ end
26
+ @request_headers.merge!(header)
27
+ @request_headers
28
+ end
29
+
30
+ def set_query_param(name, value)
31
+ if value.respond_to?(:each)
32
+ value.each { |v| set_query_param(name, v) }
33
+ else
34
+ name = name.camel_case
35
+ value = is_enum_param(name) ? value.snake_case(:upper) : value
36
+ current_value = query[name]
37
+
38
+ if current_value.nil?
39
+ query[name] = value
40
+ elsif current_value.is_a?(Array)
41
+ query[name] << value
42
+ else
43
+ query[name] = [current_value, value]
44
+ end
45
+ end
46
+ end
47
+
48
+ def qualified_uri(server, path)
49
+ uri = test_env.servers[server.to_sym]
50
+ raise "Test Error: #{server} doesn't appear to be defined in the environments.yml" if uri.nil?
51
+ File.join(uri.to_s, path)
52
+ end
53
+
54
+ # request methods
55
+
56
+ def http_get(server, path, header = {})
57
+ uri = qualified_uri(server, path)
58
+ params = query if query.count > 0
59
+ @response = http_client.get(uri, query: params, header: request_headers(header), follow_redirect: true)
60
+ end
61
+
62
+ def http_post(server, path, body = {}, header = {})
63
+ uri = qualified_uri(server, path)
64
+ @response = http_client.post(uri, body: format_body(body), header: request_headers({"Content-Type" => CONTENT_TYPE}.merge(header)))
65
+ end
66
+
67
+ def http_put(server, path, body = {}, header = {})
68
+ uri = qualified_uri(server, path)
69
+ @response = http_client.put(uri, body: format_body(body), header: request_headers({"Content-Type" => CONTENT_TYPE}.merge(header)))
70
+ end
71
+
72
+ def http_delete(server, path, header = {})
73
+ uri = qualified_uri(server, path)
74
+ params = query if query.count > 0
75
+ @response = http_client.delete(uri, query: params, header: request_headers(header))
76
+ end
77
+
78
+ private
79
+
80
+ def format_body(body)
81
+ body.is_a?(Hash) ? JSON.dump(body) : body
82
+ end
83
+
84
+ # So that we don't have to put enum parameters in the Gherkin in SCREAMING_SNAKE_CASE this heuristic identifies
85
+ # enum parameters so that we can transform them, meaning an enum value like PURCHASE_DATE can be written in the
86
+ # Gherkin as "purchase date" but still be sent correctly. This heuristic will need updating over time.
87
+ def is_enum_param(name)
88
+ ["bookmarkType", "order", "role"].include?(name)
89
+ end
90
+ end
91
+
92
+ World(KnowsAboutApiRequests)
@@ -0,0 +1,135 @@
1
+ # encoding: utf-8
2
+ module KnowsAboutResponseValidation
3
+ INFINITY = 1.0 / 0.0
4
+
5
+ # Parses a string into a data if that's the specified date type. This is needed for interpreting JSON markup as
6
+ # it doesn't have dates as a first-class concept so they should appear as specifically formatted strings.
7
+ def parse_and_validate_date_if_necessary(value, type)
8
+ # note: cannot use 'case type' as that expands to === which checks for instances of rather than type equality
9
+ if type == Date
10
+ expect(value).to match(/^\d{4}-\d{2}-\d{2}$/)
11
+ Date.strptime(value, "%Y-%m-%d")
12
+ elsif type == DateTime
13
+ expect(value).to match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/)
14
+ DateTime.strptime(value, "%Y-%m-%dT%H:%M:%SZ")
15
+ else
16
+ value
17
+ end
18
+ end
19
+
20
+ def validate_attribute(data, name, options = {})
21
+ type = options[:type]
22
+ type = type.constantize if type.respond_to?(:constantize) # allows it to be passed in as a string or a constant
23
+ expected_value = options[:is] || options[:value]
24
+ expected_value = expected_value.to_type(type) if expected_value.is_a?(String) && !type.nil?
25
+ expected_content = options[:contains]
26
+
27
+ value = parse_and_validate_date_if_necessary(data.deep_key(name), type)
28
+
29
+ begin
30
+ expect(value).to_not be_nil
31
+ expect(value).to be_a_kind_of(type) unless type.nil?
32
+ expect(value).to eq(expected_value) unless expected_value.nil?
33
+ expect(value).to match(/#{Regexp.escape(expected_content)}/) unless expected_content.nil?
34
+ yield value if block_given?
35
+ rescue => e
36
+ message = "'#{name}' is invalid:\n#{e.message}"
37
+ send((options[:warn_only] ? "puts" : "raise").to_sym, message)
38
+ end
39
+ end
40
+
41
+ def validate_entity(data, type, options = {})
42
+ warn_only = options[:warn_only] || []
43
+ validate_attribute(data, "type", type: String, warn_only: warn_only.include?(:type)) { |value| expect(value).to eq("urn:blinkboxbooks:schema:#{type}") }
44
+ validate_attribute(data, "guid", type: String, warn_only: warn_only.include?(:guid)) { |value| expect(value).to start_with "urn:blinkboxbooks:id:#{type}:#{data["id"]}" }
45
+ end
46
+
47
+ def validate_link(data)
48
+ validate_attribute(data, "rel", type: String) { |value| expect(value).to start_with "urn:blinkboxbooks:schema:" }
49
+ validate_attribute(data, "href", type: String) { |value| expect(value).to_not be_empty } if data["href"]
50
+ validate_attribute(data, "title", type: String) { |value| expect(value).to_not be_empty } if data["title"]
51
+ validate_attribute(data, "text", type: String) { |value| expect(value).to_not be_empty } if data["text"]
52
+ end
53
+
54
+ def validate_links(data, *expected)
55
+ validate_attribute(data, "links", type: Array)
56
+ data["links"].each { |link_data| validate_link(link_data) }
57
+ expected.each do |link_info|
58
+ rel = link_info[:rel] || link_info[:relationship]
59
+ rel = "urn:blinkboxbooks:schema:" << rel.tr(" ", "").downcase unless rel.start_with?("urn:")
60
+ count = data["links"].select { |link| link["rel"] == rel }.count
61
+ min = link_info[:min].to_i
62
+ max = %w{∞ *}.include?(link_info[:max]) ? INFINITY : link_info[:min].to_i
63
+ raise "Wrong number of #{rel} links: Expected #{min..max}, Actual: #{count}" unless count >= min && count <= max
64
+ end
65
+ end
66
+
67
+ # Validates a list of items is in the standardised blinkbox books format.
68
+ #
69
+ # @param options [Hash] Options for the validation.
70
+ # @option options [String] :item_type The (singular, snake cased) name of the items in the list, and the validation method (`validate_item_type`) that will be used to test them.
71
+ # @option options [String] :list_type The (signular, snake cased) name of the list type to be validated. Corresponds to the schema urn of `urn:blinkboxbooks:schema:listtypelist` and will look for the method `validate_list_of_list_type`.
72
+ # @option options [Integer] :min_count The minimum number of items there must be.
73
+ # @option options [Integer] :max_count The maximum number of items there can be.
74
+ # @option options [Integer] :count The exact number of items there must be. (Is overridden by min_ and max_count)
75
+ # @option options [Integer] :offset The offset expected for the data (used for ensuring the `offset` value is correct)
76
+ # @option options [Array<Symbol>] :warn_only Ask the validator to be lenient while testing the specified attributes (NB. Use snake_case)
77
+ def validate_list(data, options = {})
78
+ list_type = options[:list_type]
79
+ item_type = options[:item_type]
80
+ min_count = options[:min_count] || options[:count] || 0
81
+ max_count = options[:max_count] || options[:count] || 1000000
82
+ offset = options[:offset] || 0
83
+ warn_only = options[:warn_only] || []
84
+
85
+ # TODO: Should this be :list:#{list_type} rather than the list type before list?
86
+ expected_type = "urn:blinkboxbooks:schema:#{(list_type || "").tr("_", "")}list"
87
+ validate_attribute(data, "type", type: String, warn_only: warn_only.include?(:type)) { |value| expect(value).to eq(expected_type) }
88
+ validate_attribute(data, "count", type: Integer, warn_only: warn_only.include?(:count)) { |value| expect(min_count..max_count).to cover(value) }
89
+ validate_attribute(data, "offset", type: Integer, warn_only: warn_only.include?(:offset)) { |value| expect(value).to eq(offset) }
90
+ validate_attribute(data, "numberOfResults", type: Integer, warn_only: warn_only.include?(:number_of_results)) { |value| expect(value).to be >= data["count"] }
91
+ validate_attribute(data, "items", type: Array, warn_only: warn_only.include?(:empty_items))
92
+
93
+ unless list_type.nil?
94
+ further_validation = "validate_list_of_#{list_type}".to_sym
95
+ send(further_validation, data) if respond_to?(further_validation)
96
+ end
97
+
98
+ if data["items"] || min_count > 0
99
+ validate_attribute(data, "items", type: Array) do |value|
100
+ if min_count == max_count
101
+ expect(value.count).to eq(min_count)
102
+ else
103
+ expect(value.count).to be_between(min_count, max_count)
104
+ end
105
+ end
106
+ unless item_type.nil?
107
+ item_validation_method = "validate_#{item_type}".to_sym
108
+ data["items"].each { |item| self.send(item_validation_method, item) }
109
+ end
110
+ end
111
+ end
112
+
113
+ def validate_list_order(data, attribute_name, descending: false)
114
+ attribute_values = data["items"].map.with_index do |item, index|
115
+ value = item[attribute_name]
116
+ expect(value).to_not be_nil, "'#{attribute_name}' is nil in item at index #{index}"
117
+ if attribute_name =~ /date$/i
118
+ DateTime.parse(value)
119
+ else
120
+ value
121
+ end
122
+ end
123
+ expected_values = attribute_values.sort do |a, b|
124
+ if a.respond_to?(:upcase)
125
+ a.upcase <=> b.upcase # ordering of values should be case-insensitive
126
+ else
127
+ a <=> b
128
+ end
129
+ end
130
+ expected_values.reverse! if descending
131
+ expect(attribute_values).to eq(expected_values)
132
+ end
133
+ end
134
+
135
+ World(KnowsAboutResponseValidation)
@@ -0,0 +1,17 @@
1
+ require "http_capture"
2
+
3
+ module KnowsAboutApiResponses
4
+ # Parses response data that is expected to be in JSON format.
5
+ #
6
+ # @return [Hash] The response data.
7
+ def parse_response_data
8
+ expect(HttpCapture::RESPONSES.last["Content-Type"]).to match(%r{^application/vnd.blinkboxbooks.data.v1\+json;?})
9
+ begin
10
+ @response_data = JSON.load(HttpCapture::RESPONSES.last.body)
11
+ rescue => e
12
+ raise "The response is not valid JSON: #{e.message}"
13
+ end
14
+ end
15
+ end
16
+
17
+ World(KnowsAboutApiResponses)
@@ -0,0 +1,28 @@
1
+ # This module allows steps to set the subject of a scenario simply.
2
+ #
3
+ # subject(:book, {"isbn" => "9780111222333"})
4
+ # subject(:contributor, {"guid" => "abc123"})
5
+ #
6
+ # p subject(:book)
7
+ # # => {"isbn" => "9780111222333"}
8
+ #
9
+ # It's really just a readable wrapper for a hash with some test specific exceptions and things
10
+ module KnowsAboutGrammaticalSubjects
11
+ SUBJECTS = {}
12
+ USING_SETTER = :you_will_never_accidentally_pass_this
13
+
14
+ def subject(type, details = USING_SETTER)
15
+ if details == USING_SETTER
16
+ raise "Test error: A #{type} subject hasn't been defined in this scenario yet." unless SUBJECTS[type]
17
+ return SUBJECTS[type]
18
+ else
19
+ SUBJECTS[type] = details
20
+ end
21
+ end
22
+ end
23
+
24
+ World(KnowsAboutGrammaticalSubjects)
25
+
26
+ Before do
27
+ KnowsAboutGrammaticalSubjects::SUBJECTS.clear
28
+ end
@@ -0,0 +1,56 @@
1
+ require_relative "../../spec_helper"
2
+ require 'rspec'
3
+ require 'cucumber/blinkbox/requests'
4
+
5
+ # needed for String#camel_case
6
+ # (ought this be required by cucumber/blinkbox/requests ?)
7
+ require 'cucumber/helpers'
8
+
9
+ # needed for String#camelize
10
+ # (ought this be required by cucumber/helpers ?)
11
+ require 'active_support/core_ext/string'
12
+
13
+ describe "requests" do
14
+
15
+ describe "setting query parameters" do
16
+
17
+ before :each do
18
+ @request = Object.new
19
+ @request.extend(KnowsAboutApiRequests)
20
+ end
21
+
22
+ it "accepts a single value" do
23
+ @request.set_query_param("foo", 1)
24
+ @request.query["foo"].should eq(1)
25
+ end
26
+
27
+ it "accepts an array of values" do
28
+ @request.set_query_param("foo", [1, 2])
29
+ @request.query["foo"].should eq([1, 2])
30
+ end
31
+
32
+ it "accepts multiple single values" do
33
+ @request.set_query_param("foo", 1)
34
+ @request.set_query_param("foo", 2)
35
+ @request.query["foo"].should eq([1, 2])
36
+ end
37
+
38
+ it "appends arrays to existing arrays" do
39
+ @request.set_query_param("foo", [1, 2])
40
+ @request.set_query_param("foo", [3, 4])
41
+ @request.query["foo"].should eq([1, 2, 3, 4])
42
+ end
43
+
44
+ it "appends single values to existing arrays" do
45
+ @request.set_query_param("foo", [1, 2])
46
+ @request.set_query_param("foo", 3)
47
+ @request.query["foo"].should eq([1, 2, 3])
48
+ end
49
+
50
+ it "appends arrays to existing values" do
51
+ @request.set_query_param("foo", 1)
52
+ @request.set_query_param("foo", [2, 3])
53
+ @request.query["foo"].should eq([1, 2, 3])
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,6 @@
1
+ $:<<File.join(File.dirname(__FILE__), "..", "lib")
2
+
3
+ # Modules under test register themselves with Cucumber by passing themselves to
4
+ # World(m) Since Cucumber doesn't exist in test scope, however, we need to
5
+ # create a noop World
6
+ def World(m) end
metadata ADDED
@@ -0,0 +1,169 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cucumber-blinkbox
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.3
5
+ platform: ruby
6
+ authors:
7
+ - blinkbox books
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: cucumber
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: httpclient
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'
55
+ - !ruby/object:Gem::Dependency
56
+ name: http_capture
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '1.3'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '1.3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '2.99'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '2.99'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: cucumber-helpers
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ! '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: blinkbox books specific cucumber test helpers
126
+ email:
127
+ - jphastings@blinkbox.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - VERSION
133
+ - lib/cucumber/blinkbox.rb
134
+ - lib/cucumber/blinkbox/data_dependencies.rb
135
+ - lib/cucumber/blinkbox/environment.rb
136
+ - lib/cucumber/blinkbox/formatter/html.rb
137
+ - lib/cucumber/blinkbox/requests.rb
138
+ - lib/cucumber/blinkbox/response_validation.rb
139
+ - lib/cucumber/blinkbox/responses.rb
140
+ - lib/cucumber/blinkbox/subjects.rb
141
+ - spec/cucumber/blinkbox/requests_spec.rb
142
+ - spec/spec_helper.rb
143
+ homepage: http://blinkboxbooks.github.io/
144
+ licenses:
145
+ - MIT
146
+ metadata: {}
147
+ post_install_message:
148
+ rdoc_options: []
149
+ require_paths:
150
+ - lib
151
+ required_ruby_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ! '>='
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ required_rubygems_version: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ! '>='
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ requirements: []
162
+ rubyforge_project:
163
+ rubygems_version: 2.4.5
164
+ signing_key:
165
+ specification_version: 4
166
+ summary: blinkbox books specific cucumber test helpers
167
+ test_files:
168
+ - spec/cucumber/blinkbox/requests_spec.rb
169
+ - spec/spec_helper.rb