fear 1.0.0 → 1.1.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 (119) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -60
  3. data/.travis.yml +8 -4
  4. data/CHANGELOG.md +7 -1
  5. data/Gemfile +5 -3
  6. data/Gemfile.lock +18 -20
  7. data/README.md +28 -14
  8. data/Rakefile +61 -60
  9. data/examples/pattern_extracting.rb +8 -6
  10. data/examples/pattern_matching_binary_tree_set.rb +4 -2
  11. data/examples/pattern_matching_number_in_words.rb +46 -42
  12. data/fear.gemspec +29 -27
  13. data/lib/fear.rb +44 -37
  14. data/lib/fear/await.rb +33 -0
  15. data/lib/fear/awaitable.rb +28 -0
  16. data/lib/fear/either.rb +2 -0
  17. data/lib/fear/either_api.rb +2 -0
  18. data/lib/fear/either_pattern_match.rb +2 -0
  19. data/lib/fear/empty_partial_function.rb +3 -1
  20. data/lib/fear/extractor.rb +30 -28
  21. data/lib/fear/extractor/anonymous_array_splat_matcher.rb +2 -0
  22. data/lib/fear/extractor/any_matcher.rb +2 -0
  23. data/lib/fear/extractor/array_head_matcher.rb +2 -0
  24. data/lib/fear/extractor/array_matcher.rb +2 -0
  25. data/lib/fear/extractor/array_splat_matcher.rb +2 -0
  26. data/lib/fear/extractor/empty_list_matcher.rb +2 -0
  27. data/lib/fear/extractor/extractor_matcher.rb +5 -3
  28. data/lib/fear/extractor/grammar.rb +5 -3
  29. data/lib/fear/extractor/identifier_matcher.rb +2 -0
  30. data/lib/fear/extractor/matcher.rb +5 -3
  31. data/lib/fear/extractor/matcher/and.rb +3 -1
  32. data/lib/fear/extractor/named_array_splat_matcher.rb +2 -0
  33. data/lib/fear/extractor/pattern.rb +7 -5
  34. data/lib/fear/extractor/typed_identifier_matcher.rb +2 -0
  35. data/lib/fear/extractor/value_matcher.rb +2 -0
  36. data/lib/fear/extractor_api.rb +2 -0
  37. data/lib/fear/failure.rb +2 -0
  38. data/lib/fear/failure_pattern_match.rb +2 -0
  39. data/lib/fear/for.rb +4 -2
  40. data/lib/fear/for_api.rb +3 -1
  41. data/lib/fear/future.rb +141 -64
  42. data/lib/fear/future_api.rb +2 -0
  43. data/lib/fear/left.rb +3 -1
  44. data/lib/fear/left_pattern_match.rb +2 -0
  45. data/lib/fear/none.rb +4 -2
  46. data/lib/fear/none_pattern_match.rb +2 -0
  47. data/lib/fear/option.rb +3 -1
  48. data/lib/fear/option_api.rb +2 -0
  49. data/lib/fear/option_pattern_match.rb +2 -0
  50. data/lib/fear/partial_function.rb +10 -8
  51. data/lib/fear/partial_function/and_then.rb +4 -2
  52. data/lib/fear/partial_function/any.rb +2 -0
  53. data/lib/fear/partial_function/combined.rb +3 -1
  54. data/lib/fear/partial_function/empty.rb +2 -0
  55. data/lib/fear/partial_function/guard.rb +7 -5
  56. data/lib/fear/partial_function/guard/and.rb +2 -0
  57. data/lib/fear/partial_function/guard/and3.rb +2 -0
  58. data/lib/fear/partial_function/guard/or.rb +2 -0
  59. data/lib/fear/partial_function/lifted.rb +2 -0
  60. data/lib/fear/partial_function/or_else.rb +3 -1
  61. data/lib/fear/partial_function_class.rb +3 -1
  62. data/lib/fear/pattern_match.rb +3 -1
  63. data/lib/fear/pattern_matching_api.rb +3 -1
  64. data/lib/fear/promise.rb +11 -3
  65. data/lib/fear/right.rb +3 -1
  66. data/lib/fear/right_biased.rb +4 -2
  67. data/lib/fear/right_pattern_match.rb +2 -0
  68. data/lib/fear/some.rb +2 -0
  69. data/lib/fear/some_pattern_match.rb +2 -0
  70. data/lib/fear/struct.rb +235 -0
  71. data/lib/fear/success.rb +2 -0
  72. data/lib/fear/success_pattern_match.rb +2 -0
  73. data/lib/fear/try.rb +2 -0
  74. data/lib/fear/try_api.rb +2 -0
  75. data/lib/fear/try_pattern_match.rb +2 -0
  76. data/lib/fear/unit.rb +6 -2
  77. data/lib/fear/utils.rb +4 -2
  78. data/lib/fear/version.rb +4 -1
  79. data/spec/fear/done_spec.rb +7 -5
  80. data/spec/fear/either/mixin_spec.rb +4 -2
  81. data/spec/fear/either_pattern_match_spec.rb +10 -8
  82. data/spec/fear/extractor/array_matcher_spec.rb +65 -63
  83. data/spec/fear/extractor/extractor_matcher_spec.rb +64 -62
  84. data/spec/fear/extractor/grammar_array_spec.rb +5 -3
  85. data/spec/fear/extractor/identified_matcher_spec.rb +18 -16
  86. data/spec/fear/extractor/identifier_matcher_spec.rb +26 -24
  87. data/spec/fear/extractor/pattern_spec.rb +17 -15
  88. data/spec/fear/extractor/typed_identifier_matcher_spec.rb +23 -21
  89. data/spec/fear/extractor/value_matcher_number_spec.rb +29 -27
  90. data/spec/fear/extractor/value_matcher_string_spec.rb +27 -25
  91. data/spec/fear/extractor/value_matcher_symbol_spec.rb +24 -22
  92. data/spec/fear/extractor_api_spec.rb +70 -68
  93. data/spec/fear/extractor_spec.rb +23 -21
  94. data/spec/fear/failure_spec.rb +59 -57
  95. data/spec/fear/for_spec.rb +19 -17
  96. data/spec/fear/future_spec.rb +456 -240
  97. data/spec/fear/guard_spec.rb +26 -24
  98. data/spec/fear/left_spec.rb +60 -58
  99. data/spec/fear/none_spec.rb +36 -34
  100. data/spec/fear/option/mixin_spec.rb +9 -7
  101. data/spec/fear/option_pattern_match_spec.rb +10 -8
  102. data/spec/fear/partial_function/empty_spec.rb +12 -10
  103. data/spec/fear/partial_function_and_then_spec.rb +39 -37
  104. data/spec/fear/partial_function_composition_spec.rb +46 -44
  105. data/spec/fear/partial_function_or_else_spec.rb +92 -90
  106. data/spec/fear/partial_function_spec.rb +46 -44
  107. data/spec/fear/pattern_match_spec.rb +31 -29
  108. data/spec/fear/promise_spec.rb +19 -17
  109. data/spec/fear/right_biased/left.rb +28 -26
  110. data/spec/fear/right_biased/right.rb +51 -49
  111. data/spec/fear/right_spec.rb +58 -56
  112. data/spec/fear/some_spec.rb +30 -28
  113. data/spec/fear/success_spec.rb +50 -48
  114. data/spec/fear/try/mixin_spec.rb +5 -3
  115. data/spec/fear/try_pattern_match_spec.rb +10 -8
  116. data/spec/fear/utils_spec.rb +16 -14
  117. data/spec/spec_helper.rb +7 -5
  118. data/spec/struct_spec.rb +226 -0
  119. metadata +18 -13
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # require 'codeclimate-test-reporter'
2
4
  # CodeClimate::TestReporter.start
3
5
 
4
- require 'fear'
5
- require File.expand_path('spec/fear/right_biased/right')
6
- require File.expand_path('spec/fear/right_biased/left')
7
- require 'date'
6
+ require "fear"
7
+ require File.expand_path("spec/fear/right_biased/right")
8
+ require File.expand_path("spec/fear/right_biased/left")
9
+ require "date"
8
10
 
9
11
  RSpec.configure do |config|
10
12
  # rspec-expectations config goes here. You can use an alternate
@@ -56,7 +58,7 @@ RSpec.configure do |config|
56
58
  # Use the documentation formatter for detailed output,
57
59
  # unless a formatter has already been configured
58
60
  # (e.g. via a command-line flag).
59
- config.default_formatter = 'doc'
61
+ config.default_formatter = "doc"
60
62
  end
61
63
 
62
64
  # Print the 10 slowest examples and example groups at the
@@ -0,0 +1,226 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Fear::Struct do
4
+ describe ".with_attributes" do
5
+ context "same arguments" do
6
+ subject { struct_class.new(a: 42, b: 43) }
7
+
8
+ let(:struct_class) { described_class.with_attributes(:a, :b) }
9
+
10
+ it { is_expected.to have_attributes(a: 42, b: 43) }
11
+ end
12
+
13
+ context "string arguments" do
14
+ subject { -> { struct_class.new("a" => 42, "b" => 43) } }
15
+
16
+ let(:struct_class) { described_class.with_attributes(:a, :b) }
17
+
18
+ it { is_expected.to raise_error(ArgumentError, "wrong number of arguments (given 1, expected 0)") }
19
+ end
20
+
21
+ context "extra argument" do
22
+ subject { -> { struct_class.new(a: 42, b: 41, c: 43, d: 44) } }
23
+
24
+ let(:struct_class) { described_class.with_attributes(:a, :b) }
25
+
26
+ it { is_expected.to raise_error(ArgumentError, "unknown keywords: c, d") }
27
+ end
28
+
29
+ context "missing argument" do
30
+ subject { -> { struct_class.new } }
31
+
32
+ let(:struct_class) { described_class.with_attributes(:a, :b) }
33
+
34
+ it { is_expected.to raise_error(ArgumentError, "missing keywords: a, b") }
35
+ end
36
+
37
+ context "inheritance" do
38
+ let(:parent_struct) { described_class.with_attributes(:a, :b) }
39
+
40
+ it "does not change parent attributes" do
41
+ expect do
42
+ parent_struct.with_attributes(:c)
43
+ end.not_to change { parent_struct.attributes }.from([:a, :b])
44
+ end
45
+
46
+ it "extends parent attributes" do
47
+ child_struct = parent_struct.with_attributes(:c)
48
+ expect(child_struct.attributes).to eq([:a, :b, :c])
49
+ end
50
+ end
51
+
52
+ context "with block" do
53
+ subject { struct_class.new(a: 42, b: 43).a_plus_b }
54
+
55
+ let(:struct_class) do
56
+ described_class.with_attributes(:a, :b) do
57
+ def a_plus_b
58
+ a + b
59
+ end
60
+ end
61
+ end
62
+
63
+ it "evaluates block in context of struct" do
64
+ is_expected.to eq(85)
65
+ end
66
+ end
67
+ end
68
+
69
+ describe "#==" do
70
+ context "with members" do
71
+ let(:struct_class) { described_class.with_attributes(:a, :b) }
72
+
73
+ context "same class and members" do
74
+ subject { struct_class.new(a: 42, b: 43) == struct_class.new(a: 42, b: 43) } # rubocop: disable Lint/UselessComparison:
75
+
76
+ it { is_expected.to eq(true) }
77
+ end
78
+
79
+ context "same class and different members" do
80
+ subject { struct_class.new(a: 42, b: 43) == struct_class.new(a: 42, b: 0) }
81
+
82
+ it { is_expected.to eq(false) }
83
+ end
84
+
85
+ context "different class and same members" do
86
+ subject { struct_class.new(a: 42, b: 43) == struct_class_1.new(a: 42, b: 43) }
87
+
88
+ let(:struct_class_1) { described_class.with_attributes(:a, :b) }
89
+
90
+ it { is_expected.to eq(true) }
91
+ end
92
+
93
+ context "different class and different members" do
94
+ subject { struct_class.new(a: 42, b: 43) == struct_class.new(a: 42, b: 0) }
95
+
96
+ let(:struct_class_1) { described_class.with_attributes(:a, :b) }
97
+
98
+ it { is_expected.to eq(false) }
99
+ end
100
+ end
101
+ end
102
+
103
+ describe "#members" do
104
+ let(:struct) { struct_class.new(b: 43, a: 42) }
105
+ let(:struct_class) { described_class.with_attributes(:a, :b) }
106
+
107
+ it "returns members in the order they defined" do
108
+ expect(struct.members).to eq([:a, :b])
109
+ end
110
+
111
+ it "is immutable" do
112
+ expect { struct.members << :c }.not_to change { struct.members }.from([:a, :b])
113
+ end
114
+ end
115
+
116
+ describe "#to_a" do
117
+ let(:struct) { struct_class.new(b: 43, a: 42) }
118
+ let(:struct_class) { described_class.with_attributes(:a, :b) }
119
+
120
+ it "returns members values in the order they defined" do
121
+ expect(struct.to_a).to eq([42, 43])
122
+ end
123
+
124
+ it "is immutable" do
125
+ expect { struct.to_a << 44 }.not_to change { struct.to_a }.from([42, 43])
126
+ end
127
+ end
128
+
129
+ describe "#to_h" do
130
+ let(:struct_class) { described_class.with_attributes(:a, :b) }
131
+
132
+ context "without block" do
133
+ let(:struct) { struct_class.new(b: 43, a: 42) }
134
+
135
+ it "returns a Hash containing the names and values for the structs members" do
136
+ expect(struct.to_h).to eq(a: 42, b: 43)
137
+ end
138
+
139
+ it "is immutable" do
140
+ expect { struct.to_h.merge(c: 44) }.not_to change { struct.to_h }.from(a: 42, b: 43)
141
+ end
142
+ end
143
+
144
+ context "with block" do
145
+ subject do
146
+ struct.to_h do |key, value|
147
+ [key.upcase, value / 2]
148
+ end
149
+ end
150
+ let(:struct) { struct_class.new(b: 2, a: 4) }
151
+
152
+ it "returns a Hash containing the names and values for the structs members" do
153
+ is_expected.to eq(A: 2, B: 1)
154
+ end
155
+ end
156
+ end
157
+
158
+ describe "#copy" do
159
+ let(:struct_class) { described_class.with_attributes(:a, :b) }
160
+ let(:struct) { struct_class.new(b: 43, a: 42) }
161
+
162
+ context "attributes given" do
163
+ subject { struct.copy(b: 44) }
164
+
165
+ it { is_expected.to eq(struct_class.new(a: 42, b: 44)) }
166
+ end
167
+
168
+ context "string attributes" do
169
+ subject { -> { struct.copy("a" => 44) } }
170
+
171
+ it { is_expected.to raise_error(ArgumentError, "wrong number of arguments (given 1, expected 0)") }
172
+ end
173
+
174
+ context "no attributes given" do
175
+ subject { struct.copy == struct }
176
+
177
+ it { is_expected.to eq(true) }
178
+ end
179
+ end
180
+
181
+ describe "#inspect" do
182
+ subject { StrInspect.new(a: 2, b: nil).inspect }
183
+ StrInspect = Fear::Struct.with_attributes(:a, :b)
184
+
185
+ it { is_expected.to eq("<#Fear::Struct StrInspect a=2, b=nil>") }
186
+ end
187
+
188
+ describe "#inspect" do
189
+ subject { StrToS.new(a: 2, b: nil).inspect }
190
+ StrToS = Fear::Struct.with_attributes(:a, :b)
191
+
192
+ it { is_expected.to eq("<#Fear::Struct StrToS a=2, b=nil>") }
193
+ end
194
+
195
+ context "extract" do
196
+ Str = Fear::Struct.with_attributes(:a, :b)
197
+ let(:struct) { Str.new(b: 43, a: 42) }
198
+
199
+ context "Fear::Struct subclass" do
200
+ context "match by one member" do
201
+ subject do
202
+ proc do |effect|
203
+ struct.match do |m|
204
+ m.xcase("Str(a, 43)", &effect)
205
+ end
206
+ end
207
+ end
208
+
209
+ it { is_expected.to yield_with_args(a: 42) }
210
+ end
211
+
212
+ context "does not match" do
213
+ subject do
214
+ proc do |effect|
215
+ struct.match do |m|
216
+ m.xcase("Str(_, 40)", &effect)
217
+ m.else {}
218
+ end
219
+ end
220
+ end
221
+
222
+ it { is_expected.not_to yield_control }
223
+ end
224
+ end
225
+ end
226
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fear
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tema Bolshakov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-29 00:00:00.000000000 Z
11
+ date: 2019-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lru_redux
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: '10.0'
131
+ version: '12.3'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '10.0'
138
+ version: '12.3'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: rspec
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -151,33 +151,33 @@ dependencies:
151
151
  - !ruby/object:Gem::Version
