brine-dsl 0.10.0 → 0.11.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 690350fecddec6e5978bcb684189f2ac742a7918
4
- data.tar.gz: 6a37f34f8424ac9422517f3cc0282cb8eb5b321d
2
+ SHA256:
3
+ metadata.gz: 906c5a5791f773d74511eb23f0dd53a1ee25f29d3e7b4318f8b1b2f4299c5696
4
+ data.tar.gz: 06d1b4ffc9d6a745f06b2ebb7c6164b650d3c5fa6d6cd918dcb9c406a1b98656
5
5
  SHA512:
6
- metadata.gz: 41b4ddf87394b647485b3ae8f77c517742661330583650eebf980e52050b2b8878f6d27c150613682e4da04b3ad0c109c62d97018a36effcb698e4f5bda3caae
7
- data.tar.gz: 786aa5afef5cca973ac32c12b5fac728810da1d1eeface795254ac9d61f2b1f14b6fb4978c7f14463616f7342f45e30aabe02b566e32af09b64e9e2687a9e326
6
+ metadata.gz: d94513fc23ac9e9d5d21e45641821c1e90e9b06245947d68007277e033efff64fc6bc2054750e0d451c8455c8088614a52621cd63e45f3b925ef20171f8be7c0
7
+ data.tar.gz: 3395d12a8fd7c8ee1b3df7e86474807ec3c666e49a3d6c974f77dad51d5175b87ece0ecbc016cd823e1beb7feba8357ec2067a4a2167400405478e444cffab6a
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- brine-dsl (0.10.2.pre.SNAPSHOT)
4
+ brine-dsl (0.11.0)
5
5
  cucumber (~> 2.4)
6
6
  faraday (~> 0.12)
7
7
  faraday_middleware (~> 0.12)
@@ -52,15 +52,15 @@ GEM
52
52
  rspec-core (~> 3.8.0)
53
53
  rspec-expectations (~> 3.8.0)
54
54
  rspec-mocks (~> 3.8.0)
55
- rspec-core (3.8.0)
55
+ rspec-core (3.8.1)
56
56
  rspec-support (~> 3.8.0)
57
- rspec-expectations (3.8.3)
57
+ rspec-expectations (3.8.4)
58
58
  diff-lcs (>= 1.2.0, < 2.0)
59
59
  rspec-support (~> 3.8.0)
60
- rspec-mocks (3.8.0)
60
+ rspec-mocks (3.8.1)
61
61
  diff-lcs (>= 1.2.0, < 2.0)
62
62
  rspec-support (~> 3.8.0)
63
- rspec-support (3.8.0)
63
+ rspec-support (3.8.2)
64
64
  to_regexp (0.2.1)
65
65
 
66
66
  PLATFORMS
data/Rakefile CHANGED
@@ -1,12 +1,5 @@
1
1
  # encoding: utf-8
2
2
  require 'bundler'
3
- require 'cucumber/rake/task'
4
-
5
- Cucumber::Rake::Task.new(:check) do |t|
6
- # Cucumber needs some help to deal with the features and support being split.
7
- t.libs = "#{__dir__}"
8
- end
9
3
 
10
4
  Bundler::GemHelper.install_tasks
11
5
 
12
- task default: %w[check]
data/lib/brine.rb CHANGED
@@ -30,7 +30,7 @@ def brine_mix
30
30
  require 'brine/step_definitions/perform'
31
31
  require 'brine/step_definitions/selection'
32
32
 
33
- require 'brine/transforms'
33
+ require 'brine/transforming'
34
34
  require 'brine/hooks'
35
35
 
36
36
  Brine
@@ -69,6 +69,7 @@ module Brine
69
69
  def coerce(first, second)
70
70
  @map[[first.class, second.class]].call(first, second)
71
71
  end
72
+
72
73
  end
73
74
 
74
75
  ##
@@ -2,7 +2,6 @@
2
2
  # @file mustache_expanding.rb
3
3
  # Support for expanding Mustache templates with a defined binding.
4
4
  ##
5
-
6
5
  module Brine
7
6
 
8
7
  ##
@@ -33,15 +32,52 @@ module Brine
33
32
 
34
33
  ##
35
34
  # Expanded Mustache template using binding environment.
36
- # Mustache in...no Mustache out.
35
+ #
36
+ # This exists to support latent expansion and template retrieval.
37
37
  #
38
38
  # @param [String] template Template content to expand with binding.
39
39
  # @return [String] The contents of `template` with any expansions done using `binding`.
40
40
  ##
41
- def shave_value(template)
42
- Mustache.render(template, binding)
41
+ class BrineTemplate < Mustache
42
+
43
+ ##
44
+ # Instantiate a Brine template.
45
+ #
46
+ # @param tmpl [String] The string content of the template.
47
+ # @param binding [Hash] A reference to the (mutable) binding.
48
+ ##
49
+ def initialize(tmpl, binding)
50
+ @template = tmpl
51
+ @binding = binding
52
+ end
53
+
54
+ ##
55
+ # Expand the template using the current bindings.
56
+ ##
57
+ def expand
58
+ begin
59
+ context.push(@binding)
60
+ render
61
+ ensure
62
+ context.pop
63
+ end
64
+ end
65
+
66
+ ##
67
+ # Stringify as template contents.
68
+ #
69
+ # This supports cases such as dynamic steps
70
+ # where a string is expected but the template should not yet
71
+ # be expanded.
72
+ ##
73
+ def to_s
74
+ @template
75
+ end
43
76
  end
44
77
 
78
+ def as_template(str)
79
+ BrineTemplate.new(str, binding)
80
+ end
45
81
  end
46
82
 
47
83
  ##
@@ -3,6 +3,8 @@
3
3
  # Selection of one or more values to be used by Brine (normally for assertion).
4
4
  ##
5
5
 
6
+ require 'brine/transforming.rb'
7
+
6
8
  module Brine
7
9
 
8
10
  ##
@@ -23,6 +25,7 @@ module Brine
23
25
  # which it applied against the targeted value.
24
26
  ##
25
27
  class Selector
28
+ include ParameterTransforming
26
29
  include RSpec::Matchers
27
30
 
28
31
  ##
@@ -69,7 +72,7 @@ module Brine
69
72
  def assert_that(value, negated=nil)
70
73
  # shim while moving negation to assertions.
71
74
  negated = @negated if negated.nil?
72
- target, value = coercer.coerce(@target, value)
75
+ target, value = coercer.coerce(expand(@target), expand(value))
73
76
  message = negated ? :to_not : :to
74
77
  matcher = filter_matcher(yield(value))
75
78
  expect(target).send(message, matcher)
@@ -156,11 +159,12 @@ end
156
159
  RESPONSE_ATTRIBUTES='(status|headers|body)'
