Skip to content

Commit

Permalink
[WIP] Overload ElementError to allow a string or options object
Browse files Browse the repository at this point in the history
I've disabled @typescript-eslint since it didn't seem to be working out that `messageOrOptions` wasn't `any` in the case of the options object.

Guess I could typedef that options object to see if that fixes it.

Otherwise, this looks good
  • Loading branch information
domoscargin committed Oct 18, 2023
1 parent e925428 commit ea7b4a4
Show file tree
Hide file tree
Showing 14 changed files with 120 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,10 @@ export class Accordion extends GOVUKFrontendComponent {
super()

if (!($module instanceof HTMLElement)) {
throw new ElementError('Root element (`$module`)', {
throw new ElementError({
componentName: 'Accordion',
element: $module
element: $module,
identifier: 'Root element (`$module`)'
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ export class Button extends GOVUKFrontendComponent {
super()

if (!($module instanceof HTMLElement)) {
throw new ElementError('Root element (`$module`)', {
throw new ElementError({
componentName: 'Button',
element: $module
element: $module,
identifier: 'Root element (`$module`)'
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,10 @@ export class CharacterCount extends GOVUKFrontendComponent {
super()

if (!($module instanceof HTMLElement)) {
throw new ElementError('Root element (`$module`)', {
throw new ElementError({
componentName: 'Character count',
element: $module
element: $module,
identifier: 'Root element (`$module`)'
})
}

Expand All @@ -88,10 +89,11 @@ export class CharacterCount extends GOVUKFrontendComponent {
$textarea instanceof HTMLInputElement
)
) {
throw new ElementError('.govuk-js-character-count', {
throw new ElementError({
componentName: 'Character count',
element: $textarea,
expectedType: 'HTMLTextareaElement or HTMLInputElement'
expectedType: 'HTMLTextareaElement or HTMLInputElement',
identifier: 'Form field (`.govuk-js-character-count`)'
})
}

Expand Down Expand Up @@ -140,9 +142,10 @@ export class CharacterCount extends GOVUKFrontendComponent {
const textareaDescriptionId = `${this.$textarea.id}-info`
const $textareaDescription = document.getElementById(textareaDescriptionId)
if (!$textareaDescription) {
throw new ElementError(`#${textareaDescriptionId}`, {
throw new ElementError({
componentName: 'Character count',
element: $textareaDescription
element: $textareaDescription,
identifier: `#${textareaDescriptionId}`
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,8 @@ describe('Character count', () => {
})
).rejects.toEqual({
name: 'ElementError',
message: 'Character count: .govuk-js-character-count not found'
message:
'Character count: Form field (`.govuk-js-character-count`) not found'
})
})

Expand All @@ -884,7 +885,7 @@ describe('Character count', () => {
).rejects.toEqual({
name: 'ElementError',
message:
'Character count: .govuk-js-character-count is not of type HTMLTextareaElement or HTMLInputElement'
'Character count: Form field (`.govuk-js-character-count`) is not of type HTMLTextareaElement or HTMLInputElement'
})
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,18 @@ export class Checkboxes extends GOVUKFrontendComponent {
super()

if (!($module instanceof HTMLElement)) {
throw new ElementError(`[data-module="${Checkboxes.moduleName}"]`, {
throw new ElementError({
componentName: 'Checkboxes',
element: $module
element: $module,
identifier: `[data-module="${Checkboxes.moduleName}"]`
})
}

const $inputs = $module.querySelectorAll('input[type="checkbox"]')
if (!$inputs.length) {
throw new ElementError('input[type="checkbox"]', {
componentName: 'Checkboxes'
throw new ElementError({
componentName: 'Checkboxes',
identifier: 'input[type="checkbox"]'
})
}

Expand All @@ -57,8 +59,9 @@ export class Checkboxes extends GOVUKFrontendComponent {

// Throw if target conditional element does not exist.
if (!document.getElementById(targetId)) {
throw new ElementError(`#${targetId}`, {
componentName: 'Checkboxes'
throw new ElementError({
componentName: 'Checkboxes',
identifier: `#${targetId}`
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ export class ErrorSummary extends GOVUKFrontendComponent {
super()

if (!($module instanceof HTMLElement)) {
throw new ElementError('Root element (`$module`)', {
throw new ElementError({
componentName: 'Error summary',
element: $module
element: $module,
identifier: 'Root element (`$module`)'
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,18 +82,20 @@ export class ExitThisPage extends GOVUKFrontendComponent {
super()

if (!($module instanceof HTMLElement)) {
throw new ElementError('Root element (`$module`)', {
throw new ElementError({
componentName: 'Exit this page',
element: $module
element: $module,
identifier: 'Root element (`$module`)'
})
}

const $button = $module.querySelector('.govuk-exit-this-page__button')
if (!($button instanceof HTMLAnchorElement)) {
throw new ElementError('Button', {
throw new ElementError({
componentName: 'Exit this page',
element: $button,
expectedType: 'HTMLAnchorElement'
expectedType: 'HTMLAnchorElement',
identifier: 'Button'
})
}

Expand Down
15 changes: 9 additions & 6 deletions packages/govuk-frontend/src/govuk/components/header/header.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ export class Header extends GOVUKFrontendComponent {
super()

if (!$module) {
throw new ElementError('Root element (`$module`)', {
throw new ElementError({
componentName: 'Header',
element: $module
element: $module,
identifier: 'Root element (`$module`)'
})
}

Expand All @@ -63,16 +64,18 @@ export class Header extends GOVUKFrontendComponent {

const menuId = $menuButton.getAttribute('aria-controls')
if (!menuId) {
throw new ElementError('.govuk-js-header-toggle[aria-controls]', {
componentName: 'Header'
throw new ElementError({
componentName: 'Header',
identifier: '.govuk-js-header-toggle[aria-controls]'
})
}

const $menu = document.getElementById(menuId)
if (!$menu) {
throw new ElementError(`#${menuId}`, {
throw new ElementError({
componentName: 'Header',
element: $menu
element: $menu,
identifier: `#${menuId}`
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ export class NotificationBanner extends GOVUKFrontendComponent {
super()

if (!($module instanceof HTMLElement)) {
throw new ElementError('Root element (`$module`)', {
throw new ElementError({
componentName: 'Notification banner',
element: $module
element: $module,
identifier: 'Root element (`$module`)'
})
}

Expand Down
15 changes: 9 additions & 6 deletions packages/govuk-frontend/src/govuk/components/radios/radios.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,18 @@ export class Radios extends GOVUKFrontendComponent {
super()

if (!($module instanceof HTMLElement)) {
throw new ElementError(`[data-module="${Radios.moduleName}"]`, {
throw new ElementError({
componentName: 'Radios',
element: $module
element: $module,
identifier: `[data-module="${Radios.moduleName}"]`
})
}

const $inputs = $module.querySelectorAll('input[type="radio"]')
if (!$inputs.length) {
throw new ElementError('input[type="radio"]', {
componentName: 'Radios'
throw new ElementError({
componentName: 'Radios',
identifier: 'input[type="radio"]'
})
}

Expand All @@ -57,8 +59,9 @@ export class Radios extends GOVUKFrontendComponent {

// Throw if target conditional element does not exist.
if (!document.getElementById(targetId)) {
throw new ElementError(`#${targetId}`, {
componentName: 'Radios'
throw new ElementError({
componentName: 'Radios',
identifier: `#${targetId}`
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ export class SkipLink extends GOVUKFrontendComponent {
super()

if (!($module instanceof HTMLAnchorElement)) {
throw new ElementError('Root element (`$module`)', {
throw new ElementError({
componentName: 'Skip link',
element: $module,
expectedType: 'HTMLAnchorElement'
expectedType: 'HTMLAnchorElement',
identifier: 'Root element (`$module`)'
})
}

Expand All @@ -52,21 +53,18 @@ export class SkipLink extends GOVUKFrontendComponent {
// Check for link hash fragment
if (!linkedElementId) {
throw new ElementError(
'Root element (`$module`) attribute (`href`) has no URL fragment',
{
componentName: 'Skip link',
identifierIsMessage: true
}
'Skip link: Root element (`$module`) attribute (`href`) has no URL fragment'
)
}

const $linkedElement = document.getElementById(linkedElementId)

// Check for link target element
if (!$linkedElement) {
throw new ElementError(`Linked element #${linkedElementId}`, {
throw new ElementError({
componentName: 'Skip link',
element: $linkedElement
element: $linkedElement,
identifier: `Linked element #${linkedElementId}`
})
}

Expand Down
20 changes: 12 additions & 8 deletions packages/govuk-frontend/src/govuk/components/tabs/tabs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,18 @@ export class Tabs extends GOVUKFrontendComponent {
super()

if (!$module) {
throw new ElementError('Root element (`$module`)', {
throw new ElementError({
componentName: 'Tabs',
element: $module
element: $module,
identifier: 'Root element (`$module`)'
})
}

const $tabs = $module.querySelectorAll('a.govuk-tabs__tab')
if (!$tabs.length) {
throw new ElementError(`a.govuk-tabs__tab`, {
componentName: 'Tabs'
throw new ElementError({
componentName: 'Tabs',
identifier: `a.govuk-tabs__tab`
})
}

Expand All @@ -78,14 +80,16 @@ export class Tabs extends GOVUKFrontendComponent {
)

if (!$tabList) {
throw new ElementError(`.govuk-tabs__list`, {
componentName: 'Tabs'
throw new ElementError({
componentName: 'Tabs',
identifier: `.govuk-tabs__list`
})
}

if (!$tabListItems.length) {
throw new ElementError(`.govuk-tabs__list-item`, {
componentName: 'Tabs'
throw new ElementError({
componentName: 'Tabs',
identifier: `.govuk-tabs__list-item`
})
}

Expand Down
25 changes: 17 additions & 8 deletions packages/govuk-frontend/src/govuk/errors/index.jsdom.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,33 +28,42 @@ describe('errors', () => {
describe('ElementError', () => {
it('is an instance of GOVUKFrontendError', () => {
expect(
new ElementError('variableName', {
componentName: 'Component name'
new ElementError({
componentName: 'Component name',
identifier: 'variableName'
})
).toBeInstanceOf(GOVUKFrontendError)
})
it('has its own name set', () => {
expect(
new ElementError('variableName', {
componentName: 'Component name'
new ElementError({
componentName: 'Component name',
identifier: 'variableName'
}).name
).toBe('ElementError')
})
it('accepts a string and does not process it in any way', () => {
expect(new ElementError('Complex custom error message').message).toBe(
'Complex custom error message'
)
})
it('formats the message when the element is not found', () => {
expect(
new ElementError('variableName', {
componentName: 'Component name'
new ElementError({
componentName: 'Component name',
identifier: 'variableName'
}).message
).toBe('Component name: variableName not found')
})
it('formats the message when the element is not the right type', () => {
const element = document.createElement('div')

expect(
new ElementError('variableName', {
new ElementError({
componentName: 'Component name',
element,
expectedType: 'HTMLAnchorElement'
expectedType: 'HTMLAnchorElement',
identifier: 'variableName'
}).message
).toBe('Component name: variableName is not of type HTMLAnchorElement')
})
Expand Down
Loading

0 comments on commit ea7b4a4

Please sign in to comment.