edtf 2.3.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dcceec6058c69ebeff88be3fdbf269ee69f69fab
4
- data.tar.gz: 4790a440bd05bb6bef2335bbeccc84836051e23c
3
+ metadata.gz: aa655e4e89a8cb161181b107461ecfc658d4c9e9
4
+ data.tar.gz: d463ec75229bb90823ff4972dea2a7cf6fe6e2d4
5
5
  SHA512:
6
- metadata.gz: d08ef863ffaf2ffc248f1213af38b25c6ae1963bbce4599735bedef87d0c025f3d4bc329cb5fc3a89d018c8b3a144693784bbecec163a970909f6e502e1b49cd
7
- data.tar.gz: eee5144c546253056593e414621a4b9202999bf0a7f15fbdd1e0e7fa88835a67f4eb384eaf4eb9f8a287b0964daa465dae352f5d606705febd8d95610c5577ee
6
+ metadata.gz: 673e1462165a23d661c145305041799a1cc1c9dd8ea2129c19a549b5e17eade2271e48fbdc9b6038fbde747d90149e2b5b6f78f01d63c6606efb6b49b44ade61
7
+ data.tar.gz: e36ba83aacd9675b9cc3a59360ddb4428b55629ec28cbaaac48be4f413aa685d9ca984bb878af3d3c365159e9249788660e1c2442571d2bc8448e9d91c5ed3a4
@@ -1,15 +1,17 @@
1
1
  language: ruby
2
2
  bundler_args: --without debug extra
3
+ sudo: false
4
+ cache: bundler
5
+ before_install:
6
+ - gem install bundler
3
7
  script: bundle exec rake test_with_coveralls
4
8
  rvm:
5
- - 2.2
6
- - 2.1
7
- - 2.0
8
- - jruby-19mode
9
- - rbx-2
9
+ - 2.3.1
10
+ - 2.2.5
11
+ - jruby-9.0.5.0
10
12
  notifications:
11
13
  email:
12
14
  - sk@semicolon.at
13
15
  - namyra@gmail.com
14
16
  on_success: change
15
- on_failure: always
17
+ on_failure: change
data/README.md CHANGED
@@ -26,6 +26,11 @@ but we are not testing compatibility actively anymore). Active Support's date
26
26
  extensions are currently listed as a dependency, because of many functional
27
27
  overlaps (version 3.x and 4.x are supported).
28
28
 
29
+ ### ISO 8601-2
30
+
31
+ A variation of EDTF will part of the upcoming ISO 8601-2 standard. EDTF-Ruby
32
+ does not support this new version of EDTF yet, but if you are curious,
33
+ [EDTF.js](inukshuk/edtf.js), an ES6 implementation is already available.
29
34
 
30
35
  Quickstart
31
36
  ----------
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.description = 'A Ruby implementation of the Extended Date/Time Format (EDTF).'
16
16
  s.license = 'BSD-2-Clause-FreeBSD'
17
17
 
18
- s.add_runtime_dependency('activesupport', '>= 3.0', '< 5.0')
18
+ s.add_runtime_dependency('activesupport', '>= 3.0', '< 6.0')
19
19
 
20
20
  s.files = `git ls-files`.split("\n") << 'lib/edtf/parser.rb'
21
21
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -1,11 +1,11 @@
1
1
  Feature: EDTF parses ISO 8601 interval strings
2
2
  As a user of edtf-ruby
3
3
  I want to parse ISO 8601 interval strings
4
-
4
+
5
5
  Scenario Outline: parse intervals
6
6
  When I parse the string "<string>"
7
7
  Then the interval should cover the date "<date>"
8
-
8
+
9
9
  @004 @level0
10
10
  Scenarios: specification intervals
11
11
  | string | date |
@@ -8,6 +8,12 @@ Feature: Print Date/Time objects as Level 0 EDTF strings
8
8
  When I convert the date
9
9
  Then the EDTF string should be "2004-08-12"
10
10
 
11
+ @001 @level0
12
+ Scenario: Convert simple negative dates
13
+ Given the date "-0300-08-12"
14
+ When I convert the date
15
+ Then the EDTF string should be "-0300-08-12"
16
+
11
17
  @001 @level0
12
18
  Scenario: Convert simple dates with precision
13
19
  Given the date "1980-08-24" with precision set to "day"
