interactor 3.1.0 → 3.1.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 +5 -5
- data/.travis.yml +14 -1
- data/CHANGELOG.md +14 -2
- data/Gemfile +1 -1
- data/README.md +30 -35
- data/interactor.gemspec +3 -3
- data/lib/interactor/context.rb +2 -2
- data/lib/interactor/organizer.rb +3 -3
- data/spec/interactor/context_spec.rb +8 -0
- data/spec/spec_helper.rb +2 -2
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 46223de1a4e39c98aa604fcfc35f3c68bf27112ddb92c38b19dcd660ea35cb23
|
4
|
+
data.tar.gz: dced8f4dbc38e443cf11009bce3728a5268aeca3dba204a96c04e99a30f6cea1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a817f4a3c31553afd48ad04f2315abb640351bb629ea813d361212cd2d43c9b7b6af9d185614ef03c1f136649f33235fd3f7574ac5ebf992f7e681512e368337
|
7
|
+
data.tar.gz: 2a871976402baea2a0de705130d17216c9b7fa8438cdb7550829ba31e9fa7b06bc79e8d11b38712dcaa11eb9d6a4ad8eeefc44d06e6b2120860ac4e45ba59c8f
|
data/.travis.yml
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
after_success:
|
2
|
+
- bundle exec codeclimate-test-reporter
|
1
3
|
before_install:
|
2
4
|
- gem update bundler rake
|
3
5
|
branches:
|
@@ -13,10 +15,21 @@ env:
|
|
13
15
|
language: ruby
|
14
16
|
matrix:
|
15
17
|
allow_failures:
|
18
|
+
- rvm: "2.0"
|
19
|
+
- rvm: "2.1"
|
20
|
+
- rvm: "2.2"
|
16
21
|
- rvm: ruby-head
|
22
|
+
notifications:
|
23
|
+
webhooks:
|
24
|
+
on_start: always
|
25
|
+
urls:
|
26
|
+
- http://buildlight.collectiveidea.com/
|
17
27
|
rvm:
|
18
|
-
- 1.9.3
|
19
28
|
- "2.0"
|
20
29
|
- "2.1"
|
30
|
+
- "2.2"
|
31
|
+
- "2.3"
|
32
|
+
- "2.4"
|
33
|
+
- "2.5"
|
21
34
|
- ruby-head
|
22
35
|
script: bundle exec rspec
|
data/CHANGELOG.md
CHANGED
@@ -1,11 +1,18 @@
|
|
1
|
+
## 3.1.1 / 2018-05-30
|
2
|
+
|
3
|
+
* [BUGFIX] Allow Context#fail! to accept a hash with string keys
|
4
|
+
* [ENHANCEMENT] Many documentation updates
|
5
|
+
|
6
|
+
## 3.1.0 / 2014-10-13
|
7
|
+
|
8
|
+
* [FEATURE] Add around hooks
|
9
|
+
|
1
10
|
## 3.0.1 / 2014-09-09
|
2
11
|
|
3
12
|
* [ENHANCEMENT] Add TomDoc code documentation
|
4
13
|
|
5
14
|
## 3.0.0 / 2014-09-07
|
6
15
|
|
7
|
-
* [FEATURE] Halt performance if the interactor fails prior
|
8
|
-
* [ENHANCEMENT] Add support for Ruby 2.1
|
9
16
|
* [FEATURE] Remove "magical" access to the context through the interactor
|
10
17
|
* [FEATURE] Manage context values via setters/getters rather than hash access
|
11
18
|
* [FEATURE] Change the primary interactor API method from "perform" to "call"
|
@@ -15,6 +22,11 @@
|
|
15
22
|
* [ENHANCEMENT] Build a suite of realistic integration tests
|
16
23
|
* [ENHANCEMENT] Move rollback responsibility into the context
|
17
24
|
|
25
|
+
## 2.1.1 / 2014-09-30
|
26
|
+
|
27
|
+
* [FEATURE] Halt performance if the interactor fails prior
|
28
|
+
* [ENHANCEMENT] Add support for Ruby 2.1
|
29
|
+
|
18
30
|
## 2.1.0 / 2013-09-05
|
19
31
|
|
20
32
|
* [FEATURE] Roll back when an interactor within an organizer raises an error
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
# Interactor
|
2
2
|
|
3
|
-
[](https://gemnasium.com/collectiveidea/interactor)
|
3
|
+
[](http://rubygems.org/gems/interactor)
|
4
|
+
[](https://travis-ci.org/collectiveidea/interactor)
|
5
|
+
[](https://codeclimate.com/github/collectiveidea/interactor)
|
6
|
+
[](https://codeclimate.com/github/collectiveidea/interactor)
|
8
7
|
|
9
8
|
## Getting Started
|
10
9
|
|
@@ -74,6 +73,16 @@ context.fail!
|
|
74
73
|
context.success? # => false
|
75
74
|
```
|
76
75
|
|
76
|
+
#### Dealing with Failure
|
77
|
+
|
78
|
+
`context.fail!` always throws an exception of type `Interactor::Failure`.
|
79
|
+
|
80
|
+
Normally, however, these exceptions are not seen. In the recommended usage, the controller invokes the interactor using the class method `call`, then checks the `success?` method of the context.
|
81
|
+
|
82
|
+
This works because the `call` class method swallows exceptions. When unit testing an interactor, if calling custom business logic methods directly and bypassing `call`, be aware that `fail!` will generate such exceptions.
|
83
|
+
|
84
|
+
See *Interactors in the Controller*, below, for the recommended usage of `call` and `success?`.
|
85
|
+
|
77
86
|
### Hooks
|
78
87
|
|
79
88
|
#### Before Hooks
|
@@ -92,7 +101,7 @@ A symbol argument can also be given, rather than a block.
|
|
92
101
|
```ruby
|
93
102
|
before :zero_emails_sent
|
94
103
|
|
95
|
-
def
|
104
|
+
def zero_emails_sent
|
96
105
|
context.emails_sent = 0
|
97
106
|
end
|
98
107
|
```
|
@@ -108,6 +117,8 @@ after do
|
|
108
117
|
end
|
109
118
|
```
|
110
119
|
|
120
|
+
NB: After hooks are only run on success. If the `fail!` method is called, the interactor's after hooks are not run.
|
121
|
+
|
111
122
|
#### Around Hooks
|
112
123
|
|
113
124
|
You can also define around hooks in the same way as before or after hooks, using
|
@@ -135,6 +146,8 @@ def time_execution(interactor)
|
|
135
146
|
end
|
136
147
|
```
|
137
148
|
|
149
|
+
NB: If the `fail!` method is called, all of the interactor's around hooks cease execution, and no code after `interactor.call` will be run.
|
150
|
+
|
138
151
|
#### Hook Sequence
|
139
152
|
|
140
153
|
Before hooks are invoked in the order in which they were defined while after
|
@@ -260,7 +273,7 @@ class SessionsController < ApplicationController
|
|
260
273
|
|
261
274
|
if result.success?
|
262
275
|
session[:user_token] = result.token
|
263
|
-
redirect_to
|
276
|
+
redirect_to result.user
|
264
277
|
else
|
265
278
|
flash.now[:message] = t(result.message)
|
266
279
|
render :new
|
@@ -291,7 +304,7 @@ class SessionsController < ApplicationController
|
|
291
304
|
|
292
305
|
if result.success?
|
293
306
|
session[:user_token] = result.token
|
294
|
-
redirect_to
|
307
|
+
redirect_to result.user
|
295
308
|
else
|
296
309
|
flash.now[:message] = t(result.message)
|
297
310
|
render :new
|
@@ -337,7 +350,7 @@ account cancellation interaction takes on more responsibility in the future.
|
|
337
350
|
|
338
351
|
### The Future™
|
339
352
|
|
340
|
-
**
|
353
|
+
**SPOILER ALERT:** Your use case won't *stay* so simple.
|
341
354
|
|
342
355
|
In [our](http://collectiveidea.com) experience, a simple task like
|
343
356
|
authenticating a user will eventually take on multiple responsibilities:
|
@@ -481,11 +494,9 @@ context.
|
|
481
494
|
|
482
495
|
```ruby
|
483
496
|
describe AuthenticateUser do
|
484
|
-
|
485
|
-
|
486
|
-
let(:interactor) { AuthenticateUser.new(email: "john@example.com", password: "secret") }
|
487
|
-
let(:context) { interactor.context }
|
497
|
+
subject(:context) { AuthenticateUser.call(email: "john@example.com", password: "secret") }
|
488
498
|
|
499
|
+
describe ".call" do
|
489
500
|
context "when given valid credentials" do
|
490
501
|
let(:user) { double(:user, secret_token: "token") }
|
491
502
|
|
@@ -494,25 +505,15 @@ describe AuthenticateUser do
|
|
494
505
|
end
|
495
506
|
|
496
507
|
it "succeeds" do
|
497
|
-
interactor.call
|
498
|
-
|
499
508
|
expect(context).to be_a_success
|
500
509
|
end
|
501
510
|
|
502
511
|
it "provides the user" do
|
503
|
-
expect
|
504
|
-
interactor.call
|
505
|
-
}.to change {
|
506
|
-
context.user
|
507
|
-
}.from(nil).to(user)
|
512
|
+
expect(context.user).to eq(user)
|
508
513
|
end
|
509
514
|
|
510
515
|
it "provides the user's secret token" do
|
511
|
-
expect
|
512
|
-
interactor.call
|
513
|
-
}.to change {
|
514
|
-
context.token
|
515
|
-
}.from(nil).to("token")
|
516
|
+
expect(context.token).to eq("token")
|
516
517
|
end
|
517
518
|
end
|
518
519
|
|
@@ -522,17 +523,11 @@ describe AuthenticateUser do
|
|
522
523
|
end
|
523
524
|
|
524
525
|
it "fails" do
|
525
|
-
interactor.call
|
526
|
-
|
527
526
|
expect(context).to be_a_failure
|
528
527
|
end
|
529
528
|
|
530
529
|
it "provides a failure message" do
|
531
|
-
expect
|
532
|
-
interactor.call
|
533
|
-
}.to change {
|
534
|
-
context.message
|
535
|
-
}.from(nil).to be_present
|
530
|
+
expect(context.message).to be_present
|
536
531
|
end
|
537
532
|
end
|
538
533
|
end
|
@@ -610,7 +605,7 @@ class SessionsController < ApplicationController
|
|
610
605
|
|
611
606
|
if result.success?
|
612
607
|
session[:user_token] = result.token
|
613
|
-
redirect_to
|
608
|
+
redirect_to result.user
|
614
609
|
else
|
615
610
|
flash.now[:message] = t(result.message)
|
616
611
|
render :new
|
@@ -633,7 +628,7 @@ describe SessionsController do
|
|
633
628
|
end
|
634
629
|
|
635
630
|
context "when successful" do
|
636
|
-
let(:user) { double(:user) }
|
631
|
+
let(:user) { double(:user, id: 1) }
|
637
632
|
let(:context) { double(:context, success?: true, user: user, token: "token") }
|
638
633
|
|
639
634
|
it "saves the user's secret token in the session" do
|
@@ -647,7 +642,7 @@ describe SessionsController do
|
|
647
642
|
it "redirects to the homepage" do
|
648
643
|
response = post :create, session: { email: "john@doe.com", password: "secret" }
|
649
644
|
|
650
|
-
expect(response).to redirect_to(
|
645
|
+
expect(response).to redirect_to(user_path(user))
|
651
646
|
end
|
652
647
|
end
|
653
648
|
|
data/interactor.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = "interactor"
|
5
|
-
spec.version = "3.1.
|
5
|
+
spec.version = "3.1.1"
|
6
6
|
|
7
7
|
spec.author = "Collective Idea"
|
8
8
|
spec.email = "info@collectiveidea.com"
|
@@ -14,6 +14,6 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.files = `git ls-files`.split($/)
|
15
15
|
spec.test_files = spec.files.grep(/^spec/)
|
16
16
|
|
17
|
-
spec.add_development_dependency "bundler"
|
18
|
-
spec.add_development_dependency "rake"
|
17
|
+
spec.add_development_dependency "bundler"
|
18
|
+
spec.add_development_dependency "rake"
|
19
19
|
end
|
data/lib/interactor/context.rb
CHANGED
@@ -10,7 +10,7 @@ module Interactor
|
|
10
10
|
# the context is responsible for tracking individual interactor invocations
|
11
11
|
# for the purpose of rollback.
|
12
12
|
#
|
13
|
-
# The context may be
|
13
|
+
# The context may be manipulated using arbitrary getter and setter methods.
|
14
14
|
#
|
15
15
|
# Examples
|
16
16
|
#
|
@@ -121,7 +121,7 @@ module Interactor
|
|
121
121
|
#
|
122
122
|
# Raises Interactor::Failure initialized with the Interactor::Context.
|
123
123
|
def fail!(context = {})
|
124
|
-
modifiable.
|
124
|
+
context.each { |key, value| modifiable[key.to_sym] = value }
|
125
125
|
@failure = true
|
126
126
|
raise Failure, self
|
127
127
|
end
|
data/lib/interactor/organizer.rb
CHANGED
@@ -24,7 +24,7 @@ module Interactor
|
|
24
24
|
# Internal: Interactor::Organizer class methods.
|
25
25
|
module ClassMethods
|
26
26
|
# Public: Declare Interactors to be invoked as part of the
|
27
|
-
# Interactor::Organizer's invocation. These interactors
|
27
|
+
# Interactor::Organizer's invocation. These interactors are invoked in
|
28
28
|
# the order in which they are declared.
|
29
29
|
#
|
30
30
|
# interactors - Zero or more (or an Array of) Interactor classes.
|
@@ -55,7 +55,7 @@ module Interactor
|
|
55
55
|
# class MyOrganizer
|
56
56
|
# include Interactor::Organizer
|
57
57
|
#
|
58
|
-
#
|
58
|
+
# organize InteractorOne, InteractorTwo
|
59
59
|
# end
|
60
60
|
#
|
61
61
|
# MyOrganizer.organized
|
@@ -70,7 +70,7 @@ module Interactor
|
|
70
70
|
# Internal: Interactor::Organizer instance methods.
|
71
71
|
module InstanceMethods
|
72
72
|
# Internal: Invoke the organized Interactors. An Interactor::Organizer is
|
73
|
-
# expected not to define its own "call" method in favor of this default
|
73
|
+
# expected not to define its own "#call" method in favor of this default
|
74
74
|
# implementation.
|
75
75
|
#
|
76
76
|
# Returns nothing.
|
@@ -101,6 +101,14 @@ module Interactor
|
|
101
101
|
}.from("bar").to("baz")
|
102
102
|
end
|
103
103
|
|
104
|
+
it "updates the context with a string key" do
|
105
|
+
expect {
|
106
|
+
context.fail!("foo" => "baz") rescue nil
|
107
|
+
}.to change {
|
108
|
+
context.foo
|
109
|
+
}.from("bar").to("baz")
|
110
|
+
end
|
111
|
+
|
104
112
|
it "raises failure" do
|
105
113
|
expect {
|
106
114
|
context.fail!
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,43 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: interactor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.
|
4
|
+
version: 3.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Collective Idea
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
description: Interactor provides a common interface for performing complex user interactions.
|
42
42
|
email: info@collectiveidea.com
|
43
43
|
executables: []
|
@@ -86,7 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
86
|
version: '0'
|
87
87
|
requirements: []
|
88
88
|
rubyforge_project:
|
89
|
-
rubygems_version: 2.
|
89
|
+
rubygems_version: 2.7.6
|
90
90
|
signing_key:
|
91
91
|
specification_version: 4
|
92
92
|
summary: Simple interactor implementation
|