coaster 1.4.5 → 1.4.7

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
  SHA256:
3
- metadata.gz: '08822e51820887cf495240d0c1b53e44f30102f88b608c99eec3b3f455ba0f9d'
4
- data.tar.gz: 64f436a0a84ca84eb43029cbb49337c642d088650bdc7ffe438dc66d3a6f2894
3
+ metadata.gz: 5e8ae6d7e690ce70628c0687e935bd182eb3257e1b6253790a00cbd3c9ed6fc9
4
+ data.tar.gz: a9d9708ee72f4872184c9c2969b2b414015d48eedd99ee5bfe5881630f93bf25
5
5
  SHA512:
6
- metadata.gz: ba54e6173b8d509a4de9b814e319874fdb873a218befa685a8ea786e2ca6e01fed90a411bd54960459223f590bdb5e9ec6af6b22f26d820d06cc4e943e37f963
7
- data.tar.gz: 369a9b5b66b1141b5ee51ed8ab5707d7ca61331b650545af498390a465d34f2d95d72145457db051e5aa628027ba127485e611bad5378d2ad12332513d6fb336
6
+ metadata.gz: c17c5fe51f8dc29c2961d74918b949a7f0907df3e0fbbc273f75cb60aaf15fc561f51dbc8b17cf53bdc113df173acf7439b47a58a1d2d33ae8310783422328c6
7
+ data.tar.gz: cb22eedcdb827462e4b66beec6426a6b71561230e1fae62d873bd4244910ff1c1baeb176753e11734a7ec8db202d0e38472c1deef075a25fdabec2ea529a1fc0
@@ -2,4 +2,54 @@ class Date
2
2
  def to_time_range
3
3
  beginning_of_day...(self + 1.day).beginning_of_day
4
4
  end
5
+
6
+ def prev_specific_date(day_num)
7
+ raise Date::Error, 'invalid date' if day_num < 1 || day_num > 31
8
+
9
+ m = Month.from(self)
10
+ if day_num < day
11
+ begin
12
+ m.date_for_day(day_num)
13
+ rescue Date::Error
14
+ m.last_date
15
+ end
16
+ else
17
+ begin
18
+ m.previous.date_for_day(day_num)
19
+ rescue Date::Error
20
+ m.previous.last_date
21
+ end
22
+ end
23
+ end
24
+
25
+ def next_specific_date(day_num)
26
+ raise Date::Error, 'invalid date' if day_num < 1 || day_num > 31
27
+
28
+ m = Month.from(self)
29
+ if day < day_num
30
+ if m.last_date.day < day_num
31
+ if day < m.last_date.day
32
+ m.last_date
33
+ else
34
+ begin
35
+ m.later.date_for_day(day_num)
36
+ rescue Date::Error
37
+ m.later.last_date
38
+ end
39
+ end
40
+ else
41
+ begin
42
+ m.date_for_day(day_num)
43
+ rescue Date::Error
44
+ m.last_date
45
+ end
46
+ end
47
+ else
48
+ begin
49
+ m.later.date_for_day(day_num)
50
+ rescue Date::Error
51
+ m.later.last_date
52
+ end
53
+ end
54
+ end
5
55
  end
@@ -1,23 +1,26 @@
1
1
  require 'attr_extras' # gem
2
2
 
3
3
  class Month
4
- vattr_initialize :_year, :_month
4
+ attr_reader :_year, :_month
5
+ attr_reader :timezone
5
6
 
6
7
  class << self
7
- def from(object)
8
+ def from(object, timezone: nil)
8
9
  case object
9
- when Month then object
10
- when String then Month.parse(object)
11
- when Array then Month.new(object[0], object[1])
12
- else new(object.year, object.month)
10
+ when Month
11
+ object.timezone = timezone
12
+ object
13
+ when String then Month.parse(object, timezone: timezone)
14
+ when Array then Month.new(object[0], object[1], timezone: timezone)
15
+ else new(object.year, object.month, timezone: timezone)
13
16
  end
14
17
  end
15
18
 
16
19
  # Month.parse('201601')
17
20
  # Month.parse('2016-01')
18
- def parse(str)
21
+ def parse(str, timezone: nil)
19
22
  date = Date.parse(str)
20
- from(date)
23
+ from(date, timezone: timezone)
21
24
  rescue ArgumentError => e
22
25
  if str.instance_variable_defined?(:@_gsub_) && str.instance_variable_get(:@_gsub_)
23
26
  raise e, str: str.instance_variable_get(:@_gsub_)
@@ -28,7 +31,7 @@ class Month
28
31
  str_gsub.insert(4, '0') if str_gsub.length == 5
29
32
  str_gsub += '01'
30
33
  str_gsub.instance_variable_set(:@_gsub_, str_gsub)
31
- parse(str_gsub)
34
+ parse(str_gsub, timezone: timezone)
32
35
  end
