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