brine-dsl 0.7.0 → 0.8.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 +4 -4
- data/Gemfile.lock +1 -1
- data/LICENSE +1 -1
- data/README.adoc +29 -0
- data/brine-dsl.gemspec +5 -5
- data/docs/build.gradle +1 -1
- data/docs/cookbook.html +48 -40
- data/docs/guide.html +185 -119
- data/docs/index.html +18 -4
- data/docs/specs.html +227 -1
- data/docs/src/cookbook.adoc +57 -40
- data/docs/src/guide.adoc +227 -133
- data/docs/src/index.adoc +15 -3
- data/docs/src/specs.adoc +11 -0
- data/features/assignment/parameter.feature +20 -0
- data/features/assignment/random.feature +25 -0
- data/features/assignment/response_attribute.feature +33 -0
- data/features/assignment/timestamp.feature +33 -0
- data/lib/brine/cleaner_upper.rb +55 -16
- data/lib/brine/coercer.rb +55 -5
- data/lib/brine/rest_steps.rb +20 -39
- data/lib/brine/step_definitions/assignment.rb +33 -5
- data/lib/brine.rb +13 -8
- metadata +11 -3
- data/README.md +0 -7
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: A Parameter
|
2
|
+
An identifier can be assigned the value of the provided parameter.
|
3
|
+
|
4
|
+
Scenario: Parameter assignment.
|
5
|
+
Given a file named "features/parameter.feature" with:
|
6
|
+
"""
|
7
|
+
|
8
|
+
Feature: Parameter Assignment.
|
9
|
+
Scenario: Simple assignment.
|
10
|
+
Given `foo` is assigned `bar`
|
11
|
+
When the response body is assigned `{{ foo }}`
|
12
|
+
Then the value of the response body is equal to `bar`
|
13
|
+
|
14
|
+
"""
|
15
|
+
When I run `cucumber --strict features/parameter.feature`
|
16
|
+
Then the output should contain:
|
17
|
+
"""
|
18
|
+
1 passed
|
19
|
+
"""
|
20
|
+
And it should pass
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Feature: A Random String
|
2
|
+
An identifier can be assigned a random string with decent entropy.
|
3
|
+
|
4
|
+
Scenario: Random string assignment.
|
5
|
+
Given a file named "features/random.feature" with:
|
6
|
+
"""
|
7
|
+
|
8
|
+
Feature: Random Assignment.
|
9
|
+
Scenario: Several unique variables.
|
10
|
+
Given `v1` is assigned a random string
|
11
|
+
And `v2` is assigned a random string
|
12
|
+
And `v3` is assigned a random string
|
13
|
+
When the response body is assigned `[ "{{ v1 }}","{{ v2 }}","{{ v3 }}" ]`
|
14
|
+
Then the value of the response body does not have any element that is empty
|
15
|
+
And the value of the response body child `.[0]` is equal to `{{ v1 }}`
|
16
|
+
And the value of the response body children `.[1:2]` does not have any element that is equal to `{{ v1 }}`
|
17
|
+
And the value of the response body child `.[2]` is not equal to `{{ v2 }}`
|
18
|
+
|
19
|
+
"""
|
20
|
+
When I run `cucumber --strict features/random.feature`
|
21
|
+
Then the output should contain:
|
22
|
+
"""
|
23
|
+
8 passed
|
24
|
+
"""
|
25
|
+
And it should pass
|
@@ -0,0 +1,33 @@
|
|
1
|
+
Feature: A Value From A Response Attribute.
|
2
|
+
An identifier can be assigned a value extracted from a response attribute.
|
3
|
+
|
4
|
+
Scenario: Assorted attribute extractions.
|
5
|
+
Given a file named "features/response_attribute.feature" with:
|
6
|
+
"""
|
7
|
+
|
8
|
+
Feature: Reponse Attribute Path Assignment.
|
9
|
+
Scenario: Response body.
|
10
|
+
Given the response body is assigned `foo`
|
11
|
+
When `myVar` is assigned the response body
|
12
|
+
And the response body is assigned `{{ myVar }}`
|
13
|
+
Then the value of the response body is equal to `foo`
|
14
|
+
|
15
|
+
Scenario: Response body child.
|
16
|
+
Given the response body is assigned `{"response": "foo"}`
|
17
|
+
When `myVar` is assigned the response body child `.response`
|
18
|
+
And the response body is assigned `{{ myVar }}`
|
19
|
+
Then the value of the response body is equal to `foo`
|
20
|
+
|
21
|
+
Scenario: Response body children.
|
22
|
+
Given the response body is assigned `{"response": "foo"}`
|
23
|
+
When `myVar` is assigned the response body children `.response`
|
24
|
+
And the response body is assigned `{{{ myVar }}}`
|
25
|
+
Then the value of the response body is equal to `["foo"]`
|
26
|
+
|
27
|
+
"""
|
28
|
+
When I run `cucumber --strict features/response_attribute.feature`
|
29
|
+
Then the output should contain:
|
30
|
+
"""
|
31
|
+
3 passed
|
32
|
+
"""
|
33
|
+
And it should pass
|
@@ -0,0 +1,33 @@
|
|
1
|
+
Feature: A Timestamp
|
2
|
+
An identifier can be assigned a current timestamp.
|
3
|
+
|
4
|
+
Scenario: Timestamp assignment.
|
5
|
+
Given a file named "features/timestamp.feature" with:
|
6
|
+
"""
|
7
|
+
|
8
|
+
Feature: Timestamp Assignment.
|
9
|
+
Scenario: Newer than some old date.
|
10
|
+
Given `v1` is assigned a timestamp
|
11
|
+
When the response body is assigned `{{ v1 }}`
|
12
|
+
Then value of the response body is greater than `2018-06-17T12:00:00Z`
|
13
|
+
|
14
|
+
Scenario: Values increase.
|
15
|
+
Given `v1` is assigned a timestamp
|
16
|
+
When the response body is assigned `{{ v1 }}`
|
17
|
+
Then the value of the response body is not empty
|
18
|
+
|
19
|
+
When `v2` is assigned a timestamp
|
20
|
+
And the response body is assigned `{{ v2 }}`
|
21
|
+
Then the value of the response body is greater than or equal to `{{ v1 }}`
|
22
|
+
|
23
|
+
When `v3` is assigned a timestamp
|
24
|
+
And the response body is assigned `{{ v3 }}`
|
25
|
+
Then the value of the response body is greater than or equal to `{{ v1 }}`
|
26
|
+
And the value of the response body is greater than or equal to `{{ v2 }}`
|
27
|
+
|
28
|
+
"""
|
29
|
+
When I run `cucumber --strict features/timestamp.feature`
|
30
|
+
Then the output should contain:
|
31
|
+
"""
|
32
|
+
2 passed
|
33
|
+
"""
|
data/lib/brine/cleaner_upper.rb
CHANGED
@@ -1,23 +1,37 @@
|
|
1
|
-
|
1
|
+
##
|
2
|
+
# @file cleaner_upper.rb
|
3
|
+
# Clean up resources created during test run.
|
2
4
|
#
|
3
|
-
# Will issue DELETE call for all tracked URLs which will normally be triggered
|
5
|
+
# Will issue DELETE call for all tracked URLs which will normally be triggered
|
6
|
+
# in a hook.
|
4
7
|
#
|
5
|
-
# The present approach for this is to explicitly track created resources to
|
6
|
-
# DELETE calls will be sent. Cleaning up of resources will be given some
|
7
|
-
# in the future, but this functionality should be preserved.
|
8
|
+
# The present approach for this is to explicitly track created resources to
|
9
|
+
# which DELETE calls will be sent. Cleaning up of resources will be given some
|
10
|
+
# further attention in the future, but this functionality should be preserved.
|
8
11
|
|
12
|
+
##
|
13
|
+
# A command object for the delete which will be executed as part of cleaning up.
|
9
14
|
class DeleteCommand
|
10
|
-
attr_accessor :client, :path
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
|
16
|
+
##
|
17
|
+
# Construct a command with the required paramters to perform the delete.
|
18
|
+
#
|
19
|
+
# @param client The Faraday client which will send the delete message.
|
20
|
+
# @param path The path of the resource to be deleted.
|
21
|
+
# @param oks The response status codes which will be considered successful.
|
22
|
+
# @param attempts The number of times this command should be tried,
|
23
|
+
# retrying if an unsuccessful status code is received.
|
24
|
+
def initialize(client, path, oks: [200,204], attempts: 3)
|
15
25
|
@client = client
|
16
26
|
@path = path
|
17
27
|
@oks = oks
|
18
28
|
@attempts = attempts
|
19
29
|
end
|
20
30
|
|
31
|
+
##
|
32
|
+
# Issue the delete based on the parameters provided during construction.
|
33
|
+
#
|
34
|
+
# @returns true if a successful response is obtained, otherwise false.
|
21
35
|
def cleanup
|
22
36
|
while @attempts > 0
|
23
37
|
begin
|
@@ -33,29 +47,54 @@ class DeleteCommand
|
|
33
47
|
end
|
34
48
|
end
|
35
49
|
|
50
|
+
##
|
51
|
+
# A mixin which provides resource cleanup.
|
52
|
+
#
|
53
|
+
# Exposes methods to keep a stack of DeleteCommands corresponding to each
|
54
|
+
# created resource which are then popped and invoked to perform the cleanup.
|
55
|
+
#
|
56
|
+
# The LIFO behavior is adopted as it is more likely to preserve integrity,
|
57
|
+
# such as removing children added to parents or similar dependencies.
|
36
58
|
module CleanerUpper
|
37
59
|
|
38
|
-
|
39
|
-
#
|
40
|
-
#
|
60
|
+
##
|
61
|
+
# Set the Faraday HTTP client object used to issue DELETE calls.
|
62
|
+
#
|
63
|
+
# The client provided will be subsequently used to create DeleteCommands.
|
64
|
+
# This can be called multiple times where each DeleteCommand will use the
|
65
|
+
# most recently set value. In most use cases this will also be the client
|
66
|
+
# used to issue the creation requests and could therefore be passed to this
|
67
|
+
# method prior to use.
|
68
|
+
#
|
69
|
+
# @param client - The client to use to DELETE subsequently tracked resources.
|
41
70
|
def set_cleaning_client(client)
|
42
71
|
@client = client
|
43
72
|
end
|
44
73
|
|
45
|
-
|
74
|
+
##
|
75
|
+
# Record resource to be later cleaned (pushes a DeleteCommand).
|
76
|
+
#
|
77
|
+
# @param path - The path for the created resource, will be issued a DELETE.
|
46
78
|
def track_created_resource(path)
|
47
79
|
created_resources << DeleteCommand.new(@client, path)
|
48
80
|
end
|
49
81
|
|
50
|
-
|
51
|
-
#
|
82
|
+
##
|
83
|
+
# Clean recorded resources (normally after a test run).
|
52
84
|
def cleanup_created_resources
|
53
85
|
created_resources.reverse.each{|it| it.cleanup}
|
54
86
|
end
|
55
87
|
|
56
88
|
private
|
57
89
|
|
58
|
-
|
90
|
+
##
|
91
|
+
# The array which serves as the stack of DeleteCommands.
|
92
|
+
#
|
93
|
+
# Works as a "module provided property" which is a name I
|
94
|
+
# may have just made up.
|
95
|
+
#
|
96
|
+
# TODO: Find proper term for module provided property
|
97
|
+
# TODO: The name of this property seems sloppy as it contains commands.
|
59
98
|
def created_resources
|
60
99
|
@created_resources ||= []
|
61
100
|
end
|
data/lib/brine/coercer.rb
CHANGED
@@ -1,13 +1,63 @@
|
|
1
|
-
##
|
1
|
+
##
|
2
|
+
# @file coercer.rb
|
3
|
+
# Type coercion to support assertions.
|
2
4
|
|
5
|
+
##
|
6
|
+
# Coerces the types of provided objects to support desired assertions.
|
7
|
+
#
|
8
|
+
# Coercion is used to support handling richer data types in Brine without
|
9
|
+
# introducing noisy type information to the language.
|
10
|
+
# Argument Transforms can be used to convert input provided directly
|
11
|
+
# to a Brine step, however data extracted from JSON will by default be
|
12
|
+
# limited to the small amount of JSON supported data types. As normally
|
13
|
+
# the data extracted from JSON will only be directly present on one side
|
14
|
+
# of the assertion (most likely the left), the simpler JSON data types can
|
15
|
+
# be coerced to a richer type based on the right hand side.
|
16
|
+
#
|
17
|
+
# A standard example (and that which is defined at the moment here) is date/time
|
18
|
+
# values. When testing an API that returns such values it is likely desirable to
|
19
|
+
# perform assertions with proper date/time semantics, and the coercer allows
|
20
|
+
# such assertions against a value retrieved out of a JSON structure.
|
21
|
+
#
|
22
|
+
# The combination of Argument Transforms and the Coercer can also effectively
|
23
|
+
# allow for user defined types to seemlessly exist within the Brine tests.
|
24
|
+
# The date/time implementation is an example of this.
|
25
|
+
# TODO: Document this in a friendlier place, with a contrived example.
|
26
|
+
# TODO: Having the default Time stuff should likely be removed for v2.
|
27
|
+
#
|
28
|
+
# Implementation (Most of the non-implementation info should later be moved).
|
29
|
+
# ---
|
30
|
+
# Internally the Coercer is a wrapper around a map of coercion functions
|
31
|
+
# where the keys are the pairs of classes for the operands and the
|
32
|
+
# values are the functions which accept a pair of instances (ostensibly) of the
|
33
|
+
# classes and return a pair of transformed values. The default coercion function
|
34
|
+
# returns the inputs unmodified (a nop), so any pair of classes which does not
|
35
|
+
# have a key will pass through unchanged.
|
36
|
+
#
|
37
|
+
# Note that this relies solely on the hash lookup and does not attempt any kind
|
38
|
+
# of inheritance lookup or similar. The current thinking is that there should be
|
39
|
+
# few expected types and lineage could be covered through explicit keys so the
|
40
|
+
# simple, dumb approach is likely sufficient.
|
3
41
|
class Coercer
|
42
|
+
##
|
43
|
+
# Instantiate a new Coercer.
|
44
|
+
#
|
45
|
+
# Initialize the standard map of coercion functions.
|
4
46
|
def initialize
|
5
|
-
@map = Hash.new(->(
|
6
|
-
@map[[String, Time]] = ->(
|
47
|
+
@map = Hash.new(->(lhs, rhs){[lhs, rhs]})
|
48
|
+
@map[[String, Time]] = ->(lhs, rhs){[Time.parse(lhs), rhs]}
|
7
49
|
end
|
8
50
|
|
9
|
-
|
10
|
-
|
51
|
+
##
|
52
|
+
# Coerce the provided inputs as needed.
|
53
|
+
#
|
54
|
+
# Looks up and invokes the associated coercion function.
|
55
|
+
#
|
56
|
+
# @param lhs - The left hand side input.
|
57
|
+
# @param rhs - The right hand side input.
|
58
|
+
# @returns A pair (2 element array) of potentially coerced values.
|
59
|
+
def coerce(lhs, rhs)
|
60
|
+
@map[[lhs.class, rhs.class]].call(lhs, rhs)
|
11
61
|
end
|
12
62
|
end
|
13
63
|
|
data/lib/brine/rest_steps.rb
CHANGED
@@ -4,23 +4,28 @@ require 'brine/selector'
|
|
4
4
|
require 'jsonpath'
|
5
5
|
|
6
6
|
# Chopping Block
|
7
|
-
|
8
|
-
|
7
|
+
Then(/^the response #{RESPONSE_ATTRIBUTES} has `([^`]*)` with a value that is not empty$/) do
|
8
|
+
|attribute, member|
|
9
|
+
replaced_with('Then', "the value of the response #{attribute} child `#{member}` is not empty", '0.9')
|
9
10
|
end
|
10
|
-
|
11
|
-
|
11
|
+
|
12
|
+
Then(/^the response #{RESPONSE_ATTRIBUTES} includes? the entries:$/) do |attribute, table|
|
13
|
+
replaced_with('Then', "the value of the response #{attribute} is including:\n\"\"\"#{table.hashes.to_json}\"\"\"", '0.9')
|
12
14
|
end
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
|
16
|
+
Then(/^the response body is a list of length (\d+)$/) do |length|
|
17
|
+
replaced_with('Then', "the value of the response body is of length #{length}", '0.9')
|
16
18
|
end
|
17
|
-
|
18
|
-
|
19
|
+
|
20
|
+
Then(/^the response body is a list (with|without) an entry containing:$/) do |with, data|
|
21
|
+
neg = (with == 'without') ? 'not ' : ''
|
22
|
+
replaced_with('Then', "the value of the response body does #{neg}have any element that is including:\n\"\"\"#{table.hashes.to_json}\"\"\"", '0.9')
|
19
23
|
end
|
20
24
|
|
21
|
-
Then(/^the response
|
22
|
-
|
|
23
|
-
|
25
|
+
Then(/^the response body has `([^`]*)` which (in|ex)cludes? the entries:$/) do
|
26
|
+
|child, in_or_ex, table|
|
27
|
+
neg = (in_or_ex=='ex') ? 'not ' : ''
|
28
|
+
replaced_with('Then', "the value of the response body child `#{child}` is #{neg}including:\n\"\"\"#{table.hashes.to_json}\"\"\"", '0.9')
|
24
29
|
end
|
25
30
|
|
26
31
|
# This file is legacy or unsorted steps which will be deprecated or moved into
|
@@ -33,13 +38,13 @@ def kv_table(table)
|
|
33
38
|
transform_table!(table).rows_hash
|
34
39
|
end
|
35
40
|
|
41
|
+
# TODO: Requires extensible is_a_valid for deprecation
|
36
42
|
Then(/^the response body is a list which all are (\w+)$/) do |matcher|
|
37
43
|
pass_it = method(matcher.to_sym).call
|
38
44
|
expect(response_body_child.first).to all(pass_it)
|
39
45
|
end
|
40
46
|
|
41
|
-
#
|
42
|
-
# without requiring a custom step
|
47
|
+
# FIXME: In the process of being deprecated
|
43
48
|
When(/^`([^`]*)` is bound to `([^`]*)` from the response body$/) do |name, path|
|
44
49
|
binding[name] = response_body_child(path).first
|
45
50
|
end
|
@@ -47,15 +52,6 @@ end
|
|
47
52
|
#
|
48
53
|
# Response attribute (non-body) assertions
|
49
54
|
#
|
50
|
-
Then(/^the response #{RESPONSE_ATTRIBUTES} has `([^`]*)` with a value that is not empty$/) do
|
51
|
-
|attribute, member|
|
52
|
-
expect(response).to have_attributes(attribute.to_sym => include(member.to_sym => be_not_empty))
|
53
|
-
end
|
54
|
-
|
55
|
-
Then(/^the response #{RESPONSE_ATTRIBUTES} includes? the entries:$/) do |attribute, table|
|
56
|
-
expect(response).to have_attributes(attribute.to_sym => include(kv_table(table)))
|
57
|
-
end
|
58
|
-
|
59
55
|
Then(/^the response #{RESPONSE_ATTRIBUTES} contains? null fields:$/) do |attribute, table|
|
60
56
|
expect(response)
|
61
57
|
.to have_attributes(attribute.to_sym =>
|
@@ -71,21 +67,11 @@ end
|
|
71
67
|
#
|
72
68
|
# Response body assertions
|
73
69
|
#
|
70
|
+
# TODO: Write specifications around this
|
74
71
|
Then(/^the response body does not contain fields:$/) do |table|
|
75
72
|
expect(response_body_child.first.keys).to_not include(*table.raw.flatten)
|
76
73
|
end
|
77
74
|
|
78
|
-
Then(/^the response body has `([^`]*)` which (in|ex)cludes? the entries:$/) do
|
79
|
-
|child, in_or_ex, table|
|
80
|
-
expect(response_body_child(child).first)
|
81
|
-
.send(not_if(in_or_ex=='ex'),
|
82
|
-
include(kv_table(table)))
|
83
|
-
end
|
84
|
-
|
85
|
-
Then(/^the response body is a list of length (\d+)$/) do |length|
|
86
|
-
expect(response_body_child.first).to have_attributes(length: length)
|
87
|
-
end
|
88
|
-
|
89
75
|
#TODO: Maybe worth optimizing these 2 to O(n) after tests are in place
|
90
76
|
Then(/^the response body is a list sorted by `([^`]*)` ascending$/) do |path|
|
91
77
|
values = response_body_child(path)
|
@@ -97,11 +83,6 @@ Then(/^the response body is a list sorted by `([^`]*)` descending$/) do |path|
|
|
97
83
|
expect(values).to eq values.sort{|a,b| b.to_s.downcase <=> a.to_s.downcase}
|
98
84
|
end
|
99
85
|
|
100
|
-
Then(/^the response body is a list (with|without) an entry containing:$/) do |with, data|
|
101
|
-
expect(response_body_child.first)
|
102
|
-
.send(not_if(with == 'without'),
|
103
|
-
include(include(kv_table(data))))
|
104
|
-
end
|
105
86
|
|
106
87
|
Then(/^the response body is (\w+)$/) do |matcher|
|
107
88
|
pass_it = method(matcher.to_sym).call
|
@@ -1,13 +1,41 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
bind(name, SecureRandom.uuid)
|
5
|
-
end
|
1
|
+
##
|
2
|
+
# @file assignment.rb
|
3
|
+
# Assignment related steps.
|
6
4
|
|
5
|
+
##
|
6
|
+
# Assign the provided parameter.
|
7
|
+
#
|
8
|
+
# @param name - The identifier to which the value will be bound.
|
9
|
+
# @param value - The value to bind to the identifier.
|
7
10
|
When(/^`([^`]*)` is assigned `([^`]*)`$/) do |name, value|
|
8
11
|
bind(name, value)
|
9
12
|
end
|
10
13
|
|
14
|
+
##
|
15
|
+
# Assign a random string (UUID).
|
16
|
+
#
|
17
|
+
# @param name - The identifier to which a random string will be bound.
|
18
|
+
When(/^`([^`]*)` is assigned a random string$/) do |name|
|
19
|
+
bind(name, SecureRandom.uuid)
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# Assign a current timestamp.
|
24
|
+
#
|
25
|
+
# @param name - The identifier to which the current timestamp will be bound.
|
11
26
|
When(/^`([^`]*)` is assigned a timestamp$/) do |name|
|
12
27
|
bind(name, DateTime.now)
|
13
28
|
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Assign a value extracted from a response attribute.
|
32
|
+
#
|
33
|
+
# @param name - The identifier to which the extracted value will be bound.
|
34
|
+
# @param attribute - The response member from which the value will be extracted.
|
35
|
+
# @param plural - When the path is provided,
|
36
|
+
# @param path - The path within the member to extract.
|
37
|
+
# whether to extract a single match or a collection of all matching.
|
38
|
+
When(/^`([^`]*)` is assigned the response #{RESPONSE_ATTRIBUTES}(?: child(ren)? `([^`]*)`)?$/) do
|
39
|
+
|name, attribute, plural, path|
|
40
|
+
bind(name, dig_from_response(attribute, path, !plural.nil?))
|
41
|
+
end
|
data/lib/brine.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
-
|
1
|
+
##
|
2
|
+
# @file brine.rb
|
3
|
+
# Loader file for the rest of brine.
|
2
4
|
#
|
3
5
|
# The primary goal of this file is to load all resources needed to use brine.
|
4
|
-
# A secondary goal which should inform how that is done is that loading this
|
5
|
-
# should provide new objects but not otherwise impact existing
|
6
|
-
# modifying the World or defining any Steps, Transforms,
|
7
|
-
# Those types of changes should be done by
|
6
|
+
# A secondary goal which should inform how that is done is that loading this
|
7
|
+
# file by itself should provide new objects but not otherwise impact existing
|
8
|
+
# state such as by modifying the World or defining any Steps, Transforms, etc.
|
9
|
+
# Those types of changes should be done by @ref #brine_mix.
|
8
10
|
|
9
11
|
require 'brine/cleaner_upper'
|
10
12
|
require 'brine/mustache_binder'
|
@@ -13,7 +15,8 @@ require 'brine/util'
|
|
13
15
|
require 'brine/selector'
|
14
16
|
require 'brine/type_checks'
|
15
17
|
|
16
|
-
|
18
|
+
##
|
19
|
+
# Meta-module for modules to mix into World.
|
17
20
|
module Brine
|
18
21
|
include CleanerUpper
|
19
22
|
include MustacheBinder
|
@@ -23,8 +26,10 @@ module Brine
|
|
23
26
|
include TypeChecking
|
24
27
|
end
|
25
28
|
|
26
|
-
|
27
|
-
#
|
29
|
+
##
|
30
|
+
# Load the files with side effects and return @ref Brine.
|
31
|
+
#
|
32
|
+
# Expected to be called as `World(brine_mix)`
|
28
33
|
def brine_mix
|
29
34
|
require 'brine/step_definitions/assignment'
|
30
35
|
require 'brine/step_definitions/request_construction'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brine-dsl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Whipple
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-06-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cucumber
|
@@ -193,7 +193,7 @@ files:
|
|
193
193
|
- Gemfile.lock
|
194
194
|
- Guardfile
|
195
195
|
- LICENSE
|
196
|
-
- README.
|
196
|
+
- README.adoc
|
197
197
|
- Rakefile
|
198
198
|
- brine-dsl.gemspec
|
199
199
|
- config/cucumber.yml
|
@@ -226,6 +226,10 @@ files:
|
|
226
226
|
- features/assertions/is_including.feature
|
227
227
|
- features/assertions/is_matching.feature
|
228
228
|
- features/assertions/is_of_length.feature
|
229
|
+
- features/assignment/parameter.feature
|
230
|
+
- features/assignment/random.feature
|
231
|
+
- features/assignment/response_attribute.feature
|
232
|
+
- features/assignment/timestamp.feature
|
229
233
|
- features/deprecations/replaced_with.feature
|
230
234
|
- features/request_construction/basic.feature
|
231
235
|
- features/request_construction/body.feature
|
@@ -298,6 +302,10 @@ test_files:
|
|
298
302
|
- features/assertions/is_including.feature
|
299
303
|
- features/assertions/is_matching.feature
|
300
304
|
- features/assertions/is_of_length.feature
|
305
|
+
- features/assignment/parameter.feature
|
306
|
+
- features/assignment/random.feature
|
307
|
+
- features/assignment/response_attribute.feature
|
308
|
+
- features/assignment/timestamp.feature
|
301
309
|
- features/deprecations/replaced_with.feature
|
302
310
|
- features/request_construction/basic.feature
|
303
311
|
- features/request_construction/body.feature
|