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,35 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe Fear::Option::Mixin do
2
4
  include Fear::Option::Mixin
3
5
 
4
- describe 'Option()' do
5
- context 'value is nil' do
6
+ describe "Option()" do
7
+ context "value is nil" do
6
8
  subject { Option(nil) }
7
9
 
8
10
  it { is_expected.to eq(Fear.none) }
9
11
  end
10
12
 
11
- context 'value is not nil' do
13
+ context "value is not nil" do
12
14
  subject { Option(42) }
13
15
 
14
16
  it { is_expected.to eq(Fear.some(42)) }
15
17
  end
16
18
  end
17
19
 
18
- describe 'Some()' do
19
- context 'value is nil' do
20
+ describe "Some()" do
21
+ context "value is nil" do
20
22
  subject { Some(nil) }
21
23
 
22
24
  it { is_expected.to eq(Fear::Some.new(nil)) }
23
25
  end
24
26
 
25
- context 'value is not nil' do
27
+ context "value is not nil" do
26
28
  subject { Option(42) }
27
29
 
28
30
  it { is_expected.to eq(Fear::Some.new(42)) }
29
31
  end
30
32
  end
31
33
 
32
- describe 'None()' do
34
+ describe "None()" do
33
35
  subject { None() }
34
36
 
35
37
  it { is_expected.to eq(Fear::None) }
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe Fear::OptionPatternMatch do
2
- context 'Some' do
4
+ context "Some" do
3
5
  let(:matcher) do
4
6
  described_class.new do |m|
5
7
  m.some(:even?.to_proc) { |x| "#{x} is even" }
@@ -8,25 +10,25 @@ RSpec.describe Fear::OptionPatternMatch do
8
10
  end
9
11
 
10
12
  it do
11
- expect(matcher.call(Fear.some(4))).to eq('4 is even')
12
- expect(matcher.call(Fear.some(3))).to eq('3 is odd')
13
+ expect(matcher.(Fear.some(4))).to eq("4 is even")
14
+ expect(matcher.(Fear.some(3))).to eq("3 is odd")
13
15
  expect do
14
- matcher.call(Fear.none)
16
+ matcher.(Fear.none)
15
17
  end.to raise_error(Fear::MatchError)
16
18
  end
17
19
  end
18
20
 
19
- context 'None' do
21
+ context "None" do
20
22
  let(:matcher) do
21
23
  described_class.new do |m|
22
- m.none { 'nil' }
24
+ m.none { "nil" }
23
25
  end
24
26
  end
25
27
 
26
28
  it do
27
- expect(matcher.call(Fear.none)).to eq('nil')
29
+ expect(matcher.(Fear.none)).to eq("nil")
28
30
  expect do
29
- matcher.call(Fear.some(3))
31
+ matcher.(Fear.some(3))
30
32
  end.to raise_error(Fear::MatchError)
31
33
  end
