functional-light-service 0.4.4 → 6.0.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/.github/workflows/project-build.yml +43 -11
- data/.rubocop.yml +101 -160
- data/AUDIT-functional-light-service.md +352 -0
- data/Appraisals +4 -0
- data/CHANGELOG.md +118 -0
- data/Gemfile +0 -2
- data/README.md +1544 -1426
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/audit/bench.rb +99 -0
- data/audit/verify_findings.rb +172 -0
- data/functional-light-service.gemspec +15 -16
- data/lib/functional-light-service/action.rb +97 -101
- data/lib/functional-light-service/configuration.rb +26 -24
- data/lib/functional-light-service/context/key_verifier.rb +124 -118
- data/lib/functional-light-service/context.rb +63 -20
- data/lib/functional-light-service/deprecations.rb +26 -0
- data/lib/functional-light-service/errors.rb +8 -6
- data/lib/functional-light-service/functional/enum.rb +286 -250
- data/lib/functional-light-service/functional/maybe.rb +21 -15
- data/lib/functional-light-service/functional/monad.rb +77 -66
- data/lib/functional-light-service/functional/null.rb +88 -74
- data/lib/functional-light-service/functional/option.rb +100 -97
- data/lib/functional-light-service/functional/result.rb +129 -116
- data/lib/functional-light-service/localization_adapter.rb +48 -47
- data/lib/functional-light-service/organizer/execute.rb +16 -14
- data/lib/functional-light-service/organizer/iterate.rb +30 -25
- data/lib/functional-light-service/organizer/reduce_if.rb +19 -17
- data/lib/functional-light-service/organizer/reduce_until.rb +22 -20
- data/lib/functional-light-service/organizer/scoped_reducable.rb +15 -13
- data/lib/functional-light-service/organizer/with_callback.rb +28 -26
- data/lib/functional-light-service/organizer/with_reducer.rb +81 -71
- data/lib/functional-light-service/organizer/with_reducer_factory.rb +20 -18
- data/lib/functional-light-service/organizer/with_reducer_log_decorator.rb +110 -105
- data/lib/functional-light-service/organizer.rb +114 -104
- data/lib/functional-light-service/testing/context_factory.rb +48 -42
- data/lib/functional-light-service/testing.rb +3 -1
- data/lib/functional-light-service/version.rb +5 -3
- data/lib/functional-light-service.rb +30 -28
- data/spec/acceptance/after_actions_spec.rb +87 -71
- data/spec/acceptance/before_actions_spec.rb +115 -98
- data/spec/acceptance/custom_log_from_organizer_spec.rb +61 -60
- data/spec/acceptance/deprecation_warnings_spec.rb +82 -0
- data/spec/acceptance/fail_spec.rb +52 -50
- data/spec/acceptance/message_localization_spec.rb +119 -118
- data/spec/acceptance/organizer/add_aliases_spec.rb +28 -0
- data/spec/acceptance/organizer/add_to_context_spec.rb +30 -0
- data/spec/acceptance/organizer/context_failure_and_skipping_spec.rb +68 -65
- data/spec/acceptance/organizer/iterate_spec.rb +7 -0
- data/spec/acceptance/organizer/reduce_if_spec.rb +89 -83
- data/spec/acceptance/organizer/reduce_until_spec.rb +6 -0
- data/spec/acceptance/organizer/with_callback_spec.rb +113 -110
- data/spec/acceptance/{not_having_call_method_warning_spec.rb → organizer_entry_point_spec.rb} +10 -7
- data/spec/acceptance/rollback_spec.rb +183 -132
- data/spec/action_expects_and_promises_spec.rb +97 -93
- data/spec/action_promised_keys_spec.rb +126 -122
- data/spec/action_spec.rb +8 -0
- data/spec/context_spec.rb +289 -197
- data/spec/examples/controller_spec.rb +63 -63
- data/spec/examples/validate_address_spec.rb +38 -37
- data/spec/lib/deterministic/currify_spec.rb +90 -88
- data/spec/lib/deterministic/null_spec.rb +6 -1
- data/spec/lib/deterministic/option_spec.rb +140 -133
- data/spec/lib/deterministic/result/result_map_spec.rb +155 -154
- data/spec/lib/deterministic/result/result_shared.rb +3 -2
- data/spec/lib/deterministic/result_spec.rb +2 -2
- data/spec/lib/edge_cases_spec.rb +156 -0
- data/spec/lib/enum_spec.rb +1 -1
- data/spec/lib/native_pattern_matching_spec.rb +74 -0
- data/spec/organizer_spec.rb +115 -93
- data/spec/readme_spec.rb +45 -47
- data/spec/sample/calculates_order_tax_action_spec.rb +16 -16
- data/spec/sample/calculates_tax_spec.rb +1 -1
- data/spec/sample/looks_up_tax_percentage_action_spec.rb +55 -55
- data/spec/sample/provides_free_shipping_action_spec.rb +1 -1
- data/spec/sample/tax/calculates_order_tax_action.rb +10 -9
- data/spec/sample/tax/looks_up_tax_percentage_action.rb +28 -27
- data/spec/sample/tax/provides_free_shipping_action.rb +11 -10
- data/spec/spec_helper.rb +21 -13
- data/spec/test_doubles.rb +628 -564
- data/spec/testing/context_factory_spec.rb +21 -0
- metadata +49 -117
- data/.travis.yml +0 -24
- data/lib/functional-light-service/organizer/verify_call_method_exists.rb +0 -29
- data/spec/acceptance/include_warning_spec.rb +0 -29
data/spec/organizer_spec.rb
CHANGED
|
@@ -1,93 +1,115 @@
|
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
expect(
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
it "
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
end
|
|
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
CHANGED
|
@@ -1,47 +1,45 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
expect(Threenum.
|
|
43
|
-
expect(Threenum.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
end
|
|
47
|
-
end
|
|
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 +1,16 @@
|
|
|
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
|
-
|
|
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
|
|
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
|
|
@@ -10,7 +10,7 @@ describe CalculatesTax do
|
|
|
10
10
|
|
|
11
11
|
it "calls the actions in order" do
|
|
12
12
|
allow(FunctionalLightService::Context).to receive(:make)
|
|
13
|
-
.with(:order => order)
|
|
13
|
+
.with({ :order => order })
|
|
14
14
|
.and_return(ctx)
|
|
15
15
|
|
|
16
16
|
allow(LooksUpTaxPercentageAction).to receive(:execute)
|
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require_relative 'tax/looks_up_tax_percentage_action'
|
|
3
|
-
|
|
4
|
-
class TaxRange
|
|
5
|
-
extend FunctionalLightService::Action
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
describe LooksUpTaxPercentageAction do
|
|
9
|
-
let(:region) { double('region') }
|
|
10
|
-
let(:order) do
|
|
11
|
-
order = double('order')
|
|
12
|
-
allow(order).to receive_messages(:region => region)
|
|
13
|
-
allow(order).to receive_messages(:total => 200)
|
|
14
|
-
order
|
|
15
|
-
end
|
|
16
|
-
let(:context) do
|
|
17
|
-
|
|
18
|
-
end
|
|
19
|
-
let(:tax_percentage) { double('tax_percentage') }
|
|
20
|
-
let(:tax_ranges) { double('tax_ranges') }
|
|
21
|
-
|
|
22
|
-
context "when the tax_ranges were not found" do
|
|
23
|
-
it "sets the context to failure" do
|
|
24
|
-
allow(TaxRange).to receive(:for_region).with(region).and_return nil
|
|
25
|
-
LooksUpTaxPercentageAction.execute(context)
|
|
26
|
-
|
|
27
|
-
expect(context).to be_failure
|
|
28
|
-
expect(context.message).to eq "The tax ranges were not found"
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
context "when the tax_percentage is not found" do
|
|
33
|
-
it "sets the context to failure" do
|
|
34
|
-
allow(TaxRange).to receive(:for_region).with(region).and_return tax_ranges
|
|
35
|
-
allow(tax_ranges).to receive_messages(:for_total => nil)
|
|
36
|
-
|
|
37
|
-
LooksUpTaxPercentageAction.execute(context)
|
|
38
|
-
|
|
39
|
-
expect(context).to be_failure
|
|
40
|
-
expect(context.message).to eq "The tax percentage was not found"
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
context "when the tax_percentage is found" do
|
|
45
|
-
it "sets the tax_percentage in context" do
|
|
46
|
-
allow(TaxRange).to receive(:for_region).with(region).and_return tax_ranges
|
|
47
|
-
allow(tax_ranges).to receive_messages(:for_total => 25)
|
|
48
|
-
|
|
49
|
-
LooksUpTaxPercentageAction.execute(context)
|
|
50
|
-
|
|
51
|
-
expect(context).to be_success
|
|
52
|
-
expect(context.fetch(:tax_percentage)).to eq 25
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require_relative 'tax/looks_up_tax_percentage_action'
|
|
3
|
+
|
|
4
|
+
class TaxRange
|
|
5
|
+
extend FunctionalLightService::Action
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
describe LooksUpTaxPercentageAction do
|
|
9
|
+
let(:region) { double('region') }
|
|
10
|
+
let(:order) do
|
|
11
|
+
order = double('order')
|
|
12
|
+
allow(order).to receive_messages(:region => region)
|
|
13
|
+
allow(order).to receive_messages(:total => 200)
|
|
14
|
+
order
|
|
15
|
+
end
|
|
16
|
+
let(:context) do
|
|
17
|
+
FunctionalLightService::Context.make(:order => order)
|
|
18
|
+
end
|
|
19
|
+
let(:tax_percentage) { double('tax_percentage') }
|
|
20
|
+
let(:tax_ranges) { double('tax_ranges') }
|
|
21
|
+
|
|
22
|
+
context "when the tax_ranges were not found" do
|
|
23
|
+
it "sets the context to failure" do
|
|
24
|
+
allow(TaxRange).to receive(:for_region).with(region).and_return nil
|
|
25
|
+
LooksUpTaxPercentageAction.execute(context)
|
|
26
|
+
|
|
27
|
+
expect(context).to be_failure
|
|
28
|
+
expect(context.message).to eq "The tax ranges were not found"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context "when the tax_percentage is not found" do
|
|
33
|
+
it "sets the context to failure" do
|
|
34
|
+
allow(TaxRange).to receive(:for_region).with(region).and_return tax_ranges
|
|
35
|
+
allow(tax_ranges).to receive_messages(:for_total => nil)
|
|
36
|
+
|
|
37
|
+
LooksUpTaxPercentageAction.execute(context)
|
|
38
|
+
|
|
39
|
+
expect(context).to be_failure
|
|
40
|
+
expect(context.message).to eq "The tax percentage was not found"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context "when the tax_percentage is found" do
|
|
45
|
+
it "sets the tax_percentage in context" do
|
|
46
|
+
allow(TaxRange).to receive(:for_region).with(region).and_return tax_ranges
|
|
47
|
+
allow(tax_ranges).to receive_messages(:for_total => 25)
|
|
48
|
+
|
|
49
|
+
LooksUpTaxPercentageAction.execute(context)
|
|
50
|
+
|
|
51
|
+
expect(context).to be_success
|
|
52
|
+
expect(context.fetch(:tax_percentage)).to eq 25
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -15,7 +15,7 @@ describe ProvidesFreeShippingAction do
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
context "when the order total with tax is <= 200" do
|
|
18
|
-
specify "order
|
|
18
|
+
specify "order does not get free shipping" do
|
|
19
19
|
allow(order).to receive_messages(:total_with_tax => 200)
|
|
20
20
|
expect(order).not_to receive(:provide_free_shipping!)
|
|
21
21
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
class CalculatesOrderTaxAction
|
|
2
|
-
extend ::FunctionalLightService::Action
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
ctx.order.
|
|
8
|
-
|
|
9
|
-
end
|
|
1
|
+
class CalculatesOrderTaxAction
|
|
2
|
+
extend ::FunctionalLightService::Action
|
|
3
|
+
|
|
4
|
+
expects :order, :tax_percentage
|
|
5
|
+
|
|
6
|
+
executed do |ctx|
|
|
7
|
+
order_total = (ctx.order.total * (ctx.tax_percentage / 100))
|
|
8
|
+
ctx.order.tax = order_total.round(2)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
class LooksUpTaxPercentageAction
|
|
2
|
-
extend FunctionalLightService::Action
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
1
|
+
class LooksUpTaxPercentageAction
|
|
2
|
+
extend FunctionalLightService::Action
|
|
3
|
+
|
|
4
|
+
expects :order
|
|
5
|
+
promises :tax_percentage
|
|
6
|
+
|
|
7
|
+
executed do |ctx|
|
|
8
|
+
tax_ranges = TaxRange.for_region(ctx.order.region)
|
|
9
|
+
ctx.tax_percentage = 0
|
|
10
|
+
|
|
11
|
+
next ctx if object_is_nil?(tax_ranges, ctx, 'The tax ranges were not found')
|
|
12
|
+
|
|
13
|
+
ctx.tax_percentage = tax_ranges.for_total(ctx.order.total)
|
|
14
|
+
|
|
15
|
+
error_message = 'The tax percentage was not found'
|
|
16
|
+
next ctx if object_is_nil?(ctx.tax_percentage, ctx, error_message)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.object_is_nil?(object, ctx, message)
|
|
20
|
+
if object.nil?
|
|
21
|
+
ctx.fail!(message)
|
|
22
|
+
return true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
false
|
|
26
|
+
end
|
|
27
|
+
private_class_method :object_is_nil?
|
|
28
|
+
end
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
class ProvidesFreeShippingAction
|
|
2
|
-
extend FunctionalLightService::Action
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
end
|
|
1
|
+
class ProvidesFreeShippingAction
|
|
2
|
+
extend FunctionalLightService::Action
|
|
3
|
+
|
|
4
|
+
expects :order
|
|
5
|
+
|
|
6
|
+
executed do |context|
|
|
7
|
+
order = context.order
|
|
8
|
+
|
|
9
|
+
order.provide_free_shipping! if order.total_with_tax > 200
|
|
10
|
+
end
|
|
11
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
|
2
2
|
$LOAD_PATH << File.join(File.dirname(__FILE__))
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
if ENV['RUN_COVERAGE_REPORT']
|
|
5
|
+
require 'simplecov'
|
|
5
6
|
|
|
6
|
-
SimpleCov.start do
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
end
|
|
7
|
+
SimpleCov.start do
|
|
8
|
+
add_filter 'vendor/'
|
|
9
|
+
add_filter %r{^/spec/}
|
|
10
|
+
end
|
|
10
11
|
|
|
11
|
-
SimpleCov.
|
|
12
|
+
SimpleCov.minimum_coverage 98
|
|
13
|
+
SimpleCov.minimum_coverage_by_file 90
|
|
12
14
|
|
|
13
|
-
require
|
|
14
|
-
SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
|
|
15
|
+
require "simplecov-cobertura"
|
|
16
|
+
SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
|
|
17
|
+
end
|
|
15
18
|
|
|
16
|
-
require
|
|
17
|
-
require
|
|
19
|
+
require "functional-light-service"
|
|
20
|
+
require "functional-light-service/testing"
|
|
18
21
|
require "functional-light-service/functional/null"
|
|
19
|
-
require
|
|
20
|
-
require
|
|
21
|
-
require
|
|
22
|
+
require "support"
|
|
23
|
+
require "test_doubles"
|
|
24
|
+
require "stringio"
|
|
25
|
+
|
|
26
|
+
# Le API deprecate (Maybe/Null, operatori esotici) restano testate:
|
|
27
|
+
# i warning vengono silenziati globalmente e riattivati solo nelle
|
|
28
|
+
# spec che li verificano
|
|
29
|
+
FunctionalLightService::Deprecations.silenced = true
|