fear 0.9.0 → 1.2.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 (155) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/rubocop.yml +39 -0
  3. data/.github/workflows/spec.yml +42 -0
  4. data/.gitignore +0 -1
  5. data/.rubocop.yml +4 -12
  6. data/.simplecov +17 -0
  7. data/CHANGELOG.md +40 -0
  8. data/Gemfile +5 -2
  9. data/Gemfile.lock +130 -0
  10. data/LICENSE.txt +1 -1
  11. data/README.md +1293 -97
  12. data/Rakefile +369 -1
  13. data/benchmarks/README.md +1 -0
  14. data/benchmarks/dry_do_vs_fear_for.txt +11 -0
  15. data/benchmarks/dry_some_fmap_vs_fear_some_map.txt +11 -0
  16. data/benchmarks/factorial.txt +16 -0
  17. data/benchmarks/fear_gaurd_and1_vs_new.txt +13 -0
  18. data/benchmarks/fear_gaurd_and2_vs_and.txt +13 -0
  19. data/benchmarks/fear_gaurd_and3_vs_and_and.txt +13 -0
  20. data/benchmarks/fear_pattern_extracting_with_vs_without_cache.txt +11 -0
  21. data/benchmarks/fear_pattern_matching_construction_vs_execution.txt +13 -0
  22. data/benchmarks/pattern_matching_dry_vs_qo_vs_fear_try.txt +14 -0
  23. data/benchmarks/pattern_matching_qo_vs_fear_pattern_extraction.txt +11 -0
  24. data/benchmarks/pattern_matching_qo_vs_fear_try_execution.txt +11 -0
  25. data/examples/pattern_extracting.rb +17 -0
  26. data/examples/pattern_extracting_ruby2.7.rb +15 -0
  27. data/examples/pattern_matching_binary_tree_set.rb +101 -0
  28. data/examples/pattern_matching_number_in_words.rb +60 -0
  29. data/fear.gemspec +34 -23
  30. data/lib/dry/types/fear.rb +8 -0
  31. data/lib/dry/types/fear/option.rb +125 -0
  32. data/lib/fear.rb +65 -15
  33. data/lib/fear/await.rb +33 -0
  34. data/lib/fear/awaitable.rb +28 -0
  35. data/lib/fear/either.rb +131 -71
  36. data/lib/fear/either_api.rb +23 -0
  37. data/lib/fear/either_pattern_match.rb +53 -0
  38. data/lib/fear/empty_partial_function.rb +38 -0
  39. data/lib/fear/extractor.rb +112 -0
  40. data/lib/fear/extractor/anonymous_array_splat_matcher.rb +10 -0
  41. data/lib/fear/extractor/any_matcher.rb +17 -0
  42. data/lib/fear/extractor/array_head_matcher.rb +36 -0
  43. data/lib/fear/extractor/array_matcher.rb +40 -0
  44. data/lib/fear/extractor/array_splat_matcher.rb +16 -0
  45. data/lib/fear/extractor/empty_list_matcher.rb +20 -0
  46. data/lib/fear/extractor/extractor_matcher.rb +44 -0
  47. data/lib/fear/extractor/grammar.rb +203 -0
  48. data/lib/fear/extractor/grammar.treetop +129 -0
  49. data/lib/fear/extractor/identifier_matcher.rb +18 -0
  50. data/lib/fear/extractor/matcher.rb +53 -0
  51. data/lib/fear/extractor/matcher/and.rb +38 -0
  52. data/lib/fear/extractor/named_array_splat_matcher.rb +17 -0
  53. data/lib/fear/extractor/pattern.rb +58 -0
  54. data/lib/fear/extractor/typed_identifier_matcher.rb +26 -0
  55. data/lib/fear/extractor/value_matcher.rb +19 -0
  56. data/lib/fear/extractor_api.rb +35 -0
  57. data/lib/fear/failure.rb +46 -14
  58. data/lib/fear/failure_pattern_match.rb +10 -0
  59. data/lib/fear/for.rb +37 -95
  60. data/lib/fear/for_api.rb +68 -0
  61. data/lib/fear/future.rb +497 -0
  62. data/lib/fear/future_api.rb +21 -0
  63. data/lib/fear/left.rb +19 -2
  64. data/lib/fear/left_pattern_match.rb +11 -0
  65. data/lib/fear/none.rb +67 -3
  66. data/lib/fear/none_pattern_match.rb +14 -0
  67. data/lib/fear/option.rb +120 -56
  68. data/lib/fear/option_api.rb +40 -0
  69. data/lib/fear/option_pattern_match.rb +48 -0
  70. data/lib/fear/partial_function.rb +176 -0
  71. data/lib/fear/partial_function/and_then.rb +50 -0
  72. data/lib/fear/partial_function/any.rb +28 -0
  73. data/lib/fear/partial_function/combined.rb +53 -0
  74. data/lib/fear/partial_function/empty.rb +10 -0
  75. data/lib/fear/partial_function/guard.rb +80 -0
  76. data/lib/fear/partial_function/guard/and.rb +38 -0
  77. data/lib/fear/partial_function/guard/and3.rb +41 -0
  78. data/lib/fear/partial_function/guard/or.rb +38 -0
  79. data/lib/fear/partial_function/lifted.rb +23 -0
  80. data/lib/fear/partial_function/or_else.rb +64 -0
  81. data/lib/fear/partial_function_class.rb +38 -0
  82. data/lib/fear/pattern_match.rb +114 -0
  83. data/lib/fear/pattern_matching_api.rb +137 -0
  84. data/lib/fear/promise.rb +95 -0
  85. data/lib/fear/right.rb +20 -2
  86. data/lib/fear/right_biased.rb +6 -14
  87. data/lib/fear/right_pattern_match.rb +11 -0
  88. data/lib/fear/some.rb +55 -3
  89. data/lib/fear/some_pattern_match.rb +13 -0
  90. data/lib/fear/struct.rb +248 -0
  91. data/lib/fear/success.rb +35 -5
  92. data/lib/fear/success_pattern_match.rb +12 -0
  93. data/lib/fear/try.rb +136 -79
  94. data/lib/fear/try_api.rb +33 -0
  95. data/lib/fear/try_pattern_match.rb +33 -0
  96. data/lib/fear/unit.rb +32 -0
  97. data/lib/fear/utils.rb +39 -14
  98. data/lib/fear/version.rb +4 -1
  99. data/spec/dry/types/fear/option/constrained_spec.rb +22 -0
  100. data/spec/dry/types/fear/option/core_spec.rb +77 -0
  101. data/spec/dry/types/fear/option/default_spec.rb +21 -0
  102. data/spec/dry/types/fear/option/hash_spec.rb +58 -0
  103. data/spec/dry/types/fear/option/option_spec.rb +97 -0
  104. data/spec/fear/awaitable_spec.rb +17 -0
  105. data/spec/fear/done_spec.rb +8 -6
  106. data/spec/fear/either/mixin_spec.rb +17 -0
  107. data/spec/fear/either_pattern_match_spec.rb +37 -0
  108. data/spec/fear/either_pattern_matching_spec.rb +28 -0
  109. data/spec/fear/extractor/array_matcher_spec.rb +230 -0
  110. data/spec/fear/extractor/extractor_matcher_spec.rb +153 -0
  111. data/spec/fear/extractor/grammar_array_spec.rb +25 -0
  112. data/spec/fear/extractor/identified_matcher_spec.rb +49 -0
  113. data/spec/fear/extractor/identifier_matcher_spec.rb +68 -0
  114. data/spec/fear/extractor/pattern_spec.rb +34 -0
  115. data/spec/fear/extractor/typed_identifier_matcher_spec.rb +64 -0
  116. data/spec/fear/extractor/value_matcher_number_spec.rb +79 -0
  117. data/spec/fear/extractor/value_matcher_string_spec.rb +88 -0
  118. data/spec/fear/extractor/value_matcher_symbol_spec.rb +71 -0
  119. data/spec/fear/extractor_api_spec.rb +115 -0
  120. data/spec/fear/extractor_spec.rb +61 -0
  121. data/spec/fear/failure_spec.rb +145 -45
  122. data/spec/fear/for_spec.rb +57 -67
  123. data/spec/fear/future_spec.rb +691 -0
  124. data/spec/fear/guard_spec.rb +103 -0
  125. data/spec/fear/left_spec.rb +112 -46
  126. data/spec/fear/none_spec.rb +114 -16
  127. data/spec/fear/option/mixin_spec.rb +39 -0
  128. data/spec/fear/option_pattern_match_spec.rb +35 -0
  129. data/spec/fear/option_pattern_matching_spec.rb +34 -0
  130. data/spec/fear/option_spec.rb +121 -8
  131. data/spec/fear/partial_function/empty_spec.rb +38 -0
  132. data/spec/fear/partial_function_and_then_spec.rb +147 -0
  133. data/spec/fear/partial_function_composition_spec.rb +82 -0
  134. data/spec/fear/partial_function_or_else_spec.rb +276 -0
  135. data/spec/fear/partial_function_spec.rb +239 -0
  136. data/spec/fear/pattern_match_spec.rb +93 -0
  137. data/spec/fear/pattern_matching_api_spec.rb +31 -0
  138. data/spec/fear/promise_spec.rb +96 -0
  139. data/spec/fear/right_biased/left.rb +29 -32
  140. data/spec/fear/right_biased/right.rb +51 -54
  141. data/spec/fear/right_spec.rb +109 -41
  142. data/spec/fear/some_spec.rb +80 -15
  143. data/spec/fear/success_spec.rb +99 -32
  144. data/spec/fear/try/mixin_spec.rb +19 -0
  145. data/spec/fear/try_pattern_match_spec.rb +37 -0
  146. data/spec/fear/try_pattern_matching_spec.rb +34 -0
  147. data/spec/fear/utils_spec.rb +16 -14
  148. data/spec/spec_helper.rb +13 -7
  149. data/spec/struct_pattern_matching_spec.rb +36 -0
  150. data/spec/struct_spec.rb +226 -0
  151. data/spec/support/dry_types.rb +6 -0
  152. metadata +320 -29
  153. data/.travis.yml +0 -9
  154. data/lib/fear/done.rb +0 -22
  155. data/lib/fear/for/evaluation_context.rb +0 -91
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Fear::PartialFunction::Guard do
4
+ context "Class" do
5
+ context "match" do
6
+ subject { Fear::PartialFunction::Guard.new(Integer) === 4 }
7
+
8
+ it { is_expected.to eq(true) }
9
+ end
10
+
11
+ context "not match" do
12
+ subject { Fear::PartialFunction::Guard.new(Integer) === "4" }
13
+
14
+ it { is_expected.to eq(false) }
15
+ end
16
+ end
17
+
18
+ context "Symbol" do
19
+ context "match" do
20
+ subject { Fear::PartialFunction::Guard.new(:even?) === :even? }
21
+
22
+ it { is_expected.to eq(true) }
23
+ end
24
+
25
+ context "not match" do
26
+ subject { Fear::PartialFunction::Guard.new(:even?) === 4 }
27
+
28
+ it { is_expected.to eq(false) }
29
+ end
30
+ end
31
+
32
+ context "Proc" do
33
+ context "match" do
34
+ subject { Fear::PartialFunction::Guard.new(->(x) { x.even? }) === 4 }
35
+
36
+ it { is_expected.to eq(true) }
37
+ end
38
+
39
+ context "not match" do
40
+ subject { Fear::PartialFunction::Guard.new(->(x) { x.even? }) === 3 }
41
+
42
+ it { is_expected.to eq(false) }
43
+ end
44
+ end
45
+
46
+ describe ".and" do
47
+ context "match" do
48
+ subject { guard === 4 }
49
+ let(:guard) { Fear::PartialFunction::Guard.and([Integer, :even?.to_proc, ->(x) { x.even? }]) }
50
+
51
+ it { is_expected.to eq(true) }
52
+ end
53
+
54
+ context "not match" do
55
+ subject { guard === 3 }
56
+ let(:guard) { Fear::PartialFunction::Guard.and([Integer, :even?.to_proc, ->(x) { x.even? }]) }
57
+
58
+ it { is_expected.to eq(false) }
59
+ end
60
+
61
+ context "empty array" do
62
+ subject { guard === 4 }
63
+ let(:guard) { Fear::PartialFunction::Guard.and([]) }
64
+
65
+ it "matches any values" do
66
+ is_expected.to eq(true)
67
+ end
68
+ end
69
+
70
+ context "short circuit" do
71
+ let(:guard) { Fear::PartialFunction::Guard.and([first, second, third]) }
72
+ let(:first) { ->(_) { false } }
73
+ let(:second) { ->(_) { raise } }
74
+ let(:third) { ->(_) { raise } }
75
+
76
+ it "does not call the second and the third" do
77
+ expect { guard === 4 }.not_to raise_error
78
+ end
79
+ end
80
+ end
81
+
82
+ describe ".or" do
83
+ let(:guard) { Fear::PartialFunction::Guard.or(["F", Integer]) }
84
+
85
+ context "match second" do
86
+ subject { guard === 4 }
87
+
88
+ it { is_expected.to eq(true) }
89
+ end
90
+
91
+ context "match first" do
92
+ subject { guard === "F" }
93
+
94
+ it { is_expected.to eq(true) }
95
+ end
96
+
97
+ context "not match" do
98
+ subject { guard === "A&" }
99
+
100
+ it { is_expected.to eq(false) }
101
+ end
102
+ end
103
+ end
@@ -1,79 +1,79 @@
1
- RSpec.describe Fear::Left do
2
- include Fear::Either::Mixin
1
+ # frozen_string_literal: true
3
2
 
