- Introduced .editorconfig for consistent coding styles across the project. - Added .golangci.yml for Go linting configuration. - Updated AGENTS.md to clarify project structure and components. - Enhanced CONTRIBUTING.md with Makefile usage for common tasks. - Updated Dockerfiles to use Go 1.24 and improved build instructions. - Refined README.md and deployment documentation for clarity. - Added testing documentation in testing.md for backend and frontend tests. - Introduced Makefile for streamlined development commands and tasks.
135 lines
4.3 KiB
TypeScript
135 lines
4.3 KiB
TypeScript
import { describe, it, expect, vi } from 'vitest'
|
|
import {
|
|
createUniqueList,
|
|
uniqueListUpdate,
|
|
uniqueListGetElements,
|
|
uniqueListById,
|
|
} from '../UniqueList'
|
|
|
|
interface Item {
|
|
id: number
|
|
name: string
|
|
}
|
|
|
|
describe('createUniqueList', () => {
|
|
it('creates an empty list', () => {
|
|
const list = createUniqueList<Item>()
|
|
expect(list.elements).toEqual({})
|
|
expect(uniqueListGetElements(list)).toEqual([])
|
|
})
|
|
})
|
|
|
|
describe('uniqueListUpdate', () => {
|
|
it('adds new elements', () => {
|
|
const list = createUniqueList<Item>()
|
|
const addCb = vi.fn()
|
|
|
|
uniqueListUpdate(list, [{ id: 1, name: 'a' }, { id: 2, name: 'b' }], addCb)
|
|
|
|
expect(addCb).toHaveBeenCalledTimes(2)
|
|
expect(uniqueListGetElements(list)).toHaveLength(2)
|
|
expect(uniqueListById(list, 1)).toEqual({ id: 1, name: 'a' })
|
|
expect(uniqueListById(list, 2)).toEqual({ id: 2, name: 'b' })
|
|
})
|
|
|
|
it('removes elements no longer present', () => {
|
|
const list = createUniqueList<Item>()
|
|
const removeCb = vi.fn()
|
|
|
|
uniqueListUpdate(list, [{ id: 1, name: 'a' }, { id: 2, name: 'b' }])
|
|
uniqueListUpdate(list, [{ id: 1, name: 'a' }], undefined, removeCb)
|
|
|
|
expect(removeCb).toHaveBeenCalledTimes(1)
|
|
expect(removeCb).toHaveBeenCalledWith({ id: 2, name: 'b' })
|
|
expect(uniqueListGetElements(list)).toHaveLength(1)
|
|
expect(uniqueListById(list, 2)).toBeUndefined()
|
|
})
|
|
|
|
it('calls update callback for existing elements', () => {
|
|
const list = createUniqueList<Item>()
|
|
const updateCb = vi.fn()
|
|
|
|
uniqueListUpdate(list, [{ id: 1, name: 'a' }])
|
|
uniqueListUpdate(list, [{ id: 1, name: 'updated' }], undefined, undefined, updateCb)
|
|
|
|
expect(updateCb).toHaveBeenCalledTimes(1)
|
|
expect(updateCb).toHaveBeenCalledWith({ id: 1, name: 'a' }, { id: 1, name: 'updated' })
|
|
})
|
|
|
|
it('handles all callbacks together', () => {
|
|
const list = createUniqueList<Item>()
|
|
const addCb = vi.fn()
|
|
const removeCb = vi.fn()
|
|
const updateCb = vi.fn()
|
|
|
|
uniqueListUpdate(list, [{ id: 1, name: 'keep' }, { id: 2, name: 'remove' }])
|
|
|
|
uniqueListUpdate(
|
|
list,
|
|
[{ id: 1, name: 'kept' }, { id: 3, name: 'new' }],
|
|
addCb,
|
|
removeCb,
|
|
updateCb,
|
|
)
|
|
|
|
expect(addCb).toHaveBeenCalledTimes(1)
|
|
expect(addCb).toHaveBeenCalledWith({ id: 3, name: 'new' })
|
|
expect(removeCb).toHaveBeenCalledTimes(1)
|
|
expect(removeCb).toHaveBeenCalledWith({ id: 2, name: 'remove' })
|
|
expect(updateCb).toHaveBeenCalledTimes(1)
|
|
expect(updateCb).toHaveBeenCalledWith({ id: 1, name: 'keep' }, { id: 1, name: 'kept' })
|
|
})
|
|
|
|
it('works with string IDs', () => {
|
|
interface StringItem {
|
|
id: string
|
|
label: string
|
|
}
|
|
const list = createUniqueList<StringItem>()
|
|
uniqueListUpdate(list, [{ id: 'abc', label: 'first' }])
|
|
expect(uniqueListById(list, 'abc')).toEqual({ id: 'abc', label: 'first' })
|
|
})
|
|
|
|
it('handles empty update', () => {
|
|
const list = createUniqueList<Item>()
|
|
uniqueListUpdate(list, [{ id: 1, name: 'a' }])
|
|
|
|
const removeCb = vi.fn()
|
|
uniqueListUpdate(list, [], undefined, removeCb)
|
|
|
|
expect(removeCb).toHaveBeenCalledTimes(1)
|
|
expect(uniqueListGetElements(list)).toHaveLength(0)
|
|
})
|
|
|
|
it('handles update with no callbacks', () => {
|
|
const list = createUniqueList<Item>()
|
|
uniqueListUpdate(list, [{ id: 1, name: 'a' }])
|
|
uniqueListUpdate(list, [{ id: 2, name: 'b' }])
|
|
expect(uniqueListGetElements(list)).toHaveLength(1)
|
|
expect(uniqueListById(list, 2)).toEqual({ id: 2, name: 'b' })
|
|
})
|
|
})
|
|
|
|
describe('uniqueListGetElements', () => {
|
|
it('returns all elements as array', () => {
|
|
const list = createUniqueList<Item>()
|
|
uniqueListUpdate(list, [{ id: 1, name: 'a' }, { id: 2, name: 'b' }])
|
|
const elements = uniqueListGetElements(list)
|
|
expect(elements).toHaveLength(2)
|
|
expect(elements.map(e => e.id).sort()).toEqual([1, 2])
|
|
})
|
|
})
|
|
|
|
describe('uniqueListById', () => {
|
|
it('finds element by id', () => {
|
|
const list = createUniqueList<Item>()
|
|
uniqueListUpdate(list, [{ id: 42, name: 'target' }])
|
|
expect(uniqueListById(list, 42)?.name).toBe('target')
|
|
})
|
|
|
|
it('returns undefined for missing id', () => {
|
|
const list = createUniqueList<Item>()
|
|
expect(uniqueListById(list, 999)).toBeUndefined()
|
|
})
|
|
})
|