fiscally 1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9362c857fbcfb1bac89099d792bbf1b8973ff73d
4
+ data.tar.gz: 143390f0d2b770114241a70e25280455f8509a82
5
+ SHA512:
6
+ metadata.gz: c1cbbe76af2cd0b4171a811502b1ebd083d91ed57bf455247cc6a22833877d7029a5b269775a0eb911dc83efc0407a74ec9ad24af845abd275db192317cbd006
7
+ data.tar.gz: 1c8e61347016690a516100b3f6f1268d9e93e29383c9475b309a61fbeed781bbbb3ef426424724455b7b996916877cabe2d18873b2ba424361720bfa8ac2664b
@@ -0,0 +1,37 @@
1
+ ## Virtual Machine files
2
+ /.vagrant/
3
+
4
+ *.gem
5
+ *.rbc
6
+ /.config
7
+ /coverage/
8
+ /InstalledFiles
9
+ /pkg/
10
+ /spec/reports/
11
+ /test/tmp/
12
+ /test/version_tmp/
13
+ /tmp/
14
+
15
+ ## Specific to RubyMotion:
16
+ .dat*
17
+ .repl_history
18
+ build/
19
+
20
+ ## Documentation cache and generated files:
21
+ /.yardoc/
22
+ /_yardoc/
23
+ /doc/
24
+ /rdoc/
25
+
26
+ ## Environment normalisation:
27
+ /.bundle/
28
+ /lib/bundler/man/
29
+
30
+ # for a library or gem, you might want to ignore these files since the code is
31
+ # intended to run in multiple environments; otherwise, check them in:
32
+ Gemfile.lock
33
+ .ruby-version
34
+ .ruby-gemset
35
+
36
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
37
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format Fuubar
@@ -0,0 +1,14 @@
1
+ language: ruby
2
+
3
+ cache: bundler
4
+
5
+ rvm:
6
+ - 2.0.0
7
+ - 2.1.0
8
+ - 2.2.0
9
+ - 2.2.1
10
+ - 2.2.2
11
+ - 2.3.0
12
+ - ruby-head
13
+
14
+ script: bundle exec rspec spec
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Forge Software
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,357 @@
1
+ # fiscally
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/fiscally.svg)](https://rubygems.org/gems/fiscally)
4
+ [![Build Status](https://travis-ci.org/forgecrafted/fiscally.svg?branch=master)](https://travis-ci.org/forgecrafted/fiscally)
5
+ [![Coverage Status](https://coveralls.io/repos/forgecrafted/fiscally/badge.svg?branch=master)](https://coveralls.io/r/forgecrafted/fiscally?branch=master)
6
+
7
+ Projects with a financial or business bent often have to deal with awareness of a fiscal year, which typically doesn't line up with a normal calendar year.
8
+
9
+ The `Fiscally` gem adds the necessary awareness to your date and time objects, covering start and end dates for fiscal years and quarterly breakdowns.
10
+
11
+ ## Installation
12
+
13
+ Gemfile
14
+ ```
15
+ gem 'fiscally'
16
+ ```
17
+
18
+ Command line
19
+ ```
20
+ gem install 'fiscally'
21
+ ```
22
+
23
+ ### Ruby Version
24
+
25
+ Built and tested against **`2.0.0` and above**, but Probably Works&trade; in `1.9.3`.
26
+
27
+ ## Usage
28
+
29
+ All calculations are done **relative to the date and/or time represented by your object**. This is particularly important to remember for methods that calculate a "current" value. Our documentation examples use dates in the past to drive this point home.
30
+
31
+ Time is always set to midnight (`00:00:00`), when applicable.
32
+
33
+ Examples below use `Time`, but all methods outlined are available to `Date` and `DateTime` objects as well.
34
+
35
+ - [`#fiscal_start=`](https://github.com/forgecrafted/fiscally#fiscal_start) :boom:
36
+ - [`#fiscal_quarter`](https://github.com/forgecrafted/fiscally#fiscal_quarter)
37
+ - [`#all_quarter_months`](https://github.com/forgecrafted/fiscally#all_quarter_months)
38
+ - [`#fiscal_quarter_months`](https://github.com/forgecrafted/fiscally#fiscal_quarter_months)
39
+ - [`#first_month_of_quarter`](https://github.com/forgecrafted/fiscally#first_month_of_quarter)
40
+ - [`#first_quarter`](https://github.com/forgecrafted/fiscally#first_quarter)
41
+ - [`#second_quarter`](https://github.com/forgecrafted/fiscally#second_quarter)
42
+ - [`#third_quarter`](https://github.com/forgecrafted/fiscally#third_quarter)
43
+ - [`#fourth_quarter`](https://github.com/forgecrafted/fiscally#fourth_quarter)
44
+ - [`#beginning_of_fiscal_year`](https://github.com/forgecrafted/fiscally#beginning_of_fiscal_year)
45
+ - [`#beginning_of_fiscal_quarter`](https://github.com/forgecrafted/fiscally#beginning_of_fiscal_quarter)
46
+ - [`#end_of_fiscal_year`](https://github.com/forgecrafted/fiscally#end_of_fiscal_year)
47
+ - [`#end_of_fiscal_quarter`](https://github.com/forgecrafted/fiscally#end_of_fiscal_quarter)
48
+ - [`#quarter_starting_dates`](https://github.com/forgecrafted/fiscally#quarter_starting_dates)
49
+ - [`#quarter_ending_dates`](https://github.com/forgecrafted/fiscally#quarter_ending_dates)
50
+
51
+ ### `#fiscal_start=`
52
+ ###### `objekt.fiscal_start = 8`
53
+
54
+ Sets the **month** in which the fiscal calendar will start on the given `objekt`, represented as an `Integer`. The **day** is always set to the first of the month, and is immutable. Defaults to January (`fiscal_start = 1`).
55
+
56
+ This is the lynchpin of the entire system, adjusting the calendar start and end months to something other than January and December.
57
+
58
+ Calling `objekt.fiscal_start` without an assignment will return the currently set value.
59
+
60
+ This value is not frozen, and can be changed at any time.
61
+
62
+ ```ruby
63
+ foo = Time.new(2014, 1)
64
+ foo.fiscal_start
65
+ # => 1
66
+
67
+ bar = Date.new(2015, 9)
68
+ bar.fiscal_start
69
+ # => 1
70
+
71
+ baz = DateTime.new(2025, 9)
72
+ baz.fiscal_start
73
+ # => 1
74
+
75
+ # this is mutable
76
+ baz.fiscal_start = 4
77
+ baz.fiscal_start
78
+ # => 4
79
+ ```
80
+
81
+ ### `#fiscal_quarter`
82
+
83
+ Returns an integer representing the current quarter.
84
+
85
+ ```ruby
86
+ jan01 = Time.new(2015, 1)
87
+ jan01.fiscal_quarter
88
+ # => 1
89
+
90
+ jan01.fiscal_start = 4
91
+ jan01.fiscal_quarter
92
+ # => 4
93
+
94
+ jan01.fiscal_start = 10
95
+ jan01.fiscal_quarter
96
+ # => 2
97
+ ```
98
+
99
+ ### `#all_quarter_months`
100
+
101
+ Returns an array of arrays, the first level representing the quarters in order, followed by an array of integers representing the months within that quarter.
102
+
103
+ ```ruby
104
+ jan01 = Time.new(2015, 1)
105
+ jan01.all_quarter_months
106
+ # => [[1,2,3], [4,5,6], [7,8,9], [10,11,12]]
107
+
108
+ jan01.fiscal_start = 4
109
+ jan01.all_quarter_months
110
+ # => [[4,5,6], [7,8,9], [10,11,12], [1,2,3]]
111
+
112
+ jan01.fiscal_start = 11
113
+ jan01.all_quarter_months
114
+ # => [[11,12,1], [2,3,4], [5,6,7], [8,9,10]]
115
+ ```
116
+
117
+ ### `#fiscal_quarter_months`
118
+
119
+ Returns an array of integers, representing the months of the current quarter.
120
+
121
+ ```ruby
122
+ jan01 = Time.new(2015, 1)
123
+ jan01.fiscal_start = 4
124
+ jan01.fiscal_quarter_months
125
+ # => [1,2,3]
126
+
127
+ jan01.fiscal_start = 2
128
+ jan01.fiscal_quarter_months
129
+ # => [11,12,1]
130
+
131
+ jan01.fiscal_start = 11
132
+ jan01.fiscal_quarter_months
133
+ # => [11,12,1]
134
+
135
+ jan01.fiscal_start = 9
136
+ jan01.fiscal_quarter_months
137
+ # => [12,1,2]
138
+ ```
139
+
140
+ ### `#first_month_of_quarter`
141
+
142
+ Returns an integer representing the first month of the current quarter.
143
+
144
+ ```ruby
145
+ jan01 = Time.new(2015, 1)
146
+ jan01.fiscal_start = 4
147
+ jan01.first_month_of_quarter
148
+ # => 1
149
+
150
+ jan01.fiscal_start = 2
151
+ jan01.first_month_of_quarter
152
+ # => 11
153
+
154
+ jan01.fiscal_start = 11
155
+ jan01.first_month_of_quarter
156
+ # => 11
157
+
158
+ jan01.fiscal_start = 9
159
+ jan01.first_month_of_quarter
160
+ # => 12
161
+ ```
162
+
163
+ ### `#first_quarter`
164
+
165
+ Returns an array of integers, representing the months of the first quarter. Aliased to `q1`.
166
+
167
+ ```ruby
168
+ jan01 = Time.new(2015, 1)
169
+ jan01.first_quarter
170
+ # => [1,2,3]
171
+ jan01.q1
172
+ # => [1,2,3]
173
+ ```
174
+
175
+ ### `#second_quarter`
176
+
177
+ Returns an array of integers, representing the months of the second quarter. Aliased to `q2`.
178
+
179
+ ```ruby
180
+ jan01 = Time.new(2015, 1)
181
+ jan01.second_quarter
182
+ # => [4,5,6]
183
+ jan01.q2
184
+ # => [4,5,6]
185
+ ```
186
+
187
+ ### `#third_quarter`
188
+
189
+ Returns an array of integers, representing the months of the third quarter. Aliased to `q3`.
190
+
191
+ ```ruby
192
+ jan01 = Time.new(2015, 1)
193
+ jan01.third_quarter
194
+ # => [7,8,9]
195
+ jan01.q3
196
+ # => [7,8,9]
197
+ ```
198
+
199
+ ### `#fourth_quarter`
200
+
201
+ Returns an array of integers, representing the months of the fourth quarter. Aliased to `q4`.
202
+
203
+ ```ruby
204
+ jan01 = Time.new(2015, 1)
205
+ jan01.fourth_quarter
206
+ # => [10,11,12]
207
+ jan01.q4
208
+ # => [10,11,12]
209
+ ```
210
+
211
+ ### `#beginning_of_fiscal_year`
212
+
213
+ Returns a new `Time`/`Date`/`DateTime` object representing the starting date of the fiscal year.
214
+
215
+ ```ruby
216
+ jan01 = Time.new(2015, 1)
217
+ jan01.fiscal_start = 3
218
+ jan01.beginning_of_fiscal_year.strftime('%F')
219
+ # => '2014-03-01'
220
+
221
+ jan01.fiscal_start = 9
222
+ jan01.beginning_of_fiscal_year.strftime('%F')
223
+ # => '2014-09-01'
224
+
225
+ jan01.fiscal_start = 12
226
+ jan01.beginning_of_fiscal_year.strftime('%F')
227
+ # => '2014-12-01'
228
+ ```
229
+
230
+ The returned object will always match the original object class.
231
+
232
+ ```ruby
233
+ Time.new.beginning_of_fiscal_year.class
234
+ # => Time
235
+ Date.new.beginning_of_fiscal_year.class
236
+ # => Date
237
+ DateTime.new.beginning_of_fiscal_year.class
238
+ # => DateTime
239
+ ```
240
+
241
+ ### `#beginning_of_fiscal_quarter`
242
+
243
+ Returns a new `Time`/`Date`/`DateTime` object representing the starting date of the current fiscal quarter.
244
+
245
+ ```ruby
246
+ jan01 = Time.new(2015, 1)
247
+ jan01.beginning_of_fiscal_quarter.strftime('%F')
248
+ # => '2015-01-01'
249
+
250
+ jan01.fiscal_start = 4
251
+ jan01.beginning_of_fiscal_quarter.strftime('%F')
252
+ # => '2015-01-01'
253
+
254
+ jan01.fiscal_start = 2
255
+ jan01.beginning_of_fiscal_quarter.strftime('%F')
256
+ # => '2014-11-01'
257
+
258
+ jan01.fiscal_start = 11
259
+ jan01.beginning_of_fiscal_quarter.strftime('%F')
260
+ # => '2014-11-01'
261
+
262
+ jan01.fiscal_start = 9
263
+ jan01.beginning_of_fiscal_quarter.strftime('%F')
264
+ # => '2014-12-01'
265
+ ```
266
+
267
+ ### `#end_of_fiscal_year`
268
+
269
+ Returns a new `Time`/`Date`/`DateTime` object representing the last day of the current fiscal year.
270
+
271
+ ```ruby
272
+ jan01 = Time.new(2015, 1)
273
+ jan01.end_of_fiscal_quarter.strftime('%F')
274
+ # => '2015-03-31'
275
+
276
+ jan01.fiscal_start = 4
277
+ jan01.end_of_fiscal_quarter.strftime('%F')
278
+ # => '2015-03-31'
279
+
280
+ jan01.fiscal_start = 2
281
+ jan01.end_of_fiscal_quarter.strftime('%F')
282
+ # => '2015-01-31'
283
+
284
+ jan01.fiscal_start = 11
285
+ jan01.end_of_fiscal_quarter.strftime('%F')
286
+ # => '2015-01-31'
287
+
288
+ jan01.fiscal_start = 9
289
+ jan01.end_of_fiscal_quarter.strftime('%F')
290
+ # => '2015-02-28'
291
+ ```
292
+
293
+ ### `#end_of_fiscal_quarter`
294
+
295
+ Returns a new `Time`/`Date`/`DateTime` object representing the last day of the current fiscal quarter.
296
+
297
+ ```ruby
298
+ jan01 = Time.new(2015, 1)
299
+ jan01.end_of_fiscal_quarter.strftime('%F')
300
+ # => '2015-03-31'
301
+
302
+ jan01.fiscal_start = 4
303
+ jan01.end_of_fiscal_quarter.strftime('%F')
304
+ # => '2015-03-31'
305
+
306
+ jan01.fiscal_start = 2
307
+ jan01.end_of_fiscal_quarter.strftime('%F')
308
+ # => '2015-01-31'
309
+
310
+ jan01.fiscal_start = 11
311
+ jan01.end_of_fiscal_quarter.strftime('%F')
312
+ # => '2015-01-31'
313
+
314
+ jan01.fiscal_start = 9
315
+ jan01.end_of_fiscal_quarter.strftime('%F')
316
+ # => '2015-02-28'
317
+ ```
318
+
319
+ ### `#quarter_starting_dates`
320
+
321
+ Returns an array of `Time`/`Date`/`DateTime` objects representing the first day of each quarter for the current fiscal year.
322
+
323
+ ```ruby
324
+ jan01 = Time.new(2015, 1)
325
+ jan01.quarter_starting_dates.each { |time_obj| puts time_obj.strftime('%F') }
326
+ # => '2015-01-01'
327
+ # => '2015-04-01'
328
+ # => '2015-07-01'
329
+ # => '2015-10-01'
330
+
331
+ jan01.fiscal_start = 2
332
+ jan01.quarter_starting_dates.each { |time_obj| puts time_obj.strftime('%F') }
333
+ # => '2014-02-01'
334
+ # => '2014-05-01'
335
+ # => '2014-08-01'
336
+ # => '2014-11-01'
337
+ ```
338
+
339
+ ### `#quarter_ending_dates`
340
+
341
+ Returns an array of `Time`/`Date`/`DateTime` objects representing the last day of each quarter for the current fiscal year.
342
+
343
+ ```ruby
344
+ jan01 = Time.new(2015, 1)
345
+ jan01.quarter_ending_dates.each { |time_obj| puts time_obj.strftime('%F') }
346
+ # => '2015-03-31'
347
+ # => '2015-06-30'
348
+ # => '2015-09-30'
349
+ # => '2015-12-31'
350
+
351
+ jan01.fiscal_start = 2
352
+ jan01.quarter_ending_dates.each { |time_obj| puts time_obj.strftime('%F') }
353
+ # => '2014-04-30'
354
+ # => '2014-07-31'
355
+ # => '2014-10-31'
356
+ # => '2015-01-31'
357
+ ```
@@ -0,0 +1,24 @@
1
+
2
+ desc "Open an irb session preloaded with this library"
3
+ task :console do
4
+ sh "irb -rubygems -I lib -r fiscally.rb"
5
+ end
6
+ task :c => :console
7
+
8
+ namespace :gem do
9
+ desc "Connect to RubyGems.org account"
10
+ task :auth do
11
+ sh "curl -u forgecrafted https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials"
12
+ end
13
+
14
+ desc "Build the gem according to gemspec"
15
+ task :build do
16
+ sh "gem build fiscally.gemspec"
17
+ end
18
+
19
+ require "./lib/fiscally/version"
20
+ desc "Push the gem to RubyGems.org"
21
+ task :push do
22
+ sh "gem push fiscally-#{FinishingMoves::VERSION}.gem"
23
+ end
24
+ end
@@ -0,0 +1,48 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ NAME = "fiscally"
5
+ FQDN = "#{NAME}.example.com"
6
+
7
+ Vagrant.configure("2") do |config|
8
+ # "trusty" is 14.04
9
+ config.vm.box = "trusty64"
10
+ config.vm.box_url = "https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box"
11
+
12
+ # Use the normal insecure key
13
+ # https://github.com/mitchellh/vagrant/issues/2608
14
+ config.ssh.insert_key = false
15
+
16
+ config.vm.provider :virtualbox do |vb|
17
+ vb.customize ["modifyvm", :id,
18
+ # Basics.
19
+ "--name", NAME,
20
+ "--memory", 4096,
21
+ # I/O APIC must be enabled to support a multi-core guest.
22
+ "--cpus", 4,
23
+ "--ioapic", "on",
24
+ # Enable native host virtualization features (yields better performance).
25
+ "--pae", "on",
26
+ "--hwvirtex", "on",
27
+ "--largepages", "on",
28
+ "--vtxvpid", "on",
29
+ # This causes the virtual machine to proxy DNS requests through the host
30
+ # via NAT. Without this, the default resolver on the guest will introduce
31
+ # a 5 second latency on every HTTP request... which is a real downer.
32
+ "--natdnshostresolver1", "on"
33
+ ]
34
+ end
35
+
36
+ config.vm.hostname = FQDN
37
+ config.vm.provision :shell, path: "provision.sh"
38
+ end
39
+
40
+ #
41
+ # DONT FORGET!
42
+ #
43
+ # Force update VirtualBox Guest Additions
44
+ # Run the following command inside same directory as Vagrantfile
45
+ # Must be done once on your dev system
46
+ #
47
+ # vagrant plugin install vagrant-vbguest
48
+ #
@@ -0,0 +1,33 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ require "fiscally/version"
4
+
5
+ Gem::Specification.new do |s|
6
+
7
+ s.name = "fiscally"
8
+ s.version = Fiscally::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["Frank Koehl"]
11
+ s.email = ["frank@forgecrafted.com", "chris@forgecrafted.com"]
12
+ s.summary = %q{Fiscal year awareness for Ruby Date and Time classes.}
13
+ s.description = <<-EOF
14
+ Projects with a financial or business bent often have to deal with awareness of a fiscal year, which typically doesn't line up with a normal calendar year.
15
+
16
+ The `Fiscally` gem adds the necessary awareness to your date and time objects, covering start and end dates for fiscal years and quarterly breakdowns.
17
+ EOF
18
+ s.homepage = "https://github.com/forgecrafted/fiscally"
19
+ s.license = "MIT"
20
+
21
+ s.files = `git ls-files -z`.split("\x0")
22
+ s.test_files = Dir["spec/**/*"]
23
+
24
+ s.add_development_dependency 'rb-readline', '>= 0'
25
+ s.add_development_dependency 'rspec', '~> 3.1.0'
26
+ s.add_development_dependency 'priscilla', '>= 0'
27
+ s.add_development_dependency 'pry-byebug', '>= 0'
28
+ s.add_development_dependency 'fuubar', '>= 0'
29
+ s.add_development_dependency 'coveralls', '>= 0.8.0'
30
+
31
+ s.required_ruby_version = '>= 2.0.0'
32
+
33
+ end
@@ -0,0 +1,7 @@
1
+ module Fiscally
2
+
3
+ Dir[File.dirname(__FILE__) + '/fiscally/*.rb'].each do |file|
4
+ require file
5
+ end
6
+
7
+ end
@@ -0,0 +1,132 @@
1
+ require 'date'
2
+
3
+ module FiscallyGemMethods
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, FiscallyGemMethods
131
+ Date.send :include, FiscallyGemMethods
132
+ DateTime.send :include, FiscallyGemMethods
@@ -0,0 +1,3 @@
1
+ module Fiscally
2
+ VERSION = "1.0"
3
+ end
@@ -0,0 +1,61 @@
1
+ #!/bin/bash
2
+
3
+ # Shell user settings.
4
+ USER_NAME=vagrant
5
+ USER_HOME=/home/$USER_NAME
6
+ DEFAULT_RUBY='2.2.2'
7
+
8
+ ###############################################################################
9
+ # Functions
10
+ ###############################################################################
11
+ # Most of the time we can get by with this DRY wrapper for sudo commands.
12
+ as_user() {
13
+ echo "$USER_NAME:~$ > ${*}"
14
+ su -l $USER_NAME -c "$*"
15
+ }
16
+
17
+ ###############################################################################
18
+ # Base System
19
+ ###############################################################################
20
+ apt-get -y update
21
+ apt-get -yfV dist-upgrade
22
+
23
+ ###############################################################################
24
+ # rbenv & ruby-build, and Rubies
25
+ # From https://github.com/sstephenson/rbenv
26
+ # and https://github.com/sstephenson/ruby-build
27
+ ###############################################################################
28
+
29
+ # Install dependencies.
30
+ apt-get install -yfV \
31
+ build-essential \
32
+ curl \
33
+ git-core \
34
+ libcurl4-openssl-dev \
35
+ libreadline-dev \
36
+ libsqlite3-dev \
37
+ libssl-dev \
38
+ libxml2-dev \
39
+ libxslt1-dev \
40
+ libyaml-dev \
41
+ python-software-properties \
42
+ sqlite3 \
43
+ zlib1g-dev \
44
+
45
+ # Install rbenv and ruby-build.
46
+ as_user "git clone https://github.com/sstephenson/rbenv.git $USER_HOME/.rbenv"
47
+ as_user "git clone https://github.com/sstephenson/ruby-build.git $USER_HOME/.rbenv/plugins/ruby-build"
48
+
49
+ # Setup bash to use rbenv for $USER_NAME.
50
+ truncate -s 0 $USER_HOME/.bashrc
51
+ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> $USER_HOME/.bashrc
52
+ echo 'eval "$(rbenv init -)"' >> $USER_HOME/.bashrc
53
+ echo 'cd /vagrant' >> $USER_HOME/.bashrc
54
+
55
+ echo 'gem: --no-document' > $USER_HOME/.gemrc
56
+
57
+ # Install the requested version of Ruby, with Bundler.
58
+ as_user "rbenv install -s $DEFAULT_RUBY"
59
+ as_user "rbenv global $DEFAULT_RUBY"
60
+ as_user "RBENV_VERSION=$DEFAULT_RUBY gem install bundler"
61
+ as_user "cd /vagrant && bundle"
@@ -0,0 +1,254 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Fiscally' 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(Time.method_defined? :fiscal_quarter).to be true
14
+ expect(Time.method_defined? :all_quarter_months).to be true
15
+ expect(Time.method_defined? :fiscal_quarter_months).to be true
16
+
17
+ expect(Date.method_defined? :fiscal_start).to be true
18
+ expect(Date.method_defined? :fiscal_quarter).to be true
19
+ expect(Date.method_defined? :all_quarter_months).to be true
20
+ expect(Date.method_defined? :fiscal_quarter_months).to be true
21
+
22
+ expect(DateTime.method_defined? :fiscal_start).to be true
23
+ expect(DateTime.method_defined? :fiscal_quarter).to be true
24
+ expect(DateTime.method_defined? :all_quarter_months).to be true
25
+ expect(DateTime.method_defined? :fiscal_quarter_months).to be true
26
+ end
27
+
28
+ it "#fiscal_quarter" do
29
+ q = 1
30
+ default_quarters.each do |months|
31
+ months.each { |m| expect(Time.new(2015, m).fiscal_quarter).to eq q }
32
+ q += 1
33
+ end
34
+
35
+ # Adjusted fiscal calendar
36
+ @jan01.fiscal_start = 4
37
+ expect(@jan01.fiscal_quarter).to eq 4
38
+ @jan01.fiscal_start = 10
39
+ expect(@jan01.fiscal_quarter).to eq 2
40
+
41
+ # Make sure other date classes work
42
+ expect(Date.new(2015, 9).fiscal_quarter).to eq 3
43
+ expect(DateTime.new(2015, 9).fiscal_quarter).to eq 3
44
+ end
45
+
46
+ it "#all_quarter_months" do
47
+ expect(@jan01.all_quarter_months).to eq default_quarters
48
+ @jan01.fiscal_start = 4
49
+ expect(@jan01.all_quarter_months).to eq [[4,5,6], [7,8,9], [10,11,12], [1,2,3]]
50
+ @jan01.fiscal_start = 11
51
+ expect(@jan01.all_quarter_months).to eq [[11,12,1], [2,3,4], [5,6,7], [8,9,10]]
52
+
53
+ expect(Date.new(2015, 9).all_quarter_months).to eq default_quarters
54
+ expect(DateTime.new(2015, 9).all_quarter_months).to eq default_quarters
55
+ # alias check
56
+ expect(DateTime.new(2015, 9).fiscal_calendar).to eq default_quarters
57
+ end
58
+
59
+ it "#quarter shortcuts" do
60
+ expect(@jan01.first_quarter).to eq default_quarters[0]
61
+ expect(@jan01.q1).to eq default_quarters[0]
62
+ expect(@jan01.second_quarter).to eq default_quarters[1]
63
+ expect(@jan01.q2).to eq default_quarters[1]
64
+ expect(@jan01.third_quarter).to eq default_quarters[2]
65
+ expect(@jan01.q3).to eq default_quarters[2]
66
+ expect(@jan01.fourth_quarter).to eq default_quarters[3]
67
+ expect(@jan01.q4).to eq default_quarters[3]
68
+ end
69
+
70
+ it "#fiscal_quarter_months" do
71
+ expect(Time.new(2015, 1).fiscal_quarter_months).to eq [1,2,3]
72
+ expect(Date.new(2015, 2).fiscal_quarter_months).to eq [1,2,3]
73
+ expect(DateTime.new(2015, 5).fiscal_quarter_months).to eq [4,5,6]
74
+
75
+ @jan01.fiscal_start = 4
76
+ expect(@jan01.fiscal_quarter_months).to eq [1,2,3]
77
+ @jan01.fiscal_start = 2
78
+ expect(@jan01.fiscal_quarter_months).to eq [11,12,1]
79
+ @jan01.fiscal_start = 11
80
+ expect(@jan01.fiscal_quarter_months).to eq [11,12,1]
81
+ @jan01.fiscal_start = 9
82
+ expect(@jan01.fiscal_quarter_months).to eq [12,1,2]
83
+ end
84
+
85
+ it "#first_month_of_quarter" do
86
+ expect(Time.new(2015, 1).first_month_of_quarter).to eq 1
87
+ expect(Date.new(2015, 8).first_month_of_quarter).to eq 7
88
+ expect(DateTime.new(2015, 5).first_month_of_quarter).to eq 4
89
+
90
+ @jan01.fiscal_start = 4
91
+ expect(@jan01.first_month_of_quarter).to eq 1
92
+ @jan01.fiscal_start = 2
93
+ expect(@jan01.first_month_of_quarter).to eq 11
94
+ @jan01.fiscal_start = 11
95
+ expect(@jan01.first_month_of_quarter).to eq 11
96
+ @jan01.fiscal_start = 9
97
+ expect(@jan01.first_month_of_quarter).to eq 12
98
+ end
99
+
100
+ it "#beginning_of_fiscal_quarter" do
101
+ expect(Time.new.beginning_of_fiscal_quarter).to be_a Time
102
+ expect(Date.new.beginning_of_fiscal_quarter).to be_a Date
103
+ expect(DateTime.new.beginning_of_fiscal_quarter).to be_a DateTime
104
+
105
+ expect(@jan01.beginning_of_fiscal_quarter.strftime('%F')).to eq '2015-01-01'
106
+ @jan01.fiscal_start = 4
107
+ expect(@jan01.beginning_of_fiscal_quarter.strftime('%F')).to eq '2015-01-01'
108
+ @jan01.fiscal_start = 2
109
+ expect(@jan01.beginning_of_fiscal_quarter.strftime('%F')).to eq '2014-11-01'
110
+ @jan01.fiscal_start = 11
111
+ expect(@jan01.beginning_of_fiscal_quarter.strftime('%F')).to eq '2014-11-01'
112
+ @jan01.fiscal_start = 9
113
+ expect(@jan01.beginning_of_fiscal_quarter.strftime('%F')).to eq '2014-12-01'
114
+ end
115
+
116
+ it "#end_of_fiscal_quarter" do
117
+ expect(Time.new.end_of_fiscal_quarter).to be_a Time
118
+ expect(Date.new.end_of_fiscal_quarter).to be_a Date
119
+ expect(DateTime.new.end_of_fiscal_quarter).to be_a DateTime
120
+
121
+ expect(@jan01.end_of_fiscal_quarter.strftime('%F')).to eq '2015-03-31'
122
+ @jan01.fiscal_start = 4
123
+ expect(@jan01.end_of_fiscal_quarter.strftime('%F')).to eq '2015-03-31'
124
+ @jan01.fiscal_start = 2
125
+ expect(@jan01.end_of_fiscal_quarter.strftime('%F')).to eq '2015-01-31'
126
+ @jan01.fiscal_start = 11
127
+ expect(@jan01.end_of_fiscal_quarter.strftime('%F')).to eq '2015-01-31'
128
+ @jan01.fiscal_start = 9
129
+ expect(@jan01.end_of_fiscal_quarter.strftime('%F')).to eq '2015-02-28'
130
+
131
+ # Separate logic for Date and DateTime means separate tests
132
+ @jan01_date = Date.new(2015, 1)
133
+ expect(@jan01_date.end_of_fiscal_quarter.strftime('%F')).to eq '2015-03-31'
134
+ @jan01_date.fiscal_start = 4
135
+ expect(@jan01_date.end_of_fiscal_quarter.strftime('%F')).to eq '2015-03-31'
136
+ @jan01_date.fiscal_start = 2
137
+ expect(@jan01_date.end_of_fiscal_quarter.strftime('%F')).to eq '2015-01-31'
138
+ @jan01_date.fiscal_start = 11
139
+ expect(@jan01_date.end_of_fiscal_quarter.strftime('%F')).to eq '2015-01-31'
140
+ @jan01_date.fiscal_start = 9
141
+ expect(@jan01_date.end_of_fiscal_quarter.strftime('%F')).to eq '2015-02-28'
142
+
143
+ @jan01_datetime = DateTime.new(2015, 1)
144
+ expect(@jan01_datetime.end_of_fiscal_quarter.strftime('%F')).to eq '2015-03-31'
145
+ @jan01_datetime.fiscal_start = 4
146
+ expect(@jan01_datetime.end_of_fiscal_quarter.strftime('%F')).to eq '2015-03-31'
147
+ @jan01_datetime.fiscal_start = 2
148
+ expect(@jan01_datetime.end_of_fiscal_quarter.strftime('%F')).to eq '2015-01-31'
149
+ @jan01_datetime.fiscal_start = 11
150
+ expect(@jan01_datetime.end_of_fiscal_quarter.strftime('%F')).to eq '2015-01-31'
151
+ @jan01_datetime.fiscal_start = 9
152
+ expect(@jan01_datetime.end_of_fiscal_quarter.strftime('%F')).to eq '2015-02-28'
153
+ end
154
+
155
+ it "#beginning_of_fiscal_year" do
156
+ expect(Time.new.beginning_of_fiscal_year).to be_a Time
157
+ expect(Date.new.beginning_of_fiscal_year).to be_a Date
158
+ expect(DateTime.new.beginning_of_fiscal_year).to be_a DateTime
159
+
160
+ @jan01.fiscal_start = 3
161
+ expect(@jan01.beginning_of_fiscal_year.strftime('%F')).to eq '2014-03-01'
162
+ @jan01.fiscal_start = 9
163
+ expect(@jan01.beginning_of_fiscal_year.strftime('%F')).to eq '2014-09-01'
164
+ @jan01.fiscal_start = 12
165
+ expect(@jan01.beginning_of_fiscal_year.strftime('%F')).to eq '2014-12-01'
166
+ end
167
+
168
+ it "#end_of_fiscal_year" do
169
+ expect(Time.new.end_of_fiscal_year).to be_a Time
170
+ expect(Date.new.end_of_fiscal_year).to be_a Date
171
+ expect(DateTime.new.end_of_fiscal_year).to be_a DateTime
172
+
173
+ @jan01.fiscal_start = 3
174
+ expect(@jan01.end_of_fiscal_year.strftime('%F')).to eq '2015-02-28'
175
+ @jan01.fiscal_start = 9
176
+ expect(@jan01.end_of_fiscal_year.strftime('%F')).to eq '2015-08-31'
177
+ @jan01.fiscal_start = 12
178
+ expect(@jan01.end_of_fiscal_year.strftime('%F')).to eq '2015-11-30'
179
+
180
+ # Separate logic for Date and DateTime means separate tests
181
+ @jan01_date = Date.new(2015, 1)
182
+ @jan01_date.fiscal_start = 3
183
+ expect(@jan01_date.end_of_fiscal_year.strftime('%F')).to eq '2015-02-28'
184
+ @jan01_date.fiscal_start = 9
185
+ expect(@jan01_date.end_of_fiscal_year.strftime('%F')).to eq '2015-08-31'
186
+ @jan01_date.fiscal_start = 12
187
+ expect(@jan01_date.end_of_fiscal_year.strftime('%F')).to eq '2015-11-30'
188
+
189
+ @jan01_datetime = DateTime.new(2015, 1)
190
+ @jan01_datetime.fiscal_start = 3
191
+ expect(@jan01_datetime.end_of_fiscal_year.strftime('%F')).to eq '2015-02-28'
192
+ @jan01_datetime.fiscal_start = 9
193
+ expect(@jan01_datetime.end_of_fiscal_year.strftime('%F')).to eq '2015-08-31'
194
+ @jan01_datetime.fiscal_start = 12
195
+ expect(@jan01_datetime.end_of_fiscal_year.strftime('%F')).to eq '2015-11-30'
196
+ end
197
+
198
+ it "#quarter_starting_dates" do
199
+ expect(@jan01.quarter_starting_dates).to be_an Array
200
+ expect(@jan01.quarter_starting_dates.length).to eq 4
201
+
202
+ expect(@jan01.quarter_starting_dates[0].strftime('%F')).to eq '2015-01-01'
203
+ expect(@jan01.quarter_starting_dates[1].strftime('%F')).to eq '2015-04-01'
204
+ expect(@jan01.quarter_starting_dates[2].strftime('%F')).to eq '2015-07-01'
205
+ expect(@jan01.quarter_starting_dates[3].strftime('%F')).to eq '2015-10-01'
206
+
207
+ @jan01.fiscal_start = 2
208
+ expect(@jan01.quarter_starting_dates[0].strftime('%F')).to eq '2014-02-01'
209
+ expect(@jan01.quarter_starting_dates[1].strftime('%F')).to eq '2014-05-01'
210
+ expect(@jan01.quarter_starting_dates[2].strftime('%F')).to eq '2014-08-01'
211
+ expect(@jan01.quarter_starting_dates[3].strftime('%F')).to eq '2014-11-01'
212
+
213
+ @jan01.fiscal_start = 9
214
+ expect(@jan01.quarter_starting_dates[0].strftime('%F')).to eq '2014-09-01'
215
+ expect(@jan01.quarter_starting_dates[1].strftime('%F')).to eq '2014-12-01'
216
+ expect(@jan01.quarter_starting_dates[2].strftime('%F')).to eq '2015-03-01'
217
+ expect(@jan01.quarter_starting_dates[3].strftime('%F')).to eq '2015-06-01'
218
+
219
+ @jan01_date = Date.new(2015, 1)
220
+ expect(@jan01_date.quarter_starting_dates[0].strftime('%F')).to eq '2015-01-01'
221
+ expect(@jan01_date.quarter_starting_dates[1].strftime('%F')).to eq '2015-04-01'
222
+ expect(@jan01_date.quarter_starting_dates[2].strftime('%F')).to eq '2015-07-01'
223
+ expect(@jan01_date.quarter_starting_dates[3].strftime('%F')).to eq '2015-10-01'
224
+ end
225
+
226
+ it "#quarter_ending_dates" do
227
+ expect(@jan01.quarter_ending_dates).to be_an Array
228
+ expect(@jan01.quarter_ending_dates.length).to eq 4
229
+
230
+ expect(@jan01.quarter_ending_dates[0].strftime('%F')).to eq '2015-03-31'
231
+ expect(@jan01.quarter_ending_dates[1].strftime('%F')).to eq '2015-06-30'
232
+ expect(@jan01.quarter_ending_dates[2].strftime('%F')).to eq '2015-09-30'
233
+ expect(@jan01.quarter_ending_dates[3].strftime('%F')).to eq '2015-12-31'
234
+
235
+ @jan01.fiscal_start = 2
236
+ expect(@jan01.quarter_ending_dates[0].strftime('%F')).to eq '2014-04-30'
237
+ expect(@jan01.quarter_ending_dates[1].strftime('%F')).to eq '2014-07-31'
238
+ expect(@jan01.quarter_ending_dates[2].strftime('%F')).to eq '2014-10-31'
239
+ expect(@jan01.quarter_ending_dates[3].strftime('%F')).to eq '2015-01-31'
240
+
241
+ @jan01.fiscal_start = 9
242
+ expect(@jan01.quarter_ending_dates[0].strftime('%F')).to eq '2014-11-30'
243
+ expect(@jan01.quarter_ending_dates[1].strftime('%F')).to eq '2015-02-28'
244
+ expect(@jan01.quarter_ending_dates[2].strftime('%F')).to eq '2015-05-31'
245
+ expect(@jan01.quarter_ending_dates[3].strftime('%F')).to eq '2015-08-31'
246
+
247
+ @jan01_date = Date.new(2015, 1)
248
+ expect(@jan01_date.quarter_ending_dates[0].strftime('%F')).to eq '2015-03-31'
249
+ expect(@jan01_date.quarter_ending_dates[1].strftime('%F')).to eq '2015-06-30'
250
+ expect(@jan01_date.quarter_ending_dates[2].strftime('%F')).to eq '2015-09-30'
251
+ expect(@jan01_date.quarter_ending_dates[3].strftime('%F')).to eq '2015-12-31'
252
+ end
253
+
254
+ end
@@ -0,0 +1,108 @@
1
+ require 'rubygems'
2
+
3
+ require 'bundler/setup'
4
+ Bundler.setup
5
+
6
+ require 'priscilla'
7
+ require 'pry'
8
+ require 'byebug'
9
+
10
+ require 'coveralls'
11
+ Coveralls.wear!
12
+
13
+ require 'fiscally'
14
+
15
+ # This file was generated by the `rspec --init` command. Conventionally, all
16
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
17
+ # The generated `.rspec` file contains `--require spec_helper` which will cause this
18
+ # file to always be loaded, without a need to explicitly require it in any files.
19
+ #
20
+ # Given that it is always loaded, you are encouraged to keep this file as
21
+ # light-weight as possible. Requiring heavyweight dependencies from this file
22
+ # will add to the boot time of your test suite on EVERY test run, even for an
23
+ # individual file that may not need all of that loaded. Instead, consider making
24
+ # a separate helper file that requires the additional dependencies and performs
25
+ # the additional setup, and require it from the spec files that actually need it.
26
+ #
27
+ # The `.rspec` file also contains a few flags that are not defaults but that
28
+ # users commonly want.
29
+ #
30
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
31
+ RSpec.configure do |config|
32
+ # rspec-expectations config goes here. You can use an alternate
33
+ # assertion/expectation library such as wrong or the stdlib/minitest
34
+ # assertions if you prefer.
35
+ config.expect_with :rspec do |expectations|
36
+ # This option will default to `true` in RSpec 4. It makes the `description`
37
+ # and `failure_message` of custom matchers include text for helper methods
38
+ # defined using `chain`, e.g.:
39
+ # be_bigger_than(2).and_smaller_than(4).description
40
+ # # => "be bigger than 2 and smaller than 4"
41
+ # ...rather than:
42
+ # # => "be bigger than 2"
43
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
44
+ end
45
+
46
+ # rspec-mocks config goes here. You can use an alternate test double
47
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
48
+ config.mock_with :rspec do |mocks|
49
+ # Prevents you from mocking or stubbing a method that does not exist on
50
+ # a real object. This is generally recommended, and will default to
51
+ # `true` in RSpec 4.
52
+ mocks.verify_partial_doubles = true
53
+ end
54
+
55
+ config.filter_run :focus
56
+ config.run_all_when_everything_filtered = true
57
+
58
+ config.order = :random
59
+
60
+ # The settings below are suggested to provide a good initial experience
61
+ # with RSpec, but feel free to customize to your heart's content.
62
+ =begin
63
+ # These two settings work together to allow you to limit a spec run
64
+ # to individual examples or groups you care about by tagging them with
65
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
66
+ # get run.
67
+ config.filter_run :focus
68
+ config.run_all_when_everything_filtered = true
69
+
70
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
71
+ # For more details, see:
72
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
73
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
74
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
75
+ config.disable_monkey_patching!
76
+
77
+ # This setting enables warnings. It's recommended, but in some cases may
78
+ # be too noisy due to issues in dependencies.
79
+ config.warnings = true
80
+
81
+ # Many RSpec users commonly either run the entire suite or an individual
82
+ # file, and it's useful to allow more verbose output when running an
83
+ # individual spec file.
84
+ if config.files_to_run.one?
85
+ # Use the documentation formatter for detailed output,
86
+ # unless a formatter has already been configured
87
+ # (e.g. via a command-line flag).
88
+ config.default_formatter = 'doc'
89
+ end
90
+
91
+ # Print the 10 slowest examples and example groups at the
92
+ # end of the spec run, to help surface which specs are running
93
+ # particularly slow.
94
+ config.profile_examples = 10
95
+
96
+ # Run specs in random order to surface order dependencies. If you find an
97
+ # order dependency and want to debug it, you can fix the order by providing
98
+ # the seed, which is printed after each run.
99
+ # --seed 1234
100
+ config.order = :random
101
+
102
+ # Seed global randomization in this process using the `--seed` CLI option.
103
+ # Setting this allows you to use `--seed` to deterministically reproduce
104
+ # test failures related to randomization by passing the same `--seed` value
105
+ # as the one that triggered the failure.
106
+ Kernel.srand config.seed
107
+ =end
108
+ end
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fiscally
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ platform: ruby
6
+ authors:
7
+ - Frank Koehl
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-09-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rb-readline
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 3.1.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 3.1.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: priscilla
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry-byebug
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: fuubar
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: coveralls
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 0.8.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 0.8.0
97
+ description: |2
98
+ Projects with a financial or business bent often have to deal with awareness of a fiscal year, which typically doesn't line up with a normal calendar year.
99
+
100
+ The `Fiscally` gem adds the necessary awareness to your date and time objects, covering start and end dates for fiscal years and quarterly breakdowns.
101
+ email:
102
+ - frank@forgecrafted.com
103
+ - chris@forgecrafted.com
104
+ executables: []
105
+ extensions: []
106
+ extra_rdoc_files: []
107
+ files:
108
+ - ".gitignore"
109
+ - ".rspec"
110
+ - ".travis.yml"
111
+ - Gemfile
112
+ - LICENSE
113
+ - README.md
114
+ - Rakefile
115
+ - Vagrantfile
116
+ - fiscally.gemspec
117
+ - lib/fiscally.rb
118
+ - lib/fiscally/fiscally.rb
119
+ - lib/fiscally/version.rb
120
+ - provision.sh
121
+ - spec/fiscally_spec.rb
122
+ - spec/spec_helper.rb
123
+ homepage: https://github.com/forgecrafted/fiscally
124
+ licenses:
125
+ - MIT
126
+ metadata: {}
127
+ post_install_message:
128
+ rdoc_options: []
129
+ require_paths:
130
+ - lib
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: 2.0.0
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ requirements: []
142
+ rubyforge_project:
143
+ rubygems_version: 2.4.5
144
+ signing_key:
145
+ specification_version: 4
146
+ summary: Fiscal year awareness for Ruby Date and Time classes.
147
+ test_files:
148
+ - spec/fiscally_spec.rb
149
+ - spec/spec_helper.rb