fat_core 4.8.0 → 4.9.2

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: bd64293fd2c62f0fc9e089c000b8853e71500fcd14cc3899b45402aa33d237d4
4
- data.tar.gz: fa7909a5eeab9e94a54c389e60257b64a626fc9d572029709509dd044ef2a410
3
+ metadata.gz: c90648dd1bf02d613aa456a276788456ad6db68c388c9d5b77299efcf873d701
4
+ data.tar.gz: 7e1db9a329844c017bbce95086f18b1417015776aedef20645c1b163f16326a7
5
5
  SHA512:
6
- metadata.gz: 43a94a1cdfa9595041ec2076981bca528d4da3824baf8a459fef8c41d44c88441003acfc8b804cb52f1b3fb6dcf7e7d9aa03b2f430b8db72af7d029fdbafa558
7
- data.tar.gz: d8c430838d4b4cb1610b9a1f7ab7cf679df6e828043b452751c0cf5bee58afab5752f5dd9184c4f04397e7e4335953414d6a7025be16ac7e3e10583992f1d3ca
6
+ metadata.gz: 189ba88410e8af0b51da95eb3cf543183584fc692194e4d66838e13dacc927ced464093c9b6410b1dc66b0cad816bd357a38066b39b0389a8f7876dfeb75d5e7
7
+ data.tar.gz: 2cd18de337ca05bb40bfb2e39d1ce86d7ecb6fe476a0d8ce2d8d4a156f877a904afeabe5c57bddcf72eab43b199545289503a8aeeb3fa4e48139020dde832674
data/.gitignore CHANGED
@@ -20,3 +20,4 @@ tmp
20
20
  /GTAGS
21
21
  /.rubocop_todo.yml
22
22
  /gtags.files
23
+ /.ruby-version
data/.rubocop.yml CHANGED
@@ -1,3 +1,16 @@
1
- inherit_from:
2
- - '~/.rubocop.yml'
3
- - '.rubocop_todo.yml'
1
+ inherit_gem:
2
+ rubocop-shopify: rubocop.yml
3
+
4
+ AllCops:
5
+ TargetRubyVersion: 2.7
6
+ Exclude:
7
+ - 'test/tmp/**/*'
8
+ - 'vendor/bundle/**/*'
9
+
10
+ Style/MethodCallWithArgsParentheses:
11
+ Exclude:
12
+ - '**/Gemfile'
13
+
14
+ Style/ClassAndModuleChildren:
15
+ Exclude:
16
+ - 'test/**/*'
data/.travis.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  language: ruby
2
2
  bundler_args: --without debug
3
3
  rvm:
4
- - 2.2.2
5
- - 2.3
6
- - 2.4
7
- - ruby-head
4
+ - 2.5
5
+ - 2.6
6
+ - 2.7
7
+ - 3.0
data/Gemfile CHANGED
@@ -1,5 +1,8 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gem 'damerau-levenshtein', git: 'https://github.com/ddoherty03/damerau-levenshtein'
4
+ gem 'rubocop-shopify', require: false
5
+
3
6
  # Specify your gem's dependencies in fat_core.gemspec
4
7
  gemspec
5
8
 
data/lib/fat_core/all.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'fat_core/array'
2
4
  require 'fat_core/bigdecimal'
3
5
  require 'fat_core/date'
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FatCore
2
4
  module Array
3
5
  # Return the index of the last element of this Array. This is just a
4
6
  # convenience for an oft-needed Array attribute.
5
7
  def last_i
6
- self.size - 1
8
+ size - 1
7
9
  end
8
10
 
9
11
  # Return a new Array that is the intersection of this Array with +other+,
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bigdecimal'
2
4
 
3
5
  module FatCore
data/lib/fat_core/date.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'date'
2
4
  require 'active_support/core_ext/date'
3
5
  require 'active_support/core_ext/time'
@@ -106,7 +108,7 @@ module FatCore
106
108
  # form.
107
109
  # @return [String]
108
110
  def american
109
- strftime '%-m/%-d/%Y'
111
+ strftime('%-m/%-d/%Y')
110
112
  end
111
113
 
112
114
  # :category: Queries
@@ -117,7 +119,7 @@ module FatCore
117
119
  # Self's calendar "half" by analogy to calendar quarters: 1 or 2, depending
118
120
  # on whether the date falls in the first or second half of the calendar
119
121
  # year.
120
- # @return [1, 2]
122
+ # @return [Integer]
121
123
  def half
122
124
  case month
123
125
  when (1..6)
@@ -131,7 +133,7 @@ module FatCore
131
133
 
132
134
  # Self's calendar quarter: 1, 2, 3, or 4, depending on which calendar quarter
133
135
  # the date falls in.
134
- # @return [1, 2, 3, 4]
136
+ # @return [Integer]
135
137
  def quarter
136
138
  case month
137
139
  when (1..3)
@@ -147,7 +149,7 @@ module FatCore
147
149
 
148
150
  # Self's calendar bimonth: 1, 2, 3, 4, 5, or 6 depending on which calendar
149
151
  # bimonth the date falls in.
150
- # @return [1, 2, 3, 4, 5, 6]
152
+ # @return [Integer]
151
153
  def bimonth
152
154
  case month
153
155
  when (1..2)
@@ -497,12 +499,16 @@ module FatCore
497
499
  # :category: Relative ::Dates
498
500
 
499
501
  # Return the date that is the last day of the commercial biweek in which
500
- # self falls. A biweek is a period of two commercial weeks starting with an
501
- # odd-numbered week and with each week starting in Monday and ending on
502
+ # self falls. A biweek is a period of two commercial weeks starting with
503
+ # an odd-numbered week and with each week starting in Monday and ending on
502
504
  # Sunday. So this will always return a Sunday in an even-numbered week.
503
- # @return [::Date]
505
+ # In the last week of the year (if it is not part of next year's first
506
+ # week) the end of the biweek will not extend beyond self's week, so that
507
+ # week 1 of the following year will start a new biweek. @return [::Date]
504
508
  def end_of_biweek
505
- if cweek.odd?
509
+ if cweek >= 52 && end_of_week(:monday).year > year
510
+ end_of_week(:monday)
511
+ elsif cweek.odd?
506
512
  (self + 1.week).end_of_week(:monday)
507
513
  else
508
514
  end_of_week(:monday)
@@ -853,7 +859,8 @@ module FatCore
853
859
  ::Date.parse('2012-12-24'),
854
860
  # And Trump
855
861
  ::Date.parse('2018-12-24'),
856
- ::Date.parse('2019-12-24')
862
+ ::Date.parse('2019-12-24'),
863
+ ::Date.parse('2020-12-24'),
857
864
  ].freeze
858
865
 
859
866
  # Presidential funeral since JFK
@@ -873,7 +880,7 @@ module FatCore
873
880
  # GTF Funeral
874
881
  ::Date.parse('2007-01-02'),
875
882
  # GHWBFuneral
876
- ::Date.parse('2018-12-05')
883
+ ::Date.parse('2018-12-05'),
877
884
  ].freeze
878
885
 
879
886
  # Return whether this date is a United States federal holiday.
@@ -1111,7 +1118,7 @@ module FatCore
1111
1118
  def nyse_workday?
1112
1119
  !nyse_holiday?
1113
1120
  end
1114
- alias trading_day? nyse_workday?
1121
+ alias_method :trading_day?, :nyse_workday?
1115
1122
 
1116
1123
  # Return the date that is n NYSE trading days after or before (if n < 0) this
1117
1124
  # date.
@@ -1130,7 +1137,7 @@ module FatCore
1130
1137
  end
1131
1138
  d
1132
1139
  end
1133
- alias add_trading_days add_nyse_workdays
1140
+ alias_method :add_trading_days, :add_nyse_workdays
1134
1141
 
1135
1142
  # Return the next NYSE trading day after this date. The date returned is always
1136
1143
  # a date at least one day after this date, never this date.
@@ -1139,7 +1146,7 @@ module FatCore
1139
1146
  def next_nyse_workday
1140
1147
  add_nyse_workdays(1)
1141
1148
  end
1142
- alias next_trading_day next_nyse_workday
1149
+ alias_method :next_trading_day, :next_nyse_workday
1143
1150
 
1144
1151
  # Return the last NYSE trading day before this date. The date returned is always
1145
1152
  # a date at least one day before this date, never this date.
@@ -1148,7 +1155,7 @@ module FatCore
1148
1155
  def prior_nyse_workday
1149
1156
  add_nyse_workdays(-1)
1150
1157
  end
1151
- alias prior_trading_day prior_nyse_workday
1158
+ alias_method :prior_trading_day, :prior_nyse_workday
1152
1159
 
1153
1160
  # Return this date if its a trading day, otherwise skip forward to the first
1154
1161
  # later trading day.
@@ -1208,11 +1215,15 @@ module FatCore
1208
1215
  # MLK's Birthday (Third Monday in Jan) since 1998
1209
1216
  year >= 1998 && nth_wday_in_month?(3, 1, 1)
1210
1217
  when 2
