u-case 3.0.0.rc4 → 3.0.0.rc5

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
  SHA256:
3
- metadata.gz: b3374584a2cf58a68aa1bed216c91bfd715cc4365d2e7972e5693a8c3acb52eb
4
- data.tar.gz: 9bbe75661a2cd53e549cf60692811d47d1aaf5895ee71cf89f3fc7e8f8d72f0b
3
+ metadata.gz: 12b63a467f7516217f29a5705859141be80fc2fb2209c41e77d7c8a365745b8c
4
+ data.tar.gz: 4501314217a04cca7d56c0091a8a2c02f93f308f51c323462af36c71532be1b3
5
5
  SHA512:
6
- metadata.gz: d43a4e404c554e4e489cd4875af61bf66ab41bec68a84c6022b04b3ae8dd79975f8522e8ecf8c0211ae0f08cbd4fe95ac6d7320a94d0c140ce3c436d26650afb
7
- data.tar.gz: '084cabc2b47f424a789f0e0cc9f120bfa50516771e669763207bed6c2884b4f6c3b8731be495eafc5bf1dc1c68b1b82b85a308c4a77cb546d77d99f6a088a827'
6
+ metadata.gz: 85351b75b4e2e2e62e66f2dff078a607ffa29e5c0df93dc3f6ce07dbfd0444ecd3034358fc08b358698c7ca2ccd73dbc5b8ab597ce339c5d7f4970df504b8a99
7
+ data.tar.gz: 5ef5552ca31fc9d9474f9a54717c7ce9a45ad9aba46710bf6671ae5836a492981beb4bee3cbdfbb5418770bcd896a634846eb659b5eaf1c098d6fa0c9339dc7b
data/Gemfile CHANGED
@@ -22,8 +22,7 @@ end
22
22
 
23
23
  pry_byebug_version =
24
24
  case RUBY_VERSION
25
- when /\A2.2/ then '3.6'
26
- when /\A2.3/ then '3.7'
25
+ when /\A2.[23]/ then '3.6'
27
26
  else '3.9'
28
27
  end
29
28
 
@@ -37,7 +36,7 @@ pry_version =
37
36
  group :development, :test do
38
37
  gem 'awesome_print', '~> 1.8'
39
38
 
40
- gem 'byebug', '~> 10.0', '>= 10.0.2' if RUBY_VERSION =~ /\A2.2/
39
+ gem 'byebug', '~> 10.0', '>= 10.0.2' if RUBY_VERSION =~ /\A2.[23]/
41
40
 
42
41
  gem 'pry', "~> #{pry_version}"
43
42
  gem 'pry-byebug', "~> #{pry_byebug_version}"
data/README.md CHANGED
@@ -4,30 +4,31 @@
4
4
  [![Maintainability](https://api.codeclimate.com/v1/badges/5c3c8ad1b0b943f88efd/maintainability)](https://codeclimate.com/github/serradura/u-case/maintainability)
5
5
  [![Test Coverage](https://api.codeclimate.com/v1/badges/5c3c8ad1b0b943f88efd/test_coverage)](https://codeclimate.com/github/serradura/u-case/test_coverage)
6
6
 
7
- μ-case (Micro::Case) <!-- omit in toc -->
8
- ====================
7
+ <img src="./assets/ucase_logo_v1.png" alt="u-case - Create simple and powerful use cases as Ruby objects.">
9
8
 
10
- Create simple and powerful use cases as objects.
9
+ Create simple and powerful use cases as Ruby objects.
11
10
 
12
11
  The main project goals are:
13
12
  1. Easy to use and easy to learn (input **>>** process **>>** output).
14
- 2. Promote referential transparency (transforming instead of modifying) and data integrity.
15
- 3. No callbacks (e.g: before, after, around).
16
- 4. Solve complex business logic, by allowing the composition of use cases.
13
+ 2. Promote immutability (transforming data instead of modifying it) and data integrity.
14
+ 3. No callbacks (ex: before, after, around) to avoid code indirections that could compromise the state and understanding of application flows.
15
+ 4. Solve complex business logic, by allowing the composition of use cases (flow creation).
17
16
  5. Be fast and optimized (Check out the [benchmarks](#benchmarks) section).
18
17
 
19
- > Note: Check out the repo https://github.com/serradura/from-fat-controllers-to-use-cases to see a Rails application that uses this gem to handle its business logic.
18
+ > **Note:** Check out the repo https://github.com/serradura/from-fat-controllers-to-use-cases to see a Rails application that uses this gem to handle its business logic.
20
19
 
21
20
  ## Documentation <!-- omit in toc -->
22
21
 
23
22
  Version | Documentation
24
23
  --------- | -------------
25
- 3.0.0.rc3 | https://github.com/serradura/u-case/blob/master/README.md
24
+ 3.0.0.rc5 | https://github.com/serradura/u-case/blob/master/README.md
26
25
  2.6.0 | https://github.com/serradura/u-case/blob/v2.x/README.md
27
26
  1.1.0 | https://github.com/serradura/u-case/blob/v1.x/README.md
28
27
 
28
+ > **Note:** Você entende português? 🇧🇷🇵🇹 Verifique o [README traduzido em pt-BR](https://github.com/serradura/u-case/blob/main/README.pt-BR.md).
29
+
29
30
  ## Table of Contents <!-- omit in toc -->
30
- - [Required Ruby version](#required-ruby-version)
31
+ - [Compatibility](#compatibility)
31
32
  - [Dependencies](#dependencies)
32
33
  - [Installation](#installation)
33
34
  - [Usage](#usage)
@@ -35,49 +36,54 @@ Version | Documentation
35
36
  - [`Micro::Case::Result` - What is a use case result?](#microcaseresult---what-is-a-use-case-result)
36
37
  - [What are the default result types?](#what-are-the-default-result-types)
37
38
  - [How to define custom result types?](#how-to-define-custom-result-types)
38
- - [Is it possible to define a custom result type without a block?](#is-it-possible-to-define-a-custom-result-type-without-a-block)
39
+ - [Is it possible to define a custom type without a result data?](#is-it-possible-to-define-a-custom-type-without-a-result-data)
39
40
  - [How to use the result hooks?](#how-to-use-the-result-hooks)
40
- - [Why the hook usage without a type exposes the result itself?](#why-the-hook-usage-without-a-type-exposes-the-result-itself)
41
+ - [Why the hook usage without a defined type exposes the result itself?](#why-the-hook-usage-without-a-defined-type-exposes-the-result-itself)
41
42
  - [Using decomposition to access the result data and type](#using-decomposition-to-access-the-result-data-and-type)
42
43
  - [What happens if a result hook was declared multiple times?](#what-happens-if-a-result-hook-was-declared-multiple-times)
43
44
  - [How to use the `Micro::Case::Result#then` method?](#how-to-use-the-microcaseresultthen-method)
44
45
  - [What does happens when a `Micro::Case::Result#then` receives a block?](#what-does-happens-when-a-microcaseresultthen-receives-a-block)
45
46
  - [How to make attributes data injection using this feature?](#how-to-make-attributes-data-injection-using-this-feature)
46
47
  - [`Micro::Cases::Flow` - How to compose use cases?](#microcasesflow---how-to-compose-use-cases)
47
- - [Is it possible to compose a use case flow with other ones?](#is-it-possible-to-compose-a-use-case-flow-with-other-ones)
48
+ - [Is it possible to compose a flow with other flows?](#is-it-possible-to-compose-a-flow-with-other-flows)
48
49
  - [Is it possible a flow accumulates its input and merges each success result to use as the argument of the next use cases?](#is-it-possible-a-flow-accumulates-its-input-and-merges-each-success-result-to-use-as-the-argument-of-the-next-use-cases)
49
50
  - [How to understand what is happening during a flow execution?](#how-to-understand-what-is-happening-during-a-flow-execution)
50
51
  - [`Micro::Case::Result#transitions` schema](#microcaseresulttransitions-schema)
51
52
  - [Is it possible disable the `Micro::Case::Result#transitions`?](#is-it-possible-disable-the-microcaseresulttransitions)
52
- - [Is it possible to declare a flow which includes the use case itself?](#is-it-possible-to-declare-a-flow-which-includes-the-use-case-itself)
53
+ - [Is it possible to declare a flow that includes the use case itself as a step?](#is-it-possible-to-declare-a-flow-that-includes-the-use-case-itself-as-a-step)
53
54
  - [`Micro::Case::Strict` - What is a strict use case?](#microcasestrict---what-is-a-strict-use-case)
54
55
  - [`Micro::Case::Safe` - Is there some feature to auto handle exceptions inside of a use case or flow?](#microcasesafe---is-there-some-feature-to-auto-handle-exceptions-inside-of-a-use-case-or-flow)
55
56
  - [`Micro::Cases::Safe::Flow`](#microcasessafeflow)
56
57
  - [`Micro::Case::Result#on_exception`](#microcaseresulton_exception)
57
- - [`u-case/with_activemodel_validation` - How to validate use case attributes?](#u-casewith_activemodel_validation---how-to-validate-use-case-attributes)
58
- - [If I enabled the auto validation, is it possible to disable it only in specific use case classes?](#if-i-enabled-the-auto-validation-is-it-possible-to-disable-it-only-in-specific-use-case-classes)
58
+ - [`u-case/with_activemodel_validation` - How to validate the use case attributes?](#u-casewith_activemodel_validation---how-to-validate-the-use-case-attributes)
59
+ - [If I enabled the auto validation, is it possible to disable it only in specific use cases?](#if-i-enabled-the-auto-validation-is-it-possible-to-disable-it-only-in-specific-use-cases)
59
60
  - [`Kind::Validator`](#kindvalidator)
60
61
  - [`Micro::Case.config`](#microcaseconfig)
61
62
  - [Benchmarks](#benchmarks)
62
- - [`Micro::Case` (v2.6.0)](#microcase-v260)
63
- - [Best overall](#best-overall)
63
+ - [`Micro::Case` (v3.0.0)](#microcase-v300)
64
64
  - [Success results](#success-results)
65
65
  - [Failure results](#failure-results)
66
- - [`Micro::Case::Flow` (v2.6.0)](#microcaseflow-v260)
66
+ - [`Micro::Cases::Flow` (v3.0.0)](#microcasesflow-v300)
67
67
  - [Comparisons](#comparisons)
68
68
  - [Examples](#examples)
69
69
  - [1️⃣ Rails App (API)](#1️⃣-rails-app-api)
70
70
  - [2️⃣ CLI calculator](#2️⃣-cli-calculator)
71
71
  - [3️⃣ Users creation](#3️⃣-users-creation)
72
- - [4️⃣ Rescuing exception inside of the use cases](#4️⃣-rescuing-exception-inside-of-the-use-cases)
72
+ - [4️⃣ Rescuing exceptions inside of the use cases](#4️⃣-rescuing-exceptions-inside-of-the-use-cases)
73
73
  - [Development](#development)
74
74
  - [Contributing](#contributing)
75
75
  - [License](#license)
76
76
  - [Code of Conduct](#code-of-conduct)
77
77
 
78
- ## Required Ruby version
78
+ ## Compatibility
79
+
80
+ | u-case | branch | ruby | activemodel |
81
+ | -------------- | ------- | -------- | ------------- |
82
+ | 3.0.0.rc5 | main | >= 2.2.0 | >= 3.2, < 6.1 |
83
+ | 2.6.0 | v2.x | >= 2.2.0 | >= 3.2, < 6.1 |
84
+ | 1.1.0 | v1.x | >= 2.2.0 | >= 3.2, < 6.1 |
79
85
 
80
- > \>= 2.2.0
86
+ > Note: The activemodel is an optional dependency, this module [can be enabled](#u-casewith_activemodel_validation---how-to-validate-use-case-attributes) to validate the use cases' attributes.
81
87
 
82
88
  ## Dependencies
83
89
 
@@ -85,7 +91,7 @@ Version | Documentation
85
91
 
86
92
  A simple type system (at runtime) for Ruby.
87
93
 
88
- Used to validate method inputs using its [`activemodel validation`](https://github.com/serradura/kind#kindvalidator-activemodelvalidations) module is auto required by [`u-case/with_activemodel_validation`](#u-casewith_activemodel_validation---how-to-validate-use-case-attributes) mode, and expose `Kind::Of::Micro::Case`, `Kind::Of::Micro::Case::Result` type checkers.
94
+ It is used to validate some internal u-case's methods input. This gem also exposes an [`ActiveModel validator`](https://github.com/serradura/kind#kindvalidator-activemodelvalidations) when requiring the [`u-case/with_activemodel_validation`](#u-casewith_activemodel_validation---how-to-validate-use-case-attributes) module, or when the [`Micro::Case.config`](#microcaseconfig) was used to enable it. Lastly, two type checkers are available through it: [`Kind::Of::Micro::Case`, `Kind::Of::Micro::Case::Result`](https://github.com/serradura/kind#registering-new-custom-type-checker).
89
95
  2. [`u-attributes`](https://github.com/serradura/u-attributes) gem.
90
96
 
91
97
  This gem allows defining read-only attributes, that is, your objects will have only getters to access their attributes data.
@@ -96,7 +102,7 @@ Version | Documentation
96
102
  Add this line to your application's Gemfile:
97
103
 
98
104
  ```ruby
99
- gem 'u-case'
105
+ gem 'u-case', '~> 3.0.0.rc5'
100
106
  ```
101
107
 
102
108
  And then execute:
@@ -105,7 +111,7 @@ And then execute:
105
111
 
106
112
  Or install it yourself as:
107
113
 
108
- $ gem install u-case
114
+ $ gem install u-case --pre
109
115
 
110
116
  ## Usage
111
117
 
@@ -119,7 +125,7 @@ class Multiply < Micro::Case
119
125
  # 2. Define the method `call!` with its business logic
120
126
  def call!
121
127
 
122
- # 3. Wrap the use case result/output using the `Success(result: *)` or `Failure(result: *)` methods
128
+ # 3. Wrap the use case output using the `Success(result: *)` or `Failure(result: *)` methods
123
129
  if a.is_a?(Numeric) && b.is_a?(Numeric)
124
130
  Success result: { number: a * b }
125
131
  else
@@ -128,9 +134,9 @@ class Multiply < Micro::Case
128
134
  end
129
135
  end
130
136
 
131
- #==========================#
132
- # Calling a use case class #
133
- #==========================#
137
+ #========================#
138
+ # Performing an use case #
139
+ #========================#
134
140
 
135
141
  # Success result
136
142
 
@@ -148,8 +154,7 @@ bad_result.data # { message: "`a` and `b` attributes must be numeric" }
148
154
 
149
155
  # Note:
150
156
  # ----
151
- # The result of a Micro::Case.call
152
- # is an instance of Micro::Case::Result
157
+ # The result of a Micro::Case.call is an instance of Micro::Case::Result
153
158
  ```
154
159
 
155
160
  [⬆️ Back to Top](#table-of-contents-)
@@ -163,6 +168,9 @@ A `Micro::Case::Result` stores the use cases output data. These are their main m
163
168
  - `#type` a Symbol which gives meaning for the result, this is useful to declare different types of failures or success.
164
169
  - `#data` the result data itself.
165
170
  - `#[]` and `#values_at` are shortcuts to access the `#data` values.
171
+ - `#key?` returns `true` if the key is present in `#data`.
172
+ - `#value?` returns `true` if the given value is present in `#data`.
173
+ - `#slice` returns a new hash that includes only the given keys. If the given keys don't exist, an empty hash is returned.
166
174
  - `#on_success` or `#on_failure` are hook methods that help you to define the application flow.
167
175
  - `#then` this method will allow applying a new use case if the current result was a success. The idea of this feature is to allow the creation of dynamic flows.
168
176
  - `#transitions` returns an array with all of transformations wich a result [has during a flow](#how-to-understand-what-is-happening-during-a-flow-execution).
@@ -173,9 +181,9 @@ A `Micro::Case::Result` stores the use cases output data. These are their main m
173
181
 
174
182
  #### What are the default result types?
175
183
 
176
- Every result has a type and these are the defaults:
184
+ Every result has a type, and these are their default values:
177
185
  - `:ok` when success
178
- - `:error`/`:exception` when failures
186
+ - `:error` or `:exception` when failures
179
187
 
180
188
  ```ruby
181
189
  class Divide < Micro::Case
@@ -269,9 +277,9 @@ bad_result.failure? # true
269
277
 
270
278
  [⬆️ Back to Top](#table-of-contents-)
271
279
 
272
- #### Is it possible to define a custom result type without a block?
280
+ #### Is it possible to define a custom type without a result data?
273
281
 
274
- Answer: Yes, it is possible. But this will have special behavior because the result data will be a hash with the given type as the key and true as its value.
282
+ Answer: Yes, it is possible. But this will have special behavior because the result data will be a hash with the given type as the key and `true` as its value.
275
283
 
276
284
  ```ruby
277
285
  class Multiply < Micro::Case
@@ -303,7 +311,7 @@ result.use_case.attributes # {"a"=>2, "b"=>"2"}
303
311
 
304
312
  #### How to use the result hooks?
305
313
 
306
- As mentioned earlier, the `Micro::Case::Result` has two methods to improve the flow control. They are: `#on_success`, `on_failure`.
314
+ As [mentioned earlier](#microcaseresult---what-is-a-use-case-result), the `Micro::Case::Result` has two methods to improve the application flow control. They are: `#on_success`, `on_failure`.
307
315
 
308
316
  The examples below show how to use them:
309
317
 
@@ -329,7 +337,7 @@ Double
329
337
  .on_failure(:invalid) { |result| raise TypeError, result[:msg] }
330
338
  .on_failure(:lte_zero) { |result| raise ArgumentError, result[:msg] }
331
339
 
332
- # The output because it is a success:
340
+ # The output will be:
333
341
  # 6
334
342
 
335
343
  #=============================#
@@ -345,18 +353,17 @@ Double
345
353
 
346
354
  # The outputs will be:
347
355
  #
348
- # 1. Prints the message: Double was the use case responsible for the failure
349
- # 2. Raises the exception: ArgumentError (the number must be greater than 0)
356
+ # 1. It will print the message: Double was the use case responsible for the failure
357
+ # 2. It will raise the exception: ArgumentError (the number must be greater than 0)
350
358
 
351
359
  # Note:
352
360
  # ----
353
- # The use case responsible for the failure will be accessible as the second hook argument
361
+ # The use case responsible for the result will always be accessible as the second hook argument
354
362
  ```
355
363
 
356
- #### Why the hook usage without a type exposes the result itself?
364
+ #### Why the hook usage without a defined type exposes the result itself?
357
365
 
358
- Answer: To allow you to define how to handle the program flow using some
359
- conditional statement (like an `if`, `case/when`).
366
+ Answer: To allow you to define how to handle the program flow using some conditional statement like an `if` or `case when`.
360
367
 
361
368
  ```ruby
362
369
  class Double < Micro::Case
@@ -380,7 +387,7 @@ Double
380
387
  end
381
388
  end
382
389
 
383
- # The output will be the exception:
390
+ # The output will be an exception:
384
391
  #
385
392
  # ArgumentError (number `-1` must be greater than 0)
386
393
  ```
@@ -389,11 +396,11 @@ Double
389
396
 
390
397
  ##### Using decomposition to access the result data and type
391
398
 
392
- The syntax to decompose an Array can be used in methods, blocks and assigments.
399
+ The syntax to decompose an Array can be used in assignments and in method/block arguments.
393
400
  If you doesn't know it, check out the [Ruby doc](https://ruby-doc.org/core-2.2.0/doc/syntax/assignment_rdoc.html#label-Array+Decomposition).
394
401
 
395
402
  ```ruby
396
- # The object exposed in the hook is a Micro::Case::Result, and it can be decomposed using this syntax. e.g:
403
+ # The object exposed in the hook without a type is a Micro::Case::Result and it can be decomposed. e.g:
397
404
 
398
405
  Double
399
406
  .call(number: -2)
@@ -450,8 +457,7 @@ result[:number] * 4 == accum # true
450
457
 
451
458
  #### How to use the `Micro::Case::Result#then` method?
452
459
 
453
- This method allows you to create dynamic flows, so, with it,
454
- you can add new use cases or flows to continue the result transformation. e.g:
460
+ This method allows you to create dynamic flows, so, with it, you can add new use cases or flows to continue the result transformation. e.g:
455
461
 
456
462
  ```ruby
457
463
  class ForbidNegativeNumber < Micro::Case
@@ -497,7 +503,7 @@ result2.success? # true
497
503
 
498
504
  ##### What does happens when a `Micro::Case::Result#then` receives a block?
499
505
 
500
- It will yields self (a `Micro::Case::Result instance`) to the block and return the result of the block. e.g:
506
+ It will yields self (a `Micro::Case::Result` instance) to the block, and will return the output of the block instead of itself. e.g:
501
507
 
502
508
  ```ruby
503
509
  class Add < Micro::Case
@@ -549,8 +555,7 @@ Todo::FindAllForUser
549
555
 
550
556
  ### `Micro::Cases::Flow` - How to compose use cases?
551
557
 
552
- In this case, this will be a **flow** (`Micro::Cases::Flow`).
553
- The main idea of this feature is to use/reuse use cases as steps of a new use case.
558
+ We call as **flow** a composition of use cases. The main idea of this feature is to use/reuse use cases as steps of a new use case. e.g.
554
559
 
555
560
  ```ruby
556
561
  module Steps
@@ -605,9 +610,9 @@ result = Add2ToAllNumbers.call(numbers: %w[1 1 2 2 3 4])
605
610
  result.success? # true
606
611
  result.data # {:numbers => [3, 3, 4, 4, 5, 6]}
607
612
 
608
- #---------------------------------------------------#
609
- # An alternative way to create a flow using classes #
610
- #---------------------------------------------------#
613
+ #-------------------------------#
614
+ # Creating a flow using classes #
615
+ #-------------------------------#
611
616
 
612
617
  class DoubleAllNumbers < Micro::Case
613
618
  flow Steps::ConvertTextToNumbers,
@@ -617,12 +622,11 @@ end
617
622
  DoubleAllNumbers.
618
623
  call(numbers: %w[1 1 b 2 3 4]).
619
624
  on_failure { |result| puts result[:message] } # "numbers must contain only numeric types"
625
+ ```
620
626
 
621
- # Note:
622
- # ----
623
- # When happening a failure, the use case responsible
624
- # will be accessible in the result
627
+ When happening a failure, the use case responsible will be accessible in the result.
625
628
 
629
+ ```ruby
626
630
  result = DoubleAllNumbers.call(numbers: %w[1 1 b 2 3 4])
627
631
 
628
632
  result.failure? # true
@@ -635,7 +639,7 @@ end
635
639
 
636
640
  [⬆️ Back to Top](#table-of-contents-)
637
641
 
638
- #### Is it possible to compose a use case flow with other ones?
642
+ #### Is it possible to compose a flow with other flows?
639
643
 
640
644
  Answer: Yes, it is possible.
641
645
 
@@ -705,13 +709,13 @@ DoubleAllNumbersAndSquareAndAdd2
705
709
  .on_success { |result| p result[:numbers] } # [6, 6, 18, 18, 38, 66]
706
710
  ```
707
711
 
708
- Note: You can blend any of the [available syntaxes/approaches](#how-to-create-a-flow-which-has-reusable-steps-to-define-a-complex-use-case) to create use case flows - [examples](https://github.com/serradura/u-case/blob/714c6b658fc6aa02617e6833ddee09eddc760f2a/test/micro/cases/flow/blend_test.rb#L5-L35).
712
+ > **Note:** You can blend any [approach](#microcasesflow---how-to-compose-use-cases) to create use case flows - [examples](https://github.com/serradura/u-case/blob/714c6b658fc6aa02617e6833ddee09eddc760f2a/test/micro/cases/flow/blend_test.rb#L5-L35).
709
713
 
710
714
  [⬆️ Back to Top](#table-of-contents-)
711
715
 
712
716
  #### Is it possible a flow accumulates its input and merges each success result to use as the argument of the next use cases?
713
717
 
714
- Answer: Yes, it is possible! Look at the example below to understand how the data accumulation works inside of the flow execution.
718
+ Answer: Yes, it is possible! Look at the example below to understand how the data accumulation works inside of a flow execution.
715
719
 
716
720
  ```ruby
717
721
  module Users
@@ -755,7 +759,7 @@ Users::Authenticate
755
759
  .on_failure(:user_not_found) { render status: 404 }
756
760
  ```
757
761
 
758
- First, lets see the attributes used by each use case:
762
+ First, let's see the attributes used by each use case:
759
763
 
760
764
  ```ruby
761
765
  class Users::FindByEmail < Micro::Case
@@ -768,14 +772,13 @@ end
768
772
  ```
769
773
 
770
774
  As you can see the `Users::ValidatePassword` expects a user as its input. So, how does it receives the user?
771
- It receives the user from the `Users::FindByEmail` success result!
775
+ Answer: It receives the user from the `Users::FindByEmail` success result!
772
776
 
773
- And this, is the power of use cases composition because the output
774
- of one step will compose the input of the next use case in the flow!
777
+ And this is the power of use cases composition because the output of one step will compose the input of the next use case in the flow!
775
778
 
776
779
  > input **>>** process **>>** output
777
780
 
778
- > **Note:** Check out these test examples [Micro::Cases::Flow](https://github.com/serradura/u-case/blob/c96a3650469da40dc9f83ff678204055b7015d01/test/micro/cases/flow/result_transitions_test.rb) and [Micro::Cases::Safe::Flow](https://github.com/serradura/u-case/blob/c96a3650469da40dc9f83ff678204055b7015d01/test/micro/cases/safe/flow/result_transitions_test.rb) to see different use cases sharing their own data.
781
+ > **Note:** Check out these test examples [Micro::Cases::Flow](https://github.com/serradura/u-case/blob/c96a3650469da40dc9f83ff678204055b7015d01/test/micro/cases/flow/result_transitions_test.rb) and [Micro::Cases::Safe::Flow](https://github.com/serradura/u-case/blob/c96a3650469da40dc9f83ff678204055b7015d01/test/micro/cases/safe/flow/result_transitions_test.rb) to see different use cases having access to the data in a flow.
779
782
 
780
783
  [⬆️ Back to Top](#table-of-contents-)
781
784
 
@@ -824,7 +827,7 @@ user_authenticated.transitions
824
827
  ```
825
828
 
826
829
  The example above shows the output generated by the `Micro::Case::Result#transitions`.
827
- With it is possible to analyze the use cases execution order and what were the given `inputs` (`[:attributes]`) and `outputs` (`[:success][:result]`) in the entire execution.
830
+ With it is possible to analyze the use cases' execution order and what were the given `inputs` (`[:attributes]`) and `outputs` (`[:success][:result]`) in the entire execution.
828
831
 
829
832
  And look up the `accessible_attributes` property, it shows whats attributes are accessible in that flow step. For example, in the last step, you can see that the `accessible_attributes` increased because of the [data flow accumulation](#is-it-possible-a-flow-accumulates-its-input-and-merges-each-success-result-to-use-as-the-argument-of-the-next-use-cases).
830
833
 
@@ -841,11 +844,11 @@ And look up the `accessible_attributes` property, it shows whats attributes are
841
844
  [success:, failure:] => { # (Output)
842
845
  type: <Symbol>, # Result type. Defaults:
843
846
  # Success = :ok, Failure = :error/:exception
844
- result: <Hash> # The data returned by the use case
847
+ result: <Hash> # The data returned by the use case result
845
848
  },
846
849
  accessible_attributes: <Array>, # Properties that can be accessed by the use case's attributes,
847
- # starting with Hash used to invoke it and which are incremented
848
- # with each result value of the flow's use cases.
850
+ # it starts with Hash used to invoke it and that will be incremented
851
+ # with the result values of each use case in the flow.
849
852
  }
850
853
  ]
851
854
  ```
@@ -854,9 +857,9 @@ And look up the `accessible_attributes` property, it shows whats attributes are
854
857
 
855
858
  Answer: Yes, it is! You can use the `Micro::Case.config` to do this. [Link to](#microcaseconfig) this section.
856
859
 
857
- #### Is it possible to declare a flow which includes the use case itself?
860
+ #### Is it possible to declare a flow that includes the use case itself as a step?
858
861
 
859
- Answer: Yes, it is! You can use the `self.call!` macro. e.g:
862
+ Answer: Yes, it is! You can use `self` or the `self.call!` macro. e.g:
860
863
 
861
864
  ```ruby
862
865
  class ConvertTextToNumber < Micro::Case
@@ -891,16 +894,15 @@ result = Double.call(text: '4')
891
894
 
892
895
  result.success? # true
893
896
  result[:number] # "8"
894
-
895
- # NOTE: This feature can be used with the Micro::Case::Safe.
896
- # Checkout this test: https://github.com/serradura/u-case/blob/714c6b658fc6aa02617e6833ddee09eddc760f2a/test/micro/case/safe/with_inner_flow_test.rb
897
897
  ```
898
898
 
899
+ > **Note:** This feature can be used with the Micro::Case::Safe. Checkout this test to see an example: https://github.com/serradura/u-case/blob/714c6b658fc6aa02617e6833ddee09eddc760f2a/test/micro/case/safe/with_inner_flow_test.rb
900
+
899
901
  [⬆️ Back to Top](#table-of-contents-)
900
902
 
901
903
  ### `Micro::Case::Strict` - What is a strict use case?
902
904
 
903
- Answer: Is a use case which will require all the keywords (attributes) on its initialization.
905
+ Answer: it is a kind of use case that will require all the keywords (attributes) on its initialization.
904
906
 
905
907
  ```ruby
906
908
  class Double < Micro::Case::Strict
@@ -913,7 +915,7 @@ end
913
915
 
914
916
  Double.call({})
915
917
 
916
- # The output will be the following exception:
918
+ # The output will be:
917
919
  # ArgumentError (missing keyword: :numbers)
918
920
  ```
919
921
 
@@ -921,11 +923,7 @@ Double.call({})
921
923
 
922
924
  ### `Micro::Case::Safe` - Is there some feature to auto handle exceptions inside of a use case or flow?
923
925
 
924
- Answer: Yes, there is one!
925
-
926
- **Use cases:**
927
-
928
- Like `Micro::Case::Strict` the `Micro::Case::Safe` is another kind of use case. It has the ability to auto intercept any exception as a failure result. e.g:
926
+ Yes, there is one! Like `Micro::Case::Strict` the `Micro::Case::Safe` is another kind of use case. It has the ability to auto intercept any exception as a failure result. e.g:
929
927
 
930
928
  ```ruby
931
929
  require 'logger'
@@ -952,25 +950,21 @@ result[:exception].is_a?(ZeroDivisionError) # true
952
950
  result.on_failure(:exception) do |result|
953
951
  AppLogger.error(result[:exception].message) # E, [2019-08-21T00:05:44.195506 #9532] ERROR -- : divided by 0
954
952
  end
953
+ ```
955
954
 
956
- # Note:
957
- # ----
958
- # If you need to handle a specific error,
959
- # I recommend the usage of a case statement. e,g:
955
+ If you need to handle a specific error, I recommend the usage of a case statement. e,g:
960
956
 
957
+ ```ruby
961
958
  result.on_failure(:exception) do |data, use_case|
962
959
  case exception = data[:exception]
963
960
  when ZeroDivisionError then AppLogger.error(exception.message)
964
961
  else AppLogger.debug("#{use_case.class.name} was the use case responsible for the exception")
965
962
  end
966
963
  end
967
-
968
- # Another note:
969
- # ------------
970
- # It is possible to rescue an exception even when is a safe use case.
971
- # Examples: https://github.com/serradura/u-case/blob/714c6b658fc6aa02617e6833ddee09eddc760f2a/test/micro/case/safe_test.rb#L90-L118
972
964
  ```
973
965
 
966
+ > **Note:** It is possible to rescue an exception even when is a safe use case. Examples: https://github.com/serradura/u-case/blob/714c6b658fc6aa02617e6833ddee09eddc760f2a/test/micro/case/safe_test.rb#L90-L118
967
+
974
968
  [⬆️ Back to Top](#table-of-contents-)
975
969
 
976
970
  #### `Micro::Cases::Safe::Flow`
@@ -986,9 +980,11 @@ module Users
986
980
  SendToCRM
987
981
  ])
988
982
  end
983
+ ```
989
984
 
990
- # or within classes
985
+ Defining within classes:
991
986
 
987
+ ```ruby
992
988
  module Users
993
989
  class Create < Micro::Case::Safe
994
990
  flow ProcessParams,
@@ -1007,9 +1003,9 @@ In functional programming errors/exceptions are handled as regular data, the ide
1007
1003
 
1008
1004
  To address this the `Micro::Case::Result` has a special hook `#on_exception` to helping you to handle the control flow in the case of exceptions.
1009
1005
 
1010
- > **Note**: this feature will work better if you use it with a `Micro::Case::Safe` use case/flow.
1006
+ > **Note**: this feature will work better if you use it with a `Micro::Case::Safe` flow or use case.
1011
1007
 
1012
- How does it work?
1008
+ **How does it work?**
1013
1009
 
1014
1010
  ```ruby
1015
1011
  class Divide < Micro::Case::Safe
@@ -1045,21 +1041,19 @@ Divide.
1045
1041
  # Oh no, something went wrong!
1046
1042
  ```
1047
1043
 
1048
- As you can see, this hook has the same behavior of `result.on_failure(:exception)`, but, the ideia here is to have a better communication in the code, making an explicit reference when some failure happened because of an exception.
1044
+ As you can see, this hook has the same behavior of `result.on_failure(:exception)`, but, the idea here is to have a better communication in the code, making an explicit reference when some failure happened because of an exception.
1049
1045
 
1050
1046
  [⬆️ Back to Top](#table-of-contents-)
1051
1047
 
1052
- ### `u-case/with_activemodel_validation` - How to validate use case attributes?
1048
+ ### `u-case/with_activemodel_validation` - How to validate the use case attributes?
1053
1049
 
1054
1050
  **Requirement:**
1055
1051
 
1056
1052
  To do this your application must have the [activemodel >= 3.2, < 6.1.0](https://rubygems.org/gems/activemodel) as a dependency.
1057
1053
 
1054
+ By default, if your application has ActiveModel as a dependency, any kind of use case can make use of it to validate its attributes.
1055
+
1058
1056
  ```ruby
1059
- #
1060
- # By default, if your application has the activemodel as a dependency,
1061
- # any kind of use case can use it to validate their attributes.
1062
- #
1063
1057
  class Multiply < Micro::Case
1064
1058
  attributes :a, :b
1065
1059
 
@@ -1073,9 +1067,9 @@ class Multiply < Micro::Case
1073
1067
  end
1074
1068
  ```
1075
1069
 
1076
- But if do you want an automatic way to fail your use cases on validation errors, you can:
1070
+ But if do you want an automatic way to fail your use cases on validation errors, you could do:
1077
1071
 
1078
- 1. **require 'u-case/with_activemodel_validation'** mode
1072
+ 1. **require 'u-case/with_activemodel_validation'** in the Gemfile
1079
1073
 
1080
1074
  ```ruby
1081
1075
  gem 'u-case', require: 'u-case/with_activemodel_validation'
@@ -1097,16 +1091,13 @@ class Multiply < Micro::Case
1097
1091
  Success result: { number: a * b }
1098
1092
  end
1099
1093
  end
1100
-
1101
- # Note:
1102
- # ----
1103
- # After requiring the validation mode, the
1104
- # Micro::Case::Strict and Micro::Case::Safe classes will inherit this new behavior.
1105
1094
  ```
1106
1095
 
1107
- #### If I enabled the auto validation, is it possible to disable it only in specific use case classes?
1096
+ > **Note:** After requiring the validation mode, the `Micro::Case::Strict` and `Micro::Case::Safe` classes will inherit this new behavior.
1108
1097
 
1109
- Answer: Yes, it is possible. To do this, you only need to use the `disable_auto_validation` macro. e.g:
1098
+ #### If I enabled the auto validation, is it possible to disable it only in specific use cases?
1099
+
1100
+ Answer: Yes, it is possible. To do this, you will need to use the `disable_auto_validation` macro. e.g:
1110
1101
 
1111
1102
  ```ruby
1112
1103
  require 'u-case/with_activemodel_validation'
@@ -1125,7 +1116,7 @@ end
1125
1116
 
1126
1117
  Multiply.call(a: 2, b: 'a')
1127
1118
 
1128
- # The output will be the following exception:
1119
+ # The output will be:
1129
1120
  # TypeError (String can't be coerced into Integer)
1130
1121
  ```
1131
1122
 
@@ -1133,9 +1124,9 @@ Multiply.call(a: 2, b: 'a')
1133
1124
 
1134
1125
  #### `Kind::Validator`
1135
1126
 
1136
- The [kind gem](https://github.com/serradura/kind) has a module to enable the validation of data type through [`ActiveModel validations`](https://guides.rubyonrails.org/active_model_basics.html#validations). So, when you require the `'u-case/with_activemodel_validation'`, this module will require the [`Kind::Validator`](https://github.com/serradura/kind#kindvalidator-activemodelvalidations).
1127
+ The [kind gem](https://github.com/serradura/kind) has a module to enable the validation of data type through [`ActiveModel validations`](https://guides.rubyonrails.org/active_model_basics.html#validations). So, when you require the `'u-case/with_activemodel_validation'`, this module will also require the [`Kind::Validator`](https://github.com/serradura/kind#kindvalidator-activemodelvalidations).
1137
1128
 
1138
- The example below shows how to validate the attributes data types.
1129
+ The example below shows how to validate the attributes types.
1139
1130
 
1140
1131
  ```ruby
1141
1132
  class Todo::List::AddItem < Micro::Case
@@ -1160,17 +1151,17 @@ end
1160
1151
 
1161
1152
  ## `Micro::Case.config`
1162
1153
 
1163
- The idea of this feature is to allow the configuration of some `u-case` features/modules.
1154
+ The idea of this resource is to allow the configuration of some `u-case` features/modules.
1164
1155
  I recommend you use it only once in your codebase. e.g. In a Rails initializer.
1165
1156
 
1166
- You can see below, which are all of the available configurations with their default values:
1157
+ You can see below, which are the available configurations with their default values:
1167
1158
 
1168
1159
  ```ruby
1169
1160
  Micro::Case.config do |config|
1170
1161
  # Use ActiveModel to auto-validate your use cases' attributes.
1171
- config.enable_activemodel_validations = false
1162
+ config.enable_activemodel_validation = false
1172
1163
 
1173
- # Use to enable/disable the `Micro::Case::Results#transitions` tracking.
1164
+ # Use to enable/disable the `Micro::Case::Results#transitions`.
1174
1165
  config.enable_transitions = true
1175
1166
  end
1176
1167
  ```
@@ -1179,62 +1170,48 @@ end
1179
1170
 
1180
1171
  ## Benchmarks
1181
1172
 
1182
- ### `Micro::Case` (v2.6.0)
1183
-
1184
- #### Best overall
1185
-
1186
- The table below contains the average between the [Success results](#success-results) and [Failure results](#failure-results) benchmarks.
1187
-
1188
- | Gem / Abstraction | Iterations per second | Comparison |
1189
- | ---------------------- | --------------------: | ----------------: |
1190
- | **Micro::Case** | 105124.3 | _**The Fastest**_ |
1191
- | Dry::Monads | 103290.1 | 0.02x slower |
1192
- | Interactor | 21342.3 | 4.93x slower |
1193
- | Trailblazer::Operation | 14652.7 | 7.17x slower |
1194
- | Dry::Transaction | 5310.3 | 19.80x slower |
1195
-
1196
- ---
1173
+ ### `Micro::Case` (v3.0.0)
1197
1174
 
1198
1175
  #### Success results
1199
1176
 
1200
1177
  | Gem / Abstraction | Iterations per second | Comparison |
1201
1178
  | ----------------- | --------------------: | ----------------: |
1202
- | Dry::Monads | 134801.0 | _**The Fastest**_ |
1203
- | **Micro::Case** | 105909.2 | 1.27x slower |
1204
- | Interactor | 29458.2 | 4.58x slower |
1205
- | Trailblazer::Operation | 14714.9 | 9.16x slower |
1206
- | Dry::Transaction | 5642.6 | 28.89x slower |
1179
+ | Dry::Monads | 139037.7 | _**The Fastest**_ |
1180
+ | **Micro::Case** | 101497.3 | 1.37x slower |
1181
+ | Interactor | 30694.2 | 4.53x slower |
1182
+ | Trailblazer::Operation | 14580.8 | 9.54x slower |
1183
+ | Dry::Transaction | 5728.0 | 24.27x slower |
1207
1184
 
1208
1185
  <details>
1209
1186
  <summary>Show the full <a href="https://github.com/evanphx/benchmark-ips">benchmark/ips</a> results.</summary>
1210
1187
 
1211
1188
  ```ruby
1212
1189
  # Warming up --------------------------------------
1213
- # Interactor 2.897k i/100ms
1214
- # Trailblazer::Operation 1.494k i/100ms
1215
- # Dry::Monads 13.854k i/100ms
1216
- # Dry::Transaction 561.000 i/100ms
1217
- # Micro::Case 10.523k i/100ms
1218
- # Micro::Case::Strict 7.982k i/100ms
1219
- # Micro::Case::Safe 10.568k i/100ms
1190
+ # Interactor 3.056k i/100ms
1191
+ # Trailblazer::Operation 1.480k i/100ms
1192
+ # Dry::Monads 14.316k i/100ms
1193
+ # Dry::Transaction 576.000 i/100ms
1194
+ # Micro::Case 10.388k i/100ms
1195
+ # Micro::Case::Strict 8.223k i/100ms
1196
+ # Micro::Case::Safe 10.057k i/100ms
1220
1197
 
1221
1198
  # Calculating -------------------------------------
1222
- # Interactor 29.458k (± 3.4%) i/s - 147.747k in 5.021405s
1223
- # Trailblazer::Operation 14.715k1.8%) i/s - 74.700k in 5.078128s
1224
- # Dry::Monads 134.801k8.7%) i/s - 678.846k in 5.088739s
1225
- # Dry::Transaction 5.643k2.1%) i/s - 28.611k in 5.072969s
1226
- # Micro::Case 105.909k2.4%) i/s - 536.673k in 5.070329s
1227
- # Micro::Case::Strict 84.234k1.5%) i/s - 423.046k in 5.023447s
1228
- # Micro::Case::Safe 105.725k (± 1.9%) i/s - 538.968k in 5.099817s
1199
+ # Interactor 30.694k2.3%) i/s - 155.856k in 5.080475s
1200
+ # Trailblazer::Operation 14.581k3.9%) i/s - 74.000k in 5.083091s
1201
+ # Dry::Monads 139.038k3.0%) i/s - 701.484k in 5.049921s
1202
+ # Dry::Transaction 5.728k3.6%) i/s - 28.800k in 5.034599s
1203
+ # Micro::Case 100.712k3.4%) i/s - 509.012k in 5.060139s
1204
+ # Micro::Case::Strict 81.513k3.4%) i/s - 411.150k in 5.049962s
1205
+ # Micro::Case::Safe 101.497k3.1%) i/s - 512.907k in 5.058463s
1229
1206
 
1230
1207
  # Comparison:
1231
- # Dry::Monads: 134801.0 i/s
1232
- # Micro::Case: 105909.2 i/s - 1.27x (± 0.00) slower
1233
- # Micro::Case::Safe: 105725.0 i/s - 1.28x (± 0.00) slower
1234
- # Micro::Case::Strict: 84234.4 i/s - 1.60x (± 0.00) slower
1235
- # Interactor: 29458.2 i/s - 4.58x (± 0.00) slower
1236
- # Trailblazer::Operation: 14714.9 i/s - 9.16x (± 0.00) slower
1237
- # Dry::Transaction: 5642.6 i/s - 23.89x (± 0.00) slower
1208
+ # Dry::Monads: 139037.7 i/s
1209
+ # Micro::Case::Safe: 101497.3 i/s - 1.37x (± 0.00) slower
1210
+ # Micro::Case: 100711.6 i/s - 1.38x (± 0.00) slower
1211
+ # Micro::Case::Strict: 81512.9 i/s - 1.71x (± 0.00) slower
1212
+ # Interactor: 30694.2 i/s - 4.53x (± 0.00) slower
1213
+ # Trailblazer::Operation: 14580.8 i/s - 9.54x (± 0.00) slower
1214
+ # Dry::Transaction: 5728.0 i/s - 24.27x (± 0.00) slower
1238
1215
  ```
1239
1216
  </details>
1240
1217
 
@@ -1244,42 +1221,42 @@ https://github.com/serradura/u-case/blob/master/benchmarks/use_case/with_success
1244
1221
 
1245
1222
  | Gem / Abstraction | Iterations per second | Comparison |
1246
1223
  | ----------------- | --------------------: | ----------------: |
1247
- | **Micro::Case** | 104339.4 | _**The Fastest**_ |
1248
- | Dry::Monads | 71779.2 | 1.45x slower |
1249
- | Trailblazer::Operation | 14590.6 | 7.15x slower |
1250
- | Interactor | 13226.5 | 7.89x slower |
1251
- | Dry::Transaction | 4978.1 | 20.96x slower |
1224
+ | **Micro::Case** | 94619.6 | _**The Fastest**_ |
1225
+ | Dry::Monads | 70250.6 | 1.35x slower |
1226
+ | Trailblazer::Operation | 14786.1 | 6.40x slower |
1227
+ | Interactor | 13770.0 | 6.87x slower |
1228
+ | Dry::Transaction | 4994.4 | 18.95x slower |
1252
1229
 
1253
1230
  <details>
1254
1231
  <summary>Show the full <a href="https://github.com/evanphx/benchmark-ips">benchmark/ips</a> results.</summary>
1255
1232
 
1256
1233
  ```ruby
1257
1234
  # Warming up --------------------------------------
1258
- # Interactor 1.339k i/100ms
1259
- # Trailblazer::Operation 1.393k i/100ms
1260
- # Dry::Monads 7.208k i/100ms
1261
- # Dry::Transaction 423.000 i/100ms
1262
- # Micro::Case 9.620k i/100ms
1263
- # Micro::Case::Strict 8.238k i/100ms
1264
- # Micro::Case::Safe 9.906k i/100ms
1235
+ # Interactor 1.408k i/100ms
1236
+ # Trailblazer::Operation 1.492k i/100ms
1237
+ # Dry::Monads 7.224k i/100ms
1238
+ # Dry::Transaction 501.000 i/100ms
1239
+ # Micro::Case 9.664k i/100ms
1240
+ # Micro::Case::Strict 7.823k i/100ms
1241
+ # Micro::Case::Safe 9.464k i/100ms
1265
1242
 
1266
1243
  # Calculating -------------------------------------
1267
- # Interactor 13.227k3.3%) i/s - 66.950k in 5.067145s
1268
- # Trailblazer::Operation 14.591k4.0%) i/s - 73.829k in 5.069162s
1269
- # Dry::Monads 71.779k2.5%) i/s - 360.400k in 5.024294s
1270
- # Dry::Transaction 4.978k3.3%) i/s - 24.957k in 5.019153s
1271
- # Micro::Case 103.957k1.8%) i/s - 529.100k in 5.091221s
1272
- # Micro::Case::Strict 83.094k2.0%) i/s - 420.138k in 5.058233s
1273
- # Micro::Case::Safe 104.339k1.7%) i/s - 525.018k in 5.033381s
1244
+ # Interactor 13.770k4.3%) i/s - 68.992k in 5.020330s
1245
+ # Trailblazer::Operation 14.786k5.3%) i/s - 74.600k in 5.064700s
1246
+ # Dry::Monads 70.251k6.7%) i/s - 353.976k in 5.063010s
1247
+ # Dry::Transaction 4.994k4.0%) i/s - 25.050k in 5.023997s
1248
+ # Micro::Case 94.620k3.8%) i/s - 473.536k in 5.012483s
1249
+ # Micro::Case::Strict 76.059k3.0%) i/s - 383.327k in 5.044482s
1250
+ # Micro::Case::Safe 91.719k5.6%) i/s - 463.736k in 5.072552s
1274
1251
 
1275
1252
  # Comparison:
1276
- # Micro::Case::Safe: 104339.4 i/s
1277
- # Micro::Case: 103957.2 i/s - same-ish: difference falls within error
1278
- # Micro::Case::Strict: 83094.5 i/s - 1.26x (± 0.00) slower
1279
- # Dry::Monads: 71779.2 i/s - 1.45x (± 0.00) slower
1280
- # Trailblazer::Operation: 14590.6 i/s - 7.15x (± 0.00) slower
1281
- # Interactor: 13226.5 i/s - 7.89x (± 0.00) slower
1282
- # Dry::Transaction: 4978.1 i/s - 20.96x (± 0.00) slower
1253
+ # Micro::Case: 94619.6 i/s
1254
+ # Micro::Case::Safe: 91719.4 i/s - same-ish: difference falls within error
1255
+ # Micro::Case::Strict: 76058.7 i/s - 1.24x (± 0.00) slower
1256
+ # Dry::Monads: 70250.6 i/s - 1.35x (± 0.00) slower
1257
+ # Trailblazer::Operation: 14786.1 i/s - 6.40x (± 0.00) slower
1258
+ # Interactor: 13770.0 i/s - 6.87x (± 0.00) slower
1259
+ # Dry::Transaction: 4994.4 i/s - 18.95x (± 0.00) slower
1283
1260
  ```
1284
1261
  </details>
1285
1262
 
@@ -1287,33 +1264,42 @@ https://github.com/serradura/u-case/blob/master/benchmarks/use_case/with_failure
1287
1264
 
1288
1265
  ---
1289
1266
 
1290
- ### `Micro::Case::Flow` (v2.6.0)
1267
+ ### `Micro::Cases::Flow` (v3.0.0)
1291
1268
 
1292
1269
  | Gems / Abstraction | [Success results](https://github.com/serradura/u-case/blob/master/benchmarks/flow/with_success_result.rb#L40) | [Failure results](https://github.com/serradura/u-case/blob/master/benchmarks/flow/with_failure_result.rb#L40) |
1293
- | ------------------ | ----------------: | ----------------: |
1294
- | Micro::Case::Flow | _**The Fastest**_ | _**The Fastest**_ |
1295
- | Micro::Case::Safe::Flow | 0x slower | 0x slower |
1296
- | Interactor::Organizer | 1.27x slower | 5.48x slower |
1270
+ | ------------------------------------------- | ----------------: | ----------------: |
1271
+ | Micro::Case internal flow (private methods) | _**The Fastest**_ | _**The Fastest**_ |
1272
+ | Micro::Case `then` method | 1.48x slower | 0x slower |
1273
+ | Micro::Cases.flow | 1.62x slower | 1.16x slower |
1274
+ | Micro::Cases.safe_flow | 1.64x slower | 1.16x slower |
1275
+ | Interactor::Organizer | 1.95x slower | 6.17x slower |
1297
1276
 
1298
- \* The `Dry::Monads`, `Dry::Transaction`, `Trailblazer::Operation` are out of this analysis because all of them doesn't have this kind of feature.
1277
+ \* The `Dry::Monads`, `Dry::Transaction`, `Trailblazer::Operation` gems are out of this analysis because all of them doesn't have this kind of feature.
1299
1278
 
1300
1279
  <details>
1301
1280
  <summary><strong>Success results</strong> - Show the full benchmark/ips results.</summary>
1302
1281
 
1303
1282
  ```ruby
1304
1283
  # Warming up --------------------------------------
1305
- # Interactor::Organizer 4.765k i/100ms
1306
- # Micro::Case::Flow 5.372k i/100ms
1307
- # Micro::Case::Safe::Flow 5.855k i/100ms
1284
+ # Interactor::Organizer 5.219k i/100ms
1285
+ # Micro::Cases.flow([]) 6.451k i/100ms
1286
+ # Micro::Cases::safe_flow([]) 6.421k i/100ms
1287
+ # Micro::Case flow using `then` method 7.139k i/100ms
1288
+ # Micro::Case flow using private methods 10.355k i/100ms
1289
+
1308
1290
  # Calculating -------------------------------------
1309
- # Interactor::Organizer 48.598k5.2%) i/s - 243.015k in 5.014307s
1310
- # Micro::Case::Flow 61.606k4.4%) i/s - 311.576k in 5.068602s
1311
- # Micro::Case::Safe::Flow 60.688k4.8%) i/s - 304.460k in 5.028877s
1291
+ # Interactor::Organizer 52.959k1.7%) i/s - 266.169k in 5.027332s
1292
+ # Micro::Cases.flow([]) 63.947k1.7%) i/s - 322.550k in 5.045597s
1293
+ # Micro::Cases::safe_flow([]) 63.047k3.1%) i/s - 321.050k in 5.097228s
1294
+ # Micro::Case flow using `then` method 69.644k (± 4.0%) i/s - 349.811k in 5.031120s
1295
+ # Micro::Case flow using private methods 103.297k (± 1.4%) i/s - 517.750k in 5.013254s
1312
1296
 
1313
1297
  # Comparison:
1314
- # Micro::Case::Flow: 61606.3 i/s
1315
- # Micro::Case::Safe::Flow: 60688.3 i/s - same-ish: difference falls within error
1316
- # Interactor::Organizer: 48598.2 i/s - 1.27x slower\
1298
+ # Micro::Case flow using private methods: 103297.4 i/s
1299
+ # Micro::Case flow using `then` method: 69644.0 i/s - 1.48x (± 0.00) slower
1300
+ # Micro::Cases.flow([]): 63946.7 i/s - 1.62x (± 0.00) slower
1301
+ # Micro::Cases::safe_flow([]): 63047.2 i/s - 1.64x (± 0.00) slower
1302
+ # Interactor::Organizer: 52958.9 i/s - 1.95x (± 0.00) slower
1317
1303
  ```
1318
1304
  </details>
1319
1305
 
@@ -1322,19 +1308,25 @@ https://github.com/serradura/u-case/blob/master/benchmarks/use_case/with_failure
1322
1308
 
1323
1309
  ```ruby
1324
1310
  # Warming up --------------------------------------
1325
- # Interactor::Organizer 2.209k i/100ms
1326
- # Micro::Case::Flow 11.508k i/100ms
1327
- # Micro::Case::Safe::Flow 11.605k i/100ms
1311
+ # Interactor::Organizer 2.381k i/100ms
1312
+ # Micro::Cases.flow([]) 12.003k i/100ms
1313
+ # Micro::Cases::safe_flow([]) 12.771k i/100ms
1314
+ # Micro::Case flow using `then` method 15.085k i/100ms
1315
+ # Micro::Case flow using private methods 14.254k i/100ms
1328
1316
 
1329
1317
  # Calculating -------------------------------------
1330
- # Interactor::Organizer 22.592k (± 2.8%) i/s - 114.868k in 5.088685s
1331
- # Micro::Case::Flow 123.629k2.9%) i/s - 621.432k in 5.030844s
1332
- # Micro::Case::Safe::Flow 123.862k (± 3.0%) i/s - 626.670k in 5.064097s
1318
+ # Interactor::Organizer 23.579k3.2%) i/s - 119.050k in 5.054410s
1319
+ # Micro::Cases.flow([]) 124.072k3.4%) i/s - 624.156k in 5.036618s
1320
+ # Micro::Cases::safe_flow([]) 124.894k (± 3.6%) i/s - 625.779k in 5.017494s
1321
+ # Micro::Case flow using `then` method 145.370k (± 4.8%) i/s - 739.165k in 5.096972s
1322
+ # Micro::Case flow using private methods 139.753k (± 5.6%) i/s - 698.446k in 5.015207s
1333
1323
 
1334
1324
  # Comparison:
1335
- # Micro::Case::Safe::Flow: 123862.4 i/s
1336
- # Micro::Case::Flow: 123629.3 i/s - same-ish: difference falls within error
1337
- # Interactor::Organizer: 22592.2 i/s - 5.48x slower
1325
+ # Micro::Case flow using `then` method: 145369.7 i/s
1326
+ # Micro::Case flow using private methods: 139753.4 i/s - same-ish: difference falls within error
1327
+ # Micro::Cases::safe_flow([]): 124893.7 i/s - 1.16x (± 0.00) slower
1328
+ # Micro::Cases.flow([]): 124071.8 i/s - 1.17x (± 0.00) slower
1329
+ # Interactor::Organizer: 23578.7 i/s - 6.17x (± 0.00) slower
1338
1330
  ```
1339
1331
  </details>
1340
1332
 
@@ -1353,7 +1345,7 @@ Check it out implementations of the same use case with different gems/abstractio
1353
1345
 
1354
1346
  ### 1️⃣ Rails App (API)
1355
1347
 
1356
- > This project shows different kinds of architecture (one per commit), and in the last one, how to use the Micro::Case gem to handle the application business logic.
1348
+ > This project shows different kinds of architecture (one per commit), and in the last one, how to use the `Micro::Case` gem to handle the application business logic.
1357
1349
  >
1358
1350
  > Link: https://github.com/serradura/from-fat-controllers-to-use-cases
1359
1351
 
@@ -1365,11 +1357,11 @@ Check it out implementations of the same use case with different gems/abstractio
1365
1357
 
1366
1358
  ### 3️⃣ Users creation
1367
1359
 
1368
- > An example of a use case flow that define steps to sanitize, validate, and persist its input data.
1360
+ > An example of a use case flow that defines steps to sanitize, validate, and persist its input data.
1369
1361
  >
1370
1362
  > Link: https://github.com/serradura/u-case/blob/master/examples/users_creation.rb
1371
1363
 
1372
- ### 4️⃣ Rescuing exception inside of the use cases
1364
+ ### 4️⃣ Rescuing exceptions inside of the use cases
1373
1365
 
1374
1366
  > Link: https://github.com/serradura/u-case/blob/master/examples/rescuing_exceptions.rb
1375
1367