cache.spec.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /**
  2. * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
  3. * SPDX-License-Identifier: MIT
  4. */
  5. /**
  6. * @jest-environment jsdom
  7. */
  8. import { describe, beforeEach, test, expect } from 'vitest';
  9. import { delay } from './promise-util';
  10. import { Cache, type CacheOriginItem } from './cache';
  11. interface Item extends CacheOriginItem {
  12. key: string | number;
  13. }
  14. let _uid = 0;
  15. function itemFactory(): Cache<Item> {
  16. const item: Item = {
  17. key: `${_uid++}`,
  18. };
  19. return item;
  20. }
  21. function dispose() {}
  22. function itemWithDisposeFactory(): Cache<Item> {
  23. const item: Item = {
  24. key: `${_uid++}`,
  25. };
  26. Cache.assign(item, { dispose });
  27. return item;
  28. }
  29. describe('cache', () => {
  30. beforeEach(() => {
  31. _uid = 0;
  32. });
  33. test('Cache/getFromCache', async () => {
  34. const cache = Cache.create<Item>(itemFactory);
  35. expect(cache.getFromCache()).toEqual([]);
  36. });
  37. test('Cache/get', async () => {
  38. const cache = Cache.create<Item>(itemFactory);
  39. expect(cache.get()).toEqual({ key: '0' });
  40. expect(cache.get()).toEqual({ key: '0' });
  41. });
  42. test('Cache/getMore', async () => {
  43. const cache = Cache.create<Item>(itemFactory);
  44. expect(cache.get()).toEqual({ key: '0' });
  45. expect(cache.getMore(1)).toEqual([{ key: '0' }]);
  46. expect(cache.getMore(2)).toEqual([{ key: '0' }, { key: '1' }]);
  47. expect(cache.getMore(1)).toEqual([{ key: '0' }]);
  48. expect(cache.getMore(2)).toEqual([{ key: '0' }, { key: '2' }]);
  49. expect(cache.getMore(1, false)).toEqual([{ key: '0' }]);
  50. expect(cache.getMore(3)).toEqual([{ key: '0' }, { key: '2' }, { key: '3' }]);
  51. });
  52. test('Cache/getMore/deleteLimit', async () => {
  53. const cache = Cache.create<Item>(itemFactory, { deleteLimit: 2 });
  54. expect(cache.getMore(4)).toEqual([{ key: '0' }, { key: '1' }, { key: '2' }, { key: '3' }]);
  55. expect(cache.getMore(1)).toEqual([{ key: '0' }]);
  56. expect(cache.getMore(2)).toEqual([{ key: '0' }, { key: '4' }]);
  57. });
  58. test('Cache/getFromCacheByKey', async () => {
  59. const cache = Cache.create<Item>(itemFactory);
  60. expect(cache.get()).toEqual({ key: '0' });
  61. expect(cache.getFromCacheByKey('0')).toEqual({ key: '0' });
  62. expect(cache.getFromCacheByKey('1')).toEqual(undefined);
  63. });
  64. test('Cache/getMoreByItemKeys', async () => {
  65. const cache = Cache.create<Item>(itemFactory);
  66. const items = cache.getMoreByItemKeys([{ key: '0' }, { key: '1' }]);
  67. expect(items).toEqual([{ key: '0' }, { key: '1' }]);
  68. // cache.clear()
  69. items[0].key = undefined as any;
  70. (items[0] as any).dispose = dispose;
  71. expect(cache.getMoreByItemKeys([{ key: '1' }])).toEqual([{ key: '1' }]);
  72. });
  73. test('Cache/getMoreByItems', async () => {
  74. const cache = Cache.create<Item>(itemFactory);
  75. const item1 = { key: '1' };
  76. const items = cache.getMoreByItems([{ key: '0' }, item1]);
  77. expect(items).toEqual([{ key: { key: '0' } }, { key: { key: '1' } }]);
  78. expect(cache.getMoreByItems([item1])).toEqual([{ key: { key: '1' } }]);
  79. expect(cache.getMoreByItems([{ key: '1' }])).toEqual([{ key: { key: '1' } }]);
  80. // // cache.clear()
  81. items[0].key = undefined as any;
  82. (items[0] as any).dispose = dispose;
  83. expect(cache.getMoreByItems([{ key: '1' }])).toEqual([{ key: { key: '1' } }]);
  84. // expect(cache.getMoreByItems([{ key: '2' }])).toEqual([{ key: { key: '2' } }]);
  85. });
  86. test('Cache/clear', async () => {
  87. const cache = Cache.create<Item>(itemFactory);
  88. expect(cache.getMore(2)).toEqual([{ key: '0' }, { key: '1' }]);
  89. expect(cache.get()).toEqual({ key: '0' });
  90. cache.clear();
  91. expect(cache.get()).toEqual({ key: '2' });
  92. });
  93. test('Cache/disposes', async () => {
  94. const cache = Cache.create<Item>(itemWithDisposeFactory);
  95. expect(cache.getMore(2)).toEqual([
  96. { key: '0', dispose },
  97. { key: '1', dispose },
  98. ]);
  99. expect(cache.getMore(1)).toEqual([{ key: '0', dispose }]);
  100. cache.dispose();
  101. expect(cache.getMore(2)).toEqual([
  102. { key: '2', dispose },
  103. { key: '3', dispose },
  104. ]);
  105. expect(cache.getMoreByItemKeys([{ key: '2' }])).toEqual([{ key: '2', dispose }]);
  106. });
  107. test('createShortCache', async () => {
  108. const cache = Cache.createShortCache(10);
  109. let id = 0;
  110. const getValue = () => ++id;
  111. expect(cache.get(getValue)).toEqual(1);
  112. expect(cache.get(getValue)).toEqual(1);
  113. await delay(20);
  114. expect(cache.get(getValue)).toEqual(2);
  115. const cache1 = Cache.createShortCache();
  116. expect(cache1.get(getValue)).toEqual(3);
  117. });
  118. test('createWeakCache', async () => {
  119. const cache = Cache.createWeakCache();
  120. const el = document.createElement('div');
  121. cache.save(el, 1);
  122. expect(cache.get(el)).toEqual(1);
  123. expect(cache.isChanged(el, 1)).toEqual(false);
  124. });
  125. });