class ExpressionSetTests extends BaseTest { test_simpleMath() { const grid = new SpreadsheetGrid(1, 1); grid.cells[0][0].originalValue = CellValue.fromCellString('=7*3'); const expressionSet = new CellExpressionSet(grid); expressionSet.calculateCells(); const expected = CellValue.fromValue(21); this.assertEqual(grid.cells[0][0].outputValue, expected); } test_reference() { const grid = new SpreadsheetGrid(3, 1); grid.cells[0][0].originalValue = CellValue.fromValue(123); grid.cells[1][0].originalValue = CellValue.fromValue(3); grid.cells[2][0].originalValue = CellValue.fromCellString('=A1*B1'); const expressionSet = new CellExpressionSet(grid); expressionSet.calculateCells(); const expected = CellValue.fromValue(369); this.assertEqual(grid.cells[2][0].outputValue, expected); } test_infixPriority() { const grid = new SpreadsheetGrid(1, 1); grid.cells[0][0].originalValue = CellValue.fromCellString('=4*9/3+7-4'); const expressionSet = new CellExpressionSet(grid); expressionSet.calculateCells(); const expected = CellValue.fromValue(15); this.assertEqual(grid.cells[0][0].outputValue, expected); } test_filledFormula() { const grid = new SpreadsheetGrid(3, 3); grid.cells[0][0].originalValue = CellValue.fromValue(4); grid.cells[1][0].originalValue = CellValue.fromValue(5); grid.cells[2][0].originalValue = CellValue.fromCellString('=A1*B1 FILL'); grid.cells[0][1].originalValue = CellValue.fromValue(6); grid.cells[1][1].originalValue = CellValue.fromValue(7); grid.cells[0][2].originalValue = CellValue.fromValue(8); grid.cells[1][2].originalValue = CellValue.fromValue(9); const expressionSet = new CellExpressionSet(grid); expressionSet.calculateCells(); this.assertEqual(grid.cells[2][0].outputValue, CellValue.fromValue(20)); this.assertEqual(grid.cells[2][1].outputValue, CellValue.fromValue(42)); this.assertEqual(grid.cells[2][2].outputValue, CellValue.fromValue(72)); } test_dependencies() { const grid = new SpreadsheetGrid(2, 4); grid.cells[0][0].originalValue = CellValue.fromValue(1); grid.cells[1][0].originalValue = CellValue.fromCellString('=A1+B2'); grid.cells[0][1].originalValue = CellValue.fromValue(2); grid.cells[1][1].originalValue = CellValue.fromCellString('=A2+B3'); grid.cells[0][2].originalValue = CellValue.fromValue(3); grid.cells[1][2].originalValue = CellValue.fromCellString('=A3+B4'); grid.cells[0][3].originalValue = CellValue.fromValue(4); grid.cells[1][3].originalValue = CellValue.fromCellString('=A4'); const expressionSet = new CellExpressionSet(grid); expressionSet.calculateCells(); this.assertEqual(grid.cells[1][0].outputValue, CellValue.fromValue(10)); this.assertEqual(grid.cells[1][1].outputValue, CellValue.fromValue(9)); this.assertEqual(grid.cells[1][2].outputValue, CellValue.fromValue(7)); this.assertEqual(grid.cells[1][3].outputValue, CellValue.fromValue(4)); } _test_simple_formula(formula, expected) { const grid = new SpreadsheetGrid(1, 1); grid.cells[0][0].originalValue = CellValue.fromCellString(formula); const expressionSet = new CellExpressionSet(grid); expressionSet.calculateCells(); const result = grid.cells[0][0].outputValue; const exp = (expected instanceof CellValue) ? expected : CellValue.fromValue(expected); this.assertEqual(result.type, exp.type); this.assertEqual(result.decimals, exp.decimals); this.assertEqual(result.formattedValue, exp.formattedValue); this.assertEqual(result.value, exp.value); } test_func_abs() { this._test_simple_formula('=ABS(-3)', 3); this._test_simple_formula('=ABS(4)', 4); } test_func_and() { this._test_simple_formula('=AND(FALSE, FALSE)', false); this._test_simple_formula('=AND(FALSE, TRUE)', false); this._test_simple_formula('=AND(TRUE, FALSE)', false); this._test_simple_formula('=AND(TRUE, TRUE)', true); this._test_simple_formula('=AND(TRUE, TRUE, TRUE, TRUE)', true); this._test_simple_formula('=AND(TRUE, TRUE, TRUE, FALSE)', false); } test_func_average() { this._test_simple_formula('=AVERAGE(4, 6, 2, 4)', 4); this._test_simple_formula('=AVERAGE(4, 6, 2, "foo", 4)', 4); } test_func_ceiling() { this._test_simple_formula('=CEILING(3.1)', 4); this._test_simple_formula('=CEILING(3)', 3); this._test_simple_formula('=CEILING(-3.1)', -3); } test_func_exp() { this._test_simple_formula('=EXP(1)', 2.718281828459045); } test_func_floor() { this._test_simple_formula('=FLOOR(3.1)', 3); this._test_simple_formula('=FLOOR(3)', 3); this._test_simple_formula('=FLOOR(-3.1)', -4); } test_func_if() { this._test_simple_formula('=IF(FALSE, 4, 6)', 6); this._test_simple_formula('=IF(TRUE, 4, 6)', 4); } test_func_ifs() { this._test_simple_formula('=IFS(TRUE, 1, FALSE, 2, FALSE, 3, FALSE, 4, 5)', 1); this._test_simple_formula('=IFS(FALSE, 1, TRUE, 2, FALSE, 3, FALSE, 4, 5)', 2); this._test_simple_formula('=IFS(FALSE, 1, FALSE, 2, TRUE, 3, FALSE, 4, 5)', 3); this._test_simple_formula('=IFS(FALSE, 1, FALSE, 2, FALSE, 3, TRUE, 4, 5)', 4); this._test_simple_formula('=IFS(FALSE, 1, FALSE, 2, FALSE, 3, FALSE, 4, 5)', 5); } test_func_ln() { this._test_simple_formula('=LN(2.718281828459045)', 1); } test_func_log() { this._test_simple_formula('=LOG(1000, 10)', 3); this._test_simple_formula('=LOG(64, 2)', 6); } test_func_lower() { this._test_simple_formula('=LOWER("MiXeD")', 'mixed'); } test_func_max() { this._test_simple_formula('=MAX(4, 8, 5, 2)', 8); } test_func_min() { this._test_simple_formula('=MIN(4, 8, 5, 2)', 2); } test_func_mod() { this._test_simple_formula('=MOD(37, 4)', 1); } test_func_not() { this._test_simple_formula('=NOT(TRUE)', false); this._test_simple_formula('=NOT(FALSE)', true); } test_func_or() { this._test_simple_formula('=OR(FALSE, FALSE)', false); this._test_simple_formula('=OR(FALSE, TRUE)', true); this._test_simple_formula('=OR(TRUE, FALSE)', true); this._test_simple_formula('=OR(TRUE, TRUE)', true); this._test_simple_formula('=OR(FALSE, FALSE, FALSE, TRUE)', true); } test_func_power() { this._test_simple_formula('=POWER(2, 3)', 8); } test_func_round() { this._test_simple_formula('=ROUND(3.1)', 3); this._test_simple_formula('=ROUND(3.5)', 4); this._test_simple_formula('=ROUND(4)', 4); this._test_simple_formula('=ROUND(-3.1)', -3); this._test_simple_formula('=ROUND(-3.5)', -3); this._test_simple_formula('=ROUND(-3.9)', -4); this._test_simple_formula('=ROUND(3.1415926535, 1)', 3.1); this._test_simple_formula('=ROUND(3.1415926535, 2)', 3.14); this._test_simple_formula('=ROUND(31.415926535, -1)', 30); } test_func_sqrt() { this._test_simple_formula('=SQRT(16)', 4); } test_func_substitute() { this._test_simple_formula('=SUBSTITUTE("cat sat on the mat", "at", "ot")', 'cot sot on the mot'); this._test_simple_formula('=SUBSTITUTE("cAt saT on the mat", "at", "ot")', 'cot sot on the mot'); this._test_simple_formula('=SUBSTITUTE("c.*t s.*t on the m.*t", ".*t", "ot")', 'cot sot on the mot'); } test_func_sum() { this._test_simple_formula('=SUM(1, 2, 3, 4, 5)', 15); } test_func_upper() { this._test_simple_formula('=UPPER("mIxEd")', 'MIXED'); } test_func_xor() { this._test_simple_formula('=XOR(FALSE, FALSE)', false); this._test_simple_formula('=XOR(FALSE, TRUE)', true); this._test_simple_formula('=XOR(TRUE, FALSE)', true); this._test_simple_formula('=XOR(TRUE, TRUE)', false); this._test_simple_formula('=XOR(FALSE, FALSE, TRUE)', true); this._test_simple_formula('=XOR(TRUE, FALSE, TRUE)', false); } test_format() { this._test_simple_formula('=2.718281828459045 ; number 3', new CellValue('2.718', 2.718281828459045, 'number', 3)); this._test_simple_formula('=2.718281828459045 ; percent 2', new CellValue('271.83%', 2.718281828459045, 'percent', 2)); this._test_simple_formula('=2.718281828459045 ; currency 2', new CellValue('$2.72', 2.718281828459045, 'currency', 2)); } }