bbservices 2.0.0 → 3.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 48cb6bb977e6fad5a1efd70a3dadab0366860eaa84ac41749877acc06017ae2c
4
- data.tar.gz: 38a78f0ae7a47fe6f57a35724e55b9fc4e55131af57a222c099b5a1fb1d98095
3
+ metadata.gz: 662a72a39dbe2e481513c47eba00edcde5288c6018aea566c881c5834c4020ea
4
+ data.tar.gz: fdfb42ddcd57afa106896271602c3aa715ac5d5093835b289de48de868e0ff1a
5
5
  SHA512:
6
- metadata.gz: c2d40a76870f43ee2578c50fbf40411dafb76e6fe79aafe3cdbf9bc272b4b72852c6c5e8668bb7554ad23a09904742f140eaae3f7c934c243ee0c33c67bfbd12
7
- data.tar.gz: 1a45585761e068e611fe125c96b7386f7f1872047b610ae793da213698de60e025d9f0ed63514c26b1afbb96d64d045132f6b329335238a72a0054bece284030
6
+ metadata.gz: 95a00382d51a488d15de9a3260793966052a8de0a80b24cf1b7eb25902f27438c67b5b997349e3762081b02423d8431c27e2c112c36f898a0ac3d3761aa61e40
7
+ data.tar.gz: 2248179e4cd90ad84e6f1af0bcf5c9e8c705f5d5fcabb918c6f690a58073d4d736deb4f2f85e1887aa469975fb9b7fd51fadd1718c908eb085820e07fa557ce6
data/lib/bbservices.rb CHANGED
@@ -1,2 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'bbservices/service'
2
- require_relative 'bbservices/service_provider'
4
+ require_relative 'bbservices/service_chain'
5
+ require_relative 'bbservices/service_provider'
6
+
7
+ # The BBServices namespace.
8
+ module BBServices
9
+ def self.chain(params = {}, &block)
10
+ BBServices::ServiceChain.new.tap do |service_chain|
11
+ service_chain.chain(params, &block)
12
+ end
13
+ end
14
+ end
@@ -1,75 +1,84 @@
1
+ # frozen_string_literal: true
1
2
 
3
+ require_relative 'service_chain'
4
+
5
+ # The BBServices namespace.
2
6
  module BBServices
3
- ##
4
- # The base class for all services. Handles the basic run loop and general accessors
5
- class Service
6
- attr_reader :params, :object, :errors
7
+ # Error thrown when a Hash type isn't given
8
+ class ServiceHashTypeError < StandardError
9
+ def message
10
+ 'Params need to be a Hash'
11
+ end
12
+ end
7
13
 
8
- ##
9
- # Creates a new service class, then calls run
10
- def self.run(params = nil, &block)
11
- self.new(params).tap do |service|
12
- service.run(&block)
14
+ # The lightweight service object provided by BBServices.
15
+ class Service
16
+ attr_reader :params, :object, :error
17
+
18
+ class << self
19
+
20
+ # Creates the service instances and calls run upon said instance
21
+ # @param [Hash] params The params which are passed to the service
22
+ # @param [Block] block The block which will be called upon the service finishing running
23
+ # @return [BBServices.Service] returns the service instance
24
+ def run(params = {}, &block)
25
+ new(params).tap do |service|
26
+ service.run(&block)
27
+ end
13
28
  end
14
- end
15
29
 
16
- ##
17
- # Creates a new service class, then calls run!
18
- def self.run!(params = nil, &block)
19
- self.new(params).tap do |service|
20
- service.run!(&block)
30
+ # Creates the service instances and calls run! upon said instance
31
+ # @param [Hash] params The params which are passed to the service
32
+ # @param [Block] block The block which will be called upon the service finishing running
33
+ # @return [BBServices.Service] returns the service instance
34
+ def run!(params = {}, &block)
35
+ new(params).tap do |service|
36
+ service.run!(&block)
37
+ end
21
38
  end
22
- end
23
39
 
24
- ##
25
- # Sets the service class
26
- def self.service_class(klass)
27
- @service_class = klass
28
- end
40
+ # An alias to {BBServices::Service}'s run method
41
+ alias call run
42
+
43
+ # An alias to {BBServices::Service}'s run! method
44
+ alias call! run!
45
+
46
+ # Sets the service class on the Class. Please note this is an internal method.
47
+ # @param [Class] klass The class which will be set as the service_class
48
+ # @return [BBServices.Service] returns the service instance
49
+ def service_class(klass)
50
+ @service_class = klass
51
+ end
29
52
 
