Skip to content

Commit c3c6fc7

Browse files
Add support for functions in component configs
1 parent a0f8925 commit c3c6fc7

5 files changed

Lines changed: 29 additions & 10 deletions

File tree

packages/nhsuk-frontend/src/nhsuk/common/configuration/extract-config-by-namespace.mjs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/* eslint-disable jsdoc/reject-any-type */
2+
13
import { isObject } from '../index.mjs'
24

35
import { normaliseString } from './normalise-string.mjs'
@@ -74,7 +76,7 @@ export function extractConfigByNamespace(schema, dataset, namespace) {
7476
* Schema property for component config
7577
*
7678
* @typedef {object} SchemaProperty
77-
* @property {'string' | 'boolean' | 'number' | 'object' | 'array'} type - Property type
79+
* @property {'string' | 'boolean' | 'number' | 'object' | 'array' | 'function'} type - Property type
7880
*/
7981

8082
/**
@@ -88,5 +90,6 @@ export function extractConfigByNamespace(schema, dataset, namespace) {
8890

8991
/**
9092
* @typedef {keyof ObjectNested} NestedKey
91-
* @typedef {{ [key: string]: string | boolean | number | (string | number | boolean)[] | ObjectNested | undefined }} ObjectNested
93+
* @typedef {string | boolean | number} NestedValue
94+
* @typedef {{ [key: string]: NestedValue | NestedValue[] | ((...args: any[]) => NestedValue) | ObjectNested | undefined }} ObjectNested
9295
*/

packages/nhsuk-frontend/src/nhsuk/common/configuration/normalise-dataset.jsdom.test.mjs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ describe('normaliseDataset', () => {
2222
'anArray1': '[]',
2323
'anArray2': '[true]',
2424
'anArray3': '[1, 2, 3, 4]',
25-
'anArray4': '["goose", "gull", "gannet"]'
25+
'anArray4': '["goose", "gull", "gannet"]',
26+
'aFunction': '() => "albatross"'
2627
})
2728
).toEqual({
2829
aNumber: 1000,
@@ -40,7 +41,8 @@ describe('normaliseDataset', () => {
4041
anArray1: [],
4142
anArray2: [true],
4243
anArray3: [1, 2, 3, 4],
43-
anArray4: ['goose', 'gull', 'gannet']
44+
anArray4: ['goose', 'gull', 'gannet'],
45+
aFunction: undefined // Functions are not normalised from datasets
4446
})
4547
})
4648

packages/nhsuk-frontend/src/nhsuk/common/configuration/normalise-string.jsdom.test.mjs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,17 @@ describe('normaliseString', () => {
143143

144144
it('skips unhandled property schema', () => {
145145
const inputArray = '["string", "array"]'
146+
const inputFunction = '() => "albatross"'
146147
const inputObject = '{ not: "allowed" }'
147148

148149
// Arrays in strings are ignored even with schema property type
149150
expect(normaliseString(inputArray)).toBe(inputArray)
150151
expect(normaliseString(inputArray, { type: 'array' })).toBeUndefined()
151152

153+
// Functions in strings are ignored even with schema property type
154+
expect(normaliseString(inputFunction)).toBe(inputFunction)
155+
expect(normaliseString(inputFunction, { type: 'function' })).toBeUndefined()
156+
152157
// Objects in strings are ignored even with schema property type
153158
expect(normaliseString(inputObject)).toBe(inputObject)
154159
expect(normaliseString(inputObject, { type: 'object' })).toBeUndefined()

packages/nhsuk-frontend/src/nhsuk/configurable-component.jsdom.test.mjs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,13 @@ describe('ConfigurableComponent', () => {
6464

6565
const testComponent = document.querySelector('#test-component')
6666
const configComponent = new MockConfigurableComponent(testComponent, {
67-
aNumber: 100
67+
aNumber: 100,
68+
aFunction: (name) => name
6869
})
6970

70-
expect(configComponent.config).toMatchObject({ aNumber: 100 })
71+
expect(configComponent.config.aNumber).toBe(100)
72+
expect(configComponent.config.aFunction).toBeInstanceOf(Function)
73+
expect(configComponent.config.aFunction('albatross')).toBe('albatross')
7174
})
7275

7376
it('dataset configuration over the configuration object from class initialisation', () => {
@@ -77,10 +80,13 @@ describe('ConfigurableComponent', () => {
7780

7881
const testComponent = document.querySelector('#test-component')
7982
const configComponent = new MockConfigurableComponent(testComponent, {
80-
aNumber: 100
83+
aNumber: 100,
84+
aFunction: (name) => name
8185
})
8286

83-
expect(configComponent.config).toMatchObject({ aNumber: 12 })
87+
expect(configComponent.config.aNumber).toBe(12)
88+
expect(configComponent.config.aFunction).toBeInstanceOf(Function)
89+
expect(configComponent.config.aFunction('albatross')).toBe('albatross')
8490
})
8591
})
8692
})

packages/nhsuk-frontend/src/nhsuk/lib/fixtures/configuration/mock-component.mjs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ export class MockConfigurableComponent extends ConfigurableComponent {
4040
anArray1: { type: 'array' },
4141
anArray2: { type: 'array' },
4242
anArray3: { type: 'array' },
43-
anArray4: { type: 'array' }
43+
anArray4: { type: 'array' },
44+
aFunction: { type: 'function' }
4445
}
4546
}
4647

@@ -62,7 +63,8 @@ export class MockConfigurableComponent extends ConfigurableComponent {
6263
anArray1: [],
6364
anArray2: [true],
6465
anArray3: [1, 2, 3, 4],
65-
anArray4: ['goose', 'gull', 'gannet']
66+
anArray4: ['goose', 'gull', 'gannet'],
67+
aFunction: (name) => name
6668
}
6769
}
6870

@@ -233,6 +235,7 @@ export class MockConfigurableComponentMixed extends ConfigurableComponent {
233235
* @property {(string | number | boolean)[]} anArray2 - An array
234236
* @property {(string | number | boolean)[]} anArray3 - An array
235237
* @property {(string | number | boolean)[]} anArray4 - An array
238+
* @property {(name: string) => string} aFunction - A function
236239
*/
237240

238241
/**

0 commit comments

Comments
 (0)