simple_service 1.2.6 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 515fadc80305add45e86b396802b338cede2aa06
4
- data.tar.gz: 841835535e8881c65fa145ae53eecd09bc33b89b
3
+ metadata.gz: c3411c81d77a21d53355ecbf0e36e8e8ab775d7f
4
+ data.tar.gz: ab7e72e01db7d9f4b759f8c3a2e2b6e1a255016c
5
5
  SHA512:
6
- metadata.gz: 5b0c5dd85db59e62815ecec3ea749d4f81d0638f10e335da322576613626c8a7cd12a2815d7eeda6c39ee27b4dc43bee0d9c41910075de319a6a09a7053552ac
7
- data.tar.gz: 2cfc971c8db2575311a893e53cce3f4aca902687eafcb7e68924bee36e8c22a30c9cfb6a85891420dbb3a2f57261cc57660e9a723a1fa46ce4281574f5f70e46
6
+ metadata.gz: a3ec8495a52be6cd7ffa5e6e8b3a8d29e85c32011540dd4f85e2444da22ade6451a5853af1ec58ec84837a04766bfe75bbf47c74d7a9ceb1ccfb6cd1ffdb5362
7
+ data.tar.gz: 6d5eb35ca7b7bb0d68f1009e0062f84cb924330887e1dafc33ca1e4e13d7f13757803a0bd583d93266530d4b8a39aa7755904b0c95b213a9655ee7526ea33608
data/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # SimpleService
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/simple_service.svg)](http://badge.fury.io/rb/simple_service)
3
4
  [![Code Climate](https://codeclimate.com/github/jspillers/simple_service/badges/gpa.svg)](https://codeclimate.com/github/jspillers/simple_service)
4
5
  [![Test Coverage](https://codeclimate.com/github/jspillers/simple_service/badges/coverage.svg)](https://codeclimate.com/github/jspillers/simple_service)
5
6
  [![Build Status](https://travis-ci.org/jspillers/simple_service.svg?branch=master)](https://travis-ci.org/jspillers/simple_service)
7
+ <!--![](http://ruby-gem-downloads-badge.herokuapp.com/jspillers/simple_service)-->
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 of arguments is passed in. This 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
@@ -3,7 +3,7 @@ module SimpleService
3
3
 
4
4
  expects :provided_commands
5
5
 
6
- skip_validation true
6
+ skip_validation true # prevent infinite loop
7
7
 
8
8
  def call
9
9
  if provided_commands.nil? || provided_commands.empty?
@@ -3,7 +3,7 @@ module SimpleService
3
3
 
4
4
  expects :provided_commands
5
5
 
6
- skip_validation true
6
+ skip_validation true # prevent infinite loop
7
7
 
8
8
  def call
9
9
  # valid commands inherit from Command and do not inherit from service
@@ -3,7 +3,7 @@ module SimpleService
3
3
 
4
4
  expects :expected_keys, :provided_keys
5
5
 
6
- skip_validation true
6
+ skip_validation true # prevent infinite loop
7
7
 
8
8
  def call
9
9
  arguments_not_included = expected_keys.to_a - provided_keys.to_a
@@ -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
- @context.merge!(command.new(context).call)
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
- find_specified_return_keys
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 all_specified_context_keys
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
- all_specified_context_keys.each do |key|
93
+ all_context_keys.each do |key|
78
94
  self.class.class_eval do
79
95
 
80
96
  # getter
@@ -1,3 +1,3 @@
1
1
  module SimpleService
2
- VERSION = '1.2.6'
2
+ VERSION = '1.3.0'
3
3
  end
@@ -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
- describe 'service using getters and setters' do
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.2.6
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-04-10 00:00:00.000000000 Z
11
+ date: 2015-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler