#include #include #include "interval.h" using namespace fakeit; // Global variable to simulate time in milliseconds static uint32_t fakeMillis = 0; // Fake function to override millis() uint32_t fakeMillisFunc() { return fakeMillis; } // setUp() is called before each test void setUp(void) { // Reset fake time fakeMillis = 0; ArduinoFakeReset(); // Override millis() to use our fakeMillisFunc() When(Method(ArduinoFake(), millis)).AlwaysDo(fakeMillisFunc); } // tearDown() is called after each test (if needed) void tearDown(void) { // No teardown actions required } // Test for Compatibility Mode (using set() method) void test_CompatibilityMode(void) { Interval interval; interval.set(1000); // Set timeout to 1000ms in compatibility mode fakeMillis = 500; TEST_ASSERT_FALSE(interval.expired()); // Should not be expired at 500ms fakeMillis = 1000; TEST_ASSERT_TRUE(interval.expired()); // Should be expired at 1000ms // In compatibility mode, subsequent calls should still return true once expired TEST_ASSERT_TRUE(interval.expired()); } // Test for One-shot Mode (using setOneshot() method) void test_OneshotMode(void) { Interval interval; interval.setOneshot(1000); // Set timeout to 1000ms in oneshot mode fakeMillis = 500; TEST_ASSERT_FALSE(interval.expired()); // Not yet expired fakeMillis = 1000; TEST_ASSERT_TRUE(interval.expired()); // Expired at 1000ms // Subsequent calls should return false because oneshot mode triggers only once TEST_ASSERT_FALSE(interval.expired()); } // Test for Periodic Mode (using setPeriodic() method) void test_PeriodicMode(void) { Interval interval; interval.setPeriodic(1000); // Set periodic mode with 1000ms timeout fakeMillis = 500; TEST_ASSERT_FALSE(interval.expired()); // Not yet expired fakeMillis = 1000; TEST_ASSERT_TRUE(interval.expired()); // First period expired // After expiration, timer is reset; simulate next period fakeMillis = 1500; TEST_ASSERT_FALSE(interval.expired()); // Still within new period fakeMillis = 2000; TEST_ASSERT_TRUE(interval.expired()); // Second period expired } // Test for elapsed() and remains() functions void test_elapsed_and_remains(void) { Interval interval; interval.set(1000); // Using compatibility mode, timeout set to 1000ms fakeMillis = 0; TEST_ASSERT_EQUAL_UINT32(0, interval.elapsed()); TEST_ASSERT_EQUAL_UINT32(1000, interval.remains()); fakeMillis = 500; TEST_ASSERT_EQUAL_UINT32(500, interval.elapsed()); TEST_ASSERT_EQUAL_UINT32(500, interval.remains()); fakeMillis = 1100; TEST_ASSERT_EQUAL_UINT32(1100, interval.elapsed()); // remains() uses unsigned arithmetic, so it will underflow if elapsed > timeout TEST_ASSERT_EQUAL_UINT32(1000 - 1100, interval.remains()); } // Test for handling overflow of millis() value void test_overflow(void) { Interval interval; // Set fakeMillis to a value near the maximum of 32-bit unsigned int fakeMillis = 0xFFFFFFF0; interval.set(100); // Set timeout to 100ms in compatibility mode; _timefrom = 0xFFFFFFF0 // Simulate time just before expiration after overflow. // After overflow, fakeMillis is low. For example, fakeMillis = 0x00000050. // Expected elapsed time = 0x00000050 + (0x100000000 - 0xFFFFFFF0) = 0x50 + 0x10 = 96ms. fakeMillis = 0x00000050; TEST_ASSERT_FALSE(interval.expired()); // Not yet expired // Now simulate time after expiration: // Set fakeMillis = 0x00000070. Expected elapsed time = 0x70 + 0x10 = 128ms, which is >= 100ms. fakeMillis = 0x00000070; TEST_ASSERT_TRUE(interval.expired()); // Should be expired due to overflow handling } // Test for reload() functionality in oneshot mode void test_reload(void) { Interval interval; interval.setOneshot(1000); // Set oneshot mode with 1000ms timeout fakeMillis = 0; // Simulate expiration fakeMillis = 1100; TEST_ASSERT_TRUE(interval.expired()); // Expired at 1100ms // Reload the interval to reset the timer and reactivate oneshot mode fakeMillis = 1100; interval.reload(); // Immediately after reload, should not be expired fakeMillis = 1200; TEST_ASSERT_FALSE(interval.expired()); // After passing the timeout from reload, it should expire again fakeMillis = 2200; TEST_ASSERT_TRUE(interval.expired()); } int main(int argc, char **argv) { UNITY_BEGIN(); RUN_TEST(test_CompatibilityMode); RUN_TEST(test_OneshotMode); RUN_TEST(test_PeriodicMode); RUN_TEST(test_elapsed_and_remains); RUN_TEST(test_overflow); RUN_TEST(test_reload); return UNITY_END(); }