brine-dsl 0.5.0
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 +7 -0
- data/.gitignore +4 -0
- data/.ruby-version +1 -0
- data/.travis.yml +11 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +123 -0
- data/Guardfile +12 -0
- data/LICENSE +21 -0
- data/README.md +137 -0
- data/Rakefile +32 -0
- data/brine-dsl.gemspec +32 -0
- data/config/cucumber.yml +2 -0
- data/docs/build.gradle +19 -0
- data/docs/cookbook.html +567 -0
- data/docs/gradle/wrapper/gradle-wrapper.jar +0 -0
- data/docs/gradle/wrapper/gradle-wrapper.properties +6 -0
- data/docs/gradlew +172 -0
- data/docs/gradlew.bat +84 -0
- data/docs/guide.html +1149 -0
- data/docs/index.html +472 -0
- data/docs/specs.html +1672 -0
- data/docs/src/cookbook.adoc +87 -0
- data/docs/src/guide.adoc +427 -0
- data/docs/src/index.adoc +16 -0
- data/docs/src/spec.erb +121 -0
- data/docs/src/specs.adoc +24 -0
- data/features/argument_transforms/boolean.feature +37 -0
- data/features/argument_transforms/datetime.feature +45 -0
- data/features/argument_transforms/integer.feature +41 -0
- data/features/argument_transforms/list.feature +46 -0
- data/features/argument_transforms/object.feature +66 -0
- data/features/argument_transforms/quoted.feature +41 -0
- data/features/argument_transforms/regex.feature +40 -0
- data/features/argument_transforms/template.feature +46 -0
- data/features/argument_transforms/whitespace.feature +51 -0
- data/features/assertions/is_a_valid.feature +184 -0
- data/features/assertions/is_equal_to.feature +60 -0
- data/features/assertions/is_including.feature +29 -0
- data/features/assertions/is_matching.feature +35 -0
- data/features/deprecations/replaced_with.feature +35 -0
- data/features/request_construction/basic.feature +29 -0
- data/features/request_construction/body.feature +26 -0
- data/features/request_construction/clearing.feature +46 -0
- data/features/request_construction/headers.feature +94 -0
- data/features/request_construction/params.feature +60 -0
- data/features/resource_cleanup/cleanup.feature +86 -0
- data/features/selectors/all.feature +55 -0
- data/features/selectors/any.feature +48 -0
- data/features/step_definitions/test_steps.rb +5 -0
- data/features/support/env.rb +10 -0
- data/lib/brine/cleaner_upper.rb +62 -0
- data/lib/brine/coercer.rb +18 -0
- data/lib/brine/hooks.rb +4 -0
- data/lib/brine/mustache_binder.rb +25 -0
- data/lib/brine/requester.rb +125 -0
- data/lib/brine/rest_steps.rb +138 -0
- data/lib/brine/selector.rb +66 -0
- data/lib/brine/step_definitions/assertions.rb +37 -0
- data/lib/brine/step_definitions/assignment.rb +13 -0
- data/lib/brine/step_definitions/cleanup.rb +4 -0
- data/lib/brine/step_definitions/request_construction.rb +19 -0
- data/lib/brine/step_definitions/selection.rb +37 -0
- data/lib/brine/test_steps.rb +138 -0
- data/lib/brine/transforms.rb +81 -0
- data/lib/brine/type_checks.rb +35 -0
- data/lib/brine/util.rb +35 -0
- data/lib/brine.rb +39 -0
- data/tutorial/missing.feature +5 -0
- data/tutorial/post_matching.feature +12 -0
- data/tutorial/post_status.feature +10 -0
- data/tutorial/support/env.rb +2 -0
- metadata +306 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
Feature: Including
|
2
|
+
It can be asserted that a value is a superset of another value.
|
3
|
+
|
4
|
+
Scenario: Equals
|
5
|
+
Given a file named "features/includes.feature" with:
|
6
|
+
"""
|
7
|
+
Feature: Includes
|
8
|
+
Scenario: Basic object membership
|
9
|
+
When the response body is assigned:
|
10
|
+
\"\"\"
|
11
|
+
{"foo":"bar",
|
12
|
+
"baz": 1,
|
13
|
+
"other": "blah"}
|
14
|
+
\"\"\"
|
15
|
+
Then the value of the response body is including:
|
16
|
+
\"\"\"
|
17
|
+
{"baz":1}
|
18
|
+
\"\"\"
|
19
|
+
And the value of the response body is not including:
|
20
|
+
\"\"\"
|
21
|
+
{"missing":"value"}
|
22
|
+
\"\"\"
|
23
|
+
"""
|
24
|
+
When I run `cucumber features/includes.feature`
|
25
|
+
Then the output should contain:
|
26
|
+
"""
|
27
|
+
1 passed
|
28
|
+
"""
|
29
|
+
And it should pass
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Feature: Matching
|
2
|
+
It can be asserted that a value matches another string or regex
|
3
|
+
|
4
|
+
Scenario: Assorted positive and negative assertions.
|
5
|
+
Given a file named "features/is_matching.feature" with:
|
6
|
+
"""
|
7
|
+
|
8
|
+
Feature: Assert value matchiness
|
9
|
+
Scenario: String in response body matched against a regex
|
10
|
+
When the response body is assigned:
|
11
|
+
\"\"\"
|
12
|
+
http://www.github.com?var=val
|
13
|
+
\"\"\"
|
14
|
+
Then the value of the response body is matching `/github/`
|
15
|
+
And the value of the response body is matching `/git.*\?.*=/`
|
16
|
+
And the value of the response body is not matching `/gh/`
|
17
|
+
And the value of the response body is not matching `/^github/`
|
18
|
+
|
19
|
+
Scenario: Regex in response body matched against a string
|
20
|
+
When the response body is assigned:
|
21
|
+
\"\"\"
|
22
|
+
/(.+)\1/
|
23
|
+
\"\"\"
|
24
|
+
Then the value of the response body is matching `blahblah`
|
25
|
+
And the value of the response body is matching `boo`
|
26
|
+
And the value of the response body is not matching `blah blah`
|
27
|
+
And the value of the response body is not matching `blah`
|
28
|
+
|
29
|
+
"""
|
30
|
+
When I run `cucumber --strict features/is_matching.feature`
|
31
|
+
Then the output should contain:
|
32
|
+
"""
|
33
|
+
2 passed
|
34
|
+
"""
|
35
|
+
And it should pass
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Feature: Deprecation Messaging
|
2
|
+
|
3
|
+
Scenario: Deprecation Message is Displayed
|
4
|
+
Given a file named "features/deprecation.feature" with:
|
5
|
+
"""
|
6
|
+
Feature: Deprecation Messaging
|
7
|
+
Scenario: Multine String
|
8
|
+
When the response body is:
|
9
|
+
\"\"\"
|
10
|
+
Anything
|
11
|
+
\"\"\"
|
12
|
+
Then the response body as JSON is:
|
13
|
+
\"\"\"
|
14
|
+
""Anything""
|
15
|
+
\"\"\"
|
16
|
+
Scenario: Multine Object
|
17
|
+
When the response body is:
|
18
|
+
\"\"\"
|
19
|
+
{"isObj": true}
|
20
|
+
\"\"\"
|
21
|
+
Then the response body as JSON is:
|
22
|
+
\"\"\"
|
23
|
+
'{"isObj":true}'
|
24
|
+
\"\"\"
|
25
|
+
"""
|
26
|
+
When I run `cucumber features/deprecation.feature`
|
27
|
+
Then the output should contain:
|
28
|
+
"""
|
29
|
+
2 passed
|
30
|
+
"""
|
31
|
+
And the output should contain:
|
32
|
+
"""
|
33
|
+
DEPRECATION:
|
34
|
+
"""
|
35
|
+
And it should pass
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Feature: Basic Request Construction
|
2
|
+
A simple request with a specified method and path can be sent.
|
3
|
+
|
4
|
+
Scenario Outline: Varying Methods
|
5
|
+
Given a file named "features/basic_requests.feature" with:
|
6
|
+
|
7
|
+
"""
|
8
|
+
Feature: Sending a method
|
9
|
+
Scenario: Basic URL
|
10
|
+
Given expected <method> sent to `/profile`
|
11
|
+
|
12
|
+
When a <method> is sent to `/profile`
|
13
|
+
Then expected calls are verified
|
14
|
+
"""
|
15
|
+
|
16
|
+
When I run `cucumber features/basic_requests.feature`
|
17
|
+
Then the output should contain:
|
18
|
+
"""
|
19
|
+
1 passed
|
20
|
+
"""
|
21
|
+
And it should pass
|
22
|
+
|
23
|
+
Examples:
|
24
|
+
| method |
|
25
|
+
| GET |
|
26
|
+
| POST |
|
27
|
+
| PATCH |
|
28
|
+
| DELETE |
|
29
|
+
| PUT |
|
@@ -0,0 +1,26 @@
|
|
1
|
+
Feature: Assigning a Request Body
|
2
|
+
|
3
|
+
Scenario: Request With Body
|
4
|
+
Given a file named "features/request_body.feature" with:
|
5
|
+
"""
|
6
|
+
Feature: Passing a body
|
7
|
+
Scenario: Basic URL
|
8
|
+
Given expected request body:
|
9
|
+
\"\"\"
|
10
|
+
{"request":1}
|
11
|
+
\"\"\"
|
12
|
+
And expected PUT sent to `/store`
|
13
|
+
|
14
|
+
When the request body is assigned:
|
15
|
+
\"\"\"
|
16
|
+
{"request":1}
|
17
|
+
\"\"\"
|
18
|
+
When a PUT is sent to `/store`
|
19
|
+
Then expected calls are verified
|
20
|
+
"""
|
21
|
+
When I run `cucumber features/request_body.feature`
|
22
|
+
Then the output should contain:
|
23
|
+
"""
|
24
|
+
5 passed
|
25
|
+
"""
|
26
|
+
And it should pass
|
@@ -0,0 +1,46 @@
|
|
1
|
+
Feature: Cleared After Sent
|
2
|
+
After a request is sent, any values that were added to that request
|
3
|
+
are cleared and will not be present in subsequent requests.
|
4
|
+
|
5
|
+
Scenario: Request is Cleared Before Second Send
|
6
|
+
Given a file named "features/request_clearing.feature" with:
|
7
|
+
|
8
|
+
"""
|
9
|
+
Feature: Clearing the request.
|
10
|
+
Scenario: Request body is cleared.
|
11
|
+
Given expected request body:
|
12
|
+
\"\"\"
|
13
|
+
{"request":1}
|
14
|
+
\"\"\"
|
15
|
+
And expected PUT sent to `/profile`
|
16
|
+
Given expected request body:
|
17
|
+
\"\"\"
|
18
|
+
\"\"\"
|
19
|
+
And expected PUT sent to `/store`
|
20
|
+
|
21
|
+
When the request body is assigned:
|
22
|
+
\"\"\"
|
23
|
+
{"request":1}
|
24
|
+
\"\"\"
|
25
|
+
And a PUT is sent to `/profile`
|
26
|
+
And a PUT is sent to `/store`
|
27
|
+
|
28
|
+
Then expected calls are verified
|
29
|
+
|
30
|
+
Scenario: Request parameter
|
31
|
+
Given expected GET sent to `/query?foo=bar`
|
32
|
+
And expected GET sent to `/resource`
|
33
|
+
|
34
|
+
Given the request query parameter `foo` is assigned `bar`
|
35
|
+
And a GET is sent to `/query`
|
36
|
+
|
37
|
+
When a GET is sent to `/resource`
|
38
|
+
Then expected calls are verified
|
39
|
+
"""
|
40
|
+
|
41
|
+
When I run `cucumber features/request_clearing.feature`
|
42
|
+
Then the output should contain:
|
43
|
+
"""
|
44
|
+
2 passed
|
45
|
+
"""
|
46
|
+
And it should pass
|
@@ -0,0 +1,94 @@
|
|
1
|
+
Feature: Adding Headers
|
2
|
+
|
3
|
+
Scenario: Headers are added to requests.
|
4
|
+
Given a file named "features/headers.feature" with:
|
5
|
+
|
6
|
+
"""
|
7
|
+
Feature: Request headers can be specified.
|
8
|
+
Scenario: A new header with a single value is added to request.
|
9
|
+
Given expected request headers:
|
10
|
+
\"\"\"
|
11
|
+
{"foo":"bar"}
|
12
|
+
\"\"\"
|
13
|
+
And expected GET sent to `/query`
|
14
|
+
|
15
|
+
When the request header `foo` is assigned `bar`
|
16
|
+
And a GET is sent to `/query`
|
17
|
+
|
18
|
+
Then expected calls are verified
|
19
|
+
|
20
|
+
Scenario: Default headers are present in requests.
|
21
|
+
Given expected request headers:
|
22
|
+
\"\"\"
|
23
|
+
{"Content-Type": "application/json"}
|
24
|
+
\"\"\"
|
25
|
+
And expected GET sent to `/query`
|
26
|
+
|
27
|
+
When a GET is sent to `/query`
|
28
|
+
|
29
|
+
Then expected calls are verified
|
30
|
+
|
31
|
+
Scenario: Default headers can be overridden.
|
32
|
+
Given expected request headers:
|
33
|
+
\"\"\"
|
34
|
+
{"Content-Type": "text/plain"}
|
35
|
+
\"\"\"
|
36
|
+
And expected GET sent to `/query`
|
37
|
+
|
38
|
+
When the request header `Content-Type` is assigned `text/plain`
|
39
|
+
And a GET is sent to `/query`
|
40
|
+
|
41
|
+
Then expected calls are verified
|
42
|
+
|
43
|
+
Scenario: Array header values are added to requests.
|
44
|
+
Given expected request headers:
|
45
|
+
\"\"\"
|
46
|
+
{"X-Array": "1, 2, 3"}
|
47
|
+
\"\"\"
|
48
|
+
And expected GET sent to `/query`
|
49
|
+
|
50
|
+
When the request header `X-Array` is assigned `[1, 2, 3]`
|
51
|
+
And a GET is sent to `/query`
|
52
|
+
|
53
|
+
Then expected calls are verified
|
54
|
+
|
55
|
+
Scenario: The last set value for a given header wins.
|
56
|
+
Given expected request headers:
|
57
|
+
\"\"\"
|
58
|
+
{"foo":"baz"}
|
59
|
+
\"\"\"
|
60
|
+
And expected GET sent to `/query`
|
61
|
+
|
62
|
+
When the request header `foo` is assigned `bar`
|
63
|
+
And the request header `foo` is assigned `baz`
|
64
|
+
And a GET is sent to `/query`
|
65
|
+
|
66
|
+
Then expected calls are verified
|
67
|
+
|
68
|
+
Scenario Outline: Header is added regardless of HTTP method.
|
69
|
+
Given expected request headers:
|
70
|
+
\"\"\"
|
71
|
+
{"foo":"bar"}
|
72
|
+
\"\"\"
|
73
|
+
And expected <method> sent to `/query`
|
74
|
+
|
75
|
+
When the request header `foo` is assigned `bar`
|
76
|
+
And a <method> is sent to `/query`
|
77
|
+
|
78
|
+
Then expected calls are verified
|
79
|
+
|
80
|
+
Examples:
|
81
|
+
| method |
|
82
|
+
| POST |
|
83
|
+
| PUT |
|
84
|
+
| DELETE |
|
85
|
+
| HEAD |
|
86
|
+
| OPTIONS |
|
87
|
+
"""
|
88
|
+
|
89
|
+
When I run `cucumber features/headers.feature`
|
90
|
+
Then the output should contain:
|
91
|
+
"""
|
92
|
+
10 passed
|
93
|
+
"""
|
94
|
+
And it should pass
|
@@ -0,0 +1,60 @@
|
|
1
|
+
@wip
|
2
|
+
Feature: Adding Query Parameters
|
3
|
+
|
4
|
+
Scenario: Query parameters are added to requests.
|
5
|
+
Given a file named "features/params.feature" with:
|
6
|
+
|
7
|
+
"""
|
8
|
+
Feature: Request query parameters can be specified.
|
9
|
+
Scenario: A single parameter is appended to the URL.
|
10
|
+
Given expected GET sent to `/query?foo=bar`
|
11
|
+
|
12
|
+
When the request query parameter `foo` is assigned `bar`
|
13
|
+
And a GET is sent to `/query`
|
14
|
+
|
15
|
+
Then expected calls are verified
|
16
|
+
|
17
|
+
Scenario: Multiple parameters are appended to the URL with proper formatting.
|
18
|
+
Given expected GET sent to `/query?foo=bar&baz=1`
|
19
|
+
|
20
|
+
When the request query parameter `foo` is assigned `bar`
|
21
|
+
And the request query parameter `baz` is assigned `1`
|
22
|
+
And a GET is sent to `/query`
|
23
|
+
|
24
|
+
Then expected calls are verified
|
25
|
+
|
26
|
+
Scenario Outline: Values are encoded appropriately.
|
27
|
+
Given expected GET sent to `/query?foo=<encoded>`
|
28
|
+
|
29
|
+
When the request query parameter `foo` is assigned `<input>`
|
30
|
+
And a GET is sent to `/query`
|
31
|
+
|
32
|
+
Then expected calls are verified
|
33
|
+
Examples:
|
34
|
+
| input | encoded |
|
35
|
+
| bar & grill | bar+%26+grill |
|
36
|
+
| + + | %2B+%2B |
|
37
|
+
| (imbalance)) | %28imbalance%29%29 |
|
38
|
+
|
39
|
+
Scenario Outline: Parametes are added regardless of HTTP method.
|
40
|
+
Given expected <method> sent to `/query?foo=bar`
|
41
|
+
|
42
|
+
When the request query parameter `foo` is assigned `bar`
|
43
|
+
And a <method> is sent to `/query`
|
44
|
+
|
45
|
+
Then expected calls are verified
|
46
|
+
Examples:
|
47
|
+
| method |
|
48
|
+
| POST |
|
49
|
+
| PUT |
|
50
|
+
| DELETE |
|
51
|
+
| HEAD |
|
52
|
+
| OPTIONS |
|
53
|
+
"""
|
54
|
+
|
55
|
+
When I run `cucumber features/params.feature`
|
56
|
+
Then the output should contain:
|
57
|
+
"""
|
58
|
+
10 passed
|
59
|
+
"""
|
60
|
+
And it should pass
|
@@ -0,0 +1,86 @@
|
|
1
|
+
Feature: Resource Cleanup
|
2
|
+
Resources created during testing can be marked for deletion.
|
3
|
+
|
4
|
+
Scenario: Initial Success
|
5
|
+
Given a file named "features/cleanup.feature" with:
|
6
|
+
|
7
|
+
"""
|
8
|
+
Feature: Resource Cleanup
|
9
|
+
|
10
|
+
Scenario: Successful Basic Deletion
|
11
|
+
Given expected DELETE sent to `/some/path`
|
12
|
+
|
13
|
+
When a resource is created at `/some/path`
|
14
|
+
"""
|
15
|
+
|
16
|
+
When I run `cucumber --strict features/cleanup.feature`
|
17
|
+
Then the output should match %r<delete http://www.example.com/some/path>
|
18
|
+
And the output should not contain:
|
19
|
+
"""
|
20
|
+
ERROR
|
21
|
+
"""
|
22
|
+
And it should pass
|
23
|
+
|
24
|
+
Scenario: Returned 4xx
|
25
|
+
Given a file named "features/cleanup_failure.feature" with:
|
26
|
+
|
27
|
+
"""
|
28
|
+
Feature: Resource Cleanup
|
29
|
+
|
30
|
+
Scenario: Failed Deletion
|
31
|
+
Given expected response status of `409`
|
32
|
+
And expected DELETE sent to `/some/path`
|
33
|
+
|
34
|
+
When a resource is created at `/some/path`
|
35
|
+
"""
|
36
|
+
|
37
|
+
When I run `cucumber --strict features/cleanup_failure.feature`
|
38
|
+
Then the output should match %r<(?:.*delete http://www.example.com/some/path.*){3}>
|
39
|
+
And the output should contain:
|
40
|
+
"""
|
41
|
+
ERROR
|
42
|
+
"""
|
43
|
+
And it should pass
|
44
|
+
|
45
|
+
Scenario: Success Upon Retry
|
46
|
+
Given a file named "features/cleanup_retried.feature" with:
|
47
|
+
|
48
|
+
"""
|
49
|
+
Feature: Resource Cleanup
|
50
|
+
|
51
|
+
Scenario: Success Upon Retry
|
52
|
+
Given expected response status sequence of `[504, 200]`
|
53
|
+
And expected DELETE sent to `/some/path`
|
54
|
+
|
55
|
+
When a resource is created at `/some/path`
|
56
|
+
"""
|
57
|
+
|
58
|
+
When I run `cucumber --strict -o ../../out.log features/cleanup_retried.feature`
|
59
|
+
Then the output should match %r<(?:.*delete http://www.example.com/some/path.*){2}>
|
60
|
+
And the output should not contain:
|
61
|
+
"""
|
62
|
+
ERROR
|
63
|
+
"""
|
64
|
+
And it should pass
|
65
|
+
|
66
|
+
|
67
|
+
Scenario: Unreached Success
|
68
|
+
Given a file named "features/cleanup_unreached.feature" with:
|
69
|
+
|
70
|
+
"""
|
71
|
+
Feature: Resource Cleanup
|
72
|
+
|
73
|
+
Scenario: Unreached Success
|
74
|
+
Given expected response status sequence of `[504, 504, 504, 200]`
|
75
|
+
And expected DELETE sent to `/some/path`
|
76
|
+
|
77
|
+
When a resource is created at `/some/path`
|
78
|
+
"""
|
79
|
+
|
80
|
+
When I run `cucumber --strict -o ../../out.log features/cleanup_unreached.feature`
|
81
|
+
Then the output should match %r<(?:.*delete http://www.example.com/some/path.*){3}>
|
82
|
+
And the output should contain:
|
83
|
+
"""
|
84
|
+
ERROR
|
85
|
+
"""
|
86
|
+
And it should pass
|
@@ -0,0 +1,55 @@
|
|
1
|
+
Feature: All Elements
|
2
|
+
Assertions can be done against all elements of a structure.
|
3
|
+
|
4
|
+
Scenario: Assorted positive and negative assertions.
|
5
|
+
Given a file named "features/all.feature" with:
|
6
|
+
"""
|
7
|
+
|
8
|
+
Feature: Allow selection of all structure elements
|
9
|
+
Scenario: List in response body
|
10
|
+
When the response body is assigned:
|
11
|
+
\"\"\"
|
12
|
+
["a", "bb", "ccc"]
|
13
|
+
\"\"\"
|
14
|
+
Then the value of the response body has elements which are all matching `/\w+/`
|
15
|
+
|
16
|
+
Scenario: Spread nested lists
|
17
|
+
When the response body is assigned:
|
18
|
+
\"\"\"
|
19
|
+
[{"val": "foo"},{"val": "foo"}]
|
20
|
+
\"\"\"
|
21
|
+
Then the value of the response body children `..val` has elements which are all equal to `foo`
|
22
|
+
|
23
|
+
"""
|
24
|
+
When I run `cucumber --strict features/all.feature`
|
25
|
+
Then the output should contain:
|
26
|
+
"""
|
27
|
+
4 passed
|
28
|
+
"""
|
29
|
+
And it should pass
|
30
|
+
|
31
|
+
Scenario: Failing tests since negation isn't available yet.
|
32
|
+
Given a file named "features/all.feature" with:
|
33
|
+
"""
|
34
|
+
|
35
|
+
Feature: Allow selection of all structure elements
|
36
|
+
Scenario: List in response body
|
37
|
+
When the response body is assigned:
|
38
|
+
\"\"\"
|
39
|
+
["a", "bb", "ccc"]
|
40
|
+
\"\"\"
|
41
|
+
Then the value of the response body has elements which are all matching `/^\w$/`
|
42
|
+
|
43
|
+
Scenario: Spread nested lists
|
44
|
+
When the response body is assigned:
|
45
|
+
\"\"\"
|
46
|
+
[{"val": "foo"},{"val": "fob"}]
|
47
|
+
\"\"\"
|
48
|
+
Then the value of the response body children `..val` has elements which are all equal to `foo`
|
49
|
+
|
50
|
+
"""
|
51
|
+
When I run `cucumber --strict features/all.feature`
|
52
|
+
Then the output should contain:
|
53
|
+
"""
|
54
|
+
2 failed
|
55
|
+
"""
|
@@ -0,0 +1,48 @@
|
|
1
|
+
Feature: Any Element
|
2
|
+
Assertions can be done against any element of a structure.
|
3
|
+
|
4
|
+
Scenario: Assorted positive and negative assertions.
|
5
|
+
Given a file named "features/any.feature" with:
|
6
|
+
"""
|
7
|
+
|
8
|
+
Feature: Allow selection of any structure element
|
9
|
+
Scenario: List in response body
|
10
|
+
When the response body is assigned:
|
11
|
+
\"\"\"
|
12
|
+
["a", "b", "c"]
|
13
|
+
\"\"\"
|
14
|
+
Then the value of the response body does have any element that is equal to `a`
|
15
|
+
And the value of the response body does not have any element that is equal to `d`
|
16
|
+
|
17
|
+
Scenario: Nested list in response body
|
18
|
+
When the response body is assigned:
|
19
|
+
\"\"\"
|
20
|
+
{"letters": ["a", "b", "c"]}
|
21
|
+
\"\"\"
|
22
|
+
Then the value of the response body child `letters` does have any element that is equal to `a`
|
23
|
+
And the value of the response body child `letters` does not have any element that is equal to `d`
|
24
|
+
|
25
|
+
Scenario: Map matches entries
|
26
|
+
When the response body is assigned:
|
27
|
+
\"\"\"
|
28
|
+
{"a": 1, "b": 2}
|
29
|
+
\"\"\"
|
30
|
+
#Equality will match keys
|
31
|
+
Then the value of the response body does have any element that is equal to `a`
|
32
|
+
And the value of the response body does not have any element that is equal to `d`
|
33
|
+
|
34
|
+
Scenario: Spread nested lists
|
35
|
+
When the response body is assigned:
|
36
|
+
\"\"\"
|
37
|
+
[{"val":"foo"},{"val":"bar"}]
|
38
|
+
\"\"\"
|
39
|
+
Then the value of the response body children `..val` does have any element that is equal to `foo`
|
40
|
+
And the value of the response body children `..val` does not have any element that is equal to `other`
|
41
|
+
|
42
|
+
"""
|
43
|
+
When I run `cucumber --strict features/any.feature`
|
44
|
+
Then the output should contain:
|
45
|
+
"""
|
46
|
+
4 passed
|
47
|
+
"""
|
48
|
+
And it should pass
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# cleaner_upper.rb -- clean up resources created during test run
|
2
|
+
#
|
3
|
+
# Will issue DELETE call for all tracked URLs which will normally be triggered in a hook.
|
4
|
+
#
|
5
|
+
# The present approach for this is to explicitly track created resources to which
|
6
|
+
# DELETE calls will be sent. Cleaning up of resources will be given some further attention
|
7
|
+
# in the future, but this functionality should be preserved.
|
8
|
+
|
9
|
+
class DeleteCommand
|
10
|
+
attr_accessor :client, :path
|
11
|
+
|
12
|
+
def initialize(client, path,
|
13
|
+
oks:[200,204],
|
14
|
+
attempts: 3)
|
15
|
+
@client = client
|
16
|
+
@path = path
|
17
|
+
@oks = oks
|
18
|
+
@attempts = attempts
|
19
|
+
end
|
20
|
+
|
21
|
+
def cleanup
|
22
|
+
while @attempts > 0
|
23
|
+
begin
|
24
|
+
resp=@client.delete(@path)
|
25
|
+
return true if @oks.include?(resp.status)
|
26
|
+
rescue ex
|
27
|
+
puts "WARNING: #{ex}"
|
28
|
+
end
|
29
|
+
@attempts -= 1
|
30
|
+
end
|
31
|
+
puts "ERROR: Could not DELETE #{@path}"
|
32
|
+
false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
module CleanerUpper
|
37
|
+
|
38
|
+
# HTTP client object used to issue DELETE calls
|
39
|
+
# must support #delete(path)
|
40
|
+
# to be injected by calling code
|
41
|
+
def set_cleaning_client(client)
|
42
|
+
@client = client
|
43
|
+
end
|
44
|
+
|
45
|
+
# Record resource to be cleaned
|
46
|
+
def track_created_resource(path)
|
47
|
+
created_resources << DeleteCommand.new(@client, path)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Clean recorded resources
|
51
|
+
# Expected to be called after test run
|
52
|
+
def cleanup_created_resources
|
53
|
+
created_resources.reverse.each{|it| it.cleanup}
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
# Lazily initialized array of resources to remove
|
59
|
+
def created_resources
|
60
|
+
@created_resources ||= []
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
## coercer.rb::
|
2
|
+
|
3
|
+
class Coercer
|
4
|
+
def initialize
|
5
|
+
@map = Hash.new(->(l, r){[l, r]})
|
6
|
+
@map[[String, Time]] = ->(l, r){[Time.parse(l), r]}
|
7
|
+
end
|
8
|
+
|
9
|
+
def coerce(l, r)
|
10
|
+
@map[[l.class, r.class]].call(l, r)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module Coercion
|
15
|
+
def coercer
|
16
|
+
@coercer ||= Coercer.new
|
17
|
+
end
|
18
|
+
end
|
data/lib/brine/hooks.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'mustache'
|
2
|
+
|
3
|
+
# Provides a binding environment and template expansion functions that use that
|
4
|
+
# environment
|
5
|
+
module MustacheBinder
|
6
|
+
|
7
|
+
# getter for mutable hash which serves as binding environment
|
8
|
+
def binding
|
9
|
+
@binding ||= {}
|
10
|
+
end
|
11
|
+
|
12
|
+
# assign `value' to `key' within binding
|
13
|
+
# defined in a method to allow observability/interception
|
14
|
+
def bind(key, value)
|
15
|
+
puts "Assigning #{value} to #{key}" if ENV['BRINE_LOG_BINDING']
|
16
|
+
binding[key] = value
|
17
|
+
end
|
18
|
+
|
19
|
+
# return value as expanded Mustache template using binding environment
|
20
|
+
# Mustache in...no Mustache out
|
21
|
+
def shave_value(val)
|
22
|
+
Mustache.render(val, binding)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|