Skip to content

Commit 7989963

Browse files
committed
Centralize rest yaml test parsing helper methods
1 parent 5950655 commit 7989963

File tree

5 files changed

+85
-117
lines changed

5 files changed

+85
-117
lines changed

api-spec-testing/test_file/test.rb

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,47 @@ class TestFile
2626
# @since 6.2.0
2727
class Test
2828

29+
class << self
30+
31+
# Given a list of keys, find the value in a recursively nested document.
32+
#
33+
# @param [ Array<String> ] chain The list of nested document keys.
34+
# @param [ Hash ] document The document to find the value in.
35+
#
36+
# @return [ Object ] The value at the nested key.
37+
#
38+
# @since 6.2.0
39+
def find_value_in_document(chain, document)
40+
return document[chain[0]] unless chain.size > 1
41+
# a number can be a string key in a Hash or indicate an element in a list
42+
if document.is_a?(Hash)
43+
find_value_in_document(chain[1..-1], document[chain[0].to_s]) if document[chain[0].to_s]
44+
elsif document[chain[0]]
45+
find_value_in_document(chain[1..-1], document[chain[0]]) if document[chain[0]]
46+
end
47+
end
48+
49+
# Given a string representing a nested document key using dot notation,
50+
# split it, keeping escaped dots as part of a key name and replacing
51+
# numerics with a Ruby Integer.
52+
#
53+
# For example:
54+
# "joe.metadata.2.key2" => ['joe', 'metadata', 2, 'key2']
55+
# "jobs.0.node.attributes.ml\\.enabled" => ["jobs", 0, "node", "attributes", "ml\\.enabled"]
56+
#
57+
# @param [ String ] chain The list of nested document keys.
58+
# @param [ Hash ] document The document to find the value in.
59+
#
60+
# @return [ Array<Object> ] A list of the nested keys.
61+
#
62+
# @since 6.2.0
63+
def split_and_parse_key(key)
64+
key.split(/(?<!\\)\./).map do |key|
65+
(key =~ /\A[-+]?[0-9]+\z/) ? key.to_i: key.gsub('\\', '')
66+
end.reject { |k| k == '$body' }
67+
end
68+
end
69+
2970
attr_reader :description
3071
attr_reader :test_file
3172
attr_reader :cached_values
@@ -192,6 +233,23 @@ def skip_test?(client, features_to_skip = test_file.features_to_skip)
192233
end
193234
end
194235

236+
# Replace the `$master` substring in a key with the cached master node's id.
237+
#
238+
# @param [ String ] expected_key The expected key, containing the substring `$master` that needs to be replaced.
239+
#
240+
# See test xpack/10_basic.yml
241+
242+
# @return [ String ] The altered key.
243+
#
244+
# @since 7.2.0
245+
def inject_master_node_id(expected_key)
246+
if cached_values['master']
247+
expected_key.gsub(/\$master/, cached_values['master'])
248+
else
249+
expected_key
250+
end
251+
end
252+
195253
private
196254

197255
def contains_features_to_skip?(features_to_skip, skip_defintion)

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

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
# ssl test returns results at '$body' key. See ssl/10_basic.yml
2828
expected_pairs = expected_pairs['$body'] if expected_pairs['$body']
2929

30-
expected_key = inject_master_node_id(expected_key, test)
31-
split_key = split_and_parse_key(expected_key)
30+
expected_key = test.inject_master_node_id(expected_key)
31+
split_key = Test.split_and_parse_key(expected_key)
3232

3333
actual_value = split_key.inject(response) do |_response, key|
3434
# If the key is an index, indicating element of a list
@@ -49,8 +49,8 @@
4949
match do |response|
5050
# Handle is_true: ''
5151
return !!response if field == ''
52-
split_key = split_and_parse_key(field).collect { |k| test.get_cached_value(k) }
53-
!!find_value_in_document(split_key, response)
52+
split_key = Test.split_and_parse_key(field).collect { |k| test.get_cached_value(k) }
53+
!!Test.find_value_in_document(split_key, response)
5454
end
5555
end
5656

@@ -60,8 +60,8 @@
6060
match do |response|
6161
# Handle is_false: ''
6262
return !response if field == ''
63-
split_key = split_and_parse_key(field).collect { |k| test.get_cached_value(k) }
64-
value_in_doc = find_value_in_document(split_key, response)
63+
split_key = Test.split_and_parse_key(field).collect { |k| test.get_cached_value(k) }
64+
value_in_doc = Test.find_value_in_document(split_key, response)
6565
value_in_doc == 0 || !value_in_doc
6666
end
6767
end
@@ -72,8 +72,8 @@
7272
match do |response|
7373
expected_pairs.all? do |expected_key, expected_value|
7474

75-
expected_key = inject_master_node_id(expected_key, test)
76-
split_key = split_and_parse_key(expected_key)
75+
expected_key = test.inject_master_node_id(expected_key)
76+
split_key = Test.split_and_parse_key(expected_key)
7777

