update tests

This commit is contained in:
Chris Wanstrath 2025-12-28 19:31:53 -08:00
parent 8a8428e5ca
commit 5be72837ee
2 changed files with 147 additions and 6 deletions

View File

@ -216,4 +216,5 @@ export function define(nameOrDef: string | TagDef, defIfNamed?: TagDef) {
} }
} }
// shortcut so you only have to import one thing, if you want
define.Styles = Styles define.Styles = Styles

View File

@ -744,6 +744,147 @@ describe('variants on parts via props', () => {
}) })
}) })
describe('base with attributes', () => {
test('extracts element name from base with attributes', () => {
const Component = define('InputRadio', {
base: 'input[type=radio]',
display: 'block'
})
const html = renderToString(Component({}))
expect(html).toContain('<input')
expect(html).toContain('type="radio"')
expect(html).toContain('class="InputRadio"')
})
test('extracts multiple attribute formats', () => {
const Component = define('InputCheckbox', {
base: 'input[type=checkbox]'
})
const html = renderToString(Component({}))
expect(html).toContain('type="checkbox"')
})
test('works without attributes', () => {
const Component = define('PlainInput', {
base: 'input',
padding: 10
})
const html = renderToString(Component({}))
expect(html).toContain('<input')
expect(html).not.toContain('type=')
})
test('base attributes can be overridden by props', () => {
const Component = define('OverridableInput', {
base: 'input[type=text]'
})
const html = renderToString(Component({ type: 'email' }))
expect(html).toContain('type="email"')
})
})
describe('selectors with @ and &', () => {
test('generates CSS for selectors with @PartName', () => {
define('SelectorTest', {
parts: {
Input: { base: 'input[type=checkbox]', display: 'none' },
Label: {
base: 'label',
color: '#666',
selectors: {
'@Input:checked + &': {
color: 'blue'
}
}
}
}
})
const css = getStylesCSS()
expect(css).toContain('.SelectorTest_Input:checked + .SelectorTest_Label')
expect(css).toContain('color: blue')
})
test('selectors support general sibling combinator ~', () => {
define('SiblingTest', {
parts: {
Trigger: { base: 'input[type=checkbox]' },
Content: {
display: 'none',
selectors: {
'@Trigger:checked ~ &': {
display: 'block'
}
}
}
}
})
const css = getStylesCSS()
expect(css).toContain('.SiblingTest_Trigger:checked ~ .SiblingTest_Content')
expect(css).toContain('display: block')
})
test('selectors can include pseudo-classes on &', () => {
define('PseudoTest', {
parts: {
Radio: { base: 'input[type=radio]', display: 'none' },
Label: {
base: 'label',
selectors: {
'@Radio:checked + &:hover': {
background: 'lightblue'
}
}
}
}
})
const css = getStylesCSS()
expect(css).toContain('.PseudoTest_Radio:checked + .PseudoTest_Label:hover')
expect(css).toContain('background: lightblue')
})
test('selectors work on root level', () => {
define('RootSelectorTest', {
color: 'black',
selectors: {
'&:hover': {
color: 'blue'
}
}
})
const css = getStylesCSS()
expect(css).toContain('.RootSelectorTest:hover')
expect(css).toContain('color: blue')
})
test('supports multiple selectors', () => {
define('MultiSelectorTest', {
parts: {
Input: { base: 'input[type=checkbox]' },
Label: {
selectors: {
'@Input:checked + &': { color: 'green' },
'@Input:disabled + &': { opacity: 0.5 }
}
}
}
})
const css = getStylesCSS()
expect(css).toContain('.MultiSelectorTest_Input:checked + .MultiSelectorTest_Label')
expect(css).toContain('color: green')
expect(css).toContain('.MultiSelectorTest_Input:disabled + .MultiSelectorTest_Label')
expect(css).toContain('opacity: 0.5')
})
})
describe('edge cases', () => { describe('edge cases', () => {
test('handles empty definition', () => { test('handles empty definition', () => {
const Component = define({}) const Component = define({})
@ -777,13 +918,12 @@ describe('edge cases', () => {
expect(html).toContain('size-small') expect(html).toContain('size-small')
}) })
test('does not duplicate styles when registered multiple times', () => { test('throws error when defining duplicate component names', () => {
define('NoDuplicate', { width: 100 }) define('NoDuplicateTest', { width: 100 })
define('NoDuplicate', { width: 200 })
const styles = parseCSS(getStylesCSS()) expect(() => {
// Should keep first value (??= operator) define('NoDuplicateTest', { width: 200 })
expect(styles['NoDuplicate']?.['width']).toBe('100px') }).toThrow('NoDuplicateTest is already defined! Must use unique names.')
}) })
test('handles complex nested structures', () => { test('handles complex nested structures', () => {