30
- ##
31
- # Gets the service class
32
- def self.get_service_class
33
- @service_class
53
+ # Gets the current service class
54
+ # @return [Class] returns the service class. Please note this is an internal method.
55
+ def internal_service_class
56
+ @service_class
57
+ end
34
58
  end
35
59
 
36
- def initialize(params = nil)
37
- ##
38
- # The object which will be assigned to the service
60
+ # Initializes the service with a hash of params
61
+ # @param [Hash] params The params which are passed to the service
62
+ def initialize(params = {})
39
63
  @object = nil
40
-
41
- ##
42
- # The state of success, was the service successful
43
64
  @successful = false
44
-
45
- ##
46
- # The state of the run, has the service being ran
47
65
  @ran = false
48
-
49
- ##
50
- # The errors which are returned by the service
51
- @errors = nil
52
-
53
- ##
54
- # The service class stored on the instance. This will override the
55
- # service class set statically
66
+ @error = nil
56
67
  @service_class = nil
57
68
 
58
- ##
59
- # The params passed to the resource
60
69
  @params = params
61
70
  end
62
71
 
63
- ##
64
- # This runs the safe version of the service. E.g. Will rescue on exception
65
- # and set the error attribute
72
+ # Runs the service using 'safe' execution. The @run variable will be set to true, initialize_service and run_service
73
+ # will then be called.
74
+ # @param [Block] block The block which will be called upon the service finishing running
75
+ # @return [BBServices.Service] returns the service instance
66
76
  def run(&block)
67
77
  set_ran
68
78
  begin
69
79
  initialize_service
70
- internal_validation
71
80
  run_service
72
- rescue StandardError => e
81
+ rescue => e
73
82
  set_successful(false)
74
83
  set_error(e)
75
84
  ensure
@@ -77,129 +86,192 @@ module BBServices
77
86
  end
78
87
  end
79
88
 
80
- ##
81
- # This runs the unsafe version of the service. E.g. Exceptions will be thrown
89
+ # Runs the service using 'unsafe' execution. The @run variable will be set to true,
90
+ # initialize_service and run_service will then be called.
91
+ # @param [Block] block The block which will be called upon the service finishing running
92
+ # @return [BBServices.Service] returns the service instance
82
93
  def run!(&block)
83
94
  set_ran
84
95
  begin
85
96
  initialize_service
86
- internal_validation
87
97
  run_service!
88
98
  call_block(&block)
89
- rescue StandardError => e
99
+ rescue => e
90
100
  set_successful(false)
91
101
  set_error(e)
92
102
  raise e
93
103
  end
94
104
  end
95
105
 
96
- def set_service_class(value)
97
- @service_class = value
106
+ # An alias to {BBServices::Service}'s run method
107
+ alias call run
108
+
109
+ # An alias to {BBServices::Service}'s run! method
110
+ alias call! run!
111
+
112
+ # Sets the service_class on the instance. This will override the self.class.internal_service_class.
113
+ # @param [Class] new_service_class The new service class.
114
+ def set_service_class(new_service_class)
115
+ @service_class = new_service_class
98
116
  end
99
117
 
100
- ##
101
- # Sets the service_class instance variable
102
- def service_class=(value)
103
- set_service_class(value)
118
+ # Sets the service_class on the instance. This will override the self.class.internal_service_class.
119
+ # @param [Class] new_service_class The new service class.
120
+ def service_class=(new_service_class)
121
+ set_service_class(new_service_class)
104
122
  end
105
123
 
106
- ##
107
- # Gets the service_class. This will go instance first, then static
124
+ # Gets the current service class. This will use @service_class if set, otherwise will fallback to
125
+ # self.class.internal_service_class.
126
+ # @return [Class] new_service_class The new service class.
108
127
  def service_class
109
- @service_class || self.class.get_service_class
128
+ @service_class ||= self.class.internal_service_class
110
129
  end
111
130
 
