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

spec/arduino_ci_spec.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require "spec_helper"
22

33
RSpec.describe ArduinoCI do
4+
next if skip_ruby_tests
45
context "gem" do
56
it "has a version number" do
67
expect(ArduinoCI::VERSION).not_to be nil
@@ -9,6 +10,7 @@
910
end
1011

1112
RSpec.describe ArduinoCI::Host do
13+
next if skip_ruby_tests
1214
context "which" do
1315
it "can find things with which" do
1416
ruby_path = ArduinoCI::Host.which("ruby")

spec/arduino_cmd_spec.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ def get_sketch(dir, file)
77

88

99
RSpec.describe ArduinoCI::ArduinoCmd do
10+
next if skip_ruby_tests
11+
next if skip_splash_screen_tests
12+
1013
arduino_cmd = ArduinoCI::ArduinoInstallation.autolocate!
1114

1215
after(:each) do |example|

spec/arduino_downloader_spec.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
DESIRED_VERSION = "rhubarb"
44
RSpec.describe ArduinoCI::ArduinoDownloader do
5+
next if skip_ruby_tests
56
context "Basics" do
67
it "has correct class properties" do
78
ad = ArduinoCI::ArduinoDownloader
@@ -24,6 +25,7 @@
2425
end
2526

2627
RSpec.describe ArduinoCI::ArduinoDownloaderLinux do
28+
next if skip_ruby_tests
2729
context "Basics" do
2830
it "has correct class properties" do
2931
ad = ArduinoCI::ArduinoDownloaderLinux
@@ -49,6 +51,7 @@
4951
end
5052

5153
RSpec.describe ArduinoCI::ArduinoDownloaderOSX do
54+
next if skip_ruby_tests
5255
context "Basics" do
5356
it "has correct class properties" do
5457
ad = ArduinoCI::ArduinoDownloaderOSX

spec/arduino_installation_spec.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
require "spec_helper"
22

33
RSpec.describe ArduinoCI::ArduinoInstallation do
4+
next if skip_ruby_tests
5+
next if skip_splash_screen_tests
6+
47
context "autolocate" do
58
it "doesn't fail" do
69
ArduinoCI::ArduinoInstallation.autolocate

spec/ci_config_spec.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
require "pathname"
33

44
RSpec.describe ArduinoCI::CIConfig do
5+
next if skip_ruby_tests
56
context "default" do
67
it "loads from yaml" do
78
default_config = ArduinoCI::CIConfig.default

spec/cpp_library_spec.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ def get_relative_dir(sampleprojects_tests_dir)
1111
end
1212

1313
RSpec.describe ArduinoCI::CppLibrary do
14+
next if skip_ruby_tests
1415
cpp_lib_path = sampleproj_path + "DoSomething"
1516
cpp_library = ArduinoCI::CppLibrary.new(cpp_lib_path, Pathname.new("my_fake_arduino_lib_dir"))
1617
context "cpp_files" do

spec/spec_helper.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,15 @@
1212
c.syntax = :expect
1313
end
1414
end
15+
16+
def skip_splash_screen_tests
17+
!ENV["ARDUINO_CI_SKIP_SPLASH_SCREEN_RSPEC_TESTS"].nil?
18+
end
19+
20+
def skip_ruby_tests
21+
!ENV["ARDUINO_CI_SKIP_RUBY_RSPEC_TESTS"].nil?
22+
end
23+
24+
def skip_cpp_tests
25+
!ENV["ARDUINO_CI_SKIP_CPP_RSPEC_TESTS"].nil?
26+
end

spec/testsomething_unittests_spec.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ def get_relative_dir(sampleprojects_tests_dir)
1111
end
1212

1313
RSpec.describe "TestSomething C++" do
14+
next if skip_cpp_tests
1415
cpp_lib_path = sampleproj_path + "TestSomething"
1516
cpp_library = ArduinoCI::CppLibrary.new(cpp_lib_path, Pathname.new("my_fake_arduino_lib_dir"))
1617
context "cpp_files" do

0 commit comments

Comments
 (0)