Skip to content

Commit e97e682

Browse files
authored
Merge pull request #103 from ianfixes/2019-01-29_updates
Unit test additions (both Ruby and C++)
2 parents 429fe9d + 31bfc62 commit e97e682

18 files changed

+135
-67
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1010
- `ArduinoInstallation::force_install` now optionally accepts a version string
1111
- `arduino_library_location.rb` script to print Arduino library location to stdout
1212
- `arduino_ci_remote.rb` now supports `--skip-unittests` and `--skip-compilation`. If you skip both, only the `autolocate!` of the Arduino binary will be performed.
13+
- `keepachangelog_manager` gem to begin streamlining the release process
14+
- `unittest_setup()` and `unittest_teardown()` macros, my thanks to @hlovdal for contributing this code
15+
- Added rspec sensitivity to the environment variable `$ARDUINO_CI_SKIP_SPLASH_SCREEN_RSPEC_TESTS` (for `arduino_ci` gem hackers)
16+
- Added rspec sensitivity to the environment variable `$ARDUINO_CI_SKIP_RUBY_RSPEC_TESTS` (for `arduino_ci` gem hackers)
17+
- Added rspec sensitivity to the environment variable `$ARDUINO_CI_SKIP_CPP_RSPEC_TESTS` (for `arduino_ci` gem hackers)
18+
- `nullptr` definition in C++
19+
- `assertNull()` for unit tests
1320

1421
### Changed
1522
- Unit tests and examples are now executed alphabetically by filename
1623
- The `pgm_read_...` preprocessor macros in cpp/arduino/avr/pgmspace.h now expands to an expression with applicable type.
24+
- Unit tests for interrupts (`attachInterrupt` and `detachInterrupt`) get their own file
1725

