tzu 0.0.2.0 → 0.1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +395 -0
- data/lib/tzu.rb +12 -51
- data/lib/tzu/core_extensions/string.rb +17 -0
- data/lib/tzu/hooks.rb +21 -4
- data/lib/tzu/invalid.rb +0 -2
- data/lib/tzu/outcome.rb +0 -1
- data/lib/tzu/run_methods.rb +32 -0
- data/lib/tzu/sequence.rb +68 -0
- data/lib/tzu/step.rb +34 -0
- data/lib/tzu/validation.rb +5 -14
- data/spec/sequence_spec.rb +206 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/step_spec.rb +24 -0
- data/spec/tzu_spec.rb +195 -20
- data/spec/validation_spec.rb +21 -37
- metadata +24 -5
- data/lib/tzu/organizer.rb +0 -35
- data/spec/organizer_spec.rb +0 -48
data/spec/spec_helper.rb
CHANGED
data/spec/step_spec.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tzu::Step do
|
4
|
+
let(:dummy_mutator) { proc { 'Dummy!' } }
|
5
|
+
|
6
|
+
context '#name' do
|
7
|
+
context 'when name is symbol' do
|
8
|
+
let(:step) { Tzu::Step.new(:step_name) }
|
9
|
+
|
10
|
+
it 'returns name' do
|
11
|
+
expect(step.name).to eq :step_name
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when name is a class' do
|
16
|
+
let(:step) { Tzu::Step.new(StandardError) }
|
17
|
+
let(:outcome) { ControlledOutcome.run(result: :success) }
|
18
|
+
|
19
|
+
it 'returns underscored name' do
|
20
|
+
expect(step.name).to eq :standard_error
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/spec/tzu_spec.rb
CHANGED
@@ -1,39 +1,214 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
class ControlledOutcome
|
4
|
+
include Tzu
|
5
|
+
|
6
|
+
def call(params)
|
7
|
+
result = params[:result]
|
8
|
+
return 123 if result == :success
|
9
|
+
return invalid!('Invalid Message') if result == :invalid
|
10
|
+
return fail!(:falure_type, 'Failure Message') if result == :failure
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class MyRequestObject
|
15
|
+
attr_reader :value, :errors
|
16
|
+
|
17
|
+
def initialize(params)
|
18
|
+
@params = params
|
19
|
+
@value = params[:value]
|
20
|
+
@errors = 'Error Message'
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid?
|
24
|
+
@params[:valid]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class VirtusRequestObject
|
29
|
+
include Virtus.model
|
30
|
+
include ActiveModel::Validations
|
31
|
+
|
32
|
+
validates :name, :age, presence: :true
|
33
|
+
|
34
|
+
attribute :name, String
|
35
|
+
attribute :age, Integer
|
36
|
+
end
|
37
|
+
|
38
|
+
class ValidatedCommand
|
39
|
+
include Tzu
|
40
|
+
|
41
|
+
request_object MyRequestObject
|
42
|
+
|
43
|
+
def call(request)
|
44
|
+
request.value
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class VirtusValidatedCommand
|
49
|
+
include Tzu
|
50
|
+
|
51
|
+
request_object VirtusRequestObject
|
52
|
+
|
53
|
+
def call(request)
|
54
|
+
"Name: #{request.name}, Age: #{request.age}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
3
58
|
describe Tzu do
|
59
|
+
context '#run' do
|
60
|
+
context 'when command succeeds' do
|
61
|
+
let(:outcome) { ControlledOutcome.run(result: :success) }
|
4
62
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
63
|
+
it 'correctly returns sets pass/fail flags' do
|
64
|
+
expect(outcome.success?).to be true
|
65
|
+
expect(outcome.failure?).to be false
|
66
|
+
end
|
9
67
|
|
10
|
-
|
11
|
-
|
12
|
-
end
|
68
|
+
it 'returns result' do
|
69
|
+
expect(outcome.result).to eq(123)
|
13
70
|
end
|
14
71
|
end
|
15
72
|
|
16
|
-
|
17
|
-
|
18
|
-
|
73
|
+
context 'when command is invalid' do
|
74
|
+
let(:outcome) { ControlledOutcome.run(result: :invalid) }
|
75
|
+
|
76
|
+
it 'correctly returns sets pass/fail flags' do
|
77
|
+
expect(outcome.success?).to be false
|
78
|
+
expect(outcome.failure?).to be true
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'returns error string as errors hash' do
|
82
|
+
expect(outcome.result).to eq(errors: 'Invalid Message')
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'sets type to validation' do
|
86
|
+
expect(outcome.type).to eq(:validation)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'when command fails' do
|
91
|
+
let(:outcome) { ControlledOutcome.run(result: :failure) }
|
92
|
+
|
93
|
+
it 'correctly returns sets pass/fail flags' do
|
94
|
+
expect(outcome.success?).to be false
|
95
|
+
expect(outcome.failure?).to be true
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'returns error string as errors hash' do
|
99
|
+
expect(outcome.result).to eq(errors: 'Failure Message')
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'sets type to falure_type' do
|
103
|
+
expect(outcome.type).to eq(:falure_type)
|
104
|
+
end
|
19
105
|
end
|
20
106
|
end
|
21
107
|
|
22
|
-
context '
|
23
|
-
|
24
|
-
|
25
|
-
|
108
|
+
context '#run with block' do
|
109
|
+
let(:success_spy) { spy('success') }
|
110
|
+
let(:invalid_spy) { spy('invalid') }
|
111
|
+
let(:failure_spy) { spy('failure') }
|
26
112
|
|
27
|
-
|
28
|
-
|
29
|
-
|
113
|
+
before do
|
114
|
+
ControlledOutcome.run(result: result) do
|
115
|
+
success { |_| success_spy.call }
|
116
|
+
invalid { |_| invalid_spy.call }
|
117
|
+
failure { |_| failure_spy.call }
|
30
118
|
end
|
31
119
|
end
|
32
120
|
|
33
|
-
|
34
|
-
result
|
35
|
-
|
121
|
+
context 'when command succeeds' do
|
122
|
+
let(:result) { :success }
|
123
|
+
it 'executes success block' do
|
124
|
+
expect(success_spy).to have_received(:call)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'when command is invalid' do
|
129
|
+
let(:result) { :invalid }
|
130
|
+
it 'executes invalid block' do
|
131
|
+
expect(invalid_spy).to have_received(:call)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'when command fails' do
|
136
|
+
let(:result) { :failure }
|
137
|
+
it 'executes failure block' do
|
138
|
+
expect(failure_spy).to have_received(:call)
|
139
|
+
end
|
36
140
|
end
|
37
141
|
end
|
38
142
|
|
143
|
+
context '#run with request object' do
|
144
|
+
context 'when request is valid' do
|
145
|
+
let(:outcome) { ValidatedCommand.run(value: 1111, valid: true) }
|
146
|
+
|
147
|
+
it 'executes successfully' do
|
148
|
+
expect(outcome.success?).to be true
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'returns value' do
|
152
|
+
expect(outcome.result).to eq 1111
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'when request is invalid' do
|
157
|
+
let(:outcome) { ValidatedCommand.run(value: 2222, valid: false) }
|
158
|
+
|
159
|
+
it 'does not execute successfully' do
|
160
|
+
expect(outcome.failure?).to be true
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'has outcome type :validation' do
|
164
|
+
expect(outcome.type).to eq :validation
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'returns error string as errors hash' do
|
168
|
+
expect(outcome.result).to eq(errors: 'Error Message')
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context 'with virtus/active_model request object' do
|
173
|
+
let(:outcome) { VirtusValidatedCommand.run(params) }
|
174
|
+
|
175
|
+
context 'when request is valid' do
|
176
|
+
let(:params) { { name: 'Young Tzu', age: '19' } }
|
177
|
+
|
178
|
+
it 'executes successfully' do
|
179
|
+
expect(outcome.success?).to be true
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context 'when request is invalid' do
|
184
|
+
let(:params) { { name: 'My Name' } }
|
185
|
+
|
186
|
+
it 'does not execute successfully' do
|
187
|
+
expect(outcome.failure?).to be true
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'returns ActiveModel error object' do
|
191
|
+
expect(outcome.result).to eq(age: ["can't be blank"])
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
context '#run!' do
|
198
|
+
context 'when command is invalid' do
|
199
|
+
let(:outcome) { ControlledOutcome.run!(result: :invalid) }
|
200
|
+
|
201
|
+
it 'raises Tzu::Invalid' do
|
202
|
+
expect { outcome }.to raise_error Tzu::Invalid, 'Invalid Message'
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context 'when command fails' do
|
207
|
+
let(:outcome) { ControlledOutcome.run!(result: :failure) }
|
208
|
+
|
209
|
+
it 'raises Tzu::Failure' do
|
210
|
+
expect { outcome }.to raise_error Tzu::Failure, 'Failure Message'
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
39
214
|
end
|
data/spec/validation_spec.rb
CHANGED
@@ -6,7 +6,6 @@ describe Tzu::Validation do
|
|
6
6
|
subject do
|
7
7
|
Class.new do
|
8
8
|
include Tzu
|
9
|
-
include Tzu::Validation
|
10
9
|
end
|
11
10
|
end
|
12
11
|
|
@@ -24,29 +23,10 @@ describe Tzu::Validation do
|
|
24
23
|
end
|
25
24
|
end
|
26
25
|
|
27
|
-
context '
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
include Tzu::Validation
|
32
|
-
|
33
|
-
def valid?(params)
|
34
|
-
Tzu::ValidationResult.new(false, [])
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'returns validation result' do
|
40
|
-
result = subject.run(nil)
|
41
|
-
expect(result).to have_attributes(success: false, type: :validation)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context 'error message is string' do
|
46
|
-
let(:str) { 'error_message' }
|
47
|
-
subject { Tzu::Invalid.new(str) }
|
48
|
-
|
49
|
-
context 'invoked directly' do
|
26
|
+
context 'invoked directly' do
|
27
|
+
context 'error message is string' do
|
28
|
+
let(:str) { 'error_message' }
|
29
|
+
subject { Tzu::Invalid.new(str) }
|
50
30
|
it 'has string as #message' do
|
51
31
|
expect(subject.message).to eq str
|
52
32
|
end
|
@@ -55,36 +35,40 @@ describe Tzu::Validation do
|
|
55
35
|
expect(subject.errors).to eq(errors: str)
|
56
36
|
end
|
57
37
|
end
|
38
|
+
end
|
58
39
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
include Tzu::Validation
|
40
|
+
context 'rescued' do
|
41
|
+
subject do
|
42
|
+
Class.new do
|
43
|
+
include Tzu
|
64
44
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
45
|
+
def call(params)
|
46
|
+
raise StandardError.new(params[:message])
|
47
|
+
rescue StandardError => e
|
48
|
+
invalid! e
|
70
49
|
end
|
71
50
|
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'error message is string' do
|
54
|
+
let(:str) { 'error_message' }
|
55
|
+
let(:params) { { message: str } }
|
72
56
|
|
73
57
|
describe '#run' do
|
74
58
|
it 'returns error hash as result' do
|
75
|
-
outcome = subject.run(
|
59
|
+
outcome = subject.run(params)
|
76
60
|
expect(outcome.result).to eq(errors: str)
|
77
61
|
end
|
78
62
|
end
|
79
63
|
|
80
64
|
describe '#run!' do
|
81
65
|
it 'has string as #message' do
|
82
|
-
expect { subject.run!(
|
66
|
+
expect { subject.run!(params) }.to raise_error Tzu::Invalid, str
|
83
67
|
end
|
84
68
|
|
85
69
|
it 'has string as #errors' do
|
86
70
|
begin
|
87
|
-
subject.run!(
|
71
|
+
subject.run!(params)
|
88
72
|
expect(false).to be true # Should never reach this
|
89
73
|
rescue Tzu::Invalid => e
|
90
74
|
expect(e.errors).to eq(errors: str)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tzu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Morgan Bruce
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-07-
|
12
|
+
date: 2015-07-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -95,6 +95,20 @@ dependencies:
|
|
95
95
|
- - ">="
|
96
96
|
- !ruby/object:Gem::Version
|
97
97
|
version: '0'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: virtus
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
98
112
|
description: Encapsulate your database queries with dynamically generated classes
|
99
113
|
email: morgan@onfido.com
|
100
114
|
executables: []
|
@@ -104,18 +118,22 @@ files:
|
|
104
118
|
- LICENSE.txt
|
105
119
|
- README.md
|
106
120
|
- lib/tzu.rb
|
121
|
+
- lib/tzu/core_extensions/string.rb
|
107
122
|
- lib/tzu/failure.rb
|
108
123
|
- lib/tzu/hooks.rb
|
109
124
|
- lib/tzu/invalid.rb
|
110
125
|
- lib/tzu/match.rb
|
111
|
-
- lib/tzu/organizer.rb
|
112
126
|
- lib/tzu/outcome.rb
|
127
|
+
- lib/tzu/run_methods.rb
|
128
|
+
- lib/tzu/sequence.rb
|
129
|
+
- lib/tzu/step.rb
|
113
130
|
- lib/tzu/validation.rb
|
114
131
|
- lib/tzu/validation_result.rb
|
115
132
|
- spec/hooks_spec.rb
|
116
|
-
- spec/organizer_spec.rb
|
117
133
|
- spec/outcome_spec.rb
|
134
|
+
- spec/sequence_spec.rb
|
118
135
|
- spec/spec_helper.rb
|
136
|
+
- spec/step_spec.rb
|
119
137
|
- spec/tzu_spec.rb
|
120
138
|
- spec/validation_spec.rb
|
121
139
|
homepage: https://github.com/onfido/tzu
|
@@ -145,9 +163,10 @@ summary: Get is a library designed to encapsulate Rails database queries and pre
|
|
145
163
|
query pollution in the view layer.
|
146
164
|
test_files:
|
147
165
|
- spec/hooks_spec.rb
|
148
|
-
- spec/organizer_spec.rb
|
149
166
|
- spec/outcome_spec.rb
|
167
|
+
- spec/sequence_spec.rb
|
150
168
|
- spec/spec_helper.rb
|
169
|
+
- spec/step_spec.rb
|
151
170
|
- spec/tzu_spec.rb
|
152
171
|
- spec/validation_spec.rb
|
153
172
|
has_rdoc:
|
data/lib/tzu/organizer.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'ostruct'
|
2
|
-
|
3
|
-
module Tzu
|
4
|
-
module Organizer
|
5
|
-
def self.included(base)
|
6
|
-
base.class_eval do
|
7
|
-
include Tzu
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
Step = Struct.new(:command, :transform)
|
12
|
-
|
13
|
-
def steps
|
14
|
-
@steps ||= []
|
15
|
-
end
|
16
|
-
|
17
|
-
def add_step(command, &transform)
|
18
|
-
steps << Step.new(command, transform)
|
19
|
-
end
|
20
|
-
|
21
|
-
def call(params)
|
22
|
-
result = call_steps(params)
|
23
|
-
self.respond_to?(:parse) ? parse(result) : result
|
24
|
-
end
|
25
|
-
|
26
|
-
def call_steps(params)
|
27
|
-
result = ::OpenStruct.new
|
28
|
-
steps.each do |step|
|
29
|
-
call_with = step.transform ? step.transform(params, result) : params
|
30
|
-
result[step.command.command_name] = step.command.run!(call_with)
|
31
|
-
end
|
32
|
-
result
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|