1 package net.sourceforge.jarduino;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.nio.charset.StandardCharsets;
6 import java.util.Arrays;
7 import java.util.stream.Stream;
8
9 import org.junit.jupiter.api.Assertions;
10 import org.junit.jupiter.api.DynamicContainer;
11 import org.junit.jupiter.api.DynamicNode;
12 import org.junit.jupiter.api.DynamicTest;
13 import org.junit.jupiter.api.TestFactory;
14
15 import net.sourceforge.jarduino.message.ArduinoGenerator;
16 import net.sourceforge.jarduino.message.ArduinoLibrary;
17 import net.sourceforge.jarduino.message.ArduinoMessage;
18 import net.sourceforge.jarduino.message.ArduinoMsgFilter;
19 import net.sourceforge.jarduino.message.ArduinoParser;
20 import net.sourceforge.jarduino.message.ArduinoSystem;
21 import net.sourceforge.jarduino.util.ArduinoField;
22
23
24
25
26 public class ArduinoTest {
27
28
29
30
31 @TestFactory
32 public Stream<DynamicNode> buildTests() {
33
34 Stream<DynamicNode> myStream = Stream.empty();
35 myStream = Stream.concat(myStream, loadTest("Test1"));
36 myStream = Stream.concat(myStream, loadTest("Test2"));
37 myStream = Stream.concat(myStream, loadTest("Test3"));
38 return Stream.concat(myStream, parseTest());
39 }
40
41
42
43
44
45
46 private Stream<DynamicNode> loadTest(final String pName) {
47 return Stream.of(DynamicTest.dynamicTest(pName, () -> testDBCFile(pName)));
48 }
49
50
51
52
53
54 private Stream<DynamicNode> parseTest() {
55 return Stream.of(DynamicContainer.dynamicContainer("fields", Stream.of(
56 DynamicTest.dynamicTest("parse", () -> parseTest()),
57 DynamicTest.dynamicTest("littleEndian", () -> checkLittleEndian()),
58 DynamicTest.dynamicTest("bigEndian", () -> checkBigEndian())
59 )));
60 }
61
62
63
64
65
66
67 private void testDBCFile(final String pName) throws ArduinoException {
68
69 try (InputStream myStream = ArduinoTest.class.getResourceAsStream(pName + ".dbc")) {
70
71 final ArduinoSystem mySystem = ArduinoParser.parseStream(pName, StandardCharsets.ISO_8859_1, myStream);
72
73
74 final ArduinoMsgFilter myFilter = new ArduinoMsgFilter();
75 myFilter.resetSelection(mySystem);
76
77
78 ArduinoLibrary.loadLibraryHeader();
79
80
81 ArduinoLibrary.loadLibraryCode();
82
83
84 ArduinoGenerator.formatHeader(mySystem, myFilter);
85
86
87 ArduinoGenerator.formatBody(mySystem, myFilter);
88
89
90 for (ArduinoMessage myMessage : mySystem.getMessages()) {
91 myMessage.toString();
92 }
93
94
95 } catch (IOException e) {
96 throw new ArduinoException("Failed to load file", e);
97 }
98 }
99
100
101
102
103 private void checkParseFields() {
104
105 final byte[] myBuff = { (byte) 0b11001000, (byte) 0b00110011, (byte) 0b11000011 };
106
107
108 long myValue = ArduinoField.parseLEField(myBuff, 5, 2, false);
109 Assertions.assertEquals(0b10, myValue, "Parse failure");
110 myValue = ArduinoField.parseLEField(myBuff, 0, 8, false);
111 Assertions.assertEquals(0b11001000, myValue, "Parse failure");
112 myValue = ArduinoField.parseLEField(myBuff, 6, 8, false);
113 Assertions.assertEquals(0b11001111, myValue, "Parse failure");
114 myValue = ArduinoField.parseLEField(myBuff, 0, 10, false);
115 Assertions.assertEquals(0b1111001000, myValue, "Parse failure");
116 myValue = ArduinoField.parseLEField(myBuff, 14, 10, false);
117 Assertions.assertEquals(0b1100001100, myValue, "Parse failure");
118 myValue = ArduinoField.parseLEField(myBuff, 6, 17, false);
119 Assertions.assertEquals(0b10000110011001111, myValue, "Parse failure");
120
121
122 myValue = ArduinoField.parseBEField(myBuff, 5, 3, false);
123 Assertions.assertEquals(0b001, myValue, "Parse failure");
124 myValue = ArduinoField.parseBEField(myBuff, 7, 8, false);
125 Assertions.assertEquals(0b11001000, myValue, "Parse failure");
126 myValue = ArduinoField.parseBEField(myBuff, 9, 8, false);
127 Assertions.assertEquals(0b11110000, myValue, "Parse failure");
128 myValue = ArduinoField.parseBEField(myBuff, 6, 12, false);
129 Assertions.assertEquals(0b100100000110, myValue, "Parse failure");
130 myValue = ArduinoField.parseBEField(myBuff, 6, 16, false);
131 Assertions.assertEquals(0b1001000001100111, myValue, "Parse failure");
132 }
133
134
135
136
137 private void checkLittleEndian() {
138
139 checkLittleEndian(0, 3);
140 checkLittleEndian(3, 3);
141 checkLittleEndian(1, 6);
142 checkLittleEndian(9, 3);
143
144
145 checkLittleEndian(0, 8);
146 checkLittleEndian(8, 8);
147 checkLittleEndian(16, 8);
148
149
150 checkLittleEndian(0, 16);
151 checkLittleEndian(8, 16);
152 checkLittleEndian(16, 16);
153
154
155 checkLittleEndian(5, 8);
156 checkLittleEndian(11, 7);
157 checkLittleEndian(18, 7);
158
159
160 checkLittleEndian(7, 18);
161
162
163 checkLittleEndian(7, 38);
164 checkLittleEndian(0, 64);
165 }
166
167
168
169
170
171
172 private void checkLittleEndian(final int pStart,
173 final int pLength) {
174
175 final byte[] myBuff = new byte[Long.BYTES];
176
177
178 final long myMax = (1L << pLength) - 1;
179 final long myRange = Math.min(myMax, Short.MAX_VALUE);
180
181
182 for (long i = 0; i <= myRange; i++) {
183
184 ArduinoField.setLEField(myBuff, pStart, pLength, i);
185 long myValue = ArduinoField.parseLEField(myBuff, pStart, pLength, false);
186 Assertions.assertEquals(i, myValue, "Parse failure");
187 Arrays.fill(myBuff, (byte) 0);
188
189
190 long mySigned = i - (1L << pLength - 1);
191 ArduinoField.setLEField(myBuff, pStart, pLength, mySigned);
192 myValue = ArduinoField.parseLEField(myBuff, pStart, pLength, true);
193 Assertions.assertEquals(mySigned, myValue, "Parse failure");
194 Arrays.fill(myBuff, (byte) 0);
195
196
197 if (myRange < myMax) {
198
199 long myTest = i + (myMax - myRange);
200 ArduinoField.setLEField(myBuff, pStart, pLength, myTest);
201 myValue = ArduinoField.parseLEField(myBuff, pStart, pLength, false);
202 Assertions.assertEquals(myTest, myValue, "Parse failure");
203 Arrays.fill(myBuff, (byte) 0);
204
205
206 mySigned = myTest - (1L << pLength - 1);
207 ArduinoField.setLEField(myBuff, pStart, pLength, mySigned);
208 myValue = ArduinoField.parseLEField(myBuff, pStart, pLength, true);
209 Assertions.assertEquals(mySigned, myValue, "Parse failure");
210 Arrays.fill(myBuff, (byte) 0);
211 }
212 }
213 }
214
215
216
217
218 private void checkBigEndian() {
219
220 checkBigEndian(7, 3);
221 checkBigEndian(5, 3);
222 checkBigEndian(6, 6);
223 checkBigEndian(14, 3);
224
225
226 checkBigEndian(7, 8);
227 checkBigEndian(15, 8);
228 checkBigEndian(23, 8);
229
230
231 checkBigEndian(7, 16);
232 checkBigEndian(15, 16);
233 checkBigEndian(23, 16);
234
235
236 checkBigEndian(5, 8);
237 checkBigEndian(11, 7);
238 checkBigEndian(18, 7);
239
240
241 checkBigEndian(0, 18);
242
243
244 checkBigEndian(1, 38);
245 checkBigEndian(7, 64);
246 }
247
248
249
250
251
252
253 private void checkBigEndian(final int pStart,
254 final int pLength) {
255
256 final byte[] myBuff = new byte[Long.BYTES];
257
258
259 final long myMax = (1L << pLength) - 1;
260 final long myRange = Math.min(myMax, Short.MAX_VALUE);
261
262
263 for (long i = 0; i <= myRange; i++) {
264
265 ArduinoField.setBEField(myBuff, pStart, pLength, i);
266 long myValue = ArduinoField.parseBEField(myBuff, pStart, pLength, false);
267 Assertions.assertEquals(i, myValue, "Parse failure");
268 Arrays.fill(myBuff, (byte) 0);
269
270
271 long mySigned = i - (1L << pLength - 1);
272 Arrays.fill(myBuff, (byte) -1);
273 ArduinoField.setBEField(myBuff, pStart, pLength, mySigned);
274 myValue = ArduinoField.parseBEField(myBuff, pStart, pLength, true);
275 Assertions.assertEquals(mySigned, myValue, "Parse failure");
276
277
278 if (myRange < myMax) {
279
280 long myTest = i + (myMax - myRange);
281 ArduinoField.setBEField(myBuff, pStart, pLength, myTest);
282 myValue = ArduinoField.parseBEField(myBuff, pStart, pLength, false);
283 Assertions.assertEquals(myTest, myValue, "Parse failure");
284 Arrays.fill(myBuff, (byte) 0);
285
286
287 mySigned = myTest - (1L << pLength - 1);
288 ArduinoField.setLEField(myBuff, pStart, pLength, mySigned);
289 myValue = ArduinoField.parseLEField(myBuff, pStart, pLength, true);
290 Assertions.assertEquals(mySigned, myValue, "Parse failure");
291 Arrays.fill(myBuff, (byte) 0);
292 }
293 }
294 }
295 }