From 4104f0e42864b09c9043747a7608a358e9b4d124 Mon Sep 17 00:00:00 2001 From: Ian Katz Date: Tue, 29 Jan 2019 08:10:38 -0500 Subject: [PATCH 1/7] Include keepachangelog_manager gem for CHANGELOG.md updating --- CHANGELOG.md | 1 + CONTRIBUTING.md | 2 +- arduino_ci.gemspec | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06a64cf3..3d3e5882 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `ArduinoInstallation::force_install` now optionally accepts a version string - `arduino_library_location.rb` script to print Arduino library location to stdout - `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. +- `keepachangelog_manager` gem to begin streamlining the release process ### Changed - Unit tests and examples are now executed alphabetically by filename diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f8ff2239..e8f6a2ae 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -32,8 +32,8 @@ See `SampleProjects/TestSomething/test/*.cpp` for the existing tests (run by rsp * Merge pull request with new features * `git stash save` (at least before the gem build step, but easiest here). * `git pull --rebase` +* Update the sections of `CHANGELOG.md` by running `bundle exec keepachangelog_release.md --increment-patch` * 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) -* Update the sections of `CHANGELOG.md` * `git add README.md CHANGELOG.md lib/arduino_ci/version.rb` * `git commit -m "vVERSION bump"` * `git tag -a vVERSION -m "Released version VERSION"` diff --git a/arduino_ci.gemspec b/arduino_ci.gemspec index 5e56d987..769b77f4 100644 --- a/arduino_ci.gemspec +++ b/arduino_ci.gemspec @@ -29,6 +29,7 @@ Gem::Specification.new do |spec| spec.add_dependency "rubyzip", "~> 1.2" spec.add_development_dependency "bundler", "~> 1.15" + spec.add_development_dependency "keepachangelog_manager", "~> 0.0.1" spec.add_development_dependency "rspec", "~> 3.0" spec.add_development_dependency 'rubocop', '~>0.59.0' spec.add_development_dependency 'yard', '~>0.9.11' From a2857af912dbddabd36b58770b3baa711d3a6d87 Mon Sep 17 00:00:00 2001 From: Ian Katz Date: Tue, 29 Jan 2019 08:28:07 -0500 Subject: [PATCH 2/7] Add ability to suppress annoying splash screen during (local) testing --- CHANGELOG.md | 1 + spec/arduino_cmd_spec.rb | 2 ++ spec/arduino_installation_spec.rb | 2 ++ spec/spec_helper.rb | 4 ++++ 4 files changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d3e5882..26ad4e2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `arduino_library_location.rb` script to print Arduino library location to stdout - `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. - `keepachangelog_manager` gem to begin streamlining the release process +- Added rspec sensitivity to the environment variable `$ARDUINO_CI_SKIP_SPLASH_SCREEN_RSPEC_TESTS` (for `arduino_ci` gem hackers) ### Changed - Unit tests and examples are now executed alphabetically by filename diff --git a/spec/arduino_cmd_spec.rb b/spec/arduino_cmd_spec.rb index bbade553..360e7165 100644 --- a/spec/arduino_cmd_spec.rb +++ b/spec/arduino_cmd_spec.rb @@ -7,6 +7,8 @@ def get_sketch(dir, file) RSpec.describe ArduinoCI::ArduinoCmd do + next if skip_splash_screen_tests + arduino_cmd = ArduinoCI::ArduinoInstallation.autolocate! after(:each) do |example| diff --git a/spec/arduino_installation_spec.rb b/spec/arduino_installation_spec.rb index 86dd86aa..d76fa3af 100644 --- a/spec/arduino_installation_spec.rb +++ b/spec/arduino_installation_spec.rb @@ -1,6 +1,8 @@ require "spec_helper" RSpec.describe ArduinoCI::ArduinoInstallation do + next if skip_splash_screen_tests + context "autolocate" do it "doesn't fail" do ArduinoCI::ArduinoInstallation.autolocate diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 77b061d4..09f19259 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -12,3 +12,7 @@ c.syntax = :expect end end + +def skip_splash_screen_tests + !ENV["ARDUINO_CI_SKIP_SPLASH_SCREEN_RSPEC_TESTS"].nil? +end From b9d71b736385b40083cb75410adbfda62616efd8 Mon Sep 17 00:00:00 2001 From: Ian Katz Date: Tue, 29 Jan 2019 08:37:56 -0500 Subject: [PATCH 3/7] fix indentation --- cpp/unittest/ArduinoUnitTests.h | 46 ++++++++++++++++----------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/cpp/unittest/ArduinoUnitTests.h b/cpp/unittest/ArduinoUnitTests.h index 29a4e77f..ac81a1dd 100644 --- a/cpp/unittest/ArduinoUnitTests.h +++ b/cpp/unittest/ArduinoUnitTests.h @@ -69,29 +69,29 @@ class Test } template void onAssert( - const char* file, - int line, - const char* description, - bool pass, - const char* lhsRelevance, - const char* lhsLabel, - const A &lhs, - const char* opLabel, - const char* rhsRelevance, - const char* rhsLabel, - const B &rhs - ) { - cerr << " " << (pass ? "" : "not ") << "ok " << ++mAssertCounter << " - "; - cerr << description << " " << lhsLabel << " " << opLabel << " " << rhsLabel << endl; - if (!pass) { - cerr << " ---" << endl; - cerr << " operator: " << opLabel << endl; - cerr << " " << lhsRelevance << ": " << lhs << endl; - cerr << " " << rhsRelevance << ": " << rhs << endl; - cerr << " at:" << endl; - cerr << " file: " << file << endl; - cerr << " line: " << line << endl; - cerr << " ..." << endl; + const char* file, + int line, + const char* description, + bool pass, + const char* lhsRelevance, + const char* lhsLabel, + const A &lhs, + const char* opLabel, + const char* rhsRelevance, + const char* rhsLabel, + const B &rhs + ) { + cerr << " " << (pass ? "" : "not ") << "ok " << ++mAssertCounter << " - "; + cerr << description << " " << lhsLabel << " " << opLabel << " " << rhsLabel << endl; + if (!pass) { + cerr << " ---" << endl; + cerr << " operator: " << opLabel << endl; + cerr << " " << lhsRelevance << ": " << lhs << endl; + cerr << " " << rhsRelevance << ": " << rhs << endl; + cerr << " at:" << endl; + cerr << " file: " << file << endl; + cerr << " line: " << line << endl; + cerr << " ..." << endl; } } }; From 707c94d8c0509dae869070a2714069a7dcd55168 Mon Sep 17 00:00:00 2001 From: Ian Katz Date: Tue, 29 Jan 2019 08:38:40 -0500 Subject: [PATCH 4/7] Fix setup and teardown example --- CHANGELOG.md | 1 + ...d_treardown.cpp => setup_and_teardown.cpp} | 58 ++++++++++++------- 2 files changed, 38 insertions(+), 21 deletions(-) rename SampleProjects/TestSomething/test/{setup_and_treardown.cpp => setup_and_teardown.cpp} (57%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26ad4e2c..ea9bb5bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `arduino_library_location.rb` script to print Arduino library location to stdout - `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. - `keepachangelog_manager` gem to begin streamlining the release process +- `unittest_setup()` and `unittest_teardown()` macros, my thanks to @hlovdal for contributing this code - Added rspec sensitivity to the environment variable `$ARDUINO_CI_SKIP_SPLASH_SCREEN_RSPEC_TESTS` (for `arduino_ci` gem hackers) ### Changed diff --git a/SampleProjects/TestSomething/test/setup_and_treardown.cpp b/SampleProjects/TestSomething/test/setup_and_teardown.cpp similarity index 57% rename from SampleProjects/TestSomething/test/setup_and_treardown.cpp rename to SampleProjects/TestSomething/test/setup_and_teardown.cpp index 7a644e71..ce519a46 100644 --- a/SampleProjects/TestSomething/test/setup_and_treardown.cpp +++ b/SampleProjects/TestSomething/test/setup_and_teardown.cpp @@ -8,35 +8,56 @@ class LcdInterface { class MockLcd : public LcdInterface { public: - void print(const char *) {} + String s; + void print(const char* c) + { + s = String(c); + } }; -LcdInterface *Lcd_p; - class Calculator { + private: + LcdInterface *m_lcd; + public: - int add(int a, int b) { - int result = a + b; - char buf[40]; - sprintf(buf, "%d + %d = %d", a, b, result); - Lcd_p->print(buf); - return result; + Calculator(LcdInterface* lcd) { + m_lcd = lcd; + } + + ~Calculator() { + m_lcd = 0; + } + + int add(int a, int b) + { + int result = a + b; + char buf[40]; + sprintf(buf, "%d + %d = %d", a, b, result); + m_lcd->print(buf); + return result; } }; + +// This is a typical test where using setup (and teardown) would be useful +// to set up the "external" lcd dependency that the calculator uses indirectly +// but it is not something that is related to the functionality that is tested. + +MockLcd* lcd_p; +Calculator* c; + unittest_setup() { - Lcd_p = new MockLcd(); + lcd_p = new MockLcd(); + c = new Calculator(lcd_p); } unittest_teardown() { - delete Lcd_p; + delete c; + delete lcd_p; } -// This is a typical test where using setup (and teardown) would be useful -// to set up the "external" lcd dependency that the calculator uses indirectly -// but it is not something that is related to the functionality that is tested. // When you want to test that the calculator actually prints the calculations, // then that should be done in the arrange part of the actual test (by setting @@ -44,14 +65,9 @@ unittest_teardown() unittest(add) { - // Arrange - Calculator c; - - // Act - int result = c.add(11, 22); - - // Assert + int result = c->add(11, 22); assertEqual(33, result); + assertEqual("11 + 22 = 33", lcd_p->s); } unittest_main() From df838ba48babb4895bb7f47815cd5b362d2cf0ab Mon Sep 17 00:00:00 2001 From: Ian Katz Date: Tue, 29 Jan 2019 08:41:35 -0500 Subject: [PATCH 5/7] Split interrupts testing into its own file --- CHANGELOG.md | 1 + SampleProjects/TestSomething/test/godmode.cpp | 22 --------------- .../TestSomething/test/interrupts.cpp | 28 +++++++++++++++++++ 3 files changed, 29 insertions(+), 22 deletions(-) create mode 100644 SampleProjects/TestSomething/test/interrupts.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index ea9bb5bd..27c42eea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed - Unit tests and examples are now executed alphabetically by filename - The `pgm_read_...` preprocessor macros in cpp/arduino/avr/pgmspace.h now expands to an expression with applicable type. +- Unit tests for interrupts (`attachInterrupt` and `detachInterrupt`) get their own file ### Deprecated diff --git a/SampleProjects/TestSomething/test/godmode.cpp b/SampleProjects/TestSomething/test/godmode.cpp index e4cf69e2..ab177df3 100644 --- a/SampleProjects/TestSomething/test/godmode.cpp +++ b/SampleProjects/TestSomething/test/godmode.cpp @@ -34,17 +34,6 @@ unittest(random) assertEqual(state->seed, 4294967282); } -void myInterruptHandler() { -} - -unittest(interrupts) -{ - // these are meaningless for testing; just call the routine directly. - // make sure our mocks work though - attachInterrupt(2, myInterruptHandler, CHANGE); - detachInterrupt(2); -} - unittest(pins) { GodmodeState* state = GODMODE(); @@ -172,17 +161,6 @@ unittest(pin_write_history) } -unittest(interrupt_attachment) { - GodmodeState *state = GODMODE(); - state->reset(); - assertFalse(state->interrupt[0].attached); - attachInterrupt(0, (void (*)(void))0, 3); - assertTrue(state->interrupt[0].attached); - assertEqual(state->interrupt[0].mode, 3); - detachInterrupt(0); - assertFalse(state->interrupt[0].attached); -} - unittest(spi) { GodmodeState *state = GODMODE(); state->reset(); diff --git a/SampleProjects/TestSomething/test/interrupts.cpp b/SampleProjects/TestSomething/test/interrupts.cpp new file mode 100644 index 00000000..0a558d84 --- /dev/null +++ b/SampleProjects/TestSomething/test/interrupts.cpp @@ -0,0 +1,28 @@ +#include +#include + +void myInterruptHandler() { +} + +unittest(interrupts) +{ + // these are meaningless for testing; just call the routine directly. + // make sure our mocks work though + attachInterrupt(2, myInterruptHandler, CHANGE); + detachInterrupt(2); +} + +unittest(interrupt_attachment) { + GodmodeState *state = GODMODE(); + state->reset(); + assertFalse(state->interrupt[0].attached); + attachInterrupt(0, (void (*)(void))0, 3); + assertTrue(state->interrupt[0].attached); + assertEqual(state->interrupt[0].mode, 3); + detachInterrupt(0); + assertFalse(state->interrupt[0].attached); +} + + + +unittest_main() From 5a7029c4716c9bf6f7e0b027cabb23608210ecbe Mon Sep 17 00:00:00 2001 From: Ian Katz Date: Tue, 29 Jan 2019 11:57:24 -0500 Subject: [PATCH 6/7] Add more skippability to rspec --- CHANGELOG.md | 2 ++ spec/arduino_ci_spec.rb | 2 ++ spec/arduino_cmd_spec.rb | 1 + spec/arduino_downloader_spec.rb | 3 +++ spec/arduino_installation_spec.rb | 1 + spec/ci_config_spec.rb | 1 + spec/cpp_library_spec.rb | 1 + spec/spec_helper.rb | 8 ++++++++ spec/testsomething_unittests_spec.rb | 1 + 9 files changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27c42eea..cf973f9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `keepachangelog_manager` gem to begin streamlining the release process - `unittest_setup()` and `unittest_teardown()` macros, my thanks to @hlovdal for contributing this code - Added rspec sensitivity to the environment variable `$ARDUINO_CI_SKIP_SPLASH_SCREEN_RSPEC_TESTS` (for `arduino_ci` gem hackers) +- Added rspec sensitivity to the environment variable `$ARDUINO_CI_SKIP_RUBY_RSPEC_TESTS` (for `arduino_ci` gem hackers) +- Added rspec sensitivity to the environment variable `$ARDUINO_CI_SKIP_CPP_RSPEC_TESTS` (for `arduino_ci` gem hackers) ### Changed - Unit tests and examples are now executed alphabetically by filename diff --git a/spec/arduino_ci_spec.rb b/spec/arduino_ci_spec.rb index e63fca26..05b97fd2 100644 --- a/spec/arduino_ci_spec.rb +++ b/spec/arduino_ci_spec.rb @@ -1,6 +1,7 @@ require "spec_helper" RSpec.describe ArduinoCI do + next if skip_ruby_tests context "gem" do it "has a version number" do expect(ArduinoCI::VERSION).not_to be nil @@ -9,6 +10,7 @@ end RSpec.describe ArduinoCI::Host do + next if skip_ruby_tests context "which" do it "can find things with which" do ruby_path = ArduinoCI::Host.which("ruby") diff --git a/spec/arduino_cmd_spec.rb b/spec/arduino_cmd_spec.rb index 360e7165..1b098694 100644 --- a/spec/arduino_cmd_spec.rb +++ b/spec/arduino_cmd_spec.rb @@ -7,6 +7,7 @@ def get_sketch(dir, file) RSpec.describe ArduinoCI::ArduinoCmd do + next if skip_ruby_tests next if skip_splash_screen_tests arduino_cmd = ArduinoCI::ArduinoInstallation.autolocate! diff --git a/spec/arduino_downloader_spec.rb b/spec/arduino_downloader_spec.rb index 693d5816..442b2bfc 100644 --- a/spec/arduino_downloader_spec.rb +++ b/spec/arduino_downloader_spec.rb @@ -2,6 +2,7 @@ DESIRED_VERSION = "rhubarb" RSpec.describe ArduinoCI::ArduinoDownloader do + next if skip_ruby_tests context "Basics" do it "has correct class properties" do ad = ArduinoCI::ArduinoDownloader @@ -24,6 +25,7 @@ end RSpec.describe ArduinoCI::ArduinoDownloaderLinux do + next if skip_ruby_tests context "Basics" do it "has correct class properties" do ad = ArduinoCI::ArduinoDownloaderLinux @@ -49,6 +51,7 @@ end RSpec.describe ArduinoCI::ArduinoDownloaderOSX do + next if skip_ruby_tests context "Basics" do it "has correct class properties" do ad = ArduinoCI::ArduinoDownloaderOSX diff --git a/spec/arduino_installation_spec.rb b/spec/arduino_installation_spec.rb index d76fa3af..551dc47f 100644 --- a/spec/arduino_installation_spec.rb +++ b/spec/arduino_installation_spec.rb @@ -1,6 +1,7 @@ require "spec_helper" RSpec.describe ArduinoCI::ArduinoInstallation do + next if skip_ruby_tests next if skip_splash_screen_tests context "autolocate" do diff --git a/spec/ci_config_spec.rb b/spec/ci_config_spec.rb index 35e39e20..bec81f02 100644 --- a/spec/ci_config_spec.rb +++ b/spec/ci_config_spec.rb @@ -2,6 +2,7 @@ require "pathname" RSpec.describe ArduinoCI::CIConfig do + next if skip_ruby_tests context "default" do it "loads from yaml" do default_config = ArduinoCI::CIConfig.default diff --git a/spec/cpp_library_spec.rb b/spec/cpp_library_spec.rb index 572d05f9..8044486a 100644 --- a/spec/cpp_library_spec.rb +++ b/spec/cpp_library_spec.rb @@ -11,6 +11,7 @@ def get_relative_dir(sampleprojects_tests_dir) end RSpec.describe ArduinoCI::CppLibrary do + next if skip_ruby_tests cpp_lib_path = sampleproj_path + "DoSomething" cpp_library = ArduinoCI::CppLibrary.new(cpp_lib_path, Pathname.new("my_fake_arduino_lib_dir")) context "cpp_files" do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 09f19259..eb6f5631 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -16,3 +16,11 @@ def skip_splash_screen_tests !ENV["ARDUINO_CI_SKIP_SPLASH_SCREEN_RSPEC_TESTS"].nil? end + +def skip_ruby_tests + !ENV["ARDUINO_CI_SKIP_RUBY_RSPEC_TESTS"].nil? +end + +def skip_cpp_tests + !ENV["ARDUINO_CI_SKIP_CPP_RSPEC_TESTS"].nil? +end diff --git a/spec/testsomething_unittests_spec.rb b/spec/testsomething_unittests_spec.rb index 0e616e53..3cd16678 100644 --- a/spec/testsomething_unittests_spec.rb +++ b/spec/testsomething_unittests_spec.rb @@ -11,6 +11,7 @@ def get_relative_dir(sampleprojects_tests_dir) end RSpec.describe "TestSomething C++" do + next if skip_cpp_tests cpp_lib_path = sampleproj_path + "TestSomething" cpp_library = ArduinoCI::CppLibrary.new(cpp_lib_path, Pathname.new("my_fake_arduino_lib_dir")) context "cpp_files" do From 31bfc62b0b29cfe5b0c03a99e454781351ad92f2 Mon Sep 17 00:00:00 2001 From: Ian Katz Date: Tue, 29 Jan 2019 12:14:04 -0500 Subject: [PATCH 7/7] Add nullptr and assertNull() --- CHANGELOG.md | 2 ++ SampleProjects/TestSomething/test/null.cpp | 7 +++++++ cpp/arduino/Arduino.h | 2 ++ cpp/unittest/Assertion.h | 2 ++ 4 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf973f9d..7503fa0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added rspec sensitivity to the environment variable `$ARDUINO_CI_SKIP_SPLASH_SCREEN_RSPEC_TESTS` (for `arduino_ci` gem hackers) - Added rspec sensitivity to the environment variable `$ARDUINO_CI_SKIP_RUBY_RSPEC_TESTS` (for `arduino_ci` gem hackers) - Added rspec sensitivity to the environment variable `$ARDUINO_CI_SKIP_CPP_RSPEC_TESTS` (for `arduino_ci` gem hackers) +- `nullptr` definition in C++ +- `assertNull()` for unit tests ### Changed - Unit tests and examples are now executed alphabetically by filename diff --git a/SampleProjects/TestSomething/test/null.cpp b/SampleProjects/TestSomething/test/null.cpp index f9c5e59a..27292fe6 100644 --- a/SampleProjects/TestSomething/test/null.cpp +++ b/SampleProjects/TestSomething/test/null.cpp @@ -19,4 +19,11 @@ unittest(nothing) { } +unittest(nullpointer) +{ + int* myPointer = NULL; + assertNull(myPointer); + assertNull(nullptr); +} + unittest_main() diff --git a/cpp/arduino/Arduino.h b/cpp/arduino/Arduino.h index 0eb0796a..7cc69a58 100644 --- a/cpp/arduino/Arduino.h +++ b/cpp/arduino/Arduino.h @@ -72,5 +72,7 @@ inline unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8) #define word(...) makeWord(__VA_ARGS__) +// Define C++11 nullptr +#define nullptr (std::nullptr_t)NULL diff --git a/cpp/unittest/Assertion.h b/cpp/unittest/Assertion.h index 1e9e6b16..1231e760 100644 --- a/cpp/unittest/Assertion.h +++ b/cpp/unittest/Assertion.h @@ -38,6 +38,7 @@ #define assertMoreOrEqual(arg1,arg2) assertOp("assertMoreOrEqual","upperBound",arg1,compareMoreOrEqual,">=","lowerBound",arg2) #define assertTrue(arg) assertEqual(true, arg) #define assertFalse(arg) assertEqual(false, arg) +#define assertNull(arg) assertEqual((void*)NULL, (void*)arg) /** macro generates optional output and calls fail() followed by a return if false. */ #define assureEqual(arg1,arg2) assureOp("assureEqual","expected",arg1,compareEqual,"==","actual",arg2) @@ -48,4 +49,5 @@ #define assureMoreOrEqual(arg1,arg2) assureOp("assureMoreOrEqual","upperBound",arg1,compareMoreOrEqual,">=","lowerBound",arg2) #define assureTrue(arg) assureEqual(true, arg) #define assureFalse(arg) assureEqual(false, arg) +#define assureNull(arg) assureEqual((void*)NULL, (void*)arg)