cucumber-apis 0.10 → 0.12

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9c8d2d92ec42c065c7e394e9c65e626b5959dff28f762f8156823d5e4323a6c
4
- data.tar.gz: 8132bcaa3fa74712acbdceb76a4dd41f33083c528911d0272281aed8db9874ca
3
+ metadata.gz: 4e87d8d57cf08d02cbc711ddf04c6639a59aaecf0780f5aa375ce81127545462
4
+ data.tar.gz: 5b637a0bb285ce98c9c0d2a699da0f320cd76d8dcdda8eabf4e4889935095003
5
5
  SHA512:
6
- metadata.gz: 736b57acce0025754c451bfff7e928be4897a735afacedd9a5081018cdd4f61ebad11ca5e05a2d346f0ca184354e4009314d64cf8cf801ab43ee14acf8b026b1
7
- data.tar.gz: d7f1a320b70f38b8b3952841819b73bcc8dbe506cf029831a67ea2cf2fc899abfeffd68016ee66a377828bb85c5f27d31489cda2b09f73fd862a7c5fb9b94b5c
6
+ metadata.gz: 3ee18f7f9bee4f1186796bc3aa01d39e2131781ec29d38248922b78e7fbbe8a196544ef1160edf497f010565f30805d3cb348bbae3d09d1640b9b62423091fa7
7
+ data.tar.gz: f3c87a52a414b24cb3066f1f37dae8e5fe4e04df6c0b26ecade0e89edf8b05bc01c33c2c442f44f818a5f0891315eb0ff8cacebff5e952e880515e5e24efd7b8
data/lib/.DS_Store ADDED
Binary file
@@ -0,0 +1,21 @@
1
+ module CucumberApi
2
+ module Helpers
3
+ # Bind grabbed values into placeholders in given URL
4
+ # Ex: http://example.com?id={id} with {id => 1} becomes http://example.com?id=1
5
+ # @param url [String] parameterized URL with placeholders
6
+ # @return [String] binded URL or original URL if no placeholders
7
+ def resolve url
8
+ url.gsub!(/\{([a-zA-Z0-9_]+)\}/) do |s|
9
+ s.gsub!(/[\{\}]/, '')
10
+ if instance_variable_defined?("@#{s}")
11
+ CGI.escape %/#{instance_variable_get("@#{s}")}/
12
+ else
13
+ raise 'Did you forget to "grab" ' + s + '?'
14
+ end
15
+ end
16
+ url
17
+ end
18
+ end
19
+ end
20
+
21
+ World(CucumberApi::Helpers)
@@ -0,0 +1,117 @@
1
+ require 'json'
2
+ require 'jsonpath'
3
+ require 'rest-client'
4
+
5
+ module CucumberApi
6
+
7
+ # Extension of {RestClient::Response} with support for JSON path traversal and validation
8
+ module Response
9
+ # Create a Response with JSON path support
10
+ # @param response [RestClient::Response] original response
11
+ # @return [Response] self
12
+ def self.create response
13
+ result = response
14
+ result.extend Response
15
+ result
16
+ end
17
+
18
+ # Check if given JSON path exists
19
+ # @param json_path [String] a valid JSON path expression
20
+ # @param json [String] optional JSON from which to check JSON path, default to response body
21
+ # @return [true, false] true if JSON path is valid and exists, false otherwise
22
+ def has json_path, json=nil
23
+ if json.nil?
24
+ json = JSON.parse body
25
+ end
26
+ not JsonPath.new(json_path).on(json).empty?
27
+ end
28
+
29
+ # Retrieve value of the first JSON element with given JSON path
30
+ # @param json_path [String] a valid JSON path expression
31
+ # @param json [String] optional JSON from which to apply JSON path, default to response body
32
+ # @return [Object] value of first retrieved JSON element in form of Ruby object
33
+ # @raise [Exception] if JSON path is invalid or no matching JSON element found
34
+ def get json_path, json=nil
35
+ if json.nil?
36
+ json = JSON.parse body
37
+ end
38
+ results = JsonPath.new(json_path).on(json)
39
+ if results.empty?
40
+ raise %/Expected json path '#{json_path}' not found\n#{to_json_s}/
41
+ end
42
+ results.first
43
+ end
44
+
45
+ # Retrieve value of the first JSON element with given JSON path as given type
46
+ # @param json_path [String] a valid JSON path expression
47
+ # @param type [String] required type, possible values are 'numeric', 'array', 'string', 'boolean', 'numeric_string'
48
+ # or 'object'
49
+ # @param json [String] optional JSON from which to apply JSON path, default to response body
50
+ # @return [Object] value of first retrieved JSON element in form of given type
51
+ # @raise [Exception] if JSON path is invalid or no matching JSON element found or matching element does not match
52
+ # required type
53
+ def get_as_type json_path, type, json=nil
54
+ value = get json_path, json
55
+ case type
56
+ when 'numeric'
57
+ valid = value.is_a? Numeric
58
+ when 'array'
59
+ valid = value.is_a? Array
60
+ when 'string'
61
+ valid = value.is_a? String
62
+ when 'boolean'
63
+ valid = !!value == value
64
+ when 'numeric_string'
65
+ valid = value.is_a?(Numeric) or value.is_a?(String)
66
+ when 'object'
67
+ valid = value.is_a? Hash
68
+ else
69
+ raise %/Invalid expected type '#{type}'/
70
+ end
71
+
72
+ unless valid
73
+ raise %/Expect '#{json_path}' as a '#{type}' but was '#{value.class}'\n#{to_json_s}/
74
+ end
75
+ value
76
+ end
77
+
78
+ # Retrieve value of the first JSON element with given JSON path as given type, with nil value allowed
79
+ # @param json_path [String] a valid JSON path expression
80
+ # @param type [String] required type, possible values are 'numeric', 'array', 'string', 'boolean', 'numeric_string'
81
+ # or 'object'
82
+ # @param json [String] optional JSON from which to apply JSON path, default to response body
83
+ # @return [Object] value of first retrieved JSON element in form of given type or nil
84
+ # @raise [Exception] if JSON path is invalid or no matching JSON element found or matching element does not match
85
+ # required type
86
+ def get_as_type_or_null json_path, type, json=nil
87
+ value = get json_path, json
88
+ value.nil? ? value : get_as_type(json_path, type, json)
89
+ end
90
+
91
+ # Retrieve value of the first JSON element with given JSON path as given type, and check for a given value
92
+ # @param json_path [String] a valid JSON path expression
93
+ # @param type [String] required type, possible values are 'numeric', 'string', 'boolean', or 'numeric_string'
94
+ # @param value [String] value to check for
95
+ # @param json [String] optional JSON from which to apply JSON path, default to response body
96
+ # @return [Object] value of first retrieved JSON element in form of given type or nil
97
+ # @raise [Exception] if JSON path is invalid or no matching JSON element found or matching element does not match
98
+ # required type or value
99
+ def get_as_type_and_check_value json_path, type, value, json=nil
100
+ v = get_as_type json_path, type, json
101
+ if value != v.to_s
102
+ raise %/Expect '#{json_path}' to be '#{value}' but was '#{v}'\n#{to_json_s}/
103
+ end
104
+ end
105
+
106
+ # Retrieve pretty JSON response for logging
107
+ # @return [String] pretty JSON response if verbose setting is true, empty string otherwise
108
+ def to_json_s
109
+ if ENV['cucumber_api_verbose'] == 'true'
110
+ JSON.pretty_generate(JSON.parse to_s)
111
+ else
112
+ ''
113
+ end
114
+ end
115
+ RestClient::Response.send(:include, self)
116
+ end
117
+ end
@@ -0,0 +1,180 @@
1
+ require 'cucumber-api/response'
2
+ require 'cucumber-api/helpers'
3
+ require 'rest-client'
4
+ require 'json-schema'
5
+
6
+ if ENV['cucumber_api_verbose'] == 'true'
7
+ RestClient.log = 'stdout'
8
+ end
9
+
10
+ $cache = {}
11
+
12
+ Given(/^I clear the response cache$/) do
13
+ $cache = {}
14
+ end
15
+
16
+ Given(/^I send and accept JSON$/) do
17
+ steps %Q{
18
+ Given I send "application/json" and accept JSON
19
+ }
20
+ end
21
+
22
+ Given(/^I send "(.*?)" and accept JSON$/) do |content_type|
23
+ @headers = {
24
+ :Accept => 'application/json',
25
+ :'Content-Type' => %/#{content_type}/
26
+ }
27
+ end
28
+
29
+ Given(/^I add Headers:$/) do |params|
30
+ params.rows_hash.each do |key, value|
31
+ @headers[key.to_sym] = resolve(value)
32
+ end
33
+ end
34
+
35
+ When(/^I grab "([^"]+)"$/) do |k|
36
+ if @response.nil?
37
+ raise 'No response found.'
38
+ end
39
+
40
+ if k[0] == '$'
41
+ v = k
42
+ else
43
+ v = "$.#{k}"
44
+ end
45
+
46
+ k.gsub!(/[^0-9a-zA-Z_]/, '')
47
+ instance_variable_set("@#{k}", @response.get(v))
48
+ end
49
+
50
+ When(/^I grab "([^"]+)" as "([^"]+)"$/) do |k, v|
51
+ if @response.nil?
52
+ raise 'No response found.'
53
+ end
54
+
55
+ k = "$.#{k}" unless k[0] == '$'
56
+ instance_variable_set("@#{v}", @response.get(k))
57
+ end
58
+
59
+ When(/^I set JSON request body to '(.*?)'$/) do |body|
60
+ @body = JSON.parse body
61
+ end
62
+
63
+ When(/^I set JSON request body to:$/) do |body|
64
+ @body = JSON.dump(JSON.parse(body))
65
+ end
66
+
67
+ When(/^I set form request body to:$/) do |params|
68
+ @body = {}
69
+ params.rows_hash.each do |key, value|
70
+ p_value = value
71
+ @grabbed.each { |k, v| p_value = v if value == %/{#{k}}/ } unless @grabbed.nil?
72
+ p_value = File.new %-#{Dir.pwd}/#{p_value.sub 'file://', ''}- if %/#{p_value}/.start_with? "file://"
73
+ @body[%/#{key}/] = p_value
74
+ end
75
+ end
76
+
77
+ When(/^I set request body from "(.*?).(yml|json)"$/) do |filename, extension|
78
+ path = %-#{Dir.pwd}/#{filename}.#{extension}-
79
+ if File.file? path
80
+ case extension
81
+ when 'yml'
82
+ @body = YAML.load File.open(path)
83
+ when 'json'
84
+ @body = JSON.parse File.read(path)
85
+ else
86
+ raise %/Unsupported file type: '#{path}'/
87
+ end
88
+ else
89
+ raise %/File not found: '#{path}'/
90
+ end
91
+ end
92
+
93
+ When(/^I send a (GET|POST|PATCH|PUT|DELETE) request to "(.*?)" with:$/) do |method, url, params|
94
+ unless params.hashes.empty?
95
+ query = params.hashes.first.map{|key, value| %/CGI.escape #{key}=#{value}/}.join("&")
96
+ url = url.include?('?') ? %/#{url}&#{query}/ : %/#{url}?#{query}/
97
+ end
98
+ steps %Q{
99
+ When I send a #{method} request to "#{url}"
100
+ }
101
+ end
102
+
103
+ When(/^I send a (GET|POST|PATCH|PUT|DELETE) request to "(.*?)"$/) do |method, url|
104
+ request_url = resolve(url)
105
+ if 'GET' == %/#{method}/ and $cache.has_key? %/#{request_url}/
106
+ @response = $cache[%/#{request_url}/]
107
+ @headers = nil
108
+ @body = nil
109
+ next
110
+ end
111
+
112
+ @headers = {} if @headers.nil?
113
+ begin
114
+ case method
115
+ when 'GET'
116
+ response = RestClient.get request_url, @headers
117
+ when 'POST'
118
+ response = RestClient.post request_url, @body, @headers
119
+ when 'PATCH'
120
+ response = RestClient.patch request_url, @body, @headers
121
+ when 'PUT'
122
+ response = RestClient.put request_url, @body, @headers
123
+ else
124
+ response = RestClient.delete request_url, @headers
125
+ end
126
+ rescue RestClient::Exception => e
127
+ response = e.response
128
+ end
129
+ @response = CucumberApi::Response.create response
130
+ @headers = nil
131
+ @body = nil
132
+ $cache[%/#{request_url}/] = @response if 'GET' == %/#{method}/
133
+ end
134
+
135
+ Then(/^the response status should be "(\d+)"$/) do |status_code|
136
+ raise %/Expect #{status_code} but was #{@response.code}/ if @response.code != status_code.to_i
137
+ end
138
+
139
+ Then(/^the JSON response should follow "(.*?)"$/) do |schema|
140
+ file_path = %-#{Dir.pwd}/#{schema}-
141
+ if File.file? file_path
142
+ begin
143
+ JSON::Validator.validate!(file_path, @response.to_s)
144
+ rescue JSON::Schema::ValidationError => e
145
+ raise JSON::Schema::ValidationError.new(%/#{$!.message}\n#{@response.to_json_s}/,
146
+ $!.fragments, $!.failed_attribute, $!.schema)
147
+ end
148
+ else
149
+ raise %/Schema not found: '#{file_path}'/
150
+ end
151
+ end
152
+
153
+ Then(/^the JSON response root should be (object|array)$/) do |type|
154
+ steps %Q{
155
+ Then the JSON response should have required key "$" of type #{type}
156
+ }
157
+ end
158
+
159
+ Then(/^the JSON response should have key "([^\"]*)"$/) do |json_path|
160
+ steps %Q{
161
+ Then the JSON response should have required key "#{json_path}" of type any
162
+ }
163
+ end
164
+
165
+ Then(/^the JSON response should have (required|optional) key "(.*?)" of type \
166
+ (numeric|string|boolean|numeric_string|object|array|any)( or null)?$/) do |optionality, json_path, type, null_allowed|
167
+ next if optionality == 'optional' and not @response.has(json_path) # if optional and no such key then skip
168
+ if 'any' == type
169
+ @response.get json_path
170
+ elsif null_allowed.nil?
171
+ @response.get_as_type json_path, type
172
+ else
173
+ @response.get_as_type_or_null json_path, type
174
+ end
175
+ end
176
+
177
+ Then(/^the JSON response should have "([^"]*)" of type \
178
+ (numeric|string|boolean|numeric_string) and value "([^"]*)"$/) do |json_path, type, value|
179
+ @response.get_as_type_and_check_value json_path, type, resolve(value)
180
+ end
@@ -0,0 +1,3 @@
1
+ module CucumberApi
2
+ VERSION = "0.12"
3
+ end
@@ -0,0 +1 @@
1
+ require 'cucumber-api/steps'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cucumber-apis
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.10'
4
+ version: '0.12'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ha Duy Trung
@@ -29,22 +29,16 @@ dependencies:
29
29
  name: cucumber
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - "~>"
33
- - !ruby/object:Gem::Version
34
- version: '3.0'
35
- - - ">"
32
+ - - ">="
36
33
  - !ruby/object:Gem::Version
37
- version: 3.0.0
34
+ version: '0'
38
35
  type: :runtime
39
36
  prerelease: false
40
37
  version_requirements: !ruby/object:Gem::Requirement
41
38
  requirements:
42
- - - "~>"
43
- - !ruby/object:Gem::Version
44
- version: '3.0'
45
- - - ">"
39
+ - - ">="
46
40
  - !ruby/object:Gem::Version
47
- version: 3.0.0
41
+ version: '0'
48
42
  - !ruby/object:Gem::Dependency
49
43
  name: jsonpath
50
44
  requirement: !ruby/object:Gem::Requirement
@@ -95,7 +89,13 @@ email:
95
89
  executables: []
96
90
  extensions: []
97
91
  extra_rdoc_files: []
98
- files: []
92
+ files:
93
+ - lib/.DS_Store
94
+ - lib/cucumber-api.rb
95
+ - lib/cucumber-api/helpers.rb
96
+ - lib/cucumber-api/response.rb
97
+ - lib/cucumber-api/steps.rb
98
+ - lib/cucumber-api/version.rb
99
99
  homepage: https://github.com/hidroh/cucumber-api
100
100
  licenses:
101
101
  - Apache-2.0