timeboss 0.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 +7 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +23 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.gitignore +5 -0
- data/.replit +2 -0
- data/.rspec +2 -0
- data/.travis.yml +16 -0
- data/.yardopts +1 -0
- data/CODE_OF_CONDUCT.md +76 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +233 -0
- data/Rakefile +5 -0
- data/bin/tbsh +15 -0
- data/lib/tasks/calendars.rake +22 -0
- data/lib/tasks/timeboss.rake +6 -0
- data/lib/timeboss.rb +6 -0
- data/lib/timeboss/calendar.rb +64 -0
- data/lib/timeboss/calendar/day.rb +48 -0
- data/lib/timeboss/calendar/half.rb +22 -0
- data/lib/timeboss/calendar/month.rb +22 -0
- data/lib/timeboss/calendar/parser.rb +53 -0
- data/lib/timeboss/calendar/period.rb +83 -0
- data/lib/timeboss/calendar/quarter.rb +22 -0
- data/lib/timeboss/calendar/support/formatter.rb +33 -0
- data/lib/timeboss/calendar/support/month_basis.rb +21 -0
- data/lib/timeboss/calendar/support/monthly_unit.rb +55 -0
- data/lib/timeboss/calendar/support/navigable.rb +72 -0
- data/lib/timeboss/calendar/support/shiftable.rb +241 -0
- data/lib/timeboss/calendar/support/translatable.rb +93 -0
- data/lib/timeboss/calendar/support/unit.rb +88 -0
- data/lib/timeboss/calendar/waypoints.rb +12 -0
- data/lib/timeboss/calendar/waypoints/absolute.rb +113 -0
- data/lib/timeboss/calendar/waypoints/relative.rb +267 -0
- data/lib/timeboss/calendar/week.rb +53 -0
- data/lib/timeboss/calendar/year.rb +18 -0
- data/lib/timeboss/calendars.rb +53 -0
- data/lib/timeboss/calendars/broadcast.rb +32 -0
- data/lib/timeboss/calendars/gregorian.rb +30 -0
- data/lib/timeboss/support/shellable.rb +17 -0
- data/lib/timeboss/version.rb +4 -0
- data/spec/calendar/day_spec.rb +60 -0
- data/spec/calendar/quarter_spec.rb +32 -0
- data/spec/calendar/support/monthly_unit_spec.rb +85 -0
- data/spec/calendar/support/unit_spec.rb +90 -0
- data/spec/calendar/week_spec.rb +80 -0
- data/spec/calendars/broadcast_spec.rb +796 -0
- data/spec/calendars/gregorian_spec.rb +684 -0
- data/spec/calendars_spec.rb +50 -0
- data/spec/spec_helper.rb +12 -0
- data/timeboss.gemspec +31 -0
- metadata +216 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require_relative 'calendar'
|
|
3
|
+
|
|
4
|
+
module TimeBoss
|
|
5
|
+
module Calendars
|
|
6
|
+
extend self
|
|
7
|
+
extend Enumerable
|
|
8
|
+
delegate :each, :length, to: :all
|
|
9
|
+
|
|
10
|
+
# Register a new calendar
|
|
11
|
+
# @return [Entry]
|
|
12
|
+
def register(name, klass)
|
|
13
|
+
Entry.new(name.to_sym, klass).tap do |entry|
|
|
14
|
+
(@entries ||= {})[name.to_sym] = entry
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Retrieve a list of all registered calendars.
|
|
19
|
+
# @return [Array<Entry>]
|
|
20
|
+
def all
|
|
21
|
+
return if @entries.nil?
|
|
22
|
+
@entries.values.sort_by { |e| e.name.to_s }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Retrieve an instance of the specified named calendar.
|
|
26
|
+
# @param name [String, Symbol] the name of the calendar to retrieve.
|
|
27
|
+
# @return [Calendar]
|
|
28
|
+
def [](name)
|
|
29
|
+
return if @entries.nil?
|
|
30
|
+
@entries[name&.to_sym]&.calendar
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
Entry = Struct.new(:name, :klass) do
|
|
36
|
+
# @!method name
|
|
37
|
+
# Get the name of the calendar referenced in this entry.
|
|
38
|
+
# @return [Symbol]
|
|
39
|
+
|
|
40
|
+
# @!method klass
|
|
41
|
+
# The class implementing this calendar.
|
|
42
|
+
# @return [Class<Calendar>]
|
|
43
|
+
|
|
44
|
+
# Get an instance of the calendar referenced in this entry.
|
|
45
|
+
# @return [Calendar]
|
|
46
|
+
def calendar
|
|
47
|
+
@_calendar ||= klass.new
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
Dir[File.expand_path('../calendars/*.rb', __FILE__)].each { |f| require f }
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require_relative '../calendar'
|
|
3
|
+
|
|
4
|
+
module TimeBoss
|
|
5
|
+
module Calendars
|
|
6
|
+
class Broadcast < Calendar
|
|
7
|
+
register!
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
super(basis: Basis)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
class Basis < Calendar::Support::MonthBasis
|
|
16
|
+
def start_date
|
|
17
|
+
@_start_date ||= begin
|
|
18
|
+
date = Date.civil(year, month, 1)
|
|
19
|
+
date - (date.wday + 6) % 7
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def end_date
|
|
24
|
+
@_end_date ||= begin
|
|
25
|
+
date = Date.civil(year, month, -1)
|
|
26
|
+
date - date.wday
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require_relative '../calendar'
|
|
3
|
+
|
|
4
|
+
module TimeBoss
|
|
5
|
+
module Calendars
|
|
6
|
+
class Gregorian < Calendar
|
|
7
|
+
register!
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
super(basis: Basis)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def supports_weeks?
|
|
14
|
+
false
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
class Basis < Calendar::Support::MonthBasis
|
|
20
|
+
def start_date
|
|
21
|
+
@_start_date ||= Date.civil(year, month, 1)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def end_date
|
|
25
|
+
@_end_date ||= Date.civil(year, month, -1)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module TimeBoss
|
|
2
|
+
module Support
|
|
3
|
+
module Shellable
|
|
4
|
+
def self.open(context)
|
|
5
|
+
context.extend(self).open_shell
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def open_shell
|
|
9
|
+
require 'irb'
|
|
10
|
+
IRB.setup nil
|
|
11
|
+
IRB.conf[:MAIN_CONTEXT] = IRB::Irb.new.context
|
|
12
|
+
require 'irb/ext/multi-irb'
|
|
13
|
+
IRB.irb nil, self
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module TimeBoss
|
|
2
|
+
class Calendar
|
|
3
|
+
describe Day do
|
|
4
|
+
let(:calendar) { instance_double(TimeBoss::Calendar) }
|
|
5
|
+
let(:start_date) { Date.parse('2019-09-30') }
|
|
6
|
+
let(:subject) { described_class.new(calendar, start_date) }
|
|
7
|
+
|
|
8
|
+
it 'knows its stuff' do
|
|
9
|
+
expect(subject.start_date).to eq start_date
|
|
10
|
+
expect(subject.end_date).to eq start_date
|
|
11
|
+
expect(subject.to_range).to eq start_date..start_date
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'knows its name' do
|
|
15
|
+
expect(subject.name).to eq start_date.to_s
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'knows its title' do
|
|
19
|
+
expect(subject.title).to eq 'September 30, 2019'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'can stringify itself' do
|
|
23
|
+
expect(subject.to_s).to eq subject.name
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe '#index' do
|
|
27
|
+
before(:each) { allow(subject).to receive(:year).and_return double(start_date: start_date - 3) }
|
|
28
|
+
|
|
29
|
+
it 'gets its index within the year' do
|
|
30
|
+
expect(subject.index).to eq 4
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe '#current?' do
|
|
35
|
+
it 'knows when it is' do
|
|
36
|
+
allow(Date).to receive(:today).and_return start_date
|
|
37
|
+
expect(subject).to be_current
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'knows when it is not' do
|
|
41
|
+
expect(subject).not_to be_current
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context 'navigation' do
|
|
46
|
+
it 'can get the previous date' do
|
|
47
|
+
result = subject.previous
|
|
48
|
+
expect(result).to be_a described_class
|
|
49
|
+
expect(result.start_date).to eq start_date - 1.day
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'can get the next date' do
|
|
53
|
+
result = subject.next
|
|
54
|
+
expect(result).to be_a described_class
|
|
55
|
+
expect(result.start_date).to eq start_date + 1.day
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module TimeBoss
|
|
2
|
+
class Calendar
|
|
3
|
+
describe Quarter do
|
|
4
|
+
let(:calendar) { instance_double(TimeBoss::Calendar) }
|
|
5
|
+
let(:start_date) { Date.parse('2019-09-30') }
|
|
6
|
+
let(:end_date) { Date.parse('2019-12-29') }
|
|
7
|
+
let(:subject) { described_class.new(calendar, 2019, 4, start_date, end_date) }
|
|
8
|
+
|
|
9
|
+
it 'knows its stuff' do
|
|
10
|
+
expect(subject.name).to eq '2019Q4'
|
|
11
|
+
expect(subject.start_date).to eq start_date
|
|
12
|
+
expect(subject.end_date).to eq end_date
|
|
13
|
+
expect(subject.to_range).to eq start_date..end_date
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'can stringify itself' do
|
|
17
|
+
expect(subject.to_s).to include('2019Q4', start_date.to_s, end_date.to_s)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe '#current?' do
|
|
21
|
+
it 'knows when it is' do
|
|
22
|
+
allow(Date).to receive(:today).and_return start_date
|
|
23
|
+
expect(subject).to be_current
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'knows when it is not' do
|
|
27
|
+
expect(subject).not_to be_current
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
module TimeBoss
|
|
2
|
+
class Calendar
|
|
3
|
+
module Support
|
|
4
|
+
describe MonthlyUnit do
|
|
5
|
+
class MonthBasedChunk < described_class
|
|
6
|
+
NUM_MONTHS = 2
|
|
7
|
+
|
|
8
|
+
def name
|
|
9
|
+
"#{year_index}C#{index}"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
let(:described_class) { MonthBasedChunk }
|
|
13
|
+
let(:calendar) { double }
|
|
14
|
+
let(:start_date) { Date.parse('2018-06-25') }
|
|
15
|
+
let(:end_date) { Date.parse('2018-08-26') }
|
|
16
|
+
let(:subject) { described_class.new(calendar, 2018, 4, start_date, end_date) }
|
|
17
|
+
|
|
18
|
+
it 'knows its stuff' do
|
|
19
|
+
expect(subject.start_date).to eq start_date
|
|
20
|
+
expect(subject.end_date).to eq end_date
|
|
21
|
+
expect(subject.to_range).to eq start_date..end_date
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'can stringify itself' do
|
|
25
|
+
expect(subject.to_s).to eq "2018C4: 2018-06-25 thru 2018-08-26"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe '#weeks' do
|
|
29
|
+
let(:base) { double(start_date: Date.parse('2018-01-01'), end_date: Date.parse('2018-12-30')) }
|
|
30
|
+
before(:each) { allow(calendar).to receive(:year).with(2018).and_return base }
|
|
31
|
+
|
|
32
|
+
it 'can get the relevant weeks for the period' do
|
|
33
|
+
allow(calendar).to receive(:supports_weeks?).and_return true
|
|
34
|
+
result = subject.weeks
|
|
35
|
+
result.each { |w| expect(w).to be_instance_of TimeBoss::Calendar::Week }
|
|
36
|
+
expect(result.map { |w| w.start_date.to_s }).to eq [
|
|
37
|
+
'2018-06-25',
|
|
38
|
+
'2018-07-02',
|
|
39
|
+
'2018-07-09',
|
|
40
|
+
'2018-07-16',
|
|
41
|
+
'2018-07-23',
|
|
42
|
+
'2018-07-30',
|
|
43
|
+
'2018-08-06',
|
|
44
|
+
'2018-08-13',
|
|
45
|
+
'2018-08-20'
|
|
46
|
+
]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'blows up when weeks are not supported' do
|
|
50
|
+
allow(calendar).to receive(:supports_weeks?).and_return false
|
|
51
|
+
expect { subject.weeks }.to raise_error TimeBoss::Calendar::Support::Unit::UnsupportedUnitError
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
context 'navigation' do
|
|
56
|
+
let(:result) { double }
|
|
57
|
+
|
|
58
|
+
describe '#previous' do
|
|
59
|
+
it 'moves easily within itself' do
|
|
60
|
+
expect(calendar).to receive(:month_based_chunk).with(48, 3).and_return result
|
|
61
|
+
expect(described_class.new(calendar, 48, 4, nil, nil).previous).to eq result
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it 'flips to the previous container' do
|
|
65
|
+
expect(calendar).to receive(:month_based_chunk).with(47, 6).and_return result
|
|
66
|
+
expect(described_class.new(calendar, 48, 1, nil, nil).previous).to eq result
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe '#next' do
|
|
71
|
+
it 'moves easily within itself' do
|
|
72
|
+
expect(calendar).to receive(:month_based_chunk).with(48, 3).and_return result
|
|
73
|
+
expect(described_class.new(calendar, 48, 2, nil, nil).next).to eq result
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it 'flips to the previous container' do
|
|
77
|
+
expect(calendar).to receive(:month_based_chunk).with(48, 1).and_return result
|
|
78
|
+
expect(described_class.new(calendar, 47, 6, nil, nil).next).to eq result
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
module TimeBoss
|
|
2
|
+
class Calendar
|
|
3
|
+
module Support
|
|
4
|
+
describe Unit do
|
|
5
|
+
class ChunkUnit < described_class
|
|
6
|
+
end
|
|
7
|
+
let(:described_class) { ChunkUnit }
|
|
8
|
+
let(:calendar) { double }
|
|
9
|
+
let(:start_date) { Date.parse('2018-06-25') }
|
|
10
|
+
let(:end_date) { Date.parse('2018-08-26') }
|
|
11
|
+
let(:subject) { described_class.new(calendar, start_date, end_date) }
|
|
12
|
+
|
|
13
|
+
it 'knows its stuff' do
|
|
14
|
+
expect(subject.start_date).to eq start_date
|
|
15
|
+
expect(subject.end_date).to eq end_date
|
|
16
|
+
expect(subject.to_range).to eq start_date..end_date
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe '#current?' do
|
|
20
|
+
it 'is not current right now' do
|
|
21
|
+
expect(subject).not_to be_current
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'is current when today falls in the middle' do
|
|
25
|
+
allow(Date).to receive(:today).and_return start_date + 3.days
|
|
26
|
+
expect(subject).to be_current
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
context 'periods' do
|
|
31
|
+
before(:each) do
|
|
32
|
+
allow(calendar).to receive(:days_for).with(subject).and_return %w[D1 D2 D3 D4 D5 D6 D7 D8]
|
|
33
|
+
allow(calendar).to receive(:weeks_for).with(subject).and_return %w[W1 W2 W3 W4]
|
|
34
|
+
allow(calendar).to receive(:months_for).with(subject).and_return %w[M1 M2 M3]
|
|
35
|
+
allow(calendar).to receive(:quarters_for).with(subject).and_return %w[Q1 Q2]
|
|
36
|
+
allow(calendar).to receive(:halves_for).with(subject).and_return %w[H1]
|
|
37
|
+
allow(calendar).to receive(:years_for).with(subject).and_return %w[Y1]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'knows about its days' do
|
|
41
|
+
expect(subject.days).to eq %w[D1 D2 D3 D4 D5 D6 D7 D8]
|
|
42
|
+
expect(subject.day).to be nil
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'knows about its weeks' do
|
|
46
|
+
expect(subject.weeks).to eq %w[W1 W2 W3 W4]
|
|
47
|
+
expect(subject.week).to be nil
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'knows about its months' do
|
|
51
|
+
expect(subject.months).to eq %w[M1 M2 M3]
|
|
52
|
+
expect(subject.month).to be nil
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'knows about its quarters' do
|
|
56
|
+
expect(subject.quarters).to eq %w[Q1 Q2]
|
|
57
|
+
expect(subject.quarter).to be nil
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'knows about its halves' do
|
|
61
|
+
expect(subject.halves).to eq %w[H1]
|
|
62
|
+
expect(subject.half).to eq 'H1'
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'knows about its years' do
|
|
66
|
+
expect(subject.years).to eq %w[Y1]
|
|
67
|
+
expect(subject.year).to eq 'Y1'
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context 'navigation' do
|
|
72
|
+
let(:result) { double }
|
|
73
|
+
|
|
74
|
+
describe '#offset' do
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'can increment' do
|
|
78
|
+
expect(subject).to receive(:offset).with(7).and_return result
|
|
79
|
+
expect(subject + 7).to eq result
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it 'can decrement' do
|
|
83
|
+
expect(subject).to receive(:offset).with(-23).and_return result
|
|
84
|
+
expect(subject - 23).to eq result
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
module TimeBoss
|
|
2
|
+
class Calendar
|
|
3
|
+
describe Week do
|
|
4
|
+
let(:calendar) { instance_double(TimeBoss::Calendar, supports_weeks?: true) }
|
|
5
|
+
let(:start_date) { Date.parse('2048-04-06') }
|
|
6
|
+
let(:end_date) { Date.parse('2048-04-12') }
|
|
7
|
+
let(:subject) { described_class.new(calendar, start_date, end_date) }
|
|
8
|
+
|
|
9
|
+
it "doesn't even exist if its calendar doesn't support weeks" do
|
|
10
|
+
allow(calendar).to receive(:supports_weeks?).and_return false
|
|
11
|
+
expect { subject }.to raise_error TimeBoss::Calendar::Support::Unit::UnsupportedUnitError
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'knows its stuff' do
|
|
15
|
+
expect(subject.start_date).to eq start_date
|
|
16
|
+
expect(subject.end_date).to eq end_date
|
|
17
|
+
expect(subject.to_range).to eq start_date..end_date
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'knows its title' do
|
|
21
|
+
expect(subject.title).to eq "Week of April 6, 2048"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe '#current?' do
|
|
25
|
+
it 'knows when it is' do
|
|
26
|
+
allow(Date).to receive(:today).and_return start_date
|
|
27
|
+
expect(subject).to be_current
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'knows when it is not' do
|
|
31
|
+
expect(subject).not_to be_current
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context 'navigation' do
|
|
36
|
+
let(:calendar) { TimeBoss::Calendars::Broadcast.new }
|
|
37
|
+
|
|
38
|
+
describe '#previous' do
|
|
39
|
+
it 'can back up simply' do
|
|
40
|
+
result = subject.previous
|
|
41
|
+
expect(result).to be_a described_class
|
|
42
|
+
expect(result.to_s).to eq "2048W14: 2048-03-30 thru 2048-04-05"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'can wrap to the previous 52-week year' do
|
|
46
|
+
result = described_class.new(calendar, Date.parse('2021-12-27'), Date.parse('2022-01-02')).previous
|
|
47
|
+
expect(result).to be_a described_class
|
|
48
|
+
expect(result.to_s).to eq "2021W52: 2021-12-20 thru 2021-12-26"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'can wrap to the previous 53-week year' do
|
|
52
|
+
result = described_class.new(calendar, Date.parse('2024-01-01'), Date.parse('2024-01-07')).previous
|
|
53
|
+
expect(result).to be_a described_class
|
|
54
|
+
expect(result.to_s).to eq "2023W53: 2023-12-25 thru 2023-12-31"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe '#next' do
|
|
59
|
+
it 'can move forward simply' do
|
|
60
|
+
result = subject.next
|
|
61
|
+
expect(result).to be_a described_class
|
|
62
|
+
expect(result.to_s).to eq "2048W16: 2048-04-13 thru 2048-04-19"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'can wrap from week 52 to the next year' do
|
|
66
|
+
result = described_class.new(calendar, Date.parse('2021-12-20'), Date.parse('2021-12-26')).next
|
|
67
|
+
expect(result).to be_a described_class
|
|
68
|
+
expect(result.to_s).to eq "2022W1: 2021-12-27 thru 2022-01-02"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it 'can wrap from week 53 to the next year' do
|
|
72
|
+
result = described_class.new(calendar, Date.parse('2023-12-25'), Date.parse('2023-12-31')).next
|
|
73
|
+
expect(result).to be_a described_class
|
|
74
|
+
expect(result.to_s).to eq "2024W1: 2024-01-01 thru 2024-01-07"
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|