Skip to content

Instantly share code, notes, and snippets.

@gmcnaughton
Forked from henrik/month.rb
Created November 18, 2015 14:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gmcnaughton/45707296470f9a0de1ea to your computer and use it in GitHub Desktop.
Save gmcnaughton/45707296470f9a0de1ea to your computer and use it in GitHub Desktop.
Ruby Month class.
require "attr_extras" # gem
class Month
vattr_initialize :year, :month_number
def self.from(object)
case object
when Month then object
else new(object.year, object.month)
end
end
# Relies on Rails' Time.zone.
def self.now
from(Time.zone.now)
end
def first_date
Date.new(year, month_number, 1)
end
def last_date
Date.new(year, month_number, -1)
end
def last_day
last_date.day
end
def date_for_day(number)
Date.new(year, month_number, number)
end
def previous
self.class.from(first_date - 1)
end
def next
self.class.from(last_date + 1)
end
end
require "spec_helper"
describe Month do
it "has value object equality" do
expect(Month.new(2014, 6)).to eq Month.new(2014, 6)
end
end
describe Month, ".from" do
it "builds a Month from a Date" do
month = Month.from(Date.new(2014, 6, 1))
expect(month).to eq Month.new(2014, 6)
end
it "builds a Month from a Time" do
month = Month.from(Time.zone.local(2014, 6, 1, 0, 0, 0))
expect(month).to eq Month.new(2014, 6)
end
it "returns the input when given a Month, since it's a value object" do
month = Month.from(Month.new(2014, 6))
expect(month).to eq Month.new(2014, 6)
end
end
describe Month, ".now" do
it "is the current month" do
Timecop.freeze(Time.zone.local(2014, 1, 1, 0, 0, 0)) do
expect(Month.now).to eq Month.new(2014, 1)
end
end
end
describe Month, "#first_date" do
it "is the first date of the month" do
month = Month.new(2014, 2)
expect(month.first_date).to eq Date.new(2014, 2, 1)
end
end
describe Month, "#last_date" do
it "is the last date of the month" do
month = Month.new(2014, 2)
expect(month.last_date).to eq Date.new(2014, 2, 28)
end
end
describe Month, "#last_day" do
it "is the last day number of the month" do
month = Month.new(2014, 2)
expect(month.last_day).to eq 28
end
end
describe Month, "#date_for_day" do
it "gives you such a date" do
date = Month.new(2014, 1).date_for_day(2)
expect(date).to eq Date.new(2014, 1, 2)
end
end
describe Month, "#previous" do
it "is the previous month" do
month = Month.new(2014, 2)
expect(month.previous).to eq Month.new(2014, 1)
expect(month.previous.previous).to eq Month.new(2013, 12)
end
end
describe Month, "#next" do
it "is the next month" do
month = Month.new(2013, 11)
expect(month.next).to eq Month.new(2013, 12)
expect(month.next.next).to eq Month.new(2014, 1)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment