fat_core 4.17.0 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a535331fa37f8a1247eb587f0b2a4770c5e37f7f27f7c2cb850ea9f31b4bd1ca
4
- data.tar.gz: b0644ff70137d300cc2f02cdefdfa1aa9857f6f333e000137dc8e8124f02d760
3
+ metadata.gz: 6d377f4ea28c3310ce28733b4da66dad3e39dc13be3f5406ab1cce4b4e784924
4
+ data.tar.gz: d1e6f6fb84c9211104a87c2e4d596a3637eaacfa5bc82349b3d5baaa2b9657df
5
5
  SHA512:
6
- metadata.gz: 7ee6dee2e096d81087efb0a8a517010738b609102892e8f32617ca780edca9ba129433e79ef19e6c9979a27f4e451b141d1291fdd7457ccdbf38cec6cca53331
7
- data.tar.gz: dcf803b07f015dbb3846a13a4cb27122e185dfae6b7461345a4deaf1ff2cfb838cfb75f6a0d5ce61f2bb1299bc80b8b1023bf898e800369a54564d6f5001fe2c
6
+ metadata.gz: 0f81e05b5728f6dc3a7fe556bcd48ff011a006375938afd269ced9d3b6266715118dd5281d7e5c2dd39665257ed8f49a86fc73ddb3d5c3a1f9b1bc728efecb15
7
+ data.tar.gz: 8c6fd80723f159aaaf92cf52b249cb194f4394bb8f655963a4287c37523e8212e93ed27c7a9b40be8620bb45773cd47e38a701b0ceead250e1f69fd20fab162a
data/.envrc ADDED
@@ -0,0 +1 @@
1
+ PATH_add .bundle/bin
data/.gitignore CHANGED
@@ -21,3 +21,6 @@ tmp
21
21
  /.rubocop_todo.yml
22
22
  /gtags.files
23
23
  /.ruby-version
24
+ /.idea/
25
+ /README.md
26
+ /TAGS
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
+ --require 'spec_helper'
1
2
  --color
2
3
  --format documentation
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FatCore
4
+ # Useful extensions to the core Array class.
4
5
  module Array
5
6
  # Return the index of the last element of this Array. This is just a
6
7
  # convenience for an oft-needed Array attribute.
@@ -8,14 +9,14 @@ module FatCore
8
9
  size - 1
9
10
  end
10
11
 
11
- # Return a new Array that is the intersection of this Array with +other+,
12
- # but without removing duplicates as the Array#& method does. All items of
13
- # this Array are included in the result but only if they also appear in the
14
- # +other+ Array.
15
- def intersect(other)
12
+ # Return a new Array that is the intersection of this Array with all
13
+ # +others+, but without removing duplicates as the Array#& method
14
+ # does. All items of this Array are included in the result but only if
15
+ # they also appear in all of the other Arrays.
16
+ def intersect_with_dups(*others)
16
17
  result = []
17
18
  each do |itm|
18
- result << itm if other.include?(itm)
19
+ result << itm if others.all? { |oth| oth.include?(itm) }
19
20
  end
20
21
  result
21
22
  end
@@ -24,10 +25,53 @@ module FatCore
24
25
  # without removing duplicates as the Array#- method does. All items of this
25
26
  # Array are included in the result unless they also appear in the +other+
26
27
  # Array.
27
- def difference(other)
28
+ def diff_with_dups(*others)
28
29
  result = []
29
30
  each do |itm|
