2016-10-03 05:16:10 +00:00
|
|
|
package fzf
|
|
|
|
|
|
|
|
import (
|
|
|
|
"regexp"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/junegunn/fzf/src/util"
|
|
|
|
)
|
|
|
|
|
|
|
|
func newItem(str string) *Item {
|
|
|
|
bytes := []byte(str)
|
|
|
|
trimmed, _, _ := extractColor(str, nil, nil)
|
2017-07-21 08:29:14 +00:00
|
|
|
return &Item{origText: &bytes, text: util.ToChars([]byte(trimmed))}
|
2016-10-03 05:16:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestReplacePlaceholder(t *testing.T) {
|
2017-01-27 08:46:56 +00:00
|
|
|
item1 := newItem(" foo'bar \x1b[31mbaz\x1b[m")
|
|
|
|
items1 := []*Item{item1, item1}
|
2016-10-03 05:16:10 +00:00
|
|
|
items2 := []*Item{
|
2017-01-27 08:46:56 +00:00
|
|
|
newItem("foo'bar \x1b[31mbaz\x1b[m"),
|
2016-10-03 05:16:10 +00:00
|
|
|
newItem("foo'bar \x1b[31mbaz\x1b[m"),
|
|
|
|
newItem("FOO'BAR \x1b[31mBAZ\x1b[m")}
|
|
|
|
|
2018-03-30 02:47:46 +00:00
|
|
|
delim := "'"
|
|
|
|
var regex *regexp.Regexp
|
|
|
|
|
2016-10-03 05:16:10 +00:00
|
|
|
var result string
|
|
|
|
check := func(expected string) {
|
|
|
|
if result != expected {
|
|
|
|
t.Errorf("expected: %s, actual: %s", expected, result)
|
|
|
|
}
|
|
|
|
}
|
2019-10-27 14:50:12 +00:00
|
|
|
printsep := "\n"
|
2016-10-03 05:16:10 +00:00
|
|
|
// {}, preserve ansi
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {}", false, Delimiter{}, printsep, false, "query", items1)
|
2016-10-03 05:16:10 +00:00
|
|
|
check("echo ' foo'\\''bar \x1b[31mbaz\x1b[m'")
|
|
|
|
|
|
|
|
// {}, strip ansi
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {}", true, Delimiter{}, printsep, false, "query", items1)
|
2016-10-03 05:16:10 +00:00
|
|
|
check("echo ' foo'\\''bar baz'")
|
|
|
|
|
|
|
|
// {}, with multiple items
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {}", true, Delimiter{}, printsep, false, "query", items2)
|
2017-01-27 08:46:56 +00:00
|
|
|
check("echo 'foo'\\''bar baz'")
|
2016-10-03 05:16:10 +00:00
|
|
|
|
|
|
|
// {..}, strip leading whitespaces, preserve ansi
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {..}", false, Delimiter{}, printsep, false, "query", items1)
|
2016-10-03 05:16:10 +00:00
|
|
|
check("echo 'foo'\\''bar \x1b[31mbaz\x1b[m'")
|
|
|
|
|
|
|
|
// {..}, strip leading whitespaces, strip ansi
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {..}", true, Delimiter{}, printsep, false, "query", items1)
|
2016-10-03 05:16:10 +00:00
|
|
|
check("echo 'foo'\\''bar baz'")
|
|
|
|
|
|
|
|
// {q}
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {} {q}", true, Delimiter{}, printsep, false, "query", items1)
|
2016-10-03 05:16:10 +00:00
|
|
|
check("echo ' foo'\\''bar baz' 'query'")
|
|
|
|
|
|
|
|
// {q}, multiple items
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {+}{q}{+}", true, Delimiter{}, printsep, false, "query 'string'", items2)
|
2016-10-03 05:16:10 +00:00
|
|
|
check("echo 'foo'\\''bar baz' 'FOO'\\''BAR BAZ''query '\\''string'\\''''foo'\\''bar baz' 'FOO'\\''BAR BAZ'")
|
|
|
|
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {}{q}{}", true, Delimiter{}, printsep, false, "query 'string'", items2)
|
2017-01-27 08:46:56 +00:00
|
|
|
check("echo 'foo'\\''bar baz''query '\\''string'\\''''foo'\\''bar baz'")
|
|
|
|
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {1}/{2}/{2,1}/{-1}/{-2}/{}/{..}/{n.t}/\\{}/\\{1}/\\{q}/{3}", true, Delimiter{}, printsep, false, "query", items1)
|
2016-10-03 05:16:10 +00:00
|
|
|
check("echo 'foo'\\''bar'/'baz'/'bazfoo'\\''bar'/'baz'/'foo'\\''bar'/' foo'\\''bar baz'/'foo'\\''bar baz'/{n.t}/{}/{1}/{q}/''")
|
|
|
|
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {1}/{2}/{-1}/{-2}/{..}/{n.t}/\\{}/\\{1}/\\{q}/{3}", true, Delimiter{}, printsep, false, "query", items2)
|
2017-01-27 08:46:56 +00:00
|
|
|
check("echo 'foo'\\''bar'/'baz'/'baz'/'foo'\\''bar'/'foo'\\''bar baz'/{n.t}/{}/{1}/{q}/''")
|
|
|
|
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {+1}/{+2}/{+-1}/{+-2}/{+..}/{n.t}/\\{}/\\{1}/\\{q}/{+3}", true, Delimiter{}, printsep, false, "query", items2)
|
2016-10-03 05:16:10 +00:00
|
|
|
check("echo 'foo'\\''bar' 'FOO'\\''BAR'/'baz' 'BAZ'/'baz' 'BAZ'/'foo'\\''bar' 'FOO'\\''BAR'/'foo'\\''bar baz' 'FOO'\\''BAR BAZ'/{n.t}/{}/{1}/{q}/'' ''")
|
|
|
|
|
2017-01-27 08:46:56 +00:00
|
|
|
// forcePlus
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {1}/{2}/{-1}/{-2}/{..}/{n.t}/\\{}/\\{1}/\\{q}/{3}", true, Delimiter{}, printsep, true, "query", items2)
|
2017-01-27 08:46:56 +00:00
|
|
|
check("echo 'foo'\\''bar' 'FOO'\\''BAR'/'baz' 'BAZ'/'baz' 'BAZ'/'foo'\\''bar' 'FOO'\\''BAR'/'foo'\\''bar baz' 'FOO'\\''BAR BAZ'/{n.t}/{}/{1}/{q}/'' ''")
|
|
|
|
|
2018-03-30 02:47:46 +00:00
|
|
|
// Whitespace preserving flag with "'" delimiter
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {s1}", true, Delimiter{str: &delim}, printsep, false, "query", items1)
|
2018-03-30 02:47:46 +00:00
|
|
|
check("echo ' foo'")
|
|
|
|
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {s2}", true, Delimiter{str: &delim}, printsep, false, "query", items1)
|
2018-03-30 02:47:46 +00:00
|
|
|
check("echo 'bar baz'")
|
|
|
|
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {s}", true, Delimiter{str: &delim}, printsep, false, "query", items1)
|
2018-03-30 02:47:46 +00:00
|
|
|
check("echo ' foo'\\''bar baz'")
|
|
|
|
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {s..}", true, Delimiter{str: &delim}, printsep, false, "query", items1)
|
2018-03-30 02:47:46 +00:00
|
|
|
check("echo ' foo'\\''bar baz'")
|
|
|
|
|
|
|
|
// Whitespace preserving flag with regex delimiter
|
Improvements to code quality and readability (#1737)
* Remove 1 unused field and 3 unused functions
unused elements fount by running
golangci-lint run --disable-all --enable unused
src/result.go:19:2: field `index` is unused (unused)
index int32
^
src/tui/light.go:716:23: func `(*LightWindow).stderr` is unused (unused)
func (w *LightWindow) stderr(str string) {
^
src/terminal.go:1015:6: func `numLinesMax` is unused (unused)
func numLinesMax(str string, max int) int {
^
src/tui/tui.go:167:20: func `ColorPair.is24` is unused (unused)
func (p ColorPair) is24() bool {
^
* Address warnings from "gosimple" linter
src/options.go:389:83: S1003: should use strings.Contains(str, ",,,") instead (gosimple)
if str == "," || strings.HasPrefix(str, ",,") || strings.HasSuffix(str, ",,") || strings.Index(str, ",,,") >= 0 {
^
src/options.go:630:18: S1007: should use raw string (`...`) with regexp.MustCompile to avoid having to escape twice (gosimple)
executeRegexp = regexp.MustCompile(
^
src/terminal.go:29:16: S1007: should use raw string (`...`) with regexp.MustCompile to avoid having to escape twice (gosimple)
placeholder = regexp.MustCompile("\\\\?(?:{[+sf]*[0-9,-.]*}|{q}|{\\+?f?nf?})")
^
src/terminal_test.go:92:10: S1007: should use raw string (`...`) with regexp.MustCompile to avoid having to escape twice (gosimple)
regex = regexp.MustCompile("\\w+")
^
* Address warnings from "staticcheck" linter
src/algo/algo.go:374:2: SA4006: this value of `offset32` is never used (staticcheck)
offset32, T := alloc32(offset32, slab, N)
^
src/algo/algo.go:456:2: SA4006: this value of `offset16` is never used (staticcheck)
offset16, C := alloc16(offset16, slab, width*M)
^
src/tui/tui.go:119:2: SA9004: only the first constant in this group has an explicit type (staticcheck)
colUndefined Color = -2
^
2019-11-05 00:46:51 +00:00
|
|
|
regex = regexp.MustCompile(`\w+`)
|
2018-03-30 02:47:46 +00:00
|
|
|
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {s1}", true, Delimiter{regex: regex}, printsep, false, "query", items1)
|
2018-03-30 02:47:46 +00:00
|
|
|
check("echo ' '")
|
|
|
|
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {s2}", true, Delimiter{regex: regex}, printsep, false, "query", items1)
|
2018-03-30 02:47:46 +00:00
|
|
|
check("echo ''\\'''")
|
|
|
|
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {s3}", true, Delimiter{regex: regex}, printsep, false, "query", items1)
|
2018-03-30 02:47:46 +00:00
|
|
|
check("echo ' '")
|
|
|
|
|
2017-01-27 08:46:56 +00:00
|
|
|
// No match
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {}/{+}", true, Delimiter{}, printsep, false, "query", []*Item{nil, nil})
|
2017-01-27 08:46:56 +00:00
|
|
|
check("echo /")
|
|
|
|
|
|
|
|
// No match, but with selections
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {}/{+}", true, Delimiter{}, printsep, false, "query", []*Item{nil, item1})
|
2017-01-27 08:46:56 +00:00
|
|
|
check("echo /' foo'\\''bar baz'")
|
|
|
|
|
2016-10-03 05:16:10 +00:00
|
|
|
// String delimiter
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {}/{1}/{2}", true, Delimiter{str: &delim}, printsep, false, "query", items1)
|
2016-10-03 05:16:10 +00:00
|
|
|
check("echo ' foo'\\''bar baz'/'foo'/'bar baz'")
|
|
|
|
|
|
|
|
// Regex delimiter
|
2018-03-30 02:47:46 +00:00
|
|
|
regex = regexp.MustCompile("[oa]+")
|
2016-10-03 05:16:10 +00:00
|
|
|
// foo'bar baz
|
2019-10-27 14:50:12 +00:00
|
|
|
result = replacePlaceholder("echo {}/{1}/{3}/{2..3}", true, Delimiter{regex: regex}, printsep, false, "query", items1)
|
2016-10-03 05:16:10 +00:00
|
|
|
check("echo ' foo'\\''bar baz'/'f'/'r b'/''\\''bar b'")
|
|
|
|
}
|
2017-10-02 15:36:19 +00:00
|
|
|
|
|
|
|
func TestQuoteEntryCmd(t *testing.T) {
|
|
|
|
tests := map[string]string{
|
|
|
|
`"`: `^"\^"^"`,
|
|
|
|
`\`: `^"\\^"`,
|
|
|
|
`\"`: `^"\\\^"^"`,
|
|
|
|
`"\\\"`: `^"\^"\\\\\\\^"^"`,
|
|
|
|
`&|<>()@^%!`: `^"^&^|^<^>^(^)^@^^^%^!^"`,
|
|
|
|
`%USERPROFILE%`: `^"^%USERPROFILE^%^"`,
|
|
|
|
`C:\Program Files (x86)\`: `^"C:\\Program Files ^(x86^)\\^"`,
|
|
|
|
}
|
|
|
|
|
|
|
|
for input, expected := range tests {
|
|
|
|
escaped := quoteEntryCmd(input)
|
|
|
|
if escaped != expected {
|
|
|
|
t.Errorf("Input: %s, expected: %s, actual %s", input, expected, escaped)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|