1211
- # Lincoln's birthday until 1953
1212
- # Washington's Birthday (Third Monday in Feb)
1213
- (year <= 1953 && month == 2 && day == 12) ||
1214
- (year <= 1970 ? (month == 2 && day == 22)
1215
- : nth_wday_in_month?(3, 1, 2))
1218
+ # Washington's Birthday was celebrated on February 22 until 1970. In
1219
+ # 1971 and later, it was moved to the third Monday in February. Note:
1220
+ # Lincoln's birthday is not an official holiday, but is sometimes
1221
+ # included with Washington's and called "Presidents' Day."
1222
+ if year <= 1970
1223
+ month == 2 && day == 22
1224
+ else
1225
+ nth_wday_in_month?(3, 1, 2)
1226
+ end
1216
1227
  when 3, 4
1217
1228
  # Good Friday
1218
1229
  if !friday?
@@ -1415,7 +1426,7 @@ module FatCore
1415
1426
  #
1416
1427
  # @param spec [String, #to_s] the spec to be interpreted as a calendar period
1417
1428
  #
1418
- # @param spec_type [:from, :to] return the first (:from) or last (:to)
1429
+ # @param spec_type [Symbol, :from, :to] return the first (:from) or last (:to)
1419
1430
  # date in the spec's period respectively
1420
1431
  #
1421
1432
  # @return [::Date] date that is the first (:from) or last (:to) in the period
@@ -1428,11 +1439,12 @@ module FatCore
1428
1439
 
1429
1440
  today = ::Date.current
1430
1441
  case spec.clean
1431
- when %r{\A(\d\d\d\d)[-/](\d\d?)[-/](\d\d?)\z}
1442
+ when %r{\A(?<yr>\d\d\d\d)[-/](?<mo>\d\d?)[-/](?<dy>\d\d?)\z}
1432
1443
  # A specified date
1433
- ::Date.new($1.to_i, $2.to_i, $3.to_i)
1434
- when /\AW(\d\d?)\z/, /\A(\d\d?)W\z/
1435
- week_num = $1.to_i
1444
+ ::Date.new(Regexp.last_match[:yr].to_i, Regexp.last_match[:mo].to_i,
1445
+ Regexp.last_match[:dy].to_i)
1446
+ when /\AW(?<wk>\d\d?)\z/, /\A(?<wk>\d\d?)W\z/
1447
+ week_num = Regexp.last_match[:wk].to_i
1436
1448
  if week_num < 1 || week_num > 53
1437
1449
  raise ArgumentError, "invalid week number (1-53): '#{spec}'"
1438
1450
  end
@@ -1442,9 +1454,9 @@ module FatCore
1442
1454
  else
1443
1455
  ::Date.commercial(today.year, week_num).end_of_week
1444
1456
  end
1445
- when %r{\A(\d\d\d\d)[-/]W(\d\d?)\z}, %r{\A(\d\d\d\d)[-/](\d\d?)W\z}
1446
- year = $1.to_i
1447
- week_num = $2.to_i
1457
+ when %r{\A(?<yr>\d\d\d\d)[-/]W(?<wk>\d\d?)\z}, %r{\A(?<yr>\d\d\d\d)[-/](?<wk>\d\d?)W\z}
1458
+ year = Regexp.last_match[:yr].to_i
1459
+ week_num = Regexp.last_match[:wk].to_i
1448
1460
  if week_num < 1 || week_num > 53
1449
1461
  raise ArgumentError, "invalid week number (1-53): '#{spec}'"
1450
1462
  end
@@ -1454,10 +1466,10 @@ module FatCore
1454
1466
  else
1455
1467
  ::Date.commercial(year, week_num).end_of_week
1456
1468
  end
1457
- when %r{^(\d\d\d\d)[-/](\d)[Qq]$}, %r{^(\d\d\d\d)[-/][Qq](\d)$}
1469
+ when %r{^(?<yr>\d\d\d\d)[-/](?<qt>\d)[Qq]$}, %r{^(?<yr>\d\d\d\d)[-/][Qq](?<qt>\d)$}
1458
1470
  # Year-Quarter
1459
- year = $1.to_i
1460
- quarter = $2.to_i
1471
+ year = Regexp.last_match[:yr].to_i
1472
+ quarter = Regexp.last_match[:qt].to_i
1461
1473
  unless [1, 2, 3, 4].include?(quarter)
1462
1474
  raise ArgumentError, "invalid quarter number (1-4): '#{spec}'"
1463
1475
  end
@@ -1468,10 +1480,10 @@ module FatCore
1468
1480
  else
1469
1481
  ::Date.new(year, month, 1).end_of_quarter
1470
1482
  end
