Skip to content

Commit

Permalink
checkSupport now static and protected
Browse files Browse the repository at this point in the history
`checkSupport` of `GOVUKFrontend` can be overloaded by classes that
extend it. Added tests for `createAll` when `checkSupport` has been
overloaded.
  • Loading branch information
patrickpatrickpatrick committed Sep 19, 2024
1 parent 3a651ba commit 6c3228e
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 2 deletions.
12 changes: 11 additions & 1 deletion packages/govuk-frontend/src/govuk/govuk-frontend-component.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@ export class GOVUKFrontendComponent {
* @param {Element | null} [$module] - HTML element to use for component
*/
constructor($module) {
// const checkSupport = /** @type {ChildClassConstructor} */ (this.constructor)
// .checkSupport

// if (typeof checkSupport === 'function') {
// checkSupport()
// } else {
this.checkSupport()
// }

this.checkInitialised($module)

const moduleName = /** @type {ChildClassConstructor} */ (this.constructor)
Expand Down Expand Up @@ -49,7 +57,8 @@ export class GOVUKFrontendComponent {
/**
* Validates whether components are supported
*
* @private
* @protected
* @static
* @throws {SupportError} when the components are not supported
*/
checkSupport() {
Expand All @@ -72,6 +81,7 @@ export class GOVUKFrontendComponent {
/**
* @typedef ChildClass
* @property {string} [moduleName] - The module name that'll be looked for in the DOM when initialising the component
* @property {() => void} [checkSupport] - The module name that'll be looked for in the DOM when initialising the component
*/

/**
Expand Down
47 changes: 46 additions & 1 deletion packages/govuk-frontend/src/govuk/init.jsdom.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
} from '@govuk-frontend/lib/names'

import * as GOVUKFrontend from './all.mjs'
import { GOVUKFrontendComponent } from './govuk-frontend-component.mjs'
import { initAll, createAll } from './init.mjs'

// Annoyingly these don't get hoisted if done in a loop
Expand Down Expand Up @@ -226,8 +227,9 @@ describe('createAll', () => {
document.body.outerHTML = '<body></body>'
})

class MockComponent {
class MockComponent extends GOVUKFrontendComponent {
constructor(...args) {
super(...args)
this.args = args
}

Expand Down Expand Up @@ -292,6 +294,49 @@ describe('createAll', () => {
)
})

it('executes overloaded checkSupport of component', () => {
const componentRoot = document.createElement('div')
componentRoot.setAttribute('data-module', 'mock-component')
document.body.appendChild(componentRoot)

const checkSupportMock = jest.fn(() => {})

class MockComponentWithCheckSupport extends MockComponent {
checkSupport() {
checkSupportMock()
}
}

const result = createAll(MockComponentWithCheckSupport)

expect(checkSupportMock).toHaveBeenCalled()
expect(result).toStrictEqual([expect.any(MockComponent)])
})

it('returns empty array if overloaded checkSupport of component throws error', () => {
const componentRoot = document.createElement('div')
componentRoot.setAttribute('data-module', 'mock-component')
document.body.appendChild(componentRoot)

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

const checkSupportMock = jest.fn(() => {
throw Error('Mock error')
})

class MockComponentWithCheckSupport extends MockComponent {
checkSupport() {
checkSupportMock()
}
}

const result = createAll(MockComponentWithCheckSupport)
expect(checkSupportMock).toHaveBeenCalled()
expect(result).toStrictEqual([])
expect(global.console.log).toHaveBeenCalledWith(expect.any(Error))
})

it('returns an empty array if no matching components exist on the page', () => {
const componentRoot = document.createElement('div')
componentRoot.setAttribute(
Expand Down

0 comments on commit 6c3228e

Please sign in to comment.