Path: blob/main/extensions/copilot/src/extension/chatSessions/common/test/ttlCache.spec.ts
13405 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';6import { SingleSlotTtlCache, TtlCache } from '../ttlCache';78describe('TtlCache', () => {9beforeEach(() => {10vi.useFakeTimers();11});1213afterEach(() => {14vi.useRealTimers();15});1617it('returns undefined for missing keys', () => {18const cache = new TtlCache<string>(1000);19expect(cache.get('missing')).toBeUndefined();20});2122it('stores and retrieves values within TTL', () => {23const cache = new TtlCache<number>(5000);24cache.set('key', 42);25expect(cache.get('key')).toBe(42);26});2728it('expires entries after TTL elapses', () => {29const cache = new TtlCache<string>(1000);30cache.set('key', 'value');3132vi.advanceTimersByTime(999);33expect(cache.get('key')).toBe('value');3435vi.advanceTimersByTime(1);36expect(cache.get('key')).toBeUndefined();37});3839it('supports multiple independent keys', () => {40const cache = new TtlCache<string>(2000);41cache.set('a', 'alpha');4243vi.advanceTimersByTime(1000);44cache.set('b', 'beta');4546vi.advanceTimersByTime(1000);47// 'a' was set 2000ms ago → expired48expect(cache.get('a')).toBeUndefined();49// 'b' was set 1000ms ago → still valid50expect(cache.get('b')).toBe('beta');51});5253it('overwrites existing entry and resets TTL', () => {54const cache = new TtlCache<string>(1000);55cache.set('key', 'old');5657vi.advanceTimersByTime(800);58cache.set('key', 'new');5960vi.advanceTimersByTime(800);61// 800ms since last set → still valid62expect(cache.get('key')).toBe('new');63});6465it('delete removes entry', () => {66const cache = new TtlCache<string>(5000);67cache.set('key', 'value');68cache.delete('key');69expect(cache.get('key')).toBeUndefined();70});7172it('clear removes all entries', () => {73const cache = new TtlCache<string>(5000);74cache.set('a', '1');75cache.set('b', '2');76cache.clear();77expect(cache.get('a')).toBeUndefined();78expect(cache.get('b')).toBeUndefined();79});8081it('has returns true for non-expired entries and false otherwise', () => {82const cache = new TtlCache<string>(1000);83expect(cache.has('key')).toBe(false);8485cache.set('key', 'value');86expect(cache.has('key')).toBe(true);8788vi.advanceTimersByTime(1000);89expect(cache.has('key')).toBe(false);90});9192it('supports per-entry TTL override', () => {93const cache = new TtlCache<string>(5000);94cache.set('default', 'value1');95cache.set('short', 'value2', 1000);9697vi.advanceTimersByTime(999);98expect(cache.get('default')).toBe('value1');99expect(cache.get('short')).toBe('value2');100101vi.advanceTimersByTime(1);102expect(cache.get('default')).toBe('value1');103expect(cache.get('short')).toBeUndefined(); // expired at 1000ms104105vi.advanceTimersByTime(4000);106expect(cache.get('default')).toBeUndefined(); // expired at 5000ms107});108});109110describe('SingleSlotTtlCache', () => {111beforeEach(() => {112vi.useFakeTimers();113});114115afterEach(() => {116vi.useRealTimers();117});118119it('returns undefined when empty', () => {120const cache = new SingleSlotTtlCache<string>(1000);121expect(cache.get('any')).toBeUndefined();122});123124it('stores and retrieves a value within TTL', () => {125const cache = new SingleSlotTtlCache<number>(5000);126cache.set('key', 42);127expect(cache.get('key')).toBe(42);128});129130it('returns undefined when key does not match', () => {131const cache = new SingleSlotTtlCache<string>(5000);132cache.set('key1', 'value');133expect(cache.get('key2')).toBeUndefined();134});135136it('expires entry after TTL elapses', () => {137const cache = new SingleSlotTtlCache<string>(1000);138cache.set('key', 'value');139140vi.advanceTimersByTime(999);141expect(cache.get('key')).toBe('value');142143vi.advanceTimersByTime(1);144expect(cache.get('key')).toBeUndefined();145});146147it('replaces previous entry when set with new key', () => {148const cache = new SingleSlotTtlCache<string>(5000);149cache.set('key1', 'a');150cache.set('key2', 'b');151152expect(cache.get('key1')).toBeUndefined();153expect(cache.get('key2')).toBe('b');154});155156it('replaces and resets TTL on same key', () => {157const cache = new SingleSlotTtlCache<string>(1000);158cache.set('key', 'old');159160vi.advanceTimersByTime(800);161cache.set('key', 'new');162163vi.advanceTimersByTime(800);164expect(cache.get('key')).toBe('new');165});166167it('clear removes entry', () => {168const cache = new SingleSlotTtlCache<string>(5000);169cache.set('key', 'value');170cache.clear();171expect(cache.get('key')).toBeUndefined();172});173174it('has returns true for non-expired matching key', () => {175const cache = new SingleSlotTtlCache<string>(1000);176expect(cache.has('key')).toBe(false);177178cache.set('key', 'value');179expect(cache.has('key')).toBe(true);180expect(cache.has('other')).toBe(false);181182vi.advanceTimersByTime(1000);183expect(cache.has('key')).toBe(false);184});185});186187188