+++ /dev/null
-// Copyright Jerome Benoit. 2021-2024. All Rights Reserved.
-
-export const DEFAULT_CIRCULAR_ARRAY_SIZE = 385
-
-/**
- * Array with a maximum length and shifting items when full.
- */
-export class CircularArray<T> extends Array<T> {
- public size: number
-
- constructor (size: number = DEFAULT_CIRCULAR_ARRAY_SIZE, ...items: T[]) {
- super()
- this.checkSize(size)
- this.size = size
- if (arguments.length > 1) {
- this.push(...items)
- }
- }
-
- public push (...items: T[]): number {
- const length = super.push(...items)
- if (length > this.size) {
- super.splice(0, length - this.size)
- }
- return this.length
- }
-
- public unshift (...items: T[]): number {
- const length = super.unshift(...items)
- if (length > this.size) {
- super.splice(this.size, items.length)
- }
- return this.length
- }
-
- public concat (...items: Array<T | ConcatArray<T>>): CircularArray<T> {
- const concatenatedCircularArray = super.concat(items as T[]) as CircularArray<T>
- concatenatedCircularArray.size = this.size
- if (concatenatedCircularArray.length > concatenatedCircularArray.size) {
- concatenatedCircularArray.splice(
- 0,
- concatenatedCircularArray.length - concatenatedCircularArray.size
- )
- }
- return concatenatedCircularArray
- }
-
- public splice (start: number, deleteCount?: number, ...items: T[]): CircularArray<T> {
- let itemsRemoved: T[] = []
- if (arguments.length >= 3 && deleteCount != null) {
- itemsRemoved = super.splice(start, deleteCount, ...items)
- if (this.length > this.size) {
- const itemsOverflowing = super.splice(0, this.length - this.size)
- itemsRemoved = new CircularArray<T>(
- itemsRemoved.length + itemsOverflowing.length,
- ...itemsRemoved,
- ...itemsOverflowing
- )
- }
- } else if (arguments.length === 2) {
- itemsRemoved = super.splice(start, deleteCount)
- } else {
- itemsRemoved = super.splice(start)
- }
- return itemsRemoved as CircularArray<T>
- }
-
- public resize (size: number): void {
- this.checkSize(size)
- if (size === 0) {
- this.length = 0
- } else if (size < this.size) {
- for (let i = size; i < this.size; i++) {
- super.pop()
- }
- }
- this.size = size
- }
-
- public empty (): boolean {
- return this.length === 0
- }
-
- public full (): boolean {
- return this.length === this.size
- }
-
- private checkSize (size: number): void {
- if (!Number.isSafeInteger(size)) {
- throw new TypeError(`Invalid circular array size: ${size} is not a safe integer`)
- }
- if (size < 0) {
- throw new RangeError(`Invalid circular array size: ${size} < 0`)
- }
- }
-}
+++ /dev/null
-import { describe, it } from 'node:test'
-
-import { expect } from 'expect'
-
-import { CircularArray, DEFAULT_CIRCULAR_ARRAY_SIZE } from '../../src/utils/CircularArray.js'
-
-await describe('CircularArray test suite', async () => {
- await it('Verify that circular array can be instantiated', () => {
- const circularArray = new CircularArray()
- expect(circularArray).toBeInstanceOf(CircularArray)
- })
-
- await it('Verify circular array default size at instance creation', () => {
- const circularArray = new CircularArray()
- expect(circularArray.size).toBe(DEFAULT_CIRCULAR_ARRAY_SIZE)
- })
-
- await it('Verify that circular array size can be set at instance creation', () => {
- const circularArray = new CircularArray(1000)
- expect(circularArray.size).toBe(1000)
- })
-
- await it('Verify that circular array size and items can be set at instance creation', () => {
- let circularArray = new CircularArray(1000, 1, 2, 3, 4, 5)
- expect(circularArray.size).toBe(1000)
- expect(circularArray.length).toBe(5)
- circularArray = new CircularArray(4, 1, 2, 3, 4, 5)
- expect(circularArray.size).toBe(4)
- expect(circularArray.length).toBe(4)
- })
-
- await it('Verify that circular array size is valid at instance creation', () => {
- expect(() => new CircularArray(0.25)).toThrow(
- new TypeError('Invalid circular array size: 0.25 is not a safe integer')
- )
- expect(() => new CircularArray(-1)).toThrow(
- new RangeError('Invalid circular array size: -1 < 0')
- )
- expect(() => new CircularArray(Number.MAX_SAFE_INTEGER + 1)).toThrow(
- new TypeError(
- `Invalid circular array size: ${Number.MAX_SAFE_INTEGER + 1} is not a safe integer`
- )
- )
- })
-
- await it('Verify that circular array empty works as intended', () => {
- const circularArray = new CircularArray()
- expect(circularArray.empty()).toBe(true)
- })
-
- await it('Verify that circular array full works as intended', () => {
- const circularArray = new CircularArray(5, 1, 2, 3, 4, 5)
- expect(circularArray.full()).toBe(true)
- })
-
- await it('Verify that circular array push works as intended', () => {
- let circularArray = new CircularArray(4)
- let arrayLength = circularArray.push(1, 2, 3, 4, 5)
- expect(arrayLength).toBe(circularArray.size)
- expect(circularArray.length).toBe(circularArray.size)
- expect(circularArray).toStrictEqual(new CircularArray(4, 2, 3, 4, 5))
- arrayLength = circularArray.push(6, 7)
- expect(arrayLength).toBe(circularArray.size)
- expect(circularArray.length).toBe(circularArray.size)
- expect(circularArray).toStrictEqual(new CircularArray(4, 4, 5, 6, 7))
- circularArray = new CircularArray(100)
- arrayLength = circularArray.push(1, 2, 3, 4, 5)
- expect(arrayLength).toBe(5)
- expect(circularArray.size).toBe(100)
- expect(circularArray.length).toBe(5)
- expect(circularArray).toStrictEqual(new CircularArray(100, 1, 2, 3, 4, 5))
- })
-
- await it('Verify that circular array splice works as intended', () => {
- let circularArray = new CircularArray(1000, 1, 2, 3, 4, 5)
- let deletedItems = circularArray.splice(2)
- expect(deletedItems).toStrictEqual(new CircularArray(3, 3, 4, 5))
- expect(circularArray.length).toBe(2)
- expect(circularArray).toStrictEqual(new CircularArray(1000, 1, 2))
- circularArray = new CircularArray(1000, 1, 2, 3, 4, 5)
- deletedItems = circularArray.splice(2, 1)
- expect(deletedItems).toStrictEqual(new CircularArray(1, 3))
- expect(circularArray.length).toBe(4)
- expect(circularArray).toStrictEqual(new CircularArray(1000, 1, 2, 4, 5))
- circularArray = new CircularArray(4, 1, 2, 3, 4)
- deletedItems = circularArray.splice(2, 1, 5, 6)
- expect(deletedItems).toStrictEqual(new CircularArray(2, 3, 1))
- expect(circularArray.length).toBe(4)
- expect(circularArray).toStrictEqual(new CircularArray(4, 2, 5, 6, 4))
- })
-
- await it('Verify that circular array concat works as intended', () => {
- let circularArray = new CircularArray(5, 1, 2, 3, 4, 5)
- circularArray = circularArray.concat(6, 7)
- expect(circularArray.length).toBe(5)
- expect(circularArray).toStrictEqual(new CircularArray(5, 3, 4, 5, 6, 7))
- circularArray = new CircularArray(1)
- circularArray = circularArray.concat(6, 7)
- expect(circularArray.length).toBe(1)
- expect(circularArray).toStrictEqual(new CircularArray(1, 7))
- })
-
- await it('Verify that circular array unshift works as intended', () => {
- let circularArray = new CircularArray(5, 1, 2, 3, 4, 5)
- let arrayLength = circularArray.unshift(6, 7)
- expect(arrayLength).toBe(5)
- expect(circularArray.length).toBe(5)
- expect(circularArray).toStrictEqual(new CircularArray(5, 6, 7, 1, 2, 3))
- circularArray = new CircularArray(1)
- arrayLength = circularArray.unshift(6, 7)
- expect(arrayLength).toBe(1)
- expect(circularArray.length).toBe(1)
- expect(circularArray).toStrictEqual(new CircularArray(1, 6))
- })
-
- await it('Verify that circular array resize works as intended', () => {
- expect(() => {
- new CircularArray().resize(0.25)
- }).toThrow(new TypeError('Invalid circular array size: 0.25 is not a safe integer'))
- expect(() => {
- new CircularArray().resize(-1)
- }).toThrow(new RangeError('Invalid circular array size: -1 < 0'))
- expect(() => {
- new CircularArray().resize(Number.MAX_SAFE_INTEGER + 1)
- }).toThrow(
- new TypeError(
- `Invalid circular array size: ${Number.MAX_SAFE_INTEGER + 1} is not a safe integer`
- )
- )
- let circularArray = new CircularArray(5, 1, 2, 3, 4, 5)
- circularArray.resize(0)
- expect(circularArray.size).toBe(0)
- expect(circularArray).toStrictEqual(new CircularArray(0))
- circularArray = new CircularArray(5, 1, 2, 3, 4, 5)
- circularArray.resize(1)
- expect(circularArray.size).toBe(1)
- expect(circularArray).toStrictEqual(new CircularArray(1, 1))
- circularArray = new CircularArray(5, 1, 2, 3, 4, 5)
- circularArray.resize(3)
- expect(circularArray.size).toBe(3)
- expect(circularArray).toStrictEqual(new CircularArray(3, 1, 2, 3))
- circularArray = new CircularArray(5, 1, 2, 3, 4, 5)
- circularArray.resize(8)
- expect(circularArray.size).toBe(8)
- expect(circularArray).toStrictEqual(new CircularArray(8, 1, 2, 3, 4, 5))
- })
-})