arduino_ci 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +46 -6
- data/cpp/arduino/ArduinoDefines.h +3 -0
- data/cpp/arduino/Godmode.h +5 -0
- data/cpp/arduino/HardwareSerial.h +2 -5
- data/cpp/arduino/Print.h +25 -24
- data/cpp/arduino/Stream.h +1 -1
- data/cpp/arduino/WString.h +18 -2
- data/exe/arduino_ci_remote.rb +24 -18
- data/lib/arduino_ci/ci_config.rb +8 -0
- data/lib/arduino_ci/cpp_library.rb +6 -7
- data/lib/arduino_ci/version.rb +1 -1
- data/misc/default.yml +2 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c3461f2bb4dc34e5e4f0d2f098858babddd990b2fc992a3b29ad034de6e13604
|
4
|
+
data.tar.gz: 613db06952916c533425d68f2d2b721fb121284f0f6c6d44dab83386114a386d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4600b16b94d531d8e70986d80df1dc175fa959a59051e14e1024491cde81d58c5487a77d530eb639a37ec58b83c6e40c23802e03e94a410767c2a7640053a032
|
7
|
+
data.tar.gz: 70b1c55559663b2d6f0e49d01bbc311982830c98ca3cbc24dfb06af2e687f0fb8787f593543f902aaf193efcb4328d197ae425bc3e7a996acde7a30f6f07916b
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
[](https://rubygems.org/gems/arduino_ci)
|
2
2
|
[](https://travis-ci.org/ifreecarve/arduino_ci)
|
3
|
-
[](http://www.rubydoc.info/gems/arduino_ci/0.1.
|
3
|
+
[](http://www.rubydoc.info/gems/arduino_ci/0.1.8)
|
4
4
|
|
5
5
|
# ArduinoCI Ruby gem (`arduino_ci`)
|
6
6
|
|
@@ -86,15 +86,13 @@ unittest(pin_history)
|
|
86
86
|
digitalWrite(myPin, HIGH);
|
87
87
|
digitalWrite(myPin, HIGH);
|
88
88
|
|
89
|
+
// pin history is queued in case we want to analyze it later.
|
90
|
+
// we expect 6 values in that queue.
|
89
91
|
assertEqual(6, state->digitalPin[1].size());
|
90
92
|
bool expected[6] = {LOW, HIGH, LOW, LOW, HIGH, HIGH};
|
91
93
|
bool actual[6];
|
92
94
|
|
93
|
-
//
|
94
|
-
// the history is destructive -- it's a linked-list queue. this
|
95
|
-
// means that if toArray or hasElements fails, the queue will be in
|
96
|
-
// an unknown state and you should reset it before continuing with
|
97
|
-
// other tests
|
95
|
+
// convert history queue into an array so we can verify it
|
98
96
|
int numMoved = state->digitalPin[myPin].toArray(actual, 6);
|
99
97
|
assertEqual(6, numMoved);
|
100
98
|
|
@@ -102,6 +100,7 @@ unittest(pin_history)
|
|
102
100
|
for (int i = 0; i < 6; ++i) {
|
103
101
|
assertEqual(expected[i], actual[i]);
|
104
102
|
}
|
103
|
+
}
|
105
104
|
```
|
106
105
|
|
107
106
|
|
@@ -141,6 +140,43 @@ unittest(pin_read_history)
|
|
141
140
|
|
142
141
|
#### Serial Data
|
143
142
|
|
143
|
+
Basic input and output verification of serial port data can be done as follows:
|
144
|
+
|
145
|
+
```c++
|
146
|
+
unittest(reading_writing_serial)
|
147
|
+
{
|
148
|
+
GodmodeState* state = GODMODE();
|
149
|
+
state->serialPort[0].dataIn = ""; // the queue of data waiting to be read
|
150
|
+
state->serialPort[0].dataOut = ""; // the history of data written
|
151
|
+
|
152
|
+
// When there is no data, nothing happens
|
153
|
+
assertEqual(-1, Serial.peek());
|
154
|
+
assertEqual("", state->serialPort[0].dataIn);
|
155
|
+
assertEqual("", state->serialPort[0].dataOut);
|
156
|
+
|
157
|
+
// if we put data on the input and peek at it, we see the value and it's not consumed
|
158
|
+
state->serialPort[0].dataIn = "a";
|
159
|
+
assertEqual('a', Serial.peek());
|
160
|
+
assertEqual("a", state->serialPort[0].dataIn);
|
161
|
+
assertEqual("", state->serialPort[0].dataOut);
|
162
|
+
|
163
|
+
// if we read the input, we see the value and it's consumed
|
164
|
+
assertEqual('a', Serial.read());
|
165
|
+
assertEqual("", state->serialPort[0].dataIn);
|
166
|
+
assertEqual("", state->serialPort[0].dataOut);
|
167
|
+
|
168
|
+
// when we write data, it shows up in the history -- the output buffer
|
169
|
+
Serial.write('b');
|
170
|
+
assertEqual("", state->serialPort[0].dataIn);
|
171
|
+
assertEqual("b", state->serialPort[0].dataOut);
|
172
|
+
|
173
|
+
// when we print more data, note that the history
|
174
|
+
// still contains the first thing we wrote
|
175
|
+
Serial.print("cdefg");
|
176
|
+
assertEqual("", state->serialPort[0].dataIn);
|
177
|
+
assertEqual("bcdefg", state->serialPort[0].dataOut);
|
178
|
+
}
|
179
|
+
```
|
144
180
|
|
145
181
|
A more complicated example: working with serial port IO. Let's say I have the following function:
|
146
182
|
|
@@ -313,6 +349,10 @@ For your unit tests, in addition to setting specific libraries and platforms, yo
|
|
313
349
|
|
314
350
|
```yaml
|
315
351
|
unittest:
|
352
|
+
compilers:
|
353
|
+
- g++ # default
|
354
|
+
- g++-4.9
|
355
|
+
- g++-7
|
316
356
|
testfiles:
|
317
357
|
select:
|
318
358
|
- "*-*.*"
|
@@ -89,3 +89,6 @@
|
|
89
89
|
#define TIMER5B 17
|
90
90
|
#define TIMER5C 18
|
91
91
|
|
92
|
+
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
93
|
+
#define LED_BUILTIN 13
|
94
|
+
#endif
|
data/cpp/arduino/Godmode.h
CHANGED
@@ -91,6 +91,11 @@ void analogWrite(uint8_t, int);
|
|
91
91
|
#define analogReadResolution(...) _NOP()
|
92
92
|
#define analogWriteResolution(...) _NOP()
|
93
93
|
|
94
|
+
// TODO: issue #26 to track the commanded state here
|
95
|
+
inline void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0) {}
|
96
|
+
inline void tone(uint8_t _pin, unsigned int frequency) {}
|
97
|
+
inline void noTone(uint8_t _pin) {}
|
98
|
+
|
94
99
|
|
95
100
|
GodmodeState* GODMODE();
|
96
101
|
|
@@ -57,11 +57,8 @@ class HardwareSerial : public Stream, public ObservableDataStream
|
|
57
57
|
return 1;
|
58
58
|
}
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
inline size_t write(unsigned int n) { return write((uint8_t)n); }
|
63
|
-
inline size_t write(int n) { return write((uint8_t)n); }
|
64
|
-
// using Print::write; // pull in write(str) and write(buf, size) from Print
|
60
|
+
// https://stackoverflow.com/a/4271276
|
61
|
+
using Print::write; // pull in write(str) and write(buf, size) from Print
|
65
62
|
operator bool() { return true; }
|
66
63
|
|
67
64
|
};
|
data/cpp/arduino/Print.h
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
3
|
#include <stdio.h>
|
4
|
+
#include <avr/pgmspace.h>
|
4
5
|
#include "WString.h"
|
5
6
|
|
6
7
|
#define DEC 10
|
@@ -32,38 +33,38 @@ class Print
|
|
32
33
|
virtual size_t write(uint8_t) = 0;
|
33
34
|
size_t write(const char *str) { return str == NULL ? 0 : write((const uint8_t *)str, String(str).length()); }
|
34
35
|
|
35
|
-
|
36
36
|
virtual size_t write(const uint8_t *buffer, size_t size) {
|
37
37
|
size_t n;
|
38
38
|
for (n = 0; size && write(*buffer++) && ++n; --size);
|
39
39
|
return n;
|
40
40
|
}
|
41
|
+
|
41
42
|
size_t write(const char *buffer, size_t size) { return write((const uint8_t *)buffer, size); }
|
42
43
|
|
43
|
-
size_t print(const String &s)
|
44
|
-
size_t print(const __FlashStringHelper *str)
|
45
|
-
size_t print(const char* str)
|
46
|
-
size_t print(char c)
|
47
|
-
size_t print(unsigned char b, int base)
|
48
|
-
size_t print(int n,
|
49
|
-
size_t print(unsigned int n,
|
50
|
-
size_t print(long n,
|
51
|
-
size_t print(unsigned long n, int base)
|
52
|
-
size_t print(double n,
|
53
|
-
size_t print(const Printable& x)
|
44
|
+
size_t print(const String &s) { return write(s.c_str(), s.length()); }
|
45
|
+
size_t print(const __FlashStringHelper *str) { return print(reinterpret_cast<PGM_P>(str)); }
|
46
|
+
size_t print(const char* str) { return print(String(str)); }
|
47
|
+
size_t print(char c) { return print(String(c)); }
|
48
|
+
size_t print(unsigned char b, int base = DEC) { return print(String(b, base)); }
|
49
|
+
size_t print(int n, int base = DEC) { return print(String(n, base)); }
|
50
|
+
size_t print(unsigned int n, int base = DEC) { return print(String(n, base)); }
|
51
|
+
size_t print(long n, int base = DEC) { return print(String(n, base)); }
|
52
|
+
size_t print(unsigned long n, int base = DEC) { return print(String(n, base)); }
|
53
|
+
size_t print(double n, int base = DEC) { return print(String(n, base)); }
|
54
|
+
size_t print(const Printable& x) { return x.printTo(*this); }
|
54
55
|
|
55
|
-
size_t println(void)
|
56
|
-
size_t println(const String &s)
|
57
|
-
size_t println(const __FlashStringHelper *str)
|
58
|
-
size_t println(const char* c)
|
59
|
-
size_t println(char c)
|
60
|
-
size_t println(unsigned char b,
|
61
|
-
size_t println(int num,
|
62
|
-
size_t println(unsigned int num,
|
63
|
-
size_t println(long num,
|
64
|
-
size_t println(unsigned long num, int base)
|
65
|
-
size_t println(double num,
|
66
|
-
size_t println(const Printable& x)
|
56
|
+
size_t println(void) { return print("\r\n"); }
|
57
|
+
size_t println(const String &s) { return print(s) + println(); }
|
58
|
+
size_t println(const __FlashStringHelper *str) { return println(reinterpret_cast<PGM_P>(str)); }
|
59
|
+
size_t println(const char* c) { return println(String(c)); }
|
60
|
+
size_t println(char c) { return println(String(c)); }
|
61
|
+
size_t println(unsigned char b, int base = DEC) { return println(String(b, base)); }
|
62
|
+
size_t println(int num, int base = DEC) { return println(String(num, base)); }
|
63
|
+
size_t println(unsigned int num, int base = DEC) { return println(String(num, base)); }
|
64
|
+
size_t println(long num, int base = DEC) { return println(String(num, base)); }
|
65
|
+
size_t println(unsigned long num, int base = DEC) { return println(String(num, base)); }
|
66
|
+
size_t println(double num, int base = DEC) { return println(String(num, base)); }
|
67
|
+
size_t println(const Printable& x) { return print(x) + println(); }
|
67
68
|
|
68
69
|
virtual void flush() { }
|
69
70
|
|
data/cpp/arduino/Stream.h
CHANGED
@@ -56,11 +56,11 @@ class Stream : public Print
|
|
56
56
|
return ret;
|
57
57
|
}
|
58
58
|
|
59
|
+
// https://stackoverflow.com/a/4271276
|
59
60
|
using Print::write;
|
60
61
|
|
61
62
|
virtual size_t write(uint8_t aChar) { mGodmodeDataIn->append(String((char)aChar)); return 1; }
|
62
63
|
|
63
|
-
|
64
64
|
Stream() {
|
65
65
|
mTimeoutMillis = 1000;
|
66
66
|
mGodmodeMicrosDelay = NULL;
|
data/cpp/arduino/WString.h
CHANGED
@@ -9,6 +9,22 @@
|
|
9
9
|
|
10
10
|
typedef std::string string;
|
11
11
|
|
12
|
+
// work around some portability issues
|
13
|
+
#if defined(__clang__)
|
14
|
+
#define ARDUINOCI_ISNAN ::isnan
|
15
|
+
#define ARDUINOCI_ISINF ::isinf
|
16
|
+
#elif defined(__GNUC__) || defined(__GNUG__)
|
17
|
+
#define ARDUINOCI_ISNAN std::isnan
|
18
|
+
#define ARDUINOCI_ISINF std::isinf
|
19
|
+
#elif defined(_MSC_VER)
|
20
|
+
// TODO: no idea
|
21
|
+
#define ARDUINOCI_ISNAN ::isnan
|
22
|
+
#define ARDUINOCI_ISINF ::isinf
|
23
|
+
#else
|
24
|
+
#define ARDUINOCI_ISNAN ::isnan
|
25
|
+
#define ARDUINOCI_ISINF ::isinf
|
26
|
+
#endif
|
27
|
+
|
12
28
|
class __FlashStringHelper;
|
13
29
|
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
|
14
30
|
|
@@ -36,8 +52,8 @@ class String: public string
|
|
36
52
|
|
37
53
|
static string dtoas(double val, int decimalPlaces) {
|
38
54
|
double r = 0.5 * pow(0.1, decimalPlaces); // make sure that integer truncation will properly round
|
39
|
-
if (
|
40
|
-
if (
|
55
|
+
if (ARDUINOCI_ISNAN(val)) return "nan";
|
56
|
+
if (ARDUINOCI_ISINF(val)) return "inf";
|
41
57
|
val += val > 0 ? r : -r;
|
42
58
|
if (val > 4294967040.0) return "ovf";
|
43
59
|
if (val <-4294967040.0) return "ovf";
|
data/exe/arduino_ci_remote.rb
CHANGED
@@ -69,11 +69,15 @@ cpp_library = ArduinoCI::CppLibrary.new(installed_library_path)
|
|
69
69
|
attempt("Library installed at #{installed_library_path}") { true }
|
70
70
|
|
71
71
|
# check GCC
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
72
|
+
compilers = config.compilers_to_use
|
73
|
+
assure("The set of compilers (#{compilers.length}) isn't empty") { !compilers.empty? }
|
74
|
+
compilers.each do |gcc_binary|
|
75
|
+
attempt_multiline("Checking #{gcc_binary} version") do
|
76
|
+
version = cpp_library.gcc_version(gcc_binary)
|
77
|
+
next nil unless version
|
78
|
+
puts version.split("\n").map { |l| " #{l}" }.join("\n")
|
79
|
+
version
|
80
|
+
end
|
77
81
|
end
|
78
82
|
|
79
83
|
# gather up all required boards so we can install them up front.
|
@@ -121,20 +125,22 @@ else
|
|
121
125
|
last_board = board
|
122
126
|
cpp_library.test_files.each do |unittest_path|
|
123
127
|
unittest_name = File.basename(unittest_path)
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
128
|
+
compilers.each do |gcc_binary|
|
129
|
+
attempt_multiline("Unit testing #{unittest_name} with #{gcc_binary}") do
|
130
|
+
exe = cpp_library.build_for_test_with_configuration(
|
131
|
+
unittest_path,
|
132
|
+
config.aux_libraries_for_unittest,
|
133
|
+
config.gcc_config(p)
|
134
|
+
)
|
135
|
+
puts
|
136
|
+
unless exe
|
137
|
+
puts "Last command: #{cpp_library.last_cmd}"
|
138
|
+
puts cpp_library.last_out
|
139
|
+
puts cpp_library.last_err
|
140
|
+
next false
|
141
|
+
end
|
142
|
+
cpp_library.run_test_file(exe)
|
136
143
|
end
|
137
|
-
cpp_library.run_test_file(exe)
|
138
144
|
end
|
139
145
|
end
|
140
146
|
end
|
data/lib/arduino_ci/ci_config.rb
CHANGED
@@ -25,6 +25,7 @@ COMPILE_SCHEMA = {
|
|
25
25
|
}.freeze
|
26
26
|
|
27
27
|
UNITTEST_SCHEMA = {
|
28
|
+
compilers: Array,
|
28
29
|
platforms: Array,
|
29
30
|
libraries: Array,
|
30
31
|
testfiles: {
|
@@ -197,6 +198,13 @@ module ArduinoCI
|
|
197
198
|
@package_info[package][:url]
|
198
199
|
end
|
199
200
|
|
201
|
+
# compilers to build (unit tests) with
|
202
|
+
# @return [Array<String>] The compiler binary names (e.g. g++) to build with
|
203
|
+
def compilers_to_use
|
204
|
+
return [] if @unittest_info[:compilers].nil?
|
205
|
+
@unittest_info[:compilers]
|
206
|
+
end
|
207
|
+
|
200
208
|
# platforms to build [the examples on]
|
201
209
|
# @return [Array<String>] The platforms to build
|
202
210
|
def platforms_to_build
|
@@ -107,10 +107,9 @@ module ArduinoCI
|
|
107
107
|
end
|
108
108
|
|
109
109
|
# wrapper for the GCC command
|
110
|
-
def run_gcc(*args, **kwargs)
|
111
|
-
full_args = [
|
110
|
+
def run_gcc(gcc_binary, *args, **kwargs)
|
111
|
+
full_args = [gcc_binary] + args
|
112
112
|
@last_cmd = " $ #{full_args.join(' ')}"
|
113
|
-
|
114
113
|
ret = Host.run_and_capture(*full_args, **kwargs)
|
115
114
|
@last_err = ret[:err]
|
116
115
|
@last_out = ret[:out]
|
@@ -119,8 +118,8 @@ module ArduinoCI
|
|
119
118
|
|
120
119
|
# Return the GCC version
|
121
120
|
# @return [String] the version reported by `gcc -v`
|
122
|
-
def gcc_version
|
123
|
-
return nil unless run_gcc("-v")
|
121
|
+
def gcc_version(gcc_binary)
|
122
|
+
return nil unless run_gcc(gcc_binary, "-v")
|
124
123
|
@last_err
|
125
124
|
end
|
126
125
|
|
@@ -183,7 +182,7 @@ module ArduinoCI
|
|
183
182
|
# @param aux_libraries [String] The external Arduino libraries required by this project
|
184
183
|
# @param ci_gcc_config [Hash] The GCC config object
|
185
184
|
# @return [String] path to the compiled test executable
|
186
|
-
def build_for_test_with_configuration(test_file, aux_libraries, ci_gcc_config)
|
185
|
+
def build_for_test_with_configuration(test_file, aux_libraries, gcc_binary, ci_gcc_config)
|
187
186
|
base = File.basename(test_file)
|
188
187
|
executable = File.expand_path("unittest_#{base}.bin")
|
189
188
|
File.delete(executable) if File.exist?(executable)
|
@@ -192,7 +191,7 @@ module ArduinoCI
|
|
192
191
|
test_args(aux_libraries, ci_gcc_config),
|
193
192
|
[test_file],
|
194
193
|
].flatten(1)
|
195
|
-
return nil unless run_gcc(*args)
|
194
|
+
return nil unless run_gcc(gcc_binary, *args)
|
196
195
|
artifacts << executable
|
197
196
|
executable
|
198
197
|
end
|
data/lib/arduino_ci/version.rb
CHANGED
data/misc/default.yml
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arduino_ci
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ian Katz
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-03
|
11
|
+
date: 2018-04-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: os
|