Set up vitest and add tests for interactive
This commit is contained in:
parent
4bd89c4c8c
commit
5369f2c25a
25 changed files with 4546 additions and 2163 deletions
1
styles/.gitignore
vendored
1
styles/.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
node_modules/
|
||||
coverage/
|
||||
|
|
2306
styles/package-lock.json
generated
2306
styles/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -6,7 +6,8 @@
|
|||
"scripts": {
|
||||
"build": "ts-node ./src/buildThemes.ts",
|
||||
"build-licenses": "ts-node ./src/buildLicenses.ts",
|
||||
"build-tokens": "ts-node ./src/buildTokens.ts"
|
||||
"build-tokens": "ts-node ./src/buildTokens.ts",
|
||||
"test": "vitest"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
|
@ -22,12 +23,16 @@
|
|||
"toml": "^3.0.0",
|
||||
"ts-deepmerge": "^6.0.3",
|
||||
"ts-node": "^10.9.1",
|
||||
"utility-types": "^3.10.0"
|
||||
"utility-types": "^3.10.0",
|
||||
"vitest": "^0.32.0"
|
||||
},
|
||||
"prettier": {
|
||||
"semi": false,
|
||||
"printWidth": 80,
|
||||
"htmlWhitespaceSensitivity": "strict",
|
||||
"tabWidth": 4
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitest/coverage-v8": "^0.32.0"
|
||||
}
|
||||
}
|
||||
|
|
3
styles/src/element/interactive/index.ts
Normal file
3
styles/src/element/interactive/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import { interactive } from "./interactive";
|
||||
|
||||
export { interactive }
|
59
styles/src/element/interactive/interactive.test.ts
Normal file
59
styles/src/element/interactive/interactive.test.ts
Normal file
|
@ -0,0 +1,59 @@
|
|||
import { NOT_ENOUGH_STATES_ERROR, NO_DEFAULT_OR_BASE_ERROR, interactive } from './interactive'
|
||||
import { describe, it, expect } from 'vitest'
|
||||
|
||||
describe('interactive', () => {
|
||||
|
||||
it('creates an Interactive<Element> with base properties and states', () => {
|
||||
|
||||
const result = interactive({
|
||||
base: { fontSize: 10, color: '#FFFFFF' },
|
||||
state: {
|
||||
hovered: { color: '#EEEEEE' },
|
||||
clicked: { color: '#CCCCCC' },
|
||||
}
|
||||
})
|
||||
|
||||
expect(result).toEqual({
|
||||
default: { color: '#FFFFFF', fontSize: 10 },
|
||||
hovered: { color: '#EEEEEE', fontSize: 10 },
|
||||
clicked: { color: '#CCCCCC', fontSize: 10 },
|
||||
})
|
||||
})
|
||||
|
||||
it('creates an Interactive<Element> with no base properties', () => {
|
||||
|
||||
const result = interactive({
|
||||
state: {
|
||||
default: { color: '#FFFFFF', fontSize: 10 },
|
||||
hovered: { color: '#EEEEEE' },
|
||||
clicked: { color: '#CCCCCC' },
|
||||
}
|
||||
})
|
||||
|
||||
expect(result).toEqual({
|
||||
default: { color: '#FFFFFF', fontSize: 10 },
|
||||
hovered: { color: '#EEEEEE', fontSize: 10 },
|
||||
clicked: { color: '#CCCCCC', fontSize: 10 },
|
||||
})
|
||||
})
|
||||
|
||||
it('throws error when both default and base are missing', () => {
|
||||
const state = {
|
||||
hovered: { color: 'blue' },
|
||||
}
|
||||
|
||||
expect(() => interactive({ state })).toThrow(
|
||||
NO_DEFAULT_OR_BASE_ERROR
|
||||
)
|
||||
})
|
||||
|
||||
it('throws error when no other state besides default is present', () => {
|
||||
const state = {
|
||||
default: { fontSize: 10 },
|
||||
}
|
||||
|
||||
expect(() => interactive({ state })).toThrow(
|
||||
NOT_ENOUGH_STATES_ERROR
|
||||
)
|
||||
})
|
||||
})
|
|
@ -10,24 +10,27 @@ type Interactive<T> = {
|
|||
disabled?: T,
|
||||
};
|
||||
|
||||
export const NO_DEFAULT_OR_BASE_ERROR = "An interactive object must have a default state, or a base property."
|
||||
export const NOT_ENOUGH_STATES_ERROR = "An interactive object must have a default and at least one other state."
|
||||
|
||||
interface InteractiveProps<T> {
|
||||
base?: T,
|
||||
state: Partial<Record<InteractiveState, T>>
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for creating Interactive<T> objects that works pretty much like Toggle<T>.
|
||||
* It takes a object to be used as a value for `default` field and then fills out other fields
|
||||
* with fields from either `base` or `modifications`.
|
||||
* Notably, it does not touch `hover`, `clicked` and `disabled` if there are no modifications for it.
|
||||
* Helper function for creating Interactive<T> objects that works with Toggle<T>-like behavior.
|
||||
* It takes a default object to be used as the value for `default` field and fills out other fields
|
||||
* with fields from either `base` or from the `state` object which contains values for specific states.
|
||||
* Notably, it does not touch `hover`, `clicked`, `selected` and `disabled` states if there are no modifications for them.
|
||||
*
|
||||
* @param defaultObj Object to be used as the value for `default` field.
|
||||
* @param base Object containing base fields to be included in the resulting object.
|
||||
* @param modifications Object containing modified fields to be included in the resulting object.
|
||||
* @returns Interactive<T> object with fields from `base` and `modifications`.
|
||||
* @param defaultObj Object to be used as the value for the `default` field.
|
||||
* @param base Optional object containing base fields to be included in the resulting object.
|
||||
* @param state Object containing optional modified fields to be included in the resulting object for each state.
|
||||
* @returns Interactive<T> object with fields from `base` and `state`.
|
||||
*/
|
||||
export function interactive<T extends Object>({ base, state }: InteractiveProps<T>): Interactive<T> {
|
||||
if (!base && !state.default) throw new Error("An interactive object must have a default state, or a base property.");
|
||||
if (!base && !state.default) throw new Error(NO_DEFAULT_OR_BASE_ERROR);
|
||||
|
||||
let defaultState: T;
|
||||
|
||||
|
@ -64,7 +67,7 @@ export function interactive<T extends Object>({ base, state }: InteractiveProps<
|
|||
}
|
||||
|
||||
if (stateCount < 1) {
|
||||
throw new Error("An interactive object must have a default and at least one other state.");
|
||||
throw new Error(NOT_ENOUGH_STATES_ERROR);
|
||||
}
|
||||
|
||||
return interactiveObj;
|
|
@ -1,7 +1,7 @@
|
|||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { text, border, background, foreground } from "./components"
|
||||
import editor from "./editor"
|
||||
import { interactive } from "./interactive"
|
||||
import { interactive } from "../element/interactive"
|
||||
|
||||
export default function assistant(colorScheme: ColorScheme) {
|
||||
const layer = colorScheme.highest
|
||||
|
|
|
@ -2,7 +2,7 @@ import { ColorScheme } from "../theme/colorScheme"
|
|||
import { withOpacity } from "../theme/color"
|
||||
import { text, background } from "./components"
|
||||
import { toggleable } from "./toggle"
|
||||
import { interactive } from "./interactive"
|
||||
import { interactive } from "../element/interactive"
|
||||
|
||||
export default function commandPalette(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.highest
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, border, borderColor, foreground, text } from "./components"
|
||||
import { toggleable } from "./toggle"
|
||||
import { interactive } from "./interactive"
|
||||
import { interactive } from "../element/interactive"
|
||||
export default function contactsPanel(colorScheme: ColorScheme) {
|
||||
const nameMargin = 8
|
||||
const sidePadding = 12
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, foreground, text } from "./components"
|
||||
import { interactive } from "./interactive"
|
||||
import { interactive } from "../element/interactive"
|
||||
const avatarSize = 12
|
||||
const headerPadding = 8
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, border, borderColor, text } from "./components"
|
||||
import { interactive } from "./interactive"
|
||||
import { interactive } from "../element/interactive"
|
||||
import { toggleable } from "./toggle"
|
||||
|
||||
export default function contextMenu(colorScheme: ColorScheme) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, border, foreground, svg, text } from "./components"
|
||||
import { interactive } from "./interactive"
|
||||
import { interactive } from "../element/interactive"
|
||||
export default function copilot(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.middle
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import { background, border, borderColor, foreground, text } from "./components"
|
|||
import hoverPopover from "./hoverPopover"
|
||||
|
||||
import { buildSyntax } from "../theme/syntax"
|
||||
import { interactive } from "./interactive"
|
||||
import { interactive } from "../element/interactive"
|
||||
import { toggleable } from "./toggle"
|
||||
|
||||
export default function editor(colorScheme: ColorScheme) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, border, text } from "./components"
|
||||
import { interactive } from "./interactive"
|
||||
import { interactive } from "../element/interactive"
|
||||
|
||||
export default function feedback(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.highest
|
||||
|
|
|
@ -2,7 +2,7 @@ import { ColorScheme } from "../theme/colorScheme"
|
|||
import { withOpacity } from "../theme/color"
|
||||
import { background, border, text } from "./components"
|
||||
import { toggleable } from "./toggle"
|
||||
import { interactive } from "./interactive"
|
||||
import { interactive } from "../element/interactive"
|
||||
|
||||
export default function picker(colorScheme: ColorScheme): any {
|
||||
let layer = colorScheme.lowest
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { withOpacity } from "../theme/color"
|
||||
import { background, border, foreground, text } from "./components"
|
||||
import { interactive } from "./interactive"
|
||||
import { interactive } from "../element/interactive"
|
||||
import { toggleable } from "./toggle"
|
||||
export default function projectPanel(colorScheme: ColorScheme) {
|
||||
const { isLight } = colorScheme
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { withOpacity } from "../theme/color"
|
||||
import { background, border, foreground, text } from "./components"
|
||||
import { interactive } from "./interactive"
|
||||
import { interactive } from "../element/interactive"
|
||||
import { toggleable } from "./toggle"
|
||||
|
||||
export default function search(colorScheme: ColorScheme) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, border, foreground, text } from "./components"
|
||||
import { interactive } from "./interactive"
|
||||
import { interactive } from "../element/interactive"
|
||||
|
||||
const headerPadding = 8
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, border, foreground, text } from "./components"
|
||||
import { interactive } from "./interactive"
|
||||
import { interactive } from "../element/interactive"
|
||||
import { toggleable } from "./toggle"
|
||||
export default function statusBar(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.lowest
|
||||
|
|
|
@ -2,7 +2,7 @@ import { ColorScheme } from "../theme/colorScheme"
|
|||
import { withOpacity } from "../theme/color"
|
||||
import { text, border, background, foreground } from "./components"
|
||||
import { toggleable } from "./toggle"
|
||||
import { interactive } from "./interactive"
|
||||
import { interactive } from "../element/interactive"
|
||||
|
||||
export default function tabBar(colorScheme: ColorScheme) {
|
||||
const height = 32
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, border, text } from "./components"
|
||||
import { interactive } from "./interactive"
|
||||
import { interactive } from "../element/interactive"
|
||||
import { toggleable } from "./toggle"
|
||||
export default function dropdownMenu(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.middle
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { foreground, text } from "./components"
|
||||
import { interactive } from "./interactive"
|
||||
import { interactive } from "../element/interactive"
|
||||
|
||||
const headerPadding = 8
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
TextProperties,
|
||||
svg,
|
||||
} from "./components"
|
||||
import { interactive } from "./interactive"
|
||||
import { interactive } from "../element/interactive"
|
||||
|
||||
export default function welcome(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.highest
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
} from "./components"
|
||||
import statusBar from "./statusBar"
|
||||
import tabBar from "./tabBar"
|
||||
import { interactive } from "./interactive"
|
||||
import { interactive } from "../element/interactive"
|
||||
import merge from 'ts-deepmerge';
|
||||
export default function workspace(colorScheme: ColorScheme) {
|
||||
const layer = colorScheme.lowest
|
||||
|
|
8
styles/vitest.config.ts
Normal file
8
styles/vitest.config.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { configDefaults, defineConfig } from 'vitest/config'
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
exclude: [...configDefaults.exclude, 'target/*'],
|
||||
include: ['src/**/*.{spec,test}.ts'],
|
||||
},
|
||||
})
|
Loading…
Add table
Add a link
Reference in a new issue