u-service 0.13.0 → 0.13.1

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: f637ed45a67693473bf30661b6a4822f1d6ea15246d46b24df3051546781a16b
4
- data.tar.gz: ec7c4d4c8052ff1f293b9323bdb447505880dd658a1d0e6219dd2233a40a2b1a
3
+ metadata.gz: b93d4099f9d4f7646b94241bb5b66190635dff1a56781c7aa152fb458acce958
4
+ data.tar.gz: bf4a7a017a8fbc891904a74ffa80b8aaaadc577cfcfd178e062ed42410dfec9a
5
5
  SHA512:
6
- metadata.gz: 5339646f0ce88b4842c9f8d0425ddb16c5edacb81f97dea46eb695da625a2b142fb24a15bf7256f16952f5fb45526c0d812ab8e7a54ac045ce49959ff5a1b637
7
- data.tar.gz: 1927b9f7da2f9a5ca5ea369c768173485ff704e3fb8142eccaa612484e6c83a9aeba7589c11f61d573ed7a0b341ba437003f5e9e57bb74eb76ef5789fde84169
6
+ metadata.gz: 7d69adaf4e77a2707904a31a29ffd51abc866a27cdd210039b24c5def4ce9fbbbb0dec88e0b39bbfe6e855692d2a186c0931de6225d0269de6b972f048de936e
7
+ data.tar.gz: eb3812b5a44fa8742560eee26e49fd987f6bb4a5fb30e35aafa6a0b6d870c4a96b62a9a1af5b5387c7a58b8e97d45e739b64b4768d95bdd53c3784fa4df879f2
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Micro
4
4
  module Service
5
- VERSION = '0.13.0'.freeze
5
+ VERSION = '0.13.1'.freeze
6
6
  end
7
7
  end
data/u-service.gemspec CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
  # Specify which files should be added to the gem when it is released.
30
30
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
31
31
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
32
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
32
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|assets|benchmarks|comparisons|examples)/}) }
33
33
  end
34
34
  spec.bindir = 'exe'
35
35
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: u-service
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 0.13.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura
@@ -68,23 +68,8 @@ files:
68
68
  - LICENSE.txt
69
69
  - README.md
70
70
  - Rakefile
71
- - assets/u-service_benchmarks.png
72
- - benchmarks/interactor/pipeline_failure.rb
73
- - benchmarks/interactor/pipeline_success.rb
74
- - benchmarks/interactor/service_failure.rb
75
- - benchmarks/interactor/service_success.rb
76
71
  - bin/console
77
72
  - bin/setup
78
- - comparisons/interactor.rb
79
- - comparisons/u-service.rb
80
- - examples/calculator/README.md
81
- - examples/calculator/Rakefile
82
- - examples/calculator/assets/usage.gif
83
- - examples/calculator/calc/normalize_args.rb
84
- - examples/calculator/calc/operation.rb
85
- - examples/calculator/calc/transform_into_numbers.rb
86
- - examples/rescuing_exceptions.rb
87
- - examples/users_creation.rb
88
73
  - lib/micro/service.rb
89
74
  - lib/micro/service/base.rb
90
75
  - lib/micro/service/pipeline.rb
