👻

カレンダー作成問題をやってみた

に公開

動機

Railsを一年ほどやっていないので、リハビリがてらにカレンダー問題をやってみました。

実装

lib/calendar.rb
# frozen_string_literal: true

require 'active_support/all'

class Calendar
  def year_month_header
    "#{today.strftime('%b')} #{today.year}".center(20)
  end

  def wday_header
    'Su Mo Tu We Th Fr Sa'
  end

  def first_line
    line = ' ' * 20
    line[today.beginning_of_month.wday * 3 + 1] = '1'

    line
  end

  def other_lines
    lines = []
    line = []

    (2..today.end_of_month.day).each do |i|
      line << format('%2d', i)

      next unless line.length == 7

      lines << line.join(' ')

      line = []
    end

    lines << line.join(' ')

    lines.join("\n")
  end

  def today
    @today ||= Date.today
  end
end
spec/calendar_spec.rb
# frozen_string_literal: true

describe Calendar do
  let(:calendar) { described_class.new }

  describe '#year_month_header' do
    subject { calendar.year_month_header }

    around do |ex|
      travel_to(today) { ex.run }
    end

    context 'when today is 2025/03/31' do
      let(:today) { Date.parse('2025/03/31') }

      it { is_expected.to eq '      Mar 2025      ' }
    end

    context 'when today is 2025/04/01' do
      let(:today) { Date.parse('2025/04/01') }

      it { is_expected.to eq '      Apr 2025      ' }
    end
  end

  describe '#wday_header' do
    subject { calendar.wday_header }

    it { is_expected.to eq 'Su Mo Tu We Th Fr Sa' }
  end

  describe '#first_line' do
    subject { calendar.first_line }

    around do |ex|
      travel_to(today) { ex.run }
    end

    context 'when today is 2025/03/31' do
      let(:today) { Date.parse('2025/03/31') }

      it { is_expected.to eq '                   1' }
    end

    context 'when today is 2025/04/01' do
      let(:today) { Date.parse('2025/04/01') }

      it { is_expected.to eq '       1            ' }
    end
  end

  describe '#other_lines' do
    subject { calendar.other_lines }

    it {
      is_expected.to eq " 2  3  4  5  6  7  8\n 9 10 11 12 13 14 15\n16 17 18 19 20 21 22\n23 24 25 26 27 28 29\n30 31"
    }
  end
end

感想

素のRubyからActiveSupportを使ったりしたので、良いリハビリになりました。次は、カラオケマシン問題をやってみます。

Discussion