mirror of
https://github.com/ruilisi/fortune-sheet.git
synced 2025-01-08 11:47:38 +08:00
Add tabIndex attribute to all tags with an onClick attribute (+ ran npx prettier --write ./packages
to address warnings)
This commit is contained in:
parent
e5b8a11cbb
commit
822cc5524b
@ -1638,7 +1638,7 @@ const make_ssf = function make_ssf(SSF) {
|
||||
throw new Error("cannot find right format for |" + fmt.join("|") + "|");
|
||||
// 这行代码弃用,有可能v会有"1"的情况出现,并且需要排查true,false,‘ ’这些值所以需要使用parseFloat(v).toString()去判断是不是Number类型
|
||||
// if (typeof v !== "number")
|
||||
if(parseFloat(v).toString() == "NaN")
|
||||
if (parseFloat(v).toString() == "NaN")
|
||||
return [4, fmt.length === 4 || lat > -1 ? fmt[fmt.length - 1] : "@"];
|
||||
switch (fmt.length) {
|
||||
case 1:
|
||||
@ -1717,15 +1717,15 @@ const make_ssf = function make_ssf(SSF) {
|
||||
if (vlength > 4) {
|
||||
if (vlength > 8) {
|
||||
var y = parseInt(v / 100000000); //亿
|
||||
var w = parseInt(parseFloat(v)-(y * 100000000) / 10000); //万
|
||||
var q = parseFloat(v)-(y * 100000000 + w * 10000); //千以后
|
||||
var w = parseInt(parseFloat(v) - (y * 100000000) / 10000); //万
|
||||
var q = parseFloat(v) - (y * 100000000 + w * 10000); //千以后
|
||||
if (acc != "") {
|
||||
q = numeral(q).format(acc); //处理精确度
|
||||
}
|
||||
v = y + "亿" + w + "万" + q;
|
||||
} else {
|
||||
var w = parseInt(v / 10000); //万
|
||||
var q = parseFloat(v)-(w * 10000); //千以后
|
||||
var q = parseFloat(v) - w * 10000; //千以后
|
||||
if (acc != "") {
|
||||
q = numeral(q).format(acc); //处理精确度
|
||||
}
|
||||
|
@ -1,19 +1,25 @@
|
||||
{
|
||||
"presets": [
|
||||
["@babel/preset-env", {
|
||||
modules: false,
|
||||
}]
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"modules": false
|
||||
}
|
||||
]
|
||||
],
|
||||
"env": {
|
||||
"commonjs": {
|
||||
"plugins": [
|
||||
["@babel/plugin-transform-modules-commonjs", { loose: true }]
|
||||
["@babel/plugin-transform-modules-commonjs", { "loose": true }]
|
||||
]
|
||||
},
|
||||
"es": {
|
||||
"plugins": [
|
||||
["./.config/plugin/babel/add-import-extension.js", { extension: "mjs" }]
|
||||
[
|
||||
"./.config/plugin/babel/add-import-extension.js",
|
||||
{ "extension": "mjs" }
|
||||
]
|
||||
]
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,24 +4,24 @@ engines:
|
||||
enabled: true
|
||||
config:
|
||||
languages:
|
||||
- ruby
|
||||
- javascript
|
||||
- python
|
||||
- php
|
||||
- ruby
|
||||
- javascript
|
||||
- python
|
||||
- php
|
||||
eslint:
|
||||
enabled: true
|
||||
fixme:
|
||||
enabled: true
|
||||
ratings:
|
||||
paths:
|
||||
- "**.inc"
|
||||
- "**.js"
|
||||
- "**.jsx"
|
||||
- "**.module"
|
||||
- "**.php"
|
||||
- "**.py"
|
||||
- "**.rb"
|
||||
- "**.inc"
|
||||
- "**.js"
|
||||
- "**.jsx"
|
||||
- "**.module"
|
||||
- "**.php"
|
||||
- "**.py"
|
||||
- "**.rb"
|
||||
exclude_paths:
|
||||
- dist/
|
||||
- test/
|
||||
- src/grammar-parser/
|
||||
- dist/
|
||||
- test/
|
||||
- src/grammar-parser/
|
||||
|
@ -1,34 +1,42 @@
|
||||
const { types } = require('@babel/core');
|
||||
const { declare } = require('@babel/helper-plugin-utils');
|
||||
const { existsSync, lstatSync } = require('fs');
|
||||
const { dirname, resolve } = require('path');
|
||||
const { types } = require("@babel/core");
|
||||
const { declare } = require("@babel/helper-plugin-utils");
|
||||
const { existsSync, lstatSync } = require("fs");
|
||||
const { dirname, resolve } = require("path");
|
||||
|
||||
const VALID_EXTENSIONS = ['js', 'mjs'];
|
||||
const VALID_EXTENSIONS = ["js", "mjs"];
|
||||
|
||||
const hasExtension = (moduleName) => VALID_EXTENSIONS.some(ext => moduleName.endsWith(`.${ext}`));
|
||||
const isCoreJSPolyfill = (moduleName) => moduleName.startsWith('core-js');
|
||||
const isLocalModule = (moduleName) => moduleName.startsWith('.');
|
||||
const hasExtension = (moduleName) =>
|
||||
VALID_EXTENSIONS.some((ext) => moduleName.endsWith(`.${ext}`));
|
||||
const isCoreJSPolyfill = (moduleName) => moduleName.startsWith("core-js");
|
||||
const isLocalModule = (moduleName) => moduleName.startsWith(".");
|
||||
const isNodeModule = (moduleName) => {
|
||||
try {
|
||||
require.resolve(moduleName);
|
||||
|
||||
return true;
|
||||
} catch (ex) {
|
||||
if (ex.code === 'MODULE_NOT_FOUND') {
|
||||
if (ex.code === "MODULE_NOT_FOUND") {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const isProcessableModule = (moduleName) => {
|
||||
return !hasExtension(moduleName) && (isCoreJSPolyfill(moduleName) || isLocalModule(moduleName));
|
||||
}
|
||||
return (
|
||||
!hasExtension(moduleName) &&
|
||||
(isCoreJSPolyfill(moduleName) || isLocalModule(moduleName))
|
||||
);
|
||||
};
|
||||
|
||||
const createVisitor = ({ declaration, origArgs, extension = 'js' }) => {
|
||||
const createVisitor = ({ declaration, origArgs, extension = "js" }) => {
|
||||
return (path, { file }) => {
|
||||
const { node: { source, exportKind, importKind } } = path;
|
||||
const { opts: { filename } } = file;
|
||||
const isTypeOnly = exportKind === 'type' || importKind === 'type';
|
||||
const {
|
||||
node: { source, exportKind, importKind },
|
||||
} = path;
|
||||
const {
|
||||
opts: { filename },
|
||||
} = file;
|
||||
const isTypeOnly = exportKind === "type" || importKind === "type";
|
||||
|
||||
if (!source || isTypeOnly || !isProcessableModule(source.value)) {
|
||||
return;
|
||||
@ -36,7 +44,7 @@ const createVisitor = ({ declaration, origArgs, extension = 'js' }) => {
|
||||
|
||||
const { value: moduleName } = source;
|
||||
const absoluteFilePath = resolve(dirname(filename), moduleName);
|
||||
const finalExtension = isCoreJSPolyfill(moduleName) ? 'js' : extension;
|
||||
const finalExtension = isCoreJSPolyfill(moduleName) ? "js" : extension;
|
||||
|
||||
let newModulePath;
|
||||
|
||||
@ -59,17 +67,22 @@ const createVisitor = ({ declaration, origArgs, extension = 'js' }) => {
|
||||
if (existsSync(`${absoluteFilePath}.js`)) {
|
||||
newModulePath = `${moduleName}.${finalExtension}`;
|
||||
|
||||
// In a case when the file doesn't exist and the module is a directory it will
|
||||
// rename to `plugins/index.js`.
|
||||
} else if (existsSync(absoluteFilePath) && lstatSync(absoluteFilePath).isDirectory()) {
|
||||
newModulePath = `${moduleName}/index.${finalExtension}`;
|
||||
// In a case when the file doesn't exist and the module is a directory it will
|
||||
// rename to `plugins/index.js`.
|
||||
} else if (
|
||||
existsSync(absoluteFilePath) &&
|
||||
lstatSync(absoluteFilePath).isDirectory()
|
||||
) {
|
||||
newModulePath = `${moduleName}/index.${finalExtension}`;
|
||||
|
||||
// And for other cases it simply put the extension on the end of the module path
|
||||
// And for other cases it simply put the extension on the end of the module path
|
||||
} else {
|
||||
newModulePath = `${moduleName}.${finalExtension}`;
|
||||
}
|
||||
|
||||
path.replaceWith(declaration(...origArgs(path), types.stringLiteral(newModulePath)));
|
||||
path.replaceWith(
|
||||
declaration(...origArgs(path), types.stringLiteral(newModulePath))
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
@ -77,7 +90,7 @@ module.exports = declare((api, options) => {
|
||||
api.assertVersion(7);
|
||||
|
||||
return {
|
||||
name: 'add-import-extension',
|
||||
name: "add-import-extension",
|
||||
visitor: {
|
||||
// It covers default and named imports
|
||||
ImportDeclaration: createVisitor({
|
||||
@ -88,13 +101,16 @@ module.exports = declare((api, options) => {
|
||||
ExportNamedDeclaration: createVisitor({
|
||||
extension: options.extension,
|
||||
declaration: types.exportNamedDeclaration,
|
||||
origArgs: ({ node: { declaration, specifiers } }) => [declaration, specifiers],
|
||||
origArgs: ({ node: { declaration, specifiers } }) => [
|
||||
declaration,
|
||||
specifiers,
|
||||
],
|
||||
}),
|
||||
ExportAllDeclaration: createVisitor({
|
||||
extension: options.extension,
|
||||
declaration: types.exportAllDeclaration,
|
||||
origArgs: () => [],
|
||||
}),
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
export default {
|
||||
target: 'browser',
|
||||
target: "browser",
|
||||
cjs: { type: "babel", lazy: true },
|
||||
esm: { type: "babel" },
|
||||
disableTypeCheck: false,
|
||||
|
@ -5,17 +5,8 @@
|
||||
"skip_git_push": false,
|
||||
"release_message": true,
|
||||
"remote": "origin",
|
||||
"pre_commit_commands": [
|
||||
"npm run clean",
|
||||
"npm run build",
|
||||
"npm run test"
|
||||
],
|
||||
"pre_commit_commands": ["npm run clean", "npm run build", "npm run test"],
|
||||
"post_commit_commands": [],
|
||||
"post_complete_commands": [
|
||||
"cd tmp && npm publish",
|
||||
"npm run clean"
|
||||
],
|
||||
"files_to_commit": [
|
||||
"./dist/**/*"
|
||||
]
|
||||
"post_complete_commands": ["cd tmp && npm publish", "npm run clean"],
|
||||
"files_to_commit": ["./dist/**/*"]
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ language: node_js
|
||||
sudo: false
|
||||
|
||||
node_js:
|
||||
- '10'
|
||||
- "10"
|
||||
|
||||
install:
|
||||
- npm ci
|
||||
|
@ -1,13 +1,12 @@
|
||||
:warning: This repository is deprecated. We've released new and improved [HyperFormula](https://github.com/handsontable/hyperformula/) engine.
|
||||
|
||||
|
||||
<details>
|
||||
|
||||
Formula Parser [![Build Status](https://travis-ci.org/handsontable/formula-parser.png?branch=master)](https://travis-ci.org/handsontable/formula-parser) [![Test Coverage](https://codeclimate.com/github/handsontable/formula-parser/badges/coverage.svg)](https://codeclimate.com/github/handsontable/formula-parser/coverage) [![hot-formula-parser](https://img.shields.io/npm/v/hot-formula-parser.svg)](https://www.npmjs.com/package/hot-formula-parser)
|
||||
==========
|
||||
# Formula Parser [![Build Status](https://travis-ci.org/handsontable/formula-parser.png?branch=master)](https://travis-ci.org/handsontable/formula-parser) [![Test Coverage](https://codeclimate.com/github/handsontable/formula-parser/badges/coverage.svg)](https://codeclimate.com/github/handsontable/formula-parser/coverage) [![hot-formula-parser](https://img.shields.io/npm/v/hot-formula-parser.svg)](https://www.npmjs.com/package/hot-formula-parser)
|
||||
|
||||
Library provides a `Parser` class that evaluates excel and mathematical formulas.
|
||||
|
||||
- - -
|
||||
---
|
||||
|
||||
## Install
|
||||
|
||||
@ -18,38 +17,41 @@ $ npm install hot-formula-parser --save
|
||||
```
|
||||
|
||||
Node.js:
|
||||
|
||||
```js
|
||||
var FormulaParser = require('hot-formula-parser').Parser;
|
||||
var FormulaParser = require("hot-formula-parser").Parser;
|
||||
var parser = new FormulaParser();
|
||||
|
||||
parser.parse('SUM(1, 6, 7)'); // It returns `Object {error: null, result: 14}`
|
||||
parser.parse("SUM(1, 6, 7)"); // It returns `Object {error: null, result: 14}`
|
||||
```
|
||||
|
||||
Browser:
|
||||
|
||||
```html
|
||||
<script src="/node_modules/hot-formula-parser/dist/formula-parser.min.js"></script>
|
||||
<script>
|
||||
var parser = new formulaParser.Parser();
|
||||
var parser = new formulaParser.Parser();
|
||||
|
||||
parser.parse('SUM(1, 6, 7)'); // It returns `Object {error: null, result: 14}`
|
||||
parser.parse("SUM(1, 6, 7)"); // It returns `Object {error: null, result: 14}`
|
||||
</script>
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
It supports:
|
||||
|
||||
* Any numbers, negative and positive as float or integer;
|
||||
* Arithmetic operations like `+`, `-`, `/`, `*`, `%`, `^`;
|
||||
* Logical operations like `AND()`, `OR()`, `NOT()`, `XOR()`;
|
||||
* Comparison operations like `=`, `>`, `>=`, `<`, `<=`, `<>`;
|
||||
* All JavaScript Math constants like `PI()`, `E()`, `LN10()`, `LN2()`, `LOG10E()`, `LOG2E()`, `SQRT1_2()`, `SQRT2()`;
|
||||
* String operations like `&` (concatenation eq. `parser.parse('-(2&5)');` will return `-25`);
|
||||
* All excel formulas defined in [formula.js](https://github.com/handsontable/formula.js);
|
||||
* Relative and absolute cell coordinates like `A1`, `$A1`, `A$1`, `$A$1`;
|
||||
* Build-in variables like `TRUE`, `FALSE`, `NULL`
|
||||
* Custom variables;
|
||||
* Custom functions/formulas;
|
||||
* Node and Browser environment.
|
||||
- Any numbers, negative and positive as float or integer;
|
||||
- Arithmetic operations like `+`, `-`, `/`, `*`, `%`, `^`;
|
||||
- Logical operations like `AND()`, `OR()`, `NOT()`, `XOR()`;
|
||||
- Comparison operations like `=`, `>`, `>=`, `<`, `<=`, `<>`;
|
||||
- All JavaScript Math constants like `PI()`, `E()`, `LN10()`, `LN2()`, `LOG10E()`, `LOG2E()`, `SQRT1_2()`, `SQRT2()`;
|
||||
- String operations like `&` (concatenation eq. `parser.parse('-(2&5)');` will return `-25`);
|
||||
- All excel formulas defined in [formula.js](https://github.com/handsontable/formula.js);
|
||||
- Relative and absolute cell coordinates like `A1`, `$A1`, `A$1`, `$A$1`;
|
||||
- Build-in variables like `TRUE`, `FALSE`, `NULL`
|
||||
- Custom variables;
|
||||
- Custom functions/formulas;
|
||||
- Node and Browser environment.
|
||||
|
||||
## API (methods)
|
||||
|
||||
@ -61,17 +63,18 @@ var parser = new formulaParser.Parser();
|
||||
|
||||
Parses and evaluates provided expression. It always returns an object with `result` and `error` properties. `result` property
|
||||
always keep evaluated value. If error occurs `error` property will be set as:
|
||||
* `#ERROR!` General error;
|
||||
* `#DIV/0!` Divide by zero error;
|
||||
* `#NAME?` Not recognised function name or variable name;
|
||||
* `#N/A` Indicates that a value is not available to a formula;
|
||||
* `#NUM!` Occurs when formula encounters an invalid number;
|
||||
* `#VALUE!` Occurs when one of formula arguments is of the wrong type.
|
||||
|
||||
- `#ERROR!` General error;
|
||||
- `#DIV/0!` Divide by zero error;
|
||||
- `#NAME?` Not recognised function name or variable name;
|
||||
- `#N/A` Indicates that a value is not available to a formula;
|
||||
- `#NUM!` Occurs when formula encounters an invalid number;
|
||||
- `#VALUE!` Occurs when one of formula arguments is of the wrong type.
|
||||
|
||||
```js
|
||||
parser.parse('(1 + 5 + (5 * 10)) / 10'); // returns `Object {error: null, result: 5.6}`
|
||||
parser.parse('SUM(MY_VAR)'); // returns `Object {error: "#NAME?", result: null}`
|
||||
parser.parse('1;;1'); // returns `Object {error: "#ERROR!", result: null}`
|
||||
parser.parse("(1 + 5 + (5 * 10)) / 10"); // returns `Object {error: null, result: 5.6}`
|
||||
parser.parse("SUM(MY_VAR)"); // returns `Object {error: "#NAME?", result: null}`
|
||||
parser.parse("1;;1"); // returns `Object {error: "#ERROR!", result: null}`
|
||||
```
|
||||
|
||||
### .setVariable(name, value)
|
||||
@ -79,10 +82,10 @@ parser.parse('1;;1'); // returns `Object {error: "#ERROR!", result: null}`
|
||||
Set predefined variable name which can be visible while parsing formula expression.
|
||||
|
||||
```js
|
||||
parser.setVariable('MY_VARIABLE', 5);
|
||||
parser.setVariable('fooBar', 10);
|
||||
parser.setVariable("MY_VARIABLE", 5);
|
||||
parser.setVariable("fooBar", 10);
|
||||
|
||||
parser.parse('(1 + MY_VARIABLE + (5 * fooBar)) / fooBar'); // returns `5.6`
|
||||
parser.parse("(1 + MY_VARIABLE + (5 * fooBar)) / fooBar"); // returns `5.6`
|
||||
```
|
||||
|
||||
### .getVariable(name)
|
||||
@ -90,9 +93,9 @@ parser.parse('(1 + MY_VARIABLE + (5 * fooBar)) / fooBar'); // returns `5.6`
|
||||
Get variable name.
|
||||
|
||||
```js
|
||||
parser.setVariable('fooBar', 10);
|
||||
parser.setVariable("fooBar", 10);
|
||||
|
||||
parser.getVariable('fooBar'); // returns `10`
|
||||
parser.getVariable("fooBar"); // returns `10`
|
||||
```
|
||||
|
||||
### .setFunction(name, fn)
|
||||
@ -100,17 +103,17 @@ parser.getVariable('fooBar'); // returns `10`
|
||||
Set custom function which can be visible while parsing formula expression.
|
||||
|
||||
```js
|
||||
parser.setFunction('ADD_5', function(params) {
|
||||
parser.setFunction("ADD_5", function (params) {
|
||||
return params[0] + 5;
|
||||
});
|
||||
parser.setFunction('GET_LETTER', function(params) {
|
||||
parser.setFunction("GET_LETTER", function (params) {
|
||||
var string = params[0];
|
||||
var index = params[1] - 1;
|
||||
|
||||
return string.charAt(index);
|
||||
});
|
||||
|
||||
parser.parse('SUM(4, ADD_5(1))'); // returns `10`
|
||||
parser.parse("SUM(4, ADD_5(1))"); // returns `10`
|
||||
parser.parse('GET_LETTER("Some string", 3)'); // returns `m`
|
||||
```
|
||||
|
||||
@ -119,11 +122,11 @@ parser.parse('GET_LETTER("Some string", 3)'); // returns `m`
|
||||
Get custom function.
|
||||
|
||||
```js
|
||||
parser.setFunction('ADD_5', function(params) {
|
||||
parser.setFunction("ADD_5", function (params) {
|
||||
return params[0] + 5;
|
||||
});
|
||||
|
||||
parser.getFunction('ADD_5')([1]); // returns `6`
|
||||
parser.getFunction("ADD_5")([1]); // returns `6`
|
||||
```
|
||||
|
||||
### .SUPPORTED_FORMULAS
|
||||
@ -131,7 +134,7 @@ parser.getFunction('ADD_5')([1]); // returns `6`
|
||||
List of all supported formulas function.
|
||||
|
||||
```js
|
||||
require('hot-formula-parser').SUPPORTED_FORMULAS; // An array of formula names
|
||||
require("hot-formula-parser").SUPPORTED_FORMULAS; // An array of formula names
|
||||
```
|
||||
|
||||
## API (hooks)
|
||||
@ -141,13 +144,13 @@ require('hot-formula-parser').SUPPORTED_FORMULAS; // An array of formula names
|
||||
Fired while retrieving variable. If variable was defined earlier using `setVariable` you can overwrite it by this hook.
|
||||
|
||||
```js
|
||||
parser.on('callVariable', function(name, done) {
|
||||
if (name === 'foo') {
|
||||
parser.on("callVariable", function (name, done) {
|
||||
if (name === "foo") {
|
||||
done(Math.PI / 2);
|
||||
}
|
||||
});
|
||||
|
||||
parser.parse('SUM(SIN(foo), COS(foo))'); // returns `1`
|
||||
parser.parse("SUM(SIN(foo), COS(foo))"); // returns `1`
|
||||
```
|
||||
|
||||
### 'callFunction' (name, params, done)
|
||||
@ -156,13 +159,13 @@ Fired while calling function. If function was defined earlier using `setFunction
|
||||
You can also use this to override result of build-in formulas.
|
||||
|
||||
```js
|
||||
parser.on('callFunction', function(name, params, done) {
|
||||
if (name === 'ADD_5') {
|
||||
parser.on("callFunction", function (name, params, done) {
|
||||
if (name === "ADD_5") {
|
||||
done(params[0] + 5);
|
||||
}
|
||||
});
|
||||
|
||||
parser.parse('ADD_5(3)'); // returns `8`
|
||||
parser.parse("ADD_5(3)"); // returns `8`
|
||||
```
|
||||
|
||||
### 'callCellValue' (cellCoord, done)
|
||||
@ -170,24 +173,29 @@ parser.parse('ADD_5(3)'); // returns `8`
|
||||
Fired while retrieving cell value by its label (eq: `B3`, `B$3`, `B$3`, `$B$3`).
|
||||
|
||||
```js
|
||||
parser.on('callCellValue', function(cellCoord, done) {
|
||||
parser.on("callCellValue", function (cellCoord, done) {
|
||||
// using label
|
||||
if (cellCoord.label === 'B$6') {
|
||||
done('hello');
|
||||
if (cellCoord.label === "B$6") {
|
||||
done("hello");
|
||||
}
|
||||
// or using indexes
|
||||
if (cellCoord.row.index === 5 && cellCoord.row.isAbsolute && cellCoord.column.index === 1 && !cellCoord.column.isAbsolute) {
|
||||
done('hello');
|
||||
if (
|
||||
cellCoord.row.index === 5 &&
|
||||
cellCoord.row.isAbsolute &&
|
||||
cellCoord.column.index === 1 &&
|
||||
!cellCoord.column.isAbsolute
|
||||
) {
|
||||
done("hello");
|
||||
}
|
||||
|
||||
if (cellCoord.label === 'C6') {
|
||||
if (cellCoord.label === "C6") {
|
||||
done(0.75);
|
||||
}
|
||||
});
|
||||
|
||||
parser.parse('B$6'); // returns `"hello"`
|
||||
parser.parse("B$6"); // returns `"hello"`
|
||||
parser.parse('B$6&" world"'); // returns `"hello world"`
|
||||
parser.parse('FISHER(C6)'); // returns `0.9729550745276566`
|
||||
parser.parse("FISHER(C6)"); // returns `0.9729550745276566`
|
||||
```
|
||||
|
||||
### 'callRangeValue' (startCellCoord, endCellCoord, done)
|
||||
@ -195,7 +203,7 @@ parser.parse('FISHER(C6)'); // returns `0.9729550745276566`
|
||||
Fired while retrieving cells range value (eq: `A1:B3`, `$A1:B$3`, `A$1:B$3`, `$A$1:$B$3`).
|
||||
|
||||
```js
|
||||
parser.on('callRangeValue', function(startCellCoord, endCellCoord, done) {
|
||||
parser.on("callRangeValue", function (startCellCoord, endCellCoord, done) {
|
||||
var data = [
|
||||
[1, 2, 3, 4, 5],
|
||||
[6, 7, 8, 9, 10],
|
||||
@ -204,11 +212,19 @@ parser.on('callRangeValue', function(startCellCoord, endCellCoord, done) {
|
||||
];
|
||||
var fragment = [];
|
||||
|
||||
for (var row = startCellCoord.row.index; row <= endCellCoord.row.index; row++) {
|
||||
for (
|
||||
var row = startCellCoord.row.index;
|
||||
row <= endCellCoord.row.index;
|
||||
row++
|
||||
) {
|
||||
var rowData = data[row];
|
||||
var colFragment = [];
|
||||
|
||||
for (var col = startCellCoord.column.index; col <= endCellCoord.column.index; col++) {
|
||||
for (
|
||||
var col = startCellCoord.column.index;
|
||||
col <= endCellCoord.column.index;
|
||||
col++
|
||||
) {
|
||||
colFragment.push(rowData[col]);
|
||||
}
|
||||
fragment.push(colFragment);
|
||||
@ -219,10 +235,10 @@ parser.on('callRangeValue', function(startCellCoord, endCellCoord, done) {
|
||||
}
|
||||
});
|
||||
|
||||
parser.parse('JOIN(A1:E2)'); // returns `"1,2,3,4,5,6,7,8,9,10"`
|
||||
parser.parse('COLUMNS(A1:E2)'); // returns `5`
|
||||
parser.parse('ROWS(A1:E2)'); // returns `2`
|
||||
parser.parse('COUNT(A1:E2)'); // returns `10`
|
||||
parser.parse("JOIN(A1:E2)"); // returns `"1,2,3,4,5,6,7,8,9,10"`
|
||||
parser.parse("COLUMNS(A1:E2)"); // returns `5`
|
||||
parser.parse("ROWS(A1:E2)"); // returns `2`
|
||||
parser.parse("COUNT(A1:E2)"); // returns `10`
|
||||
parser.parse('COUNTIF(A1:E2, ">5")'); // returns `5`
|
||||
```
|
||||
|
||||
@ -241,6 +257,5 @@ The MIT License (see the [LICENSE](https://github.com/handsontable/formula-parse
|
||||
### Contact
|
||||
|
||||
You can contact us at hello@handsontable.com.
|
||||
|
||||
</details>
|
||||
|
||||
</details>
|
||||
|
@ -7,9 +7,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/handsontable/formula-parser.git"
|
||||
},
|
||||
"authors": [
|
||||
"Handsoncode", "Handsoncode <hello@handsontable.com>"
|
||||
],
|
||||
"authors": ["Handsoncode", "Handsoncode <hello@handsontable.com>"],
|
||||
"keywords": [
|
||||
"formula",
|
||||
"formulas",
|
||||
@ -18,10 +16,5 @@
|
||||
"excel",
|
||||
"spreadsheet"
|
||||
],
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"src",
|
||||
"test"
|
||||
]
|
||||
"ignore": ["**/.*", "node_modules", "src", "test"]
|
||||
}
|
||||
|
@ -1,19 +1,20 @@
|
||||
const fse = require('fs-extra');
|
||||
const path = require('path');
|
||||
const fse = require("fs-extra");
|
||||
const path = require("path");
|
||||
|
||||
const TARGET_PATH = './tmp';
|
||||
const TARGET_PATH = "./tmp";
|
||||
const filesToMove = [
|
||||
'dist',
|
||||
'CHANGELOG.md',
|
||||
'CONTRIBUTING.md',
|
||||
'LICENSE',
|
||||
'package.json',
|
||||
'README.md',
|
||||
"dist",
|
||||
"CHANGELOG.md",
|
||||
"CONTRIBUTING.md",
|
||||
"LICENSE",
|
||||
"package.json",
|
||||
"README.md",
|
||||
];
|
||||
|
||||
filesToMove.forEach((file) => {
|
||||
fse.copySync(
|
||||
path.resolve(`./${file}`),
|
||||
path.resolve(`${TARGET_PATH}/${file}`),
|
||||
{ overwrite: true });
|
||||
{ overwrite: true }
|
||||
);
|
||||
});
|
||||
|
@ -1,21 +1,21 @@
|
||||
export const ERROR = 'ERROR';
|
||||
export const ERROR_DIV_ZERO = 'DIV/0';
|
||||
export const ERROR_NAME = 'NAME';
|
||||
export const ERROR_NOT_AVAILABLE = 'N/A';
|
||||
export const ERROR_NULL = 'NULL';
|
||||
export const ERROR_NUM = 'NUM';
|
||||
export const ERROR_REF = 'REF';
|
||||
export const ERROR_VALUE = 'VALUE';
|
||||
export const ERROR = "ERROR";
|
||||
export const ERROR_DIV_ZERO = "DIV/0";
|
||||
export const ERROR_NAME = "NAME";
|
||||
export const ERROR_NOT_AVAILABLE = "N/A";
|
||||
export const ERROR_NULL = "NULL";
|
||||
export const ERROR_NUM = "NUM";
|
||||
export const ERROR_REF = "REF";
|
||||
export const ERROR_VALUE = "VALUE";
|
||||
|
||||
const errors = {
|
||||
[ERROR]: '#ERROR!',
|
||||
[ERROR_DIV_ZERO]: '#DIV/0!',
|
||||
[ERROR_NAME]: '#NAME?',
|
||||
[ERROR_NOT_AVAILABLE]: '#N/A',
|
||||
[ERROR_NULL]: '#NULL!',
|
||||
[ERROR_NUM]: '#NUM!',
|
||||
[ERROR_REF]: '#REF!',
|
||||
[ERROR_VALUE]: '#VALUE!',
|
||||
[ERROR]: "#ERROR!",
|
||||
[ERROR_DIV_ZERO]: "#DIV/0!",
|
||||
[ERROR_NAME]: "#NAME?",
|
||||
[ERROR_NOT_AVAILABLE]: "#N/A",
|
||||
[ERROR_NULL]: "#NULL!",
|
||||
[ERROR_NUM]: "#NUM!",
|
||||
[ERROR_REF]: "#REF!",
|
||||
[ERROR_VALUE]: "#VALUE!",
|
||||
};
|
||||
|
||||
/**
|
||||
@ -27,7 +27,7 @@ const errors = {
|
||||
export default function error(type) {
|
||||
let result;
|
||||
|
||||
type = (type + '').replace(/#|!|\?/g, '');
|
||||
type = (type + "").replace(/#|!|\?/g, "");
|
||||
|
||||
if (errors[type]) {
|
||||
result = errors[type];
|
||||
|
@ -1,18 +1,18 @@
|
||||
/* eslint-disable import/no-named-as-default-member */
|
||||
import add from './operator/add';
|
||||
import ampersand from './operator/ampersand';
|
||||
import divide from './operator/divide';
|
||||
import equal from './operator/equal';
|
||||
import formulaFunction from './operator/formula-function';
|
||||
import greaterThan from './operator/greater-than';
|
||||
import greaterThanOrEqual from './operator/greater-than-or-equal';
|
||||
import lessThan from './operator/less-than';
|
||||
import lessThanOrEqual from './operator/less-than-or-equal';
|
||||
import minus from './operator/minus';
|
||||
import multiply from './operator/multiply';
|
||||
import notEqual from './operator/not-equal';
|
||||
import power from './operator/power';
|
||||
import {ERROR_NAME} from './../error';
|
||||
import add from "./operator/add";
|
||||
import ampersand from "./operator/ampersand";
|
||||
import divide from "./operator/divide";
|
||||
import equal from "./operator/equal";
|
||||
import formulaFunction from "./operator/formula-function";
|
||||
import greaterThan from "./operator/greater-than";
|
||||
import greaterThanOrEqual from "./operator/greater-than-or-equal";
|
||||
import lessThan from "./operator/less-than";
|
||||
import lessThanOrEqual from "./operator/less-than-or-equal";
|
||||
import minus from "./operator/minus";
|
||||
import multiply from "./operator/multiply";
|
||||
import notEqual from "./operator/not-equal";
|
||||
import power from "./operator/power";
|
||||
import { ERROR_NAME } from "./../error";
|
||||
|
||||
const availableOperators = Object.create(null);
|
||||
|
||||
|
@ -1,10 +1,13 @@
|
||||
import {toNumber} from './../../helper/number';
|
||||
import {ERROR_VALUE} from './../../error';
|
||||
import { toNumber } from "./../../helper/number";
|
||||
import { ERROR_VALUE } from "./../../error";
|
||||
|
||||
export const SYMBOL = '+';
|
||||
export const SYMBOL = "+";
|
||||
|
||||
export default function func(first, ...rest) {
|
||||
const result = rest.reduce((acc, value) => acc + toNumber(value || 0), toNumber(first || 0));
|
||||
const result = rest.reduce(
|
||||
(acc, value) => acc + toNumber(value || 0),
|
||||
toNumber(first || 0)
|
||||
);
|
||||
|
||||
if (isNaN(result)) {
|
||||
throw Error(ERROR_VALUE);
|
||||
|
@ -1,7 +1,7 @@
|
||||
export const SYMBOL = '&';
|
||||
export const SYMBOL = "&";
|
||||
|
||||
export default function func(...params) {
|
||||
return params.reduce((acc, value) => acc + value.toString(), '');
|
||||
return params.reduce((acc, value) => acc + value.toString(), "");
|
||||
}
|
||||
|
||||
func.SYMBOL = SYMBOL;
|
||||
|
@ -1,10 +1,13 @@
|
||||
import {toNumber} from './../../helper/number';
|
||||
import {ERROR_DIV_ZERO, ERROR_VALUE} from './../../error';
|
||||
import { toNumber } from "./../../helper/number";
|
||||
import { ERROR_DIV_ZERO, ERROR_VALUE } from "./../../error";
|
||||
|
||||
export const SYMBOL = '/';
|
||||
export const SYMBOL = "/";
|
||||
|
||||
export default function func(first, ...rest) {
|
||||
const result = rest.reduce((acc, value) => acc / toNumber(value), toNumber(first));
|
||||
const result = rest.reduce(
|
||||
(acc, value) => acc / toNumber(value),
|
||||
toNumber(first)
|
||||
);
|
||||
|
||||
if (result === Infinity) {
|
||||
return ERROR_DIV_ZERO;
|
||||
|
@ -1,4 +1,4 @@
|
||||
export const SYMBOL = '=';
|
||||
export const SYMBOL = "=";
|
||||
|
||||
export default function func(exp1, exp2) {
|
||||
return exp1 === exp2;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as formulajs from '@formulajs/formulajs';
|
||||
import SUPPORTED_FORMULAS from './../../supported-formulas';
|
||||
import {ERROR_NAME} from './../../error';
|
||||
import * as formulajs from "@formulajs/formulajs";
|
||||
import SUPPORTED_FORMULAS from "./../../supported-formulas";
|
||||
import { ERROR_NAME } from "./../../error";
|
||||
|
||||
export const SYMBOL = SUPPORTED_FORMULAS;
|
||||
|
||||
@ -8,7 +8,7 @@ export default function func(symbol) {
|
||||
return function __formulaFunction(...params) {
|
||||
symbol = symbol.toUpperCase();
|
||||
|
||||
const symbolParts = symbol.split('.');
|
||||
const symbolParts = symbol.split(".");
|
||||
let foundFormula = false;
|
||||
let result;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
export const SYMBOL = '>=';
|
||||
export const SYMBOL = ">=";
|
||||
|
||||
export default function func(exp1, exp2) {
|
||||
return exp1 >= exp2;
|
||||
|
@ -1,4 +1,4 @@
|
||||
export const SYMBOL = '>';
|
||||
export const SYMBOL = ">";
|
||||
|
||||
export default function func(exp1, exp2) {
|
||||
return exp1 > exp2;
|
||||
|
@ -1,4 +1,4 @@
|
||||
export const SYMBOL = '<=';
|
||||
export const SYMBOL = "<=";
|
||||
|
||||
export default function func(exp1, exp2) {
|
||||
return exp1 <= exp2;
|
||||
|
@ -1,4 +1,4 @@
|
||||
export const SYMBOL = '<';
|
||||
export const SYMBOL = "<";
|
||||
|
||||
export default function func(exp1, exp2) {
|
||||
return exp1 < exp2;
|
||||
|
@ -1,10 +1,13 @@
|
||||
import {toNumber} from './../../helper/number';
|
||||
import {ERROR_VALUE} from './../../error';
|
||||
import { toNumber } from "./../../helper/number";
|
||||
import { ERROR_VALUE } from "./../../error";
|
||||
|
||||
export const SYMBOL = '-';
|
||||
export const SYMBOL = "-";
|
||||
|
||||
export default function func(first, ...rest) {
|
||||
const result = rest.reduce((acc, value) => acc - toNumber(value), toNumber(first));
|
||||
const result = rest.reduce(
|
||||
(acc, value) => acc - toNumber(value),
|
||||
toNumber(first)
|
||||
);
|
||||
|
||||
if (isNaN(result)) {
|
||||
throw Error(ERROR_VALUE);
|
||||
|
@ -1,10 +1,13 @@
|
||||
import {toNumber} from './../../helper/number';
|
||||
import {ERROR_VALUE} from './../../error';
|
||||
import { toNumber } from "./../../helper/number";
|
||||
import { ERROR_VALUE } from "./../../error";
|
||||
|
||||
export const SYMBOL = '*';
|
||||
export const SYMBOL = "*";
|
||||
|
||||
export default function func(first, ...rest) {
|
||||
const result = rest.reduce((acc, value) => acc * toNumber(value), toNumber(first));
|
||||
const result = rest.reduce(
|
||||
(acc, value) => acc * toNumber(value),
|
||||
toNumber(first)
|
||||
);
|
||||
|
||||
if (isNaN(result)) {
|
||||
throw Error(ERROR_VALUE);
|
||||
|
@ -1,4 +1,4 @@
|
||||
export const SYMBOL = '<>';
|
||||
export const SYMBOL = "<>";
|
||||
|
||||
export default function func(exp1, exp2) {
|
||||
return exp1 !== exp2;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {toNumber} from './../../helper/number';
|
||||
import {ERROR_VALUE} from './../../error';
|
||||
import { toNumber } from "./../../helper/number";
|
||||
import { ERROR_VALUE } from "./../../error";
|
||||
|
||||
export const SYMBOL = '^';
|
||||
export const SYMBOL = "^";
|
||||
|
||||
export default function func(exp1, exp2) {
|
||||
const result = Math.pow(toNumber(exp1), toNumber(exp2));
|
||||
|
@ -23,7 +23,7 @@ export function rowLabelToIndex(label) {
|
||||
* @returns {String} Returns row label (eq. '1', '7').
|
||||
*/
|
||||
export function rowIndexToLabel(row) {
|
||||
let result = '';
|
||||
let result = "";
|
||||
|
||||
if (row >= 0) {
|
||||
result = `${row + 1}`;
|
||||
@ -32,7 +32,7 @@ export function rowIndexToLabel(row) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const COLUMN_LABEL_BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
const COLUMN_LABEL_BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
const COLUMN_LABEL_BASE_LENGTH = COLUMN_LABEL_BASE.length;
|
||||
|
||||
/**
|
||||
@ -44,11 +44,13 @@ const COLUMN_LABEL_BASE_LENGTH = COLUMN_LABEL_BASE.length;
|
||||
export function columnLabelToIndex(label) {
|
||||
let result = 0;
|
||||
|
||||
if (typeof label === 'string') {
|
||||
if (typeof label === "string") {
|
||||
label = label.toUpperCase();
|
||||
|
||||
for (let i = 0, j = label.length - 1; i < label.length; i += 1, j -= 1) {
|
||||
result += Math.pow(COLUMN_LABEL_BASE_LENGTH, j) * (COLUMN_LABEL_BASE.indexOf(label[i]) + 1);
|
||||
result +=
|
||||
Math.pow(COLUMN_LABEL_BASE_LENGTH, j) *
|
||||
(COLUMN_LABEL_BASE.indexOf(label[i]) + 1);
|
||||
}
|
||||
}
|
||||
--result;
|
||||
@ -63,20 +65,23 @@ export function columnLabelToIndex(label) {
|
||||
* @returns {String} Returns column label (eq. 'ABB', 'CNQ').
|
||||
*/
|
||||
export function columnIndexToLabel(column) {
|
||||
let result = '';
|
||||
let result = "";
|
||||
|
||||
while (column >= 0) {
|
||||
result = String.fromCharCode((column % COLUMN_LABEL_BASE_LENGTH) + 97) + result;
|
||||
result =
|
||||
String.fromCharCode((column % COLUMN_LABEL_BASE_LENGTH) + 97) + result;
|
||||
column = Math.floor(column / COLUMN_LABEL_BASE_LENGTH) - 1;
|
||||
}
|
||||
|
||||
return result.toUpperCase();
|
||||
}
|
||||
|
||||
const simpleSheetName = '[A-Za-z0-9_\u00C0-\u02AF]+';
|
||||
const simpleSheetName = "[A-Za-z0-9_\u00C0-\u02AF]+";
|
||||
const quotedSheetName = "'(?:(?!').|'')*'";
|
||||
const sheetNameRegexp = `(${simpleSheetName}|${quotedSheetName})!`;
|
||||
const LABEL_EXTRACT_REGEXP = new RegExp(`^(?:${sheetNameRegexp})?([$])?([A-Za-z]*)([$])?([0-9]*)$`);
|
||||
const LABEL_EXTRACT_REGEXP = new RegExp(
|
||||
`^(?:${sheetNameRegexp})?([$])?([A-Za-z]*)([$])?([0-9]*)$`
|
||||
);
|
||||
|
||||
/**
|
||||
* Extract cell coordinates.
|
||||
@ -85,23 +90,31 @@ const LABEL_EXTRACT_REGEXP = new RegExp(`^(?:${sheetNameRegexp})?([$])?([A-Za-z]
|
||||
* @returns {Array} Returns an array of objects.
|
||||
*/
|
||||
export function extractLabel(label) {
|
||||
if (typeof label !== 'string' || !LABEL_EXTRACT_REGEXP.test(label)) {
|
||||
if (typeof label !== "string" || !LABEL_EXTRACT_REGEXP.test(label)) {
|
||||
return [];
|
||||
}
|
||||
const [, sheetNameStr, columnAbs, column, rowAbs, row] = label.toUpperCase().match(LABEL_EXTRACT_REGEXP);
|
||||
const [, sheetNameStr, columnAbs, column, rowAbs, row] = label
|
||||
.toUpperCase()
|
||||
.match(LABEL_EXTRACT_REGEXP);
|
||||
if (column == null && row == null) return [];
|
||||
const sheetName = sheetNameStr == null ? null : label.slice(0, sheetNameStr.length).replace(/^'|'$/g, "").replace(/''/g, "'");
|
||||
const sheetName =
|
||||
sheetNameStr == null
|
||||
? null
|
||||
: label
|
||||
.slice(0, sheetNameStr.length)
|
||||
.replace(/^'|'$/g, "")
|
||||
.replace(/''/g, "'");
|
||||
|
||||
return [
|
||||
{
|
||||
index: rowLabelToIndex(row),
|
||||
label: row,
|
||||
isAbsolute: rowAbs === '$',
|
||||
isAbsolute: rowAbs === "$",
|
||||
},
|
||||
{
|
||||
index: columnLabelToIndex(column),
|
||||
label: column,
|
||||
isAbsolute: columnAbs === '$',
|
||||
isAbsolute: columnAbs === "$",
|
||||
},
|
||||
sheetName,
|
||||
];
|
||||
@ -115,8 +128,9 @@ export function extractLabel(label) {
|
||||
* @returns {String} Returns cell label.
|
||||
*/
|
||||
export function toLabel(row, column) {
|
||||
const rowLabel = (row.isAbsolute ? '$' : '') + rowIndexToLabel(row.index);
|
||||
const columnLabel = (column.isAbsolute ? '$' : '') + columnIndexToLabel(column.index);
|
||||
const rowLabel = (row.isAbsolute ? "$" : "") + rowIndexToLabel(row.index);
|
||||
const columnLabel =
|
||||
(column.isAbsolute ? "$" : "") + columnIndexToLabel(column.index);
|
||||
|
||||
return columnLabel + rowLabel;
|
||||
}
|
||||
|
@ -7,11 +7,11 @@
|
||||
export function toNumber(number) {
|
||||
let result;
|
||||
|
||||
if (typeof number === 'number') {
|
||||
if (typeof number === "number") {
|
||||
result = number;
|
||||
|
||||
} else if (typeof number === 'string') {
|
||||
result = number.indexOf('.') > -1 ? parseFloat(number) : parseInt(number, 10);
|
||||
} else if (typeof number === "string") {
|
||||
result =
|
||||
number.indexOf(".") > -1 ? parseFloat(number) : parseInt(number, 10);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import Parser from './parser';
|
||||
import SUPPORTED_FORMULAS from './supported-formulas';
|
||||
import Parser from "./parser";
|
||||
import SUPPORTED_FORMULAS from "./supported-formulas";
|
||||
import error, {
|
||||
ERROR,
|
||||
ERROR_DIV_ZERO,
|
||||
@ -9,7 +9,7 @@ import error, {
|
||||
ERROR_NUM,
|
||||
ERROR_REF,
|
||||
ERROR_VALUE,
|
||||
} from './error';
|
||||
} from "./error";
|
||||
import {
|
||||
extractLabel,
|
||||
toLabel,
|
||||
@ -17,7 +17,7 @@ import {
|
||||
columnLabelToIndex,
|
||||
rowIndexToLabel,
|
||||
rowLabelToIndex,
|
||||
} from './helper/cell';
|
||||
} from "./helper/cell";
|
||||
|
||||
export {
|
||||
SUPPORTED_FORMULAS,
|
||||
|
@ -1,10 +1,15 @@
|
||||
import Emitter from 'tiny-emitter';
|
||||
import evaluateByOperator from './evaluate-by-operator/evaluate-by-operator';
|
||||
import {Parser as GrammarParser} from './grammar-parser/grammar-parser';
|
||||
import {trimEdges} from './helper/string';
|
||||
import {toNumber, invertNumber} from './helper/number';
|
||||
import errorParser, {isValidStrict as isErrorValid, ERROR, ERROR_NAME, ERROR_VALUE} from './error';
|
||||
import {extractLabel, toLabel} from './helper/cell';
|
||||
import Emitter from "tiny-emitter";
|
||||
import evaluateByOperator from "./evaluate-by-operator/evaluate-by-operator";
|
||||
import { Parser as GrammarParser } from "./grammar-parser/grammar-parser";
|
||||
import { trimEdges } from "./helper/string";
|
||||
import { toNumber, invertNumber } from "./helper/number";
|
||||
import errorParser, {
|
||||
isValidStrict as isErrorValid,
|
||||
ERROR,
|
||||
ERROR_NAME,
|
||||
ERROR_VALUE,
|
||||
} from "./error";
|
||||
import { extractLabel, toLabel } from "./helper/cell";
|
||||
|
||||
/**
|
||||
* @class Parser
|
||||
@ -28,10 +33,9 @@ class Parser extends Emitter {
|
||||
this.functions = Object.create(null);
|
||||
this.options = Object.create(null);
|
||||
|
||||
this
|
||||
.setVariable('TRUE', true)
|
||||
.setVariable('FALSE', false)
|
||||
.setVariable('NULL', null);
|
||||
this.setVariable("TRUE", true)
|
||||
.setVariable("FALSE", false)
|
||||
.setVariable("NULL", null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -48,8 +52,8 @@ class Parser extends Emitter {
|
||||
this.options = options;
|
||||
|
||||
try {
|
||||
if (expression === '') {
|
||||
result = '';
|
||||
if (expression === "") {
|
||||
result = "";
|
||||
} else {
|
||||
result = this.parser.parse(expression);
|
||||
}
|
||||
@ -107,7 +111,7 @@ class Parser extends Emitter {
|
||||
_callVariable(name) {
|
||||
let value = this.getVariable(name);
|
||||
|
||||
this.emit('callVariable', name, (newValue) => {
|
||||
this.emit("callVariable", name, (newValue) => {
|
||||
if (newValue !== void 0) {
|
||||
value = newValue;
|
||||
}
|
||||
@ -159,7 +163,7 @@ class Parser extends Emitter {
|
||||
value = fn(params);
|
||||
}
|
||||
|
||||
this.emit('callFunction', name, params, (newValue) => {
|
||||
this.emit("callFunction", name, params, (newValue) => {
|
||||
if (newValue !== void 0) {
|
||||
value = newValue;
|
||||
}
|
||||
@ -184,12 +188,17 @@ class Parser extends Emitter {
|
||||
return row.index + 1;
|
||||
} else if (row?.index === -1) {
|
||||
throw Error(ERROR_NAME);
|
||||
}
|
||||
}
|
||||
let value = void 0;
|
||||
|
||||
this.emit('callCellValue', {label, row, column, sheetName}, this.options, (_value) => {
|
||||
value = _value;
|
||||
});
|
||||
this.emit(
|
||||
"callCellValue",
|
||||
{ label, row, column, sheetName },
|
||||
this.options,
|
||||
(_value) => {
|
||||
value = _value;
|
||||
}
|
||||
);
|
||||
|
||||
return value;
|
||||
}
|
||||
@ -233,9 +242,15 @@ class Parser extends Emitter {
|
||||
|
||||
let value = [];
|
||||
|
||||
this.emit('callRangeValue', startCell, endCell, this.options, (_value = []) => {
|
||||
value = _value;
|
||||
});
|
||||
this.emit(
|
||||
"callRangeValue",
|
||||
startCell,
|
||||
endCell,
|
||||
this.options,
|
||||
(_value = []) => {
|
||||
value = _value;
|
||||
}
|
||||
);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import * as formulajs from '@formulajs/formulajs';
|
||||
import * as formulajs from "@formulajs/formulajs";
|
||||
|
||||
const SUPPORTED_FORMULAS = Object.keys(formulajs);
|
||||
|
||||
|
@ -20,10 +20,12 @@ jest.addMatchers({
|
||||
|
||||
if (a === e || isNaN(a) === isNaN(e)) {
|
||||
pass = true;
|
||||
|
||||
} else if (typeof a === 'number' && typeof e === 'number' && Math.abs(a - e) < tolerance(precision)) {
|
||||
} else if (
|
||||
typeof a === "number" &&
|
||||
typeof e === "number" &&
|
||||
Math.abs(a - e) < tolerance(precision)
|
||||
) {
|
||||
pass = true;
|
||||
|
||||
} else {
|
||||
pass = false;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Parser from '../../../src/parser';
|
||||
import Parser from "../../../src/parser";
|
||||
|
||||
describe('.parse() coordinates', () => {
|
||||
describe(".parse() coordinates", () => {
|
||||
let parser;
|
||||
let cellCoord;
|
||||
let startCellCoord;
|
||||
@ -9,11 +9,11 @@ describe('.parse() coordinates', () => {
|
||||
beforeEach(() => {
|
||||
parser = new Parser();
|
||||
|
||||
parser.on('callCellValue', (_cellCoord, done) => {
|
||||
parser.on("callCellValue", (_cellCoord, done) => {
|
||||
cellCoord = _cellCoord;
|
||||
done(55);
|
||||
});
|
||||
parser.on('callRangeValue', (_startCellCoord, _endCellCoord, done) => {
|
||||
parser.on("callRangeValue", (_startCellCoord, _endCellCoord, done) => {
|
||||
startCellCoord = _startCellCoord;
|
||||
endCellCoord = _endCellCoord;
|
||||
done([[3, 6, 10]]);
|
||||
@ -26,275 +26,368 @@ describe('.parse() coordinates', () => {
|
||||
endCellCoord = null;
|
||||
});
|
||||
|
||||
it('should parse relative cell', () => {
|
||||
expect(parser.parse('A1')).toMatchObject({error: null, result: 55});
|
||||
it("should parse relative cell", () => {
|
||||
expect(parser.parse("A1")).toMatchObject({ error: null, result: 55 });
|
||||
expect(cellCoord).toMatchObject({
|
||||
label: 'A1',
|
||||
row: {index: 0, isAbsolute: false, label: '1'},
|
||||
column: {index: 0, isAbsolute: false, label: 'A'},
|
||||
label: "A1",
|
||||
row: { index: 0, isAbsolute: false, label: "1" },
|
||||
column: { index: 0, isAbsolute: false, label: "A" },
|
||||
});
|
||||
|
||||
expect(parser.parse('a1')).toMatchObject({error: null, result: 55});
|
||||
expect(parser.parse("a1")).toMatchObject({ error: null, result: 55 });
|
||||
expect(cellCoord).toMatchObject({
|
||||
label: 'A1',
|
||||
row: {index: 0, isAbsolute: false, label: '1'},
|
||||
column: {index: 0, isAbsolute: false, label: 'A'},
|
||||
label: "A1",
|
||||
row: { index: 0, isAbsolute: false, label: "1" },
|
||||
column: { index: 0, isAbsolute: false, label: "A" },
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse absolute cell', () => {
|
||||
expect(parser.parse('$A$1')).toMatchObject({error: null, result: 55});
|
||||
it("should parse absolute cell", () => {
|
||||
expect(parser.parse("$A$1")).toMatchObject({ error: null, result: 55 });
|
||||
expect(cellCoord).toMatchObject({
|
||||
label: '$A$1',
|
||||
row: {index: 0, isAbsolute: true, label: '1'},
|
||||
column: {index: 0, isAbsolute: true, label: 'A'},
|
||||
label: "$A$1",
|
||||
row: { index: 0, isAbsolute: true, label: "1" },
|
||||
column: { index: 0, isAbsolute: true, label: "A" },
|
||||
});
|
||||
|
||||
expect(parser.parse('$a$1')).toMatchObject({error: null, result: 55});
|
||||
expect(parser.parse("$a$1")).toMatchObject({ error: null, result: 55 });
|
||||
expect(cellCoord).toMatchObject({
|
||||
label: '$A$1',
|
||||
row: {index: 0, isAbsolute: true, label: '1'},
|
||||
column: {index: 0, isAbsolute: true, label: 'A'},
|
||||
label: "$A$1",
|
||||
row: { index: 0, isAbsolute: true, label: "1" },
|
||||
column: { index: 0, isAbsolute: true, label: "A" },
|
||||
});
|
||||
|
||||
expect(parser.parse('$A$$$$1')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('$$A$1')).toMatchObject({error: '#ERROR!', result: null});
|
||||
});
|
||||
|
||||
it('should parse mixed cell', () => {
|
||||
expect(parser.parse('$A1')).toMatchObject({error: null, result: 55});
|
||||
expect(cellCoord).toMatchObject({
|
||||
label: '$A1',
|
||||
row: {index: 0, isAbsolute: false, label: '1'},
|
||||
column: {index: 0, isAbsolute: true, label: 'A'},
|
||||
expect(parser.parse("$A$$$$1")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
|
||||
expect(parser.parse('A$1')).toMatchObject({error: null, result: 55});
|
||||
expect(cellCoord).toMatchObject({
|
||||
label: 'A$1',
|
||||
row: {index: 0, isAbsolute: true, label: '1'},
|
||||
column: {index: 0, isAbsolute: false, label: 'A'},
|
||||
});
|
||||
|
||||
expect(parser.parse('a$1')).toMatchObject({error: null, result: 55});
|
||||
expect(cellCoord).toMatchObject({
|
||||
label: 'A$1',
|
||||
row: {index: 0, isAbsolute: true, label: '1'},
|
||||
column: {index: 0, isAbsolute: false, label: 'A'},
|
||||
});
|
||||
|
||||
expect(parser.parse('A$$1')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('$$A1')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('A1$')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('A1$$$')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('a1$$$')).toMatchObject({error: '#ERROR!', result: null});
|
||||
});
|
||||
|
||||
it('should parse relative cells range', () => {
|
||||
expect(parser.parse('A1:B2')).toMatchObject({error: null, result: [[3, 6, 10]]});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: 'A1',
|
||||
row: {index: 0, isAbsolute: false, label: '1'},
|
||||
column: {index: 0, isAbsolute: false, label: 'A'},
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: 'B2',
|
||||
row: {index: 1, isAbsolute: false, label: '2'},
|
||||
column: {index: 1, isAbsolute: false, label: 'B'},
|
||||
});
|
||||
|
||||
expect(parser.parse('a1:B2')).toMatchObject({error: null, result: [[3, 6, 10]]});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: 'A1',
|
||||
row: {index: 0, isAbsolute: false, label: '1'},
|
||||
column: {index: 0, isAbsolute: false, label: 'A'},
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: 'B2',
|
||||
row: {index: 1, isAbsolute: false, label: '2'},
|
||||
column: {index: 1, isAbsolute: false, label: 'B'},
|
||||
});
|
||||
|
||||
expect(parser.parse('A1:b2')).toMatchObject({error: null, result: [[3, 6, 10]]});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: 'A1',
|
||||
row: {index: 0, isAbsolute: false, label: '1'},
|
||||
column: {index: 0, isAbsolute: false, label: 'A'},
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: 'B2',
|
||||
row: {index: 1, isAbsolute: false, label: '2'},
|
||||
column: {index: 1, isAbsolute: false, label: 'B'},
|
||||
});
|
||||
|
||||
expect(parser.parse('a1:b2')).toMatchObject({error: null, result: [[3, 6, 10]]});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: 'A1',
|
||||
row: {index: 0, isAbsolute: false, label: '1'},
|
||||
column: {index: 0, isAbsolute: false, label: 'A'},
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: 'B2',
|
||||
row: {index: 1, isAbsolute: false, label: '2'},
|
||||
column: {index: 1, isAbsolute: false, label: 'B'},
|
||||
expect(parser.parse("$$A$1")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse absolute cells range', () => {
|
||||
expect(parser.parse('$A$1:$B$2')).toMatchObject({error: null, result: [[3, 6, 10]]});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: '$A$1',
|
||||
row: {index: 0, isAbsolute: true, label: '1'},
|
||||
column: {index: 0, isAbsolute: true, label: 'A'},
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: '$B$2',
|
||||
row: {index: 1, isAbsolute: true, label: '2'},
|
||||
column: {index: 1, isAbsolute: true, label: 'B'},
|
||||
it("should parse mixed cell", () => {
|
||||
expect(parser.parse("$A1")).toMatchObject({ error: null, result: 55 });
|
||||
expect(cellCoord).toMatchObject({
|
||||
label: "$A1",
|
||||
row: { index: 0, isAbsolute: false, label: "1" },
|
||||
column: { index: 0, isAbsolute: true, label: "A" },
|
||||
});
|
||||
|
||||
expect(parser.parse('$a$1:$B$2')).toMatchObject({error: null, result: [[3, 6, 10]]});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: '$A$1',
|
||||
row: {index: 0, isAbsolute: true, label: '1'},
|
||||
column: {index: 0, isAbsolute: true, label: 'A'},
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: '$B$2',
|
||||
row: {index: 1, isAbsolute: true, label: '2'},
|
||||
column: {index: 1, isAbsolute: true, label: 'B'},
|
||||
expect(parser.parse("A$1")).toMatchObject({ error: null, result: 55 });
|
||||
expect(cellCoord).toMatchObject({
|
||||
label: "A$1",
|
||||
row: { index: 0, isAbsolute: true, label: "1" },
|
||||
column: { index: 0, isAbsolute: false, label: "A" },
|
||||
});
|
||||
|
||||
expect(parser.parse('$a$1:$b$2')).toMatchObject({error: null, result: [[3, 6, 10]]});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: '$A$1',
|
||||
row: {index: 0, isAbsolute: true, label: '1'},
|
||||
column: {index: 0, isAbsolute: true, label: 'A'},
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: '$B$2',
|
||||
row: {index: 1, isAbsolute: true, label: '2'},
|
||||
column: {index: 1, isAbsolute: true, label: 'B'},
|
||||
expect(parser.parse("a$1")).toMatchObject({ error: null, result: 55 });
|
||||
expect(cellCoord).toMatchObject({
|
||||
label: "A$1",
|
||||
row: { index: 0, isAbsolute: true, label: "1" },
|
||||
column: { index: 0, isAbsolute: false, label: "A" },
|
||||
});
|
||||
|
||||
expect(parser.parse('$A$$1:$B$2')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('$A$1:$B$$2')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('$A$1:$$B$2')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('$$A$1:$B$2')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse("A$$1")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("$$A1")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("A1$")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("A1$$$")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("a1$$$")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse mixed cells range', () => {
|
||||
expect(parser.parse('$A$1:B2')).toMatchObject({error: null, result: [[3, 6, 10]]});
|
||||
it("should parse relative cells range", () => {
|
||||
expect(parser.parse("A1:B2")).toMatchObject({
|
||||
error: null,
|
||||
result: [[3, 6, 10]],
|
||||
});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: '$A$1',
|
||||
row: {index: 0, isAbsolute: true, label: '1'},
|
||||
column: {index: 0, isAbsolute: true, label: 'A'},
|
||||
label: "A1",
|
||||
row: { index: 0, isAbsolute: false, label: "1" },
|
||||
column: { index: 0, isAbsolute: false, label: "A" },
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: 'B2',
|
||||
row: {index: 1, isAbsolute: false, label: '2'},
|
||||
column: {index: 1, isAbsolute: false, label: 'B'},
|
||||
label: "B2",
|
||||
row: { index: 1, isAbsolute: false, label: "2" },
|
||||
column: { index: 1, isAbsolute: false, label: "B" },
|
||||
});
|
||||
|
||||
expect(parser.parse('$A$1:b2')).toMatchObject({error: null, result: [[3, 6, 10]]});
|
||||
expect(parser.parse("a1:B2")).toMatchObject({
|
||||
error: null,
|
||||
result: [[3, 6, 10]],
|
||||
});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: '$A$1',
|
||||
row: {index: 0, isAbsolute: true, label: '1'},
|
||||
column: {index: 0, isAbsolute: true, label: 'A'},
|
||||
label: "A1",
|
||||
row: { index: 0, isAbsolute: false, label: "1" },
|
||||
column: { index: 0, isAbsolute: false, label: "A" },
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: 'B2',
|
||||
row: {index: 1, isAbsolute: false, label: '2'},
|
||||
column: {index: 1, isAbsolute: false, label: 'B'},
|
||||
label: "B2",
|
||||
row: { index: 1, isAbsolute: false, label: "2" },
|
||||
column: { index: 1, isAbsolute: false, label: "B" },
|
||||
});
|
||||
|
||||
expect(parser.parse('A1:$B$2')).toMatchObject({error: null, result: [[3, 6, 10]]});
|
||||
expect(parser.parse("A1:b2")).toMatchObject({
|
||||
error: null,
|
||||
result: [[3, 6, 10]],
|
||||
});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: 'A1',
|
||||
row: {index: 0, isAbsolute: false, label: '1'},
|
||||
column: {index: 0, isAbsolute: false, label: 'A'},
|
||||
label: "A1",
|
||||
row: { index: 0, isAbsolute: false, label: "1" },
|
||||
column: { index: 0, isAbsolute: false, label: "A" },
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: '$B$2',
|
||||
row: {index: 1, isAbsolute: true, label: '2'},
|
||||
column: {index: 1, isAbsolute: true, label: 'B'},
|
||||
label: "B2",
|
||||
row: { index: 1, isAbsolute: false, label: "2" },
|
||||
column: { index: 1, isAbsolute: false, label: "B" },
|
||||
});
|
||||
|
||||
expect(parser.parse('$A$1:B$2')).toMatchObject({error: null, result: [[3, 6, 10]]});
|
||||
expect(parser.parse("a1:b2")).toMatchObject({
|
||||
error: null,
|
||||
result: [[3, 6, 10]],
|
||||
});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: '$A$1',
|
||||
row: {index: 0, isAbsolute: true, label: '1'},
|
||||
column: {index: 0, isAbsolute: true, label: 'A'},
|
||||
label: "A1",
|
||||
row: { index: 0, isAbsolute: false, label: "1" },
|
||||
column: { index: 0, isAbsolute: false, label: "A" },
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: 'B$2',
|
||||
row: {index: 1, isAbsolute: true, label: '2'},
|
||||
column: {index: 1, isAbsolute: false, label: 'B'},
|
||||
label: "B2",
|
||||
row: { index: 1, isAbsolute: false, label: "2" },
|
||||
column: { index: 1, isAbsolute: false, label: "B" },
|
||||
});
|
||||
});
|
||||
|
||||
expect(parser.parse('A1:$B2')).toMatchObject({error: null, result: [[3, 6, 10]]});
|
||||
it("should parse absolute cells range", () => {
|
||||
expect(parser.parse("$A$1:$B$2")).toMatchObject({
|
||||
error: null,
|
||||
result: [[3, 6, 10]],
|
||||
});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: 'A1',
|
||||
row: {index: 0, isAbsolute: false, label: '1'},
|
||||
column: {index: 0, isAbsolute: false, label: 'A'},
|
||||
label: "$A$1",
|
||||
row: { index: 0, isAbsolute: true, label: "1" },
|
||||
column: { index: 0, isAbsolute: true, label: "A" },
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: '$B2',
|
||||
row: {index: 1, isAbsolute: false, label: '2'},
|
||||
column: {index: 1, isAbsolute: true, label: 'B'},
|
||||
label: "$B$2",
|
||||
row: { index: 1, isAbsolute: true, label: "2" },
|
||||
column: { index: 1, isAbsolute: true, label: "B" },
|
||||
});
|
||||
|
||||
expect(parser.parse('A$1:B2')).toMatchObject({error: null, result: [[3, 6, 10]]});
|
||||
expect(parser.parse("$a$1:$B$2")).toMatchObject({
|
||||
error: null,
|
||||
result: [[3, 6, 10]],
|
||||
});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: 'A$1',
|
||||
row: {index: 0, isAbsolute: true, label: '1'},
|
||||
column: {index: 0, isAbsolute: false, label: 'A'},
|
||||
label: "$A$1",
|
||||
row: { index: 0, isAbsolute: true, label: "1" },
|
||||
column: { index: 0, isAbsolute: true, label: "A" },
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: 'B2',
|
||||
row: {index: 1, isAbsolute: false, label: '2'},
|
||||
column: {index: 1, isAbsolute: false, label: 'B'},
|
||||
label: "$B$2",
|
||||
row: { index: 1, isAbsolute: true, label: "2" },
|
||||
column: { index: 1, isAbsolute: true, label: "B" },
|
||||
});
|
||||
|
||||
expect(parser.parse('A$1:$B$2')).toMatchObject({error: null, result: [[3, 6, 10]]});
|
||||
expect(parser.parse("$a$1:$b$2")).toMatchObject({
|
||||
error: null,
|
||||
result: [[3, 6, 10]],
|
||||
});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: 'A$1',
|
||||
row: {index: 0, isAbsolute: true, label: '1'},
|
||||
column: {index: 0, isAbsolute: false, label: 'A'},
|
||||
label: "$A$1",
|
||||
row: { index: 0, isAbsolute: true, label: "1" },
|
||||
column: { index: 0, isAbsolute: true, label: "A" },
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: '$B$2',
|
||||
row: {index: 1, isAbsolute: true, label: '2'},
|
||||
column: {index: 1, isAbsolute: true, label: 'B'},
|
||||
label: "$B$2",
|
||||
row: { index: 1, isAbsolute: true, label: "2" },
|
||||
column: { index: 1, isAbsolute: true, label: "B" },
|
||||
});
|
||||
|
||||
expect(parser.parse('A$1:$B2')).toMatchObject({error: null, result: [[3, 6, 10]]});
|
||||
expect(parser.parse("$A$$1:$B$2")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("$A$1:$B$$2")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("$A$1:$$B$2")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("$$A$1:$B$2")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it("should parse mixed cells range", () => {
|
||||
expect(parser.parse("$A$1:B2")).toMatchObject({
|
||||
error: null,
|
||||
result: [[3, 6, 10]],
|
||||
});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: 'A$1',
|
||||
row: {index: 0, isAbsolute: true, label: '1'},
|
||||
column: {index: 0, isAbsolute: false, label: 'A'},
|
||||
label: "$A$1",
|
||||
row: { index: 0, isAbsolute: true, label: "1" },
|
||||
column: { index: 0, isAbsolute: true, label: "A" },
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: '$B2',
|
||||
row: {index: 1, isAbsolute: false, label: '2'},
|
||||
column: {index: 1, isAbsolute: true, label: 'B'},
|
||||
label: "B2",
|
||||
row: { index: 1, isAbsolute: false, label: "2" },
|
||||
column: { index: 1, isAbsolute: false, label: "B" },
|
||||
});
|
||||
|
||||
expect(parser.parse('a$1:$b2')).toMatchObject({error: null, result: [[3, 6, 10]]});
|
||||
expect(parser.parse("$A$1:b2")).toMatchObject({
|
||||
error: null,
|
||||
result: [[3, 6, 10]],
|
||||
});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: 'A$1',
|
||||
row: {index: 0, isAbsolute: true, label: '1'},
|
||||
column: {index: 0, isAbsolute: false, label: 'A'},
|
||||
label: "$A$1",
|
||||
row: { index: 0, isAbsolute: true, label: "1" },
|
||||
column: { index: 0, isAbsolute: true, label: "A" },
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: '$B2',
|
||||
row: {index: 1, isAbsolute: false, label: '2'},
|
||||
column: {index: 1, isAbsolute: true, label: 'B'},
|
||||
label: "B2",
|
||||
row: { index: 1, isAbsolute: false, label: "2" },
|
||||
column: { index: 1, isAbsolute: false, label: "B" },
|
||||
});
|
||||
|
||||
expect(parser.parse('A1:$$B2')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('A1:B2$')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('a1:b2$')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('A1$:B2')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse("A1:$B$2")).toMatchObject({
|
||||
error: null,
|
||||
result: [[3, 6, 10]],
|
||||
});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: "A1",
|
||||
row: { index: 0, isAbsolute: false, label: "1" },
|
||||
column: { index: 0, isAbsolute: false, label: "A" },
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: "$B$2",
|
||||
row: { index: 1, isAbsolute: true, label: "2" },
|
||||
column: { index: 1, isAbsolute: true, label: "B" },
|
||||
});
|
||||
|
||||
expect(parser.parse("$A$1:B$2")).toMatchObject({
|
||||
error: null,
|
||||
result: [[3, 6, 10]],
|
||||
});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: "$A$1",
|
||||
row: { index: 0, isAbsolute: true, label: "1" },
|
||||
column: { index: 0, isAbsolute: true, label: "A" },
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: "B$2",
|
||||
row: { index: 1, isAbsolute: true, label: "2" },
|
||||
column: { index: 1, isAbsolute: false, label: "B" },
|
||||
});
|
||||
|
||||
expect(parser.parse("A1:$B2")).toMatchObject({
|
||||
error: null,
|
||||
result: [[3, 6, 10]],
|
||||
});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: "A1",
|
||||
row: { index: 0, isAbsolute: false, label: "1" },
|
||||
column: { index: 0, isAbsolute: false, label: "A" },
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: "$B2",
|
||||
row: { index: 1, isAbsolute: false, label: "2" },
|
||||
column: { index: 1, isAbsolute: true, label: "B" },
|
||||
});
|
||||
|
||||
expect(parser.parse("A$1:B2")).toMatchObject({
|
||||
error: null,
|
||||
result: [[3, 6, 10]],
|
||||
});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: "A$1",
|
||||
row: { index: 0, isAbsolute: true, label: "1" },
|
||||
column: { index: 0, isAbsolute: false, label: "A" },
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: "B2",
|
||||
row: { index: 1, isAbsolute: false, label: "2" },
|
||||
column: { index: 1, isAbsolute: false, label: "B" },
|
||||
});
|
||||
|
||||
expect(parser.parse("A$1:$B$2")).toMatchObject({
|
||||
error: null,
|
||||
result: [[3, 6, 10]],
|
||||
});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: "A$1",
|
||||
row: { index: 0, isAbsolute: true, label: "1" },
|
||||
column: { index: 0, isAbsolute: false, label: "A" },
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: "$B$2",
|
||||
row: { index: 1, isAbsolute: true, label: "2" },
|
||||
column: { index: 1, isAbsolute: true, label: "B" },
|
||||
});
|
||||
|
||||
expect(parser.parse("A$1:$B2")).toMatchObject({
|
||||
error: null,
|
||||
result: [[3, 6, 10]],
|
||||
});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: "A$1",
|
||||
row: { index: 0, isAbsolute: true, label: "1" },
|
||||
column: { index: 0, isAbsolute: false, label: "A" },
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: "$B2",
|
||||
row: { index: 1, isAbsolute: false, label: "2" },
|
||||
column: { index: 1, isAbsolute: true, label: "B" },
|
||||
});
|
||||
|
||||
expect(parser.parse("a$1:$b2")).toMatchObject({
|
||||
error: null,
|
||||
result: [[3, 6, 10]],
|
||||
});
|
||||
expect(startCellCoord).toMatchObject({
|
||||
label: "A$1",
|
||||
row: { index: 0, isAbsolute: true, label: "1" },
|
||||
column: { index: 0, isAbsolute: false, label: "A" },
|
||||
});
|
||||
expect(endCellCoord).toMatchObject({
|
||||
label: "$B2",
|
||||
row: { index: 1, isAbsolute: false, label: "2" },
|
||||
column: { index: 1, isAbsolute: true, label: "B" },
|
||||
});
|
||||
|
||||
expect(parser.parse("A1:$$B2")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("A1:B2$")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("a1:b2$")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("A1$:B2")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Parser from '../../../src/parser';
|
||||
import Parser from "../../../src/parser";
|
||||
|
||||
describe('.parse() error', () => {
|
||||
describe(".parse() error", () => {
|
||||
let parser;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -10,54 +10,129 @@ describe('.parse() error', () => {
|
||||
parser = null;
|
||||
});
|
||||
|
||||
it('should parse general error', () => {
|
||||
expect(parser.parse('#ERROR!')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('#ERRfefweOR!')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse(' #ERRfefweOR! ')).toMatchObject({error: '#ERROR!', result: null});
|
||||
it("should parse general error", () => {
|
||||
expect(parser.parse("#ERROR!")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("#ERRfefweOR!")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse(" #ERRfefweOR! ")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse DIV/0 error', () => {
|
||||
expect(parser.parse('#DIV/0!')).toMatchObject({error: '#DIV/0!', result: null});
|
||||
expect(parser.parse('#DIV/0?')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('#DIV/1!')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('#DIV/')).toMatchObject({error: '#ERROR!', result: null});
|
||||
it("should parse DIV/0 error", () => {
|
||||
expect(parser.parse("#DIV/0!")).toMatchObject({
|
||||
error: "#DIV/0!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("#DIV/0?")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("#DIV/1!")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("#DIV/")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse NAME error', () => {
|
||||
expect(parser.parse('#NAME?')).toMatchObject({error: '#NAME?', result: null});
|
||||
expect(parser.parse('#NAME!')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('#NAMe!')).toMatchObject({error: '#ERROR!', result: null});
|
||||
it("should parse NAME error", () => {
|
||||
expect(parser.parse("#NAME?")).toMatchObject({
|
||||
error: "#NAME?",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("#NAME!")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("#NAMe!")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse N/A error', () => {
|
||||
expect(parser.parse('#N/A')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse('#N/A!')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('#N/A?')).toMatchObject({error: '#ERROR!', result: null});
|
||||
it("should parse N/A error", () => {
|
||||
expect(parser.parse("#N/A")).toMatchObject({ error: "#N/A", result: null });
|
||||
expect(parser.parse("#N/A!")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("#N/A?")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
/* eslint-disable no-useless-escape */
|
||||
expect(parser.parse('#N\A')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse("#NA")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse NULL error', () => {
|
||||
expect(parser.parse('#NULL!')).toMatchObject({error: '#NULL!', result: null});
|
||||
expect(parser.parse('#NULL?')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('#NULl!')).toMatchObject({error: '#ERROR!', result: null});
|
||||
it("should parse NULL error", () => {
|
||||
expect(parser.parse("#NULL!")).toMatchObject({
|
||||
error: "#NULL!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("#NULL?")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("#NULl!")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse NUM error', () => {
|
||||
expect(parser.parse('#NUM!')).toMatchObject({error: '#NUM!', result: null});
|
||||
expect(parser.parse('#NUM?')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('#NuM!')).toMatchObject({error: '#ERROR!', result: null});
|
||||
it("should parse NUM error", () => {
|
||||
expect(parser.parse("#NUM!")).toMatchObject({
|
||||
error: "#NUM!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("#NUM?")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("#NuM!")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse REF error', () => {
|
||||
expect(parser.parse('#REF!')).toMatchObject({error: '#REF!', result: null});
|
||||
expect(parser.parse('#REF?')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('#REf!')).toMatchObject({error: '#ERROR!', result: null});
|
||||
it("should parse REF error", () => {
|
||||
expect(parser.parse("#REF!")).toMatchObject({
|
||||
error: "#REF!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("#REF?")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("#REf!")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse VALUE error', () => {
|
||||
expect(parser.parse('#VALUE!')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('#VALUE?')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('#VALUe!')).toMatchObject({error: '#ERROR!', result: null});
|
||||
it("should parse VALUE error", () => {
|
||||
expect(parser.parse("#VALUE!")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("#VALUE?")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("#VALUe!")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Parser from '../../../src/parser';
|
||||
import Parser from "../../../src/parser";
|
||||
|
||||
describe('.parse()', () => {
|
||||
describe(".parse()", () => {
|
||||
let parser;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -10,20 +10,32 @@ describe('.parse()', () => {
|
||||
parser = null;
|
||||
});
|
||||
|
||||
it('should return error when number of arguments is not valid', () => {
|
||||
it("should return error when number of arguments is not valid", () => {
|
||||
/* eslint-disable */
|
||||
expect(parser.parse('ACOTH("foo")')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse("ACOTH('foo')")).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('ACOTH("foo")')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("ACOTH('foo')")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
/* eslint-enable */
|
||||
});
|
||||
|
||||
it('should return error when used variable is not defined', () => {
|
||||
expect(parser.parse('ACOTH(foo)')).toMatchObject({error: '#NAME?', result: null});
|
||||
it("should return error when used variable is not defined", () => {
|
||||
expect(parser.parse("ACOTH(foo)")).toMatchObject({
|
||||
error: "#NAME?",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should evaluate formula expression provided in lower case', () => {
|
||||
parser.setVariable('foo', [7, 3.5, 3.5, 1, 2]);
|
||||
it("should evaluate formula expression provided in lower case", () => {
|
||||
parser.setVariable("foo", [7, 3.5, 3.5, 1, 2]);
|
||||
|
||||
expect(parser.parse('sum(2, 3, Rank.eq(2, foo))')).toMatchObject({error: null, result: 9});
|
||||
expect(parser.parse("sum(2, 3, Rank.eq(2, foo))")).toMatchObject({
|
||||
error: null,
|
||||
result: 9,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Parser from '../../../../src/parser';
|
||||
import Parser from "../../../../src/parser";
|
||||
|
||||
describe('.parse() date & time formulas', () => {
|
||||
describe(".parse() date & time formulas", () => {
|
||||
let parser;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -10,10 +10,13 @@ describe('.parse() date & time formulas', () => {
|
||||
parser = null;
|
||||
});
|
||||
|
||||
it('DATE', () => {
|
||||
expect(parser.parse('DATE()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
it("DATE", () => {
|
||||
expect(parser.parse("DATE()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
|
||||
const {error, result} = parser.parse('DATE(2001, 5, 12)');
|
||||
const { error, result } = parser.parse("DATE(2001, 5, 12)");
|
||||
|
||||
expect(error).toBeNull();
|
||||
expect(result.getFullYear()).toBe(2001);
|
||||
@ -21,151 +24,345 @@ describe('.parse() date & time formulas', () => {
|
||||
expect(result.getDate()).toBe(12);
|
||||
});
|
||||
|
||||
it('DATEVALUE', () => {
|
||||
expect(parser.parse('DATEVALUE()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DATEVALUE("1/1/1900")')).toMatchObject({error: null, result: 1});
|
||||
expect(parser.parse('DATEVALUE("1/1/2000")')).toMatchObject({error: null, result: 36526});
|
||||
it("DATEVALUE", () => {
|
||||
expect(parser.parse("DATEVALUE()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('DATEVALUE("1/1/1900")')).toMatchObject({
|
||||
error: null,
|
||||
result: 1,
|
||||
});
|
||||
expect(parser.parse('DATEVALUE("1/1/2000")')).toMatchObject({
|
||||
error: null,
|
||||
result: 36526,
|
||||
});
|
||||
});
|
||||
|
||||
it('DAY', () => {
|
||||
expect(parser.parse('DAY()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DAY(1)')).toMatchObject({error: null, result: 1});
|
||||
expect(parser.parse('DAY(2958465)')).toMatchObject({error: null, result: 31});
|
||||
expect(parser.parse('DAY("2958465")')).toMatchObject({error: null, result: 31});
|
||||
it("DAY", () => {
|
||||
expect(parser.parse("DAY()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("DAY(1)")).toMatchObject({ error: null, result: 1 });
|
||||
expect(parser.parse("DAY(2958465)")).toMatchObject({
|
||||
error: null,
|
||||
result: 31,
|
||||
});
|
||||
expect(parser.parse('DAY("2958465")')).toMatchObject({
|
||||
error: null,
|
||||
result: 31,
|
||||
});
|
||||
});
|
||||
|
||||
it('DAYS', () => {
|
||||
expect(parser.parse('DAYS()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DAYS(1)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DAYS(1, 6)')).toMatchObject({error: null, result: -5});
|
||||
expect(parser.parse('DAYS("1/2/2000", "1/10/2001")')).toMatchObject({error: null, result: -374});
|
||||
it("DAYS", () => {
|
||||
expect(parser.parse("DAYS()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("DAYS(1)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("DAYS(1, 6)")).toMatchObject({
|
||||
error: null,
|
||||
result: -5,
|
||||
});
|
||||
expect(parser.parse('DAYS("1/2/2000", "1/10/2001")')).toMatchObject({
|
||||
error: null,
|
||||
result: -374,
|
||||
});
|
||||
});
|
||||
|
||||
it('DAYS360', () => {
|
||||
expect(parser.parse('DAYS360()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DAYS360(1)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DAYS360(1, 6)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DAYS360("1/1/1901", "2/1/1901", TRUE)')).toMatchObject({error: null, result: 30});
|
||||
expect(parser.parse('DAYS360("1/1/1901", "12/31/1901", FALSE)')).toMatchObject({error: null, result: 360});
|
||||
it("DAYS360", () => {
|
||||
expect(parser.parse("DAYS360()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("DAYS360(1)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("DAYS360(1, 6)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('DAYS360("1/1/1901", "2/1/1901", TRUE)')).toMatchObject(
|
||||
{ error: null, result: 30 }
|
||||
);
|
||||
expect(
|
||||
parser.parse('DAYS360("1/1/1901", "12/31/1901", FALSE)')
|
||||
).toMatchObject({ error: null, result: 360 });
|
||||
});
|
||||
|
||||
it('EDATE', () => {
|
||||
expect(parser.parse('EDATE()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('EDATE(1)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('EDATE("1/1/1900", 1)')).toMatchObject({error: null, result: 32});
|
||||
it("EDATE", () => {
|
||||
expect(parser.parse("EDATE()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("EDATE(1)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('EDATE("1/1/1900", 1)')).toMatchObject({
|
||||
error: null,
|
||||
result: 32,
|
||||
});
|
||||
});
|
||||
|
||||
it('EOMONTH', () => {
|
||||
expect(parser.parse('EOMONTH()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('EOMONTH(1)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('EOMONTH("1/1/1900", 1)')).toMatchObject({error: null, result: 59});
|
||||
it("EOMONTH", () => {
|
||||
expect(parser.parse("EOMONTH()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("EOMONTH(1)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('EOMONTH("1/1/1900", 1)')).toMatchObject({
|
||||
error: null,
|
||||
result: 59,
|
||||
});
|
||||
});
|
||||
|
||||
it('HOUR', () => {
|
||||
expect(parser.parse('HOUR()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('HOUR("1/1/1900 16:33")')).toMatchObject({error: null, result: 16});
|
||||
it("HOUR", () => {
|
||||
expect(parser.parse("HOUR()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('HOUR("1/1/1900 16:33")')).toMatchObject({
|
||||
error: null,
|
||||
result: 16,
|
||||
});
|
||||
});
|
||||
|
||||
it('INTERVAL', () => {
|
||||
expect(parser.parse('INTERVAL()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('INTERVAL(0)')).toMatchObject({error: null, result: 'PT'});
|
||||
expect(parser.parse('INTERVAL(1)')).toMatchObject({error: null, result: 'PT1S'});
|
||||
expect(parser.parse('INTERVAL(60)')).toMatchObject({error: null, result: 'PT1M'});
|
||||
expect(parser.parse('INTERVAL(10000000)')).toMatchObject({error: null, result: 'P3M25DT17H46M40S'});
|
||||
it("INTERVAL", () => {
|
||||
expect(parser.parse("INTERVAL()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("INTERVAL(0)")).toMatchObject({
|
||||
error: null,
|
||||
result: "PT",
|
||||
});
|
||||
expect(parser.parse("INTERVAL(1)")).toMatchObject({
|
||||
error: null,
|
||||
result: "PT1S",
|
||||
});
|
||||
expect(parser.parse("INTERVAL(60)")).toMatchObject({
|
||||
error: null,
|
||||
result: "PT1M",
|
||||
});
|
||||
expect(parser.parse("INTERVAL(10000000)")).toMatchObject({
|
||||
error: null,
|
||||
result: "P3M25DT17H46M40S",
|
||||
});
|
||||
});
|
||||
|
||||
it('ISOWEEKNUM', () => {
|
||||
expect(parser.parse('ISOWEEKNUM()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('ISOWEEKNUM("1/8/1901")')).toMatchObject({error: null, result: 2});
|
||||
expect(parser.parse('ISOWEEKNUM("6/6/1902")')).toMatchObject({error: null, result: 23});
|
||||
it("ISOWEEKNUM", () => {
|
||||
expect(parser.parse("ISOWEEKNUM()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('ISOWEEKNUM("1/8/1901")')).toMatchObject({
|
||||
error: null,
|
||||
result: 2,
|
||||
});
|
||||
expect(parser.parse('ISOWEEKNUM("6/6/1902")')).toMatchObject({
|
||||
error: null,
|
||||
result: 23,
|
||||
});
|
||||
});
|
||||
|
||||
it('MINUTE', () => {
|
||||
expect(parser.parse('MINUTE()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('MINUTE("1/1/1901 1:01")')).toMatchObject({error: null, result: 1});
|
||||
expect(parser.parse('MINUTE("1/1/1901 15:36")')).toMatchObject({error: null, result: 36});
|
||||
it("MINUTE", () => {
|
||||
expect(parser.parse("MINUTE()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('MINUTE("1/1/1901 1:01")')).toMatchObject({
|
||||
error: null,
|
||||
result: 1,
|
||||
});
|
||||
expect(parser.parse('MINUTE("1/1/1901 15:36")')).toMatchObject({
|
||||
error: null,
|
||||
result: 36,
|
||||
});
|
||||
});
|
||||
|
||||
it('MONTH', () => {
|
||||
expect(parser.parse('MONTH()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('MONTH("2/1/1901")')).toMatchObject({error: null, result: 2});
|
||||
expect(parser.parse('MONTH("10/1/1901")')).toMatchObject({error: null, result: 10});
|
||||
it("MONTH", () => {
|
||||
expect(parser.parse("MONTH()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('MONTH("2/1/1901")')).toMatchObject({
|
||||
error: null,
|
||||
result: 2,
|
||||
});
|
||||
expect(parser.parse('MONTH("10/1/1901")')).toMatchObject({
|
||||
error: null,
|
||||
result: 10,
|
||||
});
|
||||
});
|
||||
|
||||
it('NETWORKDAYS', () => {
|
||||
expect(parser.parse('NETWORKDAYS()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('NETWORKDAYS("2/1/1901")')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('NETWORKDAYS("2013-12-04", "2013-12-05")')).toMatchObject({error: null, result: 2});
|
||||
expect(parser.parse('NETWORKDAYS("2013-11-04", "2013-12-05")')).toMatchObject({error: null, result: 24});
|
||||
it("NETWORKDAYS", () => {
|
||||
expect(parser.parse("NETWORKDAYS()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('NETWORKDAYS("2/1/1901")')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(
|
||||
parser.parse('NETWORKDAYS("2013-12-04", "2013-12-05")')
|
||||
).toMatchObject({ error: null, result: 2 });
|
||||
expect(
|
||||
parser.parse('NETWORKDAYS("2013-11-04", "2013-12-05")')
|
||||
).toMatchObject({ error: null, result: 24 });
|
||||
});
|
||||
|
||||
it('NOW', () => {
|
||||
const {error, result} = parser.parse('NOW()');
|
||||
it("NOW", () => {
|
||||
const { error, result } = parser.parse("NOW()");
|
||||
const now = new Date();
|
||||
|
||||
expect(error).toBeNull();
|
||||
expect(result.toString()).toBe(now.toString());
|
||||
});
|
||||
|
||||
it('SECOND', () => {
|
||||
expect(parser.parse('SECOND()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('SECOND("2/1/1901 13:33:12")')).toMatchObject({error: null, result: 12});
|
||||
it("SECOND", () => {
|
||||
expect(parser.parse("SECOND()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('SECOND("2/1/1901 13:33:12")')).toMatchObject({
|
||||
error: null,
|
||||
result: 12,
|
||||
});
|
||||
});
|
||||
|
||||
it('TIME', () => {
|
||||
expect(parser.parse('TIME()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('TIME(0)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('TIME(0, 0)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('TIME(0, 0, 0)')).toMatchObject({error: null, result: 0});
|
||||
expect(parser.parse('TIME(1, 1, 1)')).toMatchObject({error: null, result: 0.04237268518518519});
|
||||
expect(parser.parse('TIME(24, 0, 0)')).toMatchObject({error: null, result: 1});
|
||||
it("TIME", () => {
|
||||
expect(parser.parse("TIME()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("TIME(0)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("TIME(0, 0)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("TIME(0, 0, 0)")).toMatchObject({
|
||||
error: null,
|
||||
result: 0,
|
||||
});
|
||||
expect(parser.parse("TIME(1, 1, 1)")).toMatchObject({
|
||||
error: null,
|
||||
result: 0.04237268518518519,
|
||||
});
|
||||
expect(parser.parse("TIME(24, 0, 0)")).toMatchObject({
|
||||
error: null,
|
||||
result: 1,
|
||||
});
|
||||
});
|
||||
|
||||
it('TIMEVALUE', () => {
|
||||
expect(parser.parse('TIMEVALUE()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('TIMEVALUE("1/1/1900 00:00:00")')).toMatchObject({error: null, result: 0});
|
||||
expect(parser.parse('TIMEVALUE("1/1/1900 23:00:00")')).toMatchObject({error: null, result: 0.9583333333333334});
|
||||
it("TIMEVALUE", () => {
|
||||
expect(parser.parse("TIMEVALUE()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('TIMEVALUE("1/1/1900 00:00:00")')).toMatchObject({
|
||||
error: null,
|
||||
result: 0,
|
||||
});
|
||||
expect(parser.parse('TIMEVALUE("1/1/1900 23:00:00")')).toMatchObject({
|
||||
error: null,
|
||||
result: 0.9583333333333334,
|
||||
});
|
||||
});
|
||||
|
||||
it('TODAY', () => {
|
||||
const {error, result} = parser.parse('TODAY()');
|
||||
it("TODAY", () => {
|
||||
const { error, result } = parser.parse("TODAY()");
|
||||
const now = new Date();
|
||||
|
||||
expect(error).toBeNull();
|
||||
expect(result.getDate()).toBe(now.getDate());
|
||||
});
|
||||
|
||||
it('WEEKDAY', () => {
|
||||
expect(parser.parse('WEEKDAY()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('WEEKDAY("1/1/1901")')).toMatchObject({error: null, result: 3});
|
||||
expect(parser.parse('WEEKDAY("1/1/1901", 2)')).toMatchObject({error: null, result: 2});
|
||||
it("WEEKDAY", () => {
|
||||
expect(parser.parse("WEEKDAY()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('WEEKDAY("1/1/1901")')).toMatchObject({
|
||||
error: null,
|
||||
result: 3,
|
||||
});
|
||||
expect(parser.parse('WEEKDAY("1/1/1901", 2)')).toMatchObject({
|
||||
error: null,
|
||||
result: 2,
|
||||
});
|
||||
});
|
||||
|
||||
it('WEEKNUM', () => {
|
||||
expect(parser.parse('WEEKNUM()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('WEEKNUM("2/1/1900")')).toMatchObject({error: null, result: 5});
|
||||
expect(parser.parse('WEEKNUM("2/1/1909", 2)')).toMatchObject({error: null, result: 6});
|
||||
it("WEEKNUM", () => {
|
||||
expect(parser.parse("WEEKNUM()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('WEEKNUM("2/1/1900")')).toMatchObject({
|
||||
error: null,
|
||||
result: 5,
|
||||
});
|
||||
expect(parser.parse('WEEKNUM("2/1/1909", 2)')).toMatchObject({
|
||||
error: null,
|
||||
result: 6,
|
||||
});
|
||||
});
|
||||
|
||||
it('WORKDAY', () => {
|
||||
expect(parser.parse('WORKDAY()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('WORKDAY("1/1/1900")')).toMatchObject({error: '#VALUE!', result: null});
|
||||
it("WORKDAY", () => {
|
||||
expect(parser.parse("WORKDAY()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('WORKDAY("1/1/1900")')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
|
||||
const {result, error} = parser.parse('WORKDAY("1/1/1900", 1)');
|
||||
const { result, error } = parser.parse('WORKDAY("1/1/1900", 1)');
|
||||
|
||||
expect(error).toBeNull();
|
||||
expect(result.getDate()).toBe(2);
|
||||
});
|
||||
|
||||
it('YEAR', () => {
|
||||
expect(parser.parse('YEAR()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('YEAR("1/1/1904")')).toMatchObject({error: null, result: 1904});
|
||||
expect(parser.parse('YEAR("12/12/2001")')).toMatchObject({error: null, result: 2001});
|
||||
it("YEAR", () => {
|
||||
expect(parser.parse("YEAR()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('YEAR("1/1/1904")')).toMatchObject({
|
||||
error: null,
|
||||
result: 1904,
|
||||
});
|
||||
expect(parser.parse('YEAR("12/12/2001")')).toMatchObject({
|
||||
error: null,
|
||||
result: 2001,
|
||||
});
|
||||
});
|
||||
|
||||
it('YEARFRAC', () => {
|
||||
expect(parser.parse('YEARFRAC()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('YEARFRAC("1/1/1904")')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('YEARFRAC("1/1/1900", "1/2/1900")')).toMatchObject({error: null, result: 0.002777777777777778});
|
||||
it("YEARFRAC", () => {
|
||||
expect(parser.parse("YEARFRAC()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('YEARFRAC("1/1/1904")')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('YEARFRAC("1/1/1900", "1/2/1900")')).toMatchObject({
|
||||
error: null,
|
||||
result: 0.002777777777777778,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
import Parser from '../../../../src/parser';
|
||||
import Parser from "../../../../src/parser";
|
||||
|
||||
describe('.parse() financial formulas', () => {
|
||||
describe(".parse() financial formulas", () => {
|
||||
let parser;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -10,255 +10,640 @@ describe('.parse() financial formulas', () => {
|
||||
parser = null;
|
||||
});
|
||||
|
||||
it('ACCRINT', () => {
|
||||
expect(parser.parse('ACCRINT()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('ACCRINT("2/2/2012")')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('ACCRINT("2/2/2012", "3/30/2012")')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('ACCRINT("2/2/2012", "3/30/2012", "12/4/2013")')).toMatchObject({error: '#NUM!', result: null});
|
||||
expect(parser.parse('ACCRINT("2/2/2012", "3/30/2012", "12/4/2013", 0.1)')).toMatchObject({error: '#NUM!', result: null});
|
||||
expect(parser.parse('ACCRINT("2/2/2012", "3/30/2012", "12/4/2013", 0.1, 1000)')).toMatchObject({error: '#NUM!', result: null});
|
||||
expect(parser.parse('ACCRINT("2/2/2012", "3/30/2012", "12/4/2013", 0.1, 1000, 1)')).toMatchObject({error: '#NUM!', result: null});
|
||||
expect(parser.parse('ACCRINT("2/2/2012", "3/30/2012", "12/4/2013", 0.1, 1000, 1, 0)')).toMatchObject({error: null, result: 183.88888888888889});
|
||||
it("ACCRINT", () => {
|
||||
expect(parser.parse("ACCRINT()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('ACCRINT("2/2/2012")')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('ACCRINT("2/2/2012", "3/30/2012")')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(
|
||||
parser.parse('ACCRINT("2/2/2012", "3/30/2012", "12/4/2013")')
|
||||
).toMatchObject({ error: "#NUM!", result: null });
|
||||
expect(
|
||||
parser.parse('ACCRINT("2/2/2012", "3/30/2012", "12/4/2013", 0.1)')
|
||||
).toMatchObject({ error: "#NUM!", result: null });
|
||||
expect(
|
||||
parser.parse('ACCRINT("2/2/2012", "3/30/2012", "12/4/2013", 0.1, 1000)')
|
||||
).toMatchObject({ error: "#NUM!", result: null });
|
||||
expect(
|
||||
parser.parse(
|
||||
'ACCRINT("2/2/2012", "3/30/2012", "12/4/2013", 0.1, 1000, 1)'
|
||||
)
|
||||
).toMatchObject({ error: "#NUM!", result: null });
|
||||
expect(
|
||||
parser.parse(
|
||||
'ACCRINT("2/2/2012", "3/30/2012", "12/4/2013", 0.1, 1000, 1, 0)'
|
||||
)
|
||||
).toMatchObject({ error: null, result: 183.88888888888889 });
|
||||
});
|
||||
|
||||
it('CUMIPMT', () => {
|
||||
expect(parser.parse('CUMIPMT()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('CUMIPMT(0.1/12)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('CUMIPMT(0.1/12, 30*12)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('CUMIPMT(0.1/12, 30*12, 100000)')).toMatchObject({error: '#NUM!', result: null});
|
||||
expect(parser.parse('CUMIPMT(0.1/12, 30*12, 100000, 13)')).toMatchObject({error: '#NUM!', result: null});
|
||||
expect(parser.parse('CUMIPMT(0.1/12, 30*12, 100000, 13, 24)')).toMatchObject({error: '#NUM!', result: null});
|
||||
expect(parser.parse('CUMIPMT(0.1/12, 30*12, 100000, 13, 24, 0)')).toMatchObject({error: null, result: -9916.77251395708});
|
||||
it("CUMIPMT", () => {
|
||||
expect(parser.parse("CUMIPMT()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("CUMIPMT(0.1/12)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("CUMIPMT(0.1/12, 30*12)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("CUMIPMT(0.1/12, 30*12, 100000)")).toMatchObject({
|
||||
error: "#NUM!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("CUMIPMT(0.1/12, 30*12, 100000, 13)")).toMatchObject({
|
||||
error: "#NUM!",
|
||||
result: null,
|
||||
});
|
||||
expect(
|
||||
parser.parse("CUMIPMT(0.1/12, 30*12, 100000, 13, 24)")
|
||||
).toMatchObject({ error: "#NUM!", result: null });
|
||||
expect(
|
||||
parser.parse("CUMIPMT(0.1/12, 30*12, 100000, 13, 24, 0)")
|
||||
).toMatchObject({ error: null, result: -9916.77251395708 });
|
||||
});
|
||||
|
||||
it('CUMPRINC', () => {
|
||||
expect(parser.parse('CUMPRINC()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('CUMPRINC(0.1/12)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('CUMPRINC(0.1/12, 30*12)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('CUMPRINC(0.1/12, 30*12, 100000)')).toMatchObject({error: '#NUM!', result: null});
|
||||
expect(parser.parse('CUMPRINC(0.1/12, 30*12, 100000, 13)')).toMatchObject({error: '#NUM!', result: null});
|
||||
expect(parser.parse('CUMPRINC(0.1/12, 30*12, 100000, 13, 24)')).toMatchObject({error: '#NUM!', result: null});
|
||||
expect(parser.parse('CUMPRINC(0.1/12, 30*12, 100000, 13, 24, 0)')).toMatchObject({error: null, result: -614.0863271085149});
|
||||
it("CUMPRINC", () => {
|
||||
expect(parser.parse("CUMPRINC()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("CUMPRINC(0.1/12)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("CUMPRINC(0.1/12, 30*12)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("CUMPRINC(0.1/12, 30*12, 100000)")).toMatchObject({
|
||||
error: "#NUM!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("CUMPRINC(0.1/12, 30*12, 100000, 13)")).toMatchObject({
|
||||
error: "#NUM!",
|
||||
result: null,
|
||||
});
|
||||
expect(
|
||||
parser.parse("CUMPRINC(0.1/12, 30*12, 100000, 13, 24)")
|
||||
).toMatchObject({ error: "#NUM!", result: null });
|
||||
expect(
|
||||
parser.parse("CUMPRINC(0.1/12, 30*12, 100000, 13, 24, 0)")
|
||||
).toMatchObject({ error: null, result: -614.0863271085149 });
|
||||
});
|
||||
|
||||
it('DB', () => {
|
||||
expect(parser.parse('DB()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DB(10000)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DB(10000, 1000)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DB(10000, 1000, 6)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DB(10000, 1000, 6, 1)')).toMatchObject({error: null, result: 3190});
|
||||
it("DB", () => {
|
||||
expect(parser.parse("DB()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("DB(10000)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("DB(10000, 1000)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("DB(10000, 1000, 6)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("DB(10000, 1000, 6, 1)")).toMatchObject({
|
||||
error: null,
|
||||
result: 3190,
|
||||
});
|
||||
});
|
||||
|
||||
it('DDB', () => {
|
||||
expect(parser.parse('DDB()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DDB(10000)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DDB(10000, 1000)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DDB(10000, 1000, 6)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DDB(10000, 1000, 6, 1)')).toMatchObject({error: null, result: 3333.333333333333});
|
||||
it("DDB", () => {
|
||||
expect(parser.parse("DDB()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("DDB(10000)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("DDB(10000, 1000)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("DDB(10000, 1000, 6)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("DDB(10000, 1000, 6, 1)")).toMatchObject({
|
||||
error: null,
|
||||
result: 3333.333333333333,
|
||||
});
|
||||
});
|
||||
|
||||
it('DOLLARDE', () => {
|
||||
expect(parser.parse('DOLLARDE()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DOLLARDE(1.1)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DOLLARDE(1.1, 4)')).toMatchObject({error: null, result: 1.25});
|
||||
it("DOLLARDE", () => {
|
||||
expect(parser.parse("DOLLARDE()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("DOLLARDE(1.1)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("DOLLARDE(1.1, 4)")).toMatchObject({
|
||||
error: null,
|
||||
result: 1.25,
|
||||
});
|
||||
});
|
||||
|
||||
it('DOLLARFR', () => {
|
||||
expect(parser.parse('DOLLARFR()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DOLLARFR(1.1)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DOLLARFR(1.1, 4)')).toMatchObject({error: null, result: 1.04});
|
||||
it("DOLLARFR", () => {
|
||||
expect(parser.parse("DOLLARFR()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("DOLLARFR(1.1)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("DOLLARFR(1.1, 4)")).toMatchObject({
|
||||
error: null,
|
||||
result: 1.04,
|
||||
});
|
||||
});
|
||||
|
||||
it('EFFECT', () => {
|
||||
expect(parser.parse('EFFECT()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('EFFECT(1.1)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('EFFECT(1.1, 4)')).toBeMatchCloseTo({error: null, result: 1.6426566406249994});
|
||||
it("EFFECT", () => {
|
||||
expect(parser.parse("EFFECT()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("EFFECT(1.1)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("EFFECT(1.1, 4)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: 1.6426566406249994,
|
||||
});
|
||||
});
|
||||
|
||||
it('FV', () => {
|
||||
expect(parser.parse('FV()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('FV(1.1, 10)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('FV(1.1, 10, -200)')).toMatchObject({error: null, result: 303088.7450582});
|
||||
expect(parser.parse('FV(1.1, 10, -200, -500)')).toMatchObject({error: null, result: 1137082.79396825});
|
||||
expect(parser.parse('FV(1.1, 10, -200, -500, 1)')).toMatchObject({error: null, result: 1470480.4135322701});
|
||||
it("FV", () => {
|
||||
expect(parser.parse("FV()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("FV(1.1, 10)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("FV(1.1, 10, -200)")).toMatchObject({
|
||||
error: null,
|
||||
result: 303088.7450582,
|
||||
});
|
||||
expect(parser.parse("FV(1.1, 10, -200, -500)")).toMatchObject({
|
||||
error: null,
|
||||
result: 1137082.79396825,
|
||||
});
|
||||
expect(parser.parse("FV(1.1, 10, -200, -500, 1)")).toMatchObject({
|
||||
error: null,
|
||||
result: 1470480.4135322701,
|
||||
});
|
||||
});
|
||||
|
||||
it('FVSCHEDULE', () => {
|
||||
parser.on('callRangeValue', (a, b, done) => done([[0.09, 0.1, 0.11]]));
|
||||
it("FVSCHEDULE", () => {
|
||||
parser.on("callRangeValue", (a, b, done) => done([[0.09, 0.1, 0.11]]));
|
||||
|
||||
expect(parser.parse('FVSCHEDULE(100, A1:C1)')).toMatchObject({error: null, result: 133.08900000000003});
|
||||
expect(parser.parse("FVSCHEDULE(100, A1:C1)")).toMatchObject({
|
||||
error: null,
|
||||
result: 133.08900000000003,
|
||||
});
|
||||
});
|
||||
|
||||
it('IPMT', () => {
|
||||
expect(parser.parse('IPMT()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('IPMT(0.2, 6)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('IPMT(0.2, 6, 24)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('IPMT(0.2, 6, 24, 1000)')).toMatchObject({error: null, result: -196.20794961065468});
|
||||
expect(parser.parse('IPMT(0.2, 6, 24, 1000, 200)')).toMatchObject({error: null, result: -195.44953953278565});
|
||||
expect(parser.parse('IPMT(0.2, 6, 24, 1000, 200, 1)')).toMatchObject({error: null, result: -162.87461627732137});
|
||||
it("IPMT", () => {
|
||||
expect(parser.parse("IPMT()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("IPMT(0.2, 6)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("IPMT(0.2, 6, 24)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("IPMT(0.2, 6, 24, 1000)")).toMatchObject({
|
||||
error: null,
|
||||
result: -196.20794961065468,
|
||||
});
|
||||
expect(parser.parse("IPMT(0.2, 6, 24, 1000, 200)")).toMatchObject({
|
||||
error: null,
|
||||
result: -195.44953953278565,
|
||||
});
|
||||
expect(parser.parse("IPMT(0.2, 6, 24, 1000, 200, 1)")).toMatchObject({
|
||||
error: null,
|
||||
result: -162.87461627732137,
|
||||
});
|
||||
});
|
||||
|
||||
it('IRR', () => {
|
||||
parser.on('callRangeValue', (a, b, done) => done([[-75000, 12000, 15000, 18000, 21000, 24000]]));
|
||||
it("IRR", () => {
|
||||
parser.on("callRangeValue", (a, b, done) =>
|
||||
done([[-75000, 12000, 15000, 18000, 21000, 24000]])
|
||||
);
|
||||
|
||||
expect(parser.parse('IRR(A1:C1)')).toMatchObject({error: null, result: 0.05715142887178453});
|
||||
expect(parser.parse("IRR(A1:C1)")).toMatchObject({
|
||||
error: null,
|
||||
result: 0.05715142887178453,
|
||||
});
|
||||
});
|
||||
|
||||
it('ISPMT', () => {
|
||||
expect(parser.parse('ISPMT()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('ISPMT(1.1, 2)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('ISPMT(1.1, 2, 16)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('ISPMT(1.1, 2, 16)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('ISPMT(1.1, 2, 16, 1000)')).toMatchObject({error: null, result: -962.5});
|
||||
it("ISPMT", () => {
|
||||
expect(parser.parse("ISPMT()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("ISPMT(1.1, 2)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("ISPMT(1.1, 2, 16)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("ISPMT(1.1, 2, 16)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("ISPMT(1.1, 2, 16, 1000)")).toMatchObject({
|
||||
error: null,
|
||||
result: -962.5,
|
||||
});
|
||||
});
|
||||
|
||||
it('MIRR', () => {
|
||||
parser.on('callRangeValue', (a, b, done) => done([[-75000, 12000, 15000, 18000, 21000, 24000]]));
|
||||
it("MIRR", () => {
|
||||
parser.on("callRangeValue", (a, b, done) =>
|
||||
done([[-75000, 12000, 15000, 18000, 21000, 24000]])
|
||||
);
|
||||
|
||||
expect(parser.parse('MIRR(A1:C1, 0.1, 0.12)')).toBeMatchCloseTo({error: null, result: 0.07971710360838036});
|
||||
expect(parser.parse("MIRR(A1:C1, 0.1, 0.12)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: 0.07971710360838036,
|
||||
});
|
||||
});
|
||||
|
||||
it('NOMINAL', () => {
|
||||
expect(parser.parse('NOMINAL()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('NOMINAL(1.1)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('NOMINAL(1.1, 2)')).toBeMatchCloseTo({error: null, result: 0.8982753492378879});
|
||||
it("NOMINAL", () => {
|
||||
expect(parser.parse("NOMINAL()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("NOMINAL(1.1)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("NOMINAL(1.1, 2)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: 0.8982753492378879,
|
||||
});
|
||||
});
|
||||
|
||||
it('NPER', () => {
|
||||
expect(parser.parse('NPER()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('NPER(1.1)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('NPER(1.1, -2)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('NPER(1.1, -2, -100)')).toBeMatchCloseTo({error: null, result: -5.4254604102768305});
|
||||
expect(parser.parse('NPER(1.1, -2, -100, 1000)')).toBeMatchCloseTo({error: null, result: 3.081639082679854});
|
||||
expect(parser.parse('NPER(1.1, -2, -100, 1000, 1)')).toBeMatchCloseTo({error: null, result: 3.058108732153963});
|
||||
it("NPER", () => {
|
||||
expect(parser.parse("NPER()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("NPER(1.1)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("NPER(1.1, -2)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("NPER(1.1, -2, -100)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: -5.4254604102768305,
|
||||
});
|
||||
expect(parser.parse("NPER(1.1, -2, -100, 1000)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: 3.081639082679854,
|
||||
});
|
||||
expect(parser.parse("NPER(1.1, -2, -100, 1000, 1)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: 3.058108732153963,
|
||||
});
|
||||
});
|
||||
|
||||
it('NPV', () => {
|
||||
expect(parser.parse('NPV()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('NPV(1.1)')).toMatchObject({error: null, result: 0});
|
||||
expect(parser.parse('NPV(1.1, -2)')).toBeMatchCloseTo({error: null, result: -0.9523809523809523});
|
||||
expect(parser.parse('NPV(1.1, -2, -100)')).toBeMatchCloseTo({error: null, result: -23.6281179138322});
|
||||
expect(parser.parse('NPV(1.1, -2, -100, 1000)')).toBeMatchCloseTo({error: null, result: 84.3515819026023});
|
||||
expect(parser.parse('NPV(1.1, -2, -100, 1000, 1)')).toBeMatchCloseTo({error: null, result: 84.4030008072768});
|
||||
it("NPV", () => {
|
||||
expect(parser.parse("NPV()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("NPV(1.1)")).toMatchObject({ error: null, result: 0 });
|
||||
expect(parser.parse("NPV(1.1, -2)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: -0.9523809523809523,
|
||||
});
|
||||
expect(parser.parse("NPV(1.1, -2, -100)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: -23.6281179138322,
|
||||
});
|
||||
expect(parser.parse("NPV(1.1, -2, -100, 1000)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: 84.3515819026023,
|
||||
});
|
||||
expect(parser.parse("NPV(1.1, -2, -100, 1000, 1)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: 84.4030008072768,
|
||||
});
|
||||
});
|
||||
|
||||
it('PDURATION', () => {
|
||||
expect(parser.parse('PDURATION()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('PDURATION(0.1)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('PDURATION(0.1, 200)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('PDURATION(0.1, 200, 400)')).toBeMatchCloseTo({error: null, result: 7.272540897341714});
|
||||
it("PDURATION", () => {
|
||||
expect(parser.parse("PDURATION()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("PDURATION(0.1)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("PDURATION(0.1, 200)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("PDURATION(0.1, 200, 400)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: 7.272540897341714,
|
||||
});
|
||||
});
|
||||
|
||||
it('PMT', () => {
|
||||
expect(parser.parse('PMT()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('PMT(0.1)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('PMT(0.1, 200)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('PMT(0.1, 200, 400)')).toBeMatchCloseTo({error: null, result: -40.00000021063133});
|
||||
expect(parser.parse('PMT(0.1, 200, 400, 500)')).toBeMatchCloseTo({error: null, result: -40.00000047392049});
|
||||
it("PMT", () => {
|
||||
expect(parser.parse("PMT()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("PMT(0.1)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("PMT(0.1, 200)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("PMT(0.1, 200, 400)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: -40.00000021063133,
|
||||
});
|
||||
expect(parser.parse("PMT(0.1, 200, 400, 500)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: -40.00000047392049,
|
||||
});
|
||||
});
|
||||
|
||||
it('PPMT', () => {
|
||||
expect(parser.parse('PPMT()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('PPMT(0.1)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('PPMT(0.1, 200)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('PPMT(0.1, 200, 400)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('PPMT(0.1, 200, 400, 5000)')).toBeMatchCloseTo({error: null, result: 0.000012207031261368684});
|
||||
it("PPMT", () => {
|
||||
expect(parser.parse("PPMT()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("PPMT(0.1)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("PPMT(0.1, 200)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("PPMT(0.1, 200, 400)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("PPMT(0.1, 200, 400, 5000)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: 0.000012207031261368684,
|
||||
});
|
||||
});
|
||||
|
||||
it('PV', () => {
|
||||
expect(parser.parse('PV()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('PV(1.1)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('PV(1.1, 200)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('PV(1.1, 200, 400)')).toBeMatchCloseTo({error: null, result: -363.6363636363636});
|
||||
expect(parser.parse('PV(1.1, 200, 400, 5000)')).toBeMatchCloseTo({error: null, result: -363.6363636363636});
|
||||
expect(parser.parse('PV(1.1, 200, 400, 5000, 1)')).toBeMatchCloseTo({error: null, result: -763.6363636363636});
|
||||
it("PV", () => {
|
||||
expect(parser.parse("PV()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("PV(1.1)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("PV(1.1, 200)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("PV(1.1, 200, 400)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: -363.6363636363636,
|
||||
});
|
||||
expect(parser.parse("PV(1.1, 200, 400, 5000)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: -363.6363636363636,
|
||||
});
|
||||
expect(parser.parse("PV(1.1, 200, 400, 5000, 1)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: -763.6363636363636,
|
||||
});
|
||||
});
|
||||
|
||||
it('RATE', () => {
|
||||
expect(parser.parse('RATE()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('RATE(24)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('RATE(24, -1000)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('RATE(24, -1000, -10000)')).toBeMatchCloseTo({error: null, result: -1.2079096886965142});
|
||||
expect(parser.parse('RATE(24, -1000, -10000, 10000)')).toMatchObject({error: null, result: -0.1});
|
||||
expect(parser.parse('RATE(24, -1000, -10000, 10000, 1)')).toBeMatchCloseTo({error: null, result: -0.09090909090909093});
|
||||
expect(parser.parse('RATE(24, -1000, -10000, 10000, 1, 0.1)')).toBeMatchCloseTo({error: null, result: -0.09090909090909091});
|
||||
it("RATE", () => {
|
||||
expect(parser.parse("RATE()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("RATE(24)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("RATE(24, -1000)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("RATE(24, -1000, -10000)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: -1.2079096886965142,
|
||||
});
|
||||
expect(parser.parse("RATE(24, -1000, -10000, 10000)")).toMatchObject({
|
||||
error: null,
|
||||
result: -0.1,
|
||||
});
|
||||
expect(parser.parse("RATE(24, -1000, -10000, 10000, 1)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: -0.09090909090909093,
|
||||
});
|
||||
expect(
|
||||
parser.parse("RATE(24, -1000, -10000, 10000, 1, 0.1)")
|
||||
).toBeMatchCloseTo({ error: null, result: -0.09090909090909091 });
|
||||
});
|
||||
|
||||
it('RRI', () => {
|
||||
expect(parser.parse('RRI()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('RRI(8)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('RRI(8, 100)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('RRI(8, 100, 300)')).toBeMatchCloseTo({error: null, result: 0.1472026904398771});
|
||||
it("RRI", () => {
|
||||
expect(parser.parse("RRI()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("RRI(8)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("RRI(8, 100)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("RRI(8, 100, 300)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: 0.1472026904398771,
|
||||
});
|
||||
});
|
||||
|
||||
it('SLN', () => {
|
||||
expect(parser.parse('SLN()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('SLN(200)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('SLN(200, 750)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('SLN(200, 750, 10)')).toMatchObject({error: null, result: -55});
|
||||
it("SLN", () => {
|
||||
expect(parser.parse("SLN()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("SLN(200)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("SLN(200, 750)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("SLN(200, 750, 10)")).toMatchObject({
|
||||
error: null,
|
||||
result: -55,
|
||||
});
|
||||
});
|
||||
|
||||
it('SYD', () => {
|
||||
expect(parser.parse('SYD()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('SYD(200)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('SYD(200, 750)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('SYD(200, 750, 10)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('SYD(200, 750, 10, 1)')).toMatchObject({error: null, result: -100});
|
||||
it("SYD", () => {
|
||||
expect(parser.parse("SYD()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("SYD(200)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("SYD(200, 750)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("SYD(200, 750, 10)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("SYD(200, 750, 10, 1)")).toMatchObject({
|
||||
error: null,
|
||||
result: -100,
|
||||
});
|
||||
});
|
||||
|
||||
it('TBILLEQ', () => {
|
||||
expect(parser.parse('TBILLEQ()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('TBILLEQ("03/31/2008")')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('TBILLEQ("03/31/2008", "06/01/2008")')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('TBILLEQ("03/31/2008", "06/01/2008", 0.09)')).toBeMatchCloseTo({error: null, result: 0.09266311246509266});
|
||||
it("TBILLEQ", () => {
|
||||
expect(parser.parse("TBILLEQ()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('TBILLEQ("03/31/2008")')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('TBILLEQ("03/31/2008", "06/01/2008")')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(
|
||||
parser.parse('TBILLEQ("03/31/2008", "06/01/2008", 0.09)')
|
||||
).toBeMatchCloseTo({ error: null, result: 0.09266311246509266 });
|
||||
});
|
||||
|
||||
it('TBILLPRICE', () => {
|
||||
expect(parser.parse('TBILLPRICE()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('TBILLPRICE("03/31/2008")')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('TBILLPRICE("03/31/2008", "06/01/2008")')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('TBILLPRICE("03/31/2008", "06/01/2008", 0.09)')).toBeMatchCloseTo({error: null, result: 98.475});
|
||||
it("TBILLPRICE", () => {
|
||||
expect(parser.parse("TBILLPRICE()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('TBILLPRICE("03/31/2008")')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(
|
||||
parser.parse('TBILLPRICE("03/31/2008", "06/01/2008")')
|
||||
).toMatchObject({ error: "#VALUE!", result: null });
|
||||
expect(
|
||||
parser.parse('TBILLPRICE("03/31/2008", "06/01/2008", 0.09)')
|
||||
).toBeMatchCloseTo({ error: null, result: 98.475 });
|
||||
});
|
||||
|
||||
it('TBILLYIELD', () => {
|
||||
expect(parser.parse('TBILLYIELD()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('TBILLYIELD("03/31/2008")')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('TBILLYIELD("03/31/2008", "06/01/2008")')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('TBILLYIELD("03/31/2008", "06/01/2008", 0.09)')).toBeMatchCloseTo({error: null, result: 6551.475409836065});
|
||||
it("TBILLYIELD", () => {
|
||||
expect(parser.parse("TBILLYIELD()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('TBILLYIELD("03/31/2008")')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(
|
||||
parser.parse('TBILLYIELD("03/31/2008", "06/01/2008")')
|
||||
).toMatchObject({ error: "#VALUE!", result: null });
|
||||
expect(
|
||||
parser.parse('TBILLYIELD("03/31/2008", "06/01/2008", 0.09)')
|
||||
).toBeMatchCloseTo({ error: null, result: 6551.475409836065 });
|
||||
});
|
||||
|
||||
// TODO: Not supported yet
|
||||
xit('XIRR', () => {
|
||||
parser.on('callRangeValue', (a, b, done) => {
|
||||
xit("XIRR", () => {
|
||||
parser.on("callRangeValue", (a, b, done) => {
|
||||
let values;
|
||||
|
||||
if (a.label === 'A1' && b.label === 'C1') {
|
||||
if (a.label === "A1" && b.label === "C1") {
|
||||
values = [[-10000, 2750, 4250, 3250, 2750]];
|
||||
|
||||
} else if (a.label === 'A2' && b.label === 'C2') {
|
||||
values = [['01/jan/08', '01/mar/08', '30/oct/08', '15/feb/09', '01/apr/09']];
|
||||
} else if (a.label === "A2" && b.label === "C2") {
|
||||
values = [
|
||||
["01/jan/08", "01/mar/08", "30/oct/08", "15/feb/09", "01/apr/09"],
|
||||
];
|
||||
}
|
||||
|
||||
done(values);
|
||||
});
|
||||
|
||||
expect(parser.parse('XIRR(A1:C1, A2:C2, 0.1)')).toBeMatchCloseTo({error: null, result: 0.373374019797564});
|
||||
expect(parser.parse("XIRR(A1:C1, A2:C2, 0.1)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: 0.373374019797564,
|
||||
});
|
||||
});
|
||||
|
||||
it('XNPV', () => {
|
||||
parser.on('callRangeValue', (a, b, done) => {
|
||||
it("XNPV", () => {
|
||||
parser.on("callRangeValue", (a, b, done) => {
|
||||
let values;
|
||||
|
||||
if (a.label === 'A1' && b.label === 'C1') {
|
||||
if (a.label === "A1" && b.label === "C1") {
|
||||
values = [[-10000, 2750, 4250, 3250, 2750]];
|
||||
|
||||
} else if (a.label === 'A2' && b.label === 'C2') {
|
||||
values = [['01/01/2008', '03/01/2008', '10/30/2008', '02/15/2009', '04/01/2009']];
|
||||
} else if (a.label === "A2" && b.label === "C2") {
|
||||
values = [
|
||||
[
|
||||
"01/01/2008",
|
||||
"03/01/2008",
|
||||
"10/30/2008",
|
||||
"02/15/2009",
|
||||
"04/01/2009",
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
done(values);
|
||||
});
|
||||
|
||||
expect(parser.parse('XNPV(0.09, A1:C1, A2:C2)')).toBeMatchCloseTo({error: null, result: 2086.6718943024616});
|
||||
expect(parser.parse("XNPV(0.09, A1:C1, A2:C2)")).toBeMatchCloseTo({
|
||||
error: null,
|
||||
result: 2086.6718943024616,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Parser from '../../../../src/parser';
|
||||
import Parser from "../../../../src/parser";
|
||||
|
||||
describe('.parse() information formulas', () => {
|
||||
describe(".parse() information formulas", () => {
|
||||
let parser;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -10,60 +10,159 @@ describe('.parse() information formulas', () => {
|
||||
parser = null;
|
||||
});
|
||||
|
||||
it('ISBINARY', () => {
|
||||
expect(parser.parse('ISBINARY()')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('ISBINARY(1)')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('ISBINARY(0)')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('ISBINARY("1010")')).toMatchObject({error: null, result: true});
|
||||
it("ISBINARY", () => {
|
||||
expect(parser.parse("ISBINARY()")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("ISBINARY(1)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("ISBINARY(0)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse('ISBINARY("1010")')).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('ISBLANK', () => {
|
||||
expect(parser.parse('ISBLANK(NULL)')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('ISBLANK(FALSE)')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('ISBLANK(0)')).toMatchObject({error: null, result: false});
|
||||
it("ISBLANK", () => {
|
||||
expect(parser.parse("ISBLANK(NULL)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("ISBLANK(FALSE)")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("ISBLANK(0)")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('ISEVEN', () => {
|
||||
expect(parser.parse('ISEVEN(1)')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('ISEVEN(2)')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('ISEVEN(2.5)')).toMatchObject({error: null, result: true});
|
||||
it("ISEVEN", () => {
|
||||
expect(parser.parse("ISEVEN(1)")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("ISEVEN(2)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("ISEVEN(2.5)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('ISLOGICAL', () => {
|
||||
expect(parser.parse('ISLOGICAL(1)')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('ISLOGICAL(TRUE)')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('ISLOGICAL(FALSE)')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('ISLOGICAL(NULL)')).toMatchObject({error: null, result: false});
|
||||
it("ISLOGICAL", () => {
|
||||
expect(parser.parse("ISLOGICAL(1)")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("ISLOGICAL(TRUE)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("ISLOGICAL(FALSE)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("ISLOGICAL(NULL)")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('ISNONTEXT', () => {
|
||||
expect(parser.parse('ISNONTEXT()')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('ISNONTEXT(1)')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('ISNONTEXT(TRUE)')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('ISNONTEXT("FALSE")')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('ISNONTEXT("foo")')).toMatchObject({error: null, result: false});
|
||||
it("ISNONTEXT", () => {
|
||||
expect(parser.parse("ISNONTEXT()")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("ISNONTEXT(1)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("ISNONTEXT(TRUE)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse('ISNONTEXT("FALSE")')).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse('ISNONTEXT("foo")')).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('ISNUMBER', () => {
|
||||
expect(parser.parse('ISNUMBER()')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('ISNUMBER(1)')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('ISNUMBER(0.142342)')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('ISNUMBER(TRUE)')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('ISNUMBER("FALSE")')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('ISNUMBER("foo")')).toMatchObject({error: null, result: false});
|
||||
it("ISNUMBER", () => {
|
||||
expect(parser.parse("ISNUMBER()")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("ISNUMBER(1)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("ISNUMBER(0.142342)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("ISNUMBER(TRUE)")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse('ISNUMBER("FALSE")')).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse('ISNUMBER("foo")')).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('ISODD', () => {
|
||||
expect(parser.parse('ISODD(1)')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('ISODD(2)')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('ISODD(2.5)')).toMatchObject({error: null, result: false});
|
||||
it("ISODD", () => {
|
||||
expect(parser.parse("ISODD(1)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("ISODD(2)")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("ISODD(2.5)")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('ISTEXT', () => {
|
||||
expect(parser.parse('ISTEXT()')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('ISTEXT(1)')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('ISTEXT(TRUE)')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('ISTEXT("FALSE")')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('ISTEXT("foo")')).toMatchObject({error: null, result: true});
|
||||
it("ISTEXT", () => {
|
||||
expect(parser.parse("ISTEXT()")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("ISTEXT(1)")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("ISTEXT(TRUE)")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse('ISTEXT("FALSE")')).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse('ISTEXT("foo")')).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Parser from '../../../../src/parser';
|
||||
import Parser from "../../../../src/parser";
|
||||
|
||||
describe('.parse() logical formulas', () => {
|
||||
describe(".parse() logical formulas", () => {
|
||||
let parser;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -10,60 +10,129 @@ describe('.parse() logical formulas', () => {
|
||||
parser = null;
|
||||
});
|
||||
|
||||
it('AND', () => {
|
||||
expect(parser.parse('AND()')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('AND(TRUE, TRUE, FALSE)')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('AND(TRUE, TRUE, TRUE)')).toMatchObject({error: null, result: true});
|
||||
it("AND", () => {
|
||||
expect(parser.parse("AND()")).toMatchObject({ error: null, result: true });
|
||||
expect(parser.parse("AND(TRUE, TRUE, FALSE)")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("AND(TRUE, TRUE, TRUE)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('CHOOSE', () => {
|
||||
expect(parser.parse('CHOOSE()')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse('CHOOSE(1, "foo", "bar", "baz")')).toMatchObject({error: null, result: 'foo'});
|
||||
expect(parser.parse('CHOOSE(3, "foo", "bar", "baz")')).toMatchObject({error: null, result: 'baz'});
|
||||
expect(parser.parse('CHOOSE(4, "foo", "bar", "baz")')).toMatchObject({error: '#VALUE!', result: null});
|
||||
it("CHOOSE", () => {
|
||||
expect(parser.parse("CHOOSE()")).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('CHOOSE(1, "foo", "bar", "baz")')).toMatchObject({
|
||||
error: null,
|
||||
result: "foo",
|
||||
});
|
||||
expect(parser.parse('CHOOSE(3, "foo", "bar", "baz")')).toMatchObject({
|
||||
error: null,
|
||||
result: "baz",
|
||||
});
|
||||
expect(parser.parse('CHOOSE(4, "foo", "bar", "baz")')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('FALSE', () => {
|
||||
expect(parser.parse('FALSE()')).toMatchObject({error: null, result: false});
|
||||
it("FALSE", () => {
|
||||
expect(parser.parse("FALSE()")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('IF', () => {
|
||||
expect(parser.parse('IF()')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('IF(TRUE, 1, 2)')).toMatchObject({error: null, result: 1});
|
||||
expect(parser.parse('IF(FALSE, 1, 2)')).toMatchObject({error: null, result: 2});
|
||||
it("IF", () => {
|
||||
expect(parser.parse("IF()")).toMatchObject({ error: null, result: true });
|
||||
expect(parser.parse("IF(TRUE, 1, 2)")).toMatchObject({
|
||||
error: null,
|
||||
result: 1,
|
||||
});
|
||||
expect(parser.parse("IF(FALSE, 1, 2)")).toMatchObject({
|
||||
error: null,
|
||||
result: 2,
|
||||
});
|
||||
});
|
||||
|
||||
it('NOT', () => {
|
||||
expect(parser.parse('NOT()')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('NOT(TRUE)')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('NOT(FALSE)')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('NOT(0)')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('NOT(1)')).toMatchObject({error: null, result: false});
|
||||
it("NOT", () => {
|
||||
expect(parser.parse("NOT()")).toMatchObject({ error: null, result: true });
|
||||
expect(parser.parse("NOT(TRUE)")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("NOT(FALSE)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("NOT(0)")).toMatchObject({ error: null, result: true });
|
||||
expect(parser.parse("NOT(1)")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('OR', () => {
|
||||
expect(parser.parse('OR()')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('OR(TRUE, TRUE, TRUE)')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('OR(TRUE, FALSE, FALSE)')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('OR(FALSE, FALSE, FALSE)')).toMatchObject({error: null, result: false});
|
||||
it("OR", () => {
|
||||
expect(parser.parse("OR()")).toMatchObject({ error: null, result: false });
|
||||
expect(parser.parse("OR(TRUE, TRUE, TRUE)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("OR(TRUE, FALSE, FALSE)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("OR(FALSE, FALSE, FALSE)")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('TRUE', () => {
|
||||
expect(parser.parse('TRUE()')).toMatchObject({error: null, result: true});
|
||||
it("TRUE", () => {
|
||||
expect(parser.parse("TRUE()")).toMatchObject({ error: null, result: true });
|
||||
});
|
||||
|
||||
it('XOR', () => {
|
||||
expect(parser.parse('XOR()')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('XOR(TRUE, TRUE)')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('XOR(TRUE, FALSE)')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('XOR(FALSE, TRUE)')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('XOR(FALSE, FALSE)')).toMatchObject({error: null, result: false});
|
||||
it("XOR", () => {
|
||||
expect(parser.parse("XOR()")).toMatchObject({ error: null, result: false });
|
||||
expect(parser.parse("XOR(TRUE, TRUE)")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("XOR(TRUE, FALSE)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("XOR(FALSE, TRUE)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("XOR(FALSE, FALSE)")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('SWITCH', () => {
|
||||
expect(parser.parse('SWITCH()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('SWITCH(7, "foo")')).toMatchObject({error: null, result: 'foo'});
|
||||
expect(parser.parse('SWITCH(7, 9, "foo", 7, "bar")')).toMatchObject({error: null, result: 'bar'});
|
||||
expect(parser.parse('SWITCH(10, 9, "foo", 7, "bar")')).toMatchObject({error: '#N/A', result: null});
|
||||
it("SWITCH", () => {
|
||||
expect(parser.parse("SWITCH()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('SWITCH(7, "foo")')).toMatchObject({
|
||||
error: null,
|
||||
result: "foo",
|
||||
});
|
||||
expect(parser.parse('SWITCH(7, 9, "foo", 7, "bar")')).toMatchObject({
|
||||
error: null,
|
||||
result: "bar",
|
||||
});
|
||||
expect(parser.parse('SWITCH(10, 9, "foo", 7, "bar")')).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Parser from '../../../../src/parser';
|
||||
import Parser from "../../../../src/parser";
|
||||
|
||||
describe('.parse() lookup-reference formulas', () => {
|
||||
describe(".parse() lookup-reference formulas", () => {
|
||||
let parser;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -10,16 +10,37 @@ describe('.parse() lookup-reference formulas', () => {
|
||||
parser = null;
|
||||
});
|
||||
|
||||
it('MATCH', () => {
|
||||
parser.setVariable('foo', [0, 1, 2, 3, 4, 100, 7]);
|
||||
parser.setVariable('bar', ['jima', 'jimb', 'jimc', 'bernie']);
|
||||
it("MATCH", () => {
|
||||
parser.setVariable("foo", [0, 1, 2, 3, 4, 100, 7]);
|
||||
parser.setVariable("bar", ["jima", "jimb", "jimc", "bernie"]);
|
||||
|
||||
expect(parser.parse('MATCH()')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse('MATCH(1)')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse('MATCH(1, foo)')).toMatchObject({error: null, result: 2});
|
||||
expect(parser.parse('MATCH(4, foo, 1)')).toMatchObject({error: null, result: 5});
|
||||
expect(parser.parse('MATCH("jima", bar, 0)')).toMatchObject({error: null, result: 1});
|
||||
expect(parser.parse('MATCH("j?b", bar, 0)')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse('MATCH("jimc", bar, 0)')).toMatchObject({error: null, result: 3});
|
||||
expect(parser.parse("MATCH()")).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("MATCH(1)")).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("MATCH(1, foo)")).toMatchObject({
|
||||
error: null,
|
||||
result: 2,
|
||||
});
|
||||
expect(parser.parse("MATCH(4, foo, 1)")).toMatchObject({
|
||||
error: null,
|
||||
result: 5,
|
||||
});
|
||||
expect(parser.parse('MATCH("jima", bar, 0)')).toMatchObject({
|
||||
error: null,
|
||||
result: 1,
|
||||
});
|
||||
expect(parser.parse('MATCH("j?b", bar, 0)')).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('MATCH("jimc", bar, 0)')).toMatchObject({
|
||||
error: null,
|
||||
result: 3,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
import Parser from '../../../../src/parser';
|
||||
import Parser from "../../../../src/parser";
|
||||
|
||||
describe('.parse() miscellaneous formulas', () => {
|
||||
describe(".parse() miscellaneous formulas", () => {
|
||||
let parser;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -10,51 +10,84 @@ describe('.parse() miscellaneous formulas', () => {
|
||||
parser = null;
|
||||
});
|
||||
|
||||
it('UNIQUE', () => {
|
||||
expect(parser.parse('UNIQUE()')).toMatchObject({error: null, result: []});
|
||||
expect(parser.parse('UNIQUE(1, 2, 3, 4, 4, 4, 4, 3)')).toMatchObject({error: null, result: [1, 2, 3, 4]});
|
||||
expect(parser.parse('UNIQUE("foo", "bar", "foo")')).toMatchObject({error: null, result: ['foo', 'bar']});
|
||||
it("UNIQUE", () => {
|
||||
expect(parser.parse("UNIQUE()")).toMatchObject({ error: null, result: [] });
|
||||
expect(parser.parse("UNIQUE(1, 2, 3, 4, 4, 4, 4, 3)")).toMatchObject({
|
||||
error: null,
|
||||
result: [1, 2, 3, 4],
|
||||
});
|
||||
expect(parser.parse('UNIQUE("foo", "bar", "foo")')).toMatchObject({
|
||||
error: null,
|
||||
result: ["foo", "bar"],
|
||||
});
|
||||
});
|
||||
|
||||
it('ARGS2ARRAY', () => {
|
||||
expect(parser.parse('ARGS2ARRAY()')).toMatchObject({error: null, result: []});
|
||||
expect(parser.parse('ARGS2ARRAY(1, 4, 4, 3)')).toMatchObject({error: null, result: [1, 4, 4, 3]});
|
||||
expect(parser.parse('ARGS2ARRAY("foo", "bar", "foo")')).toMatchObject({error: null, result: ['foo', 'bar', 'foo']});
|
||||
it("ARGS2ARRAY", () => {
|
||||
expect(parser.parse("ARGS2ARRAY()")).toMatchObject({
|
||||
error: null,
|
||||
result: [],
|
||||
});
|
||||
expect(parser.parse("ARGS2ARRAY(1, 4, 4, 3)")).toMatchObject({
|
||||
error: null,
|
||||
result: [1, 4, 4, 3],
|
||||
});
|
||||
expect(parser.parse('ARGS2ARRAY("foo", "bar", "foo")')).toMatchObject({
|
||||
error: null,
|
||||
result: ["foo", "bar", "foo"],
|
||||
});
|
||||
});
|
||||
|
||||
it('FLATTEN', () => {
|
||||
parser.on('callRangeValue', (a, b, done) => {
|
||||
if (a.label === 'A1' && b.label === 'B3') {
|
||||
it("FLATTEN", () => {
|
||||
parser.on("callRangeValue", (a, b, done) => {
|
||||
if (a.label === "A1" && b.label === "B3") {
|
||||
done([[1, 2, [3], [4, 5]]]);
|
||||
}
|
||||
});
|
||||
|
||||
expect(parser.parse('FLATTEN(A1:B3)')).toMatchObject({error: null, result: [1, 2, 3, 4, 5]});
|
||||
expect(parser.parse("FLATTEN(A1:B3)")).toMatchObject({
|
||||
error: null,
|
||||
result: [1, 2, 3, 4, 5],
|
||||
});
|
||||
});
|
||||
|
||||
it('JOIN', () => {
|
||||
parser.on('callRangeValue', (a, b, done) => {
|
||||
if (a.label === 'A1' && b.label === 'B3') {
|
||||
it("JOIN", () => {
|
||||
parser.on("callRangeValue", (a, b, done) => {
|
||||
if (a.label === "A1" && b.label === "B3") {
|
||||
done([[1, 2, [3], [4, 5]]]);
|
||||
}
|
||||
});
|
||||
|
||||
expect(parser.parse('JOIN(A1:B3)')).toMatchObject({error: null, result: '1,2,3,4,5'});
|
||||
expect(parser.parse("JOIN(A1:B3)")).toMatchObject({
|
||||
error: null,
|
||||
result: "1,2,3,4,5",
|
||||
});
|
||||
});
|
||||
|
||||
it('NUMBERS', () => {
|
||||
expect(parser.parse('NUMBERS()')).toMatchObject({error: null, result: []});
|
||||
expect(parser.parse('NUMBERS(1, "4", "4", 3)')).toMatchObject({error: null, result: [1, 3]});
|
||||
expect(parser.parse('NUMBERS("foo", 2, "bar", "foo")')).toMatchObject({error: null, result: [2]});
|
||||
it("NUMBERS", () => {
|
||||
expect(parser.parse("NUMBERS()")).toMatchObject({
|
||||
error: null,
|
||||
result: [],
|
||||
});
|
||||
expect(parser.parse('NUMBERS(1, "4", "4", 3)')).toMatchObject({
|
||||
error: null,
|
||||
result: [1, 3],
|
||||
});
|
||||
expect(parser.parse('NUMBERS("foo", 2, "bar", "foo")')).toMatchObject({
|
||||
error: null,
|
||||
result: [2],
|
||||
});
|
||||
});
|
||||
|
||||
it('REFERENCE', () => {
|
||||
parser.on('callCellValue', (a, done) => {
|
||||
if (a.label === 'A1') {
|
||||
done({name: {firstName: 'Jim'}});
|
||||
it("REFERENCE", () => {
|
||||
parser.on("callCellValue", (a, done) => {
|
||||
if (a.label === "A1") {
|
||||
done({ name: { firstName: "Jim" } });
|
||||
}
|
||||
});
|
||||
|
||||
expect(parser.parse('REFERENCE(A1, "name.firstName")')).toMatchObject({error: null, result: 'Jim'});
|
||||
expect(parser.parse('REFERENCE(A1, "name.firstName")')).toMatchObject({
|
||||
error: null,
|
||||
result: "Jim",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
import Parser from '../../../../src/parser';
|
||||
import Parser from "../../../../src/parser";
|
||||
|
||||
describe('.parse() text formulas', () => {
|
||||
describe(".parse() text formulas", () => {
|
||||
let parser;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -10,195 +10,472 @@ describe('.parse() text formulas', () => {
|
||||
parser = null;
|
||||
});
|
||||
|
||||
it('CHAR', () => {
|
||||
expect(parser.parse('CHAR()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('CHAR(33)')).toMatchObject({error: null, result: '!'});
|
||||
it("CHAR", () => {
|
||||
expect(parser.parse("CHAR()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("CHAR(33)")).toMatchObject({
|
||||
error: null,
|
||||
result: "!",
|
||||
});
|
||||
});
|
||||
|
||||
it('CLEAN', () => {
|
||||
expect(parser.parse('CLEAN()')).toMatchObject({error: null, result: ''});
|
||||
expect(parser.parse('CLEAN(CHAR(9)&"Monthly report"&CHAR(10))')).toMatchObject({error: null, result: 'Monthly report'});
|
||||
it("CLEAN", () => {
|
||||
expect(parser.parse("CLEAN()")).toMatchObject({ error: null, result: "" });
|
||||
expect(
|
||||
parser.parse('CLEAN(CHAR(9)&"Monthly report"&CHAR(10))')
|
||||
).toMatchObject({ error: null, result: "Monthly report" });
|
||||
});
|
||||
|
||||
it('CODE', () => {
|
||||
expect(parser.parse('CODE()')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse('CODE("a")')).toMatchObject({error: null, result: 97});
|
||||
it("CODE", () => {
|
||||
expect(parser.parse("CODE()")).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('CODE("a")')).toMatchObject({
|
||||
error: null,
|
||||
result: 97,
|
||||
});
|
||||
});
|
||||
|
||||
it('CONCATENATE', () => {
|
||||
expect(parser.parse('CONCATENATE()')).toMatchObject({error: null, result: ''});
|
||||
expect(parser.parse('CONCATENATE("a")')).toMatchObject({error: null, result: 'a'});
|
||||
expect(parser.parse('CONCATENATE("a", 1)')).toMatchObject({error: null, result: 'a1'});
|
||||
expect(parser.parse('CONCATENATE("a", 1, TRUE)')).toMatchObject({error: null, result: 'a1TRUE'});
|
||||
it("CONCATENATE", () => {
|
||||
expect(parser.parse("CONCATENATE()")).toMatchObject({
|
||||
error: null,
|
||||
result: "",
|
||||
});
|
||||
expect(parser.parse('CONCATENATE("a")')).toMatchObject({
|
||||
error: null,
|
||||
result: "a",
|
||||
});
|
||||
expect(parser.parse('CONCATENATE("a", 1)')).toMatchObject({
|
||||
error: null,
|
||||
result: "a1",
|
||||
});
|
||||
expect(parser.parse('CONCATENATE("a", 1, TRUE)')).toMatchObject({
|
||||
error: null,
|
||||
result: "a1TRUE",
|
||||
});
|
||||
});
|
||||
|
||||
xit('DOLLAR', () => {
|
||||
expect(parser.parse('DOLLAR()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('DOLLAR(1100)')).toMatchObject({error: null, result: '$1,100.00'});
|
||||
expect(parser.parse('DOLLAR(1100, -2)')).toMatchObject({error: null, result: '$1,100'});
|
||||
xit("DOLLAR", () => {
|
||||
expect(parser.parse("DOLLAR()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("DOLLAR(1100)")).toMatchObject({
|
||||
error: null,
|
||||
result: "$1,100.00",
|
||||
});
|
||||
expect(parser.parse("DOLLAR(1100, -2)")).toMatchObject({
|
||||
error: null,
|
||||
result: "$1,100",
|
||||
});
|
||||
});
|
||||
|
||||
it('EXACT', () => {
|
||||
expect(parser.parse('EXACT()')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse('EXACT(1100)')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse('EXACT(1100, -2)')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('EXACT(1100, 1100)')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('EXACT(1100, "1100")')).toMatchObject({error: null, result: false});
|
||||
it("EXACT", () => {
|
||||
expect(parser.parse("EXACT()")).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("EXACT(1100)")).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("EXACT(1100, -2)")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("EXACT(1100, 1100)")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse('EXACT(1100, "1100")')).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('FIND', () => {
|
||||
expect(parser.parse('FIND()')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse('FIND("o")')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse('FIND("o", "FooBar")')).toMatchObject({error: null, result: 2});
|
||||
expect(parser.parse('FIND("O", "FooBar")')).toMatchObject({error: null, result: 0});
|
||||
it("FIND", () => {
|
||||
expect(parser.parse("FIND()")).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('FIND("o")')).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('FIND("o", "FooBar")')).toMatchObject({
|
||||
error: null,
|
||||
result: 2,
|
||||
});
|
||||
expect(parser.parse('FIND("O", "FooBar")')).toMatchObject({
|
||||
error: null,
|
||||
result: 0,
|
||||
});
|
||||
});
|
||||
|
||||
xit('FIXED', () => {
|
||||
expect(parser.parse('FIXED()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('FIXED(12345.11, -1)')).toMatchObject({error: null, result: '12,350'});
|
||||
expect(parser.parse('FIXED(12345.11, 0)')).toMatchObject({error: null, result: '12,345'});
|
||||
expect(parser.parse('FIXED(12345.11, 0, TRUE)')).toMatchObject({error: null, result: '12345'});
|
||||
expect(parser.parse('FIXED(12345.11, 4, TRUE)')).toMatchObject({error: null, result: '12345.1100'});
|
||||
xit("FIXED", () => {
|
||||
expect(parser.parse("FIXED()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("FIXED(12345.11, -1)")).toMatchObject({
|
||||
error: null,
|
||||
result: "12,350",
|
||||
});
|
||||
expect(parser.parse("FIXED(12345.11, 0)")).toMatchObject({
|
||||
error: null,
|
||||
result: "12,345",
|
||||
});
|
||||
expect(parser.parse("FIXED(12345.11, 0, TRUE)")).toMatchObject({
|
||||
error: null,
|
||||
result: "12345",
|
||||
});
|
||||
expect(parser.parse("FIXED(12345.11, 4, TRUE)")).toMatchObject({
|
||||
error: null,
|
||||
result: "12345.1100",
|
||||
});
|
||||
});
|
||||
|
||||
it('HTML2TEXT', () => {
|
||||
expect(parser.parse('HTML2TEXT()')).toMatchObject({error: null, result: ''});
|
||||
expect(parser.parse('HTML2TEXT("Click <a>Link</a>")')).toMatchObject({error: null, result: 'Click Link'});
|
||||
it("HTML2TEXT", () => {
|
||||
expect(parser.parse("HTML2TEXT()")).toMatchObject({
|
||||
error: null,
|
||||
result: "",
|
||||
});
|
||||
expect(parser.parse('HTML2TEXT("Click <a>Link</a>")')).toMatchObject({
|
||||
error: null,
|
||||
result: "Click Link",
|
||||
});
|
||||
});
|
||||
|
||||
it('LEFT', () => {
|
||||
expect(parser.parse('LEFT()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('LEFT("Foo Bar")')).toMatchObject({error: null, result: 'F'});
|
||||
expect(parser.parse('LEFT("Foo Bar", 3)')).toMatchObject({error: null, result: 'Foo'});
|
||||
it("LEFT", () => {
|
||||
expect(parser.parse("LEFT()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('LEFT("Foo Bar")')).toMatchObject({
|
||||
error: null,
|
||||
result: "F",
|
||||
});
|
||||
expect(parser.parse('LEFT("Foo Bar", 3)')).toMatchObject({
|
||||
error: null,
|
||||
result: "Foo",
|
||||
});
|
||||
});
|
||||
|
||||
it('LEN', () => {
|
||||
expect(parser.parse('LEN()')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('LEN(TRUE)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('LEN(1023)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('LEN("Foo Bar")')).toMatchObject({error: null, result: 7});
|
||||
it("LEN", () => {
|
||||
expect(parser.parse("LEN()")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("LEN(TRUE)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("LEN(1023)")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('LEN("Foo Bar")')).toMatchObject({
|
||||
error: null,
|
||||
result: 7,
|
||||
});
|
||||
});
|
||||
|
||||
it('LOWER', () => {
|
||||
expect(parser.parse('LOWER()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('LOWER("")')).toMatchObject({error: null, result: ''});
|
||||
expect(parser.parse('LOWER("Foo Bar")')).toMatchObject({error: null, result: 'foo bar'});
|
||||
it("LOWER", () => {
|
||||
expect(parser.parse("LOWER()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('LOWER("")')).toMatchObject({
|
||||
error: null,
|
||||
result: "",
|
||||
});
|
||||
expect(parser.parse('LOWER("Foo Bar")')).toMatchObject({
|
||||
error: null,
|
||||
result: "foo bar",
|
||||
});
|
||||
});
|
||||
|
||||
it('MID', () => {
|
||||
expect(parser.parse('MID()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('MID("")')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('MID("Foo Bar", 2)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('MID("Foo Bar", 2, 5)')).toMatchObject({error: null, result: 'oo Ba'});
|
||||
it("MID", () => {
|
||||
expect(parser.parse("MID()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('MID("")')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('MID("Foo Bar", 2)')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('MID("Foo Bar", 2, 5)')).toMatchObject({
|
||||
error: null,
|
||||
result: "oo Ba",
|
||||
});
|
||||
});
|
||||
|
||||
it('PROPER', () => {
|
||||
expect(parser.parse('PROPER()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('PROPER("")')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('PROPER(TRUE)')).toMatchObject({error: null, result: 'True'});
|
||||
expect(parser.parse('PROPER(1234)')).toMatchObject({error: null, result: '1234'});
|
||||
expect(parser.parse('PROPER("foo bar")')).toMatchObject({error: null, result: 'Foo Bar'});
|
||||
it("PROPER", () => {
|
||||
expect(parser.parse("PROPER()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('PROPER("")')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("PROPER(TRUE)")).toMatchObject({
|
||||
error: null,
|
||||
result: "True",
|
||||
});
|
||||
expect(parser.parse("PROPER(1234)")).toMatchObject({
|
||||
error: null,
|
||||
result: "1234",
|
||||
});
|
||||
expect(parser.parse('PROPER("foo bar")')).toMatchObject({
|
||||
error: null,
|
||||
result: "Foo Bar",
|
||||
});
|
||||
});
|
||||
|
||||
it('REGEXEXTRACT', () => {
|
||||
expect(parser.parse('REGEXEXTRACT()')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse('REGEXEXTRACT("extract foo bar", "(foo)")')).toMatchObject({error: null, result: 'foo'});
|
||||
expect(parser.parse('REGEXEXTRACT("pressure 12.21bar", "([0-9]+.[0-9]+)")')).toMatchObject({error: null, result: '12.21'});
|
||||
it("REGEXEXTRACT", () => {
|
||||
expect(parser.parse("REGEXEXTRACT()")).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
expect(
|
||||
parser.parse('REGEXEXTRACT("extract foo bar", "(foo)")')
|
||||
).toMatchObject({ error: null, result: "foo" });
|
||||
expect(
|
||||
parser.parse('REGEXEXTRACT("pressure 12.21bar", "([0-9]+.[0-9]+)")')
|
||||
).toMatchObject({ error: null, result: "12.21" });
|
||||
});
|
||||
|
||||
it('REGEXREPLACE', () => {
|
||||
expect(parser.parse('REGEXREPLACE()')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse('REGEXREPLACE("extract foo bar", "(foo)", "baz")')).toMatchObject({error: null, result: 'extract baz bar'});
|
||||
expect(parser.parse('REGEXREPLACE("pressure 12.21bar", "([0-9]+.[0-9]+)", "43.1")')).toMatchObject({error: null, result: 'pressure 43.1bar'});
|
||||
it("REGEXREPLACE", () => {
|
||||
expect(parser.parse("REGEXREPLACE()")).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
expect(
|
||||
parser.parse('REGEXREPLACE("extract foo bar", "(foo)", "baz")')
|
||||
).toMatchObject({ error: null, result: "extract baz bar" });
|
||||
expect(
|
||||
parser.parse(
|
||||
'REGEXREPLACE("pressure 12.21bar", "([0-9]+.[0-9]+)", "43.1")'
|
||||
)
|
||||
).toMatchObject({ error: null, result: "pressure 43.1bar" });
|
||||
});
|
||||
|
||||
it('REGEXMATCH', () => {
|
||||
expect(parser.parse('REGEXMATCH()')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse('REGEXMATCH("pressure 12.21bar", "([0-9]+.[0-9]+)")')).toMatchObject({error: null, result: true});
|
||||
it("REGEXMATCH", () => {
|
||||
expect(parser.parse("REGEXMATCH()")).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
expect(
|
||||
parser.parse('REGEXMATCH("pressure 12.21bar", "([0-9]+.[0-9]+)")')
|
||||
).toMatchObject({ error: null, result: true });
|
||||
|
||||
const result = parser.parse('REGEXMATCH("pressure 12.33bar", "([0-9]+.[0-9]+)", TRUE)');
|
||||
const result = parser.parse(
|
||||
'REGEXMATCH("pressure 12.33bar", "([0-9]+.[0-9]+)", TRUE)'
|
||||
);
|
||||
|
||||
expect(result).toBeInstanceOf(Object);
|
||||
});
|
||||
|
||||
it('REPLACE', () => {
|
||||
expect(parser.parse('REPLACE()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('REPLACE("foo bar")')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('REPLACE("foo bar", 2)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('REPLACE("foo bar", 2, 5)')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('REPLACE("foo bar", 2, 5, "*")')).toMatchObject({error: null, result: 'f*r'});
|
||||
it("REPLACE", () => {
|
||||
expect(parser.parse("REPLACE()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('REPLACE("foo bar")')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('REPLACE("foo bar", 2)')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('REPLACE("foo bar", 2, 5)')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('REPLACE("foo bar", 2, 5, "*")')).toMatchObject({
|
||||
error: null,
|
||||
result: "f*r",
|
||||
});
|
||||
});
|
||||
|
||||
it('REPT', () => {
|
||||
expect(parser.parse('REPT()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('REPT("foo ")')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('REPT("foo ", 5)')).toMatchObject({error: null, result: 'foo foo foo foo foo '});
|
||||
it("REPT", () => {
|
||||
expect(parser.parse("REPT()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('REPT("foo ")')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('REPT("foo ", 5)')).toMatchObject({
|
||||
error: null,
|
||||
result: "foo foo foo foo foo ",
|
||||
});
|
||||
});
|
||||
|
||||
it('RIGHT', () => {
|
||||
expect(parser.parse('RIGHT()')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse('RIGHT("foo bar")')).toMatchObject({error: null, result: 'r'});
|
||||
expect(parser.parse('RIGHT("foo bar", 4)')).toMatchObject({error: null, result: ' bar'});
|
||||
it("RIGHT", () => {
|
||||
expect(parser.parse("RIGHT()")).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('RIGHT("foo bar")')).toMatchObject({
|
||||
error: null,
|
||||
result: "r",
|
||||
});
|
||||
expect(parser.parse('RIGHT("foo bar", 4)')).toMatchObject({
|
||||
error: null,
|
||||
result: " bar",
|
||||
});
|
||||
});
|
||||
|
||||
it('SEARCH', () => {
|
||||
expect(parser.parse('SEARCH()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('SEARCH("bar")')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('SEARCH("bar", "foo bar")')).toMatchObject({error: null, result: 5});
|
||||
it("SEARCH", () => {
|
||||
expect(parser.parse("SEARCH()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('SEARCH("bar")')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('SEARCH("bar", "foo bar")')).toMatchObject({
|
||||
error: null,
|
||||
result: 5,
|
||||
});
|
||||
});
|
||||
|
||||
it('SPLIT', () => {
|
||||
expect(parser.parse('SPLIT()')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse('SPLIT("foo bar baz")')).toMatchObject({error: null, result: ['foo bar baz']});
|
||||
expect(parser.parse('SPLIT("foo bar baz", " ")')).toMatchObject({error: null, result: ['foo', 'bar', 'baz']});
|
||||
it("SPLIT", () => {
|
||||
expect(parser.parse("SPLIT()")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('SPLIT("foo bar baz")')).toMatchObject({
|
||||
error: null,
|
||||
result: ["foo bar baz"],
|
||||
});
|
||||
expect(parser.parse('SPLIT("foo bar baz", " ")')).toMatchObject({
|
||||
error: null,
|
||||
result: ["foo", "bar", "baz"],
|
||||
});
|
||||
});
|
||||
|
||||
it('SUBSTITUTE', () => {
|
||||
expect(parser.parse('SUBSTITUTE()')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse('SUBSTITUTE("foo bar baz")')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse('SUBSTITUTE("foo bar baz", "a", "A")')).toMatchObject({error: null, result: 'foo bAr bAz'});
|
||||
it("SUBSTITUTE", () => {
|
||||
expect(parser.parse("SUBSTITUTE()")).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('SUBSTITUTE("foo bar baz")')).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('SUBSTITUTE("foo bar baz", "a", "A")')).toMatchObject({
|
||||
error: null,
|
||||
result: "foo bAr bAz",
|
||||
});
|
||||
});
|
||||
|
||||
it('T', () => {
|
||||
expect(parser.parse('T()')).toMatchObject({error: null, result: ''});
|
||||
expect(parser.parse('T(TRUE)')).toMatchObject({error: null, result: ''});
|
||||
expect(parser.parse('T(9.887)')).toMatchObject({error: null, result: ''});
|
||||
expect(parser.parse('T("foo bar baz")')).toMatchObject({error: null, result: 'foo bar baz'});
|
||||
it("T", () => {
|
||||
expect(parser.parse("T()")).toMatchObject({ error: null, result: "" });
|
||||
expect(parser.parse("T(TRUE)")).toMatchObject({ error: null, result: "" });
|
||||
expect(parser.parse("T(9.887)")).toMatchObject({ error: null, result: "" });
|
||||
expect(parser.parse('T("foo bar baz")')).toMatchObject({
|
||||
error: null,
|
||||
result: "foo bar baz",
|
||||
});
|
||||
});
|
||||
|
||||
xit('TEXT', () => {
|
||||
expect(parser.parse('TEXT()')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse('TEXT(1234.99)')).toMatchObject({error: null, result: '1,235'});
|
||||
expect(parser.parse('TEXT(1234.99, "####.#")')).toMatchObject({error: null, result: '1235.0'});
|
||||
expect(parser.parse('TEXT(1234.99, "####.###")')).toMatchObject({error: null, result: '1234.990'});
|
||||
xit("TEXT", () => {
|
||||
expect(parser.parse("TEXT()")).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("TEXT(1234.99)")).toMatchObject({
|
||||
error: null,
|
||||
result: "1,235",
|
||||
});
|
||||
expect(parser.parse('TEXT(1234.99, "####.#")')).toMatchObject({
|
||||
error: null,
|
||||
result: "1235.0",
|
||||
});
|
||||
expect(parser.parse('TEXT(1234.99, "####.###")')).toMatchObject({
|
||||
error: null,
|
||||
result: "1234.990",
|
||||
});
|
||||
});
|
||||
|
||||
it('TRIM', () => {
|
||||
expect(parser.parse('TRIM()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('TRIM("")')).toMatchObject({error: null, result: ''});
|
||||
expect(parser.parse('TRIM(" ")')).toMatchObject({error: null, result: ''});
|
||||
expect(parser.parse('TRIM(" foo ")')).toMatchObject({error: null, result: 'foo'});
|
||||
it("TRIM", () => {
|
||||
expect(parser.parse("TRIM()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('TRIM("")')).toMatchObject({ error: null, result: "" });
|
||||
expect(parser.parse('TRIM(" ")')).toMatchObject({
|
||||
error: null,
|
||||
result: "",
|
||||
});
|
||||
expect(parser.parse('TRIM(" foo ")')).toMatchObject({
|
||||
error: null,
|
||||
result: "foo",
|
||||
});
|
||||
});
|
||||
|
||||
it('UNICHAR', () => {
|
||||
expect(parser.parse('UNICHAR()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('UNICHAR(33)')).toMatchObject({error: null, result: '!'});
|
||||
it("UNICHAR", () => {
|
||||
expect(parser.parse("UNICHAR()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse("UNICHAR(33)")).toMatchObject({
|
||||
error: null,
|
||||
result: "!",
|
||||
});
|
||||
});
|
||||
|
||||
it('UNICODE', () => {
|
||||
expect(parser.parse('UNICODE()')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse('UNICODE("!")')).toMatchObject({error: null, result: 33});
|
||||
it("UNICODE", () => {
|
||||
expect(parser.parse("UNICODE()")).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('UNICODE("!")')).toMatchObject({
|
||||
error: null,
|
||||
result: 33,
|
||||
});
|
||||
});
|
||||
|
||||
it('UPPER', () => {
|
||||
expect(parser.parse('UPPER()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('UPPER("foo Bar")')).toMatchObject({error: null, result: 'FOO BAR'});
|
||||
it("UPPER", () => {
|
||||
expect(parser.parse("UPPER()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('UPPER("foo Bar")')).toMatchObject({
|
||||
error: null,
|
||||
result: "FOO BAR",
|
||||
});
|
||||
});
|
||||
|
||||
xit('VALUE', () => {
|
||||
expect(parser.parse('VALUE()')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse('VALUE("$1,000")')).toMatchObject({error: null, result: 1000});
|
||||
expect(parser.parse('VALUE("01:00:00")')).toMatchObject({error: null, result: 3600});
|
||||
expect(parser.parse('VALUE("foo Bar")')).toMatchObject({error: null, result: 0});
|
||||
xit("VALUE", () => {
|
||||
expect(parser.parse("VALUE()")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('VALUE("$1,000")')).toMatchObject({
|
||||
error: null,
|
||||
result: 1000,
|
||||
});
|
||||
expect(parser.parse('VALUE("01:00:00")')).toMatchObject({
|
||||
error: null,
|
||||
result: 3600,
|
||||
});
|
||||
expect(parser.parse('VALUE("foo Bar")')).toMatchObject({
|
||||
error: null,
|
||||
result: 0,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Parser from '../../../src/parser';
|
||||
import Parser from "../../../src/parser";
|
||||
|
||||
describe('.parse() custom function', () => {
|
||||
describe(".parse() custom function", () => {
|
||||
let parser;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -10,24 +10,36 @@ describe('.parse() custom function', () => {
|
||||
parser = null;
|
||||
});
|
||||
|
||||
it('should evaluate custom functions', () => {
|
||||
expect(parser.parse('foo()')).toMatchObject({error: '#NAME?', result: null});
|
||||
it("should evaluate custom functions", () => {
|
||||
expect(parser.parse("foo()")).toMatchObject({
|
||||
error: "#NAME?",
|
||||
result: null,
|
||||
});
|
||||
|
||||
parser.setFunction('ADD_5', (params) => params[0] + 5);
|
||||
parser.setFunction('GET_LETTER', (params) => {
|
||||
parser.setFunction("ADD_5", (params) => params[0] + 5);
|
||||
parser.setFunction("GET_LETTER", (params) => {
|
||||
const string = params[0];
|
||||
const index = params[1] - 1;
|
||||
|
||||
return string.charAt(index);
|
||||
});
|
||||
|
||||
expect(parser.parse('SUM(4, ADD_5(1))')).toMatchObject({error: null, result: 10});
|
||||
expect(parser.parse('GET_LETTER("Some string", 3)')).toMatchObject({error: null, result: 'm'});
|
||||
expect(parser.parse("SUM(4, ADD_5(1))")).toMatchObject({
|
||||
error: null,
|
||||
result: 10,
|
||||
});
|
||||
expect(parser.parse('GET_LETTER("Some string", 3)')).toMatchObject({
|
||||
error: null,
|
||||
result: "m",
|
||||
});
|
||||
});
|
||||
|
||||
it('should evaluate function with arguments passed as an stringified array', () => {
|
||||
expect(parser.parse('SUM([])')).toMatchObject({error: null, result: 0});
|
||||
expect(parser.parse('SUM([1])')).toMatchObject({error: null, result: 1});
|
||||
expect(parser.parse('SUM([1,2,3])')).toMatchObject({error: null, result: 6});
|
||||
it("should evaluate function with arguments passed as an stringified array", () => {
|
||||
expect(parser.parse("SUM([])")).toMatchObject({ error: null, result: 0 });
|
||||
expect(parser.parse("SUM([1])")).toMatchObject({ error: null, result: 1 });
|
||||
expect(parser.parse("SUM([1,2,3])")).toMatchObject({
|
||||
error: null,
|
||||
result: 6,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Parser from '../../../src/parser';
|
||||
import Parser from "../../../src/parser";
|
||||
|
||||
describe('.parse() general', () => {
|
||||
describe(".parse() general", () => {
|
||||
let parser;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -10,34 +10,52 @@ describe('.parse() general', () => {
|
||||
parser = null;
|
||||
});
|
||||
|
||||
it('should parse an empty string as it is', () => {
|
||||
expect(parser.parse('')).toMatchObject({error: null, result: ''});
|
||||
it("should parse an empty string as it is", () => {
|
||||
expect(parser.parse("")).toMatchObject({ error: null, result: "" });
|
||||
});
|
||||
|
||||
it('should not parse an number type data', () => {
|
||||
expect(parser.parse(200)).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse(20.1)).toMatchObject({error: '#ERROR!', result: null});
|
||||
it("should not parse an number type data", () => {
|
||||
expect(parser.parse(200)).toMatchObject({ error: "#ERROR!", result: null });
|
||||
expect(parser.parse(20.1)).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should not parse null type data', () => {
|
||||
expect(parser.parse(null)).toMatchObject({error: '#ERROR!', result: null});
|
||||
it("should not parse null type data", () => {
|
||||
expect(parser.parse(null)).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should not parse undefined type data', () => {
|
||||
expect(parser.parse(void 0)).toMatchObject({error: '#ERROR!', result: null});
|
||||
it("should not parse undefined type data", () => {
|
||||
expect(parser.parse(void 0)).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should not parse object type data', () => {
|
||||
expect(parser.parse({})).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse({a: 1})).toMatchObject({error: '#ERROR!', result: null});
|
||||
it("should not parse object type data", () => {
|
||||
expect(parser.parse({})).toMatchObject({ error: "#ERROR!", result: null });
|
||||
expect(parser.parse({ a: 1 })).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should not parse array type data', () => {
|
||||
expect(parser.parse([])).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse([1, 2])).toMatchObject({error: '#ERROR!', result: null});
|
||||
it("should not parse array type data", () => {
|
||||
expect(parser.parse([])).toMatchObject({ error: "#ERROR!", result: null });
|
||||
expect(parser.parse([1, 2])).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should not parse array type data', () => {
|
||||
expect(parser.parse(() => {})).toMatchObject({error: '#ERROR!', result: null});
|
||||
it("should not parse array type data", () => {
|
||||
expect(parser.parse(() => {})).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Parser from '../../../src/parser';
|
||||
import Parser from "../../../src/parser";
|
||||
|
||||
describe('.parse() logical', () => {
|
||||
describe(".parse() logical", () => {
|
||||
let parser;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -10,60 +10,159 @@ describe('.parse() logical', () => {
|
||||
parser = null;
|
||||
});
|
||||
|
||||
it('operator: =', () => {
|
||||
expect(parser.parse('10 = 10')).toMatchObject({error: null, result: true});
|
||||
it("operator: =", () => {
|
||||
expect(parser.parse("10 = 10")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
|
||||
expect(parser.parse('10 = 11')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse("10 = 11")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('operator: >', () => {
|
||||
expect(parser.parse('11 > 10')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('10 > 1.1')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('10 >- 10')).toMatchObject({error: null, result: true});
|
||||
it("operator: >", () => {
|
||||
expect(parser.parse("11 > 10")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("10 > 1.1")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("10 >- 10")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
|
||||
expect(parser.parse('10 > 11')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('10 > 11.1')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('10 > 10.00001')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse("10 > 11")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("10 > 11.1")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("10 > 10.00001")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('operator: <', () => {
|
||||
expect(parser.parse('10 < 11')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('10 < 11.1')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('10 < 10.00001')).toMatchObject({error: null, result: true});
|
||||
it("operator: <", () => {
|
||||
expect(parser.parse("10 < 11")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("10 < 11.1")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("10 < 10.00001")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
|
||||
expect(parser.parse('11 < 10')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('10 < 1.1')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('10 <- 10')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse("11 < 10")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("10 < 1.1")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("10 <- 10")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('operator: >=', () => {
|
||||
expect(parser.parse('11 >= 10')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('11 >= 11')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('10 >= 10')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('10 >= -10')).toMatchObject({error: null, result: true});
|
||||
it("operator: >=", () => {
|
||||
expect(parser.parse("11 >= 10")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("11 >= 11")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("10 >= 10")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("10 >= -10")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
|
||||
expect(parser.parse('10 >= 11')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('10 >= 11.1')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('10 >= 10.00001')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse("10 >= 11")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("10 >= 11.1")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("10 >= 10.00001")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('operator: <=', () => {
|
||||
expect(parser.parse('10 <= 10')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('1.1 <= 10')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('-10 <= 10')).toMatchObject({error: null, result: true});
|
||||
it("operator: <=", () => {
|
||||
expect(parser.parse("10 <= 10")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("1.1 <= 10")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("-10 <= 10")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
|
||||
expect(parser.parse('11 <= 10')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('11.1 <= 10')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('10.00001 <= 10')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse("11 <= 10")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("11.1 <= 10")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("10.00001 <= 10")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('operator: <>', () => {
|
||||
expect(parser.parse('10 <> 11')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('1.1 <> 10')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('-10 <> 10')).toMatchObject({error: null, result: true});
|
||||
it("operator: <>", () => {
|
||||
expect(parser.parse("10 <> 11")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("1.1 <> 10")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
expect(parser.parse("-10 <> 10")).toMatchObject({
|
||||
error: null,
|
||||
result: true,
|
||||
});
|
||||
|
||||
expect(parser.parse('10 <> 10')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('11.1 <> 11.1')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('10.00001 <> 10.00001')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse("10 <> 10")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("11.1 <> 11.1")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
expect(parser.parse("10.00001 <> 10.00001")).toMatchObject({
|
||||
error: null,
|
||||
result: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Parser from '../../../src/parser';
|
||||
import Parser from "../../../src/parser";
|
||||
|
||||
describe('.parse() math', () => {
|
||||
describe(".parse() math", () => {
|
||||
let parser;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -10,53 +10,111 @@ describe('.parse() math', () => {
|
||||
parser = null;
|
||||
});
|
||||
|
||||
it('operator: +', () => {
|
||||
expect(parser.parse('10+10')).toMatchObject({error: null, result: 20});
|
||||
expect(parser.parse('10 + 10')).toMatchObject({error: null, result: 20});
|
||||
expect(parser.parse('10 + 11 + 23 + 11 + 2')).toMatchObject({error: null, result: 57});
|
||||
expect(parser.parse('1.4425 + 4.333')).toMatchObject({error: null, result: 5.7755});
|
||||
expect(parser.parse('"foo" + 4.333')).toMatchObject({error: '#VALUE!', result: null});
|
||||
it("operator: +", () => {
|
||||
expect(parser.parse("10+10")).toMatchObject({ error: null, result: 20 });
|
||||
expect(parser.parse("10 + 10")).toMatchObject({ error: null, result: 20 });
|
||||
expect(parser.parse("10 + 11 + 23 + 11 + 2")).toMatchObject({
|
||||
error: null,
|
||||
result: 57,
|
||||
});
|
||||
expect(parser.parse("1.4425 + 4.333")).toMatchObject({
|
||||
error: null,
|
||||
result: 5.7755,
|
||||
});
|
||||
expect(parser.parse('"foo" + 4.333')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('operator: -', () => {
|
||||
expect(parser.parse('10-10')).toMatchObject({error: null, result: 0});
|
||||
expect(parser.parse('10 - 10')).toMatchObject({error: null, result: 0});
|
||||
expect(parser.parse('10 - 10 - 2')).toMatchObject({error: null, result: -2});
|
||||
expect(parser.parse('10 - 11 - 23 - 11 - 2')).toMatchObject({error: null, result: -37});
|
||||
expect(parser.parse('"foo" - 4.333')).toMatchObject({error: '#VALUE!', result: null});
|
||||
it("operator: -", () => {
|
||||
expect(parser.parse("10-10")).toMatchObject({ error: null, result: 0 });
|
||||
expect(parser.parse("10 - 10")).toMatchObject({ error: null, result: 0 });
|
||||
expect(parser.parse("10 - 10 - 2")).toMatchObject({
|
||||
error: null,
|
||||
result: -2,
|
||||
});
|
||||
expect(parser.parse("10 - 11 - 23 - 11 - 2")).toMatchObject({
|
||||
error: null,
|
||||
result: -37,
|
||||
});
|
||||
expect(parser.parse('"foo" - 4.333')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('operator: /', () => {
|
||||
expect(parser.parse('2 / 1')).toMatchObject({error: null, result: 2});
|
||||
expect(parser.parse('64 / 2 / 4')).toMatchObject({error: null, result: 8});
|
||||
expect(parser.parse('2 / 0')).toMatchObject({error: '#DIV/0!', result: null});
|
||||
expect(parser.parse('"foo" / 4.333')).toMatchObject({error: '#VALUE!', result: null});
|
||||
it("operator: /", () => {
|
||||
expect(parser.parse("2 / 1")).toMatchObject({ error: null, result: 2 });
|
||||
expect(parser.parse("64 / 2 / 4")).toMatchObject({
|
||||
error: null,
|
||||
result: 8,
|
||||
});
|
||||
expect(parser.parse("2 / 0")).toMatchObject({
|
||||
error: "#DIV/0!",
|
||||
result: null,
|
||||
});
|
||||
expect(parser.parse('"foo" / 4.333')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('operator: *', () => {
|
||||
expect(parser.parse('0 * 0 * 0 * 0 * 0')).toMatchObject({error: null, result: 0});
|
||||
expect(parser.parse('2 * 1')).toMatchObject({error: null, result: 2});
|
||||
expect(parser.parse('64 * 2 * 4')).toMatchObject({error: null, result: 512});
|
||||
expect(parser.parse('"foo" * 4.333')).toMatchObject({error: '#VALUE!', result: null});
|
||||
it("operator: *", () => {
|
||||
expect(parser.parse("0 * 0 * 0 * 0 * 0")).toMatchObject({
|
||||
error: null,
|
||||
result: 0,
|
||||
});
|
||||
expect(parser.parse("2 * 1")).toMatchObject({ error: null, result: 2 });
|
||||
expect(parser.parse("64 * 2 * 4")).toMatchObject({
|
||||
error: null,
|
||||
result: 512,
|
||||
});
|
||||
expect(parser.parse('"foo" * 4.333')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('operator: ^', () => {
|
||||
expect(parser.parse('2 ^ 5')).toMatchObject({error: null, result: 32});
|
||||
expect(parser.parse('"foo" ^ 4')).toMatchObject({error: '#VALUE!', result: null});
|
||||
it("operator: ^", () => {
|
||||
expect(parser.parse("2 ^ 5")).toMatchObject({ error: null, result: 32 });
|
||||
expect(parser.parse('"foo" ^ 4')).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('operator: &', () => {
|
||||
expect(parser.parse('2 & 5')).toMatchObject({error: null, result: '25'});
|
||||
expect(parser.parse('(2 & 5)')).toMatchObject({error: null, result: '25'});
|
||||
expect(parser.parse('("" & "")')).toMatchObject({error: null, result: ''});
|
||||
expect(parser.parse('"" & ""')).toMatchObject({error: null, result: ''});
|
||||
expect(parser.parse('("Hello" & " world") & "!"')).toMatchObject({error: null, result: 'Hello world!'});
|
||||
it("operator: &", () => {
|
||||
expect(parser.parse("2 & 5")).toMatchObject({ error: null, result: "25" });
|
||||
expect(parser.parse("(2 & 5)")).toMatchObject({
|
||||
error: null,
|
||||
result: "25",
|
||||
});
|
||||
expect(parser.parse('("" & "")')).toMatchObject({
|
||||
error: null,
|
||||
result: "",
|
||||
});
|
||||
expect(parser.parse('"" & ""')).toMatchObject({ error: null, result: "" });
|
||||
expect(parser.parse('("Hello" & " world") & "!"')).toMatchObject({
|
||||
error: null,
|
||||
result: "Hello world!",
|
||||
});
|
||||
});
|
||||
|
||||
it('mixed operators', () => {
|
||||
expect(parser.parse('1 + 10 - 20 * 3/2')).toMatchObject({error: null, result: -19});
|
||||
expect(parser.parse('((1 + 10 - 20 * 3 / 2) + 20) * 10')).toMatchObject({error: null, result: 10});
|
||||
expect(parser.parse('(((1 + 10 - 20 * 3/2) + 20) * 10) / 5.12')).toMatchObject({error: null, result: 1.953125});
|
||||
expect(parser.parse('(((1 + "foo" - 20 * 3/2) + 20) * 10) / 5.12')).toMatchObject({error: '#VALUE!', result: null});
|
||||
it("mixed operators", () => {
|
||||
expect(parser.parse("1 + 10 - 20 * 3/2")).toMatchObject({
|
||||
error: null,
|
||||
result: -19,
|
||||
});
|
||||
expect(parser.parse("((1 + 10 - 20 * 3 / 2) + 20) * 10")).toMatchObject({
|
||||
error: null,
|
||||
result: 10,
|
||||
});
|
||||
expect(
|
||||
parser.parse("(((1 + 10 - 20 * 3/2) + 20) * 10) / 5.12")
|
||||
).toMatchObject({ error: null, result: 1.953125 });
|
||||
expect(
|
||||
parser.parse('(((1 + "foo" - 20 * 3/2) + 20) * 10) / 5.12')
|
||||
).toMatchObject({ error: "#VALUE!", result: null });
|
||||
});
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Parser from '../../../src/parser';
|
||||
import Parser from "../../../src/parser";
|
||||
|
||||
describe('.parse() variable', () => {
|
||||
describe(".parse() variable", () => {
|
||||
let parser;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -10,19 +10,25 @@ describe('.parse() variable', () => {
|
||||
parser = null;
|
||||
});
|
||||
|
||||
it('should evaluate defaults variables', () => {
|
||||
expect(parser.parse('TRUE')).toMatchObject({error: null, result: true});
|
||||
expect(parser.parse('FALSE')).toMatchObject({error: null, result: false});
|
||||
expect(parser.parse('NULL')).toMatchObject({error: null, result: null});
|
||||
it("should evaluate defaults variables", () => {
|
||||
expect(parser.parse("TRUE")).toMatchObject({ error: null, result: true });
|
||||
expect(parser.parse("FALSE")).toMatchObject({ error: null, result: false });
|
||||
expect(parser.parse("NULL")).toMatchObject({ error: null, result: null });
|
||||
});
|
||||
|
||||
it('should evaluate custom variables', () => {
|
||||
expect(parser.parse('foo')).toMatchObject({error: '#NAME?', result: null});
|
||||
it("should evaluate custom variables", () => {
|
||||
expect(parser.parse("foo")).toMatchObject({
|
||||
error: "#NAME?",
|
||||
result: null,
|
||||
});
|
||||
|
||||
parser.setVariable('foo', 'bar');
|
||||
parser.setVariable('baz', '6.6');
|
||||
parser.setVariable("foo", "bar");
|
||||
parser.setVariable("baz", "6.6");
|
||||
|
||||
expect(parser.parse('foo')).toMatchObject({error: null, result: 'bar'});
|
||||
expect(parser.parse('SUM(baz, 2.1, 0.2)')).toMatchObject({error: null, result: 8.899999999999999});
|
||||
expect(parser.parse("foo")).toMatchObject({ error: null, result: "bar" });
|
||||
expect(parser.parse("SUM(baz, 2.1, 0.2)")).toMatchObject({
|
||||
error: null,
|
||||
result: 8.899999999999999,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,151 +1,151 @@
|
||||
import error, {isValidStrict} from '../../src/error';
|
||||
import error, { isValidStrict } from "../../src/error";
|
||||
|
||||
describe('.error()', () => {
|
||||
it('should return null for unrecognized error types', () => {
|
||||
describe(".error()", () => {
|
||||
it("should return null for unrecognized error types", () => {
|
||||
expect(error()).toBe(null);
|
||||
expect(error('')).toBe(null);
|
||||
expect(error('dewdewdw')).toBe(null);
|
||||
expect(error('ERROR1')).toBe(null);
|
||||
expect(error(' ERROR!')).toBe(null);
|
||||
expect(error(' #ERROR!')).toBe(null);
|
||||
expect(error("")).toBe(null);
|
||||
expect(error("dewdewdw")).toBe(null);
|
||||
expect(error("ERROR1")).toBe(null);
|
||||
expect(error(" ERROR!")).toBe(null);
|
||||
expect(error(" #ERROR!")).toBe(null);
|
||||
});
|
||||
|
||||
it('should return `#ERROR!`', () => {
|
||||
expect(error('ERROR')).toBe('#ERROR!');
|
||||
expect(error('ERROR!')).toBe('#ERROR!');
|
||||
expect(error('#ERROR')).toBe('#ERROR!');
|
||||
expect(error('#ERROR!')).toBe('#ERROR!');
|
||||
expect(error('#ERROR?')).toBe('#ERROR!');
|
||||
it("should return `#ERROR!`", () => {
|
||||
expect(error("ERROR")).toBe("#ERROR!");
|
||||
expect(error("ERROR!")).toBe("#ERROR!");
|
||||
expect(error("#ERROR")).toBe("#ERROR!");
|
||||
expect(error("#ERROR!")).toBe("#ERROR!");
|
||||
expect(error("#ERROR?")).toBe("#ERROR!");
|
||||
});
|
||||
|
||||
it('should return `#DIV/0!`', () => {
|
||||
expect(error('DIV/0')).toBe('#DIV/0!');
|
||||
expect(error('DIV/0!')).toBe('#DIV/0!');
|
||||
expect(error('#DIV/0')).toBe('#DIV/0!');
|
||||
expect(error('#DIV/0!')).toBe('#DIV/0!');
|
||||
expect(error('#DIV/0?')).toBe('#DIV/0!');
|
||||
it("should return `#DIV/0!`", () => {
|
||||
expect(error("DIV/0")).toBe("#DIV/0!");
|
||||
expect(error("DIV/0!")).toBe("#DIV/0!");
|
||||
expect(error("#DIV/0")).toBe("#DIV/0!");
|
||||
expect(error("#DIV/0!")).toBe("#DIV/0!");
|
||||
expect(error("#DIV/0?")).toBe("#DIV/0!");
|
||||
});
|
||||
|
||||
it('should return `#NAME?`', () => {
|
||||
expect(error('NAME')).toBe('#NAME?');
|
||||
expect(error('NAME!')).toBe('#NAME?');
|
||||
expect(error('#NAME')).toBe('#NAME?');
|
||||
expect(error('#NAME!')).toBe('#NAME?');
|
||||
expect(error('#NAME?')).toBe('#NAME?');
|
||||
it("should return `#NAME?`", () => {
|
||||
expect(error("NAME")).toBe("#NAME?");
|
||||
expect(error("NAME!")).toBe("#NAME?");
|
||||
expect(error("#NAME")).toBe("#NAME?");
|
||||
expect(error("#NAME!")).toBe("#NAME?");
|
||||
expect(error("#NAME?")).toBe("#NAME?");
|
||||
});
|
||||
|
||||
it('should return `#N/A`', () => {
|
||||
expect(error('N/A')).toBe('#N/A');
|
||||
expect(error('N/A!')).toBe('#N/A');
|
||||
expect(error('#N/A')).toBe('#N/A');
|
||||
expect(error('#N/A!')).toBe('#N/A');
|
||||
expect(error('#N/A?')).toBe('#N/A');
|
||||
it("should return `#N/A`", () => {
|
||||
expect(error("N/A")).toBe("#N/A");
|
||||
expect(error("N/A!")).toBe("#N/A");
|
||||
expect(error("#N/A")).toBe("#N/A");
|
||||
expect(error("#N/A!")).toBe("#N/A");
|
||||
expect(error("#N/A?")).toBe("#N/A");
|
||||
});
|
||||
|
||||
it('should return `#NULL!`', () => {
|
||||
expect(error('NULL')).toBe('#NULL!');
|
||||
expect(error('NULL!')).toBe('#NULL!');
|
||||
expect(error('#NULL')).toBe('#NULL!');
|
||||
expect(error('#NULL!')).toBe('#NULL!');
|
||||
expect(error('#NULL?')).toBe('#NULL!');
|
||||
it("should return `#NULL!`", () => {
|
||||
expect(error("NULL")).toBe("#NULL!");
|
||||
expect(error("NULL!")).toBe("#NULL!");
|
||||
expect(error("#NULL")).toBe("#NULL!");
|
||||
expect(error("#NULL!")).toBe("#NULL!");
|
||||
expect(error("#NULL?")).toBe("#NULL!");
|
||||
});
|
||||
|
||||
it('should return `#NUM!`', () => {
|
||||
expect(error('NUM')).toBe('#NUM!');
|
||||
expect(error('NUM!')).toBe('#NUM!');
|
||||
expect(error('#NUM')).toBe('#NUM!');
|
||||
expect(error('#NUM!')).toBe('#NUM!');
|
||||
expect(error('#NUM?')).toBe('#NUM!');
|
||||
it("should return `#NUM!`", () => {
|
||||
expect(error("NUM")).toBe("#NUM!");
|
||||
expect(error("NUM!")).toBe("#NUM!");
|
||||
expect(error("#NUM")).toBe("#NUM!");
|
||||
expect(error("#NUM!")).toBe("#NUM!");
|
||||
expect(error("#NUM?")).toBe("#NUM!");
|
||||
});
|
||||
|
||||
it('should return `#REF!`', () => {
|
||||
expect(error('REF')).toBe('#REF!');
|
||||
expect(error('REF!')).toBe('#REF!');
|
||||
expect(error('#REF')).toBe('#REF!');
|
||||
expect(error('#REF!')).toBe('#REF!');
|
||||
expect(error('#REF?')).toBe('#REF!');
|
||||
it("should return `#REF!`", () => {
|
||||
expect(error("REF")).toBe("#REF!");
|
||||
expect(error("REF!")).toBe("#REF!");
|
||||
expect(error("#REF")).toBe("#REF!");
|
||||
expect(error("#REF!")).toBe("#REF!");
|
||||
expect(error("#REF?")).toBe("#REF!");
|
||||
});
|
||||
|
||||
it('should return `#VALUE?`', () => {
|
||||
expect(error('VALUE')).toBe('#VALUE!');
|
||||
expect(error('VALUE!')).toBe('#VALUE!');
|
||||
expect(error('#VALUE')).toBe('#VALUE!');
|
||||
expect(error('#VALUE!')).toBe('#VALUE!');
|
||||
expect(error('#VALUE?')).toBe('#VALUE!');
|
||||
it("should return `#VALUE?`", () => {
|
||||
expect(error("VALUE")).toBe("#VALUE!");
|
||||
expect(error("VALUE!")).toBe("#VALUE!");
|
||||
expect(error("#VALUE")).toBe("#VALUE!");
|
||||
expect(error("#VALUE!")).toBe("#VALUE!");
|
||||
expect(error("#VALUE?")).toBe("#VALUE!");
|
||||
});
|
||||
});
|
||||
|
||||
describe('.isValidStrict()', () => {
|
||||
it('should return false for unrecognized error types', () => {
|
||||
describe(".isValidStrict()", () => {
|
||||
it("should return false for unrecognized error types", () => {
|
||||
expect(isValidStrict()).toBeFalsy();
|
||||
expect(isValidStrict('')).toBeFalsy();
|
||||
expect(isValidStrict('dewdewdw')).toBeFalsy();
|
||||
expect(isValidStrict('ERROR1')).toBeFalsy();
|
||||
expect(isValidStrict(' ERROR!')).toBeFalsy();
|
||||
expect(isValidStrict(' #ERROR!')).toBeFalsy();
|
||||
expect(isValidStrict("")).toBeFalsy();
|
||||
expect(isValidStrict("dewdewdw")).toBeFalsy();
|
||||
expect(isValidStrict("ERROR1")).toBeFalsy();
|
||||
expect(isValidStrict(" ERROR!")).toBeFalsy();
|
||||
expect(isValidStrict(" #ERROR!")).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return true for valid general error (`#ERROR!`)', () => {
|
||||
expect(isValidStrict('#ERROR!')).toBeTruthy();
|
||||
expect(isValidStrict('ERROR')).toBeFalsy();
|
||||
expect(isValidStrict('ERROR!')).toBeFalsy();
|
||||
expect(isValidStrict('#ERROR')).toBeFalsy();
|
||||
expect(isValidStrict('#ERROR?')).toBeFalsy();
|
||||
it("should return true for valid general error (`#ERROR!`)", () => {
|
||||
expect(isValidStrict("#ERROR!")).toBeTruthy();
|
||||
expect(isValidStrict("ERROR")).toBeFalsy();
|
||||
expect(isValidStrict("ERROR!")).toBeFalsy();
|
||||
expect(isValidStrict("#ERROR")).toBeFalsy();
|
||||
expect(isValidStrict("#ERROR?")).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return true for valid `#DIV/0!` error', () => {
|
||||
expect(isValidStrict('#DIV/0!')).toBeTruthy();
|
||||
expect(isValidStrict('DIV/0')).toBeFalsy();
|
||||
expect(isValidStrict('DIV/0!')).toBeFalsy();
|
||||
expect(isValidStrict('#DIV/0')).toBeFalsy();
|
||||
expect(isValidStrict('#DIV/0?')).toBeFalsy();
|
||||
it("should return true for valid `#DIV/0!` error", () => {
|
||||
expect(isValidStrict("#DIV/0!")).toBeTruthy();
|
||||
expect(isValidStrict("DIV/0")).toBeFalsy();
|
||||
expect(isValidStrict("DIV/0!")).toBeFalsy();
|
||||
expect(isValidStrict("#DIV/0")).toBeFalsy();
|
||||
expect(isValidStrict("#DIV/0?")).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return true for valid `#NAME?` error', () => {
|
||||
expect(isValidStrict('#NAME?')).toBeTruthy();
|
||||
expect(isValidStrict('NAME')).toBeFalsy();
|
||||
expect(isValidStrict('NAME!')).toBeFalsy();
|
||||
expect(isValidStrict('#NAME')).toBeFalsy();
|
||||
expect(isValidStrict('#NAME!')).toBeFalsy();
|
||||
it("should return true for valid `#NAME?` error", () => {
|
||||
expect(isValidStrict("#NAME?")).toBeTruthy();
|
||||
expect(isValidStrict("NAME")).toBeFalsy();
|
||||
expect(isValidStrict("NAME!")).toBeFalsy();
|
||||
expect(isValidStrict("#NAME")).toBeFalsy();
|
||||
expect(isValidStrict("#NAME!")).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return true for valid `#N/A` error', () => {
|
||||
expect(isValidStrict('#N/A')).toBeTruthy();
|
||||
expect(isValidStrict('N/A')).toBeFalsy();
|
||||
expect(isValidStrict('N/A!')).toBeFalsy();
|
||||
expect(isValidStrict('#N/A!')).toBeFalsy();
|
||||
expect(isValidStrict('#N/A?')).toBeFalsy();
|
||||
it("should return true for valid `#N/A` error", () => {
|
||||
expect(isValidStrict("#N/A")).toBeTruthy();
|
||||
expect(isValidStrict("N/A")).toBeFalsy();
|
||||
expect(isValidStrict("N/A!")).toBeFalsy();
|
||||
expect(isValidStrict("#N/A!")).toBeFalsy();
|
||||
expect(isValidStrict("#N/A?")).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return true for valid `#NULL!` error', () => {
|
||||
expect(isValidStrict('#NULL!')).toBeTruthy();
|
||||
expect(isValidStrict('NULL')).toBeFalsy();
|
||||
expect(isValidStrict('NULL!')).toBeFalsy();
|
||||
expect(isValidStrict('#NULL')).toBeFalsy();
|
||||
expect(isValidStrict('#NULL?')).toBeFalsy();
|
||||
it("should return true for valid `#NULL!` error", () => {
|
||||
expect(isValidStrict("#NULL!")).toBeTruthy();
|
||||
expect(isValidStrict("NULL")).toBeFalsy();
|
||||
expect(isValidStrict("NULL!")).toBeFalsy();
|
||||
expect(isValidStrict("#NULL")).toBeFalsy();
|
||||
expect(isValidStrict("#NULL?")).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return true for valid `#NUM!` error', () => {
|
||||
expect(isValidStrict('#NUM!')).toBeTruthy();
|
||||
expect(isValidStrict('NUM')).toBeFalsy();
|
||||
expect(isValidStrict('NUM!')).toBeFalsy();
|
||||
expect(isValidStrict('#NUM')).toBeFalsy();
|
||||
expect(isValidStrict('#NUM?')).toBeFalsy();
|
||||
it("should return true for valid `#NUM!` error", () => {
|
||||
expect(isValidStrict("#NUM!")).toBeTruthy();
|
||||
expect(isValidStrict("NUM")).toBeFalsy();
|
||||
expect(isValidStrict("NUM!")).toBeFalsy();
|
||||
expect(isValidStrict("#NUM")).toBeFalsy();
|
||||
expect(isValidStrict("#NUM?")).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return true for valid `#REF!` error', () => {
|
||||
expect(isValidStrict('#REF!')).toBeTruthy();
|
||||
expect(isValidStrict('REF')).toBeFalsy();
|
||||
expect(isValidStrict('REF!')).toBeFalsy();
|
||||
expect(isValidStrict('#REF')).toBeFalsy();
|
||||
expect(isValidStrict('#REF?')).toBeFalsy();
|
||||
it("should return true for valid `#REF!` error", () => {
|
||||
expect(isValidStrict("#REF!")).toBeTruthy();
|
||||
expect(isValidStrict("REF")).toBeFalsy();
|
||||
expect(isValidStrict("REF!")).toBeFalsy();
|
||||
expect(isValidStrict("#REF")).toBeFalsy();
|
||||
expect(isValidStrict("#REF?")).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return true for valid `#VALUE!` error', () => {
|
||||
expect(isValidStrict('#VALUE!')).toBeTruthy();
|
||||
expect(isValidStrict('VALUE')).toBeFalsy();
|
||||
expect(isValidStrict('VALUE!')).toBeFalsy();
|
||||
expect(isValidStrict('#VALUE')).toBeFalsy();
|
||||
expect(isValidStrict('#VALUE?')).toBeFalsy();
|
||||
it("should return true for valid `#VALUE!` error", () => {
|
||||
expect(isValidStrict("#VALUE!")).toBeTruthy();
|
||||
expect(isValidStrict("VALUE")).toBeFalsy();
|
||||
expect(isValidStrict("VALUE!")).toBeFalsy();
|
||||
expect(isValidStrict("#VALUE")).toBeFalsy();
|
||||
expect(isValidStrict("#VALUE?")).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
@ -1,99 +1,101 @@
|
||||
import evaluateByOperator, {registerOperation} from '../../../src/evaluate-by-operator/evaluate-by-operator';
|
||||
import evaluateByOperator, {
|
||||
registerOperation,
|
||||
} from "../../../src/evaluate-by-operator/evaluate-by-operator";
|
||||
|
||||
describe('.registerOperation()', () => {
|
||||
it('should register new operator and evaluate it', () => {
|
||||
registerOperation('foo', (a, b) => a + b);
|
||||
describe(".registerOperation()", () => {
|
||||
it("should register new operator and evaluate it", () => {
|
||||
registerOperation("foo", (a, b) => a + b);
|
||||
|
||||
expect(evaluateByOperator('foo', [2, 8.8])).toBe(10.8);
|
||||
expect(evaluateByOperator('foo', ['2', '8.8'])).toBe('28.8');
|
||||
expect(evaluateByOperator("foo", [2, 8.8])).toBe(10.8);
|
||||
expect(evaluateByOperator("foo", ["2", "8.8"])).toBe("28.8");
|
||||
});
|
||||
});
|
||||
|
||||
describe('.evaluateByOperator()', () => {
|
||||
it('should throw exception when operator do not exist', () => {
|
||||
describe(".evaluateByOperator()", () => {
|
||||
it("should throw exception when operator do not exist", () => {
|
||||
expect(() => {
|
||||
evaluateByOperator('bar', [2, 8.8]);
|
||||
}).toThrow('NAME');
|
||||
evaluateByOperator("bar", [2, 8.8]);
|
||||
}).toThrow("NAME");
|
||||
expect(() => {
|
||||
evaluateByOperator('baz');
|
||||
}).toThrow('NAME');
|
||||
evaluateByOperator("baz");
|
||||
}).toThrow("NAME");
|
||||
});
|
||||
|
||||
it('should not to throw exception for `add` operator', () => {
|
||||
it("should not to throw exception for `add` operator", () => {
|
||||
expect(() => {
|
||||
evaluateByOperator('+', [2, 8.8]);
|
||||
evaluateByOperator("+", [2, 8.8]);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not to throw exception for `ampersand` operator', () => {
|
||||
it("should not to throw exception for `ampersand` operator", () => {
|
||||
expect(() => {
|
||||
evaluateByOperator('&', [2, 8.8]);
|
||||
evaluateByOperator("&", [2, 8.8]);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not to throw exception for `divide` operator', () => {
|
||||
it("should not to throw exception for `divide` operator", () => {
|
||||
expect(() => {
|
||||
evaluateByOperator('/', [2, 8.8]);
|
||||
evaluateByOperator("/", [2, 8.8]);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not to throw exception for `equal` operator', () => {
|
||||
it("should not to throw exception for `equal` operator", () => {
|
||||
expect(() => {
|
||||
evaluateByOperator('=', [2, 8.8]);
|
||||
evaluateByOperator("=", [2, 8.8]);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not to throw exception for `formula function` operator', () => {
|
||||
it("should not to throw exception for `formula function` operator", () => {
|
||||
expect(() => {
|
||||
evaluateByOperator('SUM', [2, 8.8]);
|
||||
evaluateByOperator("SUM", [2, 8.8]);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not to throw exception for `greater than` operator', () => {
|
||||
it("should not to throw exception for `greater than` operator", () => {
|
||||
expect(() => {
|
||||
evaluateByOperator('>', [2, 8.8]);
|
||||
evaluateByOperator(">", [2, 8.8]);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not to throw exception for `greater than or equal` operator', () => {
|
||||
it("should not to throw exception for `greater than or equal` operator", () => {
|
||||
expect(() => {
|
||||
evaluateByOperator('>=', [2, 8.8]);
|
||||
evaluateByOperator(">=", [2, 8.8]);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not to throw exception for `less than` operator', () => {
|
||||
it("should not to throw exception for `less than` operator", () => {
|
||||
expect(() => {
|
||||
evaluateByOperator('<', [2, 8.8]);
|
||||
evaluateByOperator("<", [2, 8.8]);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not to throw exception for `less than or equal` operator', () => {
|
||||
it("should not to throw exception for `less than or equal` operator", () => {
|
||||
expect(() => {
|
||||
evaluateByOperator('<=', [2, 8.8]);
|
||||
evaluateByOperator("<=", [2, 8.8]);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not to throw exception for `minus` operator', () => {
|
||||
it("should not to throw exception for `minus` operator", () => {
|
||||
expect(() => {
|
||||
evaluateByOperator('-', [2, 8.8]);
|
||||
evaluateByOperator("-", [2, 8.8]);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not to throw exception for `multiply` operator', () => {
|
||||
it("should not to throw exception for `multiply` operator", () => {
|
||||
expect(() => {
|
||||
evaluateByOperator('*', [2, 8.8]);
|
||||
evaluateByOperator("*", [2, 8.8]);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not to throw exception for `not equal` operator', () => {
|
||||
it("should not to throw exception for `not equal` operator", () => {
|
||||
expect(() => {
|
||||
evaluateByOperator('<>', [2, 8.8]);
|
||||
evaluateByOperator("<>", [2, 8.8]);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not to throw exception for `power` operator', () => {
|
||||
it("should not to throw exception for `power` operator", () => {
|
||||
expect(() => {
|
||||
evaluateByOperator('^', [2, 2]);
|
||||
evaluateByOperator("^", [2, 2]);
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
@ -1,17 +1,17 @@
|
||||
/* eslint-disable import/no-named-as-default-member */
|
||||
import func from '../../../../src/evaluate-by-operator/operator/add';
|
||||
import func from "../../../../src/evaluate-by-operator/operator/add";
|
||||
|
||||
describe('add operator', () => {
|
||||
it('should set SYMBOL const', () => {
|
||||
expect(func.SYMBOL).toBe('+');
|
||||
describe("add operator", () => {
|
||||
it("should set SYMBOL const", () => {
|
||||
expect(func.SYMBOL).toBe("+");
|
||||
});
|
||||
|
||||
it('should correctly process values', () => {
|
||||
it("should correctly process values", () => {
|
||||
expect(func(2, 8.8)).toBe(10.8);
|
||||
expect(func('2', 8.8)).toBe(10.8);
|
||||
expect(func('2', '8.8')).toBe(10.8);
|
||||
expect(func('2', '-8.8', 6, 0.4)).toBe(-0.4000000000000007);
|
||||
expect(() => func('foo', ' ', 'bar', ' baz')).toThrow('VALUE');
|
||||
expect(() => func('foo', 2)).toThrow('VALUE');
|
||||
expect(func("2", 8.8)).toBe(10.8);
|
||||
expect(func("2", "8.8")).toBe(10.8);
|
||||
expect(func("2", "-8.8", 6, 0.4)).toBe(-0.4000000000000007);
|
||||
expect(() => func("foo", " ", "bar", " baz")).toThrow("VALUE");
|
||||
expect(() => func("foo", 2)).toThrow("VALUE");
|
||||
});
|
||||
});
|
||||
|
@ -1,15 +1,15 @@
|
||||
/* eslint-disable import/no-named-as-default-member */
|
||||
import func from '../../../../src/evaluate-by-operator/operator/ampersand';
|
||||
import func from "../../../../src/evaluate-by-operator/operator/ampersand";
|
||||
|
||||
describe('ampersand operator', () => {
|
||||
it('should set SYMBOL const', () => {
|
||||
expect(func.SYMBOL).toBe('&');
|
||||
describe("ampersand operator", () => {
|
||||
it("should set SYMBOL const", () => {
|
||||
expect(func.SYMBOL).toBe("&");
|
||||
});
|
||||
|
||||
it('should correctly process values', () => {
|
||||
expect(func(2, 8.8)).toBe('28.8');
|
||||
expect(func('2', 8.8)).toBe('28.8');
|
||||
expect(func('2', '-8.8', 6, 0.4)).toBe('2-8.860.4');
|
||||
expect(func('foo', ' ', 'bar', ' baz')).toBe('foo bar baz');
|
||||
it("should correctly process values", () => {
|
||||
expect(func(2, 8.8)).toBe("28.8");
|
||||
expect(func("2", 8.8)).toBe("28.8");
|
||||
expect(func("2", "-8.8", 6, 0.4)).toBe("2-8.860.4");
|
||||
expect(func("foo", " ", "bar", " baz")).toBe("foo bar baz");
|
||||
});
|
||||
});
|
||||
|
@ -1,17 +1,17 @@
|
||||
/* eslint-disable import/no-named-as-default-member */
|
||||
import func from '../../../../src/evaluate-by-operator/operator/divide';
|
||||
import func from "../../../../src/evaluate-by-operator/operator/divide";
|
||||
|
||||
describe('divide operator', () => {
|
||||
it('should set SYMBOL const', () => {
|
||||
expect(func.SYMBOL).toBe('/');
|
||||
describe("divide operator", () => {
|
||||
it("should set SYMBOL const", () => {
|
||||
expect(func.SYMBOL).toBe("/");
|
||||
});
|
||||
|
||||
it('should correctly process values', () => {
|
||||
it("should correctly process values", () => {
|
||||
expect(func(2, 8.8)).toBe(0.22727272727272727);
|
||||
expect(func('2', 8.8)).toBe(0.22727272727272727);
|
||||
expect(func('2', '-8.8', 6, 0.4)).toBe(-0.0946969696969697);
|
||||
expect(() => func('foo', ' ', 'bar', ' baz')).toThrow('VALUE');
|
||||
expect(func("2", 8.8)).toBe(0.22727272727272727);
|
||||
expect(func("2", "-8.8", 6, 0.4)).toBe(-0.0946969696969697);
|
||||
expect(() => func("foo", " ", "bar", " baz")).toThrow("VALUE");
|
||||
expect(func(0, 1)).toBe(0);
|
||||
expect(() => func(1, 0)).toThrow('DIV/0');
|
||||
expect(() => func(1, 0)).toThrow("DIV/0");
|
||||
});
|
||||
});
|
||||
|
@ -1,15 +1,15 @@
|
||||
/* eslint-disable import/no-named-as-default-member */
|
||||
import func from '../../../../src/evaluate-by-operator/operator/equal';
|
||||
import func from "../../../../src/evaluate-by-operator/operator/equal";
|
||||
|
||||
describe('equal operator', () => {
|
||||
it('should set SYMBOL const', () => {
|
||||
expect(func.SYMBOL).toBe('=');
|
||||
describe("equal operator", () => {
|
||||
it("should set SYMBOL const", () => {
|
||||
expect(func.SYMBOL).toBe("=");
|
||||
});
|
||||
|
||||
it('should correctly process values', () => {
|
||||
it("should correctly process values", () => {
|
||||
expect(func(2, 8.8)).toBe(false);
|
||||
expect(func('2', 8.8)).toBe(false);
|
||||
expect(func(1, '1')).toBe(false);
|
||||
expect(func("2", 8.8)).toBe(false);
|
||||
expect(func(1, "1")).toBe(false);
|
||||
expect(func(void 0, null)).toBe(false);
|
||||
expect(func(0, null)).toBe(false);
|
||||
expect(func(0, void 0)).toBe(false);
|
||||
|
@ -1,33 +1,33 @@
|
||||
/* eslint-disable import/no-named-as-default-member */
|
||||
import SUPPORTED_FORMULAS from '../../../../src/supported-formulas';
|
||||
import func from '../../../../src/evaluate-by-operator/operator/formula-function';
|
||||
import SUPPORTED_FORMULAS from "../../../../src/supported-formulas";
|
||||
import func from "../../../../src/evaluate-by-operator/operator/formula-function";
|
||||
|
||||
describe('formula function operator', () => {
|
||||
it('should set SYMBOL const', () => {
|
||||
describe("formula function operator", () => {
|
||||
it("should set SYMBOL const", () => {
|
||||
expect(func.SYMBOL).toBe(SUPPORTED_FORMULAS);
|
||||
});
|
||||
|
||||
it('should set isFactory const', () => {
|
||||
it("should set isFactory const", () => {
|
||||
expect(func.isFactory).toBe(true);
|
||||
});
|
||||
|
||||
it('should return error when formula not exist (shallow call)', () => {
|
||||
expect(() => func('SUMEE')(8.8, 2, 1, 4)).toThrow('NAME');
|
||||
it("should return error when formula not exist (shallow call)", () => {
|
||||
expect(() => func("SUMEE")(8.8, 2, 1, 4)).toThrow("NAME");
|
||||
});
|
||||
|
||||
it('should return error when formula not exist (deep call)', () => {
|
||||
expect(() => func('SUMEE.INT')(8.8, 2, 1, 4)).toThrow('NAME');
|
||||
it("should return error when formula not exist (deep call)", () => {
|
||||
expect(() => func("SUMEE.INT")(8.8, 2, 1, 4)).toThrow("NAME");
|
||||
});
|
||||
|
||||
it('should correctly process formula (shallow call)', () => {
|
||||
const result = func('SUM')(8.8, 2, 1, 4);
|
||||
it("should correctly process formula (shallow call)", () => {
|
||||
const result = func("SUM")(8.8, 2, 1, 4);
|
||||
|
||||
expect(result).toBe(15.8);
|
||||
});
|
||||
|
||||
it('should correctly process formula passed in lower case', () => {
|
||||
const result1 = func('Sum')(8.8, 2, 1, 4);
|
||||
const result2 = func('Rank.eq')(2, [7, 3.5, 3.5, 1, 2]);
|
||||
it("should correctly process formula passed in lower case", () => {
|
||||
const result1 = func("Sum")(8.8, 2, 1, 4);
|
||||
const result2 = func("Rank.eq")(2, [7, 3.5, 3.5, 1, 2]);
|
||||
|
||||
expect(result1).toBe(15.8);
|
||||
expect(result2).toBe(4);
|
||||
|
@ -1,19 +1,19 @@
|
||||
/* eslint-disable import/no-named-as-default-member */
|
||||
import func from '../../../../src/evaluate-by-operator/operator/greater-than-or-equal';
|
||||
import func from "../../../../src/evaluate-by-operator/operator/greater-than-or-equal";
|
||||
|
||||
describe('greater than or equal operator', () => {
|
||||
it('should set SYMBOL const', () => {
|
||||
expect(func.SYMBOL).toBe('>=');
|
||||
describe("greater than or equal operator", () => {
|
||||
it("should set SYMBOL const", () => {
|
||||
expect(func.SYMBOL).toBe(">=");
|
||||
});
|
||||
|
||||
it('should correctly process values', () => {
|
||||
it("should correctly process values", () => {
|
||||
expect(func(2, 8.8)).toBe(false);
|
||||
expect(func('2', 8.8)).toBe(false);
|
||||
expect(func("2", 8.8)).toBe(false);
|
||||
expect(func(void 0, null)).toBe(false);
|
||||
expect(func(0, void 0)).toBe(false);
|
||||
|
||||
expect(func(0, null)).toBe(true); // JS natively
|
||||
expect(func(1, '1')).toBe(true);
|
||||
expect(func(1, "1")).toBe(true);
|
||||
expect(func(1, 1)).toBe(true);
|
||||
expect(func(2, 1)).toBe(true);
|
||||
expect(func(2.2, 2.1)).toBe(true);
|
||||
|
@ -1,15 +1,15 @@
|
||||
/* eslint-disable import/no-named-as-default-member */
|
||||
import func from '../../../../src/evaluate-by-operator/operator/greater-than';
|
||||
import func from "../../../../src/evaluate-by-operator/operator/greater-than";
|
||||
|
||||
describe('greater than operator', () => {
|
||||
it('should set SYMBOL const', () => {
|
||||
expect(func.SYMBOL).toBe('>');
|
||||
describe("greater than operator", () => {
|
||||
it("should set SYMBOL const", () => {
|
||||
expect(func.SYMBOL).toBe(">");
|
||||
});
|
||||
|
||||
it('should correctly process values', () => {
|
||||
it("should correctly process values", () => {
|
||||
expect(func(2, 8.8)).toBe(false);
|
||||
expect(func('2', 8.8)).toBe(false);
|
||||
expect(func(1, '1')).toBe(false);
|
||||
expect(func("2", 8.8)).toBe(false);
|
||||
expect(func(1, "1")).toBe(false);
|
||||
expect(func(1, 1)).toBe(false);
|
||||
expect(func(void 0, null)).toBe(false);
|
||||
expect(func(0, null)).toBe(false);
|
||||
|
@ -1,21 +1,21 @@
|
||||
/* eslint-disable import/no-named-as-default-member */
|
||||
import func from '../../../../src/evaluate-by-operator/operator/less-than-or-equal';
|
||||
import func from "../../../../src/evaluate-by-operator/operator/less-than-or-equal";
|
||||
|
||||
describe('less than or equal operator', () => {
|
||||
it('should set SYMBOL const', () => {
|
||||
expect(func.SYMBOL).toBe('<=');
|
||||
describe("less than or equal operator", () => {
|
||||
it("should set SYMBOL const", () => {
|
||||
expect(func.SYMBOL).toBe("<=");
|
||||
});
|
||||
|
||||
it('should correctly process values', () => {
|
||||
it("should correctly process values", () => {
|
||||
expect(func(2, 1)).toBe(false);
|
||||
expect(func(2.2, 2.1)).toBe(false);
|
||||
expect(func(void 0, null)).toBe(false);
|
||||
expect(func(0, void 0)).toBe(false);
|
||||
|
||||
expect(func(0, null)).toBe(true); // JS natively
|
||||
expect(func(1, '1')).toBe(true);
|
||||
expect(func(1, "1")).toBe(true);
|
||||
expect(func(1, 1)).toBe(true);
|
||||
expect(func('2', 8.8)).toBe(true);
|
||||
expect(func("2", 8.8)).toBe(true);
|
||||
expect(func(2, 8.8)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -1,21 +1,21 @@
|
||||
/* eslint-disable import/no-named-as-default-member */
|
||||
import func from '../../../../src/evaluate-by-operator/operator/less-than';
|
||||
import func from "../../../../src/evaluate-by-operator/operator/less-than";
|
||||
|
||||
describe('less than operator', () => {
|
||||
it('should set SYMBOL const', () => {
|
||||
expect(func.SYMBOL).toBe('<');
|
||||
describe("less than operator", () => {
|
||||
it("should set SYMBOL const", () => {
|
||||
expect(func.SYMBOL).toBe("<");
|
||||
});
|
||||
|
||||
it('should correctly process values', () => {
|
||||
it("should correctly process values", () => {
|
||||
expect(func(2, 1)).toBe(false);
|
||||
expect(func(2.2, 2.1)).toBe(false);
|
||||
expect(func(1, '1')).toBe(false);
|
||||
expect(func(1, "1")).toBe(false);
|
||||
expect(func(1, 1)).toBe(false);
|
||||
expect(func(void 0, null)).toBe(false);
|
||||
expect(func(0, null)).toBe(false);
|
||||
expect(func(0, void 0)).toBe(false);
|
||||
|
||||
expect(func('2', 8.8)).toBe(true);
|
||||
expect(func("2", 8.8)).toBe(true);
|
||||
expect(func(2, 8.8)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -1,17 +1,17 @@
|
||||
/* eslint-disable import/no-named-as-default-member */
|
||||
import func from '../../../../src/evaluate-by-operator/operator/minus';
|
||||
import func from "../../../../src/evaluate-by-operator/operator/minus";
|
||||
|
||||
describe('minus operator', () => {
|
||||
it('should set SYMBOL const', () => {
|
||||
expect(func.SYMBOL).toBe('-');
|
||||
describe("minus operator", () => {
|
||||
it("should set SYMBOL const", () => {
|
||||
expect(func.SYMBOL).toBe("-");
|
||||
});
|
||||
|
||||
it('should correctly process values', () => {
|
||||
it("should correctly process values", () => {
|
||||
expect(func(2, 8.8)).toBe(-6.800000000000001);
|
||||
expect(func('2', 8.8)).toBe(-6.800000000000001);
|
||||
expect(func('2', '8.8')).toBe(-6.800000000000001);
|
||||
expect(func('2', '-8.8', 6, 0.4)).toBe(4.4);
|
||||
expect(() => func('foo', ' ', 'bar', ' baz')).toThrow('VALUE');
|
||||
expect(() => func('foo', 2)).toThrow('VALUE');
|
||||
expect(func("2", 8.8)).toBe(-6.800000000000001);
|
||||
expect(func("2", "8.8")).toBe(-6.800000000000001);
|
||||
expect(func("2", "-8.8", 6, 0.4)).toBe(4.4);
|
||||
expect(() => func("foo", " ", "bar", " baz")).toThrow("VALUE");
|
||||
expect(() => func("foo", 2)).toThrow("VALUE");
|
||||
});
|
||||
});
|
||||
|
@ -1,17 +1,17 @@
|
||||
/* eslint-disable import/no-named-as-default-member */
|
||||
import func from '../../../../src/evaluate-by-operator/operator/multiply';
|
||||
import func from "../../../../src/evaluate-by-operator/operator/multiply";
|
||||
|
||||
describe('multiply operator', () => {
|
||||
it('should set SYMBOL const', () => {
|
||||
expect(func.SYMBOL).toBe('*');
|
||||
describe("multiply operator", () => {
|
||||
it("should set SYMBOL const", () => {
|
||||
expect(func.SYMBOL).toBe("*");
|
||||
});
|
||||
|
||||
it('should correctly process values', () => {
|
||||
it("should correctly process values", () => {
|
||||
expect(func(2, 8.8)).toBe(17.6);
|
||||
expect(func('2', 8.8)).toBe(17.6);
|
||||
expect(func('2', '8.8')).toBe(17.6);
|
||||
expect(func('2', '-8.8', 6, 0.4)).toBe(-42.24000000000001);
|
||||
expect(() => func('foo', ' ', 'bar', ' baz')).toThrow('VALUE');
|
||||
expect(() => func('foo', 2)).toThrow('VALUE');
|
||||
expect(func("2", 8.8)).toBe(17.6);
|
||||
expect(func("2", "8.8")).toBe(17.6);
|
||||
expect(func("2", "-8.8", 6, 0.4)).toBe(-42.24000000000001);
|
||||
expect(() => func("foo", " ", "bar", " baz")).toThrow("VALUE");
|
||||
expect(() => func("foo", 2)).toThrow("VALUE");
|
||||
});
|
||||
});
|
||||
|
@ -1,15 +1,15 @@
|
||||
/* eslint-disable import/no-named-as-default-member */
|
||||
import func from '../../../../src/evaluate-by-operator/operator/not-equal';
|
||||
import func from "../../../../src/evaluate-by-operator/operator/not-equal";
|
||||
|
||||
describe('not equal operator', () => {
|
||||
it('should set SYMBOL const', () => {
|
||||
expect(func.SYMBOL).toBe('<>');
|
||||
describe("not equal operator", () => {
|
||||
it("should set SYMBOL const", () => {
|
||||
expect(func.SYMBOL).toBe("<>");
|
||||
});
|
||||
|
||||
it('should correctly process values', () => {
|
||||
it("should correctly process values", () => {
|
||||
expect(func(2, 8.8)).toBe(true);
|
||||
expect(func('2', 8.8)).toBe(true);
|
||||
expect(func(1, '1')).toBe(true);
|
||||
expect(func("2", 8.8)).toBe(true);
|
||||
expect(func(1, "1")).toBe(true);
|
||||
expect(func(void 0, null)).toBe(true);
|
||||
expect(func(0, null)).toBe(true);
|
||||
expect(func(0, void 0)).toBe(true);
|
||||
|
@ -1,17 +1,17 @@
|
||||
/* eslint-disable import/no-named-as-default-member */
|
||||
import func from '../../../../src/evaluate-by-operator/operator/power';
|
||||
import func from "../../../../src/evaluate-by-operator/operator/power";
|
||||
|
||||
describe('power operator', () => {
|
||||
it('should set SYMBOL const', () => {
|
||||
expect(func.SYMBOL).toBe('^');
|
||||
describe("power operator", () => {
|
||||
it("should set SYMBOL const", () => {
|
||||
expect(func.SYMBOL).toBe("^");
|
||||
});
|
||||
|
||||
it('should correctly process values', () => {
|
||||
it("should correctly process values", () => {
|
||||
expect(func(2, 8.8)).toBe(445.7218884076158);
|
||||
expect(func('2', 8.8)).toBe(445.7218884076158);
|
||||
expect(func('2', '8.8')).toBe(445.7218884076158);
|
||||
expect(func('2', '8.8', 6, 0.4)).toBe(445.7218884076158);
|
||||
expect(() => func('foo', ' ', 'bar', ' baz')).toThrow('VALUE');
|
||||
expect(() => func('foo', 2)).toThrow('VALUE');
|
||||
expect(func("2", 8.8)).toBe(445.7218884076158);
|
||||
expect(func("2", "8.8")).toBe(445.7218884076158);
|
||||
expect(func("2", "8.8", 6, 0.4)).toBe(445.7218884076158);
|
||||
expect(() => func("foo", " ", "bar", " baz")).toThrow("VALUE");
|
||||
expect(() => func("foo", 2)).toThrow("VALUE");
|
||||
});
|
||||
});
|
||||
|
@ -5,170 +5,180 @@ import {
|
||||
columnLabelToIndex,
|
||||
rowIndexToLabel,
|
||||
rowLabelToIndex,
|
||||
} from '../../../src/helper/cell';
|
||||
} from "../../../src/helper/cell";
|
||||
|
||||
describe('.extractLabel()', () => {
|
||||
it('should correctly extract coordinates', () => {
|
||||
expect(extractLabel('A1')).toMatchObject([
|
||||
describe(".extractLabel()", () => {
|
||||
it("should correctly extract coordinates", () => {
|
||||
expect(extractLabel("A1")).toMatchObject([
|
||||
{
|
||||
index: 0,
|
||||
label: '1',
|
||||
label: "1",
|
||||
isAbsolute: false,
|
||||
},
|
||||
{
|
||||
index: 0,
|
||||
label: 'A',
|
||||
label: "A",
|
||||
isAbsolute: false,
|
||||
},
|
||||
]);
|
||||
expect(extractLabel('a1')).toMatchObject([
|
||||
expect(extractLabel("a1")).toMatchObject([
|
||||
{
|
||||
index: 0,
|
||||
label: '1',
|
||||
label: "1",
|
||||
isAbsolute: false,
|
||||
},
|
||||
{
|
||||
index: 0,
|
||||
label: 'A',
|
||||
label: "A",
|
||||
isAbsolute: false,
|
||||
},
|
||||
]);
|
||||
expect(extractLabel('A$1')).toMatchObject([
|
||||
expect(extractLabel("A$1")).toMatchObject([
|
||||
{
|
||||
index: 0,
|
||||
label: '1',
|
||||
label: "1",
|
||||
isAbsolute: true,
|
||||
},
|
||||
{
|
||||
index: 0,
|
||||
label: 'A',
|
||||
label: "A",
|
||||
isAbsolute: false,
|
||||
},
|
||||
]);
|
||||
expect(extractLabel('a$1')).toMatchObject([
|
||||
expect(extractLabel("a$1")).toMatchObject([
|
||||
{
|
||||
index: 0,
|
||||
label: '1',
|
||||
label: "1",
|
||||
isAbsolute: true,
|
||||
},
|
||||
{
|
||||
index: 0,
|
||||
label: 'A',
|
||||
label: "A",
|
||||
isAbsolute: false,
|
||||
},
|
||||
]);
|
||||
expect(extractLabel('$A1')).toMatchObject([
|
||||
expect(extractLabel("$A1")).toMatchObject([
|
||||
{
|
||||
index: 0,
|
||||
label: '1',
|
||||
label: "1",
|
||||
isAbsolute: false,
|
||||
},
|
||||
{
|
||||
index: 0,
|
||||
label: 'A',
|
||||
label: "A",
|
||||
isAbsolute: true,
|
||||
},
|
||||
]);
|
||||
expect(extractLabel('$A$1')).toMatchObject([
|
||||
expect(extractLabel("$A$1")).toMatchObject([
|
||||
{
|
||||
index: 0,
|
||||
label: '1',
|
||||
label: "1",
|
||||
isAbsolute: true,
|
||||
},
|
||||
{
|
||||
index: 0,
|
||||
label: 'A',
|
||||
label: "A",
|
||||
isAbsolute: true,
|
||||
},
|
||||
]);
|
||||
expect(extractLabel('$AG199')).toMatchObject([
|
||||
expect(extractLabel("$AG199")).toMatchObject([
|
||||
{
|
||||
index: 198,
|
||||
label: '199',
|
||||
label: "199",
|
||||
isAbsolute: false,
|
||||
},
|
||||
{
|
||||
index: 32,
|
||||
label: 'AG',
|
||||
label: "AG",
|
||||
isAbsolute: true,
|
||||
},
|
||||
]);
|
||||
expect(extractLabel('$Ag199')).toMatchObject([
|
||||
expect(extractLabel("$Ag199")).toMatchObject([
|
||||
{
|
||||
index: 198,
|
||||
label: '199',
|
||||
label: "199",
|
||||
isAbsolute: false,
|
||||
},
|
||||
{
|
||||
index: 32,
|
||||
label: 'AG',
|
||||
label: "AG",
|
||||
isAbsolute: true,
|
||||
},
|
||||
]);
|
||||
expect(extractLabel('$$AG199')).toMatchObject([]);
|
||||
expect(extractLabel('AG$$199')).toMatchObject([]);
|
||||
expect(extractLabel("$$AG199")).toMatchObject([]);
|
||||
expect(extractLabel("AG$$199")).toMatchObject([]);
|
||||
expect(extractLabel(null)).toMatchObject([]);
|
||||
expect(extractLabel(void 0)).toMatchObject([]);
|
||||
expect(extractLabel(0)).toMatchObject([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.toLabel()', () => {
|
||||
it('should correctly convert coords to label ', () => {
|
||||
expect(toLabel({index: 0, isAbsolute: false}, {index: 0, isAbsolute: false})).toBe('A1');
|
||||
expect(toLabel({index: 0, isAbsolute: true}, {index: 0, isAbsolute: false})).toBe('A$1');
|
||||
expect(toLabel({index: 0, isAbsolute: true}, {index: 0, isAbsolute: true})).toBe('$A$1');
|
||||
expect(toLabel({index: 44, isAbsolute: true}, {index: 20, isAbsolute: true})).toBe('$U$45');
|
||||
expect(toLabel({index: 1, isAbsolute: false}, {index: 20, isAbsolute: true})).toBe('$U2');
|
||||
describe(".toLabel()", () => {
|
||||
it("should correctly convert coords to label ", () => {
|
||||
expect(
|
||||
toLabel({ index: 0, isAbsolute: false }, { index: 0, isAbsolute: false })
|
||||
).toBe("A1");
|
||||
expect(
|
||||
toLabel({ index: 0, isAbsolute: true }, { index: 0, isAbsolute: false })
|
||||
).toBe("A$1");
|
||||
expect(
|
||||
toLabel({ index: 0, isAbsolute: true }, { index: 0, isAbsolute: true })
|
||||
).toBe("$A$1");
|
||||
expect(
|
||||
toLabel({ index: 44, isAbsolute: true }, { index: 20, isAbsolute: true })
|
||||
).toBe("$U$45");
|
||||
expect(
|
||||
toLabel({ index: 1, isAbsolute: false }, { index: 20, isAbsolute: true })
|
||||
).toBe("$U2");
|
||||
});
|
||||
});
|
||||
|
||||
describe('.columnIndexToLabel()', () => {
|
||||
it('should correctly convert column index to label ', () => {
|
||||
expect(columnIndexToLabel(-100)).toBe('');
|
||||
expect(columnIndexToLabel(-1)).toBe('');
|
||||
expect(columnIndexToLabel(0)).toBe('A');
|
||||
expect(columnIndexToLabel(1)).toBe('B');
|
||||
expect(columnIndexToLabel(10)).toBe('K');
|
||||
expect(columnIndexToLabel(100)).toBe('CW');
|
||||
expect(columnIndexToLabel(1000)).toBe('ALM');
|
||||
expect(columnIndexToLabel(10000)).toBe('NTQ');
|
||||
describe(".columnIndexToLabel()", () => {
|
||||
it("should correctly convert column index to label ", () => {
|
||||
expect(columnIndexToLabel(-100)).toBe("");
|
||||
expect(columnIndexToLabel(-1)).toBe("");
|
||||
expect(columnIndexToLabel(0)).toBe("A");
|
||||
expect(columnIndexToLabel(1)).toBe("B");
|
||||
expect(columnIndexToLabel(10)).toBe("K");
|
||||
expect(columnIndexToLabel(100)).toBe("CW");
|
||||
expect(columnIndexToLabel(1000)).toBe("ALM");
|
||||
expect(columnIndexToLabel(10000)).toBe("NTQ");
|
||||
});
|
||||
});
|
||||
|
||||
describe('.columnLabelToIndex()', () => {
|
||||
it('should correctly convert column label to index', () => {
|
||||
expect(columnLabelToIndex('')).toBe(-1);
|
||||
expect(columnLabelToIndex('')).toBe(-1);
|
||||
expect(columnLabelToIndex('A')).toBe(0);
|
||||
expect(columnLabelToIndex('B')).toBe(1);
|
||||
expect(columnLabelToIndex('K')).toBe(10);
|
||||
expect(columnLabelToIndex('k')).toBe(10);
|
||||
expect(columnLabelToIndex('CW')).toBe(100);
|
||||
expect(columnLabelToIndex('ALM')).toBe(1000);
|
||||
expect(columnLabelToIndex('aLM')).toBe(1000);
|
||||
expect(columnLabelToIndex('NTQ')).toBe(10000);
|
||||
describe(".columnLabelToIndex()", () => {
|
||||
it("should correctly convert column label to index", () => {
|
||||
expect(columnLabelToIndex("")).toBe(-1);
|
||||
expect(columnLabelToIndex("")).toBe(-1);
|
||||
expect(columnLabelToIndex("A")).toBe(0);
|
||||
expect(columnLabelToIndex("B")).toBe(1);
|
||||
expect(columnLabelToIndex("K")).toBe(10);
|
||||
expect(columnLabelToIndex("k")).toBe(10);
|
||||
expect(columnLabelToIndex("CW")).toBe(100);
|
||||
expect(columnLabelToIndex("ALM")).toBe(1000);
|
||||
expect(columnLabelToIndex("aLM")).toBe(1000);
|
||||
expect(columnLabelToIndex("NTQ")).toBe(10000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.rowIndexToLabel()', () => {
|
||||
it('should correctly convert row index to label ', () => {
|
||||
expect(rowIndexToLabel(-100)).toBe('');
|
||||
expect(rowIndexToLabel(-1)).toBe('');
|
||||
expect(rowIndexToLabel(0)).toBe('1');
|
||||
expect(rowIndexToLabel(1)).toBe('2');
|
||||
expect(rowIndexToLabel(10)).toBe('11');
|
||||
expect(rowIndexToLabel(100)).toBe('101');
|
||||
describe(".rowIndexToLabel()", () => {
|
||||
it("should correctly convert row index to label ", () => {
|
||||
expect(rowIndexToLabel(-100)).toBe("");
|
||||
expect(rowIndexToLabel(-1)).toBe("");
|
||||
expect(rowIndexToLabel(0)).toBe("1");
|
||||
expect(rowIndexToLabel(1)).toBe("2");
|
||||
expect(rowIndexToLabel(10)).toBe("11");
|
||||
expect(rowIndexToLabel(100)).toBe("101");
|
||||
});
|
||||
});
|
||||
|
||||
describe('.rowLabelToIndex()', () => {
|
||||
it('should correctly convert row label to index', () => {
|
||||
expect(rowLabelToIndex('')).toBe(-1);
|
||||
expect(rowLabelToIndex('0')).toBe(-1);
|
||||
expect(rowLabelToIndex('1')).toBe(0);
|
||||
expect(rowLabelToIndex('2')).toBe(1);
|
||||
expect(rowLabelToIndex('100')).toBe(99);
|
||||
expect(rowLabelToIndex('92')).toBe(91);
|
||||
describe(".rowLabelToIndex()", () => {
|
||||
it("should correctly convert row label to index", () => {
|
||||
expect(rowLabelToIndex("")).toBe(-1);
|
||||
expect(rowLabelToIndex("0")).toBe(-1);
|
||||
expect(rowLabelToIndex("1")).toBe(0);
|
||||
expect(rowLabelToIndex("2")).toBe(1);
|
||||
expect(rowLabelToIndex("100")).toBe(99);
|
||||
expect(rowLabelToIndex("92")).toBe(91);
|
||||
});
|
||||
});
|
||||
|
@ -1,31 +1,31 @@
|
||||
import {toNumber, invertNumber} from '../../../src/helper/number';
|
||||
import { toNumber, invertNumber } from "../../../src/helper/number";
|
||||
|
||||
describe('.toNumber()', () => {
|
||||
it('should correctly convert passed value into number', () => {
|
||||
describe(".toNumber()", () => {
|
||||
it("should correctly convert passed value into number", () => {
|
||||
expect(toNumber(-100)).toBe(-100);
|
||||
expect(toNumber(-1)).toBe(-1);
|
||||
expect(toNumber(19)).toBe(19);
|
||||
expect(toNumber(19.9)).toBe(19.9);
|
||||
expect(toNumber(0.9)).toBe(0.9);
|
||||
expect(toNumber('0.9')).toBe(0.9);
|
||||
expect(toNumber('0')).toBe(0);
|
||||
expect(toNumber('-10')).toBe(-10);
|
||||
expect(toNumber(' -10 ')).toBe(-10);
|
||||
expect(isNaN(toNumber('foo'))).toBe(true);
|
||||
expect(toNumber("0.9")).toBe(0.9);
|
||||
expect(toNumber("0")).toBe(0);
|
||||
expect(toNumber("-10")).toBe(-10);
|
||||
expect(toNumber(" -10 ")).toBe(-10);
|
||||
expect(isNaN(toNumber("foo"))).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.invertNumber()', () => {
|
||||
it('should correctly invert number', () => {
|
||||
describe(".invertNumber()", () => {
|
||||
it("should correctly invert number", () => {
|
||||
expect(invertNumber(-100)).toBe(100);
|
||||
expect(invertNumber(-1)).toBe(1);
|
||||
expect(invertNumber(19)).toBe(-19);
|
||||
expect(invertNumber(19.9)).toBe(-19.9);
|
||||
expect(invertNumber(0.9)).toBe(-0.9);
|
||||
expect(invertNumber('0.9')).toBe(-0.9);
|
||||
expect(invertNumber('0')).toBe(-0);
|
||||
expect(invertNumber('-10')).toBe(10);
|
||||
expect(invertNumber(' -10 ')).toBe(10);
|
||||
expect(isNaN(invertNumber('foo'))).toBe(true);
|
||||
expect(invertNumber("0.9")).toBe(-0.9);
|
||||
expect(invertNumber("0")).toBe(-0);
|
||||
expect(invertNumber("-10")).toBe(10);
|
||||
expect(invertNumber(" -10 ")).toBe(10);
|
||||
expect(isNaN(invertNumber("foo"))).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {trimEdges} from '../../../src/helper/string';
|
||||
import { trimEdges } from "../../../src/helper/string";
|
||||
|
||||
describe('.trimEdges()', () => {
|
||||
it('should correctly trim edges', () => {
|
||||
expect(trimEdges('hello')).toBe('ell');
|
||||
expect(trimEdges('hello', 1)).toBe('ell');
|
||||
expect(trimEdges('hello', 2)).toBe('l');
|
||||
describe(".trimEdges()", () => {
|
||||
it("should correctly trim edges", () => {
|
||||
expect(trimEdges("hello")).toBe("ell");
|
||||
expect(trimEdges("hello", 1)).toBe("ell");
|
||||
expect(trimEdges("hello", 2)).toBe("l");
|
||||
});
|
||||
});
|
||||
|
@ -1,71 +1,71 @@
|
||||
import * as lib from '../../src/index';
|
||||
import * as lib from "../../src/index";
|
||||
|
||||
describe('Public API', () => {
|
||||
it('Parser should be defined', () => {
|
||||
describe("Public API", () => {
|
||||
it("Parser should be defined", () => {
|
||||
expect(lib.Parser).toBeInstanceOf(Function);
|
||||
});
|
||||
|
||||
it('SUPPORTED_FORMULAS should be defined', () => {
|
||||
it("SUPPORTED_FORMULAS should be defined", () => {
|
||||
expect(lib.SUPPORTED_FORMULAS).toBeInstanceOf(Array);
|
||||
});
|
||||
|
||||
it('ERROR should be defined', () => {
|
||||
it("ERROR should be defined", () => {
|
||||
expect(lib.ERROR).toBeDefined();
|
||||
});
|
||||
|
||||
it('ERROR_DIV_ZERO should be defined', () => {
|
||||
it("ERROR_DIV_ZERO should be defined", () => {
|
||||
expect(lib.ERROR_DIV_ZERO).toBeDefined();
|
||||
});
|
||||
|
||||
it('ERROR_NAME should be defined', () => {
|
||||
it("ERROR_NAME should be defined", () => {
|
||||
expect(lib.ERROR_NAME).toBeDefined();
|
||||
});
|
||||
|
||||
it('ERROR_NOT_AVAILABLE should be defined', () => {
|
||||
it("ERROR_NOT_AVAILABLE should be defined", () => {
|
||||
expect(lib.ERROR_NOT_AVAILABLE).toBeDefined();
|
||||
});
|
||||
|
||||
it('ERROR_NULL should be defined', () => {
|
||||
it("ERROR_NULL should be defined", () => {
|
||||
expect(lib.ERROR_NULL).toBeDefined();
|
||||
});
|
||||
|
||||
it('ERROR_NUM should be defined', () => {
|
||||
it("ERROR_NUM should be defined", () => {
|
||||
expect(lib.ERROR_NUM).toBeDefined();
|
||||
});
|
||||
|
||||
it('ERROR_REF should be defined', () => {
|
||||
it("ERROR_REF should be defined", () => {
|
||||
expect(lib.ERROR_REF).toBeDefined();
|
||||
});
|
||||
|
||||
it('ERROR_VALUE should be defined', () => {
|
||||
it("ERROR_VALUE should be defined", () => {
|
||||
expect(lib.ERROR_VALUE).toBeDefined();
|
||||
});
|
||||
|
||||
it('error should be defined', () => {
|
||||
it("error should be defined", () => {
|
||||
expect(lib.error).toBeDefined();
|
||||
});
|
||||
|
||||
it('extractLabel should be defined', () => {
|
||||
it("extractLabel should be defined", () => {
|
||||
expect(lib.extractLabel).toBeDefined();
|
||||
});
|
||||
|
||||
it('toLabel should be defined', () => {
|
||||
it("toLabel should be defined", () => {
|
||||
expect(lib.toLabel).toBeDefined();
|
||||
});
|
||||
|
||||
it('columnIndexToLabel should be defined', () => {
|
||||
it("columnIndexToLabel should be defined", () => {
|
||||
expect(lib.columnIndexToLabel).toBeDefined();
|
||||
});
|
||||
|
||||
it('columnLabelToIndex should be defined', () => {
|
||||
it("columnLabelToIndex should be defined", () => {
|
||||
expect(lib.columnLabelToIndex).toBeDefined();
|
||||
});
|
||||
|
||||
it('rowIndexToLabel should be defined', () => {
|
||||
it("rowIndexToLabel should be defined", () => {
|
||||
expect(lib.rowIndexToLabel).toBeDefined();
|
||||
});
|
||||
|
||||
it('rowLabelToIndex should be defined', () => {
|
||||
it("rowLabelToIndex should be defined", () => {
|
||||
expect(lib.rowLabelToIndex).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Parser from '../../src/parser';
|
||||
import Parser from "../../src/parser";
|
||||
|
||||
describe('Parser', () => {
|
||||
describe("Parser", () => {
|
||||
let parser;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -10,330 +10,409 @@ describe('Parser', () => {
|
||||
parser = null;
|
||||
});
|
||||
|
||||
describe('.parse()', () => {
|
||||
it('should be defined', () => {
|
||||
describe(".parse()", () => {
|
||||
it("should be defined", () => {
|
||||
expect(parser.parse).toBeInstanceOf(Function);
|
||||
});
|
||||
|
||||
it('should not internally call `parse` method of grammar parser object when an empty string was passed', () => {
|
||||
it("should not internally call `parse` method of grammar parser object when an empty string was passed", () => {
|
||||
parser.parser.parse = jest.fn();
|
||||
|
||||
parser.parse('');
|
||||
parser.parse("");
|
||||
|
||||
expect(parser.parser.parse).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should return `#ERROR!` when parser throws unknown exception', () => {
|
||||
it("should return `#ERROR!` when parser throws unknown exception", () => {
|
||||
parser.parser.parse = jest.fn(() => {
|
||||
throw Error('some error');
|
||||
throw Error("some error");
|
||||
});
|
||||
|
||||
expect(parser.parse('foo')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse("foo")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return `#ERROR!` when parser throws `#ERROR!` exception', () => {
|
||||
it("should return `#ERROR!` when parser throws `#ERROR!` exception", () => {
|
||||
parser.parser.parse = jest.fn(() => {
|
||||
throw Error('#ERROR!');
|
||||
throw Error("#ERROR!");
|
||||
});
|
||||
|
||||
expect(parser.parse('foo')).toMatchObject({error: '#ERROR!', result: null});
|
||||
expect(parser.parse("foo")).toMatchObject({
|
||||
error: "#ERROR!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return `#DIV/0!` when parser throws `#DIV/0!` exception', () => {
|
||||
it("should return `#DIV/0!` when parser throws `#DIV/0!` exception", () => {
|
||||
parser.parser.parse = jest.fn(() => {
|
||||
throw Error('#DIV/0!');
|
||||
throw Error("#DIV/0!");
|
||||
});
|
||||
|
||||
expect(parser.parse('foo')).toMatchObject({error: '#DIV/0!', result: null});
|
||||
expect(parser.parse("foo")).toMatchObject({
|
||||
error: "#DIV/0!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return `#NAME?` when parser throws `#NAME?` exception', () => {
|
||||
it("should return `#NAME?` when parser throws `#NAME?` exception", () => {
|
||||
parser.parser.parse = jest.fn(() => {
|
||||
throw Error('#NAME?');
|
||||
throw Error("#NAME?");
|
||||
});
|
||||
|
||||
expect(parser.parse('foo')).toMatchObject({error: '#NAME?', result: null});
|
||||
expect(parser.parse("foo")).toMatchObject({
|
||||
error: "#NAME?",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return `#N/A` when parser throws `#N/A` exception', () => {
|
||||
it("should return `#N/A` when parser throws `#N/A` exception", () => {
|
||||
parser.parser.parse = jest.fn(() => {
|
||||
throw Error('#N/A');
|
||||
throw Error("#N/A");
|
||||
});
|
||||
|
||||
expect(parser.parse('foo')).toMatchObject({error: '#N/A', result: null});
|
||||
expect(parser.parse("foo")).toMatchObject({
|
||||
error: "#N/A",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return `#NULL!` when parser throws `#NULL!` exception', () => {
|
||||
it("should return `#NULL!` when parser throws `#NULL!` exception", () => {
|
||||
parser.parser.parse = jest.fn(() => {
|
||||
throw Error('#NULL!');
|
||||
throw Error("#NULL!");
|
||||
});
|
||||
|
||||
expect(parser.parse('foo')).toMatchObject({error: '#NULL!', result: null});
|
||||
expect(parser.parse("foo")).toMatchObject({
|
||||
error: "#NULL!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return `#NUM!` when parser throws `#NUM!` exception', () => {
|
||||
it("should return `#NUM!` when parser throws `#NUM!` exception", () => {
|
||||
parser.parser.parse = jest.fn(() => {
|
||||
throw Error('#NUM!');
|
||||
throw Error("#NUM!");
|
||||
});
|
||||
|
||||
expect(parser.parse('foo')).toMatchObject({error: '#NUM!', result: null});
|
||||
expect(parser.parse("foo")).toMatchObject({
|
||||
error: "#NUM!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return `#REF!` when parser throws `#REF!` exception', () => {
|
||||
it("should return `#REF!` when parser throws `#REF!` exception", () => {
|
||||
parser.parser.parse = jest.fn(() => {
|
||||
throw Error('#REF!');
|
||||
throw Error("#REF!");
|
||||
});
|
||||
|
||||
expect(parser.parse('foo')).toMatchObject({error: '#REF!', result: null});
|
||||
expect(parser.parse("foo")).toMatchObject({
|
||||
error: "#REF!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return `#VALUE!` when parser throws `#VALUE!` exception', () => {
|
||||
it("should return `#VALUE!` when parser throws `#VALUE!` exception", () => {
|
||||
parser.parser.parse = jest.fn(() => {
|
||||
throw Error('#VALUE!');
|
||||
throw Error("#VALUE!");
|
||||
});
|
||||
|
||||
expect(parser.parse('foo')).toMatchObject({error: '#VALUE!', result: null});
|
||||
expect(parser.parse("foo")).toMatchObject({
|
||||
error: "#VALUE!",
|
||||
result: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('should not return `#ERROR!` when parser evaluate expression as `ERROR`', () => {
|
||||
parser.parser.parse = jest.fn(() => 'ERROR');
|
||||
it("should not return `#ERROR!` when parser evaluate expression as `ERROR`", () => {
|
||||
parser.parser.parse = jest.fn(() => "ERROR");
|
||||
|
||||
expect(parser.parse('foo')).toMatchObject({error: null, result: 'ERROR'});
|
||||
expect(parser.parse("foo")).toMatchObject({
|
||||
error: null,
|
||||
result: "ERROR",
|
||||
});
|
||||
});
|
||||
|
||||
it('should not return `#ERROR!` when parser evaluate expression as `#ERROR!`', () => {
|
||||
parser.parser.parse = jest.fn(() => '#ERROR!');
|
||||
it("should not return `#ERROR!` when parser evaluate expression as `#ERROR!`", () => {
|
||||
parser.parser.parse = jest.fn(() => "#ERROR!");
|
||||
|
||||
expect(parser.parse('foo')).toMatchObject({error: null, result: '#ERROR!'});
|
||||
expect(parser.parse("foo")).toMatchObject({
|
||||
error: null,
|
||||
result: "#ERROR!",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('.setVariable()/.getVariable()', () => {
|
||||
it('should return default variables', () => {
|
||||
expect(parser.getVariable('TRUE')).toBe(true);
|
||||
expect(parser.getVariable('FALSE')).toBe(false);
|
||||
expect(parser.getVariable('NULL')).toBe(null);
|
||||
expect(parser.getVariable('foo')).not.toBeDefined();
|
||||
describe(".setVariable()/.getVariable()", () => {
|
||||
it("should return default variables", () => {
|
||||
expect(parser.getVariable("TRUE")).toBe(true);
|
||||
expect(parser.getVariable("FALSE")).toBe(false);
|
||||
expect(parser.getVariable("NULL")).toBe(null);
|
||||
expect(parser.getVariable("foo")).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('should return custom variables', () => {
|
||||
parser.setVariable('foo', 1234);
|
||||
parser.setVariable('bar', '1234');
|
||||
parser.setVariable('baz', [1, 2]);
|
||||
it("should return custom variables", () => {
|
||||
parser.setVariable("foo", 1234);
|
||||
parser.setVariable("bar", "1234");
|
||||
parser.setVariable("baz", [1, 2]);
|
||||
|
||||
expect(parser.getVariable('foo')).toBe(1234);
|
||||
expect(parser.getVariable('bar')).toBe('1234');
|
||||
expect(parser.getVariable('baz')).toMatchObject([1, 2]);
|
||||
expect(parser.getVariable("foo")).toBe(1234);
|
||||
expect(parser.getVariable("bar")).toBe("1234");
|
||||
expect(parser.getVariable("baz")).toMatchObject([1, 2]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.setFunction()/.getFunction()', () => {
|
||||
it('should return custom functions', () => {
|
||||
parser.setFunction('foo', () => 1234);
|
||||
parser.setFunction('bar', (params) => params[0] + params[1]);
|
||||
describe(".setFunction()/.getFunction()", () => {
|
||||
it("should return custom functions", () => {
|
||||
parser.setFunction("foo", () => 1234);
|
||||
parser.setFunction("bar", (params) => params[0] + params[1]);
|
||||
|
||||
expect(parser.getFunction('foo')()).toBe(1234);
|
||||
expect(parser.getFunction('bar')([1, 2])).toBe(3);
|
||||
expect(parser.getFunction("foo")()).toBe(1234);
|
||||
expect(parser.getFunction("bar")([1, 2])).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('._callVariable()', () => {
|
||||
it('should return error (NAME) when variable not set', () => {
|
||||
describe("._callVariable()", () => {
|
||||
it("should return error (NAME) when variable not set", () => {
|
||||
parser.getVariable = jest.fn(() => void 0);
|
||||
|
||||
expect(parser._callVariable.bind(parser)).toThrow(/NAME/);
|
||||
});
|
||||
|
||||
it('should return variable when it was set', () => {
|
||||
parser.getVariable = jest.fn((name) => (name === 'bar' ? 'foo' : 'baz'));
|
||||
it("should return variable when it was set", () => {
|
||||
parser.getVariable = jest.fn((name) => (name === "bar" ? "foo" : "baz"));
|
||||
|
||||
expect(parser._callVariable('bar')).toBe('foo');
|
||||
expect(parser._callVariable('barrr')).toBe('baz');
|
||||
expect(parser._callVariable("bar")).toBe("foo");
|
||||
expect(parser._callVariable("barrr")).toBe("baz");
|
||||
});
|
||||
|
||||
it('should return variable set by event emitter', () => {
|
||||
parser.getVariable = jest.fn(() => 'baz');
|
||||
it("should return variable set by event emitter", () => {
|
||||
parser.getVariable = jest.fn(() => "baz");
|
||||
|
||||
parser.on('callVariable', (name, done) => {
|
||||
done(name === 'bar' ? 'foo' : void 0);
|
||||
parser.on("callVariable", (name, done) => {
|
||||
done(name === "bar" ? "foo" : void 0);
|
||||
});
|
||||
|
||||
expect(parser._callVariable('bar')).toBe('foo');
|
||||
expect(parser._callVariable('barrr')).toBe('baz');
|
||||
expect(parser._callVariable("bar")).toBe("foo");
|
||||
expect(parser._callVariable("barrr")).toBe("baz");
|
||||
});
|
||||
});
|
||||
|
||||
describe('._callFunction()', () => {
|
||||
it('should return error (NAME) when function not set', () => {
|
||||
expect(() => parser._callFunction('NOT_DEFINED()')).toThrow(/NAME/);
|
||||
describe("._callFunction()", () => {
|
||||
it("should return error (NAME) when function not set", () => {
|
||||
expect(() => parser._callFunction("NOT_DEFINED()")).toThrow(/NAME/);
|
||||
});
|
||||
|
||||
it('should call predefined function', () => {
|
||||
it("should call predefined function", () => {
|
||||
parser.getFunction = jest.fn(() => void 0);
|
||||
|
||||
expect(parser._callFunction('SUM', [1, 2])).toBe(3);
|
||||
expect(parser._callFunction("SUM", [1, 2])).toBe(3);
|
||||
});
|
||||
|
||||
it('should call custom funciton when it was set', () => {
|
||||
it("should call custom funciton when it was set", () => {
|
||||
parser.getFunction = jest.fn(() => (params) => params[0] + 1);
|
||||
|
||||
expect(parser._callFunction('ADD_1', [2])).toBe(3);
|
||||
expect(parser._callFunction("ADD_1", [2])).toBe(3);
|
||||
});
|
||||
|
||||
it('should return variable set by event emitter', () => {
|
||||
it("should return variable set by event emitter", () => {
|
||||
parser.getFunction = jest.fn(() => (params) => params[0] + 1);
|
||||
|
||||
parser.on('callFunction', (name, params, done) => {
|
||||
done(name === 'OVERRIDDEN' ? params[0] + 2 : void 0);
|
||||
parser.on("callFunction", (name, params, done) => {
|
||||
done(name === "OVERRIDDEN" ? params[0] + 2 : void 0);
|
||||
});
|
||||
|
||||
expect(parser._callFunction('ADD_1', [2])).toBe(3);
|
||||
expect(parser._callFunction('OVERRIDDEN', [2])).toBe(4);
|
||||
expect(parser._callFunction("ADD_1", [2])).toBe(3);
|
||||
expect(parser._callFunction("OVERRIDDEN", [2])).toBe(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('._callCellValue()', () => {
|
||||
it('should return undefined if under specified coordinates data value not exist', () => {
|
||||
expect(parser._callCellValue('A1')).not.toBeDefined();
|
||||
describe("._callCellValue()", () => {
|
||||
it("should return undefined if under specified coordinates data value not exist", () => {
|
||||
expect(parser._callCellValue("A1")).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('should return value under specified coordinates', () => {
|
||||
parser.on('callCellValue', (cell, done) => {
|
||||
const {row, column} = cell;
|
||||
it("should return value under specified coordinates", () => {
|
||||
parser.on("callCellValue", (cell, done) => {
|
||||
const { row, column } = cell;
|
||||
let value;
|
||||
|
||||
if (row.index === 0 && column.index === 2) {
|
||||
value = '4';
|
||||
value = "4";
|
||||
} else if (row.index === 0 && column.index === 7) {
|
||||
value = 45;
|
||||
} else if (row.index === 2 && column.index === 7) {
|
||||
value = [1, 2, 3];
|
||||
} else if (row.index === 3 && column.index === 7 && column.isAbsolute) {
|
||||
value = true;
|
||||
} else if (row.index === 4 && row.isAbsolute && column.index === 7 && column.isAbsolute) {
|
||||
} else if (
|
||||
row.index === 4 &&
|
||||
row.isAbsolute &&
|
||||
column.index === 7 &&
|
||||
column.isAbsolute
|
||||
) {
|
||||
value = 0.9;
|
||||
}
|
||||
|
||||
done(value);
|
||||
});
|
||||
|
||||
expect(parser._callCellValue('A1')).toBe(void 0);
|
||||
expect(parser._callCellValue('C1')).toBe('4');
|
||||
expect(parser._callCellValue('H1')).toBe(45);
|
||||
expect(parser._callCellValue('H3')).toMatchObject([1, 2, 3]);
|
||||
expect(parser._callCellValue('$H4')).toBe(true);
|
||||
expect(parser._callCellValue('$H$5')).toBe(0.9);
|
||||
expect(parser._callCellValue("A1")).toBe(void 0);
|
||||
expect(parser._callCellValue("C1")).toBe("4");
|
||||
expect(parser._callCellValue("H1")).toBe(45);
|
||||
expect(parser._callCellValue("H3")).toMatchObject([1, 2, 3]);
|
||||
expect(parser._callCellValue("$H4")).toBe(true);
|
||||
expect(parser._callCellValue("$H$5")).toBe(0.9);
|
||||
});
|
||||
});
|
||||
|
||||
describe('._callRangeValue()', () => {
|
||||
it('should return an empty array if under specified coordinates data value not exist', () => {
|
||||
expect(parser._callRangeValue('A1', 'B2')).toMatchObject([]);
|
||||
describe("._callRangeValue()", () => {
|
||||
it("should return an empty array if under specified coordinates data value not exist", () => {
|
||||
expect(parser._callRangeValue("A1", "B2")).toMatchObject([]);
|
||||
});
|
||||
|
||||
it('should return value under specified coordinates', () => {
|
||||
parser.on('callRangeValue', (firstCell, lastCell, done) => {
|
||||
const {row: row1, column: column1} = firstCell;
|
||||
const {row: row2, column: column2} = lastCell;
|
||||
it("should return value under specified coordinates", () => {
|
||||
parser.on("callRangeValue", (firstCell, lastCell, done) => {
|
||||
const { row: row1, column: column1 } = firstCell;
|
||||
const { row: row2, column: column2 } = lastCell;
|
||||
let value;
|
||||
|
||||
if (row1.index === 0 && column1.index === 2 && row2.index === 3 && column2.index === 3) {
|
||||
value = [[1, 2], [4, 5]];
|
||||
} else if (row1.index === 0 && row1.isAbsolute && column1.index === 0 &&
|
||||
row2.index === 3 && column2.index === 3 && column2.isAbsolute) {
|
||||
value = [['a', 'b'], ['z', 'd']];
|
||||
} else if (row1.index === 0 && row1.isAbsolute && column1.index === 0 && column1.isAbsolute &&
|
||||
row2.index === 4 && row2.isAbsolute && column2.index === 4 && column2.isAbsolute) {
|
||||
value = [[true, false], [true, true]];
|
||||
|
||||
} else if (row1.index === 4 && row1.isAbsolute && column1.index === 7 && column1.isAbsolute) {
|
||||
if (
|
||||
row1.index === 0 &&
|
||||
column1.index === 2 &&
|
||||
row2.index === 3 &&
|
||||
column2.index === 3
|
||||
) {
|
||||
value = [
|
||||
[1, 2],
|
||||
[4, 5],
|
||||
];
|
||||
} else if (
|
||||
row1.index === 0 &&
|
||||
row1.isAbsolute &&
|
||||
column1.index === 0 &&
|
||||
row2.index === 3 &&
|
||||
column2.index === 3 &&
|
||||
column2.isAbsolute
|
||||
) {
|
||||
value = [
|
||||
["a", "b"],
|
||||
["z", "d"],
|
||||
];
|
||||
} else if (
|
||||
row1.index === 0 &&
|
||||
row1.isAbsolute &&
|
||||
column1.index === 0 &&
|
||||
column1.isAbsolute &&
|
||||
row2.index === 4 &&
|
||||
row2.isAbsolute &&
|
||||
column2.index === 4 &&
|
||||
column2.isAbsolute
|
||||
) {
|
||||
value = [
|
||||
[true, false],
|
||||
[true, true],
|
||||
];
|
||||
} else if (
|
||||
row1.index === 4 &&
|
||||
row1.isAbsolute &&
|
||||
column1.index === 7 &&
|
||||
column1.isAbsolute
|
||||
) {
|
||||
value = 0.9;
|
||||
}
|
||||
|
||||
done(value);
|
||||
});
|
||||
|
||||
expect(parser._callRangeValue('C1', 'D4')).toMatchObject([[1, 2], [4, 5]]);
|
||||
expect(parser._callRangeValue('A$1', '$D4')).toMatchObject([['a', 'b'], ['z', 'd']]);
|
||||
expect(parser._callRangeValue('$A$1', '$E$5')).toMatchObject([[true, false], [true, true]]);
|
||||
expect(parser._callRangeValue("C1", "D4")).toMatchObject([
|
||||
[1, 2],
|
||||
[4, 5],
|
||||
]);
|
||||
expect(parser._callRangeValue("A$1", "$D4")).toMatchObject([
|
||||
["a", "b"],
|
||||
["z", "d"],
|
||||
]);
|
||||
expect(parser._callRangeValue("$A$1", "$E$5")).toMatchObject([
|
||||
[true, false],
|
||||
[true, true],
|
||||
]);
|
||||
});
|
||||
|
||||
it('should convert coordinates in top-left bottom-right format (from bottom-left to top-right)', () => {
|
||||
it("should convert coordinates in top-left bottom-right format (from bottom-left to top-right)", () => {
|
||||
const cb = jest.fn();
|
||||
|
||||
parser.on('callRangeValue', cb);
|
||||
parser._callRangeValue('$A$9', 'B2');
|
||||
parser.on("callRangeValue", cb);
|
||||
parser._callRangeValue("$A$9", "B2");
|
||||
|
||||
const startCell = {
|
||||
row: {index: 1, isAbsolute: false, label: '2'},
|
||||
column: {index: 0, isAbsolute: true, label: 'A'},
|
||||
label: '$A2',
|
||||
row: { index: 1, isAbsolute: false, label: "2" },
|
||||
column: { index: 0, isAbsolute: true, label: "A" },
|
||||
label: "$A2",
|
||||
};
|
||||
const endCell = {
|
||||
row: {index: 8, isAbsolute: true, label: '9'},
|
||||
column: {index: 1, isAbsolute: false, label: 'B'},
|
||||
label: 'B$9',
|
||||
row: { index: 8, isAbsolute: true, label: "9" },
|
||||
column: { index: 1, isAbsolute: false, label: "B" },
|
||||
label: "B$9",
|
||||
};
|
||||
|
||||
expect(cb).toHaveBeenCalledWith(startCell, endCell, expect.anything());
|
||||
});
|
||||
|
||||
it('should convert coordinates in top-left bottom-right format (from top-right to bottom-left)', () => {
|
||||
it("should convert coordinates in top-left bottom-right format (from top-right to bottom-left)", () => {
|
||||
const cb = jest.fn();
|
||||
|
||||
parser.on('callRangeValue', cb);
|
||||
parser._callRangeValue('B$2', 'A$8');
|
||||
parser.on("callRangeValue", cb);
|
||||
parser._callRangeValue("B$2", "A$8");
|
||||
|
||||
const startCell = {
|
||||
row: {index: 1, isAbsolute: true, label: '2'},
|
||||
column: {index: 0, isAbsolute: false, label: 'A'},
|
||||
label: 'A$2',
|
||||
row: { index: 1, isAbsolute: true, label: "2" },
|
||||
column: { index: 0, isAbsolute: false, label: "A" },
|
||||
label: "A$2",
|
||||
};
|
||||
const endCell = {
|
||||
row: {index: 7, isAbsolute: true, label: '8'},
|
||||
column: {index: 1, isAbsolute: false, label: 'B'},
|
||||
label: 'B$8',
|
||||
row: { index: 7, isAbsolute: true, label: "8" },
|
||||
column: { index: 1, isAbsolute: false, label: "B" },
|
||||
label: "B$8",
|
||||
};
|
||||
|
||||
expect(cb).toHaveBeenCalledWith(startCell, endCell, expect.anything());
|
||||
});
|
||||
});
|
||||
|
||||
describe('._throwError()', () => {
|
||||
it('should throw general error', () => {
|
||||
expect(() => parser._throwError('#ERROR!')).toThrow('ERROR');
|
||||
describe("._throwError()", () => {
|
||||
it("should throw general error", () => {
|
||||
expect(() => parser._throwError("#ERROR!")).toThrow("ERROR");
|
||||
});
|
||||
|
||||
it('should throw dividing by 0 error', () => {
|
||||
expect(() => parser._throwError('#DIV/0!')).toThrow('DIV/0');
|
||||
it("should throw dividing by 0 error", () => {
|
||||
expect(() => parser._throwError("#DIV/0!")).toThrow("DIV/0");
|
||||
});
|
||||
|
||||
it('should throw name error', () => {
|
||||
expect(() => parser._throwError('#NAME?')).toThrow('NAME');
|
||||
it("should throw name error", () => {
|
||||
expect(() => parser._throwError("#NAME?")).toThrow("NAME");
|
||||
});
|
||||
|
||||
it('should throw not available error', () => {
|
||||
expect(() => parser._throwError('#N/A')).toThrow('N/A');
|
||||
it("should throw not available error", () => {
|
||||
expect(() => parser._throwError("#N/A")).toThrow("N/A");
|
||||
});
|
||||
|
||||
it('should throw null error', () => {
|
||||
expect(() => parser._throwError('#NULL!')).toThrow('NULL');
|
||||
it("should throw null error", () => {
|
||||
expect(() => parser._throwError("#NULL!")).toThrow("NULL");
|
||||
});
|
||||
|
||||
it('should throw num error', () => {
|
||||
expect(() => parser._throwError('#NUM!')).toThrow('NUM');
|
||||
it("should throw num error", () => {
|
||||
expect(() => parser._throwError("#NUM!")).toThrow("NUM");
|
||||
});
|
||||
|
||||
it('should throw ref error', () => {
|
||||
expect(() => parser._throwError('#REF!')).toThrow('REF');
|
||||
it("should throw ref error", () => {
|
||||
expect(() => parser._throwError("#REF!")).toThrow("REF");
|
||||
});
|
||||
|
||||
it('should throw value error', () => {
|
||||
expect(() => parser._throwError('#VALUE!')).toThrow('VALUE');
|
||||
it("should throw value error", () => {
|
||||
expect(() => parser._throwError("#VALUE!")).toThrow("VALUE");
|
||||
});
|
||||
|
||||
it('should return general error if value not matches to any of known errors', () => {
|
||||
expect(() => parser._throwError('VALUE foo')).toThrow('ERROR');
|
||||
it("should return general error if value not matches to any of known errors", () => {
|
||||
expect(() => parser._throwError("VALUE foo")).toThrow("ERROR");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
import SUPPORTED_FORMULAS from '../../src/supported-formulas';
|
||||
import SUPPORTED_FORMULAS from "../../src/supported-formulas";
|
||||
|
||||
describe('.SUPPORTED_FORMULAS', () => {
|
||||
it('should be defined', () => {
|
||||
describe(".SUPPORTED_FORMULAS", () => {
|
||||
it("should be defined", () => {
|
||||
expect(SUPPORTED_FORMULAS.length).toBe(385);
|
||||
});
|
||||
});
|
||||
|
@ -1,42 +1,42 @@
|
||||
'use strict';
|
||||
"use strict";
|
||||
|
||||
const webpack = require('webpack');
|
||||
const path = require('path');
|
||||
const webpack = require("webpack");
|
||||
const path = require("path");
|
||||
|
||||
const ROOT_DIRECTORY = process.cwd();
|
||||
const NODE_ENV = process.env.NODE_ENV;
|
||||
|
||||
const config = {
|
||||
mode: 'production',
|
||||
mode: "production",
|
||||
devtool: false,
|
||||
entry: {
|
||||
main: path.resolve(ROOT_DIRECTORY, 'src/index.js'),
|
||||
main: path.resolve(ROOT_DIRECTORY, "src/index.js"),
|
||||
},
|
||||
output: {
|
||||
library: 'formulaParser',
|
||||
libraryTarget: 'umd',
|
||||
path: path.resolve(ROOT_DIRECTORY, 'dist'),
|
||||
filename: `formula-parser${NODE_ENV === 'production' ? '.min' : ''}.js`,
|
||||
library: "formulaParser",
|
||||
libraryTarget: "umd",
|
||||
path: path.resolve(ROOT_DIRECTORY, "dist"),
|
||||
filename: `formula-parser${NODE_ENV === "production" ? ".min" : ""}.js`,
|
||||
umdNamedDefine: true,
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
loaders: ['babel-loader'],
|
||||
exclude: /node_modules|grammar\-parser\.js$/
|
||||
loaders: ["babel-loader"],
|
||||
exclude: /node_modules|grammar\-parser\.js$/,
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
optimization: {
|
||||
minimize: NODE_ENV === 'production',
|
||||
minimize: NODE_ENV === "production",
|
||||
},
|
||||
plugins: [
|
||||
new webpack.optimize.OccurrenceOrderPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': JSON.stringify(NODE_ENV)
|
||||
})
|
||||
]
|
||||
"process.env.NODE_ENV": JSON.stringify(NODE_ENV),
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
|
@ -7,7 +7,7 @@
|
||||
left: 197px;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 2px 4px rgb(0 0 0 / 20%);
|
||||
border: 1px solid rgba(0, 0, 0, .2);
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
#fortune-change-color .color-reset {
|
||||
@ -63,4 +63,4 @@
|
||||
border: 1px solid #0188fb;
|
||||
color: #fff;
|
||||
margin-right: -4px;
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,11 @@ export const ChangeColor: React.FC<Props> = ({ triggerParentUpdate }) => {
|
||||
|
||||
return (
|
||||
<div id="fortune-change-color">
|
||||
<div className="color-reset" onClick={() => setSelectColor(undefined)}>
|
||||
<div
|
||||
className="color-reset"
|
||||
onClick={() => setSelectColor(undefined)}
|
||||
tabIndex={0}
|
||||
>
|
||||
{sheetconfig.resetColor}
|
||||
</div>
|
||||
<div className="custom-color">
|
||||
@ -55,6 +59,7 @@ export const ChangeColor: React.FC<Props> = ({ triggerParentUpdate }) => {
|
||||
onClick={() => {
|
||||
certainBtn();
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.confirm}
|
||||
</div>
|
||||
|
@ -325,6 +325,7 @@ const ConditionRules: React.FC<{ type: string }> = ({ type }) => {
|
||||
// hideDialog();
|
||||
close("confirm");
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.confirm}
|
||||
</div>
|
||||
@ -334,6 +335,7 @@ const ConditionRules: React.FC<{ type: string }> = ({ type }) => {
|
||||
// hideDialog();
|
||||
close("close");
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.cancel}
|
||||
</div>
|
||||
|
@ -3,7 +3,7 @@
|
||||
top: -8px;
|
||||
box-shadow: 0 2px 4px rgb(0 0 0 / 20%);
|
||||
background: #fff;
|
||||
border: 1px solid rgba(0, 0, 0, .2);
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
cursor: default;
|
||||
font-size: 12px;
|
||||
z-index: 1004;
|
||||
@ -34,8 +34,6 @@
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.condition-rules .button-basic {
|
||||
display: inline-block;
|
||||
margin-bottom: 0;
|
||||
@ -136,8 +134,8 @@
|
||||
|
||||
.condition-rules-select-color {
|
||||
padding: 2px;
|
||||
border: solid 1px #E5E5E5;
|
||||
background: #F5F5F5;
|
||||
border: solid 1px #e5e5e5;
|
||||
background: #f5f5f5;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
@ -182,4 +180,4 @@
|
||||
|
||||
.condition-rules-project-input {
|
||||
margin: 0px 6px;
|
||||
}
|
||||
}
|
||||
|
@ -117,6 +117,7 @@ const ConditionalFormat: React.FC<{
|
||||
setOpen(false);
|
||||
showDialog(<ConditionRules type={v.text} />);
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{(conditionformat as any)[v.text]}
|
||||
<span>{v.value}</span>
|
||||
@ -165,6 +166,7 @@ const ConditionalFormat: React.FC<{
|
||||
setOpen(false);
|
||||
showDialog(<ConditionRules type={v.text} />);
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{(conditionformat as any)[v.text]}
|
||||
<span>{v.value}</span>
|
||||
@ -232,6 +234,7 @@ const ConditionalFormat: React.FC<{
|
||||
updateItem(ctx, "delSheet");
|
||||
});
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{(conditionformat as any)[v]}
|
||||
</div>
|
||||
|
@ -80,6 +80,7 @@ const DateSelectTreeItem: React.FC<{
|
||||
onExpand?.(item.key, !expand);
|
||||
setExpand(!expand);
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{_.isEmpty(item.children) ? (
|
||||
<div style={{ width: 10 }} />
|
||||
@ -97,6 +98,7 @@ const DateSelectTreeItem: React.FC<{
|
||||
onChange(item, !checked);
|
||||
}}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
tabIndex={0}
|
||||
/>
|
||||
<div>{item.text}</div>
|
||||
<span className="count">{`( ${item.rows.length} )`}</span>
|
||||
@ -305,6 +307,7 @@ const FilterMenu: React.FC = () => {
|
||||
key={v.color}
|
||||
className="item"
|
||||
onClick={() => onSelectChange(key, v.color, !v.checked)}
|
||||
tabIndex={0}
|
||||
>
|
||||
<div
|
||||
className="color-label"
|
||||
@ -540,17 +543,26 @@ const FilterMenu: React.FC = () => {
|
||||
<div className="luckysheet-filter-byvalue">
|
||||
<div className="fortune-menuitem-row byvalue-btn-row">
|
||||
<div>
|
||||
<span className="fortune-byvalue-btn" onClick={selectAll}>
|
||||
<span
|
||||
className="fortune-byvalue-btn"
|
||||
onClick={selectAll}
|
||||
tabIndex={0}
|
||||
>
|
||||
{filter.filterValueByAllBtn}
|
||||
</span>
|
||||
{" - "}
|
||||
<span className="fortune-byvalue-btn" onClick={clearAll}>
|
||||
<span
|
||||
className="fortune-byvalue-btn"
|
||||
onClick={clearAll}
|
||||
tabIndex={0}
|
||||
>
|
||||
{filter.filterValueByClearBtn}
|
||||
</span>
|
||||
{" - "}
|
||||
<span
|
||||
className="fortune-byvalue-btn"
|
||||
onClick={inverseSelect}
|
||||
tabIndex={0}
|
||||
>
|
||||
{filter.filterValueByInverseBtn}
|
||||
</span>
|
||||
@ -678,6 +690,7 @@ const FilterMenu: React.FC = () => {
|
||||
draftCtx.filterContextMenu = undefined;
|
||||
});
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{filter.filterConform}
|
||||
</div>
|
||||
@ -688,6 +701,7 @@ const FilterMenu: React.FC = () => {
|
||||
draftCtx.filterContextMenu = undefined;
|
||||
});
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{filter.filterCancel}
|
||||
</div>
|
||||
@ -698,6 +712,7 @@ const FilterMenu: React.FC = () => {
|
||||
clearFilter(draftCtx);
|
||||
});
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{filter.clearFilter}
|
||||
</div>
|
||||
@ -770,6 +785,7 @@ const FilterMenu: React.FC = () => {
|
||||
draftCtx.filterContextMenu = undefined;
|
||||
});
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{filter.filterConform}
|
||||
</div>
|
||||
|
@ -29,6 +29,7 @@ const Menu: React.FC<Props> = ({
|
||||
onClick={(e) => onClick?.(e, containerRef.current!)}
|
||||
onMouseLeave={(e) => onMouseLeave?.(e, containerRef.current!)}
|
||||
onMouseEnter={(e) => onMouseEnter?.(e, containerRef.current!)}
|
||||
tabIndex={0}
|
||||
>
|
||||
<div className="luckysheet-cols-menuitem-content luckysheet-mousedown-cancel">
|
||||
{children}
|
||||
|
@ -49,10 +49,12 @@
|
||||
/* 右击菜单项目 hover背景色 */
|
||||
.luckysheet-cols-menu .luckysheet-cols-menuitem:hover,
|
||||
.luckysheet-cols-menu .luckysheet-cols-menuitem-hover {
|
||||
background: #EFEFEF;
|
||||
background: #efefef;
|
||||
}
|
||||
|
||||
.luckysheet-cols-menu .luckysheet-cols-menuitem .luckysheet-cols-menuitem-content {
|
||||
.luckysheet-cols-menu
|
||||
.luckysheet-cols-menuitem
|
||||
.luckysheet-cols-menuitem-content {
|
||||
position: relative;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
@ -67,7 +69,9 @@
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.fortune-filter-menu .luckysheet-cols-menuitem .luckysheet-cols-menuitem-content {
|
||||
.fortune-filter-menu
|
||||
.luckysheet-cols-menuitem
|
||||
.luckysheet-cols-menuitem-content {
|
||||
padding: 7px 24px;
|
||||
}
|
||||
|
||||
@ -84,7 +88,6 @@
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
|
||||
.luckysheet-filter-bycolor-submenu .button-basic,
|
||||
.fortune-filter-menu .button-basic {
|
||||
display: flex;
|
||||
@ -117,7 +120,7 @@
|
||||
.luckysheet-filter-bycolor-submenu .button-primary,
|
||||
.fortune-filter-menu .button-primary {
|
||||
color: white;
|
||||
background-color: #0188FB;
|
||||
background-color: #0188fb;
|
||||
}
|
||||
|
||||
.luckysheet-filter-bycolor-submenu .button-primary:hover,
|
||||
@ -163,7 +166,7 @@
|
||||
}
|
||||
|
||||
.filtermenu-input-container input.luckysheet-mousedown-cancel {
|
||||
border: 1px solid #A1A1A1;
|
||||
border: 1px solid #a1a1a1;
|
||||
}
|
||||
|
||||
.filtermenu-input-container input.luckysheet-mousedown-cancel:focus {
|
||||
@ -226,7 +229,7 @@
|
||||
font-size: 12px;
|
||||
padding: 5px 0;
|
||||
z-index: 1004;
|
||||
border: 1px solid rgba(0, 0, 0, .2);
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
@ -276,4 +279,4 @@
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: -18px;
|
||||
}
|
||||
}
|
||||
|
@ -135,6 +135,7 @@ const ContextMenu: React.FC = () => {
|
||||
<input
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onKeyDown={(e) => e.stopPropagation()}
|
||||
tabIndex={0}
|
||||
type="text"
|
||||
className="luckysheet-mousedown-cancel"
|
||||
placeholder={rightclick.number}
|
||||
@ -204,6 +205,7 @@ const ContextMenu: React.FC = () => {
|
||||
<input
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onKeyDown={(e) => e.stopPropagation()}
|
||||
tabIndex={0}
|
||||
type="text"
|
||||
className="luckysheet-mousedown-cancel"
|
||||
placeholder={rightclick.number}
|
||||
@ -424,6 +426,7 @@ const ContextMenu: React.FC = () => {
|
||||
<input
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onKeyDown={(e) => e.stopPropagation()}
|
||||
tabIndex={0}
|
||||
type="number"
|
||||
min={1}
|
||||
max={545}
|
||||
@ -484,6 +487,7 @@ const ContextMenu: React.FC = () => {
|
||||
<input
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onKeyDown={(e) => e.stopPropagation()}
|
||||
tabIndex={0}
|
||||
type="number"
|
||||
min={1}
|
||||
max={545}
|
||||
|
@ -162,6 +162,7 @@ const CustomSort: React.FC<{}> = () => {
|
||||
});
|
||||
hideDialog();
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{sort.confirm}
|
||||
</div>
|
||||
|
@ -103,6 +103,7 @@ const DropDownList: React.FC = () => {
|
||||
onKeyDown={(e) => e.stopPropagation()}
|
||||
onMouseDown={(e) => e.stopPropagation()}
|
||||
onMouseUp={(e) => e.stopPropagation()}
|
||||
tabIndex={0}
|
||||
>
|
||||
{list.map((v, i) => (
|
||||
<div
|
||||
@ -121,6 +122,7 @@ const DropDownList: React.FC = () => {
|
||||
setDropcownValue(ctx, v, arr);
|
||||
});
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
<SVGIcon
|
||||
name="check"
|
||||
|
@ -72,6 +72,7 @@ const RangeDialog: React.FC = () => {
|
||||
onKeyDown={(e) => e.stopPropagation()}
|
||||
onMouseDown={(e) => e.stopPropagation()}
|
||||
onMouseUp={(e) => e.stopPropagation()}
|
||||
tabIndex={0}
|
||||
>
|
||||
<div className="dialog-title">{dataVerification.selectCellRange}</div>
|
||||
<input
|
||||
@ -88,6 +89,7 @@ const RangeDialog: React.FC = () => {
|
||||
});
|
||||
close();
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.confirm}
|
||||
</div>
|
||||
@ -96,6 +98,7 @@ const RangeDialog: React.FC = () => {
|
||||
onClick={() => {
|
||||
close();
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.close}
|
||||
</div>
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
#fortune-data-verification .box .box-item {
|
||||
padding: 10px;
|
||||
border-bottom: 1px solid #E1E4E8;
|
||||
border-bottom: 1px solid #e1e4e8;
|
||||
}
|
||||
|
||||
#fortune-data-verification .box .box-item .box-item-title {
|
||||
@ -38,7 +38,6 @@
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
}
|
||||
|
||||
#fortune-data-verification .box .box-item .show-box-item .check-box input {
|
||||
@ -124,12 +123,11 @@
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
#range-dialog {
|
||||
box-shadow: 0 4px 16px rgb(0 0 0 / 20%);
|
||||
background: #fff;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid rgba(0, 0, 0, .333);
|
||||
border: 1px solid rgba(0, 0, 0, 0.333);
|
||||
outline: 0;
|
||||
position: absolute;
|
||||
color: #000;
|
||||
@ -190,5 +188,5 @@
|
||||
}
|
||||
|
||||
#luckysheet-dataVerification-dropdown-List .dropdown-List-item:hover {
|
||||
background-color: #E1E1E1;
|
||||
}
|
||||
background-color: #e1e1e1;
|
||||
}
|
||||
|
@ -250,6 +250,7 @@ const DataVerification: React.FC = () => {
|
||||
context.dataVerification!.dataRegulation!.value1
|
||||
);
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
<SVGIcon name="tab" width={18} />
|
||||
</i>
|
||||
@ -328,6 +329,7 @@ const DataVerification: React.FC = () => {
|
||||
context.dataVerification!.dataRegulation!.value1
|
||||
)
|
||||
}
|
||||
tabIndex={0}
|
||||
>
|
||||
<SVGIcon name="tab" width={18} />
|
||||
</i>
|
||||
@ -643,6 +645,7 @@ const DataVerification: React.FC = () => {
|
||||
// hideDialog();
|
||||
btn("confirm");
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.confirm}
|
||||
</div>
|
||||
@ -651,6 +654,7 @@ const DataVerification: React.FC = () => {
|
||||
onClick={() => {
|
||||
btn("delete");
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{dataVerification.deleteVerification}
|
||||
</div>
|
||||
@ -659,6 +663,7 @@ const DataVerification: React.FC = () => {
|
||||
onClick={() => {
|
||||
btn("close");
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.cancel}
|
||||
</div>
|
||||
|
@ -45,7 +45,7 @@
|
||||
|
||||
.fortune-message-box-button.button-primary {
|
||||
color: white;
|
||||
background-color: #0188FB;
|
||||
background-color: #0188fb;
|
||||
}
|
||||
|
||||
.fortune-modal-dialog-header {
|
||||
@ -61,4 +61,4 @@
|
||||
|
||||
.fortune-modal-dialog-icon-close:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,11 @@ const Dialog: React.FC<Props> = ({
|
||||
return (
|
||||
<div className="fortune-dialog" style={containerStyle}>
|
||||
<div className="fortune-modal-dialog-header">
|
||||
<div className="fortune-modal-dialog-icon-close" onClick={onCancel}>
|
||||
<div
|
||||
className="fortune-modal-dialog-icon-close"
|
||||
onClick={onCancel}
|
||||
tabIndex={0}
|
||||
>
|
||||
<SVGIcon name="close" style={{ padding: 7, cursor: "pointer" }} />
|
||||
</div>
|
||||
</div>
|
||||
@ -39,6 +43,7 @@ const Dialog: React.FC<Props> = ({
|
||||
<div
|
||||
className="fortune-message-box-button button-default"
|
||||
onClick={onOk}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.confirm}
|
||||
</div>
|
||||
@ -47,12 +52,14 @@ const Dialog: React.FC<Props> = ({
|
||||
<div
|
||||
className="fortune-message-box-button button-primary"
|
||||
onClick={onOk}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.confirm}
|
||||
</div>
|
||||
<div
|
||||
className="fortune-message-box-button button-default"
|
||||
onClick={onCancel}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.cancel}
|
||||
</div>
|
||||
|
@ -169,6 +169,7 @@ const FilterOptions: React.FC<{ getContainer: () => HTMLDivElement }> = ({
|
||||
showFilterContextMenu(v_adjusted, i);
|
||||
}}
|
||||
onDoubleClick={(e) => e.stopPropagation()}
|
||||
tabIndex={0}
|
||||
key={i}
|
||||
style={_.assign(rowOverflowFreezeStyle, columnOverflowFreezeStyle, {
|
||||
left,
|
||||
|
@ -11,12 +11,9 @@
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
|
||||
.format-list {
|
||||
width: 300px;
|
||||
height: 170px;
|
||||
border: 1px solid #d4d4d4;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
|
||||
|
@ -121,6 +121,7 @@ export const FormatSearch: React.FC<{
|
||||
onClick={() => {
|
||||
setSelectedFormatIndex(index);
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
<div>{v.name}</div>
|
||||
<div>{v.value}</div>
|
||||
@ -135,12 +136,14 @@ export const FormatSearch: React.FC<{
|
||||
<div
|
||||
className="fortune-message-box-button button-primary"
|
||||
onClick={onConfirm}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.confirm}
|
||||
</div>
|
||||
<div
|
||||
className="fortune-message-box-button button-default"
|
||||
onClick={onCancel}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.cancel}
|
||||
</div>
|
||||
|
@ -60,6 +60,6 @@
|
||||
}
|
||||
|
||||
.listBox.on {
|
||||
background-color: #8C89FE;
|
||||
background-color: #8c89fe;
|
||||
color: #fff;
|
||||
}
|
||||
|
@ -165,6 +165,7 @@ export const FormulaSearch: React.FC<{ onCancel: () => void }> = ({
|
||||
className={`listBox${index === selectedFuncIndex ? " on" : ""}`}
|
||||
key={v.n}
|
||||
onClick={() => setSelectedFuncIndex(index)}
|
||||
tabIndex={0}
|
||||
>
|
||||
<div>{v.n}</div>
|
||||
<div>{v.a}</div>
|
||||
@ -176,12 +177,14 @@ export const FormulaSearch: React.FC<{ onCancel: () => void }> = ({
|
||||
<div
|
||||
className="fortune-message-box-button button-primary"
|
||||
onClick={onConfirm}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.confirm}
|
||||
</div>
|
||||
<div
|
||||
className="fortune-message-box-button button-default"
|
||||
onClick={onCancel}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.cancel}
|
||||
</div>
|
||||
|
@ -64,9 +64,9 @@
|
||||
background-color: white;
|
||||
padding-top: 7px;
|
||||
box-sizing: border-box;
|
||||
color:black;
|
||||
color: black;
|
||||
text-align: left;
|
||||
}
|
||||
.fortune-fx-input[contenteditable="true"] {
|
||||
-webkit-user-modify: read-write-plaintext-only;
|
||||
}
|
||||
}
|
||||
|
@ -118,6 +118,7 @@ const ImgBoxs: React.FC = () => {
|
||||
});
|
||||
e.stopPropagation();
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
<div
|
||||
className="luckysheet-modal-dialog-content"
|
||||
|
@ -16,7 +16,6 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
|
||||
.fortune-link-modify-modal .link-content {
|
||||
margin-right: 6px;
|
||||
}
|
||||
@ -29,7 +28,7 @@
|
||||
.fortune-link-modify-modal .divider {
|
||||
width: 1px;
|
||||
height: 16px;
|
||||
margin: 0px 6px ;
|
||||
margin: 0px 6px;
|
||||
background-color: #e0e0e0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
@ -88,7 +87,7 @@
|
||||
|
||||
.fortune-link-modify-input.error-input,
|
||||
.fortune-link-modify-modal .range-selection-input.error-input {
|
||||
border: 1px solid #EF4E2F !important;
|
||||
border: 1px solid #ef4e2f !important;
|
||||
}
|
||||
|
||||
.fortune-link-modify-cell-selector {
|
||||
@ -107,7 +106,7 @@
|
||||
.fortune-link-modify-modal .modal-title {
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
color: rgba(0, 0, 0, .88);
|
||||
color: rgba(0, 0, 0, 0.88);
|
||||
margin-bottom: 12px;
|
||||
line-height: 24px;
|
||||
}
|
||||
@ -139,8 +138,8 @@
|
||||
.fortune-link-modify-modal .validation-input-tip {
|
||||
height: 17px;
|
||||
font-size: 12px;
|
||||
color: #EF4E2F;
|
||||
margin: 3px 0px ;
|
||||
color: #ef4e2f;
|
||||
margin: 3px 0px;
|
||||
}
|
||||
|
||||
.fortune-link-modify-modal .button-group {
|
||||
@ -178,6 +177,6 @@
|
||||
|
||||
.fortune-link-modify-modal .button-primary {
|
||||
color: white;
|
||||
background-color: #0188FB;
|
||||
background-color: #0188fb;
|
||||
margin-left: 14px;
|
||||
}
|
||||
}
|
||||
|
@ -87,10 +87,18 @@ export const LinkEditCard: React.FC<LinkCardProps> = ({
|
||||
const renderBottomButton = useCallback(
|
||||
(onOk: () => void, onCancel: () => void) => (
|
||||
<div className="button-group">
|
||||
<div className="button-basic button-default" onClick={onCancel}>
|
||||
<div
|
||||
className="button-basic button-default"
|
||||
onClick={onCancel}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.cancel}
|
||||
</div>
|
||||
<div className="button-basic button-primary" onClick={onOk}>
|
||||
<div
|
||||
className="button-basic button-primary"
|
||||
onClick={onOk}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.confirm}
|
||||
</div>
|
||||
</div>
|
||||
@ -100,7 +108,7 @@ export const LinkEditCard: React.FC<LinkCardProps> = ({
|
||||
|
||||
const renderToolbarButton = useCallback(
|
||||
(iconId: string, onClick: () => void) => (
|
||||
<div className="fortune-toolbar-button" onClick={onClick}>
|
||||
<div className="fortune-toolbar-button" onClick={onClick} tabIndex={0}>
|
||||
<SVGIcon name={iconId} style={{ width: 18, height: 18 }} />
|
||||
</div>
|
||||
),
|
||||
@ -164,6 +172,7 @@ export const LinkEditCard: React.FC<LinkCardProps> = ({
|
||||
)
|
||||
);
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{linkType === "webpage"
|
||||
? insertLink.openLink
|
||||
@ -210,6 +219,7 @@ export const LinkEditCard: React.FC<LinkCardProps> = ({
|
||||
<div
|
||||
className="modal-icon-close"
|
||||
onClick={() => setRangeModalVisible(false)}
|
||||
tabIndex={0}
|
||||
>
|
||||
<SVGIcon name="close" />
|
||||
</div>
|
||||
@ -314,6 +324,7 @@ export const LinkEditCard: React.FC<LinkCardProps> = ({
|
||||
<div
|
||||
className="fortune-link-modify-cell-selector"
|
||||
onClick={() => setRangeModalVisible(true)}
|
||||
tabIndex={0}
|
||||
>
|
||||
<SVGIcon name="border-all" />
|
||||
</div>
|
||||
|
@ -1,74 +1,74 @@
|
||||
label {
|
||||
cursor: default;
|
||||
cursor: default;
|
||||
}
|
||||
#fortune-location-condition {
|
||||
min-width: 500px;
|
||||
min-width: 500px;
|
||||
}
|
||||
#fortune-location-condition .title {
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
cursor: default;
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
line-height: 48px;
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
cursor: default;
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
line-height: 48px;
|
||||
}
|
||||
#fortune-location-condition .listbox {
|
||||
border: 1px solid #dfdfdf;
|
||||
padding: 10px;
|
||||
font-size: 14px;
|
||||
color: #000;
|
||||
border: 1px solid #dfdfdf;
|
||||
padding: 10px;
|
||||
font-size: 14px;
|
||||
color: #000;
|
||||
}
|
||||
#fortune-location-condition .listbox .listItem {
|
||||
padding: 5px 0;
|
||||
padding: 5px 0;
|
||||
}
|
||||
#fortune-location-condition .listbox .listItem input[type="radio"] {
|
||||
float: left;
|
||||
margin-top: 5px;
|
||||
float: left;
|
||||
margin-top: 5px;
|
||||
}
|
||||
#fortune-location-condition .listItem {
|
||||
padding: 5px 0;
|
||||
padding: 5px 0;
|
||||
}
|
||||
#fortune-location-condition .listItem .subItem {
|
||||
height: 30px;
|
||||
padding: 0 10px;
|
||||
display: block;
|
||||
height: 30px;
|
||||
padding: 0 10px;
|
||||
display: block;
|
||||
}
|
||||
#fortune-location-condition input[type="radio"] {
|
||||
float: left;
|
||||
margin-top: 3px;
|
||||
float: left;
|
||||
margin-top: 3px;
|
||||
}
|
||||
#fortune-location-condition .listbox .listItem .subbox {
|
||||
height: 30px;
|
||||
padding: 0 10px;
|
||||
height: 30px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
#fortune-location-condition .listbox .listItem .subbox .subItem {
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
}
|
||||
#fortune-location-condition .button-basic {
|
||||
display: inline-block;
|
||||
margin-bottom: 0;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
touch-action: manipulation;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
padding: 4px 8px;
|
||||
font-size: 14px;
|
||||
line-height: 1.42857143;
|
||||
border-radius: 2px;
|
||||
user-select: none;
|
||||
margin-top: 10px;
|
||||
display: inline-block;
|
||||
margin-bottom: 0;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
touch-action: manipulation;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
padding: 4px 8px;
|
||||
font-size: 14px;
|
||||
line-height: 1.42857143;
|
||||
border-radius: 2px;
|
||||
user-select: none;
|
||||
margin-top: 10px;
|
||||
}
|
||||
#fortune-location-condition .button-primary {
|
||||
background: #0188fb;
|
||||
border: 1px solid #0188fb;
|
||||
color: #fff;
|
||||
margin-right: 10px;
|
||||
background: #0188fb;
|
||||
border: 1px solid #0188fb;
|
||||
color: #fff;
|
||||
margin-right: 10px;
|
||||
}
|
||||
#fortune-location-condition .button-close {
|
||||
color: #333;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
color: #333;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
@ -264,6 +264,7 @@ export const LocationCondition: React.FC<{}> = () => {
|
||||
hideDialog();
|
||||
onConfirm();
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.confirm}
|
||||
</div>
|
||||
@ -272,6 +273,7 @@ export const LocationCondition: React.FC<{}> = () => {
|
||||
onClick={() => {
|
||||
hideDialog();
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.cancel}
|
||||
</div>
|
||||
|
@ -26,8 +26,8 @@
|
||||
}
|
||||
|
||||
#fortune-search-replace .tabBox span.on {
|
||||
background-color: #8C89FE;
|
||||
border-color: #726EFE;
|
||||
background-color: #8c89fe;
|
||||
border-color: #726efe;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@
|
||||
}
|
||||
|
||||
#fortune-search-replace #searchAllbox .boxMain .boxItem.on {
|
||||
background-color: #8C89FE;
|
||||
background-color: #8c89fe;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@ -158,4 +158,4 @@
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
@ -81,6 +81,7 @@ const SearchReplace: React.FC<{
|
||||
<div
|
||||
className="icon-close fortune-modal-dialog-icon-close"
|
||||
onClick={closeDialog}
|
||||
tabIndex={0}
|
||||
>
|
||||
<SVGIcon name="close" style={{ padding: 7, cursor: "pointer" }} />
|
||||
</div>
|
||||
@ -89,6 +90,7 @@ const SearchReplace: React.FC<{
|
||||
id="searchTab"
|
||||
className={showReplace ? "" : "on"}
|
||||
onClick={() => setShowReplace(false)}
|
||||
tabIndex={0}
|
||||
>
|
||||
{findAndReplace.find}
|
||||
</span>
|
||||
@ -96,6 +98,7 @@ const SearchReplace: React.FC<{
|
||||
id="replaceTab"
|
||||
className={showReplace ? "on" : ""}
|
||||
onClick={() => setShowReplace(true)}
|
||||
tabIndex={0}
|
||||
>
|
||||
{findAndReplace.replace}
|
||||
</span>
|
||||
@ -170,6 +173,7 @@ const SearchReplace: React.FC<{
|
||||
showAlert(alertMsg);
|
||||
});
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
{findAndReplace.allReplaceBtn}
|
||||
</div>
|
||||
@ -190,6 +194,7 @@ const SearchReplace: React.FC<{
|
||||
}
|
||||
})
|
||||
}
|
||||
tabIndex={0}
|
||||
>
|
||||
{findAndReplace.replaceBtn}
|
||||
</div>
|
||||
@ -207,6 +212,7 @@ const SearchReplace: React.FC<{
|
||||
if (_.isEmpty(res)) showAlert(findAndReplace.noFindTip);
|
||||
})
|
||||
}
|
||||
tabIndex={0}
|
||||
>
|
||||
{findAndReplace.allFindBtn}
|
||||
</div>
|
||||
@ -220,6 +226,7 @@ const SearchReplace: React.FC<{
|
||||
if (alertMsg != null) showAlert(alertMsg);
|
||||
})
|
||||
}
|
||||
tabIndex={0}
|
||||
>
|
||||
{findAndReplace.findBtn}
|
||||
</div>
|
||||
@ -228,6 +235,7 @@ const SearchReplace: React.FC<{
|
||||
<div
|
||||
className="close-button fortune-message-box-button button-default"
|
||||
onClick={closeDialog}
|
||||
tabIndex={0}
|
||||
>
|
||||
{button.close}
|
||||
</div>
|
||||
@ -261,6 +269,7 @@ const SearchReplace: React.FC<{
|
||||
});
|
||||
setSelectedCell({ r: v.r, c: v.c });
|
||||
}}
|
||||
tabIndex={0}
|
||||
>
|
||||
<span>{v.sheetName}</span>
|
||||
<span>{v.cellPosition}</span>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user