7878
actual_value = split_key.inject(response) do |_response, key|
7979

@@ -95,8 +95,8 @@
9595
match do |response|
9696
expected_pairs.all? do |expected_key, expected_value|
9797

98-
expected_key = inject_master_node_id(expected_key, test)
99-
split_key = split_and_parse_key(expected_key)
98+
expected_key = test.inject_master_node_id(expected_key)
99+
split_key = Test.split_and_parse_key(expected_key)
100100

101101
actual_value = split_key.inject(response) do |_response, key|
102102
# If the key is an index, indicating element of a list
@@ -117,8 +117,8 @@
117117
match do |response|
118118
expected_pairs.all? do |expected_key, expected_value|
119119

120-
expected_key = inject_master_node_id(expected_key, test)
121-
split_key = split_and_parse_key(expected_key)
120+
expected_key = test.inject_master_node_id(expected_key)
121+
split_key = Test.split_and_parse_key(expected_key)
122122

123123
actual_value = split_key.inject(response) do |_response, key|
124124
# If the key is an index, indicating element of a list
@@ -139,8 +139,8 @@
139139
match do |response|
140140
expected_pairs.all? do |expected_key, expected_value|
141141

142-
expected_key = inject_master_node_id(expected_key, test)
143-
split_key = split_and_parse_key(expected_key)
142+
expected_key = test.inject_master_node_id(expected_key)
143+
split_key = Test.split_and_parse_key(expected_key)
144144

145145
actual_value = split_key.inject(response) do |_response, key|
146146
# If the key is an index, indicating element of a list
@@ -172,10 +172,10 @@
172172

173173
# See test xpack/10_basic.yml
174174
# The master node id must be injected in the keys of match clauses
175-
expected_key = inject_master_node_id(expected_key, test)
175+
expected_key = test.inject_master_node_id(expected_key)
176176

177-
split_key = split_and_parse_key(expected_key)
178-
actual_value = find_value_in_document(split_key, response)
177+
split_key = Test.split_and_parse_key(expected_key)
178+
actual_value = Test.find_value_in_document(split_key, response)
179179

180180
# Sometimes the expected value is a cached value from a previous request.
181181
# See test api_key/10_basic.yml

elasticsearch-api/spec/rest_yaml_tests_helper.rb

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -90,59 +90,3 @@
9090

9191
# The features to skip
9292
REST_API_YAML_SKIP_FEATURES = ['warnings'].freeze
93-
94-
# Given a list of keys, find the value in a recursively nested document.
95-
#
96-
# @param [ Array<String> ] chain The list of nested document keys.
97-
# @param [ Hash ] document The document to find the value in.
98-
#
99-
# @return [ Object ] The value at the nested key.
100-
#
101-
# @since 6.2.0
102-
def find_value_in_document(chain, document)
103-
return document[chain[0]] unless chain.size > 1
104-
# a number can be a string key in a Hash or indicate an element in a list
105-
if document.is_a?(Hash)
106-
find_value_in_document(chain[1..-1], document[chain[0].to_s]) if document[chain[0].to_s]
107-
elsif document[chain[0]]
108-
find_value_in_document(chain[1..-1], document[chain[0]]) if document[chain[0]]
109-
end
110-
end
111-
112-
# Given a string representing a nested document key using dot notation,
113-
# split it, keeping escaped dots as part of a key name and replacing
114-
# numerics with a Ruby Integer.
115-
#
116-
# For example:
117-
# "joe.metadata.2.key2" => ['joe', 'metadata', 2, 'key2']
118-
# "jobs.0.node.attributes.ml\\.enabled" => ["jobs", 0, "node", "attributes", "ml\\.enabled"]
119-
#
120-
# @param [ String ] chain The list of nested document keys.
121-
# @param [ Hash ] document The document to find the value in.
122-
#
123-
# @return [ Array<Object> ] A list of the nested keys.
124-
#
125-
# @since 6.2.0
126-
def split_and_parse_key(key)
127-
key.split(/(?<!\\)\./).map do |key|
128-
(key =~ /\A[-+]?[0-9]+\z/) ? key.to_i: key.gsub('\\', '')
129-
end.reject { |k| k == '$body' }
130-
end
131-
132-
# Replace the `$master` substring in a key with the cached master node's id.
133-
#
134-
# @param [ String ] expected_key The expected key, containing the substring `$master` that needs to be replaced.
135-
# @param [ Elasticsearch::RestAPIYAMLTests::TestFile::Test ] test The test.
136-
#
137-
# See test xpack/10_basic.yml
138-
#
139-
# @return [ String ] The altered key.
140-
#
141-
# @since 7.1.1
142-
def inject_master_node_id(expected_key, test)
143-
if test.cached_values['master']
144-
expected_key.gsub(/\$master/, test.cached_values['master'])
145-
else
146-
expected_key
147-
end
148-
end

elasticsearch-xpack/spec/rest_yaml_tests_helper.rb

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -144,37 +144,3 @@
144144