1471
- when /^([1234])[qQ]$/, /^[qQ]([1234])$/
1483
+ when /^(?<qt>[1234])[qQ]$/, /^[qQ](?<qt>[1234])$/
1472
1484
  # Quarter only
1473
1485
  this_year = today.year
1474
- quarter = $1.to_i
1486
+ quarter = Regexp.last_match[:qt].to_i
1475
1487
  unless [1, 2, 3, 4].include?(quarter)
1476
1488
  raise ArgumentError, "invalid quarter number (1-4): '#{spec}'"
1477
1489
  end
@@ -1482,10 +1494,10 @@ module FatCore
1482
1494
  else
1483
1495
  date.end_of_quarter
1484
1496
  end
1485
- when %r{^(\d\d\d\d)[-/](\d)[Hh]$}, %r{^(\d\d\d\d)[-/][Hh](\d)$}
1497
+ when %r{^(?<yr>\d\d\d\d)[-/](?<hf>\d)[Hh]$}, %r{^(?<yr>\d\d\d\d)[-/][Hh](?<hf>\d)$}
1486
1498
  # Year-Half
1487
- year = $1.to_i
1488
- half = $2.to_i
1499
+ year = Regexp.last_match[:yr].to_i
1500
+ half = Regexp.last_match[:hf].to_i
1489
1501
  msg = "invalid half number: '#{spec}'"
1490
1502
  raise ArgumentError, msg unless [1, 2].include?(half)
1491
1503
 
@@ -1495,10 +1507,10 @@ module FatCore
1495
1507
  else
1496
1508
  ::Date.new(year, month, 1).end_of_half
1497
1509
  end
1498
- when /^([12])[hH]$/, /^[hH]([12])$/
1510
+ when /^(?<hf>[12])[hH]$/, /^[hH](?<hf>[12])$/
1499
1511
  # Half only
1500
1512
  this_year = today.year
1501
- half = $1.to_i
1513
+ half = Regexp.last_match[:hf].to_i
1502
1514
  msg = "invalid half number: '#{spec}'"
1503
1515
  raise ArgumentError, msg unless [1, 2].include?(half)
1504
1516
 
@@ -1508,10 +1520,10 @@ module FatCore
1508
1520
  else
1509
1521
  date.end_of_half
1510
1522
  end
1511
- when %r{^(\d\d\d\d)[-/](\d\d?)*$}
1523
+ when %r{^(?<yr>\d\d\d\d)[-/](?<mo>\d\d?)*$}
1512
1524
  # Year-Month only
1513
- year = $1.to_i
1514
- month = $2.to_i
1525
+ year = Regexp.last_match[:yr].to_i
1526
+ month = Regexp.last_match[:mo].to_i
1515
1527
  unless [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].include?(month)
1516
1528
  raise ArgumentError, "invalid month number (1-12): '#{spec}'"
1517
1529
  end
@@ -1521,10 +1533,10 @@ module FatCore
1521
1533
  else
1522
1534
  ::Date.new(year, month, 1).end_of_month
1523
1535
  end
1524
- when %r{^(\d\d?)[-/](\d\d?)*$}
1536
+ when %r{^(?<mo>\d\d?)[-/](?<dy>\d\d?)*$}
1525
1537
  # Month-Day only
1526
- month = $1.to_i
1527
- day = $2.to_i
1538
+ month = Regexp.last_match[:mo].to_i
1539
+ day = Regexp.last_match[:dy].to_i
1528
1540
  unless [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].include?(month)
1529
1541
  raise ArgumentError, "invalid month number (1-12): '#{spec}'"
1530
1542
  end
@@ -1534,9 +1546,9 @@ module FatCore
1534
1546
  else
1535
1547
  ::Date.new(today.year, month, day).end_of_month
1536
1548
  end
1537
- when /\A(\d\d?)\z/
1549
+ when /\A(?<mo>\d\d?)\z/
1538
1550
  # Month only
1539
- month = $1.to_i
1551
+ month = Regexp.last_match[:mo].to_i
1540
1552
  unless [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].include?(month)
1541
1553
  raise ArgumentError, "invalid month number (1-12): '#{spec}'"
1542
1554
  end
@@ -1546,12 +1558,13 @@ module FatCore
1546
1558
  else
1547
1559
  ::Date.new(today.year, month, 1).end_of_month
1548
1560
  end
1549
- when /^(\d\d\d\d)$/
1561
+ when /^(?<yr>\d\d\d\d)$/
1550
1562
  # Year only
1563
+ year = Regexp.last_match[:yr].to_i
1551
1564
  if spec_type == :from
1552
- ::Date.new($1.to_i, 1, 1)
1565
+ ::Date.new(year, 1, 1)
1553
1566
  else
1554
- ::Date.new($1.to_i, 12, 31)
1567
+ ::Date.new(year, 12, 31)
1555
1568
  end
1556
1569
  when /^(to|this_?)?day/
1557
1570
  today
@@ -1675,6 +1688,43 @@ module FatCore
1675
1688
  end
1676
1689
  end
1677
1690
 
1691
+ # Return the 1-indexed integer that corresponds to a month name.
1692
+ #
1693
+ # @param name [String] a name of a month
1694
+ #
1695
+ # @return [Integer] the integer integer that corresponds to a month
1696
+ # name, or nil of no month recognized.
1697
+ def mo_name_to_num(name)
1698
+ case name.clean
1699
+ when /\Ajan/i
1700
+ 1
1701
+ when /\Afeb/i
1702
+ 2
1703
+ when /\Amar/i
1704
+ 3
1705
+ when /\Aapr/i
1706
+ 4
1707
+ when /\Amay/i
1708
+ 5
1709
+ when /\Ajun/i
1710
+ 6
1711
+ when /\Ajul/i
1712
+ 7
1713
+ when /\Aaug/i
1714
+ 8
1715
+ when /\Asep/i
1716
+ 9
1717
+ when /\Aoct/i
1718
+ 10
1719
+ when /\Anov/i
1720
+ 11
1721
+ when /\Adec/i
1722
+ 12
1723
+ else
1724
+ nil
1725
+ end
1726
+ end
1727
+
1678
1728
  # Return the nth weekday in the given month. If n is negative, count from
1679
1729
  # last day of month.
1680
1730
  #
@@ -1740,8 +1790,8 @@ module FatCore
1740
1790
  # Ensure that date is of class Date based either on a string or Date
1741
1791
  # object.
1742
1792
  #
1743
- # @param dat [String|Date|Time] the object to be converted to Date
1744
- # @return [Date]
1793
+ # @param dat [String, Date, Time] the object to be converted to Date
1794
+ # @return [Date, DateTime]
1745
1795
  def ensure_date(dat)
1746
1796
  case dat
1747
1797
  when String
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerable
2
4
  # Yield items in groups of n, for each group yield the group number, starting
3
5
  # with zero and an Array of n items, or all remaining items if less than n.
@@ -8,7 +10,10 @@ module Enumerable
8
10
  # end
9
11
  def groups_of(num)
10
12
  k = -1
11
- group_by { k += 1; k.div(num) }
13
+ group_by do
14
+ k += 1
15
+ k.div(num)
16
+ end
12
17
  end
13
18
 
14
19
  # Yield each item together with two booleans that indicate whether the item is
data/lib/fat_core/hash.rb CHANGED
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
1
4
  # The FatCore extensions to Hash provide a handful of generally useful methods
2
5
  # on Ruby Hash objects.
3
6
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'fat_core/numeric'
2
4
 
3
5
  module Kernel
data/lib/fat_core/nil.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FatCore
2
4
  module NilClass
3
5
  # Allow nils to respond to #as_string like String and Symbol
@@ -6,7 +8,7 @@ module FatCore
6
8
  def as_string
7
9
  ''
8
10
  end
9
- alias entitle as_string
11
+ alias_method :entitle, :as_string
10
12
 
11
13
  # Allow nils to respond to #tex_quote for use in TeX documents
12
14
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'fat_core/patches'
2
4
  require 'active_support/core_ext/object/blank'
3
5
 
@@ -74,11 +76,11 @@ module FatCore
74
76
  end
75
77
 
76
78
  # Break the number into parts; underscores are possible in all components.
77
- str =~ /\A([-+])?([\d_]*)((\.)?([\d_]*))?([eE][+-]?[\d_]+)?\z/
78
- sig = $1 || ''
79
- whole = $2 ? $2.delete('_') : ''
80
- frac = $5 || ''
81
- exp = $6 || ''
79
+ str =~ /\A(?<sg>[-+])?(?<wh>[\d_]*)((\.)?(?<fr>[\d_]*))?(?<ex>x[eE][+-]?[\d_]+)?\z/
80
+ sig = Regexp.last_match[:sg] || ''
81
+ whole = Regexp.last_match[:wh] ? Regexp.last_match[:wh].delete('_') : ''
82
+ frac = Regexp.last_match[:fr] || ''
83
+ exp = Regexp.last_match[:ex] || ''
82
84
 
83
85
  # Pad out the fractional part with zeroes to the right
84
86
  unless places.nil?
@@ -133,12 +135,13 @@ module FatCore
133
135
  mins, secs = divmod(60)
