active_period 6.1.1 → 6.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 244cb233b1cdd1aeac905c1c7467cdb90a9bd4179ed28d2c14928ebd5cd95308
4
- data.tar.gz: 98776fbef793f99dc2f0ac63bb8dbd380fb709878f9eb2985cb393e008622f99
3
+ metadata.gz: b844daa7cc7ef648456cbfca6a0160a4cc6f12da6977066ad8a4a310d78bad2e
4
+ data.tar.gz: 520d626a06a54380df33877babdb6854f338c10908d8b03a644aab2e8416b7e8
5
5
  SHA512:
6
- metadata.gz: 27251125b3cb392249e94eeeec0feb6faf4836dff714a1bd9996ffa032ea782b264798b07fea01ccf019fd8d2f2583a049fda7b0438156a297a4f20e0484fdf8
7
- data.tar.gz: eae48296375f9d0323c4e2e2b5356a135dd9287dbe345f315526363b9e5c578ae858239434c1729fb0b9b01c6c80a5de01cbf259eb83cbe7637814d5dfb453bb
6
+ metadata.gz: 63a99d4de2e83d52f0c24e1110ad4e37acbad1d7980ea5b6d4c1084dfaae1a676e05a4850f3bb903e725f8c1ca98d09db9b1a14d102cd9686a844b12ca9f84d3
7
+ data.tar.gz: 11f0c8d57e2995e8a745885bddcc8b268920e65d30309048da2f0aeb9d4faa0cee43225f7686529995c6e919e0da1940f0c40d8b3b3ea93c299bf1662750798e
data/Gemfile.lock CHANGED
@@ -1,36 +1,77 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- active_period (6.0.0)
5
- activesupport (~> 6)
4
+ active_period (6.3.0)
5
+ activesupport (~> 6, >= 5)
6
6
  i18n (~> 1)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activesupport (6.1.3.1)
11
+ activesupport (6.0.0)
12
12
  concurrent-ruby (~> 1.0, >= 1.0.2)
13
- i18n (>= 1.6, < 2)
14
- minitest (>= 5.1)
15
- tzinfo (~> 2.0)
16
- zeitwerk (~> 2.3)
17
- concurrent-ruby (1.1.8)
13
+ i18n (>= 0.7, < 2)
14
+ minitest (~> 5.1)
15
+ tzinfo (~> 1.1)
16
+ zeitwerk (~> 2.1, >= 2.1.8)
17
+ builder (3.2.4)
18
+ concurrent-ruby (1.1.9)
19
+ cucumber (7.0.0)
20
+ builder (~> 3.2, >= 3.2.4)
21
+ cucumber-core (~> 10.0, >= 10.0.1)
22
+ cucumber-create-meta (~> 6.0, >= 6.0.1)
23
+ cucumber-cucumber-expressions (~> 12.1, >= 12.1.1)
24
+ cucumber-gherkin (~> 20.0, >= 20.0.1)
25
+ cucumber-html-formatter (~> 16.0, >= 16.0.1)
26
+ cucumber-messages (~> 17.0, >= 17.0.1)
27
+ cucumber-wire (~> 6.0, >= 6.0.1)
28
+ diff-lcs (~> 1.4, >= 1.4.4)
29
+ mime-types (~> 3.3, >= 3.3.1)
30
+ multi_test (~> 0.1, >= 0.1.2)
31
+ sys-uname (~> 1.2, >= 1.2.2)
32
+ cucumber-core (10.0.1)
33
+ cucumber-gherkin (~> 20.0, >= 20.0.1)
34
+ cucumber-messages (~> 17.0, >= 17.0.1)
35
+ cucumber-tag-expressions (~> 3.0, >= 3.0.1)
36
+ cucumber-create-meta (6.0.1)
37
+ cucumber-messages (~> 17.0, >= 17.0.1)
38
+ sys-uname (~> 1.2, >= 1.2.2)
39
+ cucumber-cucumber-expressions (12.1.1)
40
+ cucumber-gherkin (20.0.1)
41
+ cucumber-messages (~> 17.0, >= 17.0.1)
42
+ cucumber-html-formatter (16.0.1)
43
+ cucumber-messages (~> 17.0, >= 17.0.1)
44
+ cucumber-messages (17.0.1)
45
+ cucumber-tag-expressions (3.0.1)
46
+ cucumber-wire (6.0.1)
47
+ cucumber-core (~> 10.0, >= 10.0.1)
48
+ cucumber-cucumber-expressions (~> 12.1, >= 12.1.1)
49
+ cucumber-messages (~> 17.0, >= 17.0.1)
50
+ diff-lcs (1.4.4)
51
+ ffi (1.15.3)
18
52
  i18n (1.8.10)
