Skip to content

Commit 3b187e2

Browse files
chrisgervangclaude
andcommitted
chore(test): convert spy.called to vitest toHaveBeenCalled()
Vitest's MockInstance doesn't have a `.called` property like sinon spies. Updated the migration script to convert to idiomatic vitest assertions: - expect(spy.called).toBeTruthy() → expect(spy).toHaveBeenCalled() - expect(spy.called).toBeFalsy() → expect(spy).not.toHaveBeenCalled() Co-Authored-By: Claude (global.anthropic.claude-opus-4-5-20251101-v1:0) <[email protected]>
1 parent 541f0c1 commit 3b187e2

File tree

10 files changed

+87
-112
lines changed

10 files changed

+87
-112
lines changed

scripts/tape-to-vitest-migration.cjs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,26 @@ function convertTapeToVitest(content, filePath = '') {
262262
// assert: t.ok -> assert: (cond, msg) => expect(cond).toBeTruthy()
263263
result = result.replace(/assert:\s*t\d*\.ok/g, 'assert: (cond, msg) => expect(cond).toBeTruthy()');
264264

265+
// Step 8b: Convert sinon-style spy.called assertions to vitest toHaveBeenCalled()
266+
// expect(spy.called, 'message').toBeTruthy() -> expect(spy, 'message').toHaveBeenCalled()
267+
// expect(spy.called, 'message').toBeFalsy() -> expect(spy, 'message').not.toHaveBeenCalled()
268+
result = result.replace(
269+
/expect\(([^,)]+)\.called,\s*([^)]+)\)\.toBeTruthy\(\)/g,
270+
'expect($1, $2).toHaveBeenCalled()'
271+
);
272+
result = result.replace(
273+
/expect\(([^,)]+)\.called\)\.toBeTruthy\(\)/g,
274+
'expect($1).toHaveBeenCalled()'
275+
);
276+
result = result.replace(
277+
/expect\(([^,)]+)\.called,\s*([^)]+)\)\.toBeFalsy\(\)/g,
278+
'expect($1, $2).not.toHaveBeenCalled()'
279+
);
280+
result = result.replace(
281+
/expect\(([^,)]+)\.called\)\.toBeFalsy\(\)/g,
282+
'expect($1).not.toHaveBeenCalled()'
283+
);
284+
265285
// Step 9: Handle utility files that export functions taking t as parameter
266286
// Convert: export function testFoo(t, ...) to export function testFoo(...)
267287
// These helper functions need the t parameter removed

