arduino_ci 0.1.21 → 0.2.0

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
  SHA1:
3
- metadata.gz: f16bbf16889f4244fd035daa6af2901f48652617
4
- data.tar.gz: f95a8a86712af293b2e48aa386031ae1a2872f36
3
+ metadata.gz: ec22bfa6969f75cdb38ffa4365c3d8f2f83f2185
4
+ data.tar.gz: 2380ce41fe0779e258471b28e9e94eee3c238369
5
5
  SHA512:
6
- metadata.gz: 379a7bee7c9c88ce6dcc0abffa990ca67c1a2e2c6b04a5521c4958fa29ba2b65672a1d21e8d1b523f8bc0a098d3cf8e9f9d9c9a97336248855d3890472511a81
7
- data.tar.gz: 491efe2046ef7414f7adf381c6bd9cf68d7b203c88f644a0a0cd836319611195b0338676a73db4bad3d210f6612071af8e976243f07a4fa17618afa5492d9a43
6
+ metadata.gz: 2c464279ef51852b51b22287960474da51a2818c9d41b8aadc181287636fa095effa8644f08320a62af7316a8540e9279ccf904c4936da619e82b7fb0011b21c
7
+ data.tar.gz: 7dfecd48948dfa8588e150841ee24c472480a20f10892c6098905fa35220bca26690708f827ec5b290d1564006f5a3c3019c7638eac27b9669311f6203f3973c
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- # ArduinoCI Ruby gem (`arduino_ci`) [![Gem Version](https://badge.fury.io/rb/arduino_ci.svg)](https://rubygems.org/gems/arduino_ci) [![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://www.rubydoc.info/gems/arduino_ci/0.1.21)
2
+ # ArduinoCI Ruby gem (`arduino_ci`) [![Gem Version](https://badge.fury.io/rb/arduino_ci.svg)](https://rubygems.org/gems/arduino_ci) [![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://www.rubydoc.info/gems/arduino_ci/0.2.0)
3
3
 
4
4
  You want to run tests on your Arduino library (bonus: without hardware present), but the IDE doesn't support that. Arduino CI provides that ability.
5
5
 
@@ -2,37 +2,45 @@
2
2
  #include "HardwareSerial.h"
3
3
  #include "SPI.h"
4
4
 
5
- GodmodeState godmode = GodmodeState();
6
-
7
5
  GodmodeState* GODMODE() {
8
- return &godmode;
6
+ return GodmodeState::getInstance();
7
+ }
8
+
9
+ GodmodeState* GodmodeState::instance = nullptr;
10
+
11
+ GodmodeState* GodmodeState::getInstance()
12
+ {
13
+ if (instance == nullptr)
14
+ {
15
+ instance = new GodmodeState();
16
+ for (int i = 0; i < MOCK_PINS_COUNT; ++i) {
17
+ instance->digitalPin[i].setMicrosRetriever(&GodmodeState::getMicros);
18
+ instance->analogPin[i].setMicrosRetriever(&GodmodeState::getMicros);
19
+ }
20
+ }
21
+
22
+ return instance;
9
23
  }
10
24
 
11
25
  unsigned long millis() {
12
- GodmodeState* godmode = GODMODE();
13
- return godmode->micros / 1000;
26
+ return GODMODE()->micros / 1000;
14
27
  }
15
28
 
16
29
  unsigned long micros() {
17
- GodmodeState* godmode = GODMODE();
18
- return godmode->micros;
30
+ return GODMODE()->micros;
19
31
  }
20
32
 
21
33
  void delay(unsigned long millis) {
22
- GodmodeState* godmode = GODMODE();
23
- godmode->micros += millis * 1000;
34
+ GODMODE()->micros += millis * 1000;
24
35
  }
25
36
 
26
37
  void delayMicroseconds(unsigned long micros) {
27
- GodmodeState* godmode = GODMODE();
28
- godmode->micros += micros;
38
+ GODMODE()->micros += micros;
29
39
  }
30
40
 
31
-
32
41
  void randomSeed(unsigned long seed)
33
42
  {
34
- GodmodeState* godmode = GODMODE();
35
- godmode->seed = seed;
43
+ GODMODE()->seed = seed;
36
44
  }
37
45
 
38
46
  long random(long vmax)
@@ -81,16 +89,16 @@ void detachInterrupt(uint8_t interrupt) {
81
89
 
82
90
  // Serial ports
83
91
  #if defined(HAVE_HWSERIAL0)
84
- HardwareSerial Serial(&godmode.serialPort[0].dataIn, &godmode.serialPort[0].dataOut, &godmode.serialPort[0].readDelayMicros);
92
+ HardwareSerial Serial(&GODMODE()->serialPort[0].dataIn, &GODMODE()->serialPort[0].dataOut, &GODMODE()->serialPort[0].readDelayMicros);
85
93
  #endif
86
94
  #if defined(HAVE_HWSERIAL1)
87
- HardwareSerial Serial1(&godmode.serialPort[1].dataIn, &godmode.serialPort[1].dataOut, &godmode.serialPort[1].readDelayMicros);
95
+ HardwareSerial Serial1(&GODMODE()->serialPort[1].dataIn, &GODMODE()->serialPort[1].dataOut, &GODMODE()->serialPort[1].readDelayMicros);
88
96
  #endif
89
97
  #if defined(HAVE_HWSERIAL2)
90
- HardwareSerial Serial2(&godmode.serialPort[2].dataIn, &godmode.serialPort[2].dataOut, &godmode.serialPort[2].readDelayMicros);
98
+ HardwareSerial Serial2(&GODMODE()->serialPort[2].dataIn, &GODMODE()->serialPort[2].dataOut, &GODMODE()->serialPort[2].readDelayMicros);
91
99
  #endif
92
100
  #if defined(HAVE_HWSERIAL3)
93
- HardwareSerial Serial3(&godmode.serialPort[3].dataIn, &godmode.serialPort[3].dataOut, &godmode.serialPort[3].readDelayMicros);
101
+ HardwareSerial Serial3(&GODMODE()->serialPort[3].dataIn, &GODMODE()->serialPort[3].dataOut, &GODMODE()->serialPort[3].readDelayMicros);
94
102
  #endif
95
103
 
96
104
  template <typename T>
@@ -100,4 +108,4 @@ inline std::ostream& operator << ( std::ostream& out, const PinHistory<T>& ph )
100
108
  }
101
109
 
102
110
  // defined in SPI.h
103
- SPIClass SPI = SPIClass(&godmode.spi.dataIn, &godmode.spi.dataOut);
111
+ SPIClass SPI = SPIClass(&GODMODE()->spi.dataIn, &GODMODE()->spi.dataOut);
@@ -16,7 +16,6 @@ void delayMicroseconds(unsigned long micros);
16
16
  unsigned long millis();
17
17
  unsigned long micros();
18
18
 
19
-
20
19
  #define MOCK_PINS_COUNT 256
21
20
 
22
21
  #if defined(UBRR3H)
@@ -32,16 +31,19 @@ unsigned long micros();
32
31
  #endif
33
32
 
