koyomi 0.1.1 → 0.2.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: 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