require "test_helper" class WeeklyEnumeratorTest < ActiveSupport::TestCase include Hiccup test "should generate a cycle of [7] for something that occurs every week on one day" do assert_equal [7], cycle_for( :start_date => Date.new(2013, 9, 23), :weekly_pattern => ["Monday"]) end test "should generate a cycle of [21] for something that occurs every _third_ week on one day" do assert_equal [21], cycle_for( :start_date => Date.new(2013, 9, 23), :weekly_pattern => ["Monday"], :skip => 3) end test "should generate a cycle of [6, 8] for something that occurs every other Saturday and Sunday when the start date is a Sunday" do assert_equal [6, 8], cycle_for( :start_date => Date.new(2013, 9, 22), :weekly_pattern => ["Saturday", "Sunday"], :skip => 2) end test "should generate a cycle of [8, 6] for something that occurs every other Saturday and Sunday when the start date is a Saturday" do assert_equal [8, 6], cycle_for( :start_date => Date.new(2013, 9, 28), :weekly_pattern => ["Saturday", "Sunday"], :skip => 2) end test "should generate a cycle of [2, 2, 10] for something that occurs every other Monday, Wednesday, Friday when the start date is a Monday" do assert_equal [2, 2, 10], cycle_for( :start_date => Date.new(2013, 9, 23), :weekly_pattern => ["Monday", "Wednesday", "Friday"], :skip => 2) end test "should generate a cycle of [2, 10, 2] for something that occurs every other Monday, Wednesday, Friday when the start date is a Wednesday" do assert_equal [2, 10, 2], cycle_for( :start_date => Date.new(2013, 9, 25), :weekly_pattern => ["Monday", "Wednesday", "Friday"], :skip => 2) end test "should generate a cycle of [10, 2, 2] for something that occurs every other Monday, Wednesday, Friday when the start date is a Friday" do assert_equal [10, 2, 2], cycle_for( :start_date => Date.new(2013, 9, 27), :weekly_pattern => ["Monday", "Wednesday", "Friday"], :skip => 2) end test "should generate a cycle of [2, 5] for something that occurs every Tuesday and Thursday when the start date is a Friday" do assert_equal [2, 5], cycle_for( :start_date => Date.new(2013, 9, 27), :weekly_pattern => ["Tuesday", "Thursday"]) end context "#position_of" do setup do @schedule = Schedule.new( :kind => :weekly, :start_date => Date.new(2013, 9, 26), # Thursday :weekly_pattern => ["Tuesday", "Thursday", "Friday"], :skip => 2) end should "be a sane test" do assert_equal [1, 11, 2], cycle_for(@schedule) end should "find the correct position for the given date" do assert_equal 0, position_of(@schedule, 2013, 9, 26) assert_equal 1, position_of(@schedule, 2013, 9, 27) assert_equal 2, position_of(@schedule, 2013, 10, 8) assert_equal 0, position_of(@schedule, 2013, 10, 10) assert_equal 1, position_of(@schedule, 2013, 10, 11) assert_equal 2, position_of(@schedule, 2013, 10, 22) end end context "with a complex schedule" do setup do @schedule = Schedule.new( :kind => :weekly, :start_date => Date.new(2013, 9, 26), # Thursday :weekly_pattern => ["Tuesday", "Thursday", "Friday"]) end should "pick the right date when enumerating backward" do enumerator = @schedule.enumerator.new(@schedule, Date.new(2013, 10, 16)) # Wednesday! assert_equal Date.new(2013, 10, 15), enumerator.prev end end context "Given an invalid schedule with no weekly pattern, it" do setup do @schedule = Schedule.new( :kind => :weekly, :start_date => Date.new(2013, 9, 26), :weekly_pattern => []) end should "return nil for prev rather than raising an exception" do enumerator = @schedule.enumerator.new(@schedule, Date.today) assert_equal nil, enumerator.prev end should "return nil for next rather than raising an exception" do enumerator = @schedule.enumerator.new(@schedule, Date.today) assert_equal nil, enumerator.next end end private def cycle_for(options={}) schedule = build_schedule(options) enumerator = schedule.enumerator.new(schedule, Date.today) enumerator.send :calculate_cycle, schedule end def position_of(schedule, *args) date = build_date(*args) enumerator = schedule.enumerator.new(schedule, date) enumerator.send :position_of, date end def build_schedule(options={}) return options if options.is_a? Schedule Schedule.new(options.merge(:kind => :weekly)) end def build_date(*args) return Date.new(*args) if args.length == 3 args.first end end