u-case 2.1.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +33 -14
- data/lib/micro/case.rb +55 -17
- data/lib/micro/case/safe.rb +1 -1
- data/lib/micro/case/safe/flow.rb +2 -2
- data/lib/micro/case/version.rb +1 -1
- data/lib/micro/case/with_validation.rb +6 -8
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ba53faeaf465b491f94a686da7fc2537e9c50108b18162d11c473246e6a531e
|
4
|
+
data.tar.gz: 6b91c842ad57b917678649f4003f34ade8459a70c56938d2e226a4d8322e855d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d4790abfb49211a69d9874900e83a0237d5fe0f0b288102e9bcff33fd932db4192e66ea2e5814990da2d5e92b5499dd93173257433639e2248463f2b3c991e8
|
7
|
+
data.tar.gz: e2bd4e73018961d931a76298dacf8000836d26f2331f975b777bc0371dcfe84d2064a51ef12636f31eaf22986a76b97f99e7cbe16b653a1bd1923ae5f8f4f125
|
data/README.md
CHANGED
@@ -15,8 +15,10 @@ The main project goals are:
|
|
15
15
|
4. Solve complex business logic, by allowing the composition of use cases.
|
16
16
|
5. Be fast and optimized (Check out the [benchmarks](#benchmarks) section).
|
17
17
|
|
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.
|
19
|
+
|
18
20
|
## Table of Contents <!-- omit in toc -->
|
19
|
-
- [μ-case (Micro::Case)](
|
21
|
+
- [μ-case (Micro::Case)](#%ce%bc-case-microcase)
|
20
22
|
- [Required Ruby version](#required-ruby-version)
|
21
23
|
- [Dependencies](#dependencies)
|
22
24
|
- [Installation](#installation)
|
@@ -32,10 +34,10 @@ The main project goals are:
|
|
32
34
|
- [Micro::Case::Flow - How to compose use cases?](#microcaseflow---how-to-compose-use-cases)
|
33
35
|
- [Is it possible to compose a use case flow with other ones?](#is-it-possible-to-compose-a-use-case-flow-with-other-ones)
|
34
36
|
- [Is it possible a flow accumulates its input and merges each success result to use as the argument of their use cases?](#is-it-possible-a-flow-accumulates-its-input-and-merges-each-success-result-to-use-as-the-argument-of-their-use-cases)
|
35
|
-
- [Is it possible to declare a flow
|
37
|
+
- [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)
|
36
38
|
- [Micro::Case::Strict - What is a strict use case?](#microcasestrict---what-is-a-strict-use-case)
|
37
39
|
- [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)
|
38
|
-
- [u-case/with_validation - How to validate use case attributes?](#u-
|
40
|
+
- [u-case/with_validation - How to validate use case attributes?](#u-casewithvalidation---how-to-validate-use-case-attributes)
|
39
41
|
- [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)
|
40
42
|
- [Benchmarks](#benchmarks)
|
41
43
|
- [Micro::Case](#microcase)
|
@@ -45,6 +47,10 @@ The main project goals are:
|
|
45
47
|
- [Micro::Case::Flow](#microcaseflow)
|
46
48
|
- [Comparisons](#comparisons)
|
47
49
|
- [Examples](#examples)
|
50
|
+
- [1️⃣ Rails App (API)](#1%ef%b8%8f%e2%83%a3-rails-app-api)
|
51
|
+
- [2️⃣ CLI calculator](#2%ef%b8%8f%e2%83%a3-cli-calculator)
|
52
|
+
- [3️⃣ Users creation](#3%ef%b8%8f%e2%83%a3-users-creation)
|
53
|
+
- [4️⃣ Rescuing exception inside of the use cases](#4%ef%b8%8f%e2%83%a3-rescuing-exception-inside-of-the-use-cases)
|
48
54
|
- [Development](#development)
|
49
55
|
- [Contributing](#contributing)
|
50
56
|
- [License](#license)
|
@@ -598,7 +604,7 @@ Answer: Yes, it is! Check out these test examples [Micro::Case::Flow](https://gi
|
|
598
604
|
|
599
605
|
[⬆️ Back to Top](#table-of-contents-)
|
600
606
|
|
601
|
-
#### Is it possible to declare a flow
|
607
|
+
#### Is it possible to declare a flow which includes the use case itself?
|
602
608
|
|
603
609
|
Answer: Yes, it is! You can use the `self.call!` macro. e.g:
|
604
610
|
|
@@ -620,16 +626,15 @@ class ConvertNumberToText < Micro::Case
|
|
620
626
|
end
|
621
627
|
|
622
628
|
class Double < Micro::Case
|
629
|
+
flow ConvertTextToNumber,
|
630
|
+
self.call!,
|
631
|
+
ConvertNumberToText
|
632
|
+
|
623
633
|
attribute :number
|
624
634
|
|
625
635
|
def call!
|
626
636
|
Success { { number: number * 2 } }
|
627
637
|
end
|
628
|
-
|
629
|
-
# NOTE: You need to declare the flow after the definition of the attributes.
|
630
|
-
flow ConvertTextToNumber,
|
631
|
-
self.call!,
|
632
|
-
ConvertNumberToText
|
633
638
|
end
|
634
639
|
|
635
640
|
result = Double.call(text: '4')
|
@@ -1022,13 +1027,27 @@ Check it out implementations of the same use case with different gems/abstractio
|
|
1022
1027
|
|
1023
1028
|
## Examples
|
1024
1029
|
|
1025
|
-
1
|
1026
|
-
|
1030
|
+
### 1️⃣ Rails App (API)
|
1031
|
+
|
1032
|
+
> 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.
|
1033
|
+
>
|
1034
|
+
> Link: https://github.com/serradura/from-fat-controllers-to-use-cases
|
1035
|
+
|
1036
|
+
### 2️⃣ CLI calculator
|
1037
|
+
|
1038
|
+
> Rake tasks to demonstrate how to handle user data, and how to use different failure types to control the program flow.
|
1039
|
+
>
|
1040
|
+
> Link: https://github.com/serradura/u-case/tree/master/examples/calculator
|
1041
|
+
|
1042
|
+
### 3️⃣ Users creation
|
1043
|
+
|
1044
|
+
> An example of a use case flow that define steps to sanitize, validate, and persist its input data.
|
1045
|
+
>
|
1046
|
+
> Link: https://github.com/serradura/u-case/blob/master/examples/users_creation.rb
|
1027
1047
|
|
1028
|
-
|
1029
|
-
3. [CLI calculator](https://github.com/serradura/u-case/tree/master/examples/calculator)
|
1048
|
+
### 4️⃣ Rescuing exception inside of the use cases
|
1030
1049
|
|
1031
|
-
|
1050
|
+
> Link: https://github.com/serradura/u-case/blob/master/examples/rescuing_exceptions.rb
|
1032
1051
|
|
1033
1052
|
[⬆️ Back to Top](#table-of-contents-)
|
1034
1053
|
|
data/lib/micro/case.rb
CHANGED
@@ -42,35 +42,57 @@ module Micro
|
|
42
42
|
instance
|
43
43
|
end
|
44
44
|
|
45
|
-
def self.
|
45
|
+
def self.__call!
|
46
|
+
return const_get(:Flow_Step) if const_defined?(:Flow_Step)
|
47
|
+
|
48
|
+
const_set(:Flow_Step, Class.new(self) do
|
49
|
+
private def __call
|
50
|
+
__call_use_case
|
51
|
+
end
|
52
|
+
end)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.call!
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.__flow_reducer
|
60
|
+
Flow::Reducer
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.__flow_get
|
46
64
|
@__flow
|
47
65
|
end
|
48
66
|
|
49
|
-
private_class_method def self.
|
50
|
-
|
67
|
+
private_class_method def self.__flow_use_cases_set(args)
|
68
|
+
@__flow_use_cases = args
|
69
|
+
end
|
70
|
+
|
71
|
+
private_class_method def self.__flow_use_cases_get
|
72
|
+
Array(@__flow_use_cases)
|
73
|
+
.map { |use_case| use_case == self ? self.__call! : use_case }
|
74
|
+
end
|
75
|
+
|
76
|
+
private_class_method def self.__flow_set(args)
|
77
|
+
return if __flow_get
|
78
|
+
|
79
|
+
def self.use_cases; __flow_get.use_cases; end
|
51
80
|
|
52
81
|
self.class_eval('def use_cases; self.class.use_cases; end')
|
53
82
|
|
54
|
-
|
83
|
+
@__flow = __flow_reducer.build(args)
|
55
84
|
end
|
56
85
|
|
57
|
-
def self.
|
58
|
-
|
86
|
+
def self.__flow_set!
|
87
|
+
__flow_set(__flow_use_cases_get) if !__flow_get && @__flow_use_cases
|
59
88
|
end
|
60
89
|
|
61
|
-
def self.
|
62
|
-
|
63
|
-
|
64
|
-
const_set(:Flow_Step, Class.new(self) do
|
65
|
-
private def __call
|
66
|
-
__call_use_case
|
67
|
-
end
|
68
|
-
end)
|
90
|
+
def self.flow(*args)
|
91
|
+
__flow_use_cases_set(args)
|
69
92
|
end
|
70
93
|
|
71
94
|
def initialize(input)
|
72
|
-
|
73
|
-
self.attributes = input
|
95
|
+
__setup_use_case(input)
|
74
96
|
end
|
75
97
|
|
76
98
|
def call!
|
@@ -90,8 +112,16 @@ module Micro
|
|
90
112
|
|
91
113
|
private
|
92
114
|
|
115
|
+
def __setup_use_case(input)
|
116
|
+
self.class.__flow_set!
|
117
|
+
|
118
|
+
@__input = input
|
119
|
+
|
120
|
+
self.attributes = input
|
121
|
+
end
|
122
|
+
|
93
123
|
def __call
|
94
|
-
return
|
124
|
+
return __call_use_case_flow if __call_use_case_flow?
|
95
125
|
|
96
126
|
__call_use_case
|
97
127
|
end
|
@@ -104,6 +134,14 @@ module Micro
|
|
104
134
|
raise Error::UnexpectedResult.new(self.class)
|
105
135
|
end
|
106
136
|
|
137
|
+
def __call_use_case_flow?
|
138
|
+
self.class.__flow_get
|
139
|
+
end
|
140
|
+
|
141
|
+
def __call_use_case_flow
|
142
|
+
self.class.__flow_get.call(@__input)
|
143
|
+
end
|
144
|
+
|
107
145
|
def Success(arg = :ok)
|
108
146
|
value, type = block_given? ? [yield, arg] : [arg, :ok]
|
109
147
|
|
data/lib/micro/case/safe.rb
CHANGED
data/lib/micro/case/safe/flow.rb
CHANGED
data/lib/micro/case/version.rb
CHANGED
@@ -15,21 +15,19 @@ module Micro
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def initialize(input)
|
18
|
-
|
19
|
-
|
18
|
+
__setup_use_case(input)
|
19
|
+
|
20
20
|
run_validations! if respond_to?(:run_validations!, true)
|
21
21
|
end
|
22
22
|
|
23
23
|
private
|
24
24
|
|
25
|
-
def
|
26
|
-
return
|
27
|
-
|
28
|
-
result = call!
|
25
|
+
def __call
|
26
|
+
return __call_use_case_flow if __call_use_case_flow?
|
29
27
|
|
30
|
-
return
|
28
|
+
return failure_by_validation_error(self) if !self.class.auto_validation_disabled? && invalid?
|
31
29
|
|
32
|
-
|
30
|
+
__call_use_case
|
33
31
|
end
|
34
32
|
|
35
33
|
def failure_by_validation_error(object)
|