Skip to content

Commit 4d17586

Browse files
authored
Merge pull request #116 from ianfixes/2019-02-20_timed_history
Add timestamps to pin histories (extensible to all settable items)
2 parents 997ae76 + bd37109 commit 4d17586

15 files changed

+561
-186
lines changed

CHANGELOG.md

+12
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,26 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99
### Added
10+
* `release-new-version.sh` script
11+
* outputs for `PinHistory` can now report timestamps
12+
* Fibonacci Clock for clock testing purposes (internal to this library)
1013

1114
### Changed
15+
* Shortened `ArduinoQueue` push and pop operations
16+
* `ci/Queue.h` is now `MockEventQueue.h`, with timing data
17+
* `MockEventQueue::Node` now contains struct `MockEventQueue::Event`, which contains both the templated type `T` and a field for a timestamp.
18+
* Construction of `MockEventQueue` now includes a constructor argument for the time-fetching function
19+
* Construction of `PinHistory` now includes a constructor argument for the time-fetching function
20+
* `PinHistory` can now return an array of timestamps for its events
21+
* `GodmodeState` is now a singleton pattern, which is necessary to support the globality of Arduino functions
22+
* `GodmodeState` now uses timestamped PinHistory for Analog and Digital
1223

1324
### Deprecated
1425

1526
### Removed
1627

1728
### Fixed
29+
* `ArduinoQueue` no longer leaks memory
1830

1931
### Security
2032

CONTRIBUTING.md

+13-12
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,17 @@ ARDUINO_CI_SKIP_RUBY_RSPEC_TESTS=1 bundle exec rspec
4646
## Packaging the Gem
4747

