From 1b2c904f22e790b85c0100b23511b0fa40d818f2 Mon Sep 17 00:00:00 2001 From: rk Date: Sat, 24 Oct 2026 02:26:18 +0500 Subject: [PATCH] fix(@schematics/angular): keep the default getter access type of spyOnProperty in refactor-jasmine-vitest Jasmine spies on getter when `spyOnProperty` gets no access type, migration turned `spyOnProperty(obj, 'prop')` into `vi.spyOn(obj, 'prop')`, which Vitest treats as method spy, so converted spec failed with TS2769 now `'get'` is passed when access type is omited, explicit one is kept --- .../jasmine-vitest/transformers/jasmine-spy.ts | 9 ++++++++- .../transformers/jasmine-spy_spec.ts | 14 ++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy.ts index ed62bbf0f981..6ac2a12c41f0 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy.ts @@ -103,11 +103,18 @@ function transformPrimarySpy(node: ts.CallExpression, refactorCtx: RefactorConte ) { addVitestValueImport(pendingVitestValueImports, 'vi'); + // `spyOnProperty` defaults to the getter while `vi.spyOn` needs the access type to spy on + // a property instead of a method. + const args = + node.expression.text === 'spyOnProperty' && node.arguments.length === 2 + ? [...node.arguments, ts.factory.createStringLiteral('get', true)] + : node.arguments; + const viSpyOnCall = ts.factory.updateCallExpression( node, createPropertyAccess('vi', 'spyOn'), node.typeArguments, - node.arguments, + args, ); if (isChainedWithAnd(node)) { diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy_spec.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy_spec.ts index 6d2b6979b128..27b4655b5c4a 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy_spec.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy_spec.ts @@ -60,9 +60,19 @@ describe('Jasmine to Vitest Transformer - transformSpies', () => { }, { description: - 'should transform spyOnProperty(object, "prop") to vi.spyOn(object, "prop").mockReturnValue(undefined)', + 'should transform spyOnProperty(object, "prop") to vi.spyOn(object, "prop", "get").mockReturnValue(undefined)', input: `spyOnProperty(service, 'myProp');`, - expected: `vi.spyOn(service, 'myProp').mockReturnValue(undefined);`, + expected: `vi.spyOn(service, 'myProp', 'get').mockReturnValue(undefined);`, + }, + { + description: 'should default the access type of a chained spyOnProperty to "get"', + input: `spyOnProperty(service, 'myProp').and.returnValue(42);`, + expected: `vi.spyOn(service, 'myProp', 'get').mockReturnValue(42);`, + }, + { + description: 'should keep an explicit spyOnProperty access type', + input: `spyOnProperty(service, 'myProp', 'set');`, + expected: `vi.spyOn(service, 'myProp', 'set').mockReturnValue(undefined);`, }, { description: 'should transform .and.stub() to .mockImplementation(() => {})',