From 75e79dcaf9116c4f71719ee0b201fa7affb061be Mon Sep 17 00:00:00 2001 From: Travis Prescott Date: Wed, 8 Feb 2023 13:11:33 -0800 Subject: [PATCH] Final fixes. --- .../emitters/cadl-apiview/CHANGELOG.md | 5 +- .../emitters/cadl-apiview/src/apiview.ts | 5 +- .../cadl-apiview/test/apiview-options.test.ts | 62 +++++++++++++++++-- .../emitters/cadl-apiview/test/test-host.ts | 13 +++- 4 files changed, 77 insertions(+), 8 deletions(-) diff --git a/tools/apiview/emitters/cadl-apiview/CHANGELOG.md b/tools/apiview/emitters/cadl-apiview/CHANGELOG.md index 340881f9958..6b12380fa64 100644 --- a/tools/apiview/emitters/cadl-apiview/CHANGELOG.md +++ b/tools/apiview/emitters/cadl-apiview/CHANGELOG.md @@ -1,10 +1,13 @@ # Release History ## Version 0.3.5 (Unreleased) -BREAKING CHANGE: Removed the `--namespace` emitter option. +Support latest release of Cadl compiler. +**BREAKING CHANGE**: Removed the `--namespace` emitter option. Added the `--service` emitter option to support filtering output for multi-service specs. Emitter options `--output-file` and `--version` cannot be used with multi-service specs unless the `--service` option is provided. +Added the `--include-global-namespace` option to permit including the global namespace in the token file. +Fixed issue where namespaces that are not proper subnamespaces may be included in the token file. ## Version 0.3.4 (01-13-2023) Support latest release of Cadl compiler. diff --git a/tools/apiview/emitters/cadl-apiview/src/apiview.ts b/tools/apiview/emitters/cadl-apiview/src/apiview.ts index 97d596d132a..a103706b2bc 100644 --- a/tools/apiview/emitters/cadl-apiview/src/apiview.ts +++ b/tools/apiview/emitters/cadl-apiview/src/apiview.ts @@ -319,7 +319,6 @@ export class ApiView { if (name === this.packageName) { return true; } - // FIXME: This should actually ensure that it is a proper subnamespace if (!name.startsWith(this.packageName)) { return false; } @@ -343,7 +342,9 @@ export class ApiView { if (!this.shouldEmitNamespace(name)) { continue; } - const nsModel = new NamespaceModel(name, ns, program); + // use a fake name to make the global namespace clear + const namespaceName = name == "" ? "::GLOBAL::" : name; + const nsModel = new NamespaceModel(namespaceName, ns, program); if (nsModel.shouldEmit()) { this.tokenizeNamespaceModel(nsModel); this.buildNavigation(nsModel); diff --git a/tools/apiview/emitters/cadl-apiview/test/apiview-options.test.ts b/tools/apiview/emitters/cadl-apiview/test/apiview-options.test.ts index f5782f4de69..29ea0a74afb 100644 --- a/tools/apiview/emitters/cadl-apiview/test/apiview-options.test.ts +++ b/tools/apiview/emitters/cadl-apiview/test/apiview-options.test.ts @@ -1,7 +1,7 @@ import { Diagnostic, logDiagnostics, resolvePath } from "@cadl-lang/compiler"; -import { expectDiagnosticEmpty } from "@cadl-lang/compiler/testing"; +import { expectDiagnosticEmpty, expectDiagnostics } from "@cadl-lang/compiler/testing"; import { strictEqual } from "assert"; -import { apiViewFor, apiViewText, compare } from "./test-host.js"; +import { apiViewFor, apiViewText, compare, createApiViewTestRunner, diagnosticsFor } from "./test-host.js"; describe("apiview-options: tests", () => { @@ -44,8 +44,16 @@ describe("apiview-options: tests", () => { } `; const expect = ` - model SomeGlobal {}; + namespace ::GLOBAL:: { + model SomeGlobal {} + } + @Cadl.service( + { + title: "Test"; + version: "1"; + } + ) namespace Azure.Test { model Foo {} } @@ -54,7 +62,53 @@ describe("apiview-options: tests", () => { "include-global-namespace": true }); const actual = apiViewText(apiview); - compare(expect, actual, 9); + compare(expect, actual, 1); }); + it("emits error if multi-service package tries to specify version", async () => { + const input = ` + @Cadl.service( { title: "Test", version: "1" } ) + namespace Azure.Test { + model Foo {}; + } + + @Cadl.service( { title: "OtherTest", version: "1" } ) + namespace Azure.OtherTest { + model Foo {}; + } + ` + const diagnostics = await diagnosticsFor(input, {"version": "1"}); + expectDiagnostics(diagnostics, [ + { + code: "@azure-tools/cadl-apiview/invalid-option", + message: `Option "--output-file" cannot be used with multi-service specs unless "--service" is also supplied.` + }, + { + code: "@azure-tools/cadl-apiview/invalid-option", + message: `Option "--version" cannot be used with multi-service specs unless "--service" is also supplied.` + } + ]); + }); + + it("allows options if multi-service package specifies --service", async () => { + const input = ` + @Cadl.service( { title: "Test", version: "1" } ) + namespace Azure.Test { + model Foo {}; + } + + @Cadl.service( { title: "OtherTest", version: "1" } ) + namespace Azure.OtherTest { + model Foo {}; + } + `; + const expect = ` + namespace Azure.OtherTest { + model Foo {} + } + `; + const apiview = await apiViewFor(input, {"version": "1", "service": "OtherTest"}); + const actual = apiViewText(apiview); + compare(expect, actual, 9); + }); }); diff --git a/tools/apiview/emitters/cadl-apiview/test/test-host.ts b/tools/apiview/emitters/cadl-apiview/test/test-host.ts index ac7e61312e9..6f030ba197b 100644 --- a/tools/apiview/emitters/cadl-apiview/test/test-host.ts +++ b/tools/apiview/emitters/cadl-apiview/test/test-host.ts @@ -6,7 +6,7 @@ import { ApiViewTestLibrary } from "../src/testing/index.js"; import "@azure-tools/cadl-apiview"; import { ApiViewEmitterOptions } from "../src/lib.js"; import { ApiViewDocument, ApiViewTokenKind } from "../src/apiview.js"; -import { resolvePath } from "@cadl-lang/compiler"; +import { Diagnostic, resolvePath } from "@cadl-lang/compiler"; import { strictEqual } from "assert"; export async function createApiViewTestHost() { @@ -34,6 +34,17 @@ export async function createApiViewTestRunner({ }); } +export async function diagnosticsFor(code: string, options: ApiViewEmitterOptions): Promise { + const runner = await createApiViewTestRunner({withVersioning: true}); + const outPath = resolvePath("/apiview.json"); + const diagnostics = await runner.diagnose(code, { + noEmit: false, + emitters: { "@azure-tools/cadl-apiview": { ...options, "output-file": outPath } }, + miscOptions: { "disable-linter": true }, + }); + return diagnostics; +} + export async function apiViewFor(code: string, options: ApiViewEmitterOptions): Promise { const runner = await createApiViewTestRunner({withVersioning: true}); const outPath = resolvePath("/apiview.json");