@@ -174,7 +174,9 @@ class Date
174
174
  def edtf
175
175
  return "y#{year}" if long_year?
176
176
 
177
- s = FORMATS.take(values.length).zip(values).map { |f,v| f % v }
177
+ v = values
178
+ s = FORMATS.take(v.length).zip(v).map { |f,d| f % d.abs }
179
+ s[0] = "-#{s[0]}" if year < 0
178
180
  s = unspecified.mask(s)
179
181
 
180
182
  unless (h = ua_hash).zero?
@@ -1,5 +1,5 @@
1
1
  module EDTF
2
-
2
+
3
3
  # An interval behaves like a regular Range but is dedicated to EDTF dates.
4
4
  # Most importantly, intervals use the date's precision when generating
5
5
  # the set of contained values and for membership tests. All tests are
@@ -21,20 +21,38 @@ module EDTF
21
21
  class Interval
22
22
 
23
23
  extend Forwardable
24
-
24
+
25
25
  include Comparable
26
26
  include Enumerable
27
27
 
28
28
  # Intervals delegate hash calculation to Ruby Range
29
29
  def_delegators :to_range, :eql?, :hash
30
30
  def_delegators :to_a, :length, :empty?
31
-
32
- attr_accessor :from, :to
31
+
32
+ attr_reader :from, :to
33
33
 
34
34
  def initialize(from = Date.today, to = :open)
35
- @from, @to = from, to
35
+ self.from, self.to = from, to
36
+ end
37
+
38
+ def from=(date)
39
+ case date
40
+ when Date, :unknown
41
+ @from = date
42
+ else
43
+ throw ArgumentError.new("Intervals cannot start with: #{date}")
44
+ end
45
+ end
46
+
47
+ def to=(date)
48
+ case date
49
+ when Date, :unknown, :open
50
+ @to = date
51
+ else
52
+ throw ArgumentError.new("Intervals cannot end with: #{date}")
53
+ end
36
54
  end
37
-
55
+
38
56
  [:open, :unknown].each do |method_name|
39
57
  define_method("#{method_name}_end!") do
40
58
  @to = method_name
@@ -45,34 +63,34 @@ module EDTF
45
63
  @to == method_name
46
64
  end
47
65
  end
48
-
66
+
49
67
  alias open! open_end!
50
68
  alias open? open_end?
51
-
69
+
52
70
  def unknown_start?
53
71
  from == :unknown
54
72
  end
55
-
73
+
56
74
  def unknown_start!
57
75
  @from = :unknown
58
76
  self
59
77
  end
60
-
78
+
61
79
  def unknown?
62
80
  unknown_start? || unknown_end?
63
81
  end
64
-
82
+
65
83
  # Returns the intervals precision. Mixed precisions are currently not
66
84
  # supported; in that case, the start date's precision takes precedence.
67
85
  def precision
68
86
  min.precision || max.precision
69
87
  end
70
-
88
+
71
89
  # Returns true if the precisions of start and end date are not the same.
72
90
  def mixed_precision?
73
91
  min.precision != max.precision
74
92
  end
75
-
93
+
76
94
  def each(&block)
77
95
  step(1, &block)
78
96
  end
@@ -90,37 +108,37 @@ module EDTF
90
108
  # If not block is given, returns an enumerator instead.
91
109
  #
92
110
  def step(by = 1)
93
- raise ArgumentError unless by.respond_to?(:to_i)
94
-
111
+ raise ArgumentError unless by.respond_to?(:to_i)
112
+
95
113
  if block_given?
96
114
  f, t, by = min, max, by.to_i
97
115
 
98
116
  unless f.nil? || t.nil? || by < 1
99
117
  by = { Date::PRECISIONS[precision] => by }
100
-
118
+
101
119
  until f > t do
102
120
  yield f
103
121
  f = f.advance(by)
104
122
  end
105
123
  end
106
-
124
+
107
125
  self
108
126
  else
109
127
  enum_for(:step, by)
110
128
  end
111
129
  end
112
130
 
113
-
131
+
114
132
  # This method always returns false for Range compatibility. EDTF intervals
115
133
  # always include the last date.
116
134
  def exclude_end?
117
135
  false
118
136
  end
119
-
120
-
137
+
138
+
121
139
  # TODO how to handle +/- Infinity for Dates?
122
140
  # TODO we can't delegate to Ruby range for mixed precision intervals
123
-
141
+
124
142
  # Returns the Interval as a Range.
125
143
  def to_range
126
144
  case
@@ -130,7 +148,7 @@ module EDTF
130
148
  Range.new(unknown_start? ? Date.new : @from, max)
131
149
  end
132
150
  end
133
-
151
+
134
152
  # Returns true if other is an element of the Interval, false otherwise.
135
153
  # Comparision is done according to the Interval's min/max date and
136
154
  # precision.
@@ -138,15 +156,15 @@ module EDTF
138
156
  cover?(other) && precision == other.precision
139
157
  end
140
158
  alias member? include?
141
-
159
+
142
160
  # Returns true if other is an element of the Interval, false otherwise.
143
161
  # In contrast to #include? and #member? this method does not take into
144
- # account the date's precision.
162
+ # account the date's precision.
145
163
  def cover?(other)
146
164
  return false unless other.is_a?(Date)
147
-
165
+
148
166
  other = other.day_precision
149
-
167
+
150
168
  case
151
169
  when unknown_start?
152
170
  max.day_precision! == other
@@ -158,7 +176,7 @@ module EDTF
158
176
  min.day_precision! <= other && other <= max.day_precision!
159
177
  end
160
178
  end
161
-
179
+
162
180
  # call-seq:
163
181
  # interval.first -> Date or nil
164
182
  # interval.first(n) -> Array
@@ -166,12 +184,12 @@ module EDTF
166
184
  # Returns the first date in the interval, or the first n dates.
167
185
  def first(n = 1)
168
186
  if n > 1
169
- (ds = Array(min)).empty? ? ds : ds.concat(ds[0].next(n - 1))
187
+ (ds = Array(min)).empty? ? ds : ds.concat(ds[0].next(n - 1))
170
188
  else
171
189
  min
172
190
  end
173
191
  end
174
-
192
+
175
193
  # call-seq:
176
194
  # interval.last -> Date or nil
177
195
  # interval.last(n) -> Array
@@ -179,12 +197,12 @@ module EDTF
179
197
  # Returns the last date in the interval, or the last n dates.
180
198
  def last(n = 1)
181
199
  if n > 1
182
- (ds = Array(max)).empty? ? ds : ds.concat(ds[0].prev(n - 1))
200
+ (ds = Array(max)).empty? ? ds : ds.concat(ds[0].prev(n - 1))
183
201
  else
184
202
  max
185
203
  end
186
204
  end
187
-
205
+
188
206
  # call-seq:
189
207
  # interval.min -> Date or nil
190
208
  # interval.min { |a,b| block } -> Date or nil
@@ -209,11 +227,11 @@ module EDTF
209
227
  end
210
228
  end
211
229
  end
212
-
230
+
213
231
  def begin
214
232
  min
215
233
  end
216
-
234
+
217
235
  # call-seq:
218
236
  # interval.max -> Date or nil
219
237
  # interval.max { |a,b| block } -> Date or nil
@@ -233,7 +251,7 @@ module EDTF
233
251
  case
234
252
  when open_end?, unknown_end?, !unknown_start? && to < from
235
253
  nil
236
- when to.day_precision?
254
+ when to.day_precision?
237
255
  to
238
256
  when to.month_precision?
239
257
  to.end_of_month
@@ -242,11 +260,11 @@ module EDTF
242
260
  end
243
261
  end
244
262
  end
245
-
263
+
246
264
  def end
247
265
  max
248
266
  end
249
-
267
+
250
268
  def <=>(other)
251
269
  case other
252
270
  when Interval, Season, Epoch
@@ -257,7 +275,7 @@ module EDTF
257
275
  nil
258
276
  end
259
277
  end
260
-
278
+
261
279
  def ===(other)
262
280
  case other
263
281
  when Interval
@@ -268,8 +286,8 @@ module EDTF
268
286
  false
269
287
  end
270
288
  end
271
-
272
-
289
+
290
+
273
291
  # Returns the Interval as an EDTF string.
274
292
  def edtf
275
293
  [
@@ -277,9 +295,9 @@ module EDTF
277
295
  to.send(to.respond_to?(:edtf) ? :edtf : :to_s)
278
296
  ] * '/'
279
297
  end
280
-
298
+
281
299
  alias to_s edtf
282
-
300
+
283
301
  end
284
-
302
+
285
303
  end