4848
* Merge pull request with new features
49-
* `git stash save` (at least before the gem build step, but easiest here).
50-
* `git pull --rebase`
51-
* Update the sections of `CHANGELOG.md` by running `bundle exec keepachangelog_manager.rb --increment-patch`
52-
* 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)
53-
* `git add README.md CHANGELOG.md lib/arduino_ci/version.rb`
54-
* `git commit -m "vVERSION bump"`
55-
* `git tag -a vVERSION -m "Released version VERSION"`
56-
* `gem build arduino_ci.gemspec`
57-
* `git stash pop`
58-
* `gem push arduino_ci-VERSION.gem`
59-
* `git push upstream`
60-
* `git push upstream --tags`
49+
* Execute `release-new-version.sh` with the appropriate argument (e.g. `--increment-patch`), which does the following:
50+
* `git stash save` (at least before the gem build step, but easiest here).
51+
* `git pull --rebase`
52+
* Update the sections of `CHANGELOG.md` by running `bundle exec keepachangelog_manager.rb --increment-patch`
53+
* 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)
54+
* `git add README.md CHANGELOG.md lib/arduino_ci/version.rb`
55+
* `git commit -m "vVERSION bump"`
56+
* `git tag -a vVERSION -m "Released version VERSION"`
57+
* `gem build arduino_ci.gemspec`
58+
* `git stash pop`
59+
* `gem push arduino_ci-VERSION.gem`
60+
* `git push upstream`
61+
* `git push upstream --tags`
6162
* Visit http://www.rubydoc.info/gems/arduino_ci/VERSION to initiate the doc generation process
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Purpose
2+
3+
These files are designed to test the Ruby gem itself, such that its basic tasks of library installation and compilation can be verified. (i.e., use minimal C++ files -- feature tests for C++ unittest/arduino code belong in `../TestSomething/test/`).
4+
5+
## Naming convention
6+
7+
Files in this directory are expected to have names that either contains "bad" if it is expected to fail or "good" if it is expected to pass. This provides a signal to `rspec` for how the code is expected to perform.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#pragma once
2+
3+
// fibbonacci clock
4+
unsigned long lastFakeMicros = 1;
5+
unsigned long fakeMicros = 0;
6+
7+
void resetFibClock() {
8+
lastFakeMicros = 1;
9+
fakeMicros = 0;
10+
}
11+
12+
unsigned long fibMicros() {
13+
unsigned long ret = lastFakeMicros + fakeMicros;
14+
lastFakeMicros = fakeMicros;
15+
fakeMicros = ret;
16+
return ret;
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include <ArduinoUnitTests.h>
2+
#include <Arduino.h>
3+
#include "fibonacciClock.h"
4+
5+
unittest(my_fib_clock)
6+
{
7+
resetFibClock();
8+
assertEqual(1, fibMicros());
9+
assertEqual(1, fibMicros());
10+
assertEqual(2, fibMicros());
11+
assertEqual(3, fibMicros());
12+
assertEqual(5, fibMicros());
13+
assertEqual(8, fibMicros());
14+
assertEqual(13, fibMicros());
15+
assertEqual(21, fibMicros());
16+
17+
// and again
18+
resetFibClock();
19+
assertEqual(1, fibMicros());
20+
assertEqual(1, fibMicros());
21+
assertEqual(2, fibMicros());
22+
}
23+
24+
25+
unittest_main()

SampleProjects/TestSomething/test/godmode.cpp

+37-30
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
#include <ArduinoUnitTests.h>
22
#include <Arduino.h>
3+
#include "fibonacciClock.h"
34

45
GodmodeState* state = GODMODE();
56

6-
unittest_setup()
7-
{
7+
unittest_setup() {
8+
resetFibClock();
89
state->reset();
910
}
1011

11-
unittest(millis_micros_and_delay)
12-
{
12+
unittest(millis_micros_and_delay) {
1313
assertEqual(0, millis());
1414
assertEqual(0, micros());
1515
delay(3);
@@ -20,8 +20,7 @@ unittest(millis_micros_and_delay)
2020
assertEqual(14000, micros());
2121
}
2222

23-
unittest(random)
24-
{
23+
unittest(random) {
2524
randomSeed(1);
2625
assertEqual(state->seed, 1);
2726

@@ -37,8 +36,7 @@ unittest(random)
3736
assertEqual(state->seed, 4294967282);
3837
}
3938

40-
unittest(pins)
41-
{
39+
unittest(pins) {
4240
pinMode(1, OUTPUT); // this is a no-op in unit tests. it's just here to prove compilation
4341
digitalWrite(1, HIGH);
4442
assertEqual(HIGH, state->digitalPin[1]);
@@ -64,8 +62,7 @@ unittest(pins)
6462
assertEqual(56, analogRead(1));
6563
}
6664

67-
unittest(pin_read_history)
68-
{
65+
unittest(pin_read_history) {
6966
int future[6] = {33, 22, 55, 11, 44, 66};
7067
state->analogPin[1].fromArray(future, 6);
7168
for (int i = 0; i < 6; ++i)
@@ -88,20 +85,20 @@ unittest(pin_read_history)
8885
}
8986
}
9087

91-
unittest(pin_write_history)
92-
{
88+
unittest(digital_pin_write_history_with_timing) {
9389
int numMoved;
90+
bool expectedD[6] = {LOW, HIGH, LOW, LOW, HIGH, HIGH};
91+
bool actualD[6];
92+
unsigned long expectedT[6] = {0, 1, 1, 2, 3, 5};
93+
unsigned long actualT[6];
9494

95-
// history for digital pin
96-
digitalWrite(1, HIGH);
97-
digitalWrite(1, LOW);
98-
digitalWrite(1, LOW);
99-
digitalWrite(1, HIGH);
100-
digitalWrite(1, HIGH);
95+
// history for digital pin. start from 1 since LOW is the initial value
96+
for (int i = 1; i < 6; ++i) {
97+
state->micros = fibMicros();
98+
digitalWrite(1, expectedD[i]);
99+
}
101100

102101
assertEqual(6, state->digitalPin[1].historySize());
103-
bool expectedD[6] = {LOW, HIGH, LOW, LOW, HIGH, HIGH};
104-
bool actualD[6];
105102
numMoved = state->digitalPin[1].toArray(actualD, 6);
106103
assertEqual(6, numMoved);
107104
// assert non-destructive
@@ -113,6 +110,19 @@ unittest(pin_write_history)
113110
assertEqual(expectedD[i], actualD[i]);
114111
}
115112

113+
numMoved = state->digitalPin[1].toTimestampArray(actualT, 6);
114+
assertEqual(6, numMoved);
115+
for (int i = 0; i < numMoved; ++i)
116+
{
117+
assertEqual(expectedT[i], actualT[i]);
118+
}
119+
}
120+
121+
unittest(analog_pin_write_history) {
122+
int numMoved;
123+
int expectedA[6] = {0, 11, 22, 33, 44, 55};
124+
int actualA[6];
125+
116126
// history for analog pin
117127
analogWrite(1, 11);
118128
analogWrite(1, 22);
@@ -121,8 +131,7 @@ unittest(pin_write_history)
121131
analogWrite(1, 55);
122132

123133
assertEqual(6, state->analogPin[1].historySize());
124-
int expectedA[6] = {0, 11, 22, 33, 44, 55};
125-
int actualA[6];
134+
126135
numMoved = state->analogPin[1].toArray(actualA, 6);
127136
assertEqual(6, numMoved);
128137
// assert non-destructive
@@ -133,7 +142,9 @@ unittest(pin_write_history)
133142
{
134143
assertEqual(expectedA[i], actualA[i]);
135144
}
145+
}
136146

147+
unittest(ascii_pin_write_history) {
137148
// digitial history as serial data, big-endian
138149
bool binaryAscii[24] = {
139150
0, 1, 0, 1, 1, 0, 0, 1,
@@ -207,8 +218,7 @@ unittest(spi) {
207218
}
208219
}
209220

210-
unittest(does_nothing_if_no_data)
211-
{
221+
unittest(does_nothing_if_no_data) {
212222
int myPin = 3;
213223
state->serialPort[0].dataIn = "";
214224
state->serialPort[0].dataOut = "";
@@ -218,8 +228,7 @@ unittest(spi) {
218228
assertEqual("", state->serialPort[0].dataOut);
219229
}
220230

221-
unittest(keeps_pin_low_and_acks)
222-
{
231+
unittest(keeps_pin_low_and_acks) {
223232
int myPin = 3;
224233
state->serialPort[0].dataIn = "0";
225234
state->serialPort[0].dataOut = "";
@@ -230,8 +239,7 @@ unittest(spi) {
230239
assertEqual("Ack 3 0", state->serialPort[0].dataOut);
231240
}
232241

233-
unittest(flips_pin_high_and_acks)
234-
{
242+
unittest(flips_pin_high_and_acks) {
235243
int myPin = 3;
236244
state->serialPort[0].dataIn = "1";
237245
state->serialPort[0].dataOut = "";
@@ -242,8 +250,7 @@ unittest(spi) {
242250
assertEqual("Ack 3 1", state->serialPort[0].dataOut);
243251
}
244252

245-
unittest(two_flips)
246-
{
253+
unittest(two_flips) {
247254
int myPin = 3;
248255
state->serialPort[0].dataIn = "10junk";
249256
state->serialPort[0].dataOut = "";

0 commit comments

Comments
 (0)