Skip to content

Commit 7906e9d

Browse files
committed
Update rspec matcher to test nested hashes
1 parent 20fa242 commit 7906e9d

File tree

6 files changed

+71
-38
lines changed

6 files changed

+71
-38
lines changed

CHANGELOG.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
## 7.0.0.pre
1111

1212
* Added `elastic_ruby_console` executable
13-
1413
### Client
1514

1615
* Fixed failing integration test

api-spec-testing/rspec_matchers.rb

Lines changed: 65 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -157,62 +157,94 @@
157157
end
158158

159159
# Match an arbitrary field of a response to a given value.
160-
RSpec::Matchers.define :match_response do |expected_pairs, test|
160+
RSpec::Matchers.define :match_response do |pairs, test|
161161

162162
match do |response|
163-
mismatched_values(sanitize_pairs(expected_pairs), test, response).empty?
163+
pairs = sanitize_pairs(pairs)
164+
compare_pairs(pairs, response, test).empty?
164165
end
165166

166167
failure_message do |response|
167-
"the pair/value #{mismatched_values(sanitize_pairs(expected_pairs), test, response)}" +
168-
" does not match the pair/value in the response #{response}"
168+
"the actual response pair/value(s) #{@mismatched_pairs}" +
169+
" does not match the pair/value(s) in the response #{response}"
169170
end
170171

171172
def sanitize_pairs(expected_pairs)
172173
# sql test returns results at '$body' key. See sql/translate.yml
173174
@pairs ||= expected_pairs['$body'] ? expected_pairs['$body'] : expected_pairs
174175
end
175176

176-
def mismatched_values(pairs, test, response)
177-
@mismatched_values ||= begin
178-
if pairs.is_a?(String)
179-
# Must return an empty list if there are no mismatched values
180-
compare_string_response(pairs, response) ? [] : [ pairs ]
181-
else
182-
compare_hash(pairs, response, test)
183-
end
177+
def compare_pairs(expected_pairs, response, test)
178+
@mismatched_pairs = {}
179+
if expected_pairs.is_a?(String)
180+
@mismatched_pairs = expected_pairs unless compare_string_response(expected_pairs, response)
181+
else
182+
compare_hash(expected_pairs, response, test)
184183
end
184+
@mismatched_pairs
185185
end
186186

187-
def compare_hash(expected_keys_values, response, test)
188-
expected_keys_values.reject do |expected_key, expected_value|
187+
def compare_hash(expected_pairs, actual_hash, test)
188+
expected_pairs.each do |expected_key, expected_value|
189189
# Select the values that don't match, used for the failure message.
190190

191-
if expected_value.is_a?(Hash)
192-
compare_hash(response[expected_key], expected_value, test)
193-
elsif expected_value.is_a?(String)
194-
split_key = TestFile::Test.split_and_parse_key(expected_key).collect do |k|
195-
test.get_cached_value(k)
191+
# Find the value to compare in the response
192+
split_key = TestFile::Test.split_and_parse_key(expected_key).collect do |k|
193+
# Sometimes the expected *key* is a cached value from a previous request.
194+
test.get_cached_value(k)
195+
end
196+
actual_value = TestFile::Test.find_value_in_document(split_key, actual_hash)
197+
# Sometimes the key includes dots. See watcher/put_watch/60_put_watch_with_action_condition.yml
198+
actual_value = TestFile::Test.find_value_in_document(expected_key, actual_hash) if actual_value.nil?
199+
200+
# Sometimes the expected *value* is a cached value from a previous request.
201+
# See test api_key/10_basic.yml
202+
expected_value = test.get_cached_value(expected_value)
203+
204+
case expected_value
205+
when Hash
206+
compare_hash(expected_value, actual_value, test)
207+
when Array
208+
unless compare_array(expected_value, actual_value, test, actual_hash)
209+
@mismatched_pairs.merge!(expected_key => expected_value)
196210
end
197-
actual_value = TestFile::Test.find_value_in_document(split_key, response)
198-
199-
# Sometimes the expected value is a cached value from a previous request.
200-
# See test api_key/10_basic.yml
201-
expected_value = test.get_cached_value(expected_value)
202-
203-
# When you must match a regex. For example:
204-
# match: {task: '/.+:\d+/'}
205-
if expected_value.is_a?(String) && expected_value[0] == "/" && expected_value[-1] == "/"
206-
/#{expected_value.tr("/", "")}/ =~ actual_value
207-
elsif expected_key == ''
208-
expected_value == response
209-
else
210-
actual_value == expected_value
211+
when String
212+
unless compare_string(expected_value, actual_value, test, actual_hash)
213+
@mismatched_pairs.merge!(expected_key => expected_value)
214+
end
215+
else
216+
unless expected_value == actual_value
217+
@mismatched_pairs.merge!(expected_key => expected_value)
211218
end
212219
end
213220
end
214221
end
215222

