1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.utils.units;
18
19 import org.hipparchus.fraction.Fraction;
20 import org.junit.jupiter.api.Assertions;
21 import org.junit.jupiter.api.Test;
22 import org.orekit.errors.OrekitException;
23 import org.orekit.errors.OrekitMessages;
24
25
26
27
28
29
30 public class LexerTest {
31
32 @Test
33 public void testAllTypes() {
34 final Lexer lexer = new Lexer("√kg*km** (3/2) /(µs^2*Ω⁻⁷)");
35 expect(lexer, "√", TokenType.SQUARE_ROOT, 0, 1);
36 expect(lexer, "kg", TokenType.IDENTIFIER, 0, 1);
37 expect(lexer, "*", TokenType.MULTIPLICATION, 0, 1);
38 expect(lexer, "km", TokenType.IDENTIFIER, 0, 1);
39 expect(lexer, "**", TokenType.POWER, 0, 1);
40 expect(lexer, "(", TokenType.OPEN, 0, 1);
41 expect(lexer, "3", TokenType.INTEGER, 3, 1);
42 expect(lexer, "/", TokenType.DIVISION, 0, 1);
43 expect(lexer, "2", TokenType.INTEGER, 2, 1);
44 expect(lexer, ")", TokenType.CLOSE, 0, 1);
45 expect(lexer, "/", TokenType.DIVISION, 0, 1);
46 expect(lexer, "(", TokenType.OPEN, 0, 1);
47 expect(lexer, "µs", TokenType.IDENTIFIER, 0, 1);
48 expect(lexer, "^", TokenType.POWER, 0, 1);
49 expect(lexer, "2", TokenType.INTEGER, 2, 1);
50 expect(lexer, "*", TokenType.MULTIPLICATION, 0, 1);
51 expect(lexer, "Ω", TokenType.IDENTIFIER, 0, 1);
52 expect(lexer, "", TokenType.POWER, 0, 1);
53 expect(lexer, "⁻⁷", TokenType.INTEGER, -7, 1);
54 expect(lexer, ")", TokenType.CLOSE, 0, 1);
55 Assertions.assertNull(lexer.next());
56 }
57
58 @Test
59 public void testRegularExponent() {
60 final Lexer lexer = new Lexer("N^123450 × MHz^-98765");
61 expect(lexer, "N", TokenType.IDENTIFIER, 0, 1);
62 expect(lexer, "^", TokenType.POWER, 0, 1);
63 expect(lexer, "123450", TokenType.INTEGER, 123450, 1);
64 expect(lexer, "×", TokenType.MULTIPLICATION, 0, 1);
65 expect(lexer, "MHz", TokenType.IDENTIFIER, 0, 1);
66 expect(lexer, "^", TokenType.POWER, 0, 1);
67 expect(lexer, "-98765", TokenType.INTEGER, -98765, 1);
68 Assertions.assertNull(lexer.next());
69 }
70
71 @Test
72 public void testSuperscriptExponent() {
73 final Lexer lexer = new Lexer("SFU⁺¹²³⁴⁵⁰ ⁄ mas⁻⁹⁸⁷⁶⁵");
74 expect(lexer, "SFU", TokenType.IDENTIFIER, 0, 1);
75 expect(lexer, "", TokenType.POWER, 0, 1);
76 expect(lexer, "⁺¹²³⁴⁵⁰", TokenType.INTEGER, 123450, 1);
77 expect(lexer, "⁄", TokenType.DIVISION, 0, 1);
78 expect(lexer, "mas", TokenType.IDENTIFIER, 0, 1);
79 expect(lexer, "", TokenType.POWER, 0, 1);
80 expect(lexer, "⁻⁹⁸⁷⁶⁵", TokenType.INTEGER, -98765, 1);
81 Assertions.assertNull(lexer.next());
82 }
83
84 @Test
85 public void testSignWithoutDigits() {
86 final Lexer lexer = new Lexer("Pa⁻");
87 expect(lexer, "Pa", TokenType.IDENTIFIER, 0, 1);
88 expect(lexer, "", TokenType.POWER, 0, 1);
89 expectFailure(lexer);
90 }
91
92 @Test
93 public void testMultipleSigns() {
94 final Lexer lexer = new Lexer("MJ⁻⁺²");
95 expect(lexer, "MJ", TokenType.IDENTIFIER, 0, 1);
96 expect(lexer, "", TokenType.POWER, 0, 1);
97 expectFailure(lexer);
98 }
99
100 @Test
101 public void testUnknownCharacter() {
102 final Lexer lexer = new Lexer("pW^2∇");
103 expect(lexer, "pW", TokenType.IDENTIFIER, 0, 1);
104 expect(lexer, "^", TokenType.POWER, 0, 1);
105 expect(lexer, "2", TokenType.INTEGER, 2, 1);
106 expectFailure(lexer);
107 }
108
109 @Test
110 public void testPercentageCharacter() {
111 final Lexer lexer = new Lexer("%");
112 expect(lexer, "%", TokenType.IDENTIFIER, 0, 1);
113 Assertions.assertNull(lexer.next());
114 }
115
116 @Test
117 public void testStartWithSuperscript() {
118 final Lexer lexer = new Lexer("³");
119 expect(lexer, "³", TokenType.INTEGER, 3, 1);
120 Assertions.assertNull(lexer.next());
121 }
122
123 @Test
124 public void testCharacters() {
125 final Lexer lexer = new Lexer("d*°*min*◦*deg*′*hh*'*ad*″*a*\"*µ''");
126 expect(lexer, "d", TokenType.IDENTIFIER, 0, 1);
127 expect(lexer, "*", TokenType.MULTIPLICATION, 0, 1);
128 expect(lexer, "°", TokenType.IDENTIFIER, 0, 1);
129 expect(lexer, "*", TokenType.MULTIPLICATION, 0, 1);
130 expect(lexer, "min", TokenType.IDENTIFIER, 0, 1);
131 expect(lexer, "*", TokenType.MULTIPLICATION, 0, 1);
132 expect(lexer, "◦", TokenType.IDENTIFIER, 0, 1);
133 expect(lexer, "*", TokenType.MULTIPLICATION, 0, 1);
134 expect(lexer, "deg", TokenType.IDENTIFIER, 0, 1);
135 expect(lexer, "*", TokenType.MULTIPLICATION, 0, 1);
136 expect(lexer, "′", TokenType.IDENTIFIER, 0, 1);
137 expect(lexer, "*", TokenType.MULTIPLICATION, 0, 1);
138 expect(lexer, "hh", TokenType.IDENTIFIER, 0, 1);
139 expect(lexer, "*", TokenType.MULTIPLICATION, 0, 1);
140 expect(lexer, "'", TokenType.IDENTIFIER, 0, 1);
141 expect(lexer, "*", TokenType.MULTIPLICATION, 0, 1);
142 expect(lexer, "ad", TokenType.IDENTIFIER, 0, 1);
143 expect(lexer, "*", TokenType.MULTIPLICATION, 0, 1);
144 expect(lexer, "″", TokenType.IDENTIFIER, 0, 1);
145 expect(lexer, "*", TokenType.MULTIPLICATION, 0, 1);
146 expect(lexer, "a", TokenType.IDENTIFIER, 0, 1);
147 expect(lexer, "*", TokenType.MULTIPLICATION, 0, 1);
148 expect(lexer, "\"", TokenType.IDENTIFIER, 0, 1);
149 expect(lexer, "*", TokenType.MULTIPLICATION, 0, 1);
150 expect(lexer, "µ''", TokenType.IDENTIFIER, 0, 1);
151 Assertions.assertNull(lexer.next());
152 }
153
154 @Test
155 public void testIdentifierUnicodeLetter() {
156 final String s = "αβγDEFghi";
157 final Lexer lexer = new Lexer(s);
158 expect(lexer, s, TokenType.IDENTIFIER, 0, 1);
159 Assertions.assertNull(lexer.next());
160 }
161
162 @Test
163 public void testOneHalfAsDecimal() {
164 final Lexer lexer = new Lexer("0.5");
165 expect(lexer, "0.5", TokenType.FRACTION, 1, 2);
166 Assertions.assertNull(lexer.next());
167 }
168
169 @Test
170 public void testThreeHalfAsDecimal() {
171 final Lexer lexer = new Lexer("1.5");
172 expect(lexer, "1.5", TokenType.FRACTION, 3, 2);
173 Assertions.assertNull(lexer.next());
174 }
175
176 @Test
177 public void testUnicodeFractions() {
178 final Lexer lexer = new Lexer("¼½¾⅐⅑⅒⅓⅔⅕⅖⅗⅘⅙⅚⅛⅜⅝⅞");
179 expect(lexer, "¼", TokenType.FRACTION, 1, 4);
180 expect(lexer, "½", TokenType.FRACTION, 1, 2);
181 expect(lexer, "¾", TokenType.FRACTION, 3, 4);
182 expect(lexer, "⅐", TokenType.FRACTION, 1, 7);
183 expect(lexer, "⅑", TokenType.FRACTION, 1, 9);
184 expect(lexer, "⅒", TokenType.FRACTION, 1, 10);
185 expect(lexer, "⅓", TokenType.FRACTION, 1, 3);
186 expect(lexer, "⅔", TokenType.FRACTION, 2, 3);
187 expect(lexer, "⅕", TokenType.FRACTION, 1, 5);
188 expect(lexer, "⅖", TokenType.FRACTION, 2, 5);
189 expect(lexer, "⅗", TokenType.FRACTION, 3, 5);
190 expect(lexer, "⅘", TokenType.FRACTION, 4, 5);
191 expect(lexer, "⅙", TokenType.FRACTION, 1, 6);
192 expect(lexer, "⅚", TokenType.FRACTION, 5, 6);
193 expect(lexer, "⅛", TokenType.FRACTION, 1, 8);
194 expect(lexer, "⅜", TokenType.FRACTION, 3, 8);
195 expect(lexer, "⅝", TokenType.FRACTION, 5, 8);
196 expect(lexer, "⅞", TokenType.FRACTION, 7, 8);
197 Assertions.assertNull(lexer.next());
198 }
199
200 @Test
201 public void testPushBack() {
202 final Lexer lexer = new Lexer("m/s");
203 expect(lexer, "m", TokenType.IDENTIFIER, 0, 1);
204 expect(lexer, "/", TokenType.DIVISION, 0, 1);
205 lexer.pushBack();
206 expect(lexer, "/", TokenType.DIVISION, 0, 1);
207 expect(lexer, "s", TokenType.IDENTIFIER, 0, 1);
208 }
209
210 @Test
211 public void testPushBackBeforeVirtualExponent() {
212 final Lexer lexer = new Lexer("m²/s");
213 expect(lexer, "m", TokenType.IDENTIFIER, 0, 1);
214 lexer.pushBack();
215 expect(lexer, "m", TokenType.IDENTIFIER, 0, 1);
216 expect(lexer, "", TokenType.POWER, 0, 1);
217 expect(lexer, "²", TokenType.INTEGER, 2, 1);
218 expect(lexer, "/", TokenType.DIVISION, 0, 1);
219 expect(lexer, "s", TokenType.IDENTIFIER, 0, 1);
220 }
221
222 @Test
223 public void testPushBackAtVirtualExponent() {
224 final Lexer lexer = new Lexer("m²/s");
225 expect(lexer, "m", TokenType.IDENTIFIER, 0, 1);
226 expect(lexer, "", TokenType.POWER, 0, 1);
227 lexer.pushBack();
228 expect(lexer, "", TokenType.POWER, 0, 1);
229 expect(lexer, "²", TokenType.INTEGER, 2, 1);
230 expect(lexer, "/", TokenType.DIVISION, 0, 1);
231 expect(lexer, "s", TokenType.IDENTIFIER, 0, 1);
232 }
233
234 @Test
235 public void testPushBackAfterVirtualExponent() {
236 final Lexer lexer = new Lexer("m²/s");
237 expect(lexer, "m", TokenType.IDENTIFIER, 0, 1);
238 expect(lexer, "", TokenType.POWER, 0, 1);
239 expect(lexer, "²", TokenType.INTEGER, 2, 1);
240 lexer.pushBack();
241 expect(lexer, "²", TokenType.INTEGER, 2, 1);
242 expect(lexer, "/", TokenType.DIVISION, 0, 1);
243 expect(lexer, "s", TokenType.IDENTIFIER, 0, 1);
244 }
245
246 @Test
247 public void testPushBackAtEnd() {
248 final Lexer lexer = new Lexer("m²/s");
249 expect(lexer, "m", TokenType.IDENTIFIER, 0, 1);
250 expect(lexer, "", TokenType.POWER, 0, 1);
251 expect(lexer, "²", TokenType.INTEGER, 2, 1);
252 expect(lexer, "/", TokenType.DIVISION, 0, 1);
253 expect(lexer, "s", TokenType.IDENTIFIER, 0, 1);
254 Assertions.assertNull(lexer.next());
255 lexer.pushBack();
256 Assertions.assertNull(lexer.next());
257 }
258
259 private void expect(Lexer lexer, String subString, TokenType type,
260 int numerator, int denominator) {
261 Token t = lexer.next();
262 Assertions.assertEquals(subString, t.getSubString());
263 Assertions.assertEquals(type, t.getType());
264 Assertions.assertEquals(numerator, t.getInt());
265 Assertions.assertEquals(type == TokenType.FRACTION ? new Fraction(numerator, denominator) : null,
266 t.getFraction());
267 }
268
269 private void expectFailure(Lexer lexer) {
270 try {
271 lexer.next();
272 Assertions.fail("an exception should have been thrown");
273 } catch (OrekitException oe) {
274 Assertions.assertEquals(OrekitMessages.UNKNOWN_UNIT, oe.getSpecifier());
275 Assertions.assertEquals(lexer.getUnitSpecification(), oe.getParts()[0]);
276 }
277 }
278
279 }