fear 1.0.0 → 2.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.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +27 -0
  3. data/.github/workflows/rubocop.yml +39 -0
  4. data/.github/workflows/spec.yml +42 -0
  5. data/.rubocop.yml +4 -60
  6. data/.simplecov +17 -0
  7. data/CHANGELOG.md +29 -1
  8. data/Gemfile +5 -5
  9. data/Gemfile.lock +86 -50
  10. data/README.md +240 -209
  11. data/Rakefile +72 -65
  12. data/examples/pattern_extracting.rb +10 -8
  13. data/examples/pattern_matching_binary_tree_set.rb +7 -2
  14. data/examples/pattern_matching_number_in_words.rb +48 -42
  15. data/fear.gemspec +33 -34
  16. data/lib/dry/types/fear/option.rb +125 -0
  17. data/lib/dry/types/fear.rb +8 -0
  18. data/lib/fear/await.rb +33 -0
  19. data/lib/fear/awaitable.rb +28 -0
  20. data/lib/fear/either.rb +15 -4
  21. data/lib/fear/either_api.rb +4 -0
  22. data/lib/fear/either_pattern_match.rb +9 -5
  23. data/lib/fear/empty_partial_function.rb +3 -1
  24. data/lib/fear/failure.rb +7 -7
  25. data/lib/fear/failure_pattern_match.rb +4 -0
  26. data/lib/fear/for.rb +4 -2
  27. data/lib/fear/for_api.rb +5 -1
  28. data/lib/fear/future.rb +157 -82
  29. data/lib/fear/future_api.rb +17 -4
  30. data/lib/fear/left.rb +3 -9
  31. data/lib/fear/left_pattern_match.rb +2 -0
  32. data/lib/fear/none.rb +28 -10
  33. data/lib/fear/none_pattern_match.rb +2 -0
  34. data/lib/fear/option.rb +30 -2
  35. data/lib/fear/option_api.rb +4 -0
  36. data/lib/fear/option_pattern_match.rb +8 -3
  37. data/lib/fear/partial_function/and_then.rb +4 -2
  38. data/lib/fear/partial_function/any.rb +2 -0
  39. data/lib/fear/partial_function/combined.rb +3 -1
  40. data/lib/fear/partial_function/empty.rb +6 -0
  41. data/lib/fear/partial_function/guard/and.rb +2 -0
  42. data/lib/fear/partial_function/guard/and3.rb +2 -0
  43. data/lib/fear/partial_function/guard/or.rb +2 -0
  44. data/lib/fear/partial_function/guard.rb +8 -6
  45. data/lib/fear/partial_function/lifted.rb +2 -0
  46. data/lib/fear/partial_function/or_else.rb +5 -1
  47. data/lib/fear/partial_function.rb +18 -9
  48. data/lib/fear/partial_function_class.rb +3 -1
  49. data/lib/fear/pattern_match.rb +3 -11
  50. data/lib/fear/pattern_matching_api.rb +6 -28
  51. data/lib/fear/promise.rb +7 -5
  52. data/lib/fear/right.rb +3 -9
  53. data/lib/fear/right_biased.rb +5 -3
  54. data/lib/fear/right_pattern_match.rb +4 -0
  55. data/lib/fear/some.rb +35 -8
  56. data/lib/fear/some_pattern_match.rb +2 -0
  57. data/lib/fear/struct.rb +237 -0
  58. data/lib/fear/success.rb +7 -8
  59. data/lib/fear/success_pattern_match.rb +4 -0
  60. data/lib/fear/try.rb +8 -2
  61. data/lib/fear/try_api.rb +4 -0
  62. data/lib/fear/try_pattern_match.rb +9 -5
  63. data/lib/fear/unit.rb +6 -2
  64. data/lib/fear/utils.rb +14 -2
  65. data/lib/fear/version.rb +4 -1
  66. data/lib/fear.rb +26 -44
  67. data/spec/dry/types/fear/option/constrained_spec.rb +22 -0
  68. data/spec/dry/types/fear/option/core_spec.rb +77 -0
  69. data/spec/dry/types/fear/option/default_spec.rb +21 -0
  70. data/spec/dry/types/fear/option/hash_spec.rb +58 -0
  71. data/spec/dry/types/fear/option/option_spec.rb +97 -0
  72. data/spec/fear/awaitable_spec.rb +19 -0
  73. data/spec/fear/done_spec.rb +7 -5
  74. data/spec/fear/either/mixin_spec.rb +4 -2
  75. data/spec/fear/either_pattern_match_spec.rb +10 -8
  76. data/spec/fear/either_pattern_matching_spec.rb +28 -0
  77. data/spec/fear/either_spec.rb +26 -0
  78. data/spec/fear/failure_spec.rb +57 -70
  79. data/spec/fear/for/mixin_spec.rb +15 -0
  80. data/spec/fear/for_spec.rb +19 -17
  81. data/spec/fear/future_spec.rb +477 -237
  82. data/spec/fear/guard_spec.rb +136 -24
  83. data/spec/fear/left_spec.rb +57 -70
  84. data/spec/fear/none_spec.rb +39 -43
  85. data/spec/fear/option/mixin_spec.rb +9 -7
  86. data/spec/fear/option_pattern_match_spec.rb +10 -8
  87. data/spec/fear/option_pattern_matching_spec.rb +34 -0
  88. data/spec/fear/option_spec.rb +142 -0
  89. data/spec/fear/partial_function/any_spec.rb +25 -0
  90. data/spec/fear/partial_function/empty_spec.rb +12 -10
  91. data/spec/fear/partial_function_and_then_spec.rb +39 -37
  92. data/spec/fear/partial_function_composition_spec.rb +46 -44
  93. data/spec/fear/partial_function_or_else_spec.rb +92 -90
  94. data/spec/fear/partial_function_spec.rb +91 -61
  95. data/spec/fear/pattern_match_spec.rb +19 -51
  96. data/spec/fear/pattern_matching_api_spec.rb +31 -0
  97. data/spec/fear/promise_spec.rb +23 -23
  98. data/spec/fear/right_biased/left.rb +28 -26
  99. data/spec/fear/right_biased/right.rb +51 -49
  100. data/spec/fear/right_spec.rb +48 -68
  101. data/spec/fear/some_spec.rb +30 -40
  102. data/spec/fear/success_spec.rb +40 -60
  103. data/spec/fear/try/mixin_spec.rb +19 -3
  104. data/spec/fear/try_api_spec.rb +23 -0
  105. data/spec/fear/try_pattern_match_spec.rb +10 -8
  106. data/spec/fear/try_pattern_matching_spec.rb +34 -0
  107. data/spec/fear/utils_spec.rb +16 -14
  108. data/spec/spec_helper.rb +13 -7
  109. data/spec/struct_pattern_matching_spec.rb +36 -0
  110. data/spec/struct_spec.rb +194 -0
  111. data/spec/support/dry_types.rb +6 -0
  112. metadata +128 -87
  113. data/.travis.yml +0 -13
  114. data/lib/fear/extractor/anonymous_array_splat_matcher.rb +0 -8
  115. data/lib/fear/extractor/any_matcher.rb +0 -15
  116. data/lib/fear/extractor/array_head_matcher.rb +0 -34
  117. data/lib/fear/extractor/array_matcher.rb +0 -38
  118. data/lib/fear/extractor/array_splat_matcher.rb +0 -14
  119. data/lib/fear/extractor/empty_list_matcher.rb +0 -18
  120. data/lib/fear/extractor/extractor_matcher.rb +0 -42
  121. data/lib/fear/extractor/grammar.rb +0 -201
  122. data/lib/fear/extractor/grammar.treetop +0 -129
  123. data/lib/fear/extractor/identifier_matcher.rb +0 -16
  124. data/lib/fear/extractor/matcher/and.rb +0 -36
  125. data/lib/fear/extractor/matcher.rb +0 -54
  126. data/lib/fear/extractor/named_array_splat_matcher.rb +0 -15
  127. data/lib/fear/extractor/pattern.rb +0 -55
  128. data/lib/fear/extractor/typed_identifier_matcher.rb +0 -24
  129. data/lib/fear/extractor/value_matcher.rb +0 -17
  130. data/lib/fear/extractor.rb +0 -108
  131. data/lib/fear/extractor_api.rb +0 -33
  132. data/spec/fear/extractor/array_matcher_spec.rb +0 -228
  133. data/spec/fear/extractor/extractor_matcher_spec.rb +0 -151
  134. data/spec/fear/extractor/grammar_array_spec.rb +0 -23
  135. data/spec/fear/extractor/identified_matcher_spec.rb +0 -47
  136. data/spec/fear/extractor/identifier_matcher_spec.rb +0 -66
  137. data/spec/fear/extractor/pattern_spec.rb +0 -32
  138. data/spec/fear/extractor/typed_identifier_matcher_spec.rb +0 -62
  139. data/spec/fear/extractor/value_matcher_number_spec.rb +0 -77
  140. data/spec/fear/extractor/value_matcher_string_spec.rb +0 -86
  141. data/spec/fear/extractor/value_matcher_symbol_spec.rb +0 -69
  142. data/spec/fear/extractor_api_spec.rb +0 -113
  143. data/spec/fear/extractor_spec.rb +0 -59
