Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Unit test additions (both Ruby and C++) #103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jan 29, 2019
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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,18 @@ 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
- `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)
- `nullptr` definition in C++
- `assertNull()` for unit tests

### 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

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand Down
22 changes: 0 additions & 22 deletions SampleProjects/TestSomething/test/godmode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
28 changes: 28 additions & 0 deletions SampleProjects/TestSomething/test/interrupts.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include <ArduinoUnitTests.h>
#include <Arduino.h>

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()
7 changes: 7 additions & 0 deletions SampleProjects/TestSomething/test/null.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,11 @@ unittest(nothing)
{
}

unittest(nullpointer)
{
int* myPointer = NULL;
assertNull(myPointer);
assertNull(nullptr);
}

unittest_main()
Original file line number Diff line number Diff line change
Expand Up @@ -8,50 +8,66 @@ 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
// up an mock lcd class that keeps a list of all messages printed).

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()
1 change: 1 addition & 0 deletions arduino_ci.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
2 changes: 2 additions & 0 deletions cpp/arduino/Arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -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


46 changes: 23 additions & 23 deletions cpp/unittest/ArduinoUnitTests.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,29 +69,29 @@ class Test
}

template <typename A, typename B> 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;
}
}
};
Expand Down
2 changes: 2 additions & 0 deletions cpp/unittest/Assertion.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)

2 changes: 2 additions & 0 deletions spec/arduino_ci_spec.rb
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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")
Expand Down
3 changes: 3 additions & 0 deletions spec/arduino_cmd_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ 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!

after(:each) do |example|
Expand Down
3 changes: 3 additions & 0 deletions spec/arduino_downloader_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
3 changes: 3 additions & 0 deletions spec/arduino_installation_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
require "spec_helper"

RSpec.describe ArduinoCI::ArduinoInstallation do
next if skip_ruby_tests
next if skip_splash_screen_tests

context "autolocate" do
it "doesn't fail" do
ArduinoCI::ArduinoInstallation.autolocate
Expand Down
1 change: 1 addition & 0 deletions spec/ci_config_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions spec/cpp_library_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,15 @@
c.syntax = :expect
end
end

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
1 change: 1 addition & 0 deletions spec/testsomething_unittests_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down