test/modules/aggregation-layers/aggregation-layer.spec.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,11 @@ test('AggregationLayer#updateState', () => {
115115
},
116116
spies: ['updateShaders', 'updateAttributes'],
117117
onAfterUpdate({spies, layer}) {
118-
expect(spies.updateAttributes.called, 'should always call updateAttributes').toBeTruthy();
118+
expect(spies.updateAttributes, 'should always call updateAttributes').toHaveBeenCalled();
119119
expect(
120-
spies.updateShaders.called,
120+
spies.updateShaders,
121121
'should not call updateShaders when extensions not changed'
122-
).toBeFalsy();
122+
).not.toHaveBeenCalled();
123123
expect(layer.state.aggregationDirty, 'Aggregation should not be dirty').toBeFalsy();
124124
expect(layer.state.anyAttributeChanged, 'Should change one attribute').toBeTruthy();
125125
expect(layer.state.aOneAttributeChanged, 'Should not update attribute').toBeFalsy();
@@ -144,9 +144,9 @@ test('AggregationLayer#updateState', () => {
144144
spies: ['updateShaders'],
145145
onAfterUpdate({spies, layer}) {
146146
expect(
147-
spies.updateShaders.called,
147+
spies.updateShaders,
148148
'should call updateShaders when extensions changed'
149-
).toBeTruthy();
149+
).toHaveBeenCalled();
150150
expect(
151151
layer.state.aggregationDirty,
152152
'Aggregation should be dirty when extensions changed'
@@ -160,9 +160,9 @@ test('AggregationLayer#updateState', () => {
160160
spies: ['updateState'],
161161
onAfterUpdate({spies, layer}) {
162162
expect(
163-
spies.updateState.called,
163+
spies.updateState,
164164
'should not call updateState nothing changed'
165-
).toBeFalsy();
165+
).not.toHaveBeenCalled();
166166
}
167167
},
168168
{

test/modules/aggregation-layers/heatmap-layer/heatmap-layer.spec.ts

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ test.skip('HeatmapLayer#updates', t => {
9090
onAfterUpdate({layer, subLayers, spies}) {
9191
expect(subLayers.length === 1, 'Sublayer rendered').toBeTruthy();
9292

93-
expect(spies._updateColorTexture.called, 'should update color texture').toBeTruthy();
93+
expect(spies._updateColorTexture, 'should update color texture').toHaveBeenCalled();
9494
expect(
95-
spies._updateBounds.called,
95+
spies._updateBounds,
9696
'viewport not changed, should not call _updateBounds'
97-
).toBeFalsy();
97+
).not.toHaveBeenCalled();
9898
spies._updateColorTexture.restore();
9999
spies._updateBounds.restore();
100100
}
@@ -109,19 +109,22 @@ test.skip('HeatmapLayer#updates', t => {
109109
],
110110
onAfterUpdate({layer, subLayers, spies}) {
111111
const {zoom} = layer.state;
112-
expect(spies._updateColorTexture.called, 'should not update color texture').toBeFalsy();
113112
expect(
114-
spies._updateBounds.called,
113+
spies._updateColorTexture,
114+
'should not update color texture'
115+
).not.toHaveBeenCalled();
116+
expect(
117+
spies._updateBounds,
115118
'viewport changed, should call _updateBounds'
116-
).toBeTruthy();
119+
).toHaveBeenCalled();
117120
expect(
118-
spies._updateWeightmap.called,
121+
spies._updateWeightmap,
119122
'boundsChanged changed, should _updateWeightmap'
120-
).toBeTruthy();
123+
).toHaveBeenCalled();
121124
expect(
122-
spies._updateTextureRenderingBounds.called,
125+
spies._updateTextureRenderingBounds,
123126
'vieport changed, should call _updateTextureRenderingBounds'
124-
).toBeTruthy();
127+
).toHaveBeenCalled();
125128
expect(zoom, 'should update state.zoom').toBe(viewport1.zoom);
126129
spies._updateColorTexture.restore();
127130
spies._updateBounds.restore();
@@ -134,17 +137,17 @@ test.skip('HeatmapLayer#updates', t => {
134137
spies: ['_updateBounds', '_updateWeightmap', '_updateTextureRenderingBounds'],
135138
onAfterUpdate({layer, subLayers, spies}) {
136139
expect(
137-
spies._updateBounds.called,
140+
spies._updateBounds,
138141
'viewport changed slightly, should call _updateBounds'
139-
).toBeTruthy();
142+
).toHaveBeenCalled();
140143
expect(
141-
spies._updateWeightmap.called,
144+
spies._updateWeightmap,
142145
'viewport changed slightly, should not call _updateWeightmap'
143-
).toBeFalsy();
146+
).not.toHaveBeenCalled();
144147
expect(
145-
spies._updateTextureRenderingBounds.called,
148+
spies._updateTextureRenderingBounds,
146149
'viewport changed slightly, should call _updateTextureRenderingBounds'
147-
).toBeTruthy();
150+
).toHaveBeenCalled();
148151
spies._updateBounds.restore();
149152
spies._updateWeightmap.restore();
150153
spies._updateTextureRenderingBounds.restore();
@@ -155,13 +158,13 @@ test.skip('HeatmapLayer#updates', t => {
155158
spies: ['_updateBounds', '_updateWeightmap'],
156159
onAfterUpdate({layer, subLayers, spies}) {
157160
expect(
158-
spies._updateBounds.called,
161+
spies._updateBounds,
159162
'viewport panned too far, should call _updateBounds'
160-
).toBeTruthy();
163+
).toHaveBeenCalled();
161164
expect(
162-
spies._updateWeightmap.called,
165+
spies._updateWeightmap,
163166
'viewport panned too far, should call _updateWeightmap'
164-
).toBeTruthy();
167+
).toHaveBeenCalled();
165168
spies._updateBounds.restore();
166169
spies._updateWeightmap.restore();
167170
}
@@ -172,13 +175,13 @@ test.skip('HeatmapLayer#updates', t => {
172175
onAfterUpdate({layer, subLayers, spies}) {
173176
const {zoom} = layer.state;
174177
expect(
175-
spies._updateBounds.called,
178+
spies._updateBounds,
176179
'viewport zoom changed, should call _updateBounds'
177-
).toBeTruthy();
180+
).toHaveBeenCalled();
178181
expect(
179-
spies._debouncedUpdateWeightmap.called,
182+
spies._debouncedUpdateWeightmap,
180183
'viewport zoom changed, should call _debouncedUpdateWeightmap'
181-
).toBeTruthy();
184+
).toHaveBeenCalled();
182185
spies._updateBounds.restore();
183186
spies._debouncedUpdateWeightmap.restore();
184187
expect(zoom, 'viewport zoom changed, should update state.zoom').toBe(
@@ -194,9 +197,9 @@ test.skip('HeatmapLayer#updates', t => {
194197
spies: ['_updateWeightmap'],
195198
onAfterUpdate({layer, subLayers, spies}) {
196199
expect(
197-
spies._updateWeightmap.called,
200+
spies._updateWeightmap,
198201
'should update weight map on uniform change'
199-
).toBeTruthy();
202+
).toHaveBeenCalled();
200203
spies._updateWeightmap.restore();
201204
}
202205
}

test/modules/core/controllers/test-controller.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -248,12 +248,8 @@ export default async function testController(ViewClass, defaultProps, blackList
248248
controller.setProps(controllerProps);
249249
await triggerEvents(controller, testCase, timeline);
250250

251-
expect(onViewStateChangeCalled, `${testCase.title} onViewStateChange`).toBe(
252-
testCase.viewStateChanges
253-
);
254-
expect(affectedStates.size, `${testCase.title} interaction state updated`).toBe(
255-
testCase.interactionStates
256-
);
251+
expect(onViewStateChangeCalled, `${testCase.title} onViewStateChange`).toBe(testCase.viewStateChanges);
252+
expect(affectedStates.size, `${testCase.title} interaction state updated`).toBe(testCase.interactionStates);
257253
}
258254
}
259255

test/modules/core/lib/async-iterator-test-utils.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,8 @@ export function testAsyncData(data) {
2222
expect(props.data.length > oldProps.data.length, 'data has changed').toBeTruthy();
2323
}
2424
if (Array.isArray(changeFlags.dataChanged)) {
25-
expect(changeFlags.dataChanged[0].startRow, 'data diff starts from last position').toBe(
26-
oldProps.data.length
27-
);
28-
expect(
29-
changeFlags.dataChanged[changeFlags.dataChanged.length - 1].endRow,
30-
'data diff covers rest of range'
31-
).toBe(props.data.length);
25+
expect(changeFlags.dataChanged[0].startRow, 'data diff starts from last position').toBe(oldProps.data.length);
26+
expect(changeFlags.dataChanged[changeFlags.dataChanged.length - 1].endRow, 'data diff covers rest of range').toBe(props.data.length);
3227
}
3328
}
3429
}

test/modules/core/lib/attribute/attribute.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -775,9 +775,9 @@ test('Attribute#setExternalBuffer', () => {
775775
'should successfully set external buffer if setting external buffer to the same object'
776776
).toBeTruthy();
777777
expect(
778-
spy.called,
778+
spy,
779779
'Should not call update if setting external buffer to the same object'
780-
).toBeFalsy();
780+
).not.toHaveBeenCalled();
781781

782782
expect(
783783
attribute.setExternalBuffer(value1),
@@ -798,9 +798,9 @@ test('Attribute#setExternalBuffer', () => {
798798
'should successfully set external buffer if setting external buffer to the same object'
799799
).toBeTruthy();
800800
expect(
801-
spy.called,
801+
spy,
802802
'Should not call update if setting external buffer to the same object'
803-
).toBeFalsy();
803+
).not.toHaveBeenCalled();
804804

805805
expect(
806806
attribute.setExternalBuffer({

test/modules/core/lib/layer.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ test('Layer#diffProps', () => {
210210
new SubLayer(LAYER_PROPS, {updateTriggers: {time: {version: 0}}}).props,
211211
layer.props
212212
);
213-
expect(spy.called, 'updateTriggers fired').toBeTruthy();
213+
expect(spy, 'updateTriggers fired').toHaveBeenCalled();
214214
spy.restore();
215215

216216
layer = new SubLayer(LAYER_PROPS, {updateTriggers: {time: 0}});

test/modules/imports-spec.ts

Lines changed: 18 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -35,39 +35,24 @@ describe('Top-level imports', () => {
3535
test('import "deck.gl"', () => {
3636
expect(hasEmptyExports(deck), 'No empty top-level export in deck.gl').toBeFalsy();
3737
expect(hasEmptyExports(core), 'No empty top-level export in @deck.gl/core').toBeFalsy();
38-
});
38+
});
3939

4040
test('import layers', () => {
4141
expect(hasEmptyExports(layers), 'No empty top-level export in @deck.gl/layers').toBeFalsy();
42-
expect(
43-
hasEmptyExports(aggregationLayers),
44-
'No empty top-level export in @deck.gl/aggregation-layers'
45-
).toBeFalsy();
42+
expect(hasEmptyExports(aggregationLayers), 'No empty top-level export in @deck.gl/aggregation-layers').toBeFalsy();
4643
expect(hasEmptyExports(carto), 'No empty top-level export in @deck.gl/carto').toBeFalsy();
47-
expect(
48-
hasEmptyExports(geoLayers),
49-
'No empty top-level export in @deck.gl/geo-layers'
50-
).toBeFalsy();
51-
expect(
52-
hasEmptyExports(meshLayers),
53-
'No empty top-level export in @deck.gl/mesh-layers'
54-
).toBeFalsy();
55-
});
44+
expect(hasEmptyExports(geoLayers), 'No empty top-level export in @deck.gl/geo-layers').toBeFalsy();
45+
expect(hasEmptyExports(meshLayers), 'No empty top-level export in @deck.gl/mesh-layers').toBeFalsy();
46+
});
5647

5748
test('import utilities', () => {
5849
expect(hasEmptyExports(json), 'No empty top-level export in @deck.gl/json').toBeFalsy();
5950
expect(hasEmptyExports(arcgis), 'No empty top-level export in @deck.gl/arcgis').toBeFalsy();
60-
expect(
61-
hasEmptyExports(googleMaps),
62-
'No empty top-level export in @deck.gl/google-maps'
63-
).toBeFalsy();
51+
expect(hasEmptyExports(googleMaps), 'No empty top-level export in @deck.gl/google-maps').toBeFalsy();
6452
expect(hasEmptyExports(mapbox), 'No empty top-level export in @deck.gl/mapbox').toBeFalsy();
6553
expect(hasEmptyExports(react), 'No empty top-level export in @deck.gl/react').toBeFalsy();
66-
expect(
67-
hasEmptyExports(testUtils),
68-
'No empty top-level export in @deck.gl/test-utils'
69-
).toBeFalsy();
70-
});
54+
expect(hasEmptyExports(testUtils), 'No empty top-level export in @deck.gl/test-utils').toBeFalsy();
55+
});
7156

7257
test('selected imports', () => {
7358
expect(deck.Layer, 'Layer symbol imported').toBeTruthy();
@@ -76,23 +61,14 @@ describe('Top-level imports', () => {
7661
expect(deck.ArcLayer, 'ArcLayer symbol imported').toBeTruthy();
7762
expect(deck.LineLayer, 'LineLayer symbol imported').toBeTruthy();
7863

79-
expect(
80-
Number.isFinite(deck.COORDINATE_SYSTEM.LNGLAT),
81-
'COORDINATE_SYSTEM.LNGLAT imported'
82-
).toBeTruthy();
83-
expect(
84-
Number.isFinite(deck.COORDINATE_SYSTEM.METER_OFFSETS),
85-
'COORDINATE_SYSTEM.METERS imported'
86-
).toBeTruthy();
87-
expect(
88-
Number.isFinite(deck.COORDINATE_SYSTEM.CARTESIAN),
89-
'COORDINATE_SYSTEM.CARTESIAN imported'
90-
).toBeTruthy();
91-
});
64+
expect(Number.isFinite(deck.COORDINATE_SYSTEM.LNGLAT), 'COORDINATE_SYSTEM.LNGLAT imported').toBeTruthy();
65+
expect(Number.isFinite(deck.COORDINATE_SYSTEM.METER_OFFSETS), 'COORDINATE_SYSTEM.METERS imported').toBeTruthy();
66+
expect(Number.isFinite(deck.COORDINATE_SYSTEM.CARTESIAN), 'COORDINATE_SYSTEM.CARTESIAN imported').toBeTruthy();
67+
});
9268

9369
test('deck.gl default import', () => {
9470
expect(DeckGL, 'DeckGL symbol imported from /react').toBeTruthy();
95-
});
71+
});
9672
});
9773

9874
test('deck.gl re-exports', () => {
@@ -107,24 +83,9 @@ test('deck.gl re-exports', () => {
10783
return missingExports.length ? missingExports : null;
10884
};
10985

110-
expect(
111-
findMissingExports(core, deck),
112-
'deck.gl re-exports everything from @deck.gl/core'
113-
).toBeFalsy();
114-
expect(
115-
findMissingExports(layers, deck),
116-
'deck.gl re-exports everything from @deck.gl/layers'
117-
).toBeFalsy();
118-
expect(
119-
findMissingExports(aggregationLayers, deck),
120-
'deck.gl re-exports everything from @deck.gl/aggregation-layers'
121-
).toBeFalsy();
122-
expect(
123-
findMissingExports(geoLayers, deck),
124-
'deck.gl re-exports everything from @deck.gl/geo-layers'
125-
).toBeFalsy();
126-
expect(
127-
findMissingExports(meshLayers, deck),
128-
'deck.gl re-exports everything from @deck.gl/mesh-layers'
129-
).toBeFalsy();
86+
expect(findMissingExports(core, deck), 'deck.gl re-exports everything from @deck.gl/core').toBeFalsy();
87+
expect(findMissingExports(layers, deck), 'deck.gl re-exports everything from @deck.gl/layers').toBeFalsy();
88+
expect(findMissingExports(aggregationLayers, deck), 'deck.gl re-exports everything from @deck.gl/aggregation-layers').toBeFalsy();
89+
expect(findMissingExports(geoLayers, deck), 'deck.gl re-exports everything from @deck.gl/geo-layers').toBeFalsy();
90+
expect(findMissingExports(meshLayers, deck), 'deck.gl re-exports everything from @deck.gl/mesh-layers').toBeFalsy();
13091
});

test/modules/json/json-converter.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ test('JSONConverter#badConvert', () => {
6969
makeSpy(log, 'warn');
7070
jsonConverter.convert(badData);
7171
expect(
72-
log.warn.called,
72+
log.warn,
7373
'should produce a warning message if the layer type is invalid'
74-
).toBeTruthy();
74+
).toHaveBeenCalled();
7575
log.warn.restore();
7676
});
7777

test/modules/jupyter-widget/utils/google-maps-utils.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ test('jupyter-widget: Google Maps base', () => {
1212
makeSpy(log, 'warn');
1313
const overlay = createGoogleMapsDeckOverlay({props: {}});
1414
expect(
15-
log.warn.called,
15+
log.warn,
1616
'should produce a warning message if no Google Maps API key is provided'
17-
).toBeTruthy();
17+
).toHaveBeenCalled();
1818
expect(!overlay, 'Absent Google Maps API key creates null overlay').toBeTruthy();
1919
log.warn.restore();
2020
});

0 commit comments

Comments
 (0)