all_systems 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 275aae9e309c5a4d6f18fe23d05d4bb7866da786
4
+ data.tar.gz: ef9a2045793ed0faeeab07c3cf17c9ce7696cf66
5
+ SHA512:
6
+ metadata.gz: 974da988fad1bb04fb61d9a6a014504aa6f2826472b54ee6bbbbfe022e63b44edb03b4627a16bea5e61a2c4f6901a0052615a1b8b0955f056cef0ce56813fccf
7
+ data.tar.gz: 4bebef0a58c8863eff9908e638aa7257aafe9b6041afe0f91d835337fff681aa3ff5f3a0b95c65affb3a83e2893f331fc990be02469f6beeb7be23994b91ba7e
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in usecase.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Peter Saxton
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,240 @@
1
+ # AllSystems
2
+
3
+ **Simple Ruby usecases/interactors/service-object to encapsulate business logic**
4
+
5
+ ### Well what is it?
6
+ The three terms above are all used at various times to describe the use of a dedicated object separate to the delivery mechanism (read ApplicationController) to coordinate the calls on several domain objects (such as user models). Service object is sometimes used to describe the encapsulation of an external service that you system uses. E.g. you might have a Stripe service object, so I do not use that term. Also usecase seams to make more sense on a non technical level, so the Login usecase is what the customer does. It is achieved using the Login interactor, the Ruby object. A good starting point is this [article](https://netguru.co/blog/service-objects-in-rails-will-help) as well as the further reading listed. This [article](http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/) helps explain there place in the landscape of objeccts beyond MVC
7
+
8
+ ### Overview
9
+ An interactor encapsulates a specific business interaction, often a user interaction, such as `LogIn` or `CreatePost`. The business logic is declared by defining a `go!` method. All possible outcomes are stated by defining a outcomes method. Each instance of the interactor executes the `go!` method once only to produce a single result. The result consists of an outcome and optional output. The outcome is a single :symbol to name the result. The output an array of zero or more values.
10
+
11
+ Results are reported within the `go!` method of the interactor.
12
+
13
+ ```rb
14
+ Class WelcomeJohn < AllSystems::Interactor
15
+ def options
16
+ # Will always succeed
17
+ [:success]
18
+ end
19
+
20
+ def go!
21
+ new_user = {:name => 'John Smith'}
22
+ report :success, new_user
23
+ end
24
+ end
25
+
26
+ welcome = WelcomeJohn.new
27
+ welcome.result == [:success, new_user]
28
+ welcome.outcome == :success
29
+ welcome.output = [new_user]
30
+ ```
31
+
32
+ The interactor outcome can then be used to decide response
33
+
34
+ ```rb
35
+ welcome.on :success do |user|
36
+ puts "Hello #{user[:name]}"
37
+ end
38
+ ```
39
+
40
+ ### why?
41
+
42
+ Such a simple class that a library is almost not needed. I have found its value not in reduced work when making my specific interactors but in reduced testing for those interactor. Don't need to test things like single execution and predicate methods on specific interactors
43
+
44
+ ## Installation
45
+
46
+ Add this line to your application's Gemfile:
47
+
48
+ ```ruby
49
+ gem 'usecase'
50
+ ```
51
+
52
+ And then execute:
53
+
54
+ $ bundle
55
+
56
+ Or install it yourself as:
57
+
58
+ $ gem install usecase
59
+
60
+ ## Usage
61
+
62
+ ### Example 1 *Flipping a coin*
63
+
64
+ ```rb
65
+ Class FlipCoin < AllSystems::Interactor
66
+ def outcomes
67
+ [:heads, :tails]
68
+ end
69
+
70
+ def go!
71
+ report_tails if [true, false].sample
72
+ report_heads
73
+ end
74
+ end
75
+
76
+ filp = FlipCoin.new
77
+
78
+ flip.result
79
+ # => [:heads]
80
+
81
+ filp.outcome
82
+ # => :heads
83
+
84
+ flip.output?
85
+ # => []
86
+
87
+ flip.heads?
88
+ # => true
89
+
90
+ flip.tails?
91
+ # => false
92
+
93
+ flip.other?
94
+ # raise UnknownMethodError
95
+
96
+ flip.heads do
97
+ puts "Hooray"
98
+ end
99
+ ```
100
+
101
+ Example 2
102
+
103
+ ```rb
104
+ class Customer
105
+ # One of several customer actions
106
+ class PasswordReset < AllSystems::Interactor
107
+ def initialize(context, id, params)
108
+ @context = context
109
+ @id = id
110
+ @params = params
111
+ end
112
+
113
+ attr_reader :context, :id, :params
114
+
115
+ def outcomes
116
+ [:succeded, :account_unknown, :user_unknown, :not_permitted, :invalid_details]
117
+ end
118
+
119
+ def go!
120
+ report_account_unknown id, unless account
121
+ report_user_unknown if authority.guest?
122
+ report_not_permitted unless authority == account || authority.admin?
123
+ report_invalid_details form unless form.valid?
124
+ account.password = form.password
125
+ account.save
126
+ send_email
127
+ report_succeeded account
128
+ end
129
+
130
+ def send_email
131
+ context.customer_mailer.password_reset
132
+ end
133
+
134
+ def form
135
+ @form ||= Form.new params
136
+ end
137
+
138
+ def account
139
+ @account ||= Customers[id]
140
+ end
141
+
142
+ def authority
143
+ @authority ||= context.current_user
144
+ end
145
+
146
+ end
147
+ end
148
+
149
+ # use in controller
150
+ class CustomerController
151
+ def password_reset(id)
152
+ reset = Customer::Password.new(self, id, request.POST['customer'])
153
+
154
+ reset.succeeded do |customer| # 204: No Content
155
+ flash['success'] = 'Password update successful'
156
+ redirect customer_page(customer), 204
157
+ end
158
+
159
+ reset.unknown_account do |id| # 404: Not found
160
+ flash['error'] = "account: #{id} not found"
161
+ redirect customers_page, 404
162
+ end
163
+
164
+ reset.unknow_user do # 401: Unauthenticated
165
+ flash['error'] = 'Login required'
166
+ redirect login_page, 401
167
+ end
168
+
169
+ reset.not_permitted do # 403: Forbidden
170
+ flash['error'] = 'Not authorized'
171
+ redirect customer_page, 403
172
+ end
173
+
174
+ reset.invalid_details do |form| # 400: bad request
175
+ status = 400
176
+ render :new, :locals => {:form => form}
177
+ end
178
+ end
179
+ end
180
+ ```
181
+ establish, deduce, ascertain, settle, evaluate
182
+
183
+ ## Docs
184
+
185
+ **#go!** `interactor.go! => raise AbstractMethodError`
186
+
187
+ Abstract method that will always raise an error. Should be over written in for specific interactors
188
+
189
+ **#outcomes** `interactor.outcomes => []`
190
+
191
+ Should be over written in for specific interactors to return list of possible outcomes
192
+
193
+ **#name** `interactor.name => class_name`
194
+
195
+ Returns the name of the class or Anonymous if class not set to constant
196
+
197
+ **(private)#report** `interactor.report(outcome, *output) => terminate with result`
198
+
199
+ Use within the interactor to report that an outcome state has been reached with optional output. Terminates execution of go!
200
+
201
+ **#outcome** `interactor.outcome => symbol`
202
+
203
+ Returns the outcome of goning the interactor
204
+
205
+ **#outcome?(outcome)** `interactor.outcome?(outcome) => boolean`
206
+
207
+ Does the outcome match the predicate outcome.
208
+
209
+ **#output** `interactor.output => [*output]`
210
+
211
+ Returns an array of output from goning the interactor
212
+
213
+ **#on(:outcome)** `interactor.on(:outcome, &block) => block return value`
214
+
215
+ If the interactors out come was the same as given here then the output is yielded to the block, else no action.
216
+
217
+
218
+ **#&lt;outcome&gt;?** `interactor.<outcome>? => boolean`
219
+
220
+ Was the outcome equal to the method name, raises error if method name not one of possible outcomes
221
+
222
+ **#&lt;outcome&gt;** `interactor.<outcome> &block => block_return_value`
223
+
224
+ Yields output to block if outcome equal to method name, raises error if method name not one of possible outcomes
225
+
226
+ **#report_&lt;outcome&gt;** `interactor.report_<outcome>(*output) => terminate with result`
227
+
228
+ Use within the interactor to report that an outcome state has been reached with optional output. Terminates execution of go!
229
+
230
+
231
+ ## Upcoming
232
+ 8. actions on class passed to instance *possible to declare action before use*
233
+
234
+ ## Contributing
235
+
236
+ 1. Fork it ( https://github.com/[my-github-username]/usecase/fork )
237
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
238
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
239
+ 4. Push to the branch (`git push origin my-new-feature`)
240
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+ test_tasks = Dir['test/*/'].map { |d| File.basename(d) }
5
+
6
+ test_tasks.each do |folder|
7
+ Rake::TestTask.new("test:#{folder}") do |test|
8
+ test.pattern = "test/#{folder}/**/*_test.rb"
9
+ test.verbose = true
10
+ end
11
+ end
12
+
13
+ desc "Run application test suite"
14
+ Rake::TestTask.new("test") do |test|
15
+ test.pattern = "test/**/*_test.rb"
16
+ test.verbose = true
17
+ end
@@ -0,0 +1,7 @@
1
+ require "all_systems/version"
2
+ require "all_systems/errors"
3
+ require "all_systems/interactor"
4
+
5
+ module AllSystems
6
+ # Your code goes here...
7
+ end
@@ -0,0 +1,6 @@
1
+ module AllSystems
2
+ AbstractMethodError = Class.new(StandardError)
3
+ NoOutcomeError = Class.new(StandardError)
4
+ UnknownOutcomeReportError = Class.new(StandardError)
5
+ UnknownOutcomeError = Class.new(StandardError)
6
+ end
@@ -0,0 +1,65 @@
1
+ module AllSystems
2
+ class Interactor
3
+ def go!
4
+ raise AbstractMethodError, "please define #{__method__} for #{name} interactor"
5
+ end
6
+
7
+ def outcomes
8
+ # TODO throw error on abstract
9
+ []
10
+ end
11
+
12
+ def name
13
+ self.class.name || 'Anonymous'
14
+ end
15
+
16
+ def outcome
17
+ result.first
18
+ end
19
+
20
+ def outcome?(predicate)
21
+ raise UnknownOutcomeError unless outcomes.include? predicate
22
+ predicate == outcome
23
+ end
24
+
25
+ def output
26
+ result.drop 1
27
+ end
28
+
29
+ def on(conditional_outcome)
30
+ yield *output if outcome? conditional_outcome
31
+ end
32
+
33
+ private
34
+
35
+ def go
36
+ catch(:report) do
37
+ go!
38
+ raise NoOutcomeError, "#{name} concluded without reporting an outcome"
39
+ end
40
+ end
41
+
42
+ def result
43
+ @result ||= go
44
+ end
45
+
46
+ def report(*result)
47
+ raise UnknownOutcomeReportError unless outcomes.include? result.first
48
+ throw :report, result
49
+ end
50
+
51
+ def method_missing(method_symbol, *args, &block)
52
+ case method_symbol
53
+ when *outcomes
54
+ return on method_symbol, &block
55
+ when /report_([^?]+)/
56
+ report $1.to_sym, *args
57
+ when /([^?]+)\?/
58
+ super unless outcomes.include? $1.to_sym
59
+ outcome? $1.to_sym
60
+ else
61
+ super
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,3 @@
1
+ module AllSystems
2
+ VERSION = "0.2.0"
3
+ end
@@ -0,0 +1,35 @@
1
+ require_relative '../test_config'
2
+
3
+ module AllSystems
4
+ class InteractorErrorTest < MiniTest::Test
5
+ NoGoInteractor = Class.new(AllSystems::Interactor)
6
+
7
+ def test_raises_error_for_no_go_bang_method
8
+ interactor = NoGoInteractor.new
9
+ err = assert_raises AbstractMethodError do
10
+ interactor.outcome
11
+ end
12
+ assert_includes err.message, 'go!'
13
+ end
14
+
15
+ NoOutcomeInteractor = Class.new(AllSystems::Interactor) do
16
+ def go! ; end
17
+ end
18
+
19
+ def test_raises_error_if_go_does_not_report_outcome
20
+ interactor = NoOutcomeInteractor.new
21
+ err = assert_raises NoOutcomeError do
22
+ interactor.outcome
23
+ end
24
+ assert_includes err.message, 'NoOutcomeInteractor'
25
+ end
26
+
27
+ def test_raises_correct_error_for_unnamed_interactor
28
+ interactor = Class.new(AllSystems::Interactor).new
29
+ err = assert_raises AbstractMethodError do
30
+ interactor.outcome
31
+ end
32
+ assert_includes err.message, 'Anonymous interactor'
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,63 @@
1
+ require_relative '../test_config'
2
+
3
+ module AllSystems
4
+ class InteractorInvalidOutcomeTest < MiniTest::Test
5
+ def interactor_klass
6
+ @interactor_klass ||= Class.new(AllSystems::Interactor) do
7
+ def initialize(pass)
8
+ @pass = pass
9
+ end
10
+
11
+ def outcomes
12
+ [:success]
13
+ end
14
+
15
+ def go!
16
+ report :success if @pass
17
+ report :random
18
+ end
19
+ end
20
+ end
21
+
22
+ def test_cant_report_unknown_outcome
23
+ interactor = interactor_klass.new false
24
+ assert_raises AllSystems::UnknownOutcomeReportError do
25
+ interactor.outcome
26
+ end
27
+ end
28
+
29
+ def test_cant_check_unknown_outcome
30
+ interactor = interactor_klass.new true
31
+ assert_raises AllSystems::UnknownOutcomeError do
32
+ interactor.outcome? :random
33
+ end
34
+ end
35
+
36
+ def test_cant_define_callback_for_unknown_outcome
37
+ interactor = interactor_klass.new true
38
+ assert_raises AllSystems::UnknownOutcomeError do
39
+ interactor.on :random do
40
+ flunk
41
+ end
42
+ end
43
+ end
44
+
45
+ def test_no_method_error_for_invalid_outcomes
46
+ interactor = interactor_klass.new true
47
+ assert_raises NoMethodError do
48
+ interactor.random do
49
+ flunk
50
+ end
51
+ end
52
+ end
53
+
54
+ def test_no_method_error_for_invalid_outcome_queries
55
+ interactor = interactor_klass.new true
56
+ assert_raises NoMethodError do
57
+ interactor.random? do
58
+ flunk
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,135 @@
1
+ require_relative '../test_config'
2
+
3
+ module AllSystems
4
+ class InteractorOutcomeTest < MiniTest::Test
5
+ def interactor_klass
6
+ @interactor_klass ||= Class.new(AllSystems::Interactor) do
7
+ def initialize(pass)
8
+ @pass = pass
9
+ end
10
+
11
+ def outcomes
12
+ [:success, :failure]
13
+ end
14
+
15
+ def go!
16
+ report :success if @pass
17
+ report :failure
18
+ end
19
+ end
20
+ end
21
+
22
+ def test_reports_outcome_as_success_for_pass
23
+ interactor = interactor_klass.new true
24
+ assert_equal :success, interactor.outcome
25
+ end
26
+
27
+ def test_reports_outcome_as_failure_for_no_pass
28
+ interactor = interactor_klass.new false
29
+ assert_equal :failure, interactor.outcome
30
+ end
31
+
32
+ def test_confirms_outcome_success_for_pass
33
+ interactor = interactor_klass.new true
34
+ assert_equal true, interactor.outcome?(:success)
35
+ end
36
+
37
+ def test_denys_outcome_success_for_no_pass
38
+ interactor = interactor_klass.new false
39
+ assert_equal false, interactor.outcome?(:success)
40
+ end
41
+
42
+ def test_success_query_is_true_for_pass
43
+ interactor = interactor_klass.new true
44
+ assert_equal true, interactor.success?
45
+ end
46
+
47
+ def test_success_query_is_false_for_no_pass
48
+ interactor = interactor_klass.new false
49
+ assert_equal false, interactor.success?
50
+ end
51
+
52
+ def test_failure_query_is_true_for_no_pass
53
+ interactor = interactor_klass.new false
54
+ assert_equal true, interactor.failure?
55
+ end
56
+
57
+ def test_failure_query_is_false_for_pass
58
+ interactor = interactor_klass.new true
59
+ assert_equal false, interactor.failure?
60
+ end
61
+
62
+ def test_calls_on_success_action_for_pass
63
+ interactor = interactor_klass.new true
64
+ mock = MiniTest::Mock.new
65
+ mock.expect :report, true
66
+ interactor.on :success do
67
+ mock.report
68
+ end
69
+ mock.verify
70
+ end
71
+
72
+ # TODO decide
73
+ # def test_calls_on_either_action_for_pass
74
+ # interactor = interactor_klass.new true
75
+ # mock = MiniTest::Mock.new
76
+ # mock.expect :report, true
77
+ # interactor.on :success, :failue do
78
+ # mock.report
79
+ # end
80
+ # mock.verify
81
+ # end
82
+ #
83
+ # def test_calls_on_either_action_for_no_pass
84
+ # interactor = interactor_klass.new false
85
+ # mock = MiniTest::Mock.new
86
+ # mock.expect :report, true
87
+ # interactor.on :success, :failure do
88
+ # mock.report
89
+ # end
90
+ # mock.verify
91
+ # end
92
+
93
+ def test_doesnt_call_on_success_action_for_no_pass
94
+ interactor = interactor_klass.new false
95
+ interactor.on :success do
96
+ flunk 'Should not process'
97
+ end
98
+ end
99
+
100
+ def test_calls_success_action_for_pass
101
+ interactor = interactor_klass.new true
102
+ mock = MiniTest::Mock.new
103
+ mock.expect :report, true
104
+ interactor.success do
105
+ mock.report
106
+ end
107
+ mock.verify
108
+ end
109
+
110
+ def test_doesnt_call_success_for_no_pass
111
+ interactor = interactor_klass.new false
112
+ interactor.success do
113
+ flunk 'Should not be a success'
114
+ end
115
+ end
116
+
117
+ def test_calls_failure_action_for_no_pass
118
+ interactor = interactor_klass.new false
119
+ mock = MiniTest::Mock.new
120
+ mock.expect :report, true
121
+ interactor.failure do
122
+ mock.report
123
+ end
124
+ mock.verify
125
+ end
126
+
127
+ def test_doesnt_call_failure_for_pass
128
+ interactor = interactor_klass.new true
129
+ interactor.failure do
130
+ flunk 'Should not be a failure'
131
+ end
132
+ end
133
+ end
134
+
135
+ end
@@ -0,0 +1,80 @@
1
+ require_relative '../test_config'
2
+
3
+ module AllSystems
4
+ class InteractorOutputTest < MiniTest::Test
5
+ def interactor_klass
6
+ @interactor_klass ||= Class.new(AllSystems::Interactor) do
7
+ def initialize(value)
8
+ @value = value
9
+ end
10
+
11
+ def outcomes
12
+ [:none, :one, :two, :unique]
13
+ end
14
+
15
+ def go!
16
+ case @value
17
+ when 0
18
+ report :none
19
+ when 1
20
+ report :one, 1
21
+ when 2
22
+ report :two, 1, 2
23
+ when :unique
24
+ report :unique, Class.new
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ def test_empty_out_put_array_when_none_given
31
+ interactor = interactor_klass.new 0
32
+ assert_equal [], interactor.output
33
+ end
34
+
35
+ def test_callback_recives_no_output
36
+ interactor = interactor_klass.new 0
37
+ mock = MiniTest::Mock.new
38
+ mock.expect :report, true, []
39
+ interactor.none do |*args|
40
+ mock.report *args
41
+ end
42
+ mock.verify
43
+ end
44
+
45
+ def test_single_item_output
46
+ interactor = interactor_klass.new 1
47
+ assert_equal [1], interactor.output
48
+ end
49
+
50
+ def test_callback_recives_single_output
51
+ interactor = interactor_klass.new 1
52
+ mock = MiniTest::Mock.new
53
+ mock.expect :report, true, [1]
54
+ interactor.one do |*args|
55
+ mock.report *args
56
+ end
57
+ mock.verify
58
+ end
59
+
60
+ def test_two_item_output
61
+ interactor = interactor_klass.new 2
62
+ assert_equal [1, 2], interactor.output
63
+ end
64
+
65
+ def test_callback_recives_double_output
66
+ interactor = interactor_klass.new 2
67
+ mock = MiniTest::Mock.new
68
+ mock.expect :report, true, [1, 2]
69
+ interactor.two do |*args|
70
+ mock.report *args
71
+ end
72
+ mock.verify
73
+ end
74
+
75
+ def test_go_is_only_executed_once
76
+ interactor = interactor_klass.new :unique
77
+ assert_equal interactor.output.first, interactor.output.first
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,64 @@
1
+ require_relative '../test_config'
2
+
3
+ module AllSystems
4
+ class InteractorReportHelperTest < MiniTest::Test
5
+ def interactor_klass
6
+ @interactor_klass ||= Class.new(AllSystems::Interactor) do
7
+ def initialize(pass)
8
+ @pass = pass
9
+ end
10
+
11
+ def outcomes
12
+ [:success, :failure]
13
+ end
14
+
15
+ def go!
16
+ report_success :item if @pass
17
+ report_failure
18
+ end
19
+ end
20
+ end
21
+
22
+ def test_reports_outcome_as_success_for_pass
23
+ interactor = interactor_klass.new true
24
+ assert_equal :success, interactor.outcome
25
+ end
26
+
27
+ def test_reports_outoutput_for_pass
28
+ interactor = interactor_klass.new true
29
+ assert_equal [:item], interactor.output
30
+ end
31
+
32
+ def test_reports_outcome_as_failure_for_no_pass
33
+ interactor = interactor_klass.new false
34
+ assert_equal :failure, interactor.outcome
35
+ end
36
+ class Undefined < AllSystems::Interactor
37
+ def outcomes
38
+ []
39
+ end
40
+
41
+ def go!
42
+ report_created
43
+ end
44
+ end
45
+
46
+ def test_handles_undefined_outcomes
47
+ assert_raises AllSystems::UnknownOutcomeReportError do
48
+ Undefined.new().outcome
49
+ end
50
+ end
51
+
52
+ class Nonedefined < AllSystems::Interactor
53
+ def go!
54
+ report_created
55
+ end
56
+ end
57
+
58
+ def test_handles_nonedefined_outcomes
59
+ assert_raises AllSystems::UnknownOutcomeReportError do
60
+ Nonedefined.new().outcome
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,6 @@
1
+ require 'all_systems'
2
+ require 'minitest/autorun'
3
+ require 'minitest/reporters'
4
+
5
+ reporter_options = {color: true, slow_count: 5}
6
+ Minitest::Reporters.use! [Minitest::Reporters::DefaultReporter.new(reporter_options)]
data/usecase.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'all_systems/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "all_systems"
8
+ spec.version = AllSystems::VERSION
9
+ spec.authors = ["Peter Saxton"]
10
+ spec.email = ["peterhsaxton@gmail.com"]
11
+ spec.summary = %q{Simple usecase/interactor/service objects to encapsulate business logic}
12
+ spec.description = %q{An interactor encapsulates the action of specific business usecase. For example a `LogIn` or `CreatePost`. It executes this action by coordinating the interaction of over business objects in the system.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "minitest", "~> 5.4.3"
24
+ spec.add_development_dependency "minitest-reporters", "~> 1.0.6"
25
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: all_systems
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Peter Saxton
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 5.4.3
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 5.4.3
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest-reporters
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.0.6
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.0.6
69
+ description: An interactor encapsulates the action of specific business usecase. For
70
+ example a `LogIn` or `CreatePost`. It executes this action by coordinating the interaction
71
+ of over business objects in the system.
72
+ email:
73
+ - peterhsaxton@gmail.com
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - ".gitignore"
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - lib/all_systems.rb
84
+ - lib/all_systems/errors.rb
85
+ - lib/all_systems/interactor.rb
86
+ - lib/all_systems/version.rb
87
+ - test/interactor/error_test.rb
88
+ - test/interactor/invalid_outcomes_test.rb
89
+ - test/interactor/outcome_test.rb
90
+ - test/interactor/output_test.rb
91
+ - test/interactor/report_helper_test.rb
92
+ - test/test_config.rb
93
+ - usecase.gemspec
94
+ homepage: ''
95
+ licenses:
96
+ - MIT
97
+ metadata: {}
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubyforge_project:
114
+ rubygems_version: 2.4.6
115
+ signing_key:
116
+ specification_version: 4
117
+ summary: Simple usecase/interactor/service objects to encapsulate business logic
118
+ test_files:
119
+ - test/interactor/error_test.rb
120
+ - test/interactor/invalid_outcomes_test.rb
121
+ - test/interactor/outcome_test.rb
122
+ - test/interactor/output_test.rb
123
+ - test/interactor/report_helper_test.rb
124
+ - test/test_config.rb