149 lines
4.6 KiB
C++
149 lines
4.6 KiB
C++
#include <ArduinoFake.h>
|
|
#include <unity.h>
|
|
#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();
|
|
}
|