require "./spec_helper" describe JosieHealth::Utils::Recurrence do describe ".parse_interval" do it "parses weeks (1w)" do JosieHealth::Utils::Recurrence.parse_interval("1w").should eq(604800) end it "parses days (5d)" do JosieHealth::Utils::Recurrence.parse_interval("5d").should eq(432000) end it "parses hours (2h)" do JosieHealth::Utils::Recurrence.parse_interval("2h").should eq(7200) end it "parses minutes (30m)" do JosieHealth::Utils::Recurrence.parse_interval("30m").should eq(1800) end it "parses seconds (45s)" do JosieHealth::Utils::Recurrence.parse_interval("45s").should eq(45) end it "parses combined units (1h30m)" do JosieHealth::Utils::Recurrence.parse_interval("1h30m").should eq(5400) end it "parses complex combined (1w2d3h)" do JosieHealth::Utils::Recurrence.parse_interval("1w2d3h").should eq(788400) end it "is case insensitive (1H30M)" do JosieHealth::Utils::Recurrence.parse_interval("1H30M").should eq(5400) end it "parses decimal weeks (1.5w)" do JosieHealth::Utils::Recurrence.parse_interval("1.5w").should eq(907200) end it "parses decimal hours (2.5h)" do JosieHealth::Utils::Recurrence.parse_interval("2.5h").should eq(9000) end it "parses decimal days (0.5d)" do JosieHealth::Utils::Recurrence.parse_interval("0.5d").should eq(43200) end it "returns nil for invalid pattern" do JosieHealth::Utils::Recurrence.parse_interval("invalid").should be_nil end it "returns nil for empty string" do JosieHealth::Utils::Recurrence.parse_interval("").should be_nil end it "returns nil for day names" do JosieHealth::Utils::Recurrence.parse_interval("monday").should be_nil end end describe ".parse_day_of_week" do it "parses monday" do JosieHealth::Utils::Recurrence.parse_day_of_week("monday").should eq(1) end it "parses friday" do JosieHealth::Utils::Recurrence.parse_day_of_week("friday").should eq(5) end it "parses sunday" do JosieHealth::Utils::Recurrence.parse_day_of_week("sunday").should eq(7) end it "is case insensitive (MONDAY)" do JosieHealth::Utils::Recurrence.parse_day_of_week("MONDAY").should eq(1) end it "returns nil for invalid day" do JosieHealth::Utils::Recurrence.parse_day_of_week("notaday").should be_nil end it "returns nil for interval patterns" do JosieHealth::Utils::Recurrence.parse_day_of_week("1h").should be_nil end end describe ".valid?" do it "returns true for interval patterns" do JosieHealth::Utils::Recurrence.valid?("1h").should be_true end it "returns true for day names" do JosieHealth::Utils::Recurrence.valid?("monday").should be_true end it "returns false for empty string" do JosieHealth::Utils::Recurrence.valid?("").should be_false end it "returns false for invalid patterns" do JosieHealth::Utils::Recurrence.valid?("invalid").should be_false end end describe ".next_trigger" do it "adds interval to current time" do base_time = Time.utc(2025, 1, 1, 12, 0, 0) result = JosieHealth::Utils::Recurrence.next_trigger("1h", base_time) result.should eq(Time.utc(2025, 1, 1, 13, 0, 0).to_unix) end it "adds combined intervals" do base_time = Time.utc(2025, 1, 1, 12, 0, 0) result = JosieHealth::Utils::Recurrence.next_trigger("1d12h", base_time) result.should eq(Time.utc(2025, 1, 3, 0, 0, 0).to_unix) end it "calculates next monday from wednesday" do base_time = Time.utc(2025, 1, 1, 12, 0, 0) # Wednesday result = JosieHealth::Utils::Recurrence.next_trigger("monday", base_time) expected = Time.utc(2025, 1, 6, 12, 0, 0) # Next Monday result.should eq(expected.to_unix) end it "calculates next friday from wednesday" do base_time = Time.utc(2025, 1, 1, 12, 0, 0) # Wednesday result = JosieHealth::Utils::Recurrence.next_trigger("friday", base_time) expected = Time.utc(2025, 1, 3, 12, 0, 0) # Friday result.should eq(expected.to_unix) end it "skips to next week if same day" do base_time = Time.utc(2025, 1, 1, 12, 0, 0) # Wednesday result = JosieHealth::Utils::Recurrence.next_trigger("wednesday", base_time) expected = Time.utc(2025, 1, 8, 12, 0, 0) # Next Wednesday result.should eq(expected.to_unix) end it "returns current time for invalid pattern" do base_time = Time.utc(2025, 1, 1, 12, 0, 0) result = JosieHealth::Utils::Recurrence.next_trigger("invalid", base_time) result.should eq(base_time.to_unix) end it "uses Time.utc as default" do result = JosieHealth::Utils::Recurrence.next_trigger("1h") result.should be > Time.utc.to_unix end end describe ".format_compact" do it "formats weeks" do JosieHealth::Utils::Recurrence.format_compact(604800).should eq("1w") end it "formats days" do JosieHealth::Utils::Recurrence.format_compact(86400).should eq("1d") end it "formats hours" do JosieHealth::Utils::Recurrence.format_compact(3600).should eq("1h") end it "formats minutes" do JosieHealth::Utils::Recurrence.format_compact(60).should eq("1m") end it "formats seconds only" do JosieHealth::Utils::Recurrence.format_compact(45).should eq("45s") end it "formats combined (1d12h)" do JosieHealth::Utils::Recurrence.format_compact(129600).should eq("1d12h") end it "formats complex combined (1w2d3h30m)" do JosieHealth::Utils::Recurrence.format_compact(790200).should eq("1w2d3h30m") end end describe ".format_human" do it "formats single week" do JosieHealth::Utils::Recurrence.format_human(604800).should eq("1 week") end it "formats multiple weeks" do JosieHealth::Utils::Recurrence.format_human(1209600).should eq("2 weeks") end it "formats single day" do JosieHealth::Utils::Recurrence.format_human(86400).should eq("1 day") end it "formats multiple days" do JosieHealth::Utils::Recurrence.format_human(172800).should eq("2 days") end it "formats single hour" do JosieHealth::Utils::Recurrence.format_human(3600).should eq("1 hour") end it "formats combined (1 day, 1 hour, 1 minute)" do JosieHealth::Utils::Recurrence.format_human(90060).should eq("1 day, 1 hour, 1 minute") end it "formats seconds when only seconds" do JosieHealth::Utils::Recurrence.format_human(45).should eq("45 seconds") end it "formats single second" do JosieHealth::Utils::Recurrence.format_human(1).should eq("1 second") end end describe ".format" do it "formats interval patterns compactly" do JosieHealth::Utils::Recurrence.format("1h30m").should eq("1h30m") end it "capitalizes day names" do JosieHealth::Utils::Recurrence.format("monday").should eq("Monday") end it "capitalizes uppercase day names" do JosieHealth::Utils::Recurrence.format("FRIDAY").should eq("Friday") end it "returns invalid pattern as-is" do JosieHealth::Utils::Recurrence.format("invalid").should eq("invalid") end end end