3
+ RSpec.describe Fear::Left do
4
4
  it_behaves_like Fear::RightBiased::Left do
5
- let(:left) { Left('value') }
5
+ let(:left) { Fear.left("value") }
6
6
  end
7
7
 
8
- let(:left) { Left('value') }
8
+ let(:left) { Fear.left("value") }
9
9
 
10
- describe '#right?' do
10
+ describe "#right?" do
11
11
  subject { left }
12
12
  it { is_expected.not_to be_right }
13
13
  end
14
14
 
15
- describe '#left?' do
15
+ describe "#left?" do
16
16
  subject { left }
17
17
  it { is_expected.to be_left }
18
18
  end
19
19
 
20
- describe '#select_or_else' do
20
+ describe "#select_or_else" do
21
21
  subject do
22
- left.select_or_else(default) { |v| v == 'value' }
22
+ left.select_or_else(default) { |v| v == "value" }
23
23
  end
24
24
 
25
- context 'proc default' do
25
+ context "proc default" do
26
26
  let(:default) { -> { -1 } }
27
27
 
28
- it 'returns itself' do
28
+ it "returns itself" do
29
29
  is_expected.to eq(left)
30
30
  end
31
31
  end
32
32
 
33
- context 'default' do
33
+ context "default" do
34
34
  let(:default) { -1 }
