Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ module.exports = {
'@typescript-eslint',
'license-header',
'jsdoc',
'jasmine',
'jest',
],
env: {
jasmine: true,
'jest/globals': true,
},
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.test.json',
Expand All @@ -17,6 +23,9 @@ module.exports = {
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
'plugin:jasmine/recommended',
'plugin:jest/recommended',
'plugin:jest/style',
],
rules: {
// Automatic fixers
Expand Down Expand Up @@ -113,6 +122,13 @@ module.exports = {
MethodDefinition: true,
}
}],
'jest/no-jasmine-globals': 'off',
'jest/no-alias-methods': 'off',
'jest/no-conditional-expect': 'warn',
'jest/no-standalone-expect': 'warn',
'jest/no-test-prefixes': 'off',
'jest/prefer-to-be': 'warn',
'jest/prefer-to-have-length': 'off',
},
overrides: [
{
Expand All @@ -127,5 +143,11 @@ module.exports = {
'sort-keys': ['error', 'asc'],
}
},
{
files: ['**/*.spec.ts'],
rules: {
'@typescript-eslint/no-non-null-assertion': 'off',
}
}
],
}
2 changes: 1 addition & 1 deletion .github/workflows/audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ jobs:

- name: Run audit
run: |
npm audit --omit='dev'
npm run audit
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

### Fixed