@@ -1,76 +1,78 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe Fear::Right do
2
4
  it_behaves_like Fear::RightBiased::Right do
3
- let(:right) { Fear.right('value') }
5
+ let(:right) { Fear.right("value") }
4
6
  end
5
7
 
6
- let(:right) { Fear.right('value') }
8
+ let(:right) { Fear.right("value") }
7
9
 
8
- describe '#right?' do
10
+ describe "#right?" do
9
11
  subject { right }
10
12
  it { is_expected.to be_right }
11
13
  end
12
14
 
13
- describe '#left?' do
15
+ describe "#left?" do
14
16
  subject { right }
15
17
  it { is_expected.not_to be_left }
16
18
  end
17
19
 
18
- describe '#select_or_else' do
20
+ describe "#select_or_else" do
19
21
  subject { right.select_or_else(default, &predicate) }
20
22
 
21
- context 'predicate evaluates to true' do
22
- let(:predicate) { ->(v) { v == 'value' } }
23
+ context "predicate evaluates to true" do
24
+ let(:predicate) { ->(v) { v == "value" } }
23
25
  let(:default) { -1 }
24
26
  it { is_expected.to eq(right) }
25
27
  end
26
28
 
27
- context 'predicate evaluates to false and default is a proc' do
28
- let(:predicate) { ->(v) { v != 'value' } }
29
+ context "predicate evaluates to false and default is a proc" do
30
+ let(:predicate) { ->(v) { v != "value" } }
29
31
  let(:default) { -> { -1 } }