152
152
  version: '3.1'
153
153
  - !ruby/object:Gem::Dependency
154
- name: rubocop
154
+ name: rubocop-rspec
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - '='
158
158
  - !ruby/object:Gem::Version
159
- version: 0.65.0
159
+ version: 1.33.0
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - '='
165
165
  - !ruby/object:Gem::Version
166
- version: 0.65.0
166
+ version: 1.33.0
167
167
  - !ruby/object:Gem::Dependency
168
- name: rubocop-rspec
168
+ name: ruby_coding_standard
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
- - - '='
171
+ - - ">="
172
172
  - !ruby/object:Gem::Version
173
- version: 1.32.0
173
+ version: '0'
174
174
  type: :development
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
- - - '='
178
+ - - ">="
179
179
  - !ruby/object:Gem::Version
180
- version: 1.32.0
180
+ version: '0'
181
181
  - !ruby/object:Gem::Dependency
182
182
  name: yard
183
183
  requirement: !ruby/object:Gem::Requirement
@@ -227,6 +227,8 @@ files:
227
227
  - examples/pattern_matching_number_in_words.rb
228
228
  - fear.gemspec
229
229
  - lib/fear.rb
230
+ - lib/fear/await.rb
231
+ - lib/fear/awaitable.rb
230
232
  - lib/fear/either.rb
