tzu 0.0.2.0 → 0.1.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/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
|