From abb55213af141607133d3b200d2b79eb551edd3a Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Fri, 26 Sep 2025 09:09:24 -0500 Subject: [PATCH 01/18] Verbose ctest --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a283e22..5cd44e2 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ build: cmake .PHONY: test test: - @cd $(CURDIR)/build && CTEST_OUTPUT_ON_FAILURE=TRUE make test + @cd $(CURDIR)/build && ctest --verbose .PHONY: pio-test pio-test: From 77af8d9d5d6bfe0c0b1373e11873a8a96bf40a6c Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Mon, 29 Sep 2025 13:51:44 -0500 Subject: [PATCH 02/18] test/main.cpp should return the number of failing tests. --- test/main.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/main.cpp b/test/main.cpp index a308066..8163209 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -46,9 +46,7 @@ int main(int argc, char **argv) RUN_TEST_GROUP(ClientTest); RUN_TEST_GROUP(IncludeTest); - UNITY_END(); - - return 0; + return UNITY_END(); } #endif From a3dfa88e2db6de6cbb62e9e133c918bd02740709 Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Wed, 8 Oct 2025 08:07:02 -0500 Subject: [PATCH 03/18] Prevent race condition(s) - statically allocate ArduinoFakeContext --- src/ArduinoFake.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/ArduinoFake.cpp b/src/ArduinoFake.cpp index 8678cbd..1b7be17 100644 --- a/src/ArduinoFake.cpp +++ b/src/ArduinoFake.cpp @@ -1,12 +1,7 @@ #include "ArduinoFake.h" -ArduinoFakeContext* arduinoFakeContext; - ArduinoFakeContext* getArduinoFakeContext() { - if (!arduinoFakeContext) { - arduinoFakeContext = new ArduinoFakeContext(); - } - - return arduinoFakeContext; + static ArduinoFakeContext arduinoFakeContext; + return &arduinoFakeContext; } From d1ba3bb22f9e9bfae7d5ae7fe44172c47c25d55b Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Wed, 8 Oct 2025 08:08:39 -0500 Subject: [PATCH 04/18] Simplify: allocate ArduinoFakeMocks as part of ArduinoFakeContext instead of on the heap. --- src/ArduinoFake.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ArduinoFake.h b/src/ArduinoFake.h index 7eaa22b..7c4b4d7 100644 --- a/src/ArduinoFake.h +++ b/src/ArduinoFake.h @@ -34,7 +34,7 @@ new mock##FakeProxy(ArduinoFakeInstance(mock)) #define _ArduinoFakeGetMock(mock) \ - getArduinoFakeContext()->Mocks->mock + getArduinoFakeContext()->Mocks.mock #define _ArduinoFakeGetFunction() _ArduinoFakeGetMock(Function) #define _ArduinoFakeGetSerial() _ArduinoFakeGetMock(Serial) @@ -50,7 +50,7 @@ mock##Fake* mock() \ { \ if (!this->Instances->mock){ \ - this->Instances->mock = &this->Mocks->mock.get(); \ + this->Instances->mock = &this->Mocks.mock.get(); \ } \ return this->Instances->mock; \ } @@ -95,7 +95,7 @@ class ArduinoFakeContext { public: ArduinoFakeInstances* Instances = new ArduinoFakeInstances(); - ArduinoFakeMocks* Mocks = new ArduinoFakeMocks(); + ArduinoFakeMocks Mocks; std::unordered_map Mapping; _ArduinoFakeInstanceGetter1(Print) @@ -127,14 +127,14 @@ class ArduinoFakeContext } this->Instances = new ArduinoFakeInstances(); - this->Mocks->Function.Reset(); - this->Mocks->Stream.Reset(); - this->Mocks->Serial.Reset(); - this->Mocks->Wire.Reset(); - this->Mocks->Client.Reset(); - this->Mocks->Print.Reset(); - this->Mocks->SPI.Reset(); - this->Mocks->EEPROM.Reset(); + this->Mocks.Function.Reset(); + this->Mocks.Stream.Reset(); + this->Mocks.Serial.Reset(); + this->Mocks.Wire.Reset(); + this->Mocks.Client.Reset(); + this->Mocks.Print.Reset(); + this->Mocks.SPI.Reset(); + this->Mocks.EEPROM.Reset(); Mapping[&::Serial] = this->Serial(); Mapping[&::Wire] = this->Wire(); From dc8ea6ec3918e6e92e16954210c5c8fe5b235a33 Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Wed, 8 Oct 2025 08:12:46 -0500 Subject: [PATCH 05/18] ArduinoFakeContext::reset() should clear the mapping. --- src/ArduinoFake.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ArduinoFake.h b/src/ArduinoFake.h index 7c4b4d7..79b0db5 100644 --- a/src/ArduinoFake.h +++ b/src/ArduinoFake.h @@ -136,6 +136,7 @@ class ArduinoFakeContext this->Mocks.SPI.Reset(); this->Mocks.EEPROM.Reset(); + Mapping.clear(); Mapping[&::Serial] = this->Serial(); Mapping[&::Wire] = this->Wire(); Mapping[&::SPI] = this->SPI(); From 9339832454a078bc4439764a357834ebc2fa303e Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Wed, 8 Oct 2025 08:15:39 -0500 Subject: [PATCH 06/18] Move mock reset to ArduinoFakeMocks --- src/ArduinoFake.h | 21 ++++++++++++------- test/main.cpp | 2 ++ test/test_ArduinoFake_t.h | 44 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 test/test_ArduinoFake_t.h diff --git a/src/ArduinoFake.h b/src/ArduinoFake.h index 79b0db5..2afb14d 100644 --- a/src/ArduinoFake.h +++ b/src/ArduinoFake.h @@ -77,6 +77,18 @@ struct ArduinoFakeMocks fakeit::Mock Print; fakeit::Mock SPI; fakeit::Mock EEPROM; + + void reset(void) + { + Function.Reset(); + Stream.Reset(); + Serial.Reset(); + Wire.Reset(); + Client.Reset(); + Print.Reset(); + SPI.Reset(); + EEPROM.Reset(); + } }; struct ArduinoFakeInstances @@ -127,14 +139,7 @@ class ArduinoFakeContext } this->Instances = new ArduinoFakeInstances(); - this->Mocks.Function.Reset(); - this->Mocks.Stream.Reset(); - this->Mocks.Serial.Reset(); - this->Mocks.Wire.Reset(); - this->Mocks.Client.Reset(); - this->Mocks.Print.Reset(); - this->Mocks.SPI.Reset(); - this->Mocks.EEPROM.Reset(); + this->Mocks.reset(); Mapping.clear(); Mapping[&::Serial] = this->Serial(); diff --git a/test/main.cpp b/test/main.cpp index 8163209..4bc8ebc 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -16,6 +16,7 @@ using namespace fakeit; #include "test_client.h" #include "test_arduino_string.h" #include "test_include.h" +#include "test_ArduinoFake_t.h" #ifdef UNIT_TEST @@ -45,6 +46,7 @@ int main(int argc, char **argv) RUN_TEST_GROUP(EEPROMTest); RUN_TEST_GROUP(ClientTest); RUN_TEST_GROUP(IncludeTest); + RUN_TEST_GROUP(ArduinoFakeTTest); return UNITY_END(); } diff --git a/test/test_ArduinoFake_t.h b/test/test_ArduinoFake_t.h new file mode 100644 index 0000000..6f91969 --- /dev/null +++ b/test/test_ArduinoFake_t.h @@ -0,0 +1,44 @@ +#ifdef UNIT_TEST + +namespace ArduinoFakeTTest +{ + struct IDummy + { + virtual long dummyMethod(void) = 0; + }; + + void test_reset(void) + { + ArduinoFake_t arduinoFake; + + auto method = Method(arduinoFake.Fake, dummyMethod); + When(method).AlwaysReturn(101L); + + Verify(method).Never(); + + // Call the "real" method... + arduinoFake.getFake()->dummyMethod(); + // ...which should call the faked method + Verify(method).Once(); + + // Reset + arduinoFake.reset(); + + try { + // This should throw an exception... + arduinoFake.getFake()->dummyMethod(); + // ...fail the test if not. + TEST_FAIL(); + } + catch (fakeit::FakeitException &e) { + Verify(method).Never(); + } + } + + void run_tests(void) + { + RUN_TEST(ArduinoFakeTTest::test_reset); + } +} + +#endif \ No newline at end of file From bde43680ebbda3f969578c8c87078372ce2f75a1 Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Wed, 8 Oct 2025 09:38:00 -0500 Subject: [PATCH 07/18] Simplify: allocate ArduinoFakeInstances as part of ArduinoFakeContext instead of on the heap. --- src/ArduinoFake.h | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/ArduinoFake.h b/src/ArduinoFake.h index 2afb14d..0862f20 100644 --- a/src/ArduinoFake.h +++ b/src/ArduinoFake.h @@ -49,10 +49,10 @@ #define _ArduinoFakeInstanceGetter1(mock) \ mock##Fake* mock() \ { \ - if (!this->Instances->mock){ \ - this->Instances->mock = &this->Mocks.mock.get(); \ + if (!this->Instances.mock){ \ + this->Instances.mock = &this->Mocks.mock.get(); \ } \ - return this->Instances->mock; \ + return this->Instances.mock; \ } #define _ArduinoFakeInstanceGetter2(name, clazz) \ @@ -101,12 +101,29 @@ struct ArduinoFakeInstances PrintFake* Print; SPIFake* SPI; EEPROMFake* EEPROM; + + ArduinoFakeInstances() + { + reset(); + } + + void reset(void) + { + Function = nullptr; + Serial = nullptr; + Wire = nullptr; + Stream = nullptr; + Client = nullptr; + Print = nullptr; + SPI = nullptr; + EEPROM = nullptr; + } }; class ArduinoFakeContext { public: - ArduinoFakeInstances* Instances = new ArduinoFakeInstances(); + ArduinoFakeInstances Instances; ArduinoFakeMocks Mocks; std::unordered_map Mapping; @@ -134,11 +151,7 @@ class ArduinoFakeContext void reset(void) { - if (this->Instances) { - delete this->Instances; - } - this->Instances = new ArduinoFakeInstances(); - + this->Instances.reset(); this->Mocks.reset(); Mapping.clear(); From 4a0fefde977621210fd4215cb4855d9c006976b2 Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Wed, 8 Oct 2025 11:29:08 -0500 Subject: [PATCH 08/18] Bind the fake & instance together into ArduinoFake_t struct. --- src/ArduinoFake.h | 81 ++++++++++++++++------------------------------- 1 file changed, 27 insertions(+), 54 deletions(-) diff --git a/src/ArduinoFake.h b/src/ArduinoFake.h index 0862f20..09781f7 100644 --- a/src/ArduinoFake.h +++ b/src/ArduinoFake.h @@ -34,7 +34,7 @@ new mock##FakeProxy(ArduinoFakeInstance(mock)) #define _ArduinoFakeGetMock(mock) \ - getArduinoFakeContext()->Mocks.mock + getArduinoFakeContext()->_##mock.Fake #define _ArduinoFakeGetFunction() _ArduinoFakeGetMock(Function) #define _ArduinoFakeGetSerial() _ArduinoFakeGetMock(Serial) @@ -49,10 +49,10 @@ #define _ArduinoFakeInstanceGetter1(mock) \ mock##Fake* mock() \ { \ - if (!this->Instances.mock){ \ - this->Instances.mock = &this->Mocks.mock.get(); \ + if (!this->_##mock.Instance){ \ + this->_##mock.Instance = &this->_##mock.Fake.get(); \ } \ - return this->Instances.mock; \ + return this->_##mock.Instance; \ } #define _ArduinoFakeInstanceGetter2(name, clazz) \ @@ -67,64 +67,31 @@ throw std::runtime_error("Unknown instance"); \ } -struct ArduinoFakeMocks +template +struct ArduinoFake_t { - fakeit::Mock Function; - fakeit::Mock Serial; - fakeit::Mock Wire; - fakeit::Mock Stream; - fakeit::Mock Client; - fakeit::Mock Print; - fakeit::Mock SPI; - fakeit::Mock EEPROM; + fakeit::Mock Fake; + FakeT *Instance; void reset(void) { - Function.Reset(); - Stream.Reset(); - Serial.Reset(); - Wire.Reset(); - Client.Reset(); - Print.Reset(); - SPI.Reset(); - EEPROM.Reset(); - } -}; - -struct ArduinoFakeInstances -{ - FunctionFake* Function; - SerialFake* Serial; - WireFake* Wire; - StreamFake* Stream; - ClientFake* Client; - PrintFake* Print; - SPIFake* SPI; - EEPROMFake* EEPROM; - - ArduinoFakeInstances() - { - reset(); - } - - void reset(void) - { - Function = nullptr; - Serial = nullptr; - Wire = nullptr; - Stream = nullptr; - Client = nullptr; - Print = nullptr; - SPI = nullptr; - EEPROM = nullptr; + Fake.Reset(); + Instance = nullptr; } }; class ArduinoFakeContext { public: - ArduinoFakeInstances Instances; - ArduinoFakeMocks Mocks; + ArduinoFake_t _Function; + ArduinoFake_t _Serial; + ArduinoFake_t _Wire; + ArduinoFake_t _Stream; + ArduinoFake_t _Client; + ArduinoFake_t _Print; + ArduinoFake_t _SPI; + ArduinoFake_t _EEPROM; + std::unordered_map Mapping; _ArduinoFakeInstanceGetter1(Print) @@ -151,8 +118,14 @@ class ArduinoFakeContext void reset(void) { - this->Instances.reset(); - this->Mocks.reset(); + _Function.reset(); + _Serial.reset(); + _Wire.reset(); + _Stream.reset(); + _Client.reset(); + _Print.reset(); + _SPI.reset(); + _EEPROM.reset(); Mapping.clear(); Mapping[&::Serial] = this->Serial(); From 1b62f82cdf6af47d2d2ad8f1395829650426a67a Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Wed, 8 Oct 2025 12:15:38 -0500 Subject: [PATCH 09/18] Use templates to manage proxy and fake access --- src/ArduinoFake.h | 47 +++++++++++++++++---------- src/ClientFake.h | 2 +- src/EEPROMFake.h | 2 +- src/PrintFake.h | 2 +- src/SPIFake.h | 2 +- src/SerialFake.h | 2 +- src/StreamFake.h | 2 +- src/WireFake.h | 2 +- test/main.cpp | 2 ++ test/test_ProxiedArduinoFake_t.h | 54 ++++++++++++++++++++++++++++++++ test/test_context.h | 2 ++ 11 files changed, 95 insertions(+), 24 deletions(-) create mode 100644 test/test_ProxiedArduinoFake_t.h diff --git a/src/ArduinoFake.h b/src/ArduinoFake.h index 09781f7..4bdf7c0 100644 --- a/src/ArduinoFake.h +++ b/src/ArduinoFake.h @@ -49,10 +49,7 @@ #define _ArduinoFakeInstanceGetter1(mock) \ mock##Fake* mock() \ { \ - if (!this->_##mock.Instance){ \ - this->_##mock.Instance = &this->_##mock.Fake.get(); \ - } \ - return this->_##mock.Instance; \ + return this->_##mock.getFake(); \ } #define _ArduinoFakeInstanceGetter2(name, clazz) \ @@ -61,22 +58,38 @@ if (Mapping[instance]) { \ return (name##Fake*) Mapping[instance]; \ } \ - if (dynamic_cast(instance)) { \ - return dynamic_cast(instance)->get##name##Fake(); \ - } \ - throw std::runtime_error("Unknown instance"); \ + return this->_##name.getFake(instance); \ } template struct ArduinoFake_t { fakeit::Mock Fake; - FakeT *Instance; void reset(void) { Fake.Reset(); - Instance = nullptr; + } + + FakeT* getFake(void) + { + return &Fake.get(); + } +}; + +template > +struct ProxiedArduinoFake_t : public BaseT +{ + // Pull in base class getFake() + using BaseT::getFake; + + template + FakeT* getFake(ArduinoT *instance) + { + if (dynamic_cast(instance)) { + return dynamic_cast(instance)->getFake(); + } + throw std::runtime_error("Unknown instance"); } }; @@ -84,13 +97,13 @@ class ArduinoFakeContext { public: ArduinoFake_t _Function; - ArduinoFake_t _Serial; - ArduinoFake_t _Wire; - ArduinoFake_t _Stream; - ArduinoFake_t _Client; - ArduinoFake_t _Print; - ArduinoFake_t _SPI; - ArduinoFake_t _EEPROM; + ProxiedArduinoFake_t _Serial; + ProxiedArduinoFake_t _Wire; + ProxiedArduinoFake_t _Stream; + ProxiedArduinoFake_t _Client; + ProxiedArduinoFake_t _Print; + ProxiedArduinoFake_t _SPI; + ProxiedArduinoFake_t _EEPROM; std::unordered_map Mapping; diff --git a/src/ClientFake.h b/src/ClientFake.h index 804e54f..dbfbce1 100644 --- a/src/ClientFake.h +++ b/src/ClientFake.h @@ -97,7 +97,7 @@ class ClientFakeProxy : public StreamFakeProxy, public Client virtual operator bool(); - ClientFake* getClientFake() + ClientFake* getFake() { return clientFake; } diff --git a/src/EEPROMFake.h b/src/EEPROMFake.h index bcb1b7a..3f58038 100644 --- a/src/EEPROMFake.h +++ b/src/EEPROMFake.h @@ -17,5 +17,5 @@ class EEPROMFakeProxy : public EEPROMClass { public: EEPROMFakeProxy(EEPROMFake *fake) { eepromFake = fake; } - EEPROMFake *getEEPROMFake() { return eepromFake; } + EEPROMFake *getFake() { return eepromFake; } }; diff --git a/src/PrintFake.h b/src/PrintFake.h index 6173f82..d0b7c0e 100644 --- a/src/PrintFake.h +++ b/src/PrintFake.h @@ -55,7 +55,7 @@ class PrintFakeProxy : public Print return printFake->write(value); } - PrintFake* getPrintFake() + PrintFake* getFake() { return printFake; } diff --git a/src/SPIFake.h b/src/SPIFake.h index 9e90f9a..4b1699e 100644 --- a/src/SPIFake.h +++ b/src/SPIFake.h @@ -22,5 +22,5 @@ class SPIFakeProxy : public SPIClass { public: SPIFakeProxy(SPIFake *fake) { spiFake = fake; } - SPIFake *getSPIFake() { return spiFake; } + SPIFake *getFake() { return spiFake; } }; diff --git a/src/SerialFake.h b/src/SerialFake.h index a4cc725..9941fe4 100644 --- a/src/SerialFake.h +++ b/src/SerialFake.h @@ -43,7 +43,7 @@ class SerialFakeProxy : public StreamFakeProxy, public Serial_ serialFake = fake; } - SerialFake* getSerialFake() + SerialFake* getFake() { return serialFake; } diff --git a/src/StreamFake.h b/src/StreamFake.h index 106bb54..65113ac 100644 --- a/src/StreamFake.h +++ b/src/StreamFake.h @@ -74,7 +74,7 @@ class StreamFakeProxy : public Stream, public PrintFakeProxy streamFake->flush(); } - StreamFake* getStreamFake() + StreamFake* getFake() { return streamFake; } diff --git a/src/WireFake.h b/src/WireFake.h index b076bf4..1b5b07f 100644 --- a/src/WireFake.h +++ b/src/WireFake.h @@ -37,5 +37,5 @@ class WireFakeProxy : public StreamFakeProxy, public TwoWire { public: WireFakeProxy(WireFake *fake) : StreamFakeProxy(fake) { wireFake = fake; } - WireFake *getWireFake() { return wireFake; } + WireFake *getFake() { return wireFake; } }; \ No newline at end of file diff --git a/test/main.cpp b/test/main.cpp index 4bc8ebc..0d13878 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -17,6 +17,7 @@ using namespace fakeit; #include "test_arduino_string.h" #include "test_include.h" #include "test_ArduinoFake_t.h" +#include "test_ProxiedArduinoFake_t.h" #ifdef UNIT_TEST @@ -47,6 +48,7 @@ int main(int argc, char **argv) RUN_TEST_GROUP(ClientTest); RUN_TEST_GROUP(IncludeTest); RUN_TEST_GROUP(ArduinoFakeTTest); + RUN_TEST_GROUP(ProxiedArduinoFakeTTest); return UNITY_END(); } diff --git a/test/test_ProxiedArduinoFake_t.h b/test/test_ProxiedArduinoFake_t.h new file mode 100644 index 0000000..3c49e1d --- /dev/null +++ b/test/test_ProxiedArduinoFake_t.h @@ -0,0 +1,54 @@ +#ifdef UNIT_TEST + +namespace ProxiedArduinoFakeTTest +{ + struct IDummy + { + virtual void foo(void) { } + }; + + struct IArduino + { + virtual void bar(void) {} + }; + + struct IDummyProxy : public IArduino + { + IDummy *_dummy; + IDummy* getFake(void) { return _dummy; } + + virtual void bar(void) override {} + }; + + void test_getFake(void) + { + ProxiedArduinoFake_t subject; + + IDummyProxy proxy; + + proxy._dummy = nullptr; + TEST_ASSERT_EQUAL_PTR(nullptr, subject.getFake(&proxy)); + + IDummy dummy; + proxy._dummy = &dummy; + TEST_ASSERT_EQUAL_PTR(&dummy, subject.getFake(&proxy)); + + // Following should throw exception + try + { + IArduino arduino; + TEST_ASSERT_EQUAL_PTR(&dummy, subject.getFake(&arduino)); + TEST_FAIL(); + } + catch(const std::runtime_error& e) + { + } + } + + void run_tests(void) + { + RUN_TEST(test_getFake); + } +} + +#endif \ No newline at end of file diff --git a/test/test_context.h b/test/test_context.h index 1ae3b02..c9425bc 100644 --- a/test/test_context.h +++ b/test/test_context.h @@ -15,12 +15,14 @@ namespace ArduinoContextTest void test_reset(void) { + #if false ArduinoFakeContext* context = getArduinoFakeContext(); ArduinoFakeInstances* instances = context->Instances; ArduinoFakeReset(); TEST_ASSERT_NOT_EQUAL(context->Instances, instances); + #endif } void test_function_mock(void) From bcb29d718271da37890a1b1e373414e9fce14e4e Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Wed, 8 Oct 2025 15:27:36 -0500 Subject: [PATCH 10/18] Limit _ArduinoFakeInstanceGetter macro scope. --- src/ArduinoFake.h | 134 ++++++++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 65 deletions(-) diff --git a/src/ArduinoFake.h b/src/ArduinoFake.h index 4bdf7c0..167f8a6 100644 --- a/src/ArduinoFake.h +++ b/src/ArduinoFake.h @@ -46,21 +46,6 @@ #define _ArduinoFakeGetPrint() _ArduinoFakeGetMock(Print) #define _ArduinoFakeGet() _ArduinoFakeGetMock(Function) -#define _ArduinoFakeInstanceGetter1(mock) \ - mock##Fake* mock() \ - { \ - return this->_##mock.getFake(); \ - } - -#define _ArduinoFakeInstanceGetter2(name, clazz) \ - name##Fake* name(class clazz* instance) \ - { \ - if (Mapping[instance]) { \ - return (name##Fake*) Mapping[instance]; \ - } \ - return this->_##name.getFake(instance); \ - } - template struct ArduinoFake_t { @@ -95,57 +80,76 @@ struct ProxiedArduinoFake_t : public BaseT class ArduinoFakeContext { - public: - ArduinoFake_t _Function; - ProxiedArduinoFake_t _Serial; - ProxiedArduinoFake_t _Wire; - ProxiedArduinoFake_t _Stream; - ProxiedArduinoFake_t _Client; - ProxiedArduinoFake_t _Print; - ProxiedArduinoFake_t _SPI; - ProxiedArduinoFake_t _EEPROM; - - std::unordered_map Mapping; - - _ArduinoFakeInstanceGetter1(Print) - _ArduinoFakeInstanceGetter1(Stream) - _ArduinoFakeInstanceGetter1(Serial) - _ArduinoFakeInstanceGetter1(Wire) - _ArduinoFakeInstanceGetter1(Client) - _ArduinoFakeInstanceGetter1(Function) - _ArduinoFakeInstanceGetter1(SPI) - _ArduinoFakeInstanceGetter1(EEPROM) - - _ArduinoFakeInstanceGetter2(Print, Print) - _ArduinoFakeInstanceGetter2(Client, Client) - _ArduinoFakeInstanceGetter2(Stream, Stream) - _ArduinoFakeInstanceGetter2(Serial, Serial_) - _ArduinoFakeInstanceGetter2(Wire, TwoWire) - _ArduinoFakeInstanceGetter2(SPI, SPIClass) - _ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass) - - ArduinoFakeContext() - { - this->reset(); - } +public: + ArduinoFake_t _Function; + ProxiedArduinoFake_t _Serial; + ProxiedArduinoFake_t _Wire; + ProxiedArduinoFake_t _Stream; + ProxiedArduinoFake_t _Client; + ProxiedArduinoFake_t _Print; + ProxiedArduinoFake_t _SPI; + ProxiedArduinoFake_t _EEPROM; + + std::unordered_map Mapping; - void reset(void) - { - _Function.reset(); - _Serial.reset(); - _Wire.reset(); - _Stream.reset(); - _Client.reset(); - _Print.reset(); - _SPI.reset(); - _EEPROM.reset(); - - Mapping.clear(); - Mapping[&::Serial] = this->Serial(); - Mapping[&::Wire] = this->Wire(); - Mapping[&::SPI] = this->SPI(); - Mapping[&::EEPROM] = this->EEPROM(); - } +#define _ArduinoFakeInstanceGetter1(mock) \ + mock##Fake* mock() \ + { \ + return this->_##mock.getFake(); \ + } + + _ArduinoFakeInstanceGetter1(Print) + _ArduinoFakeInstanceGetter1(Stream) + _ArduinoFakeInstanceGetter1(Serial) + _ArduinoFakeInstanceGetter1(Wire) + _ArduinoFakeInstanceGetter1(Client) + _ArduinoFakeInstanceGetter1(Function) + _ArduinoFakeInstanceGetter1(SPI) + _ArduinoFakeInstanceGetter1(EEPROM) + +#undef _ArduinoFakeInstanceGetter1 + +#define _ArduinoFakeInstanceGetter2(name, clazz) \ + name##Fake* name(class clazz* instance) \ + { \ + if (Mapping[instance]) { \ + return (name##Fake*) Mapping[instance]; \ + } \ + return this->_##name.getFake(instance); \ + } + + _ArduinoFakeInstanceGetter2(Print, Print) + _ArduinoFakeInstanceGetter2(Client, Client) + _ArduinoFakeInstanceGetter2(Stream, Stream) + _ArduinoFakeInstanceGetter2(Serial, Serial_) + _ArduinoFakeInstanceGetter2(Wire, TwoWire) + _ArduinoFakeInstanceGetter2(SPI, SPIClass) + _ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass) + +#undef _ArduinoFakeInstanceGetter2 + + ArduinoFakeContext() + { + this->reset(); + } + + void reset(void) + { + _Function.reset(); + _Serial.reset(); + _Wire.reset(); + _Stream.reset(); + _Client.reset(); + _Print.reset(); + _SPI.reset(); + _EEPROM.reset(); + + Mapping.clear(); + Mapping[&::Serial] = this->Serial(); + Mapping[&::Wire] = this->Wire(); + Mapping[&::SPI] = this->SPI(); + Mapping[&::EEPROM] = this->EEPROM(); + } }; ArduinoFakeContext* getArduinoFakeContext(); From a72264218a9960cba9b22c758ed4171ad1d7bf36 Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Wed, 8 Oct 2025 15:35:09 -0500 Subject: [PATCH 11/18] Update macro declaration order so it reads top to bottom --- src/ArduinoFake.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ArduinoFake.h b/src/ArduinoFake.h index 167f8a6..17e78fa 100644 --- a/src/ArduinoFake.h +++ b/src/ArduinoFake.h @@ -22,8 +22,6 @@ #include "SPI.h" #include "EEPROM.h" -#define ArduinoFake(mock) _ArduinoFakeGet##mock() - #define ArduinoFakeReset() \ getArduinoFakeContext()->reset() @@ -46,6 +44,8 @@ #define _ArduinoFakeGetPrint() _ArduinoFakeGetMock(Print) #define _ArduinoFakeGet() _ArduinoFakeGetMock(Function) +#define ArduinoFake(mock) _ArduinoFakeGet##mock() + template struct ArduinoFake_t { From 46659af87bf1e30b5f44c9f0d59e1debbcbc57bb Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Wed, 8 Oct 2025 22:38:22 -0500 Subject: [PATCH 12/18] Simplify macros - inject the global Fake override into getFake() --- src/ArduinoFake.h | 16 +++++++++++----- test/test_ProxiedArduinoFake_t.h | 6 +++--- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/ArduinoFake.h b/src/ArduinoFake.h index 17e78fa..f3267d0 100644 --- a/src/ArduinoFake.h +++ b/src/ArduinoFake.h @@ -69,8 +69,11 @@ struct ProxiedArduinoFake_t : public BaseT using BaseT::getFake; template - FakeT* getFake(ArduinoT *instance) + FakeT* getFake(void* pOverride, ArduinoT *instance) { + if (pOverride!=nullptr) { + return (FakeT*)pOverride; + } if (dynamic_cast(instance)) { return dynamic_cast(instance)->getFake(); } @@ -112,10 +115,7 @@ class ArduinoFakeContext #define _ArduinoFakeInstanceGetter2(name, clazz) \ name##Fake* name(class clazz* instance) \ { \ - if (Mapping[instance]) { \ - return (name##Fake*) Mapping[instance]; \ - } \ - return this->_##name.getFake(instance); \ + return this->_##name.getFake(getGlobalOverride(instance), instance); \ } _ArduinoFakeInstanceGetter2(Print, Print) @@ -150,6 +150,12 @@ class ArduinoFakeContext Mapping[&::SPI] = this->SPI(); Mapping[&::EEPROM] = this->EEPROM(); } + + void *getGlobalOverride(void *instance) + { + auto iter = Mapping.find(instance); + return iter==Mapping.end() ? nullptr : iter->second; + } }; ArduinoFakeContext* getArduinoFakeContext(); diff --git a/test/test_ProxiedArduinoFake_t.h b/test/test_ProxiedArduinoFake_t.h index 3c49e1d..8a3fe2e 100644 --- a/test/test_ProxiedArduinoFake_t.h +++ b/test/test_ProxiedArduinoFake_t.h @@ -27,17 +27,17 @@ namespace ProxiedArduinoFakeTTest IDummyProxy proxy; proxy._dummy = nullptr; - TEST_ASSERT_EQUAL_PTR(nullptr, subject.getFake(&proxy)); + TEST_ASSERT_EQUAL_PTR(nullptr, subject.getFake(nullptr, &proxy)); IDummy dummy; proxy._dummy = &dummy; - TEST_ASSERT_EQUAL_PTR(&dummy, subject.getFake(&proxy)); + TEST_ASSERT_EQUAL_PTR(&dummy, subject.getFake(nullptr, &proxy)); // Following should throw exception try { IArduino arduino; - TEST_ASSERT_EQUAL_PTR(&dummy, subject.getFake(&arduino)); + TEST_ASSERT_EQUAL_PTR(&dummy, subject.getFake(nullptr, &arduino)); TEST_FAIL(); } catch(const std::runtime_error& e) From 9ea17c59b8e8ef249c016e15815ed1ef8f1a45ec Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Thu, 9 Oct 2025 08:17:18 -0500 Subject: [PATCH 13/18] Valid reset tests :-) --- test/test_context.h | 101 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 7 deletions(-) diff --git a/test/test_context.h b/test/test_context.h index c9425bc..3bf3450 100644 --- a/test/test_context.h +++ b/test/test_context.h @@ -13,16 +13,102 @@ namespace ArduinoContextTest TEST_ASSERT_EQUAL(context1, context2); } - void test_reset(void) + template + void assert_test_reset(FakeMethod fakeMethod, std::function realMethod) { - #if false - ArduinoFakeContext* context = getArduinoFakeContext(); - ArduinoFakeInstances* instances = context->Instances; + Verify(fakeMethod).Never(); + + // Call the "real" method... + realMethod(); + // ...which should call the faked method + Verify(fakeMethod).Once(); + // Reset all fakes ArduinoFakeReset(); + + try { + // This should throw an exception... + realMethod(); + // ...fail the test if not. + TEST_FAIL(); + } + catch (fakeit::FakeitException &e) { + Verify(fakeMethod).Never(); + } + } - TEST_ASSERT_NOT_EQUAL(context->Instances, instances); - #endif + void test_reset_function(void) + { + auto method = Method(ArduinoFake(Function), millis); + When(method).AlwaysReturn(101L); + assert_test_reset(method, []() { (void)millis(); }); + } + + void test_reset_print(void) + { + auto method = OverloadedMethod(ArduinoFake(Print), print, size_t(const char[])); + When(method).AlwaysDo([](const char *str) { + std::cout << str; + return strlen(str); + }); + assert_test_reset(method, []() { (ArduinoFakeMock(Print))->print("abc"); }); + } + + void test_reset_serial(void) + { + auto method = Method(ArduinoFake(Serial), end); + When(method).AlwaysReturn(); + assert_test_reset(method, []() { (ArduinoFakeMock(Serial))->end(); }); + } + + void test_reset_wire(void) + { + auto method = Method(ArduinoFake(Wire), end); + When(method).AlwaysReturn(); + assert_test_reset(method, []() { (ArduinoFakeMock(Wire))->end(); }); + } + + void test_reset_stream(void) + { + auto method = OverloadedMethod(ArduinoFake(Stream), find, bool(char *)); + When(method).AlwaysReturn(false); + assert_test_reset(method, []() { + char toFind[] = "abc"; + (ArduinoFakeMock(Stream))->find(toFind); + }); + } + + void test_reset_client(void) + { + auto method = Method(ArduinoFake(Client), available); + When(method).AlwaysReturn(); + assert_test_reset(method, []() { (ArduinoFakeMock(Client))->available(); }); + } + + void test_reset_spi(void) + { + auto method = Method(ArduinoFake(SPI), end); + When(method).AlwaysReturn(); + assert_test_reset(method, []() { (ArduinoFakeMock(SPI))->end(); }); + } + + void test_reset_eeprom(void) + { + auto method = Method(ArduinoFake(EEPROM), length); + When(method).AlwaysReturn(0xffff); + assert_test_reset(method, []() { (ArduinoFakeMock(EEPROM))->length(); }); + } + + void test_reset(void) + { + RUN_TEST(test_reset_function); + RUN_TEST(test_reset_serial); + RUN_TEST(test_reset_wire); + RUN_TEST(test_reset_stream); + RUN_TEST(test_reset_client); + RUN_TEST(test_reset_print); + RUN_TEST(test_reset_spi); + RUN_TEST(test_reset_eeprom); } void test_function_mock(void) @@ -127,7 +213,6 @@ namespace ArduinoContextTest void run_tests(void) { RUN_TEST(ArduinoContextTest::test_single_instance); - RUN_TEST(ArduinoContextTest::test_reset); RUN_TEST(ArduinoContextTest::test_function_mock); RUN_TEST(ArduinoContextTest::test_print_mock); RUN_TEST(ArduinoContextTest::test_stream_mock); @@ -135,6 +220,8 @@ namespace ArduinoContextTest RUN_TEST(ArduinoContextTest::test_getter_overload_with_proxy); RUN_TEST(ArduinoContextTest::test_getter_overload_with_mapping); RUN_TEST(ArduinoContextTest::test_unknown_instance_exception); + + ArduinoContextTest::test_reset(); } } From a5f4aed113a24f5f1f519571cad0cf17172ab503 Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Thu, 9 Oct 2025 09:34:39 -0500 Subject: [PATCH 14/18] Formalize the overrides into a separate class --- src/ArduinoFake.h | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/ArduinoFake.h b/src/ArduinoFake.h index f3267d0..db332c2 100644 --- a/src/ArduinoFake.h +++ b/src/ArduinoFake.h @@ -81,6 +81,29 @@ struct ProxiedArduinoFake_t : public BaseT } }; +class FakeOverride_t +{ +public: + void reset(void) + { + _mapping.clear(); + } + + void *getOverride(void *instance) + { + auto iter = _mapping.find(instance); + return iter==_mapping.end() ? nullptr : iter->second; + } + + void setOverride(void *instance, void *override) + { + _mapping[instance] = override; + } + +private: + std::unordered_map _mapping; +}; + class ArduinoFakeContext { public: @@ -93,7 +116,7 @@ class ArduinoFakeContext ProxiedArduinoFake_t _SPI; ProxiedArduinoFake_t _EEPROM; - std::unordered_map Mapping; + FakeOverride_t fakeOverrides; #define _ArduinoFakeInstanceGetter1(mock) \ mock##Fake* mock() \ @@ -144,17 +167,16 @@ class ArduinoFakeContext _SPI.reset(); _EEPROM.reset(); - Mapping.clear(); - Mapping[&::Serial] = this->Serial(); - Mapping[&::Wire] = this->Wire(); - Mapping[&::SPI] = this->SPI(); - Mapping[&::EEPROM] = this->EEPROM(); + fakeOverrides.reset(); + fakeOverrides.setOverride(&::Serial, this->Serial()); + fakeOverrides.setOverride(&::Wire, this->Wire()); + fakeOverrides.setOverride(&::SPI, this->SPI()); + fakeOverrides.setOverride(&::EEPROM, this->EEPROM()); } void *getGlobalOverride(void *instance) { - auto iter = Mapping.find(instance); - return iter==Mapping.end() ? nullptr : iter->second; + return fakeOverrides.getOverride(instance); } }; From 9b33162dbd3e6ca13d548cadb00808d3fd3c7c13 Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Thu, 9 Oct 2025 09:46:38 -0500 Subject: [PATCH 15/18] Add OverrideableProxiedArduinoFake_t - replaces macro based logic. --- src/ArduinoFake.h | 72 +++++++++++++------- test/main.cpp | 2 + test/test_OverrideableProxiedArduinoFake_t.h | 44 ++++++++++++ test/test_ProxiedArduinoFake_t.h | 6 +- 4 files changed, 98 insertions(+), 26 deletions(-) create mode 100644 test/test_OverrideableProxiedArduinoFake_t.h diff --git a/src/ArduinoFake.h b/src/ArduinoFake.h index db332c2..ec7ce2b 100644 --- a/src/ArduinoFake.h +++ b/src/ArduinoFake.h @@ -69,11 +69,8 @@ struct ProxiedArduinoFake_t : public BaseT using BaseT::getFake; template - FakeT* getFake(void* pOverride, ArduinoT *instance) + FakeT* getFake(ArduinoT *instance) { - if (pOverride!=nullptr) { - return (FakeT*)pOverride; - } if (dynamic_cast(instance)) { return dynamic_cast(instance)->getFake(); } @@ -104,20 +101,44 @@ class FakeOverride_t std::unordered_map _mapping; }; +template > +struct OverrideableProxiedArduinoFake_t : public BaseT +{ + FakeOverride_t &_overrides; + + OverrideableProxiedArduinoFake_t(FakeOverride_t &overrides) + : BaseT() + , _overrides(overrides) + { + } + + // Pull in base class getFake() + using BaseT::getFake; + + template + FakeT* getFake(ArduinoT *instance) + { + void *pOverride = _overrides.getOverride(instance); + if (pOverride!=nullptr) { + return (FakeT*)pOverride; + } + return BaseT::getFake(instance); + } +}; + class ArduinoFakeContext { public: + FakeOverride_t _fakeOverrides; ArduinoFake_t _Function; - ProxiedArduinoFake_t _Serial; - ProxiedArduinoFake_t _Wire; - ProxiedArduinoFake_t _Stream; - ProxiedArduinoFake_t _Client; - ProxiedArduinoFake_t _Print; - ProxiedArduinoFake_t _SPI; - ProxiedArduinoFake_t _EEPROM; + OverrideableProxiedArduinoFake_t _Serial; + OverrideableProxiedArduinoFake_t _Wire; + OverrideableProxiedArduinoFake_t _Stream; + OverrideableProxiedArduinoFake_t _Client; + OverrideableProxiedArduinoFake_t _Print; + OverrideableProxiedArduinoFake_t _SPI; + OverrideableProxiedArduinoFake_t _EEPROM; - FakeOverride_t fakeOverrides; - #define _ArduinoFakeInstanceGetter1(mock) \ mock##Fake* mock() \ { \ @@ -138,7 +159,7 @@ class ArduinoFakeContext #define _ArduinoFakeInstanceGetter2(name, clazz) \ name##Fake* name(class clazz* instance) \ { \ - return this->_##name.getFake(getGlobalOverride(instance), instance); \ + return this->_##name.getFake(instance); \ } _ArduinoFakeInstanceGetter2(Print, Print) @@ -152,6 +173,15 @@ class ArduinoFakeContext #undef _ArduinoFakeInstanceGetter2 ArduinoFakeContext() + : _fakeOverrides() + , _Function() + , _Serial(_fakeOverrides) + , _Wire(_fakeOverrides) + , _Stream(_fakeOverrides) + , _Client(_fakeOverrides) + , _Print(_fakeOverrides) + , _SPI(_fakeOverrides) + , _EEPROM(_fakeOverrides) { this->reset(); } @@ -167,17 +197,13 @@ class ArduinoFakeContext _SPI.reset(); _EEPROM.reset(); - fakeOverrides.reset(); - fakeOverrides.setOverride(&::Serial, this->Serial()); - fakeOverrides.setOverride(&::Wire, this->Wire()); - fakeOverrides.setOverride(&::SPI, this->SPI()); - fakeOverrides.setOverride(&::EEPROM, this->EEPROM()); + _fakeOverrides.reset(); + _fakeOverrides.setOverride(&::Serial, this->Serial()); + _fakeOverrides.setOverride(&::Wire, this->Wire()); + _fakeOverrides.setOverride(&::SPI, this->SPI()); + _fakeOverrides.setOverride(&::EEPROM, this->EEPROM()); } - void *getGlobalOverride(void *instance) - { - return fakeOverrides.getOverride(instance); - } }; ArduinoFakeContext* getArduinoFakeContext(); diff --git a/test/main.cpp b/test/main.cpp index 0d13878..a002648 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -18,6 +18,7 @@ using namespace fakeit; #include "test_include.h" #include "test_ArduinoFake_t.h" #include "test_ProxiedArduinoFake_t.h" +#include "test_OverrideableProxiedArduinoFake_t.h" #ifdef UNIT_TEST @@ -49,6 +50,7 @@ int main(int argc, char **argv) RUN_TEST_GROUP(IncludeTest); RUN_TEST_GROUP(ArduinoFakeTTest); RUN_TEST_GROUP(ProxiedArduinoFakeTTest); + RUN_TEST_GROUP(OverrideableProxiedArduinoFakeTTest); return UNITY_END(); } diff --git a/test/test_OverrideableProxiedArduinoFake_t.h b/test/test_OverrideableProxiedArduinoFake_t.h new file mode 100644 index 0000000..d37dd96 --- /dev/null +++ b/test/test_OverrideableProxiedArduinoFake_t.h @@ -0,0 +1,44 @@ +#ifdef UNIT_TEST + +namespace OverrideableProxiedArduinoFakeTTest +{ + struct IDummy + { + virtual void foo(void) { } + }; + + struct IArduino + { + virtual void bar(void) {} + }; + + struct IDummyProxy : public IArduino + { + IDummy *_dummy; + IDummy* getFake(void) { return _dummy; } + + virtual void bar(void) override {} + }; + + void test_getFake(void) + { + FakeOverride_t overrides; + OverrideableProxiedArduinoFake_t subject(overrides); + + // No override, should get the proxy fake + IDummyProxy proxy; + TEST_ASSERT_EQUAL_PTR(proxy.getFake(), subject.getFake(&proxy)); + + // Should return the alternate, since it's now overriden + ArduinoFake_t alternateFake; + overrides.setOverride(&proxy, alternateFake.getFake()); + TEST_ASSERT_EQUAL_PTR(alternateFake.getFake(), subject.getFake(&proxy)); + } + + void run_tests(void) + { + RUN_TEST(test_getFake); + } +} + +#endif \ No newline at end of file diff --git a/test/test_ProxiedArduinoFake_t.h b/test/test_ProxiedArduinoFake_t.h index 8a3fe2e..3c49e1d 100644 --- a/test/test_ProxiedArduinoFake_t.h +++ b/test/test_ProxiedArduinoFake_t.h @@ -27,17 +27,17 @@ namespace ProxiedArduinoFakeTTest IDummyProxy proxy; proxy._dummy = nullptr; - TEST_ASSERT_EQUAL_PTR(nullptr, subject.getFake(nullptr, &proxy)); + TEST_ASSERT_EQUAL_PTR(nullptr, subject.getFake(&proxy)); IDummy dummy; proxy._dummy = &dummy; - TEST_ASSERT_EQUAL_PTR(&dummy, subject.getFake(nullptr, &proxy)); + TEST_ASSERT_EQUAL_PTR(&dummy, subject.getFake(&proxy)); // Following should throw exception try { IArduino arduino; - TEST_ASSERT_EQUAL_PTR(&dummy, subject.getFake(nullptr, &arduino)); + TEST_ASSERT_EQUAL_PTR(&dummy, subject.getFake(&arduino)); TEST_FAIL(); } catch(const std::runtime_error& e) From e4c93f1db80a46452e3a2cace052b4b122e8a4d3 Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Thu, 9 Oct 2025 12:56:58 -0500 Subject: [PATCH 16/18] Set the overrides to actual ArduinoFake_t instances --- src/ArduinoFake.h | 12 ++++++------ test/test_OverrideableProxiedArduinoFake_t.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ArduinoFake.h b/src/ArduinoFake.h index ec7ce2b..67ef15d 100644 --- a/src/ArduinoFake.h +++ b/src/ArduinoFake.h @@ -118,9 +118,9 @@ struct OverrideableProxiedArduinoFake_t : public BaseT template FakeT* getFake(ArduinoT *instance) { - void *pOverride = _overrides.getOverride(instance); + ArduinoFake_t *pOverride = static_cast *>(_overrides.getOverride(instance)); if (pOverride!=nullptr) { - return (FakeT*)pOverride; + return pOverride->getFake(); } return BaseT::getFake(instance); } @@ -198,10 +198,10 @@ class ArduinoFakeContext _EEPROM.reset(); _fakeOverrides.reset(); - _fakeOverrides.setOverride(&::Serial, this->Serial()); - _fakeOverrides.setOverride(&::Wire, this->Wire()); - _fakeOverrides.setOverride(&::SPI, this->SPI()); - _fakeOverrides.setOverride(&::EEPROM, this->EEPROM()); + _fakeOverrides.setOverride(&::Serial, &_Serial); + _fakeOverrides.setOverride(&::Wire, &_Wire); + _fakeOverrides.setOverride(&::SPI, &_SPI); + _fakeOverrides.setOverride(&::EEPROM, &_EEPROM); } }; diff --git a/test/test_OverrideableProxiedArduinoFake_t.h b/test/test_OverrideableProxiedArduinoFake_t.h index d37dd96..2142ae5 100644 --- a/test/test_OverrideableProxiedArduinoFake_t.h +++ b/test/test_OverrideableProxiedArduinoFake_t.h @@ -31,7 +31,7 @@ namespace OverrideableProxiedArduinoFakeTTest // Should return the alternate, since it's now overriden ArduinoFake_t alternateFake; - overrides.setOverride(&proxy, alternateFake.getFake()); + overrides.setOverride(&proxy, &alternateFake); TEST_ASSERT_EQUAL_PTR(alternateFake.getFake(), subject.getFake(&proxy)); } From 655ef1c92ce381835643e25215b2adb415f87960 Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Thu, 9 Oct 2025 14:15:39 -0500 Subject: [PATCH 17/18] reset() -> Reset() --- src/ArduinoFake.h | 30 +++++++++++++++--------------- test/test_ArduinoFake_t.h | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/ArduinoFake.h b/src/ArduinoFake.h index 67ef15d..700500a 100644 --- a/src/ArduinoFake.h +++ b/src/ArduinoFake.h @@ -23,7 +23,7 @@ #include "EEPROM.h" #define ArduinoFakeReset() \ - getArduinoFakeContext()->reset() + getArduinoFakeContext()->Reset() #define ArduinoFakeInstance(mock, ...) \ getArduinoFakeContext()->mock(__VA_ARGS__) @@ -51,7 +51,7 @@ struct ArduinoFake_t { fakeit::Mock Fake; - void reset(void) + void Reset(void) { Fake.Reset(); } @@ -81,7 +81,7 @@ struct ProxiedArduinoFake_t : public BaseT class FakeOverride_t { public: - void reset(void) + void Reset(void) { _mapping.clear(); } @@ -183,21 +183,21 @@ class ArduinoFakeContext , _SPI(_fakeOverrides) , _EEPROM(_fakeOverrides) { - this->reset(); + this->Reset(); } - void reset(void) + void Reset(void) { - _Function.reset(); - _Serial.reset(); - _Wire.reset(); - _Stream.reset(); - _Client.reset(); - _Print.reset(); - _SPI.reset(); - _EEPROM.reset(); - - _fakeOverrides.reset(); + _Function.Reset(); + _Serial.Reset(); + _Wire.Reset(); + _Stream.Reset(); + _Client.Reset(); + _Print.Reset(); + _SPI.Reset(); + _EEPROM.Reset(); + + _fakeOverrides.Reset(); _fakeOverrides.setOverride(&::Serial, &_Serial); _fakeOverrides.setOverride(&::Wire, &_Wire); _fakeOverrides.setOverride(&::SPI, &_SPI); diff --git a/test/test_ArduinoFake_t.h b/test/test_ArduinoFake_t.h index 6f91969..eda17be 100644 --- a/test/test_ArduinoFake_t.h +++ b/test/test_ArduinoFake_t.h @@ -22,7 +22,7 @@ namespace ArduinoFakeTTest Verify(method).Once(); // Reset - arduinoFake.reset(); + arduinoFake.Reset(); try { // This should throw an exception... From c16f38261f4083d23f40dc9abb3cca7a50dae321 Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Thu, 9 Oct 2025 14:24:02 -0500 Subject: [PATCH 18/18] Remove ArduinoFake_t - use fakeit::Mock directly. --- src/ArduinoFake.h | 38 ++++------------- test/main.cpp | 2 - test/test_ArduinoFake_t.h | 44 -------------------- test/test_OverrideableProxiedArduinoFake_t.h | 4 +- 4 files changed, 10 insertions(+), 78 deletions(-) delete mode 100644 test/test_ArduinoFake_t.h diff --git a/src/ArduinoFake.h b/src/ArduinoFake.h index 700500a..e6bdd05 100644 --- a/src/ArduinoFake.h +++ b/src/ArduinoFake.h @@ -32,7 +32,7 @@ new mock##FakeProxy(ArduinoFakeInstance(mock)) #define _ArduinoFakeGetMock(mock) \ - getArduinoFakeContext()->_##mock.Fake + getArduinoFakeContext()->_##mock #define _ArduinoFakeGetFunction() _ArduinoFakeGetMock(Function) #define _ArduinoFakeGetSerial() _ArduinoFakeGetMock(Serial) @@ -46,28 +46,9 @@ #define ArduinoFake(mock) _ArduinoFakeGet##mock() -template -struct ArduinoFake_t -{ - fakeit::Mock Fake; - - void Reset(void) - { - Fake.Reset(); - } - - FakeT* getFake(void) - { - return &Fake.get(); - } -}; - -template > +template > struct ProxiedArduinoFake_t : public BaseT -{ - // Pull in base class getFake() - using BaseT::getFake; - +{ template FakeT* getFake(ArduinoT *instance) { @@ -111,16 +92,13 @@ struct OverrideableProxiedArduinoFake_t : public BaseT , _overrides(overrides) { } - - // Pull in base class getFake() - using BaseT::getFake; - + template FakeT* getFake(ArduinoT *instance) { - ArduinoFake_t *pOverride = static_cast *>(_overrides.getOverride(instance)); + fakeit::Mock *pOverride = static_cast *>(_overrides.getOverride(instance)); if (pOverride!=nullptr) { - return pOverride->getFake(); + return &pOverride->get(); } return BaseT::getFake(instance); } @@ -130,7 +108,7 @@ class ArduinoFakeContext { public: FakeOverride_t _fakeOverrides; - ArduinoFake_t _Function; + fakeit::Mock _Function; OverrideableProxiedArduinoFake_t _Serial; OverrideableProxiedArduinoFake_t _Wire; OverrideableProxiedArduinoFake_t _Stream; @@ -142,7 +120,7 @@ class ArduinoFakeContext #define _ArduinoFakeInstanceGetter1(mock) \ mock##Fake* mock() \ { \ - return this->_##mock.getFake(); \ + return &this->_##mock.get(); \ } _ArduinoFakeInstanceGetter1(Print) diff --git a/test/main.cpp b/test/main.cpp index a002648..4ef2cb4 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -16,7 +16,6 @@ using namespace fakeit; #include "test_client.h" #include "test_arduino_string.h" #include "test_include.h" -#include "test_ArduinoFake_t.h" #include "test_ProxiedArduinoFake_t.h" #include "test_OverrideableProxiedArduinoFake_t.h" @@ -48,7 +47,6 @@ int main(int argc, char **argv) RUN_TEST_GROUP(EEPROMTest); RUN_TEST_GROUP(ClientTest); RUN_TEST_GROUP(IncludeTest); - RUN_TEST_GROUP(ArduinoFakeTTest); RUN_TEST_GROUP(ProxiedArduinoFakeTTest); RUN_TEST_GROUP(OverrideableProxiedArduinoFakeTTest); diff --git a/test/test_ArduinoFake_t.h b/test/test_ArduinoFake_t.h deleted file mode 100644 index eda17be..0000000 --- a/test/test_ArduinoFake_t.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifdef UNIT_TEST - -namespace ArduinoFakeTTest -{ - struct IDummy - { - virtual long dummyMethod(void) = 0; - }; - - void test_reset(void) - { - ArduinoFake_t arduinoFake; - - auto method = Method(arduinoFake.Fake, dummyMethod); - When(method).AlwaysReturn(101L); - - Verify(method).Never(); - - // Call the "real" method... - arduinoFake.getFake()->dummyMethod(); - // ...which should call the faked method - Verify(method).Once(); - - // Reset - arduinoFake.Reset(); - - try { - // This should throw an exception... - arduinoFake.getFake()->dummyMethod(); - // ...fail the test if not. - TEST_FAIL(); - } - catch (fakeit::FakeitException &e) { - Verify(method).Never(); - } - } - - void run_tests(void) - { - RUN_TEST(ArduinoFakeTTest::test_reset); - } -} - -#endif \ No newline at end of file diff --git a/test/test_OverrideableProxiedArduinoFake_t.h b/test/test_OverrideableProxiedArduinoFake_t.h index 2142ae5..017386a 100644 --- a/test/test_OverrideableProxiedArduinoFake_t.h +++ b/test/test_OverrideableProxiedArduinoFake_t.h @@ -30,9 +30,9 @@ namespace OverrideableProxiedArduinoFakeTTest TEST_ASSERT_EQUAL_PTR(proxy.getFake(), subject.getFake(&proxy)); // Should return the alternate, since it's now overriden - ArduinoFake_t alternateFake; + fakeit::Mock alternateFake; overrides.setOverride(&proxy, &alternateFake); - TEST_ASSERT_EQUAL_PTR(alternateFake.getFake(), subject.getFake(&proxy)); + TEST_ASSERT_EQUAL_PTR(&alternateFake.get(), subject.getFake(&proxy)); } void run_tests(void)