Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unit tests #535

Merged
merged 12 commits into from
Mar 28, 2024
27 changes: 27 additions & 0 deletions .github/workflows/jest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: 'Jest unit tests'
on:
push:
paths-ignore:
- '**/dist/**'
- '**/*.md'
- '.github/**'
- '.vscode/**'
pull_request:
branches:
- develop
paths-ignore:
- '**/dist/**'
- '**/*.md'
- '.github/**'
- '.vscode/**'
jobs:
jest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '21.5.0'
cache: 'npm'
- run: npm ci
- run: npm run test
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**/dist
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Advanced select dropdown

[![NPM Downloads](https://img.shields.io/npm/dt/slim-select.svg)](https://www.npmjs.com/package/slim-select)
![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/brianvoe/slim-select/jest.yml?logo=jest&label=unit%20tests)

## Support

Expand Down
6 changes: 6 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,10 @@ module.exports = {
testEnvironment: 'jsdom',
testMatch: ['**/*.test.ts'],
roots: ['./src/slim-select'],
reporters: process.env.CI ? [['github-actions', {silent: false}], 'summary'] : ['default'],
coverageThreshold: {
global: {
lines: 75,
},
},
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@
"build:library:js": "cd src/slim-select && rollup --config ./rollup.config.mjs && cd ../../",
"build:library:css": "cd src/slim-select && sass ./slimselect.scss ../../dist/slimselect.css --style=compressed && cd ../../",
"build:frameworks": "npm run build --workspaces",
"test": "jest"
"test": "jest",
"test:coverage": "jest --coverage"
},
"devDependencies": {
"@jest/globals": "^29.7.0",
Expand Down
71 changes: 71 additions & 0 deletions src/slim-select/css_classes.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
'use strict'
import { describe, expect, test } from '@jest/globals'
import CssClasses from './css_classes'

const defaultClasses: { [key: string]: string } = {
main: 'ss-main',
placeholder: 'ss-placeholder',
values: 'ss-values',
single: 'ss-single',
max: 'ss-max',
value: 'ss-value',
valueText: 'ss-value-text',
valueDelete: 'ss-value-delete',
valueOut: 'ss-value-out',
deselect: 'ss-deselect',
deselectPath: 'M10,10 L90,90 M10,90 L90,10',
arrow: 'ss-arrow',
arrowClose: 'M10,30 L50,70 L90,30',
arrowOpen: 'M10,70 L50,30 L90,70',
content: 'ss-content',
openAbove: 'ss-open-above',
openBelow: 'ss-open-below',
search: 'ss-search',
searchHighlighter: 'ss-search-highlight',
searching: 'ss-searching',
addable: 'ss-addable',
addablePath: 'M50,10 L50,90 M10,50 L90,50',
list: 'ss-list',
optgroup: 'ss-optgroup',
optgroupLabel: 'ss-optgroup-label',
optgroupLabelText: 'ss-optgroup-label-text',
optgroupActions: 'ss-optgroup-actions',
optgroupSelectAll: 'ss-selectall',
optgroupSelectAllBox: 'M60,10 L10,10 L10,90 L90,90 L90,50',
optgroupSelectAllCheck: 'M30,45 L50,70 L90,10',
optgroupClosable: 'ss-closable',
option: 'ss-option',
optionDelete: 'M10,10 L90,90 M10,90 L90,10',
highlighted: 'ss-highlighted',
open: 'ss-open',
close: 'ss-close',
selected: 'ss-selected',
error: 'ss-error',
disabled: 'ss-disabled',
hide: 'ss-hide',
}

describe('CssClasses module', () => {
test('empty constructor returns default classes', () => {
// We test the traditional classes here. Since old versions of slim-select didn't allow CSS class overrides, users
// may have written their CSS to match those classes, which means we should never change them in the library.

// Convert to unknown and then to custom object to prevent TS from throwing errors
const classes = new CssClasses() as unknown as { [key: string]: string }
Object.keys(defaultClasses).forEach((key) => {
expect(classes[key]).toBe(defaultClasses[key])
})
})

test('classes can be overwritten via the constructor', () => {
const classesWithOverride = JSON.parse(JSON.stringify(defaultClasses))
classesWithOverride['main'] = 'new-main'
classesWithOverride['open'] = 'new-open'

// Convert to unknown and then to custom object to prevent TS from throwing errors
const classes = new CssClasses({ main: 'new-main', open: 'new-open' }) as unknown as { [key: string]: string }
Object.keys(classesWithOverride).forEach((key) => {
expect(classes[key]).toBe(classesWithOverride[key])
})
})
})
192 changes: 96 additions & 96 deletions src/slim-select/css_classes.ts
Original file line number Diff line number Diff line change
@@ -1,111 +1,111 @@
export type CssClassesPartial = Partial<CssClasses>

export default class CssClasses {
public main: string
// Placeholder
public placeholder: string
public main: string
// Placeholder
public placeholder: string

// Values
public values: string
public single: string
public max: string
public value: string
public valueText: string
public valueDelete: string
public valueOut: string
// Values
public values: string
public single: string
public max: string
public value: string
public valueText: string
public valueDelete: string
public valueOut: string

// Deselect
public deselect: string
public deselectPath: string // Not a class but whatever
// Deselect
public deselect: string
public deselectPath: string // Not a class but whatever

// Arrow
public arrow: string
public arrowClose: string // Not a class but whatever
public arrowOpen: string // Not a class but whatever
// Arrow
public arrow: string
public arrowClose: string // Not a class but whatever
public arrowOpen: string // Not a class but whatever

// Content
public content: string
public openAbove: string
public openBelow: string
// Content
public content: string
public openAbove: string
public openBelow: string

// Search
public search: string
public searchHighlighter: string
public searching: string
public addable: string
public addablePath: string // Not a class but whatever
// Search
public search: string
public searchHighlighter: string
public searching: string
public addable: string
public addablePath: string // Not a class but whatever

// List optgroups/options
public list: string
// List optgroups/options
public list: string

// Optgroup
public optgroup: string
public optgroupLabel: string
public optgroupLabelText: string
public optgroupActions: string
public optgroupSelectAll: string // optgroup select all
public optgroupSelectAllBox: string // Not a class but whatever
public optgroupSelectAllCheck: string // Not a class but whatever
public optgroupClosable: string
// Optgroup
public optgroup: string
public optgroupLabel: string
public optgroupLabelText: string
public optgroupActions: string
public optgroupSelectAll: string // optgroup select all
public optgroupSelectAllBox: string // Not a class but whatever
public optgroupSelectAllCheck: string // Not a class but whatever
public optgroupClosable: string

// Option
public option: string
public optionDelete: string // Not a class but whatever
public highlighted: string
// Option
public option: string
public optionDelete: string // Not a class but whatever
public highlighted: string

// Misc
public open: string
public close: string
public selected: string
public error: string
public disabled: string
public hide: string

constructor(classes?: CssClassesPartial) {
if (!classes) {
classes = {}
}

this.main = classes.main || 'ss-main'
this.placeholder = classes.placeholder || 'ss-placeholder'
this.values = classes.values || 'ss-values'
this.single = classes.single || 'ss-single'
this.max = classes.max || 'ss-max'
this.value = classes.value || 'ss-value'
this.valueText = classes.valueText || 'ss-value-text'
this.valueDelete = classes.valueDelete || 'ss-value-delete'
this.valueOut = classes.valueOut || 'ss-value-out'
// Misc
public open: string
public close: string
public selected: string
public error: string
public disabled: string
public hide: string

this.deselect = classes.deselect || 'ss-deselect'
this.deselectPath = classes.deselectPath || 'M10,10 L90,90 M10,90 L90,10'
this.arrow = classes.arrow || 'ss-arrow'
this.arrowClose = classes.arrowClose || 'M10,30 L50,70 L90,30'
this.arrowOpen = classes.arrowOpen || 'M10,70 L50,30 L90,70'
this.content = classes.content || 'ss-content'
this.openAbove = classes.openAbove || 'ss-open-above'
this.openBelow = classes.openBelow || 'ss-open-below'
this.search = classes.search || 'ss-search'
this.searchHighlighter = classes.searchHighlighter || 'ss-search-highlight'
this.searching = classes.searching || 'ss-searching'
this.addable = classes.addable || 'ss-addable'
this.addablePath = classes.addablePath || 'M50,10 L50,90 M10,50 L90,50'
this.list = classes.list || 'ss-list'
this.optgroup = classes.optgroup || 'ss-optgroup'
this.optgroupLabel = classes.optgroupLabel || 'ss-optgroup-label'
this.optgroupLabelText = classes.optgroupLabelText || 'ss-optgroup-label-text'
this.optgroupActions = classes.optgroupActions || 'ss-optgroup-actions'
this.optgroupSelectAll = classes.optgroupSelectAll || 'ss-selectall'
this.optgroupSelectAllBox = classes.optgroupSelectAllBox || 'M60,10 L10,10 L10,90 L90,90 L90,50'
this.optgroupSelectAllCheck = classes.optgroupSelectAllCheck || 'M30,45 L50,70 L90,10'
this.optgroupClosable = classes.optgroupClosable || 'ss-closable'
this.option = classes.option || 'ss-option'
this.optionDelete = classes.optionDelete || 'M10,10 L90,90 M10,90 L90,10'
this.highlighted = classes.highlighted || 'ss-highlighted'
this.open = classes.open || 'ss-open'
this.close = classes.close || 'ss-close'
this.selected = classes.selected || 'ss-selected'
this.error = classes.error || 'ss-error'
this.disabled = classes.disabled || 'ss-disabled'
this.hide = classes.hide || 'ss-hide'
constructor(classes?: CssClassesPartial) {
if (!classes) {
classes = {}
}

this.main = classes.main || 'ss-main'
this.placeholder = classes.placeholder || 'ss-placeholder'
this.values = classes.values || 'ss-values'
this.single = classes.single || 'ss-single'
this.max = classes.max || 'ss-max'
this.value = classes.value || 'ss-value'
this.valueText = classes.valueText || 'ss-value-text'
this.valueDelete = classes.valueDelete || 'ss-value-delete'
this.valueOut = classes.valueOut || 'ss-value-out'

this.deselect = classes.deselect || 'ss-deselect'
this.deselectPath = classes.deselectPath || 'M10,10 L90,90 M10,90 L90,10'
this.arrow = classes.arrow || 'ss-arrow'
this.arrowClose = classes.arrowClose || 'M10,30 L50,70 L90,30'
this.arrowOpen = classes.arrowOpen || 'M10,70 L50,30 L90,70'
this.content = classes.content || 'ss-content'
this.openAbove = classes.openAbove || 'ss-open-above'
this.openBelow = classes.openBelow || 'ss-open-below'
this.search = classes.search || 'ss-search'
this.searchHighlighter = classes.searchHighlighter || 'ss-search-highlight'
this.searching = classes.searching || 'ss-searching'
this.addable = classes.addable || 'ss-addable'
this.addablePath = classes.addablePath || 'M50,10 L50,90 M10,50 L90,50'
this.list = classes.list || 'ss-list'
this.optgroup = classes.optgroup || 'ss-optgroup'
this.optgroupLabel = classes.optgroupLabel || 'ss-optgroup-label'
this.optgroupLabelText = classes.optgroupLabelText || 'ss-optgroup-label-text'
this.optgroupActions = classes.optgroupActions || 'ss-optgroup-actions'
this.optgroupSelectAll = classes.optgroupSelectAll || 'ss-selectall'
this.optgroupSelectAllBox = classes.optgroupSelectAllBox || 'M60,10 L10,10 L10,90 L90,90 L90,50'
this.optgroupSelectAllCheck = classes.optgroupSelectAllCheck || 'M30,45 L50,70 L90,10'
this.optgroupClosable = classes.optgroupClosable || 'ss-closable'
this.option = classes.option || 'ss-option'
this.optionDelete = classes.optionDelete || 'M10,10 L90,90 M10,90 L90,10'
this.highlighted = classes.highlighted || 'ss-highlighted'
this.open = classes.open || 'ss-open'
this.close = classes.close || 'ss-close'
this.selected = classes.selected || 'ss-selected'
this.error = classes.error || 'ss-error'
this.disabled = classes.disabled || 'ss-disabled'
this.hide = classes.hide || 'ss-hide'
}
}
Loading