Skip to content

test(time): expand is_rfc3339_datetime coverage for the separator, length, and leap-second date rule#2686

Merged
jviotti merged 1 commit into
sourcemeta:mainfrom
vtushar06:test-datetime-coverage
Jul 26, 2026
Merged

test(time): expand is_rfc3339_datetime coverage for the separator, length, and leap-second date rule#2686
jviotti merged 1 commit into
sourcemeta:mainfrom
vtushar06:test-datetime-coverage

Conversation

@vtushar06

@vtushar06 vtushar06 commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

I added 100 tests to test/time/rfc3339_datetime_test.cc. Core already passes all of them, so this is coverage, not a fix.

is_rfc3339_datetime delegates the two halves to is_rfc3339_fulldate and is_rfc3339_fulltime, which have their own test files, so I kept these focused on what only exists at this level: the length guard, the T separator, and the date-aware leap-second rule.

What is new

  • length guard (size < 20) - every length from 0 to 19, plus the 20-character minimum.
  • the T separator - t accepted, and 11 wrong characters rejected individually (space, underscore, hyphen, slash, colon, tab, newline, a digit, Z, NUL, pipe), plus a doubled TT and the no-separator form that shifts the time half left.
  • the seam into each half - a handful of representative rejects from the date side (month 13/00, day 32/00, non-leap Feb 29, one-digit month, a sign prefix) and the time side (hour 24, minute 60, second 61, missing offset, colonless offset, empty secfrac), so a regression in the delegation itself is visible here and not only in the halves' own files.
  • the date-aware leap-second rule, which is the part neither half can check. Section 5.7 puts second 60 at the end of a month in which a leap second occurs - June 30 or December 31 - and shifts that point by the zone offset, so the offset can roll the UTC date across a day boundary. Covered: June 30 and December 31 in UTC (valid); January 31, March 31, September 30, June 29, December 30 and mid-month (invalid); an offset that rolls the UTC instant back into June 30 or December 31 from the following day (valid); an offset that rolls it off a month end (invalid); the maximum ±23:59 offsets; a leap second at a UTC time that is not 23:59; February 29 in a leap year; and the year 0001 and 9999 boundaries.
  • long-fraction reads - second 60 is read from value[17..18] before the offset is located, so there are cases with a 40-digit fraction on both the leap and non-leap paths to pin that the read is not confused by fraction length.
  • terminators - LF, CR, CRLF, TAB, space, NUL, a trailing letter, NBSP and a BOM, leading and trailing.

A note on the leap-second reading

These lock in Core's current behaviour, which enforces the June-30 / December-31 month end. That reading is not universal - other implementations treat second 60 as shape-only (any date), and a third group checks a historical leap-second table. The test-suite side of that question is open, so I have deliberately written these as regression tests for what Core does today rather than as a claim about what the spec requires. If you would rather this file not pin that behaviour yet, say so and I will drop the month-end cases and keep the rest.

How I checked the expected values

Every input was run through the real is_rfc3339_datetime, compiled from this branch's source together with its two dependencies, and the EXPECT_TRUE / EXPECT_FALSE was emitted from what the function actually returned - then the whole file was compiled and run again. sourcemeta_core_time_unit reports 528 passed, 0 failed. clang-format is clean and the diff is additions only.

Inputs with an embedded NUL are emitted as std::string_view("...", N) so they are not truncated, and the literal is split where a \x00 escape would otherwise swallow a following hex digit.

RFC references

…ngth, and leap-second date rule

Signed-off-by: Tushar Verma <tusharmyself06@gmail.com>
Copilot AI review requested due to automatic review settings July 25, 2026 18:10

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@augmentcode

augmentcode Bot commented Jul 25, 2026

Copy link
Copy Markdown
🤖 Augment PR Summary

Summary: This PR expands unit test coverage for sourcemeta::core::is_rfc3339_datetime without changing implementation behavior.

Changes:

  • Adds exhaustive “too short” cases for the function’s minimum-length guard (covering lengths below the 20-character minimum and a representative valid minimum case).
  • Adds focused validation around the required date/time separator (accepting lowercase t and rejecting a variety of incorrect single-character separators and malformed forms like doubled TT / missing separator).
  • Adds representative “seam” cases to ensure delegation into is_rfc3339_fulldate / is_rfc3339_fulltime remains visible at the datetime level.
  • Greatly expands coverage of the date-aware leap-second rule (month-end constraint + zone-offset shifting across day/month boundaries).
  • Adds long-fraction cases to pin leap-second detection before offset parsing and ensure long secfrac doesn’t alter the decision path.
  • Adds terminator/whitespace and non-ASCII input cases (embedded NUL via std::string_view, BOM, NBSP-like bytes, fullwidth separator, Unicode minus).

