month_range 0.1.4 → 0.1.5
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 +4 -4
- data/.github/workflows/gempush.yml +30 -0
- data/.github/workflows/rspec.yml +16 -0
- data/.github/workflows/rubocop.yml +16 -0
- data/.rubocop.yml +6 -2
- data/.rubocop_todo.yml +1 -25
- data/Gemfile.lock +1 -1
- data/README.md +3 -0
- data/lib/month_range/collection.rb +57 -74
- data/lib/month_range/m_range.rb +25 -9
- data/lib/month_range/month.rb +7 -23
- data/lib/month_range/service.rb +28 -26
- data/lib/month_range/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 145bd280f50a75b41f7ee8db8764ad61df4abb453104342b111d3e318a446976
|
4
|
+
data.tar.gz: a67950427a8cbc5c36456cd2e7397126b0f0ac8ed7b30563b699d0a5da8349b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12085289adf414dbe060ae5dca642c0b1b86abf0142bb519eee399373422f1a64a0a1a6dae6e08009fee8ea254a18e190483fe38b0d8014b178ec5b839ba8865
|
7
|
+
data.tar.gz: 801af3b96e8306bde0c4f2e90dd7895455cd12dd055d0de645f95babb974a486a35d247d87fad75f3ef9babd255743dd4e507e2fec04aee1c42706c4f222bbf5
|
@@ -0,0 +1,30 @@
|
|
1
|
+
name: Ruby Gem
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ master ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
build:
|
11
|
+
name: Build + Publish
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
|
14
|
+
steps:
|
15
|
+
- uses: actions/checkout@v2
|
16
|
+
- name: Set up Ruby 2.6
|
17
|
+
uses: actions/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
version: 2.6.x
|
20
|
+
|
21
|
+
- name: Publish to RubyGems
|
22
|
+
run: |
|
23
|
+
mkdir -p $HOME/.gem
|
24
|
+
touch $HOME/.gem/credentials
|
25
|
+
chmod 0600 $HOME/.gem/credentials
|
26
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
27
|
+
gem build *.gemspec
|
28
|
+
gem push *.gem
|
29
|
+
env:
|
30
|
+
GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
name: RSpec
|
2
|
+
on: [pull_request]
|
3
|
+
jobs:
|
4
|
+
build:
|
5
|
+
runs-on: ubuntu-latest
|
6
|
+
steps:
|
7
|
+
- uses: actions/checkout@v2
|
8
|
+
- uses: actions/setup-ruby@v1
|
9
|
+
with:
|
10
|
+
version: 2.6
|
11
|
+
- name: Build
|
12
|
+
run: |
|
13
|
+
gem install bundler
|
14
|
+
bundle install
|
15
|
+
- name: rspec
|
16
|
+
run: bundle exec rspec
|
@@ -0,0 +1,16 @@
|
|
1
|
+
name: RuboCop
|
2
|
+
on: [pull_request]
|
3
|
+
jobs:
|
4
|
+
build:
|
5
|
+
runs-on: ubuntu-latest
|
6
|
+
steps:
|
7
|
+
- uses: actions/checkout@v2
|
8
|
+
- uses: actions/setup-ruby@v1
|
9
|
+
with:
|
10
|
+
version: 2.6
|
11
|
+
- name: Build
|
12
|
+
run: |
|
13
|
+
gem install bundler
|
14
|
+
bundle install
|
15
|
+
- name: rubocop
|
16
|
+
run: bundle exec rubocop
|
data/.rubocop.yml
CHANGED
@@ -6,10 +6,14 @@ Style/ClassAndModuleChildren:
|
|
6
6
|
Style/AsciiComments:
|
7
7
|
Enabled: false
|
8
8
|
Layout/LineLength:
|
9
|
-
Max:
|
9
|
+
Max: 393
|
10
|
+
Exclude:
|
11
|
+
- "spec/**/*"
|
10
12
|
Style/Documentation:
|
11
13
|
Enabled: false
|
12
|
-
|
14
|
+
Metrics/BlockLength:
|
15
|
+
Exclude:
|
16
|
+
- "spec/**/*"
|
13
17
|
AllCops:
|
14
18
|
Exclude:
|
15
19
|
- tmp/**/*
|
data/.rubocop_todo.yml
CHANGED
@@ -1,31 +1,7 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on 2020-
|
3
|
+
# on 2020-04-12 14:58:59 +0900 using RuboCop version 0.80.1.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
8
|
-
|
9
|
-
# Offense count: 6
|
10
|
-
# Cop supports --auto-correct.
|
11
|
-
# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
12
|
-
# URISchemes: http, https
|
13
|
-
Layout/LineLength:
|
14
|
-
Max: 393
|
15
|
-
|
16
|
-
# Offense count: 2
|
17
|
-
Metrics/AbcSize:
|
18
|
-
Max: 23
|
19
|
-
|
20
|
-
# Offense count: 1
|
21
|
-
Metrics/CyclomaticComplexity:
|
22
|
-
Max: 8
|
23
|
-
|
24
|
-
# Offense count: 1
|
25
|
-
# Configuration parameters: CountComments, ExcludedMethods.
|
26
|
-
Metrics/MethodLength:
|
27
|
-
Max: 20
|
28
|
-
|
29
|
-
# Offense count: 1
|
30
|
-
Metrics/PerceivedComplexity:
|
31
|
-
Max: 9
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,107 +1,90 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class MonthRange::Collection
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :stored_m_ranges
|
5
5
|
|
6
|
-
def initialize
|
7
|
-
@
|
6
|
+
def initialize(m_ranges = [])
|
7
|
+
@stored_m_ranges = []
|
8
|
+
m_ranges.each { |m_range| add(m_range) }
|
8
9
|
end
|
9
10
|
|
10
11
|
def to_a
|
11
|
-
@
|
12
|
+
@stored_m_ranges.map do |collection_range|
|
13
|
+
[collection_range.start_month.to_date, collection_range.end_month.to_date]
|
14
|
+
end
|
12
15
|
end
|
13
16
|
|
14
|
-
def add(
|
15
|
-
raise MonthRange::Error, 'Need MonthRange::MRange' unless
|
16
|
-
return @
|
17
|
-
|
18
|
-
overlapped_collection_ranges = @collection_ranges.select { |collection_range| collection_range.overlap?(range) }
|
19
|
-
return @collection_ranges if overlapped_collection_ranges.nil?
|
17
|
+
def add(m_range)
|
18
|
+
raise MonthRange::Error, 'Need MonthRange::MRange' unless m_range.is_a?(MonthRange::MRange)
|
19
|
+
return @stored_m_ranges << m_range if @stored_m_ranges.empty?
|
20
20
|
|
21
|
-
|
21
|
+
update_stored_m_ranges(m_range) do |overlapped_collection_ranges|
|
22
|
+
[merge_range(overlapped_collection_ranges, m_range)]
|
23
|
+
end
|
22
24
|
end
|
23
25
|
|
24
|
-
def subtract(
|
25
|
-
raise MonthRange::Error, 'Need MonthRange::MRange' unless
|
26
|
-
|
27
|
-
|
28
|
-
overlapped_collection_ranges = @collection_ranges.select { |collection_range| collection_range.overlap?(range) }
|
29
|
-
return @collection_ranges if overlapped_collection_ranges.nil?
|
26
|
+
def subtract(m_range)
|
27
|
+
raise MonthRange::Error, 'Need MonthRange::MRange' unless m_range.is_a?(MonthRange::MRange)
|
28
|
+
return if @stored_m_ranges.empty?
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
def self.new_from_date_range_array(date_range_array)
|
35
|
-
collection = new
|
36
|
-
date_range_array.each do |range|
|
37
|
-
start_month = range[0]
|
38
|
-
end_month = range[1]
|
39
|
-
m_range = MonthRange::MRange.new(start_month, end_month)
|
40
|
-
collection.add(m_range)
|
30
|
+
update_stored_m_ranges(m_range) do |overlapped_collection_ranges|
|
31
|
+
subtract_range(overlapped_collection_ranges, m_range)
|
41
32
|
end
|
42
|
-
collection
|
43
33
|
end
|
44
34
|
|
45
35
|
private
|
46
36
|
|
47
|
-
def
|
48
|
-
@
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
37
|
+
def overlapped_collection_ranges(m_range)
|
38
|
+
@stored_m_ranges.select { |collection_range| collection_range.overlap?(m_range) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def update_stored_m_ranges(m_range)
|
42
|
+
m_ranges = overlapped_collection_ranges(m_range)
|
43
|
+
delete_m_ranges_to_stored(m_ranges)
|
44
|
+
add_m_ranges_to_stored(yield(m_ranges))
|
53
45
|
end
|
54
46
|
|
55
|
-
def
|
56
|
-
|
47
|
+
def delete_m_ranges_to_stored(m_ranges)
|
48
|
+
@stored_m_ranges -= m_ranges
|
49
|
+
@stored_m_ranges = combine_continuous_range(sort_ranges_asc(@stored_m_ranges.flatten.compact))
|
50
|
+
end
|
57
51
|
|
58
|
-
|
52
|
+
def add_m_ranges_to_stored(m_ranges)
|
53
|
+
@stored_m_ranges += m_ranges
|
54
|
+
@stored_m_ranges = combine_continuous_range(sort_ranges_asc(@stored_m_ranges.flatten.compact))
|
59
55
|
end
|
60
56
|
|
61
|
-
def
|
62
|
-
|
63
|
-
|
64
|
-
|
57
|
+
def sort_ranges_asc(m_ranges)
|
58
|
+
return m_ranges if m_ranges.size <= 1
|
59
|
+
|
60
|
+
m_ranges.sort { |a, b| a.start_month <=> b.start_month }
|
65
61
|
end
|
66
62
|
|
67
|
-
def
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
end
|
72
|
-
output_range.flatten.compact
|
63
|
+
def merge_range(m_ranges, m_range)
|
64
|
+
start_month = (m_ranges + [m_range]).map(&:start_month).min { |a, b| a <=> b }
|
65
|
+
end_month = (m_ranges + [m_range]).map(&:end_month).max { |a, b| a <=> b }
|
66
|
+
MonthRange::MRange.new(start_month, end_month)
|
73
67
|
end
|
74
68
|
|
75
|
-
def
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
output_ranges = []
|
80
|
-
ranges.each_with_index do |range, idx|
|
81
|
-
(temp_range = range) && next if idx.zero?
|
82
|
-
|
83
|
-
if idx == ranges.size - 1 && continuous?(temp_range, range)
|
84
|
-
output_ranges << MonthRange::MRange.new(temp_range.start_month, range.end_month)
|
85
|
-
next
|
86
|
-
elsif idx == ranges.size - 1
|
87
|
-
output_ranges << temp_range
|
88
|
-
output_ranges << range
|
89
|
-
next
|
90
|
-
elsif continuous?(temp_range, range)
|
91
|
-
temp_range = MonthRange::MRange.new(temp_range.start_month, range.end_month)
|
92
|
-
next
|
93
|
-
end
|
94
|
-
output_ranges << temp_range
|
95
|
-
temp_range = range
|
69
|
+
def subtract_range(m_ranges, m_range)
|
70
|
+
output_m_range = []
|
71
|
+
m_ranges.each do |r|
|
72
|
+
output_m_range << r.subtract(m_range)
|
96
73
|
end
|
97
|
-
|
74
|
+
output_m_range.flatten.compact
|
98
75
|
end
|
99
76
|
|
100
|
-
def
|
101
|
-
return
|
102
|
-
raise if range.start_month >= next_range.start_month
|
103
|
-
return false if range.end_month.infinite?
|
77
|
+
def combine_continuous_range(m_ranges) # rubocop:disable Metrics/CyclomaticComplexity
|
78
|
+
return m_ranges if m_ranges.count <= 1
|
104
79
|
|
105
|
-
|
80
|
+
before_m_range = nil
|
81
|
+
output_m_ranges = []
|
82
|
+
m_ranges.each_with_index do |m_range, idx|
|
83
|
+
(before_m_range = m_range) && next if idx.zero?
|
84
|
+
(before_m_range = before_m_range.combine(m_range)) && next if before_m_range.continuous?(m_range)
|
85
|
+
output_m_ranges << before_m_range
|
86
|
+
before_m_range = m_range
|
87
|
+
end
|
88
|
+
output_m_ranges << before_m_range unless output_m_ranges.include?(before_m_range)
|
106
89
|
end
|
107
90
|
end
|
data/lib/month_range/m_range.rb
CHANGED
@@ -7,6 +7,8 @@ class MonthRange::MRange < Range
|
|
7
7
|
attr_reader :start_month, :end_month
|
8
8
|
class InvalidStartEnd < MonthRange::Error
|
9
9
|
end
|
10
|
+
class NotMRange < MonthRange::Error
|
11
|
+
end
|
10
12
|
|
11
13
|
def initialize(start_month, end_month)
|
12
14
|
raise InvalidStartEnd unless start_month.is_a?(MonthRange::Month)
|
@@ -18,12 +20,10 @@ class MonthRange::MRange < Range
|
|
18
20
|
@end_month = end_month
|
19
21
|
end
|
20
22
|
|
21
|
-
def overlap?(
|
22
|
-
raise "#{
|
23
|
+
def overlap?(m_range)
|
24
|
+
raise NotMRange, "#{m_range} must be MRange." unless m_range.is_a?(MonthRange::MRange)
|
23
25
|
|
24
|
-
if cover?(
|
25
|
-
true
|
26
|
-
end
|
26
|
+
true if cover?(m_range.start_month) || cover?(m_range.end_month) || m_range.cover?(self)
|
27
27
|
end
|
28
28
|
|
29
29
|
def non_terminated?
|
@@ -34,12 +34,12 @@ class MonthRange::MRange < Range
|
|
34
34
|
!end_month.infinite?
|
35
35
|
end
|
36
36
|
|
37
|
-
def subtract(
|
38
|
-
return self unless overlap?(
|
37
|
+
def subtract(m_range) # rubocop:disable Metrics/AbcSize
|
38
|
+
return self unless overlap?(m_range)
|
39
39
|
|
40
40
|
output_range = []
|
41
|
-
output_range << MonthRange::MRange.new(start_month,
|
42
|
-
output_range << MonthRange::MRange.new(
|
41
|
+
output_range << MonthRange::MRange.new(start_month, m_range.just_before) if cover?(m_range.just_before)
|
42
|
+
output_range << MonthRange::MRange.new(m_range.just_after, end_month) if cover?(m_range.just_after) && m_range.terminated?
|
43
43
|
output_range.flatten.compact
|
44
44
|
end
|
45
45
|
|
@@ -51,6 +51,22 @@ class MonthRange::MRange < Range
|
|
51
51
|
non_terminated? ? end_month : end_month.next_month(1)
|
52
52
|
end
|
53
53
|
|
54
|
+
def continuous?(m_range)
|
55
|
+
return false if m_range.nil?
|
56
|
+
raise if start_month >= m_range.start_month
|
57
|
+
return false if end_month.infinite?
|
58
|
+
|
59
|
+
end_month == m_range.just_before
|
60
|
+
end
|
61
|
+
|
62
|
+
def combine(m_range)
|
63
|
+
if start_month < m_range.start_month
|
64
|
+
MonthRange::MRange.new(start_month, m_range.end_month)
|
65
|
+
else
|
66
|
+
MonthRange::MRange.new(m_range.start_month, end_month)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
54
70
|
private
|
55
71
|
|
56
72
|
def valid_start_end_relation?(start_month, end_month)
|
data/lib/month_range/month.rb
CHANGED
@@ -19,21 +19,11 @@ class MonthRange::Month < Date
|
|
19
19
|
Date.new(year, month, mday)
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
attr_reader :d
|
28
|
-
|
29
|
-
def zero?
|
30
|
-
false
|
31
|
-
end
|
32
|
-
|
33
|
-
def finite?
|
34
|
-
false
|
35
|
-
end
|
22
|
+
def infinite?
|
23
|
+
false
|
24
|
+
end
|
36
25
|
|
26
|
+
class Infinity < Numeric
|
37
27
|
def infinite?
|
38
28
|
true
|
39
29
|
end
|
@@ -57,21 +47,15 @@ class MonthRange::Month < Date
|
|
57
47
|
def <=>(other)
|
58
48
|
case other
|
59
49
|
when Infinity
|
60
|
-
return
|
50
|
+
return 1
|
61
51
|
when MonthRange::Month
|
62
|
-
return
|
52
|
+
return 1
|
63
53
|
end
|
64
54
|
nil
|
65
55
|
end
|
66
56
|
|
67
57
|
def to_f
|
68
|
-
|
69
|
-
|
70
|
-
if @d.positive?
|
71
|
-
Float::INFINITY
|
72
|
-
else
|
73
|
-
-Float::INFINITY
|
74
|
-
end
|
58
|
+
Float::INFINITY
|
75
59
|
end
|
76
60
|
end
|
77
61
|
end
|
data/lib/month_range/service.rb
CHANGED
@@ -30,12 +30,21 @@ class MonthRange::Service
|
|
30
30
|
# MonthRange::Service.add(range_array, from_range_arrays)
|
31
31
|
#
|
32
32
|
# #=> [[#<Date: 2020-01-01 ((2458850j,0s,0n),+0s,2299161j)>, #<Date: 2020-04-01 ((2458941j,0s,0n),+0s,2299161j)>]]
|
33
|
-
def self.subtraction(range_array, from_range_arrays)
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
def self.subtraction(range_array, from_range_arrays) # rubocop:disable Metrics/MethodLength:
|
34
|
+
m_ranges = from_range_arrays.map do |range|
|
35
|
+
MonthRange::MRange.new(
|
36
|
+
MonthRange::Month.create(range[0]),
|
37
|
+
MonthRange::Month.create(range[1])
|
38
|
+
)
|
39
|
+
end
|
40
|
+
collection = MonthRange::Collection.new(m_ranges)
|
41
|
+
|
42
|
+
collection.subtract(
|
43
|
+
MonthRange::MRange.new(
|
44
|
+
MonthRange::Month.create(range_array[0]),
|
45
|
+
MonthRange::Month.create(range_array[1])
|
46
|
+
)
|
47
|
+
)
|
39
48
|
collection.to_a
|
40
49
|
end
|
41
50
|
|
@@ -69,26 +78,19 @@ class MonthRange::Service
|
|
69
78
|
# MonthRange::Service.add(range_array, from_range_arrays)
|
70
79
|
#
|
71
80
|
# #=> [[#<Date: 2020-01-01 ((2458850j,0s,0n),+0s,2299161j)>, nil]]
|
72
|
-
def self.add(range_array, from_range_arrays)
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
collection.to_a
|
79
|
-
end
|
80
|
-
|
81
|
-
# Change to MonthRange::Collection
|
82
|
-
# @param [[[Date, Date], [Date, Date],]] range_arrays
|
83
|
-
# @return [MonthRange::Collection]
|
84
|
-
def self.range_arrays_to_collection(range_arrays)
|
85
|
-
collection = MonthRange::Collection.new
|
86
|
-
range_arrays.each do |range|
|
87
|
-
start_month = MonthRange::Month.create(range[0])
|
88
|
-
end_month = MonthRange::Month.create(range[1])
|
89
|
-
m_range = MonthRange::MRange.new(start_month, end_month)
|
90
|
-
collection.add(m_range)
|
81
|
+
def self.add(range_array, from_range_arrays) # rubocop:disable Metrics/MethodLength
|
82
|
+
m_ranges = from_range_arrays.map do |range|
|
83
|
+
MonthRange::MRange.new(
|
84
|
+
MonthRange::Month.create(range[0]),
|
85
|
+
MonthRange::Month.create(range[1])
|
86
|
+
)
|
91
87
|
end
|
92
|
-
collection
|
88
|
+
collection = MonthRange::Collection.new(m_ranges)
|
89
|
+
|
90
|
+
collection.add(MonthRange::MRange.new(
|
91
|
+
MonthRange::Month.create(range_array[0]),
|
92
|
+
MonthRange::Month.create(range_array[1])
|
93
|
+
))
|
94
|
+
collection.to_a
|
93
95
|
end
|
94
96
|
end
|
data/lib/month_range/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: month_range
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jungo araki
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-04-
|
11
|
+
date: 2020-04-12 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -17,6 +17,9 @@ executables: []
|
|
17
17
|
extensions: []
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
|
+
- ".github/workflows/gempush.yml"
|
21
|
+
- ".github/workflows/rspec.yml"
|
22
|
+
- ".github/workflows/rubocop.yml"
|
20
23
|
- ".gitignore"
|
21
24
|
- ".rspec"
|
22
25
|
- ".rubocop.yml"
|
@@ -61,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
61
64
|
- !ruby/object:Gem::Version
|
62
65
|
version: '0'
|
63
66
|
requirements: []
|
64
|
-
rubygems_version: 3.
|
67
|
+
rubygems_version: 3.0.3
|
65
68
|
signing_key:
|
66
69
|
specification_version: 4
|
67
70
|
summary: Addition and subtraction for month range.
|