|
|
@@ -228,5 +228,86 @@ final class ExpressionSetTests extends TestCase {
|
|
228
|
228
|
$this->test_simple_formula(new CellValue('271.83%', 2.718281828459045, 'percent', 2), '=2.718281828459045 ; percent 2');
|
|
229
|
229
|
$this->test_simple_formula(new CellValue('$2.72', 2.718281828459045, 'currency', 2), '=2.718281828459045 ; currency 2');
|
|
230
|
230
|
}
|
|
|
231
|
+
|
|
|
232
|
+ private function iterateCharacters(string $formula, bool $testFinal=false) {
|
|
|
233
|
+ for ($i = 1; $i < mb_strlen($formula); $i++) {
|
|
|
234
|
+ $portion = mb_substr($formula, 0, $i);
|
|
|
235
|
+ $grid = new SpreadsheetGrid(1, 1);
|
|
|
236
|
+ $grid->cells[0][0]->originalValue = CellValue::fromCellString($portion);
|
|
|
237
|
+ $expressionSet = new CellExpressionSet($grid);
|
|
|
238
|
+ $expressionSet->calculateCells();
|
|
|
239
|
+ }
|
|
|
240
|
+ if ($testFinal) {
|
|
|
241
|
+ $grid = new SpreadsheetGrid(1, 1);
|
|
|
242
|
+ $grid->cells[0][0]->originalValue = CellValue::fromCellString($formula);
|
|
|
243
|
+ $expressionSet = new CellExpressionSet($grid);
|
|
|
244
|
+ $expressionSet->calculateCells();
|
|
|
245
|
+ $actual = $grid->cells[0][0]->outputValue;
|
|
|
246
|
+ if ($actual === null) {
|
|
|
247
|
+ $this->fail("Expected \"{$formula}\" to evaluate to a value, got null");
|
|
|
248
|
+ } elseif ($actual->type === CellValue::TYPE_ERROR) {
|
|
|
249
|
+ $this->fail("Expected \"{$formula}\" to evaluate to a value, got error {$actual->value->getMessage()}");
|
|
|
250
|
+ }
|
|
|
251
|
+ }
|
|
|
252
|
+ }
|
|
|
253
|
+
|
|
|
254
|
+ public function test_partialAndBrokenSyntax() {
|
|
|
255
|
+ // Like `BrokenSyntaxTests`, this tries parsing a bunch of cell values
|
|
|
256
|
+ // character by character like an author typing them in and makes sure
|
|
|
257
|
+ // they don't throw exceptions. The `true` flag will do a simple check
|
|
|
258
|
+ // that the final complete expression evaluates to something other than
|
|
|
259
|
+ // `null` or an error.
|
|
|
260
|
+ $this->iterateCharacters("123", true);
|
|
|
261
|
+ $this->iterateCharacters("-123", true);
|
|
|
262
|
+ $this->iterateCharacters("true", true);
|
|
|
263
|
+ $this->iterateCharacters("false", true);
|
|
|
264
|
+ $this->iterateCharacters("TrUe", true);
|
|
|
265
|
+ $this->iterateCharacters("fAlSe", true);
|
|
|
266
|
+ $this->iterateCharacters("$123.45", true);
|
|
|
267
|
+ $this->iterateCharacters("-$123.45", true);
|
|
|
268
|
+ $this->iterateCharacters("12.34%", true);
|
|
|
269
|
+ $this->iterateCharacters("-12.34%", true);
|
|
|
270
|
+ $this->iterateCharacters("'01234", true);
|
|
|
271
|
+ $this->iterateCharacters("' ", true);
|
|
|
272
|
+ $this->iterateCharacters("Foo bar", true);
|
|
|
273
|
+ $this->iterateCharacters("=====");
|
|
|
274
|
+ $this->iterateCharacters("=1*2*3*4", true);
|
|
|
275
|
+ $this->iterateCharacters("=1**2");
|
|
|
276
|
+ $this->iterateCharacters("=**123");
|
|
|
277
|
+ $this->iterateCharacters("=6+*3");
|
|
|
278
|
+ $this->iterateCharacters("=)))");
|
|
|
279
|
+ $this->iterateCharacters("=(3*)");
|
|
|
280
|
+ $this->iterateCharacters("=(*3)");
|
|
|
281
|
+ $this->iterateCharacters("=(((");
|
|
|
282
|
+ $this->iterateCharacters("=\")");
|
|
|
283
|
+ $this->iterateCharacters("=-123", true);
|
|
|
284
|
+ $this->iterateCharacters("=--123");
|
|
|
285
|
+ $this->iterateCharacters("=---123");
|
|
|
286
|
+ $this->iterateCharacters("=-\"str\"");
|
|
|
287
|
+ $this->iterateCharacters("=\"str\"&3", true);
|
|
|
288
|
+ $this->iterateCharacters("=1<3", true);
|
|
|
289
|
+ $this->iterateCharacters("=1<=3", true);
|
|
|
290
|
+ $this->iterateCharacters("=1>3", true);
|
|
|
291
|
+ $this->iterateCharacters("=1>=3", true);
|
|
|
292
|
+ $this->iterateCharacters("=1==3", true);
|
|
|
293
|
+ $this->iterateCharacters("=1!=3", true);
|
|
|
294
|
+ $this->iterateCharacters("=>=3");
|
|
|
295
|
+ $this->iterateCharacters("=<=3");
|
|
|
296
|
+ $this->iterateCharacters("=!=3");
|
|
|
297
|
+ $this->iterateCharacters("=MAX)");
|
|
|
298
|
+ $this->iterateCharacters("=MAX(3,,)");
|
|
|
299
|
+ $this->iterateCharacters("=MAX(\"a\",\"b\")");
|
|
|
300
|
+ $this->iterateCharacters("=ZZ999");
|
|
|
301
|
+ $this->iterateCharacters('=$ZZ999');
|
|
|
302
|
+ $this->iterateCharacters('=ZZ$999');
|
|
|
303
|
+ $this->iterateCharacters('=$ZZ$999');
|
|
|
304
|
+ $this->iterateCharacters("=1+2", true);
|
|
|
305
|
+ $this->iterateCharacters("=1-2", true);
|
|
|
306
|
+ $this->iterateCharacters("=1*2", true);
|
|
|
307
|
+ $this->iterateCharacters("=1/2", true);
|
|
|
308
|
+ $this->iterateCharacters("=A1(1)");
|
|
|
309
|
+ $this->iterateCharacters('=$A$1(1)');
|
|
|
310
|
+ $this->assertTrue(true); // to satisfy PHPUnit
|
|
|
311
|
+ }
|
|
231
|
312
|
}
|
|
232
|
313
|
?>
|