nanosplash
Version:
The tiny loading screen for web artisans
123 lines (105 loc) • 4.37 kB
text/typescript
import { describe, it, expect, beforeEach } from 'vitest'
import {useNs} from "@/composables/ns";
import type {INSElement} from "@/interfaces/INSElement";
import {Selectors} from "@/constants/ns";
const get = (selector: string) => document.querySelector(selector)
const getAll = (selector: string) => document.querySelectorAll(selector)
const div = (id?: string) => {
const element: HTMLDivElement = document.createElement("div")
if (id) {
element.id = id
}
return element
}
describe('useNs', () => {
let ns: ReturnType<typeof useNs>
beforeEach(() => {
// Reset DOM
document.body.innerHTML = ''
ns = useNs()
})
describe('show', () => {
it('creates a new Nanosplash with text', () => {
const id = ns.show('Loading...')
const nsElement = get(Selectors.ns)
const textElement = nsElement?.querySelector(Selectors.nsText)
const spinnerElement = nsElement?.querySelector(Selectors.nsSpinner)
expect(nsElement).toBeTruthy()
expect(textElement?.textContent).toBe('Loading...')
expect(spinnerElement).toBeTruthy()
expect(typeof id).toBe('number')
})
it('creates a new Nanosplash without text', () => {
const id = ns.show()
const nsElement = get(Selectors.ns)
const textElement = nsElement?.querySelector(Selectors.nsText)
expect(nsElement).toBeTruthy()
expect(textElement?.textContent).toBe(undefined)
expect(typeof id).toBe('number')
})
it('places Nanosplash inside a specified element', () => {
const container = div('container')
document.body.append(container)
ns.show('Inside', '#container')
const hostElement = container.querySelector(Selectors.ns)
expect(hostElement).toBeTruthy()
})
it('reuses an existing Nanosplash in the same container', () => {
ns.show('A')
const firstElement = get(Selectors.ns) as INSElement
const firstId = firstElement.nsId
ns.show('B')
const secondElement = get(Selectors.ns) as INSElement
const secondId = secondElement.nsId
const nsElements = getAll(Selectors.ns)
expect(firstId).toBe(secondId)
expect(nsElements.length).toBe(1)
})
})
describe('hide', () => {
it('removes the oldest Nanosplash element (FIFO)', () => {
document.body.append(div('a'), div('b'))
ns.show('A', '#a')
ns.show('B', '#b')
expect(getAll(Selectors.ns).length).toBe(2)
ns.hide()
expect(getAll(Selectors.ns).length).toBe(1)
expect(get(Selectors.nsText)?.textContent).toBe('B')
})
it('removes a specific Nanosplash by ID', () => {
document.body.append(div('a'), div('b'))
const idA = ns.show('A', '#a') as number
ns.show('B', '#b')
expect(getAll(Selectors.ns).length).toBe(2)
ns.hide(idA)
expect(getAll(Selectors.ns).length).toBe(1)
expect(get(Selectors.nsText)?.textContent).toBe('B')
})
it('removes all Nanosplash elements when given "*"', () => {
ns.show('One')
ns.show('Two')
ns.hide('*')
expect(getAll(Selectors.ns).length).toBe(0)
})
})
describe('style injection', () => {
it('injects the style element into the document', () => {
const styleElement = get('style#ns')
expect(styleElement).toBeTruthy()
expect(styleElement).toBeInstanceOf(HTMLStyleElement)
})
it('replaces an existing style element when re-invoked', () => {
const oldStyleElement = get('style#ns') as HTMLElement
useNs()
const newStyleElement = get('style#ns') as HTMLElement
expect(newStyleElement).toBeTruthy()
expect(newStyleElement).not.toBe(oldStyleElement)
})
})
describe('version', () => {
it('exposes the version from package.json', () => {
expect(typeof ns.version).toBe('string')
expect(ns.version).toMatch(/^\d+\.\d+\.\d+/)
})
})
})