Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

* text=auto
55 changes: 0 additions & 55 deletions cmake/git-download.cmake

This file was deleted.

2 changes: 1 addition & 1 deletion examples/mock-injection/test/test_my_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ void test_connect(void)
When(OverloadedMethod(ArduinoFake(Client), println, size_t(const char *))).AlwaysReturn();
When(OverloadedMethod(ArduinoFake(Client), connect, int(const char*, uint16_t))).Return(1);

Client* clientMock = ArduinoFakeMock(Client);
std::shared_ptr<Client> clientMock(ArduinoFakeMock(Client));

MyService service(clientMock);

Expand Down
3 changes: 0 additions & 3 deletions external/CMakeLists.txt

This file was deleted.

18 changes: 0 additions & 18 deletions external/fakeit/CMakeLists.txt

This file was deleted.

20 changes: 0 additions & 20 deletions external/unity/CMakeLists.txt

This file was deleted.

2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ArduinoFake",
"version": "0.4.0",
"version": "1.0.0",
"keywords": "test, mock, fake, arduino",
"description": "Arduino mocking made easy.",
"repository": {
Expand Down
79 changes: 60 additions & 19 deletions src/ArduinoFake.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,31 @@
#include "SPI.h"
#include "EEPROM.h"

#define CONCAT2(x,y) x##y
#define CONCAT(x,y) CONCAT2(x,y)

// These map a Arduino class name (E.g. "SPIClass") to
// the corresponding fake member name (E.g. "SPI")
#define _ClazzToFakePrint() Print
#define _ClazzToFakeClient() Client
#define _ClazzToFakeStream() Stream
#define _ClazzToFakeSerial_() Serial
#define _ClazzToFakeTwoWire() Wire
#define _ClazzToFakeSPIClass() SPI
#define _ClazzToFakeEEPROMClass() EEPROM
#define _ClazzToFake(clazz) _ClazzToFake##clazz()

#define ArduinoFakeReset() \
getArduinoFakeContext()->Reset()

#define ArduinoFakeInstance(mock, ...) \
getArduinoFakeContext()->mock(__VA_ARGS__)
#define ArduinoFakeInstance0(mock) \
getArduinoFakeContext()->mock()

#define ArduinoFakeInstance(clazz) \
getArduinoFakeContext()->getFake(clazz)

#define ArduinoFakeMock(mock) \
new mock##FakeProxy(ArduinoFakeInstance(mock))
std::shared_ptr<mock##FakeProxy>(new mock##FakeProxy(ArduinoFakeInstance0(mock)))

#define _ArduinoFakeGetMock(mock) \
getArduinoFakeContext()->_##mock
Expand All @@ -46,9 +63,20 @@

#define ArduinoFake(mock) _ArduinoFakeGet##mock()

// Access fakeit::Mock<T>.get()
// There is no equivalent in fakeit since Mock is a template
struct IFake
{
// Ideally this have a templated return type, but then it can't be
// virtual :-(
// We need this to be virtual to store instances in a map.
virtual void* toFake(void) = 0;
};

template <class FakeT, class ProxyT, typename BaseT = fakeit::Mock<FakeT>>
struct ProxiedArduinoFake_t : public BaseT
struct ProxiedArduinoFake_t : public BaseT, IFake
{
// Proxy to fake
template <class ArduinoT>
FakeT* getFake(ArduinoT *instance)
{
Expand All @@ -57,8 +85,21 @@ struct ProxiedArduinoFake_t : public BaseT
}
throw std::runtime_error("Unknown instance");
}

// Get the 'real' fake - the one that is actually mocked.
virtual void* toFake(void) override
{
return &fakeit::Mock<FakeT>::get();
}
};

// Maps from global instances to the equivalent IFake.
// E.g. Serial => SerialFake
//
// Required to respect inherited classes.
// E.g. Stream has 2 derived classes, Serial_ & TwoWire. Each has a global instance, Serial & Wire.
// We want to allow different mock implementations *of the same Stream method* for Serial_ & TwoWire
// and have the global instances use those different mocks.
class FakeOverride_t
{
public:
Expand All @@ -67,19 +108,19 @@ class FakeOverride_t
_mapping.clear();
}

void *getOverride(void *instance)
IFake *getOverride(void *instance)
{
auto iter = _mapping.find(instance);
return iter==_mapping.end() ? nullptr : iter->second;
}

void setOverride(void *instance, void *override)
void setOverride(void *instance, IFake *override)
{
_mapping[instance] = override;
}

private:
std::unordered_map<void*, void*> _mapping;
std::unordered_map<void*, IFake*> _mapping;
};