19
53
  concurrent-ruby (~> 1.0)
54
+ mime-types (3.3.1)
55
+ mime-types-data (~> 3.2015)
56
+ mime-types-data (3.2021.0704)
20
57
  minitest (5.14.4)
58
+ multi_test (0.1.2)
21
59
  rake (10.5.0)
22
- tzinfo (2.0.4)
23
- concurrent-ruby (~> 1.0)
60
+ sys-uname (1.2.2)
61
+ ffi (~> 1.1)
62
+ thread_safe (0.3.6)
63
+ tzinfo (1.2.9)
64
+ thread_safe (~> 0.1)
24
65
  zeitwerk (2.4.2)
25
66
 
26
67
  PLATFORMS
27
68
  ruby
28
- x86_64-darwin-19
29
69
 
30
70
  DEPENDENCIES
31
71
  active_period!
32
72
  bundler (~> 2.0)
73
+ cucumber
33
74
  rake (~> 10.0)
34
75
 
35
76
  BUNDLED WITH
36
- 2.2.3
77
+ 2.1.2
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
- # ActivePeriod
2
- [![Gem Version](https://badge.fury.io/rb/active_period.svg)](https://badge.fury.io/rb/active_period)
3
- [![Code Climate](https://codeclimate.com/github/billaul/period.svg)](https://codeclimate.com/github/billaul/period)
4
- [![Inline docs](http://inch-ci.org/github/billaul/period.svg)](http://inch-ci.org/github/billaul/period)
1
+ # ActivePeriod
2
+ [![Gem Version](https://badge.fury.io/rb/active_period.svg)](https://badge.fury.io/rb/active_period)
3
+ [![Code Climate](https://codeclimate.com/github/billaul/period.svg)](https://codeclimate.com/github/billaul/period)
4
+ [![Inline docs](http://inch-ci.org/github/billaul/period.svg)](http://inch-ci.org/github/billaul/period)
5
5
  [![RubyGems](http://img.shields.io/gem/dt/active_period.svg?style=flat)](http://rubygems.org/gems/active_period)
6
6
 
7
7
  ActivePeriod aims to simplify Time-range manipulation.
@@ -51,6 +51,9 @@ Period.new(..Time.now).months.reverse_each # => Enumerable
51
51
  # Write a date for me (I18n supported)
52
52
  Period.new('20/01/2017'...'20/01/2021').to_s
53
53
  => "From the 20 January 2017 to the 20 January 2021 excluded"
54
+
55
+ # Get all US holidays in the next week (see holiday's section below)
56
+ Period.next_week.holidays(:us)
54
57
  ```
55
58
 
56
59
  ## Detailed view
@@ -311,7 +314,7 @@ For a FreePeriod or if you need to print the start and the end of your period di
311
314
  ## The tricky case of Weeks
312
315
 
313
316
  Weeks are implemented following the [ISO 8601](https://en.wikipedia.org/wiki/ISO_week_date)
314
- So `Period.this_month.weeks.first` doesn't necessarily include the first days of the month
317
+ So `Period.this_month.weeks.first` doesn't necessarily include the first days of the month
315
318
  Also a **StandardPeriod** and a **FreePeriod** covering the same range of time, may not includes the same `Weeks`
316
319
 
317
320
  ## TimeZone
@@ -320,10 +323,43 @@ Time zone are supported
320
323
  If you change the global `Time.zone` of your app
321
324
  If your Period [begin in a time zone and end in another](https://en.wikipedia.org/wiki/Daylight_saving_time), you have nothing to do
322
325
 
326
+ ## Holidays
327
+
328
+ `ActivePeriod` include an optional support of the [gem holidays](https://github.com/holidays/holidays)
329
+ If your project include this gem you can use the power of `.holidays` and `.holiday?`
330
+
331
+ `.holiday?` and `.holidays` take the same params as `Holidays.on` except the first one
332
+ `Holidays.on(Date.civil(2008, 4, 25), :au)` become `Period.day('24/04/2008').holidays(:au)` or `Period.day('24/04/2008').holiday?(:au)`
333
+
334
+ ```ruby
335
+ require 'holidays'
336
+ # Get all worldwide holidays in the current month
337
+ Period.this_month.holidays
338
+
339
+ # Get all US holidays in the next week
340
+ Period.next_week.holidays(:us)
341
+
342
+ # Get all US and CA holidays in the prev quarter
343
+ Period.prev_quarter.holidays(:us, :ca)
344
+
345
+ # First up coming `FR` holiday
346
+ holiday = (Time.now..).to_period.holidays(:fr).first
347
+ # return the next holiday with same options as the original `.holidays` collection
348
+ holiday.next
349
+ # return the previous holiday with same options as the original `.holidays` collection
350
+ holiday.prev
351
+ ```
352
+
353
+ :warning: If you call a `holidays` related method without the [gem holidays](https://github.com/holidays/holidays) in your project
354
+ You will raise a `RuntimeError`
355
+ ```ruby
356
+ Period.this_month.holidays
357
+ #=> RuntimeError (The gem "holidays" is needed for this feature to work)
358
+ ```
359
+
323
360
  ## Planned updates
324
361
 
325
362
  - [ ] ActiveRecord Serializer (maybe)
326
- - [ ] Holidays support (gem Holidays) -> COMING SOON
327
363
 
328
364
  ## Bug reports
329
365
 
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
 
10
10
  spec.summary = 'Manage time ranges without brain damage.'
11
11
  # spec.description = "Period.new('01/01/2020'..Time.now)"
12
- spec.homepage = "https://github.com/billaul/period"
12
+ spec.homepage = "https://github.com/billaul/active_period"
13
13
  spec.license = 'MIT'
14
14
 
15
15
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
@@ -37,8 +37,11 @@ Gem::Specification.new do |spec|
37
37
  spec.require_paths = %w[lib config]
38
38
 
39
39
  spec.required_ruby_version = '>= 2.7'
40
- spec.add_runtime_dependency 'activesupport', '~> 5'
40
+
41
+ spec.add_runtime_dependency 'activesupport', '>= 5', '~> 6'
41
42
  spec.add_runtime_dependency 'i18n', '~> 1'
43
+
42
44
  spec.add_development_dependency 'bundler', '~> 2.0'
43
45
  spec.add_development_dependency 'rake', '~> 10.0'
46
+ spec.add_development_dependency 'cucumber'
44
47
  end
data/lib/active_period.rb CHANGED
@@ -23,6 +23,8 @@ require_relative 'active_period/year.rb'
23
23
  require_relative 'active_period/holiday.rb'
24
24
  require_relative 'period.rb'
25
25
 
26
+ # TODO find a way to cleanup this require_relative mess ><
27
+
26
28
  module ActivePeriod
27
29
 
28
30
  end
@@ -23,7 +23,7 @@ module ActivePeriod
23
23
  raise RangeError.new "cannot get the last element of endless range" if period.endless?
24
24
 
25
25
  Enumerator.new do |yielder|
26
- current = klass.new(period.end)
26
+ current = klass.new(period.calculated_end)
27
27
  while period.begin.nil? || period.include?(current.begin) || period.include?(current.calculated_end)
28
28
  yielder << current
29
29
  current = current.prev
@@ -19,7 +19,7 @@ module ActivePeriod
19
19
  days = period.try(:days) || [period]
20
20
  days.each do |day|
21
21
  Holidays.on(day.begin.to_date, *options).each do |hash|
22
- yielder << ActivePeriod::Holiday.new(**hash)
22
+ yielder << ActivePeriod::Holiday.new(**hash, options: @options)
23
23
  end
24
24
  end
25
25
  # At the end (if there is one) the Collection will be return
@@ -32,7 +32,7 @@ module ActivePeriod
32
32
  days = period.try(:days) || [period]
33
33
  days.reverse_each do |day|
34
34
  Holidays.on(day.begin.to_date, *options).each do |hash|
35
- yielder << ActivePeriod::Holiday.new(**hash)
35
+ yielder << ActivePeriod::Holiday.new(**hash, options: @options)
36
36
  end
37
37
  end
38
38
  # At the end (if there is one) the Collection will be return
@@ -8,7 +8,7 @@ module ActivePeriod
8
8
  def enumerator
9
9
  Enumerator.new do |yielder|
10
10
  current = klass.new(period.begin)
11
- while current.end <= period.end || period.include?(current)
11
+ while current.calculated_end <= period.calculated_end || period.include?(current)
12
12
  yielder << current if period.include?(current)
13
13
  current = current.next
14
14
  end
@@ -19,7 +19,7 @@ module ActivePeriod
19
19
 
20
20
  def reverse_enumerator
21
21
  Enumerator.new do |yielder|
22
- current = klass.new(period.end)
22
+ current = klass.new(period.calculated_end)
23
23
  while current.begin <= period.begin || period.include?(current)
24
24
  yielder << current if period.include?(current)
25
25
  current = current.prev
@@ -10,27 +10,32 @@ class ActivePeriod::Holiday < ActivePeriod::Day
10
10
  # @return [<Symbol>] regions where the Holiday occure
11
11
  attr_reader :regions
12
12
 
13
+ # @!attribute [r] options
14
+ # @return [Array] The array of options for Holidays.on
15
+ attr_reader :options
13
16
 
14
17
  # @param date [...] A valid param for Period.day(...)
15
18
  # @param name [String] The name of the Holiday
16
19
  # @param regions [<Symbol>] region where the Holiday occure
20
+ # @param options [...] The array of options for Holidays.on
17
21
  # @return [Type] ActivePeriod::Holiday
18
22
  # @raise RuntimeError if the gem "holidays" is not included
19
- def initialize(date: , name:, regions: )
23
+ def initialize(date: , name:, regions: , options: )
20
24
  raise I18n.t(:gem_require, scope: %i[active_period holiday_period]) unless Object.const_defined?('Holidays')
21
25
  super(date)
22
26
 
23
27
  @name = name
24
28
  @regions = regions
29
+ @options = options
25
30
  end
26
31
 
27
32
  def next
28
- raise NotImplementedError
33
+ Period.new(beginning+1.day..).holidays(options).first
29
34
  end
30
35
  alias succ next
31
36
 
32
37
  def prev
33
- raise NotImplementedError
38
+ Period.new(...ending).holidays(options).last
34
39
  end
35
40
 
36
41
  def _period
@@ -62,7 +67,7 @@ class ActivePeriod::Holiday < ActivePeriod::Day
62
67
  end
63
68
 
64
69
  def i18n(&block)
65
- return yield(from, to) if block.present?
70
+ return yield(self) if block.present?
66
71
 
67
72
  I18n.t(:default_format,
68
73
  scope: i18n_scope,
@@ -72,6 +77,7 @@ class ActivePeriod::Holiday < ActivePeriod::Day
72
77
  month: I18n.l(from, format: '%B').capitalize,
73
78
  year: from.year)
74
79
  end
80
+ alias inspect i18n
75
81
 
76
82
  def i18n_scope
77
83
  [:active_period, :holiday_period]
@@ -1,5 +1,5 @@
1
1
  module ActivePeriod
2
2
 
3
- VERSION = '6.1.1'.freeze
3
+ VERSION = '6.3.1'.freeze
4
4
 
5
5
  end
data/lib/period.rb CHANGED
@@ -1,34 +1,43 @@
1
+ # This module is intended to hide the complexity of ActivePeriod
2
+ # And permit the user to write less and doing more
1
3
  module Period
4
+
5
+ # Shorthand to ActivePeriod::FreePeriod.new
2
6
  def self.new(*args)
3
7
  ActivePeriod::FreePeriod.new(*args)
4
8
  end
5
9
 
10
+ # Shorthand ActivePeriod::FreePeriod.new(range, allow_beginless: false, allow_endless: false)
6
11
  def self.bounded(range)
7
12
  ActivePeriod::FreePeriod.new(range, allow_beginless: false, allow_endless: false)
8
13
  end
9
14
 
15
+ # env_time provide a Fallback if the project dont specify any Time.zone
10
16
  def self.env_time
11
17
  (Time.zone || Time)
12
18
  end
13
19
 
20
+ # Dynamic definition of `.(last|this|next)_(day|week|month|quarter|year)`
21
+ # and `.yesterday` `.today` `.tomorrow`
22
+ # TODO implement (last|next)_holiday
14
23
  class << self
15
- %i[day week month quarter year].each do |period|
16
- define_method "last_#{period}" do
17
- date = env_time.now.send(period == :day ? 'yesterday' : "last_#{period}")
18
- Object.const_get("ActivePeriod::#{period.capitalize}").new(date)
24
+ %i[day week month quarter year].each do |standard_period|
25
+ define_method "last_#{standard_period}" do
26
+ date = env_time.now.send(standard_period == :day ? 'yesterday' : "last_#{standard_period}")
27
+ Object.const_get("ActivePeriod::#{standard_period.capitalize}").new(date)
19
28
  end
20
29
 
21
- define_method "this_#{period}" do
22
- Object.const_get("ActivePeriod::#{period.capitalize}").new(env_time.now)
30
+ define_method "this_#{standard_period}" do
31
+ Object.const_get("ActivePeriod::#{standard_period.capitalize}").new(env_time.now)
23
32
  end
24
33
 
25
- define_method "next_#{period}" do
26
- date = env_time.now.send(period == :day ? 'tomorrow' : "next_#{period}")
27
- Object.const_get("ActivePeriod::#{period.capitalize}").new(date)
34
+ define_method "next_#{standard_period}" do
35
+ date = env_time.now.send(standard_period == :day ? 'tomorrow' : "next_#{standard_period}")
36
+ Object.const_get("ActivePeriod::#{standard_period.capitalize}").new(date)
28
37
  end
29
38
 
30
- define_method period.to_s do |range|
31
- Object.const_get("ActivePeriod::#{period.capitalize}").new(range)
39
+ define_method standard_period.to_s do |range|
40
+ Object.const_get("ActivePeriod::#{standard_period.capitalize}").new(range)
32
41
  end
33
42
  end
34
43
 
@@ -36,6 +45,10 @@ module Period
36
45
  alias tomorrow next_day
37
46
  alias today this_day
38
47
 
48
+ # Experimental non-documented feature
49
+ # Inpired form ActiveRecord dynamic find_by_x like User.find_by_name
50
+ # Example: Period.last_3_weeks_from_now == Period.mew(2.weeks.ago.beginning_of_week..Time.now.end_of_week)
51
+ # Note : Maybe it should return a collection of StandardPeriod
39
52
  def method_missing(method_name, *arguments, &block)
40
53
  super unless method_name.match?(/(last|next)_\d+_(day|week|month|quarter|year)s?(_from_now)?/)
41
54
  last_next, count, klass = method_name.to_s.split('_')
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_period
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.1
4
+ version: 6.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - billau_l
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-03 00:00:00.000000000 Z
11
+ date: 2021-07-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '5'
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '6'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
29
  version: '5'
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '6'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: i18n
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +72,20 @@ dependencies:
66
72
  - - "~>"
67
73
  - !ruby/object:Gem::Version
68
74
  version: '10.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: cucumber
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
69
89
  description:
70
90
  email:
71
91
  executables: []
@@ -115,14 +135,14 @@ files:
115
135
  - lib/numeric.rb
116
136
  - lib/period.rb
117
137
  - lib/range.rb
118
- homepage: https://github.com/billaul/period
138
+ homepage: https://github.com/billaul/active_period
119
139
  licenses:
120
140
  - MIT
121
141
  metadata:
122
- bug_tracker_uri: https://github.com/billaul/period/issues
123
- homepage_uri: https://github.com/billaul/period
124
- documentation_uri: https://github.com/billaul/period
125
- source_code_uri: https://github.com/billaul/period
142
+ bug_tracker_uri: https://github.com/billaul/active_period/issues
143
+ homepage_uri: https://github.com/billaul/active_period
144
+ documentation_uri: https://github.com/billaul/active_period
145
+ source_code_uri: https://github.com/billaul/active_period
126
146
  post_install_message:
127
147
  rdoc_options: []
128
148
  require_paths: