Skip to content

Commit

Permalink
Add a configuration option context that can be used to pass data to…
Browse files Browse the repository at this point in the history
… custom functions (#1400)

Add generic context option for custom function resolution (#1398)

* Add generic context option for custom function resolution

* Apply suggestions from code review

* Unknown type; add function test

* Update changelog

Co-authored-by: Michael Bridge <[email protected]>
  • Loading branch information
sequba and michaelbridge authored Apr 3, 2024
1 parent a752b76 commit 2404ac4
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

### Added

- Added a configuration option `context` that can be used to pass data to custom functions.

## [2.6.2] - 2024-02-15

### Changed
Expand Down
5 changes: 5 additions & 0 deletions src/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export class Config implements ConfigParams, ParserConfig {
currencySymbol: ['$'],
caseSensitive: false,
caseFirst: 'lower',
context: undefined,
chooseAddressMappingPolicy: new AlwaysDense(),
dateFormats: ['DD/MM/YYYY', 'DD/MM/YY'],
decimalSeparator: '.',
Expand Down Expand Up @@ -136,6 +137,8 @@ export class Config implements ConfigParams, ParserConfig {
public readonly currencySymbol: string[]
/** @inheritDoc */
public readonly undoLimit: number
/** @inheritDoc */
public readonly context: unknown

/**
* Built automatically based on translation package.
Expand Down Expand Up @@ -168,6 +171,7 @@ export class Config implements ConfigParams, ParserConfig {
caseSensitive,
caseFirst,
chooseAddressMappingPolicy,
context,
currencySymbol,
dateFormats,
decimalSeparator,
Expand Down Expand Up @@ -254,6 +258,7 @@ export class Config implements ConfigParams, ParserConfig {
this.maxColumns = configValueFromParam(maxColumns, 'number', 'maxColumns')
this.currencySymbol = this.setupCurrencySymbol(currencySymbol)
validateNumberToBeAtLeast(this.maxColumns, 'maxColumns', 1)
this.context = context

privatePool.set(this, {
licenseKeyValidityState: checkLicenseKeyValidity(this.licenseKey)
Expand Down
6 changes: 6 additions & 0 deletions src/ConfigParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ export interface ConfigParams {
* @category Engine
*/
chooseAddressMappingPolicy: ChooseAddressMapping,
/**
* A generic parameter that can be used to pass data to custom functions.
* @default undefined
* @category Engine
*/
context: unknown,
/**
* Sets symbols that denote currency numbers.
*
Expand Down
6 changes: 6 additions & 0 deletions test/config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ describe('Config', () => {
expect(() => new Config({caseFirst: 'abcd'})).toThrowError('Expected one of \'upper\' \'lower\' \'false\' for config parameter: caseFirst')
})

it('should return the specified context', () => {
const context ={a: 1, b: 2}
const config = new Config({context})
expect(config.context).toBe(context)
})

it('should throw error when Function Translation cannot be found', () => {
const config = new Config()
const functionName = '0123456ABCDEFGH'
Expand Down
28 changes: 27 additions & 1 deletion test/custom-functions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ class GreetingsPlugin extends FunctionPlugin {
EXAMPLE_ARRAY_FUNCTION: 'EXAMPLE_ARRAY_FUNCTION',
}
}

greet(ast: ProcedureAst, state: InterpreterState) {
return this.runFunction(
ast.args,
Expand Down Expand Up @@ -219,6 +219,18 @@ class GreetingsPlugin extends FunctionPlugin {
}
}

class ContextPlugin extends FunctionPlugin {
public static implementedFunctions = {
'GETCONTEXT': {
method: 'getContext',
}
}

public getContext(ast: ProcedureAst, state: InterpreterState): unknown {
return this.config.context
}
}

describe('Register static custom plugin', () => {
it('should register plugin with translations', () => {
HyperFormula.registerLanguage('plPL', plPL)
Expand Down Expand Up @@ -552,3 +564,17 @@ describe('Custom function implemented with runFunction)', () => {
}).toThrow(new Error('Function returning array cannot be vectorized.'))
})
})

describe('Context accessible within custom function', () => {
it('works', () => {
HyperFormula.registerFunctionPlugin(ContextPlugin)
HyperFormula.getLanguage('enGB').extendFunctions({GETCONTEXT: 'GETCONTEXT'})

const context = 'abc'
const engine = HyperFormula.buildFromArray([
['=GETCONTEXT()'],
], {context})

expect(engine.getCellValue(adr('A1'))).toEqual(context)
})
})

0 comments on commit 2404ac4

Please sign in to comment.