1
0
mirror of https://github.com/bdring/Grbl_Esp32.git synced 2025-09-01 18:32:37 +02:00

Added some unit tests; fixed pin option parser.

This commit is contained in:
Stefan de Bruijn
2020-10-22 20:16:27 +02:00
parent 04690ed6cf
commit d5143f5c9d
8 changed files with 170 additions and 7 deletions

View File

@@ -16,7 +16,6 @@ Global
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Debug|x64.ActiveCfg = Debug|x64
{11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Debug|x64.Build.0 = Debug|x64
{11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Debug|x86.ActiveCfg = Debug|Win32
{11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Debug|x86.Build.0 = Debug|Win32
{11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Release|x64.ActiveCfg = Release|x64
@@ -24,6 +23,7 @@ Global
{11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Release|x86.ActiveCfg = Release|Win32
{11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Release|x86.Build.0 = Release|Win32
{33ECE513-60D1-4949-A4A9-C95D353C2CF0}.Debug|x64.ActiveCfg = Debug|x64
{33ECE513-60D1-4949-A4A9-C95D353C2CF0}.Debug|x64.Build.0 = Debug|x64
{33ECE513-60D1-4949-A4A9-C95D353C2CF0}.Debug|x86.ActiveCfg = Debug|Win32
{33ECE513-60D1-4949-A4A9-C95D353C2CF0}.Debug|x86.Build.0 = Debug|Win32
{33ECE513-60D1-4949-A4A9-C95D353C2CF0}.Release|x64.ActiveCfg = Release|x64

View File

@@ -21,7 +21,7 @@ namespace Pins {
bool PinAttributes::validateWith(PinCapabilities caps) {
auto capMask = (caps._value & capabilityMask);
auto attrMask = _value;
auto attrMask = (_value & capabilityMask);
// We're good if:
return (capMask & attrMask) == attrMask && // the capabilities overlap with the required attributes AND

View File

@@ -3,11 +3,11 @@
#include <cstring>
namespace Pins {
PinOption::PinOption(char* start, const char* end) : _start(start) {}
PinOption::PinOption(char* start, const char* end) : _start(start), _end(end) {}
bool PinOption::is(const char* option) const { return !::strcmp(option, _start); }
PinOption PinOption ::operator++() const {
PinOption& PinOption::operator++() {
if (_start == _end) {
return *this;
}
@@ -16,13 +16,14 @@ namespace Pins {
if (newStart != _end) { // and 1 past it if we're not at the end
++newStart;
}
return PinOption(newStart, _end);
_start = newStart;
return *this;
}
PinOptionsParser::PinOptionsParser(char* buffer, char* bufferEnd) : _buffer(buffer), _bufferEnd(bufferEnd) {
// Do the actual parsing:
for (auto i = buffer; i != bufferEnd; ++i) {
if (*i == ':') {
if (*i == ':' || *i == ';') {
*i = '\0';
} else if (*i >= 'A' && *i <= 'Z') { // where did cstring->tolower go? Anyways, here goes:
*i = char(*i + 32);

View File

@@ -35,7 +35,7 @@ namespace Pins {
// Iterator support:
inline PinOption const* operator->() const { return this; }
inline PinOption operator*() const { return *this; }
PinOption operator++() const;
PinOption& operator++();
bool operator==(const PinOption& o) const { return _start == o._start; }
bool operator!=(const PinOption& o) const { return _start != o._start; }

View File

@@ -247,4 +247,34 @@ namespace Pins {
Pin gpio16 = Pin::create("gpio.16");
Assert(gpio16.name().equals("GPIO.16"), "Name is %s", gpio16.name().c_str());
}
Test(GPIO, ActiveLow) {
GPIONative::initialize();
PinLookup::ResetAllPins();
Pin gpio16 = Pin::create("gpio.16:low");
Pin gpio17 = Pin::create("gpio.17");
gpio16.setAttr(Pin::Attr::Output | Pin::Attr::InitialHigh);
gpio17.setAttr(Pin::Attr::Input);
Assert(false == gpio16.read());
Assert(true == gpio17.read());
Assert(false == GPIONative::read(16));
Assert(true == GPIONative::read(17));
gpio16.on();
Assert(true == gpio16.read());
Assert(false == gpio17.read());
Assert(true == GPIONative::read(16));
Assert(false == GPIONative::read(17));
gpio16.off();
Assert(false == gpio16.read());
Assert(true == gpio17.read());
Assert(false == GPIONative::read(16));
Assert(true == GPIONative::read(17));
}
}

View File

@@ -0,0 +1,128 @@
#include "../TestFramework.h"
#include "src/Pins/PinOptionsParser.h"
#include <cstdio>
#include <cstring>
namespace Pins {
Test(PinOptionParsing, NoArgs) {
char nullDescr[1] = { '\0' };
Pins::PinOptionsParser parser(nullDescr, nullDescr);
{
auto opt = parser.begin();
auto endopt = parser.end();
Assert(opt == endopt, "Expected empty enumerator");
}
// Typical use is a for loop. Let's test the two ways to use it:
for (auto it : parser) {
Assert(false, "Didn't expect to get here");
}
for (auto it = parser.begin(); it != parser.end(); ++it) {
Assert(false, "Didn't expect to get here");
}
}
Test(PinOptionParsing, SingleArg) {
const char* input = "first";
char tmp[20];
int n = snprintf(tmp, 20, "%s", input);
Pins::PinOptionsParser parser(tmp, tmp + n);
{
auto opt = parser.begin();
auto endopt = parser.end();
Assert(opt != endopt, "Expected an argument");
Assert(opt->is("first"), "Expected 'first'");
++opt;
Assert(opt == endopt, "Expected one argument");
}
// Typical use is a for loop. Let's test the two ways to use it:
int ctr = 0;
for (auto it : parser) {
if (ctr == 0) {
Assert(it.is("first"), "Expected 'first'");
} else {
Assert(false, "Didn't expect to get here");
}
++ctr;
}
}
Test(PinOptionParsing, TwoArg1) {
const char* input = "first;second";
char tmp[20];
int n = snprintf(tmp, 20, "%s", input);
Pins::PinOptionsParser parser(tmp, tmp + n);
{
auto opt = parser.begin();
auto endopt = parser.end();
Assert(opt != endopt, "Expected an argument");
Assert(opt->is("first"), "Expected 'first'");
++opt;
Assert(opt != endopt, "Expected second argument");
Assert(opt->is("second"), "Expected 'second'");
++opt;
Assert(opt == endopt, "Expected one argument");
}
// Typical use is a for loop. Let's test the two ways to use it:
int ctr = 0;
for (auto it : parser) {
if (ctr == 0) {
Assert(it.is("first"), "Expected 'first'");
} else if (ctr == 1) {
Assert(it.is("second"), "Expected 'second'");
} else {
Assert(false, "Didn't expect to get here");
}
++ctr;
}
}
Test(PinOptionParsing, TwoArg2) {
const char* input = "first:second";
char tmp[20];
int n = snprintf(tmp, 20, "%s", input);
Pins::PinOptionsParser parser(tmp, tmp + n);
{
auto opt = parser.begin();
auto endopt = parser.end();
Assert(opt != endopt, "Expected an argument");
Assert(opt->is("first"), "Expected 'first'");
++opt;
Assert(opt != endopt, "Expected second argument");
Assert(opt->is("second"), "Expected 'second'");
++opt;
Assert(opt == endopt, "Expected one argument");
}
// Typical use is a for loop. Let's test the two ways to use it:
int ctr = 0;
for (auto it : parser) {
if (ctr == 0) {
Assert(it.is("first"), "Expected 'first'");
}
else if (ctr == 1) {
Assert(it.is("second"), "Expected 'second'");
}
else {
Assert(false, "Didn't expect to get here");
}
++ctr;
}
}
}

View File

@@ -73,6 +73,7 @@
<ClCompile Include="Grbl_Esp32\test\Pins\BasicGPIO.cpp" />
<ClCompile Include="Grbl_Esp32\test\Pins\Error.cpp" />
<ClCompile Include="Grbl_Esp32\test\Pins\GPIO.cpp" />
<ClCompile Include="Grbl_Esp32\test\Pins\PinOptionParsing.cpp" />
<ClCompile Include="Grbl_Esp32\test\Pins\Undefined.cpp" />
<ClCompile Include="Grbl_Esp32\test\TestFactory.cpp" />
<ClCompile Include="Grbl_Esp32\test\TestFrameworkTest.cpp" />

View File

@@ -143,6 +143,9 @@
<ClCompile Include="X86TestSupport\Arduino.cpp">
<Filter>X86TestSupport</Filter>
</ClCompile>
<ClCompile Include="Grbl_Esp32\test\Pins\PinOptionParsing.cpp">
<Filter>test\Pins</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="Grbl_Esp32\test\UnitTests.md">