jace 0.0.2 → 0.1.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 +4 -4
- data/.circleci/config.yml +54 -5
- data/.rubocop.yml +1 -0
- data/Dockerfile +2 -2
- data/README.md +38 -5
- data/config/check_specs.yml +1 -0
- data/config/yardstick.yml +11 -4
- data/jace.gemspec +12 -12
- data/lib/jace/dispatcher.rb +54 -0
- data/lib/jace/executer.rb +43 -9
- data/lib/jace/handler.rb +39 -0
- data/lib/jace/registry.rb +83 -0
- data/lib/jace/version.rb +1 -1
- data/lib/jace.rb +5 -2
- data/spec/integration/readme/jace/registry_spec.rb +30 -0
- data/spec/integration/yard/jace/registry_spec.rb +46 -0
- data/spec/lib/jace/dispatcher_spec.rb +188 -0
- data/spec/lib/jace/executer_spec.rb +34 -0
- data/spec/lib/jace/handler_spec.rb +101 -0
- data/spec/lib/jace/registry_spec.rb +240 -0
- data/spec/support/models/context.rb +5 -0
- data/spec/support/models/person.rb +5 -1
- data/spec/support/models/some_context.rb +15 -0
- metadata +37 -28
@@ -0,0 +1,188 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Jace::Dispatcher do
|
6
|
+
subject(:dispatcher) do
|
7
|
+
described_class.new(
|
8
|
+
before: before,
|
9
|
+
after: after
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:before) { nil }
|
14
|
+
let(:after) { nil }
|
15
|
+
let(:person) { Person.new }
|
16
|
+
|
17
|
+
describe '#dispatch' do
|
18
|
+
context 'without before or after' do
|
19
|
+
let(:result) do
|
20
|
+
described_class.new.dispatch(person) { 10 }
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'returns re result of block call' do
|
24
|
+
expect(result).to eq(10)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'executes in current context ignoring given context' do
|
28
|
+
expect(described_class.new.dispatch(person) { self })
|
29
|
+
.to eq(self)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'with before option' do
|
34
|
+
context 'with symbol' do
|
35
|
+
let(:before) { :init_age }
|
36
|
+
|
37
|
+
let(:result) do
|
38
|
+
dispatcher.dispatch(person) { person.age }
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'returns result after running before code' do
|
42
|
+
expect(result).to eq(1)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'changes state of context object' do
|
46
|
+
expect { result }.to change(person, :age)
|
47
|
+
.from(nil).to(1)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'with block' do
|
52
|
+
let(:block) { proc { @age = 10 } }
|
53
|
+
let(:before) { block }
|
54
|
+
|
55
|
+
let(:result) do
|
56
|
+
dispatcher.dispatch(person) { person.age }
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'returns result after running before code' do
|
60
|
+
expect(result).to eq(10)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'changes state of context object' do
|
64
|
+
expect { result }.to change(person, :age)
|
65
|
+
.from(nil).to(10)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'with array' do
|
70
|
+
let(:block) { proc { @brothers = @age ? 2 : 10 } }
|
71
|
+
let(:before) { [:init_age, block] }
|
72
|
+
|
73
|
+
let(:result) do
|
74
|
+
dispatcher.dispatch(person) do
|
75
|
+
person.age + person.brothers
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'returns result after running all before code' do
|
80
|
+
expect(result).to eq(3)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'changes state of context object by block call' do
|
84
|
+
expect { result }.to change(person, :brothers)
|
85
|
+
.from(0).to(2)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'changes state of context object by method call' do
|
89
|
+
expect { result }.to change(person, :age)
|
90
|
+
.from(nil).to(1)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'with after option' do
|
96
|
+
context 'with symbol' do
|
97
|
+
let(:after) { :init_age }
|
98
|
+
|
99
|
+
let(:result) do
|
100
|
+
dispatcher.dispatch(person) { person.age }
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'returns result before running after code' do
|
104
|
+
expect(result).to be_nil
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'changes state of context object' do
|
108
|
+
expect { result }.to change(person, :age)
|
109
|
+
.from(nil).to(1)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'with block' do
|
114
|
+
let(:block) { proc { @age = 10 } }
|
115
|
+
let(:after) { block }
|
116
|
+
|
117
|
+
let(:result) do
|
118
|
+
dispatcher.dispatch(person) { person.age }
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'returns result before running after code' do
|
122
|
+
expect(result).to be_nil
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'changes state of context object' do
|
126
|
+
expect { result }.to change(person, :age)
|
127
|
+
.from(nil).to(10)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context 'with array' do
|
132
|
+
let(:block) { proc { @brothers = @age ? 2 : 10 } }
|
133
|
+
let(:after) { [:init_age, block] }
|
134
|
+
|
135
|
+
let(:result) do
|
136
|
+
dispatcher.dispatch(person) do
|
137
|
+
person.age.to_i + person.brothers
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'returns result before running all after code' do
|
142
|
+
expect(result).to eq(0)
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'changes state of context object by block call' do
|
146
|
+
expect { result }.to change(person, :brothers)
|
147
|
+
.from(0).to(2)
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'changes state of context object by method call' do
|
151
|
+
expect { result }.to change(person, :age)
|
152
|
+
.from(nil).to(1)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context 'when no block is provided' do
|
158
|
+
let(:result) do
|
159
|
+
dispatcher.dispatch(person)
|
160
|
+
end
|
161
|
+
|
162
|
+
it do
|
163
|
+
expect(result).to be_nil
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'when handlers are given' do
|
167
|
+
let(:before) { :init_age }
|
168
|
+
let(:after) { :init_height }
|
169
|
+
|
170
|
+
it do
|
171
|
+
expect(result).to be_nil
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'calls before handler' do
|
175
|
+
expect { result }
|
176
|
+
.to change(person, :age)
|
177
|
+
.to(1)
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'calls after handler' do
|
181
|
+
expect { result }
|
182
|
+
.to change(person, :height)
|
183
|
+
.to(178)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
@@ -140,5 +140,39 @@ describe Jace::Executer do
|
|
140
140
|
end
|
141
141
|
end
|
142
142
|
end
|
143
|
+
|
144
|
+
context 'when no block is provided' do
|
145
|
+
let(:result) do
|
146
|
+
described_class.call(context: person)
|
147
|
+
end
|
148
|
+
|
149
|
+
it do
|
150
|
+
expect(result).to be_nil
|
151
|
+
end
|
152
|
+
|
153
|
+
context 'when handlers are given' do
|
154
|
+
let(:result) do
|
155
|
+
described_class.call(
|
156
|
+
before: :init_age, after: :init_height, context: person
|
157
|
+
)
|
158
|
+
end
|
159
|
+
|
160
|
+
it do
|
161
|
+
expect(result).to be_nil
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'calls before handler' do
|
165
|
+
expect { result }
|
166
|
+
.to change(person, :age)
|
167
|
+
.to(1)
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'calls after handler' do
|
171
|
+
expect { result }
|
172
|
+
.to change(person, :height)
|
173
|
+
.to(178)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
143
177
|
end
|
144
178
|
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Jace::Handler do
|
6
|
+
let(:context) { instance_double(Context) }
|
7
|
+
|
8
|
+
describe '#call' do
|
9
|
+
context 'when handler is initialized with a block' do
|
10
|
+
subject(:handler) { described_class.new { method_call } }
|
11
|
+
|
12
|
+
before { allow(context).to receive(:method_call) }
|
13
|
+
|
14
|
+
it 'calls the block' do
|
15
|
+
handler.call(context)
|
16
|
+
|
17
|
+
expect(context).to have_received(:method_call).once
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when handler is initialized with a proc' do
|
22
|
+
subject(:handler) { described_class.new(proc { method_call }) }
|
23
|
+
|
24
|
+
before { allow(context).to receive(:method_call) }
|
25
|
+
|
26
|
+
it 'calls the block' do
|
27
|
+
handler.call(context)
|
28
|
+
|
29
|
+
expect(context).to have_received(:method_call).once
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when handler is initialized with a symbol' do
|
34
|
+
subject(:handler) { described_class.new(:method_call) }
|
35
|
+
|
36
|
+
before { allow(context).to receive(:method_call) }
|
37
|
+
|
38
|
+
it 'calls the block' do
|
39
|
+
handler.call(context)
|
40
|
+
|
41
|
+
expect(context).to have_received(:method_call).once
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#to_proc' do
|
47
|
+
context 'when handler is initialized with a block' do
|
48
|
+
subject(:handler) { described_class.new { method_call } }
|
49
|
+
|
50
|
+
it do
|
51
|
+
expect(handler.to_proc).to be_a(Proc)
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when the proc is called' do
|
55
|
+
before { allow(context).to receive(:method_call) }
|
56
|
+
|
57
|
+
it 'calls the block' do
|
58
|
+
context.instance_eval(&handler.to_proc)
|
59
|
+
|
60
|
+
expect(context).to have_received(:method_call).once
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when handler is initialized with a proc' do
|
66
|
+
subject(:handler) { described_class.new(proc { method_call }) }
|
67
|
+
|
68
|
+
it do
|
69
|
+
expect(handler.to_proc).to be_a(Proc)
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'when the proc is called' do
|
73
|
+
before { allow(context).to receive(:method_call) }
|
74
|
+
|
75
|
+
it 'calls the block' do
|
76
|
+
context.instance_eval(&handler.to_proc)
|
77
|
+
|
78
|
+
expect(context).to have_received(:method_call).once
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'when handler is initialized with a symbol' do
|
84
|
+
subject(:handler) { described_class.new(:method_call) }
|
85
|
+
|
86
|
+
it do
|
87
|
+
expect(handler.to_proc).to be_a(Proc)
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'when the proc is called' do
|
91
|
+
before { allow(context).to receive(:method_call) }
|
92
|
+
|
93
|
+
it 'calls the block' do
|
94
|
+
context.instance_eval(&handler.to_proc)
|
95
|
+
|
96
|
+
expect(context).to have_received(:method_call).once
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,240 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Jace::Registry do
|
6
|
+
subject(:registry) { described_class.new }
|
7
|
+
|
8
|
+
describe '#register' do
|
9
|
+
let(:event_name) { :event_name }
|
10
|
+
let(:expected_registry) do
|
11
|
+
{ event_name: Jace::Dispatcher }
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'when event is a symbol' do
|
15
|
+
it 'adds even to events registry' do
|
16
|
+
expect { registry.register(event_name) {} }
|
17
|
+
.to change(registry, :registry)
|
18
|
+
.to(expected_registry)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'adds event to event list' do
|
22
|
+
expect { registry.register(event_name) {} }
|
23
|
+
.to change(registry, :events)
|
24
|
+
.by([:event_name])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when event is a string' do
|
29
|
+
let(:event_name) { 'event_name' }
|
30
|
+
let(:expected_registry) do
|
31
|
+
{ event_name: Jace::Dispatcher }
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'adds even to events registry' do
|
35
|
+
expect { registry.register(event_name) {} }
|
36
|
+
.to change(registry, :registry)
|
37
|
+
.to(expected_registry)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'adds event to event list' do
|
41
|
+
expect { registry.register(event_name) {} }
|
42
|
+
.to change(registry, :events)
|
43
|
+
.by([:event_name])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when the event was already registerd' do
|
48
|
+
before { registry.register(event_name) {} }
|
49
|
+
|
50
|
+
it 'does not repace dispatcher' do
|
51
|
+
expect { registry.register(event_name) {} }
|
52
|
+
.not_to change(registry, :registry)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'adds event to event list' do
|
56
|
+
expect { registry.register(event_name) {} }
|
57
|
+
.not_to(change(registry, :events))
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'when another event was already registerd' do
|
62
|
+
let(:expected_registry) do
|
63
|
+
{
|
64
|
+
event_name: Jace::Dispatcher,
|
65
|
+
other_event_name: Jace::Dispatcher
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
before { registry.register(:other_event_name) {} }
|
70
|
+
|
71
|
+
it 'adds even a callback to the event registry' do
|
72
|
+
expect { registry.register(event_name) {} }
|
73
|
+
.to change(registry, :registry)
|
74
|
+
.to(expected_registry)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'adds event to event list' do
|
78
|
+
expect { registry.register(event_name) {} }
|
79
|
+
.to change(registry, :events)
|
80
|
+
.by([:event_name])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'when registering for another instant' do
|
85
|
+
let(:expected_registry) do
|
86
|
+
{
|
87
|
+
event_name: Jace::Dispatcher
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'adds even a callback to the event registry' do
|
92
|
+
expect { registry.register(event_name, :before) {} }
|
93
|
+
.to change(registry, :registry)
|
94
|
+
.to(expected_registry)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'adds event to event list' do
|
98
|
+
expect { registry.register(event_name) {} }
|
99
|
+
.to change(registry, :events)
|
100
|
+
.by([:event_name])
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'when registering for another instant of an exiosting event' do
|
105
|
+
let(:expected_registry) do
|
106
|
+
{
|
107
|
+
event_name: { before: [Proc], after: [Proc] }
|
108
|
+
}
|
109
|
+
end
|
110
|
+
|
111
|
+
before { registry.register(event_name, :after) {} }
|
112
|
+
|
113
|
+
it 'does not repace dispatcher' do
|
114
|
+
expect { registry.register(event_name, :before) {} }
|
115
|
+
.not_to change(registry, :registry)
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'does not add event to event list' do
|
119
|
+
expect { registry.register(event_name) {} }
|
120
|
+
.not_to(change(registry, :events))
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe '#trigger' do
|
126
|
+
let(:event_name) { :event_name }
|
127
|
+
let(:context) { instance_double(Context) }
|
128
|
+
|
129
|
+
context 'when an event handler has been registered' do
|
130
|
+
before do
|
131
|
+
allow(context).to receive(:method_call)
|
132
|
+
allow(context).to receive(:other_method)
|
133
|
+
registry.register(event_name) { method_call }
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'execute the event handler' do
|
137
|
+
registry.trigger(event_name, context) {}
|
138
|
+
expect(context).to have_received(:method_call)
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'execute the block' do
|
142
|
+
registry.trigger(event_name, context) { context.other_method }
|
143
|
+
expect(context).to have_received(:other_method)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'when many event handlers have been registered' do
|
148
|
+
before do
|
149
|
+
allow(context).to receive(:method_call)
|
150
|
+
allow(context).to receive(:another_method_call)
|
151
|
+
allow(context).to receive(:other_method)
|
152
|
+
|
153
|
+
registry.register(event_name) { method_call }
|
154
|
+
registry.register(event_name) { another_method_call }
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'execute the event handler' do
|
158
|
+
registry.trigger(event_name, context) {}
|
159
|
+
expect(context).to have_received(:method_call)
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'execute the other event handler' do
|
163
|
+
registry.trigger(event_name, context) {}
|
164
|
+
expect(context).to have_received(:another_method_call)
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'execute the block' do
|
168
|
+
registry.trigger(event_name, context) { context.other_method }
|
169
|
+
expect(context).to have_received(:other_method).once
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'when another event handler has been registered' do
|
174
|
+
before do
|
175
|
+
allow(context).to receive(:method_call)
|
176
|
+
allow(context).to receive(:other_method)
|
177
|
+
registry.register(:other_event) { method_call }
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'does not execute the event handler' do
|
181
|
+
registry.trigger(event_name, context) {}
|
182
|
+
expect(context).not_to have_received(:method_call)
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'execute the block' do
|
186
|
+
registry.trigger(event_name, context) { context.other_method }
|
187
|
+
expect(context).to have_received(:other_method)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
context 'when an event handler has not been registered' do
|
192
|
+
before do
|
193
|
+
allow(context).to receive(:other_method)
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'execute the block' do
|
197
|
+
registry.trigger(event_name, context) { context.other_method }
|
198
|
+
expect(context).to have_received(:other_method)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
context 'when no block is given' do
|
203
|
+
before do
|
204
|
+
allow(context).to receive(:method_call)
|
205
|
+
|
206
|
+
registry.register(event_name) { method_call }
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'execute the event handler' do
|
210
|
+
registry.trigger(event_name, context)
|
211
|
+
|
212
|
+
expect(context).to have_received(:method_call)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
describe 'order execution' do
|
217
|
+
let(:context) { SomeContext.new }
|
218
|
+
let(:expected_texts) do
|
219
|
+
[
|
220
|
+
'doing something before',
|
221
|
+
'doing something middle',
|
222
|
+
'doing something after'
|
223
|
+
]
|
224
|
+
end
|
225
|
+
|
226
|
+
before do
|
227
|
+
registry.register(:the_event) { do_something(:after) }
|
228
|
+
registry.register(:the_event, :before) { do_something(:before) }
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'runs the event handlers in order' do
|
232
|
+
registry.trigger(:the_event, context) do
|
233
|
+
context.do_something(:middle)
|
234
|
+
end
|
235
|
+
|
236
|
+
expect(context.text).to eq(expected_texts)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Person
|
4
|
-
attr_accessor :age
|
4
|
+
attr_accessor :age, :height
|
5
5
|
|
6
6
|
def brothers
|
7
7
|
@brothers ||= 0
|
@@ -9,6 +9,10 @@ class Person
|
|
9
9
|
|
10
10
|
private
|
11
11
|
|
12
|
+
def init_height
|
13
|
+
@height = 178
|
14
|
+
end
|
15
|
+
|
12
16
|
def init_age
|
13
17
|
@age ||= 1
|
14
18
|
end
|