light-service 0.3.6 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/spec/context_spec.rb CHANGED
@@ -1,125 +1,124 @@
1
1
  require "spec_helper"
2
+ require 'test_doubles'
2
3
 
3
- module LightService
4
- describe Context do
4
+ describe LightService::Context do
5
5
 
6
- describe "can be made" do
7
- context "with no arguments" do
8
- subject { Context.make }
9
- it { is_expected.to be_success }
10
- its(:message) { should be_empty }
11
- end
6
+ describe "can be made" do
7
+ context "with no arguments" do
8
+ subject { LightService::Context.make }
9
+ it { is_expected.to be_success }
10
+ its(:message) { should be_empty }
11
+ end
12
12
 
13
- context "with a hash" do
14
- it "has the hash values" do
15
- context = Context.make(:one => 1)
13
+ context "with a hash" do
14
+ it "has the hash values" do
15
+ context = LightService::Context.make(:one => 1)
16
16
 
17
- expect(context[:one]).to eq(1)
18
- end
17
+ expect(context[:one]).to eq(1)
19
18
  end
19
+ end
20
20
 
21
- context "with FAILURE" do
22
- it "is failed" do
23
- context = Context.new({}, ::LightService::Outcomes::FAILURE, '')
21
+ context "with FAILURE" do
22
+ it "is failed" do
23
+ context = LightService::Context.new({}, ::LightService::Outcomes::FAILURE, '')
24
24
 
25
- expect(context).to be_failure
26
- end
25
+ expect(context).to be_failure
27
26
  end
28
27
  end
28
+ end
29
29
 
30
- describe "can't be made" do
31
- specify "with invalid parameters" do
32
- expect{Context.make([])}.to raise_error(ArgumentError)
33
- end
30
+ describe "can't be made" do
31
+ specify "with invalid parameters" do
32
+ expect{LightService::Context.make([])}.to raise_error(ArgumentError)
34
33
  end
34
+ end
35
35
 
36
- it "can be asked for success?" do
37
- context = Context.new({}, ::LightService::Outcomes::SUCCESS)
36
+ it "can be asked for success?" do
37
+ context = LightService::Context.new({}, ::LightService::Outcomes::SUCCESS)
38
38
 
39
- expect(context).to be_success
40
- end
39
+ expect(context).to be_success
40
+ end
41
41
 
42
- it "can be asked for failure?" do
43
- context = Context.new({}, ::LightService::Outcomes::FAILURE)
42
+ it "can be asked for failure?" do
43
+ context = LightService::Context.new({}, ::LightService::Outcomes::FAILURE)
44
44
 
45
- expect(context).to be_failure
46
- end
47
-
48
- it "can be asked for skip_all?" do
49
- context = Context.make
50
- context.skip_all!
45
+ expect(context).to be_failure
46
+ end
51
47
 
52
- expect(context.skip_all?).to be_truthy
53
- end
48
+ it "can be asked for skip_all?" do
49
+ context = LightService::Context.make
50
+ context.skip_all!
54
51
 
55
- it "can be pushed into a SUCCESS state" do
56
- context = Context.make
57
- context.succeed!("a happy end")
52
+ expect(context.skip_all?).to be_truthy
53
+ end
58
54
 
59
- expect(context).to be_success
60
- end
55
+ it "can be pushed into a SUCCESS state" do
56
+ context = LightService::Context.make
57
+ context.succeed!("a happy end")
61
58
 
62
- it "can be pushed into a SUCCESS state without a message" do
63
- context = Context.make
64
- context.succeed!
59
+ expect(context).to be_success
60
+ end
65
61
 
66
- expect(context).to be_success
67
- expect(context.message).to be_nil
68
- end
62
+ it "can be pushed into a SUCCESS state without a message" do
63
+ context = LightService::Context.make
64
+ context.succeed!
69
65
 
70
- it "can be pushed into a FAILURE state without a message" do
71
- context = Context.make
72
- context.fail!
66
+ expect(context).to be_success
67
+ expect(context.message).to be_nil
68
+ end
73
69
 
74
- expect(context).to be_failure
75
- expect(context.message).to be_nil
76
- end
70
+ it "can be pushed into a FAILURE state without a message" do
71
+ context = LightService::Context.make
72
+ context.fail!
77
73
 
78
- it "can be pushed into a FAILURE state with a message" do
79
- context = Context.make
80
- context.fail!("a sad end")
74
+ expect(context).to be_failure
75
+ expect(context.message).to be_nil
76
+ end
81
77
 
