Skip to content

Commit

Permalink
add test 'MultiSelect applies style props to the correct element'
Browse files Browse the repository at this point in the history
  • Loading branch information
janosh committed Jan 14, 2024
1 parent 3147363 commit 23a1453
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 15 deletions.
12 changes: 8 additions & 4 deletions src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,30 @@ export const get_label = (opt: Option) => {
return `${opt}`
}

// this function is used extract CSS strings from a {selected, option} style object to be used in the style attribute of the option
// if the style is a string, it will be returned as is
export function get_style(
option: { style?: OptionStyle; [key: string]: unknown } | string | number,
key: 'selected' | 'option' | null = null,
) {
if (!option?.style) return null
let css_str = ``
if (![`selected`, `option`, null].includes(key)) {
console.error(`MultiSelect: Invalid key=${key} for get_style`)
return
}
if (typeof option == `object` && option.style) {
if (typeof option.style == `string`) {
return option.style
css_str = option.style
}
if (typeof option.style == `object`) {
if (key && key in option.style) return option.style[key]
if (key && key in option.style) return option.style[key] ?? ``
else {
console.error(
`Invalid style object for option=${JSON.stringify(option)}`,
)
}
}
}
// ensure css_str ends with a semicolon
if (css_str.trim() && !css_str.trim().endsWith(`;`)) css_str += `;`
return css_str
}
50 changes: 39 additions & 11 deletions tests/unit/MultiSelect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1200,15 +1200,18 @@ test.each([[true], [-1], [3.5], [`foo`], [{}]])(
},
)

const css_str = `test-style`

test.each([
// Invalid key cases
[css_str, `invalid`, `MultiSelect: Invalid key=invalid for get_style`],
[
`test-style`,
`invalid`,
`test-style;`,
`MultiSelect: Invalid key=invalid for get_style`,
],
// Valid key cases
[css_str, `selected`, css_str],
[css_str, `option`, css_str],
[css_str, null, css_str],
[`test-style`, `selected`, `test-style;`],
[`test-style`, `option`, `test-style;`],
[`test-style`, null, `test-style;`],
// Object style cases
[
{ selected: `selected-style`, option: `option-style` },
Expand All @@ -1224,24 +1227,24 @@ test.each([
[
{ invalid: `invalid-style` },
`selected`,
``,
`Invalid style object for option=${JSON.stringify({
style: { invalid: `invalid-style` },
})}`,
],
])(
`get_style returns correct style for different option and key combinations`,
async (style, key, expected) => {
`get_style returns and console.errors correctly (%s, %s, %s, %s)`,
async (style, key, expected, err_msg = ``) => {
console.error = vi.fn()

// @ts-expect-error test invalid option
const result = get_style({ style }, key)

if (expected.startsWith(`Invalid`) || expected.startsWith(`MultiSelect`)) {
expect(console.error).toHaveBeenCalledTimes(1)
expect(console.error).toHaveBeenCalledWith(expected)
} else {
expect(result).toBe(expected)
expect(console.error).toHaveBeenCalledWith(err_msg)
}
expect(result).toBe(expected)
},
)

Expand Down Expand Up @@ -1287,6 +1290,31 @@ test.each([
},
)

test.each([
[`style`, `div.multiselect`],
[`ulSelectedStyle`, `ul.selected`],
[`ulOptionsStyle`, `ul.options`],
[`liSelectedStyle`, `ul.selected > li`],
[`liOptionStyle`, `ul.options > li`],
[`inputStyle`, `input[autocomplete]`],
])(
`MultiSelect applies style props to the correct element`,
async (prop, css_selector) => {
const css_str = `font-weight: bold; color: red;`
new MultiSelect({
target: document.body,
props: { options: [1, 2, 3], [prop]: css_str, selected: [1] },
})

await tick()

const err_msg = `${prop} (${css_selector})`
const elem = doc_query(css_selector)
await tick()
expect(elem?.style.cssText, err_msg).toContain(css_str)
},
)

test.each([true, false, `desktop`] as const)(
`closeDropdownOnSelect=%s controls input focus and dropdown closing`,
async (closeDropdownOnSelect) => {
Expand Down

0 comments on commit 23a1453

Please sign in to comment.