223+
def compare_string(expected, actual_value, test, response)
224+
# When you must match a regex. For example:
225+
# match: {task: '/.+:\d+/'}
226+
if expected[0] == "/" && expected[-1] == "/"
227+
/#{expected.tr("/", "")}/ =~ actual_value
228+
elsif expected == ''
229+
actual_value == response
230+
else
231+
expected == actual_value
232+
end
233+
end
234+
235+
def compare_array(expected, actual, test, response)
236+
expected.each_with_index do |value, i|
237+
case value
238+
when Hash
239+
return false unless compare_hash(value, actual[i], test)
240+
when Array
241+
return false unless compare_array(value, actual[i], test, response)
242+
when String
243+
return false unless compare_string(value, actual[i], test, response)
244+
end
245+
end
246+
end
247+
216248
def compare_string_response(expected_string, response)
217249
regexp = Regexp.new(expected_string.strip[1..-2], Regexp::EXTENDED|Regexp::MULTILINE)
218250
regexp =~ response

api-spec-testing/test_file/test.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class << self
2424
#
2525
# @since 6.2.0
2626
def find_value_in_document(chain, document)
27+
return document[chain] unless chain.is_a?(Array)
2728
return document[chain[0]] unless chain.size > 1
2829
# a number can be a string key in a Hash or indicate an element in a list
2930
if document.is_a?(Hash)

elasticsearch-api/spec/elasticsearch/api/rest_api_yaml_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
context "#{test.description}" do
1919

2020
if test.skip_test?(ADMIN_CLIENT)
21-
skip 'Test contains feature(s) not yet support or version is not satisfied'
21+
skip 'Test contains feature(s) not yet supported or version is not satisfied'
2222

2323
else
2424

elasticsearch-xpack/lib/elasticsearch/xpack/api/actions/data_frame/put_data_frame_transform.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ def put_data_frame_transform(arguments={})
2222
raise ArgumentError, "Required argument 'body' missing" unless arguments[:body]
2323
raise ArgumentError, "Required argument 'transform_id' missing" unless arguments[:transform_id]
2424
arguments = arguments.clone
25-
2625
transform_id = URI.escape(arguments.delete(:transform_id))
2726
body = arguments.delete(:body)
2827

@@ -33,10 +32,12 @@ def put_data_frame_transform(arguments={})
3332
perform_request(method, path, params, body).body
3433
end
3534

36-
3735
# Register this action with its valid params when the module is loaded.
3836
#
3937
# @since 8.0.0
38+
# Register this action with its valid params when the module is loaded.
39+
#
40+
# @since 7.4.0
4041
ParamsRegistry.register(:put_data_frame_transform, [ :defer_validation ].freeze)
4142
end
4243
end

elasticsearch-xpack/spec/xpack/rest_api_yaml_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
context "#{test.description}" do
2424

2525
if test.skip_test?(ADMIN_CLIENT)
26-
skip 'Test contains feature(s) not yet support or version is not satisfied'
26+
skip 'Test contains feature(s) not yet supported or version is not satisfied'
2727

2828
else
2929

0 commit comments

Comments
 (0)