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.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +11 -0
  5. data/Gemfile +3 -0
  6. data/Gemfile.lock +123 -0
  7. data/Guardfile +12 -0
  8. data/LICENSE +21 -0
  9. data/README.md +137 -0
  10. data/Rakefile +32 -0
  11. data/brine-dsl.gemspec +32 -0
  12. data/config/cucumber.yml +2 -0
  13. data/docs/build.gradle +19 -0
  14. data/docs/cookbook.html +567 -0
  15. data/docs/gradle/wrapper/gradle-wrapper.jar +0 -0
  16. data/docs/gradle/wrapper/gradle-wrapper.properties +6 -0
  17. data/docs/gradlew +172 -0
  18. data/docs/gradlew.bat +84 -0
  19. data/docs/guide.html +1149 -0
  20. data/docs/index.html +472 -0
  21. data/docs/specs.html +1672 -0
  22. data/docs/src/cookbook.adoc +87 -0
  23. data/docs/src/guide.adoc +427 -0
  24. data/docs/src/index.adoc +16 -0
  25. data/docs/src/spec.erb +121 -0
  26. data/docs/src/specs.adoc +24 -0
  27. data/features/argument_transforms/boolean.feature +37 -0
  28. data/features/argument_transforms/datetime.feature +45 -0
  29. data/features/argument_transforms/integer.feature +41 -0
  30. data/features/argument_transforms/list.feature +46 -0
  31. data/features/argument_transforms/object.feature +66 -0
  32. data/features/argument_transforms/quoted.feature +41 -0
  33. data/features/argument_transforms/regex.feature +40 -0
  34. data/features/argument_transforms/template.feature +46 -0
  35. data/features/argument_transforms/whitespace.feature +51 -0
  36. data/features/assertions/is_a_valid.feature +184 -0
  37. data/features/assertions/is_equal_to.feature +60 -0
  38. data/features/assertions/is_including.feature +29 -0
  39. data/features/assertions/is_matching.feature +35 -0
  40. data/features/deprecations/replaced_with.feature +35 -0
  41. data/features/request_construction/basic.feature +29 -0
  42. data/features/request_construction/body.feature +26 -0
  43. data/features/request_construction/clearing.feature +46 -0
  44. data/features/request_construction/headers.feature +94 -0
  45. data/features/request_construction/params.feature +60 -0
  46. data/features/resource_cleanup/cleanup.feature +86 -0
  47. data/features/selectors/all.feature +55 -0
  48. data/features/selectors/any.feature +48 -0
  49. data/features/step_definitions/test_steps.rb +5 -0
  50. data/features/support/env.rb +10 -0
  51. data/lib/brine/cleaner_upper.rb +62 -0
  52. data/lib/brine/coercer.rb +18 -0
  53. data/lib/brine/hooks.rb +4 -0
  54. data/lib/brine/mustache_binder.rb +25 -0
  55. data/lib/brine/requester.rb +125 -0
  56. data/lib/brine/rest_steps.rb +138 -0
  57. data/lib/brine/selector.rb +66 -0
  58. data/lib/brine/step_definitions/assertions.rb +37 -0
  59. data/lib/brine/step_definitions/assignment.rb +13 -0
  60. data/lib/brine/step_definitions/cleanup.rb +4 -0
  61. data/lib/brine/step_definitions/request_construction.rb +19 -0
  62. data/lib/brine/step_definitions/selection.rb +37 -0
  63. data/lib/brine/test_steps.rb +138 -0
  64. data/lib/brine/transforms.rb +81 -0
  65. data/lib/brine/type_checks.rb +35 -0
  66. data/lib/brine/util.rb +35 -0
  67. data/lib/brine.rb +39 -0
  68. data/tutorial/missing.feature +5 -0
  69. data/tutorial/post_matching.feature +12 -0
  70. data/tutorial/post_status.feature +10 -0
  71. data/tutorial/support/env.rb +2 -0
  72. 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,5 @@
1
+ # the output should contain: is useful for seeing failures
2
+ # TODO: Swap this out with standard aruba step
3
+ Then(/^it should pass$/) do
4
+ expect(last_command_started).to be_successfully_executed
5
+ end
@@ -0,0 +1,10 @@
1
+ require 'aruba/cucumber'
2
+
3
+ Before do
4
+ write_file 'features/support/env.rb',
5
+ <<-END
6
+ require 'brine'
7
+ require 'brine/test_steps'
8
+ World(brine_mix)
9
+ END
10
+ end
@@ -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
@@ -0,0 +1,4 @@
1
+ # Call CleanerUpper after test run
2
+ After do
3
+ cleanup_created_resources
4
+ end
@@ -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