- Fixed an issue where cells were not recalculated after adding, removing and renaming sheets. [#1116](https://github.com/handsontable/hyperformula/issues/1116)
- Fixed an issue where overwriting a non-computed cell caused the `Value of the formula cell is not computed` error. [#1194](https://github.com/handsontable/hyperformula/issues/1194)

## [3.1.0] - 2025-10-14

### Changed
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/basic-operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ consists of a sheet ID, column ID, and row ID, like this:

Alternatively, you can work with the **A1 notation** known from
spreadsheets like Excel or Google Sheets. The API provides the helper
function [`simpleCellAddressFromString`](../api/globals.md#simplecelladdressfromstring) which you can use to retrieve
function [`simpleCellAddressFromString`](../api/classes/hyperformula.md#simplecelladdressfromstring) which you can use to retrieve
the [`SimpleCellAddress`](../api/interfaces/simplecelladdress) .
:::

Expand Down
11 changes: 11 additions & 0 deletions docs/guide/compatibility-with-microsoft-excel.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ That said, there are cases when HyperFormula can't be compatible with all three

Still, with the right configuration, you can achieve nearly full compatibility.

### Excel function coverage

HyperFormula implements **350 out of 515 Excel functions** (68% coverage), as of version 3.1.0 and Excel 2024. This means that **165 Excel functions** (32%) are not yet available in HyperFormula.

Additionally, HyperFormula includes some functions that are not part of Excel's standard function set, bringing the total number of available functions to **{{ $page.functionsCount }}**.

For a complete list of supported functions, see the [built-in functions](built-in-functions.md) page.

If you need any of the missing Excel functions, you can [contact us](contact.md) or implement them as [custom functions](custom-functions.md), extending HyperFormula's capabilities to meet your specific requirements.


## Configure compatibility with Microsoft Excel

### String comparison rules
Expand Down
7 changes: 7 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,11 @@ module.exports = {
transform: {
"^.+\\.(ts|tsx)$": "ts-jest"
},

watchPathIgnorePatterns: [
'/node_modules/',
'/dist/',
'/commonjs/',
'/es/',
]
};
95 changes: 67 additions & 28 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"test": "npm-run-all lint test:unit test:browser test:compatibility",
"test:unit": "cross-env NODE_ICU_DATA=node_modules/full-icu jest",
"test:watch": "cross-env NODE_ICU_DATA=node_modules/full-icu jest --watch",
"test:tdd": "cross-env NODE_ICU_DATA=node_modules/full-icu jest --watch custom-functions",
"test:tdd": "cross-env NODE_ICU_DATA=node_modules/full-icu jest --watch adding-sheet",
"test:coverage": "npm run test:unit -- --coverage",
"test:logMemory": "cross-env NODE_ICU_DATA=node_modules/full-icu jest --runInBand --logHeapUsage",
"test:unit.ci": "cross-env NODE_ICU_DATA=node_modules/full-icu node --expose-gc ./node_modules/jest/bin/jest --forceExit",
Expand All @@ -93,6 +93,7 @@
"benchmark:compare-benchmarks": "npm run tsnode test/performance/compare-benchmarks.ts",
"lint": "eslint . --ext .js,.ts",
"lint:fix": "eslint . --ext .js,.ts --fix",
"audit": "npm audit --omit=dev",
"clean": "rimraf coverage/ commonjs/ dist/ es/ languages/ lib/ typings/ test-jasmine/",
"compile": "tsc",
"check:licenses": "license-checker --production --excludePackages=\"[email protected]\" --onlyAllow=\"MIT; Apache-2.0; BSD-3-Clause; BSD-2-Clause; ISC; BSD; Unlicense\"",
Expand Down Expand Up @@ -133,6 +134,8 @@
"env-cmd": "^10.1.0",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-jasmine": "^4.2.2",
"eslint-plugin-jest": "^27.9.0",
"eslint-plugin-jsdoc": "^50.5.0",
"eslint-plugin-license-header": "^0.6.1",
"eslint-plugin-prettier": "^5.2.1",
Expand Down
12 changes: 8 additions & 4 deletions src/BuildEngineFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,17 @@ export class BuildEngineFactory {
throw new SheetSizeLimitExceededError()
}
const sheetId = sheetMapping.addSheet(sheetName)
addressMapping.autoAddSheet(sheetId, boundaries)
addressMapping.addSheetAndSetStrategyBasedOnBoundaries(sheetId, boundaries, { throwIfSheetAlreadyExists: true })
}
}

const parser = new ParserWithCaching(config, functionRegistry, sheetMapping.get)
const parser = new ParserWithCaching(
config,
functionRegistry,
dependencyGraph.sheetReferenceRegistrar.ensureSheetRegistered.bind(dependencyGraph.sheetReferenceRegistrar)
)
lazilyTransformingAstService.parser = parser
const unparser = new Unparser(config, buildLexerConfig(config), sheetMapping.fetchDisplayName, namedExpressions)
const unparser = new Unparser(config, sheetMapping, namedExpressions)
const dateTimeHelper = new DateTimeHelper(config)
const numberLiteralHelper = new NumberLiteralHelper(config)
const arithmeticHelper = new ArithmeticHelper(config, dateTimeHelper, numberLiteralHelper)
Expand All @@ -106,7 +110,7 @@ export class BuildEngineFactory {
const clipboardOperations = new ClipboardOperations(config, dependencyGraph, operations)
const crudOperations = new CrudOperations(config, operations, undoRedo, clipboardOperations, dependencyGraph, columnSearch, parser, cellContentParser, lazilyTransformingAstService, namedExpressions)

const exporter = new Exporter(config, namedExpressions, sheetMapping.fetchDisplayName, lazilyTransformingAstService)
const exporter = new Exporter(config, namedExpressions, sheetMapping, lazilyTransformingAstService)
const serialization = new Serialization(dependencyGraph, unparser, exporter)

const interpreter = new Interpreter(config, dependencyGraph, columnSearch, stats, arithmeticHelper, functionRegistry, namedExpressions, serialization, arraySizePredictor, dateTimeHelper)
Expand Down
15 changes: 10 additions & 5 deletions src/Cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
* Copyright (c) 2025 Handsoncode. All rights reserved.
*/

import {ArrayVertex, CellVertex, FormulaCellVertex, ParsingErrorVertex, ValueCellVertex} from './DependencyGraph'
import {FormulaVertex} from './DependencyGraph/FormulaCellVertex'
import {ArrayFormulaVertex, CellVertex, ScalarFormulaVertex, ParsingErrorVertex, ValueCellVertex} from './DependencyGraph'
import {FormulaVertex} from './DependencyGraph/FormulaVertex'
import {ErrorMessage} from './error-message'
import {
EmptyValue,
Expand Down Expand Up @@ -59,14 +59,14 @@ export enum CellType {
}

export const getCellType = (vertex: Maybe<CellVertex>, address: SimpleCellAddress): CellType => {
if (vertex instanceof ArrayVertex) {
if (vertex instanceof ArrayFormulaVertex) {
if (vertex.isLeftCorner(address)) {
return CellType.ARRAYFORMULA
} else {
return CellType.ARRAY
}
}
if (vertex instanceof FormulaCellVertex || vertex instanceof ParsingErrorVertex) {
if (vertex instanceof ScalarFormulaVertex || vertex instanceof ParsingErrorVertex) {
return CellType.FORMULA
}
if (vertex instanceof ValueCellVertex) {
Expand Down Expand Up @@ -196,7 +196,12 @@ export interface SimpleCellAddress {
}

export const simpleCellAddress = (sheet: number, col: number, row: number): SimpleCellAddress => ({sheet, col, row})
export const invalidSimpleCellAddress = (address: SimpleCellAddress): boolean => (address.col < 0 || address.row < 0)

/**
* Checks if the column or row id is negative.
*/
export const isColOrRowInvalid = (address: SimpleCellAddress): boolean => (address.col < 0 || address.row < 0)

export const movedSimpleCellAddress = (address: SimpleCellAddress, toSheet: number, toRight: number, toBottom: number): SimpleCellAddress => {
return simpleCellAddress(toSheet, address.col + toRight, address.row + toBottom)
}
Expand Down
4 changes: 2 additions & 2 deletions src/ClipboardOperations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import {AbsoluteCellRange} from './AbsoluteCellRange'
import {invalidSimpleCellAddress, simpleCellAddress, SimpleCellAddress} from './Cell'
import {isColOrRowInvalid, simpleCellAddress, SimpleCellAddress} from './Cell'
import {RawCellContent} from './CellContentParser'
import {Config} from './Config'
import {DependencyGraph} from './DependencyGraph'
Expand Down Expand Up @@ -119,7 +119,7 @@ export class ClipboardOperations {
return
}

if (invalidSimpleCellAddress(destinationLeftCorner) ||
if (isColOrRowInvalid(destinationLeftCorner) ||
!this.dependencyGraph.sheetMapping.hasSheetWithId(destinationLeftCorner.sheet)) {
throw new InvalidArgumentsError('a valid target address.')
}
Expand Down
Loading
Loading