231
233
  - lib/fear/either_api.rb
232
234
  - lib/fear/either_pattern_match.rb
@@ -282,6 +284,7 @@ files:
282
284
  - lib/fear/right_pattern_match.rb
283
285
  - lib/fear/some.rb
284
286
  - lib/fear/some_pattern_match.rb
287
+ - lib/fear/struct.rb
285
288
  - lib/fear/success.rb
286
289
  - lib/fear/success_pattern_match.rb
287
290
  - lib/fear/try.rb
@@ -329,6 +332,7 @@ files:
329
332
  - spec/fear/try_pattern_match_spec.rb
330
333
  - spec/fear/utils_spec.rb
331
334
  - spec/spec_helper.rb
335
+ - spec/struct_spec.rb
332
336
  homepage: https://github.com/bolshakov/fear
333
337
  licenses:
334
338
  - MIT
@@ -336,7 +340,7 @@ metadata: {}
336
340
  post_install_message: |2
337
341
  Fear v0.11.0 introduces backwards-incompatible changes.
338
342
  Please see https://github.com/bolshakov/fear/blob/master/CHANGELOG.md#0110 for details.
339
- Successfully installed fear-1.0.0
343
+ Successfully installed fear-1.1.0
340
344
  rdoc_options: []
341
345
  require_paths:
342
346
  - lib
@@ -395,3 +399,4 @@ test_files:
395
399
  - spec/fear/try_pattern_match_spec.rb
396
400
  - spec/fear/utils_spec.rb
397
401
  - spec/spec_helper.rb
402
+ - spec/struct_spec.rb