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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 82a935a3542b8ab937b7176122e9db548ce380680c2d79705106bfe452c8e527
4
- data.tar.gz: 5924a473a766721cf3ce2c7a3b47536c0ab57afae539e506349a3d4691d6d401
3
+ metadata.gz: c3461f2bb4dc34e5e4f0d2f098858babddd990b2fc992a3b29ad034de6e13604
4
+ data.tar.gz: 613db06952916c533425d68f2d2b721fb121284f0f6c6d44dab83386114a386d
5
5
  SHA512:
6
- metadata.gz: 9f09f7ff8912769fe5660e519fddf7b07da5b4774e7719a04154f76ff8fb7fdb8e1ccb6732e17b49ad5b286f33fab6538e8c57f5b94e8487a1bff246d3017c89
7
- data.tar.gz: 47ee9f776d6fcf2bf5a77de5762b949b131c0fc21fa68663743d79bf4c97bd6e4794da6251e5dbb335611879fb929afe14a69e19b8518c45e58a7496aada4397
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.7)
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
- // move history queue into an array because at the moment, reading
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
@@ -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
- inline size_t write(unsigned long n) { return write((uint8_t)n); }
61
- inline size_t write(long n) { return write((uint8_t)n); }
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) { return write(s.c_str(), s.length()); }
44
- size_t print(const __FlashStringHelper *str) { return print(reinterpret_cast<PGM_P>(str)); }
45
- size_t print(const char* str) { return print(String(str)); }
46
- size_t print(char c) { return print(String(c)); }
47
- size_t print(unsigned char b, int base) { return print(String(b, base)); }
48
- size_t print(int n, int base) { return print(String(n, base)); }
49
- size_t print(unsigned int n, int base) { return print(String(n, base)); }
50
- size_t print(long n, int base) { return print(String(n, base)); }
51
- size_t print(unsigned long n, int base) { return print(String(n, base)); }
52
- size_t print(double n, int digits) { return print(String(n, digits)); }
53
- size_t print(const Printable& x) { return x.printTo(*this); }
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) { return print("\r\n"); }
56
- size_t println(const String &s) { return print(s) + println(); }
57
- size_t println(const __FlashStringHelper *str) { return println(reinterpret_cast<PGM_P>(str)); }
58
- size_t println(const char* c) { return println(String(c)); }
59
- size_t println(char c) { return println(String(c)); }
60
- size_t println(unsigned char b, int base) { return println(String(b, base)); }
61
- size_t println(int num, int base) { return println(String(num, base)); }
62
- size_t println(unsigned int num, int base) { return println(String(num, base)); }
63
- size_t println(long num, int base) { return println(String(num, base)); }
64
- size_t println(unsigned long num, int base) { return println(String(num, base)); }
65
- size_t println(double num, int digits) { return println(String(num, digits)); }
66
- size_t println(const Printable& x) { return print(x) + println(); }
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;
@@ -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 (std::isnan(val)) return "nan";
40
- if (std::isinf(val)) return "inf";
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";
@@ -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
- attempt_multiline("Checking GCC version") do
73
- version = cpp_library.gcc_version
74
- next nil unless version
75
- puts version.split("\n").map { |l| " #{l}" }.join("\n")
76
- version
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
- attempt_multiline("Unit testing #{unittest_name}") do
125
- exe = cpp_library.build_for_test_with_configuration(
126
- unittest_path,
127
- config.aux_libraries_for_unittest,
128
- config.gcc_config(p)
129
- )
130
- puts
131
- unless exe
132
- puts "Last command: #{cpp_library.last_cmd}"
133
- puts cpp_library.last_out
134
- puts cpp_library.last_err
135
- next false
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
@@ -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 = ["g++"] + 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
@@ -1,3 +1,3 @@
1
1
  module ArduinoCI
2
- VERSION = "0.1.7".freeze
2
+ VERSION = "0.1.8".freeze
3
3
  end
data/misc/default.yml CHANGED
@@ -80,6 +80,8 @@ compile:
80
80
  - leonardo
81
81
 
82
82
  unittest:
83
+ compilers:
84
+ - g++
83
85
  libraries: ~
84
86
  platforms:
85
87
  - uno
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.7
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-07 00:00:00.000000000 Z
11
+ date: 2018-04-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: os