30
32
  it { is_expected.to eq(Fear.left(-1)) }
31
33
  end
32
34
 
33
- context 'predicate evaluates to false and default is not a proc' do
34
- let(:predicate) { ->(v) { v != 'value' } }
35
+ context "predicate evaluates to false and default is not a proc" do
36
+ let(:predicate) { ->(v) { v != "value" } }
35
37
  let(:default) { -1 }
36
38
  it { is_expected.to eq(Fear.left(-1)) }
37
39
  end
38
40
  end
39
41
 
40
- describe '#select' do
42
+ describe "#select" do
41
43
  subject { right.select(&predicate) }
42
44
 
43
- context 'predicate evaluates to true' do
44
- let(:predicate) { ->(v) { v == 'value' } }
45
+ context "predicate evaluates to true" do
46
+ let(:predicate) { ->(v) { v == "value" } }
45
47
  it { is_expected.to eq(right) }
46
48
  end
47
49
 
48
- context 'predicate evaluates to false' do
49
- let(:predicate) { ->(v) { v != 'value' } }
50
- it { is_expected.to eq(Fear.left('value')) }
50
+ context "predicate evaluates to false" do
51
+ let(:predicate) { ->(v) { v != "value" } }
52
+ it { is_expected.to eq(Fear.left("value")) }
51
53
  end
52
54
  end
53
55
 
54
- describe '#reject' do
56
+ describe "#reject" do
55
57
  subject { right.reject(&predicate) }
56
58
 
57
- context 'predicate evaluates to true' do
58
- let(:predicate) { ->(v) { v == 'value' } }
59
- it { is_expected.to eq(Fear.left('value')) }
59
+ context "predicate evaluates to true" do
60
+ let(:predicate) { ->(v) { v == "value" } }
61
+ it { is_expected.to eq(Fear.left("value")) }
60
62
  end
61
63
 
62
- context 'predicate evaluates to false' do
63
- let(:predicate) { ->(v) { v != 'value' } }
64
+ context "predicate evaluates to false" do
65
+ let(:predicate) { ->(v) { v != "value" } }
64
66
  it { is_expected.to eq(right) }
65
67
  end
66
68
  end
67
69
 
68
- describe '#swap' do
70
+ describe "#swap" do
69
71
  subject { right.swap }
70
- it { is_expected.to eq(Fear.left('value')) }
72
+ it { is_expected.to eq(Fear.left("value")) }
71
73
  end
72
74
 
73
- describe '#reduce' do
75
+ describe "#reduce" do
74
76
  subject do
75
77
  right.reduce(
76
78
  ->(left) { "Left: #{left}" },
@@ -78,45 +80,45 @@ RSpec.describe Fear::Right do
78
80
  )
79
81
  end
80
82
 
81
- it { is_expected.to eq('Right: value') }
83
+ it { is_expected.to eq("Right: value") }
82
84
  end
83
85
 
84
- describe '#join_right' do
85
- context 'value is Either' do
86
+ describe "#join_right" do
87
+ context "value is Either" do
86
88
  subject { described_class.new(value).join_right }
87
- let(:value) { Fear.left('error') }
89
+ let(:value) { Fear.left("error") }
88
90
 
89
- it 'returns value' do
91
+ it "returns value" do
90
92
  is_expected.to eq(value)
91
93
  end
92
94
  end
93
95
 
94
- context 'value is not Either' do
95
- subject { proc { described_class.new('35').join_right } }
96
+ context "value is not Either" do
97
+ subject { proc { described_class.new("35").join_right } }
96
98
 
97
- it 'fails with type error' do
99
+ it "fails with type error" do
98
100
  is_expected.to raise_error(TypeError)
99
101
  end
100
102
  end
101
103
  end
102
104
 
103
- describe '#join_left' do
104
- context 'value is Either' do
105
+ describe "#join_left" do
106
+ context "value is Either" do
105
107
  subject { either.join_left }
106
- let(:either) { described_class.new(Fear.left('error')) }
108
+ let(:either) { described_class.new(Fear.left("error")) }
107
109
 
108
110
  it { is_expected.to eq(either) }
109
111
  end
110
112
 
111
- context 'value is not Either' do
113
+ context "value is not Either" do
112
114
  subject { either.join_left }
113
- let(:either) { described_class.new('result') }
115
+ let(:either) { described_class.new("result") }
114
116
  it { is_expected.to eq(either) }
115
117
  end
116
118
  end
117
119
 
118
- describe '#match' do
119
- context 'matched' do
120
+ describe "#match" do
121
+ context "matched" do
120
122
  subject do
121
123
  right.match do |m|
122
124
  m.right(->(x) { x.length < 2 }) { |x| "Right: #{x}" }
@@ -125,15 +127,15 @@ RSpec.describe Fear::Right do
125
127
  end
126
128
  end
127
129
 
128
- it { is_expected.to eq('Right: value') }
130
+ it { is_expected.to eq("Right: value") }
129
131
  end
130
132
 
131
- context 'nothing matched and no else given' do
133
+ context "nothing matched and no else given" do
132
134
  subject do
133
135
  proc do
134
136
  right.match do |m|
135
137
  m.right(->(x) { x.length < 2 }) { |x| "Right: #{x}" }
136
- m.left { |_| 'noop' }
138
+ m.left { |_| "noop" }
137
139
  end
138
140
  end
139
141
  end
@@ -141,7 +143,7 @@ RSpec.describe Fear::Right do
141
143
  it { is_expected.to raise_error(Fear::MatchError) }
142
144
  end
143
145
 
144
- context 'nothing matched and else given' do
146
+ context "nothing matched and else given" do
145
147
  subject do
146
148
  right.match do |m|
147
149
  m.right(->(x) { x.length < 2 }) { |x| "Right: #{x}" }
@@ -153,31 +155,9 @@ RSpec.describe Fear::Right do
153
155
  end
154
156
  end
155
157
 