35
35
 
36
- it 'returns itself' do
36
+ it "returns itself" do
37
37
  is_expected.to eq(left)
38
38
  end
39
39
  end
40
40
  end
41
41
 
42
- describe '#or_else' do
42
+ describe "#or_else" do
43
43
  subject { left.or_else { alternative } }
44
- let(:alternative) { Left(42) }
44
+ let(:alternative) { Fear.left(42) }
45
45
 
46
- it 'returns alternative' do
46
+ it "returns alternative" do
47
47
  is_expected.to eq(alternative)
48
48
  end
49
49
  end
50
50
 
51
- describe '#select' do
51
+ describe "#select" do
52
52
  subject do
53
- left.select { |v| v == 'value' }
53
+ left.select { |v| v == "value" }
54
54
  end
55
55
 
56
- it 'return self' do
56
+ it "return self" do
57
57
  is_expected.to eq(left)
58
58
  end
59
59
  end
60
60
 
61
- describe '#reject' do
61
+ describe "#reject" do
62
62
  subject do
63
- left.reject { |v| v == 'value' }
63
+ left.reject { |v| v == "value" }
64
64
  end
65
65
 
66
- it 'return self' do
66
+ it "return self" do
67
67
  is_expected.to eq(left)
68
68
  end
69
69
  end