145145
# The features to skip
146146
REST_API_YAML_SKIP_FEATURES = ['warnings'].freeze
147-
148-
149-
# Given a list of keys, find the value in a recursively nested document.
150-
#
151-
# @param [ Array<String> ] chain The list of nested document keys.
152-
# @param [ Hash ] document The document to find the value in.
153-
#
154-
# @return [ Object ] The value at the nested key.
155-
#
156-
# @since 6.2.0
157-
def find_value_in_document(chain, document)
158-
return document[chain[0]] unless chain.size > 1
159-
find_value_in_document(chain[1..-1], document[chain[0]]) if document[chain[0]]
160-
end
161-
162-
# Given a string representing a nested document key using dot notation,
163-
# split it, keeping escaped dots as part of a key name and replacing
164-
# numerics with a Ruby Integer.
165-
#
166-
# For example:
167-
# "joe.metadata.2.key2" => ['joe', 'metadata', 2, 'key2']
168-
# "jobs.0.node.attributes.ml\\.enabled" => ["jobs", 0, "node", "attributes", "ml\\.enabled"]
169-
#
170-
# @param [ String ] chain The list of nested document keys.
171-
# @param [ Hash ] document The document to find the value in.
172-
#
173-
# @return [ Array<Object> ] A list of the nested keys.
174-
#
175-
# @since 6.2.0
176-
def split_and_parse_key(key)
177-
key.split(/(?<!\\)\./).map do |key|
178-
(key =~ /\A[-+]?[0-9]+\z/) ? key.to_i: key.gsub('\\', '')
179-
end.reject { |k| k == '$body' }
180-
end

elasticsearch-xpack/spec/xpack/rest_api_yaml_spec.rb

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
# ssl test returns results at '$body' key. See ssl/10_basic.yml
2727
expected_pairs = expected_pairs['$body'] if expected_pairs['$body']
2828

29-
split_key = split_and_parse_key(expected_key)
29+
split_key = Test.split_and_parse_key(expected_key)
3030

3131
actual_value = split_key.inject(response) do |_response, key|
3232
# If the key is an index, indicating element of a list
@@ -46,7 +46,7 @@
4646
match do |response|
4747
# Handle is_true: ''
4848
return response == true if field == ''
49-
!!find_value_in_document(split_and_parse_key(field), response)
49+
!!Test.find_value_in_document(split_and_parse_key(field), response)
5050
end
5151
end
5252

@@ -55,15 +55,15 @@
5555
match do |response|
5656
# Handle is_false: ''
5757
return response == false if field == ''
58-
!find_value_in_document(split_and_parse_key(field), response)
58+
!Test.find_value_in_document(split_and_parse_key(field), response)
5959
end
6060
end
6161

6262
RSpec::Matchers.define :match_gte_field do |expected_pairs|
6363

6464
match do |response|
6565
expected_pairs.all? do |expected_key, expected_value|
66-
split_key = split_and_parse_key(expected_key)
66+
split_key = Test.split_and_parse_key(expected_key)
6767

6868
actual_value = split_key.inject(response) do |_response, key|
6969
# If the key is an index, indicating element of a list
@@ -82,7 +82,7 @@
8282

8383
match do |response|
8484
expected_pairs.all? do |expected_key, expected_value|
85-
split_key = split_and_parse_key(expected_key)
85+
split_key = Test.split_and_parse_key(expected_key)
8686

8787
actual_value = split_key.inject(response) do |_response, key|
8888
# If the key is an index, indicating element of a list
@@ -101,7 +101,7 @@
101101

102102
match do |response|
103103
expected_pairs.all? do |expected_key, expected_value|
104-
split_key = split_and_parse_key(expected_key)
104+
split_key = Test.split_and_parse_key(expected_key)
105105

106106
actual_value = split_key.inject(response) do |_response, key|
107107
# If the key is an index, indicating element of a list
@@ -120,7 +120,7 @@
120120

121121
match do |response|
122122
expected_pairs.all? do |expected_key, expected_value|
123-
split_key = split_and_parse_key(expected_key)
123+
split_key = Test.split_and_parse_key(expected_key)
124124

125125
actual_value = split_key.inject(response) do |_response, key|
126126
# If the key is an index, indicating element of a list
@@ -151,10 +151,10 @@
151151

152152
# See test xpack/10_basic.yml
153153
# The master node id must be injected in the keys of match clauses
154-
expected_key = inject_master_node_id(expected_key, test)
154+
expected_key = test.inject_master_node_id(expected_key)
155155

156-
split_key = split_and_parse_key(expected_key)
157-
actual_value = find_value_in_document(split_key, response)
156+
split_key = Test.split_and_parse_key(expected_key)
157+
actual_value = Test.find_value_in_document(split_key, response)
158158

159159
# Sometimes the expected value is a cached value from a previous request.
160160
# See test api_key/10_basic.yml

0 commit comments

Comments
 (0)