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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a0411016e16662d422a9f6b641ae91a516225e877f5cd8951058b479ea1b413d
4
- data.tar.gz: 586af968d98bf2add7a9882a894db2ea4e6ada5eb3c3e31eae39a1d09e2410bf
3
+ metadata.gz: 3ba53faeaf465b491f94a686da7fc2537e9c50108b18162d11c473246e6a531e
4
+ data.tar.gz: 6b91c842ad57b917678649f4003f34ade8459a70c56938d2e226a4d8322e855d
5
5
  SHA512:
6
- metadata.gz: ab3231e87cca1c25cc5148f922292177239738da22a7f1528bd4cdc56a601028c4a4e9eec0660e00c1cfc0a126746c53f37db159002639d9226f22cec931b812
7
- data.tar.gz: 308404bc8b913d4ef84cd59e31fecd18b6bfe5ba51c6724d4a8880525c6058d01bf7b669676a843f2ff47754a7db9e643abcbbd53f50b178d72efce6c979eb40
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)](#μ-case-microcase)
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 using the use case itself?](#is-it-possible-to-declare-a-flow-using-the-use-case-itself)
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-casewith_validation---how-to-validate-use-case-attributes)
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 using the use case itself?
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. [Rescuing an exception inside of use cases](https://github.com/serradura/u-case/blob/master/examples/rescuing_exceptions.rb)
1026
- 2. [Users creation](https://github.com/serradura/u-case/blob/master/examples/users_creation.rb)
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
- An example of flow in how to define steps to sanitize, validate, and persist some input data.
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
- A more complex example which use rake tasks to demonstrate how to handle user data, and how to use different failures type to control the program flow.
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
 
@@ -42,35 +42,57 @@ module Micro
42
42
  instance
43
43
  end
44
44
 
45
- def self.__get_flow__
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.__set_flow__(reducer, args)
50
- def self.use_cases; __get_flow__.use_cases; end
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
- reducer.build(args)
83
+ @__flow = __flow_reducer.build(args)
55
84
  end
56
85
 
57
- def self.flow(*args)
58
- @__flow ||= __set_flow__(Flow::Reducer, args)
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.call!
62
- return const_get(:Flow_Step) if const_defined?(:Flow_Step)
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
- @__input = input
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 self.class.__get_flow__.call(@__input) if self.class.__get_flow__
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
 
@@ -4,7 +4,7 @@ module Micro
4
4
  class Case
5
5
  class Safe < ::Micro::Case
6
6
  def call
7
- super
7
+ __call
8
8
  rescue => exception
9
9
  raise exception if Error::ByWrongUsage.check(exception)
10
10
 
@@ -36,8 +36,8 @@ module Micro
36
36
  Flow::Reducer.build(Array(args))
37
37
  end
38
38
 
39
- def self.flow(*args)
40
- @__flow ||= __set_flow__(Flow::Reducer, args)
39
+ def self.__flow_reducer
40
+ Flow::Reducer
41
41
  end
42
42
  end
43
43
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Micro
4
4
  class Case
5
- VERSION = '2.1.1'.freeze
5
+ VERSION = '2.2.0'.freeze
6
6
  end
7
7
  end
@@ -15,21 +15,19 @@ module Micro
15
15
  end
16
16
 
17
17
  def initialize(input)
18
- @__input = input
19
- self.attributes = input
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 __call_use_case
26
- return failure_by_validation_error(self) if !self.class.auto_validation_disabled? && invalid?
27
-
28
- result = call!
25
+ def __call
26
+ return __call_use_case_flow if __call_use_case_flow?
29
27
 
30
- return result if result.is_a?(Result)
28
+ return failure_by_validation_error(self) if !self.class.auto_validation_disabled? && invalid?
31
29
 
32
- raise Error::UnexpectedResult.new(self.class)
30
+ __call_use_case
33
31
  end
34
32
 
35
33
  def failure_by_validation_error(object)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: u-case
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura