edtf 3.2.0 → 3.3.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 +4 -4
- data/.github/workflows/ci.yml +9 -6
- data/.gitignore +1 -1
- data/Gemfile +9 -11
- data/LICENSE +1 -1
- data/README.md +3 -2
- data/Rakefile +6 -33
- data/features/step_definitions/edtf_steps.rb +60 -58
- data/lib/edtf/interval.rb +18 -15
- data/lib/edtf/parser.rb +766 -655
- data/lib/edtf/parser.y +37 -5
- data/lib/edtf/version.rb +1 -1
- data/spec/edtf/interval_spec.rb +153 -6
- data/spec/edtf/set_spec.rb +25 -0
- metadata +4 -9
- data/.autotest +0 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e91fb341cfc4a8bc2ba77ed40f51240510578ef0c535b8b7ae44812328d69cdf
|
|
4
|
+
data.tar.gz: 89af7cf2bdfb4dfdd644d88a4765f2cd7487e479ee8f75bcea75d0da7e42b83d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 48847ec7463218a2fd6b505271da96471b0341e5e88c5cd11ff302fd636040f580dc2a78be5c1c22f33b225e93ffecf6a3dda9d9e4fa5e5ff998636e936c3e0d
|
|
7
|
+
data.tar.gz: 1fbe3d006b3a72cf21a4c4ca07a5933b888a32c221158f32230f1011e159583c79fea5e8d8d00b1b1b434ecdf36cbc2b59b5e5d02b8b73124f26d3f51d79c11c
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -13,16 +13,19 @@ jobs:
|
|
|
13
13
|
|
|
14
14
|
strategy:
|
|
15
15
|
matrix:
|
|
16
|
+
coverage:
|
|
17
|
+
- false
|
|
16
18
|
ruby-version:
|
|
17
|
-
- '
|
|
18
|
-
- '3.0'
|
|
19
|
-
- '3.1'
|
|
19
|
+
- '3.3'
|
|
20
20
|
- '3.2'
|
|
21
21
|
- 'jruby'
|
|
22
|
+
include:
|
|
23
|
+
- ruby-version: '4.0'
|
|
24
|
+
coverage: true
|
|
22
25
|
|
|
23
26
|
steps:
|
|
24
27
|
- name: Git checkout
|
|
25
|
-
uses: actions/checkout@
|
|
28
|
+
uses: actions/checkout@v7
|
|
26
29
|
|
|
27
30
|
- name: Setup Ruby
|
|
28
31
|
uses: ruby/setup-ruby@v1
|
|
@@ -34,8 +37,8 @@ jobs:
|
|
|
34
37
|
run: bundle exec rake
|
|
35
38
|
|
|
36
39
|
- name: Upload coverage results
|
|
37
|
-
if: matrix.
|
|
40
|
+
if: matrix.coverage
|
|
38
41
|
continue-on-error: true
|
|
39
|
-
uses: coverallsapp/github-action@
|
|
42
|
+
uses: coverallsapp/github-action@v2
|
|
40
43
|
with:
|
|
41
44
|
github-token: ${{ github.token }}
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
source 'https://rubygems.org'
|
|
2
2
|
gemspec
|
|
3
3
|
|
|
4
|
-
group :
|
|
5
|
-
|
|
4
|
+
group :coverage do
|
|
5
|
+
platforms :mri do
|
|
6
|
+
gem 'simplecov'
|
|
7
|
+
gem 'simplecov-lcov'
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
group :debug, optional: true do
|
|
12
|
+
gem 'debug', '>= 1.0.0', require: false
|
|
6
13
|
end
|
|
7
14
|
|
|
8
15
|
group :development do
|
|
@@ -10,13 +17,4 @@ group :development do
|
|
|
10
17
|
gem 'racc'
|
|
11
18
|
gem 'cucumber'
|
|
12
19
|
gem 'rspec'
|
|
13
|
-
gem 'simplecov', platform: 'mri'
|
|
14
|
-
gem 'simplecov-lcov', platform: 'mri'
|
|
15
20
|
end
|
|
16
|
-
|
|
17
|
-
group :extra do
|
|
18
|
-
gem 'ZenTest'
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# active_support requires this
|
|
22
|
-
gem 'i18n'
|
data/LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -28,9 +28,10 @@ overlaps (version 3.x and 4.x are supported).
|
|
|
28
28
|
|
|
29
29
|
### ISO 8601-2
|
|
30
30
|
|
|
31
|
-
A variation of EDTF
|
|
31
|
+
A variation of EDTF has been adopted by the ISO 8601-2 standard. EDTF-Ruby
|
|
32
32
|
does not support this new version of EDTF yet, but if you are curious,
|
|
33
|
-
[EDTF.js](https://github.com/inukshuk/edtf.js), an ES6 implementation
|
|
33
|
+
[EDTF.js](https://github.com/inukshuk/edtf.js), an ES6 implementation
|
|
34
|
+
is already available.
|
|
34
35
|
|
|
35
36
|
Quickstart
|
|
36
37
|
----------
|
data/Rakefile
CHANGED
|
@@ -1,21 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
require '
|
|
3
|
-
begin
|
|
4
|
-
Bundler.setup
|
|
5
|
-
rescue Bundler::BundlerError => e
|
|
6
|
-
$stderr.puts e.message
|
|
7
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
|
8
|
-
exit e.status_code
|
|
9
|
-
end
|
|
1
|
+
require 'bundler/gem_tasks'
|
|
2
|
+
require 'rake/clean'
|
|
10
3
|
|
|
11
4
|
$:.unshift(File.join(File.dirname(__FILE__), './lib'))
|
|
12
5
|
require 'edtf/version'
|
|
13
6
|
|
|
14
|
-
require 'rake/clean'
|
|
15
|
-
|
|
16
7
|
task :default => [:spec, :cucumber]
|
|
17
8
|
|
|
18
|
-
desc 'Run an IRB session with
|
|
9
|
+
desc 'Run an IRB session with EDTF loaded'
|
|
19
10
|
task :console, [:script] do |t,args|
|
|
20
11
|
ARGV.clear
|
|
21
12
|
|
|
@@ -28,12 +19,12 @@ end
|
|
|
28
19
|
|
|
29
20
|
desc 'Generates the parser'
|
|
30
21
|
task :racc do
|
|
31
|
-
|
|
22
|
+
sh 'bundle exec racc -o lib/edtf/parser.rb lib/edtf/parser.y'
|
|
32
23
|
end
|
|
33
24
|
|
|
34
25
|
desc 'Generates the parser with debug information'
|
|
35
26
|
task :racc_debug do
|
|
36
|
-
|
|
27
|
+
sh 'bundle exec racc -v -t -o lib/edtf/parser.rb lib/edtf/parser.y'
|
|
37
28
|
end
|
|
38
29
|
|
|
39
30
|
require 'rspec/core'
|
|
@@ -45,24 +36,6 @@ end
|
|
|
45
36
|
require 'cucumber/rake/task'
|
|
46
37
|
Cucumber::Rake::Task.new(:cucumber)
|
|
47
38
|
|
|
48
|
-
desc 'Builds the gem file'
|
|
49
|
-
task :build => [:check_warnings] do
|
|
50
|
-
system 'gem build edtf.gemspec'
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
task :check_warnings do
|
|
54
|
-
$VERBOSE = true
|
|
55
|
-
require 'edtf'
|
|
56
|
-
puts EDTF::VERSION
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
task :release => [ :build] do
|
|
60
|
-
system "git tag #{EDTF::VERSION}"
|
|
61
|
-
system "git push --tags"
|
|
62
|
-
system "gem push edtf-#{EDTF::VERSION}.gem"
|
|
63
|
-
end
|
|
64
|
-
|
|
65
39
|
CLEAN.include('lib/edtf/parser.rb')
|
|
66
40
|
CLEAN.include('lib/edtf/parser.output')
|
|
67
|
-
|
|
68
|
-
CLEAN.include('**/*.rbc')
|
|
41
|
+
CLOBBER.include('pkg')
|
|
@@ -1,148 +1,150 @@
|
|
|
1
|
-
Given
|
|
1
|
+
Given('the date {string}') do |date|
|
|
2
2
|
@date = Date.parse(date)
|
|
3
|
-
@date.precision = precision unless precision.nil?
|
|
4
3
|
end
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
Given('the date {string} with precision set to {string}') do |date, precision|
|
|
6
|
+
@date = Date.parse(date)
|
|
7
|
+
@date.precision = precision
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
When('I convert the date') do
|
|
7
11
|
@string = @date.edtf
|
|
8
12
|
end
|
|
9
13
|
|
|
10
|
-
Then
|
|
14
|
+
Then('the EDTF string should be {string}') do |edtf|
|
|
11
15
|
expect(@string).to eq(edtf)
|
|
12
16
|
end
|
|
13
17
|
|
|
14
|
-
When
|
|
18
|
+
When('I parse the string {string}') do |string|
|
|
15
19
|
@date = EDTF.parse!(string)
|
|
16
20
|
end
|
|
17
21
|
|
|
18
|
-
Then
|
|
22
|
+
Then('the year should be {string}') do |year|
|
|
19
23
|
expect(@date.year).to eq(year.to_i)
|
|
20
24
|
end
|
|
21
25
|
|
|
22
|
-
Then
|
|
26
|
+
Then('the month should be {string}') do |month|
|
|
23
27
|
expect(@date.month).to eq(month.to_i)
|
|
24
28
|
end
|
|
25
29
|
|
|
26
|
-
Then
|
|
30
|
+
Then('the day should be {string}') do |day|
|
|
27
31
|
expect(@date.day).to eq(day.to_i)
|
|
28
32
|
end
|
|
29
33
|
|
|
30
|
-
Then
|
|
34
|
+
Then('the hours should be {string}') do |hours|
|
|
31
35
|
expect(@date.hour).to eq(hours.to_i)
|
|
32
36
|
end
|
|
33
37
|
|
|
34
|
-
Then
|
|
38
|
+
Then('the year should be {string} \(UTC)') do |year|
|
|
35
39
|
expect(@date.to_time.utc.year).to eq(year.to_i)
|
|
36
40
|
end
|
|
37
41
|
|
|
38
|
-
Then
|
|
42
|
+
Then('the month should be {string} \(UTC)') do |month|
|
|
39
43
|
expect(@date.to_time.utc.month).to eq(month.to_i)
|
|
40
44
|
end
|
|
41
45
|
|
|
42
|
-
Then
|
|
46
|
+
Then('the day should be {string} \(UTC)') do |day|
|
|
43
47
|
expect(@date.to_time.utc.day).to eq(day.to_i)
|
|
44
48
|
end
|
|
45
49
|
|
|
46
|
-
Then
|
|
50
|
+
Then('the hours should be {string} \(UTC)') do |hours|
|
|
47
51
|
expect(@date.to_time.utc.hour).to eq(hours.to_i)
|
|
48
52
|
end
|
|
49
53
|
|
|
50
|
-
|
|
51
|
-
Then /^the minutes should be "([^"]*)"$/ do |minutes|
|
|
54
|
+
Then('the minutes should be {string}') do |minutes|
|
|
52
55
|
expect(@date.min).to eq(minutes.to_i)
|
|
53
56
|
end
|
|
54
57
|
|
|
55
|
-
Then
|
|
58
|
+
Then('the seconds should be {string}') do |seconds|
|
|
56
59
|
expect(@date.sec).to eq(seconds.to_i)
|
|
57
60
|
end
|
|
58
61
|
|
|
59
|
-
Then
|
|
60
|
-
expect([@date.begin.year.to_s, @date.end.year.to_s]).to eq([from,to])
|
|
62
|
+
Then('the duration should range from {string} to {string}') do |from, to|
|
|
63
|
+
expect([@date.begin.year.to_s, @date.end.year.to_s]).to eq([from, to])
|
|
61
64
|
end
|
|
62
65
|
|
|
63
|
-
Then
|
|
66
|
+
Then('the interval should start at {string}') do |date|
|
|
64
67
|
expect(@date.begin.to_s).to eq(date)
|
|
65
68
|
end
|
|
66
69
|
|
|
67
|
-
Then
|
|
70
|
+
Then('the interval should end at {string}') do |date|
|
|
68
71
|
expect(@date.end.to_s).to eq(date)
|
|
69
72
|
end
|
|
70
73
|
|
|
71
|
-
Then
|
|
74
|
+
Then('the interval should include the date {string}') do |date|
|
|
72
75
|
expect(@date).to include(Date.parse(date))
|
|
73
76
|
end
|
|
74
77
|
|
|
75
|
-
Then
|
|
78
|
+
Then('the interval should cover the date {string}') do |date|
|
|
76
79
|
expect(@date).to be_cover(Date.parse(date))
|
|
77
80
|
end
|
|
78
81
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
expect(@date.uncertain?).to eq(!!(arg1 =~ /y(es)?/i))
|
|
82
|
+
Then('the date should be uncertain? {string}') do |answer|
|
|
83
|
+
expect(@date.uncertain?).to eq(!!(answer =~ /y(es)?/i))
|
|
82
84
|
end
|
|
83
85
|
|
|
84
|
-
Then
|
|
85
|
-
expect(@date.uncertain?(:year)).to eq(!!(
|
|
86
|
+
Then('the year should be uncertain? {string}') do |answer|
|
|
87
|
+
expect(@date.uncertain?(:year)).to eq(!!(answer =~ /y(es)?/i))
|
|
86
88
|
end
|
|
87
89
|
|
|
88
|
-
Then
|
|
89
|
-
expect(@date.uncertain?(:month)).to eq(!!(
|
|
90
|
+
Then('the month should be uncertain? {string}') do |answer|
|
|
91
|
+
expect(@date.uncertain?(:month)).to eq(!!(answer =~ /y(es)?/i))
|
|
90
92
|
end
|
|
91
93
|
|
|
92
|
-
Then
|
|
93
|
-
expect(@date.uncertain?(:day)).to eq(!!(
|
|
94
|
+
Then('the day should be uncertain? {string}') do |answer|
|
|
95
|
+
expect(@date.uncertain?(:day)).to eq(!!(answer =~ /y(es)?/i))
|
|
94
96
|
end
|
|
95
97
|
|
|
96
|
-
Then
|
|
97
|
-
expect(@date.approximate?).to eq(!!(
|
|
98
|
+
Then('the date should be approximate? {string}') do |answer|
|
|
99
|
+
expect(@date.approximate?).to eq(!!(answer =~ /y(es)?/i))
|
|
98
100
|
end
|
|
99
101
|
|
|
100
|
-
Then
|
|
101
|
-
expect(@date.approximate?(:year)).to eq(!!(
|
|
102
|
+
Then('the year should be approximate? {string}') do |answer|
|
|
103
|
+
expect(@date.approximate?(:year)).to eq(!!(answer =~ /y(es)?/i))
|
|
102
104
|
end
|
|
103
105
|
|
|
104
|
-
Then
|
|
105
|
-
expect(@date.approximate?(:month)).to eq(!!(
|
|
106
|
+
Then('the month should be approximate? {string}') do |answer|
|
|
107
|
+
expect(@date.approximate?(:month)).to eq(!!(answer =~ /y(es)?/i))
|
|
106
108
|
end
|
|
107
109
|
|
|
108
|
-
Then
|
|
109
|
-
expect(@date.approximate?(:day)).to eq(!!(
|
|
110
|
+
Then('the day should be approximate? {string}') do |answer|
|
|
111
|
+
expect(@date.approximate?(:day)).to eq(!!(answer =~ /y(es)?/i))
|
|
110
112
|
end
|
|
111
113
|
|
|
112
|
-
Then
|
|
114
|
+
Then('the result should be an Unknown') do
|
|
113
115
|
expect(@date).to be_an(EDTF::Unknown)
|
|
114
116
|
end
|
|
115
117
|
|
|
116
|
-
Then
|
|
117
|
-
expect(@date.unspecified.to_s).to eq(
|
|
118
|
+
Then('the unspecified string code be {string}') do |code|
|
|
119
|
+
expect(@date.unspecified.to_s).to eq(code)
|
|
118
120
|
end
|
|
119
121
|
|
|
120
|
-
When
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
When('I parse the following strings an error should be raised:') do |table|
|
|
123
|
+
table.raw.each do |row|
|
|
124
|
+
expect { Date.edtf!(row[0]) }.to raise_error(ArgumentError)
|
|
125
|
+
end
|
|
124
126
|
end
|
|
125
127
|
|
|
126
|
-
When
|
|
127
|
-
|
|
128
|
+
When('the year is uncertain: {string}') do |answer|
|
|
129
|
+
@date.uncertain!(:year) if answer =~ /y(es)?/i
|
|
128
130
|
end
|
|
129
131
|
|
|
130
|
-
When
|
|
131
|
-
|
|
132
|
+
When('the month is uncertain: {string}') do |answer|
|
|
133
|
+
@date.uncertain!(:month) if answer =~ /y(es)?/i
|
|
132
134
|
end
|
|
133
135
|
|
|
134
|
-
When
|
|
135
|
-
|
|
136
|
+
When('the day is uncertain: {string}') do |answer|
|
|
137
|
+
@date.uncertain!(:day) if answer =~ /y(es)?/i
|
|
136
138
|
end
|
|
137
139
|
|
|
138
|
-
When
|
|
139
|
-
|
|
140
|
+
When('the year is approximate: {string}') do |answer|
|
|
141
|
+
@date.approximate!(:year) if answer =~ /y(es)?/i
|
|
140
142
|
end
|
|
141
143
|
|
|
142
|
-
When
|
|
143
|
-
|
|
144
|
+
When('the month is approximate: {string}') do |answer|
|
|
145
|
+
@date.approximate!(:month) if answer =~ /y(es)?/i
|
|
144
146
|
end
|
|
145
147
|
|
|
146
|
-
When
|
|
147
|
-
|
|
148
|
+
When('the day is approximate {string}') do |answer|
|
|
149
|
+
@date.approximate!(:day) if answer =~ /y(es)?/i
|
|
148
150
|
end
|
data/lib/edtf/interval.rb
CHANGED
|
@@ -37,7 +37,7 @@ module EDTF
|
|
|
37
37
|
|
|
38
38
|
def from=(date)
|
|
39
39
|
case date
|
|
40
|
-
when Date, :unknown
|
|
40
|
+
when Date, :unknown, :open
|
|
41
41
|
@from = date
|
|
42
42
|
else
|
|
43
43
|
throw ArgumentError.new("Intervals cannot start with: #{date}")
|
|
@@ -54,6 +54,15 @@ module EDTF
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
[:open, :unknown].each do |method_name|
|
|
57
|
+
define_method("#{method_name}_start!") do
|
|
58
|
+
@from = method_name
|
|
59
|
+
self
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
define_method("#{method_name}_start?") do
|
|
63
|
+
@from == method_name
|
|
64
|
+
end
|
|
65
|
+
|
|
57
66
|
define_method("#{method_name}_end!") do
|
|
58
67
|
@to = method_name
|
|
59
68
|
self
|
|
@@ -64,16 +73,8 @@ module EDTF
|
|
|
64
73
|
end
|
|
65
74
|
end
|
|
66
75
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def unknown_start?
|
|
71
|
-
from == :unknown
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def unknown_start!
|
|
75
|
-
@from = :unknown
|
|
76
|
-
self
|
|
76
|
+
def open?
|
|
77
|
+
open_start? || open_end?
|
|
77
78
|
end
|
|
78
79
|
|
|
79
80
|
def unknown?
|
|
@@ -83,12 +84,12 @@ module EDTF
|
|
|
83
84
|
# Returns the intervals precision. Mixed precisions are currently not
|
|
84
85
|
# supported; in that case, the start date's precision takes precedence.
|
|
85
86
|
def precision
|
|
86
|
-
min
|
|
87
|
+
min&.precision || max&.precision
|
|
87
88
|
end
|
|
88
89
|
|
|
89
90
|
# Returns true if the precisions of start and end date are not the same.
|
|
90
91
|
def mixed_precision?
|
|
91
|
-
min
|
|
92
|
+
min&.precision != max&.precision
|
|
92
93
|
end
|
|
93
94
|
|
|
94
95
|
def each(&block)
|
|
@@ -170,6 +171,8 @@ module EDTF
|
|
|
170
171
|
max.day_precision! == other
|
|
171
172
|
when unknown_end?
|
|
172
173
|
min.day_precision! == other
|
|
174
|
+
when open_start?
|
|
175
|
+
max.day_precision! >= other
|
|
173
176
|
when open_end?
|
|
174
177
|
min.day_precision! <= other
|
|
175
178
|
else
|
|
@@ -216,7 +219,7 @@ module EDTF
|
|
|
216
219
|
to_a.min(&block)
|
|
217
220
|
else
|
|
218
221
|
case
|
|
219
|
-
when unknown_start?, !unknown_end? && !open? && to < from
|
|
222
|
+
when open_start?, unknown_start?, !(open_end? || unknown_end?) && !open? && to < from
|
|
220
223
|
nil
|
|
221
224
|
when from.day_precision?
|
|
222
225
|
from
|
|
@@ -249,7 +252,7 @@ module EDTF
|
|
|
249
252
|
to_a.max(&block)
|
|
250
253
|
else
|
|
251
254
|
case
|
|
252
|
-
when open_end?, unknown_end?, !unknown_start? && to < from
|
|
255
|
+
when open_end?, unknown_end?, !(open_start? || unknown_start?) && to < from
|
|
253
256
|
nil
|
|
254
257
|
when to.day_precision?
|
|
255
258
|
to
|