82
- expect(context).to be_failure
83
- end
78
+ it "can be pushed into a FAILURE state with a message" do
79
+ context = LightService::Context.make
80
+ context.fail!("a sad end")
84
81
 
85
- it "can be pushed into a FAILURE state with a message in an options hash" do
86
- context = Context.make
87
- context.fail!("a sad end")
82
+ expect(context).to be_failure
83
+ end
88
84
 
89
- expect(context).to be_failure
90
- expect(context.message).to eq("a sad end")
91
- expect(context.error_code).to be_nil
92
- end
85
+ it "can be pushed into a FAILURE state with a message in an options hash" do
86
+ context = LightService::Context.make
87
+ context.fail!("a sad end")
93
88
 
94
- it "can be pushed into a FAILURE state with an error code in an options hash" do
95
- context = Context.make
96
- context.fail!("a sad end", 10005)
89
+ expect(context).to be_failure
90
+ expect(context.message).to eq("a sad end")
91
+ expect(context.error_code).to be_nil
92
+ end
97
93
 
98
- expect(context).to be_failure
99
- expect(context.message).to eq("a sad end")
100
- expect(context.error_code).to eq(10005)
101
- end
94
+ it "can be pushed into a FAILURE state with an error code in an options hash" do
95
+ context = LightService::Context.make
96
+ context.fail!("a sad end", 10005)
102
97
 
103
- it "can set a flag to skip all subsequent actions" do
104
- context = Context.make
105
- context.skip_all!
98
+ expect(context).to be_failure
99
+ expect(context.message).to eq("a sad end")
100
+ expect(context.error_code).to eq(10005)
101
+ end
106
102
 
107
- expect(context).to be_skip_all
108
- end
103
+ it "can set a flag to skip all subsequent actions" do
104
+ context = LightService::Context.make
105
+ context.skip_all!
109
106
 
110
- context "stopping additional processing in an action" do
111
- let(:context) { Context.make }
107
+ expect(context).to be_skip_all
108
+ end
112
109
 
113
- it "flags processing to stop on failure" do
114
- context.fail!("on purpose")
115
- expect(context.stop_processing?).to be_truthy
116
- end
110
+ context "stopping additional processing in an action" do
111
+ let(:context) { LightService::Context.make }
117
112
 
118
- it "flags processing to stop when remaining actions should be skipped" do
119
- context.skip_all!
120
- expect(context.stop_processing?).to be_truthy
121
- end
113
+ it "flags processing to stop on failure" do
114
+ context.fail!("on purpose")
115
+ expect(context.stop_processing?).to be_truthy
122
116
  end
123
117
 
118
+ it "flags processing to stop when remaining actions should be skipped" do
119
+ context.skip_all!
120
+ expect(context.stop_processing?).to be_truthy
121
+ end
124
122
  end
123
+
125
124
  end
@@ -1,77 +1,60 @@
1
1
  require 'spec_helper'
2
+ require 'test_doubles'
2
3
 
3
4
  describe LightService::Organizer do
4
- class AnAction; end
5
- class AnotherAction; end
6
5
 
7
- class AnOrganizer
8
- include LightService::Organizer
9
-
10
- def self.do_something(action_arguments)
11
- with(action_arguments).reduce([AnAction, AnotherAction])
12
- end
13
-
14
- def self.do_something_with_no_actions(action_arguments)
15
- with(action_arguments).reduce
16
- end
17
-
18
- def self.do_something_with_no_starting_context
19
- reduce([AnAction, AnotherAction])
20
- end
21
- end
22
-
23
- let(:context) { ::LightService::Context.make(user: user) }
6
+ let(:context) { LightService::Context.make(:user => user) }
24
7
  let(:user) { double(:user) }
25
8
 
26
9
  context "when #with is called with hash" do
27
10
  before do
28
- expect(AnAction).to receive(:execute) \
11
+ expect(TestDoubles::AnAction).to receive(:execute) \
29
12
  .with(context) \
30
13
  .and_return context
31
- expect(AnotherAction).to receive(:execute) \
14
+ expect(TestDoubles::AnotherAction).to receive(:execute) \
32
15
  .with(context) \
33
16
  .and_return context
34
17
  end
35
18
 
36
19
  it "implicitly creates a Context" do
37
- result = AnOrganizer.do_something(:user => user)
20
+ result = TestDoubles::AnOrganizer.do_something(:user => user)
38
21
  expect(result).to eq(context)
39
22
  end
40
23
  end
41
24
 
