teckel 0.4.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +71 -0
- data/README.md +3 -3
- data/lib/teckel/chain/config.rb +286 -0
- data/lib/teckel/chain/result.rb +3 -3
- data/lib/teckel/chain/runner.rb +28 -17
- data/lib/teckel/chain.rb +14 -190
- data/lib/teckel/config.rb +13 -7
- data/lib/teckel/operation/config.rb +400 -0
- data/lib/teckel/operation/result.rb +8 -8
- data/lib/teckel/operation/runner.rb +29 -25
- data/lib/teckel/operation.rb +87 -388
- data/lib/teckel/result.rb +8 -6
- data/lib/teckel/version.rb +1 -1
- data/lib/teckel.rb +0 -1
- data/spec/chain/around_hook_spec.rb +100 -0
- data/spec/chain/default_settings_spec.rb +39 -0
- data/spec/chain/inheritance_spec.rb +44 -44
- data/spec/chain/none_input_spec.rb +36 -0
- data/spec/chain/results_spec.rb +28 -28
- data/spec/chain_spec.rb +132 -57
- data/spec/doctest_helper.rb +1 -0
- data/spec/operation/config_spec.rb +227 -0
- data/spec/operation/contract_trace_spec.rb +118 -0
- data/spec/operation/default_settings_spec.rb +120 -0
- data/spec/operation/fail_on_input_spec.rb +103 -0
- data/spec/operation/inheritance_spec.rb +38 -38
- data/spec/operation/result_spec.rb +27 -12
- data/spec/operation/results_spec.rb +67 -67
- data/spec/operation_spec.rb +276 -230
- data/spec/rb27/pattern_matching_spec.rb +2 -2
- data/spec/result_spec.rb +12 -10
- data/spec/spec_helper.rb +10 -0
- metadata +41 -12
- data/spec/chain_around_hook_spec.rb +0 -100
@@ -4,24 +4,39 @@ RSpec.describe Teckel::Operation::Result do
|
|
4
4
|
let(:failure_value) { "some error" }
|
5
5
|
let(:failed_result) { Teckel::Operation::Result.new(failure_value, false) }
|
6
6
|
|
7
|
-
let(:success_value) { "some
|
8
|
-
let(:successful_result) { Teckel::Operation::Result.new(
|
7
|
+
let(:success_value) { "some success" }
|
8
|
+
let(:successful_result) { Teckel::Operation::Result.new(success_value, true) }
|
9
9
|
|
10
|
-
it { expect(successful_result.successful?).to
|
11
|
-
it { expect(failed_result.successful?).to
|
10
|
+
it { expect(successful_result.successful?).to eq(true) }
|
11
|
+
it { expect(failed_result.successful?).to eq(false) }
|
12
12
|
|
13
|
-
it { expect(successful_result.failure?).to
|
14
|
-
it { expect(failed_result.failure?).to
|
13
|
+
it { expect(successful_result.failure?).to eq(false) }
|
14
|
+
it { expect(failed_result.failure?).to eq(true) }
|
15
15
|
|
16
16
|
it { expect(successful_result.value).to eq(success_value) }
|
17
17
|
it { expect(failed_result.value).to eq(failure_value) }
|
18
18
|
|
19
19
|
describe "#success" do
|
20
|
-
it
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
it("on successful result, returns value") {
|
21
|
+
expect(successful_result.success).to eq(success_value)
|
22
|
+
}
|
23
|
+
|
24
|
+
describe "on failed result" do
|
25
|
+
it("with no fallbacks, returns nil") {
|
26
|
+
expect(failed_result.success).to eq(nil)
|
27
|
+
}
|
28
|
+
it("with default-argument, returns default-argument") {
|
29
|
+
expect(failed_result.success("other")).to eq("other")
|
30
|
+
}
|
31
|
+
it("with block, returns block return value") {
|
32
|
+
expect(failed_result.success { |value| "Failed: #{value}" } ).to eq("Failed: some error")
|
33
|
+
}
|
34
|
+
it("with default-argument and block given, returns default-argument, skips block") {
|
35
|
+
expect { |blk|
|
36
|
+
expect(failed_result.success("default", &blk)).to_not eq("default")
|
37
|
+
}.to(yield_control)
|
38
|
+
}
|
39
|
+
end
|
25
40
|
end
|
26
41
|
|
27
42
|
describe "#failure" do
|
@@ -29,6 +44,6 @@ RSpec.describe Teckel::Operation::Result do
|
|
29
44
|
|
30
45
|
it { expect(successful_result.failure).to eq(nil) }
|
31
46
|
it { expect(successful_result.failure("other")).to eq("other") }
|
32
|
-
it { expect(successful_result.failure { |value| "Failed: #{value}" } ).to eq("Failed: some
|
47
|
+
it { expect(successful_result.failure { |value| "Failed: #{value}" } ).to eq("Failed: some success") }
|
33
48
|
end
|
34
49
|
end
|
@@ -3,27 +3,75 @@
|
|
3
3
|
require 'support/dry_base'
|
4
4
|
require 'support/fake_models'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
6
|
+
class CreateUserWithResult
|
7
|
+
include Teckel::Operation
|
8
|
+
|
9
|
+
result!
|
10
|
+
|
11
|
+
input Types::Hash.schema(name: Types::String, age: Types::Coercible::Integer)
|
12
|
+
output Types.Instance(User)
|
13
|
+
error Types::Hash.schema(message: Types::String, errors: Types::Array.of(Types::Hash))
|
14
|
+
|
15
|
+
def call(input)
|
16
|
+
user = User.new(name: input[:name], age: input[:age])
|
17
|
+
if user.save
|
18
|
+
success! user
|
19
|
+
else
|
20
|
+
fail!(message: "Could not save User", errors: user.errors)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class CreateUserCustomResult
|
26
|
+
include Teckel::Operation
|
27
|
+
|
28
|
+
class MyResult
|
29
|
+
include Teckel::Result # makes sure this can be used in a Chain
|
30
|
+
|
31
|
+
def initialize(value, success, opts = {})
|
32
|
+
@value, @success, @opts = value, success, opts
|
25
33
|
end
|
26
34
|
|
35
|
+
# implementing Teckel::Result
|
36
|
+
def successful?
|
37
|
+
@success
|
38
|
+
end
|
39
|
+
|
40
|
+
# implementing Teckel::Result
|
41
|
+
attr_reader :value
|
42
|
+
|
43
|
+
attr_reader :opts
|
44
|
+
end
|
45
|
+
|
46
|
+
result MyResult
|
47
|
+
result_constructor ->(value, success) { MyResult.new(value, success, time: Time.now.to_i) }
|
48
|
+
|
49
|
+
input Types::Hash.schema(name: Types::String, age: Types::Coercible::Integer)
|
50
|
+
output Types.Instance(User)
|
51
|
+
error Types::Hash.schema(message: Types::String, errors: Types::Array.of(Types::Hash))
|
52
|
+
|
53
|
+
def call(input)
|
54
|
+
user = User.new(name: input[:name], age: input[:age])
|
55
|
+
if user.save
|
56
|
+
success! user
|
57
|
+
else
|
58
|
+
fail!(message: "Could not save User", errors: user.errors)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class CreateUserOverwritingResult
|
64
|
+
include Teckel::Operation
|
65
|
+
|
66
|
+
class Result
|
67
|
+
include Teckel::Result # makes sure this can be used in a Chain
|
68
|
+
|
69
|
+
def initialize(value, success); end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
RSpec.describe Teckel::Operation do
|
74
|
+
context "with build in result object" do
|
27
75
|
specify "output" do
|
28
76
|
result = CreateUserWithResult.call(name: "Bob", age: 23)
|
29
77
|
expect(result).to be_a(Teckel::Result)
|
@@ -40,44 +88,6 @@ RSpec.describe Teckel::Operation do
|
|
40
88
|
end
|
41
89
|
|
42
90
|
context "using custom result" do
|
43
|
-
class CreateUserCustomResult
|
44
|
-
include Teckel::Operation
|
45
|
-
|
46
|
-
class MyResult
|
47
|
-
include Teckel::Result # makes sure this can be used in a Chain
|
48
|
-
|
49
|
-
def initialize(value, success, opts = {})
|
50
|
-
@value, @success, @opts = value, success, opts
|
51
|
-
end
|
52
|
-
|
53
|
-
# implementing Teckel::Result
|
54
|
-
def successful?
|
55
|
-
@success
|
56
|
-
end
|
57
|
-
|
58
|
-
# implementing Teckel::Result
|
59
|
-
attr_reader :value
|
60
|
-
|
61
|
-
attr_reader :opts
|
62
|
-
end
|
63
|
-
|
64
|
-
result MyResult
|
65
|
-
result_constructor ->(value, success) { result.new(value, success, time: Time.now.to_i) }
|
66
|
-
|
67
|
-
input Types::Hash.schema(name: Types::String, age: Types::Coercible::Integer)
|
68
|
-
output Types.Instance(User)
|
69
|
-
error Types::Hash.schema(message: Types::String, errors: Types::Array.of(Types::Hash))
|
70
|
-
|
71
|
-
def call(input)
|
72
|
-
user = User.new(name: input[:name], age: input[:age])
|
73
|
-
if user.save
|
74
|
-
user
|
75
|
-
else
|
76
|
-
fail!(message: "Could not save User", errors: user.errors)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
91
|
specify "output" do
|
82
92
|
result = CreateUserCustomResult.call(name: "Bob", age: 23)
|
83
93
|
expect(result).to be_a(CreateUserCustomResult::MyResult)
|
@@ -98,16 +108,6 @@ RSpec.describe Teckel::Operation do
|
|
98
108
|
end
|
99
109
|
|
100
110
|
context "overwriting Result" do
|
101
|
-
class CreateUserOverwritingResult
|
102
|
-
include Teckel::Operation
|
103
|
-
|
104
|
-
class Result
|
105
|
-
include Teckel::Result # makes sure this can be used in a Chain
|
106
|
-
|
107
|
-
def initialize(value, success); end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
111
|
it "uses the class definition" do
|
112
112
|
expect(CreateUserOverwritingResult.result).to_not eq(Teckel::Operation::Result)
|
113
113
|
expect(CreateUserOverwritingResult.result).to eq(CreateUserOverwritingResult::Result)
|