32
34
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Fear::Option do
4
+ describe "pattern matching" do
5
+ subject do
6
+ case value
7
+ in Fear::Some(Integer => int)
8
+ "some of #{int}"
9
+ in Fear::None
10
+ "none"
11
+ else
12
+ "something else"
13
+ end
14
+ end
15
+
16
+ context "when value is some of integer" do
17
+ let(:value) { Fear.some(42) }
18
+
19
+ it { is_expected.to eq("some of 42") }
20
+ end
21
+
22
+ context "when value is none" do
23
+ let(:value) { Fear.none }
24
+
25
+ it { is_expected.to eq("none") }
26
+ end
27
+
28
+ context "when value is not some of integer" do
29
+ let(:value) { Fear.some("42") }
30
+
31
+ it { is_expected.to eq("something else") }
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Fear::Option do
4
+ describe "#zip" do
5
+ subject(:zip) { left.zip(right) }
6
+
7
+ context "some with some" do
8
+ let(:left) { Fear.some(42) }
9
+ let(:right) { Fear.some(664) }
10
+
11
+ context "without a block" do
12
+ subject { left.zip(right) }
13
+
14
+ it { is_expected.to eq(Fear.some([42, 664])) }
15
+ end
16
+
17
+ context "with a block" do
18
+ subject { left.zip(right) { |x, y| x * y } }
19
+
20
+ it { is_expected.to eq(Fear.some(27_888)) }
21
+ end
22
+ end
23
+
24
+ context "some with none" do
25
+ let(:left) { Fear.some(42) }
26
+ let(:right) { Fear.none }
27
+
28
+ it { is_expected.to eq(Fear.none) }
29
+ end
30
+
31
+ context "some with non-option" do
32
+ let(:left) { Fear.some(42) }
33
+ let(:right) { 42 }
34
+
35
+ it { expect { zip }.to raise_error(TypeError) }
36
+ end
37
+
38
+ context "none with some" do
39
+ let(:left) { Fear.none }
40
+ let(:right) { Fear.some(42) }
41
+
42
+ it { is_expected.to eq(Fear.none) }
43
+ end
44
+
45
+ context "none with none" do
46
+ let(:left) { Fear.none }
47
+ let(:right) { Fear.none }
48
+
49
+ it { is_expected.to eq(Fear.none) }
50
+ end
51
+
52
+ context "none with non-option" do
53
+ let(:left) { Fear.none }
54
+ let(:right) { 42 }
55
+
56
+ it { expect { zip }.to raise_error(TypeError) }
57
+ end
58
+ end
59
+
60
+ describe "#filter_map" do
61
+ subject { option.filter_map(&filter_map) }
62
+
63
+ context "some mapped to nil" do
64
+ let(:option) { Fear.some(42) }
65
+ let(:filter_map) { ->(*) { nil } }
66
+
67
+ it { is_expected.to be_none }
68
+ end
69
+
70
+ context "some mapped to false" do
71
+ let(:option) { Fear.some(42) }
72
+ let(:filter_map) { ->(*) { false } }
73
+
74
+ it { is_expected.to be_none }
75
+ end
76
+
77
+ context "some mapped to true" do
78
+ let(:option) { Fear.some(42) }
79
+ let(:filter_map) { ->(*) { true } }
80
+
81
+ it { is_expected.to be_some_of(true) }
82
+ end
83
+
84
+ context "some mapped to another value" do
85
+ let(:option) { Fear.some(42) }
86
+ let(:filter_map) { ->(x) { x / 2 if x.even? } }
87
+
88
+ it { is_expected.to be_some_of(21) }
89
+ end
90
+
91
+ context "none" do
92
+ let(:option) { Fear.none }
93
+ let(:filter_map) { ->(x) { x / 2 } }
94
+
95
+ it { is_expected.to be_none }
96
+ end
97
+ end
98
+
99
+ describe "#matcher" do
100
+ subject(:result) { matcher.(value) }
101
+
102
+ let(:matcher) do
103
+ described_class.matcher do |m|
104
+ m.some { |x| "some of #{x}" }
105
+ m.none { "none" }
106
+ end
107
+ end
108
+
109
+ context "when matches some branch" do
110
+ let(:value) { Fear.some(42) }
111
+
112
+ it { is_expected.to eq("some of 42") }
113
+ end
114
+
115
+ context "when matches none branch" do
116
+ let(:value) { Fear.none }
117
+
118
+ it { is_expected.to eq("none") }
119
+ end
120
+ end
121
+
122
+ describe "#match" do
123
+ subject(:matcher) do
124
+ described_class.match(value) do |m|
125
+ m.some { |x| "some of #{x}" }
126
+ m.none { "none" }
127
+ end
128
+ end
129
+
130
+ context "when matches some branch" do
131
+ let(:value) { Fear.some(42) }
132
+
133
+ it { is_expected.to eq("some of 42") }
134
+ end
135
+
136
+ context "when matches none branch" do
137
+ let(:value) { Fear.none }
138
+
139
+ it { is_expected.to eq("none") }
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Fear::PartialFunction::Any do
4
+ subject(:any) { described_class }
5
+
6
+ describe ".===" do
7
+ it { expect(any === 42).to eq(true) }
8
+ it { expect(any === "foo").to eq(true) }
9
+ it { expect(any === Object.new).to eq(true) }
10
+ end
11
+
12
+ describe ".==" do
13
+ it { expect(any == 42).to eq(true) }
14
+ it { expect(any == "foo").to eq(true) }
15
+ it { expect(any == Object.new).to eq(true) }
16
+ end
17
+
18
+ describe ".to_proc" do
19
+ subject(:any_proc) { any.to_proc }
20
+
21
+ it { expect(any_proc.(42)).to eq(true) }
22
+ it { expect(any_proc.("foo")).to eq(true) }
23
+ it { expect(any_proc.(Object.new)).to eq(true) }
24
+ end
25
+ end
@@ -1,33 +1,35 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe Fear::PartialFunction::EMPTY do
2
- describe '#defined?' do
4
+ describe "#defined?" do
3
5
  subject { described_class.defined_at?(42) }
4
6
 
5
7
  it { is_expected.to be(false) }
6
8
  end
7
9
 
8
- describe '#call' do
9
- subject { -> { described_class.call(42) } }
10
+ describe "#call" do
11
+ subject { -> { described_class.(42) } }
10
12
 
11
- it { is_expected.to raise_error(Fear::MatchError, 'partial function not defined at: 42') }
13
+ it { is_expected.to raise_error(Fear::MatchError, "partial function not defined at: 42") }
12
14
  end
13
15
 
14
- describe '#call_or_else' do
16
+ describe "#call_or_else" do
15
17
  subject { described_class.call_or_else(42, &default) }
16
18
  let(:default) { ->(x) { "default: #{x}" } }
17
19
 
18
- it { is_expected.to eq('default: 42') }
20
+ it { is_expected.to eq("default: 42") }
19
21
  end
20
22
 
21
- describe '#and_then' do
22
- subject { described_class.and_then { |_x| 'then' } }
23
+ describe "#and_then" do
24
+ subject { described_class.and_then { |_x| "then" } }
23
25
 
24
26
  it { is_expected.to eq(described_class) }
25
27
  end
26
28
 
27
- describe '#or_else' do
29
+ describe "#or_else" do
28
30
  subject { described_class.or_else(other) }
29
31
 
30
- let(:other) { Fear.case(proc { true }) { 'other' } }
32
+ let(:other) { Fear.case(proc { true }) { "other" } }
31
33
 
32
34
  it { is_expected.to eq(other) }
33
35
  end
@@ -1,60 +1,62 @@
1
- RSpec.describe Fear::PartialFunction, '#and_then' do
2
- context 'proc' do
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Fear::PartialFunction, "#and_then" do
4
+ context "proc" do
3
5
  subject(:pf_and_f) { partial_function.and_then(&function) }
4
6
 
5
7
  let(:partial_function) { Fear.case(->(x) { x.even? }) { |x| "pf: #{x}" } }
6
8
  let(:function) { ->(x) { "f: #{x}" } }
7
9
 
8
- describe '#defined_at?' do
9
- context 'defined' do
10
+ describe "#defined_at?" do
11
+ context "defined" do
10
12
  subject { pf_and_f.defined_at?(4) }
11
13
 
12
14
  it { is_expected.to eq(true) }
13
15
  end
14
16
 
15
- context 'not defined' do
17
+ context "not defined" do
16
18
  subject { pf_and_f.defined_at?(3) }
17
19
 
18
20
  it { is_expected.to eq(false) }
19
21
  end
20
22
  end
21
23
 
22
- describe '#call' do
23
- context 'defined' do
24
- subject { pf_and_f.call(4) }
24
+ describe "#call" do
25
+ context "defined" do
26
+ subject { pf_and_f.(4) }
25
27
 
26
- it { is_expected.to eq('f: pf: 4') }
28
+ it { is_expected.to eq("f: pf: 4") }
27
29
  end
28
30
 
29
- context 'not defined' do
30
- subject { -> { pf_and_f.call(3) } }
31
+ context "not defined" do
32
+ subject { -> { pf_and_f.(3) } }
31
33
 
32
- it { is_expected.to raise_error(Fear::MatchError, 'partial function not defined at: 3') }
34
+ it { is_expected.to raise_error(Fear::MatchError, "partial function not defined at: 3") }
33
35
  end
34
36
  end
35
37
 
36
- describe '#call_or_else' do
38
+ describe "#call_or_else" do
37
39
  let(:fallback) { ->(x) { "fallback: #{x}" } }
38
40
 
39
- context 'defined' do
41
+ context "defined" do
40
42
  subject { pf_and_f.call_or_else(4, &fallback) }
41
43
 
42
- it { is_expected.to eq('f: pf: 4') }
44
+ it { is_expected.to eq("f: pf: 4") }
43
45
  end
44
46
 
45
- context 'not defined' do
47
+ context "not defined" do
46
48
  subject { pf_and_f.call_or_else(3, &fallback) }
47
49
 
48
- it { is_expected.to eq('fallback: 3') }
50
+ it { is_expected.to eq("fallback: 3") }
49
51
  end
50
52
  end
51
53
  end
52
54
 
53
- context 'partial function' do
55
+ context "partial function" do
54
56
  subject(:first_and_then_second) { first.and_then(second) }
55
57
 
56
- describe '#defined_at?' do
57
- context 'first defined, second defined on result of first' do
58
+ describe "#defined_at?" do
59
+ context "first defined, second defined on result of first" do
58
60
  subject { first_and_then_second.defined_at?(6) }
59
61
 
60
62
  let(:first) { Fear.case(->(x) { x.even? }) { |x| x / 2 } }
@@ -63,7 +65,7 @@ RSpec.describe Fear::PartialFunction, '#and_then' do
63
65
  it { is_expected.to eq(true) }
64
66
  end
65
67
 
66
- context 'first defined, second not defined on result of first' do
68
+ context "first defined, second not defined on result of first" do
67
69
  subject { first_and_then_second.defined_at?(4) }
68
70
 
69
71
  let(:first) { Fear.case(->(x) { x.even? }) { |x| x / 2 } }
@@ -72,7 +74,7 @@ RSpec.describe Fear::PartialFunction, '#and_then' do
72
74
  it { is_expected.to eq(false) }
73
75
  end
74
76
 
75
- context 'first not defined' do
77
+ context "first not defined" do
76
78
  subject { first_and_then_second.defined_at?(3) }
77
79
 
78
80
  let(:first) { Fear.case(->(x) { x.even? }) { |x| "first: #{x}" } }
@@ -82,9 +84,9 @@ RSpec.describe Fear::PartialFunction, '#and_then' do
82
84
  end
83
85
  end
84
86
 
85
- describe '#call' do
86
- context 'first defined, second defined on result of first' do
87
- subject { first_and_then_second.call(6) }
87
+ describe "#call" do
88
+ context "first defined, second defined on result of first" do
89
+ subject { first_and_then_second.(6) }
88
90
 
89
91
  let(:first) { Fear.case(->(x) { x.even? }) { |x| x / 2 } }
90
92
  let(:second) { Fear.case(->(x) { x % 3 == 0 }) { |x| x / 3 } }
@@ -92,29 +94,29 @@ RSpec.describe Fear::PartialFunction, '#and_then' do
92
94
  it { is_expected.to eq(1) }
93
95
  end
94
96
 
95
- context 'first defined, second not defined on result of first' do
96
- subject { -> { first_and_then_second.call(4) } }
97
+ context "first defined, second not defined on result of first" do
98
+ subject { -> { first_and_then_second.(4) } }
97
99
 
98
100
  let(:first) { Fear.case(->(x) { x.even? }) { |x| x / 2 } }