42
25
  context "when #with is called with Context" do
43
26
  before do
44
- expect(AnAction).to receive(:execute) \
27
+ expect(TestDoubles::AnAction).to receive(:execute) \
45
28
  .with(context) \
46
29
  .and_return context
47
- expect(AnotherAction).to receive(:execute) \
30
+ expect(TestDoubles::AnotherAction).to receive(:execute) \
48
31
  .with(context) \
49
32
  .and_return context
50
33
  end
51
34
 
52
35
  it "uses that Context without recreating it" do
53
- result = AnOrganizer.do_something(context)
36
+ result = TestDoubles::AnOrganizer.do_something(context)
54
37
  expect(result).to eq(context)
55
38
  end
56
39
  end
57
40
 
58
41
  context "when no Actions are specified" do
59
42
  it "throws a Runtime error" do
60
- expect { AnOrganizer.do_something_with_no_actions(context) }.to \
43
+ expect { TestDoubles::AnOrganizer.do_something_with_no_actions(context) }.to \
61
44
  raise_error RuntimeError, "No action(s) were provided"
62
45
  end
63
46
  end
64
47
 
65
48
  context "when no starting context is specified" do
66
49
  it "creates one implicitly" do
67
- expect(AnAction).to receive(:execute) \
50
+ expect(TestDoubles::AnAction).to receive(:execute) \
68
51
  .with({}) \
69
52
  .and_return(context)
70
- expect(AnotherAction).to receive(:execute) \
53
+ expect(TestDoubles::AnotherAction).to receive(:execute) \
71
54
  .with(context) \
72
55
  .and_return(context)
73
56
 
74
- expect { AnOrganizer.do_something_with_no_starting_context } \
57
+ expect { TestDoubles::AnOrganizer.do_something_with_no_starting_context } \
75
58
  .not_to raise_error
76
59
  end
77
60
  end
@@ -6,7 +6,8 @@ require_relative 'tax/provides_free_shipping_action'
6
6
 
7
7
  describe CalculatesTax do
8
8
  let(:order) { double('order') }
9
- let(:context) { double('context') }
9
+ let(:context) { double('context', :keys => [:user],
10
+ :failure? => false, :skip_all? => false) }
10
11
 
11
12
  it "calls the actions in order" do
12
13
  allow(::LightService::Context).to receive(:make) \
