From 88d74a15aaeb1e1445180910520e2147060dfc9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vlastimil=20Ov=C4=8D=C3=A1=C4=8D=C3=ADk?= Date: Fri, 24 Sep 2021 02:45:06 +0200 Subject: [PATCH] Change the tests to run on Windows (#2615) Most of the "expected" strings in terminal.go test were changed to "text/template" values. Quotes in those string were parametrized in the templates. Two functions handling templates were added for convenience. Templates has the advantage of: - parametrize repetitive strings inside "expected" values - inner and outer quotes were parametrized in templates - long and confusing test values are more readable - templates can be localized for other operating systems --- src/reader_test.go | 2 +- src/terminal_test.go | 74 +++++++++++++++++++++++++++++++------------- 2 files changed, 53 insertions(+), 23 deletions(-) diff --git a/src/reader_test.go b/src/reader_test.go index 8bbb488..feb45fc 100644 --- a/src/reader_test.go +++ b/src/reader_test.go @@ -22,7 +22,7 @@ func TestReadFromCommand(t *testing.T) { } // Normal command - reader.fin(reader.readFromCommand(nil, `echo abc && echo def`)) + reader.fin(reader.readFromCommand(nil, `echo abc&&echo def`)) if len(strs) != 2 || strs[0] != "abc" || strs[1] != "def" { t.Errorf("%s", strs) } diff --git a/src/terminal_test.go b/src/terminal_test.go index 74dd106..bb10ec1 100644 --- a/src/terminal_test.go +++ b/src/terminal_test.go @@ -1,8 +1,10 @@ package fzf import ( + "bytes" "regexp" "testing" + "text/template" "github.com/junegunn/fzf/src/util" ) @@ -30,75 +32,91 @@ func TestReplacePlaceholder(t *testing.T) { t.Errorf("expected: %s, actual: %s", expected, result) } } + // helper function that converts template format into string and carries out the check() + checkFormat := func(format string) { + type quotes struct{ O, I string } // outer, inner quotes + unixStyle := quotes{"'", "'\\''"} + windowsStyle := quotes{"^\"", "'"} + var effectiveStyle quotes + + if util.IsWindows() { + effectiveStyle = windowsStyle + } else { + effectiveStyle = unixStyle + } + + expected := templateToString(format, effectiveStyle) + check(expected) + } printsep := "\n" // {}, preserve ansi result = replacePlaceholder("echo {}", false, Delimiter{}, printsep, false, "query", items1) - check("echo ' foo'\\''bar \x1b[31mbaz\x1b[m'") + checkFormat("echo {{.O}} foo{{.I}}bar \x1b[31mbaz\x1b[m{{.O}}") // {}, strip ansi result = replacePlaceholder("echo {}", true, Delimiter{}, printsep, false, "query", items1) - check("echo ' foo'\\''bar baz'") + checkFormat("echo {{.O}} foo{{.I}}bar baz{{.O}}") // {}, with multiple items result = replacePlaceholder("echo {}", true, Delimiter{}, printsep, false, "query", items2) - check("echo 'foo'\\''bar baz'") + checkFormat("echo {{.O}}foo{{.I}}bar baz{{.O}}") // {..}, strip leading whitespaces, preserve ansi result = replacePlaceholder("echo {..}", false, Delimiter{}, printsep, false, "query", items1) - check("echo 'foo'\\''bar \x1b[31mbaz\x1b[m'") + checkFormat("echo {{.O}}foo{{.I}}bar \x1b[31mbaz\x1b[m{{.O}}") // {..}, strip leading whitespaces, strip ansi result = replacePlaceholder("echo {..}", true, Delimiter{}, printsep, false, "query", items1) - check("echo 'foo'\\''bar baz'") + checkFormat("echo {{.O}}foo{{.I}}bar baz{{.O}}") // {q} result = replacePlaceholder("echo {} {q}", true, Delimiter{}, printsep, false, "query", items1) - check("echo ' foo'\\''bar baz' 'query'") + checkFormat("echo {{.O}} foo{{.I}}bar baz{{.O}} {{.O}}query{{.O}}") // {q}, multiple items result = replacePlaceholder("echo {+}{q}{+}", true, Delimiter{}, printsep, false, "query 'string'", items2) - check("echo 'foo'\\''bar baz' 'FOO'\\''BAR BAZ''query '\\''string'\\''''foo'\\''bar baz' 'FOO'\\''BAR BAZ'") + checkFormat("echo {{.O}}foo{{.I}}bar baz{{.O}} {{.O}}FOO{{.I}}BAR BAZ{{.O}}{{.O}}query {{.I}}string{{.I}}{{.O}}{{.O}}foo{{.I}}bar baz{{.O}} {{.O}}FOO{{.I}}BAR BAZ{{.O}}") result = replacePlaceholder("echo {}{q}{}", true, Delimiter{}, printsep, false, "query 'string'", items2) - check("echo 'foo'\\''bar baz''query '\\''string'\\''''foo'\\''bar baz'") + checkFormat("echo {{.O}}foo{{.I}}bar baz{{.O}}{{.O}}query {{.I}}string{{.I}}{{.O}}{{.O}}foo{{.I}}bar baz{{.O}}") result = replacePlaceholder("echo {1}/{2}/{2,1}/{-1}/{-2}/{}/{..}/{n.t}/\\{}/\\{1}/\\{q}/{3}", true, Delimiter{}, printsep, false, "query", items1) - check("echo 'foo'\\''bar'/'baz'/'bazfoo'\\''bar'/'baz'/'foo'\\''bar'/' foo'\\''bar baz'/'foo'\\''bar baz'/{n.t}/{}/{1}/{q}/''") + checkFormat("echo {{.O}}foo{{.I}}bar{{.O}}/{{.O}}baz{{.O}}/{{.O}}bazfoo{{.I}}bar{{.O}}/{{.O}}baz{{.O}}/{{.O}}foo{{.I}}bar{{.O}}/{{.O}} foo{{.I}}bar baz{{.O}}/{{.O}}foo{{.I}}bar baz{{.O}}/{n.t}/{}/{1}/{q}/{{.O}}{{.O}}") result = replacePlaceholder("echo {1}/{2}/{-1}/{-2}/{..}/{n.t}/\\{}/\\{1}/\\{q}/{3}", true, Delimiter{}, printsep, false, "query", items2) - check("echo 'foo'\\''bar'/'baz'/'baz'/'foo'\\''bar'/'foo'\\''bar baz'/{n.t}/{}/{1}/{q}/''") + checkFormat("echo {{.O}}foo{{.I}}bar{{.O}}/{{.O}}baz{{.O}}/{{.O}}baz{{.O}}/{{.O}}foo{{.I}}bar{{.O}}/{{.O}}foo{{.I}}bar baz{{.O}}/{n.t}/{}/{1}/{q}/{{.O}}{{.O}}") result = replacePlaceholder("echo {+1}/{+2}/{+-1}/{+-2}/{+..}/{n.t}/\\{}/\\{1}/\\{q}/{+3}", true, Delimiter{}, printsep, false, "query", items2) - check("echo 'foo'\\''bar' 'FOO'\\''BAR'/'baz' 'BAZ'/'baz' 'BAZ'/'foo'\\''bar' 'FOO'\\''BAR'/'foo'\\''bar baz' 'FOO'\\''BAR BAZ'/{n.t}/{}/{1}/{q}/'' ''") + checkFormat("echo {{.O}}foo{{.I}}bar{{.O}} {{.O}}FOO{{.I}}BAR{{.O}}/{{.O}}baz{{.O}} {{.O}}BAZ{{.O}}/{{.O}}baz{{.O}} {{.O}}BAZ{{.O}}/{{.O}}foo{{.I}}bar{{.O}} {{.O}}FOO{{.I}}BAR{{.O}}/{{.O}}foo{{.I}}bar baz{{.O}} {{.O}}FOO{{.I}}BAR BAZ{{.O}}/{n.t}/{}/{1}/{q}/{{.O}}{{.O}} {{.O}}{{.O}}") // forcePlus result = replacePlaceholder("echo {1}/{2}/{-1}/{-2}/{..}/{n.t}/\\{}/\\{1}/\\{q}/{3}", true, Delimiter{}, printsep, true, "query", items2) - check("echo 'foo'\\''bar' 'FOO'\\''BAR'/'baz' 'BAZ'/'baz' 'BAZ'/'foo'\\''bar' 'FOO'\\''BAR'/'foo'\\''bar baz' 'FOO'\\''BAR BAZ'/{n.t}/{}/{1}/{q}/'' ''") + checkFormat("echo {{.O}}foo{{.I}}bar{{.O}} {{.O}}FOO{{.I}}BAR{{.O}}/{{.O}}baz{{.O}} {{.O}}BAZ{{.O}}/{{.O}}baz{{.O}} {{.O}}BAZ{{.O}}/{{.O}}foo{{.I}}bar{{.O}} {{.O}}FOO{{.I}}BAR{{.O}}/{{.O}}foo{{.I}}bar baz{{.O}} {{.O}}FOO{{.I}}BAR BAZ{{.O}}/{n.t}/{}/{1}/{q}/{{.O}}{{.O}} {{.O}}{{.O}}") // Whitespace preserving flag with "'" delimiter result = replacePlaceholder("echo {s1}", true, Delimiter{str: &delim}, printsep, false, "query", items1) - check("echo ' foo'") + checkFormat("echo {{.O}} foo{{.O}}") result = replacePlaceholder("echo {s2}", true, Delimiter{str: &delim}, printsep, false, "query", items1) - check("echo 'bar baz'") + checkFormat("echo {{.O}}bar baz{{.O}}") result = replacePlaceholder("echo {s}", true, Delimiter{str: &delim}, printsep, false, "query", items1) - check("echo ' foo'\\''bar baz'") + checkFormat("echo {{.O}} foo{{.I}}bar baz{{.O}}") result = replacePlaceholder("echo {s..}", true, Delimiter{str: &delim}, printsep, false, "query", items1) - check("echo ' foo'\\''bar baz'") + checkFormat("echo {{.O}} foo{{.I}}bar baz{{.O}}") // Whitespace preserving flag with regex delimiter regex = regexp.MustCompile(`\w+`) result = replacePlaceholder("echo {s1}", true, Delimiter{regex: regex}, printsep, false, "query", items1) - check("echo ' '") + checkFormat("echo {{.O}} {{.O}}") result = replacePlaceholder("echo {s2}", true, Delimiter{regex: regex}, printsep, false, "query", items1) - check("echo ''\\'''") + checkFormat("echo {{.O}}{{.I}}{{.O}}") result = replacePlaceholder("echo {s3}", true, Delimiter{regex: regex}, printsep, false, "query", items1) - check("echo ' '") + checkFormat("echo {{.O}} {{.O}}") // No match result = replacePlaceholder("echo {}/{+}", true, Delimiter{}, printsep, false, "query", []*Item{nil, nil}) @@ -106,17 +124,17 @@ func TestReplacePlaceholder(t *testing.T) { // No match, but with selections result = replacePlaceholder("echo {}/{+}", true, Delimiter{}, printsep, false, "query", []*Item{nil, item1}) - check("echo /' foo'\\''bar baz'") + checkFormat("echo /{{.O}} foo{{.I}}bar baz{{.O}}") // String delimiter result = replacePlaceholder("echo {}/{1}/{2}", true, Delimiter{str: &delim}, printsep, false, "query", items1) - check("echo ' foo'\\''bar baz'/'foo'/'bar baz'") + checkFormat("echo {{.O}} foo{{.I}}bar baz{{.O}}/{{.O}}foo{{.O}}/{{.O}}bar baz{{.O}}") // Regex delimiter regex = regexp.MustCompile("[oa]+") // foo'bar baz result = replacePlaceholder("echo {}/{1}/{3}/{2..3}", true, Delimiter{regex: regex}, printsep, false, "query", items1) - check("echo ' foo'\\''bar baz'/'f'/'r b'/''\\''bar b'") + checkFormat("echo {{.O}} foo{{.I}}bar baz{{.O}}/{{.O}}f{{.O}}/{{.O}}r b{{.O}}/{{.O}}{{.I}}bar b{{.O}}") } func TestQuoteEntryCmd(t *testing.T) { @@ -137,3 +155,15 @@ func TestQuoteEntryCmd(t *testing.T) { } } } + +// Helper function to parse, execute and convert "text/template" to string. Panics on error. +func templateToString(format string, data interface{}) string { + bb := &bytes.Buffer{} + + err := template.Must(template.New("").Parse(format)).Execute(bb, data) + if err != nil { + panic(err) + } + + return bb.String() +}