ndr_support 5.4.2 → 5.7.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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +41 -0
- data/code_safety.yml +55 -39
- data/gemfiles/Gemfile.rails60 +6 -0
- data/lib/ndr_support.rb +3 -0
- data/lib/ndr_support/concerns/working_days.rb +64 -9
- data/lib/ndr_support/date_and_time_extensions.rb +1 -3
- data/lib/ndr_support/daterange.rb +24 -5
- data/lib/ndr_support/integer/working_days.rb +11 -0
- data/lib/ndr_support/string/conversions.rb +3 -4
- data/lib/ndr_support/threat_scanner.rb +64 -0
- data/lib/ndr_support/utf8_encoding.rb +5 -2
- data/lib/ndr_support/utf8_encoding/control_characters.rb +2 -8
- data/lib/ndr_support/version.rb +1 -1
- data/lib/ndr_support/working_days.rb +5 -0
- data/ndr_support.gemspec +5 -5
- data/test/concerns/working_days_test.rb +18 -0
- data/test/daterange_test.rb +44 -0
- data/test/integer/working_days_test.rb +14 -0
- data/test/string/conversions_test.rb +13 -3
- data/test/test_helper.rb +1 -1
- data/test/threat_scanner_test.rb +75 -0
- metadata +33 -22
- data/gemfiles/Gemfile.rails42 +0 -6
- data/gemfiles/Gemfile.rails50 +0 -6
- data/gemfiles/Gemfile.rails51 +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e06c6fad074bb00f7ba16334d194b9fcf369147688dbd1f22dcd1cca86e71073
|
4
|
+
data.tar.gz: 7ede15deb1aec6e6ee02d627437eb7c94810755dbcb717db9212c17c2f09ca3e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f3b03a27b86891d3cb52dcf3fab222cf3bd42b05cb859918142dd6791a6dc18e5ebba0075911d9d177e7451a5b447b0cf6324455641f913ebb86c78808cf5843
|
7
|
+
data.tar.gz: e5d89586818d5a50a1c3211086ce812d485e90b3080c46986be570ec32e7c740f6d5c312a8580ef727243c5910b60d5acd13f8e94276e0fa07dbf922879a9a85
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
## [Unreleased]
|
2
|
+
*no unreleased changes*
|
3
|
+
|
4
|
+
## 5.7.0 / 2020-06-30
|
5
|
+
## Added
|
6
|
+
* Handle three char months in Daterange
|
7
|
+
|
8
|
+
## 5.6.1 / 2020-01-02
|
9
|
+
## Fixed
|
10
|
+
* Fix issue with 2020 public holiday
|
11
|
+
* Support 2021 public holidays
|
12
|
+
* Ensure dateranges up to 2030 are supported
|
13
|
+
|
14
|
+
## 5.6.0 / 2019-08-29
|
15
|
+
### Added
|
16
|
+
* Add `Integer#working_days_since`. (#11)
|
17
|
+
|
18
|
+
## 5.5.1 / 2019-05-15
|
19
|
+
### Fixed
|
20
|
+
* Support Ruby 2.6, Rails 6.0. Minimum Ruby/Rails versions are now 2.5/5.2
|
21
|
+
* Warn when WorkingDays lookup is getting stale
|
22
|
+
* Improved date parsing in `String#to_date`
|
23
|
+
|
24
|
+
## 5.5.0 / 2018-11-16
|
25
|
+
### Added
|
26
|
+
* Add `ThreatScanner` to wrap ClamAV for virus detection (#10)
|
27
|
+
|
28
|
+
### Fixed
|
29
|
+
* Added missing bank holidays for 2017-2019 (#9)
|
30
|
+
|
31
|
+
## 5.4.2 / 2018-08-06
|
32
|
+
### Fixed
|
33
|
+
* Fix Daterange equality comparisons
|
34
|
+
|
35
|
+
## 5.4.1 / 2018-07-09
|
36
|
+
### Fixed
|
37
|
+
* ensure Range#exclude? is available
|
38
|
+
|
39
|
+
## 5.4.0 / 2018-05-09
|
40
|
+
### Added
|
41
|
+
* Support Rails 5.2
|
data/code_safety.yml
CHANGED
@@ -12,8 +12,12 @@ file safety:
|
|
12
12
|
comments: 'diff failed; reviewed whole file. Revision c88f5ac8c12fd657bb142144e0d3afaa7f9bc361:
|
13
13
|
Slack notification secret is public/private key encrypted, so not a disclosure
|
14
14
|
risk. As a secondary protection, it''s excluded from the .gem file by ndr_support.gemspec'
|
15
|
-
reviewed_by:
|
16
|
-
safe_revision:
|
15
|
+
reviewed_by: josh.pencheon
|
16
|
+
safe_revision: 0cfcfac5ddcd721a67dcd23f04cbf6bc2278b922
|
17
|
+
CHANGELOG.md:
|
18
|
+
comments:
|
19
|
+
reviewed_by: ollietulloch
|
20
|
+
safe_revision: ce582c10aa4ddddcd22f907d6228cc7bb324a280
|
17
21
|
CODE_OF_CONDUCT.md:
|
18
22
|
comments:
|
19
23
|
reviewed_by: timgentry
|
@@ -38,42 +42,34 @@ file safety:
|
|
38
42
|
comments:
|
39
43
|
reviewed_by: timgentry
|
40
44
|
safe_revision: e33e9dae7f38bc449ce9276515a539836dbbbd53
|
41
|
-
gemfiles/Gemfile.rails42:
|
42
|
-
comments:
|
43
|
-
reviewed_by: pauleves
|
44
|
-
safe_revision: f76ad0fe72d42b1ff37553c8194935a8b93a6848
|
45
|
-
gemfiles/Gemfile.rails50:
|
46
|
-
comments:
|
47
|
-
reviewed_by: josh.pencheon
|
48
|
-
safe_revision: 55ed1c2a18b9cc4d1d996ee69419f5ee38f87746
|
49
|
-
gemfiles/Gemfile.rails51:
|
50
|
-
comments:
|
51
|
-
reviewed_by: brian.shand
|
52
|
-
safe_revision: 4e87fd9d64fc0f15b359ba60fc48cda54453c647
|
53
45
|
gemfiles/Gemfile.rails52:
|
54
46
|
comments:
|
55
47
|
reviewed_by: josh.pencheon
|
56
48
|
safe_revision: 8a6bedae77d33d0db1b67eaed7972870b6afc993
|
57
|
-
|
49
|
+
gemfiles/Gemfile.rails60:
|
58
50
|
comments:
|
59
51
|
reviewed_by: josh.pencheon
|
60
|
-
safe_revision:
|
52
|
+
safe_revision: 0cfcfac5ddcd721a67dcd23f04cbf6bc2278b922
|
53
|
+
lib/ndr_support.rb:
|
54
|
+
comments:
|
55
|
+
reviewed_by: brian.shand
|
56
|
+
safe_revision: 44fbdf72f47f4022c7dc9148150ebc18589dac8f
|
61
57
|
lib/ndr_support/array.rb:
|
62
58
|
comments:
|
63
59
|
reviewed_by: pauleves
|
64
60
|
safe_revision: 4a4ed24d2cfe7e1736baadf4cf6e0fece6823be1
|
65
61
|
lib/ndr_support/concerns/working_days.rb:
|
66
62
|
comments:
|
67
|
-
reviewed_by:
|
68
|
-
safe_revision:
|
63
|
+
reviewed_by: josh.pencheon
|
64
|
+
safe_revision: fe6c3beff445e3c84ed0c89f08e1ab10bfb00587
|
69
65
|
lib/ndr_support/date_and_time_extensions.rb:
|
70
66
|
comments:
|
71
67
|
reviewed_by: josh.pencheon
|
72
|
-
safe_revision:
|
68
|
+
safe_revision: c1158eccb843b637b4dd82815dc7c081f12b93e4
|
73
69
|
lib/ndr_support/daterange.rb:
|
74
70
|
comments:
|
75
|
-
reviewed_by:
|
76
|
-
safe_revision:
|
71
|
+
reviewed_by: ollietulloch
|
72
|
+
safe_revision: 9a4b8e53f477725c2c2be5000b3c9e66f07d7389
|
77
73
|
lib/ndr_support/hash.rb:
|
78
74
|
comments:
|
79
75
|
reviewed_by: pauleves
|
@@ -90,6 +86,10 @@ file safety:
|
|
90
86
|
comments:
|
91
87
|
reviewed_by: josh.pencheon
|
92
88
|
safe_revision: 2685f35c907af6968a69eabb5ab9424b490d0f40
|
89
|
+
lib/ndr_support/integer/working_days.rb:
|
90
|
+
comments:
|
91
|
+
reviewed_by: josh.pencheon
|
92
|
+
safe_revision: c1158eccb843b637b4dd82815dc7c081f12b93e4
|
93
93
|
lib/ndr_support/nil.rb:
|
94
94
|
comments:
|
95
95
|
reviewed_by: pauleves
|
@@ -132,20 +132,24 @@ file safety:
|
|
132
132
|
safe_revision: 60cc69774d5aff92252558feae9604544def7583
|
133
133
|
lib/ndr_support/string/conversions.rb:
|
134
134
|
comments:
|
135
|
-
reviewed_by:
|
136
|
-
safe_revision:
|
135
|
+
reviewed_by: ollietulloch
|
136
|
+
safe_revision: 9a4b8e53f477725c2c2be5000b3c9e66f07d7389
|
137
137
|
lib/ndr_support/tasks.rb:
|
138
138
|
comments:
|
139
139
|
reviewed_by: timgentry
|
140
140
|
safe_revision: 62337584a32e5c30c2e9af7cd998a9df684885cc
|
141
|
+
lib/ndr_support/threat_scanner.rb:
|
142
|
+
comments:
|
143
|
+
reviewed_by: josh.pencheon
|
144
|
+
safe_revision: ed8ff421cc9353456af13a37049a07ce2545aac1
|
141
145
|
lib/ndr_support/utf8_encoding.rb:
|
142
146
|
comments:
|
143
|
-
reviewed_by:
|
144
|
-
safe_revision:
|
147
|
+
reviewed_by: josh.pencheon
|
148
|
+
safe_revision: 8e024a4bacfd36e172aad4b800f1960faae0b4b6
|
145
149
|
lib/ndr_support/utf8_encoding/control_characters.rb:
|
146
150
|
comments:
|
147
|
-
reviewed_by:
|
148
|
-
safe_revision:
|
151
|
+
reviewed_by: josh.pencheon
|
152
|
+
safe_revision: 8e024a4bacfd36e172aad4b800f1960faae0b4b6
|
149
153
|
lib/ndr_support/utf8_encoding/force_binary.rb:
|
150
154
|
comments:
|
151
155
|
reviewed_by: timgentry
|
@@ -156,28 +160,32 @@ file safety:
|
|
156
160
|
safe_revision: f7adf44fc2772e1926df37abfd9041d41c303328
|
157
161
|
lib/ndr_support/version.rb:
|
158
162
|
comments:
|
159
|
-
reviewed_by:
|
160
|
-
safe_revision:
|
163
|
+
reviewed_by: ollietulloch
|
164
|
+
safe_revision: ce582c10aa4ddddcd22f907d6228cc7bb324a280
|
165
|
+
lib/ndr_support/working_days.rb:
|
166
|
+
comments:
|
167
|
+
reviewed_by: josh.pencheon
|
168
|
+
safe_revision: c1158eccb843b637b4dd82815dc7c081f12b93e4
|
161
169
|
lib/ndr_support/yaml/serialization_migration.rb:
|
162
170
|
comments:
|
163
171
|
reviewed_by: timgentry
|
164
172
|
safe_revision: 29595e6431587ff9b7db6e3ad3abbb3577bff99c
|
165
173
|
ndr_support.gemspec:
|
166
174
|
comments:
|
167
|
-
reviewed_by:
|
168
|
-
safe_revision:
|
175
|
+
reviewed_by: josh.pencheon
|
176
|
+
safe_revision: c685e94ddb1cf2814eb145e87a4c8bc6bced59fb
|
169
177
|
test/array_test.rb:
|
170
178
|
comments:
|
171
179
|
reviewed_by: timgentry
|
172
180
|
safe_revision: 2a5d30674dc9dde336e1dbbbf3c8a98905647432
|
173
181
|
test/concerns/working_days_test.rb:
|
174
182
|
comments:
|
175
|
-
reviewed_by:
|
176
|
-
safe_revision:
|
183
|
+
reviewed_by: josh.pencheon
|
184
|
+
safe_revision: fe6c3beff445e3c84ed0c89f08e1ab10bfb00587
|
177
185
|
test/daterange_test.rb:
|
178
186
|
comments:
|
179
|
-
reviewed_by:
|
180
|
-
safe_revision:
|
187
|
+
reviewed_by: ollietulloch
|
188
|
+
safe_revision: 9a4b8e53f477725c2c2be5000b3c9e66f07d7389
|
181
189
|
test/hash_test.rb:
|
182
190
|
comments:
|
183
191
|
reviewed_by: timgentry
|
@@ -190,6 +198,10 @@ file safety:
|
|
190
198
|
comments:
|
191
199
|
reviewed_by: josh.pencheon
|
192
200
|
safe_revision: 2685f35c907af6968a69eabb5ab9424b490d0f40
|
201
|
+
test/integer/working_days_test.rb:
|
202
|
+
comments:
|
203
|
+
reviewed_by: josh.pencheon
|
204
|
+
safe_revision: c1158eccb843b637b4dd82815dc7c081f12b93e4
|
193
205
|
test/nil_test.rb:
|
194
206
|
comments:
|
195
207
|
reviewed_by: timgentry
|
@@ -232,12 +244,16 @@ file safety:
|
|
232
244
|
safe_revision: 60cc69774d5aff92252558feae9604544def7583
|
233
245
|
test/string/conversions_test.rb:
|
234
246
|
comments:
|
235
|
-
reviewed_by:
|
236
|
-
safe_revision:
|
247
|
+
reviewed_by: ollietulloch
|
248
|
+
safe_revision: 9a4b8e53f477725c2c2be5000b3c9e66f07d7389
|
237
249
|
test/test_helper.rb:
|
238
250
|
comments:
|
239
|
-
reviewed_by:
|
240
|
-
safe_revision:
|
251
|
+
reviewed_by: josh.pencheon
|
252
|
+
safe_revision: 34ae80f2952f0bfd18688541862774cbaaa6c5f5
|
253
|
+
test/threat_scanner_test.rb:
|
254
|
+
comments:
|
255
|
+
reviewed_by: josh.pencheon
|
256
|
+
safe_revision: ed8ff421cc9353456af13a37049a07ce2545aac1
|
241
257
|
test/utf8_encoding/control_characters_test.rb:
|
242
258
|
comments:
|
243
259
|
reviewed_by: timgentry
|
data/lib/ndr_support.rb
CHANGED
@@ -13,6 +13,7 @@ require 'ndr_support/safe_file'
|
|
13
13
|
require 'ndr_support/safe_path'
|
14
14
|
require 'ndr_support/string/cleaning'
|
15
15
|
require 'ndr_support/string/conversions'
|
16
|
+
require 'ndr_support/threat_scanner'
|
16
17
|
require 'ndr_support/utf8_encoding'
|
17
18
|
require 'ndr_support/version'
|
18
19
|
require 'ndr_support/yaml/serialization_migration'
|
@@ -20,3 +21,5 @@ require 'ndr_support/yaml/serialization_migration'
|
|
20
21
|
module NdrSupport
|
21
22
|
# Your code goes here...
|
22
23
|
end
|
24
|
+
|
25
|
+
WorkingDays.check_lookup
|
@@ -3,6 +3,8 @@ require 'active_support/time'
|
|
3
3
|
# This module contains logic for #working_days_until, #weekday?, and #public_holiday?.
|
4
4
|
module WorkingDays
|
5
5
|
WEEK_DAYS = 1..5
|
6
|
+
|
7
|
+
# TODO: could we use https://github.com/alphagov/gds-api-adapters ?
|
6
8
|
HOLIDAYS = [ # Sourced from https://www.gov.uk/bank-holidays
|
7
9
|
# 2012
|
8
10
|
'2012-01-02', # Monday - New Year's Day (substitute day)
|
@@ -50,14 +52,66 @@ module WorkingDays
|
|
50
52
|
'2016-08-29', # Monday - Summer bank holiday
|
51
53
|
'2016-12-26', # Monday - Boxing Day
|
52
54
|
'2016-12-27', # Tuesday - Christmas Day (substitute day)
|
55
|
+
# 2017
|
56
|
+
'2017-01-02', # Monday - New Year's Day
|
57
|
+
'2017-04-14', # Friday - Good Friday
|
58
|
+
'2017-04-17', # Monday - Easter Monday
|
59
|
+
'2017-05-01', # Monday - Early May bank holiday
|
60
|
+
'2017-05-29', # Monday - Spring bank holiday
|
61
|
+
'2017-08-28', # Monday - Summer bank holiday
|
62
|
+
'2017-12-25', # Monday - Christmas Day
|
63
|
+
'2017-12-26', # Tuesday - Boxing Day
|
64
|
+
# 2018
|
65
|
+
'2018-01-01', # Monday - New Year's Day
|
66
|
+
'2018-03-30', # Friday - Good Friday
|
67
|
+
'2018-04-02', # Monday - Easter Monday
|
68
|
+
'2018-05-07', # Monday - Early May bank holiday
|
69
|
+
'2018-05-28', # Monday - Spring bank holiday
|
70
|
+
'2018-08-27', # Monday - Summer bank holiday
|
71
|
+
'2018-12-25', # Tuesday - Christmas Day
|
72
|
+
'2018-12-26', # Wednesday - Boxing Day
|
73
|
+
# 2019
|
74
|
+
'2019-01-01', # Tuesday - New Year's Day
|
75
|
+
'2019-04-19', # Friday - Good Friday
|
76
|
+
'2019-04-22', # Monday - Easter Monday
|
77
|
+
'2019-05-06', # Monday - Early May bank holiday
|
78
|
+
'2019-05-27', # Monday - Spring bank holiday
|
79
|
+
'2019-08-26', # Monday - Summer bank holiday
|
80
|
+
'2019-12-25', # Wednesday - Christmas Day
|
81
|
+
'2019-12-26', # Thursday - Boxing Day
|
82
|
+
# 2020
|
83
|
+
'2020-01-01', # Wednesday - New Year's Day
|
84
|
+
'2020-04-10', # Friday - Good Friday
|
85
|
+
'2020-04-13', # Monday - Easter Monday
|
86
|
+
'2020-05-08', # Friday - Early May bank holiday (moved from Monday)
|
87
|
+
'2020-05-25', # Monday - Spring bank holiday
|
88
|
+
'2020-08-31', # Monday - Summer bank holiday
|
89
|
+
'2020-12-25', # Friday - Christmas Day
|
90
|
+
'2020-12-28', # Monday - Boxing Day (substitute day)
|
91
|
+
# 2021
|
92
|
+
'2021-01-01', # Friday - New Year’s Day
|
93
|
+
'2021-04-02', # Friday - Good Friday
|
94
|
+
'2021-04-05', # Monday - Easter Monday
|
95
|
+
'2021-05-03', # Monday - Early May bank holiday
|
96
|
+
'2021-05-31', # Monday - Spring bank holiday
|
97
|
+
'2021-08-30', # Monday - Summer bank holiday
|
98
|
+
'2021-12-27', # Monday - Christmas Day
|
99
|
+
'2021-12-28', # Tuesday - Boxing Day
|
53
100
|
].map { |str| Date.parse(str) }
|
54
101
|
|
102
|
+
def self.check_lookup
|
103
|
+
return true if HOLIDAYS.max >= 1.year.from_now
|
104
|
+
|
105
|
+
warn "NdrSupport's WorkingDays extension has under a year of future data. Check for updates?"
|
106
|
+
false
|
107
|
+
end
|
108
|
+
|
55
109
|
# How many complete working days there are until the given
|
56
110
|
# `other`. Returns negative number if `other` is earlier.
|
57
111
|
def working_days_until(other)
|
58
112
|
return -other.working_days_until(self) if other < self
|
59
113
|
|
60
|
-
|
114
|
+
count_whole_days_to(other) do |day|
|
61
115
|
day.weekday? && !day.public_holiday?
|
62
116
|
end
|
63
117
|
end
|
@@ -66,7 +120,7 @@ module WorkingDays
|
|
66
120
|
# `other`. Returns negative number if `other` is earlier.
|
67
121
|
def weekdays_until(other)
|
68
122
|
return -other.weekdays_until(self) if other < self
|
69
|
-
|
123
|
+
count_whole_days_to(other, &:weekday?)
|
70
124
|
end
|
71
125
|
|
72
126
|
# Is this a weekday?
|
@@ -81,14 +135,15 @@ module WorkingDays
|
|
81
135
|
|
82
136
|
private
|
83
137
|
|
84
|
-
def
|
85
|
-
|
86
|
-
|
87
|
-
next_day = days.last + 1.day
|
88
|
-
next_day <= other ? days.push(next_day) : break
|
89
|
-
end
|
138
|
+
def count_whole_days_to(other, &block)
|
139
|
+
day = self + 1.day
|
140
|
+
count = 0
|
90
141
|
|
91
|
-
|
142
|
+
while day <= other
|
143
|
+
count += 1 if block.call(day)
|
144
|
+
day += 1.day
|
92
145
|
end
|
146
|
+
|
147
|
+
count
|
93
148
|
end
|
94
149
|
end
|
@@ -6,7 +6,7 @@ require 'ndr_support/integer/julian_date_conversions'
|
|
6
6
|
class Daterange
|
7
7
|
attr_reader :date1, :date2, :source
|
8
8
|
|
9
|
-
OKYEARS = 1880..
|
9
|
+
OKYEARS = 1880..2030
|
10
10
|
|
11
11
|
def self.extract(dates_string)
|
12
12
|
dates_string.to_s.split(',').map { |str| new(str) }
|
@@ -135,12 +135,12 @@ class Daterange
|
|
135
135
|
|
136
136
|
# Update our attribute values using a string representation of the date(s).
|
137
137
|
# +s+ consists of one or more dates separated with spaces.
|
138
|
-
# Each date can be in various formats, e.g. d/m/yyyy, ddmmyyyy, yyyy-mm-dd
|
139
|
-
# Each date can omit days or months, e.g. yyyy, dd/yyyy, yyyy-mm
|
138
|
+
# Each date can be in various formats, e.g. d/m/yyyy, ddmmyyyy, yyyy-mm-dd, dd-mon-yyyy
|
139
|
+
# Each date can omit days or months, e.g. yyyy, dd/yyyy, yyyy-mm, mon-yyyy
|
140
140
|
def source=(s)
|
141
141
|
@source = s
|
142
142
|
ss = s.upcase.sub(/TO/, ' ') # accept default _to_s format
|
143
|
-
if ss =~ /[
|
143
|
+
if ss =~ /[^\w0-9\-\/\. ]/i # only allow letters, digits, hyphen, slash, dot, space
|
144
144
|
@date1 = @date2 = nil
|
145
145
|
else
|
146
146
|
da = [] # temporary array of arrays of dates
|
@@ -184,7 +184,9 @@ class Daterange
|
|
184
184
|
# e.g year only or year/month only) and return an array of 1..3 integers
|
185
185
|
# representing the year, month and day
|
186
186
|
def date_string_parts(ds)
|
187
|
-
if ds =~
|
187
|
+
if ds =~ /\A(\d{1,2}[\/\.\-])?\w{3}[\/\.\-]\d{4}\z/i # dd[-/.]mon[-/.]yyyy or mon[-/.]yyyy
|
188
|
+
result = handle_three_char_months(ds)
|
189
|
+
elsif ds =~ /([\/\.\-])/ # find a slash or dot or hyphen
|
188
190
|
delimiter = $1
|
189
191
|
result = ds.split(delimiter)
|
190
192
|
elsif ds.length == 8 # ddmmyyyy
|
@@ -200,4 +202,21 @@ class Daterange
|
|
200
202
|
result.reverse! unless delimiter == '-' # change to YMD if not ISO format
|
201
203
|
result.collect(&:to_i)
|
202
204
|
end
|
205
|
+
|
206
|
+
def handle_three_char_months(datestring)
|
207
|
+
delimiter = datestring.match(%r{[\/\.\-]})[0]
|
208
|
+
components = datestring.split(delimiter)
|
209
|
+
|
210
|
+
if datestring =~ /\A\d{1,2}#{delimiter}\w{3}#{delimiter}\d{4}\z/i
|
211
|
+
month = abbreviated_month_index_for(components[1])
|
212
|
+
month.nil? ? [] : [components.first, month, components.last]
|
213
|
+
elsif datestring =~ /\A\w{3}#{delimiter}\d{4}\z/i
|
214
|
+
month = abbreviated_month_index_for(components.first)
|
215
|
+
month.nil? ? [] : [month, components.last]
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def abbreviated_month_index_for(string)
|
220
|
+
Date::ABBR_MONTHNAMES.index(string.capitalize)
|
221
|
+
end
|
203
222
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# Mixin for working_days
|
2
|
+
class Integer
|
3
|
+
# Returns a date of the number of working days since a given date
|
4
|
+
def working_days_since(date)
|
5
|
+
times do
|
6
|
+
date = date.next
|
7
|
+
date = date.next while date.public_holiday? || !date.weekday?
|
8
|
+
end
|
9
|
+
date
|
10
|
+
end
|
11
|
+
end
|
@@ -85,7 +85,6 @@ class String
|
|
85
85
|
# Try to convert the string value into a date.
|
86
86
|
# If given a pattern, use it to parse date, otherwise use default setting to parse it
|
87
87
|
def to_date(pattern = nil)
|
88
|
-
return '' if empty? # TODO: check if this is used... :/
|
89
88
|
return nil if blank?
|
90
89
|
|
91
90
|
pattern = '%d%m%Y' if 'ddmmyyyy' == pattern
|
@@ -112,13 +111,13 @@ class String
|
|
112
111
|
|
113
112
|
if ['yyyy/dd/mm', 'mm/dd/yyyy'].include?(pattern)
|
114
113
|
month, day = day, month
|
115
|
-
elsif 8 == length && self
|
114
|
+
elsif 8 == length && self =~ /\A\d{2}[^A-Z0-9]\d{2}[^A-Z0-9]\d{2}\z/i
|
116
115
|
# dd/mm/yy, rather than yyyymmdd
|
117
116
|
year, day = day, year
|
118
117
|
year += 100 if year <= Ourdate.today.year % 100
|
119
118
|
year += 1900
|
120
|
-
elsif 9 == length
|
121
|
-
# dd/
|
119
|
+
elsif 9 == length && self =~ /\A\d{2}[^A-Z0-9][A-Z]{3}[^A-Z0-9]\d{2}\z/i
|
120
|
+
# dd/mon/yy, rare case.
|
122
121
|
year += 100 if year <= Ourdate.today.year % 100
|
123
122
|
year += 1900
|
124
123
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'English'
|
2
|
+
|
3
|
+
# Runs a virus/malware check against the given path, using ClamAV.
|
4
|
+
#
|
5
|
+
# Sample usage:
|
6
|
+
#
|
7
|
+
# # Call with a file object:
|
8
|
+
# ThreatScanner.new(@unknown_tempfile).check!
|
9
|
+
#
|
10
|
+
# # ...or with a path:
|
11
|
+
# ThreatScanner.new('path/to/README').check!
|
12
|
+
#
|
13
|
+
class ThreatScanner
|
14
|
+
class Error < StandardError; end
|
15
|
+
|
16
|
+
class MissingFileError < Error; end
|
17
|
+
class MissingScannerError < Error; end
|
18
|
+
class ScannerOperationError < Error; end
|
19
|
+
class ThreatDetectedError < Error; end
|
20
|
+
|
21
|
+
def self.installed?
|
22
|
+
system('which clamdscan > /dev/null 2>&1')
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_reader :path
|
26
|
+
|
27
|
+
def initialize(path)
|
28
|
+
@path = path.respond_to?(:path) ? path.path : path
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns true if the given file is deemed safe, and false if it could not
|
32
|
+
# be checked. Raises if a threat is detected, or the file did not exist.
|
33
|
+
def check
|
34
|
+
check!
|
35
|
+
rescue MissingScannerError, ScannerOperationError
|
36
|
+
false
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns true if the given file is deemed safe, and raises an exception
|
40
|
+
# otherwise (if the file is unsafe / does not exist / scanner broke etc).
|
41
|
+
def check!
|
42
|
+
check_existence! && check_installed! && run_scanner!
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def check_existence!
|
48
|
+
File.exist?(@path) || raise(MissingFileError, "#{@path} does not exist!")
|
49
|
+
end
|
50
|
+
|
51
|
+
def check_installed!
|
52
|
+
self.class.installed? || raise(MissingScannerError, 'no scanner is available')
|
53
|
+
end
|
54
|
+
|
55
|
+
def run_scanner!
|
56
|
+
`clamdscan --fdpass --quiet #{Shellwords.escape(@path)}`
|
57
|
+
|
58
|
+
case $CHILD_STATUS.exitstatus
|
59
|
+
when 0 then true
|
60
|
+
when 1 then raise(ThreatDetectedError, "possible virus detected at #{@path}!")
|
61
|
+
else raise(ScannerOperationError, 'the scan was unable to complete')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -16,6 +16,9 @@ module UTF8Encoding
|
|
16
16
|
# How should unmappable characters be escaped, when forcing encoding?
|
17
17
|
REPLACEMENT_SCHEME = lambda { |char| '0x' + char.ord.to_s(16).rjust(2, '0') }
|
18
18
|
|
19
|
+
UTF8 = 'UTF-8'.freeze
|
20
|
+
BINARY = 'BINARY'.freeze
|
21
|
+
|
19
22
|
# Returns a new string with valid UTF-8 encoding,
|
20
23
|
# or raises an exception if encoding fails.
|
21
24
|
def ensure_utf8(string, source_encoding = nil)
|
@@ -51,7 +54,7 @@ module UTF8Encoding
|
|
51
54
|
ensure_utf8!(string, source_encoding)
|
52
55
|
rescue UTF8CoercionError
|
53
56
|
# ...before going back-to-basics, and replacing things that don't map:
|
54
|
-
string.encode!(
|
57
|
+
string.encode!(UTF8, BINARY, :fallback => REPLACEMENT_SCHEME)
|
55
58
|
end
|
56
59
|
|
57
60
|
private
|
@@ -60,7 +63,7 @@ module UTF8Encoding
|
|
60
63
|
candidates.detect do |encoding|
|
61
64
|
begin
|
62
65
|
# Attempt to encode as UTF-8 from source `encoding`:
|
63
|
-
string.encode!(
|
66
|
+
string.encode!(UTF8, encoding)
|
64
67
|
# If that worked, we're done; otherwise, move on.
|
65
68
|
string.valid_encoding?
|
66
69
|
rescue EncodingError
|
@@ -5,9 +5,7 @@ module UTF8Encoding
|
|
5
5
|
# escaped, using standard replacement scheme.
|
6
6
|
module ControlCharacters
|
7
7
|
# The range of characters we consider:
|
8
|
-
CONTROL_CHARACTERS = /[\x00-\x1f]|\x7f/
|
9
|
-
# Exceptions that are allowed:
|
10
|
-
ALLOWED_CONTROL_CHARACTERS = %W( \x09 \x0a \x0d )
|
8
|
+
CONTROL_CHARACTERS = /[\x00-\x08]|[\x0b-\x0c]|[\x0e-\x1f]|\x7f/
|
11
9
|
|
12
10
|
# Recursively escape any control characters in `object`.
|
13
11
|
def escape_control_chars_in_object!(object)
|
@@ -31,11 +29,7 @@ module UTF8Encoding
|
|
31
29
|
# Escapes in-place any control characters in `string`, before returning it.
|
32
30
|
def escape_control_chars!(string)
|
33
31
|
string.gsub!(CONTROL_CHARACTERS) do |character|
|
34
|
-
|
35
|
-
character
|
36
|
-
else
|
37
|
-
UTF8Encoding::REPLACEMENT_SCHEME[character]
|
38
|
-
end
|
32
|
+
UTF8Encoding::REPLACEMENT_SCHEME[character]
|
39
33
|
end
|
40
34
|
string
|
41
35
|
end
|
data/lib/ndr_support/version.rb
CHANGED
data/ndr_support.gemspec
CHANGED
@@ -20,19 +20,19 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
21
|
spec.require_paths = ['lib']
|
22
22
|
|
23
|
-
spec.add_dependency 'activerecord', '>=
|
24
|
-
spec.add_dependency 'activesupport', '>=
|
23
|
+
spec.add_dependency 'activerecord', '>= 5.2.0', '< 7'
|
24
|
+
spec.add_dependency 'activesupport', '>= 5.2.0', '< 7'
|
25
25
|
|
26
|
-
spec.add_development_dependency 'bundler'
|
26
|
+
spec.add_development_dependency 'bundler'
|
27
27
|
spec.add_development_dependency 'rake', '~> 10.0'
|
28
28
|
|
29
|
-
spec.required_ruby_version = '>= 2.
|
29
|
+
spec.required_ruby_version = '>= 2.5.0'
|
30
30
|
|
31
31
|
# Avoid std-lib minitest (which has different namespace)
|
32
32
|
spec.add_development_dependency 'minitest', '>= 5.0.0'
|
33
33
|
spec.add_development_dependency 'mocha', '~> 1.1'
|
34
34
|
|
35
|
-
spec.add_development_dependency 'ndr_dev_support', '~>
|
35
|
+
spec.add_development_dependency 'ndr_dev_support', '~> 5.4', '>= 5.4.5'
|
36
36
|
spec.add_development_dependency 'guard'
|
37
37
|
spec.add_development_dependency 'listen', '< 3.1' # Bundle 1.12 should be (but isn't) resolving Ruby 2.1 issue
|
38
38
|
spec.add_development_dependency 'guard-rubocop'
|
@@ -119,4 +119,22 @@ class WorkingDaysTest < Minitest::Test
|
|
119
119
|
assert_equal 253, @normal_time.working_days_until(@normal_time + 1.year)
|
120
120
|
assert_equal 253, @normal_date_time.working_days_until(@normal_date_time + 1.year)
|
121
121
|
end
|
122
|
+
|
123
|
+
test 'against GOV.UK holidays' do
|
124
|
+
require 'net/http'
|
125
|
+
require 'json'
|
126
|
+
|
127
|
+
url = 'https://www.gov.uk/bank-holidays/england-and-wales.json'
|
128
|
+
response = Net::HTTP.get(URI(url))
|
129
|
+
|
130
|
+
events = JSON.parse(response)['events']
|
131
|
+
events.each do |event|
|
132
|
+
event_date = event['date']
|
133
|
+
parsed_date = Date.parse(event_date)
|
134
|
+
|
135
|
+
assert parsed_date.public_holiday?, "#{event_date} should be a public holiday"
|
136
|
+
# next if parsed_date.public_holiday?
|
137
|
+
# puts "'#{event_date}', # #{parsed_date.strftime('%A')} - #{event['title']}"
|
138
|
+
end
|
139
|
+
end
|
122
140
|
end
|
data/test/daterange_test.rb
CHANGED
@@ -63,6 +63,12 @@ class DaterangeTest < Minitest::Test
|
|
63
63
|
assert_equal '1880 2020', dr.source
|
64
64
|
end
|
65
65
|
|
66
|
+
def test_year_range_future
|
67
|
+
s = 2.years.from_now.strftime('%Y')
|
68
|
+
dr = Daterange.new(s)
|
69
|
+
assert_equal s, dr.to_s, "Daterange should support future years up to #{s}"
|
70
|
+
end
|
71
|
+
|
66
72
|
def test_hyphen_month_input_style
|
67
73
|
dr = Daterange.new('2000-05')
|
68
74
|
assert_equal '05.2000', dr.to_s
|
@@ -220,4 +226,42 @@ class DaterangeTest < Minitest::Test
|
|
220
226
|
refute_equal dr1, nil
|
221
227
|
refute_equal dr1, 0
|
222
228
|
end
|
229
|
+
|
230
|
+
def test_three_char_months
|
231
|
+
dr1 = Daterange.new('01-APR-2020')
|
232
|
+
assert_equal '01.04.2020', dr1.date1.to_s
|
233
|
+
assert_equal '01.04.2020', dr1.date2.to_s
|
234
|
+
|
235
|
+
dr2 = Daterange.new('APR-2020')
|
236
|
+
assert_equal '01.04.2020', dr2.date1.to_s
|
237
|
+
assert_equal '30.04.2020', dr2.date2.to_s
|
238
|
+
|
239
|
+
dr3 = Daterange.new('JAN-2020 TO apr-2020')
|
240
|
+
assert_equal '01.01.2020', dr3.date1.to_s
|
241
|
+
assert_equal '30.04.2020', dr3.date2.to_s
|
242
|
+
|
243
|
+
dr4 = Daterange.new('20-JAN-2020 TO 12-Apr-2020')
|
244
|
+
assert_equal '20.01.2020', dr4.date1.to_s
|
245
|
+
assert_equal '12.04.2020', dr4.date2.to_s
|
246
|
+
|
247
|
+
dr5 = Daterange.new('01-BOB-2020')
|
248
|
+
assert_nil dr5.date1
|
249
|
+
assert_nil dr5.date2
|
250
|
+
|
251
|
+
dr6 = Daterange.new('01/APR/2020')
|
252
|
+
assert_equal '01.04.2020', dr6.date1.to_s
|
253
|
+
assert_equal '01.04.2020', dr6.date2.to_s
|
254
|
+
|
255
|
+
dr7 = Daterange.new('APR/2020')
|
256
|
+
assert_equal '01.04.2020', dr7.date1.to_s
|
257
|
+
assert_equal '30.04.2020', dr7.date2.to_s
|
258
|
+
|
259
|
+
dr8 = Daterange.new('JAN/2020 TO apr.2020')
|
260
|
+
assert_equal '01.01.2020', dr8.date1.to_s
|
261
|
+
assert_equal '30.04.2020', dr8.date2.to_s
|
262
|
+
|
263
|
+
dr9 = Daterange.new('20.JAN.2020 TO 12/Apr/2020')
|
264
|
+
assert_equal '20.01.2020', dr9.date1.to_s
|
265
|
+
assert_equal '12.04.2020', dr9.date2.to_s
|
266
|
+
end
|
223
267
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# This tests our Integer working days extension
|
4
|
+
class Integer::WorkingDaysTest < Minitest::Test
|
5
|
+
test 'Integer should be extended with #working_days_since' do
|
6
|
+
assert 1.respond_to?(:working_days_since)
|
7
|
+
end
|
8
|
+
|
9
|
+
test 'Integer#working_days_since should behave correctly' do
|
10
|
+
assert_equal Date.new(2019, 12, 23), 1.working_days_since(Date.new(2019, 12, 20))
|
11
|
+
assert_equal Date.new(2019, 12, 27), 3.working_days_since(Date.new(2019, 12, 20))
|
12
|
+
assert_equal Date.new(2019, 12, 30), 4.working_days_since(Date.new(2019, 12, 20))
|
13
|
+
end
|
14
|
+
end
|
@@ -58,6 +58,10 @@ class String::ConversionsTest < Minitest::Test
|
|
58
58
|
assert_ymd [2001, 3, 2], '02/03/2001'.to_date
|
59
59
|
assert_ymd [2010, 7, 11], '2010-07-11'.to_date
|
60
60
|
|
61
|
+
assert_ymd [2001, 3, 2], '2.3.2001'.to_date
|
62
|
+
assert_ymd [2001, 3, 2], '2/3/2001'.to_date
|
63
|
+
assert_ymd [2010, 7, 11], '2010-7-11'.to_date
|
64
|
+
|
61
65
|
assert_ymd [2001, 2, 3], '2001/02/03'.to_date('yyyy/mm/dd')
|
62
66
|
assert_ymd [2001, 2, 3], '2001/03/02'.to_date('yyyy/dd/mm')
|
63
67
|
assert_ymd [2001, 2, 3], '2001-02-03'.to_date('yyyy-mm-dd')
|
@@ -240,8 +244,8 @@ class String::ConversionsTest < Minitest::Test
|
|
240
244
|
assert_equal Ourdate.build_datetime(1998, 02, 13), '1998-02-13'.to_date('%Y-%m-%d')
|
241
245
|
assert_equal Ourdate.build_datetime(1998, 05, 03), '1998-05-03'.to_date('%Y-%m-%d')
|
242
246
|
|
243
|
-
|
244
|
-
|
247
|
+
assert_nil ''.to_date('%Y-%m-%d') # Should behave like Rails-defined to_date
|
248
|
+
assert_nil ' '.to_date('%Y-%m-%d')
|
245
249
|
end
|
246
250
|
|
247
251
|
test '%d-%m-%Y string to_date' do
|
@@ -307,7 +311,7 @@ class String::ConversionsTest < Minitest::Test
|
|
307
311
|
assert_equal Ourdate.build_datetime(2008, 05, 03), '03/05/08'.to_date
|
308
312
|
end
|
309
313
|
|
310
|
-
test 'inferred dd/
|
314
|
+
test 'inferred dd/mon/yy string to_date' do
|
311
315
|
# pre_epoch
|
312
316
|
assert_equal Ourdate.build_datetime(1945, 02, 13), '13/FEB/45'.to_date
|
313
317
|
assert_equal Ourdate.build_datetime(1945, 06, 03), '03/JUN/45'.to_date
|
@@ -334,6 +338,12 @@ class String::ConversionsTest < Minitest::Test
|
|
334
338
|
assert_equal Ourdate.build_datetime(2008, 05, 03), '03/05/2008 13:38'.to_date
|
335
339
|
end
|
336
340
|
|
341
|
+
test 'incorrectly formatted string to_date' do
|
342
|
+
assert_nil '10-1975'.to_date
|
343
|
+
assert_nil '10.1975A'.to_date
|
344
|
+
assert_nil '10.1975AA'.to_date
|
345
|
+
end
|
346
|
+
|
337
347
|
test 'to_boolean' do
|
338
348
|
assert_equal true, 'true'.to_boolean
|
339
349
|
assert_equal true, 'yes'.to_boolean
|
data/test/test_helper.rb
CHANGED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# This tests our ThreatScanner extension
|
4
|
+
class ThreatScannerTest < Minitest::Test
|
5
|
+
def setup
|
6
|
+
@tempfile = Tempfile.new
|
7
|
+
@scanner = ThreatScanner.new(@tempfile)
|
8
|
+
|
9
|
+
ThreatScanner.stubs(installed?: true)
|
10
|
+
ThreatScanner.any_instance.stubs(:`)
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
@tempfile.close!
|
15
|
+
end
|
16
|
+
|
17
|
+
test 'can be initialised with a file' do
|
18
|
+
assert_equal @tempfile.path, @scanner.path
|
19
|
+
end
|
20
|
+
|
21
|
+
test 'can be initialised with a path' do
|
22
|
+
scanner = ThreatScanner.new(@tempfile.path)
|
23
|
+
assert_equal @tempfile.path, scanner.path
|
24
|
+
end
|
25
|
+
|
26
|
+
test 'returns true if no threat is detected (when being strict)' do
|
27
|
+
Process::Status.any_instance.stubs(exitstatus: 0)
|
28
|
+
assert_equal true, @scanner.check!
|
29
|
+
end
|
30
|
+
|
31
|
+
test 'raises if a threat is detected (when being strict)' do
|
32
|
+
Process::Status.any_instance.stubs(exitstatus: 1)
|
33
|
+
assert_raises(ThreatScanner::ThreatDetectedError) { @scanner.check! }
|
34
|
+
end
|
35
|
+
|
36
|
+
test 'raises if the file does not exist (when being strict)' do
|
37
|
+
@tempfile.close!
|
38
|
+
assert_raises(ThreatScanner::MissingFileError) { @scanner.check! }
|
39
|
+
end
|
40
|
+
|
41
|
+
test 'raises if ClamAV is not installed (when being strict)' do
|
42
|
+
ThreatScanner.stubs(installed?: false)
|
43
|
+
assert_raises(ThreatScanner::MissingScannerError) { @scanner.check! }
|
44
|
+
end
|
45
|
+
|
46
|
+
test 'raises if there is an operational error (when being strict)' do
|
47
|
+
Process::Status.any_instance.stubs(exitstatus: 2)
|
48
|
+
assert_raises(ThreatScanner::ScannerOperationError) { @scanner.check! }
|
49
|
+
end
|
50
|
+
|
51
|
+
test 'returns true if no threat is detected (when being relaxed)' do
|
52
|
+
Process::Status.any_instance.stubs(exitstatus: 0)
|
53
|
+
assert_equal true, @scanner.check
|
54
|
+
end
|
55
|
+
|
56
|
+
test 'raises if a threat is detected (when being relaxed)' do
|
57
|
+
Process::Status.any_instance.stubs(exitstatus: 1)
|
58
|
+
assert_raises(ThreatScanner::ThreatDetectedError) { @scanner.check }
|
59
|
+
end
|
60
|
+
|
61
|
+
test 'raises if the file does not exist (when being relaxed)' do
|
62
|
+
@tempfile.close!
|
63
|
+
assert_raises(ThreatScanner::MissingFileError) { @scanner.check }
|
64
|
+
end
|
65
|
+
|
66
|
+
test 'returns false if ClamAV is not installed (when being relaxed)' do
|
67
|
+
ThreatScanner.stubs(installed?: false)
|
68
|
+
assert_equal false, @scanner.check
|
69
|
+
end
|
70
|
+
|
71
|
+
test 'returns false if there is an operational error (when being relaxed)' do
|
72
|
+
Process::Status.any_instance.stubs(exitstatus: 2)
|
73
|
+
assert_equal false, @scanner.check
|
74
|
+
end
|
75
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ndr_support
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- NCRS Development Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,54 +16,54 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 5.2.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '7'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 5.2.0
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '7'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: activesupport
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
39
|
+
version: 5.2.0
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '
|
42
|
+
version: '7'
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
49
|
+
version: 5.2.0
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version: '
|
52
|
+
version: '7'
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: bundler
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
56
56
|
requirements:
|
57
|
-
- - "
|
57
|
+
- - ">="
|
58
58
|
- !ruby/object:Gem::Version
|
59
|
-
version: '
|
59
|
+
version: '0'
|
60
60
|
type: :development
|
61
61
|
prerelease: false
|
62
62
|
version_requirements: !ruby/object:Gem::Requirement
|
63
63
|
requirements:
|
64
|
-
- - "
|
64
|
+
- - ">="
|
65
65
|
- !ruby/object:Gem::Version
|
66
|
-
version: '
|
66
|
+
version: '0'
|
67
67
|
- !ruby/object:Gem::Dependency
|
68
68
|
name: rake
|
69
69
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,14 +112,20 @@ dependencies:
|
|
112
112
|
requirements:
|
113
113
|
- - "~>"
|
114
114
|
- !ruby/object:Gem::Version
|
115
|
-
version: '
|
115
|
+
version: '5.4'
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: 5.4.5
|
116
119
|
type: :development
|
117
120
|
prerelease: false
|
118
121
|
version_requirements: !ruby/object:Gem::Requirement
|
119
122
|
requirements:
|
120
123
|
- - "~>"
|
121
124
|
- !ruby/object:Gem::Version
|
122
|
-
version: '
|
125
|
+
version: '5.4'
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: 5.4.5
|
123
129
|
- !ruby/object:Gem::Dependency
|
124
130
|
name: guard
|
125
131
|
requirement: !ruby/object:Gem::Requirement
|
@@ -226,6 +232,7 @@ extra_rdoc_files: []
|
|
226
232
|
files:
|
227
233
|
- ".gitignore"
|
228
234
|
- ".rubocop.yml"
|
235
|
+
- CHANGELOG.md
|
229
236
|
- CODE_OF_CONDUCT.md
|
230
237
|
- Gemfile
|
231
238
|
- Guardfile
|
@@ -233,10 +240,8 @@ files:
|
|
233
240
|
- README.md
|
234
241
|
- Rakefile
|
235
242
|
- code_safety.yml
|
236
|
-
- gemfiles/Gemfile.rails42
|
237
|
-
- gemfiles/Gemfile.rails50
|
238
|
-
- gemfiles/Gemfile.rails51
|
239
243
|
- gemfiles/Gemfile.rails52
|
244
|
+
- gemfiles/Gemfile.rails60
|
240
245
|
- lib/ndr_support.rb
|
241
246
|
- lib/ndr_support/array.rb
|
242
247
|
- lib/ndr_support/concerns/working_days.rb
|
@@ -246,6 +251,7 @@ files:
|
|
246
251
|
- lib/ndr_support/integer/calculations.rb
|
247
252
|
- lib/ndr_support/integer/julian_date_conversions.rb
|
248
253
|
- lib/ndr_support/integer/rounding.rb
|
254
|
+
- lib/ndr_support/integer/working_days.rb
|
249
255
|
- lib/ndr_support/nil.rb
|
250
256
|
- lib/ndr_support/obfuscator.rb
|
251
257
|
- lib/ndr_support/ourdate.rb
|
@@ -258,11 +264,13 @@ files:
|
|
258
264
|
- lib/ndr_support/string/cleaning.rb
|
259
265
|
- lib/ndr_support/string/conversions.rb
|
260
266
|
- lib/ndr_support/tasks.rb
|
267
|
+
- lib/ndr_support/threat_scanner.rb
|
261
268
|
- lib/ndr_support/utf8_encoding.rb
|
262
269
|
- lib/ndr_support/utf8_encoding/control_characters.rb
|
263
270
|
- lib/ndr_support/utf8_encoding/force_binary.rb
|
264
271
|
- lib/ndr_support/utf8_encoding/object_support.rb
|
265
272
|
- lib/ndr_support/version.rb
|
273
|
+
- lib/ndr_support/working_days.rb
|
266
274
|
- lib/ndr_support/yaml/serialization_migration.rb
|
267
275
|
- ndr_support.gemspec
|
268
276
|
- test/array_test.rb
|
@@ -271,6 +279,7 @@ files:
|
|
271
279
|
- test/hash_test.rb
|
272
280
|
- test/integer/calculations_test.rb
|
273
281
|
- test/integer/rounding_test.rb
|
282
|
+
- test/integer/working_days_test.rb
|
274
283
|
- test/nil_test.rb
|
275
284
|
- test/obfuscator_test.rb
|
276
285
|
- test/ourdate_test.rb
|
@@ -283,6 +292,7 @@ files:
|
|
283
292
|
- test/string/cleaning_test.rb
|
284
293
|
- test/string/conversions_test.rb
|
285
294
|
- test/test_helper.rb
|
295
|
+
- test/threat_scanner_test.rb
|
286
296
|
- test/utf8_encoding/control_characters_test.rb
|
287
297
|
- test/utf8_encoding/force_binary_test.rb
|
288
298
|
- test/utf8_encoding_test.rb
|
@@ -299,15 +309,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
299
309
|
requirements:
|
300
310
|
- - ">="
|
301
311
|
- !ruby/object:Gem::Version
|
302
|
-
version: 2.
|
312
|
+
version: 2.5.0
|
303
313
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
304
314
|
requirements:
|
305
315
|
- - ">="
|
306
316
|
- !ruby/object:Gem::Version
|
307
317
|
version: '0'
|
308
318
|
requirements: []
|
309
|
-
|
310
|
-
rubygems_version: 2.5.2.3
|
319
|
+
rubygems_version: 3.0.3
|
311
320
|
signing_key:
|
312
321
|
specification_version: 4
|
313
322
|
summary: NDR Support library
|
@@ -318,6 +327,7 @@ test_files:
|
|
318
327
|
- test/hash_test.rb
|
319
328
|
- test/integer/calculations_test.rb
|
320
329
|
- test/integer/rounding_test.rb
|
330
|
+
- test/integer/working_days_test.rb
|
321
331
|
- test/nil_test.rb
|
322
332
|
- test/obfuscator_test.rb
|
323
333
|
- test/ourdate_test.rb
|
@@ -330,6 +340,7 @@ test_files:
|
|
330
340
|
- test/string/cleaning_test.rb
|
331
341
|
- test/string/conversions_test.rb
|
332
342
|
- test/test_helper.rb
|
343
|
+
- test/threat_scanner_test.rb
|
333
344
|
- test/utf8_encoding/control_characters_test.rb
|
334
345
|
- test/utf8_encoding/force_binary_test.rb
|
335
346
|
- test/utf8_encoding_test.rb
|
data/gemfiles/Gemfile.rails42
DELETED
data/gemfiles/Gemfile.rails50
DELETED