156
- describe '#to_s' do
158
+ describe "#to_s" do
157
159
  subject { right.to_s }
158
160
 
159
161
  it { is_expected.to eq('#<Fear::Right value="value">') }
160
162
  end
161
-
162
- describe 'pattern matching' do
163
- subject { Fear.xcase('Right(v : Integer)') { |v:| "matched #{v}" }.call_or_else(var) { 'nothing' } }
164
-
165
- context 'right of int' do
166
- let(:var) { Fear.right(42) }
167
-
168
- it { is_expected.to eq('matched 42') }
169
- end
170
-
171
- context 'right of string' do
172
- let(:var) { Fear.right('42') }
173
-
174
- it { is_expected.to eq('nothing') }
175
- end
176
-
177
- context 'not right' do
178
- let(:var) { '42' }
179
-
180
- it { is_expected.to eq('nothing') }
181
- end
182
- end
183
163
  end
@@ -1,71 +1,83 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe Fear::Some do
2
4
  it_behaves_like Fear::RightBiased::Right do
3
- let(:right) { Fear.some('value') }
5
+ let(:right) { Fear.some("value") }
4
6
  end
5
7
 
6
8
  subject(:some) { Fear.some(42) }
7
9
 
8
- describe '#select' do
10
+ describe "#select" do
9
11
  subject { some.select(&predicate) }
10
12
 
11
- context 'predicate evaluates to true' do
13
+ context "predicate evaluates to true" do
12
14
  let(:predicate) { ->(v) { v > 40 } }
13
15
  it { is_expected.to eq(some) }
14
16
  end
15
17
 
16
- context 'predicate evaluates to false' do
18
+ context "predicate evaluates to false" do
17
19
  let(:predicate) { ->(v) { v < 40 } }
18
20
  it { is_expected.to eq(Fear.none) }
19
21
  end
20
22
  end
21
23
 
22
- describe '#reject' do
24
+ describe "#reject" do
23
25
  subject { some.reject(&predicate) }
24
26
 
25
- context 'predicate evaluates to true' do
27
+ context "predicate evaluates to true" do
26
28
  let(:predicate) { ->(v) { v > 40 } }
27
29
  it { is_expected.to eq(Fear.none) }
28
30
  end
29
31
 
30
- context 'predicate evaluates to false' do
32
+ context "predicate evaluates to false" do
31
33
  let(:predicate) { ->(v) { v < 40 } }
32
34
  it { is_expected.to eq(some) }
33
35
  end
34
36
  end
35
37
 
36
- describe '#get' do
38
+ describe "#get" do
37
39
  subject { some.get }
38
40
  it { is_expected.to eq(42) }
39
41
  end
40
42
 
41
- describe '#or_nil' do
43
+ describe "#or_nil" do
42
44
  subject { some.or_nil }
43
45
  it { is_expected.to eq(42) }
44
46
  end
45
47
 
46
- describe '#empty?' do
48
+ describe "#empty?" do
47
49
  subject { some.empty? }
48
50
  it { is_expected.to eq(false) }
49
51
  end
50
52
 
51
- describe '#match' do
52
- context 'matched' do
53
+ describe "#blank?" do
54
+ subject { some.blank? }
55
+ it { is_expected.to eq(false) }
56
+ end
57
+
58
+ describe "#present?" do
59
+ subject { some.present? }
60
+ it { is_expected.to be_truthy }
61
+ end
62
+
63
+ describe "#match" do
64
+ context "matched" do
53
65
  subject do
54
66
  some.match do |m|
55
67
  m.some(->(x) { x > 2 }) { |x| x * 2 }
56
- m.none { 'noop' }
68
+ m.none { "noop" }
57
69
  end
58
70
  end
59
71
 
60
72
  it { is_expected.to eq(84) }
61
73
  end
62
74
 
63
- context 'nothing matched and no else given' do
75
+ context "nothing matched and no else given" do
64
76
  subject do
65
77
  proc do
66
78
  some.match do |m|
67
79
  m.some(->(x) { x < 2 }) { |x| x * 2 }
68
- m.none { 'noop' }
80
+ m.none { "noop" }
69
81
  end
70
82
  end
71
83
  end
