|
| 1 | +import { afterEach, beforeEach, describe, expect, it, vi, type MockInstance } from 'vitest' |
| 2 | +import { presetA11y, resetA11yWarnings } from '../../uno-preset-a11y' |
| 3 | +import { createGenerator, presetWind4 } from 'unocss' |
| 4 | + |
| 5 | +describe('uno-preset-a11y', () => { |
| 6 | + let warnSpy: MockInstance |
| 7 | + |
| 8 | + beforeEach(() => { |
| 9 | + resetA11yWarnings() |
| 10 | + warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}) |
| 11 | + }) |
| 12 | + |
| 13 | + afterEach(() => { |
| 14 | + warnSpy.mockRestore() |
| 15 | + }) |
| 16 | + |
| 17 | + it('a11y rules generate font-size and warn correctly', async () => { |
| 18 | + const uno = await createGenerator({ |
| 19 | + presets: [presetWind4(), presetA11y()], |
| 20 | + }) |
| 21 | + |
| 22 | + const { css } = await uno.generate( |
| 23 | + 'text-[11px] text-[10px] text-[9px] text-[8px] text-[12px] text-[1.5em]', |
| 24 | + ) |
| 25 | + |
| 26 | + expect(css).toMatchInlineSnapshot(` |
| 27 | + "/* layer: theme */ |
| 28 | + :root, :host { --font-sans: ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"; --font-mono: ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; --default-font-family: var(--font-sans); --default-monoFont-family: var(--font-mono); } |
| 29 | + /* layer: base */ |
| 30 | + *, ::after, ::before, ::backdrop, ::file-selector-button { box-sizing: border-box; margin: 0; padding: 0; border: 0 solid; } html, :host { line-height: 1.5; -webkit-text-size-adjust: 100%; tab-size: 4; font-family: var( --default-font-family, ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji' ); font-feature-settings: var(--default-font-featureSettings, normal); font-variation-settings: var(--default-font-variationSettings, normal); -webkit-tap-highlight-color: transparent; } hr { height: 0; color: inherit; border-top-width: 1px; } abbr:where([title]) { -webkit-text-decoration: underline dotted; text-decoration: underline dotted; } h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; } a { color: inherit; -webkit-text-decoration: inherit; text-decoration: inherit; } b, strong { font-weight: bolder; } code, kbd, samp, pre { font-family: var( --default-monoFont-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace ); font-feature-settings: var(--default-monoFont-featureSettings, normal); font-variation-settings: var(--default-monoFont-variationSettings, normal); font-size: 1em; } small { font-size: 80%; } sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sub { bottom: -0.25em; } sup { top: -0.5em; } table { text-indent: 0; border-color: inherit; border-collapse: collapse; } :-moz-focusring { outline: auto; } progress { vertical-align: baseline; } summary { display: list-item; } ol, ul, menu { list-style: none; } img, svg, video, canvas, audio, iframe, embed, object { display: block; vertical-align: middle; } img, video { max-width: 100%; height: auto; } button, input, select, optgroup, textarea, ::file-selector-button { font: inherit; font-feature-settings: inherit; font-variation-settings: inherit; letter-spacing: inherit; color: inherit; border-radius: 0; background-color: transparent; opacity: 1; } :where(select:is([multiple], [size])) optgroup { font-weight: bolder; } :where(select:is([multiple], [size])) optgroup option { padding-inline-start: 20px; } ::file-selector-button { margin-inline-end: 4px; } ::placeholder { opacity: 1; } @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) { ::placeholder { color: color-mix(in oklab, currentcolor 50%, transparent); } } textarea { resize: vertical; } ::-webkit-search-decoration { -webkit-appearance: none; } ::-webkit-date-and-time-value { min-height: 1lh; text-align: inherit; } ::-webkit-datetime-edit { display: inline-flex; } ::-webkit-datetime-edit-fields-wrapper { padding: 0; } ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field { padding-block: 0; } ::-webkit-calendar-picker-indicator { line-height: 1; } :-moz-ui-invalid { box-shadow: none; } button, input:where([type='button'], [type='reset'], [type='submit']), ::file-selector-button { appearance: button; } ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { height: auto; } [hidden]:where(:not([hidden~='until-found'])) { display: none !important; } |
| 31 | + /* layer: default */ |
| 32 | + .text-\\[10px\\]{font-size:10px;} |
| 33 | + .text-\\[11px\\]{font-size:11px;} |
| 34 | + .text-\\[12px\\]{font-size:12px;} |
| 35 | + .text-\\[8px\\]{font-size:8px;} |
| 36 | + .text-\\[9px\\]{font-size:9px;} |
| 37 | + .text-\\[1\\.5em\\]{font-size:1.5em;}" |
| 38 | + `) |
| 39 | + |
| 40 | + const warnings = warnSpy.mock.calls.flat() |
| 41 | + expect(warnings).toMatchInlineSnapshot(` |
| 42 | + [ |
| 43 | + "[a11y] Avoid using 'text-[11px]', use 'text-2xs' instead.", |
| 44 | + "[a11y] Avoid using 'text-[10px]', use 'text-3xs' instead.", |
| 45 | + "[a11y] Avoid using 'text-[9px]', use 'text-4xs' instead.", |
| 46 | + "[a11y] Avoid using 'text-[8px]', use 'text-5xs' instead.", |
| 47 | + "[a11y] Avoid using 'text-[12px]', use text-<size> classes or rem values instead of custom values.", |
| 48 | + "[a11y] Avoid using 'text-[1.5em]', use text-<size> classes or rem values instead of custom values.", |
| 49 | + ] |
| 50 | + `) |
| 51 | + }) |
| 52 | + |
| 53 | + it('when checker is provided, checker is called and no console.warn', async () => { |
| 54 | + const collected: Array<[string, string]> = [] |
| 55 | + const checker = (warning: string, rule: string) => { |
| 56 | + collected.push([warning, rule]) |
| 57 | + } |
| 58 | + |
| 59 | + const uno = await createGenerator({ |
| 60 | + presets: [presetWind4(), presetA11y(checker)], |
| 61 | + }) |
| 62 | + |
| 63 | + const { css } = await uno.generate('text-[11px] text-[12px] text-[1.5em]') |
| 64 | + |
| 65 | + expect(css).toMatchInlineSnapshot(` |
| 66 | + "/* layer: theme */ |
| 67 | + :root, :host { --font-sans: ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"; --font-mono: ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; --default-font-family: var(--font-sans); --default-monoFont-family: var(--font-mono); } |
| 68 | + /* layer: base */ |
| 69 | + *, ::after, ::before, ::backdrop, ::file-selector-button { box-sizing: border-box; margin: 0; padding: 0; border: 0 solid; } html, :host { line-height: 1.5; -webkit-text-size-adjust: 100%; tab-size: 4; font-family: var( --default-font-family, ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji' ); font-feature-settings: var(--default-font-featureSettings, normal); font-variation-settings: var(--default-font-variationSettings, normal); -webkit-tap-highlight-color: transparent; } hr { height: 0; color: inherit; border-top-width: 1px; } abbr:where([title]) { -webkit-text-decoration: underline dotted; text-decoration: underline dotted; } h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; } a { color: inherit; -webkit-text-decoration: inherit; text-decoration: inherit; } b, strong { font-weight: bolder; } code, kbd, samp, pre { font-family: var( --default-monoFont-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace ); font-feature-settings: var(--default-monoFont-featureSettings, normal); font-variation-settings: var(--default-monoFont-variationSettings, normal); font-size: 1em; } small { font-size: 80%; } sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sub { bottom: -0.25em; } sup { top: -0.5em; } table { text-indent: 0; border-color: inherit; border-collapse: collapse; } :-moz-focusring { outline: auto; } progress { vertical-align: baseline; } summary { display: list-item; } ol, ul, menu { list-style: none; } img, svg, video, canvas, audio, iframe, embed, object { display: block; vertical-align: middle; } img, video { max-width: 100%; height: auto; } button, input, select, optgroup, textarea, ::file-selector-button { font: inherit; font-feature-settings: inherit; font-variation-settings: inherit; letter-spacing: inherit; color: inherit; border-radius: 0; background-color: transparent; opacity: 1; } :where(select:is([multiple], [size])) optgroup { font-weight: bolder; } :where(select:is([multiple], [size])) optgroup option { padding-inline-start: 20px; } ::file-selector-button { margin-inline-end: 4px; } ::placeholder { opacity: 1; } @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) { ::placeholder { color: color-mix(in oklab, currentcolor 50%, transparent); } } textarea { resize: vertical; } ::-webkit-search-decoration { -webkit-appearance: none; } ::-webkit-date-and-time-value { min-height: 1lh; text-align: inherit; } ::-webkit-datetime-edit { display: inline-flex; } ::-webkit-datetime-edit-fields-wrapper { padding: 0; } ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field { padding-block: 0; } ::-webkit-calendar-picker-indicator { line-height: 1; } :-moz-ui-invalid { box-shadow: none; } button, input:where([type='button'], [type='reset'], [type='submit']), ::file-selector-button { appearance: button; } ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { height: auto; } [hidden]:where(:not([hidden~='until-found'])) { display: none !important; } |
| 70 | + /* layer: default */ |
| 71 | + .text-\\[11px\\]{font-size:11px;} |
| 72 | + .text-\\[12px\\]{font-size:12px;} |
| 73 | + .text-\\[1\\.5em\\]{font-size:1.5em;}" |
| 74 | + `) |
| 75 | + |
| 76 | + expect(warnSpy).not.toHaveBeenCalled() |
| 77 | + expect(collected).toMatchInlineSnapshot(` |
| 78 | + [ |
| 79 | + [ |
| 80 | + "[a11y] Avoid using 'text-[11px]', use 'text-2xs' instead.", |
| 81 | + "text-[11px]", |
| 82 | + ], |
| 83 | + [ |
| 84 | + "[a11y] Avoid using 'text-[12px]', use text-<size> classes or rem values instead of custom values.", |
| 85 | + "text-[12px]", |
| 86 | + ], |
| 87 | + [ |
| 88 | + "[a11y] Avoid using 'text-[1.5em]', use text-<size> classes or rem values instead of custom values.", |
| 89 | + "text-[1.5em]", |
| 90 | + ], |
| 91 | + ] |
| 92 | + `) |
| 93 | + }) |
| 94 | +}) |
0 commit comments