99
101
  let(:second) { Fear.case(->(x) { x % 3 == 0 }) { |x| x / 3 } }
100
102
 
101
- it { is_expected.to raise_error(Fear::MatchError, 'partial function not defined at: 2') }
103
+ it { is_expected.to raise_error(Fear::MatchError, "partial function not defined at: 2") }
102
104
  end
103
105
 
104
- context 'first not defined' do
105
- subject { -> { first_and_then_second.call(3) } }
106
+ context "first not defined" do
107
+ subject { -> { first_and_then_second.(3) } }
106
108
 
107
109
  let(:first) { Fear.case(->(x) { x.even? }) { |x| "first: #{x}" } }
108
110
  let(:second) { Fear.case(->(x) { x % 3 == 0 }) { |x| "second: #{x}" } }
109
111
 
110
- it { is_expected.to raise_error(Fear::MatchError, 'partial function not defined at: 3') }
112
+ it { is_expected.to raise_error(Fear::MatchError, "partial function not defined at: 3") }
111
113
  end
112
114
  end
113
115
 
114
- describe '#call_or_else' do
116
+ describe "#call_or_else" do
115
117
  let(:fallback) { ->(x) { "fallback: #{x}" } }
116
118
 
117
- context 'first defined, second defined on result of first' do
119
+ context "first defined, second defined on result of first" do
118
120
  subject { first_and_then_second.call_or_else(6, &fallback) }
119
121
 
120
122
  let(:first) { Fear.case(->(x) { x.even? }) { |x| x / 2 } }
@@ -123,22 +125,22 @@ RSpec.describe Fear::PartialFunction, '#and_then' do
123
125
  it { is_expected.to eq(1) }
124
126
  end
125
127
 
126
- context 'first defined, second not defined on result of first' do
128
+ context "first defined, second not defined on result of first" do
127
129
  subject { first_and_then_second.call_or_else(4, &fallback) }
128
130
 
129
131
  let(:first) { Fear.case(->(x) { x.even? }) { |x| x / 2 } }
130
132
  let(:second) { Fear.case(->(x) { x % 3 == 0 }) { |x| x / 3 } }
131
133
 
132
- it { is_expected.to eq('fallback: 4') }
134
+ it { is_expected.to eq("fallback: 4") }
133
135
  end
134
136
 
135
- context 'first not defined' do
137
+ context "first not defined" do
136
138
  subject { first_and_then_second.call_or_else(3, &fallback) }
137
139
 
138
140
  let(:first) { Fear.case(->(x) { x.even? }) { |x| "first: #{x}" } }
139
141
  let(:second) { Fear.case { |x| "second: #{x}" } }
140
142
 
141
- it { is_expected.to eq('fallback: 3') }
143
+ it { is_expected.to eq("fallback: 3") }
142
144
  end
143
145
  end
144
146
  end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file contains tests from
2
4
  # https://github.com/scala/scala/blob/2.13.x/test/junit/scala/PartialFunctionCompositionTest.scala
3
5
  RSpec.describe Fear::PartialFunction do
4
- let(:fallback_fun) { ->(_) { 'fallback' } }
6
+ let(:fallback_fun) { ->(_) { "fallback" } }
5
7
  let(:pass_all) { Fear.case(proc { true }) { |x| x } }
6
8
  let(:pass_short) { Fear.case(->(x) { x.length < 5 }) { |x| x } }
7
- let(:pass_pass) { Fear.case(->(x) { x.include?('pass') }) { |x| x } }
9
+ let(:pass_pass) { Fear.case(->(x) { x.include?("pass") }) { |x| x } }
8
10
 
9
11
  let(:all_and_then_short) { pass_all & pass_short }
10
12
  let(:short_and_then_all) { pass_short & pass_all }
@@ -13,68 +15,68 @@ RSpec.describe Fear::PartialFunction do
13
15
  let(:pass_and_then_short) { pass_pass & pass_short }
14
16
  let(:short_and_then_pass) { pass_short & pass_pass }