33
36
 
34
37
  def current
@@ -40,6 +43,17 @@ class Month
40
43
  end
41
44
  end
42
45
 
46
+ def initialize(year, month, timezone: nil)
47
+ @_year = year
48
+ @_month = month
49
+ self.timezone = timezone
50
+ end
51
+
52
+ def timezone=(tz)
53
+ tz = ActiveSupport::TimeZone[tz] if tz.is_a?(String)
54
+ @timezone = tz || Time.zone
55
+ end
56
+
43
57
  def year
44
58
  Integer(@_year)
45
59
  end
@@ -49,11 +63,11 @@ class Month
49
63
  end
50
64
 
51
65
  def first_date
52
- Date.new(year, month, 1)
66
+ @first_date ||= Date.new(year, month, 1)
53
67
  end
54
68
 
55
69
  def last_date
56
- Date.new(year, month, -1)
70
+ @last_date ||= Date.new(year, month, -1)
57
71
  end
58
72
 
59
73
  def each_date(&block)
@@ -69,11 +83,11 @@ class Month
69
83
  end
70
84
 
71
85
  def beginning_of_month
72
- first_date.beginning_of_day
86
+ first_date.in_time_zone(timezone)
73
87
  end
74
88
 
75
89
  def end_of_month
76
- last_date.end_of_day
90
+ last_date.in_time_zone(timezone).end_of_day
77
91
  end
78
92
 
79
93
  def date_for_day(number)
@@ -93,16 +107,24 @@ class Month
93
107
  end
94
108
 
95
109
  def to_s
96
- "#{year}-#{month}"
110
+ first_date.strftime('%Y-%m')
97
111
  end
98
112
  alias_method :inspect, :to_s
99
113
 
100
114
  def -(time)
101
- first_date - time
115
+ case time
116
+ when ActiveSupport::Duration then first_date.in_time_zone(timezone) - time
117
+ else
118
+ first_date - time
119
+ end
102
120
  end
103
121
 
104
122
  def +(time)
105
- first_date + time
123
+ case time
124
+ when ActiveSupport::Duration then first_date.in_time_zone(timezone) + time
125
+ else
126
+ first_date + time
127
+ end
106
128
  end
107
129
 
108
130
  include Comparable
@@ -117,10 +117,10 @@ module Coaster
117
117
  puts "[DEEP_MERGE] #{path} #{pointer}"
118
118
  submodules.values.each do |submodule|
119
119
  sm_sha = submodule_sha(submodule.path, pointer: pointer)
120
- submodule.merge(sm_sha)
120
+ submodule.merge(sm_sha) if sm_sha.present?
121
121
  end
122
122
  merge_without_submodules do
123
- merge(pointer)
123
+ merge(pointer) if pointer.present?
124
124
  end
125
125
  end
126
126
 
@@ -106,7 +106,7 @@ module Coaster
106
106
  _define_serialized_property(serialize_column, key, default: default || [])
107
107
  elsif type.respond_to?(:serialized_property_serializer) && (serializer = type.serialized_property_serializer)
108
108
  _define_serialized_property(serialize_column, key, getter: serializer[:getter], setter: serializer[:setter], setter_callback: serializer[:setter_callback], default: default)
109
- elsif type && type < ActiveRecord::Base
109
+ elsif type.is_a?(Class) && type < ActiveRecord::Base
110
110
  _define_serialized_property serialize_column, "#{key}_id", default: default
111
111
 
112
112
  define_method key.to_sym do
@@ -1,3 +1,3 @@
1
1
  module Coaster
2
- VERSION = '1.4.5'
2
+ VERSION = '1.4.7'
3
3
  end
data/test/test_helper.rb CHANGED
@@ -2,6 +2,8 @@ ENV['DEBUG'] = 'true'
2
2
 
3
3
  require 'minitest'
4
4
  require 'pry'
5
+ require 'pry-byebug'
6
+ require 'pry-stack_explorer'
5
7
 
6
8
  require 'rubygems'
7
9
  require 'bundler/setup'
data/test/test_month.rb CHANGED
@@ -9,6 +9,54 @@ module Coaster
9
9
  assert_equal m.last_date, Date.parse('20200131')
10
10
  assert_equal m.end_of_month, Date.parse('20200131').end_of_day
11
11
  assert_equal m.to_time_range, Date.parse('20200101').beginning_of_day...Date.parse('20200201').beginning_of_day
