Skip to content

Commit d375809

Browse files
add tests
1 parent 0f4f603 commit d375809

File tree

2 files changed

+168
-38
lines changed

2 files changed

+168
-38
lines changed

src/tile/bounded_lru_cache.test.ts

Lines changed: 152 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,72 @@ describe('BoundedLRUCache', () => {
3838
});
3939

4040
test('get without removing', () => {
41+
let removeCount = 0;
4142
const cache = new BoundedLRUCache<string, Tile>({
4243
maxEntries: 10,
4344
onRemove: () => {
44-
throw new Error('test "get without removing" failed');
45+
removeCount++;
4546
}
4647
});
4748
cache.set(idA, tileA);
4849
expect(cache.get(idA)).toBe(tileA);
4950
keysExpected(cache, [idA]);
5051
expect(cache.get(idA)).toBe(tileA);
52+
expect(removeCount).toBe(0);
5153
});
5254

53-
test('duplicate set', () => {
55+
test('remove tile calls onRemove', () => {
56+
let removeCount = 0;
57+
const cache = new BoundedLRUCache<string, Tile>({
58+
maxEntries: 10,
59+
onRemove: () => {
60+
removeCount++;
61+
}
62+
});
63+
cache.set(idA, tileA);
64+
cache.remove(idA);
65+
expect(removeCount).toBe(1);
66+
});
67+
68+
test('set of tile id using the same tile retains tile and moves to end without calling remove', () => {
69+
let removeCount = 0;
70+
const cache = new BoundedLRUCache<string, Tile>({
71+
maxEntries: 10,
72+
onRemove: () => {
73+
removeCount++;
74+
}
75+
});
76+
cache.set(idA, tileA);
77+
cache.set(idB, tileB);
78+
keysExpected(cache, [idA, idB]);
79+
80+
// Set the same tile reference again, but it should not call remove.
81+
cache.set(idA, tileA);
82+
expect(removeCount).toBe(0);
83+
keysExpected(cache, [idB, idA]);
84+
expect(cache.get(idA)).toBe(tileA);
85+
});
86+
87+
test('set of same tile id using a new tile remove previous tile reference and calls remove', () => {
88+
let removeCount = 0;
89+
const cache = new BoundedLRUCache<string, Tile>({
90+
maxEntries: 10,
91+
onRemove: () => {
92+
removeCount++;
93+
}
94+
});
95+
cache.set(idA, tileA);
96+
cache.set(idB, tileB);
97+
keysExpected(cache, [idA, idB]);
98+
99+
// Set the same tile id but with new tile, remove should be called
100+
cache.set(idA, tileA2);
101+
expect(removeCount).toBe(1);
102+
keysExpected(cache, [idB, idA]);
103+
expect(cache.get(idA)).toBe(tileA2);
104+
});
105+
106+
test('duplicate set of same tile id updates entry to most recently added tile', () => {
54107
const cache = new BoundedLRUCache<string, Tile>({maxEntries: 10});
55108
cache.set(idA, tileA);
56109
cache.set(idA, tileA2);
@@ -59,7 +112,27 @@ describe('BoundedLRUCache', () => {
59112
expect(cache.get(idA)).toBe(tileA2);
60113
});
61114

62-
test('remove', () => {
115+
test('set of tile over max entries trims the cache', () => {
116+
let removeCount = 0;
117+
const cache = new BoundedLRUCache<string, Tile>({
118+
maxEntries: 1,
119+
onRemove: () => {
120+
removeCount++;
121+
}
122+
});
123+
cache.set(idA, tileA);
124+
cache.set(idB, tileB);
125+
keysExpected(cache, [idB]);
126+
expect(cache.get(idB)).toBe(tileB);
127+
128+
cache.set(idA, tileA2);
129+
keysExpected(cache, [idA]);
130+
expect(cache.get(idA)).toBe(tileA2);
131+
132+
expect(removeCount).toBe(2);
133+
});
134+
135+
test('removes tiles', () => {
63136
const cache = new BoundedLRUCache<string, Tile>({
64137
maxEntries: 10,
65138
onRemove: () => {}
@@ -78,21 +151,73 @@ describe('BoundedLRUCache', () => {
78151
expect(() => cache.remove(idB)).not.toThrow();
79152
});
80153

81-
test('overflow', () => {
154+
test('removes the oldest entry', () => {
82155
const cache = new BoundedLRUCache<string, Tile>({
83-
maxEntries: 1,
84-
onRemove: (removed) => {
85-
expect(removed).toBe(tileA);
156+
maxEntries: 10,
157+
onRemove: () => {}
158+
});
159+
160+
cache.set(idA, tileA);
161+
cache.set(idB, tileB);
162+
cache.set(idC, tileC);
163+
164+
cache.removeOldest();
165+
keysExpected(cache, [idB, idC]);
166+
167+
cache.set(idC, tileC);
168+
cache.set(idB, tileB);
169+
cache.set(idA, tileA);
170+
171+
cache.removeOldest();
172+
keysExpected(cache, [idB, idA]);
173+
});
174+
175+
test('filters tiles using provided function', () => {
176+
let removeCount = 0;
177+
const cache = new BoundedLRUCache<string, Tile>({
178+
maxEntries: 10,
179+
onRemove: () => {
180+
removeCount++;
86181
}
87182
});
88183
cache.set(idA, tileA);
89184
cache.set(idB, tileB);
185+
cache.set(idC, tileC);
186+
cache.set(idD, tileD);
90187

91-
expect(cache.get(idB)).toBeTruthy();
92-
expect(cache.get(idA)).toBeFalsy();
188+
cache.filter(tile => tile.tileID.canonical.y === 2 || tile.tileID.canonical.y === 3);
189+
keysExpected(cache, [idB, idC]);
190+
expect(removeCount).toBe(2);
191+
192+
removeCount = 0;
193+
cache.set(idA, tileA);
194+
cache.set(idB, tileB);
195+
cache.set(idC, tileC);
196+
cache.set(idD, tileD);
197+
cache.filter(tile => tile.tileID.canonical.y === 1 || tile.tileID.canonical.y === 4);
198+
keysExpected(cache, [idA, idD]);
199+
expect(removeCount).toBe(2);
200+
});
201+
202+
test('clear tiles call onRemove on all tiles', () => {
203+
let removeCount = 0;
204+
const cache = new BoundedLRUCache<string, Tile>({
205+
maxEntries: 10,
206+
onRemove: () => {
207+
removeCount++;
208+
}
209+
});
210+
211+
cache.set(idA, tileA);
212+
cache.set(idB, tileB);
213+
cache.set(idC, tileC);
214+
215+
cache.clear();
216+
keysExpected(cache, []);
217+
expect(removeCount).toBe(3);
93218
});
94219

95-
test('.reset', () => {
220+
test('.clear removes all tiles', () => {
96221
let called;
97222
const cache = new BoundedLRUCache<string, Tile>({
98223
maxEntries: 10,
@@ -107,7 +232,21 @@ describe('BoundedLRUCache', () => {
107232
expect(called).toBeTruthy();
108233
});
109234

110-
test('.setMaxSize', () => {
235+
test('overflow automatically evicts', () => {
236+
const cache = new BoundedLRUCache<string, Tile>({
237+
maxEntries: 1,
238+
onRemove: (removed) => {
239+
expect(removed).toBe(tileA);
240+
}
241+
});
242+
cache.set(idA, tileA);
243+
cache.set(idB, tileB);
244+
245+
expect(cache.get(idB)).toBeTruthy();
246+
expect(cache.get(idA)).toBeFalsy();
247+
});
248+
249+
test('.setMaxSize trims tile count', () => {
111250
let numRemoved = 0;
112251
const cache = new BoundedLRUCache<string, Tile>({
113252
maxEntries: 10,
@@ -123,8 +262,10 @@ describe('BoundedLRUCache', () => {
123262
expect(numRemoved).toBe(0);
124263
cache.setMaxSize(1);
125264
expect(numRemoved).toBe(2);
265+
keysExpected(cache, [idC]);
126266
cache.set(idD, tileD);
127267
expect(numRemoved).toBe(3);
268+
keysExpected(cache, [idD]);
128269
});
129270

130271
test('evicts least-recently-used item when capacity exceeded', () => {

src/tile/tile_manager.test.ts

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,22 @@ describe('TileManager.addTile', () => {
267267
expect(tileManager._cache.get(tileID.key)).toBeTruthy();
268268
});
269269

270+
test('expired tiles in cache are ignored and removed upon retrieval', () => {
271+
const tileID = new OverscaledTileID(0, 0, 0, 0, 0);
272+
273+
const tileManager = createTileManager();
274+
tileManager._source.loadTile = async (tile) => {
275+
tile.state = 'loaded';
276+
tile.expirationTime = now() - 1000;
277+
};
278+
279+
tileManager._addTile(tileID);
280+
tileManager._removeTile(tileID.key);
281+
expect(tileManager._cache.get(tileID.key)).toBeTruthy();
282+
expect(tileManager._getTileFromCache(tileID)).toBe(null);
283+
expect(tileManager._cache.get(tileID.key)).toBeFalsy();
284+
});
285+
270286
test('does not reuse wrapped tile', () => {
271287
const tileID = new OverscaledTileID(0, 0, 0, 0, 0);
272288
let load = 0,
@@ -2370,33 +2386,6 @@ describe('TileManager reloads expiring tiles', () => {
23702386

23712387
});
23722388

2373-
describe('TileManager sets max cache size correctly', () => {
2374-
test('sets cache size based on 512 tiles', () => {
2375-
const tileManager = createTileManager({
2376-
tileSize: 256
2377-
});
2378-
2379-
const tr = new MercatorTransform();
2380-
tr.resize(512, 512);
2381-
2382-
// Expect max size to be ((512 / tileSize + 1) ^ 2) * 5 => 3 * 3 * 5
2383-
expect(tileManager._cache.getMaxSize()).toBe(45);
2384-
});
2385-
2386-
test('sets cache size based on 256 tiles', () => {
2387-
const tileManager = createTileManager({
2388-
tileSize: 512
2389-
});
2390-
2391-
const tr = new MercatorTransform();
2392-
tr.resize(512, 512);
2393-
2394-
// Expect max size to be ((512 / tileSize + 1) ^ 2) * 5 => 2 * 2 * 5
2395-
expect(tileManager._cache.getMaxSize()).toBe(20);
2396-
});
2397-
2398-
});
2399-
24002389
describe('TileManager.onRemove', () => {
24012390
test('clears tiles', () => {
24022391
const tileManager = createTileManager();

0 commit comments

Comments
 (0)