112
- def set_params(value)
113
- @params = value
131
+ # Sets the params variable (@params) on the service.
132
+ # @param [Hash] new_params The new params Hash.
133
+ def set_params(new_params)
134
+ raise BBServices::ServiceHashTypeError unless new_params.is_a?(Hash)
135
+
136
+ @params = new_params
114
137
  end
115
138
 
116
- def params=(value)
117
- set_params(value)
139
+ # Sets the params variable (@params) on the service.
140
+ # @param [Hash] new_params The new params Hash.
141
+ def params=(new_params)
142
+ set_params(new_params)
118
143
  end
119
144
 
145
+ # Gets a single param using a key
146
+ # @param [String/Symbol] key The key which is used to find the param
147
+ # @return [Hash] The param found using the key
120
148
  def param_for(key)
121
149
  param(key)
122
150
  end
123
151
 
152
+ # Gets a single param using a key
153
+ # @param [String/Symbol] key The key which is used to find the param
154
+ # @return [Hash] The param found using the key
124
155
  def param(key)
125
156
  @params[key] if @params
126
157
  end
127
158
 
159
+ # Gets the number of params
160
+ # @return [Number] The number of params
161
+ def number_of_params
162
+ @params ? @params.length : 0
163
+ end
164
+
165
+ # Returns true/false on if the service has been ran
166
+ # @return [Boolean] True/False value on if the service has been ran
128
167
  def ran?
129
168
  @ran
130
169
  end
131
170
 
171
+ # Returns true / false if the service has any params
172
+ # @return [Boolean] true/false if the service has any params
173
+ def params?
174
+ !!(@params && @params.length)
175
+ end
176
+
177
+ # An alias to {BBServices::Service}'s ran? method
178
+ alias run? ran?
179
+
180
+ # Returns true/false on if the service did succeed.
181
+ # @return [Boolean] true/false on if the service did succeed.
132
182
  def succeeded?
133
- (@successful && !errors?)
183
+ successful?
134
184
  end
135
185
 
186
+ # Returns true/false on if the service was successful.
187
+ # @return [Boolean] true/false on if the service was successful.
136
188
  def successful?
137
- (@successful && !errors?)
189
+ @successful
138
190
  end
139
191
 
192
+ # Returns true/false on if the service was unsuccessful. This will always be the inverse of successful?
193
+ # @return [Boolean] true/false on if the service failed.
140
194
  def failed?
141
195
  !succeeded?
142
196
  end
143
197
 
144
- def success(&block)
145
- call_block(&block) if succeeded?
198
+ # Calls the given block if the service was successful
199
+ def success
200
+ yield(self) if succeeded?
146
201
  end
147
202
 
148
- def failure(&block)
149
- call_block(&block) if failed?
203
+ # Calls the given block if the service failed
204
+ def failure
205
+ yield(self) if failed?
150
206
  end
151
207
 
152
- def errors?
153
- !!(@errors && @errors.length.positive?)
208
+ # Calls success on success?, failure on !success?
209
+ # @param [Proc] success The proc to be called upon a successful service
210
+ # @param [Proc] failure
211
+ # @return [Boolean] true/false if the service has any params
212
+ def on(success: proc {}, failure: proc {})
213
+ if successful?
214
+ success.call
215
+ else
216
+ failure.call
217
+ end
154
218
  end
155
219
 
156
- def params?
157
- !!@params
220
+ # Returns true / false if the service threw an error
221
+ # @return [Boolean] true/false on if an error has occurred
222
+ def error?
223
+ !!@error
158
224
  end
159
225
 
160
226
  protected
161
227
 
228
+ # Called upon run / run!, should be overridden in order to setup any variable
229
+ # initalization
162
230
  def initialize_service() end
163
231
 
232
+ # Called upon run, should be overridden in order to setup any variable
233
+ # initalization
164
234
  def run_service
165
235
  set_successful
166
236
  set_object(nil)
167
237
  end
168
238
 
239
+ # Called upon run, should be overridden in order to setup any variable
240
+ # initalization
169
241
  def run_service!
170
242
  set_successful
171
243
  set_object(nil)
172
244
  end
173
245
 
246
+ # Sets the @object instance variable, the object will be accessible via the .object property outside of the service
247
+ # @param obj The object which will be assigned to the @object instance variable
174
248
  def set_object(obj)
175
249
  @object = obj
176
250
  end
177
251
 
178
- def set_error(error)
179
- set_errors([]) unless @errors
180
- @errors << error
181
- end
252
+ private
182
253
 
183
- def set_errors(errors)
184
- @errors = errors
254
+ # Sets the internal @ran instance variable
255
+ # @param [Boolean] ran True / False if the service has been ran
256
+ def set_ran(ran = true)
257
+ @ran = ran
185
258
  end
186
259
 
260
+ # Sets the internal @successful instance variable
261
+ # @param [Boolean] successful True / False if the service has been successful
187
262
  def set_successful(successful = true)
188
263
  @successful = successful
189
264
  end
190
265
 
191
- def set_ran(ran = true)
192
- @ran = ran
193
- end
194
-
195
- private
196
-
197
- def internal_validation
198
- set_params({}) unless params?
266
+ # Sets the internal @error instance variable
267
+ # @param [Error] error The error to be assigned
268
+ def set_error(error)
269
+ @error = error
199
270
  end
200
271
 
272
+ # Calls the block which has been passed
201
273
  def call_block
202
274
  yield(self) if block_given?
203
275
  end
204
276
  end
205
- end
277
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The BBServices namespace.
4
+ module BBServices
5
+ # Container for chained services.
6
+ class ServiceChain
7
+
8
+ attr_reader :services
9
+
10
+ # Initializes the ServiceChain
11
+ def initialize
12
+ @services = []
13
+ @successful = true
14
+ end
15
+
16
+ def chain(params = {})
17
+ tap do |_service_chain|
18
+ if @successful
19
+ service = yield(params, self, previous_service)
20
+ process_service(service)
21
+ end
22
+ end
23
+ end
24
+
25
+ def previous_service
26
+ return nil unless @services.length
27
+
28
+ @services.last
29
+ end
30
+
31
+ # Returns true/false on if the chain did succeed.
32
+ # @return [Boolean] true/false on if the chain did succeed.
33
+ def succeeded?
34
+ successful?
35
+ end
36
+
37
+ # Returns true/false on if the chain was successful.
38
+ # @return [Boolean] true/false on if the chain was successful.
39
+ def successful?
40
+ @successful
41
+ end
42
+
43
+ # Returns true/false on if the chain was unsuccessful. This will always be the inverse of successful?
44
+ # @return [Boolean] true/false on if the chain failed.
45
+ def failed?
46
+ !succeeded?
47
+ end
48
+
49
+ # Calls the given block if the chain was successful
50
+ def success
51
+ yield(self) if succeeded?
52
+ end
53
+
54
+ # Calls the given block if the chain failed
55
+ def failure
56
+ yield(self) if failed?
57
+ end
58
+
59
+ # Calls success on success?, failure on !success?
60
+ # @param [Proc] success The proc to be called upon a successful chain
61
+ # @param [Proc] failure
62
+ # @return [Boolean] true/false if the chain has any params
63
+ def on(success: proc {}, failure: proc {})
64
+ if successful?
65
+ success.call
66
+ else
67
+ failure.call
68
+ end
69
+ end
70
+
71
+ # Returns true / false if the chain threw an error
72
+ # @return [Boolean] true/false on if an error has occurred
73
+ def error?
74
+ previous_service ? previous_service.error? : false
75
+ end
76
+
77
+ def error
78
+ previous_service ? previous_service.error : nil
79
+ end
80
+
81
+ private
82
+
83
+ def process_service(service)
84
+ if service.is_a?(BBServices::Service)
85
+ @services << service
86
+ @successful = service.successful?
87
+ else
88
+ @successful = !!service
89
+ end
90
+ end
91
+ end
92
+ end
@@ -1,42 +1,64 @@
1
+ # frozen_string_literal: true
1
2
 
2
- module BBServices
3
- ##
4
- #
3
+ # The BBServices namespace.
4
+ module BBServices
5
+ # Module to allow external classes (Namely controllers) to interact with underlying service objects
5
6
  module ServiceProvider
6
7
  def self.included(base)
7
- base.extend ClassMethods
8
8
  base.class_eval do