134
136
  hrs, mins = mins.divmod(60)
135
137
  if frac.round(5) > 0.0
136
- '%02<hrs>d:%02<mins>d:%02<secs>d.%<frac>d' % { hrs: hrs,
137
- mins: mins, secs: secs,
138
- frac: frac.round(5) * 100 }
138
+ format('%02<hrs>d:%02<mins>d:%02<secs>d.%<frac>d',
139
+ { hrs: hrs,
140
+ mins: mins, secs: secs,
141
+ frac: frac.round(5) * 100 })
139
142
  else
140
- '%02<hrs>d:%02<mins>d:%02<secs>d' % { hrs: hrs, mins: mins,
141
- secs: secs }
143
+ format('%02<hrs>d:%02<mins>d:%02<secs>d',
144
+ { hrs: hrs, mins: mins, secs: secs })
142
145
  end
143
146
  end
144
147
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Provide #positive? and #negative? for older versions of Ruby.
2
4
  unless 2.respond_to?(:positive?)
3
5
  # Patch Numeric
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # FatCore extends the Range class with methods that
2
4
  #
3
5
  # 1. provide some set operations operations on Ranges, union, intersection, and
@@ -130,7 +132,7 @@ module FatCore
130
132
 
131
133
  ([min, other.min].max..[max, other.max].min)
132
134
  end
133
- alias & intersection
135
+ alias_method :&, :intersection
134
136
 
135
137
  # Return a Range that represents the union between this range and the
136
138
  # `other` range. If there is no overlap and self is not contiguous with
@@ -148,36 +150,44 @@ module FatCore
148
150
 
149
151
  ([min, other.min].min..[max, other.max].max)
150
152
  end
151
- alias + union
153
+ alias_method :+, :union
152
154
 
153
155
  # The difference method, -, removes the overlapping part of the other
154
156
  # argument from self. Because in the case where self is a superset of the
155
157
  # other range, this will result in the difference being two non-contiguous
156
158
  # ranges, this returns an array of ranges. If there is no overlap or if
157
159
  # self is a subset of the other range, return an array of self
160
+ #
161
+ # @param other [Range] the Range whose overlap is removed from self
162
+ # @return [Array<Range>] the Ranges representing self with other removed
158
163
  def difference(other)
159
164
  unless max.respond_to?(:succ) && min.respond_to?(:pred) &&
160
165
  other.max.respond_to?(:succ) && other.min.respond_to?(:pred)
161
166
  raise 'Range difference requires objects have pred and succ methods'
162
167
  end
163
168
 
164
- if subset_of?(other)
165
- # (4..7) - (0..10)
166
- []
167
- elsif proper_superset_of?(other)
168
- # (4..7) - (5..5) -> [(4..4), (6..7)]
169
- [(min..other.min.pred), (other.max.succ..max)]
170
- elsif overlaps?(other) && other.min <= min
171
- # (4..7) - (2..5) -> (6..7)
172
- [(other.max.succ..max)]
173
- elsif overlaps?(other) && other.max >= max
174
- # (4..7) - (6..10) -> (4..5)
175
- [(min..other.min.pred)]
169
+ # Remove the intersection of self and other from self. The intersection
170
+ # is either (a) empty, so return self, (b) coincides with self, so
171
+ # return nothing,
172
+ isec = self & other
173
+ return [self] if isec.nil?
174
+ return [] if isec == self
175
+
176
+ # (c) touches self on the right, (d) touches self on the left, or (e)
177
+ # touches on neither the left or right, in which case the difference is
178
+ # two ranges.
179
+ if isec.max == max && isec.min > min
180
+ # Return the part to the left of isec
181
+ [(min..isec.min.pred)]
182
+ elsif isec.min == min && isec.max < max
183
+ # Return the part to the right of isec
184
+ [(isec.max.succ..max)]
176
185
  else
177
- [self]
186
+ # Return the parts to the left and right of isec
187
+ [(min..isec.min.pred), (isec.max.succ..max)]
178
188
  end
179
189
  end
180
- alias - difference
190
+ alias_method :-, :difference
181
191
 
182
192
  # Allow erb or erubis documents to directly interpolate a Range.
183
193
  #
@@ -280,13 +290,14 @@ module FatCore
280
290
  min >= other.min && max <= other.max
281
291
  end
282
292
 
283
- # Return whether self is contained within `other` range, without their
284
- # boundaries touching.
293
+ # Return whether self is contained within `other` range, with at most one
294
+ # boundary touching.
285
295
  #
286
296
  # @param other [Range] the containing range
287
297
  # @return [Boolean] is self wholly within other
288
298
  def proper_subset_of?(other)
289
- min > other.min && max < other.max
299
+ subset_of?(other) &&
300
+ (min > other.min || max < other.max)
290
301
  end
291
302
 
292
303
  # Return whether self contains `other` range, even if their
@@ -298,13 +309,14 @@ module FatCore
298
309
  min <= other.min && max >= other.max
299
310
  end
300
311
 
301
- # Return whether self contains `other` range, without their
302
- # boundaries touching.
312
+ # Return whether self contains `other` range, with at most one
313
+ # boundary touching.
303
314
  #
304
315
  # @param other [Range] the contained range
305
316
  # @return [Boolean] does self wholly contain other
306
317
  def proper_superset_of?(other)
307
- min < other.min && max > other.max
318
+ superset_of?(other) &&
319
+ (min < other.min || max > other.max)
308
320
  end
309
321
 
310
322
  # Return whether self overlaps with other Range.
@@ -368,7 +380,7 @@ module FatCore
368
380
  # (4..8) <=> (4..8) #=> 0
369
381
  #
370
382
  # @param other [Range] range to compare self with
371
- # @return [-1, 0, 1] if self is less, equal, or greater than other
383
+ # @return [Integer, -1, 0, 1] if self is less, equal, or greater than other
372
384
  def <=>(other)
373
385
  [min, max] <=> other.minmax
374
386
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bigdecimal'
2
4
  require 'fat_core/patches'
3
5
  require 'damerau-levenshtein'
@@ -49,14 +51,14 @@ module FatCore
49
51
  #
50
52
  # @return [String] self wrapped
51
53
  def wrap(width = 70, hang = 0)
52
- result = ''
54
+ result = ::String.new
53
55
  first_line = true
54
56
  first_word_on_line = true
55
57
  line_width_so_far = 0
56
58
  words = split(' ')
57
59
  words.each do |w|
58
- w = ' ' * hang + w if !first_line && first_word_on_line
59
- w = ' ' + w unless first_word_on_line
60
+ w = ::String.new(' ') * hang + w if !first_line && first_word_on_line
61
+ w = ::String.new(' ') + w unless first_word_on_line
60
62
  result << w
61
63
  first_word_on_line = false
62
64
  line_width_so_far += 1 + w.length
@@ -104,8 +106,10 @@ module FatCore
104
106
  #
105
107
  # @return [Date] the translated Date
106
108
  def as_date
107
- if self =~ %r{(\d\d\d\d)[-/]?(\d\d?)[-/]?(\d\d?)}
108
- ::Date.new($1.to_i, $2.to_i, $3.to_i)
109
+ if self =~ %r{(?<yr>\d\d\d\d)[-/]?(?<mo>\d\d?)[-/]?(?<dy>\d\d?)}
110
+ ::Date.new(Regexp.last_match[:yr].to_i,
111
+ Regexp.last_match[:mo].to_i,
112
+ Regexp.last_match[:dy].to_i)
109
113
  end
110
114
  end
111
115
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'fat_core/string'
2
4
 
3
5
  module FatCore
@@ -14,7 +16,7 @@ module FatCore
14
16
  def as_string
15
17
  to_s.tr('_', ' ').split(' ').join(' ').entitle
16
18
  end
17
- alias entitle as_string
19
+ alias_method :entitle, :as_string
18
20
 
19
21
  # Return self. This (together with String#as_sym) allows `#as_sym` to be
20
22
  # applied to a string or Symbol and get back a Symbol with out testing for
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FatCore
2
4
  MAJOR = 4
3
- MINOR = 8
4
- PATCH = 0
5
+ MINOR = 9
6
+ PATCH = 2
5
7
 
6
8
  # FatCore version number
7
9
  VERSION = [MAJOR, MINOR, PATCH].compact.join('.')
@@ -1,3 +1,4 @@
1
+ require 'spec_helper'
1
2
  require 'fat_core/bigdecimal'
2
3
 
3
4
  describe BigDecimal do
@@ -1,6 +1,6 @@
1
1
  # coding: utf-8
2
- #require 'spec_helper'
3
2
 
3
+ require 'spec_helper'
4
4
  require 'fat_core/date'
5
5
 
6
6
  describe Date do
@@ -425,6 +425,22 @@ describe Date do
425
425
  expect(Date.parse_spec('forever', :to)).to eq Date::EOT
426
426
  expect(Date.parse_spec('never')).to be_nil
427
427
  end
