brine-dsl 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
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