forked from playcanvas/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpreprocessor.test.mjs
More file actions
358 lines (276 loc) · 10.5 KB
/
preprocessor.test.mjs
File metadata and controls
358 lines (276 loc) · 10.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
import { expect } from 'chai';
import { Preprocessor } from '../../src/core/preprocessor.js';
describe('Preprocessor', function () {
const includes = new Map([
['inc1', `
block1
#ifdef FEATURE2
nested
#endif
`],
['inc2', 'block2'],
['incLoop', 'inserted{i}\n']
]);
const srcData = `
#define LOOP_COUNT 3
#define {COUNT} 2
#define {STRING} hello
#define FEATURE1
#define FEATURE2
#define AND1
#define AND2
#define OR1
#define OR2
#include "incLoop, LOOP_COUNT"
#if (defined(AND1) && defined(AND2))
ANDS1
#endif
#if (defined(UNDEFINED) && defined(AND2))
ANDS2
#endif
#if (defined(OR1) || defined(OR2))
ORS1
#endif
#if (defined(UNDEFINED) || defined(OR2))
ORS2
#endif
#if (defined(UNDEFINED) || defined(UNDEFINED2) || defined(OR2))
ORS3
#endif
#ifdef FEATURE1
TEST1
#include "inc1"
#endif
#if defined(FEATURE1)
TEST2
#endif
#ifdef FEATURE1
#if defined(FEATURE2)
TEST3
#endif
#endif
#ifndef UNKNOWN
TEST4
#endif
#if defined (UNKNOWN)
TEST5
#include "inc2"
#else
TEST6
#endif
$// comment
// TEST7
/*
TEST8
*/
#ifdef UNKNOWN
TEST9
#elif FEATURE2
TEST10
#else
TEST11
#endif
#undef FEATURE1
#ifdef FEATURE1
TEST12
#endif
#ifndef FEATURE1
TEST13
#endif
#ifdef (UNKNOWN)
#define TEST14 // this should not be defined
#endif
#define INDEX 3
#if INDEX == 3
CMP1
#endif
#if INDEX != 3
CMP2
#endif
#if INDEX > 2
CMP3
#endif
#define NAME hello
#if NAME == hello
CMP4
#endif
#if NAME != hello
CMP5
#endif
// Test parentheses precedence
#define A
#define B
#define C
// Without parentheses, AND has higher precedence than OR
#if defined(A) || defined(B) && defined(UNDEFINED)
PREC1
#endif
// With parentheses, force OR to be evaluated first
#if (defined(A) || defined(B)) && defined(UNDEFINED)
PREC2
#endif
// Nested parentheses
#if (defined(A) && (defined(B) || defined(UNDEFINED))) && defined(C)
PREC3
#endif
// Complex expression with multiple parentheses
#if (defined(A) || defined(UNDEFINED)) && (defined(B) || defined(UNDEFINED)) && defined(C)
PREC4
#endif
// Parentheses with comparisons
#if (INDEX > 2) && (INDEX < 4)
PREC5
#endif
// Mixed defined() and comparisons with parentheses
#if (defined(A) && INDEX == 3) || (defined(UNDEFINED) && INDEX > 10)
PREC6
#endif
// Make sure defined() parentheses are not treated as precedence
#if defined(A) && defined(B)
PREC7
#endif
// Multiple levels of nesting
#if ((defined(A) || defined(B)) && (defined(C) || defined(UNDEFINED))) || defined(UNDEFINED)
PREC8
#endif
// Spaces in and around precedence parens
#if ( ( defined(A) && INDEX == 3) || ( defined(UNDEFINED) && INDEX > 10 ) )
PREC9
#endif
TESTINJECTION {COUNT}
INJECTSTRING {STRING}(x)
`;
it('returns false for MORPH_A', function () {
expect(Preprocessor.run(srcData, includes).includes('MORPH_A')).to.equal(false);
});
it('returns false for MORPH_B', function () {
expect(Preprocessor.run(srcData, includes).includes('MORPH_B')).to.equal(false);
});
it('returns true for $', function () {
expect(Preprocessor.run(srcData, includes).includes('$')).to.equal(true);
});
it('returns true for TEST1', function () {
expect(Preprocessor.run(srcData, includes).includes('TEST1')).to.equal(true);
});
it('returns true for TEST2', function () {
expect(Preprocessor.run(srcData, includes).includes('TEST2')).to.equal(true);
});
it('returns true for TEST3', function () {
expect(Preprocessor.run(srcData, includes).includes('TEST3')).to.equal(true);
});
it('returns true for TEST4', function () {
expect(Preprocessor.run(srcData, includes).includes('TEST4')).to.equal(true);
});
it('returns false for TEST5', function () {
expect(Preprocessor.run(srcData, includes).includes('TEST5')).to.equal(false);
});
it('returns true for TEST6', function () {
expect(Preprocessor.run(srcData, includes).includes('TEST6')).to.equal(true);
});
it('returns false for TEST7', function () {
expect(Preprocessor.run(srcData, includes).includes('TEST7')).to.equal(false);
});
it('returns false for TEST8', function () {
expect(Preprocessor.run(srcData, includes).includes('TEST8')).to.equal(false);
});
it('returns false for TEST9', function () {
expect(Preprocessor.run(srcData, includes).includes('TEST9')).to.equal(false);
});
it('returns true for TEST10', function () {
expect(Preprocessor.run(srcData, includes).includes('TEST10')).to.equal(true);
});
it('returns false for TEST11', function () {
expect(Preprocessor.run(srcData, includes).includes('TEST11')).to.equal(false);
});
it('returns false for TEST12', function () {
expect(Preprocessor.run(srcData, includes).includes('TEST12')).to.equal(false);
});
it('returns true for TEST13', function () {
expect(Preprocessor.run(srcData, includes).includes('TEST13')).to.equal(true);
});
it('returns false for TEST14', function () {
expect(Preprocessor.run(srcData, includes).includes('TEST14')).to.equal(false);
});
it('returns true for INC1', function () {
expect(Preprocessor.run(srcData, includes).includes('block1')).to.equal(true);
});
it('returns false for INC2', function () {
expect(Preprocessor.run(srcData, includes).includes('block2')).to.equal(false);
});
it('returns true for nested', function () {
expect(Preprocessor.run(srcData, includes).includes('nested')).to.equal(true);
});
it('returns true for CMP1', function () {
expect(Preprocessor.run(srcData, includes).includes('CMP1')).to.equal(true);
});
it('returns false for CMP2', function () {
expect(Preprocessor.run(srcData, includes).includes('CMP2')).to.equal(false);
});
it('returns true for CMP3', function () {
expect(Preprocessor.run(srcData, includes).includes('CMP3')).to.equal(true);
});
it('returns true for CMP4', function () {
expect(Preprocessor.run(srcData, includes).includes('CMP4')).to.equal(true);
});
it('returns false for CMP5', function () {
expect(Preprocessor.run(srcData, includes).includes('CMP5')).to.equal(false);
});
it('returns false for any leftover hash symbols', function () {
expect(Preprocessor.run(srcData, includes, { stripDefines: true }).includes('#')).to.equal(false);
});
it('returns true for working integer injection', function () {
expect(Preprocessor.run(srcData, includes).includes('TESTINJECTION 2')).to.equal(true);
});
it('returns true for working string injection', function () {
expect(Preprocessor.run(srcData, includes).includes('INJECTSTRING hello(x)')).to.equal(true);
});
it('returns true for loop injection', function () {
expect(Preprocessor.run(srcData, includes).includes('inserted0')).to.equal(true);
expect(Preprocessor.run(srcData, includes).includes('inserted1')).to.equal(true);
expect(Preprocessor.run(srcData, includes).includes('inserted2')).to.equal(true);
expect(Preprocessor.run(srcData, includes).includes('inserted3')).to.equal(false);
});
it('returns true for ANDS1', function () {
expect(Preprocessor.run(srcData, includes).includes('ANDS1')).to.equal(true);
});
it('returns false for ANDS2', function () {
expect(Preprocessor.run(srcData, includes).includes('ANDS2')).to.equal(false);
});
it('returns true for ORS1', function () {
expect(Preprocessor.run(srcData, includes).includes('ORS1')).to.equal(true);
});
it('returns true for ORS2', function () {
expect(Preprocessor.run(srcData, includes).includes('ORS2')).to.equal(true);
});
it('returns true for ORS3', function () {
expect(Preprocessor.run(srcData, includes).includes('ORS3')).to.equal(true);
});
// Parentheses precedence tests
it('returns true for PREC1 (without parentheses, A || B && UNDEFINED)', function () {
expect(Preprocessor.run(srcData, includes).includes('PREC1')).to.equal(true);
});
it('returns false for PREC2 (with parentheses, (A || B) && UNDEFINED)', function () {
expect(Preprocessor.run(srcData, includes).includes('PREC2')).to.equal(false);
});
it('returns true for PREC3 (nested parentheses)', function () {
expect(Preprocessor.run(srcData, includes).includes('PREC3')).to.equal(true);
});
it('returns true for PREC4 (complex expression with parentheses)', function () {
expect(Preprocessor.run(srcData, includes).includes('PREC4')).to.equal(true);
});
it('returns true for PREC5 (parentheses with comparisons)', function () {
expect(Preprocessor.run(srcData, includes).includes('PREC5')).to.equal(true);
});
it('returns true for PREC6 (mixed defined and comparisons)', function () {
expect(Preprocessor.run(srcData, includes).includes('PREC6')).to.equal(true);
});
it('returns true for PREC7 (defined() parentheses not treated as precedence)', function () {
expect(Preprocessor.run(srcData, includes).includes('PREC7')).to.equal(true);
});
it('returns true for PREC8 (multiple levels of nesting)', function () {
expect(Preprocessor.run(srcData, includes).includes('PREC8')).to.equal(true);
});
it('returns true for PREC9 (spaces inside precedence parens)', function () {
expect(Preprocessor.run(srcData, includes).includes('PREC9')).to.equal(true);
});
});