15
17
 
16
- it '#and_then' do
17
- expect(all_and_then_short.call_or_else('pass', &fallback_fun)).to eq('pass')
18
- expect(short_and_then_all.call_or_else('pass', &fallback_fun)).to eq('pass')
19
- expect(all_and_then_short.defined_at?('pass')).to eq(true)
20
- expect(short_and_then_all.defined_at?('pass')).to eq(true)
18
+ it "#and_then" do
19
+ expect(all_and_then_short.call_or_else("pass", &fallback_fun)).to eq("pass")
20
+ expect(short_and_then_all.call_or_else("pass", &fallback_fun)).to eq("pass")
21
+ expect(all_and_then_short.defined_at?("pass")).to eq(true)
22
+ expect(short_and_then_all.defined_at?("pass")).to eq(true)
21
23
 
22
- expect(all_and_then_pass.call_or_else('pass', &fallback_fun)).to eq('pass')
23
- expect(pass_and_then_all.call_or_else('pass', &fallback_fun)).to eq('pass')
24
- expect(all_and_then_pass.defined_at?('pass')).to eq(true)
25
- expect(pass_and_then_all.defined_at?('pass')).to eq(true)
24
+ expect(all_and_then_pass.call_or_else("pass", &fallback_fun)).to eq("pass")
25
+ expect(pass_and_then_all.call_or_else("pass", &fallback_fun)).to eq("pass")
26
+ expect(all_and_then_pass.defined_at?("pass")).to eq(true)
27
+ expect(pass_and_then_all.defined_at?("pass")).to eq(true)
26
28
 
27
- expect(all_and_then_pass.call_or_else('longpass', &fallback_fun)).to eq('longpass')
28
- expect(pass_and_then_all.call_or_else('longpass', &fallback_fun)).to eq('longpass')
29
- expect(all_and_then_pass.defined_at?('longpass')).to eq(true)
30
- expect(pass_and_then_all.defined_at?('longpass')).to eq(true)
29
+ expect(all_and_then_pass.call_or_else("longpass", &fallback_fun)).to eq("longpass")
30
+ expect(pass_and_then_all.call_or_else("longpass", &fallback_fun)).to eq("longpass")
31
+ expect(all_and_then_pass.defined_at?("longpass")).to eq(true)
32
+ expect(pass_and_then_all.defined_at?("longpass")).to eq(true)
31
33
 
32
- expect(all_and_then_short.call_or_else('longpass', &fallback_fun)).to eq('fallback')
33
- expect(short_and_then_all.call_or_else('longpass', &fallback_fun)).to eq('fallback')
34
- expect(all_and_then_short.defined_at?('longpass')).to eq(false)
35
- expect(short_and_then_all.defined_at?('longpass')).to eq(false)
34
+ expect(all_and_then_short.call_or_else("longpass", &fallback_fun)).to eq("fallback")
35
+ expect(short_and_then_all.call_or_else("longpass", &fallback_fun)).to eq("fallback")
36
+ expect(all_and_then_short.defined_at?("longpass")).to eq(false)
37
+ expect(short_and_then_all.defined_at?("longpass")).to eq(false)
36
38
 
37
- expect(all_and_then_pass.call_or_else('longstr', &fallback_fun)).to eq('fallback')
38
- expect(pass_and_then_all.call_or_else('longstr', &fallback_fun)).to eq('fallback')
39
- expect(all_and_then_pass.defined_at?('longstr')).to eq(false)
40
- expect(pass_and_then_all.defined_at?('longstr')).to eq(false)
39
+ expect(all_and_then_pass.call_or_else("longstr", &fallback_fun)).to eq("fallback")
40
+ expect(pass_and_then_all.call_or_else("longstr", &fallback_fun)).to eq("fallback")
41
+ expect(all_and_then_pass.defined_at?("longstr")).to eq(false)
42
+ expect(pass_and_then_all.defined_at?("longstr")).to eq(false)
41
43
 
42
- expect(pass_and_then_short.call_or_else('pass', &fallback_fun)).to eq('pass')
43
- expect(short_and_then_pass.call_or_else('pass', &fallback_fun)).to eq('pass')
44
- expect(pass_and_then_short.defined_at?('pass')).to eq(true)
45
- expect(short_and_then_pass.defined_at?('pass')).to eq(true)
44
+ expect(pass_and_then_short.call_or_else("pass", &fallback_fun)).to eq("pass")
45
+ expect(short_and_then_pass.call_or_else("pass", &fallback_fun)).to eq("pass")
46
+ expect(pass_and_then_short.defined_at?("pass")).to eq(true)
47
+ expect(short_and_then_pass.defined_at?("pass")).to eq(true)
46
48
 
47
- expect(pass_and_then_short.call_or_else('longpass', &fallback_fun)).to eq('fallback')
48
- expect(short_and_then_pass.call_or_else('longpass', &fallback_fun)).to eq('fallback')
49
- expect(pass_and_then_short.defined_at?('longpass')).to eq(false)
50
- expect(short_and_then_pass.defined_at?('longpass')).to eq(false)
49
+ expect(pass_and_then_short.call_or_else("longpass", &fallback_fun)).to eq("fallback")
50
+ expect(short_and_then_pass.call_or_else("longpass", &fallback_fun)).to eq("fallback")
51
+ expect(pass_and_then_short.defined_at?("longpass")).to eq(false)
52
+ expect(short_and_then_pass.defined_at?("longpass")).to eq(false)
51
53
 
52
- expect(short_and_then_pass.call_or_else('longstr', &fallback_fun)).to eq('fallback')
53
- expect(pass_and_then_short.call_or_else('longstr', &fallback_fun)).to eq('fallback')
54
- expect(short_and_then_pass.defined_at?('longstr')).to eq(false)
55
- expect(pass_and_then_short.defined_at?('longstr')).to eq(false)
54
+ expect(short_and_then_pass.call_or_else("longstr", &fallback_fun)).to eq("fallback")
55
+ expect(pass_and_then_short.call_or_else("longstr", &fallback_fun)).to eq("fallback")
56
+ expect(short_and_then_pass.defined_at?("longstr")).to eq(false)
57
+ expect(pass_and_then_short.defined_at?("longstr")).to eq(false)
56
58
  end
57
59
 
58
- it 'two branches' do
59
- first_branch = Fear.case(Integer, &:itself).and_then(Fear.case(1) { 'one' })
60
+ it "two branches" do
61
+ first_branch = Fear.case(Integer, &:itself).and_then(Fear.case(1) { "one" })
60
62
  second_branch = Fear.case(String, &:itself).and_then(
61
- (Fear.case('zero') { 0 }).or_else(Fear.case('one') { 1 }),
63
+ (Fear.case("zero") { 0 }).or_else(Fear.case("one") { 1 }),
62
64
  )
63
65
 
64
66
  full = first_branch.or_else(second_branch)
65
- expect(full.call(1)).to eq('one')
66
- expect(full.call('zero')).to eq(0)
67
- expect(full.call('one')).to eq(1)
67
+ expect(full.(1)).to eq("one")
68
+ expect(full.("zero")).to eq(0)
69
+ expect(full.("one")).to eq(1)
68
70
  end
69
71
 
70
- it 'or else anh then' do
72
+ it "or else anh then" do
71
73
  f1 = Fear.case(->(x) { x < 5 }) { 1 }
72
74
  f2 = Fear.case(->(x) { x > 10 }) { 10 }
73
75
  f3 = Fear.case { |x| x * 2 }
74
76
 
75
77
  f5 = f1.and_then(f3).or_else(f2)
76
78
 
77
- expect(f5.call(11)).to eq(10)
78
- expect(f5.call(3)).to eq(2)
79
+ expect(f5.(11)).to eq(10)
80
+ expect(f5.(3)).to eq(2)
79
81
  end
80
82
  end