157
160
  Then(/^the value of `([^`]*)` is( not)? (.*)$/) do |value, negated, assertion|
158
161
  select(value, (!negated.nil?))
159
- step "it is #{assertion}"
162
+ # Stringify in case the assertion clause is a template.
163
+ step "it is #{assertion.to_s}"
160
164
  end
161
165
 
162
166
  def dig_from_response(attribute, path=nil, plural=false)
163
167
  root = response.send(attribute.to_sym)
164
168
  return root if !path
165
- JsonPath.new("$.#{path}").send(plural ? :on : :first, root)
169
+ JsonPath.new("$.#{path}").send(plural ? :on : :first, expand(root))
166
170
  end
@@ -0,0 +1,170 @@
1
+ ##
2
+ # @file transforming.rb
3
+ # Argument Parameter transforming for Brine.
4
+ ##
5
+ module Brine
6
+
7
+ ##
8
+ #
9
+ # A module that converts provided paramters to richer types.
10
+ #
11
+ # This eases use of types beyond the Cucumber-provided simple strings.
12
+ ##
13
+ module ParameterTransforming
14
+
15
+ ##
16
+ # A class which will transform supported input.
17
+ #
18
+ # This implementation is designed around instances being
19
+ # defined with patterns which define whether they should handle
20
+ # provided input, and procs which should do the transformation
21
+ # (when the patterns match).
22
+ ##
23
+ class Transformer
24
+ attr_reader :type
25
+
26
+ ##
27
+ # Return a new Transformer instance configured as specified.
28
+ #
29
+ # @param [String] type The name of the type produced by this transformer.
30
+ # This will be used for upcoming explicit type conversion.
31
+ # @param [Regexp] pattern A pattern which input should match for this Transformer to function.
32
+ # @param [Proc] xfunk The function which will be passed string input and will return
33
+ # the output type of this Transformer.
34
+ ##
35
+ def initialize(type, pattern, &xfunc)
36
+ @type = type
37
+ @pattern = pattern
38
+ @xfunc = xfunc
39
+ end
40
+
41
+ ##
42
+ # Whether this instance should attempt to transform the input.
43
+ #
44
+ # @param [String] input The String input as provided by Cucumber.
45
+ # @return [Boolean] Whether this#transform should be called for input.
46
+ ##
47
+ def can_handle?(input)
48
+ input =~ @pattern
49
+ end
50
+
51
+ ##
52
+ # Transform the provided input.
53
+ #
54
+ # @param [String] input The String input as provided by Cucumber.
55
+ # @return [Object] The transformed input into the appropriate type.
56
+ ##
57
+ def transform(input)
58
+ STDERR.puts("Handling #{input} as #{@type}") if ENV['BRINE_LOG_TRANSFORMS']
59
+ @xfunc.call(input)
60
+ end
61
+ end
62
+
63
+ # Constants used for DateTime transformation.
64
+ DATE='\d{4}-\d{2}-\d{2}'
65
+ TIME='\d{2}:\d{2}:\d{2}'
66
+ MILLIS='(?:\.\d{3})?'
67
+ TZ='(?:Z|(?:[+-]\d{2}:\d{2}))'
68
+
69
+ ##
70
+ # The chain of Transformers which will be used to convert parameters.
71
+ #
72
+ # In the default implicit mode the list will be iterated over in sequence
73
+ # and the first Transformer which can handle the input will be used.
74
+ # The order of the Transformers is therefore significant: higher priority
75
+ # or more specific Transfomers should be earlier in the list than those
76
+ # that are lower priority or can handle a superset of supported input
77
+ # relative to those previous.
78
+ #
79
+ # This exposed for direct list manipulation as an advanced customization point.
80
+ ##
81
+ def parameter_transformers
82
+ @parameter_transformers ||= [
83
+
84
+ # These will be deprecated in preference for explicit type specification.
85
+ Transformer.new('Double Quoted', /\A".*"\z/) {|input|
86
+ input[1..-2] },
87
+ Transformer.new('Single Quoted', /\A'.*'\z/) {|input|
88
+ input[1..-2] },
89
+
90
+ # Whitespace removal transforms
91
+ # Handle stripping leading and trailing whitespace.
92
+ # These are split out from the transforms to consolidate the behavior.
93
+ # They call transform on the stripped value so that subsequent transforms no longer
94
+ # have to deal with such whitespace.
95
+ #
96
+ # Note that these need to deal with multiline string arguments which require
97
+ # the multiline flag and \A/\z anchors to properly operate on the full string rather than
98
+ # being line oriented. The calls to +#strip+ are also not likely to properly clean up
99
+ # multiline strings but is just meant as a (potentially ineffective) optimization over
100
+ # recursive calls and capturing.
101
+ Transformer.new('Trailing Whitespace', /\A\s+.*\z/) {|input|
102
+ transformed_parameter(input.strip) },
103
+ Transformer.new('Leading Whitespace', /\A.*\s+\z/m) {|input|
104
+ transformed_parameter(input.strip) },
105
+
106
+ # Template Expansion
107
+ Transformer.new('Template', /.*{{.*}}.*/) {|input|
108
+ as_template(input) },
109
+
110
+ # Scalars
111
+ Transformer.new('Integer', /\A-?\d+\z/) {|input|
112
+ input.to_i },
113
+ Transformer.new('Boolean', /\Atrue|false\z/) {|input|
114
+ input.to_s == "true" },
115
+ # This presently does not support flags after the closing slash, support for these should be added as needed
116
+ Transformer.new('Regex', /\A\/.*\/\z/) {|input|
117
+ Regexp.new(input[1..-2]) },
118
+ Transformer.new('DateTime', /^#{DATE}T#{TIME}#{MILLIS}#{TZ}$/) {|input|
119
+ Time.parse(input) },
120
+
121
+ # Structures
122
+ Transformer.new('Array', /\A\[.*\]\z/m) {|input| JSON.parse(input) },
123
+ Transformer.new('Object', /\A{.*}\z$/m) {|input| JSON.parse(input) },
124
+
125
+ # String sentinel...this is last to act as a catch-all.
126
+ Transformer.new('String', /.*/) {|input| input },
127
+ ]
128
+ end
129
+
130
+ ##
131
+ # Transform the provided input using #parameter_transformers.
132
+ #
133
+ # @param [String] input The String input as provided by Cucumber.
134
+ # @return [Object] The input converted by the handling Transformer.
135
+ ##
136
+ def transformed_parameter(input)
137
+ parameter_transformers.find {|it| it.can_handle? input }
138
+ .transform(input)
139
+ end
140
+
141
+ ##
142
+ # Expand val if needed and transform the result.
143
+ #
144
+ # If val is not `expand`able it will be returned as is.
145
+ #
146
+ # @param [Object] val The value to potentially expand.
147
+ # @return The expanded value of val.
148
+ ##
149
+ def expand(val)
150
+ if val.respond_to? :expand
151
+ transformed_parameter(val.expand)
152
+ else
153
+ val
154
+ end
155
+ end
156
+
157
+ end
158
+
159
+ ##
160
+ # Mix the ParameterTransforming module functionality into the main Brine module.
161
+ ##
162
+ include ParameterTransforming
163
+ end
164
+
165
+ ##
166
+ # Configure Cucumber to use these transformers.
167
+ ##
168
+ Transform /.*/ do |input|
169
+ transformed_parameter(input)
170
+ end
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.10.0
4
+ version: 0.11.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: 2019-05-29 00:00:00.000000000 Z
11
+ date: 2019-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cucumber
@@ -153,7 +153,7 @@ files:
153
153
  - lib/brine/step_definitions/request_construction.rb
154
154
  - lib/brine/step_definitions/selection.rb
155
155
  - lib/brine/test_steps.rb
156
- - lib/brine/transforms.rb
156
+ - lib/brine/transforming.rb
157
157
  - lib/brine/type_checking.rb
158
158
  - lib/brine/util.rb
159
159
  homepage: http://github.com/brightcove/brine
@@ -176,7 +176,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
176
176
  version: '0'
177
177
  requirements: []
178
178
  rubyforge_project:
179
- rubygems_version: 2.5.1
179
+ rubygems_version: 2.7.9
180
180
  signing_key:
181
181
  specification_version: 4
182
182
  summary: Cucumber@REST in Brine
@@ -1,89 +0,0 @@
1
- ##
2
- # @file transformers.rb
3
- # Argument Transforms for Brine.
4
- #
5
- # The Transforms that convert provided inputs to support richer
6
- # functionaliy than the simple strings which Cucumber provides.
7
-
8
- ##
9
- # @defgroup Scalar transforms
10
- # Convert inputs into basic Ruby data types which represent a single value
11
- ##
12
-
13
- # Integers
14
- Transform /\A(-?\d+)\z/ do |number|
15
- number.to_i
16
- end
17
-
18
- # Booleans
19
- Transform /\A(?:true|false)\z/ do |boolean|
20
- boolean.to_s == "true"
21
- end
22
-
23
- # Regexp
24
- # This presently does not support flags after the closing slash, support for these should be added as needed
25
- Transform /\A\/(.*)\/\z/ do |pattern|
26
- Regexp.new(pattern)
27
- end
28
-
29
- # Temporal
30
- DATE='\d{4}-\d{2}-\d{2}'
31
- TIME='\d{2}:\d{2}:\d{2}'
32
- MILLIS='(?:\.\d{3})?'
33
- TZ='(?:Z|(?:[+-]\d{2}:\d{2}))'
34
- Transform /^#{DATE}T#{TIME}#{MILLIS}#{TZ}$/ do |date|
35
- Time.parse(date)
36
- end
37
-
38
- ##
39
- # @defgroup Structure transforms
40
- # Converts inputs to general data structures
41
- ##
42
-
43
- # Lists
44
- Transform /\A\[.*\]\z/m do |input|
45
- JSON.parse(input)
46
- end
47
-
48
- # Objects
49
- # Rely on templates being registered later and therefore given higher priority.
50
- # Lookarounds could avoid the ambiguity but are a nastier pattern.
51
- Transform /\A{.*}\z$/m do |input|
52
- JSON.parse(input)
53
- end
54
-
55
- ##
56
- # @defgroup Atypical transforms
57
- # Transforms for which data type is not the primary focus
58
- ##
59
-
60
- # Whitespace removal transforms
61
- # Handle stripping leading and trailing whitespace.
62
- # These are split out from the transforms to consolidate the behavior.
63
- # They call transform on the stripped value so that subsequent transforms no longer
64
- # have to deal with such whitespace.
65
- #
66
- # Note that these need to deal with multiline string arguments which require
67
- # the multiline flag and \A/\z anchors to properly operate on the full string rather than
68
- # being line oriented. The calls to +#strip+ are also not likely to properly clean up
69
- # multiline strings but is just meant as a (potentially ineffective) optimization over
70
- # recursive calls and capturing.
71
- Transform /\A\s+(.*)\z/m do |input|
72
- Transform(input.strip)
73
- end
74
- Transform /\A(.*)\s+\z/m do |input|
75
- Transform(input.strip)
76
- end
77
-
78
- # Quotes
79
- Transform /\A".*"\z/ do |quoted|
80
- quoted[1..-2]
81
- end
82
- Transform /\A'.*'\z/ do |quoted|
83
- quoted[1..-2]
84
- end
85
-
86
- # Template Expansion
87
- Transform /.*{{.*}}.*/ do |template|
88
- Transform(shave_value(template))
89
- end