34
33
  class GodmodeState {
35
- struct PortDef {
36
- String dataIn;
37
- String dataOut;
38
- unsigned long readDelayMicros;
39
- };
34
+ private:
35
+ struct PortDef {
36
+ String dataIn;
37
+ String dataOut;
38
+ unsigned long readDelayMicros;
39
+ };
40
+
41
+ struct InterruptDef {
42
+ bool attached;
43
+ uint8_t mode;
44
+ };
40
45
 
41
- struct InterruptDef {
42
- bool attached;
43
- uint8_t mode;
44
- };
46
+ static GodmodeState* instance;
45
47
 
46
48
  public:
47
49
  unsigned long micros;
@@ -98,8 +100,24 @@ class GodmodeState {
98
100
  return NUM_SERIAL_PORTS;
99
101
  }
100
102
 
101
- GodmodeState()
102
- {
103
+ // Using this for anything other than unit testing arduino_ci itself
104
+ // is unsupported at the moment
105
+ void overrideClockTruth(unsigned long (*getMicros)(void)) {
106
+ }
107
+
108
+ // singleton pattern
109
+ static GodmodeState* getInstance();
110
+
111
+ static unsigned long getMicros() {
112
+ return instance->micros;
113
+ }
114
+
115
+ // C++ 11, declare as public for better compiler error messages
116
+ GodmodeState(GodmodeState const&) = delete;
117
+ void operator=(GodmodeState const&) = delete;
118
+
119
+ private:
120
+ GodmodeState() {
103
121
  reset();
104
122
  }
105
123
  };
@@ -123,4 +141,3 @@ inline void noTone(uint8_t _pin) {}
123
141
 
124
142
 
125
143
  GodmodeState* GODMODE();
126
-
@@ -0,0 +1,86 @@
1
+ #pragma once
2
+
3
+ template <typename T>
4
+ class MockEventQueue {
5
+ public:
6
+ struct Event {
7
+ T data;
8
+ unsigned long micros;
9
+
10
+ Event() : data(T()), micros(0) {}
11
+ Event(const T &d, unsigned long const t) : data(d), micros(t) { }
12
+ };
13
+
14
+ private:
15
+ struct Node {
16
+ Event event;
17
+ Node* next;
18
+
19
+ Node(const Event &e, Node* n) : event(e), next(n) { }
20
+ };
21
+
22
+ Node* mFront;
23
+ Node* mBack;
24
+ unsigned long mSize;
25
+ T mNil;
26
+ unsigned long (*mGetMicros)(void);
27
+
28
+ void init(unsigned long (*getMicros)(void)) {
29
+ mFront = mBack = nullptr;
30
+ mSize = 0;
31
+ mGetMicros = getMicros;
32
+ }
33
+
34
+ public:
35
+ MockEventQueue(unsigned long (*getMicros)(void)): mNil() { init(getMicros); }
36
+ MockEventQueue(): mNil() { init(nullptr); }
37
+
38
+ MockEventQueue(const MockEventQueue<T>& q) {
39
+ init(q.mGetMicros);
40
+ for (Node* n = q.mFront; n; n = n->next) push(n->event);
41
+ }
42
+
43
+ void setMicrosRetriever(unsigned long (*getMicros)(void)) { mGetMicros = getMicros; }
44
+
45
+ inline unsigned long size() const { return mSize; }
46
+ inline bool empty() const { return 0 == mSize; }
47
+ inline Event front() const { return empty() ? Event(mNil, 0) : mFront->event; }
48
+ inline Event back() const { return empty() ? Event(mNil, 0) : mBack->event; }
49
+ inline T frontData() const { return front().data; }
50
+ inline T backData() const { return back().data; }
51
+ inline unsigned long frontTime() const { return front().micros; }
52
+ inline unsigned long backTime() const { return back().micros; }
53
+
54
+
55
+ // fully formed event
56
+ bool push(const Event& e) {
57
+ Node *n = new Node(e, nullptr);
58
+ if (n == nullptr) return false;
59
+ mBack = (mFront == nullptr ? mFront : mBack->next) = n;
60
+ return ++mSize;
61
+ }
62
+
63
+ // fully specfied event
64
+ bool push(const T& v, unsigned long const time) {
65
+ Event e = {v, time};
66
+ return push(e);
67
+ }
68
+
69
+ // event needing timestamp
70
+ bool push(const T& v) {
71
+ unsigned long micros = mGetMicros == nullptr ? 0 : mGetMicros();
72
+ return push(v, micros);
73
+ }
74
+
75
+ void pop() {
76
+ if (empty()) return;
77
+ Node* n = mFront;
78
+ mFront = mFront->next;
79
+ delete n;
80
+ if (--mSize == 0) mBack = nullptr;
81
+ }
82
+
83
+ void clear() { while (!empty()) pop(); }
84
+
85
+ ~MockEventQueue() { clear(); }
86
+ };
@@ -1,5 +1,5 @@
1
1
  #pragma once
2
- #include "ci/Queue.h"
2
+ #include "MockEventQueue.h"
3
3
  #include "ci/ObservableDataStream.h"
4
4
  #include "WString.h"
5
5
 
@@ -7,8 +7,8 @@
7
7
  template <typename T>
8
8
  class PinHistory : public ObservableDataStream {
9
9
  private:
10
- ArduinoCIQueue<T> qIn;
11
- ArduinoCIQueue<T> qOut;
10
+ MockEventQueue<T> qIn;
11
+ MockEventQueue<T> qOut;
12
12
 
13
13
  void clear() {
14
14
  qOut.clear();
@@ -16,14 +16,14 @@ class PinHistory : public ObservableDataStream {
16
16
  }
17
17
 
18
18
  // enqueue ascii bits
19
- void a2q(ArduinoCIQueue<T> &q, String input, bool bigEndian, bool advertise) {
19
+ void a2q(MockEventQueue<T> &q, String input, bool bigEndian, bool advertise) {
20
20
  // 8 chars at a time, form up
21
21
  for (int j = 0; j < input.length(); ++j) {
22
22
  for (int i = 0; i < 8; ++i) {
23
23
  int shift = bigEndian ? 7 - i : i;
24
24
  unsigned char mask = (0x01 << shift);
25
25
  q.push(mask & input[j]);
26
- if (advertise) advertiseBit(q.back()); // not valid for all possible types but whatever
26
+ if (advertise) advertiseBit(q.backData()); // not valid for all possible types but whatever
27
27
  }
28
28
  }
29
29
  }
@@ -31,10 +31,10 @@ class PinHistory : public ObservableDataStream {
31
31
 
32
32
  // convert a queue to a string as if it was serial bits
33
33
  // start from offset, consider endianness
34
- String q2a(const ArduinoCIQueue<T> &q, unsigned int offset, bool bigEndian) const {
34
+ String q2a(const MockEventQueue<T> &q, unsigned int offset, bool bigEndian) const {
35
35
  String ret = "";
36
36
 
37
- ArduinoCIQueue<T> q2(q);
37
+ MockEventQueue<T> q2(q);
38
38
 
39
39
  while (offset) {
40
40
  q2.pop();
@@ -48,7 +48,7 @@ class PinHistory : public ObservableDataStream {
48
48
  unsigned char acc = 0x00;
49
49
  for (int i = 0; i < 8; ++i) {
50
50
  int shift = bigEndian ? 7 - i : i;
51
- T val = q2.front();
51
+ T val = q2.frontData();
52
52
  unsigned char bit = val ? 0x1 : 0x0;
53
53
  acc |= (bit << shift);
54
54
  q2.pop();
@@ -59,15 +59,25 @@ class PinHistory : public ObservableDataStream {
59
59
  return ret;
60
60
  }
61
61
 
62
+ void init() {
63
+ asciiEncodingOffsetIn = 0; // default is sensible
64
+ asciiEncodingOffsetOut = 1; // default is sensible
65
+ }
66
+
62
67
  public:
63
68
  unsigned int asciiEncodingOffsetIn;
64
69
  unsigned int asciiEncodingOffsetOut;
65
70
 
71
+ PinHistory(unsigned long (*getMicros)(void)) : ObservableDataStream(), qOut(getMicros) {
72
+ init();
73
+ }
74
+
66
75
  PinHistory() : ObservableDataStream() {
67
- asciiEncodingOffsetIn = 0; // default is sensible
68
- asciiEncodingOffsetOut = 1; // default is sensible
76
+ init();
69
77
  }
70
78
 
79
+ void setMicrosRetriever(unsigned long (*getMicros)(void)) { qOut.setMicrosRetriever(getMicros); }
80
+
71
81
  void reset(T val) {
72
82
  clear();
73
83
  qOut.push(val);
@@ -79,8 +89,8 @@ class PinHistory : public ObservableDataStream {
79
89
 
80
90
  // This returns the "value" of the pin in a raw sense
81
91
  operator T() const {
82
- if (!qIn.empty()) return qIn.front();
83
- return qOut.back();
92
+ if (!qIn.empty()) return qIn.frontData();
93
+ return qOut.backData();
84
94
  }
85
95
 
86
96
  // this sets the value of the pin authoritatively
@@ -89,8 +99,8 @@ class PinHistory : public ObservableDataStream {
89
99
  T operator=(const T& i) {
90
100
  qIn.clear();
91
101
  qOut.push(i);
92
- advertiseBit(qOut.back()); // not valid for all possible types but whatever
93
- return qOut.back();
102
+ advertiseBit(qOut.backData()); // not valid for all possible types but whatever
103
+ return qOut.backData();
94
104
  }
95
105
 
96
106
  // This returns the "value" of the pin according to the queued values
@@ -98,14 +108,14 @@ class PinHistory : public ObservableDataStream {
98
108
  // then take the latest output.
99
109
  T retrieve() {
100
110
  if (!qIn.empty()) {
101
- T hack_required_by_travis_ci = qIn.front();
111
+ T hack_required_by_travis_ci = qIn.frontData();
102
112
  qIn.pop();
103
113
  qOut.push(hack_required_by_travis_ci);
104
114
  }
105
- return qOut.back();
115
+ return qOut.backData();
106
116
  }
107
117
 
108
- // enqueue a set of elements
118
+ // enqueue a set of data elements
109
119
  void fromArray(T const * const arr, unsigned int length) {
110
120
  for (int i = 0; i < length; ++i) qIn.push(arr[i]);
111
121
  }
@@ -124,18 +134,48 @@ class PinHistory : public ObservableDataStream {
124
134
  // start from offset, consider endianness
125
135
  String incomingToAscii(bool bigEndian) const { return incomingToAscii(asciiEncodingOffsetIn, bigEndian); }
126
136
 
127
- // convert the pin history to a string as if it was Serial comms
137
+ // convert the pin history data to a string as if it was Serial comms
128
138
  // start from offset, consider endianness
129
139
  String toAscii(unsigned int offset, bool bigEndian) const { return q2a(qOut, offset, bigEndian); }
130
140
 
131
- // convert the pin history to a string as if it was Serial comms
141
+ // convert the pin history data to a string as if it was Serial comms
132
142
  // start from offset, consider endianness
133
143
  String toAscii(bool bigEndian) const { return toAscii(asciiEncodingOffsetOut, bigEndian); }
134
144
 
135
- // copy elements to an array, up to a given length
145
+ // copy data elements to an array, up to a given length
136
146
  // return the number of elements moved
137
147
  int toArray (T* arr, unsigned int length) const {
138
- ArduinoCIQueue<T> q2(qOut);
148
+ MockEventQueue<T> q2(qOut); // preserve const by copying
149
+
150
+ int ret = 0;
151
+ for (int i = 0; i < length && q2.size(); ++i) {
152
+ arr[i] = q2.frontData();
153
+ q2.pop();
154
+ ++ret;
155
+ }
156
+ return ret;
157
+ }
158
+
159
+ // copy pin history timing to an array, up to a given length.
160
+ // note that this records times between calls to the pin, not between transitions
161
+ // return the number of elements moved
162
+ int toTimestampArray(unsigned long* arr, unsigned int length) const {
163
+ MockEventQueue<T> q2(qOut); // preserve const by copying
164
+
165
+ int ret = 0;
166
+ for (int i = 0; i < length && q2.size(); ++i) {
167
+ arr[i] = q2.frontTime();
168
+ q2.pop();
169
+ ++ret;
170
+ }
171
+ return ret;
172
+ }
173
+
174
+ // copy pin history timing to an array, up to a given length.
175
+ // note that this records times between calls to the pin, not between transitions
176
+ // return the number of elements moved
177
+ int toEventArray(typename MockEventQueue<T>::Event* arr, unsigned int length) const {
178
+ MockEventQueue<T> q2(qOut); // preserve const by copying
139
179
 
140
180
  int ret = 0;
141
181
  for (int i = 0; i < length && q2.size(); ++i) {
@@ -146,12 +186,12 @@ class PinHistory : public ObservableDataStream {
146
186
  return ret;
147
187
  }
148
188
 
149
- // see if the array matches the elements in the queue
189
+ // see if the array matches the data of the elements in the queue
150
190
  bool hasElements (T const * const arr, unsigned int length) const {
151
191
  int i;
152
- ArduinoCIQueue<T> q2(qOut);
192
+ MockEventQueue<T> q2(qOut); // preserve const by copying
153
193
  for (i = 0; i < length && q2.size(); ++i) {
154
- if (q2.front() != arr[i]) return false;
194
+ if (q2.frontData() != arr[i]) return false;
155
195
  q2.pop();
156
196
  }
157
197
  return i == length;
@@ -1,3 +1,3 @@
1
1
  module ArduinoCI
2
- VERSION = "0.1.21".freeze
2
+ VERSION = "0.2.0".freeze
3
3
  end
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.21
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ian Katz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-02-07 00:00:00.000000000 Z
11
+ date: 2019-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: os
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.0.1
61
+ version: 0.0.2
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.0.1
68
+ version: 0.0.2
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -129,6 +129,7 @@ files:
129
129
  - cpp/arduino/Godmode.cpp
130
130
  - cpp/arduino/Godmode.h
131
131
  - cpp/arduino/HardwareSerial.h
132
+ - cpp/arduino/MockEventQueue.h
132
133
  - cpp/arduino/PinHistory.h
133
134
  - cpp/arduino/Print.h
134
135
  - cpp/arduino/SPI.h
@@ -414,7 +415,6 @@ files:
414
415
  - cpp/arduino/binary.h
415
416
  - cpp/arduino/ci/DeviceUsingBytes.h
416
417
  - cpp/arduino/ci/ObservableDataStream.h
417
- - cpp/arduino/ci/Queue.h
418
418
  - cpp/arduino/ci/README.md
419
419
  - cpp/arduino/ci/Table.h
420
420
  - cpp/arduino/stdlib.cpp
@@ -1,73 +0,0 @@
1
- #pragma once
2
-
3
- template <typename T>
4
- class ArduinoCIQueue {
5
- private:
6
- struct Node {
7
- T data;
8
- Node* next;
9
- };
10
-
11
- Node* mFront;
12
- Node* mBack;
13
- unsigned long mSize;
14
- T mNil;
15
-
16
- void init() {
17
- mFront = mBack = NULL;
18
- mSize = 0;
19
- }
20
-
21
- public:
22
- ArduinoCIQueue(): mNil() { init(); }
23
-
24
- ArduinoCIQueue(const ArduinoCIQueue<T>& q) {
25
- init();
26
- for (Node* n = q.mFront; n; n = n->next) push(n->data);
27
- }
28
-
29
- inline unsigned long size() const { return mSize; }
30
-
31
- inline bool empty() const { return 0 == mSize; }
32
-
33
- T front() const { return empty() ? mNil : mFront->data; }
34
-
35
- T back() const { return empty() ? mNil : mBack->data; }
36
-
37
- bool push(const T& v)
38
- {
39
- Node *n = new Node;
40
- if (n == NULL) return false;
41
-
42
- n->data = v;
43
- n->next = NULL;
44
-
45
- if (mFront == NULL)
46
- {
47
- mFront = mBack = n;
48
- } else {
49
- mBack->next = n;
50
- mBack = n;
51
- }
52
-
53
- ++mSize;
54
- return true;
55
- }
56
-
57
- void pop() {
58
- if (empty()) return;
59
- if (mFront == mBack) {
60
- mFront = mBack = NULL;
61
- } else {
62
- Node* n = mFront;
63
- mFront = mFront->next;
64
- delete n;
65
- }
66
-
67
- --mSize;
68
- }
69
-
70
- void clear() { while (!empty()) pop(); }
71
-
72
- ~ArduinoCIQueue() { clear(); }
73
- };