arduino_ci 0.1.7 → 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/arduino_ci.svg)](https://rubygems.org/gems/arduino_ci)
|
2
2
|
[![Build Status](https://travis-ci.org/ifreecarve/arduino_ci.svg)](https://travis-ci.org/ifreecarve/arduino_ci)
|
3
|
-
[![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://www.rubydoc.info/gems/arduino_ci/0.1.
|
3
|
+
[![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](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
|