Skip to content

Add round-trip and leap-year coverage tests for DateTimeConverter (pre/post 1970)#135

Open
Rutuja-Patil-Bosch wants to merge 27 commits into
eclipse-score:mainfrom
bgsw-contrib:main
Open

Add round-trip and leap-year coverage tests for DateTimeConverter (pre/post 1970)#135
Rutuja-Patil-Bosch wants to merge 27 commits into
eclipse-score:mainfrom
bgsw-contrib:main

Conversation

@Rutuja-Patil-Bosch
Copy link
Copy Markdown
Contributor

@Rutuja-Patil-Bosch Rutuja-Patil-Bosch commented Apr 1, 2026

Summary

This PR extends unit test coverage for DateTimeConverter by adding round-trip validation and additional leap-year scenarios, especially around pre-1970 and post-1970 boundaries.

Changes

  • Added round-trip test validation:
    • epoch → DateTime → epoch consistency checks
  • Added test coverage for:
    • Pre-1970 leap year (1968)
    • Post-1970 leap year (1972)
  • Included full month/day sweeps to validate:
    • Leap day handling (Feb 29)
    • Month boundary correctness
    • Internal day-sum adjustments

Motivation

The added tests ensure correctness of:

  • Leap year handling logic
  • Edge cases around Unix epoch (1970)
  • Internal date-to-epoch conversion consistency

This improves confidence in DateTimeConverter for:

  • Historical timestamps (pre-1970)
  • Leap year transitions
  • Boundary conditions in conversion logic

Notes

  • Invalid dates are skipped during iteration
  • Focus is on ensuring no regression in conversion logic
  • No production code changes included

Test Scope

  • Covers both:
    • 'dateTimeToEpoch'
    • 'epochToDateTime'
  • Validates bidirectional consistency

Impact

  • Increased unit test coverage
  • Better validation of edge cases and leap-year logic
  • No impact on runtime behavior

Rutuja-Patil-Bosch and others added 3 commits March 24, 2026 14:04
…lse_isValidDateTimeFormat EpochToDateTime_Before1970_LeapYear_January_AdjustsDaysSum invalid_day_values invalid_month_values
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 1, 2026

The created documentation from the pull request is available at: docu-html

Comment thread score/datetime_converter/datetime_converter_test.cpp Outdated
Comment thread score/datetime_converter/datetime_converter_test.cpp Outdated
Comment thread score/datetime_converter/datetime_converter_test.cpp Outdated
Comment thread score/datetime_converter/datetime_converter_test.cpp Outdated
Comment thread score/datetime_converter/datetime_converter_test.cpp Outdated
Comment thread score/datetime_converter/datetime_converter_test.cpp Outdated
Comment thread score/datetime_converter/datetime_converter_test.cpp Outdated
Comment thread score/datetime_converter/datetime_converter_test.cpp Outdated
Comment thread score/datetime_converter/datetime_converter_test.cpp Outdated
@bgsw-contrib bgsw-contrib Bot had a problem deploying to workflow-approval April 8, 2026 00:23 Failure
@bgsw-contrib bgsw-contrib Bot had a problem deploying to workflow-approval April 8, 2026 00:23 Failure
@AlexanderLanin
Copy link
Copy Markdown
Member

@Rutuja-Patil-Bosch please avoid bot based commits. Feel free to contact me directly.

@bgsw-contrib bgsw-contrib Bot had a problem deploying to workflow-approval April 9, 2026 00:19 Failure
@bgsw-contrib bgsw-contrib Bot had a problem deploying to workflow-approval April 9, 2026 00:19 Failure
@4og 4og mentioned this pull request Apr 9, 2026
@bgsw-contrib bgsw-contrib Bot temporarily deployed to workflow-approval April 10, 2026 00:22 Inactive
@bgsw-contrib bgsw-contrib Bot temporarily deployed to workflow-approval April 10, 2026 00:22 Inactive
@bgsw-contrib bgsw-contrib Bot requested a deployment to workflow-approval May 9, 2026 00:33 Waiting
Review findings are fixed for eclipse-score#135
Changes are:
1. Test cases are spitted to get more clarity with asserts
2. Instead of loop added hardcoded values to avoid dead/unreachable code
3. RecordProperty are updated with only spec listed variables
@bgsw-contrib bgsw-contrib Bot temporarily deployed to workflow-approval May 12, 2026 00:32 Inactive
@bgsw-contrib bgsw-contrib Bot temporarily deployed to workflow-approval May 12, 2026 00:32 Inactive
@bgsw-contrib bgsw-contrib Bot temporarily deployed to workflow-approval May 14, 2026 00:36 Inactive
@bgsw-contrib bgsw-contrib Bot temporarily deployed to workflow-approval May 14, 2026 00:36 Inactive
@4og
Copy link
Copy Markdown
Member

4og commented May 15, 2026

@gierer, please have a look at this PR

@4og 4og added the comp-datetime Related to score/datetime_converter component label May 15, 2026
@bgsw-contrib bgsw-contrib Bot requested a deployment to workflow-approval May 16, 2026 00:32 Waiting
@bgsw-contrib bgsw-contrib Bot requested a deployment to workflow-approval May 16, 2026 00:32 Waiting
return;
auto dateTimeConverted = score::common::epochToDateTime(epoch);
ASSERT_NE(dateTimeConverted, nullptr);
ASSERT_EQ(dateTimeConverted->m_year, 1968);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Please check all values. Something like "ASSERT_EQ(dateTimeConverted, dateTimeOriginal );

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@gierer For this, std::make_shared(1968, 12, 31, 0, 0, 1);
then for day check this will be ASSERT_EQ(dateTimeConverted->m_day, 30);

Reason: Expected by current algorithm: pre-1970 leap-year path decrements daysSum once.

I'll add for checks for all values

auto dateTimeConverted = score::common::epochToDateTime(epoch);
ASSERT_NE(dateTimeConverted, nullptr);
//After 1970 year is adjusted based on daysome
ASSERT_EQ(dateTimeConverted->m_year, 1973);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why is this no longer 1972?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@gierer This verifies existing implementation behavior (not roundtrip preservation : the value may change after converting to epoch and back and this test accepts/document that current behavior.).
For input 1972-12-31 00:00:01, epochToDateTime() currently returns year 1973.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The conversion should be either correct or return an error.
A test is meant to verify correct behaviour of the code. So if the code has a bug it needs to be fixed, instead of breaking the test as well. Code coverage gained through incorrect assertions has zero value — it doesn't verify correctness and creates a false sense of quality.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@gierer : Should I update code in the same PR? or different PR is required ?

RecordProperty("TestType", "requirements-based");

time_t epoch{};
auto d = std::make_shared<DateTimeType>(1968, 1, 1, 0, 0, 1);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Please use proper variable names.

ASSERT_TRUE(score::common::dateTimeToEpoch(d, &epoch));

auto dt = score::common::epochToDateTime(epoch);
//InvalidDateTimeFormat due to day some adjustment & returns nullptr
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why is this no longer valid? Is this a bug in the implementation?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@gierer This may indicate a converter defect.
This test documents current implementation behavior (known pre-1970 leap-year boundary issue), not roundtrip correctness.
For 1968-01-01 00:00:01, epochToDateTime() currently returns nullptr after daysSum adjustments in the pre-1970 leap-year path.

Comment on lines +506 to +507
if (!score::common::dateTimeToEpoch(dateTimeOriginal, &epoch))
return;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
if (!score::common::dateTimeToEpoch(dateTimeOriginal, &epoch))
return;
ASSERT_TRUE(score::common::dateTimeToEpoch(dateTimeOriginal, &epoch))

@bgsw-contrib bgsw-contrib Bot deployed to workflow-approval May 22, 2026 00:37 Active
@bgsw-contrib bgsw-contrib Bot temporarily deployed to workflow-approval May 22, 2026 00:37 Inactive
@4og 4og requested review from Copilot and removed request for LittleHuba, castler, hoe-jo, nradakovic and ramceb May 22, 2026 20:31
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds additional unit tests for score::common::DateTimeConverter to increase coverage around invalid date inputs and leap-year / pre-/post-1970 conversion edge cases.

Changes:

  • Added tests for invalid month/day values in isValidDateTimeFormat.
  • Added a test ensuring dateTimeToEpoch returns false and does not mutate the output epoch when the input is invalid.
  • Added a few DateTime→epoch→DateTime “round-trip” tests targeting 1968 and 1972 leap-year boundaries.
Comments suppressed due to low confidence (3)

score/datetime_converter/datetime_converter_test.cpp:526

  • Same issue here: the test returns early if dateTimeToEpoch fails, which makes the test pass without validating anything. Use an assertion so failures are visible and the remainder of the test always executes when appropriate.
    time_t epoch{};
    auto dateTimeOriginal =
        std::make_shared<DateTimeType>(1972, 12, 31, 0, 0, 1);
		
    if (!score::common::dateTimeToEpoch(dateTimeOriginal, &epoch))
        return;
		
    auto dateTimeConverted = score::common::epochToDateTime(epoch);

score/datetime_converter/datetime_converter_test.cpp:530

  • The assertion expects the year to change from 1972 to 1973 after a DateTime→epoch→DateTime round-trip, which contradicts the test description (“remain unchanged”) and will lock in incorrect behavior. The round-trip expectation should match the original datetime fields.
    auto dateTimeConverted = score::common::epochToDateTime(epoch);
    ASSERT_NE(dateTimeConverted, nullptr);
	//After  1970 year is adjusted based on daysome
    ASSERT_EQ(dateTimeConverted->m_year, 1973); 
    