9
-
10
- ##
11
- # Creates a brand new service of a given type
12
- def service(service_type, service_params = {})
13
- service_type.new.tap do |service|
14
- service.set_params(service_params)
9
+ # Creates a service with a given type and params, the service instance will not be ran.
10
+ # Sets the @service instance on the object which includes this provider.
11
+ # @param [Class] service_type The class which should be instanciated
12
+ # @param [Hash] service_params The params which will be passed to the service
13
+ # @return [{BBServices::Service}] The service type instance
14
+ def create_service(service_type, service_params = {})
15
+ @service = service_type.new.tap do |new_service|
16
+ new_service.set_params(service_params)
15
17
  end
16
18
  end
17
19
 
18
- ##
19
- # Creates and runs a brand new service using the safe method
20
+ # Creates a service with a given type and params, the service instance will be ran using the run method.
21
+ # Sets the @service instance on the object which includes this provider.
22
+ # @param [Class] service_type The class which should be instanciated
23
+ # @param [Hash] service_params The params which will be passed to the service
24
+ # @param [Block] block The block to call upon running of the service is complete
25
+ # @return [{BBServices::Service}] The service type instance
20
26
  def run_service(service_type, service_params = {}, &block)
21
- service(service_type, service_params).tap do |service|
22
- service.set_service_class(service_type)
27
+ create_service(service_type, service_params).tap do |service|
28
+ service.service_class = service_type
23
29
  service.run(&block)
24
30
  end
25
31
  end
26
32
 
27
- ##
28
- # Creates and runs a brand new service using the unsafe method
33
+ # Creates a service with a given type and params, the service instance will be ran using the run! method.
34
+ # Sets the @service instance on the object which includes this provider.
35
+ # @param [Class] service_type The class which should be instanciated
36
+ # @param [Hash] service_params The params which will be passed to the service
37
+ # @param [Block] block The block to call upon running of the service is complete
38
+ # @return [{BBServices::Service}] The service type instance
29
39
  def run_service!(service_type, service_params = {}, &block)
30
- service(service_type, service_params).tap do |service|
31
- service.set_service_class(service_type)
40
+ create_service(service_type, service_params).tap do |service|
41
+ service.service_class = service_type
32
42
  service.run!(&block)
33
43
  end
34
44
  end
35
- end
36
- end
37
45
 
38
- module ClassMethods
39
-
46
+ def chain_services(params = {}, &block)
47
+ @service_chain = BBServices.chain(params, &block)
48
+ end
49
+
50
+ # Returns the {BBService::Service} instance currently stored within @service
51
+ # @return [{BBService::Service}] The current service
52
+ def service
53
+ @service
54
+ end
55
+
56
+ # Returns the {BBServices::ServiceChain} instance currently stored within @service_chain
57
+ # @return [{BBServices::ServiceChain}] The current service
58
+ def service_chain
59
+ @service_chain
60
+ end
61
+ end
40
62
  end
41
63
  end
42
- end
64
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bbservices
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stuart Farnaby, Big Bear Studios
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-10 00:00:00.000000000 Z
11
+ date: 2021-06-04 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: guard-rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 4.7.3
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 4.7.3
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rspec
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -30,14 +44,14 @@ dependencies:
30
44
  requirements:
31
45
  - - '='
32
46
  - !ruby/object:Gem::Version
33
- version: 0.86.0
47
+ version: '1.13'
34
48
  type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - '='
39
53
  - !ruby/object:Gem::Version
40
- version: 0.86.0
54
+ version: '1.13'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: simplecov
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +66,20 @@ dependencies:
52
66
  - - '='
53
67
  - !ruby/object:Gem::Version
54
68
  version: 0.18.5
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.8.7.6
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.8.7.6
55
83
  description:
56
84
  email:
57
85
  executables: []
@@ -60,6 +88,7 @@ extra_rdoc_files: []
60
88
  files:
61
89
  - lib/bbservices.rb
62
90
  - lib/bbservices/service.rb
91
+ - lib/bbservices/service_chain.rb
63
92
  - lib/bbservices/service_provider.rb
64
93
  homepage: https://gitlab.com/big-bear-studios-open-source/bbservices
65
94
  licenses:
@@ -73,7 +102,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
73
102
  requirements:
74
103
  - - ">="
75
104
  - !ruby/object:Gem::Version
76
- version: '0'
105
+ version: '2.5'
77
106
  required_rubygems_version: !ruby/object:Gem::Requirement
78
107
  requirements:
79
108
  - - ">="