fat_core 4.11.0 → 4.12.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8607195b8f5ef6d04df1f438fbd59d3a22ca3a730d0d5bb9430ff37166d07174
4
- data.tar.gz: e86aedc2aafebf6fc02efdf6f3f35f39ad93059b08a8bc4e635190e5964f2942
3
+ metadata.gz: a4634231d8dd0ed3baf9fd4d232e3e40adb777008b6b8299a5b5574466e10637
4
+ data.tar.gz: 4d8a1e46fa3e5ebb1014dedd75b801210921aa87ba1e01dba779cc62b4d01ca2
5
5
  SHA512:
6
- metadata.gz: 94983a4893c2c4882b360236f488c3a741ea8927488a69785ae4a7cc8f93612e11aa1f6899b359fcc2bb25742d6f062d3c76f5cbd75dfc64c24edba44be45755
7
- data.tar.gz: 9700b48e6c73ec9ec49ed7da22679b4ea90676be71011b4c4c912cb4b53c2d613bb1712b8c59f440990570a33ffe12ab51ec0986ace906638408b3bab85f59d9
6
+ metadata.gz: 0d83fd2e04a0c1a466ae1ba75fcb888621a76ddfc9fa9f1cb78c1d05d3f1493bd347fd21e96f9f94ce14c8ddf9886ca98bbc32efc7c3f72200e9920a1dce4f49
7
+ data.tar.gz: 8de95683c4f0f969b7778dfce4e1235b2cd9838ebab6125880a3bdd099c631274f7f23e98a4e82696cb8ac50da8071383fc4d5eea5d4ce749c38a79ae399e2da
data/.rubocop.yml CHANGED
@@ -1,19 +1,25 @@
1
- inherit_gem:
2
- rubocop-shopify: rubocop.yml
1
+ inherit_from:
2
+ - ~/.rubocop.yml
3
3
 
4
- AllCops:
5
- TargetRubyVersion: 2.7
6
- Exclude:
7
- - 'test/tmp/**/*'
8
- - 'vendor/bundle/**/*'
4
+ # inherit_gem:
5
+ # rubocop-shopify: rubocop.yml
9
6
 
10
- Style/MethodCallWithArgsParentheses:
11
- Exclude:
12
- - '**/Gemfile'
7
+ # require:
8
+ # - rubocop-rspec
13
9
 
14
- Style/ClassAndModuleChildren:
15
- Exclude:
16
- - 'test/**/*'
10
+ # AllCops:
11
+ # TargetRubyVersion: 2.7
12
+ # Exclude:
13
+ # - 'test/tmp/**/*'
14
+ # - 'vendor/bundle/**/*'
17
15
 
18
- Style/StringLiterals:
19
- Enabled: false
16
+ # Style/MethodCallWithArgsParentheses:
17
+ # Exclude:
18
+ # - '**/Gemfile'
19
+
20
+ # Style/ClassAndModuleChildren:
21
+ # Exclude:
22
+ # - 'test/**/*'
23
+
24
+ # Style/StringLiterals:
25
+ # Enabled: false
data/fat_core.gemspec CHANGED
@@ -1,16 +1,20 @@
1
1
  # coding: utf-8
2
2
 
3
- lib = File.expand_path('../lib', __FILE__)
4
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require 'fat_core/version'
3
+ require_relative 'lib/fat_core/version'
6
4
 
7
5
  Gem::Specification.new do |spec|
8
6
  spec.name = 'fat_core'
9
7
  spec.version = FatCore::VERSION
10
8
  spec.authors = ['Daniel E. Doherty']
11
9
  spec.email = ['ded@ddoherty.net']
12
- spec.summary = 'fat_core provides some useful core extensions'
13
- spec.description = 'Useful extensions to Date, String, Range and other classes'
10
+ spec.summary = 'some useful core extensions'
11
+ spec.description = <<~DESC
12
+ Useful extensions to Date, String, Range and other classes
13
+ including useful Date extensions for dealing with US Federal
14
+ and New York Stock Exchange holidays and working days, a useful
15
+ Enumerable#each_with_flags for flagging first and last items in the
16
+ iteration, (also for Hash), set operations on Ranges
17
+ DESC
14
18
  spec.homepage = 'https://github.com/ddoherty03/fat_core.git'