1826
### Deprecated
1927

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ See `SampleProjects/TestSomething/test/*.cpp` for the existing tests (run by rsp
3232
* Merge pull request with new features
3333
* `git stash save` (at least before the gem build step, but easiest here).
3434
* `git pull --rebase`
35+
* Update the sections of `CHANGELOG.md` by running `bundle exec keepachangelog_release.md --increment-patch`
3536
* Bump the version in lib/arduino_ci/version.rb and change it in README.md (since rubydoc.info doesn't always redirect to the latest version)
36-
* Update the sections of `CHANGELOG.md`
3737
* `git add README.md CHANGELOG.md lib/arduino_ci/version.rb`
3838
* `git commit -m "vVERSION bump"`
3939
* `git tag -a vVERSION -m "Released version VERSION"`

SampleProjects/TestSomething/test/godmode.cpp

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,6 @@ unittest(random)
3434
assertEqual(state->seed, 4294967282);
3535
}
3636

37-
void myInterruptHandler() {
38-
}
39-
40-
unittest(interrupts)
41-
{
42-
// these are meaningless for testing; just call the routine directly.
43-
// make sure our mocks work though
44-
attachInterrupt(2, myInterruptHandler, CHANGE);
45-
detachInterrupt(2);
46-
}
47-
4837
unittest(pins)
4938
{
5039
GodmodeState* state = GODMODE();
@@ -172,17 +161,6 @@ unittest(pin_write_history)
172161

173162
}
174163

175-
unittest(interrupt_attachment) {
176-
GodmodeState *state = GODMODE();
177-
state->reset();
178-
assertFalse(state->interrupt[0].attached);
179-
attachInterrupt(0, (void (*)(void))0, 3);
180-
assertTrue(state->interrupt[0].attached);
181-
assertEqual(state->interrupt[0].mode, 3);
182-
detachInterrupt(0);
183-
assertFalse(state->interrupt[0].attached);
184-
}
185-
186164
unittest(spi) {
187165
GodmodeState *state = GODMODE();
188166
state->reset();
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include <ArduinoUnitTests.h>
2+
#include <Arduino.h>
3+
4+
void myInterruptHandler() {
5+
}
6+
7+
unittest(interrupts)
8+
{
9+
// these are meaningless for testing; just call the routine directly.
10+
// make sure our mocks work though
11+
attachInterrupt(2, myInterruptHandler, CHANGE);
12+
detachInterrupt(2);
13+
}
14+
15+
unittest(interrupt_attachment) {
16+
GodmodeState *state = GODMODE();
17+
state->reset();
18+
assertFalse(state->interrupt[0].attached);
19+
attachInterrupt(0, (void (*)(void))0, 3);
20+
assertTrue(state->interrupt[0].attached);
21+
assertEqual(state->interrupt[0].mode, 3);
22+
detachInterrupt(0);
23+
assertFalse(state->interrupt[0].attached);
24+
}
25+
26+
27+
28+
unittest_main()

SampleProjects/TestSomething/test/null.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,11 @@ unittest(nothing)
1919
{
2020
}
2121

22+
unittest(nullpointer)
23+
{
24+
int* myPointer = NULL;
25+
assertNull(myPointer);
26+
assertNull(nullptr);
27+
}
28+
2229
unittest_main()

SampleProjects/TestSomething/test/setup_and_treardown.cpp renamed to SampleProjects/TestSomething/test/setup_and_teardown.cpp

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,50 +8,66 @@ class LcdInterface {
88

99
class MockLcd : public LcdInterface {
1010
public:
11-
void print(const char *) {}
11+
String s;
12+
void print(const char* c)
13+
{
14+
s = String(c);
15+
}
1216
};
1317

14-
LcdInterface *Lcd_p;
15-
1618
class Calculator {
19+
private:
20+
LcdInterface *m_lcd;
21+
1722
public:
18-
int add(int a, int b) {
19-
int result = a + b;
20-
char buf[40];
21-
sprintf(buf, "%d + %d = %d", a, b, result);
22-
Lcd_p->print(buf);
23-
return result;
23+
Calculator(LcdInterface* lcd) {
24+
m_lcd = lcd;
25+
}
26+
27+
~Calculator() {
28+
m_lcd = 0;
29+
}
30+
31+
int add(int a, int b)
32+
{
33+
int result = a + b;
34+
char buf[40];
35+
sprintf(buf, "%d + %d = %d", a, b, result);
36+
m_lcd->print(buf);
37+
return result;
2438
}
2539
};
2640

41+
42+
// This is a typical test where using setup (and teardown) would be useful
43+
// to set up the "external" lcd dependency that the calculator uses indirectly
44+
// but it is not something that is related to the functionality that is tested.
45+
46+
MockLcd* lcd_p;
47+
Calculator* c;
48+
2749
unittest_setup()
2850
{
29-
Lcd_p = new MockLcd();
51+
lcd_p = new MockLcd();
52+
c = new Calculator(lcd_p);
3053
}
3154

3255
unittest_teardown()
3356
{
34-
delete Lcd_p;
57+
delete c;
58+
delete lcd_p;
3559
}
3660

37-
// This is a typical test where using setup (and teardown) would be useful
38-
// to set up the "external" lcd dependency that the calculator uses indirectly
39-
// but it is not something that is related to the functionality that is tested.
4061

4162
// When you want to test that the calculator actually prints the calculations,
4263
// then that should be done in the arrange part of the actual test (by setting
4364
// up an mock lcd class that keeps a list of all messages printed).
4465

4566
unittest(add)
4667
{
47-
// Arrange
48-
Calculator c;
49-
50-
// Act
51-
int result = c.add(11, 22);
52-
53-
// Assert
68+
int result = c->add(11, 22);
5469
assertEqual(33, result);
70+
assertEqual("11 + 22 = 33", lcd_p->s);
5571
}
5672

5773
unittest_main()

arduino_ci.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
2929
spec.add_dependency "rubyzip", "~> 1.2"
3030

3131
spec.add_development_dependency "bundler", "~> 1.15"
32+
spec.add_development_dependency "keepachangelog_manager", "~> 0.0.1"
3233
spec.add_development_dependency "rspec", "~> 3.0"
3334
spec.add_development_dependency 'rubocop', '~>0.59.0'
3435
spec.add_development_dependency 'yard', '~>0.9.11'

cpp/arduino/Arduino.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,7 @@ inline unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8)
7272
#define word(...) makeWord(__VA_ARGS__)
7373

7474

75+
// Define C++11 nullptr
76+
#define nullptr (std::nullptr_t)NULL
7577

7678

cpp/unittest/ArduinoUnitTests.h

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -69,29 +69,29 @@ class Test
6969
}
7070

7171
template <typename A, typename B> void onAssert(
72-
const char* file,
73-
int line,
74-
const char* description,
75-
bool pass,
76-
const char* lhsRelevance,
77-
const char* lhsLabel,
78-
const A &lhs,
79-
const char* opLabel,
80-
const char* rhsRelevance,
81-
const char* rhsLabel,
82-
const B &rhs
83-
) {
84-
cerr << " " << (pass ? "" : "not ") << "ok " << ++mAssertCounter << " - ";
85-
cerr << description << " " << lhsLabel << " " << opLabel << " " << rhsLabel << endl;
86-
if (!pass) {
87-
cerr << " ---" << endl;
88-
cerr << " operator: " << opLabel << endl;
89-
cerr << " " << lhsRelevance << ": " << lhs << endl;
90-
cerr << " " << rhsRelevance << ": " << rhs << endl;
91-
cerr << " at:" << endl;
92-
cerr << " file: " << file << endl;
93-
cerr << " line: " << line << endl;
94-
cerr << " ..." << endl;
72+
const char* file,
73+
int line,
74+
const char* description,
75+
bool pass,
76+
const char* lhsRelevance,
77+
const char* lhsLabel,
78+
const A &lhs,
79+
const char* opLabel,
80+
const char* rhsRelevance,
81+
const char* rhsLabel,
82+
const B &rhs
83+
) {
84+
cerr << " " << (pass ? "" : "not ") << "ok " << ++mAssertCounter << " - ";
85+
cerr << description << " " << lhsLabel << " " << opLabel << " " << rhsLabel << endl;
86+
if (!pass) {
87+
cerr << " ---" << endl;
88+
cerr << " operator: " << opLabel << endl;
89+
cerr << " " << lhsRelevance << ": " << lhs << endl;
90+
cerr << " " << rhsRelevance << ": " << rhs << endl;
91+
cerr << " at:" << endl;
92+
cerr << " file: " << file << endl;
93+
cerr << " line: " << line << endl;
94+
cerr << " ..." << endl;
9595
}
9696
}
9797
};

cpp/unittest/Assertion.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#define assertMoreOrEqual(arg1,arg2) assertOp("assertMoreOrEqual","upperBound",arg1,compareMoreOrEqual,">=","lowerBound",arg2)
3939
#define assertTrue(arg) assertEqual(true, arg)
4040
#define assertFalse(arg) assertEqual(false, arg)
41+
#define assertNull(arg) assertEqual((void*)NULL, (void*)arg)
4142

4243
/** macro generates optional output and calls fail() followed by a return if false. */
4344
#define assureEqual(arg1,arg2) assureOp("assureEqual","expected",arg1,compareEqual,"==","actual",arg2)
@@ -48,4 +49,5 @@
4849
#define assureMoreOrEqual(arg1,arg2) assureOp("assureMoreOrEqual","upperBound",arg1,compareMoreOrEqual,">=","lowerBound",arg2)
4950
#define assureTrue(arg) assureEqual(true, arg)
5051
#define assureFalse(arg) assureEqual(false, arg)
52+
#define assureNull(arg) assureEqual((void*)NULL, (void*)arg)
5153

0 commit comments

Comments
 (0)