brine-dsl 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/Rakefile +1 -1
- data/brine-dsl.gemspec +1 -2
- data/lib/brine/cleaning_up.rb +120 -0
- data/lib/brine/client_building.rb +123 -0
- data/lib/brine/coercing.rb +91 -0
- data/lib/brine/hooks.rb +8 -1
- data/lib/brine/mustache_expanding.rb +51 -0
- data/lib/brine/performing.rb +159 -0
- data/lib/brine/requesting.rb +171 -0
- data/lib/brine/rest_steps.rb +1 -1
- data/lib/brine/selecting.rb +166 -0
- data/lib/brine/step_definitions/assertions.rb +15 -15
- data/lib/brine/step_definitions/assignment.rb +5 -4
- data/lib/brine/step_definitions/cleanup.rb +2 -2
- data/lib/brine/step_definitions/perform.rb +16 -0
- data/lib/brine/step_definitions/request_construction.rb +12 -8
- data/lib/brine/step_definitions/selection.rb +24 -12
- data/lib/brine/test_steps.rb +20 -0
- data/lib/brine/transforms.rb +12 -4
- data/lib/brine/type_checking.rb +88 -0
- data/lib/brine/util.rb +1 -0
- data/lib/brine.rb +13 -20
- metadata +12 -9
- data/lib/brine/cleaner_upper.rb +0 -101
- data/lib/brine/coercer.rb +0 -68
- data/lib/brine/mustache_binder.rb +0 -25
- data/lib/brine/requester.rb +0 -161
- data/lib/brine/selector.rb +0 -66
- data/lib/brine/type_checks.rb +0 -36
@@ -0,0 +1,88 @@
|
|
1
|
+
##
|
2
|
+
# @file type_checking.rb
|
3
|
+
# Checks whether provided values are instances of a specified type.
|
4
|
+
#
|
5
|
+
# Provides validation for an extended set of types supported byJSON.
|
6
|
+
##
|
7
|
+
|
8
|
+
module Brine
|
9
|
+
|
10
|
+
##
|
11
|
+
# Module which adds functionality to check the type of values.
|
12
|
+
##
|
13
|
+
module TypeChecking
|
14
|
+
|
15
|
+
require 'rspec/expectations'
|
16
|
+
|
17
|
+
##
|
18
|
+
# A registry of checks for types which can return a Matcher for provided types.
|
19
|
+
##
|
20
|
+
class TypeChecks
|
21
|
+
include RSpec::Matchers
|
22
|
+
|
23
|
+
##
|
24
|
+
# Initialize an instance with default checks or those provided.
|
25
|
+
#
|
26
|
+
# @param [Hash<String, Matcher>] A hash of Matchers by type, where the Matcher value will be
|
27
|
+
# used as the Matcher for the specified type.
|
28
|
+
# It is expected that no map will be provided and the default
|
29
|
+
# mapping will therefore be used.
|
30
|
+
##
|
31
|
+
def initialize(map={Object: be_a_kind_of(Hash),
|
32
|
+
String: be_a_kind_of(String),
|
33
|
+
Number: be_a_kind_of(Numeric),
|
34
|
+
Integer: be_a_kind_of(Integer),
|
35
|
+
Array: be_a_kind_of(Array),
|
36
|
+
DateTime: be_a_kind_of(Time),
|
37
|
+
Boolean: satisfy{|it| it == true || it == false } })
|
38
|
+
@map = map
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Return the Matcher for the specified type or die if not present.
|
43
|
+
#
|
44
|
+
# @param [Class] type The type whose Matcher should be returned.
|
45
|
+
# @return [RSpec::Matcher] The Matcher configured for `type`.
|
46
|
+
# @throw Exception if no Matcher exists for `type`.
|
47
|
+
##
|
48
|
+
def for_type(type)
|
49
|
+
@map[type.to_sym] || raise("Unsupported type #{type}")
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# Register the provided matcher for the specified type.
|
54
|
+
#
|
55
|
+
# @param[Class] type The type for which the Matcher will be registered.
|
56
|
+
# @param[RSpec::Matcher] matcher A matcher to verify that input is an instance of type.
|
57
|
+
##
|
58
|
+
def register_matcher(type, matcher)
|
59
|
+
@map[type.to_sym] = matcher
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# The currently active TypeCheck instance as a property, instantiating as needed.
|
65
|
+
##
|
66
|
+
def type_checks
|
67
|
+
@type_check ||= TypeChecks.new
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# Return the Matcher for the specified type.
|
72
|
+
#
|
73
|
+
# This is the primary interface for type_checking to the rest of the system,
|
74
|
+
# and is the only one expected to be used during test execution.
|
75
|
+
#
|
76
|
+
# @param [Class] type The type for which a Matcher should be returned.
|
77
|
+
# @return [RSpec::Matcher] The Matcher currently registered for the type.
|
78
|
+
##
|
79
|
+
def type_check_for(type)
|
80
|
+
type_checks.for_type(type)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Mix the TypeChecking module functionality into the main Brine module.
|
86
|
+
##
|
87
|
+
include TypeChecking
|
88
|
+
end
|
data/lib/brine/util.rb
CHANGED
data/lib/brine.rb
CHANGED
@@ -5,40 +5,33 @@
|
|
5
5
|
# The primary goal of this file is to load all resources needed to use brine.
|
6
6
|
# A secondary goal which should inform how that is done is that loading this
|
7
7
|
# file by itself should provide new objects but not otherwise impact existing
|
8
|
-
# state such as by
|
8
|
+
# state such as by modifying the World or defining any Steps, Transforms, etc.
|
9
9
|
# Those types of changes should be done by @ref #brine_mix.
|
10
|
-
|
11
|
-
require 'brine/cleaner_upper'
|
12
|
-
require 'brine/mustache_binder'
|
13
|
-
require 'brine/requester'
|
14
|
-
require 'brine/util'
|
15
|
-
require 'brine/selector'
|
16
|
-
require 'brine/type_checks'
|
17
|
-
|
18
10
|
##
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
include TypeChecking
|
27
|
-
end
|
11
|
+
|
12
|
+
require 'brine/cleaning_up'
|
13
|
+
require 'brine/mustache_expanding'
|
14
|
+
require 'brine/performing'
|
15
|
+
require 'brine/requesting'
|
16
|
+
require 'brine/selecting'
|
17
|
+
require 'brine/type_checking'
|
28
18
|
|
29
19
|
##
|
30
|
-
# Load the files with side effects
|
20
|
+
# Load the files with side effects.
|
31
21
|
#
|
32
22
|
# Expected to be called as `World(brine_mix)`
|
23
|
+
# @return [module] The `Brine` module.
|
24
|
+
##
|
33
25
|
def brine_mix
|
34
26
|
require 'brine/step_definitions/assignment'
|
35
27
|
require 'brine/step_definitions/request_construction'
|
36
28
|
require 'brine/step_definitions/assertions'
|
37
29
|
require 'brine/step_definitions/cleanup'
|
30
|
+
require 'brine/step_definitions/perform'
|
38
31
|
require 'brine/step_definitions/selection'
|
39
32
|
|
40
33
|
require 'brine/transforms'
|
41
|
-
require 'brine/rest_steps'
|
42
34
|
require 'brine/hooks'
|
35
|
+
|
43
36
|
Brine
|
44
37
|
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.
|
4
|
+
version: 0.10.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-
|
11
|
+
date: 2019-05-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cucumber
|
@@ -137,21 +137,24 @@ files:
|
|
137
137
|
- brine-dsl.gemspec
|
138
138
|
- feature_setup.rb
|
139
139
|
- lib/brine.rb
|
140
|
-
- lib/brine/
|
141
|
-
- lib/brine/
|
140
|
+
- lib/brine/cleaning_up.rb
|
141
|
+
- lib/brine/client_building.rb
|
142
|
+
- lib/brine/coercing.rb
|
142
143
|
- lib/brine/hooks.rb
|
143
|
-
- lib/brine/
|
144
|
-
- lib/brine/
|
144
|
+
- lib/brine/mustache_expanding.rb
|
145
|
+
- lib/brine/performing.rb
|
146
|
+
- lib/brine/requesting.rb
|
145
147
|
- lib/brine/rest_steps.rb
|
146
|
-
- lib/brine/
|
148
|
+
- lib/brine/selecting.rb
|
147
149
|
- lib/brine/step_definitions/assertions.rb
|
148
150
|
- lib/brine/step_definitions/assignment.rb
|
149
151
|
- lib/brine/step_definitions/cleanup.rb
|
152
|
+
- lib/brine/step_definitions/perform.rb
|
150
153
|
- lib/brine/step_definitions/request_construction.rb
|
151
154
|
- lib/brine/step_definitions/selection.rb
|
152
155
|
- lib/brine/test_steps.rb
|
153
156
|
- lib/brine/transforms.rb
|
154
|
-
- lib/brine/
|
157
|
+
- lib/brine/type_checking.rb
|
155
158
|
- lib/brine/util.rb
|
156
159
|
homepage: http://github.com/brightcove/brine
|
157
160
|
licenses:
|
@@ -173,7 +176,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
173
176
|
version: '0'
|
174
177
|
requirements: []
|
175
178
|
rubyforge_project:
|
176
|
-
rubygems_version: 2.5.
|
179
|
+
rubygems_version: 2.5.1
|
177
180
|
signing_key:
|
178
181
|
specification_version: 4
|
179
182
|
summary: Cucumber@REST in Brine
|
data/lib/brine/cleaner_upper.rb
DELETED
@@ -1,101 +0,0 @@
|
|
1
|
-
##
|
2
|
-
# @file cleaner_upper.rb
|
3
|
-
# Clean up resources created during test run.
|
4
|
-
#
|
5
|
-
# Will issue DELETE call for all tracked URLs which will normally be triggered
|
6
|
-
# in a hook.
|
7
|
-
#
|
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.
|
11
|
-
|
12
|
-
##
|
13
|
-
# A command object for the delete which will be executed as part of cleaning up.
|
14
|
-
class DeleteCommand
|
15
|
-
|
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)
|
25
|
-
@client = client
|
26
|
-
@path = path
|
27
|
-
@oks = oks
|
28
|
-
@attempts = attempts
|
29
|
-
end
|
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.
|
35
|
-
def cleanup
|
36
|
-
while @attempts > 0
|
37
|
-
begin
|
38
|
-
resp=@client.delete(@path)
|
39
|
-
return true if @oks.include?(resp.status)
|
40
|
-
rescue ex
|
41
|
-
puts "WARNING: #{ex}"
|
42
|
-
end
|
43
|
-
@attempts -= 1
|
44
|
-
end
|
45
|
-
puts "ERROR: Could not DELETE #{@path}"
|
46
|
-
false
|
47
|
-
end
|
48
|
-
end
|
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.
|
58
|
-
module CleanerUpper
|
59
|
-
|
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.
|
70
|
-
def set_cleaning_client(client)
|
71
|
-
@client = client
|
72
|
-
end
|
73
|
-
|
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.
|
78
|
-
def track_created_resource(path)
|
79
|
-
created_resources << DeleteCommand.new(@client, path)
|
80
|
-
end
|
81
|
-
|
82
|
-
##
|
83
|
-
# Clean recorded resources (normally after a test run).
|
84
|
-
def cleanup_created_resources
|
85
|
-
created_resources.reverse.each{|it| it.cleanup}
|
86
|
-
end
|
87
|
-
|
88
|
-
private
|
89
|
-
|
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.
|
98
|
-
def created_resources
|
99
|
-
@created_resources ||= []
|
100
|
-
end
|
101
|
-
end
|
data/lib/brine/coercer.rb
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
##
|
2
|
-
# @file coercer.rb
|
3
|
-
# Type coercion to support assertions.
|
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.
|
41
|
-
class Coercer
|
42
|
-
##
|
43
|
-
# Instantiate a new Coercer.
|
44
|
-
#
|
45
|
-
# Initialize the standard map of coercion functions.
|
46
|
-
def initialize
|
47
|
-
@map = Hash.new(->(lhs, rhs){[lhs, rhs]})
|
48
|
-
@map[[String, Time]] = ->(lhs, rhs){[Time.parse(lhs), rhs]}
|
49
|
-
end
|
50
|
-
|
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)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
module Coercion
|
65
|
-
def coercer
|
66
|
-
@coercer ||= Coercer.new
|
67
|
-
end
|
68
|
-
end
|
@@ -1,25 +0,0 @@
|
|
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
|
data/lib/brine/requester.rb
DELETED
@@ -1,161 +0,0 @@
|
|
1
|
-
##
|
2
|
-
# @file requester.rb
|
3
|
-
# Request construction and response storage
|
4
|
-
##
|
5
|
-
|
6
|
-
require 'oauth2'
|
7
|
-
require 'faraday_middleware'
|
8
|
-
require 'brine/util'
|
9
|
-
|
10
|
-
##
|
11
|
-
# The root url to which Brine will send requests.
|
12
|
-
#
|
13
|
-
# This will normally be the value of ENV['BRINE_ROOT_URL'],
|
14
|
-
# and that value should be directly usable after older
|
15
|
-
# ENV['ROOT_URL'] is end-of-lifed (at which point this can be removed.
|
16
|
-
#
|
17
|
-
# @return [String] The root URL to use or nil if none is provided.
|
18
|
-
##
|
19
|
-
def brine_root_url
|
20
|
-
if ENV['BRINE_ROOT_URL']
|
21
|
-
ENV['BRINE_ROOT_URL']
|
22
|
-
elsif ENV['ROOT_URL']
|
23
|
-
deprecation_message('1.0', 'ROOT_URL is deprecated, replace with BRINE_ROOT_URL') if ENV['ROOT_URL']
|
24
|
-
ENV['ROOT_URL']
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
##
|
29
|
-
# Parameter object used to configure OAuth2 middleware
|
30
|
-
#
|
31
|
-
# Also used to provide basic DSL for configuration
|
32
|
-
##
|
33
|
-
class OAuth2Params
|
34
|
-
attr_accessor :token, :token_type
|
35
|
-
|
36
|
-
def initialize
|
37
|
-
@token_type = 'bearer'
|
38
|
-
end
|
39
|
-
|
40
|
-
def fetch_from(id, secret, opts)
|
41
|
-
@token = OAuth2::Client.new(id, secret, opts)
|
42
|
-
.client_credentials.get_token.token
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# Construct a Faraday client to be used to send built requests
|
47
|
-
module ClientBuilding
|
48
|
-
|
49
|
-
# authenticate using provided info and save token for use in later requests
|
50
|
-
def use_oauth2_token(&block)
|
51
|
-
@oauth2 = OAuth2Params.new
|
52
|
-
@oauth2.instance_eval(&block)
|
53
|
-
end
|
54
|
-
|
55
|
-
def with_oauth2_token(&block)
|
56
|
-
use_oauth2_token(&block)
|
57
|
-
self
|
58
|
-
end
|
59
|
-
|
60
|
-
# This is represented as list of functions so that it can be more easily customized for
|
61
|
-
# unexpected use cases.
|
62
|
-
# It should likely be broken up a bit more sensibly and more useful insertion commands added...
|
63
|
-
# but it's likely enough of a power feature and platform specific to leave pretty raw.
|
64
|
-
def connection_handlers
|
65
|
-
@connection_handlers ||= [
|
66
|
-
proc do |conn|
|
67
|
-
conn.request :json
|
68
|
-
if @oauth2
|
69
|
-
conn.request :oauth2, @oauth2.token, :token_type => @oauth2.token_type
|
70
|
-
end
|
71
|
-
end,
|
72
|
-
proc do |conn|
|
73
|
-
if @logging
|
74
|
-
conn.response :logger, nil, :bodies => (@logging.casecmp('DEBUG') == 0)
|
75
|
-
end
|
76
|
-
conn.response :json, :content_type => /\bjson$/
|
77
|
-
end,
|
78
|
-
proc{|conn| conn.adapter Faraday.default_adapter }
|
79
|
-
]
|
80
|
-
end
|
81
|
-
|
82
|
-
def client_for_host(host, logging: ENV['BRINE_LOG_HTTP'])
|
83
|
-
@logging = logging
|
84
|
-
Faraday.new(host) do |conn|
|
85
|
-
connection_handlers.each{|h| h.call(conn) }
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
class ClientBuilder
|
91
|
-
include ClientBuilding
|
92
|
-
end
|
93
|
-
|
94
|
-
# Module in charge of constructing requests and saving responses
|
95
|
-
module Requesting
|
96
|
-
include ClientBuilding
|
97
|
-
|
98
|
-
# Utility Methods
|
99
|
-
#
|
100
|
-
# Normalize an HTTP method passed from a specification into a form
|
101
|
-
# expected by the HTTP client library (lowercased symbol)
|
102
|
-
def parse_method(method)
|
103
|
-
method.downcase.to_sym
|
104
|
-
end
|
105
|
-
|
106
|
-
def set_client(client)
|
107
|
-
@client = client
|
108
|
-
end
|
109
|
-
|
110
|
-
# return Faraday client object so that it could be used directly
|
111
|
-
# or passed to another object
|
112
|
-
def client
|
113
|
-
@client ||= client_for_host(brine_root_url || 'http://localhost:8080',
|
114
|
-
logging: ENV['BRINE_LOG_HTTP'])
|
115
|
-
end
|
116
|
-
|
117
|
-
# clear out any previously built request state and set defaults
|
118
|
-
def reset_request
|
119
|
-
@params = @headers = @body = nil
|
120
|
-
end
|
121
|
-
|
122
|
-
# store the provided body in the request options being built
|
123
|
-
# overriding any previously provided object
|
124
|
-
def set_request_body(obj)
|
125
|
-
@body = obj
|
126
|
-
end
|
127
|
-
|
128
|
-
# send a request using method to url using whatever options
|
129
|
-
# have been built for the present request
|
130
|
-
def send_request(method, url)
|
131
|
-
@response = client.run_request(method, url, @body, headers) do |req|
|
132
|
-
req.params = params
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
# getter for the latest response returned
|
137
|
-
def response
|
138
|
-
@response
|
139
|
-
end
|
140
|
-
|
141
|
-
def headers
|
142
|
-
@headers ||= {content_type: 'application/json'}
|
143
|
-
end
|
144
|
-
|
145
|
-
def add_header(k, v)
|
146
|
-
headers[k] = v
|
147
|
-
end
|
148
|
-
|
149
|
-
def params
|
150
|
-
@params ||= {}
|
151
|
-
end
|
152
|
-
|
153
|
-
def add_request_param(k, v)
|
154
|
-
params[k] = v
|
155
|
-
end
|
156
|
-
|
157
|
-
end
|
158
|
-
|
159
|
-
class Requester
|
160
|
-
include Requesting
|
161
|
-
end
|
data/lib/brine/selector.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
require 'brine/coercer'
|
2
|
-
require 'rspec/expectations'
|
3
|
-
require 'jsonpath'
|
4
|
-
|
5
|
-
# Selectors here are small wrappers around RSpec
|
6
|
-
# expectation behavior to encapsulate variations in
|
7
|
-
# some expecation associated behavior in classes.
|
8
|
-
class Selector
|
9
|
-
include RSpec::Matchers
|
10
|
-
attr_accessor :coercer
|
11
|
-
|
12
|
-
def initialize(target, negated)
|
13
|
-
@target = target
|
14
|
-
@message = negated ? :to_not : :to
|
15
|
-
end
|
16
|
-
|
17
|
-
def filter_matcher(matcher)
|
18
|
-
matcher
|
19
|
-
end
|
20
|
-
|
21
|
-
def assert_that(value)
|
22
|
-
target, value = coercer.coerce(@target, value)
|
23
|
-
matcher = filter_matcher(yield(value))
|
24
|
-
expect(target).send(@message, matcher)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
class AnySelector < Selector
|
29
|
-
def filter_matcher(matcher)
|
30
|
-
include(matcher)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
class AllSelector < Selector
|
35
|
-
def filter_matcher(matcher)
|
36
|
-
all(matcher)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
#
|
41
|
-
# Module
|
42
|
-
#
|
43
|
-
module Selection
|
44
|
-
include Coercion
|
45
|
-
attr_reader :selector
|
46
|
-
|
47
|
-
def use_selector(selector)
|
48
|
-
selector.coercer = coercer
|
49
|
-
@selector = selector
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
#
|
54
|
-
# Steps
|
55
|
-
#
|
56
|
-
RESPONSE_ATTRIBUTES='(status|headers|body)'
|
57
|
-
Then(/^the value of `([^`]*)` is( not)? (.*)$/) do |value, negated, assertion|
|
58
|
-
use_selector(Selector.new(value, (!negated.nil?)))
|
59
|
-
step "it is #{assertion}"
|
60
|
-
end
|
61
|
-
|
62
|
-
def dig_from_response(attribute, path=nil, plural=false)
|
63
|
-
root = response.send(attribute.to_sym)
|
64
|
-
return root if !path
|
65
|
-
JsonPath.new("$.#{path}").send(plural ? :on : :first, root)
|
66
|
-
end
|
data/lib/brine/type_checks.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
# type_checks.rb -- checks whether provided is a valid instance of a specified type
|
2
|
-
#
|
3
|
-
# Provides validation for standard JSON type
|
4
|
-
|
5
|
-
require 'rspec/expectations'
|
6
|
-
|
7
|
-
# This will be made extensible so it can replace current domain specific check logic
|
8
|
-
class TypeChecks
|
9
|
-
include RSpec::Matchers
|
10
|
-
|
11
|
-
def initialize
|
12
|
-
@map = {
|
13
|
-
Object: be_a_kind_of(Hash),
|
14
|
-
String: be_a_kind_of(String),
|
15
|
-
Number: be_a_kind_of(Numeric),
|
16
|
-
Integer: be_a_kind_of(Integer),
|
17
|
-
Array: be_a_kind_of(Array),
|
18
|
-
DateTime: be_a_kind_of(Time),
|
19
|
-
Boolean: satisfy{|it| it == true || it == false }
|
20
|
-
}
|
21
|
-
end
|
22
|
-
|
23
|
-
def for_type(type)
|
24
|
-
@map[type.to_sym] || raise("Unsupported type #{type}")
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
module TypeChecking
|
29
|
-
def type_checks
|
30
|
-
@type_check ||= TypeChecks.new
|
31
|
-
end
|
32
|
-
|
33
|
-
def type_check_for(type)
|
34
|
-
type_checks.for_type(type)
|
35
|
-
end
|
36
|
-
end
|