fixturama 0.0.7 → 0.4.1
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/CHANGELOG.md +100 -0
- data/README.md +71 -3
- data/lib/fixturama.rb +49 -20
- data/lib/fixturama/changes.rb +72 -0
- data/lib/fixturama/changes/base.rb +28 -0
- data/lib/fixturama/changes/chain.rb +64 -0
- data/lib/fixturama/changes/chain/actions.rb +31 -0
- data/lib/fixturama/changes/chain/arguments.rb +59 -0
- data/lib/fixturama/changes/chain/raise_action.rb +43 -0
- data/lib/fixturama/changes/chain/return_action.rb +33 -0
- data/lib/fixturama/changes/const.rb +30 -0
- data/lib/fixturama/changes/env.rb +35 -0
- data/lib/fixturama/changes/request.rb +91 -0
- data/lib/fixturama/changes/request/response.rb +62 -0
- data/lib/fixturama/changes/request/responses.rb +22 -0
- data/lib/fixturama/changes/seed.rb +39 -0
- data/lib/fixturama/config.rb +5 -0
- data/lib/fixturama/fixture_error.rb +31 -0
- data/lib/fixturama/loader.rb +1 -0
- data/lib/fixturama/loader/context.rb +1 -0
- data/lib/fixturama/loader/value.rb +1 -0
- data/lib/fixturama/version.rb +4 -0
- metadata +80 -50
- data/.gitignore +0 -12
- data/.rspec +0 -2
- data/.rubocop.yml +0 -22
- data/.travis.yml +0 -23
- data/Gemfile +0 -9
- data/LICENSE.txt +0 -21
- data/Rakefile +0 -6
- data/fixturama.gemspec +0 -23
- data/lib/fixturama/seed.rb +0 -15
- data/lib/fixturama/stubs.rb +0 -57
- data/lib/fixturama/stubs/chain.rb +0 -89
- data/lib/fixturama/stubs/chain/actions.rb +0 -39
- data/lib/fixturama/stubs/chain/actions/raise.rb +0 -21
- data/lib/fixturama/stubs/chain/actions/return.rb +0 -23
- data/lib/fixturama/stubs/chain/arguments.rb +0 -86
- data/lib/fixturama/stubs/const.rb +0 -42
- data/lib/fixturama/utils.rb +0 -39
- data/spec/fixturama/load_fixture/_spec.rb +0 -53
- data/spec/fixturama/load_fixture/data.json +0 -5
- data/spec/fixturama/load_fixture/data.yaml +0 -3
- data/spec/fixturama/load_fixture/data.yml +0 -3
- data/spec/fixturama/seed_fixture/_spec.rb +0 -33
- data/spec/fixturama/seed_fixture/seed.yml +0 -16
- data/spec/fixturama/stub_fixture/_spec.rb +0 -96
- data/spec/fixturama/stub_fixture/stub.yml +0 -60
- data/spec/spec_helper.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 779a1dc8057604e6a5524eff0ef07520ecdbaf62895711411a312fb5c81a7558
|
4
|
+
data.tar.gz: 7976718e10f2fe8036d9e934d6e720cdcb91890f4263221720bfe76815eca071
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25047655a38dedca47af366563ad14c7f0bea54ddd0230097f6a940b127593a70a6144cf556670308dc1ad1048cce74180cecfe7c89871682602e5e5bbca0988
|
7
|
+
data.tar.gz: c23c3fe8662badf370ffc5cb02c756d510ca2be2f75639bc77e8d54f4243b49be74f17f54561329861865778a06b7e08efcf1c24d6fbb873dfacbb912f53618b
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,101 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
6
6
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
7
7
|
|
8
|
+
## [0.4.1] - [2021-03-31]
|
9
|
+
|
10
|
+
### Fixed
|
11
|
+
|
12
|
+
- Dependency from hashie updated to allow v4+ (nepalez)
|
13
|
+
|
14
|
+
## [0.4.0] - [2020-03-15]
|
15
|
+
|
16
|
+
### Added
|
17
|
+
|
18
|
+
- Support for stubbing ENV variables (nepalez)
|
19
|
+
|
20
|
+
```yaml
|
21
|
+
---
|
22
|
+
- env: GOOGLE_CLOUD_KEY
|
23
|
+
value: foo
|
24
|
+
|
25
|
+
- env: GOOGLE_CLOUD_PASSWORD
|
26
|
+
value: bar
|
27
|
+
```
|
28
|
+
|
29
|
+
This would stub selected variables only, not touching the others
|
30
|
+
|
31
|
+
## [0.3.0] - [2020-03-08]
|
32
|
+
|
33
|
+
### Added
|
34
|
+
|
35
|
+
- Support for exception arguments (nepalez)
|
36
|
+
|
37
|
+
```yaml
|
38
|
+
---
|
39
|
+
- class: API
|
40
|
+
chain: get_product
|
41
|
+
arguments:
|
42
|
+
- 1
|
43
|
+
actions:
|
44
|
+
- raise: API::NotFoundError
|
45
|
+
arguments: # <--- that's that
|
46
|
+
- "Cannot find a product by id: 1"
|
47
|
+
```
|
48
|
+
|
49
|
+
which would raise `API::NotFoundError.new("Cannot find a product by id: 1")`
|
50
|
+
|
51
|
+
## [0.2.0] - [2020-02-17]
|
52
|
+
|
53
|
+
### Added
|
54
|
+
|
55
|
+
- Stubbing and seeding from the same source file via the `call_fixture` method (nepalez)
|
56
|
+
|
57
|
+
```yaml
|
58
|
+
# ./changes.yml
|
59
|
+
---
|
60
|
+
- type: user
|
61
|
+
params:
|
62
|
+
id: 1
|
63
|
+
|
64
|
+
- const: DEFAULT_USER_ID
|
65
|
+
value: 1
|
66
|
+
|
67
|
+
- url: https://example.com/users/default
|
68
|
+
method: get
|
69
|
+
responses:
|
70
|
+
- body:
|
71
|
+
id: 1
|
72
|
+
name: Andrew
|
73
|
+
```
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
before { call_fixture "#{__dir__}/changes.yml" }
|
77
|
+
```
|
78
|
+
|
79
|
+
## [0.1.0] - [2020-02-09]
|
80
|
+
|
81
|
+
### Added
|
82
|
+
|
83
|
+
- Stubbing of the HTTP requests using webmock (nepalez)
|
84
|
+
|
85
|
+
```yaml
|
86
|
+
---
|
87
|
+
- url: example.com/foo
|
88
|
+
method: get
|
89
|
+
body: foobar
|
90
|
+
query:
|
91
|
+
foo: bar
|
92
|
+
basic_auth:
|
93
|
+
user: foo
|
94
|
+
password: bar
|
95
|
+
headers:
|
96
|
+
Accept: utf-8
|
97
|
+
responses:
|
98
|
+
- status: 200
|
99
|
+
body: foobar
|
100
|
+
- status: 404
|
101
|
+
```
|
102
|
+
|
8
103
|
## [0.0.7] - [2019-07-01]
|
9
104
|
|
10
105
|
### Added
|
@@ -175,3 +270,8 @@ This is a first public release with features extracted from production app.
|
|
175
270
|
[0.0.5]: https://github.com/nepalez/fixturama/compare/v0.0.4...v0.0.5
|
176
271
|
[0.0.6]: https://github.com/nepalez/fixturama/compare/v0.0.5...v0.0.6
|
177
272
|
[0.0.7]: https://github.com/nepalez/fixturama/compare/v0.0.6...v0.0.7
|
273
|
+
[0.1.0]: https://github.com/nepalez/fixturama/compare/v0.0.7...v0.1.0
|
274
|
+
[0.2.0]: https://github.com/nepalez/fixturama/compare/v0.1.0...v0.2.0
|
275
|
+
[0.3.0]: https://github.com/nepalez/fixturama/compare/v0.2.0...v0.3.0
|
276
|
+
[0.4.0]: https://github.com/nepalez/fixturama/compare/v0.3.0...v0.4.0
|
277
|
+
[0.4.1]: https://github.com/nepalez/fixturama/compare/v0.4.0...v0.4.1
|
data/README.md
CHANGED
@@ -124,21 +124,41 @@ Use the `count: 2` key to create more objects at once.
|
|
124
124
|
|
125
125
|
### Stubbing
|
126
126
|
|
127
|
-
|
127
|
+
The gem supports stubbing message chains, constants and http requests with the following keys.
|
128
128
|
|
129
129
|
For message chains:
|
130
130
|
|
131
131
|
- `class` for stubbed class
|
132
132
|
- `chain` for messages chain
|
133
133
|
- `arguments` (optional) for specific arguments
|
134
|
-
- `actions` for an array of actions for consecutive invocations of the chain
|
134
|
+
- `actions` for an array of actions for consecutive invocations of the chain with keys
|
135
|
+
- `return` for a value to be returned
|
136
|
+
- `raise` for an exception to be risen
|
137
|
+
- `repeate` for a number of invocations with this action
|
135
138
|
|
136
139
|
For constants:
|
137
140
|
|
138
141
|
- `const` for stubbed constant
|
139
142
|
- `value` for a value of the constant
|
140
143
|
|
141
|
-
|
144
|
+
For environment variables:
|
145
|
+
|
146
|
+
- `env` for the name of a variable
|
147
|
+
`value` for a value of the variable
|
148
|
+
|
149
|
+
For http requests:
|
150
|
+
|
151
|
+
- `url` or `uri` for the URI of the request (treats values like `/.../` as regular expressions)
|
152
|
+
- `method` for the specific http-method (like `get` or `post`)
|
153
|
+
- `body` for the request body (treats values like `/.../` as regular expressions)
|
154
|
+
- `headers` for the request headers
|
155
|
+
- `query` for the request query
|
156
|
+
- `basic_auth` for the `user` and `password` of basic authentication
|
157
|
+
- `response` or `responses` for consecutively envoked responses with keys:
|
158
|
+
- `status`
|
159
|
+
- `body`
|
160
|
+
- `headers`
|
161
|
+
- `repeate` for the number of times this response should be returned before switching to the next one
|
142
162
|
|
143
163
|
```yaml
|
144
164
|
# ./stubs.yml
|
@@ -166,10 +186,34 @@ Every action either `return` some value, or `raise` some exception
|
|
166
186
|
- <%= profile_id %>
|
167
187
|
actions:
|
168
188
|
- return: true
|
189
|
+
repeate: 1 # this is the default value
|
169
190
|
- raise: ActiveRecord::RecordNotFound
|
191
|
+
arguments:
|
192
|
+
- "Profile with id: 1 not found" # for error message
|
170
193
|
|
194
|
+
# Here we stubbing a constant
|
171
195
|
- const: NOTIFIER_TIMEOUT_SEC
|
172
196
|
value: 10
|
197
|
+
|
198
|
+
# This is a stub for ENV['DEFAULT_EMAIL']
|
199
|
+
- env: DEFAULT_EMAIL
|
200
|
+
value: foo@example.com
|
201
|
+
|
202
|
+
# Examples for stubbing HTTP
|
203
|
+
- uri: /example.com/foo/ # regexp!
|
204
|
+
method: delete
|
205
|
+
basic_auth:
|
206
|
+
user: foo
|
207
|
+
password: bar
|
208
|
+
responses:
|
209
|
+
- status: 200 # for the first call
|
210
|
+
repeate: 1 # this is the default value, but you can set another one
|
211
|
+
- status: 404 # for any other call
|
212
|
+
|
213
|
+
- uri: htpps://example.com/foo # exact string!
|
214
|
+
method: delete
|
215
|
+
responses:
|
216
|
+
- status: 401
|
173
217
|
```
|
174
218
|
|
175
219
|
```graphql
|
@@ -203,6 +247,30 @@ I find it especially helpful when I need to check different edge cases. Instead
|
|
203
247
|
|
204
248
|
Looking at the spec I can easily figure out the "structure" of expectation, while looking at fixtures I can check the concrete corner cases.
|
205
249
|
|
250
|
+
## Single Source of Changes
|
251
|
+
|
252
|
+
If you will, you can list all stubs and seeds at the one single file like
|
253
|
+
|
254
|
+
```yaml
|
255
|
+
# ./changes.yml
|
256
|
+
---
|
257
|
+
- type: user
|
258
|
+
params:
|
259
|
+
id: 1
|
260
|
+
name: Andrew
|
261
|
+
|
262
|
+
- const: DEFAULT_USER_ID
|
263
|
+
value: 1
|
264
|
+
```
|
265
|
+
|
266
|
+
This fixture can be applied via `call_fixture` method just like we did above with `seed_fixture` and `stub_fixture`:
|
267
|
+
|
268
|
+
```ruby
|
269
|
+
before { call_fixture "#{__dir__}/changes.yml" }
|
270
|
+
```
|
271
|
+
|
272
|
+
In fact, since the `v0.2.0` all those methods are just the aliases of the `call_fixture`.
|
273
|
+
|
206
274
|
## License
|
207
275
|
|
208
276
|
The gem is available as open source under the terms of the [MIT License][license].
|
data/lib/fixturama.rb
CHANGED
@@ -3,46 +3,75 @@ require "factory_bot"
|
|
3
3
|
require "hashie/mash"
|
4
4
|
require "json"
|
5
5
|
require "rspec"
|
6
|
+
require "webmock/rspec"
|
6
7
|
require "yaml"
|
7
8
|
|
9
|
+
#
|
10
|
+
# A set of helpers to prettify specs with fixtures
|
11
|
+
#
|
8
12
|
module Fixturama
|
13
|
+
require_relative "fixturama/fixture_error"
|
9
14
|
require_relative "fixturama/config"
|
10
|
-
require_relative "fixturama/utils"
|
11
15
|
require_relative "fixturama/loader"
|
12
|
-
require_relative "fixturama/
|
13
|
-
require_relative "fixturama/seed"
|
16
|
+
require_relative "fixturama/changes"
|
14
17
|
|
18
|
+
# Set the initial value for database-generated IDs
|
19
|
+
# @param [#to_i] value
|
20
|
+
# @return [Fixturama]
|
15
21
|
def self.start_ids_from(value)
|
16
22
|
Config.start_ids_from(value)
|
23
|
+
self
|
17
24
|
end
|
18
25
|
|
19
|
-
|
20
|
-
|
21
|
-
|
26
|
+
# @!method read_fixture(path, options)
|
27
|
+
# Read the text content of the fixture
|
28
|
+
# @param [#to_s] path The path to the fixture file
|
29
|
+
# @param [Hash<Symbol, _>] options
|
30
|
+
# The list of options to be accessible in the fixture
|
31
|
+
# @return [String]
|
32
|
+
def read_fixture(path, **options)
|
33
|
+
content = File.read(path)
|
34
|
+
hashie = Hashie::Mash.new(options)
|
35
|
+
bindings = hashie.instance_eval { binding }
|
22
36
|
|
23
|
-
|
24
|
-
fixturama_stubs.apply(self)
|
37
|
+
ERB.new(content).result(bindings)
|
25
38
|
end
|
26
39
|
|
27
|
-
|
28
|
-
|
40
|
+
# @!method load_fixture(path, options)
|
41
|
+
# Load data from a fixture
|
42
|
+
# @param (see #read_fixture)
|
43
|
+
# @return [Object]
|
44
|
+
def load_fixture(path, **options)
|
45
|
+
Loader.new(path, options).call
|
29
46
|
end
|
30
47
|
|
31
|
-
|
32
|
-
|
48
|
+
# @!method call_fixture(path, options)
|
49
|
+
# Stub different objects and seed the database from a fixture
|
50
|
+
# @param (see #read_fixture)
|
51
|
+
# @return [RSpec::Core::Example] the current example
|
52
|
+
def call_fixture(path, **options)
|
53
|
+
items = Array load_fixture(path, **options)
|
54
|
+
items.each { |item| changes.add(item) }
|
55
|
+
tap { changes.call(self) }
|
56
|
+
rescue FixtureError => err
|
57
|
+
raise err.with_file(path)
|
33
58
|
end
|
34
59
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
60
|
+
# @!method seed_fixture(path, options)
|
61
|
+
# The alias for the +call_fixture+
|
62
|
+
# @param (see #call_fixture)
|
63
|
+
# @return (see #call_fixture)
|
64
|
+
alias seed_fixture call_fixture
|
39
65
|
|
40
|
-
|
41
|
-
|
66
|
+
# @!method stub_fixture(path, options)
|
67
|
+
# The alias for the +call_fixture+
|
68
|
+
# @param (see #call_fixture)
|
69
|
+
# @return (see #call_fixture)
|
70
|
+
alias stub_fixture call_fixture
|
42
71
|
|
43
72
|
private
|
44
73
|
|
45
|
-
def
|
46
|
-
@
|
74
|
+
def changes
|
75
|
+
@changes ||= Changes.new
|
47
76
|
end
|
48
77
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Fixturama
|
2
|
+
#
|
3
|
+
# @private
|
4
|
+
# Registry of changes (stubs and seeds)
|
5
|
+
#
|
6
|
+
class Changes
|
7
|
+
require_relative "changes/base"
|
8
|
+
require_relative "changes/chain"
|
9
|
+
require_relative "changes/const"
|
10
|
+
require_relative "changes/env"
|
11
|
+
require_relative "changes/request"
|
12
|
+
require_relative "changes/seed"
|
13
|
+
|
14
|
+
# Match option keys to the type of an item
|
15
|
+
TYPES = {
|
16
|
+
actions: Chain,
|
17
|
+
arguments: Chain,
|
18
|
+
basic_auth: Request,
|
19
|
+
body: Request,
|
20
|
+
chain: Chain,
|
21
|
+
class: Chain,
|
22
|
+
const: Const,
|
23
|
+
count: Seed,
|
24
|
+
env: Env,
|
25
|
+
headers: Request,
|
26
|
+
http_method: Request,
|
27
|
+
object: Chain,
|
28
|
+
params: Seed,
|
29
|
+
query: Request,
|
30
|
+
response: Request,
|
31
|
+
responses: Request,
|
32
|
+
traits: Seed,
|
33
|
+
type: Seed,
|
34
|
+
uri: Request,
|
35
|
+
url: Request,
|
36
|
+
}.freeze
|
37
|
+
|
38
|
+
# Adds new change to the registry
|
39
|
+
# @param [Hash] options
|
40
|
+
# @return [Fixturama::Changes]
|
41
|
+
# @raise [Fixturama::FixtureError] if the options cannot be processed
|
42
|
+
def add(options)
|
43
|
+
options = Hash(options).transform_keys(&:to_sym)
|
44
|
+
types = options.keys.map { |key| TYPES[key] }.compact.uniq
|
45
|
+
raise "Wrong count" unless types.count == 1
|
46
|
+
|
47
|
+
@changes << types.first.new(options)
|
48
|
+
self
|
49
|
+
rescue FixtureError => err
|
50
|
+
raise err
|
51
|
+
rescue StandardError => err
|
52
|
+
raise FixtureError.new("an operation", options, err)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Apply all registered changes to the RSpec example
|
56
|
+
# @param [RSpec::Core::Example] example
|
57
|
+
# @return [self]
|
58
|
+
def call(example)
|
59
|
+
@changes
|
60
|
+
.group_by(&:key)
|
61
|
+
.values
|
62
|
+
.map { |changes| changes.reduce :merge }
|
63
|
+
.each { |change| change.call(example) }
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def initialize
|
69
|
+
@changes = []
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class Fixturama::Changes
|
2
|
+
#
|
3
|
+
# @private
|
4
|
+
# @abstract
|
5
|
+
# Base class for changes downloaded from a fixture
|
6
|
+
#
|
7
|
+
class Base
|
8
|
+
# @!attribute [r] key The key identifier of the change
|
9
|
+
# @return [String]
|
10
|
+
alias key hash
|
11
|
+
|
12
|
+
# Merge the other change into the current one
|
13
|
+
# @param [Fixturama::Changes::Base] other
|
14
|
+
# @return [Fixturama::Changes::Base]
|
15
|
+
def merge(other)
|
16
|
+
# By default just take the other change if applicable
|
17
|
+
other.class == self.class && other.key == key ? other : self
|
18
|
+
end
|
19
|
+
|
20
|
+
# @abstract
|
21
|
+
# Call the corresponding change (either a stub or a seed)
|
22
|
+
# @param [RSpec::Core::Example] _example The RSpec example
|
23
|
+
# @return [self]
|
24
|
+
def call(_example)
|
25
|
+
self
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
class Fixturama::Changes
|
2
|
+
#
|
3
|
+
# @private
|
4
|
+
# Stub a chain of messages
|
5
|
+
#
|
6
|
+
class Chain < Base
|
7
|
+
require_relative "chain/raise_action"
|
8
|
+
require_relative "chain/return_action"
|
9
|
+
require_relative "chain/actions"
|
10
|
+
require_relative "chain/arguments"
|
11
|
+
|
12
|
+
def key
|
13
|
+
@key ||= ["chain", @receiver.name, *@messages].join(".")
|
14
|
+
end
|
15
|
+
|
16
|
+
def merge(other)
|
17
|
+
return self unless other.class == self.class && other.key == key
|
18
|
+
|
19
|
+
tap { @arguments = (other.arguments | arguments).sort_by(&:order) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def call(example)
|
23
|
+
call_action = example.send(:receive_message_chain, *@messages) do |*real|
|
24
|
+
action = arguments.find { |expected| expected.match?(*real) }
|
25
|
+
action ? action.call : raise("Unexpected arguments: #{real}")
|
26
|
+
end
|
27
|
+
|
28
|
+
example.send(:allow, @receiver).to call_action
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
attr_reader :arguments
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def initialize(**options)
|
38
|
+
@receiver = receiver_from(options)
|
39
|
+
@messages = messages_from(options)
|
40
|
+
@arguments = [Arguments.new(options)]
|
41
|
+
end
|
42
|
+
|
43
|
+
def receiver_from(options)
|
44
|
+
case options.slice(:class, :object).keys
|
45
|
+
when %i[class] then Kernel.const_get(options[:class])
|
46
|
+
when %i[object] then Object.send(:eval, options[:object])
|
47
|
+
else raise
|
48
|
+
end
|
49
|
+
rescue StandardError => err
|
50
|
+
raise Fixturama::FixtureError.new("a stabbed object", options, err)
|
51
|
+
end
|
52
|
+
|
53
|
+
def messages_from(options)
|
54
|
+
case value = options[:chain]
|
55
|
+
when Array then value.map(&:to_sym)
|
56
|
+
when String then [value.to_sym]
|
57
|
+
when Symbol then value
|
58
|
+
else raise
|
59
|
+
end
|
60
|
+
rescue StandardError => err
|
61
|
+
raise Fixturama::FixtureError.new("a messages chain", options, err)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|