diff --git a/common/changes/@typespec/versioning/versioning-FixTestCases_2023-04-25-18-50.json b/common/changes/@typespec/versioning/versioning-FixTestCases_2023-04-25-18-50.json new file mode 100644 index 00000000000..365ebf974b8 --- /dev/null +++ b/common/changes/@typespec/versioning/versioning-FixTestCases_2023-04-25-18-50.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@typespec/versioning", + "comment": "Fix issue where \"is\" dependencies were not detected.", + "type": "none" + } + ], + "packageName": "@typespec/versioning" +} \ No newline at end of file diff --git a/packages/versioning/src/validate.ts b/packages/versioning/src/validate.ts index 6c06433e5a1..1e7d6ad1da4 100644 --- a/packages/versioning/src/validate.ts +++ b/packages/versioning/src/validate.ts @@ -42,6 +42,7 @@ export function $onValidate(program: Program) { if (isTemplateInstance(model)) { return; } + addDependency(model.namespace, model.sourceModel); addDependency(model.namespace, model.baseModel); for (const prop of model.properties.values()) { addDependency(model.namespace, prop.type); @@ -75,6 +76,7 @@ export function $onValidate(program: Program) { } const namespace = op.namespace ?? op.interface?.namespace; + addDependency(namespace, op.sourceOperation); addDependency(namespace, op.parameters); addDependency(namespace, op.returnType); diff --git a/packages/versioning/test/versioned-dependencies.test.ts b/packages/versioning/test/versioned-dependencies.test.ts index 41ebd2ce224..664013654c4 100644 --- a/packages/versioning/test/versioned-dependencies.test.ts +++ b/packages/versioning/test/versioned-dependencies.test.ts @@ -26,6 +26,9 @@ describe("versioning: reference versioned library", () => { name: string; @added(Versions.l2) age: int32; } + + @removed(Versions.l2) + op Operation(...TParams): TResponse; } ${code}`, }); @@ -47,6 +50,8 @@ describe("versioning: reference versioned library", () => { @useDependency(VersionedLib.Versions.l1) @test namespace MyService { @test model Test extends VersionedLib.Foo {} + @test op test1 is VersionedLib.Operation<{name: string}, int32>; + alias test2 = VersionedLib.Operation<{name: string}, int32>; } `)) as { MyService: Namespace; Test: Model }; const versions = buildVersionProjections(runner.program, MyService); @@ -74,6 +79,8 @@ describe("versioning: reference versioned library", () => { @test model Test extends VersionedLib.Foo {} @test op getBar(): OtherVersionedLib.Bar; + @test op test1 is VersionedLib.Operation<{name: string}, int32>; + alias test2 = VersionedLib.Operation<{name: string}, int32>; } `)) as { MyService: Namespace; Test: Model; getBar: Operation }; const versions = buildVersionProjections(runner.program, MyService); @@ -116,6 +123,8 @@ describe("versioning: reference versioned library", () => { v2 } @test model Test extends VersionedLib.Foo {} + @test op test1 is VersionedLib.Operation<{name: string}, int32>; + alias test2 = VersionedLib.Operation<{name: string}, int32>; } `)) as { MyService: Namespace; Test: Model }; const versions = buildVersionProjections(runner.program, MyService); @@ -144,6 +153,8 @@ describe("versioning: reference versioned library", () => { v2 } @test model Test extends VersionedLib.Foo {} + @test op test1 is VersionedLib.Operation<{name: string}, int32>; + alias test2 = VersionedLib.Operation<{name: string}, int32>; } `)) as { MyService: Namespace; Test: Model }; const versions = buildVersionProjections(runner.program, MyService); @@ -200,7 +211,7 @@ describe("versioning: reference versioned library", () => { }); describe("when using versioned library without @useDependency", () => { - it("emit diagnostic when used in extends", async () => { + it("emit diagnostic when model uses extends", async () => { const diagnostics = await runner.diagnose(` namespace MyService { model Test extends VersionedLib.Foo {} @@ -213,6 +224,60 @@ describe("versioning: reference versioned library", () => { }); }); + it("emit diagnostic when model uses is", async () => { + const diagnostics = await runner.diagnose(` + namespace MyService { + model Test is VersionedLib.Foo {} + } + `); + expectDiagnostics(diagnostics, { + code: "@typespec/versioning/using-versioned-library", + message: + "Namespace 'MyService' is referencing types from versioned namespace 'VersionedLib' but didn't specify which versions with @useDependency.", + }); + }); + + it("emit diagnostic when model uses alias", async () => { + const diagnostics = await runner.diagnose(` + namespace MyService { + alias Test = VersionedLib.Foo; + op test(): Test; + } + `); + expectDiagnostics(diagnostics, { + code: "@typespec/versioning/using-versioned-library", + message: + "Namespace 'MyService' is referencing types from versioned namespace 'VersionedLib' but didn't specify which versions with @useDependency.", + }); + }); + + it("emit diagnostic when operation uses is", async () => { + const diagnostics = await runner.diagnose(` + namespace MyService { + op test is VersionedLib.Operation<{name: string}, int32>; + } + `); + expectDiagnostics(diagnostics, { + code: "@typespec/versioning/using-versioned-library", + message: + "Namespace 'MyService' is referencing types from versioned namespace 'VersionedLib' but didn't specify which versions with @useDependency.", + }); + }); + + it("emit diagnostic when operation uses alias", async () => { + const diagnostics = await runner.diagnose(` + namespace MyService { + alias test = VersionedLib.Operation<{name: string}, int32>; + op myTest is test; + } + `); + expectDiagnostics(diagnostics, { + code: "@typespec/versioning/using-versioned-library", + message: + "Namespace 'MyService' is referencing types from versioned namespace 'VersionedLib' but didn't specify which versions with @useDependency.", + }); + }); + it("emit diagnostic when used in properties", async () => { const diagnostics = await runner.diagnose(` namespace MyService {