deterministic 0.8.1 → 0.10.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/HISTORY.md +17 -0
- data/README.md +121 -153
- data/lib/deterministic/core_ext/object/result.rb +6 -0
- data/lib/deterministic/core_ext/{either.rb → result.rb} +2 -6
- data/lib/deterministic/monad.rb +3 -3
- data/lib/deterministic/result/chain.rb +27 -0
- data/lib/deterministic/result/failure.rb +5 -0
- data/lib/deterministic/{either → result}/match.rb +5 -5
- data/lib/deterministic/result/success.rb +5 -0
- data/lib/deterministic/{either.rb → result.rb} +29 -6
- data/lib/deterministic/version.rb +1 -1
- data/lib/deterministic.rb +5 -6
- data/spec/examples/bookings_spec.rb +3 -5
- data/spec/lib/deterministic/core_ext/object/either_spec.rb +3 -20
- data/spec/lib/deterministic/core_ext/result_spec.rb +22 -0
- data/spec/lib/deterministic/maybe_spec.rb +2 -0
- data/spec/lib/deterministic/monad_spec.rb +3 -3
- data/spec/lib/deterministic/result/chain_spec.rb +150 -0
- data/spec/lib/deterministic/{either → result}/failure_spec.rb +9 -6
- data/spec/lib/deterministic/{either → result}/match_spec.rb +5 -5
- data/spec/lib/deterministic/result/result_shared.rb +23 -0
- data/spec/lib/deterministic/{either → result}/success_spec.rb +10 -6
- data/spec/lib/deterministic/{either_spec.rb → result_spec.rb} +3 -3
- metadata +24 -27
- data/either.rb +0 -97
- data/lib/deterministic/core_ext/object/either.rb +0 -6
- data/lib/deterministic/either/attempt_all.rb +0 -50
- data/lib/deterministic/either/chain.rb +0 -22
- data/lib/deterministic/either/failure.rb +0 -22
- data/lib/deterministic/either/success.rb +0 -22
- data/spec/lib/deterministic/attempt_all_spec.rb +0 -115
- data/spec/lib/deterministic/core_ext/either_spec.rb +0 -50
- data/spec/lib/deterministic/either/chain_spec.rb +0 -80
- data/spec/lib/deterministic/either/either_shared.rb +0 -23
@@ -1,115 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
include Deterministic
|
4
|
-
|
5
|
-
describe Deterministic::Either::AttemptAll do
|
6
|
-
it "#try evaluates the result as Success" do
|
7
|
-
expect(
|
8
|
-
Either.attempt_all do
|
9
|
-
try { @a = 1 }
|
10
|
-
try { @b = @a + 1 }
|
11
|
-
end
|
12
|
-
).to eq Success(2)
|
13
|
-
end
|
14
|
-
|
15
|
-
it "#try values are passed to the next command" do
|
16
|
-
expect(
|
17
|
-
Either.attempt_all do
|
18
|
-
try { 1 }
|
19
|
-
try { |v| v + 1 }
|
20
|
-
end
|
21
|
-
).to eq Success(2)
|
22
|
-
end
|
23
|
-
|
24
|
-
it "try treat exceptions as Failure" do
|
25
|
-
attempt = Either.attempt_all do
|
26
|
-
try { 1 }
|
27
|
-
try { raise "error" }
|
28
|
-
end.value
|
29
|
-
expect(attempt).to be_a RuntimeError
|
30
|
-
expect(attempt.message).to eq "error"
|
31
|
-
end
|
32
|
-
|
33
|
-
it "don't continue on failure" do
|
34
|
-
fake = double()
|
35
|
-
expect(
|
36
|
-
Either.attempt_all do
|
37
|
-
try { 1 }
|
38
|
-
let { Failure(2) }
|
39
|
-
try { fake.should_not_be_called }
|
40
|
-
end
|
41
|
-
).to eq Failure(2)
|
42
|
-
end
|
43
|
-
|
44
|
-
it "#let expects Success or Failure" do
|
45
|
-
expect(
|
46
|
-
Either.attempt_all do
|
47
|
-
let { Success(1) }
|
48
|
-
end
|
49
|
-
).to eq Success(1)
|
50
|
-
|
51
|
-
expect {
|
52
|
-
Either.attempt_all do
|
53
|
-
let { 1 }
|
54
|
-
end
|
55
|
-
}.to raise_error(Deterministic::Either::AttemptAll::EitherExpectedError)
|
56
|
-
end
|
57
|
-
|
58
|
-
it "#let will not catch errors" do
|
59
|
-
expect {
|
60
|
-
Either.attempt_all do
|
61
|
-
let { raise "error" }
|
62
|
-
end
|
63
|
-
}.to raise_error
|
64
|
-
end
|
65
|
-
|
66
|
-
it "#let passes params unboxed" do
|
67
|
-
expect(
|
68
|
-
Either.attempt_all do
|
69
|
-
try { 1 }
|
70
|
-
let { |v| Success(v + 1) }
|
71
|
-
end
|
72
|
-
).to eq Success(2)
|
73
|
-
end
|
74
|
-
|
75
|
-
|
76
|
-
it "works with boxed values" do
|
77
|
-
expect(
|
78
|
-
Either.attempt_all do
|
79
|
-
try { Failure(1) }
|
80
|
-
try { 2 }
|
81
|
-
end
|
82
|
-
).to eq Failure(1)
|
83
|
-
end
|
84
|
-
|
85
|
-
it "works with an OpenStruct" do
|
86
|
-
context = OpenStruct.new
|
87
|
-
attempt = Either.attempt_all(context) do
|
88
|
-
let { Success(self.alpha = 2) }
|
89
|
-
try { self.res = 1 }
|
90
|
-
end
|
91
|
-
|
92
|
-
expect(context.res).to eq 1
|
93
|
-
expect(context.alpha).to eq 2
|
94
|
-
end
|
95
|
-
|
96
|
-
it "can operate in the context of a context" do
|
97
|
-
class Context
|
98
|
-
attr_accessor :a
|
99
|
-
def initialize
|
100
|
-
@a = 1
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
context = Context.new
|
105
|
-
|
106
|
-
expect(
|
107
|
-
Either.attempt_all(context) do
|
108
|
-
try { self.a += 1 }
|
109
|
-
try { self.a + 1 }
|
110
|
-
end
|
111
|
-
).to eq Success(3)
|
112
|
-
|
113
|
-
expect(context.a).to eq 2
|
114
|
-
end
|
115
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
require "deterministic"
|
3
|
-
require "deterministic/core_ext/either"
|
4
|
-
|
5
|
-
describe Deterministic::CoreExt::Either do
|
6
|
-
it "does something" do
|
7
|
-
h = {}
|
8
|
-
h.extend(Deterministic::CoreExt::Either)
|
9
|
-
expect(h.success?).to be_falsey
|
10
|
-
expect(h.failure?).to be_falsey
|
11
|
-
expect(h.either?).to be_falsey
|
12
|
-
end
|
13
|
-
|
14
|
-
it "enables #success?, #failure?, #either? on all Objects" do
|
15
|
-
ary = [Deterministic::Success(true), Deterministic::Success(1)]
|
16
|
-
expect(ary.all?(&:success?)).to be_truthy
|
17
|
-
|
18
|
-
ary = [Deterministic::Success(true), Deterministic::Failure(1)]
|
19
|
-
expect(ary.all?(&:success?)).to be_falsey
|
20
|
-
expect(ary.any?(&:failure?)).to be_truthy
|
21
|
-
end
|
22
|
-
|
23
|
-
it "allows using attempt_all on all Objects" do
|
24
|
-
h = {a: 1}
|
25
|
-
h.extend(Deterministic::CoreExt::Either)
|
26
|
-
res = h.attempt_all do
|
27
|
-
try { |s| s[:a] + 1}
|
28
|
-
end
|
29
|
-
|
30
|
-
expect(res).to eq Deterministic::Success(2)
|
31
|
-
end
|
32
|
-
|
33
|
-
it "use attempt_all in an instance" do
|
34
|
-
class UnderTest
|
35
|
-
include Deterministic::CoreExt::Either
|
36
|
-
def test
|
37
|
-
attempt_all do
|
38
|
-
try { foo }
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def foo
|
43
|
-
1
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
ut = UnderTest.new
|
48
|
-
expect(ut.test).to eq Success(1)
|
49
|
-
end
|
50
|
-
end
|
@@ -1,80 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
include Deterministic
|
4
|
-
|
5
|
-
describe Deterministic::Either do
|
6
|
-
context ">> (chain)" do
|
7
|
-
it "Failure stops execution" do
|
8
|
-
class ChainUnderTest
|
9
|
-
alias :m :method
|
10
|
-
|
11
|
-
def call
|
12
|
-
init >>
|
13
|
-
m(:validate) >>
|
14
|
-
m(:send) >>
|
15
|
-
m(:parse)
|
16
|
-
end
|
17
|
-
|
18
|
-
def init
|
19
|
-
Success({step: 1})
|
20
|
-
end
|
21
|
-
|
22
|
-
def validate(i)
|
23
|
-
i[:step] = i[:step] + 1
|
24
|
-
Success(i)
|
25
|
-
end
|
26
|
-
|
27
|
-
def send(i)
|
28
|
-
i[:step] = i[:step] + 1
|
29
|
-
Failure("Error @ #{i.fetch(:step)}")
|
30
|
-
end
|
31
|
-
|
32
|
-
def parse(i)
|
33
|
-
i[:step] = i[:step] + 1
|
34
|
-
Success(i)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
test = ChainUnderTest.new
|
39
|
-
|
40
|
-
expect(test.call).to eq Failure("Error @ 3")
|
41
|
-
end
|
42
|
-
|
43
|
-
it "expects an Either" do
|
44
|
-
def returns_non_either(i)
|
45
|
-
2
|
46
|
-
end
|
47
|
-
|
48
|
-
expect { Success(1) >> method(:returns_non_either) }.to raise_error(Deterministic::Monad::NotMonadError)
|
49
|
-
end
|
50
|
-
|
51
|
-
it "works with a block" do
|
52
|
-
expect(
|
53
|
-
Success(1).chain { |i| Success(i + 1) }
|
54
|
-
).to eq Success(2)
|
55
|
-
end
|
56
|
-
|
57
|
-
it "works with a lambda" do
|
58
|
-
expect(
|
59
|
-
Success(1) >> ->(i) { Success(i + 1) }
|
60
|
-
).to eq Success(2)
|
61
|
-
end
|
62
|
-
|
63
|
-
it "does not catch exceptions" do
|
64
|
-
expect {
|
65
|
-
Success(1) >> ->(i) { raise "error" }
|
66
|
-
}.to raise_error(RuntimeError)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
context ">= (try)" do
|
71
|
-
it "try (>=) catches errors and wraps them as Failure" do
|
72
|
-
def error(ctx)
|
73
|
-
raise "error #{ctx}"
|
74
|
-
end
|
75
|
-
|
76
|
-
actual = Success(1) >= method(:error)
|
77
|
-
expect(actual.inspect).to eq "Failure(error 1)"
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
shared_examples 'Either' do
|
2
|
-
let(:either_name) { described_class.name.split("::")[-1]}
|
3
|
-
specify { expect(subject.value).to eq 1 }
|
4
|
-
specify { expect(either.new(subject)).to eq either.new(1) }
|
5
|
-
|
6
|
-
it "#map" do
|
7
|
-
expect(either.new(1).map { |e| e + 1 }).to eq either.new(2)
|
8
|
-
end
|
9
|
-
|
10
|
-
it "#bind" do
|
11
|
-
expect(either.new(1).bind { |v| either.new(v + 1)}).to eq either.new(2)
|
12
|
-
end
|
13
|
-
|
14
|
-
it "#to_s" do
|
15
|
-
expect(either.new(1).to_s).to eq "1"
|
16
|
-
expect(either.new({a: 1}).to_s).to eq "{:a=>1}"
|
17
|
-
end
|
18
|
-
|
19
|
-
it "#inspect" do
|
20
|
-
expect(either.new(1).inspect).to eq "#{either_name}(1)"
|
21
|
-
expect(either.new(:a=>1).inspect).to eq "#{either_name}({:a=>1})"
|
22
|
-
end
|
23
|
-
end
|