@@ -73,7 +85,7 @@ RSpec.describe Fear::Some do
73
85
  it { is_expected.to raise_error(Fear::MatchError) }
74
86
  end
75
87
 
76
- context 'nothing matched and else given' do
88
+ context "nothing matched and else given" do
77
89
  subject do
78
90
  some.match do |m|
79
91
  m.none { |x| x * 2 }
@@ -85,31 +97,9 @@ RSpec.describe Fear::Some do
85
97
  end
86
98
  end
87
99
 
88
- describe '#to_s' do
100
+ describe "#to_s" do
89
101
  subject { some.to_s }
90
102
 
91
- it { is_expected.to eq('#<Fear::Some get=42>') }
92
- end
93
-
94
- describe 'pattern matching' do
95
- subject { Fear.xcase('Some(v : Integer)') { |v:| "matched #{v}" }.call_or_else(var) { 'nothing' } }
96
-
97
- context 'some of int' do
98
- let(:var) { Fear.some(42) }
99
-
100
- it { is_expected.to eq('matched 42') }
101
- end
102
-
103
- context 'some of string' do
104
- let(:var) { Fear.some('42') }
105
-
106
- it { is_expected.to eq('nothing') }
107
- end
108
-
109
- context 'not some' do
110
- let(:var) { '42' }
111
-
112
- it { is_expected.to eq('nothing') }
113
- end
103
+ it { is_expected.to eq("#<Fear::Some get=42>") }
114
104
  end
115
105
  end
@@ -1,114 +1,116 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe Fear::Success do
2
- let(:success) { Fear.success('value') }
4
+ let(:success) { Fear.success("value") }
3
5
 
4
6
  it_behaves_like Fear::RightBiased::Right do
5
7
  let(:right) { success }
6
8
 
7
- describe '#map', 'block fails' do
8
- subject(:map) { right.map { raise 'unexpected error' } }
9
+ describe "#map", "block fails" do
10
+ subject(:map) { right.map { raise "unexpected error" } }
9
11
 
10
12
  it { is_expected.to be_kind_of(Fear::Failure) }
11
- it { expect { map.get }.to raise_error(RuntimeError, 'unexpected error') }
13
+ it { expect { map.get }.to raise_error(RuntimeError, "unexpected error") }
12
14
  end
13
15
 
14
- describe '#flat_map', 'block fails' do
15
- subject(:flat_map) { right.flat_map { raise 'unexpected error' } }
16
+ describe "#flat_map", "block fails" do
17
+ subject(:flat_map) { right.flat_map { raise "unexpected error" } }
16
18
 
17
19
  it { is_expected.to be_kind_of(Fear::Failure) }
18
- it { expect { flat_map.get }.to raise_error(RuntimeError, 'unexpected error') }
20
+ it { expect { flat_map.get }.to raise_error(RuntimeError, "unexpected error") }
19
21
  end
20
22
  end
21
23
 
22
- describe '#get' do
24
+ describe "#get" do
23
25
  subject { success.get }
24
- it { is_expected.to eq('value') }
26
+ it { is_expected.to eq("value") }
25
27
  end
26
28
 
27
- describe '#success?' do
29
+ describe "#success?" do
28
30
  subject { success }
29
31
  it { is_expected.to be_success }
30
32
  end
31
33
 
32
- describe '#failure?' do
34
+ describe "#failure?" do
33
35
  subject { success }
34
36
  it { is_expected.not_to be_failure }
35
37
  end
36
38
 
37
- describe '#or_else' do
38
- subject { success.or_else { described_class.new('another value') } }
39
+ describe "#or_else" do
40
+ subject { success.or_else { described_class.new("another value") } }
39
41
  it { is_expected.to eq(success) }
40
42
  end
41
43
 
42
- describe '#flatten' do
44
+ describe "#flatten" do
43
45
  subject { described_class.new(value).flatten }
44
46
 
45
- context 'value is a Success' do
47
+ context "value is a Success" do
46
48
  let(:value) { described_class.new(42) }
47
49
  it { is_expected.to eq(described_class.new(42)) }
48
50
  end
49
51
 
50
- context 'value is a Success of Success' do
52
+ context "value is a Success of Success" do
51
53
  let(:value) { described_class.new(described_class.new(42)) }
52
54
  it { is_expected.to eq(described_class.new(42)) }
53
55
  end
54
56
 
55
- context 'value is a Success of Failure' do
57
+ context "value is a Success of Failure" do
56
58
  let(:failure) { Fear::Failure.new(RuntimeError.new) }
57
59
  let(:value) { described_class.new(failure) }
58
60
  it { is_expected.to eq(failure) }
59
61
  end
60
62
  end
61
63
 
62
- describe '#select' do
63
- context 'predicate holds for value' do
64
- subject { success.select { |v| v == 'value' } }
64
+ describe "#select" do
65
+ context "predicate holds for value" do
66
+ subject { success.select { |v| v == "value" } }
65
67
  it { is_expected.to eq(success) }
66
68
  end
67
69
 
68
- context 'predicate does not hold for value' do
69
- subject { proc { success.select { |v| v != 'value' }.get } } # rubocop: disable Style/InverseMethods
70
- it { is_expected.to raise_error(Fear::NoSuchElementError, 'Predicate does not hold for `value`') }
70
+ context "predicate does not hold for value" do
71
+ subject { proc { success.select { |v| v != "value" }.get } }
72
+ it { is_expected.to raise_error(Fear::NoSuchElementError, "Predicate does not hold for `value`") }
71
73
  end
72
74
 
73
- context 'predicate fails with error' do
74
- subject { proc { success.select { raise 'foo' }.get } }
75
- it { is_expected.to raise_error(RuntimeError, 'foo') }
75
+ context "predicate fails with error" do
76
+ subject { proc { success.select { raise "foo" }.get } }
77
+ it { is_expected.to raise_error(RuntimeError, "foo") }
76
78
  end
77
79
  end
78
80
 
79
- describe '#recover_with' do
81
+ describe "#recover_with" do
80
82
  subject { success.recover_with { |v| Fear.success(v * 2) } }
81
83
  it { is_expected.to eq(success) }
82
84
  end
83
85
 
84
- describe '#recover' do
86
+ describe "#recover" do
85
87
  subject { success.recover { |m| m.case { |v| v * 2 } } }
86
88
  it { is_expected.to eq(success) }
87
89
  end
88
90
 
89
- describe '#to_either' do
91
+ describe "#to_either" do
90
92
  subject { success.to_either }
91
- it { is_expected.to eq(Fear.right('value')) }
93
+ it { is_expected.to eq(Fear.right("value")) }
92
94
  end
93
95
 
94
- describe '#match' do
95
- context 'matched' do
96
+ describe "#match" do
97
+ context "matched" do
96
98
  subject do
97
99
  success.match do |m|
98
100
  m.success(->(x) { x.length > 2 }) { |x| x * 2 }
99
- m.failure { 'noop' }
101
+ m.failure { "noop" }
100
102
  end
101
103
  end
102
104
 
103
- it { is_expected.to eq('valuevalue') }
105
+ it { is_expected.to eq("valuevalue") }
104
106
  end
105
107
 
106
- context 'nothing matched and no else given' do
108
+ context "nothing matched and no else given" do
107
109
  subject do
108
110
  proc do
109
111
  success.match do |m|
110
112
  m.success(->(x) { x.length < 2 }) { |x| x * 2 }
111
- m.failure { 'noop' }
113
+ m.failure { "noop" }
112
114
  end
113
115
  end
114
116
  end
@@ -116,7 +118,7 @@ RSpec.describe Fear::Success do
116
118
  it { is_expected.to raise_error(Fear::MatchError) }
117
119
  end
118
120
 
119
- context 'nothing matched and else given' do
121
+ context "nothing matched and else given" do
120
122
  subject do
121
123
  success.match do |m|
122
124
  m.failure { |x| x * 2 }
@@ -128,31 +130,9 @@ RSpec.describe Fear::Success do
128
130
  end
129
131
  end
130
132
 
131
- describe '#to_s' do
133
+ describe "#to_s" do
132
134
  subject { success.to_s }
133
135
 
134
136
  it { is_expected.to eq('#<Fear::Success value="value">') }
135
137
  end
136
-
137
- describe 'pattern matching' do
138
- subject { Fear.xcase('Success(v : Integer)') { |v:| "matched #{v}" }.call_or_else(var) { 'nothing' } }
139
-
140
- context 'success of int' do
141
- let(:var) { Fear.success(42) }
142
-
143
- it { is_expected.to eq('matched 42') }
144
- end
145
-
146
- context 'success of string' do
147
- let(:var) { Fear.success('42') }
148
-
149
- it { is_expected.to eq('nothing') }
150
- end
151
-
152
- context 'not success' do
153
- let(:var) { '42' }
154
-
155
- it { is_expected.to eq('nothing') }
156
- end
157
- end
158
138
  end
@@ -1,17 +1,33 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe Fear::Try::Mixin do
2
4
  include Fear::Try::Mixin
3
5
 
4
- describe 'Try()' do
5
- context 'success' do
6
+ describe "Try()" do
7
+ context "success" do
6
8
  subject { Try { 4 / 2 } }
7
9
 
8
10
  it { is_expected.to eq(Fear::Success.new(2)) }
9
11
  end
10
12
 
11
- context 'failure' do
13
+ context "failure" do
12
14
  subject { Try { 4 / 0 } }
13
15
 
14
16
  it { is_expected.to be_kind_of(Fear::Failure) }
15
17
  end
16
18
  end
19
+
20
+ describe "Success()" do
21
+ subject { Success(42) }
22
+
23
+ it { is_expected.to be_success_of(42) }
24
+ end
25
+
26
+ describe "Failure()" do
27
+ subject { Failure(error) }
28
+
29
+ let(:error) { StandardError.new }
30
+
31
+ it { is_expected.to be_failure_of(error) }
32
+ end
17
33
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Fear::TryApi do
4
+ describe "Fear.try" do
5
+ context "when success" do
6
+ subject { Fear.try { 42 } }
7
+
8
+ it { is_expected.to be_success_of(42) }
9
+ end
10
+
11
+ context "when failure" do
12
+ subject { Fear.try { raise RuntimeError } }
13
+
14
+ it { is_expected.to be_failure_of(RuntimeError) }
15
+ end
16
+
17
+ context "when low level error happened" do
18
+ subject(:try) { Fear.try { raise Exception } }
19
+
20
+ it { expect { try }.to raise_error(Exception) }
21
+ end
22
+ end
23
+ end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe Fear::TryPatternMatch do
2
- context 'Success' do
4
+ context "Success" do
3
5
  let(:matcher) do
4
6
  described_class.new do |m|
5
7
  m.success(:even?.to_proc) { |x| "#{x} is even" }
@@ -8,15 +10,15 @@ RSpec.describe Fear::TryPatternMatch do
8
10
  end
9
11
 
10
12
  it do
11
- expect(matcher.call(Fear.success(4))).to eq('4 is even')
12
- expect(matcher.call(Fear.success(3))).to eq('3 is odd')
13
+ expect(matcher.(Fear.success(4))).to eq("4 is even")
14
+ expect(matcher.(Fear.success(3))).to eq("3 is odd")
13
15
  expect do
14
- matcher.call(Fear.failure(RuntimeError.new))
16
+ matcher.(Fear.failure(RuntimeError.new))
15
17
  end.to raise_error(Fear::MatchError)
16
18
  end
17
19
  end
18
20
 
19
- context 'Failure' do
21
+ context "Failure" do
20
22
  let(:matcher) do
21
23
  described_class.new do |m|
22
24
  m.failure(RuntimeError) { |x| "#{x} is first" }
@@ -25,10 +27,10 @@ RSpec.describe Fear::TryPatternMatch do
25
27
  end
26
28
 
27
29
  it do
28
- expect(matcher.call(Fear.failure(RuntimeError.new))).to eq('RuntimeError is first')
29
- expect(matcher.call(Fear.failure(StandardError.new))).to eq('StandardError is second')
30
+ expect(matcher.(Fear.failure(RuntimeError.new))).to eq("RuntimeError is first")
31
+ expect(matcher.(Fear.failure(StandardError.new))).to eq("StandardError is second")
30
32
  expect do
31
- matcher.call(Fear.success(44))
33
+ matcher.(Fear.success(44))
32
34
  end.to raise_error(Fear::MatchError)
33
35
  end
34
36
  end