Technical Notes: These tests are explicitly written as regression coverage for Core’s current interpretation of RFC 3339 leap-second handling (month-end enforcement) and do not claim to resolve the broader spec-interpretation debate.

🤖 Was this summary useful? React with 👍 or 👎

@augmentcode augmentcode Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. No suggestions at this time.

Comment augment review to trigger a new review at any time.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="test/time/rfc3339_datetime_test.cc">

<violation number="1" location="test/time/rfc3339_datetime_test.cc:546">
P3: The test name `leap_offset_lands_on_june_30_from_july` is misleading and does not describe what the test actually verifies.

The test input is `"2016-07-01T00:59:60+00:30"`. Tracing through the implementation:
- In `is_rfc3339_fulltime`, the UTC time-of-day after offset = 00:59:60 − 00:30 = 00:29:60, which is **not** 23:59:60, so `is_rfc3339_fulltime` returns false immediately — the leap-second time-side check rejects it before any date adjustment occurs.
- The UTC date actually stays on July 1 (no day rollback: local 59 min ≥ offset 30 min), so the scenario described by the name ("lands on June 30 from July") does not happen.

The test assertion (`EXPECT_FALSE`) is **correct** — the string is indeed invalid. But the name suggests the opposite scenario (a July 1 → June 30 UTC date roll), which would be a *valid* leap-second case. Consider renaming to something like `leap_not_at_2359_utc_with_offset` to match the actual behaviour, or change the input to `"2016-07-01T00:29:60+00:30"` if the intent was to test a valid June-30-from-July rollover (which would then expect `TRUE`).</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

sourcemeta::core::is_rfc3339_datetime("2016-06-30T23:59:60-01:00"));
}

TEST(leap_offset_lands_on_june_30_from_july) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The test name leap_offset_lands_on_june_30_from_july is misleading and does not describe what the test actually verifies.

The test input is "2016-07-01T00:59:60+00:30". Tracing through the implementation:

  • In is_rfc3339_fulltime, the UTC time-of-day after offset = 00:59:60 − 00:30 = 00:29:60, which is not 23:59:60, so is_rfc3339_fulltime returns false immediately — the leap-second time-side check rejects it before any date adjustment occurs.
  • The UTC date actually stays on July 1 (no day rollback: local 59 min ≥ offset 30 min), so the scenario described by the name ("lands on June 30 from July") does not happen.

The test assertion (EXPECT_FALSE) is correct — the string is indeed invalid. But the name suggests the opposite scenario (a July 1 → June 30 UTC date roll), which would be a valid leap-second case. Consider renaming to something like leap_not_at_2359_utc_with_offset to match the actual behaviour, or change the input to "2016-07-01T00:29:60+00:30" if the intent was to test a valid June-30-from-July rollover (which would then expect TRUE).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At test/time/rfc3339_datetime_test.cc, line 546:

<comment>The test name `leap_offset_lands_on_june_30_from_july` is misleading and does not describe what the test actually verifies.

The test input is `"2016-07-01T00:59:60+00:30"`. Tracing through the implementation:
- In `is_rfc3339_fulltime`, the UTC time-of-day after offset = 00:59:60 − 00:30 = 00:29:60, which is **not** 23:59:60, so `is_rfc3339_fulltime` returns false immediately — the leap-second time-side check rejects it before any date adjustment occurs.
- The UTC date actually stays on July 1 (no day rollback: local 59 min ≥ offset 30 min), so the scenario described by the name ("lands on June 30 from July") does not happen.

The test assertion (`EXPECT_FALSE`) is **correct** — the string is indeed invalid. But the name suggests the opposite scenario (a July 1 → June 30 UTC date roll), which would be a *valid* leap-second case. Consider renaming to something like `leap_not_at_2359_utc_with_offset` to match the actual behaviour, or change the input to `"2016-07-01T00:29:60+00:30"` if the intent was to test a valid June-30-from-July rollover (which would then expect `TRUE`).</comment>

<file context>
@@ -253,3 +253,440 @@ TEST(invalid_leap_second_year_zero_jan_1_underflow) {
+      sourcemeta::core::is_rfc3339_datetime("2016-06-30T23:59:60-01:00"));
+}
+
+TEST(leap_offset_lands_on_june_30_from_july) {
+  EXPECT_FALSE(
+      sourcemeta::core::is_rfc3339_datetime("2016-07-01T00:59:60+00:30"));
</file context>

@jviotti
jviotti merged commit 559550e into sourcemeta:main Jul 26, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants