From 9d2be187e550604879ad33d99379550b6fbebc3b Mon Sep 17 00:00:00 2001 From: Paco Xu Date: Tue, 27 Sep 2022 14:06:40 +0800 Subject: [PATCH] add unit test for normalizer rendering markdown --- .../kubectl/pkg/util/templates/markdown.go | 49 +++++++++--- .../kubectl/pkg/util/templates/normalizers.go | 2 +- .../pkg/util/templates/normalizers_test.go | 79 +++++++++++++++++++ 3 files changed, 117 insertions(+), 13 deletions(-) create mode 100644 staging/src/k8s.io/kubectl/pkg/util/templates/normalizers_test.go diff --git a/staging/src/k8s.io/kubectl/pkg/util/templates/markdown.go b/staging/src/k8s.io/kubectl/pkg/util/templates/markdown.go index 63b28cab4af..ff745c5664c 100644 --- a/staging/src/k8s.io/kubectl/pkg/util/templates/markdown.go +++ b/staging/src/k8s.io/kubectl/pkg/util/templates/markdown.go @@ -17,6 +17,7 @@ limitations under the License. package templates import ( + "fmt" "io" "strings" @@ -32,9 +33,10 @@ var _ blackfriday.Renderer = &ASCIIRenderer{} // documents as plain text, well suited for human reading on terminals. type ASCIIRenderer struct { Indentation string -} -func (r *ASCIIRenderer) GetFlags() int { return 0 } + listItemCount uint + listLevel uint +} // render markdown to text func (r *ASCIIRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus { @@ -51,13 +53,12 @@ func (r *ASCIIRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering } case blackfriday.HorizontalRule, blackfriday.Hardbreak: w.Write([]byte(linebreak + "----------" + linebreak)) - case blackfriday.Softbreak: - w.Write([]byte(linebreak)) - case blackfriday.Code: + case blackfriday.Code, blackfriday.CodeBlock: w.Write([]byte(linebreak)) lines := []string{} for _, line := range strings.Split(string(node.Literal), linebreak) { - indented := r.Indentation + line + trimmed := strings.Trim(line, " \t") + indented := r.Indentation + trimmed lines = append(lines, indented) } w.Write([]byte(strings.Join(lines, linebreak))) @@ -66,18 +67,42 @@ func (r *ASCIIRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering case blackfriday.Link: w.Write([]byte(" ")) w.Write(node.LinkData.Destination) - case blackfriday.List: - w.Write([]byte(linebreak)) - w.Write(node.Literal) case blackfriday.Paragraph: - w.Write(node.Literal) - w.Write([]byte(linebreak)) + if r.listLevel == 0 { + w.Write([]byte(linebreak)) + } + case blackfriday.List: + if entering { + w.Write([]byte(linebreak)) + r.listLevel++ + } else { + r.listLevel-- + r.listItemCount = 0 + } + case blackfriday.Item: + if entering { + r.listItemCount++ + for i := 0; uint(i) < r.listLevel; i++ { + w.Write([]byte(r.Indentation)) + } + if node.ListFlags&blackfriday.ListTypeOrdered != 0 { + w.Write([]byte(fmt.Sprintf("%d. ", r.listItemCount))) + } else { + w.Write([]byte("* ")) + } + } else { + w.Write([]byte(linebreak)) + } default: - w.Write(node.Literal) + normalText(w, node.Literal) } return blackfriday.GoToNext } +func normalText(w io.Writer, text []byte) { + w.Write([]byte(strings.Trim(string(text), " \n\t"))) +} + // RenderHeader writes document preamble and TOC if requested. func (r *ASCIIRenderer) RenderHeader(w io.Writer, ast *blackfriday.Node) { diff --git a/staging/src/k8s.io/kubectl/pkg/util/templates/normalizers.go b/staging/src/k8s.io/kubectl/pkg/util/templates/normalizers.go index 94d91e17e34..09094ffdfe7 100644 --- a/staging/src/k8s.io/kubectl/pkg/util/templates/normalizers.go +++ b/staging/src/k8s.io/kubectl/pkg/util/templates/normalizers.go @@ -70,7 +70,7 @@ type normalizer struct { func (s normalizer) markdown() normalizer { bytes := []byte(s.string) - formatted := blackfriday.Run(bytes, blackfriday.WithNoExtensions(), blackfriday.WithRenderer(&ASCIIRenderer{Indentation: Indentation})) + formatted := blackfriday.Run(bytes, blackfriday.WithExtensions(blackfriday.NoIntraEmphasis), blackfriday.WithRenderer(&ASCIIRenderer{Indentation: Indentation})) s.string = string(formatted) return s } diff --git a/staging/src/k8s.io/kubectl/pkg/util/templates/normalizers_test.go b/staging/src/k8s.io/kubectl/pkg/util/templates/normalizers_test.go new file mode 100644 index 00000000000..d517248d5dc --- /dev/null +++ b/staging/src/k8s.io/kubectl/pkg/util/templates/normalizers_test.go @@ -0,0 +1,79 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package templates + +import ( + "testing" +) + +func TestLongDescMarkdown(t *testing.T) { + tests := []struct { + desc string + in string + out string + }{ + { + desc: "Empty input produces empty output", + in: "", + out: "", + }, + { + desc: "Single line text is preserved as is", + in: "Some text", + out: "Some text", + }, + { + desc: "Consecutive new lines are combined into a single paragraph", + in: "Line1\nLine2", + out: "Line1 Line2", + }, + { + desc: "Two paragraphs", + in: "Line1\n\nLine2", + out: "Line1\n\n Line2", + }, + { + desc: "Leading and trailing spaces are stripped (single line)", + in: "\t \nThe text line \n \t", + out: "The text line", + }, + { + desc: "Leading and trailing spaces are stripped (multi line)", + in: "\t \nLine1\nLine2 \n \t", + out: "Line1 Line2", + }, + { + desc: "List Items with order", + in: "Title\n\n1. First item\n2. Second item\n\nSome text", + out: "Title\n\n 1. First item\n 2. Second item\n\n Some text", + }, + { + desc: "Multi lines without order", + in: "\t\t\t\t\tDescriptions.\n\n * Item.\n * Item2.", + out: "Descriptions.\n \n * Item.\n * Item2.", + }, + } + + for _, test := range tests { + t.Run(test.desc, func(t *testing.T) { + got := LongDesc(test.in) + if got != test.out { + t.Errorf("expected(%d):\n%s\n=====\ngot(%d):\n%s\n", len(test.out), test.out, len(got), got) + } + }) + } +}