15
19
  spec.license = 'MIT'
16
20
  spec.required_ruby_version = '>= 2.2.2'
data/lib/fat_core/date.rb CHANGED
@@ -119,6 +119,17 @@ module FatCore
119
119
 
120
120
  # :category: Queries
121
121
 
122
+ # Number of days in self's month
123
+ # @return [Integer]
124
+ def days_in_month
125
+ self.class.days_in_month(year, month)
126
+ end
127
+
128
+ # :category: Queries
129
+ # @group Queries
130
+
131
+ # :category: Queries
132
+
122
133
  # Self's calendar "half" by analogy to calendar quarters: 1 or 2, depending
123
134
  # on whether the date falls in the first or second half of the calendar
124
135
  # year.
@@ -357,10 +368,30 @@ module FatCore
357
368
  # @param from_date [::Date] the middle of the six-month range
358
369
  # @return [Boolean]
359
370
  def within_6mos_of?(from_date)
360
- # ::Date 6 calendar months before self
361
- start_date = self - 6.months + 2.days
362
- end_date = self + 6.months - 2.days
363
- (start_date..end_date).cover?(from_date)
371
+ from_date = Date.parse(from_date) unless from_date.is_a?(Date)
372
+ from_day = from_date.day
373
+ if [28, 29, 30, 31].include?(from_day)
374
+ # Near the end of the month, we need to make sure that when we go
375
+ # forward or backwards 6 months, we do not go past the end of the
376
+ # destination month when finding the "corresponding" day in that
377
+ # month, per Stella v. Graham Page Motors. This refinement was
378
+ # endorsed in the Jammies International case. After we find the
379
+ # corresponding day in the target month, then add two days (for the
380
+ # month six months before the from_date) or subtract two days (for the
381
+ # month six months after the from_date) to get the first and last days
382
+ # of the "within a period of less than six months" date range.
383
+ start_month = from_date.beginning_of_month - 6.months
384
+ start_days = start_month.days_in_month
385
+ start_date = ::Date.new(start_month.year, start_month.month, [start_days, from_day].min) + 2.days
386
+ end_month = from_date.beginning_of_month + 6.months
387
+ end_days = end_month.days_in_month
388
+ end_date = ::Date.new(end_month.year, end_month.month, [end_days, from_day].min) - 2.days
389
+ else
390
+ # ::Date 6 calendar months before self
391
+ start_date = from_date - 6.months + 2.days
392
+ end_date = from_date + 6.months - 2.days
393
+ end
394
+ (start_date..end_date).cover?(self)
364
395
  end
365
396
 
366
397
  # Return whether this date is Easter Sunday for the year in which it falls
@@ -1002,6 +1033,9 @@ module FatCore
1002
1033
  if mon == 1 && mday == 1
1003
1034
  # New Years (January 1),
1004
1035
  true
1036
+ elsif mon == 6 && mday == 19 && year >= 2021
1037
+ # Juneteenth,
1038
+ true
1005
1039
  elsif mon == 7 && mday == 4
1006
1040
  # Independence Day (July 4),
1007
1041
  true
@@ -4,6 +4,7 @@ require 'bigdecimal'
4
4
  require 'fat_core/patches'
5
5
  require 'damerau-levenshtein'
6
6
  require 'active_support/core_ext/regexp'
7
+ require_relative 'numeric'
7
8
 
8
9
  module FatCore
9
10
  module String
@@ -245,8 +246,9 @@ module FatCore
245
246
  #
246
247
  # 1. Remove all periods, commas, apostrophes, and asterisks (the punctuation
247
248
  # characters) from both self and `matcher`,
248
- # 2. Treat internal ':' in the matcher as the equivalent of '.*' in a
249
- # regular expression, that is, match anything in self,
249
+ # 2. Treat internal ':stuff' in the matcher as the equivalent of
250
+ # '\bstuff.*?\b' in a regular expression, that is, match any word
251
+ # starting with stuff in self,
250
252
  # 3. Treat leading ':' in the matcher as anchoring the match to the
251
253
  # beginning of the target string,
252
254
  # 4. Treat ending ':' in the matcher as anchoring the match to the
