functional-light-service 6.1.0 → 6.3.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/lib/functional-light-service.rb +6 -31
- metadata +15 -297
- data/.github/workflows/project-build.yml +0 -71
- data/.gitignore +0 -22
- data/.rspec +0 -3
- data/.rubocop.yml +0 -101
- data/.solargraph.yml +0 -11
- data/AUDIT-functional-light-service.md +0 -352
- data/Appraisals +0 -7
- data/CHANGELOG.md +0 -273
- data/CODE_OF_CONDUCT.md +0 -22
- data/Gemfile +0 -4
- data/LICENSE +0 -22
- data/README.md +0 -1578
- data/Rakefile +0 -12
- data/VERSION +0 -1
- data/audit/bench.rb +0 -99
- data/audit/verify_findings.rb +0 -172
- data/functional-light-service.gemspec +0 -33
- data/gemfiles/dry_inflector_0_2_1.gemfile +0 -5
- data/gemfiles/i18n_1_8_11.gemfile +0 -5
- data/lib/functional-light-service/action.rb +0 -97
- data/lib/functional-light-service/configuration.rb +0 -26
- data/lib/functional-light-service/context/key_verifier.rb +0 -124
- data/lib/functional-light-service/context.rb +0 -195
- data/lib/functional-light-service/deprecations.rb +0 -26
- data/lib/functional-light-service/errors.rb +0 -8
- data/lib/functional-light-service/functional/enum.rb +0 -286
- data/lib/functional-light-service/functional/maybe.rb +0 -21
- data/lib/functional-light-service/functional/monad.rb +0 -77
- data/lib/functional-light-service/functional/null.rb +0 -88
- data/lib/functional-light-service/functional/option.rb +0 -100
- data/lib/functional-light-service/functional/result.rb +0 -129
- data/lib/functional-light-service/functional/sequencer.rb +0 -144
- data/lib/functional-light-service/localization_adapter.rb +0 -48
- data/lib/functional-light-service/organizer/execute.rb +0 -16
- data/lib/functional-light-service/organizer/iterate.rb +0 -30
- data/lib/functional-light-service/organizer/reduce_if.rb +0 -19
- data/lib/functional-light-service/organizer/reduce_until.rb +0 -22
- data/lib/functional-light-service/organizer/scoped_reducable.rb +0 -15
- data/lib/functional-light-service/organizer/with_callback.rb +0 -28
- data/lib/functional-light-service/organizer/with_reducer.rb +0 -81
- data/lib/functional-light-service/organizer/with_reducer_factory.rb +0 -20
- data/lib/functional-light-service/organizer/with_reducer_log_decorator.rb +0 -110
- data/lib/functional-light-service/organizer.rb +0 -114
- data/lib/functional-light-service/testing/context_factory.rb +0 -48
- data/lib/functional-light-service/testing.rb +0 -3
- data/lib/functional-light-service/version.rb +0 -5
- data/resources/fail_actions.png +0 -0
- data/resources/light-service.png +0 -0
- data/resources/organizer_and_actions.png +0 -0
- data/resources/skip_actions.png +0 -0
- data/spec/acceptance/add_numbers_spec.rb +0 -11
- data/spec/acceptance/after_actions_spec.rb +0 -87
- data/spec/acceptance/around_each_spec.rb +0 -19
- data/spec/acceptance/before_actions_spec.rb +0 -115
- data/spec/acceptance/custom_log_from_organizer_spec.rb +0 -61
- data/spec/acceptance/deprecation_warnings_spec.rb +0 -82
- data/spec/acceptance/fail_spec.rb +0 -52
- data/spec/acceptance/log_from_organizer_spec.rb +0 -154
- data/spec/acceptance/message_localization_spec.rb +0 -119
- data/spec/acceptance/organizer/add_aliases_spec.rb +0 -28
- data/spec/acceptance/organizer/add_to_context_spec.rb +0 -30
- data/spec/acceptance/organizer/around_each_with_reduce_if_spec.rb +0 -42
- data/spec/acceptance/organizer/context_failure_and_skipping_spec.rb +0 -68
- data/spec/acceptance/organizer/execute_spec.rb +0 -46
- data/spec/acceptance/organizer/iterate_spec.rb +0 -44
- data/spec/acceptance/organizer/reduce_if_spec.rb +0 -89
- data/spec/acceptance/organizer/reduce_until_spec.rb +0 -49
- data/spec/acceptance/organizer/with_callback_spec.rb +0 -113
- data/spec/acceptance/organizer_entry_point_spec.rb +0 -35
- data/spec/acceptance/rollback_spec.rb +0 -183
- data/spec/acceptance/testing/context_factory_spec.rb +0 -54
- data/spec/action_expected_keys_spec.rb +0 -63
- data/spec/action_expects_and_promises_spec.rb +0 -97
- data/spec/action_promised_keys_spec.rb +0 -126
- data/spec/action_spec.rb +0 -97
- data/spec/context/inspect_spec.rb +0 -42
- data/spec/context_spec.rb +0 -289
- data/spec/examples/amount_spec.rb +0 -77
- data/spec/examples/controller_spec.rb +0 -63
- data/spec/examples/validate_address_spec.rb +0 -38
- data/spec/lib/deterministic/class_mixin_spec.rb +0 -24
- data/spec/lib/deterministic/currify_spec.rb +0 -90
- data/spec/lib/deterministic/monad_axioms.rb +0 -46
- data/spec/lib/deterministic/monad_spec.rb +0 -47
- data/spec/lib/deterministic/null_spec.rb +0 -65
- data/spec/lib/deterministic/option_spec.rb +0 -140
- data/spec/lib/deterministic/result/failure_spec.rb +0 -65
- data/spec/lib/deterministic/result/result_map_spec.rb +0 -155
- data/spec/lib/deterministic/result/result_shared.rb +0 -25
- data/spec/lib/deterministic/result/success_spec.rb +0 -41
- data/spec/lib/deterministic/result_spec.rb +0 -63
- data/spec/lib/deterministic/sequencer_spec.rb +0 -506
- data/spec/lib/edge_cases_spec.rb +0 -156
- data/spec/lib/enum_spec.rb +0 -114
- data/spec/lib/native_pattern_matching_spec.rb +0 -74
- data/spec/localization_adapter_spec.rb +0 -83
- data/spec/organizer/with_reducer_spec.rb +0 -56
- data/spec/organizer_key_aliases_spec.rb +0 -29
- data/spec/organizer_spec.rb +0 -115
- data/spec/readme_spec.rb +0 -45
- data/spec/sample/calculates_order_tax_action_spec.rb +0 -16
- data/spec/sample/calculates_tax_spec.rb +0 -30
- data/spec/sample/looks_up_tax_percentage_action_spec.rb +0 -55
- data/spec/sample/provides_free_shipping_action_spec.rb +0 -25
- data/spec/sample/tax/calculates_order_tax_action.rb +0 -10
- data/spec/sample/tax/calculates_tax.rb +0 -11
- data/spec/sample/tax/looks_up_tax_percentage_action.rb +0 -28
- data/spec/sample/tax/provides_free_shipping_action.rb +0 -11
- data/spec/spec_helper.rb +0 -29
- data/spec/support.rb +0 -1
- data/spec/test_doubles.rb +0 -628
- data/spec/testing/context_factory/iterate_spec.rb +0 -39
- data/spec/testing/context_factory/reduce_if_spec.rb +0 -40
- data/spec/testing/context_factory/reduce_until_spec.rb +0 -40
- data/spec/testing/context_factory/with_callback_spec.rb +0 -38
- data/spec/testing/context_factory_spec.rb +0 -76
data/spec/lib/edge_cases_spec.rb
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'functional-light-service/functional/maybe'
|
|
3
|
-
|
|
4
|
-
# Copertura dei path d'errore e delle API minori emersi dall'audit
|
|
5
|
-
describe "edge cases and error paths" do
|
|
6
|
-
include FunctionalLightService::Prelude::Result
|
|
7
|
-
include FunctionalLightService::Prelude::Option
|
|
8
|
-
|
|
9
|
-
describe FunctionalLightService::Context do
|
|
10
|
-
it "#add_to_context merges values" do
|
|
11
|
-
ctx = FunctionalLightService::Context.make(:a => 1)
|
|
12
|
-
ctx.add_to_context(:b => 2)
|
|
13
|
-
|
|
14
|
-
expect(ctx[:b]).to eq(2)
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
describe FunctionalLightService::Context::KeyVerifier do
|
|
19
|
-
it "the base verifier requires throw_error_predicate to be overridden" do
|
|
20
|
-
ctx = FunctionalLightService::Context.make
|
|
21
|
-
verifier = described_class.new(ctx, nil)
|
|
22
|
-
|
|
23
|
-
expect { verifier.throw_error_predicate([]) }.to raise_error(NotImplementedError)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
describe "Object monkey patch (opt-in via functional/maybe)" do
|
|
28
|
-
it "defines null? and some? on every object" do
|
|
29
|
-
expect("anything".null?).to be(false)
|
|
30
|
-
expect("anything".some?).to be(true)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
describe Null do
|
|
35
|
-
it "class-level unknown messages return the singleton" do
|
|
36
|
-
expect(Null.anything_at_all).to eq(Null.instance)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
it "class-level respond_to? is permissive" do
|
|
40
|
-
expect(Null.respond_to?(:anything_at_all)).to be(true)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
it "compares equal to another Null" do
|
|
44
|
-
expect(Null.instance == Null.instance).to be(true) # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
|
|
45
|
-
expect(Null.instance == "not null").to be(false)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
it "a mimic only responds to the mimicked interface" do
|
|
49
|
-
klass = Class.new { def foo; end }
|
|
50
|
-
mimic = Null.mimic(klass)
|
|
51
|
-
|
|
52
|
-
expect(mimic.respond_to?(:foo)).to be(true)
|
|
53
|
-
expect(mimic.respond_to?(:bar)).to be(false)
|
|
54
|
-
expect { mimic.bar }.to raise_error(NoMethodError)
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
describe "enum error paths" do
|
|
59
|
-
it "raises when a variant is defined twice" do
|
|
60
|
-
expect do
|
|
61
|
-
FunctionalLightService.enum do
|
|
62
|
-
Dup()
|
|
63
|
-
Dup()
|
|
64
|
-
end
|
|
65
|
-
end.to raise_error(ArgumentError, /already defined/)
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
it "the enum builder responds to any variant name" do
|
|
69
|
-
builder = FunctionalLightService::EnumBuilder.new(Class.new)
|
|
70
|
-
|
|
71
|
-
expect(builder.respond_to?(:AnyVariantName)).to be(true)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
it "raises MatchError when the match is not exhaustive" do
|
|
75
|
-
expect do
|
|
76
|
-
Some(1).match do
|
|
77
|
-
Some() { |s| s }
|
|
78
|
-
end
|
|
79
|
-
end.to raise_error(FunctionalLightService::Enum::MatchError, /non-exhaustive/)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
it "raises MatchError when the block arity does not match the variant" do
|
|
83
|
-
expect do
|
|
84
|
-
Some(1).match do
|
|
85
|
-
Some() { |a, b| [a, b] }
|
|
86
|
-
None() { nil }
|
|
87
|
-
end
|
|
88
|
-
end.to raise_error(FunctionalLightService::Enum::MatchError, /must match/)
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
it "raises MatchError when no guard matches" do
|
|
92
|
-
expect do
|
|
93
|
-
Some(1).match do
|
|
94
|
-
Some(where { s > 100 }) { |s| s }
|
|
95
|
-
None() { nil }
|
|
96
|
-
end
|
|
97
|
-
end.to raise_error(FunctionalLightService::Enum::MatchError, /No match could be made/)
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
it "rejects unnamed/rest block parameters" do
|
|
101
|
-
# su Ruby 3.1 |*| appare come [[:rest]] (ramo "Unnamed param"),
|
|
102
|
-
# da Ruby 3.2 come [[:rest, :*]] (ramo "Only :req & :opt")
|
|
103
|
-
expect do
|
|
104
|
-
Some(1).match do
|
|
105
|
-
Some() { |*| nil }
|
|
106
|
-
None() { nil }
|
|
107
|
-
end
|
|
108
|
-
end.to raise_error(ArgumentError, /Unnamed param|Only :req & :opt/)
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
it "rejects keyword block parameters" do
|
|
112
|
-
expect do
|
|
113
|
-
Some(1).match do
|
|
114
|
-
Some() { |**opts| opts }
|
|
115
|
-
None() { nil }
|
|
116
|
-
end
|
|
117
|
-
end.to raise_error(ArgumentError, /Only :req & :opt params allowed/)
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
it "None deconstructs to an empty hash and array" do
|
|
121
|
-
none = FunctionalLightService::Option::None.new
|
|
122
|
-
|
|
123
|
-
expect(none.deconstruct).to eq([])
|
|
124
|
-
expect(none.deconstruct_keys(nil)).to eq({})
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
describe "Option minor APIs" do
|
|
129
|
-
it "#value_to_a returns the raw value" do
|
|
130
|
-
expect(Some(1).value_to_a).to eq(1)
|
|
131
|
-
expect(FunctionalLightService::Option::None.new.value_to_a).to be_nil
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
it "Prelude None() builds the shared None" do
|
|
135
|
-
expect(None().none?).to be(true)
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
it "Prelude Option() returns the Option enum" do
|
|
139
|
-
expect(Option()).to eq(FunctionalLightService::Option)
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
describe "Result minor APIs" do
|
|
144
|
-
it "#+ raises NotMonadError for non-Result operands" do
|
|
145
|
-
expect { Success(1) + "not a result" } # rubocop:disable Style/StringConcatenation
|
|
146
|
-
.to raise_error(FunctionalLightService::Monad::NotMonadError)
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
it "Prelude try! wraps exceptions in Failure" do
|
|
150
|
-
result = try! { raise "boom" }
|
|
151
|
-
|
|
152
|
-
expect(result).to be_failure
|
|
153
|
-
expect(result.value).to be_a(RuntimeError)
|
|
154
|
-
end
|
|
155
|
-
end
|
|
156
|
-
end
|
data/spec/lib/enum_spec.rb
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe FunctionalLightService::Enum do
|
|
4
|
-
include FunctionalLightService
|
|
5
|
-
|
|
6
|
-
it "can't use value" do
|
|
7
|
-
expect do
|
|
8
|
-
InvalidEnum = FunctionalLightService.enum do
|
|
9
|
-
Unary(:value)
|
|
10
|
-
end
|
|
11
|
-
end.to raise_error ArgumentError
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
context "Nullary, Unary, Binary" do
|
|
15
|
-
MyEnym = FunctionalLightService.enum do
|
|
16
|
-
Nullary()
|
|
17
|
-
Unary(:a)
|
|
18
|
-
Binary(:a, :b)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
it "can't instantiate parent" do
|
|
22
|
-
expect { MyEnym.new }.to \
|
|
23
|
-
raise_error NoMethodError, /private method [`']new'/
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
it "Nullary" do
|
|
27
|
-
n = MyEnym.Nullary
|
|
28
|
-
|
|
29
|
-
expect(n).to be_a MyEnym
|
|
30
|
-
expect(n).to be_a MyEnym::Nullary
|
|
31
|
-
expect(n.name).to eq "Nullary"
|
|
32
|
-
expect { n.value }.to raise_error NoMethodError
|
|
33
|
-
expect(n.inspect).to eq "Nullary"
|
|
34
|
-
expect(n.to_s).to eq ""
|
|
35
|
-
# rubocop:disable Lint/EmptyBlock
|
|
36
|
-
expect(n.fmap {}).to eq n
|
|
37
|
-
# rubocop:enable Lint/EmptyBlock
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
it "Unary" do
|
|
41
|
-
u = MyEnym::Unary(1)
|
|
42
|
-
|
|
43
|
-
expect(u).to be_a MyEnym
|
|
44
|
-
expect(u).to be_a MyEnym::Unary
|
|
45
|
-
expect(u.name).to eq "Unary"
|
|
46
|
-
expect(u.a).to eq 1
|
|
47
|
-
expect(u.value).to eq 1
|
|
48
|
-
expect(u.inspect).to eq "Unary(1)"
|
|
49
|
-
expect(u.to_s).to eq "1"
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
it "Binary" do
|
|
53
|
-
# hash
|
|
54
|
-
b = MyEnym::Binary(:a => 1, :b => 2)
|
|
55
|
-
expect(b).to be_a MyEnym
|
|
56
|
-
expect(b).to be_a MyEnym::Binary
|
|
57
|
-
expect(b.name).to eq "Binary"
|
|
58
|
-
expect(b.inspect).to eq "Binary(a: 1, b: 2)"
|
|
59
|
-
|
|
60
|
-
expect(b.a).to eq 1
|
|
61
|
-
expect(b.b).to eq 2
|
|
62
|
-
expect(b.value).to eq(:a => 1, :b => 2)
|
|
63
|
-
|
|
64
|
-
# values only
|
|
65
|
-
b = MyEnym::Binary(1, 2)
|
|
66
|
-
expect(b.value).to eq(:a => 1, :b => 2)
|
|
67
|
-
|
|
68
|
-
# other names are ok
|
|
69
|
-
b = MyEnym::Binary(:c => 1, :d => 2)
|
|
70
|
-
expect(b.value).to eq(:a => 1, :b => 2)
|
|
71
|
-
|
|
72
|
-
expect { MyEnym::Binary(1) }.to raise_error ArgumentError
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it "generated enum" do
|
|
76
|
-
expect(MyEnym.variants.sort).to eq %i[Unary Binary Nullary].sort
|
|
77
|
-
expect(MyEnym.constants.sort.inspect).to eq %i[Matcher Unary Binary Nullary].sort.to_s
|
|
78
|
-
|
|
79
|
-
b = MyEnym::Binary(:a => 1, :b => 2)
|
|
80
|
-
|
|
81
|
-
res =
|
|
82
|
-
MyEnym.match(b) do
|
|
83
|
-
Nullary() { 0 }
|
|
84
|
-
Unary() { |a| a }
|
|
85
|
-
Binary() { |x, y| [x, y] }
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
expect(res).to eq [1, 2]
|
|
89
|
-
|
|
90
|
-
res =
|
|
91
|
-
b.match do
|
|
92
|
-
Nullary() { 0 }
|
|
93
|
-
Unary() { |a| a }
|
|
94
|
-
Binary() { |x, y| [x, y] }
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
expect(res).to eq [1, 2]
|
|
98
|
-
|
|
99
|
-
expect do
|
|
100
|
-
b.match do
|
|
101
|
-
Nullary # Nullary is treated as a constant
|
|
102
|
-
end
|
|
103
|
-
end.to raise_error(NameError)
|
|
104
|
-
|
|
105
|
-
expect do
|
|
106
|
-
b.match do
|
|
107
|
-
Nullary()
|
|
108
|
-
Unary()
|
|
109
|
-
Binary()
|
|
110
|
-
end
|
|
111
|
-
end.to raise_error ArgumentError, "No block given to `Nullary`"
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
end
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe "native Ruby pattern matching (case/in) support" do
|
|
4
|
-
include FunctionalLightService::Prelude::Result
|
|
5
|
-
include FunctionalLightService::Prelude::Option
|
|
6
|
-
|
|
7
|
-
Result = FunctionalLightService::Result
|
|
8
|
-
Option = FunctionalLightService::Option
|
|
9
|
-
|
|
10
|
-
it "deconstructs Success/Failure positionally" do
|
|
11
|
-
matched =
|
|
12
|
-
case Success(42)
|
|
13
|
-
in Result::Success[value] then "success: #{value}"
|
|
14
|
-
in Result::Failure[error] then "failure: #{error}"
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
expect(matched).to eq("success: 42")
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it "deconstructs Failure positionally" do
|
|
21
|
-
matched =
|
|
22
|
-
case Failure(:boom)
|
|
23
|
-
in Result::Success[value] then "success: #{value}"
|
|
24
|
-
in Result::Failure[error] then "failure: #{error}"
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
expect(matched).to eq("failure: boom")
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
it "deconstructs by keys using the variant's field names" do
|
|
31
|
-
matched =
|
|
32
|
-
case Success(42)
|
|
33
|
-
in Result::Success(s:) then s
|
|
34
|
-
in Result::Failure(f:) then f
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
expect(matched).to eq(42)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
it "deconstructs Some and None" do
|
|
41
|
-
some_result =
|
|
42
|
-
case Some(7)
|
|
43
|
-
in Option::Some[v] then v
|
|
44
|
-
in Option::None then :none
|
|
45
|
-
end
|
|
46
|
-
none_result =
|
|
47
|
-
case None()
|
|
48
|
-
in Option::Some[v] then v
|
|
49
|
-
in Option::None then :none
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
expect(some_result).to eq(7)
|
|
53
|
-
expect(none_result).to eq(:none)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
Shape = FunctionalLightService.enum do
|
|
57
|
-
Point(:x, :y)
|
|
58
|
-
Origin()
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it "deconstructs multi-field (Binary) variants by keys" do
|
|
62
|
-
matched =
|
|
63
|
-
case Shape::Point.new(1, 2)
|
|
64
|
-
in Shape::Point(x:, y:) then [x, y]
|
|
65
|
-
in Shape::Origin then [0, 0]
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
expect(matched).to eq([1, 2])
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def None # rubocop:disable Naming/MethodName
|
|
72
|
-
FunctionalLightService::Option::None.new
|
|
73
|
-
end
|
|
74
|
-
end
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
require 'test_doubles'
|
|
3
|
-
|
|
4
|
-
describe FunctionalLightService::LocalizationAdapter do
|
|
5
|
-
let(:action_class) { TestDoubles::AnAction }
|
|
6
|
-
let(:adapter) { described_class.new }
|
|
7
|
-
|
|
8
|
-
describe "#failure" do
|
|
9
|
-
subject { adapter.failure(message_or_key, action_class) }
|
|
10
|
-
|
|
11
|
-
context "when provided a Symbol" do
|
|
12
|
-
let(:message_or_key) { :not_found }
|
|
13
|
-
|
|
14
|
-
it "translates the message" do
|
|
15
|
-
expected_scope = "test_doubles/an_action.light_service.failures"
|
|
16
|
-
|
|
17
|
-
expect(I18n).to receive(:t)
|
|
18
|
-
.with(message_or_key, :scope => expected_scope)
|
|
19
|
-
.and_return("message")
|
|
20
|
-
|
|
21
|
-
expect(subject).to eq("message")
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it "allows passing interpolation options to I18n layer" do
|
|
25
|
-
expect(I18n).to receive(:t)
|
|
26
|
-
.with(message_or_key, hash_including(:i18n_variable => "value"))
|
|
27
|
-
.and_return("message")
|
|
28
|
-
|
|
29
|
-
subject = adapter.failure(message_or_key,
|
|
30
|
-
action_class,
|
|
31
|
-
:i18n_variable => "value")
|
|
32
|
-
|
|
33
|
-
expect(subject).to eq("message")
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
context "when provided a String" do
|
|
38
|
-
let(:message_or_key) { "action failed" }
|
|
39
|
-
|
|
40
|
-
it "returns the message" do
|
|
41
|
-
expect(subject).to eq(message_or_key)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
describe "#success" do
|
|
47
|
-
subject { adapter.success(message_or_key, action_class) }
|
|
48
|
-
|
|
49
|
-
context "when provided a Symbol" do
|
|
50
|
-
let(:message_or_key) { :not_found }
|
|
51
|
-
|
|
52
|
-
it "translates the message" do
|
|
53
|
-
expected_scope = "test_doubles/an_action.light_service.successes"
|
|
54
|
-
|
|
55
|
-
expect(I18n).to receive(:t)
|
|
56
|
-
.with(message_or_key, :scope => expected_scope)
|
|
57
|
-
.and_return("message")
|
|
58
|
-
|
|
59
|
-
expect(subject).to eq("message")
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
it "allows passing interpolation options to I18n layer" do
|
|
63
|
-
expect(I18n).to receive(:t)
|
|
64
|
-
.with(message_or_key, hash_including(:i18n_variable => "value"))
|
|
65
|
-
.and_return("message")
|
|
66
|
-
|
|
67
|
-
subject = adapter.success(message_or_key,
|
|
68
|
-
action_class,
|
|
69
|
-
:i18n_variable => "value")
|
|
70
|
-
|
|
71
|
-
expect(subject).to eq("message")
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
context "when provided a String" do
|
|
76
|
-
let(:message_or_key) { "action failed" }
|
|
77
|
-
|
|
78
|
-
it "returns the message" do
|
|
79
|
-
expect(subject).to eq(message_or_key)
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
end
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'test_doubles'
|
|
3
|
-
|
|
4
|
-
describe FunctionalLightService::Organizer::WithReducer do
|
|
5
|
-
let(:context) { FunctionalLightService::Context.make }
|
|
6
|
-
let(:action1) { TestDoubles::NullAction }
|
|
7
|
-
let(:action2) { TestDoubles::NullAction.clone }
|
|
8
|
-
let(:actions) { [action1, action2] }
|
|
9
|
-
|
|
10
|
-
before { context.current_action = action2 }
|
|
11
|
-
|
|
12
|
-
it "reduces the provided actions" do
|
|
13
|
-
result = described_class.new.with(context).reduce(actions)
|
|
14
|
-
|
|
15
|
-
expect(result).to eq(context)
|
|
16
|
-
expect(result).to be_success
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
it "executes a handler around each action and continues reducing" do
|
|
20
|
-
expect(action1).to receive(:execute).with(context).and_return(context)
|
|
21
|
-
|
|
22
|
-
result = described_class.new.with(context)
|
|
23
|
-
.around_each(TestDoubles::AroundEachNullHandler)
|
|
24
|
-
.reduce([action1])
|
|
25
|
-
|
|
26
|
-
expect(result).to eq(context)
|
|
27
|
-
expect(result).to be_success
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
context "when FailWithRollbackError is caught" do
|
|
31
|
-
it "reduces the rollback" do
|
|
32
|
-
expect(action1).to receive(:execute).with(context).and_return(context)
|
|
33
|
-
expect(action2).to receive(:execute).with(context) do
|
|
34
|
-
raise FunctionalLightService::FailWithRollbackError
|
|
35
|
-
end
|
|
36
|
-
expect(action1).to receive(:rollback).with(context).and_return(context)
|
|
37
|
-
expect(action2).to receive(:rollback).with(context).and_return(context)
|
|
38
|
-
|
|
39
|
-
result = described_class.new.with(context).reduce(actions)
|
|
40
|
-
|
|
41
|
-
expect(result).to eq(context)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it "reduces the rollback with an action without `rollback`" do
|
|
45
|
-
expect(action1).to receive(:execute).with(context).and_return(context)
|
|
46
|
-
expect(action2).to receive(:execute).with(context) do
|
|
47
|
-
raise FunctionalLightService::FailWithRollbackError
|
|
48
|
-
end
|
|
49
|
-
expect(action2).to receive(:rollback).with(context).and_return(context)
|
|
50
|
-
|
|
51
|
-
result = described_class.new.with(context).reduce(actions)
|
|
52
|
-
|
|
53
|
-
expect(result).to eq(context)
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'test_doubles'
|
|
3
|
-
|
|
4
|
-
describe "organizer aliases macro" do
|
|
5
|
-
let(:organizer_with_alias) do
|
|
6
|
-
Class.new do
|
|
7
|
-
extend FunctionalLightService::Organizer
|
|
8
|
-
|
|
9
|
-
aliases :promised_key => :expected_key
|
|
10
|
-
|
|
11
|
-
def self.call(ctx = {})
|
|
12
|
-
with(ctx).reduce(
|
|
13
|
-
[
|
|
14
|
-
TestDoubles::PromisesPromisedKeyAction,
|
|
15
|
-
TestDoubles::ExpectsExpectedKeyAction
|
|
16
|
-
]
|
|
17
|
-
)
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
context "when aliases is invoked" do
|
|
23
|
-
it "makes aliases available to the actions" do
|
|
24
|
-
result = organizer_with_alias.call
|
|
25
|
-
expect(result[:expected_key]).to eq(result[:promised_key])
|
|
26
|
-
expect(result.expected_key).to eq(result[:promised_key])
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
data/spec/organizer_spec.rb
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'test_doubles'
|
|
3
|
-
|
|
4
|
-
describe FunctionalLightService::Organizer do
|
|
5
|
-
let(:ctx) { FunctionalLightService::Context.make(:user => user) }
|
|
6
|
-
let(:user) { double(:user) }
|
|
7
|
-
|
|
8
|
-
context "when #with is called with hash" do
|
|
9
|
-
before do
|
|
10
|
-
expect(TestDoubles::AnAction).to receive(:execute)
|
|
11
|
-
.with(ctx)
|
|
12
|
-
.and_return(ctx)
|
|
13
|
-
expect(TestDoubles::AnotherAction).to receive(:execute)
|
|
14
|
-
.with(ctx)
|
|
15
|
-
.and_return(ctx)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
it "implicitly creates a Context" do
|
|
19
|
-
result = TestDoubles::AnOrganizer.call(:user => user)
|
|
20
|
-
expect(result).to eq(ctx)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it "sets itself as the organizer" do
|
|
24
|
-
result = TestDoubles::AnOrganizer.call(:user => user)
|
|
25
|
-
expect(result.organized_by).to eq TestDoubles::AnOrganizer
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
context "when #with is called with Context" do
|
|
30
|
-
before do
|
|
31
|
-
expect(TestDoubles::AnAction).to receive(:execute)
|
|
32
|
-
.with(ctx)
|
|
33
|
-
.and_return(ctx)
|
|
34
|
-
expect(TestDoubles::AnotherAction).to receive(:execute)
|
|
35
|
-
.with(ctx)
|
|
36
|
-
.and_return(ctx)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
it "uses that Context without recreating it" do
|
|
40
|
-
result = TestDoubles::AnOrganizer.call(ctx)
|
|
41
|
-
expect(result).to eq(ctx)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
context "when no Actions are specified" do
|
|
46
|
-
it "throws a Runtime error" do
|
|
47
|
-
expect { TestDoubles::AnOrganizer.do_something_with_no_actions(ctx) }.to \
|
|
48
|
-
raise_error(RuntimeError, "No action(s) were provided")
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
context "when aliases are declared" do
|
|
53
|
-
let(:organizer) do
|
|
54
|
-
Class.new do
|
|
55
|
-
extend FunctionalLightService::Organizer
|
|
56
|
-
|
|
57
|
-
aliases :foo => :bar
|
|
58
|
-
|
|
59
|
-
def self.call
|
|
60
|
-
with.reduce(TestDoubles::AnAction)
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
it "merges the aliases into the data" do
|
|
66
|
-
with_reducer = double(:reduce => true)
|
|
67
|
-
|
|
68
|
-
allow(described_class::WithReducerFactory).to receive(:make)
|
|
69
|
-
.and_return(with_reducer)
|
|
70
|
-
|
|
71
|
-
expect(with_reducer).to receive(:with)
|
|
72
|
-
.with(hash_including(:_aliases => { :foo => :bar }))
|
|
73
|
-
.and_return(with_reducer)
|
|
74
|
-
|
|
75
|
-
organizer.call
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
context "when an organizer is nested and reduced within another" do
|
|
80
|
-
let(:reduced) { TestDoubles::NestingOrganizer.call(ctx) }
|
|
81
|
-
let(:organizer_result) do
|
|
82
|
-
TestDoubles::NotExplicitlyReturningContextOrganizer.call(ctx)
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
it "reduces an organizer which returns something" do
|
|
86
|
-
expect(organizer_result).to eq([1, 2, 3])
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
it "adds :foo and :bar to the context" do
|
|
90
|
-
reduced
|
|
91
|
-
expect(ctx[:foo]).to eq([1, 2, 3])
|
|
92
|
-
expect(ctx[:bar]).to eq(ctx[:foo])
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
it "returns the context" do
|
|
96
|
-
expect(reduced).to eq(ctx)
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
context "can add items to the context" do
|
|
101
|
-
specify 'with #add_to_context' do
|
|
102
|
-
result = TestDoubles::AnOrganizerThatAddsToContext.call
|
|
103
|
-
expect(result[:strongest_avenger]).to eq :thor
|
|
104
|
-
expect(result[:last_jedi]).to eq "Rey"
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
context "can assign key aliaeses" do
|
|
109
|
-
it 'with #add_aliases' do
|
|
110
|
-
result = TestDoubles::AnOrganizerThatAddsAliases.call
|
|
111
|
-
expect(result[:foo]).to eq :bar
|
|
112
|
-
expect(result[:baz]).to eq :bar
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
end
|
data/spec/readme_spec.rb
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
include FunctionalLightService::Prelude::Result
|
|
4
|
-
|
|
5
|
-
Success(1).to_s # => "1"
|
|
6
|
-
Success(Success(1)) # => Success(1)
|
|
7
|
-
|
|
8
|
-
Failure(1).to_s # => "1"
|
|
9
|
-
Failure(Failure(1)) # => Failure(1)
|
|
10
|
-
|
|
11
|
-
Success(1).fmap { |v| v + 1 } # => Success(2)
|
|
12
|
-
Failure(1).fmap { |v| v - 1 } # => Failure(0)
|
|
13
|
-
|
|
14
|
-
Threenum = FunctionalLightService.enum do
|
|
15
|
-
Nullary()
|
|
16
|
-
Unary(:a)
|
|
17
|
-
Binary(:a, :b)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
FunctionalLightService.impl(Threenum) do
|
|
21
|
-
def sum
|
|
22
|
-
match do
|
|
23
|
-
Nullary() { 0 }
|
|
24
|
-
Unary() { |u| u }
|
|
25
|
-
Binary() { |a, b| a + b }
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def +(other)
|
|
30
|
-
match do
|
|
31
|
-
Nullary() { other.sum }
|
|
32
|
-
Unary() { |_a| sum + other.sum }
|
|
33
|
-
Binary() { |_a, _b| sum + other.sum }
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
describe Threenum do
|
|
39
|
-
it "works" do
|
|
40
|
-
expect(Threenum.Nullary + Threenum.Unary(1)).to eq 1
|
|
41
|
-
expect(Threenum.Nullary + Threenum.Binary(2, 3)).to eq 5
|
|
42
|
-
expect(Threenum.Unary(1) + Threenum.Binary(2, 3)).to eq 6
|
|
43
|
-
expect(Threenum.Binary(2, 3) + Threenum.Binary(2, 3)).to eq 10
|
|
44
|
-
end
|
|
45
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require_relative 'tax/calculates_order_tax_action'
|
|
3
|
-
|
|
4
|
-
describe CalculatesOrderTaxAction do
|
|
5
|
-
let(:order) { double('order') }
|
|
6
|
-
let(:context) do
|
|
7
|
-
data = { :order => order, :tax_percentage => 7.2 }
|
|
8
|
-
FunctionalLightService::Context.make(data)
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
it "calculates the tax based on the tax percentage" do
|
|
12
|
-
allow(order).to receive_messages(:total => 100)
|
|
13
|
-
expect(order).to receive(:tax=).with 7.2
|
|
14
|
-
CalculatesOrderTaxAction.execute(context)
|
|
15
|
-
end
|
|
16
|
-
end
|