simple_service 1.2.6 → 1.3.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 +4 -4
- data/README.md +27 -2
- data/lib/simple_service/commands/validates_commands_not_empty.rb +1 -1
- data/lib/simple_service/commands/validates_commands_properly_inherit.rb +1 -1
- data/lib/simple_service/commands/validates_expected_keys.rb +1 -1
- data/lib/simple_service/organizer.rb +5 -3
- data/lib/simple_service/service_base.rb +20 -4
- data/lib/simple_service/version.rb +1 -1
- data/spec/lib/organizer_spec.rb +38 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c3411c81d77a21d53355ecbf0e36e8e8ab775d7f
|
4
|
+
data.tar.gz: ab7e72e01db7d9f4b759f8c3a2e2b6e1a255016c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3ec8495a52be6cd7ffa5e6e8b3a8d29e85c32011540dd4f85e2444da22ade6451a5853af1ec58ec84837a04766bfe75bbf47c74d7a9ceb1ccfb6cd1ffdb5362
|
7
|
+
data.tar.gz: 6d5eb35ca7b7bb0d68f1009e0062f84cb924330887e1dafc33ca1e4e13d7f13757803a0bd583d93266530d4b8a39aa7755904b0c95b213a9655ee7526ea33608
|
data/README.md
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# SimpleService
|
2
2
|
|
3
|
+
[](http://badge.fury.io/rb/simple_service)
|
3
4
|
[](https://codeclimate.com/github/jspillers/simple_service)
|
4
5
|
[](https://codeclimate.com/github/jspillers/simple_service)
|
5
6
|
[](https://travis-ci.org/jspillers/simple_service)
|
7
|
+
<!---->
|
6
8
|
|
7
9
|
SimpleService gives you a way to organize service objects such that they adhere
|
8
10
|
to the single responsibility principle. Instead of writing large service objects
|
@@ -11,12 +13,14 @@ set of sequentially performed "Command" objects. Commands are very small classes
|
|
11
13
|
that perform exactly one task. When properly designed, these command
|
12
14
|
objects can be reused in multiple organizers minimizing code duplication.
|
13
15
|
|
14
|
-
When an organizer is instantiated a hash
|
15
|
-
is referred to as the context. The context hash is carried along throughout
|
16
|
+
When an organizer is instantiated a hash is passed in containing initial arguments.
|
17
|
+
This hash is referred to as the context. The context hash is carried along throughout
|
16
18
|
the sequence of command executions and modified by each command. After a
|
17
19
|
successful run, the keys specified are returned. If keys are not specified, the
|
18
20
|
entire context hash is returned.
|
19
21
|
|
22
|
+
# Setup
|
23
|
+
|
20
24
|
First, setup an Organizer class. An Organizer needs the following things defined:
|
21
25
|
|
22
26
|
* expects: keys that are required to be passed into initialize when an
|
@@ -86,6 +90,27 @@ class DoSomethingImportant < SimpleService::Command
|
|
86
90
|
end
|
87
91
|
```
|
88
92
|
|
93
|
+
Within any command you can call ```#failure!``` and then return in order to
|
94
|
+
abort execution of subsequent commands within the organizer.
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
class DemonstrateFailure < SimpleService::Command
|
98
|
+
|
99
|
+
expects :something
|
100
|
+
|
101
|
+
returns :good_stuff
|
102
|
+
|
103
|
+
def call
|
104
|
+
if good_stuff_happens
|
105
|
+
self.good_stuff = 'yeah, success!'
|
106
|
+
else
|
107
|
+
failure!('something not so good happened; no more commands should be called')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
```
|
113
|
+
|
89
114
|
## Usage
|
90
115
|
|
91
116
|
Using the service is straight forward - just instantiate it, passing in the
|
@@ -6,7 +6,7 @@ module SimpleService
|
|
6
6
|
|
7
7
|
attr_accessor :context
|
8
8
|
|
9
|
-
def initialize(context={})
|
9
|
+
def initialize(context = {})
|
10
10
|
@context = context
|
11
11
|
|
12
12
|
symbolize_context_keys
|
@@ -25,14 +25,16 @@ module SimpleService
|
|
25
25
|
def call
|
26
26
|
with_validation do |_commands|
|
27
27
|
_commands.each do |command|
|
28
|
-
|
28
|
+
break if context[:success] == false
|
29
|
+
new_context = command.new(context).call
|
30
|
+
@context.merge!(new_context)
|
29
31
|
end
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
33
35
|
# allow execution of the service from the class level for those
|
34
36
|
# that prefer that style
|
35
|
-
def self.call(context)
|
37
|
+
def self.call(context = {})
|
36
38
|
self.new(context).call
|
37
39
|
end
|
38
40
|
|
@@ -29,7 +29,7 @@ module SimpleService
|
|
29
29
|
# other method to return only specific context keys
|
30
30
|
define_method :call do
|
31
31
|
call_method.bind(self).call
|
32
|
-
|
32
|
+
return_context_with_success_status
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -40,6 +40,17 @@ module SimpleService
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
+
def return_context_with_success_status
|
44
|
+
_context = find_specified_return_keys
|
45
|
+
|
46
|
+
# only automatically set context[:success] on Organizers and only if its not already set
|
47
|
+
if !_context.has_key?(:success) && self.class.ancestors.include?(SimpleService::Organizer)
|
48
|
+
_context[:success] = true
|
49
|
+
end
|
50
|
+
|
51
|
+
_context
|
52
|
+
end
|
53
|
+
|
43
54
|
def find_specified_return_keys
|
44
55
|
if returns.nil? || returns.empty?
|
45
56
|
context
|
@@ -69,12 +80,17 @@ module SimpleService
|
|
69
80
|
self.class.instance_variable_get('@skip_validation')
|
70
81
|
end
|
71
82
|
|
72
|
-
def
|
73
|
-
(expects + returns).uniq
|
83
|
+
def all_context_keys
|
84
|
+
(expects + returns + ['message', 'success']).uniq
|
85
|
+
end
|
86
|
+
|
87
|
+
def failure!(message = nil)
|
88
|
+
context[:success] = false
|
89
|
+
context[:message] = message || 'There was a problem'
|
74
90
|
end
|
75
91
|
|
76
92
|
def define_getters_and_setters
|
77
|
-
|
93
|
+
all_context_keys.each do |key|
|
78
94
|
self.class.class_eval do
|
79
95
|
|
80
96
|
# getter
|
data/spec/lib/organizer_spec.rb
CHANGED
@@ -30,13 +30,13 @@ describe SimpleService::Organizer do
|
|
30
30
|
it 'returns the correct hash' do
|
31
31
|
expect(
|
32
32
|
TestOrganizer.new(foo: 'foo').call
|
33
|
-
).to eql(foo: 'foo', bar: 'bar', baz: 'baz')
|
33
|
+
).to eql(foo: 'foo', bar: 'bar', baz: 'baz', success: true)
|
34
34
|
end
|
35
35
|
|
36
36
|
it 'accepts string keys in context hash' do
|
37
37
|
expect(
|
38
38
|
TestOrganizer.new('foo' => 'foo').call
|
39
|
-
).to eql(foo: 'foo', bar: 'bar', baz: 'baz')
|
39
|
+
).to eql(foo: 'foo', bar: 'bar', baz: 'baz', success: true)
|
40
40
|
end
|
41
41
|
|
42
42
|
end
|
@@ -68,14 +68,14 @@ describe SimpleService::Organizer do
|
|
68
68
|
it 'returns the entire context' do
|
69
69
|
expect(
|
70
70
|
TestOrganizerTwo.new(foo: 'foo', extra: 'extra').call
|
71
|
-
).to eql(foo: 'foo', bar: 'bar', baz: 'baz', extra: 'extra')
|
71
|
+
).to eql(foo: 'foo', bar: 'bar', baz: 'baz', extra: 'extra', success: true)
|
72
72
|
end
|
73
73
|
|
74
74
|
end
|
75
75
|
|
76
76
|
end
|
77
77
|
|
78
|
-
|
78
|
+
context 'service using getters and setters' do
|
79
79
|
|
80
80
|
class GetterSetterCommand < SimpleService::Command
|
81
81
|
expects :foo, :bar
|
@@ -94,7 +94,40 @@ describe SimpleService::Organizer do
|
|
94
94
|
it 'returns the correct hash' do
|
95
95
|
expect(
|
96
96
|
GetterSetterOrganizer.new(foo: 'baz', bar: 'bar').call
|
97
|
-
).to eql({ baz: 'baz' })
|
97
|
+
).to eql({ baz: 'baz', success: true })
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'service with command that calls fail_and_return' do
|
103
|
+
|
104
|
+
class FailAndReturnErrorMessage < SimpleService::Command
|
105
|
+
def call
|
106
|
+
return failure!('something went wrong and we need to abort')
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class ShouldNotRun < SimpleService::Command
|
111
|
+
def call
|
112
|
+
raise 'should not have gotten here'
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
class FailAndReturn < SimpleService::Organizer
|
117
|
+
commands FailAndReturnErrorMessage, ShouldNotRun
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'returns a message' do
|
121
|
+
expect(FailAndReturn.call[:message]).to eql(
|
122
|
+
'something went wrong and we need to abort')
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'returns success as false' do
|
126
|
+
expect(FailAndReturn.call[:success]).to eql(false)
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'does not raise an exception' do
|
130
|
+
expect { FailAndReturn.call }.to_not raise_error
|
98
131
|
end
|
99
132
|
|
100
133
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_service
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jarrod Spillers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|