timeboss 1.0.0 → 1.1.1
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/gem-push.yml +31 -0
- data/.github/workflows/ruby.yml +35 -0
- data/.travis.yml +3 -2
- data/Gemfile +2 -1
- data/README.md +17 -2
- data/Rakefile +3 -1
- data/bin/tbsh +2 -2
- data/lib/tasks/calendars.rake +5 -5
- data/lib/tasks/timeboss.rake +2 -2
- data/lib/timeboss/calendar/day.rb +3 -2
- data/lib/timeboss/calendar/half.rb +2 -1
- data/lib/timeboss/calendar/month.rb +2 -1
- data/lib/timeboss/calendar/parser.rb +9 -8
- data/lib/timeboss/calendar/period.rb +9 -6
- data/lib/timeboss/calendar/quarter.rb +2 -1
- data/lib/timeboss/calendar/support/formatter.rb +5 -4
- data/lib/timeboss/calendar/support/has_fiscal_weeks.rb +17 -0
- data/lib/timeboss/calendar/support/has_iso_weeks.rb +30 -0
- data/lib/timeboss/calendar/support/month_basis.rb +1 -1
- data/lib/timeboss/calendar/support/monthly_unit.rb +8 -8
- data/lib/timeboss/calendar/support/navigable.rb +2 -1
- data/lib/timeboss/calendar/support/shiftable.rb +12 -11
- data/lib/timeboss/calendar/support/translatable.rb +3 -2
- data/lib/timeboss/calendar/support/unit.rb +20 -13
- data/lib/timeboss/calendar/waypoints/absolute.rb +4 -3
- data/lib/timeboss/calendar/waypoints/relative.rb +14 -13
- data/lib/timeboss/calendar/week.rb +3 -2
- data/lib/timeboss/calendar/year.rb +2 -1
- data/lib/timeboss/calendar.rb +8 -7
- data/lib/timeboss/calendars/broadcast.rb +10 -7
- data/lib/timeboss/calendars/gregorian.rb +4 -5
- data/lib/timeboss/calendars.rb +3 -2
- data/lib/timeboss/version.rb +2 -1
- data/lib/timeboss.rb +2 -0
- data/spec/{calendar → lib/timeboss/calendar}/day_spec.rb +14 -14
- data/spec/{calendar → lib/timeboss/calendar}/quarter_spec.rb +9 -9
- data/spec/lib/timeboss/calendar/support/monthly_unit_spec.rb +91 -0
- data/spec/{calendar → lib/timeboss/calendar}/support/unit_spec.rb +23 -22
- data/spec/{calendar → lib/timeboss/calendar}/week_spec.rb +20 -20
- data/spec/lib/timeboss/calendars/broadcast_spec.rb +796 -0
- data/spec/lib/timeboss/calendars/gregorian_spec.rb +793 -0
- data/spec/{calendars_spec.rb → lib/timeboss/calendars_spec.rb} +19 -19
- data/spec/spec_helper.rb +2 -2
- data/timeboss.gemspec +16 -14
- metadata +51 -20
- data/lib/timeboss/support/shellable.rb +0 -17
- data/spec/calendar/support/monthly_unit_spec.rb +0 -85
- data/spec/calendars/broadcast_spec.rb +0 -796
- data/spec/calendars/gregorian_spec.rb +0 -684
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative
|
4
|
-
require_relative
|
5
|
-
require_relative
|
2
|
+
|
3
|
+
require_relative "./navigable"
|
4
|
+
require_relative "./translatable"
|
5
|
+
require_relative "./shiftable"
|
6
|
+
require_relative "./formatter"
|
6
7
|
|
7
8
|
module TimeBoss
|
8
9
|
class Calendar
|
@@ -16,7 +17,7 @@ module TimeBoss
|
|
16
17
|
UnsupportedUnitError = Class.new(StandardError)
|
17
18
|
|
18
19
|
def self.type
|
19
|
-
|
20
|
+
name.demodulize.underscore
|
20
21
|
end
|
21
22
|
|
22
23
|
def initialize(calendar, start_date, end_date)
|
@@ -28,8 +29,8 @@ module TimeBoss
|
|
28
29
|
# Is the specified unit equal to this one, based on its unit type and date range?
|
29
30
|
# @param entry [Unit] the unit to compare
|
30
31
|
# @return [Boolean] true when periods are equal
|
31
|
-
def ==(
|
32
|
-
self.class ==
|
32
|
+
def ==(other)
|
33
|
+
self.class == other.class && start_date == other.start_date && end_date == other.end_date
|
33
34
|
end
|
34
35
|
|
35
36
|
# Format this period based on specified granularities.
|
@@ -59,33 +60,39 @@ module TimeBoss
|
|
59
60
|
def offset(value)
|
60
61
|
method = value.negative? ? :previous : :next
|
61
62
|
base = self
|
62
|
-
value.abs.times { base = base.
|
63
|
+
value.abs.times { base = base.public_send(method) }
|
63
64
|
base
|
64
65
|
end
|
65
66
|
|
66
67
|
# Move some number of units forward from this unit.
|
67
68
|
# @param value [Integer]
|
68
69
|
# @return [Unit]
|
69
|
-
def +(
|
70
|
-
offset(
|
70
|
+
def +(other)
|
71
|
+
offset(other)
|
71
72
|
end
|
72
73
|
|
73
74
|
# Move some number of units backward from this unit.
|
74
75
|
# @param value [Integer]
|
75
76
|
# @return [Unit]
|
76
|
-
def -(
|
77
|
-
offset(-
|
77
|
+
def -(other)
|
78
|
+
offset(-other)
|
78
79
|
end
|
79
80
|
|
80
81
|
# Express this period as a date range.
|
81
82
|
# @return [Range<Date, Date>]
|
82
83
|
def to_range
|
83
|
-
@_to_range ||= start_date
|
84
|
+
@_to_range ||= start_date..end_date
|
84
85
|
end
|
85
86
|
|
86
87
|
def inspect
|
87
88
|
"#<#{self.class.name} start_date=#{start_date}, end_date=#{end_date}>"
|
88
89
|
end
|
90
|
+
|
91
|
+
protected
|
92
|
+
|
93
|
+
def dates
|
94
|
+
@_dates ||= to_range.to_a
|
95
|
+
end
|
89
96
|
end
|
90
97
|
end
|
91
98
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module TimeBoss
|
3
4
|
class Calendar
|
4
5
|
module Waypoints
|
@@ -9,13 +10,13 @@ module TimeBoss
|
|
9
10
|
|
10
11
|
define_method type do |year_index, index = 1|
|
11
12
|
month = (index * size) - size + 1
|
12
|
-
months = (month
|
13
|
+
months = (month..month + size - 1).map { |i| basis.new(year_index, i) }
|
13
14
|
klass.new(self, year_index, index, months.first.start_date, months.last.end_date)
|
14
15
|
end
|
15
16
|
|
16
17
|
define_method "#{type}_for" do |date|
|
17
|
-
window =
|
18
|
-
|
18
|
+
window = public_send(type, date.year - 1, 1)
|
19
|
+
loop do
|
19
20
|
break window if window.to_range.include?(date)
|
20
21
|
window = window.next
|
21
22
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module TimeBoss
|
3
4
|
class Calendar
|
4
5
|
module Waypoints
|
@@ -6,17 +7,17 @@ module TimeBoss
|
|
6
7
|
%i[day week month quarter half year].each do |type|
|
7
8
|
types = type.to_s.pluralize
|
8
9
|
|
9
|
-
define_method("this_#{type}") {
|
10
|
-
define_method("last_#{type}") {
|
11
|
-
define_method("next_#{type}") {
|
10
|
+
define_method("this_#{type}") { public_send("#{type}_for", Date.today) }
|
11
|
+
define_method("last_#{type}") { public_send("this_#{type}").previous }
|
12
|
+
define_method("next_#{type}") { public_send("this_#{type}").next }
|
12
13
|
|
13
|
-
define_method("#{types}_for") { |p|
|
14
|
+
define_method("#{types}_for") { |p| public_send("#{type}_for", p.start_date).until(p.end_date) }
|
14
15
|
|
15
|
-
define_method("#{types}_back") { |q|
|
16
|
-
define_method("#{types}_ago") { |q|
|
16
|
+
define_method("#{types}_back") { |q| public_send("this_#{type}").previous(q) }
|
17
|
+
define_method("#{types}_ago") { |q| public_send("this_#{type}").ago(q) }
|
17
18
|
|
18
|
-
define_method("#{types}_forward") { |q|
|
19
|
-
define_method("#{types}_ahead") { |q|
|
19
|
+
define_method("#{types}_forward") { |q| public_send("this_#{type}").next(q) }
|
20
|
+
define_method("#{types}_ahead") { |q| public_send("this_#{type}").ahead(q) }
|
20
21
|
alias_method types.to_sym, "#{types}_forward".to_sym
|
21
22
|
end
|
22
23
|
|
@@ -66,7 +67,7 @@ module TimeBoss
|
|
66
67
|
# Get the day that occurred the specified number of days ahead.
|
67
68
|
# @param quantity [Integer] the number of days after today
|
68
69
|
# @return [Calendar::Day]
|
69
|
-
|
70
|
+
|
70
71
|
### Weeks
|
71
72
|
|
72
73
|
# @!method this_week
|
@@ -105,7 +106,7 @@ module TimeBoss
|
|
105
106
|
# Get the week that occurred the specified number of weeks ahead.
|
106
107
|
# @param quantity [Integer] the number of weeks after this week
|
107
108
|
# @return [Calendar::Week]
|
108
|
-
|
109
|
+
|
109
110
|
### Months
|
110
111
|
|
111
112
|
# @!method this_month
|
@@ -144,7 +145,7 @@ module TimeBoss
|
|
144
145
|
# Get the month that occurred the specified number of months ahead.
|
145
146
|
# @param quantity [Integer] the number of months after this month
|
146
147
|
# @return [Calendar::Month]
|
147
|
-
|
148
|
+
|
148
149
|
### Quarters
|
149
150
|
|
150
151
|
# @!method this_quarter
|
@@ -183,7 +184,7 @@ module TimeBoss
|
|
183
184
|
# Get the quarter that occurred the specified number of days ahead.
|
184
185
|
# @param quantity [Integer] the number of quarters after this quarter
|
185
186
|
# @return [Calendar::Quarter]
|
186
|
-
|
187
|
+
|
187
188
|
### Halves
|
188
189
|
|
189
190
|
# @!method this_half
|
@@ -222,7 +223,7 @@ module TimeBoss
|
|
222
223
|
# Get the half that occurred the specified number of halves ahead.
|
223
224
|
# @param quantity [Integer] the number of halves after this half
|
224
225
|
# @return [Calendar::Half]
|
225
|
-
|
226
|
+
|
226
227
|
### Years
|
227
228
|
|
228
229
|
# @!method this_year
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
require_relative "./support/unit"
|
3
4
|
|
4
5
|
module TimeBoss
|
5
6
|
class Calendar
|
@@ -18,7 +19,7 @@ module TimeBoss
|
|
18
19
|
# Get a "pretty" representation of this week.
|
19
20
|
# @return [String] (e.g. "Week of August 3, 2020")
|
20
21
|
def title
|
21
|
-
"Week of #{start_date.strftime(
|
22
|
+
"Week of #{start_date.strftime("%B %-d, %Y")}"
|
22
23
|
end
|
23
24
|
|
24
25
|
# Get a stringified representation of this week.
|
data/lib/timeboss/calendar.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require
|
2
|
+
|
3
|
+
require "active_support/inflector"
|
4
|
+
require "active_support/core_ext/numeric/time"
|
4
5
|
|
5
6
|
%w[day week month quarter half year].each { |f| require_relative "./calendar/#{f}" }
|
6
7
|
%w[waypoints period parser].each { |f| require_relative "./calendar/#{f}" }
|
7
|
-
require_relative
|
8
|
+
require_relative "./calendar/support/month_basis"
|
8
9
|
|
9
10
|
module TimeBoss
|
10
11
|
class Calendar
|
@@ -34,16 +35,16 @@ module TimeBoss
|
|
34
35
|
end
|
35
36
|
|
36
37
|
# Can this calendar support weeks?
|
37
|
-
#
|
38
|
-
#
|
38
|
+
# To support weeks, a calendar must implement a `#weeks_in(year:)` method that returns an array of
|
39
|
+
# `Calendar::Week` objects.
|
39
40
|
# @return [Boolean]
|
40
41
|
def supports_weeks?
|
41
|
-
|
42
|
+
respond_to?(:weeks_in)
|
42
43
|
end
|
43
44
|
|
44
45
|
def self.register!
|
45
46
|
return unless TimeBoss::Calendars.method_defined?(:register)
|
46
|
-
TimeBoss::Calendars.register(
|
47
|
+
TimeBoss::Calendars.register(name.to_s.demodulize.underscore, self)
|
47
48
|
end
|
48
49
|
private_class_method :register!
|
49
50
|
|
@@ -1,9 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
require_relative "../calendar"
|
4
|
+
require_relative "../calendar/support/has_fiscal_weeks"
|
3
5
|
|
4
6
|
module TimeBoss
|
5
7
|
module Calendars
|
6
8
|
class Broadcast < Calendar
|
9
|
+
include Support::HasFiscalWeeks
|
7
10
|
register!
|
8
11
|
|
9
12
|
def initialize
|
@@ -15,16 +18,16 @@ module TimeBoss
|
|
15
18
|
class Basis < Calendar::Support::MonthBasis
|
16
19
|
def start_date
|
17
20
|
@_start_date ||= begin
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
+
date = Date.civil(year, month, 1)
|
22
|
+
date - (date.wday + 6) % 7
|
23
|
+
end
|
21
24
|
end
|
22
25
|
|
23
26
|
def end_date
|
24
27
|
@_end_date ||= begin
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
+
date = Date.civil(year, month, -1)
|
29
|
+
date - date.wday
|
30
|
+
end
|
28
31
|
end
|
29
32
|
end
|
30
33
|
end
|
@@ -1,19 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
require_relative "../calendar"
|
4
|
+
require_relative "../calendar/support/has_iso_weeks"
|
3
5
|
|
4
6
|
module TimeBoss
|
5
7
|
module Calendars
|
6
8
|
class Gregorian < Calendar
|
9
|
+
include Support::HasIsoWeeks
|
7
10
|
register!
|
8
11
|
|
9
12
|
def initialize
|
10
13
|
super(basis: Basis)
|
11
14
|
end
|
12
15
|
|
13
|
-
def supports_weeks?
|
14
|
-
false
|
15
|
-
end
|
16
|
-
|
17
16
|
private
|
18
17
|
|
19
18
|
class Basis < Calendar::Support::MonthBasis
|
data/lib/timeboss/calendars.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
require_relative "calendar"
|
3
4
|
|
4
5
|
module TimeBoss
|
5
6
|
module Calendars
|
@@ -50,4 +51,4 @@ module TimeBoss
|
|
50
51
|
end
|
51
52
|
end
|
52
53
|
|
53
|
-
Dir[File.expand_path(
|
54
|
+
Dir[File.expand_path("../calendars/*.rb", __FILE__)].each { |f| require f }
|
data/lib/timeboss/version.rb
CHANGED
data/lib/timeboss.rb
CHANGED
@@ -2,54 +2,54 @@ module TimeBoss
|
|
2
2
|
class Calendar
|
3
3
|
describe Day do
|
4
4
|
let(:calendar) { instance_double(TimeBoss::Calendar) }
|
5
|
-
let(:start_date) { Date.parse(
|
5
|
+
let(:start_date) { Date.parse("2019-09-30") }
|
6
6
|
let(:subject) { described_class.new(calendar, start_date) }
|
7
7
|
|
8
|
-
it
|
8
|
+
it "knows its stuff" do
|
9
9
|
expect(subject.start_date).to eq start_date
|
10
10
|
expect(subject.end_date).to eq start_date
|
11
11
|
expect(subject.to_range).to eq start_date..start_date
|
12
12
|
end
|
13
13
|
|
14
|
-
it
|
14
|
+
it "knows its name" do
|
15
15
|
expect(subject.name).to eq start_date.to_s
|
16
16
|
end
|
17
17
|
|
18
|
-
it
|
19
|
-
expect(subject.title).to eq
|
18
|
+
it "knows its title" do
|
19
|
+
expect(subject.title).to eq "September 30, 2019"
|
20
20
|
end
|
21
21
|
|
22
|
-
it
|
22
|
+
it "can stringify itself" do
|
23
23
|
expect(subject.to_s).to eq subject.name
|
24
24
|
end
|
25
25
|
|
26
|
-
describe
|
26
|
+
describe "#index" do
|
27
27
|
before(:each) { allow(subject).to receive(:year).and_return double(start_date: start_date - 3) }
|
28
28
|
|
29
|
-
it
|
29
|
+
it "gets its index within the year" do
|
30
30
|
expect(subject.index).to eq 4
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
describe
|
35
|
-
it
|
34
|
+
describe "#current?" do
|
35
|
+
it "knows when it is" do
|
36
36
|
allow(Date).to receive(:today).and_return start_date
|
37
37
|
expect(subject).to be_current
|
38
38
|
end
|
39
39
|
|
40
|
-
it
|
40
|
+
it "knows when it is not" do
|
41
41
|
expect(subject).not_to be_current
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
context
|
46
|
-
it
|
45
|
+
context "navigation" do
|
46
|
+
it "can get the previous date" do
|
47
47
|
result = subject.previous
|
48
48
|
expect(result).to be_a described_class
|
49
49
|
expect(result.start_date).to eq start_date - 1.day
|
50
50
|
end
|
51
51
|
|
52
|
-
it
|
52
|
+
it "can get the next date" do
|
53
53
|
result = subject.next
|
54
54
|
expect(result).to be_a described_class
|
55
55
|
expect(result.start_date).to eq start_date + 1.day
|
@@ -2,28 +2,28 @@ module TimeBoss
|
|
2
2
|
class Calendar
|
3
3
|
describe Quarter do
|
4
4
|
let(:calendar) { instance_double(TimeBoss::Calendar) }
|
5
|
-
let(:start_date) { Date.parse(
|
6
|
-
let(:end_date) { Date.parse(
|
5
|
+
let(:start_date) { Date.parse("2019-09-30") }
|
6
|
+
let(:end_date) { Date.parse("2019-12-29") }
|
7
7
|
let(:subject) { described_class.new(calendar, 2019, 4, start_date, end_date) }
|
8
8
|
|
9
|
-
it
|
10
|
-
expect(subject.name).to eq
|
9
|
+
it "knows its stuff" do
|
10
|
+
expect(subject.name).to eq "2019Q4"
|
11
11
|
expect(subject.start_date).to eq start_date
|
12
12
|
expect(subject.end_date).to eq end_date
|
13
13
|
expect(subject.to_range).to eq start_date..end_date
|
14
14
|
end
|
15
15
|
|
16
|
-
it
|
17
|
-
expect(subject.to_s).to include(
|
16
|
+
it "can stringify itself" do
|
17
|
+
expect(subject.to_s).to include("2019Q4", start_date.to_s, end_date.to_s)
|
18
18
|
end
|
19
19
|
|
20
|
-
describe
|
21
|
-
it
|
20
|
+
describe "#current?" do
|
21
|
+
it "knows when it is" do
|
22
22
|
allow(Date).to receive(:today).and_return start_date
|
23
23
|
expect(subject).to be_current
|
24
24
|
end
|
25
25
|
|
26
|
-
it
|
26
|
+
it "knows when it is not" do
|
27
27
|
expect(subject).not_to be_current
|
28
28
|
end
|
29
29
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module TimeBoss
|
2
|
+
class Calendar
|
3
|
+
module Support
|
4
|
+
class TestMonthBasedChunk < MonthlyUnit
|
5
|
+
NUM_MONTHS = 2
|
6
|
+
|
7
|
+
def name
|
8
|
+
"#{year_index}C#{index}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe MonthlyUnit do
|
13
|
+
let(:described_class) { TestMonthBasedChunk }
|
14
|
+
let(:calendar) { double(supports_weeks?: false, weeks_in: nil) }
|
15
|
+
let(:start_date) { Date.parse("2018-06-25") }
|
16
|
+
let(:end_date) { Date.parse("2018-08-26") }
|
17
|
+
let(:subject) { described_class.new(calendar, 2018, 4, start_date, end_date) }
|
18
|
+
|
19
|
+
it "knows its stuff" do
|
20
|
+
expect(subject.start_date).to eq start_date
|
21
|
+
expect(subject.end_date).to eq end_date
|
22
|
+
expect(subject.to_range).to eq start_date..end_date
|
23
|
+
end
|
24
|
+
|
25
|
+
it "can stringify itself" do
|
26
|
+
expect(subject.to_s).to eq "2018C4: 2018-06-25 thru 2018-08-26"
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#weeks" do
|
30
|
+
let(:supports_weeks) { false }
|
31
|
+
before(:each) { allow(calendar).to receive(:supports_weeks?).and_return supports_weeks }
|
32
|
+
|
33
|
+
context "unsupported" do
|
34
|
+
it "blows up when weeks are not supported" do
|
35
|
+
expect { subject.weeks }.to raise_error TimeBoss::Calendar::Support::Unit::UnsupportedUnitError
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "supported" do
|
40
|
+
let(:supports_weeks) { true }
|
41
|
+
let(:base) { double(start_date: Date.parse("2018-01-01"), end_date: Date.parse("2018-12-30")) }
|
42
|
+
let(:weeks) do
|
43
|
+
["2018-04-19", "2018-06-25", "2018-07-16", "2018-08-20", "2018-09-30"].map do |date|
|
44
|
+
start_date = Date.parse(date)
|
45
|
+
TimeBoss::Calendar::Week.new(calendar, start_date, start_date + 6.days)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
before(:each) do
|
49
|
+
allow(calendar).to receive(:year).with(2018).and_return base
|
50
|
+
allow(calendar).to receive(:weeks_in).with(year: base).and_return weeks
|
51
|
+
end
|
52
|
+
|
53
|
+
it "can get the relevant weeks for the period" do
|
54
|
+
result = subject.weeks
|
55
|
+
result.each { |w| expect(w).to be_instance_of TimeBoss::Calendar::Week }
|
56
|
+
expect(result.map { |w| w.start_date.to_s }).to eq ["2018-06-25", "2018-07-16", "2018-08-20"]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "navigation" do
|
62
|
+
let(:result) { double }
|
63
|
+
|
64
|
+
describe "#previous" do
|
65
|
+
it "moves easily within itself" do
|
66
|
+
expect(calendar).to receive(:test_month_based_chunk).with(48, 3).and_return result
|
67
|
+
expect(described_class.new(calendar, 48, 4, nil, nil).previous).to eq result
|
68
|
+
end
|
69
|
+
|
70
|
+
it "flips to the previous container" do
|
71
|
+
expect(calendar).to receive(:test_month_based_chunk).with(47, 6).and_return result
|
72
|
+
expect(described_class.new(calendar, 48, 1, nil, nil).previous).to eq result
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#next" do
|
77
|
+
it "moves easily within itself" do
|
78
|
+
expect(calendar).to receive(:test_month_based_chunk).with(48, 3).and_return result
|
79
|
+
expect(described_class.new(calendar, 48, 2, nil, nil).next).to eq result
|
80
|
+
end
|
81
|
+
|
82
|
+
it "flips to the previous container" do
|
83
|
+
expect(calendar).to receive(:test_month_based_chunk).with(48, 1).and_return result
|
84
|
+
expect(described_class.new(calendar, 47, 6, nil, nil).next).to eq result
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -1,33 +1,34 @@
|
|
1
1
|
module TimeBoss
|
2
2
|
class Calendar
|
3
3
|
module Support
|
4
|
+
class TestChunkUnit < Unit
|
5
|
+
end
|
6
|
+
|
4
7
|
describe Unit do
|
5
|
-
|
6
|
-
end
|
7
|
-
let(:described_class) { ChunkUnit }
|
8
|
+
let(:described_class) { TestChunkUnit }
|
8
9
|
let(:calendar) { double }
|
9
|
-
let(:start_date) { Date.parse(
|
10
|
-
let(:end_date) { Date.parse(
|
10
|
+
let(:start_date) { Date.parse("2018-06-25") }
|
11
|
+
let(:end_date) { Date.parse("2018-08-26") }
|
11
12
|
let(:subject) { described_class.new(calendar, start_date, end_date) }
|
12
13
|
|
13
|
-
it
|
14
|
+
it "knows its stuff" do
|
14
15
|
expect(subject.start_date).to eq start_date
|
15
16
|
expect(subject.end_date).to eq end_date
|
16
17
|
expect(subject.to_range).to eq start_date..end_date
|
17
18
|
end
|
18
19
|
|
19
|
-
describe
|
20
|
-
it
|
20
|
+
describe "#current?" do
|
21
|
+
it "is not current right now" do
|
21
22
|
expect(subject).not_to be_current
|
22
23
|
end
|
23
24
|
|
24
|
-
it
|
25
|
+
it "is current when today falls in the middle" do
|
25
26
|
allow(Date).to receive(:today).and_return start_date + 3.days
|
26
27
|
expect(subject).to be_current
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
30
|
-
context
|
31
|
+
context "periods" do
|
31
32
|
before(:each) do
|
32
33
|
allow(calendar).to receive(:days_for).with(subject).and_return %w[D1 D2 D3 D4 D5 D6 D7 D8]
|
33
34
|
allow(calendar).to receive(:weeks_for).with(subject).and_return %w[W1 W2 W3 W4]
|
@@ -37,49 +38,49 @@ module TimeBoss
|
|
37
38
|
allow(calendar).to receive(:years_for).with(subject).and_return %w[Y1]
|
38
39
|
end
|
39
40
|
|
40
|
-
it
|
41
|
+
it "knows about its days" do
|
41
42
|
expect(subject.days).to eq %w[D1 D2 D3 D4 D5 D6 D7 D8]
|
42
43
|
expect(subject.day).to be nil
|
43
44
|
end
|
44
45
|
|
45
|
-
it
|
46
|
+
it "knows about its weeks" do
|
46
47
|
expect(subject.weeks).to eq %w[W1 W2 W3 W4]
|
47
48
|
expect(subject.week).to be nil
|
48
49
|
end
|
49
50
|
|
50
|
-
it
|
51
|
+
it "knows about its months" do
|
51
52
|
expect(subject.months).to eq %w[M1 M2 M3]
|
52
53
|
expect(subject.month).to be nil
|
53
54
|
end
|
54
55
|
|
55
|
-
it
|
56
|
+
it "knows about its quarters" do
|
56
57
|
expect(subject.quarters).to eq %w[Q1 Q2]
|
57
58
|
expect(subject.quarter).to be nil
|
58
59
|
end
|
59
60
|
|
60
|
-
it
|
61
|
+
it "knows about its halves" do
|
61
62
|
expect(subject.halves).to eq %w[H1]
|
62
|
-
expect(subject.half).to eq
|
63
|
+
expect(subject.half).to eq "H1"
|
63
64
|
end
|
64
65
|
|
65
|
-
it
|
66
|
+
it "knows about its years" do
|
66
67
|
expect(subject.years).to eq %w[Y1]
|
67
|
-
expect(subject.year).to eq
|
68
|
+
expect(subject.year).to eq "Y1"
|
68
69
|
end
|
69
70
|
end
|
70
71
|
|
71
|
-
context
|
72
|
+
context "navigation" do
|
72
73
|
let(:result) { double }
|
73
74
|
|
74
|
-
describe
|
75
|
+
describe "#offset" do
|
75
76
|
end
|
76
77
|
|
77
|
-
it
|
78
|
+
it "can increment" do
|
78
79
|
expect(subject).to receive(:offset).with(7).and_return result
|
79
80
|
expect(subject + 7).to eq result
|
80
81
|
end
|
81
82
|
|
82
|
-
it
|
83
|
+
it "can decrement" do
|
83
84
|
expect(subject).to receive(:offset).with(-23).and_return result
|
84
85
|
expect(subject - 23).to eq result
|
85
86
|
end
|