Binary file
@@ -1,134 +0,0 @@
1
- require 'bundler/inline'
2
-
3
- gemfile do
4
- source 'https://rubygems.org'
5
-
6
- gem 'benchmark-ips', '~> 2.7', '>= 2.7.2'
7
- gem 'interactor', '~> 3.1', '>= 3.1.1'
8
- gem 'u-service', '~> 0.12.0'
9
- end
10
-
11
- require 'benchmark/ips'
12
-
13
- module IT
14
- class ConvertToNumbers
15
- include Interactor
16
-
17
- def call
18
- numbers = context.numbers
19
-
20
- if numbers.all? { |value| String(value) =~ /\d+/ }
21
- context.numbers = numbers.map(&:to_i)
22
- else
23
- context.fail! numbers: 'must contain only numeric types'
24
- end
25
- end
26
- end
27
-
28
- class Add2
29
- include Interactor
30
-
31
- def call
32
- numbers = context.numbers
33
-
34
- context.numbers = numbers.map { |number| number + 2 }
35
- end
36
- end
37
-
38
- class Add2ToAllNumbers
39
- include Interactor::Organizer
40
-
41
- organize ConvertToNumbers, Add2
42
- end
43
- end
44
-
45
- module MSB
46
- class ConvertToNumbers < Micro::Service::Base
47
- attribute :numbers
48
-
49
- def call!
50
- if numbers.all? { |value| String(value) =~ /\d+/ }
51
- Success(numbers: numbers.map(&:to_i))
52
- else
53
- Failure(numbers: 'must contain only numeric types')
54
- end
55
- end
56
- end
57
-
58
- class Add2 < Micro::Service::Base
59
- attribute :numbers
60
-
61
- def call!
62
- Success(numbers: numbers.map { |number| number + 2 })
63
- end
64
- end
65
-
66
- Add2ToAllNumbers = ConvertToNumbers >> Add2
67
- end
68
-
69
- module MSS
70
- class ConvertToNumbers < Micro::Service::Strict
71
- attribute :numbers
72
-
73
- def call!
74
- if numbers.all? { |value| String(value) =~ /\d+/ }
75
- Success(numbers: numbers.map(&:to_i))
76
- else
77
- Failure(numbers: 'must contain only numeric types')
78
- end
79
- end
80
- end
81
-
82
- class Add2 < Micro::Service::Strict
83
- attribute :numbers
84
-
85
- def call!
86
- Success(numbers: numbers.map { |number| number + 2 })
87
- end
88
- end
89
-
90
- Add2ToAllNumbers = ConvertToNumbers >> Add2
91
- end
92
-
93
- NUMBERS = {numbers: %w[1 1 2 2 c 4]}
94
-
95
- Benchmark.ips do |x|
96
- x.config(:time => 5, :warmup => 2)
97
-
98
- x.time = 5
99
- x.warmup = 2
100
-
101
- x.report('Interactor::Organizer') do
102
- IT::Add2ToAllNumbers.call(NUMBERS)
103
- end
104
-
105
- x.report('Pipeline of Micro::Service::Base') do
106
- MSB::Add2ToAllNumbers.call(NUMBERS)
107
- end
108
-
109
- x.report('Pipeline of Micro::Service::Strict') do
110
- MSS::Add2ToAllNumbers.call(NUMBERS)
111
- end
112
-
113
- x.compare!
114
- end
115
-
116
- # Warming up --------------------------------------
117
- # Interactor::Organizer
118
- # 2.355k i/100ms
119
- # Pipeline of Micro::Service::Base
120
- # 15.483k i/100ms
121
- # Pipeline of Micro::Service::Strict
122
- # 13.467k i/100ms
123
- # Calculating -------------------------------------
124
- # Interactor::Organizer
125
- # 23.767k (± 2.1%) i/s - 120.105k in 5.055726s
126
- # Pipeline of Micro::Service::Base
127
- # 166.013k (± 1.8%) i/s - 836.082k in 5.037938s
128
- # Pipeline of Micro::Service::Strict
129
- # 141.545k (± 2.1%) i/s - 713.751k in 5.044932s
130
-
131
- # Comparison:
132
- # Pipeline of Micro::Service::Base: 166013.1 i/s
133
- # Pipeline of Micro::Service::Strict: 141545.4 i/s - 1.17x slower
134
- # Interactor::Organizer: 23766.6 i/s - 6.99x slower
@@ -1,134 +0,0 @@
1
- require 'bundler/inline'
2
-
3
- gemfile do
4
- source 'https://rubygems.org'
5
-
6
- gem 'benchmark-ips', '~> 2.7', '>= 2.7.2'
7
- gem 'interactor', '~> 3.1', '>= 3.1.1'
8
- gem 'u-service', '~> 0.12.0'
9
- end
10
-
11
- require 'benchmark/ips'
12
-
13
- module IT
14
- class ConvertToNumbers
15
- include Interactor
16
-
17
- def call
18
- numbers = context.numbers
19
-
20
- if numbers.all? { |value| String(value) =~ /\d+/ }
21
- context.numbers = numbers.map(&:to_i)
22
- else
23
- context.fail! numbers: 'must contain only numeric types'
24
- end
25
- end
26
- end
27
-
28
- class Add2
29
- include Interactor
30
-
31
- def call
32
- numbers = context.numbers
33
-
34
- context.numbers = numbers.map { |number| number + 2 }
35
- end
36
- end
37
-
38
- class Add2ToAllNumbers
39
- include Interactor::Organizer
40
-
41
- organize ConvertToNumbers, Add2
42
- end
43
- end
44
-
45
- module MSB
46
- class ConvertToNumbers < Micro::Service::Base
47
- attribute :numbers
48
-
49
- def call!
50
- if numbers.all? { |value| String(value) =~ /\d+/ }
51
- Success(numbers: numbers.map(&:to_i))
52
- else
53
- Failure(numbers: 'must contain only numeric types')
54
- end
55
- end
56
- end
57
-
58
- class Add2 < Micro::Service::Base
59
- attribute :numbers
60
-
61
- def call!
62
- Success(numbers: numbers.map { |number| number + 2 })
63
- end
64
- end
65
-
66
- Add2ToAllNumbers = ConvertToNumbers >> Add2
67
- end
68
-
69
- module MSS
70
- class ConvertToNumbers < Micro::Service::Strict
71
- attribute :numbers
72
-
73
- def call!
74
- if numbers.all? { |value| String(value) =~ /\d+/ }
75
- Success(numbers: numbers.map(&:to_i))
76
- else
77
- Failure(numbers: 'must contain only numeric types')
78
- end
79
- end
80
- end
81
-
82
- class Add2 < Micro::Service::Strict
83
- attribute :numbers
84
-
85
- def call!
86
- Success(numbers: numbers.map { |number| number + 2 })
87
- end
88
- end
89
-
90
- Add2ToAllNumbers = ConvertToNumbers >> Add2
91
- end
92
-
93
- NUMBERS = {numbers: %w[1 1 2 2 3 4]}
94
-
95
- Benchmark.ips do |x|
96
- x.config(:time => 5, :warmup => 2)
97
-
98
- x.time = 5
99
- x.warmup = 2
100
-
101
- x.report('Interactor::Organizer') do
102
- IT::Add2ToAllNumbers.call(NUMBERS)
103
- end
104
-
105
- x.report('Pipeline of Micro::Service::Base') do
106
- MSB::Add2ToAllNumbers.call(NUMBERS)
107
- end
108
-
109
- x.report('Pipeline of Micro::Service::Strict') do
110
- MSS::Add2ToAllNumbers.call(NUMBERS)
111
- end
112
-
113
- x.compare!
114
- end
115
-
116
- # Warming up --------------------------------------
117
- # Interactor::Organizer
118
- # 5.047k i/100ms
119
- # Pipeline of Micro::Service::Base
120
- # 8.069k i/100ms
121
- # Pipeline of Micro::Service::Strict
122
- # 6.706k i/100ms
123
- # Calculating -------------------------------------
124
- # Interactor::Organizer
125
- # 50.656k (± 2.4%) i/s - 257.397k in 5.084184s
126
- # Pipeline of Micro::Service::Base
127
- # 83.309k (± 1.5%) i/s - 419.588k in 5.037749s
128
- # Pipeline of Micro::Service::Strict
129
- # 69.195k (± 1.7%) i/s - 348.712k in 5.041089s
130
-
131
- # Comparison:
132
- # Pipeline of Micro::Service::Base: 83309.3 i/s
133
- # Pipeline of Micro::Service::Strict: 69195.1 i/s - 1.20x slower
134
- # Interactor::Organizer: 50656.5 i/s - 1.64x slower
@@ -1,93 +0,0 @@
1
- require 'bundler/inline'
2
-
3
- gemfile do
4
- source 'https://rubygems.org'
5
-
6
- gem 'benchmark-ips', '~> 2.7', '>= 2.7.2'
7
- gem 'interactor', '~> 3.1', '>= 3.1.1'
8
- gem 'u-service', '~> 0.12.0'
9
- end
10
-
11
- require 'benchmark/ips'
12
-
13
- class IT_Multiply
14
- include Interactor
15
-
16
- def call
17
- a = context.a
18
- b = context.b
19
-
20
- if a.is_a?(Numeric) && b.is_a?(Numeric)
21
- context.number = a * b
22
- else
23
- context.fail!(type: :invalid_data)
24
- end
25
- end
26
- end
27
-
28
- class MSB_Multiply < Micro::Service::Base
29
- attributes :a, :b
30
-
31
- def call!
32
- if a.is_a?(Numeric) && b.is_a?(Numeric)
33
- Success(a * b)
34
- else
35
- Failure(:invalid_data)
36
- end
37
- end
38
- end
39
-
40
- class MSS_Multiply < Micro::Service::Strict
41
- attributes :a, :b
42
-
43
- def call!
44
- if a.is_a?(Numeric) && b.is_a?(Numeric)
45
- Success(a * b)
46
- else
47
- Failure(:invalid_data)
48
- end
49
- end
50
- end
51
-
52
- SYMBOL_KEYS = { a: nil, b: 2 }
53
- STRING_KEYS = { 'a' => 1, 'b' => '' }
54
-
55
- Benchmark.ips do |x|
56
- x.config(:time => 5, :warmup => 2)
57
-
58
- x.time = 5
59
- x.warmup = 2
60
-
61
- x.report('Interactor') do
62
- IT_Multiply.call(SYMBOL_KEYS)
63
- IT_Multiply.call(STRING_KEYS)
64
- end
65
-
66
- x.report('Micro::Service::Base') do
67
- MSB_Multiply.call(SYMBOL_KEYS)
68
- MSB_Multiply.call(STRING_KEYS)
69
- end
70
-
71
- x.report('Micro::Service::Strict') do
72
- MSS_Multiply.call(SYMBOL_KEYS)
73
- MSS_Multiply.call(STRING_KEYS)
74
- end
75
-
76
- x.compare!
77
- end
78
-
79
- # Warming up --------------------------------------
80
- # Interactor 1.507k i/100ms
81
- # Micro::Service::Base 12.902k i/100ms
82
- # Micro::Service::Strict
83
- # 9.758k i/100ms
84
- # Calculating -------------------------------------
85
- # Interactor 15.482k (± 2.6%) i/s - 78.364k in 5.065166s
86
- # Micro::Service::Base 134.861k (± 1.3%) i/s - 683.806k in 5.071263s
87
- # Micro::Service::Strict
88
- # 101.331k (± 1.5%) i/s - 507.416k in 5.008688s
89
-
90
- # Comparison:
91
- # Micro::Service::Base: 134861.1 i/s
92
- # Micro::Service::Strict: 101331.5 i/s - 1.33x slower
93
- # Interactor: 15482.0 i/s - 8.71x slower
@@ -1,93 +0,0 @@
1
- require 'bundler/inline'
2
-
3
- gemfile do
4
- source 'https://rubygems.org'
5
-
6
- gem 'benchmark-ips', '~> 2.7', '>= 2.7.2'
7
- gem 'interactor', '~> 3.1', '>= 3.1.1'
8
- gem 'u-service', '~> 0.12.0'
9
- end
10
-
11
- require 'benchmark/ips'
12
-
13
- class IT_Multiply
14
- include Interactor
15
-
16
- def call
17
- a = context.a
18
- b = context.b
19
-
20
- if a.is_a?(Numeric) && b.is_a?(Numeric)
21
- context.number = a * b
22
- else
23
- context.fail!(:invalid_data)
24
- end
25
- end
26
- end
27
-
28
- class MSB_Multiply < Micro::Service::Base
29
- attributes :a, :b
30
-
31
- def call!
32
- if a.is_a?(Numeric) && b.is_a?(Numeric)
33
- Success(a * b)
34
- else
35
- Failure(:invalid_data)
36
- end
37
- end
38
- end
39
-
40
- class MSS_Multiply < Micro::Service::Strict
41
- attributes :a, :b
42
-
43
- def call!
44
- if a.is_a?(Numeric) && b.is_a?(Numeric)
45
- Success(a * b)
46
- else
47
- Failure(:invalid_data)
48
- end
49
- end
50
- end
51
-
52
- SYMBOL_KEYS = { a: 2, b: 2 }
53
- STRING_KEYS = { 'a' => 1, 'b' => 1 }
54
-
55
- Benchmark.ips do |x|
56
- x.config(:time => 5, :warmup => 2)
57
-
58
- x.time = 5
59
- x.warmup = 2
60
-
61
- x.report('Interactor') do
62
- IT_Multiply.call(SYMBOL_KEYS)
63
- IT_Multiply.call(STRING_KEYS)
64
- end
65
-
66
- x.report('Micro::Service::Base') do
67
- MSB_Multiply.call(SYMBOL_KEYS)
68
- MSB_Multiply.call(STRING_KEYS)
69
- end
70
-
71
- x.report('Micro::Service::Strict') do
72
- MSS_Multiply.call(SYMBOL_KEYS)
73
- MSS_Multiply.call(STRING_KEYS)
74
- end
75
-
76
- x.compare!
77
- end
78
-
79
- # Warming up --------------------------------------
80
- # Interactor 2.943k i/100ms
81
- # Micro::Service::Base 12.540k i/100ms
82
- # Micro::Service::Strict
83
- # 9.584k i/100ms
84
- # Calculating -------------------------------------
85
- # Interactor 29.874k (± 2.7%) i/s - 150.093k in 5.027909s
86
- # Micro::Service::Base 131.440k (± 1.9%) i/s - 664.620k in 5.058327s
87
- # Micro::Service::Strict
88
- # 99.111k (± 2.2%) i/s - 498.368k in 5.031006s
89
-
90
- # Comparison:
91
- # Micro::Service::Base: 131440.3 i/s
92
- # Micro::Service::Strict: 99111.3 i/s - 1.33x slower
93
- # Interactor: 29873.6 i/s - 4.40x slower
@@ -1,57 +0,0 @@
1
- class CreateResponse
2
- include Interactor
3
-
4
- def call
5
- responder = context.responder
6
-
7
- survey_response = responder.survey_responses.build(
8
- response_text: context.answers[:text],
9
- rating: answers[:rating]
10
- survey: context.survey
11
- )
12
-
13
- if survey_response.save
14
- context.survey_response = survey_response
15
- else
16
- context.fail!(errors: survey_response.errors)
17
- end
18
- end
19
- end
20
-
21
- class AddRewardPoints
22
- include Interactor
23
-
24
- def call
25
- reward_account = context.responder.reward_account
26
-
27
- reward_account.balance += context.survey.reward_points
28
-
29
- unless reward_account.save
30
- context.fail!(errors: reward_account.errors)
31
- end
32
- end
33
- end
34
-
35
- class SendNotifications
36
- include Interactor
37
-
38
- def call
39
- sender = context.survey.sender
40
-
41
- SurveyMailer.delay.notify_responder(context.responder.id)
42
- SurveyMailer.delay.notify_sender(sender.id)
43
-
44
- unless sender.add_survey_response_notification
45
- context.fail!(errors: sender.errors)
46
- end
47
- end
48
- end
49
-
50
- class ReplyToSurvey
51
- include Interactor::Organizer
52
-
53
- organize CreateResponse, AddRewardPoints, SendNotifications
54
- end
55
-
56
- # https://gist.githubusercontent.com/raderj89/cbb84b1f75e67087388bc4cdbe617138/raw/a39c3ba6b416ac3919cc7d32bfa58e82211f24ef/interactor_example.rb
57
- # https://medium.com/reflektive-engineering/from-service-objects-to-interactors-db7d2bb7dfd9
@@ -1,61 +0,0 @@
1
- class CreateResponse < Micro::Service::Strict
2
- attributes :responder, :answers, :survey
3
-
4
- def call!
5
- survey_response = responder.survey_responses.build(
6
- response_text: answers[:text],
7
- rating: answers[:rating]
8
- survey: survey
9
- )
10
-
11
- return Success { attributes(:responder, :survey) } if survey_response.save
12
-
13
- Failure(:survey_response) { survey_response.errors }
14
- end
15
- end
16
-
17
- class AddRewardPoints < Micro::Service::Strict
18
- attributes :responder, :survey
19
-
20
- def call!
21
- reward_account = responder.reward_account
22
- reward_account.balance += survey.reward_points
23
-
24
- return Success { attributes(:responder, :survey) } if reward_account.save
25
-
26
- Failure(:reward_account) { reward_account.errors }
27
- end
28
- end
29
-
30
- class SendNotifications < Micro::Service::Strict
31
- attributes :responder, :survey
32
-
33
- def call!
34
- sender = survey.sender
35
-
36
- SurveyMailer.delay.notify_responder(responder.id)
37
- SurveyMailer.delay.notify_sender(sender.id)
38
-
39
- return Success { attributes(:survey) } if sender.add_survey_response_notification
40
-
41
- Failure(:sender) { sender.errors }
42
- end
43
- end
44
-
45
- ReplyToSurvey = CreateResponse >> AddRewardPoints >> SendNotifications
46
-
47
- # or
48
-
49
- ReplyToSurvey = Micro::Service::Pipeline[
50
- CreateResponse,
51
- AddRewardPoints,
52
- SendNotifications
53
- ]
54
-
55
- # or
56
-
57
- class ReplyToSurvey
58
- include Micro::Service::Pipeline
59
-
60
- pipeline CreateResponse, AddRewardPoints, SendNotifications
61
- end
@@ -1,56 +0,0 @@
1
- # μ-service - Calculator example
2
-
3
- This example uses [rake](http://rubygems.org/gems/rake) to expose a CLI calculator.
4
-
5
- ## Installation instructions
6
- ```sh
7
- gem install rake
8
- gem install u-service -v 0.12.0
9
- ```
10
-
11
- ### Usage
12
-
13
- ![gif](https://github.com/serradura/u-service/blob/master/examples/calculator/assets/usage.gif?raw=true)
14
-
15
- #### Listing the available rake tasks
16
- ```sh
17
- rake -T
18
-
19
- # rake calc:add[a,b] # adds two numbers
20
- # rake calc:divide[a,b] # divides two numbers
21
- # rake calc:multiply[a,b] # multiplies two numbers
22
- # rake calc:subtract[a,b] # subtracts two numbers
23
- ```
24
-
25
- #### Calculating integer numbers
26
- ```sh
27
- rake calc:add[3,2]
28
- # 3 + 2 = 5
29
-
30
- rake calc:subtract[3,2]
31
- # 3 - 2 = 1
32
-
33
- rake calc:multiply[3,2]
34
- # 3 x 2 = 6
35
-
36
- rake calc:divide[3,2]
37
- # 3 / 2 = 1
38
- ```
39
-
40
- #### Calculating float numbers
41
- ```sh
42
- rake calc:divide[3.0,2.0]
43
- # 3.0 / 2.0 = 1.5
44
-
45
- rake calc:divide[-3.0,2.0]
46
- # -3.0 / 2.0 = -1.5
47
- ```
48
-
49
- #### Calculation errors
50
- ```sh
51
- rake calc:add[1,a]
52
- # ERROR: The arguments must contain only numeric values
53
-
54
- rake calc:add[-\ 1,2]
55
- # ERROR: Arguments can't have spaces: a: "- 1", b: "2"
56
- ```
@@ -1,60 +0,0 @@
1
- require 'u-service'
2
-
3
- require_relative 'calc/operation'
4
- require_relative 'calc/normalize_args'
5
- require_relative 'calc/transform_into_numbers'
6
-
7
- module Calc
8
- TransformArgsIntoNumbers = NormalizeArgs >> TransformIntoNumbers
9
-
10
- module With
11
- Add = TransformArgsIntoNumbers >> Operation::Add
12
- Divide = TransformArgsIntoNumbers >> Operation::Divide
13
- Subtract = TransformArgsIntoNumbers >> Operation::Subtract
14
- Multiply = TransformArgsIntoNumbers >> Operation::Multiply
15
- end
16
- end
17
-
18
- class PerformTask < Micro::Service::Base
19
- attributes :args, :operation
20
-
21
- def call!
22
- operation
23
- .call(args: args)
24
- .on_success { |value| print_operation(value) }
25
- .on_failure(:not_a_number) { |message| puts "ERROR: #{message}" }
26
- .on_failure(:arguments_with_space_chars) do |(a, b)|
27
- puts "ERROR: Arguments can't have spaces: a: #{a}, b: #{b}"
28
- end
29
- end
30
-
31
- private def print_operation(a:, operator:, b:, result:)
32
- puts "#{a} #{operator} #{b} = #{result}"
33
- end
34
- end
35
-
36
- namespace :calc do
37
- desc 'adds two numbers'
38
- task :add, [:a, :b] do |_task, args|
39
- PerformTask.call(args: args, operation: Calc::With::Add)
40
- end
41
-
42
- desc 'divides two numbers'
43
- task :divide, [:a, :b] do |_task, args|
44
- begin
45
- PerformTask.call(args: args, operation: Calc::With::Divide)
46
- rescue ZeroDivisionError => e
47
- puts "ERROR: #{e.message}"
48
- end
49
- end
50
-
51
- desc 'subtracts two numbers'
52
- task :subtract, [:a, :b] do |_task, args|
53
- PerformTask.call(args: args, operation: Calc::With::Subtract)
54
- end
55
-
56
- desc 'multiplies two numbers'
57
- task :multiply, [:a, :b] do |_task, args|
58
- PerformTask.call(args: args, operation: Calc::With::Multiply)
59
- end
60
- end
Binary file
@@ -1,17 +0,0 @@
1
- module Calc
2
- class NormalizeArgs < Micro::Service::Base
3
- attributes :args
4
-
5
- def call!
6
- a, b = normalize(args[:a]), normalize(args[:b])
7
-
8
- return Success(a: a, b: b) if a !~ /\s/ && b !~ /\s/
9
-
10
- Failure(:arguments_with_space_chars) { [a.inspect, b.inspect] }
11
- end
12
-
13
- private def normalize(value)
14
- String(value).strip
15
- end
16
- end
17
- end
@@ -1,39 +0,0 @@
1
- class Operation < Micro::Service::Base
2
- attributes :a, :b
3
-
4
- private def result_of(operation_result)
5
- attributes(:a, :operator, :b).merge(result: operation_result)
6
- end
7
-
8
- class Add < Operation
9
- attribute :operator, '+'
10
-
11
- def call!
12
- Success(result_of(a + b))
13
- end
14
- end
15
-
16
- class Subtract < Operation
17
- attribute :operator, '-'
18
-
19
- def call!
20
- Success(result_of(a - b))
21
- end
22
- end
23
-
24
- class Multiply < Operation
25
- attribute :operator, 'x'
26
-
27
- def call!
28
- Success(result_of(a * b))
29
- end
30
- end
31
-
32
- class Divide < Operation
33
- attribute :operator, '/'
34
-
35
- def call!
36
- Success(result_of(a / b))
37
- end
38
- end
39
- end
@@ -1,18 +0,0 @@
1
- class TransformIntoNumbers < Micro::Service::Base
2
- attributes :a, :b
3
-
4
- def call!
5
- number_a, number_b = number(a), number(b)
6
-
7
- if number_a && number_b
8
- Success(a: number(a), b: number(b))
9
- else
10
- Failure(:not_a_number) { 'The arguments must contain only numeric values' }
11
- end
12
- end
13
-
14
- private def number(value)
15
- return value.to_i if value =~ /\A[\-,=]?\d+\z/
16
- return value.to_f if value =~ /\A[\-,=]?\d+\.\d+\z/
17
- end
18
- end
@@ -1,53 +0,0 @@
1
- require 'bundler/inline'
2
-
3
- gemfile do
4
- source 'https://rubygems.org'
5
-
6
- gem 'u-service', '~> 0.12.0'
7
- end
8
-
9
- class Divide < Micro::Service::Base
10
- attributes :a, :b
11
-
12
- def call!
13
- return Failure('numbers must be greater than 0') if a < 0 || b < 0
14
-
15
- Success(a / b)
16
- rescue => e
17
- Failure(e.message)
18
- end
19
- end
20
-
21
- #---------------------------------#
22
- puts "\n-- Success scenario --\n\n"
23
- #---------------------------------#
24
-
25
- result = Divide.call(a: 4, b: 2)
26
-
27
- puts result.value if result.success?
28
-
29
- #----------------------------------#
30
- puts "\n-- Failure scenarios --\n\n"
31
- #----------------------------------#
32
-
33
- result = Divide.call(a: 4, b: 0)
34
-
35
- puts result.value if result.failure?
36
-
37
- puts ''
38
-
39
- result = Divide.call(a: -4, b: 2)
40
-
41
- puts result.value if result.failure?
42
-
43
- # :: example of the output: ::
44
-
45
- # -- Success scenario --
46
- #
47
- # 2
48
- #
49
- # -- Failure scenarios --
50
- #
51
- # divided by 0
52
- #
53
- # numbers must be greater than 0
@@ -1,133 +0,0 @@
1
- require 'bundler/inline'
2
-
3
- gemfile do
4
- source 'https://rubygems.org'
5
-
6
- # NOTE: I used an older version of the Activemodel only to show the compatibility with its older versions.
7
- gem 'activemodel', '~> 3.2', '>= 3.2.22.5'
8
- gem 'u-service', '~> 0.12.0'
9
- end
10
-
11
- require 'micro/service/with_validation'
12
-
13
- module Users
14
- class Entity
15
- include Micro::Attributes.with(:initialize)
16
-
17
- attributes :id, :name, :email
18
-
19
- def persisted?
20
- !id.nil?
21
- end
22
- end
23
-
24
- module Creation
25
- require 'uri'
26
- require 'securerandom'
27
-
28
- class ProcessParams < Micro::Service::Base
29
- attributes :name, :email
30
-
31
- def call!
32
- Success(name: normalized_name, email: String(email).downcase.strip)
33
- end
34
-
35
- private def normalized_name
36
- String(name).strip.gsub(/\s+/, ' ')
37
- end
38
- end
39
-
40
- class ValidateParams < Micro::Service::WithValidation
41
- attributes :name, :email
42
-
43
- validates :name, presence: true
44
- validates :email, format: { with: URI::MailTo::EMAIL_REGEXP }
45
-
46
- def call!
47
- Success(attributes(:name, :email))
48
- end
49
- end
50
-
51
- class Persist < Micro::Service::Base
52
- attributes :name, :email
53
-
54
- def call!
55
- Success(user: Entity.new(user_data))
56
- end
57
-
58
- private def user_data
59
- attributes.merge(id: SecureRandom.uuid)
60
- end
61
- end
62
-
63
- class SendToCRM < Micro::Service::Base
64
- attribute :user
65
-
66
- def call!
67
- return Success(user_id: user.id, crm_id: send_to_crm) if user.persisted?
68
-
69
- Failure(:crm_error) { 'User can\'t be sent to the CRM' }
70
- end
71
-
72
- private def send_to_crm
73
- # Do some integration stuff...
74
- SecureRandom.uuid
75
- end
76
- end
77
-
78
- Process = ProcessParams >> ValidateParams >> Persist >> SendToCRM
79
- end
80
- end
81
-
82
- require 'pp'
83
-
84
- params = {
85
- "name" => " Rodrigo \n Serradura ",
86
- "email" => " RoDRIGo.SERRAdura@gmail.com "
87
- }
88
-
89
- #--------------------------------------#
90
- puts "\n-- Parameters processing --\n\n"
91
- #--------------------------------------#
92
-
93
- print 'Before: '
94
- p params
95
-
96
- print ' After: '
97
- Users::Creation::ProcessParams.call(params).on_success { |value| p value }
98
-
99
- #---------------------------------#
100
- puts "\n-- Success scenario --\n\n"
101
- #---------------------------------#
102
-
103
- Users::Creation::Process
104
- .call(params)
105
- .on_success do |user_id:, crm_id:|
106
- puts " CRM ID: #{crm_id}"
107
- puts "USER ID: #{user_id}"
108
- end
109
-
110
- #---------------------------------#
111
- puts "\n-- Failure scenario --\n\n"
112
- #---------------------------------#
113
-
114
- Users::Creation::Process
115
- .call(name: '', email: '')
116
- .on_failure { |errors:| p errors.full_messages }
117
-
118
-
119
- # :: example of the output: ::
120
-
121
- # -- Parameters processing --
122
- #
123
- # Before: {"name"=>" Rodrigo \n Serradura ", "email"=>" RoDRIGo.SERRAdura@gmail.com "}
124
- # After: {:name=>"Rodrigo Serradura", :email=>"rodrigo.serradura@gmail.com"}
125
- #
126
- # -- Success scenario --
127
- #
128
- # CRM ID: f3f189f6-ba6a-40ab-998c-c86773c41c83
129
- # USER ID: c140ffc3-6a7c-4554-972a-c2a0d59f8cb1
130
- #
131
- # -- Failure scenarios --
132
- #
133
- # ["Name can't be blank", "Email is invalid"]