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();
}