30
- result << itm unless other.include?(itm)
31
+ result << itm if others.none? { |oth| oth.include?(itm) }
32
+ end
33
+ result
34
+ end
35
+
36
+ # Convert this array into a single string by (1) applying #to_s to each
37
+ # element and (2) joining the elements with the string given by the sep:
38
+ # paramater. By default the sep parameter is ', '. You may use a different
39
+ # separation string in the case when there are only two items in the list
40
+ # by supplying a two_sep parameter. You may also supply a difference
41
+ # separation string to separate the second-last and last items in the
42
+ # array by supplying a last_sep: parameter. By default, the sep parameter
43
+ # is the string ', ', the two_sep is ' and ', and the last_sep is ', and
44
+ # ', all of which makes for a well-punctuated English clause. If sep is
45
+ # given, the other two parameters are set to its value by default. If
46
+ # last_sep is given, two_sep takes its value by default. If the input
47
+ # array is empty, #comma_join returns an empty string.
48
+ def comma_join(sep: nil, last_sep: nil, two_sep: nil)
49
+ orig_sep = sep
50
+ orig_last_sep = last_sep
51
+ sep ||= ', '
52
+ last_sep ||= orig_sep || ', and '
53
+ two_sep ||= orig_sep || orig_last_sep || ' and '
54
+ result = +''
55
+ case size
56
+ when 0
57
+ result
58
+ when 1
59
+ result = self[0].to_s
60
+ when 2
61
+ result = self[0].to_s + two_sep + self[1]
62
+ else
63
+ second_last = size - 2
64
+ last = size - 1
65
+ each_with_index do |itm, k|
66
+ result <<
67
+ if k == second_last
68
+ "#{itm}#{last_sep}"
69
+ elsif k == last
70
+ itm.to_s
71
+ else
72
+ "#{itm}#{sep}"
73
+ end
74
+ end
31
75
  end
32
76
  result
33
77
  end
data/lib/fat_core/date.rb CHANGED
@@ -90,7 +90,7 @@ module FatCore
90
90
  # Format as an inactive Org date timestamp of the form `[YYYY-MM-DD <dow>]`
91
91
  # (see Emacs org-mode)
92
92
  # @return [String]
93
- def org(active = false)
93
+ def org(active: false)
94
94
  if active
95
95
  strftime('<%Y-%m-%d %a>')
96
96
  else
@@ -186,7 +186,7 @@ module FatCore
186
186
  # semimonth the date falls in.
187
187
  # @return [Integer]
188
188
  def semimonth
189
- (month - 1) * 2 + (day <= 15 ? 1 : 2)
189
+ ((month - 1) * 2) + (day <= 15 ? 1 : 2)
190
190
  end
191
191
 
192
192
  # Self's calendar biweek: 1, through 24 depending on which calendar
@@ -428,7 +428,7 @@ module FatCore
428
428
  self - 1.day
429
429
  end
430
430
 
431
- # Note: the ::Date class already has a #succ method.
431
+ # NOTE: the ::Date class already has a #succ method.
432
432
 
433
433
  # The date that is the first day of the half-year in which self falls.
434
434
  # @return [::Date]
@@ -1842,6 +1842,7 @@ module FatCore
1842
1842
  raise ArgumentError, 'requires String, Date, DateTime, or Time'
1843
1843
  end
1844
1844
  end
1845
+ alias ensure ensure_date
1845
1846
  end
1846
1847
 
1847
1848
  def self.included(base)
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Useful extensions to the core Enumerable module.
3
4
  module Enumerable
4
5
  # Yield items in groups of n, for each group yield the group number, starting
5
6
  # with zero and an Array of n items, or all remaining items if less than n.
data/lib/fat_core/hash.rb CHANGED
@@ -10,20 +10,20 @@
10
10
  # require 'fat_core/hash'
11
11
  # ```
12
12
  #
13
- # It provides a couple of methods for manipulating the keys of a Hash:
14
- # `#remap_keys` for translating the current set of keys to a new set provided by
15
- # a Hash of old to new keys, and `#replace_keys` for doing a similar operation
16
- # with an Array of new keys. Along the same line, the method `#keys_with_value`
17
- # will return the keys in a Hash equal to the given value of any of an Array of
18
- # values.
19
- #
20
- # It also provides a method for deleting all entries in a Hash whose value match
21
- # a single value or any one of an Array of values in `#delete_with_value`
22
- #
23
- # Finally, it provides an `#each_pair`-like method, `#each_pair_with_flags`,
24
- # that yields each key-value pair of the Hash along with two boolean flags that
25
- # indicate whether the element is the first or last in the Hash.
26
13
  module FatCore