@@ -1,3 +1,3 @@
1
1
  module EDTF
2
- VERSION = '2.3.1'.freeze
2
+ VERSION = '3.0.0'.freeze
3
3
  end
@@ -5,7 +5,7 @@ describe 'Date/DateTime' do
5
5
  expect(Date).to respond_to(:edtf)
6
6
  end
7
7
  end
8
-
8
+
9
9
  describe 'instance methods' do
10
10
  [:uncertain?, :approximate?, :unspecified?, :uncertain, :approximate, :unspecified].each do |method|
11
11
  it "responds to #{method}" do
@@ -13,14 +13,14 @@ describe 'Date/DateTime' do
13
13
  end
14
14
  end
15
15
  end
16
-
16
+
17
17
  describe '#dup' do
18
18
  let(:date) { Date.edtf('2004-09?~') }
19
-
19
+
20
20
  it 'copies all date values' do
21
21
  date.dup.to_s == '2004-09-01'
22
22
  end
23
-
23
+
24
24
  it 'copies uncertainty' do
25
25
  expect(date.dup).to be_uncertain
26
26
  end
@@ -32,50 +32,50 @@ describe 'Date/DateTime' do
32
32
  it 'copies precision' do
33
33
  expect(date.dup.precision).to eq(:month)
34
34
  end
35
-
35
+
36
36
  it 'copies uncertainty by value' do
37
37
  expect { date.dup.certain! }.not_to change { date.uncertain? }
38
38
  end
39
-
39
+
40
40
  end
41
41
 
42
42
  describe 'precisions' do
43
43
  let(:date) { Date.today }
44
-
44
+
45
45
  it 'has day precision by default' do
46
46
  expect(date).to be_day_precision
47
47
  end
48
-
48
+
49
49
  it '#day_precison returns a new date object' do
50
50
  expect(date.day_precision).not_to equal(date)
51
51
  expect(date.day_precision).to eq(date)
52
52
  end
53
-
53
+
54
54
  end
55
-
56
-
55
+
56
+
57
57
  describe '#negate' do
58
58
  let(:date) { Date.edtf('2004?') }
59
-
59
+
60
60
  it 'returns a new date with the negated year' do
61
61
  expect(date.negate.year).to eq(date.year * -1)
62
62
  end
63
-
63
+
64
64
  it 'returns a new date with the same month' do
65
65
  expect(date.negate.month).to eq(date.month)
66
66
  end
67
-
67
+
68
68
  it 'returns a new date with the same day' do
69
69
  expect(date.negate.day).to eq(date.day)
70
70
  end
71
-
71
+
72
72
  it 'returns a new date with the same precision' do
73
73
  expect(date.negate.precision).to eq(date.precision)
74
74
  end
75
75
  end
76
-
76
+
77
77
  describe '#succ' do
78
-
78
+
79
79
  it 'the successor of 2004 is 2005' do
80
80
  expect(Date.edtf('2004').succ.year).to eq(2005)
81
81
  end
@@ -93,43 +93,43 @@ describe 'Date/DateTime' do
93
93
  end
94
94
 
95
95
  end
96
-
96
+
97
97
  describe '#next' do
98
-
98
+
99
99
  it 'returns the successor when given no argument' do
100
100
  expect(Date.edtf('1999').next[0].year).to eq(2000)
101
101
  end
102
-
102
+
103
103
  it 'returns an array of the next 3 elements when passed 3 as an argument' do
104
104
  Date.edtf('1999').next(3).map(&:year) == [2000, 2001, 2002]
105
105
  end
106
-
106
+
107
107
  end
108
-
109
-
108
+
109
+
110
110
  describe '#change' do
111
111
  let(:date) { Date.edtf('2004-09?~') }
112
112
 
113
113
  it 'returns a copy of the date if given empty option hash' do
114
114
  expect(date.change({})).to eq(date)
115
115
  end
116
-
116
+
117
117
  it 'the returned copy is not identical at object level' do
118
118
  expect(date.change({})).not_to equal(date)
119
119
  end
120
-
120
+
121
121
  describe 'when given a new year' do
122
122
  let(:changeset) { { :year => 1999 } }
123
-
123
+
124
124
  it 'returns a new date instance with the changed year' do
125
125
  expect(date.change(changeset).year).to eq(1999)
126
126
  end
127
-
127
+
128
128
  end
129
129
 
130
130
  describe 'when given a new precision' do
131
131
  let(:changeset) { { :precision => :year } }
132
-
132
+
133
133
  it 'returns a new date instance with the changed precision' do
134
134
  expect(date.change(changeset).precision).to eq(:year)
135
135
  end
@@ -139,13 +139,13 @@ describe 'Date/DateTime' do
139
139
  it 'copies extended values by value' do
140
140
  expect { date.change({}).approximate! }.not_to change { date.approximate? }
141
141
  end
142
-
142
+
143
143
  end
144
-
144
+
145
145
  describe '#uncertain?' do
146
-
146
+
147
147
  let(:date) { Date.new }
148
-
148
+
149
149
  it { expect(Date.new).not_to be_uncertain }
150
150
 
151
151
  [:year, :month, :day].each do |part|
@@ -164,29 +164,29 @@ describe 'Date/DateTime' do
164
164
  expect(date.uncertain?(other)).to eq(false)
165
165
  end
166
166
  end
167
-
167
+
168
168
  end
169
-
169
+
170
170
  end
171
-
171
+
172
172
  describe 'uncertain/approximate hash' do
173
-
173
+
174
174
  it 'is 0 by default' do
175
175
  expect(Date.new().send(:ua_hash)).to eq(0)
176
176
  end
177
-
177
+
178
178
  it 'is 8 for approximate year' do
179
179
  expect(Date.new.approximate!(:year).send(:ua_hash)).to eq(8)
180
180
  end
181
-
181
+
182
182
  end
183
-
183
+
184
184
  describe 'sorting and comparisons' do
185
185
  let(:xmas) { Date.new(2011, 12, 24) }
186
186
  let(:new_years_eve) { Date.new(2011, 12, 31) }
187
-
187
+
188
188
  describe '#values' do
189
-
189
+
190
190
  it 'returns [2011,12,24] for christmas' do
191
191
  expect(xmas.values).to eq([2011,12,24])
192
192
  end
@@ -198,11 +198,11 @@ describe 'Date/DateTime' do
198
198
  it 'returns [2011] for christmas with year precision' do
199
199
  expect(xmas.year_precision!.values).to eq([2011])
200
200
  end
201
-
201
+
202
202
  end
203
-
203
+
204
204
  describe '#<=>' do
205
-
205
+
206
206
  it '2009-12-24 should be less than 2011-12-31' do
207
207
  expect(Date.new(2009,12,24)).to be < Date.new(2011,12,31)
208
208
  end
@@ -214,12 +214,12 @@ describe 'Date/DateTime' do
214
214
  it '2009-12-24 should be less than 2011' do
215
215
  expect(Date.new(2009,12,24)).to be < Date.edtf('2011')
216
216
  end
217
-
218
-
217
+
218
+
219
219
  end
220
-
220
+
221
221
  describe '#==' do
222
-
222
+
223
223
  it "xmas and new year's eve are not equal" do
224
224
  expect(xmas).not_to eq(new_years_eve)
225
225
  end
@@ -231,15 +231,15 @@ describe 'Date/DateTime' do
231
231
  it "xmas and january 24 are not equal using month percision" do
232
232
  expect(xmas.month_precision!).not_to eq(xmas.month_precision!.next)
233
233
  end
234
-
234
+
235
235
 
236
236
  it "xmas and new year's eve are equal using year percision" do
237
237
  expect(xmas.year_precision!).to eq(new_years_eve.year_precision!)
238
238
  end
239
-
239
+
240
240
  end
241
-
241
+
242
242
  end
243
-
244
-
245
- end
243
+
244
+
245
+ end
@@ -132,5 +132,10 @@ module EDTF
132
132
  end
133
133
  end
134
134
 
135
+ it 'may not have an open start' do
136
+ expect(
137
+ proc { Interval.new(:open, Date.today) }
138
+ ).to raise_error(ArgumentError)
139
+ end
135
140
  end
136
- end
141
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: edtf
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvester Keil
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-27 00:00:00.000000000 Z
11
+ date: 2016-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: '3.0'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '5.0'
22
+ version: '6.0'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: '3.0'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '5.0'
32
+ version: '6.0'
33
33
  description: A Ruby implementation of the Extended Date/Time Format (EDTF).
34
34
  email:
35
35
  - http://sylvester.keil.or.at