soaspec 0.2.16 → 0.2.17
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 +4 -4
- data/ChangeLog +4 -0
- data/demo/extract.html +26 -8
- data/demo/extract.json +17 -13
- data/demo/index.html +5 -1
- data/lib/soaspec/exchange_handlers/response_extractor.rb +26 -0
- data/lib/soaspec/exchange_handlers/rest_handler.rb +5 -14
- data/lib/soaspec/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2f7c6eb1593879711796c37e0d54efbc7f9ea13
|
4
|
+
data.tar.gz: 3f96430569dfd2ced08ed09534b6432062f3167c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd585f6ea3eeacec2a99dbd1cb18e43d96f4365acaa7cc5e53afd5cd6ee5d98662fb283c7b3d0b50a1cc5f8e623275ccc452afe2fadf9e957ecfe35bf5969c24
|
7
|
+
data.tar.gz: 28865b3bca9a6df7c5bf7dbb7f810b0c86ba4ddcbfa822011bf41f1b745700c6aa9f0f3998ddb8ceb00f5a03d9df24dd691a204018fd8c65b12e9686a33d1452
|
data/ChangeLog
CHANGED
data/demo/extract.html
CHANGED
@@ -2,16 +2,22 @@
|
|
2
2
|
<html>
|
3
3
|
<head>
|
4
4
|
<title>Exchange extractors</title>
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
5
6
|
<script src="js/angular.min.js"></script>
|
7
|
+
<style>
|
8
|
+
.highlighted {
|
9
|
+
background: yellow;
|
10
|
+
}
|
11
|
+
</style>
|
6
12
|
</head>
|
7
13
|
<body>
|
8
|
-
|
14
|
+
|
15
|
+
<h1>Extract value from JSON response</h1>
|
9
16
|
|
10
17
|
<div ng-app="codeDemo" ng-controller="extract">
|
11
|
-
<
|
12
|
-
|
13
|
-
|
14
|
-
</p>
|
18
|
+
<h2>Sample JSON response body</h2>
|
19
|
+
<p ng-repeat="item in sampleData | filter:myData[index].highlight"
|
20
|
+
ng-bind-html="item | highlight:myData[index].highlight">
|
15
21
|
</p>
|
16
22
|
<p>Method:
|
17
23
|
<select ng-model="index">
|
@@ -19,8 +25,12 @@
|
|
19
25
|
</option>
|
20
26
|
</select>
|
21
27
|
</p>
|
22
|
-
<p>Code:
|
23
|
-
|
28
|
+
<p>Code:
|
29
|
+
<code>{{ myData[index].method }}</code>
|
30
|
+
</p>
|
31
|
+
<p>Result:
|
32
|
+
<code>{{ myData[index].result }}</code>
|
33
|
+
</p>
|
24
34
|
</div>
|
25
35
|
<script>
|
26
36
|
var app = angular.module('codeDemo', []);
|
@@ -29,7 +39,15 @@
|
|
29
39
|
$scope.myData = response.data.methods;
|
30
40
|
$scope.sampleData = response.data.sampleData;
|
31
41
|
});
|
32
|
-
})
|
42
|
+
})
|
43
|
+
.filter('highlight', function($sce) {
|
44
|
+
return function(text, phrase) {
|
45
|
+
if (phrase) text = text.replace(new RegExp('('+phrase+')', 'gi'),
|
46
|
+
'<span class="highlighted">$1</span>')
|
47
|
+
|
48
|
+
return $sce.trustAsHtml(text)
|
49
|
+
}
|
50
|
+
});
|
33
51
|
</script>
|
34
52
|
</body>
|
35
53
|
</html>
|
data/demo/extract.json
CHANGED
@@ -1,36 +1,40 @@
|
|
1
1
|
{
|
2
2
|
"sampleData":
|
3
|
-
{"root":
|
4
|
-
{"parent1":
|
5
|
-
{"child1":5,"child2":"parent1 word"},
|
6
|
-
"parent2":
|
7
|
-
{"uniq":"val","child2":"word2"}}
|
8
|
-
},
|
3
|
+
["{\"root\":{\"parent1\":{\"child1\":\"5\", \"child2\":\"parent1 word\"},\"parent2\":{\"uniq\":\"val\",\"child2\":\"word2\"}}}" ],
|
9
4
|
"methods": [
|
10
5
|
{
|
11
6
|
"desc": "Get response object",
|
12
7
|
"method": "@exchange.response",
|
13
|
-
"result": "RestClient::Response or Savon::Response"
|
8
|
+
"result": "# RestClient::Response or Savon::Response object"
|
14
9
|
},
|
15
10
|
{
|
16
|
-
"desc": "
|
11
|
+
"desc": "Value from unique element",
|
17
12
|
"method": "@exchange['uniq']",
|
18
|
-
"result": "'val'"
|
13
|
+
"result": "'val' # String",
|
14
|
+
"highlight": "\"uniq\""
|
19
15
|
},
|
20
16
|
{
|
21
|
-
"desc": "
|
17
|
+
"desc": "Value via JSONPath",
|
22
18
|
"method": "@exchange['$..parent1.child2']",
|
23
|
-
"result": "'parent1 word'"
|
19
|
+
"result": "'parent1 word' # String",
|
20
|
+
"highlight": " \"child2\""
|
21
|
+
},
|
22
|
+
{
|
23
|
+
"desc": "Value via first matching JSONPath",
|
24
|
+
"method": "@exchange['$..parent1.uniq,$..parent2.uniq']",
|
25
|
+
"result": "'val' # String. (First JSONPath didn't find anything so second was used)",
|
26
|
+
"highlight": "\"uniq\""
|
24
27
|
},
|
25
28
|
{
|
26
29
|
"desc": "List of values matching JSONPath",
|
27
30
|
"method": "@exchange.values_at_path('$..child2')",
|
28
|
-
"result": "['parent1 word', 'word2']"
|
31
|
+
"result": "['parent1 word', 'word2'] # Array",
|
32
|
+
"highlight": "\"child2\""
|
29
33
|
},
|
30
34
|
{
|
31
35
|
"desc": "Convert response into hash",
|
32
36
|
"method": "@exchange.to_hash",
|
33
|
-
"result": "{:root=>{:parent1=>{:child1=>5, :child2=>\"word\"}, :parent2=>{:uniq=>\"val\", :child2=>\"word2\"}}}"
|
37
|
+
"result": "{:root=>{:parent1=>{:child1=>5, :child2=>\"parent1 word\"}, :parent2=>{:uniq=>\"val\", :child2=>\"word2\"}}} # Hash"
|
34
38
|
}
|
35
39
|
]
|
36
40
|
}
|
data/demo/index.html
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
<html>
|
2
2
|
<head>
|
3
3
|
<title>Samples demonstrating how Soaspec works</title>
|
4
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
4
5
|
</head>
|
5
6
|
<body>
|
6
|
-
<h1>
|
7
|
+
<h1>Soaspec</h1>
|
8
|
+
<h2>Samples demonstrating how Soaspec works</h2>
|
7
9
|
<a href="extract.html">Extract response from exchange</a>
|
10
|
+
<h2>Code coverage</h2>
|
11
|
+
<a href="coverage/index.html">RSpec test code coverage</a>
|
8
12
|
</body>
|
9
13
|
</html>
|
@@ -52,5 +52,31 @@ module Soaspec
|
|
52
52
|
end
|
53
53
|
xpath
|
54
54
|
end
|
55
|
+
|
56
|
+
# Convert snakecase to PascalCase
|
57
|
+
# @return [String] PascalCase converted path
|
58
|
+
def convert_to_pascal_case(key)
|
59
|
+
return key if /[[:upper:]]/ =~ key[0] # If first character already capital, don't do conversion
|
60
|
+
|
61
|
+
key.split('_').map(&:capitalize).join
|
62
|
+
end
|
63
|
+
|
64
|
+
# Find element with name specified or pascal case equivalent
|
65
|
+
# @return [String] String to find paths with pascal converted or given path
|
66
|
+
def add_pascal_path(json_path)
|
67
|
+
return json_path unless pascal_keys?
|
68
|
+
|
69
|
+
json_path.split(',').collect do |sub_path|
|
70
|
+
"#{sub_path},#{convert_to_pascal_case(sub_path)}"
|
71
|
+
end.join(',')
|
72
|
+
end
|
73
|
+
|
74
|
+
# @param [String] json_path Path set from Exchange
|
75
|
+
# @return [String] JSON Path
|
76
|
+
def prefix_json_path(json_path)
|
77
|
+
return json_path if json_path[0] == '$'
|
78
|
+
|
79
|
+
"$..#{json_path}"
|
80
|
+
end
|
55
81
|
end
|
56
82
|
end
|
@@ -95,13 +95,6 @@ module Soaspec
|
|
95
95
|
end]
|
96
96
|
end
|
97
97
|
|
98
|
-
# Convert snakecase to PascalCase
|
99
|
-
def convert_to_pascal_case(key)
|
100
|
-
return key if /[[:upper:]]/ =~ key[0] # If first character already capital, don't do conversion
|
101
|
-
|
102
|
-
key.split('_').map(&:capitalize).join
|
103
|
-
end
|
104
|
-
|
105
98
|
# Initialize value of merged options
|
106
99
|
# @return [Hash] Hash of merged options
|
107
100
|
def init_merge_options
|
@@ -167,16 +160,12 @@ module Soaspec
|
|
167
160
|
def json_path_values_for(response, path, attribute: nil)
|
168
161
|
raise 'JSON does not support attributes' if attribute
|
169
162
|
|
170
|
-
if path[0] != '$'
|
171
|
-
path = convert_to_pascal_case(path) if pascal_keys?
|
172
|
-
path = '$..' + path
|
173
|
-
end
|
174
163
|
JsonPath.on(response.body, path)
|
175
164
|
end
|
176
165
|
|
177
166
|
# Based on a exchange, return the value at the provided xpath
|
178
167
|
# If the path does not begin with a '/', a '//' is added to it
|
179
|
-
# @param [Response] response
|
168
|
+
# @param [RestClient::Response] response Response from API
|
180
169
|
# @param [Object] path Xpath, JSONPath or other path identifying how to find element
|
181
170
|
# @param [String] attribute Generic attribute to find. Will override path
|
182
171
|
# @return [String] Value at Xpath
|
@@ -185,16 +174,18 @@ module Soaspec
|
|
185
174
|
case Interpreter.response_type_for(response)
|
186
175
|
when :xml
|
187
176
|
result = xpath_elements_for(response: response, xpath: path, attribute: attribute).first
|
188
|
-
raise NoElementAtPath, "No value at Xpath '#{prefix_xpath(path, attribute)}'" unless result
|
177
|
+
raise NoElementAtPath, "No value at Xpath '#{prefix_xpath(path, attribute)}' in '#{response.body}'" unless result
|
189
178
|
return result.inner_text if attribute.nil?
|
190
179
|
|
191
180
|
return result.attributes[attribute].inner_text
|
192
181
|
when :json
|
182
|
+
path = add_pascal_path(path)
|
193
183
|
paths_to_check = path.split(',')
|
184
|
+
paths_to_check = paths_to_check.map { |path_to_check| prefix_json_path(path_to_check) }
|
194
185
|
matching_values = paths_to_check.collect do |path_to_check|
|
195
186
|
json_path_values_for(response, path_to_check, attribute: attribute)
|
196
187
|
end.reject(&:empty?)
|
197
|
-
raise NoElementAtPath, "
|
188
|
+
raise NoElementAtPath, "No value at JSONPath '#{paths_to_check}' in '#{response.body}'" if matching_values.empty?
|
198
189
|
|
199
190
|
matching_values.first.first
|
200
191
|
when :hash
|
data/lib/soaspec/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: soaspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- SamuelGarrattIQA
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-02-
|
11
|
+
date: 2019-02-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|