14
+ # It provides a couple of methods for manipulating the keys of a Hash:
15
+ # `#remap_keys` for translating the current set of keys to a new set provided by
16
+ # a Hash of old to new keys, and `#replace_keys` for doing a similar operation
17
+ # with an Array of new keys. Along the same line, the method `#keys_with_value`
18
+ # will return the keys in a Hash equal to the given value of any of an Array of
19
+ # values.
20
+ #
21
+ # It also provides a method for deleting all entries in a Hash whose value match
22
+ # a single value or any one of an Array of values in `#delete_with_value`
23
+ #
24
+ # Finally, it provides an `#each_pair`-like method, `#each_pair_with_flags`,
25
+ # that yields each key-value pair of the Hash along with two boolean flags that
26
+ # indicate whether the element is the first or last in the Hash.
27
27
  module Hash
28
28
  # @group Enumerable Extensions
29
29
  #
@@ -130,15 +130,13 @@ module FatCore
130
130
  # @param new_keys [Array<Object>] replacement keys
131
131
  # @return [Hash]
132
132
  def replace_keys(new_keys)
133
- unless keys.size == new_keys.size
134
- raise ArgumentError, 'replace_keys: new keys size differs from key size'
135
- end
133
+ raise ArgumentError, 'replace_keys: new keys size differs from key size' unless keys.size == new_keys.size
136
134
 
137
- to_a.each_with_index.map { |(_k, v), i| [new_keys[i], v] }.to_h
135
+ to_a.each_with_index.to_h { |(_k, v), i| [new_keys[i], v] }
138
136
  end
139
137
 
140
138
  def <<(other)
141
- self.merge(other)
139
+ merge(other)
142
140
  end
143
141
  end
144
142
  end
data/lib/fat_core/nil.rb CHANGED
@@ -8,7 +8,7 @@ module FatCore
8
8
  def as_string
9
9
  ''
10
10
  end
11
- alias_method :entitle, :as_string
11
+ alias entitle as_string
12
12
 
13
13
  # Allow nils to respond to #tex_quote for use in TeX documents
14
14
  #
@@ -132,7 +132,7 @@ module FatCore
132
132
 
133
133
  ([min, other.min].max..[max, other.max].min)
134
134
  end
135
- alias_method :&, :intersection
135
+ alias & intersection
136
136
 
137
137
  # Return a Range that represents the union between this range and the
138
138
  # `other` range. If there is no overlap and self is not contiguous with
@@ -150,7 +150,7 @@ module FatCore
150
150
 
151
151
  ([min, other.min].min..[max, other.max].max)
152
152
  end
153
- alias_method :+, :union
153
+ alias + union
154
154
 
155
155
  # The difference method, -, removes the overlapping part of the other
156
156
  # argument from self. Because in the case where self is a superset of the
@@ -187,7 +187,7 @@ module FatCore
187
187
  [(min..isec.min.pred), (isec.max.succ..max)]
188
188
  end
189
189
  end
190
- alias_method :-, :difference
190
+ alias - difference
191
191
 
192
192
  # Allow erb or erubis documents to directly interpolate a Range.
193
193
  #
@@ -297,7 +297,7 @@ module FatCore
297
297
  # @return [Boolean] is self wholly within other
298
298
  def proper_subset_of?(other)
299
299
  subset_of?(other) &&
300
- (min > other.min || max < other.max)
300
+ (min > other.min || max < other.max)
301
301
  end
302
302
 
303
303
  # Return whether self contains `other` range, even if their
@@ -324,8 +324,8 @@ module FatCore
324
324
  # @param other [Range] range to test for overlap with self
325
325
  # @return [Boolean] is there an overlap?
326
326
  def overlaps?(other)
327
- (cover?(other.min) || cover?(other.max) ||
328
- other.cover?(min) || other.cover?(max))
327
+ cover?(other.min) || cover?(other.max) ||
328
+ other.cover?(min) || other.cover?(max)
329
329
  end
