finishing_moves 0.3.1 → 0.4.0

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.
@@ -25,7 +25,7 @@ Gem::Specification.new do |s|
25
25
  s.add_development_dependency 'pry-byebug', '>= 0'
26
26
  s.add_development_dependency 'fuubar', '>= 0'
27
27
 
28
- s.required_ruby_version = '>= 2.0'
28
+ s.required_ruby_version = '>= 2.0.0'
29
29
 
30
30
  s.post_install_message = <<EOS
31
31
  ********************************************************************************
@@ -10,6 +10,7 @@ class Array
10
10
  end
11
11
  t
12
12
  end
13
+ alias_method :to_hash, :to_hash_values
13
14
  alias_method :to_hash_as_values, :to_hash_values
14
15
 
15
16
  def to_indexed_hash(starting_key = 0)
@@ -0,0 +1,132 @@
1
+ require 'date'
2
+
3
+ module FinishingMovesFiscalLogic
4
+
5
+ def fiscal_start
6
+ @fiscal_start = 1 if @fiscal_start.nil?
7
+ @fiscal_start
8
+ end
9
+
10
+ def fiscal_start=(month)
11
+ @fiscal_start = Integer(month)
12
+ end
13
+
14
+ def fiscal_quarter
15
+ ((( self.month + ( 12 - fiscal_start ) ) / 3 ) % 4 ) + 1
16
+ end
17
+
18
+ def all_quarter_months
19
+ quarters = []
20
+ this_quarter = []
21
+ this_month = fiscal_start
22
+ (1..12).each do |n|
23
+ this_quarter << this_month
24
+ if n % 3 == 0
25
+ quarters << this_quarter
26
+ this_quarter = []
27
+ end
28
+ this_month = this_month < 12 ? this_month + 1 : 1
29
+ end
30
+ quarters
31
+ end
32
+ alias_method :fiscal_calendar, :all_quarter_months
33
+
34
+ def fiscal_quarter_months
35
+ all_quarter_months[fiscal_quarter - 1]
36
+ end
37
+
38
+ def first_month_of_quarter
39
+ fiscal_quarter_months[0]
40
+ end
41
+
42
+ def first_quarter
43
+ all_quarter_months[0]
44
+ end
45
+ alias_method :q1, :first_quarter
46
+
47
+ def second_quarter
48
+ all_quarter_months[1]
49
+ end
50
+ alias_method :q2, :second_quarter
51
+
52
+ def third_quarter
53
+ all_quarter_months[2]
54
+ end
55
+ alias_method :q3, :third_quarter
56
+
57
+ def fourth_quarter
58
+ all_quarter_months[3]
59
+ end
60
+ alias_method :q4, :fourth_quarter
61
+
62
+ def beginning_of_fiscal_year
63
+ self.class.new _last_fiscal_year_for_month(q1[0]), q1[0]
64
+ end
65
+
66
+ def beginning_of_fiscal_quarter
67
+ self.class.new _last_fiscal_year_for_month(first_month_of_quarter), first_month_of_quarter
68
+ end
69
+
70
+ def end_of_fiscal_year
71
+ if self.class.name == 'Time'
72
+ d = beginning_of_fiscal_year + (60*60*24*385)
73
+ self.class.new(d.year, d.month) - (60*60*24)
74
+ else
75
+ d = beginning_of_fiscal_year >> 12
76
+ self.class.new(d.year, d.month) - 1
77
+ end
78
+ end
79
+
80
+ def end_of_fiscal_quarter
81
+ if self.class.name == 'Time'
82
+ d = beginning_of_fiscal_quarter + (60*60*24*100)
83
+ self.class.new(d.year, d.month) - (60*60*24)
84
+ else
85
+ d = beginning_of_fiscal_quarter >> 3
86
+ self.class.new(d.year, d.month) - 1
87
+ end
88
+ end
89
+
90
+ def quarter_starting_dates
91
+ ret = []
92
+ all_quarter_months.map { |months| months[0] }.each do |m|
93
+ y = m >= fiscal_start ? starting_year : starting_year + 1
94
+ ret << self.class.new(y, m)
95
+ end
96
+ ret
97
+ end
98
+
99
+ def quarter_ending_dates
100
+ ret = []
101
+ all_quarter_months.map { |months| months[2] }.each do |m|
102
+ y = m >= fiscal_start ? starting_year : starting_year + 1
103
+ if self.class.name == 'Time'
104
+ d = self.class.new(y, m) + (60*60*24*42)
105
+ ret << self.class.new(d.year, d.month) - (60*60*24)
106
+ else
107
+ d = self.class.new(y, m) >> 1
108
+ ret << self.class.new(d.year, d.month) - 1
109
+ end
110
+ end
111
+ ret
112
+ end
113
+
114
+ protected
115
+
116
+ def starting_year
117
+ fiscal_start > 1 ? self.year - 1 : self.year
118
+ end
119
+
120
+ def _last_fiscal_year_for_month(month)
121
+ if month == fiscal_start && month == self.month
122
+ self.year
123
+ else
124
+ month >= fiscal_start ? self.year - 1 : self.year
125
+ end
126
+ end
127
+
128
+ end
129
+
130
+ Time.send :include, FinishingMovesFiscalLogic
131
+ Date.send :include, FinishingMovesFiscalLogic
132
+ DateTime.send :include, FinishingMovesFiscalLogic
@@ -1,127 +1,127 @@
1
- class String
2
-
3
- def nl2br
4
- self.gsub(/(?:\n\r?|\r\n?)/, "<br />\n")
5
- end
6
-
7
- def keyify
8
- result = nil_chain do
9
- the_key = self.clone
10
-
11
- # strip all non-alphanumerics
12
- the_key.gsub!(/[^0-9a-z]+/i, '_')
13
-
14
- # borrowing some logic from Rails method underscore
15
- # http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-underscore
16
- if the_key =~ /[A-Z-]|::/
17
- the_key.gsub!(/::/, '_')
18
- the_key.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
19
- the_key.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
20
- end
21
-
22
- # Strip any leading numbers and underscores
23
- the_key.lstrip_all!('0-9_')
24
- # Strip trailing underscores
25
- the_key.rstrip_all!('_')
26
- # Combine multiple concurrent underscores
27
- the_key.dedupe!('_')
28
- # lowercase
29
- the_key.downcase!
30
- next the_key
31
- end
32
- return nil if result.nil? || result == ''
33
- result.to_sym
34
- end
35
-
36
- def keyify!
37
- result = self.keyify
38
- raise ArgumentError, "#{self.inspect} cannot be keyified, no valid characters" if result.nil?
39
- result
40
- end
41
-
42
- def strip_all(chars = nil)
43
- expr = _strip_all_prep(chars)
44
- gsub Regexp.union(_lstrip_all_regex(expr), _rstrip_all_regex(expr)), ''
45
- end
46
-
47
- def strip_all!(chars = nil)
48
- expr = _strip_all_prep(chars)
49
- gsub! Regexp.union(_lstrip_all_regex(expr), _rstrip_all_regex(expr)), ''
50
- end
51
-
52
- def lstrip_all(chars = nil)
53
- gsub _lstrip_all_regex(_strip_all_prep(chars)), ''
54
- end
55
-
56
- def lstrip_all!(chars = nil)
57
- gsub! _lstrip_all_regex(_strip_all_prep(chars)), ''
58
- end
59
-
60
- def rstrip_all(chars = nil)
61
- gsub _rstrip_all_regex(_strip_all_prep(chars)), ''
62
- end
63
-
64
- def rstrip_all!(chars = nil)
65
- gsub! _rstrip_all_regex(_strip_all_prep(chars)), ''
66
- end
67
-
68
- # strip multiple concurrent characters
69
- def dedupe(str)
70
- raise ArgumentError, "#{str.inspect} is not a string" unless str.is_a? String
71
- # Yes, this is inefficient. We welcome optimizations from the regex ninjas out there.
72
- ret = String.new self
73
- str.each_char { |c| ret.gsub! /#{Regexp.escape c}{2,}/, c }
74
- ret
75
- end
76
-
77
- def dedupe!(str)
78
- raise ArgumentError, "#{str.inspect} is not a string" unless str.is_a? String
79
- # Yes, this is inefficient. We welcome optimizations from the regex ninjas out there.
80
- str.each_char { |c| gsub! /#{Regexp.escape c}{2,}/, c }
81
- end
82
-
83
- def remove_whitespace(replace = '')
84
- gsub /[ ]/, replace
85
- end
86
-
87
- def remove_whitespace!(replace = '')
88
- gsub! /[ ]/, replace
89
- end
90
-
91
- # return true/false on regex match
92
- def match?(pattern, pos = 0)
93
- match(pattern, pos).not_nil?
94
- end
95
-
96
- protected
97
-
98
- def _lstrip_all_regex(expr)
99
- /\A[#{expr}]+/
100
- end
101
-
102
- def _rstrip_all_regex(expr)
103
- /[#{expr}]+\Z/
104
- end
105
-
106
- def _strip_all_prep(chars)
107
- chars = '-_' if chars.nil?
108
- raise ArgumentError, "#{chars.inspect} is not a string" unless chars.is_a? String
109
-
110
- expr = Regexp.escape( chars.gsub(/(0-9)+|(a-z)+|(A-Z)+|\s+/, '').strip )
111
- ['0-9', 'a-z', 'A-Z'].each do |range|
112
- expr << range if chars.include? range
113
- end
114
- expr << ' '
115
- end
116
-
117
- end
118
-
119
- # We aren't reopening Symbol class for anything else yet, so we'll just define
120
- # it in this file.
121
- class Symbol
122
-
123
- def keyify
124
- to_s.keyify
125
- end
126
-
127
- end
1
+ class String
2
+
3
+ def nl2br
4
+ self.gsub(/(?:\n\r?|\r\n?)/, "<br />\n")
5
+ end
6
+
7
+ def keyify
8
+ result = nil_chain do
9
+ the_key = self.clone
10
+
11
+ # strip all non-alphanumerics
12
+ the_key.gsub!(/[^0-9a-z]+/i, '_')
13
+
14
+ # borrowing some logic from Rails method underscore
15
+ # http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-underscore
16
+ if the_key =~ /[A-Z-]|::/
17
+ the_key.gsub!(/::/, '_')
18
+ the_key.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
19
+ the_key.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
20
+ end
21
+
22
+ # Strip any leading numbers and underscores
23
+ the_key.lstrip_all!('0-9_')
24
+ # Strip trailing underscores
25
+ the_key.rstrip_all!('_')
26
+ # Combine multiple concurrent underscores
27
+ the_key.dedupe!('_')
28
+ # lowercase
29
+ the_key.downcase!
30
+ next the_key
31
+ end
32
+ return nil if result.nil? || result == ''
33
+ result.to_sym
34
+ end
35
+
36
+ def keyify!
37
+ result = self.keyify
38
+ raise ArgumentError, "#{self.inspect} cannot be keyified, no valid characters" if result.nil?
39
+ result
40
+ end
41
+
42
+ def strip_all(chars = nil)
43
+ expr = _strip_all_prep(chars)
44
+ gsub Regexp.union(_lstrip_all_regex(expr), _rstrip_all_regex(expr)), ''
45
+ end
46
+
47
+ def strip_all!(chars = nil)
48
+ expr = _strip_all_prep(chars)
49
+ gsub! Regexp.union(_lstrip_all_regex(expr), _rstrip_all_regex(expr)), ''
50
+ end
51
+
52
+ def lstrip_all(chars = nil)
53
+ gsub _lstrip_all_regex(_strip_all_prep(chars)), ''
54
+ end
55
+
56
+ def lstrip_all!(chars = nil)
57
+ gsub! _lstrip_all_regex(_strip_all_prep(chars)), ''
58
+ end
59
+
60
+ def rstrip_all(chars = nil)
61
+ gsub _rstrip_all_regex(_strip_all_prep(chars)), ''
62
+ end
63
+
64
+ def rstrip_all!(chars = nil)
65
+ gsub! _rstrip_all_regex(_strip_all_prep(chars)), ''
66
+ end
67
+
68
+ # strip multiple concurrent characters
69
+ def dedupe(str)
70
+ raise ArgumentError, "#{str.inspect} is not a string" unless str.is_a? String
71
+ # Yes, this is inefficient. We welcome optimizations from the regex ninjas out there.
72
+ ret = String.new self
73
+ str.each_char { |c| ret.gsub! /#{Regexp.escape c}{2,}/, c }
74
+ ret
75
+ end
76
+
77
+ def dedupe!(str)
78
+ raise ArgumentError, "#{str.inspect} is not a string" unless str.is_a? String
79
+ # Yes, this is inefficient. We welcome optimizations from the regex ninjas out there.
80
+ str.each_char { |c| gsub! /#{Regexp.escape c}{2,}/, c }
81
+ end
82
+
83
+ def remove_whitespace(replace = '')
84
+ gsub /[ ]/, replace
85
+ end
86
+
87
+ def remove_whitespace!(replace = '')
88
+ gsub! /[ ]/, replace
89
+ end
90
+
91
+ # return true/false on regex match
92
+ def match?(pattern, pos = 0)
93
+ match(pattern, pos).not_nil?
94
+ end
95
+
96
+ protected
97
+
98
+ def _lstrip_all_regex(expr)
99
+ /\A[#{expr}]+/
100
+ end
101
+
102
+ def _rstrip_all_regex(expr)
103
+ /[#{expr}]+\Z/
104
+ end
105
+
106
+ def _strip_all_prep(chars)
107
+ chars = '-_' if chars.nil?
108
+ raise ArgumentError, "#{chars.inspect} is not a string" unless chars.is_a? String
109
+
110
+ expr = Regexp.escape( chars.gsub(/(0-9)+|(a-z)+|(A-Z)+|\s+/, '').strip )
111
+ ['0-9', 'a-z', 'A-Z'].each do |range|
112
+ expr << range if chars.include? range
113
+ end
114
+ expr << ' '
115
+ end
116
+
117
+ end
118
+
119
+ # We aren't reopening Symbol class for anything else yet, so we'll just define
120
+ # it in this file.
121
+ class Symbol
122
+
123
+ def keyify
124
+ to_s.keyify
125
+ end
126
+
127
+ end
@@ -1,3 +1,3 @@
1
1
  module FinishingMoves
2
- VERSION = "0.3.1"
2
+ VERSION = "0.4.0"
3
3
  end
data/provision.sh CHANGED
@@ -3,7 +3,7 @@
3
3
  # Shell user settings.
4
4
  USER_NAME=vagrant
5
5
  USER_HOME=/home/$USER_NAME
6
- DEFAULT_RUBY='2.1.5'
6
+ DEFAULT_RUBY='2.2.1'
7
7
 
8
8
  ###############################################################################
9
9
  # Functions
@@ -61,7 +61,7 @@ echo 'gem: --no-document' >> $USER_HOME/.gemrc
61
61
 
62
62
  # Install Ruby for $USER_NAME.
63
63
  install_ruby $DEFAULT_RUBY
64
- echo $DEFAULT_RUBY > $USER_HOME/.ruby-version
64
+ /home/$USER_NAME/.rbenv/bin/rbenv global $DEFAULT_RUBY
65
65
 
66
66
  ###############################################################################
67
67
  # EDIT HERE!
@@ -0,0 +1,255 @@
1
+ require 'spec_helper'
2
+
3
+ describe FinishingMovesFiscalLogic do
4
+
5
+ let(:default_quarters) { [[1,2,3], [4,5,6], [7,8,9], [10,11,12]] }
6
+
7
+ before(:example) do
8
+ @jan01 = Time.new(2015, 1)
9
+ end
10
+
11
+ it "is included into Time, Date, and DateTime" do
12
+ expect(Time.method_defined? :fiscal_start).to be true
13
+ expect(Date.method_defined? :fiscal_start).to be true
14
+ expect(DateTime.method_defined? :fiscal_start).to be true
15
+
16
+ expect(Time.method_defined? :fiscal_quarter).to be true
17
+ expect(Date.method_defined? :fiscal_quarter).to be true
18
+ expect(DateTime.method_defined? :fiscal_quarter).to be true
19
+
20
+ expect(Time.method_defined? :all_quarter_months).to be true
21
+ expect(Date.method_defined? :all_quarter_months).to be true
22
+ expect(DateTime.method_defined? :all_quarter_months).to be true
23
+
24
+ expect(Time.method_defined? :fiscal_quarter_months).to be true
25
+ expect(Date.method_defined? :fiscal_quarter_months).to be true
26
+ expect(DateTime.method_defined? :fiscal_quarter_months).to be true
27
+ end
28
+
29
+ it "#fiscal_quarter" do
30
+ q = 1
31
+ default_quarters.each do |months|
32
+ months.each { |m| expect(Time.new(2015, m).fiscal_quarter).to eq q }
33
+ q += 1
34
+ end
35
+
36
+ # Adjusted fiscal calendar
37
+ @jan01.fiscal_start = 4
38
+ expect(@jan01.fiscal_quarter).to eq 4
39
+ @jan01.fiscal_start = 10
40
+ expect(@jan01.fiscal_quarter).to eq 2
41
+
42
+ # Make sure other date classes work
43
+ expect(Date.new(2015, 9).fiscal_quarter).to eq 3
44
+ expect(DateTime.new(2015, 9).fiscal_quarter).to eq 3
45
+ end
46
+
47
+ it "#all_quarter_months" do
48
+ expect(@jan01.all_quarter_months).to eq default_quarters
49
+ @jan01.fiscal_start = 4
50
+ expect(@jan01.all_quarter_months).to eq [[4,5,6], [7,8,9], [10,11,12], [1,2,3]]
51
+ @jan01.fiscal_start = 11
52
+ expect(@jan01.all_quarter_months).to eq [[11,12,1], [2,3,4], [5,6,7], [8,9,10]]
53
+
54
+ expect(Date.new(2015, 9).all_quarter_months).to eq default_quarters
55
+ expect(DateTime.new(2015, 9).all_quarter_months).to eq default_quarters
56
+ # alias check
57
+ expect(DateTime.new(2015, 9).fiscal_calendar).to eq default_quarters
58
+ end
59
+
60
+ it "#quarter shortcuts" do
61
+ expect(@jan01.first_quarter).to eq default_quarters[0]
62
+ expect(@jan01.q1).to eq default_quarters[0]
63
+ expect(@jan01.second_quarter).to eq default_quarters[1]
64
+ expect(@jan01.q2).to eq default_quarters[1]
65
+ expect(@jan01.third_quarter).to eq default_quarters[2]
66
+ expect(@jan01.q3).to eq default_quarters[2]
67
+ expect(@jan01.fourth_quarter).to eq default_quarters[3]
68
+ expect(@jan01.q4).to eq default_quarters[3]
69
+ end
70
+
71
+ it "#fiscal_quarter_months" do
72
+ expect(Time.new(2015, 1).fiscal_quarter_months).to eq [1,2,3]
73
+ expect(Date.new(2015, 2).fiscal_quarter_months).to eq [1,2,3]
74
+ expect(DateTime.new(2015, 5).fiscal_quarter_months).to eq [4,5,6]
75
+
76
+ @jan01.fiscal_start = 4
77
+ expect(@jan01.fiscal_quarter_months).to eq [1,2,3]
78
+ @jan01.fiscal_start = 2
79
+ expect(@jan01.fiscal_quarter_months).to eq [11,12,1]
80
+ @jan01.fiscal_start = 11
81
+ expect(@jan01.fiscal_quarter_months).to eq [11,12,1]
82
+ @jan01.fiscal_start = 9
83
+ expect(@jan01.fiscal_quarter_months).to eq [12,1,2]
84
+ end
85
+
86
+ it "#first_month_of_quarter" do
87
+ expect(Time.new(2015, 1).first_month_of_quarter).to eq 1
88
+ expect(Date.new(2015, 8).first_month_of_quarter).to eq 7
89
+ expect(DateTime.new(2015, 5).first_month_of_quarter).to eq 4
90
+
91
+ @jan01.fiscal_start = 4
92
+ expect(@jan01.first_month_of_quarter).to eq 1
93
+ @jan01.fiscal_start = 2
94
+ expect(@jan01.first_month_of_quarter).to eq 11
95
+ @jan01.fiscal_start = 11
96
+ expect(@jan01.first_month_of_quarter).to eq 11
97
+ @jan01.fiscal_start = 9
98
+ expect(@jan01.first_month_of_quarter).to eq 12
99
+ end
100
+
101
+ it "#beginning_of_fiscal_quarter" do
102
+ expect(Time.new.beginning_of_fiscal_quarter).to be_a Time
103
+ expect(Date.new.beginning_of_fiscal_quarter).to be_a Date
104
+ expect(DateTime.new.beginning_of_fiscal_quarter).to be_a DateTime
105
+
106
+ expect(@jan01.beginning_of_fiscal_quarter.strftime('%F')).to eq '2015-01-01'
107
+ @jan01.fiscal_start = 4
108
+ expect(@jan01.beginning_of_fiscal_quarter.strftime('%F')).to eq '2015-01-01'
109
+ @jan01.fiscal_start = 2
110
+ expect(@jan01.beginning_of_fiscal_quarter.strftime('%F')).to eq '2014-11-01'
111
+ @jan01.fiscal_start = 11
112
+ expect(@jan01.beginning_of_fiscal_quarter.strftime('%F')).to eq '2014-11-01'
113
+ @jan01.fiscal_start = 9
114
+ expect(@jan01.beginning_of_fiscal_quarter.strftime('%F')).to eq '2014-12-01'
115
+ end
116
+
117
+ it "#end_of_fiscal_quarter" do
118
+ expect(Time.new.end_of_fiscal_quarter).to be_a Time
119
+ expect(Date.new.end_of_fiscal_quarter).to be_a Date
120
+ expect(DateTime.new.end_of_fiscal_quarter).to be_a DateTime
121
+
122
+ expect(@jan01.end_of_fiscal_quarter.strftime('%F')).to eq '2015-03-31'
123
+ @jan01.fiscal_start = 4
124
+ expect(@jan01.end_of_fiscal_quarter.strftime('%F')).to eq '2015-03-31'
125
+ @jan01.fiscal_start = 2
126
+ expect(@jan01.end_of_fiscal_quarter.strftime('%F')).to eq '2015-01-31'
127
+ @jan01.fiscal_start = 11
128
+ expect(@jan01.end_of_fiscal_quarter.strftime('%F')).to eq '2015-01-31'
129
+ @jan01.fiscal_start = 9
130
+ expect(@jan01.end_of_fiscal_quarter.strftime('%F')).to eq '2015-02-28'
131
+
132
+ # Separate logic for Date and DateTime means separate tests
133
+ @jan01_date = Date.new(2015, 1)
134
+ expect(@jan01_date.end_of_fiscal_quarter.strftime('%F')).to eq '2015-03-31'
135
+ @jan01_date.fiscal_start = 4
136
+ expect(@jan01_date.end_of_fiscal_quarter.strftime('%F')).to eq '2015-03-31'
137
+ @jan01_date.fiscal_start = 2
138
+ expect(@jan01_date.end_of_fiscal_quarter.strftime('%F')).to eq '2015-01-31'
139
+ @jan01_date.fiscal_start = 11
140
+ expect(@jan01_date.end_of_fiscal_quarter.strftime('%F')).to eq '2015-01-31'
141
+ @jan01_date.fiscal_start = 9
142
+ expect(@jan01_date.end_of_fiscal_quarter.strftime('%F')).to eq '2015-02-28'
143
+
144
+ @jan01_datetime = DateTime.new(2015, 1)
145
+ expect(@jan01_datetime.end_of_fiscal_quarter.strftime('%F')).to eq '2015-03-31'
146
+ @jan01_datetime.fiscal_start = 4
147
+ expect(@jan01_datetime.end_of_fiscal_quarter.strftime('%F')).to eq '2015-03-31'
148
+ @jan01_datetime.fiscal_start = 2
149
+ expect(@jan01_datetime.end_of_fiscal_quarter.strftime('%F')).to eq '2015-01-31'
150
+ @jan01_datetime.fiscal_start = 11
151
+ expect(@jan01_datetime.end_of_fiscal_quarter.strftime('%F')).to eq '2015-01-31'
152
+ @jan01_datetime.fiscal_start = 9
153
+ expect(@jan01_datetime.end_of_fiscal_quarter.strftime('%F')).to eq '2015-02-28'
154
+ end
155
+
156
+ it "#beginning_of_fiscal_year" do
157
+ expect(Time.new.beginning_of_fiscal_year).to be_a Time
158
+ expect(Date.new.beginning_of_fiscal_year).to be_a Date
159
+ expect(DateTime.new.beginning_of_fiscal_year).to be_a DateTime
160
+
161
+ @jan01.fiscal_start = 3
162
+ expect(@jan01.beginning_of_fiscal_year.strftime('%F')).to eq '2014-03-01'
163
+ @jan01.fiscal_start = 9
164
+ expect(@jan01.beginning_of_fiscal_year.strftime('%F')).to eq '2014-09-01'
165
+ @jan01.fiscal_start = 12
166
+ expect(@jan01.beginning_of_fiscal_year.strftime('%F')).to eq '2014-12-01'
167
+ end
168
+
169
+ it "#end_of_fiscal_year" do
170
+ expect(Time.new.end_of_fiscal_year).to be_a Time
171
+ expect(Date.new.end_of_fiscal_year).to be_a Date
172
+ expect(DateTime.new.end_of_fiscal_year).to be_a DateTime
173
+
174
+ @jan01.fiscal_start = 3
175
+ expect(@jan01.end_of_fiscal_year.strftime('%F')).to eq '2015-02-28'
176
+ @jan01.fiscal_start = 9
177
+ expect(@jan01.end_of_fiscal_year.strftime('%F')).to eq '2015-08-31'
178
+ @jan01.fiscal_start = 12
179
+ expect(@jan01.end_of_fiscal_year.strftime('%F')).to eq '2015-11-30'
180
+
181
+ # Separate logic for Date and DateTime means separate tests
182
+ @jan01_date = Date.new(2015, 1)
183
+ @jan01_date.fiscal_start = 3
184
+ expect(@jan01_date.end_of_fiscal_year.strftime('%F')).to eq '2015-02-28'
185
+ @jan01_date.fiscal_start = 9
186
+ expect(@jan01_date.end_of_fiscal_year.strftime('%F')).to eq '2015-08-31'
187
+ @jan01_date.fiscal_start = 12
188
+ expect(@jan01_date.end_of_fiscal_year.strftime('%F')).to eq '2015-11-30'
189
+
190
+ @jan01_datetime = DateTime.new(2015, 1)
191
+ @jan01_datetime.fiscal_start = 3
192
+ expect(@jan01_datetime.end_of_fiscal_year.strftime('%F')).to eq '2015-02-28'
193
+ @jan01_datetime.fiscal_start = 9
194
+ expect(@jan01_datetime.end_of_fiscal_year.strftime('%F')).to eq '2015-08-31'
195
+ @jan01_datetime.fiscal_start = 12
196
+ expect(@jan01_datetime.end_of_fiscal_year.strftime('%F')).to eq '2015-11-30'
197
+ end
198
+
199
+ it "#quarter_starting_dates" do
200
+ expect(@jan01.quarter_starting_dates).to be_an Array
201
+ expect(@jan01.quarter_starting_dates.length).to eq 4
202
+
203
+ expect(@jan01.quarter_starting_dates[0].strftime('%F')).to eq '2015-01-01'
204
+ expect(@jan01.quarter_starting_dates[1].strftime('%F')).to eq '2015-04-01'
205
+ expect(@jan01.quarter_starting_dates[2].strftime('%F')).to eq '2015-07-01'
206
+ expect(@jan01.quarter_starting_dates[3].strftime('%F')).to eq '2015-10-01'
207
+
208
+ @jan01.fiscal_start = 2
209
+ expect(@jan01.quarter_starting_dates[0].strftime('%F')).to eq '2014-02-01'
210
+ expect(@jan01.quarter_starting_dates[1].strftime('%F')).to eq '2014-05-01'
211
+ expect(@jan01.quarter_starting_dates[2].strftime('%F')).to eq '2014-08-01'
212
+ expect(@jan01.quarter_starting_dates[3].strftime('%F')).to eq '2014-11-01'
213
+
214
+ @jan01.fiscal_start = 9
215
+ expect(@jan01.quarter_starting_dates[0].strftime('%F')).to eq '2014-09-01'
216
+ expect(@jan01.quarter_starting_dates[1].strftime('%F')).to eq '2014-12-01'
217
+ expect(@jan01.quarter_starting_dates[2].strftime('%F')).to eq '2015-03-01'
218
+ expect(@jan01.quarter_starting_dates[3].strftime('%F')).to eq '2015-06-01'
219
+
220
+ @jan01_date = Date.new(2015, 1)
221
+ expect(@jan01_date.quarter_starting_dates[0].strftime('%F')).to eq '2015-01-01'
222
+ expect(@jan01_date.quarter_starting_dates[1].strftime('%F')).to eq '2015-04-01'
223
+ expect(@jan01_date.quarter_starting_dates[2].strftime('%F')).to eq '2015-07-01'
224
+ expect(@jan01_date.quarter_starting_dates[3].strftime('%F')).to eq '2015-10-01'
225
+ end
226
+
227
+ it "#quarter_ending_dates" do
228
+ expect(@jan01.quarter_ending_dates).to be_an Array
229
+ expect(@jan01.quarter_ending_dates.length).to eq 4
230
+
231
+ expect(@jan01.quarter_ending_dates[0].strftime('%F')).to eq '2015-03-31'
232
+ expect(@jan01.quarter_ending_dates[1].strftime('%F')).to eq '2015-06-30'
233
+ expect(@jan01.quarter_ending_dates[2].strftime('%F')).to eq '2015-09-30'
234
+ expect(@jan01.quarter_ending_dates[3].strftime('%F')).to eq '2015-12-31'
235
+
236
+ @jan01.fiscal_start = 2
237
+ expect(@jan01.quarter_ending_dates[0].strftime('%F')).to eq '2014-04-30'
238
+ expect(@jan01.quarter_ending_dates[1].strftime('%F')).to eq '2014-07-31'
239
+ expect(@jan01.quarter_ending_dates[2].strftime('%F')).to eq '2014-10-31'
240
+ expect(@jan01.quarter_ending_dates[3].strftime('%F')).to eq '2015-01-31'
241
+
242
+ @jan01.fiscal_start = 9
243
+ expect(@jan01.quarter_ending_dates[0].strftime('%F')).to eq '2014-11-30'
244
+ expect(@jan01.quarter_ending_dates[1].strftime('%F')).to eq '2015-02-28'
245
+ expect(@jan01.quarter_ending_dates[2].strftime('%F')).to eq '2015-05-31'
246
+ expect(@jan01.quarter_ending_dates[3].strftime('%F')).to eq '2015-08-31'
247
+
248
+ @jan01_date = Date.new(2015, 1)
249
+ expect(@jan01_date.quarter_ending_dates[0].strftime('%F')).to eq '2015-03-31'
250
+ expect(@jan01_date.quarter_ending_dates[1].strftime('%F')).to eq '2015-06-30'
251
+ expect(@jan01_date.quarter_ending_dates[2].strftime('%F')).to eq '2015-09-30'
252
+ expect(@jan01_date.quarter_ending_dates[3].strftime('%F')).to eq '2015-12-31'
253
+ end
254
+
255
+ end