cuprum 0.8.0 → 0.9.0.beta.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
- SHA1:
3
- metadata.gz: cafecaeff8b2c0209616cd9303613d88723c2477
4
- data.tar.gz: b4d1c2cdde687815ac835631c460a45d15a3306d
2
+ SHA256:
3
+ metadata.gz: 92d562710780dafcd20a5114fea623303dde6c22f7fbb2588eae26fd10adb419
4
+ data.tar.gz: 5a0c7d60b320673d3816b63b7480d84f4fa062bd52efb3b6ccca6de5237778a1
5
5
  SHA512:
6
- metadata.gz: f465ecb20dd65d5e835f6f506bbaca272e39637a5b127fac31929fef88a880069ed8b7f86802b207b01b767de952d641a688344dfabd8b1d4347d904daf926d7
7
- data.tar.gz: be12f0a8d8be45ba1aabc854b48be53be13e2716d39e1c48fecae038b99019880c19686fd96bb1d1ff04272400650723df47b789ebe48b60da1e6ba844175f3a
6
+ metadata.gz: 147d1581adb612e620a629429a7207f84a7e15a6224da5045ef30a9f270aa72ae2b9a3332221054ee902a205c1d60224d31eec998450d45bb68b335b10d5c255
7
+ data.tar.gz: 2db46aea35210874659ae9e69df64574d1f0e89e600937f6b20d45c56222c656477e663b722069b89fbe3d97d663189e7edb79776d72a67dcca3e8bdb6bd7607
@@ -1,5 +1,46 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.9.0
4
+
5
+ The "'Tis Not Too Late To Seek A Newer World" Update
6
+
7
+ Major refactoring of Command processing and the Result object. This update is **not** backwards compatible.
8
+
9
+ ### Commands
10
+
11
+ Removed the `#success` and `#failure` chaining helpers.
12
+
13
+ Permanently removed the deprecated ResultHelpers mixin.
14
+
15
+ ### Errors
16
+
17
+ Added `Cuprum::Error`, which encapsulates the failure state of a result. It is *recommended*, but not required, that when creating a failing Result, the `:error` property be set to an instance of `Cuprum::Error`.
18
+
19
+ ### Results
20
+
21
+ Results are now nominally immutable objects. All mutator methods have been removed, including `#failure!`, `#success!`, and `#update`. The `#empty?` predicate has also been removed.
22
+
23
+ Updated the constructor to take the following keyword arguments: `:value`, `:error`, and `:status`.
24
+
25
+ - The status can now be overridden on a new Result by passing in the `:status`.
26
+ - Resolves an issue when attempting to instantiate a result with a Hash value.
27
+ - *Note:* The value must now be passed in as a keyword.
28
+ - *Note:* The `:errors` keyword has been renamed to `:error`.
29
+
30
+ Removed the `:halted` status.
31
+
32
+ ### Other Changes
33
+
34
+ Removed the `Cuprum#warn` functionality.
35
+
36
+ ### Upgrade Notes
37
+
38
+ Anywhere a new `Cuprum::Result` is created directly, update the arguments to match the new `value:` and `error:` keywords.
39
+
40
+ Anywhere the `#result` is referenced inside a command, instead return the desired value directly, or return a result with the desired error.
41
+
42
+ Anywhere a command is chained with the `#success` or `#failure` shorthand, use the full `chain(on: :success)` or `chain(on: :failure)` format.
43
+
3
44
  ## 0.8.0
4
45
 
5
46
  The "We Have The Technology" Update.
@@ -2,22 +2,26 @@
2
2
 
3
3
  ## Version 0.9.0
4
4
 
5
- The "Second Star To The Right" Update
6
-
7
- ### Actions
8
-
9
- #### LifecycleHooks
10
-
11
- - :before, :after hooks
12
- - NOT included in Command by default
5
+ The "'Tis Not Too Late To Seek A Newer World" Update
13
6
 
14
7
  ## Version 0.10.0
15
8
 
16
- 'The "Out Of Context Problem" Update'
9
+ The "One Small Step" Update
17
10
 
18
11
  ### Commands
19
12
 
20
- - #context object
13
+ - Implement #<<, #>> composition methods.
14
+ - Calls commands in order passing values.
15
+ - Return Result early on Failure (or not Success), otherwise final Result.
16
+ - Implement #step method (used in #process).
17
+ - Called with command (block? method?) that returns a Result.
18
+ - Raise (and catch) exception on non-success Result (test custom status?)
19
+ - Otherwise return Result#value.
20
+
21
+ ### Matcher
22
+
23
+ - Handle success(), failure(), failure(SomeError) cases.
24
+ - Custom matcher to handle additional cases - halted, pending, etc?
21
25
 
22
26
  ## Version 1.0.0
23
27
 
data/README.md CHANGED
@@ -6,7 +6,8 @@ It defines the following concepts:
6
6
 
7
7
  - [Commands](#label-Commands) - A function-like object that responds to `#call` and returns a `Result`.
8
8
  - [Operations](#label-Operations) - A stateful `Command` that wraps and delegates to its most recent `Result`.
9
- - [Results](#label-Results) - A data object with a `#value`, an `#errors` object, and `#success?` and `#failure?` status methods.
9
+ - [Results](#label-Results) - An immutable data object with a status (either `:success` or `:failure`), and either a `#value` or an `#error` object.
10
+ - [Errors](#label-Errors) - Encapsulates a failure state of a command.
10
11
 
11
12
  ## About
12
13
 
@@ -41,7 +42,7 @@ Documentation is generated using [YARD](https://yardoc.org/), and can be generat
41
42
 
42
43
  ### License
43
44
 
44
- Copyright (c) 2017 Rob Smith
45
+ Copyright (c) 2019 Rob Smith
45
46
 
46
47
  Cuprum is released under the [MIT License](https://opensource.org/licenses/MIT).
47
48
 
@@ -63,9 +64,9 @@ Hi, I'm Rob Smith, a Ruby Engineer and the developer of this library. I use thes
63
64
 
64
65
  require 'cuprum'
65
66
 
66
- Commands are the core feature of Cuprum. In a nutshell, each Cuprum::Command is a functional object that encapsulates a business logic operation. A Command provides a consistent interface and tracking of result value and status. This minimizes boilerplate and allows for interchangeability between different implementations or strategies for managing your data and processes.
67
+ Commands are the core feature of Cuprum. In a nutshell, each `Cuprum::Command` is a functional object that encapsulates a business logic operation. A Command provides a consistent interface and tracking of result value and status. This minimizes boilerplate and allows for interchangeability between different implementations or strategies for managing your data and processes.
67
68
 
68
- Each Command implements a `#call` method that wraps your defined business logic and returns an instance of Cuprum::Result. The result wraps the returned data (with the `#value` method), any `#errors` generated when running the Command, and the overall status with the `#success?` and `#failure` methods. For more details about Cuprum::Result, [see below](#label-Results).
69
+ Each Command implements a `#call` method that wraps your defined business logic and returns an instance of `Cuprum::Result`. The result has a status (either `:success` or `:failure`), and may have a `#value` and/or an `#error` object. For more details about Cuprum::Result, [see below](#label-Results).
69
70
 
70
71
  [Class Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum%2FCommand)
71
72
 
@@ -77,12 +78,13 @@ The recommended way to define commands is to create a subclass of `Cuprum::Comma
77
78
  class BuildBookCommand < Cuprum::Command
78
79
  def process attributes
79
80
  Book.new(attributes)
80
- end # method process
81
- end # class
81
+ end
82
+ end
82
83
 
83
84
  command = BuildPostCommand.new
84
- result = command.call(:title => 'The Hobbit')
85
- result.class #=> Cuprum::Result
85
+ result = command.call(title: 'The Hobbit')
86
+ result.class #=> Cuprum::Result
87
+ result.success? #=> true
86
88
 
87
89
  book = result.value
88
90
  book.class #=> Book
@@ -97,23 +99,30 @@ Because a command is just a Ruby object, we can also pass values to the construc
97
99
  class SaveBookCommand < Cuprum::Command
98
100
  def initialize repository
99
101
  @repository = repository
100
- end # constructor
102
+ end
101
103
 
102
104
  def process book
103
- @repository.persist(book)
104
- end # method process
105
- end # class
105
+ if @repository.persist(book)
106
+ success(book)
107
+ else
108
+ failure('unable to save book')
109
+ end
110
+ end
111
+ end
106
112
 
107
113
  books = [
108
- Book.new(:title => 'The Fellowship of the Ring'),
109
- Book.new(:title => 'The Two Towers'),
110
- Book.new(:title => 'The Return of the King')
114
+ Book.new(title: 'The Fellowship of the Ring'),
115
+ Book.new(title: 'The Two Towers'),
116
+ Book.new(title: 'The Return of the King')
111
117
  ]
112
118
  command = SaveBookCommand.new(books_repository)
113
119
  books.each { |book| command.call(book) }
114
120
  ```
115
121
 
116
- Here, we are reusing the same command three times, rather than creating a new save command for each book. Each book is persisted to the `books_repository`. This is also an example of how using commands can simplify code - notice that nothing about the `SaveBookCommand` is specific to the `Book` model. Thus, we could refactor this into a generic `SaveModelCommand`.
122
+ Here, we are defining a command that might fail - maybe the database is unavailable, or there's a constraint that is violated by the inserted attributes. If the call to `#persist` succeeds, we're returning a Result with a status of `:success` and the value set to the persisted book.
123
+ Conversely, if the call to `#persist` fails, we're returning a Result with a status of `:failure` and a custom error message. Since the `#process` method returns a Result, it is returned directly by `#call`.
124
+
125
+ Note also that we are reusing the same command three times, rather than creating a new save command for each book. Each book is persisted to the `books_repository`. This is also an example of how using commands can simplify code - notice that nothing about the `SaveBookCommand` is specific to the `Book` model. Thus, we could refactor this into a generic `SaveModelCommand`.
117
126
 
118
127
  A command can also be defined by passing block to `Cuprum::Command.new`.
119
128
 
@@ -136,9 +145,9 @@ Commands defined using `Cuprum::Command.new` are quick to use, but more difficul
136
145
 
137
146
  Calling the `#call` method on a `Cuprum::Command` instance will always return an instance of `Cuprum::Result`. The result's `#value` property is determined by the object returned by the `#process` method (if the command is defined as a class) or the block (if the command is defined by passing a block to `Cuprum::Command.new`).
138
147
 
139
- The `#value` depends on whether or not the returned object is a result or is compatible with the result interface. Specifically, any object that responds to the methods `#to_result`, `#value`, and `#success?` is considered to be a result.
148
+ The `#value` depends on whether or not the returned object is a result or is compatible with the result interface. Specifically, any object that responds to the method `#to_cuprum_result` is considered to be a result.
140
149
 
141
- If the object returned is **not** a result, then the `#value` of the returned result is set to the object.
150
+ If the object returned by `#process` is **not** a result, then the `#value` of the returned result is set to the object.
142
151
 
143
152
  ```ruby
144
153
  command = Cuprum::Command.new { 'Greetings, programs!' }
@@ -147,46 +156,18 @@ result.class #=> Cuprum::Result
147
156
  result.value #=> 'Greetings, programs!'
148
157
  ```
149
158
 
150
- If the object returned is the command's own result object, then the `#value` of the returned result is unchanged. For convenience, methods to set the result status or mark the result as halted will return the result.
159
+ If the object returned by `#process` is a result object, then result is returned directly.
151
160
 
152
161
  ```ruby
153
- command = Cuprum::Command.new { result.failure! }
162
+ command = Cuprum::Command.new { Cuprum::Result.new(value: 'Greetings, programs!') }
154
163
  result = command.call
155
- result.class #=> Cuprum::Result
156
- result.value #=> nil
157
- result.success? #=> false
158
- ```
159
-
160
- If the object returned is another result or compatible object, then `#call` will call the `#to_result` method on the result and return the resulting object.
161
-
162
- ```ruby
163
- command = Cuprum::Command.new { |value| Cuprum::Result.new(value) }
164
- result = command.call('Greetings, starfighter!')
165
164
  result.class #=> Cuprum::Result
166
- result.value #=> 'Greetings, starfighter!'
167
- ```
168
-
169
- In some cases, returning a result directly will discard information on the command's own result object. When this occurs, Cuprum will display a warning.
170
-
171
- ```ruby
172
- command =
173
- Cuprum::Command.new do
174
- result.errors << 'Oops! We are throwing away this result.'
175
-
176
- Cuprum::Result.new
177
- end
178
-
179
- #=> This calls Kernel#warn with a warning message.
180
- result = command.call
181
- result.class #=> Cuprum::Result
182
- result.value #=> nil
183
- result.success? #=> true
184
- result.errors #=> []
165
+ result.value #=> 'Greetings, programs!'
185
166
  ```
186
167
 
187
168
  #### Success, Failure, and Errors
188
169
 
189
- Whether defined with a block or in the `#process` method, the Command implementation can access an `#errors` object while in the `#call` method. Any errors added to the errors object will be exposed by the `#errors` method on the result object.
170
+ Each Result has a status, either `:success` or `:failure`. A Result will have a status of `:failure` when it was created with an error object. Otherwise, a Result will have a status of `:success`. Returning a failing Result from a Command indicates that something went wrong while executing the Command.
190
171
 
191
172
  ```ruby
192
173
  class PublishBookCommand < Cuprum::Command
@@ -194,40 +175,38 @@ class PublishBookCommand < Cuprum::Command
194
175
 
195
176
  def process book
196
177
  if book.cover.nil?
197
- errors << 'This book does not have a cover.'
198
-
199
- return
200
- end # if
178
+ return Cuprum::Result.new(error: 'This book does not have a cover.')
179
+ end
201
180
 
202
181
  book.published = true
203
182
 
204
183
  book
205
- end # method process
206
- end # class
184
+ end
185
+ end
207
186
  ```
208
187
 
209
- In addition, the result object defines `#success?` and `#failure?` predicates. If the result has no errors, then `#success?` will return true and `#failure?` will return false.
188
+ In addition, the result object defines `#success?` and `#failure?` predicates.
210
189
 
211
190
  ```ruby
212
- book = Book.new(:title => 'The Silmarillion', :cover => Cover.new)
191
+ book = Book.new(title: 'The Silmarillion', cover: Cover.new)
213
192
  book.published? #=> false
214
193
 
215
194
  result = PublishBookCommand.new.call(book)
216
- result.errors #=> []
195
+ result.error #=> nil
217
196
  result.success? #=> true
218
197
  result.failure? #=> false
219
198
  result.value #=> book
220
199
  book.published? #=> true
221
200
  ```
222
201
 
223
- If the result does have errors, `#success?` will return false and `#failure?` will return true.
202
+ If the result does have an error, `#success?` will return false and `#failure?` will return true.
224
203
 
225
204
  ```ruby
226
- book = Book.new(:title => 'The Silmarillion', :cover => nil)
205
+ book = Book.new(title: 'The Silmarillion', cover: nil)
227
206
  book.published? #=> false
228
207
 
229
208
  result = PublishBookCommand.new.call(book)
230
- result.errors #=> ['This book does not have a cover.']
209
+ result.error #=> 'This book does not have a cover.'
231
210
  result.success? #=> false
232
211
  result.failure? #=> true
233
212
  result.value #=> book
@@ -248,7 +227,7 @@ add_command = Cuprum::Command.new do |addend, i|
248
227
  addend.times { i = increment_command(i).value }
249
228
 
250
229
  i
251
- end # command
230
+ end
252
231
 
253
232
  add_command.call(1, 1).value #=> 2
254
233
  add_command.call(1, 2).value #=> 3
@@ -274,8 +253,12 @@ class AddCommand < Cuprum::Command
274
253
 
275
254
  private
276
255
 
256
+ def increment_command
257
+ @increment_command ||= IncrementCommand.new
258
+ end
259
+
277
260
  def process i
278
- addend.times { i = IncrementCommand.new.call(i).value }
261
+ addend.times { i = increment_command.call(i).value }
279
262
 
280
263
  i
281
264
  end
@@ -335,9 +318,7 @@ second_command.call #=> Outputs 'First command!' then 'Second command!'.
335
318
  first_command.call #=> Outputs 'First command!' to STDOUT.
336
319
  ```
337
320
 
338
- When a chained command is called, the original command is called with whatever parameters are passed in to the `#call` method, and the command executes the `#process` method as normal, generating a `Cuprum::Result` and assigning it a value and optionally errors or a status. Rather than returning this result, however, it is passed on to the next command in the chain. In the context of a chained command, this means two things.
339
-
340
- First, the next command is called. If the next command does not take any arguments, it is not passed any arguments. If the next command takes one or more arguments, it is passed the `#value` of that previous result.
321
+ When a chained command is called, the original command is called with whatever parameters are passed in to the `#call` method, and the command executes the `#process` method as normal. Rather than returning the result, however, the next command in the chain is called. If the next command does not take any arguments, it is not passed any arguments. If the next command takes one or more arguments, it is passed the `#value` of that previous result. When the final command in the chain is called, that result is returned.
341
322
 
342
323
  ```ruby
343
324
  double_command = Cuprum::Command.new { |i| 2 * i }
@@ -360,87 +341,38 @@ result.class #=> Cuprum::Result
360
341
  result.value #=> 25
361
342
  ```
362
343
 
363
- Second, the previous result is set as the result of the next command (before it is evaluated). This makes it available to the next command during execution as the `#result` method, and makes available the value, errors, and status of the previous command (and avoids unnecessary object allocation). The value of the result will be updated to reflect the return value of the next command execution.
364
-
365
- ```ruby
366
- validate_command =
367
- Cuprum::Command.new do |object|
368
- result.errors << 'Object is invalid!' unless object.valid?
369
-
370
- object
371
- end
372
- persist_command =
373
- Cuprum::Command.new do |object|
374
- object.save if result.success?
375
-
376
- object
377
- end
378
- chained_command = validate_command.chain(persist_command)
379
-
380
- # First, validate_command is called with a valid object. This creates a result
381
- # with no errors and whose value is the valid object.
382
- #
383
- # Then, persist_command is called with the object, and its result is assigned to
384
- # the previous result. Since there are no errors on the result, the object is
385
- # saved. Finally, the value of the result is set to the object, and the result
386
- # is returned.
387
- result = chained_command.call(a_valid_object) #=> Saves the object.
388
- result.value #=> a_valid_object
389
- result.errors #=> []
390
- a_valid_object.persisted? #=> true
391
-
392
- # First, validate_command is called with an invalid object. This creates a
393
- # result whose value is the invalid object, and with errors 'Object is
394
- # invalid!'.
395
- #
396
- # Then, persist_command is called with the object, and its result is assigned to
397
- # the previous result. Since the result has an error, the object is not saved.
398
- # Finally, the value of the result is set to the object, and the result
399
- # is returned.
400
- result = chained_command.call(an_invalid_object) #=> Does not save the object.
401
- result.value #=> an_invalid_object
402
- result.errors #=> ['Object is invalid!']
403
- an_invalid_object.persisted? #=> false
404
- ```
405
-
406
344
  #### Conditional Chaining
407
345
 
408
- The `#chain` method can be passed an optional `:on => value` keyword. This keyword determines whether or not the chained command will execute, based on the previous result status. Possible values are `:success`, `:failure`, `:always`, or `nil`. The default value is `nil`.
409
-
410
- If the `:on` keyword is omitted, the chained command will always be executed after the previous command unless the result is halted (see [Halting A Command Chain](#label-Commands))
346
+ The `#chain` method can be passed an optional `on: value` keyword. This keyword determines whether or not the chained command will execute, based on the previous result status. Possible values are `:success`, `:failure`, `:always`, or `nil`. The default value is `nil`.
411
347
 
412
- If the command is chained with `:on => :success`, then the chained command will only execute if the previous result is passing, e.g. the `#success?` method returns true and the command is not halted. A result is passing if there are no errors, or if the status is set to `:success`.
348
+ If the command is chained with `on: :always`, or if the `:on` keyword is omitted, the chained command will always be executed after the previous command.
413
349
 
414
- If the command is chained with `:on => :failure`, then the chained command will only execute if the previous result is failing, e.g. the `#success?` method returns false and the command is not halted. A result is failing if the errors object is not empty, or if the status is set to `:failure`.
350
+ If the command is chained with `on: :success`, then the chained command will only execute if the previous result is passing, e.g. the `#success?` method returns true. A result is passing if there is no `#error`, or if the status is set to `:success`.
415
351
 
416
- If the command is chained with `:on => always`, then the chained command will always be executed, even if the previous result is halted.
352
+ If the command is chained with `on: :failure`, then the chained command will only execute if the previous result is failing, e.g. the `#success?` method returns false. A result is failing if there is an `#error`, or if the status is set to `:failure`.
417
353
 
418
354
  ```ruby
419
355
  find_command =
420
356
  Cuprum::Command.new do |attributes|
421
- book = Book.where(:id => attributes[:id]).first
357
+ book = Book.where(id: attributes[:id]).first
422
358
 
423
- result.errors << 'Book not found' unless book
359
+ return book if book
424
360
 
425
- book
361
+ Cuprum::Result.new(error: 'Book not found')
426
362
  end
427
363
  create_command =
428
364
  Cuprum::Command.new do |attributes|
429
365
  book = Book.new(attributes)
430
366
 
431
- if book.save
432
- result.success!
433
- else
434
- book.errors.full_messages.each { |message| result.errors << message }
435
- end
367
+ return book if book.save
436
368
 
437
- book
369
+ Cuprum::Result.new(error: book.errors.full_messages)
438
370
  end
439
371
 
440
- find_or_create_command = find_command.chain(create_command, :on => :failure)
372
+ find_or_create_command = find_command.chain(create_command, on: :failure)
441
373
 
442
374
  # With a book that exists in the database, the find_command is called and
443
- # returns a result with no errors and a value of the found book. The
375
+ # returns a result with no error and a value of the found book. The
444
376
  # create_command is not called.
445
377
  hsh = { id: 0, title: 'Journey to the West' }
446
378
  result = find_or_create_command.call(hsh)
@@ -448,19 +380,18 @@ book = result.value
448
380
  book.id #=> 0
449
381
  book.title #=> 'Journey to the West'
450
382
  result.success? #=> true
451
- result.errors #=> []
383
+ result.error #=> nil
452
384
 
453
385
  # With a book that does not exist but with valid attributes, the find command
454
386
  # returns a failing result with a value of nil. The create_command is called and
455
- # creates a new book with the attributes, returning a passing result but
456
- # preserving the errors.
387
+ # creates a new book with the attributes, returning a passing result.
457
388
  hsh = { id: 1, title: 'The Ramayana' }
458
389
  result = find_or_create_command.call(hsh)
459
390
  book = result.value
460
391
  book.id #=> 1
461
392
  book.title #=> 'The Ramayana'
462
393
  result.success? #=> true
463
- result.errors #=> ['Book not found']
394
+ result.error #=> nil
464
395
 
465
396
  # With a book that does not exist and with invalid attributes, the find command
466
397
  # returns a failing result with a value of nil. The create_command is called and
@@ -472,36 +403,7 @@ book = result.value
472
403
  book.id #=> 2
473
404
  book.title #=> nil
474
405
  result.success? #=> false
475
- result.errors #=> ['Book not found', "Title can't be blank"]
476
- ```
477
-
478
- The `#success` method can be used as shorthand for `chain(command, :on => :success)`. Likewise, the `#failure` method can be used in place of `chain(command, :on => :failure)`.
479
-
480
- #### Halting A Command Chain
481
-
482
- If the `#halt` method is called as part of a Command block or `#process` method, the command chain is halted. Any subsequent chained commands will not be called unless they were chained with the `:on => :always` option. This allows you to terminate a Command chain early without having to raise and rescue an exception.
483
-
484
- ```ruby
485
- double_command = Cuprum::Command.new { |i| 2 * i }
486
- halt_command = Cuprum::Command.new { |value| value.tap { result.halt! } }
487
- add_one_command = Cuprum::Command.new { |i| i + 1 }
488
-
489
- chained_command =
490
- double_command
491
- .chain(halt_command)
492
- .chain(add_one_command)
493
- .chain(:on => :always) { |count| "There are #{count} lights!" }
494
-
495
- # First, double_command is called with 2, returning a result with no errors and
496
- # a value of 4. Then, halt_command is called, which marks the result as halted.
497
- # Because the result is now halted, the add_one_command is not called. Finally,
498
- # the last command is called (even though the result is halted, the command is
499
- # chained :on => :always), which returns a result with the string value. The
500
- # result is passing, but is still halted.
501
- result = chained_command.call(2)
502
- result.value #=> 'There are 4 lights!'
503
- result.success? #=> true
504
- result.halted? #=> true
406
+ result.error #=> ["Title can't be blank"]
505
407
  ```
506
408
 
507
409
  ### Advanced Chaining
@@ -515,9 +417,7 @@ The `#tap_result` method allows you to insert arbitrary code into a command chai
515
417
  ```ruby
516
418
  command =
517
419
  Cuprum::Command.new do
518
- result.errors << 'Example error'
519
-
520
- 'Example value'
420
+ Cuprum::Result.new(value: 'Example value', error: 'Example error')
521
421
  end
522
422
  chained_command =
523
423
  command
@@ -530,32 +430,32 @@ result = chained_command.call
530
430
  result.class #=> Cuprum::Result
531
431
  result.value #=> 'Example value'
532
432
  result.success? #=> false
533
- result.errors #=> ['Example error']
433
+ result.error #=> 'Example error'
534
434
  ```
535
435
 
536
- Like `#chain`, `#tap_result` can be given an `:on => value` keyword.
436
+ Like `#chain`, `#tap_result` can be given an `on: value` keyword.
537
437
 
538
438
  ```ruby
539
439
  find_book_command =
540
440
  Cuprum::Command.new do |book_id|
541
- book = Book.where(:id => book_id).first
441
+ book = Book.where(id: book_id).first
542
442
 
543
- result.errors << "Unable to find book with id #{book_id}" unless book
443
+ return book if book
544
444
 
545
- book
445
+ Cuprum::Result.new(error: "Unable to find book with id #{book_id}")
546
446
  end
547
447
 
548
448
  chained_command =
549
449
  find_book_command
550
- .tap_result(:on => :success) do |result|
551
- render :show, :locals => { :book => result.value }
450
+ .tap_result(on: :success) do |result|
451
+ render :show, locals: { book: result.value }
552
452
  end
553
- .tap_result(:on => :failure) do
453
+ .tap_result(on: :failure) do
554
454
  redirect_to books_path
555
455
  end
556
456
 
557
457
  # Calls find_book_command with the id, which queries for the book and returns a
558
- # result with a value of the book and no errors. Then, the first tap_result
458
+ # result with a value of the book and no error. Then, the first tap_result
559
459
  # block is evaluated, calling the render method and passing it the book via the
560
460
  # result.value method. Because the result is passing, the next block is skipped.
561
461
  # Finally, the result of find_book_command is returned unchanged.
@@ -563,7 +463,7 @@ result = chained_command.call(valid_id)
563
463
  result.class #=> Cuprum::Result
564
464
  result.value #=> an instance of Book
565
465
  result.success? #=> true
566
- result.errors #=> []
466
+ result.error #=> nil
567
467
 
568
468
  # Calls find_book_command with the id, which queries for the book and returns a
569
469
  # result with a value of nil and the error message. Because the result is
@@ -574,14 +474,14 @@ result = chained_command.call(invalid_id)
574
474
  result.class #=> Cuprum::Result
575
475
  result.value #=> nil
576
476
  result.success? #=> false
577
- result.errors #=> ['Unable to find book with id invalid_id']
477
+ result.error #=> ['Unable to find book with id invalid_id']
578
478
  ```
579
479
 
580
480
  #### Yield Result
581
481
 
582
482
  The `#yield_result` method offers advanced control over a chained command step. The method takes a block and yields the previous result. If the object returned by the block is not a result, a new result is created with a value equal to the returned object. In either case, the result is returned and passed to the next command, or returned by `#call` if `#tap_result` is the last item in the chain.
583
483
 
584
- Unlike `#chain`, the block in `#yield_result` yields the previous result, not the previous value. In addition, `#yield_result` does not automatically carry over any errors from the previous result, the result status, or whether the result was marked as halted.
484
+ Unlike `#chain`, the block in `#yield_result` yields the previous result, not the previous value.
585
485
 
586
486
  ```ruby
587
487
  chained_command =
@@ -589,9 +489,7 @@ chained_command =
589
489
  'Example value'
590
490
  end
591
491
  .yield_result do |result|
592
- result.errors << 'Example error'
593
-
594
- result
492
+ Cuprum::Result.new(error: 'Example error')
595
493
  end
596
494
  .yield_result do |result|
597
495
  "The last result was a #{result.success? ? 'success' : 'failure'}."
@@ -599,54 +497,22 @@ chained_command =
599
497
 
600
498
  # The first command creates a passing result with a value of 'Example value'.
601
499
  #
602
- # This is passed to the first yield_result block, which adds the 'Example error'
603
- # string to the result errors, and then returns the result. Because the
604
- # yield_result block returns the previous result, it is then passed to the next
605
- # item in the chain.
500
+ # This is passed to the first yield_result block, which creates a new result
501
+ # with the same value and the string 'Example error' as the error object. It is
502
+ # then passed to the next command in the chain.
606
503
  #
607
504
  # Finally, the second yield_result block is called, which checks the status of
608
- # the passed result. Since the second block does not return the previous result,
505
+ # the passed result. Since the final block does not return the previous result,
609
506
  # the previous result is discarded and a new result is created with the string
610
507
  # value starting with 'The last result was ...'.
611
508
  result = chained_command.call
612
509
  result.class #=> Cuprum::Result
613
510
  result.value #=> 'The last result was a failure.'
614
511
  result.success? #=> true
615
- result.errors #=> []
512
+ result.error #=> nil
616
513
  ```
617
514
 
618
- Like `#chain`, `#yield_result` can be given an `:on => value` keyword.
619
-
620
- ```ruby
621
- # The Collatz conjecture in mathematics concerns a sequence of numbers defined
622
- # as follows. Start with any positive integer. If the number is even, then
623
- # divide the number by two. If the number is odd, multiply by three and add one.
624
- # These steps are repeated until the value is one or the numbers loop.
625
- step_command =
626
- Cuprum::Command.new do |i|
627
- result.failure! unless i.even?
628
-
629
- i
630
- end
631
- .yield_result(:on => :success) { |result| result.value / 2 }
632
- .yield_result(:on => :failure) { |result| 1 + 3 * result.value }
633
-
634
- # Because the value is even, the first command returns a passing result with a
635
- # value of 8. The first yield_result block is then called with that result,
636
- # returning a new result with a value of 4. The result is passing, so the second
637
- # yield_result block is skipped and the result is returned.
638
- result = collatz_command.call(8)
639
- result.value #=> 4
640
- result.success? #=> true
641
-
642
- # Because the value is odd, the first command returns a failing result with a
643
- # value of 5. Because the result is failing, the first yield_result block is
644
- # skipped. The second yield_result block is then called with the result,
645
- # returning a new (passing) result with a value of 16.
646
- result = collatz_command.call(5)
647
- result.value #=> 16
648
- result.success? #=> true
649
- ```
515
+ Like `#chain`, `#yield_result` can be given an `on: value` keyword.
650
516
 
651
517
  Under the hood, both `#chain` and `#tap_result` are implemented on top of `#yield_result`.
652
518
 
@@ -677,14 +543,14 @@ result = CreateCommentCommand.new.call({ user_id: '12345', body: body })
677
543
 
678
544
  result.value #=> an instance of Comment with the given user_id and body.
679
545
  result.success? #=> true
680
- Comment.count #=> 1; the comment was added to the database
546
+ Comment.count #=> 1 - the comment was added to the database
681
547
 
682
548
  result = CreateCommentCommand.new.call({ user_id: nil, body: body })
683
549
 
684
550
  result.value #=> an instance of Comment with the given user_id and body.
685
551
  result.success? #=> false
686
- result.errors #=> ["User id can't be blank"]
687
- Comment.count #=> 1; the comment was not added to the database
552
+ result.error #=> ["User id can't be blank"]
553
+ Comment.count #=> 1 - the comment was not added to the database
688
554
  ```
689
555
 
690
556
  ### Results
@@ -693,36 +559,115 @@ Comment.count #=> 1; the comment was not added to the database
693
559
 
694
560
  [Class Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum%2FResult)
695
561
 
696
- A Cuprum::Result is a data object that encapsulates the result of calling a Cuprum command. Each result has a `#value`, an `#errors` object (defaults to an Array), and status methods `#success?`, `#failure?`, and `#halted?`.
562
+ A `Cuprum::Result` is a data object that encapsulates the result of calling a Cuprum command. Each result has a `#value`, an `#error` object (defaults to `nil`), and a `#status` (either `:success` or `:failure`, and accessible via the `#success?` and `#failure?` predicates).
563
+
564
+ ```ruby
565
+ result = Cuprum::Result.new
566
+
567
+ result.value #=> nil
568
+ result.error #=> nil
569
+ result.status #=> :success
570
+ result.success? #=> true
571
+ result.failure? #=> true
572
+ ```
573
+
574
+ Creating a result with a value stores the value.
697
575
 
698
576
  ```ruby
699
577
  value = 'A result value'.freeze
700
- result = Cuprum::Result.new(value)
578
+ result = Cuprum::Result.new(value: value)
701
579
 
702
580
  result.value #=> 'A result value'
703
- result.errors #=> []
581
+ result.error #=> nil
582
+ result.status #=> :success
704
583
  result.success? #=> true
705
584
  result.failure? #=> false
706
- result.halted? #=> false
707
585
  ```
708
586
 
709
- Adding errors to the `#errors` object will change the status of the result.
587
+ Creating a Result with an error stores the error and sets the status to `:failure`.
588
+
589
+ ```ruby
590
+ error = Cuprum::Error.new(message: "I'm sorry, something went wrong.")
591
+ result = Cuprum::Result.new(error: error)
592
+ result.value #=> nil
593
+ result.error #=> Error with message "I'm sorry, something went wrong."
594
+ result.status #=> :failure
595
+ result.success? #=> false
596
+ result.failure? #=> true
597
+ ```
598
+
599
+ Although using a `Cuprum::Error` instance as the `:error` is recommended, it is not required. You can use a custom error object, or just a string message.
710
600
 
711
601
  ```ruby
712
- result.errors << "I'm sorry, something went wrong."
602
+ result = Cuprum::Result.new(error: "I'm sorry, something went wrong.")
603
+ result.value #=> nil
604
+ result.error #=> "I'm sorry, something went wrong."
605
+ result.status #=> :failure
713
606
  result.success? #=> false
714
607
  result.failure? #=> true
715
608
  ```
716
609
 
717
- The status can also be overriden with the `#success!` and `#failure!` methods, which will set the status regardless of the presence or absence of errors.
610
+ Finally, the status can be overridden via the `:status` keyword.
718
611
 
719
612
  ```ruby
720
- result.success!
721
- result.errors #=> ["I'm sorry, something went wrong."]
613
+ result = Cuprum::Result.new(status: :failure)
614
+ result.error #=> nil
615
+ result.status #=> :failure
616
+ result.success? #=> false
617
+ result.failure? #=> true
618
+
619
+ error = Cuprum::Error.new(message: "I'm sorry, something went wrong.")
620
+ result = Cuprum::Result.new(error: error, status: :success)
621
+ result.error #=> Error with message "I'm sorry, something went wrong."
622
+ result.status #=> :success
722
623
  result.success? #=> true
723
624
  result.failure? #=> false
724
625
  ```
725
626
 
627
+ ### Errors
628
+
629
+ require 'cuprum/error'
630
+
631
+ [Class Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum%2FError)
632
+
633
+ A `Cuprum::Error` encapsulates a specific failure state of a Command. Each Error has a `#message` property, which defaults to nil.
634
+
635
+ ```ruby
636
+ error = Cuprum::Error.new
637
+ error.message => # nil
638
+
639
+ error = Cuprum::Error.new(message: 'Something went wrong.')
640
+ error.message => # 'Something went wrong.'
641
+ ```
642
+
643
+ Each application should define its own failure states as errors. For example, a typical web application might define the following errors:
644
+
645
+ ```ruby
646
+ class NotFoundError < Cuprum::Error
647
+ def initialize(resource:, resource_id:)
648
+ @resource = resource
649
+ @resource_id = resource_id
650
+
651
+ super(message: "#{resource} not found with id #{resource_id}")
652
+ end
653
+
654
+ attr_reader :resource, :resource_id
655
+ end
656
+
657
+ class ValidationError < Cuprum::Error
658
+ def initialize(resource:, errors:)
659
+ @resource = resource
660
+ @errors = errors
661
+
662
+ super(message: "#{resource} was invalid")
663
+ end
664
+
665
+ attr_reader :resource, :errors
666
+ end
667
+ ```
668
+
669
+ It is optional but recommended to use a `Cuprum::Error` when returning a failed result from a command.
670
+
726
671
  ### Operations
727
672
 
728
673
  require 'cuprum'
@@ -737,8 +682,8 @@ These two features allow developers to simplify logic around calling and using t
737
682
  class CreateBookOperation < Cuprum::Operation
738
683
  def process
739
684
  # Implementation here.
740
- end # method process
741
- end # class
685
+ end
686
+ end
742
687
 
743
688
  # Defining a controller action using an operation.
744
689
  def create
@@ -750,13 +695,13 @@ def create
750
695
  @book = operation.value
751
696
 
752
697
  render :new
753
- end # if-else
754
- end # create
698
+ end
699
+ end
755
700
  ```
756
701
 
757
702
  Like a Command, an Operation can be defined directly by passing an implementation block to the constructor or by creating a subclass that overwrites the #process method.
758
703
 
759
- An operation inherits the `#call` method from Cuprum::Command (see above), and delegates the `#value`, `#errors`, `#success?`, and `#failure` methods to the most recent result. If the operation has not been called, these methods will return default values.
704
+ An operation inherits the `#call` method from Cuprum::Command (see above), and delegates the `#value`, `#error`, `#success?`, and `#failure` methods to the most recent result. If the operation has not been called, these methods will return default values.
760
705
 
761
706
  #### The Operation Mixin
762
707
 
@@ -764,13 +709,6 @@ An operation inherits the `#call` method from Cuprum::Command (see above), and d
764
709
 
765
710
  The implementation of `Cuprum::Operation` is defined by the `Cuprum::Operation::Mixin` module, which provides the methods defined above. Any command class or instance can be converted to an operation by including (for a class) or extending (for an instance) the operation mixin.
766
711
 
767
- Finally, the result can be halted using the `#halt` method, which indicates that further chained commands should not be executed.
768
-
769
- ```ruby
770
- result.halt!
771
- result.halted? #=> true
772
- ```
773
-
774
712
  ### Command Factories
775
713
 
776
714
  [Class Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum%2FCommandFactory)
@@ -898,15 +836,15 @@ class PublishedBooksCommand < Cuprum::Command
898
836
  end
899
837
 
900
838
  class BookFactory < Cuprum::CommandFactory
901
- command :published do
902
- PublishedBooksCommand.new(books_collection)
903
- end
904
-
905
839
  def initialize(books)
906
840
  @books_collection = books
907
841
  end
908
842
 
909
843
  attr_reader :books_collection
844
+
845
+ command :published do
846
+ PublishedBooksCommand.new(books_collection)
847
+ end
910
848
  end
911
849
  ```
912
850
 
@@ -1207,16 +1145,6 @@ Returns a new instance of Cuprum::Command. If a block is given, the `#call` meth
1207
1145
 
1208
1146
  [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#initialize-instance_method)
1209
1147
 
1210
- #### `#build_errors`
1211
-
1212
- *(Private Method)*
1213
-
1214
- build_errors() #=> Array
1215
-
1216
- Generates an empty errors object. When the command is called, the result will have its `#errors` property initialized to the value returned by `#build_errors`. By default, this is an array. If you want to use a custom errors object type, override this method in a subclass.
1217
-
1218
- [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#build_errors-instance_method)
1219
-
1220
1148
  #### `#call`
1221
1149
 
1222
1150
  call(*arguments, **keywords) { ... } #=> Cuprum::Result
@@ -1235,9 +1163,9 @@ Registers a command or block to run after the current command, or after the last
1235
1163
 
1236
1164
  The command will be passed the `#value` of the previous command result as its parameter, and the result of the chained command will be returned (or passed to the next chained command, if any).
1237
1165
 
1238
- The block will be passed the #result of the previous command as its parameter. If your use case depends on the status of the previous command or on any errors generated, use the block form of #chain.
1166
+ The block will be passed the #result of the previous command as its parameter.
1239
1167
 
1240
- If the block returns a Cuprum::Result (or an object responding to #value and #success?), the block result will be returned (or passed to the next chained command, if any). If the block returns any other value (including nil), the #result of the previous command will be returned or passed to the next command.
1168
+ If the block returns a Cuprum::Result (or an object responding to `#to_cuprum_result`), the block result will be returned (or passed to the next chained command, if any). If the block returns any other value (including `nil`), the `#result` of the previous command will be returned or passed to the next command.
1241
1169
 
1242
1170
  [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#chain-instance_method)
1243
1171
 
@@ -1253,29 +1181,13 @@ As `#chain`, but modifies the current command instead of creating a clone.
1253
1181
 
1254
1182
  [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#chain!-instance_method)
1255
1183
 
1256
- #### `#else`
1257
-
1258
- else(command) #=> Cuprum::Command
1259
-
1260
- Shorthand for `command.chain(:on => :failure)`. Registers a command or block to run after the current command. The chained command will only run if the previous command was unsuccessfully run.
1261
-
1262
- The command will be passed the `#value` of the previous command result as its parameter, and the result of the chained command will be returned (or passed to the next chained command, if any).
1263
-
1264
- else() { |result| ... } #=> Cuprum::Command
1265
-
1266
- The block will be passed the #result of the previous command as its parameter. If your use case depends on the status of the previous command or on any errors generated, use the block form of #chain.
1267
-
1268
- If the block returns a Cuprum::Result (or an object responding to #value and #success?), the block result will be returned (or passed to the next chained command, if any). If the block returns any other value (including nil), the #result of the previous command will be returned or passed to the next command.
1269
-
1270
- [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#else-instance_method)
1271
-
1272
1184
  #### `#tap_result`
1273
1185
 
1274
1186
  tap_result(on: nil) { |previous_result| } #=> Cuprum::Result
1275
1187
 
1276
1188
  Creates a copy of the command, and then chains the block to execute after the command implementation. When #call is executed, each chained block will be yielded the previous result, and the previous result returned or yielded to the next block. The return value of the block is discarded.
1277
1189
 
1278
- If the `on` parameter is omitted, the block will be called if the last result is not halted. If the `on` parameter is set to `:success`, the block will be called if the last result is successful and not halted. If the `on` parameter is set to `:failure`, the block will be called if the last result is failing and not halted. Finally, if the `on` parameter is set to `:always`, the block will always be called, even if the last result is halted.
1190
+ If the `on` parameter is set to `:success`, the block will be called if the last result is successful. If the `on` parameter is set to `:failure`, the block will be called if the last result is failing. Finally, if the `on` parameter is set to `:always` or to `nil`, the block will always be called.
1279
1191
 
1280
1192
  [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#tap_result-instance_method)
1281
1193
 
@@ -1289,29 +1201,13 @@ As `#tap_result`, but modifies the current command instead of creating a clone.
1289
1201
 
1290
1202
  [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#tap_result!-instance_method)
1291
1203
 
1292
- #### `#then`
1293
-
1294
- then(command) #=> Cuprum::Command
1295
-
1296
- Shorthand for `command.chain(:on => :success)`. Registers a command or block to run after the current command. The chained command will only run if the previous command was successfully run.
1297
-
1298
- The command will be passed the `#value` of the previous command result as its parameter, and the result of the chained command will be returned (or passed to the next chained command, if any).
1299
-
1300
- then() { |result| ... } #=> Cuprum::Command
1301
-
1302
- The block will be passed the #result of the previous command as its parameter. If your use case depends on the status of the previous command or on any errors generated, use the block form of #chain.
1303
-
1304
- If the block returns a Cuprum::Result (or an object responding to #value and #success?), the block result will be returned (or passed to the next chained command, if any). If the block returns any other value (including nil), the #result of the previous command will be returned or passed to the next command.
1305
-
1306
- [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#then-instance_method)
1307
-
1308
1204
  #### `#yield_result`
1309
1205
 
1310
1206
  yield_result(on: nil) { |previous_result| } #=> Cuprum::Result
1311
1207
 
1312
1208
  Creates a copy of the command, and then chains the block to execute after the command implementation. When #call is executed, each chained block will be yielded the previous result, and the return value wrapped in a result and returned or yielded to the next block.
1313
1209
 
1314
- If the `on` parameter is omitted, the block will be called if the last result is not halted. If the `on` parameter is set to `:success`, the block will be called if the last result is successful and not halted. If the `on` parameter is set to `:failure`, the block will be called if the last result is failing and not halted. Finally, if the `on` parameter is set to `:always`, the block will always be called, even if the last result is halted.
1210
+ If the `on` parameter is set to `:success`, the block will be called if the last result is successful. If the `on` parameter is set to `:failure`, the block will be called if the last result is failing. Finally, if the `on` parameter is set to `:always` or to `nil`, the block will always be called.
1315
1211
 
1316
1212
  [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Command#yield_result-instance_method)
1317
1213
 
@@ -1367,65 +1263,29 @@ A Cuprum::Result defines the following methods:
1367
1263
 
1368
1264
  ==(other) #=> true, false
1369
1265
 
1370
- Performs a fuzzy comparison with the other object. At a minimum, the other object must respond to `#value` and `#success?`, and the values of `other.value` and `other.success?` must be equal to the corresponding value on the result. In addition, if the `#failure?`, `#errors`, or `#halted?` methods are defined on the other object, then the value of each defined method is compared to the value on the result. Returns true if all values match, otherwise returns false.
1371
-
1372
- #### `#empty?`
1373
-
1374
- empty?() #=> true, false
1375
-
1376
- Helper method that returns true for a new result. The method returns false if `result.value` is not nil, if `result.errors` is not empty, if the status has been manually set with `#success!` or `#failure!`, or if the result has been halted.
1266
+ Performs a fuzzy comparison with the other object. At a minimum, the other object must respond to `#value`, `#success?`, `#error` and the values of `other.value`, `other.success?`, and `other.error` must be equal to the corresponding value on the result. Returns true if all values match, otherwise returns false.
1377
1267
 
1378
- #### `#errors`
1268
+ #### `#error`
1379
1269
 
1380
- errors() #=> Array
1270
+ error() #=> nil
1381
1271
 
1382
- The errors generated by the command, or an empty array if no errors were generated.
1272
+ The error generated by the command, or `nil` if no error was generated.
1383
1273
 
1384
- [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Result#errors-instance_method)
1385
-
1386
- #### `#failure!`
1387
-
1388
- failure!() #=> Cuprum::Result
1389
-
1390
- Marks the result as failing and returns the result. Calling `#failure?` will return true, even if the result has no errors.
1391
-
1392
- [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Result#failure!-instance_method)
1274
+ [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Result#error-instance_method)
1393
1275
 
1394
1276
  #### `#failure?`
1395
1277
 
1396
1278
  failure?() #=> true, false
1397
1279
 
1398
- True if the command generated one or more errors or was marked as failing. Otherwise false.
1280
+ True if the command generated an error or was marked as failing. Otherwise false.
1399
1281
 
1400
1282
  [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Result#failure%3F-instance_method)
1401
1283
 
1402
- #### `#halt!`
1403
-
1404
- halt!() #=> Cuprum::Result
1405
-
1406
- Marks the result as halted and returns the result. Calling `#halted?` will return true.
1407
-
1408
- [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Result#halt!-instance_method)
1409
-
1410
- #### `#halted?`
1411
-
1412
- halted?() #=> true, false
1413
-
1414
- True if the result is halted, which prevents chained commands from executing.
1415
-
1416
- #### `#success!`
1417
-
1418
- success!() #=> Cuprum::Result
1419
-
1420
- Marks the result as passing and returns the result. Calling `#success?` will return true, even if the result has errors.
1421
-
1422
- [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Result#success!-instance_method)
1423
-
1424
1284
  #### `#success?`
1425
1285
 
1426
1286
  success?() #=> true, false
1427
1287
 
1428
- True if the command did not generate any errors, or the result has errors but was marked as passing. Otherwise false.
1288
+ True if the command did not generate an error, or the result has an error but was marked as passing. Otherwise false.
1429
1289
 
1430
1290
  [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Result#success%3F-instance_method)
1431
1291
 
@@ -1465,9 +1325,9 @@ Finds or creates a spy object for the given module or class. Each time that the
1465
1325
  # Observing calls to instances of a command.
1466
1326
  spy = Cuprum::Utils::InstanceSpy.spy_on(CustomCommand)
1467
1327
 
1468
- expect(spy).to receive(:call).with(1, 2, 3, :four => '4')
1328
+ expect(spy).to receive(:call).with(1, 2, 3, four: '4')
1469
1329
 
1470
- CustomCommand.new.call(1, 2, 3, :four => '4')
1330
+ CustomCommand.new.call(1, 2, 3, four: '4')
1471
1331
 
1472
1332
  # Observing calls to a chained command.
1473
1333
  spy = Cuprum::Utils::InstanceSpy.spy_on(ChainedCommand)
@@ -1483,6 +1343,6 @@ Finds or creates a spy object for the given module or class. Each time that the
1483
1343
  expect(spy).to receive(:call)
1484
1344
 
1485
1345
  CustomCommand.new.call
1486
- end # spy_on
1346
+ end
1487
1347
 
1488
1348
  [Method Documentation](http://www.rubydoc.info/github/sleepingkingstudios/cuprum/master/Cuprum/Utils/InstanceSpy#spy_on%3F-instance_method)