Skip to content

Commit

Permalink
Merge pull request #5276 from alphagov/on-error-init-all
Browse files Browse the repository at this point in the history
Add `onError` to `initAll` config
  • Loading branch information
patrickpatrickpatrick authored Sep 11, 2024
2 parents ecc74dc + 5983f3a commit 5783a2b
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 5 deletions.
68 changes: 68 additions & 0 deletions packages/govuk-frontend/src/govuk/init.jsdom.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,38 @@ describe('initAll', () => {
})
)
})

it('executes onError if specified', () => {
const errorCallback = jest.fn((error, context) => {
console.log(error)
console.log(context)
})

initAll({
accordion: {
rememberExpanded: true
},
onError: errorCallback
})

expect(errorCallback).toHaveBeenCalled()

expect(global.console.log).toHaveBeenCalledWith(
expect.objectContaining({
message: 'GOV.UK Frontend is not supported in this browser'
})
)
expect(global.console.log).toHaveBeenCalledWith(
expect.objectContaining({
config: {
accordion: {
rememberExpanded: true
},
onError: errorCallback
}
})
)
})
})

it('only initialises components within a given scope', () => {
Expand Down Expand Up @@ -143,6 +175,42 @@ describe('initAll', () => {
})
)
})

it('executes onError callback on component create if specified', () => {
document.body.classList.add('govuk-frontend-supported')
document.body.innerHTML = '<div data-module="govuk-accordion"></div>'

jest.mocked(GOVUKFrontend.Accordion).mockImplementation(() => {
throw new Error('Error thrown from accordion')
})

const errorCallback = jest.fn((error, context) => {
console.log(error)
console.log(context)
})

// Silence warnings in test output, and allow us to 'expect' them
jest.spyOn(global.console, 'log').mockImplementation()

initAll({
onError: errorCallback,
accordion: {
rememberExpanded: true
}
})

expect(global.console.log).toHaveBeenCalledWith(
expect.objectContaining({
message: 'Error thrown from accordion'
})
)
expect(global.console.log).toHaveBeenCalledWith(
expect.objectContaining({
component: GOVUKFrontend.Accordion,
config: { rememberExpanded: true }
})
)
})
})

describe('createAll', () => {
Expand Down
21 changes: 16 additions & 5 deletions packages/govuk-frontend/src/govuk/init.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,20 @@ import { SupportError } from './errors/index.mjs'
* Use the `data-module` attributes to find, instantiate and init all of the
* components provided as part of GOV.UK Frontend.
*
* @param {Config & { scope?: Element }} [config] - Config for all components (with optional scope)
* @param {Config & { scope?: Element, onError?: OnErrorCallback<CompatibleClass> }} [config] - Config for all components (with optional scope)
*/
function initAll(config) {
config = typeof config !== 'undefined' ? config : {}

// Skip initialisation when GOV.UK Frontend is not supported
if (!isSupported()) {
console.log(new SupportError())
if (config.onError) {
config.onError(new SupportError(), {
config
})
} else {
console.log(new SupportError())
}
return
}

Expand All @@ -47,10 +53,15 @@ function initAll(config) {

// Allow the user to initialise GOV.UK Frontend in only certain sections of the page
// Defaults to the entire document if nothing is set.
const $scope = config.scope ?? document
// const $scope = config.scope ?? document

const options = {
scope: config.scope ?? document,
onError: config.onError
}

components.forEach(([Component, config]) => {
createAll(Component, config, $scope)
createAll(Component, config, options)
})
}

Expand Down Expand Up @@ -192,7 +203,7 @@ export { initAll, createAll }
* @template {CompatibleClass} T
* @typedef {object} ErrorContext
* @property {Element} [element] - Element used for component module initialisation
* @property {T} component - Class of component
* @property {T} [component] - Class of component
* @property {T["defaults"]} config - Config supplied to component
*/

Expand Down

0 comments on commit 5783a2b

Please sign in to comment.