teckel 0.8.0 → 0.9.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/CHANGELOG.md +28 -7
- data/lib/teckel/chain/config.rb +20 -19
- data/lib/teckel/chain/result.rb +5 -9
- data/lib/teckel/chain/runner.rb +8 -6
- data/lib/teckel/chain.rb +15 -11
- data/lib/teckel/config.rb +15 -9
- data/lib/teckel/contracts.rb +3 -3
- data/lib/teckel/operation/config.rb +31 -28
- data/lib/teckel/operation/result.rb +8 -8
- data/lib/teckel/operation/runner.rb +1 -1
- data/lib/teckel/operation.rb +5 -5
- data/lib/teckel/result.rb +2 -2
- data/lib/teckel/version.rb +2 -1
- data/lib/teckel.rb +4 -1
- metadata +19 -54
- data/spec/chain/around_hook_spec.rb +0 -100
- data/spec/chain/default_settings_spec.rb +0 -39
- data/spec/chain/inheritance_spec.rb +0 -116
- data/spec/chain/none_input_spec.rb +0 -36
- data/spec/chain/results_spec.rb +0 -53
- data/spec/chain_spec.rb +0 -255
- data/spec/config_spec.rb +0 -26
- data/spec/doctest_helper.rb +0 -8
- data/spec/operation/config_spec.rb +0 -227
- data/spec/operation/contract_trace_spec.rb +0 -118
- data/spec/operation/default_settings_spec.rb +0 -120
- data/spec/operation/fail_on_input_spec.rb +0 -103
- data/spec/operation/inheritance_spec.rb +0 -94
- data/spec/operation/result_spec.rb +0 -49
- data/spec/operation/results_spec.rb +0 -117
- data/spec/operation_spec.rb +0 -531
- data/spec/rb27/pattern_matching_spec.rb +0 -193
- data/spec/result_spec.rb +0 -22
- data/spec/spec_helper.rb +0 -35
- data/spec/support/dry_base.rb +0 -8
- data/spec/support/fake_db.rb +0 -12
- data/spec/support/fake_models.rb +0 -20
- data/spec/teckel_spec.rb +0 -7
@@ -51,13 +51,13 @@ module Teckel
|
|
51
51
|
end
|
52
52
|
|
53
53
|
# @!attribute [r] value
|
54
|
-
# @return [
|
54
|
+
# @return [Object] the value/payload
|
55
55
|
attr_reader :value
|
56
56
|
|
57
57
|
# Get the error/failure value
|
58
|
-
# @yield [
|
59
|
-
# @param default [
|
60
|
-
# @return [
|
58
|
+
# @yield [Object] If a block is given and this is not a failure result, the value is yielded to the block
|
59
|
+
# @param default [Object] return this default value if it's not a failure result
|
60
|
+
# @return [Object] the value/payload
|
61
61
|
def failure(default = nil, &block)
|
62
62
|
return value unless @successful
|
63
63
|
return yield(value) if block
|
@@ -66,9 +66,9 @@ module Teckel
|
|
66
66
|
end
|
67
67
|
|
68
68
|
# Get the success value
|
69
|
-
# @yield [
|
70
|
-
# @param default [
|
71
|
-
# @return [
|
69
|
+
# @yield [Object] If a block is given and this is not a success result, the value is yielded to the block
|
70
|
+
# @param default [Object] return this default value if it's not a success result
|
71
|
+
# @return [Object] the value/payload
|
72
72
|
def success(default = nil, &block)
|
73
73
|
return value if @successful
|
74
74
|
return yield(value) if block
|
@@ -85,7 +85,7 @@ module Teckel
|
|
85
85
|
value
|
86
86
|
end
|
87
87
|
|
88
|
-
|
88
|
+
alias_method :new, :[]
|
89
89
|
end
|
90
90
|
end
|
91
91
|
end
|
data/lib/teckel/operation.rb
CHANGED
@@ -59,11 +59,11 @@ module Teckel
|
|
59
59
|
module Operation
|
60
60
|
module ClassMethods
|
61
61
|
# @!visibility private
|
62
|
-
UNDEFINED =
|
62
|
+
UNDEFINED = Teckel::UNDEFINED
|
63
63
|
|
64
64
|
# Invoke the Operation
|
65
65
|
#
|
66
|
-
# @param input Any form of input your {Teckel::Operation::Config#input input} class can handle via the given
|
66
|
+
# @param input [Object,nil] Any form of input your {Teckel::Operation::Config#input input} class can handle via the given
|
67
67
|
# {Teckel::Operation::Config#input_constructor input_constructor}
|
68
68
|
# @return Either An instance of your defined {Teckel::Operation::Config#error error} class or
|
69
69
|
# {Teckel::Operation::Config#output output} class
|
@@ -111,7 +111,7 @@ module Teckel
|
|
111
111
|
def with(settings)
|
112
112
|
runable(settings_constructor.call(settings))
|
113
113
|
end
|
114
|
-
|
114
|
+
alias_method :set, :with
|
115
115
|
|
116
116
|
# Constructs a Runner instance for {call} and {with}.
|
117
117
|
#
|
@@ -205,8 +205,8 @@ module Teckel
|
|
205
205
|
|
206
206
|
def self.included(receiver)
|
207
207
|
receiver.class_eval do
|
208
|
-
extend
|
209
|
-
extend
|
208
|
+
extend Config
|
209
|
+
extend ClassMethods
|
210
210
|
include InstanceMethods
|
211
211
|
end
|
212
212
|
end
|
data/lib/teckel/result.rb
CHANGED
@@ -37,7 +37,7 @@ module Teckel
|
|
37
37
|
end
|
38
38
|
|
39
39
|
# @!attribute [r] value
|
40
|
-
# @return [
|
40
|
+
# @return [Object] the value/payload
|
41
41
|
def value
|
42
42
|
raise NotImplementedError, "Result object does not implement `value`"
|
43
43
|
end
|
@@ -56,7 +56,7 @@ module Teckel
|
|
56
56
|
|
57
57
|
def self.included(receiver)
|
58
58
|
receiver.class_eval do
|
59
|
-
extend
|
59
|
+
extend ClassMethods
|
60
60
|
include InstanceMethods
|
61
61
|
end
|
62
62
|
end
|
data/lib/teckel/version.rb
CHANGED
data/lib/teckel.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative "teckel/version"
|
4
4
|
|
5
5
|
module Teckel
|
6
6
|
# Base error class for this lib
|
@@ -13,6 +13,9 @@ module Teckel
|
|
13
13
|
class MissingConfigError < Teckel::Error; end
|
14
14
|
|
15
15
|
DEFAULT_CONSTRUCTOR = :[]
|
16
|
+
|
17
|
+
# @!visibility private
|
18
|
+
UNDEFINED = Object.new.freeze
|
16
19
|
end
|
17
20
|
|
18
21
|
require_relative "teckel/config"
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: teckel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Schulze
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: bundler
|
@@ -66,6 +65,20 @@ dependencies:
|
|
66
65
|
- - ">="
|
67
66
|
- !ruby/object:Gem::Version
|
68
67
|
version: '0'
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: standard
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
type: :development
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
69
82
|
- !ruby/object:Gem::Dependency
|
70
83
|
name: yard
|
71
84
|
requirement: !ruby/object:Gem::Requirement
|
@@ -121,29 +134,6 @@ files:
|
|
121
134
|
- lib/teckel/operation/runner.rb
|
122
135
|
- lib/teckel/result.rb
|
123
136
|
- lib/teckel/version.rb
|
124
|
-
- spec/chain/around_hook_spec.rb
|
125
|
-
- spec/chain/default_settings_spec.rb
|
126
|
-
- spec/chain/inheritance_spec.rb
|
127
|
-
- spec/chain/none_input_spec.rb
|
128
|
-
- spec/chain/results_spec.rb
|
129
|
-
- spec/chain_spec.rb
|
130
|
-
- spec/config_spec.rb
|
131
|
-
- spec/doctest_helper.rb
|
132
|
-
- spec/operation/config_spec.rb
|
133
|
-
- spec/operation/contract_trace_spec.rb
|
134
|
-
- spec/operation/default_settings_spec.rb
|
135
|
-
- spec/operation/fail_on_input_spec.rb
|
136
|
-
- spec/operation/inheritance_spec.rb
|
137
|
-
- spec/operation/result_spec.rb
|
138
|
-
- spec/operation/results_spec.rb
|
139
|
-
- spec/operation_spec.rb
|
140
|
-
- spec/rb27/pattern_matching_spec.rb
|
141
|
-
- spec/result_spec.rb
|
142
|
-
- spec/spec_helper.rb
|
143
|
-
- spec/support/dry_base.rb
|
144
|
-
- spec/support/fake_db.rb
|
145
|
-
- spec/support/fake_models.rb
|
146
|
-
- spec/teckel_spec.rb
|
147
137
|
homepage: https://github.com/fnordfish/teckel
|
148
138
|
licenses:
|
149
139
|
- Apache-2.0
|
@@ -151,9 +141,8 @@ metadata:
|
|
151
141
|
changelog_uri: https://github.com/fnordfish/teckel/blob/main/CHANGELOG.md
|
152
142
|
source_code_uri: https://github.com/fnordfish/teckel
|
153
143
|
bug_tracker_uri: https://github.com/fnordfish/teckel/issues
|
154
|
-
documentation_uri: https://www.rubydoc.info/gems/teckel/0.
|
144
|
+
documentation_uri: https://www.rubydoc.info/gems/teckel/0.9.0
|
155
145
|
user_docs_uri: https://fnordfish.github.io/teckel/
|
156
|
-
post_install_message:
|
157
146
|
rdoc_options: []
|
158
147
|
require_paths:
|
159
148
|
- lib
|
@@ -168,31 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
168
157
|
- !ruby/object:Gem::Version
|
169
158
|
version: '0'
|
170
159
|
requirements: []
|
171
|
-
rubygems_version: 3.
|
172
|
-
signing_key:
|
160
|
+
rubygems_version: 3.6.9
|
173
161
|
specification_version: 4
|
174
162
|
summary: Operations with enforced in/out/err data structures
|
175
|
-
test_files:
|
176
|
-
- spec/chain/around_hook_spec.rb
|
177
|
-
- spec/chain/default_settings_spec.rb
|
178
|
-
- spec/chain/inheritance_spec.rb
|
179
|
-
- spec/chain/none_input_spec.rb
|
180
|
-
- spec/chain/results_spec.rb
|
181
|
-
- spec/chain_spec.rb
|
182
|
-
- spec/config_spec.rb
|
183
|
-
- spec/doctest_helper.rb
|
184
|
-
- spec/operation/config_spec.rb
|
185
|
-
- spec/operation/contract_trace_spec.rb
|
186
|
-
- spec/operation/default_settings_spec.rb
|
187
|
-
- spec/operation/fail_on_input_spec.rb
|
188
|
-
- spec/operation/inheritance_spec.rb
|
189
|
-
- spec/operation/result_spec.rb
|
190
|
-
- spec/operation/results_spec.rb
|
191
|
-
- spec/operation_spec.rb
|
192
|
-
- spec/rb27/pattern_matching_spec.rb
|
193
|
-
- spec/result_spec.rb
|
194
|
-
- spec/spec_helper.rb
|
195
|
-
- spec/support/dry_base.rb
|
196
|
-
- spec/support/fake_db.rb
|
197
|
-
- spec/support/fake_models.rb
|
198
|
-
- spec/teckel_spec.rb
|
163
|
+
test_files: []
|
@@ -1,100 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'support/dry_base'
|
4
|
-
require 'support/fake_db'
|
5
|
-
require 'support/fake_models'
|
6
|
-
|
7
|
-
module TeckelChainAroundHookTest
|
8
|
-
class CreateUser
|
9
|
-
include ::Teckel::Operation
|
10
|
-
|
11
|
-
result!
|
12
|
-
|
13
|
-
input Types::Hash.schema(name: Types::String, age: Types::Coercible::Integer.optional)
|
14
|
-
output Types.Instance(User)
|
15
|
-
error Types::Hash.schema(message: Types::String, errors: Types::Array.of(Types::Hash))
|
16
|
-
|
17
|
-
def call(input)
|
18
|
-
user = User.new(name: input[:name], age: input[:age])
|
19
|
-
if user.save
|
20
|
-
success!(user)
|
21
|
-
else
|
22
|
-
fail!(message: "Could not safe User", errors: user.errors)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
class AddFriend
|
28
|
-
include ::Teckel::Operation
|
29
|
-
|
30
|
-
result!
|
31
|
-
|
32
|
-
settings Struct.new(:fail_befriend)
|
33
|
-
|
34
|
-
input Types.Instance(User)
|
35
|
-
output Types::Hash.schema(user: Types.Instance(User), friend: Types.Instance(User))
|
36
|
-
error Types::Hash.schema(message: Types::String)
|
37
|
-
|
38
|
-
def call(user)
|
39
|
-
if settings&.fail_befriend
|
40
|
-
fail!(message: "Did not find a friend.")
|
41
|
-
else
|
42
|
-
success! user: user, friend: User.new(name: "A friend", age: 42)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
@stack = []
|
48
|
-
def self.stack
|
49
|
-
@stack
|
50
|
-
end
|
51
|
-
|
52
|
-
class Chain
|
53
|
-
include Teckel::Chain
|
54
|
-
|
55
|
-
around ->(chain, input) {
|
56
|
-
result = nil
|
57
|
-
begin
|
58
|
-
TeckelChainAroundHookTest.stack << :before
|
59
|
-
|
60
|
-
FakeDB.transaction do
|
61
|
-
result = chain.call(input)
|
62
|
-
raise FakeDB::Rollback if result.failure?
|
63
|
-
end
|
64
|
-
|
65
|
-
TeckelChainAroundHookTest.stack << :after
|
66
|
-
result
|
67
|
-
rescue FakeDB::Rollback
|
68
|
-
result
|
69
|
-
end
|
70
|
-
}
|
71
|
-
|
72
|
-
step :create, CreateUser
|
73
|
-
step :befriend, AddFriend
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
RSpec.describe Teckel::Chain do
|
78
|
-
before { TeckelChainAroundHookTest.stack.clear }
|
79
|
-
|
80
|
-
context "success" do
|
81
|
-
it "result matches" do
|
82
|
-
result = TeckelChainAroundHookTest::Chain.call(name: "Bob", age: 23)
|
83
|
-
expect(result.success).to include(user: kind_of(User), friend: kind_of(User))
|
84
|
-
end
|
85
|
-
|
86
|
-
it "runs around hook" do
|
87
|
-
TeckelChainAroundHookTest::Chain.call(name: "Bob", age: 23)
|
88
|
-
expect(TeckelChainAroundHookTest.stack).to eq([:before, :after])
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context "failure" do
|
93
|
-
it "runs around hook" do
|
94
|
-
TeckelChainAroundHookTest::Chain.
|
95
|
-
with(befriend: :fail).
|
96
|
-
call(name: "Bob", age: 23)
|
97
|
-
expect(TeckelChainAroundHookTest.stack).to eq([:before])
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module TeckelChainDefaultSettingsTest
|
4
|
-
class MyOperation
|
5
|
-
include Teckel::Operation
|
6
|
-
result!
|
7
|
-
|
8
|
-
settings Struct.new(:say, :other)
|
9
|
-
settings_constructor ->(data) { settings.new(*data.values_at(*settings.members)) } # ruby 2.4 way for `keyword_init: true`
|
10
|
-
|
11
|
-
input none
|
12
|
-
output Hash
|
13
|
-
error none
|
14
|
-
|
15
|
-
def call(_)
|
16
|
-
success! settings.to_h
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
class Chain
|
21
|
-
include Teckel::Chain
|
22
|
-
|
23
|
-
default_settings!(a: { say: "Chain Default" })
|
24
|
-
|
25
|
-
step :a, MyOperation
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
RSpec.describe Teckel::Chain do
|
30
|
-
specify "call chain without settings, uses default settings" do
|
31
|
-
result = TeckelChainDefaultSettingsTest::Chain.call
|
32
|
-
expect(result.success).to eq(say: "Chain Default", other: nil)
|
33
|
-
end
|
34
|
-
|
35
|
-
specify "call chain with explicit settings, overwrites defaults" do
|
36
|
-
result = TeckelChainDefaultSettingsTest::Chain.with(a: { other: "What" }).call
|
37
|
-
expect(result.success).to eq(say: nil, other: "What")
|
38
|
-
end
|
39
|
-
end
|
@@ -1,116 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'support/dry_base'
|
4
|
-
require 'support/fake_models'
|
5
|
-
|
6
|
-
module TeckelChainDefaultsViaBaseClass
|
7
|
-
LOG = [] # rubocop:disable Style/MutableConstant
|
8
|
-
|
9
|
-
class LoggingChain
|
10
|
-
include Teckel::Chain
|
11
|
-
|
12
|
-
around do |chain, input|
|
13
|
-
require 'benchmark'
|
14
|
-
result = nil
|
15
|
-
LOG << Benchmark.measure { result = chain.call(input) }
|
16
|
-
result
|
17
|
-
end
|
18
|
-
|
19
|
-
freeze
|
20
|
-
end
|
21
|
-
|
22
|
-
class OperationA
|
23
|
-
include Teckel::Operation
|
24
|
-
|
25
|
-
result!
|
26
|
-
|
27
|
-
input none
|
28
|
-
output Types::Integer
|
29
|
-
error none
|
30
|
-
|
31
|
-
def call(_)
|
32
|
-
success! rand(1000)
|
33
|
-
end
|
34
|
-
|
35
|
-
finalize!
|
36
|
-
end
|
37
|
-
|
38
|
-
class OperationB
|
39
|
-
include Teckel::Operation
|
40
|
-
|
41
|
-
result!
|
42
|
-
|
43
|
-
input none
|
44
|
-
output Types::String
|
45
|
-
error none
|
46
|
-
|
47
|
-
def call(_)
|
48
|
-
success! ("a".."z").to_a.sample
|
49
|
-
end
|
50
|
-
|
51
|
-
finalize!
|
52
|
-
end
|
53
|
-
|
54
|
-
class ChainA < LoggingChain
|
55
|
-
step :roll, OperationA
|
56
|
-
|
57
|
-
finalize!
|
58
|
-
end
|
59
|
-
|
60
|
-
class ChainB < LoggingChain
|
61
|
-
step :say, OperationB
|
62
|
-
|
63
|
-
finalize!
|
64
|
-
end
|
65
|
-
|
66
|
-
class ChainC < ChainB
|
67
|
-
finalize!
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
RSpec.describe Teckel::Chain do
|
72
|
-
before do
|
73
|
-
TeckelChainDefaultsViaBaseClass::LOG.clear
|
74
|
-
end
|
75
|
-
|
76
|
-
let(:base_chain) { TeckelChainDefaultsViaBaseClass::LoggingChain }
|
77
|
-
let(:chain_a) { TeckelChainDefaultsViaBaseClass::ChainA }
|
78
|
-
let(:chain_b) { TeckelChainDefaultsViaBaseClass::ChainB }
|
79
|
-
let(:chain_c) { TeckelChainDefaultsViaBaseClass::ChainC }
|
80
|
-
|
81
|
-
it "inherits config" do
|
82
|
-
expect(chain_a.around)
|
83
|
-
expect(chain_b.around)
|
84
|
-
|
85
|
-
expect(base_chain.steps).to eq([])
|
86
|
-
expect(chain_a.steps.size).to eq(1)
|
87
|
-
expect(chain_b.steps.size).to eq(1)
|
88
|
-
end
|
89
|
-
|
90
|
-
it "runs chain a" do
|
91
|
-
expect {
|
92
|
-
result = chain_a.call
|
93
|
-
expect(result.success).to be_a(Integer)
|
94
|
-
}.to change {
|
95
|
-
TeckelChainDefaultsViaBaseClass::LOG.size
|
96
|
-
}.from(0).to(1)
|
97
|
-
end
|
98
|
-
|
99
|
-
it "runs chain b" do
|
100
|
-
expect {
|
101
|
-
result = chain_b.call
|
102
|
-
expect(result.success).to be_a(String)
|
103
|
-
}.to change {
|
104
|
-
TeckelChainDefaultsViaBaseClass::LOG.size
|
105
|
-
}.from(0).to(1)
|
106
|
-
end
|
107
|
-
|
108
|
-
it "inherits steps" do
|
109
|
-
expect {
|
110
|
-
result = chain_c.call
|
111
|
-
expect(result.success).to be_a(String)
|
112
|
-
}.to change {
|
113
|
-
TeckelChainDefaultsViaBaseClass::LOG.size
|
114
|
-
}.from(0).to(1)
|
115
|
-
end
|
116
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module TeckelChainNoneInputTest
|
4
|
-
class MyOperation
|
5
|
-
include Teckel::Operation
|
6
|
-
result!
|
7
|
-
|
8
|
-
settings Struct.new(:say)
|
9
|
-
|
10
|
-
input none
|
11
|
-
output String
|
12
|
-
error none
|
13
|
-
|
14
|
-
def call(_)
|
15
|
-
success!(settings&.say || "Called")
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
class Chain
|
20
|
-
include Teckel::Chain
|
21
|
-
|
22
|
-
step :a, MyOperation
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
RSpec.describe Teckel::Chain do
|
27
|
-
specify "call chain without input value" do
|
28
|
-
result = TeckelChainNoneInputTest::Chain.call
|
29
|
-
expect(result.success).to eq("Called")
|
30
|
-
end
|
31
|
-
|
32
|
-
specify "call chain runner without input value" do
|
33
|
-
result = TeckelChainNoneInputTest::Chain.with(a: "What").call
|
34
|
-
expect(result.success).to eq("What")
|
35
|
-
end
|
36
|
-
end
|
data/spec/chain/results_spec.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'support/dry_base'
|
4
|
-
require 'support/fake_models'
|
5
|
-
|
6
|
-
module TeckelChainResultTest
|
7
|
-
class Message
|
8
|
-
include ::Teckel::Operation
|
9
|
-
|
10
|
-
result!
|
11
|
-
|
12
|
-
input Types::Hash.schema(message: Types::String)
|
13
|
-
error none
|
14
|
-
output Types::String
|
15
|
-
|
16
|
-
def call(input)
|
17
|
-
success! input[:message].upcase
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
class Chain
|
22
|
-
include Teckel::Chain
|
23
|
-
|
24
|
-
step :message, Message
|
25
|
-
|
26
|
-
class Result < Teckel::Operation::Result
|
27
|
-
def initialize(value, success, step, opts = {})
|
28
|
-
super(value, success)
|
29
|
-
@step = step
|
30
|
-
@opts = opts
|
31
|
-
end
|
32
|
-
|
33
|
-
class << self
|
34
|
-
alias :[] :new # Alias the default constructor to :new
|
35
|
-
end
|
36
|
-
|
37
|
-
attr_reader :opts, :step
|
38
|
-
end
|
39
|
-
|
40
|
-
result_constructor ->(value, success, step) {
|
41
|
-
result.new(value, success, step, time: Time.now.to_i)
|
42
|
-
}
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
RSpec.describe Teckel::Chain do
|
47
|
-
specify do
|
48
|
-
result = TeckelChainResultTest::Chain.call(message: "Hello World!")
|
49
|
-
expect(result).to be_successful
|
50
|
-
expect(result.success).to eq("HELLO WORLD!")
|
51
|
-
expect(result.opts).to include(time: kind_of(Integer))
|
52
|
-
end
|
53
|
-
end
|