70
70
 
71
- describe '#swap' do
71
+ describe "#swap" do
72
72
  subject { left.swap }
73
- it { is_expected.to eq(Right('value')) }
73
+ it { is_expected.to eq(Fear.right("value")) }
74
74
  end
75
75
 
76
- describe '#reduce' do
76
+ describe "#reduce" do
77
77
  subject do
78
78
  left.reduce(
79
79
  ->(left) { "Left: #{left}" },
@@ -81,64 +81,130 @@ RSpec.describe Fear::Left do
81
81
  )
82
82
  end
83
83
 
84
- it { is_expected.to eq('Left: value') }
84
+ it { is_expected.to eq("Left: value") }
85
85
  end
86
86
 
87
- describe '#join_right' do
87
+ describe "#join_right" do
88
88
  subject(:join_right) { either.join_right }
89
89
 
90
- context 'value is Either' do
91
- let(:either) { described_class.new(Left('error')) }
90
+ context "value is Either" do
91
+ let(:either) { described_class.new(Fear.left("error")) }
92
92
  it { is_expected.to eq(either) }
93
93
  end
94
94
 
95
- context 'value s not Either' do
96
- let(:either) { Left('error') }
95
+ context "value s not Either" do
96
+ let(:either) { Fear.left("error") }
97
97
  it { is_expected.to eq(either) }
98
98
  end
99
99
  end
100
100
 