@@ -0,0 +1,132 @@
1
+ # A collection of Action and Organizer dummies used in specs
2
+
3
+ module TestDoubles
4
+ class AddsTwoAction
5
+ include LightService::Action
6
+
7
+ executed do |context|
8
+ number = context.fetch(:number, 0)
9
+ context[:number] = number + 2
10
+ end
11
+ end
12
+
13
+ class AnAction; end
14
+ class AnotherAction; end
15
+
16
+ class AnOrganizer
17
+ include LightService::Organizer
18
+
19
+ def self.do_something(action_arguments)
20
+ with(action_arguments).reduce([AnAction, AnotherAction])
21
+ end
22
+
23
+ def self.do_something_with_no_actions(action_arguments)
24
+ with(action_arguments).reduce
25
+ end
26
+
27
+ def self.do_something_with_no_starting_context
28
+ reduce([AnAction, AnotherAction])
29
+ end
30
+ end
31
+
32
+ class MakesTeaWithMilkAction
33
+ include LightService::Action
34
+ expects :tea, :milk
35
+ promises :milk_tea
36
+
37
+ executed do |context|
38
+ context.milk_tea = "#{context.tea} - #{context.milk}"
39
+ end
40
+ end
41
+
42
+ class MultipleExpectsAction
43
+ include LightService::Action
44
+ expects :tea
45
+ expects :milk, :chocolate
46
+ promises :milk_tea
47
+
48
+ executed do |context|
49
+ context.milk_tea = "#{context.tea} - #{context.milk} - with #{context.chocolate}"
50
+ end
51
+ end
52
+
53
+ class MakesCappuccinoAction
54
+ include LightService::Action
55
+ expects :coffee, :milk
56
+ promises :cappuccino
57
+ end
58
+
59
+ class MakesLatteAction
60
+ include LightService::Action
61
+ expects :coffee, :milk
62
+ promises :latte
63
+
64
+ executed do |context|
65
+ if context.milk == :very_hot
66
+ context.fail!("Can't make a latte from a milk that's too hot!")
67
+ next context
68
+ end
69
+
70
+ context[:latte] = "#{context.coffee} - with lots of #{context.milk}"
71
+
72
+ if context.milk == "5%"
73
+ context.skip_all!("Can't make a latte with a fatty milk like that!")
74
+ next context
75
+ end
76
+ end
77
+ end
78
+
79
+ class MultiplePromisesAction
80
+ include LightService::Action
81
+ expects :coffee, :milk
82
+ promises :cappuccino
83
+ promises :latte
84
+
85
+ executed do |context|
86
+ context.cappuccino = "Cappucino needs #{context.coffee} and a little milk"
87
+ context.latte = "Latte needs #{context.coffee} and a lot of milk"
88
+ end
89
+ end
90
+
91
+ class MakesTeaAndCappuccino
92
+ include LightService::Organizer
93
+
94
+ def self.call(tea, milk, coffee)
95
+ with(:tea => tea, :milk => milk, :coffee => coffee)
96
+ .reduce(TestDoubles::MakesTeaWithMilkAction,
97
+ TestDoubles::MakesLatteAction)
98
+ end
99
+ end
100
+
101
+ class MakesCappuccinoAddsTwo
102
+ include LightService::Organizer
103
+
104
+ def self.call(milk, coffee)
105
+ with(:milk => milk, :coffee => coffee)
106
+ .reduce(TestDoubles::AddsTwoAction,
107
+ TestDoubles::MakesLatteAction)
108
+ end
109
+ end
110
+
111
+ class MakesCappuccinoAddsTwoAndFails
112
+ include LightService::Organizer
113
+
114
+ def self.call(coffee)
115
+ with(:milk => :very_hot, :coffee => coffee)
116
+ .reduce(TestDoubles::MakesLatteAction,
117
+ TestDoubles::AddsTwoAction)
118
+
119
+ end
120
+ end
121
+
122
+ class MakesCappuccinoSkipsAddsTwo
123
+ include LightService::Organizer
124
+
125
+ def self.call(coffee)
126
+ with(:milk => "5%", :coffee => coffee)
127
+ .reduce(TestDoubles::MakesLatteAction,
128
+ TestDoubles::AddsTwoAction)
129
+
130
+ end
131
+ end
132
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: light-service
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Attila Domokos
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-27 00:00:00.000000000 Z
11
+ date: 2014-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -79,17 +79,23 @@ files:
79
79
  - Gemfile
80
80
  - LICENSE
81
81
  - README.md
82
+ - RELEASES.md
82
83
  - Rakefile
83
84
  - lib/light-service.rb
84
85
  - lib/light-service/action.rb
86
+ - lib/light-service/configuration.rb
85
87
  - lib/light-service/context.rb
86
88
  - lib/light-service/context_key_verifier.rb
87
89
  - lib/light-service/organizer.rb
90
+ - lib/light-service/organizer/with_reducer.rb
91
+ - lib/light-service/organizer/with_reducer_factory.rb
92
+ - lib/light-service/organizer/with_reducer_log_decorator.rb
88
93
  - lib/light-service/version.rb
89
94
  - light-service.gemspec
90
95
  - resources/light-service.png
91
96
  - resources/organizer_and_actions.png
92
97
  - spec/acceptance/add_numbers_spec.rb
98
+ - spec/acceptance/log_from_organizer_spec.rb
93
99
  - spec/action_expected_keys_spec.rb
94
100
  - spec/action_expects_and_promises_spec.rb
95
101
  - spec/action_promised_keys_spec.rb
@@ -105,6 +111,7 @@ files:
105
111
  - spec/sample/tax/looks_up_tax_percentage_action.rb
106
112
  - spec/sample/tax/provides_free_shipping_action.rb
107
113
  - spec/spec_helper.rb
114
+ - spec/test_doubles.rb
108
115
  homepage: https://github.com/adomokos/light-service
109
116
  licenses:
110
117
  - MIT
@@ -131,6 +138,7 @@ specification_version: 4
131
138
  summary: A service skeleton with an emphasis on simplicity
132
139
  test_files:
133
140
  - spec/acceptance/add_numbers_spec.rb
141
+ - spec/acceptance/log_from_organizer_spec.rb
134
142
  - spec/action_expected_keys_spec.rb
135
143
  - spec/action_expects_and_promises_spec.rb
136
144
  - spec/action_promised_keys_spec.rb
@@ -146,3 +154,4 @@ test_files:
146
154
  - spec/sample/tax/looks_up_tax_percentage_action.rb
147
155
  - spec/sample/tax/provides_free_shipping_action.rb
148
156
  - spec/spec_helper.rb
157
+ - spec/test_doubles.rb