koyomi 0.1.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b9fae146cc8b22c7813777006c1c558509aa3761
4
- data.tar.gz: 1294496c32deba891b31dbe5334e44fb2db1db2f
3
+ metadata.gz: 2424c6cda5e48fb64ecee69b6fb8b292b0a13e3a
4
+ data.tar.gz: b21e94aff1c9fe720a79ce9bd7bd076d679749d3
5
5
  SHA512:
6
- metadata.gz: 31eb8318ced1c68908e02837c9ca867ec673f8daa785f60b287f97d963edcfa285866c05c5f128c6456a50be968c6bd91387fb16609b3e5e67509c0cb010eb86
7
- data.tar.gz: 3672260d0178567dd8b173e6dffc005fb769edd8d567567dafe676e8b4c445a771d79bcd91ddd2796ad3a005978123e018ef6081418943b60a97bef60305c45c
6
+ metadata.gz: da9ef2356634f30e02edd0794a6e12d0a3ca0c762611a2a4aae879755f85849a57141c3e53def14b6293289cd6ddc112b3bad36aa68e5f4c8a81860f9c14f389
7
+ data.tar.gz: a90d16687d127b8182c082859e8ad78e30c5c97227a80de6d03bf7ca93ba69e15b886c4ceae56b3682129db01a9f6b168230e1e2955085289a85c942c88e6526
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --color
2
2
  --require spec_helper
3
+ # --format documentation
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.2.0 (2015-11-26)
4
+ * lib/koyomi/year.rb: Add Koyomi::Year class to treat years.
5
+ * lib/koyomi/month_cycle.rb: Add Koyomi::MonthCycle class to treat
6
+ cycles in month.
7
+ * lib/koyomi/wrong_range_error.rb: Added to raise error
8
+ outside of the month.
9
+ * lib/koyomi/month.rb: Changed to raise Koyomi::WrongRangeError
10
+ when specified date not within the month.
11
+
3
12
  ## 0.1.0 (2015-11-15)
4
13
 