template <class FakeT, class ProxyT, typename BaseT = ProxiedArduinoFake_t<FakeT, ProxyT>>
Expand All @@ -96,9 +137,9 @@ struct OverrideableProxiedArduinoFake_t : public BaseT
template <class ArduinoT>
FakeT* getFake(ArduinoT *instance)
{
fakeit::Mock<FakeT> *pOverride = static_cast<fakeit::Mock<FakeT> *>(_overrides.getOverride(instance));
auto *pOverride = _overrides.getOverride(instance);
if (pOverride!=nullptr) {
return &pOverride->get();
return (FakeT*)pOverride->toFake();
}
return BaseT::getFake(instance);
}
Expand Down Expand Up @@ -134,19 +175,19 @@ class ArduinoFakeContext

#undef _ArduinoFakeInstanceGetter1

#define _ArduinoFakeInstanceGetter2(name, clazz) \
name##Fake* name(class clazz* instance) \
#define _ArduinoFakeInstanceGetter2(clazz) \
CONCAT(_ClazzToFake(clazz), Fake)* getFake(class clazz* instance) \
{ \
return this->_##name.getFake(instance); \
return this->CONCAT(_, _ClazzToFake(clazz)).getFake(instance); \
}

_ArduinoFakeInstanceGetter2(Print, Print)
_ArduinoFakeInstanceGetter2(Client, Client)
_ArduinoFakeInstanceGetter2(Stream, Stream)
_ArduinoFakeInstanceGetter2(Serial, Serial_)
_ArduinoFakeInstanceGetter2(Wire, TwoWire)
_ArduinoFakeInstanceGetter2(SPI, SPIClass)
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
_ArduinoFakeInstanceGetter2(Print)
_ArduinoFakeInstanceGetter2(Client)
_ArduinoFakeInstanceGetter2(Stream)
_ArduinoFakeInstanceGetter2(Serial_)
_ArduinoFakeInstanceGetter2(TwoWire)
_ArduinoFakeInstanceGetter2(SPIClass)
_ArduinoFakeInstanceGetter2(EEPROMClass)

#undef _ArduinoFakeInstanceGetter2

Expand Down
7 changes: 0 additions & 7 deletions src/CMakeLists.txt

This file was deleted.

22 changes: 11 additions & 11 deletions src/ClientFake.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,57 @@

int Client::connect(IPAddress ip, uint16_t port)
{
return ArduinoFakeInstance(Client, this)->connect(ip, port);
return ArduinoFakeInstance(this)->connect(ip, port);
}

int Client::connect(const char *host, uint16_t port)
{
return ArduinoFakeInstance(Client, this)->connect(host, port);
return ArduinoFakeInstance(this)->connect(host, port);
}

size_t Client::write(uint8_t value)
{
return ArduinoFakeInstance(Client, this)->write(value);
return ArduinoFakeInstance(this)->write(value);
}

size_t Client::write(const uint8_t *buf, size_t size)
{
return ArduinoFakeInstance(Client, this)->write(buf, size);
return ArduinoFakeInstance(this)->write(buf, size);
}

int Client::available()
{
return ArduinoFakeInstance(Client, this)->available();
return ArduinoFakeInstance(this)->available();
}

int Client::read()
{
return ArduinoFakeInstance(Client, this)->read();
return ArduinoFakeInstance(this)->read();
}

int Client::read(uint8_t *buf, size_t size)
{
return ArduinoFakeInstance(Client, this)->read(buf, size);
return ArduinoFakeInstance(this)->read(buf, size);
}

int Client::peek()
{
return ArduinoFakeInstance(Client, this)->peek();
return ArduinoFakeInstance(this)->peek();
}

void Client::flush()
{
return ArduinoFakeInstance(Client, this)->flush();
return ArduinoFakeInstance(this)->flush();
}

void Client::stop()
{
return ArduinoFakeInstance(Client, this)->stop();
return ArduinoFakeInstance(this)->stop();
}

uint8_t Client::connected()
{
return ArduinoFakeInstance(Client, this)->connected();
return ArduinoFakeInstance(this)->connected();
}

Client::operator bool()
Expand Down
10 changes: 5 additions & 5 deletions src/EEPROMFake.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
// clang-format on

uint8_t EEPROMClass::read(int idx) {
return ArduinoFakeInstance(EEPROM)->read(idx);
return ArduinoFakeInstance(this)->read(idx);
};
void EEPROMClass::write(int idx, uint8_t val) {
ArduinoFakeInstance(EEPROM)->write(idx, val);
ArduinoFakeInstance(this)->write(idx, val);
};
void EEPROMClass::update(int idx, uint8_t val) {
ArduinoFakeInstance(EEPROM)->update(idx, val);
ArduinoFakeInstance(this)->update(idx, val);
};
uint16_t EEPROMClass::length() { return ArduinoFakeInstance(EEPROM)->length(); }
uint16_t EEPROMClass::length() { return ArduinoFakeInstance(this)->length(); }

EEPROMClass EEPROM = EEPROMFakeProxy(ArduinoFakeInstance(EEPROM));
EEPROMClass EEPROM = EEPROMFakeProxy(ArduinoFakeInstance0(EEPROM));
Loading
Loading