by_star 4.0.0 → 4.0.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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/mysql.yml +92 -92
  3. data/.github/workflows/postgresql.yml +99 -99
  4. data/.gitignore +6 -6
  5. data/.travis.yml +92 -92
  6. data/CHANGELOG.md +63 -59
  7. data/Gemfile +18 -18
  8. data/MIT-LICENSE +20 -20
  9. data/README.md +616 -616
  10. data/Rakefile +18 -18
  11. data/UPGRADING +4 -4
  12. data/by_star.gemspec +34 -34
  13. data/cleaner.rb +24 -24
  14. data/lib/by_star/base.rb +69 -69
  15. data/lib/by_star/between.rb +185 -185
  16. data/lib/by_star/directional.rb +35 -35
  17. data/lib/by_star/kernel/date.rb +41 -41
  18. data/lib/by_star/kernel/in_time_zone.rb +20 -20
  19. data/lib/by_star/kernel/time.rb +41 -41
  20. data/lib/by_star/normalization.rb +156 -156
  21. data/lib/by_star/orm/active_record/by_star.rb +75 -75
  22. data/lib/by_star/orm/mongoid/by_star.rb +90 -90
  23. data/lib/by_star/orm/mongoid/reorder.rb +23 -23
  24. data/lib/by_star/version.rb +3 -3
  25. data/lib/by_star.rb +18 -18
  26. data/spec/database.yml +15 -15
  27. data/spec/fixtures/active_record/models.rb +12 -12
  28. data/spec/fixtures/active_record/schema.rb +19 -19
  29. data/spec/fixtures/mongoid/models.rb +31 -31
  30. data/spec/fixtures/shared/seeds.rb +36 -36
  31. data/spec/gemfiles/Gemfile.rails +5 -5
  32. data/spec/gemfiles/Gemfile.rails32 +7 -7
  33. data/spec/gemfiles/Gemfile.rails40 +7 -7
  34. data/spec/gemfiles/Gemfile.rails41 +7 -7
  35. data/spec/gemfiles/Gemfile.rails42 +7 -7
  36. data/spec/gemfiles/Gemfile.rails50 +7 -7
  37. data/spec/gemfiles/Gemfile.rails51 +7 -7
  38. data/spec/gemfiles/Gemfile.rails52 +7 -7
  39. data/spec/gemfiles/Gemfile.rails60 +7 -7
  40. data/spec/gemfiles/Gemfile.rails61 +7 -7
  41. data/spec/integration/active_record/active_record_spec.rb +41 -41
  42. data/spec/integration/mongoid/mongoid_spec.rb +39 -39
  43. data/spec/integration/shared/at_time.rb +53 -53
  44. data/spec/integration/shared/between_dates.rb +99 -99
  45. data/spec/integration/shared/between_times.rb +99 -99
  46. data/spec/integration/shared/by_calendar_month.rb +55 -55
  47. data/spec/integration/shared/by_cweek.rb +54 -54
  48. data/spec/integration/shared/by_day.rb +120 -120
  49. data/spec/integration/shared/by_direction.rb +126 -126
  50. data/spec/integration/shared/by_fortnight.rb +48 -48
  51. data/spec/integration/shared/by_month.rb +50 -50
  52. data/spec/integration/shared/by_quarter.rb +49 -49
  53. data/spec/integration/shared/by_week.rb +54 -54
  54. data/spec/integration/shared/by_weekend.rb +49 -49
  55. data/spec/integration/shared/by_year.rb +48 -48
  56. data/spec/integration/shared/index_scope_parameter.rb +111 -111
  57. data/spec/integration/shared/offset_parameter.rb +32 -32
  58. data/spec/integration/shared/order_parameter.rb +36 -36
  59. data/spec/integration/shared/relative.rb +174 -174
  60. data/spec/spec_helper.rb +33 -33
  61. data/spec/unit/kernel_date_spec.rb +113 -113
  62. data/spec/unit/kernel_time_spec.rb +57 -57
  63. data/spec/unit/normalization_spec.rb +384 -384
  64. data/tmp/.gitignore +1 -1
  65. metadata +3 -3
