require "./spec_helper" describe JosieHealth::Utils::Timestamp do describe ".parse_ago" do it "parses HHMM format (0130 = 1h30m ago)" do result = JosieHealth::Utils::Timestamp.parse_ago("0130") result.should_not be_nil diff = Time.utc - result.not_nil! diff.total_minutes.should be_close(90, 1) end it "parses HMM format (230 = 2h30m ago)" do result = JosieHealth::Utils::Timestamp.parse_ago("230") result.should_not be_nil diff = Time.utc - result.not_nil! diff.total_minutes.should be_close(150, 1) end it "parses MM format (30 = 30m ago)" do result = JosieHealth::Utils::Timestamp.parse_ago("30") result.should_not be_nil diff = Time.utc - result.not_nil! diff.total_minutes.should be_close(30, 1) end it "parses 0000 as current time" do result = JosieHealth::Utils::Timestamp.parse_ago("0000") result.should_not be_nil diff = Time.utc - result.not_nil! diff.total_seconds.should be_close(0, 2) end it "returns nil for invalid hours (25)" do JosieHealth::Utils::Timestamp.parse_ago("2530").should be_nil end it "returns nil for invalid minutes (99)" do JosieHealth::Utils::Timestamp.parse_ago("1299").should be_nil end it "returns nil for non-numeric input" do JosieHealth::Utils::Timestamp.parse_ago("abc").should be_nil end end describe ".parse_ago_rfc3339" do it "returns RFC3339 formatted string" do result = JosieHealth::Utils::Timestamp.parse_ago_rfc3339("0100") result.should match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/) end it "returns current time for invalid input" do result = JosieHealth::Utils::Timestamp.parse_ago_rfc3339("invalid") time = Time.parse_rfc3339(result) diff = Time.utc - time diff.total_seconds.abs.should be < 2 end end describe ".parse_timestamp" do it "parses full ISO format with seconds" do result = JosieHealth::Utils::Timestamp.parse_timestamp("2025-01-15T14:30:45") result.should_not be_nil time = Time.parse_rfc3339(result.not_nil!) time.year.should eq(2025) time.month.should eq(1) time.day.should eq(15) time.hour.should eq(14) time.minute.should eq(30) time.second.should eq(45) end it "parses full ISO format without seconds" do result = JosieHealth::Utils::Timestamp.parse_timestamp("2025-01-15T14:30") result.should_not be_nil time = Time.parse_rfc3339(result.not_nil!) time.hour.should eq(14) time.minute.should eq(30) time.second.should eq(0) end it "parses HH:MM format (today)" do result = JosieHealth::Utils::Timestamp.parse_timestamp("14:30") result.should_not be_nil time = Time.parse_rfc3339(result.not_nil!) now = Time.utc time.year.should eq(now.year) time.month.should eq(now.month) time.day.should eq(now.day) time.hour.should eq(14) time.minute.should eq(30) end it "parses H:MM format (today)" do result = JosieHealth::Utils::Timestamp.parse_timestamp("9:30") result.should_not be_nil time = Time.parse_rfc3339(result.not_nil!) time.hour.should eq(9) time.minute.should eq(30) end it "parses HHMM format (today)" do result = JosieHealth::Utils::Timestamp.parse_timestamp("1430") result.should_not be_nil time = Time.parse_rfc3339(result.not_nil!) time.hour.should eq(14) time.minute.should eq(30) end it "returns nil for invalid hour" do JosieHealth::Utils::Timestamp.parse_timestamp("25:30").should be_nil end it "returns nil for invalid minute" do JosieHealth::Utils::Timestamp.parse_timestamp("14:99").should be_nil end it "returns nil for invalid format" do JosieHealth::Utils::Timestamp.parse_timestamp("not-a-time").should be_nil end end describe ".format_display" do it "shows time only for today's timestamps" do now = Time.utc today = Time.utc(now.year, now.month, now.day, 14, 30, 0).to_rfc3339 result = JosieHealth::Utils::Timestamp.format_display(today) result.should eq("14:30") end it "shows full date for past timestamps" do past = Time.utc(2024, 6, 15, 14, 30, 0).to_rfc3339 result = JosieHealth::Utils::Timestamp.format_display(past) result.should eq("2024-06-15 14:30") end it "returns input on parse error" do result = JosieHealth::Utils::Timestamp.format_display("invalid") result.should eq("invalid") end end describe ".now_rfc3339" do it "returns valid RFC3339 timestamp" do result = JosieHealth::Utils::Timestamp.now_rfc3339 result.should match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/) time = Time.parse_rfc3339(result) diff = Time.utc - time diff.total_seconds.abs.should be < 2 end end end