receptacle 0.3.1 → 2.0.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 +5 -5
- data/.github/workflows/matrix.yml +32 -0
- data/.gitignore +1 -1
- data/.rubocop.yml +6 -8
- data/CHANGELOG.md +31 -19
- data/Gemfile +2 -7
- data/Gemfile.lock +92 -0
- data/LICENSE.txt +1 -1
- data/README.md +22 -52
- data/Rakefile +8 -18
- data/bin/console +3 -3
- data/examples/simple_repo.rb +17 -15
- data/lib/receptacle/errors.rb +2 -1
- data/lib/receptacle/repo.rb +51 -0
- data/lib/receptacle/test_support.rb +2 -17
- data/lib/receptacle/version.rb +2 -1
- data/lib/receptacle.rb +3 -9
- data/receptacle.gemspec +31 -26
- data/upgrade_notes.md +45 -0
- metadata +55 -70
- data/.dir-locals.el +0 -1
- data/.travis.yml +0 -36
- data/Dangerfile +0 -26
- data/Guardfile +0 -31
- data/lib/receptacle/interface_methods.rb +0 -49
- data/lib/receptacle/method_cache.rb +0 -42
- data/lib/receptacle/method_delegation.rb +0 -136
- data/lib/receptacle/registration.rb +0 -34
- data/performance/benchmark.rb +0 -44
- data/performance/profile.rb +0 -39
- data/performance/speed_receptacle.rb +0 -104
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: eaa2e6a1b1e530f37984a21a68e20f465a0a5dc5c5549074879a9ef52dc44776
|
4
|
+
data.tar.gz: 691bee1a039ad306c3ca3e9e8cf4e71f139649a3c47b81b54e5feff8a7908b56
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 03ae765ccf54fe2ee01c20b9a2bb69d8ee8005c6f16e13b7787473512c1ce3848f9118911df840aebc2b1a1523f6c105417c62b96474893ed58c62b49c338ccb
|
7
|
+
data.tar.gz: c2fe5fa8b67040271899b1ab0ac0fadbdd33c6a2e0eeb32b2b4cb762961eeb8b9169913d2e88cdfd2c4172d3a18965c46bc6d88050d9f00f6c63ee40bb2cc607
|
@@ -0,0 +1,32 @@
|
|
1
|
+
---
|
2
|
+
name: matrix-testing
|
3
|
+
|
4
|
+
on:
|
5
|
+
push:
|
6
|
+
branches: [ main, master ]
|
7
|
+
pull_request:
|
8
|
+
branches: [ main, master ]
|
9
|
+
|
10
|
+
permissions:
|
11
|
+
contents: read
|
12
|
+
|
13
|
+
jobs:
|
14
|
+
test:
|
15
|
+
runs-on: ubuntu-latest
|
16
|
+
continue-on-error: ${{ matrix.experimental }}
|
17
|
+
strategy:
|
18
|
+
fail-fast: false
|
19
|
+
matrix:
|
20
|
+
experimental: [false]
|
21
|
+
ruby-version: ["2.7", "3.0", "3.1", "3.2", "jruby-9.3"]
|
22
|
+
include:
|
23
|
+
- ruby-version: jruby-9.4
|
24
|
+
experimental: true
|
25
|
+
steps:
|
26
|
+
- uses: actions/checkout@v3
|
27
|
+
- uses: ruby/setup-ruby@v1
|
28
|
+
with:
|
29
|
+
ruby-version: ${{ matrix.ruby-version }}
|
30
|
+
bundler-cache: true
|
31
|
+
- run: bundle exec rspec
|
32
|
+
- run: bundle exec rubocop
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,14 +1,15 @@
|
|
1
|
-
|
2
|
-
TargetRubyVersion: 2.1
|
1
|
+
require: rt_rubocop_defaults
|
3
2
|
|
4
|
-
|
5
|
-
|
3
|
+
AllCops:
|
4
|
+
TargetRubyVersion: 2.6
|
5
|
+
# vendor directory is used by github actions and causes issues if not excluded here
|
6
6
|
Exclude:
|
7
|
-
-
|
7
|
+
- vendor/bundle/**/*
|
8
8
|
|
9
9
|
Metrics/BlockLength:
|
10
10
|
Exclude:
|
11
11
|
- '*.gemspec'
|
12
|
+
- 'spec/*'
|
12
13
|
|
13
14
|
Metrics/AbcSize:
|
14
15
|
Exclude:
|
@@ -21,6 +22,3 @@ Metrics/ClassLength:
|
|
21
22
|
Metrics/MethodLength:
|
22
23
|
Exclude:
|
23
24
|
- test/*
|
24
|
-
|
25
|
-
Style/Documentation:
|
26
|
-
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,35 +1,47 @@
|
|
1
|
-
Changelog
|
2
|
-
===
|
1
|
+
# Changelog
|
3
2
|
|
4
|
-
|
5
|
-
---
|
3
|
+
All notable changes to this project will be documented in this file.
|
6
4
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
-
|
9
|
-
---
|
8
|
+
## [Unreleased]
|
10
9
|
|
11
|
-
|
10
|
+
## [2.0.0] - 2023-01-17
|
11
|
+
### Changed
|
12
|
+
* switch CI to github actions
|
13
|
+
* remove danger
|
14
|
+
* remove codecov
|
15
|
+
* Support for ruby 3
|
16
|
+
* The wrapper interface has been redesigned (breaking change, see [upgrade notes](./upgrade_notes.md))
|
17
|
+
|
18
|
+
|
19
|
+
## [1.0.0]
|
20
|
+
### Changed
|
21
|
+
* repackage 0.3.1 as 1.0.0
|
22
|
+
* setup circleci
|
23
|
+
* drop ruby < 2.4
|
12
24
|
|
13
|
-
0.3.0
|
14
|
-
---
|
15
25
|
|
26
|
+
## [0.3.1]
|
27
|
+
### Fixed
|
28
|
+
* fix after wrapper ordering bug [PR#6](https://github.com/andreaseger/receptacle/pull/6)
|
29
|
+
|
30
|
+
## [0.3.0}
|
31
|
+
### Added
|
16
32
|
* add danger
|
17
33
|
* also support higher arity methods (== method with more than one argument)
|
18
34
|
|
19
|
-
0.2.0
|
20
|
-
|
21
|
-
|
35
|
+
## [0.2.0]
|
36
|
+
### Changed
|
22
37
|
* update documentation
|
23
38
|
* enable ruby 2.1+
|
24
39
|
|
25
|
-
0.1.1
|
26
|
-
|
27
|
-
|
40
|
+
## [0.1.1]
|
41
|
+
## Added
|
28
42
|
* add changelog, update copyright
|
29
43
|
* add test helper method `ensure_method_delegators` to make rspec stubs/mocks work as expected
|
30
44
|
|
31
|
-
0.1.0
|
32
|
-
|
33
|
-
|
45
|
+
## [0.1.0]
|
46
|
+
## Added
|
34
47
|
* initial release
|
35
|
-
|
data/Gemfile
CHANGED
data/Gemfile.lock
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
receptacle (2.0.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
ast (2.4.2)
|
10
|
+
coderay (1.1.3)
|
11
|
+
diff-lcs (1.5.0)
|
12
|
+
docile (1.4.0)
|
13
|
+
ffi (1.15.5-java)
|
14
|
+
json (2.6.2)
|
15
|
+
json (2.6.2-java)
|
16
|
+
method_source (1.0.0)
|
17
|
+
parallel (1.22.1)
|
18
|
+
parser (3.1.2.1)
|
19
|
+
ast (~> 2.4.1)
|
20
|
+
pry (0.14.1)
|
21
|
+
coderay (~> 1.1)
|
22
|
+
method_source (~> 1.0)
|
23
|
+
pry (0.14.1-java)
|
24
|
+
coderay (~> 1.1)
|
25
|
+
method_source (~> 1.0)
|
26
|
+
spoon (~> 0.0)
|
27
|
+
rainbow (3.1.1)
|
28
|
+
rake (10.5.0)
|
29
|
+
regexp_parser (2.6.0)
|
30
|
+
rexml (3.2.5)
|
31
|
+
rspec (3.12.0)
|
32
|
+
rspec-core (~> 3.12.0)
|
33
|
+
rspec-expectations (~> 3.12.0)
|
34
|
+
rspec-mocks (~> 3.12.0)
|
35
|
+
rspec-core (3.12.0)
|
36
|
+
rspec-support (~> 3.12.0)
|
37
|
+
rspec-expectations (3.12.0)
|
38
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
39
|
+
rspec-support (~> 3.12.0)
|
40
|
+
rspec-mocks (3.12.0)
|
41
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
42
|
+
rspec-support (~> 3.12.0)
|
43
|
+
rspec-support (3.12.0)
|
44
|
+
rspec_junit_formatter (0.6.0)
|
45
|
+
rspec-core (>= 2, < 4, != 2.12.0)
|
46
|
+
rt_rubocop_defaults (2.4.0)
|
47
|
+
rubocop (~> 1.25)
|
48
|
+
rubocop (1.38.0)
|
49
|
+
json (~> 2.3)
|
50
|
+
parallel (~> 1.10)
|
51
|
+
parser (>= 3.1.2.1)
|
52
|
+
rainbow (>= 2.2.2, < 4.0)
|
53
|
+
regexp_parser (>= 1.8, < 3.0)
|
54
|
+
rexml (>= 3.2.5, < 4.0)
|
55
|
+
rubocop-ast (>= 1.23.0, < 2.0)
|
56
|
+
ruby-progressbar (~> 1.7)
|
57
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
58
|
+
rubocop-ast (1.23.0)
|
59
|
+
parser (>= 3.1.1.0)
|
60
|
+
rubocop-rspec (2.14.2)
|
61
|
+
rubocop (~> 1.33)
|
62
|
+
rubocop_runner (2.2.1)
|
63
|
+
ruby-progressbar (1.11.0)
|
64
|
+
simplecov (0.21.2)
|
65
|
+
docile (~> 1.1)
|
66
|
+
simplecov-html (~> 0.11)
|
67
|
+
simplecov_json_formatter (~> 0.1)
|
68
|
+
simplecov-html (0.12.3)
|
69
|
+
simplecov_json_formatter (0.1.4)
|
70
|
+
spoon (0.0.6)
|
71
|
+
ffi
|
72
|
+
unicode-display_width (2.3.0)
|
73
|
+
|
74
|
+
PLATFORMS
|
75
|
+
universal-java-11
|
76
|
+
x86_64-linux
|
77
|
+
|
78
|
+
DEPENDENCIES
|
79
|
+
bundler (>= 1.13, < 3)
|
80
|
+
pry
|
81
|
+
rake (~> 10.0)
|
82
|
+
receptacle!
|
83
|
+
rspec (~> 3.11)
|
84
|
+
rspec_junit_formatter
|
85
|
+
rt_rubocop_defaults (~> 2.4)
|
86
|
+
rubocop (~> 1.37)
|
87
|
+
rubocop-rspec (~> 2.14)
|
88
|
+
rubocop_runner (~> 2.2)
|
89
|
+
simplecov (~> 0.13)
|
90
|
+
|
91
|
+
BUNDLED WITH
|
92
|
+
2.3.26
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -2,15 +2,14 @@
|
|
2
2
|
|
3
3
|
[](https://badge.fury.io/rb/receptacle)
|
4
4
|
[](https://rubygems.org/gems/receptacle)
|
5
|
-
|
6
|
-
[](https://codecov.io/gh/andreaseger/receptacle)
|
5
|
+
|
7
6
|
|
8
7
|
## About
|
9
8
|
|
10
9
|
Provides easy and fast means to use the repository pattern to create separation
|
11
10
|
between your business logic and your data sources.
|
12
11
|
|
13
|
-
|
12
|
+
The ownership of this project has been taken over from https://github.com/andreaseger/receptacle, where you can still find version 1.0
|
14
13
|
|
15
14
|
## Installation
|
16
15
|
|
@@ -82,14 +81,14 @@ Optionally wrapper classes can be defined
|
|
82
81
|
```ruby
|
83
82
|
module Wrapper
|
84
83
|
class Validator
|
85
|
-
def
|
84
|
+
def find(id:)
|
86
85
|
raise ArgumentError if id.nil?
|
87
|
-
|
86
|
+
yield(id: id)
|
88
87
|
end
|
89
88
|
end
|
90
89
|
class ModelMapper
|
91
|
-
def
|
92
|
-
Model::User.new(
|
90
|
+
def find(id:)
|
91
|
+
Model::User.new(yield(id: id))
|
93
92
|
end
|
94
93
|
end
|
95
94
|
end
|
@@ -122,14 +121,14 @@ module Repository
|
|
122
121
|
|
123
122
|
module Wrapper
|
124
123
|
class Validator
|
125
|
-
def
|
124
|
+
def find(id:)
|
126
125
|
raise ArgumentError if id.nil?
|
127
|
-
|
126
|
+
yield(id: id)
|
128
127
|
end
|
129
128
|
end
|
130
129
|
class ModelMapper
|
131
|
-
def
|
132
|
-
Model::User.new(
|
130
|
+
def find(id:)
|
131
|
+
Model::User.new(yield(id: id))
|
133
132
|
end
|
134
133
|
end
|
135
134
|
end
|
@@ -225,47 +224,28 @@ applying them in the business logic by using wrappers.
|
|
225
224
|
|
226
225
|
One or multiple wrappers sit logically between the repository and the
|
227
226
|
strategies. Based on the repository configuration it knows when and in which
|
228
|
-
order they should be applied.
|
229
|
-
actions.
|
230
|
-
|
231
|
-
1. a _before_ method action: This action is called before the final strategy
|
232
|
-
method is executed. It has access to the method parameter and can even modify
|
233
|
-
them.
|
234
|
-
2. a _after_ method action: This action is called after the strategy method was
|
235
|
-
executed and has access to the method parameters passed to the strategy
|
236
|
-
method and the return value. The return value could be modified here too.
|
237
|
-
|
238
|
-
The extra 1/2 action type is born by the fact that if a single wrapper class
|
239
|
-
implements both an before and after action for the same method the same wrapper
|
240
|
-
instance is used to execute both. Although this doesn't cover the all use cases
|
241
|
-
an _around_ method action would but many which need state before and after the
|
242
|
-
data source is accessed are covered.
|
227
|
+
order they should be applied.
|
243
228
|
|
244
229
|
#### Implementation
|
245
230
|
|
246
231
|
Wrapper actions are implemented as plain ruby classes which provide instance
|
247
|
-
methods named like
|
248
|
-
`<method_name>` is the repository/strategy method this action should be applied
|
249
|
-
to.
|
232
|
+
methods named like the method that the repository/strategy method this action should be applied to.
|
250
233
|
|
251
234
|
```ruby
|
252
235
|
module Wrapper
|
253
236
|
class Validator
|
254
|
-
def
|
237
|
+
def find(id:)
|
255
238
|
raise ArgumentError if id.nil?
|
256
|
-
|
239
|
+
yield(id: id)
|
257
240
|
end
|
258
241
|
end
|
259
242
|
end
|
260
243
|
```
|
261
244
|
|
262
|
-
This wrapper class would
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
If multiple wrapper classes are defined the before wrapper actions are executed
|
267
|
-
in the order the wrapper classes are defined while the after actions are applied
|
268
|
-
in reverse order.
|
245
|
+
This wrapper class would execute on any `find` call. You can use it to execute code
|
246
|
+
before or after the next wrapper/strategy is called. Calling `yield` executes the next
|
247
|
+
wrapper in line or the strategy, if this is the last wrapper that is called. The return
|
248
|
+
value is passed down to the previous wrapper and in the end to the repository caller.
|
269
249
|
|
270
250
|
### Memory Strategy
|
271
251
|
|
@@ -315,8 +295,8 @@ Some alternative have some interesting features nevertheless:
|
|
315
295
|
|
316
296
|
This gem on the other hand makes absolutely no assumptions about your data
|
317
297
|
source or general structure of your code. It can be simply plugged in between
|
318
|
-
your business logic and data source to abstract the two. Of
|
319
|
-
repository pattern implementations strategy details should be hidden from the
|
298
|
+
your business logic and data source to abstract the two. Of course, like the other
|
299
|
+
repository pattern implementations, strategy details should be hidden from the
|
320
300
|
interface. The data source can essentially be anything. A SQL database, a no-SQL
|
321
301
|
database, a JSON API or even a gem. Placing a gem behind a repository can be
|
322
302
|
useful if you're not yet sure this is the correct or best possible gem,
|
@@ -327,15 +307,11 @@ this by giving all the different http libraries a common interface).
|
|
327
307
|
|
328
308
|
A module called `TestSupport` can be found
|
329
309
|
[here](https://github.com/andreaseger/receptacle/blob/master/lib/receptacle/test_support.rb).
|
330
|
-
Right now it provides
|
331
|
-
temporarily to another strategy and `ensure_method_delegators` to solve issues
|
332
|
-
caused by Rspec when attempting to stub a repository method. Both methods and
|
333
|
-
how to use them is described in more detail in the inline documentation.
|
310
|
+
Right now it provides a helper method `with_strategy` to easily toggle temporarily to another strategy. How to use it is described in more detail in the inline documentation.
|
334
311
|
|
335
312
|
## Goals of this implementation
|
336
313
|
|
337
314
|
- small core codebase
|
338
|
-
- minimal processing overhead - fast method dispatching
|
339
315
|
- flexible - all kind of methods should possible to be mediated
|
340
316
|
- basic but powerful callbacks/hooks/observer possibilities
|
341
317
|
|
@@ -354,16 +330,10 @@ to [rubygems.org](https://rubygems.org).
|
|
354
330
|
## Contributing
|
355
331
|
|
356
332
|
Bug reports and pull requests are welcome on GitHub at
|
357
|
-
https://github.com/
|
333
|
+
https://github.com/runtastic/receptacle. This project is intended to be a safe,
|
358
334
|
welcoming space for collaboration, and contributors are expected to adhere to
|
359
335
|
the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
360
336
|
|
361
|
-
## Attribution
|
362
|
-
|
363
|
-
[Runtastic][runtastic] is using the repository pattern extensively in its
|
364
|
-
backend services and inspired the creation of this library. Nevertheless no code
|
365
|
-
developed at [Runtastic][runtastic] was used in this library.
|
366
|
-
|
367
337
|
## License
|
368
338
|
|
369
339
|
The gem is available as open source under the terms of
|
data/Rakefile
CHANGED
@@ -1,25 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rake/testtask"
|
4
5
|
|
5
6
|
Rake::TestTask.new(:test) do |t|
|
6
|
-
t.libs <<
|
7
|
-
t.libs <<
|
8
|
-
t.test_files = FileList[
|
7
|
+
t.libs << "test"
|
8
|
+
t.libs << "lib"
|
9
|
+
t.test_files = FileList["test/**/test_*.rb"]
|
9
10
|
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
RuboCop::RakeTask.new
|
14
|
-
namespace :rubocop do
|
15
|
-
desc 'Install Rubocop as pre-commit hook'
|
16
|
-
task :install do
|
17
|
-
require 'rubocop_runner'
|
18
|
-
RubocopRunner.install
|
19
|
-
end
|
20
|
-
end
|
21
|
-
rescue LoadError
|
22
|
-
p 'rubocop not installed'
|
23
|
-
end
|
12
|
+
require "rubocop/rake_task"
|
13
|
+
RuboCop::RakeTask.new
|
24
14
|
|
25
15
|
task default: :test
|
data/bin/console
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
4
|
+
require "bundler/setup"
|
5
|
+
require "receptacle"
|
6
6
|
|
7
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
8
8
|
# with your gem easier. You can also use a different console, if you like.
|
9
9
|
|
10
|
-
require
|
10
|
+
require "pry"
|
11
11
|
Pry.start
|
data/examples/simple_repo.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require
|
4
|
+
require "bundler/inline"
|
4
5
|
gemfile true do
|
5
|
-
source
|
6
|
-
gem
|
7
|
-
gem
|
6
|
+
source "https://rubygems.org"
|
7
|
+
gem "receptacle", "~> 2"
|
8
|
+
gem "mongo"
|
8
9
|
end
|
9
|
-
require
|
10
|
+
require "irb"
|
10
11
|
|
11
12
|
# a simple struct to act as business entity
|
12
13
|
User = Struct.new(:id, :name)
|
@@ -18,10 +19,11 @@ module Connection
|
|
18
19
|
|
19
20
|
def initialize
|
20
21
|
::Mongo::Logger.logger.level = Logger::INFO
|
21
|
-
@client = ::Mongo::Client.new([
|
22
|
+
@client = ::Mongo::Client.new(["127.0.0.1:27017"], database: "receptacle")
|
22
23
|
client[:users].delete_many # empty collection
|
23
24
|
end
|
24
25
|
attr_reader :client
|
26
|
+
|
25
27
|
def self.client
|
26
28
|
instance.client
|
27
29
|
end
|
@@ -45,7 +47,7 @@ module Repository
|
|
45
47
|
class Mongo
|
46
48
|
def find(id:)
|
47
49
|
mongo_to_model(collection.find(_id: id).first)
|
48
|
-
rescue
|
50
|
+
rescue StandardError
|
49
51
|
nil
|
50
52
|
end
|
51
53
|
|
@@ -61,7 +63,7 @@ module Repository
|
|
61
63
|
private
|
62
64
|
|
63
65
|
def mongo_to_model(doc)
|
64
|
-
::User.new(doc[
|
66
|
+
::User.new(doc["_id"], doc["name"])
|
65
67
|
end
|
66
68
|
|
67
69
|
def collection
|
@@ -100,21 +102,21 @@ end
|
|
100
102
|
# configure the repository and use it
|
101
103
|
Repository::User.strategy Repository::User::Strategy::InMemory
|
102
104
|
|
103
|
-
user = Repository::User.create(name:
|
104
|
-
print
|
105
|
+
user = Repository::User.create(name: "foo")
|
106
|
+
print "created user: "
|
105
107
|
p user
|
106
|
-
print
|
108
|
+
print "find user by id: "
|
107
109
|
p Repository::User.find(id: user.id)
|
108
110
|
|
109
111
|
# switching to mongo and we see it's using a different store but keeps the same interface
|
110
112
|
Repository::User.strategy Repository::User::Strategy::Mongo
|
111
113
|
|
112
|
-
print
|
114
|
+
print "search same user in other strategy: "
|
113
115
|
p Repository::User.find(id: user.id)
|
114
116
|
#-> nil
|
115
117
|
|
116
|
-
user = Repository::User.create(name:
|
117
|
-
print
|
118
|
+
user = Repository::User.create(name: "foo mongo")
|
119
|
+
print "create new user: "
|
118
120
|
p user
|
119
|
-
print
|
121
|
+
print "find new user by id: "
|
120
122
|
p Repository::User.find(id: user.id)
|
data/lib/receptacle/errors.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Receptacle
|
3
4
|
module Errors
|
4
5
|
class NotConfigured < StandardError
|
5
6
|
attr_reader :repo
|
7
|
+
|
6
8
|
def initialize(repo:)
|
7
9
|
@repo = repo
|
8
10
|
super("Missing Configuration for repository: <#{repo}>")
|
9
11
|
end
|
10
12
|
end
|
11
|
-
class ReservedMethodName < StandardError; end
|
12
13
|
end
|
13
14
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "receptacle/errors"
|
4
|
+
|
5
|
+
module Receptacle
|
6
|
+
module Repo
|
7
|
+
module ClassMethods
|
8
|
+
def mediate(method_name)
|
9
|
+
define_singleton_method(method_name) do |*args, **kwargs|
|
10
|
+
raise Errors::NotConfigured.new(repo: self) unless @strategy
|
11
|
+
|
12
|
+
with_wrappers(@wrappers.dup, method_name, *args, **kwargs) do |*sub_args, **sub_kwargs|
|
13
|
+
strategy.new.public_send(method_name, *sub_args, **sub_kwargs)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def wrappers(wrappers)
|
19
|
+
@wrappers = wrappers
|
20
|
+
end
|
21
|
+
|
22
|
+
def strategy(value = nil)
|
23
|
+
if value
|
24
|
+
@strategy = value
|
25
|
+
else
|
26
|
+
@strategy
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def with_wrappers(wrappers, method_name, *args, **kwargs, &block)
|
33
|
+
next_wrapper = wrappers.shift
|
34
|
+
if next_wrapper&.method_defined?(method_name)
|
35
|
+
next_wrapper.new.public_send(method_name, *args, **kwargs) do |*sub_args, **sub_kwargs|
|
36
|
+
with_wrappers(wrappers, method_name, *sub_args, **sub_kwargs, &block)
|
37
|
+
end
|
38
|
+
elsif next_wrapper
|
39
|
+
with_wrappers(wrappers, method_name, *args, **kwargs, &block)
|
40
|
+
else
|
41
|
+
yield(*args, **kwargs)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.included(base)
|
47
|
+
base.instance_variable_set(:@wrappers, [])
|
48
|
+
base.extend(ClassMethods)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Receptacle
|
3
4
|
module TestSupport
|
4
5
|
# with_strategy
|
@@ -7,7 +8,7 @@ module Receptacle
|
|
7
8
|
#
|
8
9
|
# can be used in rspec like this
|
9
10
|
#
|
10
|
-
# require 'receptacle/test_support'
|
11
|
+
# require 'receptacle/test_support'
|
11
12
|
# RSpec.configure do |c|
|
12
13
|
# c.include Receptacle::TestSupport
|
13
14
|
# end
|
@@ -46,21 +47,5 @@ module Receptacle
|
|
46
47
|
ensure
|
47
48
|
repo.strategy original_strategy
|
48
49
|
end
|
49
|
-
|
50
|
-
# ensure_method_delegators
|
51
|
-
#
|
52
|
-
# When using something like `allow(SomeRepo).to receive(:find)` (where find
|
53
|
-
# is a mediated method) before the method was called the first time Rspec
|
54
|
-
# would stub the method with the wrong arity of 0 when also using jruby.
|
55
|
-
# This seems to be caused by the lazily defined methods. Simply calling the
|
56
|
-
# following method in a before hook when method stubbing is need solves this
|
57
|
-
# issue. As it's a problem which only affects mocking libraries it's
|
58
|
-
# currently not planned to change this behavior.
|
59
|
-
#
|
60
|
-
def ensure_method_delegators(repo)
|
61
|
-
Receptacle::Registration.repositories[repo].methods.each do |method_name|
|
62
|
-
repo.__build_method(method_name)
|
63
|
-
end
|
64
|
-
end
|
65
50
|
end
|
66
51
|
end
|
data/lib/receptacle/version.rb
CHANGED