5
14
  * use rspec
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- koyomi (0.1.1)
4
+ koyomi (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/lib/koyomi.rb CHANGED
@@ -1,13 +1,19 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require "koyomi/init"
4
- require "koyomi/version"
5
-
6
- require "koyomi/period"
7
- require "koyomi/month"
8
- require "koyomi/week"
9
- require "koyomi/calendar"
10
- require "koyomi/helper"
11
4
 
12
5
  module Koyomi
6
+ def self.year(year)
7
+ Koyomi::Year.new(year)
8
+ end
9
+
10
+ private
11
+
12
+ def self.method_missing(name, *args, &block)
13
+ if "#{name}".match(/^_[0-9]+$/)
14
+ self.year("#{name}".sub(/_/, "").to_i)
15
+ else
16
+ super
17
+ end
18
+ end
13
19
  end
@@ -6,7 +6,7 @@ require "koyomi/helper/week"
6
6
 
7
7
  class Koyomi::Calendar < Koyomi::Period
8
8
  include Koyomi::Helper::Week
9
-
9
+
10
10
  # create Koyomi::Calendar instance from date.
11
11
  #
12
12
  # @param [Date] date
@@ -15,26 +15,26 @@ class Koyomi::Calendar < Koyomi::Period
15
15
  def self.of(date, week_start = nil)
16
16
  self.new(date.year, date.month, week_start)
17
17
  end
18
-
18
+
19
19
  #--------------------#
20
20
  # instance methods
21
21
  attr_accessor :week_start
22
22
  attr_reader :year, :month, :koyomi_month
23
23
  attr_reader :weeks
24
-
24
+
25
25
  # initialize instance
26
26
  #
27
27
  # @param [Integer] year optional, use instance create date.
28
28
  # @param [Integer] month optional, use instance create date.
29
29
  # @param [Object] week_start weekday which week starts with. optional, use DEFAULT_WEEK_START.
30
- def initialize(year = nil, month = nil, week_start = nil)
30
+ def initialize(year = nil, month = nil, week_start = Koyomi::Week::DEFAULT_START)
31
31
  super()
32
32
  self.year = year||self.created_at.year
33
33
  self.month = month||self.created_at.month
34
34
  self.koyomi_month = Koyomi::Month.new(self.month, self.year)
35
- self.week_start = week_start||DEFAULT_WEEK_START
35
+ self.week_start = week_start
36
36
  end
37
-
37
+
38
38
  # set week_start
39
39
  #
40
40
  # @param [Object] value
@@ -42,44 +42,45 @@ class Koyomi::Calendar < Koyomi::Period
42
42
  self.setup_week_start(value)
43
43
  @week_start
44
44
  end
45
-
45
+
46
46
  # first date of the calendar (NOT first date of the MONTH)
47
47
  #
48
48
  # @return [Date]
49
49
  def first
50
50
  Koyomi::Week.new(self.koyomi_month.first, self.week_start).first
51
51
  end
52
-
52
+
53
53
  # last date of the calendar (NOT last date of the MONTH)
54
54
  #
55
55
  # @return [Date]
56
56
  def last
57
57
  Koyomi::Week.new(self.koyomi_month.last, self.week_start).last
58
58
  end
59
-
59
+
60
60
  # range of the calendar.
61
61
  #
62
62
  # @return [Range]
63
63
  def range
64
64
  Range.new(self.first, self.last)
65
65
  end
66
-
66
+
67
67
  # Koyomi::Month of the calendar's month.
68
68
  #
69
69
  # @return [Koyomi::Month]
70
70
  def the_month
71
71
  self.koyomi_month
72
72
  end
73
-
73
+
74
74
  # week day of nth week.
75
75
  #
76
76
  # @param [Integer] nth
77
77
  # @param [Object] wday_name
78
78
  # @return [Date]
79
79
  def nth_wday(nth, wday_name)
80
+ raise Koyomi::WrongRangeError if nth > weeks.size
80
81
  self.weeks[nth - 1].wday(wday_name)
81
82
  end
82
-
83
+
83
84
  # week days
84
85
  #
85
86
  # @param [Object] wday_name
@@ -87,7 +88,7 @@ class Koyomi::Calendar < Koyomi::Period
87
88
  def wdays(wday_name)
88
89
  self.weeks.collect { |w| w.wday(wday_name) }
89
90
  end
90
-
91
+
91
92
  # cycle dates
92
93
  #
93
94
  # @param [Array<Integer>|Integer] weeks
@@ -102,12 +103,12 @@ class Koyomi::Calendar < Koyomi::Period
102
103
  end
103
104
  _dates.sort
104
105
  end
105
-
106
+
106
107
  #--------------------#
107
108
  protected
108
-
109
+
109
110
  attr_writer :year, :month, :koyomi_month
110
-
111
+
111
112
  # setup week start
112
113
  #
113
114
  # @param [Object] value
@@ -115,7 +116,7 @@ class Koyomi::Calendar < Koyomi::Period
115
116
  @week_start = self.class.windex(value)
116
117
  self.setup_weeks(@week_start)
117
118
  end
118
-
119
+
119
120
  # setup weeks of the calendar.
120
121
  #
121
122
  # @return [Array<Week>]
@@ -123,17 +124,17 @@ class Koyomi::Calendar < Koyomi::Period
123
124
  a_date = self.first
124
125
  the_last = self.last
125
126
  @weeks = []
126
-
127
+
127
128
  while (a_date < the_last)
128
129
  @weeks << Koyomi::Week.new(a_date, week_start)
129
130
  a_date += WEEK_DAYS
130
131
  end
131
132
  @weeks
132
133
  end
133
-
134
+
134
135
  #--------------------#
135
136
  private
136
-
137
+
137
138
  # cycle weeks filter
138
139
  #
139
140
  # @param [Object] weeks
@@ -0,0 +1,5 @@
1
+ dir = File.join(File.dirname(__FILE__), "error")
2
+
3
+ Dir.glob(File.join(dir, "**/*.rb")).each do |f|
4
+ require f
5
+ end
@@ -0,0 +1,2 @@
1
+ class Koyomi::WrongRangeError < StandardError
2
+ end
data/lib/koyomi/init.rb CHANGED
@@ -6,3 +6,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
6
  # Define base module
7
7
  module Koyomi
8
8
  end
9
+
10
+ Dir.glob(File.join(lib, "**/*.rb")).each do |f|
11
+ require f
12
+ end
data/lib/koyomi/month.rb CHANGED
@@ -3,10 +3,10 @@
3
3
  require "koyomi/period"
4
4
 
5
5
  class Koyomi::Month < Koyomi::Period
6
-
6
+
7
7
  #--------------------#
8
8
  # class methods
9
-
9
+
10
10
  # create instance from date
11
11
  #
12
12
  # @param [Date] date
@@ -14,36 +14,55 @@ class Koyomi::Month < Koyomi::Period
14
14
  def self.of(date)
15
15
  self.new(date.month, date.year)
16
16
  end
17
-
17
+
18
18
  #--------------------#
19
19
  # instance methods
20
-
20
+
21
21
  attr_reader :year, :month
22
22
  attr_reader :first, :last
23
-
23
+
24
24
  # initialize instance.
25
25
  #
26
26
  # @param [Integer] month optional, default use the month of instance created.
27
27
  # @param [Integer] year optional, default use the year of instance created.
28
28
  def initialize(month = nil, year = nil)
29
29
  super()
30
- self.range = self.initialize_range(month, year)
30
+ @year = year||self.created_at.year
31
+ @month = month||self.created_at.month
32
+ @first = Date.new(self.year, self.month, 1)
33
+ @last = (first_date_of_next_month - 1)
34
+ @range = Range.new(self.first, self.last)
31
35
  end
32
-
36
+
33
37
  # next month
34
38
  #
35
39
  # @return [Koyomi::Month]
36
40
  def next
37
41
  self.class.of(self.last + 1)
38
42
  end
39
-
43
+
40
44
  # previous month
41
45
  #
42
46
  # @return [Koyomi::Month]
43
47
  def prev
44
48
  self.class.of(self.first - 1)
45
49
  end
46
-
50
+
51
+ # Create Koyomi::Calendar
52
+ #
53
+ # @param [Object] week_start
54
+ # @return [Koyomi::Calendar]
55
+ def calendar(week_start = Koyomi::Week::DEFAULT_START)
56
+ Koyomi::Calendar.new(year, month, week_start)
57
+ end
58
+
59
+ # Create Koyomi::MonthCycle
60
+ #
61
+ # @return [Koyomi::Cycle]
62
+ def cycle
63
+ Koyomi::MonthCycle.new(self)
64
+ end
65
+
47
66
  # week days of nth weeks.
48
67
  #
49
68
  # @param [Integer|Array<Integer>] nth
@@ -53,24 +72,45 @@ class Koyomi::Month < Koyomi::Period
53
72
  _dates = []
54
73
  cycle_weeks_filter(weeks).each do |n|
55
74
  [wdays].flatten.each do |w|
56
- a_date = self.nth_wday(n, w)
57
- _dates << a_date if a_date.month == self.month
75
+ begin
76
+ a_date = self.nth_wday!(n, w)
77
+ rescue Koyomi::WrongRangeError => e
78
+ next
79
+ else
80
+ _dates << a_date
81
+ end
58
82
  end
59
83
  end
60
84
  _dates.sort
61
85
  end
62
-
86
+
63
87
  # week day of nth week.
64
88
  #
65
89
  # @param [Integer] nth
66
90
  # @param [Object] wday_name
67
91
  # @return [Date]
68
92
  def nth_wday(nth, wday_name)
69
- a_date = Date.new(self.year, self.month, 1) + ((nth - 1) * Koyomi::Week::DAYS)
70
- Koyomi::Week.new(a_date, a_date.wday).wday(wday_name)
93
+ case "#{nth}"
94
+ when /first/
95
+ calc_nth_wday(1, wday_name)
96
+ when /last/
97
+ self.next.nth_wday(1, wday_name) - Koyomi::Week::DAYS
98
+ else
99
+ calc_nth_wday(nth, wday_name)
100
+ end
101
+ end
102
+
103
+ # week day of nth week.
104
+ #
105
+ # @param [Integer] nth
106
+ # @param [Object] wday_name
107
+ # @return [Date]
108
+ def nth_wday!(nth, wday_name)
109
+ date = nth_wday(nth, wday_name)
110
+ raise Koyomi::WrongRangeError if date.month != self.month
111
+ date
71
112
  end
72
-
73
-
113
+
74
114
  # week days
75
115
  #
76
116
  # @param [Object] wday_name
@@ -78,36 +118,38 @@ class Koyomi::Month < Koyomi::Period
78
118
  def wdays(wday_name)
79
119
  _dates = []
80
120
  a_date = self.nth_wday(1, wday_name)
81
-
121
+
82
122
  while (a_date.month == self.month)
83
123
  _dates << a_date
84
124
  a_date += Koyomi::Week::DAYS
85
125
  end
86
126
  _dates.sort
87
127
  end
88
-
89
- #--------------------#
90
- protected
91
-
92
- attr_writer :year, :month
93
- attr_writer :first, :last
94
-
95
- # initialize range
128
+
129
+ # date
96
130
  #
97
- # @param [Integer] month optional, default use the month of instance created.
98
- # @param [Integer] year optional, default use the year of instance created.
99
- # @return [Range]
100
- def initialize_range(month = nil, year = nil)
101
- self.year = year||self.created_at.year
102
- self.month = month||self.created_at.month
103
- self.first = Date.new(self.year, self.month, 1)
104
- self.last = (first_date_next_month(self.first) - 1)
105
- Range.new(self.first, self.last)
106
- end
107
-
131
+ # @param [Integer] days
132
+ # @return [Date]
133
+ def date(day)
134
+ begin
135
+ date!(day)
136
+ rescue ArgumentError => e
137
+ raise Koyomi::WrongRangeError
138
+ end
139
+ end
140
+
141
+ # date
142
+ # don't catch exceptions
143
+ #
144
+ # @param [Integer] days
145
+ # @return [Date]
146
+ def date!(day)
147
+ Date.new(self.year, self.month, "#{day}".to_i)
148
+ end
149
+
108
150
  #--------------------#
109
151
  private
110
-
152
+
111
153
  # filter cycle weeks
112
154
  #
113
155
  # @param [Object] weeks
@@ -121,24 +163,24 @@ class Koyomi::Month < Koyomi::Period
121
163
  end
122
164
  _weeks
123
165
  end
124
-
166
+
125
167
  # a date next month of the date
126
168
  #
127
169
  # @param [Date] date
128
170
  # @return [Date]
129
- def a_date_next_month(date)
130
- Date.new(date.year, date.month, 1) + 32
171
+ def a_date_of_next_month
172
+ self.first + 32
131
173
  end
132
-
174
+
133
175
  # first date of next month
134
176
  #
135
177
  # @param [Date] date
136
178
  # @return [Date]
137
- def first_date_next_month(date)
138
- a_date = a_date_next_month(date)
179
+ def first_date_of_next_month
180
+ a_date = a_date_of_next_month
139
181
  Date.new(a_date.year, a_date.month, 1)
140
182
  end
141
-
183
+
142
184
  # maximumn of weeks
143
185
  #
144
186
  # @return [Integer]
@@ -147,4 +189,13 @@ class Koyomi::Month < Koyomi::Period
147
189
  _fraction = (self.last.day % Koyomi::Week::DAYS)
148
190
  (_weeks + (_fraction == 0 ? 0 : 1))
149
191
  end
150
- end
192
+
193
+ def calc_nth_wday(nth, wday_name)
194
+ a_date = self.first + ((nth - 1) * Koyomi::Week::DAYS)
195
+ Koyomi::Week.new(a_date, a_date.wday).wday(wday_name)
196
+ end
197
+
198
+ def method_missing(name, *args, &block)
199
+ date("#{name}".sub(/^_/, "")) if "#{name}".match(/^_[0-9]+$/)
200
+ end
201
+ end
@@ -0,0 +1,35 @@
1
+ require "koyomi/month"
2
+
3
+ class Koyomi::MonthCycle
4
+ attr_reader :koyomi_month
5
+ attr_reader :dates
6
+
7
+ def initialize(koyomi_month)
8
+ super()
9
+ @koyomi_month = koyomi_month
10
+ @dates = []
11
+ end
12
+
13
+ def add(*args)
14
+
15
+ while arg = args.shift
16
+ case arg
17
+ when Date
18
+ raise Koyomi::WrongRangeError unless koyomi_month.range.include?(arg)
19
+ @dates << arg
20
+ else
21
+ #_args = [arg]
22
+ #_args << args.shift
23
+ @dates += koyomi_month.cycles(*arg)
24
+ end
25
+ end
26
+ uniq_and_sort
27
+ self
28
+ end
29
+
30
+ private
31
+
32
+ def uniq_and_sort
33
+ @dates = @dates.uniq.sort
34
+ end
35
+ end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Koyomi
4
- VERSION = "0.1.1"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/koyomi/week.rb CHANGED
@@ -5,18 +5,18 @@ require "koyomi/period"
5
5
  class Koyomi::Week < Koyomi::Period
6
6
  #--------------------#
7
7
  # constants
8
-
8
+
9
9
  DEFAULT_START = :mon
10
10
  WDAYS = [:sun, :mon, :tue, :wed, :thu, :fri, :sat]
11
11
  DAYS = WDAYS.size
12
12
  START_RANGE = (0..(DAYS - 1))
13
-
13
+
14
14
  #--------------------#
15
15
  # attributes
16
-
16
+
17
17
  #--------------------#
18
18
  # class methods
19
-
19
+
20
20
  # week index
21
21
  #
22
22
  # @param [Object] value
@@ -37,7 +37,7 @@ class Koyomi::Week < Koyomi::Period
37
37
  raise "Range overflow, required (#{START_RANGE})." unless START_RANGE.cover?(index)
38
38
  index
39
39
  end
40
-
40
+
41
41
  # week day name
42
42
  #
43
43
  # @param [Object] value
@@ -45,40 +45,38 @@ class Koyomi::Week < Koyomi::Period
45
45
  def self.wday_name(value)
46
46
  WDAYS.at(self.windex(value))
47
47
  end
48
-
48
+
49
49
  # week starts?
50
50
  #
51
51
  # @param [Date] date
52
52
  # @param [Object] start_wday week start
53
53
  # @return [Boolean]
54
- def self.starts?(date, start_wday = nil)
55
- start_wday ||= DEFAULT_START
54
+ def self.starts?(date, start_wday = DEFAULT_START)
56
55
  (date).wday == self.windex(start_wday)
57
56
  end
58
-
57
+
59
58
  # week end?
60
59
  #
61
60
  # @param [Date] date
62
61
  # @param [Object] start_wday week start
63
62
  # @return [Boolean]
64
- def self.ends?(date, start_wday = nil)
65
- start_wday ||= DEFAULT_START
63
+ def self.ends?(date, start_wday = DEFAULT_START)
66
64
  (date + 1).wday == self.windex(start_wday)
67
65
  end
68
-
66
+
69
67
  #--------------------#
70
68
  # instance methods
71
-
69
+
72
70
  # initialize method
73
71
  #
74
72
  # @param [Date] date optional, default use Date.today.
75
73
  # @param [Object] start_wday optionail, default use Koyomi::Week::DEFAULT_START
76
- def initialize(date = nil, start_wday = nil)
74
+ def initialize(date = nil, start_wday = DEFAULT_START)
77
75
  super()
78
76
  self.date = date||self.created_at
79
- self.start_wday = start_wday||DEFAULT_START
77
+ self.start_wday = start_wday
80
78
  end
81
-
79
+
82
80
  # sepified week day
83
81
  #
84
82
  # @param [Object] wday_name
@@ -88,27 +86,27 @@ class Koyomi::Week < Koyomi::Period
88
86
  factor = diff + ((diff < 0) ? DAYS : 0)
89
87
  self.range.first + factor
90
88
  end
91
-
89
+
92
90
  # start date
93
91
  #
94
92
  # @return [Date] date
95
93
  def starts
96
94
  self.range.first
97
95
  end
98
-
96
+
99
97
  # end date
100
98
  #
101
99
  # @return [Date] date
102
100
  def ends
103
101
  self.range.last
104
102
  end
105
-
103
+
106
104
  #--------------------#
107
105
  protected
108
-
106
+
109
107
  attr_accessor :date
110
108
  attr_reader :start_wday
111
-
109
+
112
110
  # set week starts
113
111
  #
114
112
  # @param [Object] value
@@ -117,17 +115,17 @@ class Koyomi::Week < Koyomi::Period
117
115
  self.setup_range
118
116
  @start_wday
119
117
  end
120
-
118
+
121
119
  # setup week range with given week start
122
120
  def setup_range
123
121
  diff = self.date.wday - self.class.windex(self.start_wday)
124
122
  starts = self.date - (diff + ((diff < 0) ? DAYS : 0))
125
123
  @range = Range.new(starts, starts + DAYS - 1)
126
124
  end
127
-
125
+
128
126
  #--------------------#
129
127
  private
130
-
128
+
131
129
  def method_missing(name, *args, &block)
132
130
  case
133
131
  when WDAYS.include?(name.to_s.to_sym)
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+
3
+ require "koyomi/period"
4
+
5
+ class Koyomi::Year < Koyomi::Period
6
+ #--------------------#
7
+ # class methods
8
+
9
+ # create instance from date
10
+ #
11
+ # @param [Date] date
12
+ # @return [Koyomi::Year]
13
+ def self.of(date = Date.today)
14
+ self.new(date.year)
15
+ end
16
+
17
+ #--------------------#
18
+ # instance methods
19
+
20
+ attr_reader :year
21
+ attr_reader :first, :last
22
+
23
+ # initialize instance.
24
+ #
25
+ # @param [Integer] year optional, default use the year of instance created.
26
+ def initialize(year = nil)
27
+ super()
28
+ @year = year||created_at.year
29
+ @first = Date.new(@year, 1, 1)
30
+ @last = Date.new(@year, 12, 31)
31
+ @range = (@first .. @last)
32
+ end
33
+
34
+ (1..12).each do |m|
35
+ define_method("_#{m}") do
36
+ Koyomi::Month.new(m, year)
37
+ end
38
+ end
39
+
40
+ def month(month)
41
+ Koyomi::Month.new(month, year)
42
+ end
43
+
44
+ def uruu?
45
+ begin
46
+ Date.new(year, 2, 29)
47
+ rescue ArgumentError => e
48
+ false
49
+ else
50
+ true
51
+ end
52
+ end
53
+ alias_method :leap?, :uruu?
54
+ end
@@ -0,0 +1,8 @@
1
+ require "koyomi_helper"
2
+
3
+ describe Koyomi do
4
+ describe "sequence" do
5
+ subject { described_class._2015._12._25 }
6
+ it { is_expected.to eq Date.new(2015, 12, 25) }
7
+ end
8
+ end
@@ -56,8 +56,8 @@ describe Koyomi::Calendar do
56
56
 
57
57
  describe "size" do
58
58
  subject { calendar.weeks.size }
59
- let(:calendar) { described_class.new(*test_case) }
60
- let(:test_case) { nil }
59
+ let(:calendar) { described_class.new(*given) }
60
+ let(:given) { nil }
61
61
 
62
62
  context "has 5 weeks" do
63
63
  # 2015-11 ~ 2015-12 start with sunday
@@ -69,7 +69,7 @@ describe Koyomi::Calendar do
69
69
  # 29 30 1 2 3 4 5
70
70
  #
71
71
  # #=> 5 weeks
72
- let(:test_case) { [2015, 11, :sun] }
72
+ let(:given) { [2015, 11, :sun] }
73
73
  it { is_expected.to eq 5 }
74
74
  end # context "has 5 weeks"
75
75
 
@@ -84,7 +84,7 @@ describe Koyomi::Calendar do
84
84
  # 30 1 2 3 4 5 6
85
85
  #
86
86
  # #=> 6 weeks
87
- let(:test_case) { [2015, 11, :mon] }
87
+ let(:given) { [2015, 11, :mon] }
88
88
  it { is_expected.to eq 6 }
89
89
  end # context "has 6 weeks"
90
90
  end # describe size
@@ -113,9 +113,7 @@ describe Koyomi::Calendar do
113
113
  context "range over" do
114
114
  subject { calendar.nth_wday(6, :mon) }
115
115
 
116
- xit "[TODO] raise Koyomi::WrongRangeError" do
117
- expect { subject }.to raise_error(NoMethodError)
118
- end
116
+ it { expect { subject }.to raise_error(Koyomi::WrongRangeError) }
119
117
  end
120
118
  end
121
119
 
@@ -138,10 +136,10 @@ describe Koyomi::Calendar do
138
136
  end
139
137
 
140
138
  describe "#cycles" do
141
- subject { calendar.cycles(*test_case) }
139
+ subject { calendar.cycles(*given) }
142
140
 
143
141
  context "first and third tuesday and friday" do
144
- let(:test_case) { [[1, 3], [:tue, :fri]] }
142
+ let(:given) { [[1, 3], [:tue, :fri]] }
145
143
  it { expect(subject.size).to eq 4 }
146
144
 
147
145
  it "days has requested week day" do
@@ -152,7 +150,7 @@ describe Koyomi::Calendar do
152
150
  end # context "first and third tuesday and friday"
153
151
 
154
152
  context "every monday and friday" do
155
- let(:test_case) { [:every, [:mon, :fri]] }
153
+ let(:given) { [:every, [:mon, :fri]] }
156
154
  let(:calendar) { described_class.new(2015, 12, :mon) }
157
155
  # 2015-11 ~ 2016-01 start with monday
158
156
  #
@@ -0,0 +1,116 @@
1
+ require "koyomi_helper"
2
+
3
+ describe Koyomi::MonthCycle do
4
+ let(:month_cycle) { described_class.new(*initialized) }
5
+
6
+ describe ".new" do
7
+ it("initialized with Koyomi::Month") do
8
+ month = Koyomi::Month.new
9
+ expect { described_class.new(month) }.not_to raise_error
10
+ end
11
+ end
12
+
13
+ describe "#dates" do
14
+ subject { month_cycle.dates }
15
+ let(:initialized) { Koyomi::Month.new }
16
+ it { is_expected.to be_kind_of(Array) }
17
+ end
18
+
19
+ context "2015-11" do
20
+ let(:initialized) { Koyomi::Month.new(11, 2015) }
21
+ let(:action) { month_cycle.add(given) }
22
+
23
+ context "[[3, 1], :fri] given" do
24
+ let(:given) { [[3, 1], :fri] }
25
+ let(:expected) { [Date.new(2015, 11, 6), Date.new(2015, 11, 20)] }
26
+
27
+ describe "#add" do
28
+ subject { action }
29
+ it { expect { subject }.not_to raise_error }
30
+ it { expect { subject }.to change { month_cycle.dates.size }.from(0).to(expected.size) }
31
+ end
32
+
33
+ describe "#dates" do
34
+ subject { month_cycle.dates }
35
+ before { action }
36
+ it { is_expected.to eq expected }
37
+ it("sort") { expect(subject.first).to be < subject.last }
38
+ it("uniq") { expect(subject.size).to eq expected.size }
39
+ end
40
+ end
41
+
42
+ context "Date given" do
43
+ let(:given) { date }
44
+ let(:date) { Date.new(2015, 11, 1) }
45
+ let(:expected) { [date] }
46
+
47
+ describe "#add" do
48
+ subject { action }
49
+ it { expect { subject }.not_to raise_error }
50
+ it { expect { subject }.to change { month_cycle.dates.size }.from(0).to(expected.size) }
51
+ end
52
+
53
+ describe "#dates" do
54
+ subject { month_cycle.dates }
55
+ before { action }
56
+ it { is_expected.to eq expected }
57
+ end
58
+ end
59
+
60
+ context "invalid date given" do
61
+ let(:given) { date }
62
+ let(:date) { Date.new(2015, 12, 1) }
63
+ it { expect { month_cycle.add(date) }.to raise_error(Koyomi::WrongRangeError) }
64
+ let(:expected) { Koyomi::WrongRangeError }
65
+
66
+ describe "#add" do
67
+ subject { action }
68
+ it { expect { subject }.to raise_error(expected) }
69
+ end
70
+ end
71
+
72
+ context "add some times" do
73
+ let(:action) do
74
+ month_cycle.add(Date.new(2015, 11, 6)) # first friday
75
+ month_cycle.add([[1, 3], :fri]) # 2015-11-06, 2015-11-20
76
+ month_cycle.add(Date.new(2015, 11, 1))
77
+ end
78
+ let(:expected) { [Date.new(2015, 11,1), Date.new(2015, 11,6), Date.new(2015, 11,20)] }
79
+
80
+ describe "#add" do
81
+ subject { action }
82
+ it { expect { subject }.not_to raise_error }
83
+ it { expect { subject }.to change { month_cycle.dates.size }.from(0).to(expected.size) }
84
+ end
85
+
86
+ describe "#dates" do
87
+ subject { month_cycle.dates }
88
+ before { action }
89
+ it { is_expected.to eq expected }
90
+ it("is sorted") { expect(subject.first).to be < subject.last }
91
+ it("is uniqed") { expect(subject.size).to eq expected.size }
92
+ end
93
+ end
94
+
95
+ context "add sequencial" do
96
+ let(:action) do
97
+ month_cycle.add([[3, 1], :fri]).add(Date.new(2015, 11, 1))
98
+ end
99
+ let(:expected) { [Date.new(2015, 11,1), Date.new(2015, 11,6), Date.new(2015, 11,20)] }
100
+
101
+ describe "#add" do
102
+ subject { action }
103
+ it { expect { subject }.not_to raise_error }
104
+ it { expect { subject }.to change { month_cycle.dates.size }.from(0).to(expected.size) }
105
+ end
106
+
107
+ describe "#dates" do
108
+ subject { month_cycle.dates }
109
+ before { action }
110
+ it { is_expected.to eq expected }
111
+ it("is sorted") { expect(subject.first).to be < subject.last }
112
+ it("is uniqed") { expect(subject.size).to eq expected.size }
113
+ end
114
+ end
115
+ end
116
+ end
@@ -6,32 +6,44 @@ describe Koyomi::Month do
6
6
 
7
7
  describe "#range" do
8
8
  subject { month.range }
9
-
10
9
  it { is_expected.to be_kind_of(Range) }
11
10
  end
12
11
 
13
12
  describe "#month" do
14
13
  subject { month.month }
15
-
16
14
  it { is_expected.to eq today.month }
17
15
  end
18
16
 
19
17
  describe "#next" do
20
18
  subject { month.next }
21
-
22
19
  it { is_expected.to be_kind_of(described_class) }
23
20
  it { expect(subject.month).to eq ((month.first + 32).month) }
24
21
  end
25
22
 
26
23
  describe "#prev" do
27
24
  subject { month.prev }
28
-
29
25
  it { is_expected.to be_kind_of(described_class) }
30
26
  it { expect(subject.month).to eq ((month.first - 1).month) }
31
27
  end
32
28
 
29
+ describe "#nth_wday!" do
30
+ subject { month.nth_wday!(*given) }
31
+ let(:month) { described_class.new(12, 2015) }
32
+ # 2015-12
33
+ # 1 2 3 4 5 6
34
+ # 7 8 9 10 11 12 13
35
+ # 14 15 16 17 18 19 20
36
+ # 21 22 23 24 25 26 27
37
+ # 28 29 30 31
38
+
39
+ context "5th friday" do
40
+ let(:given) { [5, :fri] }
41
+ it { expect { subject }.to raise_error(Koyomi::WrongRangeError) }
42
+ end
43
+ end
44
+
33
45
  describe "#nth_wday" do
34
- subject { month.nth_wday(*test_case) }
46
+ subject { month.nth_wday(*given) }
35
47
  let(:month) { described_class.new(12, 2015) }
36
48
  # 2015-12
37
49
  # 1 2 3 4 5 6
@@ -40,26 +52,30 @@ describe Koyomi::Month do
40
52
  # 21 22 23 24 25 26 27
41
53
  # 28 29 30 31
42
54
 
43
- context "first saturday" do
44
- let(:test_case) { [1, :sat] }
55
+ context "1st saturday" do
56
+ let(:given) { [1, :sat] }
45
57
  it { is_expected.to eq Date.new(2015, 12, 5) }
46
58
  end
47
59
 
60
+ context "first friday" do
61
+ let(:given) { [:first, :fri] }
62
+ it { is_expected.to eq Date.new(2015, 12, 4) }
63
+ end
64
+
48
65
  context "last saturday" do
49
- let(:test_case) { [:last, :sat] }
50
- xit { is_expected.to eq Date.new(2015, 12, 26) }
66
+ let(:given) { [:last, :sat] }
67
+ it { is_expected.to eq Date.new(2015, 12, 26) }
51
68
  end
52
69
 
53
70
  context "5th friday" do
54
- let(:test_case) { [5, :fri] }
55
- xit("[TODO] raise Koyomi::WrongRangeError") {
56
- is_expected.to raise_error(Koyomi::WrongRangeError)
57
- }
71
+ let(:given) { [5, :fri] }
72
+ it { expect { subject }.not_to raise_error }
73
+ it { is_expected.to eq Date.new(2016, 1, 1) }
58
74
  end
59
75
  end
60
76
 
61
77
  describe "#wdays" do
62
- subject { month.wdays(test_case) }
78
+ subject { month.wdays(given) }
63
79
  let(:month) { described_class.new(12, 2015) }
64
80
  # 2015-12
65
81
  # 1 2 3 4 5 6
@@ -69,18 +85,18 @@ describe Koyomi::Month do
69
85
  # 28 29 30 31
70
86
 
71
87
  context "monday" do
72
- let(:test_case) { :mon }
88
+ let(:given) { :mon }
73
89
  it { expect(subject.size).to eq 4 }
74
90
  end
75
91
 
76
92
  context "tuesday" do
77
- let(:test_case) { :tue }
93
+ let(:given) { :tue }
78
94
  it { expect(subject.size).to eq 5 }
79
95
  end
80
96
  end
81
97
 
82
98
  describe "#cycles" do
83
- subject { month.cycles(*test_case) }
99
+ subject { month.cycles(*given) }
84
100
  let(:month) { described_class.new(12, 2015) }
85
101
  # 2015-12
86
102
  # 1 2 3 4 5 6
@@ -91,7 +107,7 @@ describe Koyomi::Month do
91
107
 
92
108
  context "first and third monday, friday" do
93
109
  # 4, 7, 18, 21
94
- let(:test_case) { [[1, 3], [:mon, :fri]] }
110
+ let(:given) { [[1, 3], [:mon, :fri]] }
95
111
  its(:size) { is_expected.to eq 4 }
96
112
  its(:first) { is_expected.to eq Date.new(2015, 12, 4) }
97
113
  its(:last) { is_expected.to eq Date.new(2015, 12, 21) }
@@ -99,10 +115,129 @@ describe Koyomi::Month do
99
115
 
100
116
  context "every monday, thursday" do
101
117
  # 3, 7, 10, 14, 17, 21, 24, 28, 31
102
- let(:test_case) { [:every, [:mon, :thu]] }
118
+ let(:given) { [:every, [:mon, :thu]] }
103
119
  its(:size) { is_expected.to eq 9 }
104
120
  its(:first) { is_expected.to eq Date.new(2015, 12, 3) }
105
121
  its(:last) { is_expected.to eq Date.new(2015, 12, 31) }
106
122
  end
107
123
  end
124
+
125
+ describe "#first" do
126
+ subject { month.first }
127
+
128
+ context "given 2015-12" do
129
+ let(:month) { described_class.new(12, 2015) }
130
+ it { expect(subject.day).to eq 1 }
131
+ end
132
+ end
133
+
134
+ describe "#last" do
135
+ subject { month.last }
136
+
137
+ context "given 2015-12" do
138
+ let(:month) { described_class.new(12, 2015) }
139
+ it { expect(subject.day).to eq 31 }
140
+ end
141
+ end
142
+
143
+ describe "#date" do
144
+ let(:month) { described_class.new(*given) }
145
+
146
+ context "2015-11" do
147
+ let(:given) { [11, 2015] }
148
+ it { expect(month.date(1)).to eq Date.new(2015, 11, 1) }
149
+ it { expect(month._1).to eq Date.new(2015, 11, 1) }
150
+ end
151
+
152
+ context "2015-02" do
153
+ let(:given) { [2, 2015] }
154
+
155
+ context "day 28" do
156
+ let(:day) { 28 }
157
+ let(:expected) { Date.new(2015, 2, day) }
158
+ it { expect(month.date(day)).to eq expected }
159
+ it { expect(month._28).to eq expected }
160
+ end
161
+
162
+ context "day 29" do
163
+ let(:day) { 29 }
164
+ let(:expected) { Koyomi::WrongRangeError }
165
+ it { expect { month.date(day) }.to raise_error(expected) }
166
+ it { expect { month._29 }.to raise_error(expected) }
167
+ end
168
+ end
169
+ end
170
+
171
+ describe "#calendar" do
172
+ let(:month) { described_class.new(*given) }
173
+ context "week start not given" do
174
+ subject { month.calendar() }
175
+ context "2015-11" do
176
+ # 2015-11 month
177
+ # 1
178
+ # 2 3 4 5 6 7 8
179
+ # 9 10 11 12 13 14 15
180
+ # 16 17 18 19 20 21 22
181
+ # 23 24 25 26 27 28 29
182
+ # 30
183
+ #
184
+ # expected calendar
185
+ # 2015-10 ~ 2015-12
186
+ # 26 27 28 29 30 31 1
187
+ # 2 3 4 5 6 7 8
188
+ # 9 10 11 12 13 14 15
189
+ # 16 17 18 19 20 21 22
190
+ # 23 24 25 26 27 28 29
191
+ # 30 1 2 3 4 5 6
192
+ #
193
+ let(:given) { [11, 2015] }
194
+ it { is_expected.to be_kind_of Koyomi::Calendar }
195
+ describe "calendar attributes" do
196
+ let(:expected_wday) { Koyomi::Week.windex(Koyomi::Week::DEFAULT_START) }
197
+ its("#year") { expect(subject.year).to eq 2015 }
198
+ its("#month") { expect(subject.month).to eq 11 }
199
+ its("#week_start") { expect(subject.week_start).to eq expected_wday }
200
+ its("#first") { expect(subject.first).to eq Date.new(2015, 10, 26) }
201
+ its("#last") { expect(subject.last).to eq Date.new(2015, 12, 6) }
202
+ end
203
+ end
204
+ end
205
+
206
+ context "week start sunday" do
207
+ subject { month.calendar(week_start) }
208
+ let(:week_start) { :sun }
209
+ context "2015-11" do
210
+ # 2015-11 month
211
+ # 1 2 3 4 5 6 7
212
+ # 8 9 10 11 12 13 14
213
+ # 15 16 17 18 19 20 21
214
+ # 22 23 24 25 26 27 28
215
+ # 29 30
216
+ #
217
+ # expected calendar
218
+ # 2015-11 ~ 2015-12
219
+ # 1 2 3 4 5 6 7
220
+ # 8 9 10 11 12 13 14
221
+ # 15 16 17 18 19 20 21
222
+ # 22 23 24 25 26 27 28
223
+ # 29 30 1 2 3 4 5
224
+ #
225
+ let(:given) { [11, 2015] }
226
+ it { is_expected.to be_kind_of Koyomi::Calendar }
227
+ describe "calendar attributes" do
228
+ let(:expected_wday) { Koyomi::Week::WDAYS.index(week_start) }
229
+ its("#year") { expect(subject.year).to eq 2015 }
230
+ its("#month") { expect(subject.month).to eq 11 }
231
+ its("#week_start") { expect(subject.week_start).to eq expected_wday }
232
+ its("#first") { expect(subject.first).to eq Date.new(2015, 11, 1) }
233
+ its("#last") { expect(subject.last).to eq Date.new(2015, 12, 5) }
234
+ end
235
+ end
236
+ end
237
+ end
238
+
239
+ describe "#cycle" do
240
+ subject { month.cycle }
241
+ it { is_expected.to be_kind_of(Koyomi::MonthCycle) }
242
+ end
108
243
  end
@@ -0,0 +1,102 @@
1
+ require "koyomi_helper"
2
+
3
+ describe Koyomi::Year do
4
+ let(:year) { described_class.new(*given) }
5
+
6
+ describe ".of" do
7
+ subject { year }
8
+ let(:year) { described_class.of(*given) }
9
+ let!(:today) { Date.today }
10
+
11
+ context "given nothing" do
12
+ let(:given) { }
13
+ it { expect(subject.year).to eq today.year }
14
+ end
15
+
16
+ context "given today" do
17
+ let(:given) { today }
18
+ it { expect(subject.year).to eq today.year }
19
+ end
20
+
21
+ context "given next year's first" do
22
+ let(:given) { Date.new(today.year + 1, 1, 1) }
23
+ it { expect(subject.year).to eq (today.year + 1)}
24
+ end
25
+
26
+ context "given prev year's first" do
27
+ let(:given) { Date.new(today.year - 1, 1, 1) }
28
+ it { expect(subject.year).to eq (today.year - 1)}
29
+ end
30
+ end
31
+
32
+ describe "#first" do
33
+ subject { year.first }
34
+
35
+ context "given year 2015" do
36
+ let(:given) { 2015 }
37
+ it { is_expected.to eq Date.new(2015, 1, 1) }
38
+ end
39
+ end
40
+
41
+ describe "#last" do
42
+ subject { year.last }
43
+
44
+ context "given year 2015" do
45
+ let(:given) { 2015 }
46
+ it { is_expected.to eq Date.new(2015, 12, 31) }
47
+ end
48
+ end
49
+
50
+ describe "month mothods" do
51
+ (1..12).each do |month|
52
+ context "given month #{month}" do
53
+ let(:given) { month }
54
+ subject { year.__send__("_#{month}") }
55
+ it { is_expected.to be_kind_of(Koyomi::Month) }
56
+ describe "its month" do
57
+ it { expect(subject.month).to eq month }
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ describe "#month" do
64
+ subject { year.month(given) }
65
+ (1..12).each do |month|
66
+ context "given #{month}" do
67
+ let(:given) { month }
68
+ it { is_expected.to be_kind_of(Koyomi::Month) }
69
+ describe "its month" do
70
+ it { expect(subject.month).to eq month }
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ [:uruu?, :leap?].each do |method|
77
+ describe "##{method}" do
78
+ subject { year.__send__(method) }
79
+ let(:year) { described_class.new(given) }
80
+
81
+ context "given year 1999" do
82
+ let(:given) { 1999 }
83
+ it { is_expected.to be_falsy }
84
+ end
85
+
86
+ context "given year 2000" do
87
+ let(:given) { 2000 }
88
+ it { is_expected.to be_truthy }
89
+ end
90
+
91
+ context "given year 2004" do
92
+ let(:given) { 2004 }
93
+ it { is_expected.to be_truthy }
94
+ end
95
+
96
+ context "given year 2100" do
97
+ let(:given) { 2100 }
98
+ it { is_expected.to be_falsy }
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,19 @@
1
+ require "koyomi_helper"
2
+
3
+ describe Koyomi do
4
+ describe ".year" do
5
+ subject { described_class.year(*given) }
6
+ context "given 2015" do
7
+ let(:given) { 2015 }
8
+ it { is_expected.to be_kind_of(Koyomi::Year) }
9
+ end
10
+ end
11
+
12
+ describe "._ year" do
13
+ context "given 2015" do
14
+ subject { described_class._2015 }
15
+ it { is_expected.to be_kind_of(Koyomi::Year)}
16
+ it { expect(subject.year).to eq 2015 }
17
+ end
18
+ end
19
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: koyomi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - sekizo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-15 00:00:00.000000000 Z
11
+ date: 2015-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -71,21 +71,29 @@ files:
71
71
  - koyomi.gemspec
72
72
  - lib/koyomi.rb
73
73
  - lib/koyomi/calendar.rb
74
+ - lib/koyomi/error.rb
75
+ - lib/koyomi/error/wrong_range_error.rb
74
76
  - lib/koyomi/helper.rb
75
77
  - lib/koyomi/helper/date.rb
76
78
  - lib/koyomi/helper/init.rb
77
79
  - lib/koyomi/helper/week.rb
78
80
  - lib/koyomi/init.rb
79
81
  - lib/koyomi/month.rb
82
+ - lib/koyomi/month_cycle.rb
80
83
  - lib/koyomi/period.rb
81
84
  - lib/koyomi/version.rb
82
85
  - lib/koyomi/week.rb
86
+ - lib/koyomi/year.rb
87
+ - spec/feature/koyomi_sequence_spec.rb
83
88
  - spec/koyomi_helper.rb
84
89
  - spec/lib/koyomi/calendar_spec.rb
85
90
  - spec/lib/koyomi/date_spec.rb
91
+ - spec/lib/koyomi/month_cycle_spec.rb
86
92
  - spec/lib/koyomi/month_spec.rb
87
93
  - spec/lib/koyomi/version_spec.rb
88
94
  - spec/lib/koyomi/week_spec.rb
95
+ - spec/lib/koyomi/year_spec.rb
96
+ - spec/lib/koyomi_spec.rb
89
97
  - spec/spec_helper.rb
90
98
  homepage: ''
91
99
  licenses:
@@ -112,10 +120,14 @@ signing_key:
112
120
  specification_version: 4
113
121
  summary: Add some classes to handle year, month, period.
114
122
  test_files:
123
+ - spec/feature/koyomi_sequence_spec.rb
115
124
  - spec/koyomi_helper.rb
116
125
  - spec/lib/koyomi/calendar_spec.rb
117
126
  - spec/lib/koyomi/date_spec.rb
127
+ - spec/lib/koyomi/month_cycle_spec.rb
118
128
  - spec/lib/koyomi/month_spec.rb
119
129
  - spec/lib/koyomi/version_spec.rb
120
130
  - spec/lib/koyomi/week_spec.rb
131
+ - spec/lib/koyomi/year_spec.rb
132
+ - spec/lib/koyomi_spec.rb
121
133
  - spec/spec_helper.rb