@@ -1,35 +1,35 @@
1
- module ByStar
2
-
3
- module Directional
4
-
5
- def before(*args)
6
- with_by_star_options(*args) do |time, options|
7
- field = by_star_start_field(options)
8
- time = ByStar::Normalization.time(time)
9
- by_star_before_query(self, field, time)
10
- end
11
- end
12
- alias_method :before_now, :before
13
-
14
- def after(*args)
15
- with_by_star_options(*args) do |time, options|
16
- field = by_star_start_field(options)
17
- time = ByStar::Normalization.time(time)
18
- by_star_after_query(self, field, time)
19
- end
20
- end
21
- alias_method :after_now, :after
22
-
23
- def oldest(*args)
24
- with_by_star_options(*args) do |time, options|
25
- oldest_query(options)
26
- end
27
- end
28
-
29
- def newest(*args)
30
- with_by_star_options(*args) do |time, options|
31
- newest_query(options)
32
- end
33
- end
34
- end
35
- end
1
+ module ByStar
2
+
3
+ module Directional
4
+
5
+ def before(*args)
6
+ with_by_star_options(*args) do |time, options|
7
+ field = by_star_start_field(options)
8
+ time = ByStar::Normalization.time(time)
9
+ by_star_before_query(self, field, time)
10
+ end
11
+ end
12
+ alias_method :before_now, :before
13
+
14
+ def after(*args)
15
+ with_by_star_options(*args) do |time, options|
16
+ field = by_star_start_field(options)
17
+ time = ByStar::Normalization.time(time)
18
+ by_star_after_query(self, field, time)
19
+ end
20
+ end
21
+ alias_method :after_now, :after
22
+
23
+ def oldest(*args)
24
+ with_by_star_options(*args) do |time, options|
25
+ oldest_query(options)
26
+ end
27
+ end
28
+
29
+ def newest(*args)
30
+ with_by_star_options(*args) do |time, options|
31
+ newest_query(options)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,41 +1,41 @@
1
- module ByStar
2
-
3
- module Kernel
4
-
5
- module Date
6
-
7
- # A "Weekend" is defined as beginning of Saturday to end of Sunday.
8
- # The weekend for a given date will be the the next weekend if the day Mon-Thurs,
9
- # otherwise the current weekend if the day is Fri-Sun.
10
- def beginning_of_weekend
11
- beginning_of_week(:monday).advance(days: 5)
12
- end
13
-
14
- def end_of_weekend
15
- beginning_of_weekend + 1
16
- end
17
-
18
- # A "Fortnight" is defined as a two week period, with the first fortnight of the
19
- # year beginning on 1st January.
20
- def beginning_of_fortnight
21
- beginning_of_year + 14 * ((self - beginning_of_year) / 14).to_i
22
- end
23
-
24
- def end_of_fortnight
25
- beginning_of_fortnight + 13
26
- end
27
-
28
- # A "Calendar Month" is defined as a month as it appears on a calendar, including days form
29
- # previous/following months which are part of the first/last weeks of the given month.
30
- def beginning_of_calendar_month(*args)
31
- beginning_of_month.beginning_of_week(*args)
32
- end
33
-
34
- def end_of_calendar_month(*args)
35
- end_of_month.end_of_week(*args)
36
- end
37
- end
38
- end
39
- end
40
-
41
- ::Date.__send__(:include, ByStar::Kernel::Date)
1
+ module ByStar
2
+
3
+ module Kernel
4
+
5
+ module Date
6
+
7
+ # A "Weekend" is defined as beginning of Saturday to end of Sunday.
8
+ # The weekend for a given date will be the the next weekend if the day Mon-Thurs,
9
+ # otherwise the current weekend if the day is Fri-Sun.
10
+ def beginning_of_weekend
11
+ beginning_of_week(:monday).advance(days: 5)
12
+ end
13
+
14
+ def end_of_weekend
15
+ beginning_of_weekend + 1
16
+ end
17
+
18
+ # A "Fortnight" is defined as a two week period, with the first fortnight of the
19
+ # year beginning on 1st January.
20
+ def beginning_of_fortnight
21
+ beginning_of_year + 14 * ((self - beginning_of_year) / 14).to_i
22
+ end
23
+
24
+ def end_of_fortnight
25
+ beginning_of_fortnight + 13
26
+ end
27
+
28
+ # A "Calendar Month" is defined as a month as it appears on a calendar, including days form
29
+ # previous/following months which are part of the first/last weeks of the given month.
30
+ def beginning_of_calendar_month(*args)
31
+ beginning_of_month.beginning_of_week(*args)
32
+ end
33
+
34
+ def end_of_calendar_month(*args)
35
+ end_of_month.end_of_week(*args)
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ ::Date.__send__(:include, ByStar::Kernel::Date)
@@ -1,20 +1,20 @@
1
- module ByStar
2
-
3
- module Kernel
4
-
5
- module InTimeZone
6
- extend ActiveSupport::Concern
7
-
8
- included do
9
- if method_defined?(:to_time_in_current_zone) && !method_defined?(:in_time_zone)
10
- alias_method :in_time_zone, :to_time_in_current_zone
11
- end
12
- end
13
- end
14
- end
15
- end
16
-
17
- ::Date.__send__(:include, ByStar::Kernel::InTimeZone)
18
- ::Time.__send__(:include, ByStar::Kernel::InTimeZone)
19
- ::DateTime.__send__(:include, ByStar::Kernel::InTimeZone)
20
- ::ActiveSupport::TimeWithZone.__send__(:include, ByStar::Kernel::InTimeZone)
1
+ module ByStar
2
+
3
+ module Kernel
4
+
5
+ module InTimeZone
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ if method_defined?(:to_time_in_current_zone) && !method_defined?(:in_time_zone)
10
+ alias_method :in_time_zone, :to_time_in_current_zone
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ ::Date.__send__(:include, ByStar::Kernel::InTimeZone)
18
+ ::Time.__send__(:include, ByStar::Kernel::InTimeZone)
19
+ ::DateTime.__send__(:include, ByStar::Kernel::InTimeZone)
20
+ ::ActiveSupport::TimeWithZone.__send__(:include, ByStar::Kernel::InTimeZone)
@@ -1,41 +1,41 @@
1
- module ByStar
2
-
3
- module Kernel
4
-
5
- module Time
6
-
7
- # A "Weekend" is defined as beginning of Saturday to end of Sunday.
8
- # The weekend for a given date will be the the next weekend if the day Mon-Thurs,
9
- # otherwise the current weekend if the day is Fri-Sun.
10
- def beginning_of_weekend
11
- beginning_of_week(:monday).advance(days: 5)
12
- end
13
-
14
- def end_of_weekend
15
- (beginning_of_weekend + 47.hours).end_of_hour
16
- end
17
-
18
- # A "Fortnight" is defined as a two week period, with the first fortnight of the
19
- # year beginning on 1st January.
20
- def beginning_of_fortnight
21
- (beginning_of_year + 1.fortnight * ((self - beginning_of_year) / 1.fortnight).to_i).beginning_of_day
22
- end
23
-
24
- def end_of_fortnight
25
- (beginning_of_fortnight + 13.days).end_of_day
26
- end
27
-
28
- # A "Calendar Month" is defined as a month as it appears on a calendar, including days form
29
- # previous/following months which are part of the first/last weeks of the given month.
30
- def beginning_of_calendar_month(*args)
31
- beginning_of_month.beginning_of_week(*args)
32
- end
33
-
34
- def end_of_calendar_month(*args)
35
- end_of_month.end_of_week(*args)
36
- end
37
- end
38
- end
39
- end
40
-
41
- ::Time.__send__(:include, ByStar::Kernel::Time)
1
+ module ByStar
2
+
3
+ module Kernel
4
+
5
+ module Time
6
+
7
+ # A "Weekend" is defined as beginning of Saturday to end of Sunday.
8
+ # The weekend for a given date will be the the next weekend if the day Mon-Thurs,
9
+ # otherwise the current weekend if the day is Fri-Sun.
10
+ def beginning_of_weekend
11
+ beginning_of_week(:monday).advance(days: 5)
12
+ end
13
+
14
+ def end_of_weekend
15
+ (beginning_of_weekend + 47.hours).end_of_hour
16
+ end
17
+
18
+ # A "Fortnight" is defined as a two week period, with the first fortnight of the
19
+ # year beginning on 1st January.
20
+ def beginning_of_fortnight
21
+ (beginning_of_year + 1.fortnight * ((self - beginning_of_year) / 1.fortnight).to_i).beginning_of_day
22
+ end
23
+
24
+ def end_of_fortnight
25
+ (beginning_of_fortnight + 13.days).end_of_day
26
+ end
27
+
28
+ # A "Calendar Month" is defined as a month as it appears on a calendar, including days form
29
+ # previous/following months which are part of the first/last weeks of the given month.
30
+ def beginning_of_calendar_month(*args)
31
+ beginning_of_month.beginning_of_week(*args)
32
+ end
33
+
34
+ def end_of_calendar_month(*args)
35
+ end_of_month.end_of_week(*args)
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ ::Time.__send__(:include, ByStar::Kernel::Time)
@@ -1,156 +1,156 @@
1
- module ByStar
2
-
3
- class ParseError < StandardError; end
4
-
5
- module Normalization
6
-
7
- class << self
8
-
9
- def date(value)
10
- value = parse_time(value) if value.is_a?(String)
11
- value = value.try(:in_time_zone) unless value.is_a?(Date)
12
- value.try(:to_date)
13
- end
14
-
15
- def time(value)
16
- value = parse_time(value) if value.is_a?(String)
17
- value.try(:in_time_zone)
18
- end
19
-
20
- def week(value, options={})
21
- value = try_string_to_int(value)
22
- case value
23
- when Integer then week_integer(value, options)
24
- else date(value)
25
- end
26
- end
27
-
28
- def week_integer(value, options={})
29
- raise ParseError, 'Week number must be between 0 and 52' unless value.in?(0..52)
30
- time = Time.zone.local(options[:year] || Time.zone.now.year)
31
- time.beginning_of_year + value.to_i.weeks
32
- end
33
-
34
- def cweek(value, options={})
35
- _value = value
36
- if _value.is_a?(Integer)
37
- raise ParseError, 'cweek number must be between 1 and 53' unless value.in?(1..53)
38
- _value -= 1
39
- end
40
- week(_value, options)
41
- end
42
-
43
- def fortnight(value, options={})
44
- value = try_string_to_int(value)
45
- case value
46
- when Integer then fortnight_integer(value, options)
47
- else date(value)
48
- end
49
- end
50
-
51
- def fortnight_integer(value, options={})
52
- raise ParseError, 'Fortnight number must be between 0 and 26' unless value.in?(0..26)
53
- time = Time.zone.local(options[:year] || Time.zone.now.year)
54
- time + (value * 2).weeks
55
- end
56
-
57
- def quarter(value, options={})
58
- value = try_string_to_int(value)
59
- case value
60
- when Integer then quarter_integer(value, options)
61
- else date(value)
62
- end
63
- end
64
-
65
- def quarter_integer(value, options={})
66
- raise ParseError, 'Quarter number must be between 1 and 4' unless value.in?(1..4)
67
- time = Time.zone.local(options[:year] || Time.zone.now.year)
68
- time.beginning_of_year + ((value - 1) * 3).months
69
- end
70
-
71
- def month(value, options={})
72
- value = try_string_to_int(value)
73
- case value
74
- when Integer, String then month_integer(value, options)
75
- else date(value)
76
- end
77
- end
78
-
79
- def month_integer(value, options={})
80
- year = options[:year] || Time.zone.now.year
81
- Time.zone.parse "#{year}-#{value}-01"
82
- rescue
83
- raise ParseError, 'Month must be a number between 1 and 12 or a month name'
84
- end
85
-
86
- def year(value, options={})
87
- value = try_string_to_int(value)
88
- case value
89
- when Integer then year_integer(value)
90
- else date(value)
91
- end
92
- end
93
-
94
- def year_integer(value)
95
- Time.zone.local(extrapolate_year(value))
96
- end
97
-
98
- def extrapolate_year(value)
99
- case value.to_i
100
- when 0..69
101
- 2000 + value
102
- when 70..99
103
- 1900 + value
104
- else
105
- value.to_i
106
- end
107
- end
108
-
109
- def try_string_to_int(value)
110
- value.is_a?(String) ? Integer(value) : value
111
- rescue
112
- value
113
- end
114
-
115
- def time_in_units(seconds)
116
- days = seconds / 1.day
117
- time = Time.at(seconds).utc
118
- { days: days, hour: time.hour, min: time.min, sec: time.sec }
119
- end
120
-
121
- def apply_offset_start(time, offset)
122
- units = time_in_units(offset)
123
- time += units.delete(:days).days
124
- time.change(units)
125
- end
126
-
127
- def apply_offset_end(time, offset)
128
- units = time_in_units(offset)
129
- time += units.delete(:days).days
130
- (time + 1.day).change(units) - 1.second
131
- end
132
-
133
- def extract_range(args)
134
- case args[0]
135
- when Array, Range then [args[0].first, args[0].last]
136
- else args[0..1]
137
- end
138
- end
139
-
140
- private
141
-
142
- def parse_time(value)
143
- defined?(Chronic) ? parse_time_chronic(value) : parse_time_fallback(value)
144
- end
145
-
146
- def parse_time_chronic(value)
147
- Chronic.time_class = Time.zone
148
- Chronic.parse(value) || raise(ByStar::ParseError, "Chronic could not parse String #{value.inspect}")
149
- end
150
-
151
- def parse_time_fallback(value)
152
- Time.zone.parse(value) || raise(ByStar::ParseError, "Cannot parse String #{value.inspect}")
153
- end
154
- end
155
- end
156
- end
1
+ module ByStar
2
+
3
+ class ParseError < StandardError; end
4
+
5
+ module Normalization
6
+
7
+ class << self
8
+
9
+ def date(value)
10
+ value = parse_time(value) if value.is_a?(String)
11
+ value = value.try(:in_time_zone) unless value.is_a?(Date)
12
+ value.try(:to_date)
13
+ end
14
+
15
+ def time(value)
16
+ value = parse_time(value) if value.is_a?(String)
17
+ value.try(:in_time_zone)
18
+ end
19
+
20
+ def week(value, options={})
21
+ value = try_string_to_int(value)
22
+ case value
23
+ when Integer then week_integer(value, options)
24
+ else date(value)
25
+ end
26
+ end
27
+
28
+ def week_integer(value, options={})
29
+ raise ParseError, 'Week number must be between 0 and 52' unless value.in?(0..52)
30
+ time = Time.zone.local(options[:year] || Time.zone.now.year)
31
+ time.beginning_of_year + value.to_i.weeks
32
+ end
33
+
34
+ def cweek(value, options={})
35
+ _value = value
36
+ if _value.is_a?(Integer)
37
+ raise ParseError, 'cweek number must be between 1 and 53' unless value.in?(1..53)
38
+ _value -= 1
39
+ end
40
+ week(_value, options)
41
+ end
42
+
43
+ def fortnight(value, options={})
44
+ value = try_string_to_int(value)
45
+ case value
46
+ when Integer then fortnight_integer(value, options)
47
+ else date(value)
48
+ end
49
+ end
50
+
51
+ def fortnight_integer(value, options={})
52
+ raise ParseError, 'Fortnight number must be between 0 and 26' unless value.in?(0..26)
53
+ time = Time.zone.local(options[:year] || Time.zone.now.year)
54
+ time + (value * 2).weeks
55
+ end
56
+
57
+ def quarter(value, options={})
58
+ value = try_string_to_int(value)
59
+ case value
60
+ when Integer then quarter_integer(value, options)
61
+ else date(value)
62
+ end
63
+ end
64
+
65
+ def quarter_integer(value, options={})
66
+ raise ParseError, 'Quarter number must be between 1 and 4' unless value.in?(1..4)
67
+ time = Time.zone.local(options[:year] || Time.zone.now.year)
68
+ time.beginning_of_year + ((value - 1) * 3).months
69
+ end
70
+
71
+ def month(value, options={})
72
+ value = try_string_to_int(value)
73
+ case value
74
+ when Integer, String then month_integer(value, options)
75
+ else date(value)
76
+ end
77
+ end
78
+
79
+ def month_integer(value, options={})
80
+ year = options[:year] || Time.zone.now.year
81
+ Time.zone.parse "#{year}-#{value}-01"
82
+ rescue
83
+ raise ParseError, 'Month must be a number between 1 and 12 or a month name'
84
+ end
85
+
86
+ def year(value, options={})
87
+ value = try_string_to_int(value)
88
+ case value
89
+ when Integer then year_integer(value)
90
+ else date(value)
91
+ end
92
+ end
93
+
94
+ def year_integer(value)
95
+ Time.zone.local(extrapolate_year(value))
96
+ end
97
+
98
+ def extrapolate_year(value)
99
+ case value.to_i
100
+ when 0..69
101
+ 2000 + value
102
+ when 70..99
103
+ 1900 + value
104
+ else
105
+ value.to_i
106
+ end
107
+ end
108
+
109
+ def try_string_to_int(value)
110
+ value.is_a?(String) ? Integer(value) : value
111
+ rescue
112
+ value
113
+ end
114
+
115
+ def time_in_units(seconds)
116
+ days = seconds / 1.day
117
+ time = Time.at(seconds).utc
118
+ { days: days, hour: time.hour, min: time.min, sec: time.sec }
119
+ end
120
+
121
+ def apply_offset_start(time, offset)
122
+ units = time_in_units(offset)
123
+ time += units.delete(:days).days
124
+ time.change(units)
125
+ end
126
+
127
+ def apply_offset_end(time, offset)
128
+ units = time_in_units(offset)
129
+ time += units.delete(:days).days
130
+ (time + 1.day).change(units) - 1.second
131
+ end
132
+
133
+ def extract_range(args)
134
+ case args[0]
135
+ when Array, Range then [args[0].first, args[0].last]
136
+ else args[0..1]
137
+ end
138
+ end
139
+
140
+ private
141
+
142
+ def parse_time(value)
143
+ defined?(Chronic) ? parse_time_chronic(value) : parse_time_fallback(value)
144
+ end
145
+
146
+ def parse_time_chronic(value)
147
+ Chronic.time_class = Time.zone
148
+ Chronic.parse(value) || raise(ByStar::ParseError, "Chronic could not parse String #{value.inspect}")
149
+ end
150
+
151
+ def parse_time_fallback(value)
152
+ Time.zone.parse(value) || raise(ByStar::ParseError, "Cannot parse String #{value.inspect}")
153
+ end
154
+ end
155
+ end
156
+ end