330
330
 
331
331
  # Return whether any of the `ranges` that overlap self have overlaps among one
@@ -357,10 +357,10 @@ module FatCore
357
357
  joined_range = joined_range.join(r)
358
358
  break if joined_range.nil?
359
359
  end
360
- if !joined_range.nil?
361
- joined_range.min <= min && joined_range.max >= max
362
- else
360
+ if joined_range.nil?
363
361
  false
362
+ else
363
+ joined_range.min <= min && joined_range.max >= max
364
364
  end
365
365
  end
366
366
 
@@ -58,7 +58,7 @@ module FatCore
58
58
  line_width_so_far = 0
59
59
  words = split(' ')
60
60
  words.each do |w|
61
- w = ::String.new(' ') * hang + w if !first_line && first_word_on_line
61
+ w = (::String.new(' ') * hang) + w if !first_line && first_word_on_line
62
62
  w = ::String.new(' ') + w unless first_word_on_line
63
63
  result << w
64
64
  first_word_on_line = false
@@ -85,13 +85,13 @@ module FatCore
85
85
  r = dup
86
86
  r = r.gsub(/[{]/, 'XzXzXobXzXzX')
87
87
  r = r.gsub(/[}]/, 'XzXzXcbXzXzX')
88
- r = r.gsub(/\\/, '\textbackslash{}')
89
- r = r.gsub(/\^/, '\textasciicircum{}')
90
- r = r.gsub(/~/, '\textasciitilde{}')
91
- r = r.gsub(/\|/, '\textbar{}')
92
- r = r.gsub(/\</, '\textless{}')
93
- r = r.gsub(/\>/, '\textgreater{}')
94
- r = r.gsub(/([_$&%#])/) { |m| '\\' + m }
88
+ r = r.gsub("\\", '\textbackslash{}')
89
+ r = r.gsub("^", '\textasciicircum{}')
90
+ r = r.gsub("~", '\textasciitilde{}')
91
+ r = r.gsub("|", '\textbar{}')
92
+ r = r.gsub("<", '\textless{}')
93
+ r = r.gsub(">", '\textgreater{}')
94
+ r = r.gsub(/([_$&%#])/) { |m| "\\#{m}" }
95
95
  r = r.gsub('XzXzXobXzXzX', '\\{')
96
96
  r.gsub('XzXzXcbXzXzX', '\\}')
97
97
  end
@@ -14,9 +14,9 @@ module FatCore
14
14
  #
15
15
  # @return [String]
16
16
  def as_string
17
- to_s.tr('_', ' ').split(' ').join(' ').entitle
17
+ to_s.tr('_', ' ').split.join(' ').entitle
18
18
  end
19
- alias_method :entitle, :as_string
19
+ alias entitle as_string
20
20
 
21
21
  # Return self. This (together with String#as_sym) allows `#as_sym` to be
22
22
  # applied to a string or Symbol and get back a Symbol with out testing for
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FatCore
4
- MAJOR = 4
5
- MINOR = 17
4
+ MAJOR = 5
5
+ MINOR = 1
6
6
  PATCH = 0
7
7
 
8
8
  # FatCore version number
@@ -8,19 +8,61 @@ describe Array do
8
8
  expect(letters.last_i).to eq(25)
9
9
  end
10
10
 
11
- it 'intersection' do
12
- expect(%w(A A B A C A B).intersect(%w(A B A))).to eq(%w(A A B A A B))
13
- expect(%w(A A B A C A B).intersect(%w(A B))).to eq(%w(A A B A A B))
14
- expect(%w(A A B A C A B).intersect(%w(A))).to eq(%w(A A A A))
15
- expect(%w(A A B A C A B).intersect(%w(B))).to eq(%w(B B))
16
- expect(%w(A A B A C A B).intersect(%w(C))).to eq(%w(C))
17
- end
18
-
19
- it 'difference' do
20
- expect(%w(A A B A C A B).difference(%w(A B A))).to eq(%w(C))
21
- expect(%w(A A B A C A B).difference(%w(A B))).to eq(%w(C))
22
- expect(%w(A A B A C A B).difference(%w(A))).to eq(%w(B C B))
23
- expect(%w(A A B A C A B).difference(%w(B))).to eq(%w(A A A C A))
24
- expect(%w(A A B A C A B).difference(%w(C))).to eq(%w(A A B A A B))
11
+ it 'intersect_with_dups' do
12
+ expect(%w[A A B A C A B].intersect_with_dups(%w[A B A])).to eq(%w[A A B A A B])
13
+ expect(%w[A A B A C A B].intersect_with_dups(%w[A B])).to eq(%w[A A B A A B])
14
+ expect(%w[A A B A C A B].intersect_with_dups(%w[A])).to eq(%w[A A A A])
15
+ expect(%w[A A B A C A B].intersect_with_dups(%w[B])).to eq(%w[B B])
16
+ expect(%w[A A B A C A B].intersect_with_dups(%w[C])).to eq(%w[C])
17
+ end
18
+
19
+ it 'intersect_with_dups multiple' do
20
+ # Include only elements that occur in /all/ other arrays.
21
+ expect(%w[A A B A C A B].intersect_with_dups(%w[A B A], %w[A D F])).to eq(%w[A A A A])
22
+ expect(%w[A A B A C A B].intersect_with_dups(%w[A B A], %w[B D F])).to eq(%w[B B])
23
+ expect(%w[A A B A C A B].intersect_with_dups(%w[A D E F], %w[B D F])).to eq(%w[])
24
+ # expect(%w[A A B A C A B].intersect_with_dups(%w[A B])).to eq(%w[A A B A A B])
25
+ # expect(%w[A A B A C A B].intersect_with_dups(%w[A])).to eq(%w[A A A A])
26
+ # expect(%w[A A B A C A B].intersect_with_dups(%w[B])).to eq(%w[B B])
27
+ # expect(%w[A A B A C A B].intersect_with_dups(%w[C])).to eq(%w[C])
28
+ end
29
+
30
+ it 'diff_with_dups' do
31
+ expect(%w[A A B A C A B].diff_with_dups(%w[A B A])).to eq(%w[C])
32
+ expect(%w[A A B A C A B].diff_with_dups(%w[A B])).to eq(%w[C])
33
+ expect(%w[A A B A C A B].diff_with_dups(%w[A])).to eq(%w[B C B])
34
+ expect(%w[A A B A C A B].diff_with_dups(%w[B])).to eq(%w[A A A C A])
35
+ expect(%w[A A B A C A B].diff_with_dups(%w[C])).to eq(%w[A A B A A B])
36
+ end
37
+
38
+ it 'diff_with_dups multiple' do
39
+ # Include only elements that occur in /none/ of the other arrays.
40
+ expect(%w[A A B A C A B].diff_with_dups(%w[A C], %w[D F])).to eq(%w[B B])
41
+ expect(%w[A A B A C A B].diff_with_dups(%w[A C], %w[D F], %w[B R T])).to eq(%w[])
42
+ expect(%w[A A B A C A B].diff_with_dups(%w[R B])).to eq(%w[A A A C A])
43
+ end
44
+
45
+ it 'comma_join' do
46
+ expect(%w[].comma_join).to eq('')
47
+ expect(%w[A].comma_join).to eq('A')
48
+ expect(%w[A B].comma_join).to eq('A and B')
49
+ expect(%w[A B C].comma_join).to eq('A, B, and C')
50
+ expect([1, 1, 2, 3, 5, 8].comma_join).to eq('1, 1, 2, 3, 5, and 8')
51
+ end
52
+
53
+ it 'comma_join with only sep param' do
54
+ expect(%w[].comma_join(sep: '-')).to eq('')
55
+ expect(%w[A].comma_join(sep: '-')).to eq('A')
56
+ expect(%w[A B].comma_join(sep: '-')).to eq('A-B')
57
+ expect(%w[A B C].comma_join(sep: '-')).to eq('A-B-C')
58
+ expect([1, 1, 2, 3, 5, 8].comma_join(sep: '-')).to eq('1-1-2-3-5-8')
59
+ end
60
+
61
+ it 'comma_join with only last_sep param' do
62
+ expect(%w[].comma_join(last_sep: '*')).to eq('')
63
+ expect(%w[A].comma_join(last_sep: '*')).to eq('A')
64
+ expect(%w[A B].comma_join(last_sep: '*')).to eq('A*B')
65
+ expect(%w[A B C].comma_join(last_sep: '*')).to eq('A, B*C')
66
+ expect([1, 1, 2, 3, 5, 8].comma_join(last_sep: '*')).to eq('1, 1, 2, 3, 5*8')
25
67
  end
26
68
  end
@@ -15,23 +15,29 @@ describe Date do
15
15
  describe 'ensure_date parsing' do
16
16
  it 'parses a String as a date' do
17
17
  expect(described_class.ensure_date('2018-11-12').class).to be described_class
18
+ expect(described_class.ensure('2018-11-12').class).to be described_class
18
19
  end
19
20
 
20
21
  it 'leaves a Date as a date' do
21
22
  expect(described_class.ensure_date(described_class.today).class).to be described_class
23
+ expect(described_class.ensure(described_class.today).class).to be described_class
22
24
  end
23
25
 
24
26
  it 'converts Time as a date' do
25
27
  expect(described_class.ensure_date(Time.now).class).to be described_class
28
+ expect(described_class.ensure(Time.now).class).to be described_class
26
29
  end
27
30
 
28
31
  it 'raises an error for bad date string' do
29
32
  expect { described_class.ensure_date('2012-mm-tu') }.to raise_error(/invalid date/)
33
+ expect { described_class.ensure('2012-mm-tu') }.to raise_error(/invalid date/)
30
34
  end
31
35
 
32
36
  it 'raises an error for unknown class' do
33
37
  expect { described_class.ensure_date([2011, 11, 12]) }
34
38
  .to raise_error(/requires String, Date, DateTime, or Time/)
39
+ expect { described_class.ensure([2011, 11, 12]) }
40
+ .to raise_error(/requires String, Date, DateTime, or Time/)
35
41
  end
36
42
  end
37
43
 
@@ -461,7 +467,7 @@ describe Date do
461
467
  it 'prints itself in org form' do
462
468
  expect(described_class.today.org).to eq('[2012-07-18 Wed]')
463
469
  expect((described_class.today + 1.day).org).to eq('[2012-07-19 Thu]')
464
- expect((described_class.today + 1.day).org(true)).to eq('<2012-07-19 Thu>')
470
+ expect((described_class.today + 1.day).org(active: true)).to eq('<2012-07-19 Thu>')
465
471
  end
466
472
 
467
473
  it 'prints itself in eng form' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fat_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.17.0
4
+ version: 5.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel E. Doherty
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-02 00:00:00.000000000 Z
11
+ date: 2024-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -177,6 +177,7 @@ executables:
177
177
  extensions: []
178
178
  extra_rdoc_files: []
179
179
  files:
180
+ - ".envrc"
180
181
  - ".gitignore"
181
182
  - ".rspec"
182
183
  - ".rubocop.yml"
@@ -224,7 +225,7 @@ licenses:
224
225
  - MIT
225
226
  metadata:
226
227
  yard.run: yri
227
- post_install_message:
228
+ post_install_message:
228
229
  rdoc_options: []
229
230
  require_paths:
230
231
  - lib
@@ -239,8 +240,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
239
240
  - !ruby/object:Gem::Version
240
241
  version: '0'
241
242
  requirements: []
242
- rubygems_version: 3.4.10
243
- signing_key:
243
+ rubygems_version: 3.5.18
244
+ signing_key:
244
245
  specification_version: 4
245
246
  summary: some useful core extensions
246
247
  test_files: []