428
+
429
+ it 'should be able to convert a month name into its sequential number' do
430
+ expect(Date.mo_name_to_num(' January')).to eq 1
431
+ expect(Date.mo_name_to_num(' feb ')).to eq 2
432
+ expect(Date.mo_name_to_num(' mAr ')).to eq 3
433
+ expect(Date.mo_name_to_num(' Aprol ')).to eq 4
434
+ expect(Date.mo_name_to_num("\t \tmaybe")).to eq 5
435
+ expect(Date.mo_name_to_num("\t \tjunta\t \t")).to eq 6
436
+ expect(Date.mo_name_to_num("\t \tjulia\t \t")).to eq 7
437
+ expect(Date.mo_name_to_num("\t \tAugustus\t \t")).to eq 8
438
+ expect(Date.mo_name_to_num("September")).to eq 9
439
+ expect(Date.mo_name_to_num("octagon")).to eq 10
440
+ expect(Date.mo_name_to_num(" novena this month")).to eq 11
441
+ expect(Date.mo_name_to_num("decimal")).to eq 12
442
+ expect(Date.mo_name_to_num(" dewey decimal")).to be nil
443
+ end
428
444
  end
429
445
  end
430
446
 
@@ -577,6 +593,10 @@ describe Date do
577
593
  .to eq Date.parse('2013-11-17')
578
594
  expect(Date.parse('2013-03-11')).to be_beginning_of_biweek
579
595
  expect(Date.parse('2013-03-24')).to be_end_of_biweek
596
+ expect(Date.parse('2013-12-30').end_of_biweek)
597
+ .to eq Date.parse('2014-01-12')
598
+ expect(Date.parse('2009-12-30').end_of_biweek)
599
+ .to eq Date.parse('2010-01-03')
580
600
  end
581
601
 
582
602
  it 'should know about weeks' do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
-
3
2
  require 'fat_core/enumerable'
4
3
 
5
4
  describe Enumerable do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
-
3
2
  require 'fat_core/hash'
4
3
 
5
4
  describe Hash do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
-
3
2
  require 'fat_core/kernel'
4
3
 
5
4
  describe Kernel do
data/spec/lib/nil_spec.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
-
3
2
  require 'fat_core/nil'
4
3
 
5
4
  describe NilClass do
@@ -1,3 +1,4 @@
1
+ require 'spec_helper'
1
2
  require 'fat_core/numeric'
2
3
 
3
4
  describe Numeric do
@@ -1,3 +1,4 @@
1
+ require 'spec_helper'
1
2
  require 'fat_core/range'
2
3
 
3
4
  describe Range do
@@ -12,6 +13,7 @@ describe Range do
12
13
 
13
14
  it 'should know if it is a proper subset of another range' do
14
15
  expect((4..8)).to be_proper_subset_of((2..9))
16
+ expect((4..8)).to be_proper_subset_of((4..9))
15
17
  expect((4..8)).not_to be_proper_subset_of((4..8))
16
18
  expect((4..8)).not_to be_proper_subset_of((2..7))
17
19
  expect((4..8)).not_to be_proper_subset_of((5..8))
@@ -34,8 +36,8 @@ describe Range do
34
36
 
35
37
  it 'should know if it is a proper superset of another range' do
36
38
  expect((4..8)).to be_proper_superset_of((5..7))
37
- expect((4..8)).not_to be_proper_superset_of((6..8))
38
- expect((4..8)).not_to be_proper_superset_of((4..7))
39
+ expect((4..8)).to be_proper_superset_of((6..8))
40
+ expect((4..8)).to be_proper_superset_of((4..7))
39
41
  expect((4..8)).not_to be_proper_superset_of((4..8))
40
42
  expect((4..8)).not_to be_proper_superset_of((2..9))
41
43
  expect((4..8)).not_to be_proper_superset_of((2..8))
@@ -1,3 +1,4 @@
1
+ require 'spec_helper'
1
2
  require 'fat_core/symbol'
2
3
 
3
4
  describe Symbol 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.8.0
4
+ version: 4.9.2
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: 2020-03-08 00:00:00.000000000 Z
11
+ date: 2021-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: simplecov
@@ -218,7 +218,7 @@ licenses:
218
218
  - MIT
219
219
  metadata:
220
220
  yard.run: yri
221
- post_install_message:
221
+ post_install_message:
222
222
  rdoc_options: []
223
223
  require_paths:
224
224
  - lib
@@ -233,8 +233,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
233
233
  - !ruby/object:Gem::Version
234
234
  version: '0'
235
235
  requirements: []
236
- rubygems_version: 3.0.3
237
- signing_key:
236
+ rubygems_version: 3.2.3
237
+ signing_key:
238
238
  specification_version: 4
239
239
  summary: fat_core provides some useful core extensions
240
240
  test_files: