diff --git a/tools/markdown-to-html/BUILD.bazel b/tools/markdown-to-html/BUILD.bazel
index 5ffc0d29546d..e8e0be2ae210 100644
--- a/tools/markdown-to-html/BUILD.bazel
+++ b/tools/markdown-to-html/BUILD.bazel
@@ -1,11 +1,16 @@
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")
-load("//tools:defaults.bzl", "ts_library")
+load("//tools:defaults.bzl", "jasmine_node_test", "ts_library")
package(default_visibility = ["//visibility:public"])
ts_library(
name = "transform-markdown",
- srcs = glob(["**/*.ts"]),
+ srcs = glob(
+ ["**/*.ts"],
+ exclude = [
+ "*.spec.ts",
+ ],
+ ),
tsconfig = ":tsconfig.json",
deps = [
"//tools/highlight-files:sources",
@@ -23,3 +28,26 @@ nodejs_binary(
],
entry_point = ":transform-markdown.ts",
)
+
+ts_library(
+ name = "unit_test_lib",
+ testonly = True,
+ srcs = glob(
+ ["*.spec.ts"],
+ ),
+ tsconfig = ":tsconfig.json",
+ visibility = ["//visibility:private"],
+ deps = [
+ ":transform-markdown",
+ "@npm//@types/jasmine",
+ "@npm//@types/node",
+ "@npm//marked",
+ "@npm//typescript",
+ ],
+)
+
+jasmine_node_test(
+ name = "unit_tests",
+ srcs = [":unit_test_lib"],
+ visibility = ["//visibility:private"],
+)
diff --git a/tools/markdown-to-html/docs-marked-renderer.spec.ts b/tools/markdown-to-html/docs-marked-renderer.spec.ts
new file mode 100644
index 000000000000..139fb5a750aa
--- /dev/null
+++ b/tools/markdown-to-html/docs-marked-renderer.spec.ts
@@ -0,0 +1,97 @@
+import {DocsMarkdownRenderer} from './docs-marked-renderer';
+
+describe('DocsMarkdownRenderer', () => {
+ let renderer: DocsMarkdownRenderer;
+ beforeEach(() => {
+ renderer = new DocsMarkdownRenderer();
+ });
+
+ it('generates regular headings for h1 and h2', () => {
+ expect(renderer.heading('a', 1, 'ignored')).toEqual('
a
');
+ expect(renderer.heading('b', 2, 'ignored')).toEqual('b
');
+ });
+
+ it('creates header link for h3 and h4 headings', () => {
+ const heading3 = renderer.heading('heading text', 3, 'link-id');
+ expectEqualIgnoreLeadingWhitespace(heading3, `
+
+ `);
+ const heading4 = renderer.heading('heading text', 4, 'second-link-id');
+ expectEqualIgnoreLeadingWhitespace(heading4, `
+
+ `);
+ });
+
+ it('handles duplicate ids for headings', () => {
+ expect(renderer.heading('first', 3, 'id')).toContain('id="id"');
+ expect(renderer.heading('second', 3, 'id')).toContain('id="id-1"');
+ });
+
+ it('generates links', () => {
+ expect(renderer.link('something', 'some title', 'some text'))
+ .toEqual('some text');
+ expect(renderer.link('guide/something', 'some title', 'some text'))
+ .toEqual('some text');
+ expect(renderer.link('#some-hash', 'some title', 'some text'))
+ .toEqual('some text');
+ expect(renderer.link('http://google.com', 'some title', 'some text'))
+ .toEqual('some text');
+ });
+
+ it('generates html using new API', () => {
+ const result = renderer.html(``);
+
+ // TODO(annieyw): I think DocsMarkedRenderer#html needs to be fixed for the new API?
+ expectEqualIgnoreLeadingWhitespace(result, ``);
+ });
+
+ it('generates html using old API', () => {
+ expect(renderer.html(''))
+ .toEqual('');
+ });
+
+ it('allows id links with matching id element', () => {
+ let output = renderer.link('#my-id', 'link title', 'link text');
+ output += renderer.heading('heading text', 3, 'my-id');
+ const result = renderer.finalizeOutput(output, 'filename.html');
+ expect(result).toEqual(jasmine.stringMatching(/ {
+ spyOn(console, 'error');
+ spyOn(process, 'exit');
+ let output = renderer.link('#my-id', 'link title', 'link text');
+ renderer.finalizeOutput(output, 'filename.html');
+ expect((console.error as jasmine.Spy).calls.allArgs()).toEqual([
+ [jasmine.stringMatching(/Could not process file: filename.html.*/)],
+ [jasmine.stringMatching(/.*Found link to "my-id". This heading does not exist./)]
+ ]);
+ expect(process.exit).toHaveBeenCalledWith(1);
+ });
+
+ function expectEqualIgnoreLeadingWhitespace(actual: string, expected: string) {
+ expect(stripLeadingWhitespace(actual)).toEqual(stripLeadingWhitespace(expected));
+ }
+
+ function stripLeadingWhitespace(s: string) {
+ return s.replace(/^\s*/gm, '');
+ }
+});
diff --git a/tools/markdown-to-html/tsconfig.json b/tools/markdown-to-html/tsconfig.json
index 13dba047bbcf..69768c4fcf79 100644
--- a/tools/markdown-to-html/tsconfig.json
+++ b/tools/markdown-to-html/tsconfig.json
@@ -4,8 +4,14 @@
"module": "commonjs",
"target": "es5",
"sourceMap": true,
- "types": ["node"]
+ "types": [
+ "jasmine",
+ "node"
+ ]
},
+ "exclude": [
+ "*.spec.ts",
+ ],
"bazelOptions": {
"suppressTsconfigOverrideWarnings": true
}