@@ -278,7 +280,7 @@ module FatCore
278
280
  end
279
281
  target = gsub(/[\*.,']/, '')
280
282
  matchers = matcher.split(/[: ]+/)
281
- regexp_string = matchers.map { |m| ".*?\\b#{Regexp.escape(m)}.*?" }.join('[: ]')
283
+ regexp_string = matchers.map { |m| ".*?\\b#{Regexp.escape(m)}.*?" }.join('\\b')
282
284
  regexp_string.sub!(/^\.\*\?/, '')
283
285
  regexp_string.sub!(/\.\*\?$/, '')
284
286
  regexp_string.sub!(/\A/, '\\A') if begin_anchor
@@ -364,70 +366,7 @@ module FatCore
364
366
  numeric_re = /\A([-+])?([\d_]*)((\.)?([\d_]*))?([eE][+-]?[\d_]+)?\z/
365
367
  return self unless clean =~ numeric_re
366
368
 
367
- sig = $1 || ''
368
- whole = $2 ? $2.delete('_') : ''
369
- frac = $5 || ''
370
- exp = $6 || ''
371
-
372
- # Round frac or whole if places given. For positve places, round fraction
373
- # to that many places; for negative, round the whole-number part to the
374
- # absolute value of places left of the decimal.
375
- if places
376
- new_frac = frac.dup
377
- new_whole = whole.dup
378
- if places.zero?
379
- new_frac = ''
380
- elsif places.positive? && places < frac.length
381
- new_frac = frac[0...places - 1]
382
- new_frac[places - 1] =
383
- if frac[places].to_i >= 5
384
- (frac[places - 1].to_i + 1).to_s
385
- else
386
- frac[places - 1]
387
- end
388
- elsif places >= frac.length
389
- new_frac = frac + '0' * (places - frac.length)
390
- else
391
- # Negative places, round whole to places.abs from decimal
392
- places = places.abs
393
- if places > whole.length
394
- lead = whole[0].to_i >= 5 ? '1' : '0'
395
- new_whole[0] = places == whole.length + 1 ? lead : '0'
396
- new_whole[1..-1] = '0' * (places - 1)
397
- new_frac = ''
398
- elsif places > 1
399
- target = whole.length - places
400
- new_whole[target] =
401
- if whole[target + 1].to_i >= 5
402
- (whole[target].to_i + 1).to_s
403
- else
404
- whole[target]
405
- end
406
- new_whole[target + 1..whole.length - 1] =
407
- '0' * (whole.length - target - 1)
408
- new_frac = ''
409
- else
410
- # Rounding to 1 place, therefore, no rounding
411
- new_frac = ''
412
- new_whole = whole
413
- end
414
- end
415
- frac = new_frac
416
- whole = new_whole
417
- end
418
-
419
- # Place the commas in the whole part only
420
- whole = whole.reverse
421
- whole.gsub!(/([0-9]{3})/, '\\1,')
422
- whole.gsub!(/,$/, '')
423
- whole.reverse!
424
-
425
- # Reassemble
426
- if frac.blank?
427
- sig + whole + exp
428
- else
429
- sig + whole + '.' + frac + exp
430
- end
369
+ to_f.commas(places)
431
370
  end
432
371
 
433
372
  module ClassMethods
@@ -2,8 +2,8 @@
2
2
 
3
3
  module FatCore
4
4
  MAJOR = 4
5
- MINOR = 11
6
- PATCH = 0
5
+ MINOR = 12
6
+ PATCH = 1
7
7
 
8
8
  # FatCore version number
9
9
  VERSION = [MAJOR, MINOR, PATCH].compact.join('.')
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  require 'fat_core/array'
4
4
 
5
5
  describe Array do
6
- it 'should be able to report its last index' do
6
+ it 'reports its last index' do
7
7
  letters = ('a'..'z').to_a
8
8
  expect(letters.last_i).to eq(25)
9
9
  end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
  require 'fat_core/bigdecimal'
3
3
 
4
4
  describe BigDecimal do
5
- it 'should provide a human-readable inspect for BigDecimal' do
5
+ it 'provides a human-readable inspect for BigDecimal' do
6
6
  expect(BigDecimal('33.45').inspect).to eq '33.45'
7
7
  end
8
8
  end