12
+ assert_equal m.to_s, '2020-01'
13
+ end
14
+
15
+ def test_timezone
16
+ m = Month.parse('202001', timezone: 'Pacific/Midway')
17
+ assert_equal m.timezone, ActiveSupport::TimeZone['Pacific/Midway']
18
+ assert_equal m.beginning_of_month, Date.parse('20200101').in_time_zone('Pacific/Midway')
19
+ end
20
+
21
+ def test_next_specific_date
22
+ d = Date.parse('20200101')
23
+ assert_equal d.next_specific_date(1), Date.parse('20200201')
24
+ assert_equal d.next_specific_date(2), Date.parse('20200102')
25
+ assert_equal d.next_specific_date(31), Date.parse('20200131')
26
+ d = Date.parse('20200131')
27
+ assert_equal d.next_specific_date(31), Date.parse('20200229')
28
+ d = Date.parse('20200130')
29
+ assert_equal d.next_specific_date(31), Date.parse('20200131')
30
+ d = Date.parse('20200129')
31
+ assert_equal d.next_specific_date(29), Date.parse('20200229')
32
+ d = Date.parse('20200210')
33
+ assert_equal d.next_specific_date(29), Date.parse('20200229')
34
+ assert_equal d.next_specific_date(30), Date.parse('20200229')
35
+ assert_equal d.next_specific_date(31), Date.parse('20200229')
36
+ d = Date.parse('20210210')
37
+ assert_equal d.next_specific_date(9), Date.parse('20210309')
38
+ assert_equal d.next_specific_date(10), Date.parse('20210310')
39
+ assert_equal d.next_specific_date(29), Date.parse('20210228')
40
+ assert_equal d.next_specific_date(30), Date.parse('20210228')
41
+ assert_equal d.next_specific_date(31), Date.parse('20210228')
42
+ d = Date.parse('20210228')
43
+ assert_equal d.next_specific_date(31), Date.parse('20210331')
44
+ end
45
+
46
+ def test_prev_specific_date
47
+ d = Date.parse('20200101')
48
+ assert_equal d.prev_specific_date(1), Date.parse('20191201')
49
+ assert_equal d.prev_specific_date(2), Date.parse('20191202')
50
+ assert_equal d.prev_specific_date(31), Date.parse('20191231')
51
+ d = Date.parse('20200331')
52
+ assert_equal d.prev_specific_date(31), Date.parse('20200229')
53
+ assert_equal d.prev_specific_date(30), Date.parse('20200330')
54
+ d = Date.parse('20200330')
55
+ assert_equal d.prev_specific_date(30), Date.parse('20200229')
56
+ d = Date.parse('20200229')
57
+ assert_equal d.prev_specific_date(29), Date.parse('20200129')
58
+ assert_equal d.prev_specific_date(30), Date.parse('20200130')
59
+ assert_equal d.prev_specific_date(31), Date.parse('20200131')
12
60
  end
13
61
  end
14
62
  end
data/test/test_string.rb CHANGED
@@ -64,22 +64,16 @@ module Coaster
64
64
  not_target_full_seq = ((33..255).map { |c| (c + 0xfee0).chr('UTF-8') }.join.chars - full_seq.chars).join + '일이삼いちにさんイチニサン一二三'
65
65
  mixed_str = full_seq + not_target_full_seq
66
66
  # full -> half 1:1 잘 변환되는가?
67
- expect(full_seq.to_half_characters(symbol: true)).to eq half_seq
68
67
  assert_equal full_seq.to_half_characters(symbol: true), half_seq
69
68
  # full -> half -> full 변환 시, 원래 string 유지되는가?
70
- expect(full_seq.to_half_characters(symbol: true).to_full_characters(symbol: true)).to eq full_seq
71
69
  assert_equal full_seq.to_half_characters(symbol: true).to_full_characters(symbol: true), full_seq
72
70
  # not_target string은 to half 변환 시도시 원본이 유지되는가?
73
- expect(not_target_full_seq.to_half_characters(symbol: true)).to eq not_target_full_seq
74
71
  assert_equal not_target_full_seq.to_half_characters(symbol: true), not_target_full_seq
75
72
  # target / not_target이 섞여있는 문장에서, target'만' half로 변환되는가?
76
- expect(mixed_str.to_half_characters(symbol: true)).to eq half_seq + not_target_full_seq
77
73
  assert_equal mixed_str.to_half_characters(symbol: true), half_seq + not_target_full_seq
78
74
  # target / not_target이 섞여있는 문장에서, full -> half -> full 변환시, 원래 string 유지되는가?
79
- expect(mixed_str.to_half_characters(symbol: true).to_full_characters(symbol: true)).to eq mixed_str
80
75
  assert_equal mixed_str.to_half_characters(symbol: true).to_full_characters(symbol: true), mixed_str
81
76
  # 공백문자열에 다른게 추가되지는 않는가?
82
- expect(''.to_half_characters(symbol: true)).to eq ''
83
77
  assert_equal ''.to_half_characters(symbol: true), ''
84
78
  end
85
79
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coaster
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.5
4
+ version: 1.4.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - buzz jung
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-07 00:00:00.000000000 Z
11
+ date: 2024-01-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oj