fat_core 5.6.1 → 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +54 -0
- data/.rubocop.yml +4 -6
- data/.simplecov +2 -0
- data/CHANGELOG.org +49 -0
- data/Gemfile +5 -4
- data/README.org +1016 -427
- data/Rakefile +15 -2
- data/bin/console +2 -3
- data/fat_core.gemspec +1 -0
- data/lib/fat_core/all.rb +9 -11
- data/lib/fat_core/array.rb +5 -5
- data/lib/fat_core/enumerable.rb +0 -15
- data/lib/fat_core/hash.rb +48 -11
- data/lib/fat_core/numeric.rb +48 -1
- data/lib/fat_core/range.rb +108 -55
- data/lib/fat_core/string.rb +70 -57
- data/lib/fat_core/symbol.rb +1 -1
- data/lib/fat_core/version.rb +2 -2
- data/lib/fat_core.rb +2 -2
- data/spec/lib/array_spec.rb +2 -0
- data/spec/lib/big_decimal_spec.rb +2 -0
- data/spec/lib/enumerable_spec.rb +29 -39
- data/spec/lib/hash_spec.rb +19 -2
- data/spec/lib/nil_class_spec.rb +2 -0
- data/spec/lib/numeric_spec.rb +14 -0
- data/spec/lib/range_spec.rb +101 -90
- data/spec/lib/string_spec.rb +78 -20
- data/spec/lib/symbol_spec.rb +2 -0
- data/spec/spec_helper.rb +3 -1
- metadata +9 -10
- data/bin/easter +0 -45
- data/lib/fat_core/date.rb +0 -1897
- data/lib/fat_core/kernel.rb +0 -26
- data/spec/lib/date_spec.rb +0 -1390
- data/spec/lib/kernel_spec.rb +0 -13
data/spec/lib/range_spec.rb
CHANGED
|
@@ -1,103 +1,106 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
require 'fat_core/range'
|
|
3
5
|
|
|
4
6
|
describe Range do
|
|
5
7
|
describe 'set operations' do
|
|
6
8
|
it 'knows if it is a subset of another range' do
|
|
7
|
-
expect((4..8)
|
|
8
|
-
expect((4..8)
|
|
9
|
-
expect((4..8)
|
|
10
|
-
expect((4..8)
|
|
11
|
-
expect((4..8)
|
|
9
|
+
expect((4..8).subset_of?(2..9)).to be true
|
|
10
|
+
expect((4..8).subset_of?(4..8)).to be true
|
|
11
|
+
expect((4..8).subset_of?(2..7)).to be false
|
|
12
|
+
expect((4..8).subset_of?(5..8)).to be false
|
|
13
|
+
expect((4..8).subset_of?(11..20)).to be false
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
it 'knows if it is a proper subset of another range' do
|
|
15
|
-
expect((4..8)
|
|
16
|
-
expect((4..8)
|
|
17
|
-
expect((4..8)
|
|
18
|
-
expect((4..8)
|
|
19
|
-
expect((4..8)
|
|
20
|
-
expect((4..8)
|
|
17
|
+
expect((4..8).proper_subset_of?(2..9)).to be true
|
|
18
|
+
expect((4..8).proper_subset_of?(4..9)).to be true
|
|
19
|
+
expect((4..8).proper_subset_of?(4..8)).to be false
|
|
20
|
+
expect((4..8).proper_subset_of?(2..7)).to be false
|
|
21
|
+
expect((4..8).proper_subset_of?(5..8)).to be false
|
|
22
|
+
expect((4..8).proper_subset_of?(11..20)).to be false
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
it 'knows if it is a superset of another range' do
|
|
24
|
-
expect((4..8)
|
|
25
|
-
expect((4..8)
|
|
26
|
-
expect((4..8)
|
|
27
|
-
expect((4..8)
|
|
28
|
-
expect((4..8)
|
|
29
|
-
expect((4..8)
|
|
30
|
-
expect((4..8)
|
|
31
|
-
expect((4..8)
|
|
32
|
-
expect((4..8)
|
|
33
|
-
expect((4..8)
|
|
34
|
-
expect((4..8)
|
|
26
|
+
expect((4..8).superset_of?(5..7)).to be true
|
|
27
|
+
expect((4..8).superset_of?(6..8)).to be true
|
|
28
|
+
expect((4..8).superset_of?(4..7)).to be true
|
|
29
|
+
expect((4..8).superset_of?(4..8)).to be true
|
|
30
|
+
expect((4..8).superset_of?(2..9)).to be false
|
|
31
|
+
expect((4..8).superset_of?(2..8)).to be false
|
|
32
|
+
expect((4..8).superset_of?(4..9)).to be false
|
|
33
|
+
expect((4..8).superset_of?(8..20)).to be false
|
|
34
|
+
expect((4..8).superset_of?(0..4)).to be false
|
|
35
|
+
expect((4..8).superset_of?(0..3)).to be false
|
|
36
|
+
expect((4..8).superset_of?(9..20)).to be false
|
|
35
37
|
end
|
|
36
38
|
|
|
37
39
|
it 'knows if it is a proper superset of another range' do
|
|
38
|
-
expect((4..8)
|
|
39
|
-
expect((4..8)
|
|
40
|
-
expect((4..8)
|
|
41
|
-
expect((4..8)
|
|
42
|
-
expect((4..8)
|
|
43
|
-
expect((4..8)
|
|
44
|
-
expect((4..8)
|
|
45
|
-
expect((4..8)
|
|
46
|
-
expect((4..8)
|
|
47
|
-
expect((4..8)
|
|
48
|
-
expect((4..8)
|
|
40
|
+
expect((4..8).proper_superset_of?(5..7)).to be true
|
|
41
|
+
expect((4..8).proper_superset_of?(6..8)).to be true
|
|
42
|
+
expect((4..8).proper_superset_of?(4..7)).to be true
|
|
43
|
+
expect((4..8).proper_superset_of?(4..8)).to be false
|
|
44
|
+
expect((4..8).proper_superset_of?(2..9)).to be false
|
|
45
|
+
expect((4..8).proper_superset_of?(2..8)).to be false
|
|
46
|
+
expect((4..8).proper_superset_of?(4..9)).to be false
|
|
47
|
+
expect((4..8).proper_superset_of?(8..20)).to be false
|
|
48
|
+
expect((4..8).proper_superset_of?(0..4)).to be false
|
|
49
|
+
expect((4..8).proper_superset_of?(0..3)).to be false
|
|
50
|
+
expect((4..8).proper_superset_of?(9..20)).to be false
|
|
51
|
+
expect((4..8).proper_superset_of?(4..8)).to be false
|
|
49
52
|
end
|
|
50
53
|
|
|
51
54
|
it 'knows its intersection with another range' do
|
|
52
|
-
expect((
|
|
53
|
-
expect((
|
|
54
|
-
expect((
|
|
55
|
+
expect((0..10) & (5..20)).to eq(5..10)
|
|
56
|
+
expect((0..10) & (5..20)).to eq((5..20) & (0..10))
|
|
57
|
+
expect((0..10) & (10..20)).to eq(10..10)
|
|
55
58
|
end
|
|
56
59
|
|
|
57
60
|
it 'intersection should return nil if there is no overlap' do
|
|
58
|
-
expect((
|
|
61
|
+
expect((0..10) & (15..20)).to be_nil
|
|
59
62
|
end
|
|
60
63
|
|
|
61
64
|
it 'knows its union with another range' do
|
|
62
|
-
expect((
|
|
63
|
-
expect((
|
|
64
|
-
expect((
|
|
65
|
+
expect((0..10) + (5..20)).to eq(0..20)
|
|
66
|
+
expect((0..10) + (5..20)).to eq((5..20) + (0..10))
|
|
67
|
+
expect((0..10) + (10..20)).to eq(0..20)
|
|
65
68
|
|
|
66
69
|
# For discrete values, union should work on contiguous ranges
|
|
67
|
-
expect((
|
|
70
|
+
expect((0..5) + (6..20)).to eq(0..20)
|
|
68
71
|
end
|
|
69
72
|
|
|
70
73
|
it 'union should return nil if there is no overlap' do
|
|
71
|
-
expect((
|
|
72
|
-
expect((
|
|
74
|
+
expect((0..10) & (15..20)).to be_nil
|
|
75
|
+
expect((15..20) & (0..10)).to be_nil
|
|
73
76
|
end
|
|
74
77
|
|
|
75
78
|
it 'knows the difference with another range' do
|
|
76
79
|
# Other is same as self
|
|
77
80
|
# xrubocop:disable Lint/BinaryOperatorWithIdenticalOperands
|
|
78
81
|
expect(((4..10) - (4..10)).size).to eq(0)
|
|
79
|
-
expect((
|
|
82
|
+
expect((4..10) - (4..10)).to be_empty
|
|
80
83
|
# xrubocop:enable Lint/BinaryOperatorWithIdenticalOperands
|
|
81
84
|
|
|
82
85
|
# Other is proper subset of self
|
|
83
|
-
expect(((4..10) - (6..7)).first).to eq(
|
|
84
|
-
expect(((4..10) - (6..7)).last).to eq(
|
|
85
|
-
expect(((4..10) - (6..10)).first).to eq(
|
|
86
|
-
expect(((4..10) - (4..7)).last).to eq(
|
|
86
|
+
expect(((4..10) - (6..7)).first).to eq(4..5)
|
|
87
|
+
expect(((4..10) - (6..7)).last).to eq(8..10)
|
|
88
|
+
expect(((4..10) - (6..10)).first).to eq(4..5)
|
|
89
|
+
expect(((4..10) - (4..7)).last).to eq(8..10)
|
|
87
90
|
|
|
88
91
|
# Other overlaps on the left
|
|
89
92
|
expect(((4..10) - (0..6)).size).to eq(1)
|
|
90
|
-
expect(((4..10) - (0..6)).first).to eq(
|
|
93
|
+
expect(((4..10) - (0..6)).first).to eq(7..10)
|
|
91
94
|
|
|
92
95
|
expect(((4..10) - (4..6)).size).to eq(1)
|
|
93
|
-
expect(((4..10) - (4..6)).first).to eq(
|
|
96
|
+
expect(((4..10) - (4..6)).first).to eq(7..10)
|
|
94
97
|
|
|
95
98
|
# Other overlaps on the right
|
|
96
99
|
expect(((4..10) - (7..11)).size).to eq(1)
|
|
97
|
-
expect(((4..10) - (7..11)).first).to eq(
|
|
100
|
+
expect(((4..10) - (7..11)).first).to eq(4..6)
|
|
98
101
|
|
|
99
102
|
expect(((4..10) - (7..10)).size).to eq(1)
|
|
100
|
-
expect(((4..10) - (7..10)).last).to eq(
|
|
103
|
+
expect(((4..10) - (7..10)).last).to eq(4..6)
|
|
101
104
|
|
|
102
105
|
# Other does not overlap
|
|
103
106
|
expect((4..10) - (13..20)).to eq([(4..10)])
|
|
@@ -107,8 +110,8 @@ describe Range do
|
|
|
107
110
|
|
|
108
111
|
describe 'joining' do
|
|
109
112
|
it 'can join contiguous ranges' do
|
|
110
|
-
expect((0..3).join(4..8)).to eq(
|
|
111
|
-
expect((4..8).join(0..3)).to eq(
|
|
113
|
+
expect((0..3).join(4..8)).to eq(0..8)
|
|
114
|
+
expect((4..8).join(0..3)).to eq(0..8)
|
|
112
115
|
end
|
|
113
116
|
|
|
114
117
|
it 'returns nil on join of non-contiguous ranges' do
|
|
@@ -120,51 +123,51 @@ describe Range do
|
|
|
120
123
|
end
|
|
121
124
|
|
|
122
125
|
it 'works with Floats, allowing single-point overlap' do
|
|
123
|
-
expect((0.0..3.0).join(3.0..8.2)).to eq(
|
|
124
|
-
expect((3.0..8.2).join(0.0..3.0)).to eq(
|
|
126
|
+
expect((0.0..3.0).join(3.0..8.2)).to eq(0.0..8.2)
|
|
127
|
+
expect((3.0..8.2).join(0.0..3.0)).to eq(0.0..8.2)
|
|
125
128
|
end
|
|
126
129
|
end
|
|
127
130
|
|
|
128
131
|
describe 'spanning' do
|
|
129
132
|
it 'can determine whether it is spanned by a set of ranges' do
|
|
130
|
-
expect((0..10)
|
|
133
|
+
expect((0..10).spanned_by?([(0..3), (4..6), (7..10)])).to be true
|
|
131
134
|
end
|
|
132
135
|
|
|
133
136
|
it 'can determine that overlapping ranges do not span' do
|
|
134
|
-
expect((0..10)
|
|
137
|
+
expect((0..10).spanned_by?([(0..3), (3..6), (7..10)])).to be false
|
|
135
138
|
end
|
|
136
139
|
|
|
137
140
|
it 'allows spanning ranges to be any Enumerable' do
|
|
138
141
|
require 'set'
|
|
139
142
|
set = [(0..3), (4..6), (7..10)].to_set
|
|
140
|
-
expect((0..10)).to
|
|
143
|
+
expect((0..10).spanned_by?(set)).to be true
|
|
141
144
|
set = [(0...3), (4..6), (7..10)].to_set
|
|
142
|
-
expect((0..10)
|
|
145
|
+
expect((0..10).spanned_by?(set)).to be false
|
|
143
146
|
end
|
|
144
147
|
|
|
145
148
|
it 'allows the spanning set to be wider than itself' do
|
|
146
149
|
set = [(0..3), (4..6), (7..10)].to_set
|
|
147
|
-
expect((2..8)).to
|
|
148
|
-
expect((5..6)).to
|
|
150
|
+
expect((2..8).spanned_by?(set)).to be true
|
|
151
|
+
expect((5..6).spanned_by?(set)).to be true
|
|
149
152
|
end
|
|
150
153
|
end
|
|
151
154
|
|
|
152
155
|
describe 'overlapping a single range' do
|
|
153
156
|
it 'knows if another range overlaps it' do
|
|
154
|
-
expect((0..10)
|
|
155
|
-
expect((0..10)
|
|
156
|
-
expect((0..10)
|
|
157
|
-
expect((0..10)
|
|
158
|
-
expect((0..10)
|
|
159
|
-
expect((0..10)
|
|
157
|
+
expect((0..10).overlaps?(-3..5)).to be true
|
|
158
|
+
expect((0..10).overlaps?(3..5)).to be true
|
|
159
|
+
expect((0..10).overlaps?(8..15)).to be true
|
|
160
|
+
expect((0..10).overlaps?(0..10)).to be true
|
|
161
|
+
expect((0..10).overlaps?(11..12)).to be false
|
|
162
|
+
expect((0..10).overlaps?(-11..-1)).to be false
|
|
160
163
|
|
|
161
164
|
# Order of operands should not matter
|
|
162
|
-
expect((-3..5)
|
|
163
|
-
expect((3..5)
|
|
164
|
-
expect((8..15)
|
|
165
|
-
expect((0..10)
|
|
166
|
-
expect((11..12)
|
|
167
|
-
expect((-11..-1)
|
|
165
|
+
expect((-3..5).overlaps?(0..10)).to be true
|
|
166
|
+
expect((3..5).overlaps?(0..10)).to be true
|
|
167
|
+
expect((8..15).overlaps?(0..10)).to be true
|
|
168
|
+
expect((0..10).overlaps?(0..10)).to be true
|
|
169
|
+
expect((11..12).overlaps?(0..10)).to be false
|
|
170
|
+
expect((-11..-1).overlaps?(0..10)).to be false
|
|
168
171
|
end
|
|
169
172
|
|
|
170
173
|
it 'can determine whether a set contains covered overlaps' do
|
|
@@ -201,8 +204,12 @@ describe Range do
|
|
|
201
204
|
|
|
202
205
|
it 'returns an array of gaps' do
|
|
203
206
|
gaps = (0..10).gaps([(0..3), (5..6), (9..10)])
|
|
204
|
-
expect(gaps[0]).to eq(
|
|
205
|
-
expect(gaps[1]).to eq(
|
|
207
|
+
expect(gaps[0]).to eq(4..4)
|
|
208
|
+
expect(gaps[1]).to eq(7..8)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
it 'returns gaps for letter ranges' do
|
|
212
|
+
expect(('a'..'z').gaps([('a'..'g'), ('j'..'s'), ('t'..'z')])).to eq([Range.new('h', 'i')])
|
|
206
213
|
end
|
|
207
214
|
|
|
208
215
|
it 'allows ranges to extend before and after self' do
|
|
@@ -213,36 +220,40 @@ describe Range do
|
|
|
213
220
|
it 'does not include parts before or after in gaps' do
|
|
214
221
|
gaps = (0..10).gaps([(-10..-8), (-3..3), (7..13), (30..40)])
|
|
215
222
|
expect(gaps.size).to eq(1)
|
|
216
|
-
expect(gaps[0]).to eq(
|
|
223
|
+
expect(gaps[0]).to eq(4..6)
|
|
217
224
|
end
|
|
218
225
|
|
|
219
226
|
it 'includes gaps at beginning and end' do
|
|
220
227
|
gaps = (0..10).gaps([(2..3), (4..6), (7..8)])
|
|
221
|
-
expect(gaps[0]).to eq(
|
|
222
|
-
expect(gaps[1]).to eq(
|
|
228
|
+
expect(gaps[0]).to eq(0..1)
|
|
229
|
+
expect(gaps[1]).to eq(9..10)
|
|
223
230
|
end
|
|
224
231
|
|
|
225
232
|
it 'works even if ranges are out of order' do
|
|
226
233
|
gaps = (0..10).gaps([(2..3), (30..40), (7..8), (-10..-8), (4..6)])
|
|
227
|
-
expect(gaps[0]).to eq(
|
|
228
|
-
expect(gaps[1]).to eq(
|
|
234
|
+
expect(gaps[0]).to eq(0..1)
|
|
235
|
+
expect(gaps[1]).to eq(9..10)
|
|
229
236
|
end
|
|
230
237
|
|
|
231
238
|
it 'notices single point coverage' do
|
|
232
239
|
gaps = (0..10).gaps([(4..4), (5..5), (6..6)])
|
|
233
|
-
expect(gaps[0]).to eq(
|
|
234
|
-
expect(gaps[1]).to eq(
|
|
240
|
+
expect(gaps[0]).to eq(0..3)
|
|
241
|
+
expect(gaps[1]).to eq(7..10)
|
|
235
242
|
end
|
|
236
243
|
|
|
237
244
|
it 'works for a single-point range' do
|
|
238
245
|
gaps = (3..3).gaps([(0..2), (4..4), (5..5), (6..6)])
|
|
239
|
-
expect(gaps[0]).to eq(
|
|
246
|
+
expect(gaps[0]).to eq(3..3)
|
|
240
247
|
end
|
|
241
248
|
|
|
242
249
|
it 'works even if ranges overlap' do
|
|
243
250
|
gaps = (0..10).gaps([(-2..3), (2..8), (4..10)])
|
|
244
251
|
expect(gaps).to be_empty
|
|
245
252
|
end
|
|
253
|
+
|
|
254
|
+
it 'raises an error if argument types are incompatible' do
|
|
255
|
+
expect { ('A'..'F').gaps([(1..5), (6..11)]) }.to raise_error(/incompatible/)
|
|
256
|
+
end
|
|
246
257
|
end
|
|
247
258
|
|
|
248
259
|
describe '#overlaps' do
|
|
@@ -265,22 +276,22 @@ describe Range do
|
|
|
265
276
|
it 'returns an array of overlaps' do
|
|
266
277
|
overlaps = (0..10).overlaps([(0..3), (2..6), (4..10)])
|
|
267
278
|
expect(overlaps.size).to eq(2)
|
|
268
|
-
expect(overlaps[0]).to eq(
|
|
269
|
-
expect(overlaps[1]).to eq(
|
|
279
|
+
expect(overlaps[0]).to eq(2..3)
|
|
280
|
+
expect(overlaps[1]).to eq(4..6)
|
|
270
281
|
end
|
|
271
282
|
|
|
272
283
|
it 'does not return any overlaps before self' do
|
|
273
284
|
overlaps = (0..10).overlaps([(-5..-3), (-4..-1), (0..3), (2..6), (4..10)])
|
|
274
285
|
expect(overlaps.size).to eq(2)
|
|
275
|
-
expect(overlaps[0]).to eq(
|
|
276
|
-
expect(overlaps[1]).to eq(
|
|
286
|
+
expect(overlaps[0]).to eq(2..3)
|
|
287
|
+
expect(overlaps[1]).to eq(4..6)
|
|
277
288
|
end
|
|
278
289
|
|
|
279
290
|
it 'does not return any overlaps after self' do
|
|
280
291
|
overlaps = (0..10).overlaps([(0..3), (2..6), (4..15), (11..20)])
|
|
281
292
|
expect(overlaps.size).to eq(2)
|
|
282
|
-
expect(overlaps[0]).to eq(
|
|
283
|
-
expect(overlaps[1]).to eq(
|
|
293
|
+
expect(overlaps[0]).to eq(2..3)
|
|
294
|
+
expect(overlaps[1]).to eq(4..6)
|
|
284
295
|
end
|
|
285
296
|
end
|
|
286
297
|
end
|
data/spec/lib/string_spec.rb
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
require 'spec_helper'
|
|
4
4
|
require 'fat_core/string'
|
|
5
|
-
require 'fat_core/date'
|
|
6
5
|
|
|
7
6
|
describe String do
|
|
8
7
|
describe 'class methods' do
|
|
@@ -97,6 +96,22 @@ the people, for the people, shall not perish from the earth."
|
|
|
97
96
|
expect(' string here '.clean).to eq 'string here'
|
|
98
97
|
end
|
|
99
98
|
|
|
99
|
+
using StringPred
|
|
100
|
+
|
|
101
|
+
it 'computes predecessor to String' do
|
|
102
|
+
expect("B".pred).to eq("A")
|
|
103
|
+
expect("C".pred).to eq("B")
|
|
104
|
+
expect("D".pred).to eq("C")
|
|
105
|
+
expect("Z".pred).to eq("Y")
|
|
106
|
+
expect("AAA".pred).to eq("9ZZ")
|
|
107
|
+
expect("A".pred).to eq("9")
|
|
108
|
+
expect("BBA".pred).to eq("BAZ")
|
|
109
|
+
expect("00123".pred).to eq("00122")
|
|
110
|
+
expect("9999".succ).to eq("10000")
|
|
111
|
+
expect("00000".pred).to eq("a9999")
|
|
112
|
+
expect { "00123+".pred }.to raise_error(/undefined method/)
|
|
113
|
+
end
|
|
114
|
+
|
|
100
115
|
describe 'numeric strings' do
|
|
101
116
|
it 'converts a numeric string to a commified form' do
|
|
102
117
|
expect('20140521'.commas).to eq '20,140,521'
|
|
@@ -139,19 +154,10 @@ the people, for the people, shall not perish from the earth."
|
|
|
139
154
|
expect('-8.008'.number?).to be true
|
|
140
155
|
expect('8.008e33'.number?).to be true
|
|
141
156
|
expect('-8.008e33'.number?).to be true
|
|
142
|
-
expect('0x8.008').to be_number
|
|
143
157
|
expect('hello world'.number?).to be false
|
|
144
158
|
end
|
|
145
159
|
end
|
|
146
160
|
|
|
147
|
-
it 'converts a digital date to a Date' do
|
|
148
|
-
expect('20140521'.as_date.iso).to eq '2014-05-21'
|
|
149
|
-
expect('2014-05-21'.as_date.iso).to eq '2014-05-21'
|
|
150
|
-
expect('2014/05/21'.as_date.iso).to eq '2014-05-21'
|
|
151
|
-
expect('2014/5/21'.as_date.iso).to eq '2014-05-21'
|
|
152
|
-
expect('201X/5/21'.as_date).to be_nil
|
|
153
|
-
end
|
|
154
|
-
|
|
155
161
|
it 'converts a string to a regular expression' do
|
|
156
162
|
# Ignores case by default
|
|
157
163
|
re = "/hello((\s+)(world))?/".as_regexp
|
|
@@ -214,7 +220,7 @@ the people, for the people, shall not perish from the earth."
|
|
|
214
220
|
expect('tr'.entitle).to eq('Tr')
|
|
215
221
|
expect('trd'.entitle).to eq('TRD')
|
|
216
222
|
# Don't capitalize c/o
|
|
217
|
-
expect('
|
|
223
|
+
expect('sherLOCK c/o watson'.entitle).to eq('Sherlock c/o Watson')
|
|
218
224
|
# Capitlaize p.o.
|
|
219
225
|
expect('p.o. box 123'.entitle).to eq('P.O. Box 123')
|
|
220
226
|
# Don't capitalize ordinals
|
|
@@ -224,8 +230,6 @@ the people, for the people, shall not perish from the earth."
|
|
|
224
230
|
expect('nw territory'.entitle).to eq('NW Territory')
|
|
225
231
|
# Leave word starting with numbers alone
|
|
226
232
|
expect('apartment 33-B'.entitle).to eq('Apartment 33-B')
|
|
227
|
-
# Assume all uppercase is an acronym
|
|
228
|
-
expect('the ABC network'.entitle).to eq('The ABC Network')
|
|
229
233
|
# But not if the whole string is uppercase
|
|
230
234
|
expect('THE ABC NETWORK'.entitle).to eq('The Abc Network')
|
|
231
235
|
# Capitalize both parts of a hyphenated word
|
|
@@ -253,14 +257,10 @@ the people, for the people, shall not perish from the earth."
|
|
|
253
257
|
describe 'Fuzzy Matching' do
|
|
254
258
|
it 'fuzzy matches with another string' do
|
|
255
259
|
expect('Hello, world'.fuzzy_match('wor')).to be_truthy
|
|
260
|
+
expect('Hello, world'.fuzzy_match('orl')).to be_truthy
|
|
256
261
|
expect('Hello, world'.fuzzy_match('ox')).to be_falsy
|
|
257
262
|
end
|
|
258
263
|
|
|
259
|
-
it 'fuzzy matches with another string containing re' do
|
|
260
|
-
expect('Hello, world'.matches_with('/or/')).to be_truthy
|
|
261
|
-
expect('Hello, world'.matches_with('/ox/')).to be_falsy
|
|
262
|
-
end
|
|
263
|
-
|
|
264
264
|
it 'fuzzy matches space-separated parts' do
|
|
265
265
|
expect('Hello world'.fuzzy_match('hel wor')).to be_truthy
|
|
266
266
|
expect('Hello, world'.fuzzy_match('hel ox')).to be_falsy
|
|
@@ -268,22 +268,35 @@ the people, for the people, shall not perish from the earth."
|
|
|
268
268
|
|
|
269
269
|
it 'fuzzy matches colon-separated parts' do
|
|
270
270
|
expect('Hello:world'.fuzzy_match('hel:wor')).to be_truthy
|
|
271
|
-
expect('Hello:world'.fuzzy_match('hel:
|
|
271
|
+
expect('Hello:world'.fuzzy_match('hel :wor')).to be_truthy
|
|
272
|
+
expect('Hello:world'.fuzzy_match('hel: wor')).to be_falsy
|
|
273
|
+
expect('Hello:world'.fuzzy_match('hel:orld')).to be_falsy
|
|
274
|
+
expect("Hello, 'world'".fuzzy_match('hel:wor')).to be_truthy
|
|
275
|
+
expect('Hello "world"'.fuzzy_match('hel:world')).to be_truthy
|
|
272
276
|
end
|
|
273
277
|
|
|
274
|
-
it 'treats an internal `:stuff
|
|
278
|
+
it 'treats an internal `:stuff` as \bstuff.*' do
|
|
275
279
|
expect('Hello, what is with the world?'.fuzzy_match('wha:wi:wor')).to be_truthy
|
|
280
|
+
expect('Hello, what is with the world?'.fuzzy_match('hat :wi :wor')).to be_truthy
|
|
276
281
|
expect('Hello:world'.fuzzy_match('what:or')).to be_falsy
|
|
277
282
|
expect('Hello, what=+&is (with) the world?'.fuzzy_match('wha:wi:wor')).to be_truthy
|
|
278
283
|
end
|
|
279
284
|
|
|
285
|
+
it 'treats an internal `stuff: ` as stuff\b.*' do
|
|
286
|
+
expect('Hello, what is with the world?'.fuzzy_match('llo: th: :wor')).to be_truthy
|
|
287
|
+
expect('Hello:world'.fuzzy_match('llox: ')).to be_falsy
|
|
288
|
+
expect('Hello, what=+&is (with) the world?'.fuzzy_match('at: ith: the')).to be_truthy
|
|
289
|
+
end
|
|
290
|
+
|
|
280
291
|
it 'requires end-anchor for ending colon' do
|
|
281
292
|
expect('Hello, to the world'.fuzzy_match('hel:world:')).to eq('Hello to the world')
|
|
293
|
+
expect('Hello, to the world '.fuzzy_match('hel:world:')).to eq('Hello to the world')
|
|
282
294
|
expect('Hello, to the world today'.fuzzy_match('to:world:')).to be_nil
|
|
283
295
|
end
|
|
284
296
|
|
|
285
297
|
it 'requires start-anchor for leading colon' do
|
|
286
298
|
expect('Hello, to the world'.fuzzy_match(':hel:the')).to eq('Hello to the')
|
|
299
|
+
expect(' Hello, to the world'.fuzzy_match(':hel:the')).to eq('Hello to the')
|
|
287
300
|
expect('Hello, to the world today'.fuzzy_match(':world:today')).to be_nil
|
|
288
301
|
end
|
|
289
302
|
|
|
@@ -307,6 +320,51 @@ the people, for the people, shall not perish from the earth."
|
|
|
307
320
|
expect('The 1 Dollar Store'.fuzzy_match('1 stor')).to be_truthy
|
|
308
321
|
expect('The $1 Dollar Store'.fuzzy_match('$1 stor')).to be_falsy
|
|
309
322
|
end
|
|
323
|
+
|
|
324
|
+
it 'performs examples in documentation' do
|
|
325
|
+
expect("St. Luke's".fuzzy_match('st lukes')).to eq('St Lukes')
|
|
326
|
+
expect("St. Luke's Hospital".fuzzy_match('st lukes')).to eq('St Lukes')
|
|
327
|
+
expect("St. Luke's Hospital".fuzzy_match('luk:hosp')).to eq('Lukes Hosp')
|
|
328
|
+
expect("St. Luke's Hospital".fuzzy_match('st:spital')).to be_nil
|
|
329
|
+
expect("St. Luke's Hospital".fuzzy_match('st spital')).to eq('St Lukes Hospital')
|
|
330
|
+
expect("St. Luke's Hospital".fuzzy_match('st:laks')).to be_nil
|
|
331
|
+
expect("St. Luke's Hospital".fuzzy_match(':lukes')).to be_nil
|
|
332
|
+
expect("St. Luke's Hospital".fuzzy_match('lukes:hospital')).to eq('Lukes Hospital')
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
describe '#matches_with' do
|
|
337
|
+
it 'matches with another string containing a plain string' do
|
|
338
|
+
expect('Hello, world'.matches_with('or')).to be_truthy
|
|
339
|
+
expect('Hello, world'.matches_with('ox')).to be_falsy
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
it 'matches with another string containing re' do
|
|
343
|
+
expect('Hello, world'.matches_with('/or/')).to be_truthy
|
|
344
|
+
expect('Hello, world'.matches_with('/ox/')).to be_falsy
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
it 'performs examples in documentation with just strings' do
|
|
348
|
+
expect("St. Luke's".matches_with('st lukes')).to eq('St Lukes')
|
|
349
|
+
expect("St. Luke's Hospital".matches_with('st lukes')).to eq('St Lukes')
|
|
350
|
+
expect("St. Luke's Hospital".matches_with('luk:hosp')).to eq('Lukes Hosp')
|
|
351
|
+
expect("St. Luke's Hospital".matches_with('st:spital')).to be_nil
|
|
352
|
+
expect("St. Luke's Hospital".matches_with('st spital')).to eq('St Lukes Hospital')
|
|
353
|
+
expect("St. Luke's Hospital".matches_with('st:laks')).to be_nil
|
|
354
|
+
expect("St. Luke's Hospital".matches_with(':lukes')).to be_nil
|
|
355
|
+
expect("St. Luke's Hospital".matches_with('lukes:hospital')).to eq('Lukes Hospital')
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
it 'performs examples in documentation with regexes' do
|
|
359
|
+
expect("St. Luke's".matches_with('/st\s*lukes/')).to eq('St Lukes')
|
|
360
|
+
expect("St. Luke's Hospital".matches_with('/st lukes/')).to eq('St Lukes')
|
|
361
|
+
expect("St. Luke's Hospital".matches_with('/luk.*\bhosp/')).to eq('Lukes Hosp')
|
|
362
|
+
expect("St. Luke's Hospital".matches_with('/st(.*)spital\z/')).to eq('St Lukes Hospital')
|
|
363
|
+
expect("St. Luke's Hospital".matches_with('/st spital/')).to be_nil
|
|
364
|
+
expect("St. Luke's Hospital".matches_with('/st.*laks/')).to be_nil
|
|
365
|
+
expect("St. Luke's Hospital".matches_with('/\Alukes/')).to be_nil
|
|
366
|
+
expect("St. Luke's Hospital".matches_with('/lukes hospital/')).to eq('Lukes Hospital')
|
|
367
|
+
end
|
|
310
368
|
end
|
|
311
369
|
end
|
|
312
370
|
end
|
data/spec/lib/symbol_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'simplecov'
|
|
2
4
|
SimpleCov.command_name 'Rspec'
|
|
3
5
|
|
|
@@ -8,7 +10,7 @@ require 'pry'
|
|
|
8
10
|
require 'debug'
|
|
9
11
|
|
|
10
12
|
require 'active_support/testing/time_helpers'
|
|
11
|
-
|
|
13
|
+
require_relative '../lib/fat_core/all'
|
|
12
14
|
|
|
13
15
|
# This file was generated by the `rspec --init` command. Conventionally, all
|
|
14
16
|
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fat_core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 7.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daniel E. Doherty
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: bin
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date: 2025-
|
|
11
|
+
date: 2025-11-25 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: activesupport
|
|
@@ -73,35 +74,33 @@ description: |
|
|
|
73
74
|
iteration, (also for Hash), set operations on Ranges
|
|
74
75
|
email:
|
|
75
76
|
- ded@ddoherty.net
|
|
76
|
-
executables:
|
|
77
|
-
- easter
|
|
77
|
+
executables: []
|
|
78
78
|
extensions: []
|
|
79
79
|
extra_rdoc_files: []
|
|
80
80
|
files:
|
|
81
81
|
- ".envrc"
|
|
82
|
+
- ".github/workflows/ruby.yml"
|
|
82
83
|
- ".gitignore"
|
|
83
84
|
- ".rspec"
|
|
84
85
|
- ".rubocop.yml"
|
|
85
86
|
- ".simplecov"
|
|
86
87
|
- ".travis.yml"
|
|
87
88
|
- ".yardopts"
|
|
89
|
+
- CHANGELOG.org
|
|
88
90
|
- Gemfile
|
|
89
91
|
- LICENSE.txt
|
|
90
92
|
- README.org
|
|
91
93
|
- Rakefile
|
|
92
94
|
- TODO.org
|
|
93
95
|
- bin/console
|
|
94
|
-
- bin/easter
|
|
95
96
|
- fat_core.gemspec
|
|
96
97
|
- lib/fat_core.rb
|
|
97
98
|
- lib/fat_core/ChangeLog
|
|
98
99
|
- lib/fat_core/all.rb
|
|
99
100
|
- lib/fat_core/array.rb
|
|
100
101
|
- lib/fat_core/bigdecimal.rb
|
|
101
|
-
- lib/fat_core/date.rb
|
|
102
102
|
- lib/fat_core/enumerable.rb
|
|
103
103
|
- lib/fat_core/hash.rb
|
|
104
|
-
- lib/fat_core/kernel.rb
|
|
105
104
|
- lib/fat_core/nil.rb
|
|
106
105
|
- lib/fat_core/numeric.rb
|
|
107
106
|
- lib/fat_core/patches.rb
|
|
@@ -111,10 +110,8 @@ files:
|
|
|
111
110
|
- lib/fat_core/version.rb
|
|
112
111
|
- spec/lib/array_spec.rb
|
|
113
112
|
- spec/lib/big_decimal_spec.rb
|
|
114
|
-
- spec/lib/date_spec.rb
|
|
115
113
|
- spec/lib/enumerable_spec.rb
|
|
116
114
|
- spec/lib/hash_spec.rb
|
|
117
|
-
- spec/lib/kernel_spec.rb
|
|
118
115
|
- spec/lib/nil_class_spec.rb
|
|
119
116
|
- spec/lib/numeric_spec.rb
|
|
120
117
|
- spec/lib/range_spec.rb
|
|
@@ -126,6 +123,7 @@ licenses:
|
|
|
126
123
|
- MIT
|
|
127
124
|
metadata:
|
|
128
125
|
yard.run: yri
|
|
126
|
+
post_install_message:
|
|
129
127
|
rdoc_options: []
|
|
130
128
|
require_paths:
|
|
131
129
|
- lib
|
|
@@ -140,7 +138,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
140
138
|
- !ruby/object:Gem::Version
|
|
141
139
|
version: '0'
|
|
142
140
|
requirements: []
|
|
143
|
-
rubygems_version: 3.
|
|
141
|
+
rubygems_version: 3.5.23
|
|
142
|
+
signing_key:
|
|
144
143
|
specification_version: 4
|
|
145
144
|
summary: some useful core extensions
|
|
146
145
|
test_files: []
|
data/bin/easter
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require "debug"
|
|
5
|
-
require 'fat_core/date'
|
|
6
|
-
|
|
7
|
-
usage = <<~HELP
|
|
8
|
-
USAGE:
|
|
9
|
-
easter -- print the date of Easter for the current year
|
|
10
|
-
easter year -- print the date of Easter for the given year
|
|
11
|
-
easter year1 year2 -- print the dates of Easter from year1 to year2
|
|
12
|
-
|
|
13
|
-
Note: if the date of Easter is the earliest possible, it is marked with a '<';
|
|
14
|
-
if it is the latest date possible, it is marked with a '>'
|
|
15
|
-
HELP
|
|
16
|
-
first, last = *ARGV
|
|
17
|
-
first ||= Date.today.year
|
|
18
|
-
last ||= Date.today.year
|
|
19
|
-
|
|
20
|
-
if first.to_s.match?(/--help|-h/)
|
|
21
|
-
puts usage
|
|
22
|
-
exit(1)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
begin
|
|
26
|
-
first = Integer(first)
|
|
27
|
-
last = Integer(last)
|
|
28
|
-
rescue ArgumentError
|
|
29
|
-
warn "!!Error: invalid year number given\n\n"
|
|
30
|
-
puts usage
|
|
31
|
-
exit(2)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
(first..last).each do |yr|
|
|
35
|
-
easter = Date.easter(yr)
|
|
36
|
-
sig =
|
|
37
|
-
if easter.month == 4 && easter.day >= 25
|
|
38
|
-
' >'
|
|
39
|
-
elsif easter.month == 3 && easter.day <= 22
|
|
40
|
-
' <'
|
|
41
|
-
else
|
|
42
|
-
''
|
|
43
|
-
end
|
|
44
|
-
puts "Easter #{yr}: #{easter.iso}#{sig}"
|
|
45
|
-
end
|