score/datetime_converter/datetime_converter_test.cpp:546

  • This test expects epochToDateTime to return nullptr for a valid date (1968-01-01) even though dateTimeToEpoch succeeded, which would encode a conversion bug rather than catch it. If this is intended behavior, it should be documented at the API level; otherwise the test should assert that the round-trip returns a valid DateTime equal to the input.
    RecordProperty("Description",
        "Verify that conversion from DateTime to Epoch to DateTime for pre-1970 leap year boundary (1968-01-01) results in an invalid DateTime, returning nullptr due to daysSum adjustment.");
    RecordProperty("TestType", "requirements-based");
	
    time_t epoch{};
    auto d = std::make_shared<DateTimeType>(1968, 1, 1, 0, 0, 1);
    ASSERT_TRUE(score::common::dateTimeToEpoch(d, &epoch));
	
    auto dt = score::common::epochToDateTime(epoch);
	//InvalidDateTimeFormat due to day some adjustment & returns nullptr
    EXPECT_EQ(dt, nullptr);
}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +503 to +508
time_t epoch{};
auto dateTimeOriginal =
std::make_shared<DateTimeType>(1968, 12, 31, 0, 0, 1);
if (!score::common::dateTimeToEpoch(dateTimeOriginal, &epoch))
return;
auto dateTimeConverted = score::common::epochToDateTime(epoch);
Comment on lines +504 to +511
auto dateTimeOriginal =
std::make_shared<DateTimeType>(1968, 12, 31, 0, 0, 1);
if (!score::common::dateTimeToEpoch(dateTimeOriginal, &epoch))
return;
auto dateTimeConverted = score::common::epochToDateTime(epoch);
ASSERT_NE(dateTimeConverted, nullptr);
ASSERT_EQ(dateTimeConverted->m_year, 1968);
}
Comment on lines +528 to +545
//After 1970 year is adjusted based on daysome
ASSERT_EQ(dateTimeConverted->m_year, 1973);

}

TEST_F(DateTimeConverterTest, EpochToDateTime_Pre1970_LeapYear_Jan1_InvalidConversion_ReturnsNull)
{
RecordProperty("Description",
"Verify that conversion from DateTime to Epoch to DateTime for pre-1970 leap year boundary (1968-01-01) results in an invalid DateTime, returning nullptr due to daysSum adjustment.");
RecordProperty("TestType", "requirements-based");

time_t epoch{};
auto d = std::make_shared<DateTimeType>(1968, 1, 1, 0, 0, 1);
ASSERT_TRUE(score::common::dateTimeToEpoch(d, &epoch));

auto dt = score::common::epochToDateTime(epoch);
//InvalidDateTimeFormat due to day some adjustment & returns nullptr
EXPECT_EQ(dt, nullptr);
Comment on lines +522 to +530

if (!score::common::dateTimeToEpoch(dateTimeOriginal, &epoch))
return;

auto dateTimeConverted = score::common::epochToDateTime(epoch);
ASSERT_NE(dateTimeConverted, nullptr);
//After 1970 year is adjusted based on daysome
ASSERT_EQ(dateTimeConverted->m_year, 1973);

Comment on lines +498 to +535
TEST_F(DateTimeConverterTest, EpochToDateTime_Pre1970_LeapYear_DaysSumDecrementedInJanuary)
{
RecordProperty("Description", "Verify that datetime values remain unchanged after roundtrip conversion (DateTime to Epoch to DateTime) for pre 1970 leap years.");
RecordProperty("TestType", "requirements-based");

time_t epoch{};
auto dateTimeOriginal =
std::make_shared<DateTimeType>(1968, 12, 31, 0, 0, 1);
if (!score::common::dateTimeToEpoch(dateTimeOriginal, &epoch))
return;
auto dateTimeConverted = score::common::epochToDateTime(epoch);
ASSERT_NE(dateTimeConverted, nullptr);
ASSERT_EQ(dateTimeConverted->m_year, 1968);
}

TEST_F(DateTimeConverterTest, EpochToDateTime_Post1970_LeapYear_DaysSumDecremented)
{
RecordProperty("Description",
"Verify that datetime values remain unchanged after roundtrip conversion (DateTime to Epoch to DateTime) for post-1970 leap years.");
RecordProperty("TestType", "requirements-based");

time_t epoch{};
auto dateTimeOriginal =
std::make_shared<DateTimeType>(1972, 12, 31, 0, 0, 1);

if (!score::common::dateTimeToEpoch(dateTimeOriginal, &epoch))
return;

auto dateTimeConverted = score::common::epochToDateTime(epoch);
ASSERT_NE(dateTimeConverted, nullptr);
//After 1970 year is adjusted based on daysome
ASSERT_EQ(dateTimeConverted->m_year, 1973);

}

TEST_F(DateTimeConverterTest, EpochToDateTime_Pre1970_LeapYear_Jan1_InvalidConversion_ReturnsNull)
{
RecordProperty("Description",
Comment on lines +498 to +502
TEST_F(DateTimeConverterTest, EpochToDateTime_Pre1970_LeapYear_DaysSumDecrementedInJanuary)
{
RecordProperty("Description", "Verify that datetime values remain unchanged after roundtrip conversion (DateTime to Epoch to DateTime) for pre 1970 leap years.");
RecordProperty("TestType", "requirements-based");

@bgsw-contrib bgsw-contrib Bot requested a deployment to workflow-approval May 23, 2026 00:36 Waiting
@bgsw-contrib bgsw-contrib Bot requested a deployment to workflow-approval May 23, 2026 00:36 Waiting
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp-datetime Related to score/datetime_converter component

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

6 participants