101
- describe '#join_left' do
102
- context 'value is Either' do
101
+ describe "#join_left" do
102
+ context "value is Either" do
103
103
  subject { either.join_left }
104
104
  let(:either) { described_class.new(value) }
105
- let(:value) { Left('error') }
105
+ let(:value) { Fear.left("error") }
106
106
 
107
- it 'returns value' do
108
- is_expected.to eq(Left('error'))
107
+ it "returns value" do
108
+ is_expected.to eq(Fear.left("error"))
109
109
  end
110
110
  end
111
111
 
112
- context 'value is not Either' do
112
+ context "value is not Either" do
113
113
  subject { proc { left.join_left } }
114
114
 
115
- it 'fails with type error' do
115
+ it "fails with type error" do
116
116
  is_expected.to raise_error(TypeError)
117
117
  end
118
118
  end
119
119
  end
120
120
 
121
- describe '#===' do
121
+ describe "#===" do
122
122
  subject { match === left }
123
123
 
124
- context 'matches erectly' do
125
- let(:match) { Left('value') }
124
+ context "matches erectly" do
125
+ let(:match) { Fear.left("value") }
126
126
  it { is_expected.to eq(true) }
127
127
  end
128
128
 
129
- context 'value does not match' do
130
- let(:match) { Left('error') }
129
+ context "value does not match" do
130
+ let(:match) { Fear.left("error") }
131
131
  it { is_expected.to eq(false) }
132
132
  end
133
133
 
134
- context 'matches by class' do
135
- let(:match) { Left(String) }
134
+ context "matches by class" do
135
+ let(:match) { Fear.left(String) }
136
136
  it { is_expected.to eq(true) }
137
137
  end
138
138
 
139
- context 'does not matches by class' do
140
- let(:match) { Left(Integer) }
139
+ context "does not matches by class" do
140
+ let(:match) { Fear.left(Integer) }
141
141
  it { is_expected.to eq(false) }
142
142
  end
143
143
  end
144
+
145
+ describe "#match" do
146
+ context "matched" do
147
+ subject do
148
+ left.match do |m|
149
+ m.left(->(x) { x.length < 2 }) { |x| "Left: #{x}" }
150
+ m.left(->(x) { x.length > 2 }) { |x| "Left: #{x}" }
151
+ m.right(->(x) { x.length > 2 }) { |x| "Right: #{x}" }
152
+ end
153
+ end
154
+
155
+ it { is_expected.to eq("Left: value") }
156
+ end
157
+
158
+ context "nothing matched and no else given" do
159
+ subject do
160
+ proc do
161
+ left.match do |m|
162
+ m.left(->(x) { x.length < 2 }) { |x| "Left: #{x}" }
163
+ m.right { |_| "noop" }
164
+ end
165
+ end
166
+ end
167
+
168
+ it { is_expected.to raise_error(Fear::MatchError) }
169
+ end
170
+
171
+ context "nothing matched and else given" do
172
+ subject do
173
+ left.match do |m|
174
+ m.left(->(x) { x.length < 2 }) { |x| "Left: #{x}" }
175
+ m.else { :default }
176
+ end
177
+ end
178
+
179
+ it { is_expected.to eq(:default) }
180
+ end
181
+ end
182
+
183
+ describe "#to_s" do
184
+ subject { left.to_s }
185
+
186
+ it { is_expected.to eq('#<Fear::Left value="value">') }
187
+ end
188
+
189
+ describe "pattern matching" do
190
+ subject { Fear.xcase("Left(v : Integer)") { |v:| "matched #{v}" }.call_or_else(var) { "nothing" } }
191
+
192
+ context "left of int" do
193
+ let(:var) { Fear.left(42) }
194
+
195
+ it { is_expected.to eq("matched 42") }
196
+ end
197
+
198
+ context "left of string" do
199
+ let(:var) { Fear.left("42") }
200
+
201
+ it { is_expected.to eq("nothing") }
202
+ end
203
+
204
+ context "not left" do
205
+ let(:var) { "42" }
206
+
207
+ it { is_expected.to eq("nothing") }
208
+ end
209
+ end
144
210
  end
@@ -1,49 +1,147 @@
1
- RSpec.describe Fear::None do
2
- include Fear::Option::Mixin
1
+ # frozen_string_literal: true
3
2
 
3
+ RSpec.describe "Fear::None" do
4
4
  it_behaves_like Fear::RightBiased::Left do
5
- let(:left) { None() }
5
+ let(:left) { Fear.none }
6
6
  end
7
7
 
8
- subject(:none) { None() }
8
+ subject(:none) { Fear.none }
9
9
 
10
- describe '#get' do
10
+ describe "#get" do
11
11
  subject { proc { none.get } }
12
12
  it { is_expected.to raise_error(Fear::NoSuchElementError) }
13
13
  end
14
14
 
15
- describe '#or_nil' do
15
+ describe "#or_nil" do
16
16
  subject { none.or_nil }
17
17
  it { is_expected.to eq(nil) }
18
18
  end
19
19
 
20
- describe '#or_else' do
20
+ describe "#or_else" do
21
21
  subject { none.or_else { alternative } }
22
- let(:alternative) { Some(42) }
22
+ let(:alternative) { Fear.some(42) }
23
23
 
24
- it 'returns alternative' do
24
+ it "returns alternative" do
25
25
  is_expected.to eq(alternative)
26
26
  end
27
27
  end
28
28
 
29
- describe '#empty?' do
29
+ describe "#empty?" do
30
30
  subject { none.empty? }
31
31
  it { is_expected.to eq(true) }
32
32
  end
33
33
 
34
- describe '#select' do
34
+ describe "#select" do
35
35
  subject { none.select { |value| value > 42 } }
36
36
 
37
- it 'always return None' do
38
- is_expected.to eq(None())
37
+ it "always return None" do
38
+ is_expected.to eq(Fear.none)
39
39
  end
40
40
  end
41
41
 
42
- describe '#reject' do
42
+ describe "#reject" do
43
43
  subject { none.reject { |value| value > 42 } }
44
44
 
45
- it 'always return None' do
46
- is_expected.to eq(None())
45
+ it "always return None" do
46
+ is_expected.to eq(Fear.none)
47
+ end
48
+ end
49
+
50
+ describe ".new" do
51
+ subject { Fear::None.class.new }
52
+
53
+ it { is_expected.to eq(Fear::None) }
54
+ end
55
+
56
+ describe ".inherited" do
57
+ subject { -> { Class.new(Fear.none.class) } }
58
+
59
+ it "raises error" do
60
+ is_expected.to raise_error(RuntimeError, "you are not allowed to inherit from NoneClass, use Fear::None instead")
61
+ end
62
+ end
63
+
64
+ describe "#to_s" do
65
+ subject { none.to_s }
66
+
67
+ it { is_expected.to eq("#<Fear::NoneClass>") }
68
+ end
69
+
70
+ describe "#inspect" do
71
+ subject { none.inspect }
72
+
73
+ it { is_expected.to eq("#<Fear::NoneClass>") }
74
+ end
75
+
76
+ describe "#===" do
77
+ context "None" do
78
+ subject { Fear::None === none }
79
+
80
+ it { is_expected.to eq(true) }
81
+ end
82
+
83
+ context "Fear::Some" do
84
+ subject { Fear::None === Fear.some(4) }
85
+
86
+ it { is_expected.to eq(false) }
87
+ end
88
+
89
+ context "Integer" do
90
+ subject { Fear::None === 4 }
91
+
92
+ it { is_expected.to eq(false) }
93
+ end
94
+ end
95
+
96
+ describe "#match" do
97
+ context "matched" do
98
+ subject do
99
+ none.match do |m|
100
+ m.some { |x| x * 2 }
101
+ m.none { "noop" }
102
+ end
103
+ end
104
+
105
+ it { is_expected.to eq("noop") }
106
+ end
107
+
108
+ context "nothing matched and no else given" do
109
+ subject do
110
+ proc do
111
+ none.match do |m|
112
+ m.some { |x| x * 2 }
113
+ end
114
+ end
115
+ end
116
+
117
+ it { is_expected.to raise_error(Fear::MatchError) }
118
+ end
119
+
120
+ context "nothing matched and else given" do
121
+ subject do
122
+ none.match do |m|
123
+ m.some { |x| x * 2 }
124
+ m.else { :default }
125
+ end
126
+ end
127
+
128
+ it { is_expected.to eq(:default) }
129
+ end
130
+ end
131
+
132
+ describe "pattern matching" do
133
+ subject { Fear.xcase("None()") { "matched" }.call_or_else(var) { "nothing" } }
134
+
135
+ context "none" do
136
+ let(:var) { Fear.none }
137
+
138
+ it { is_expected.to eq("matched") }
139
+ end
140
+
141
+ context "not none" do
142
+ let(:var) { "42" }
143
+
144
+ it { is_expected.to eq("nothing") }
47
145
  end
48
146
  end
49
147
  end