// Copyright 2017 Google Inc. All rights reserved. // // 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 parser import ( "strings" "testing" ) var splitNTestCases = []struct { in *MakeString expected []*MakeString sep string n int }{ { // "a b c$(var1)d e f$(var2) h i j" in: genMakeString("a b c", "var1", "d e f", "var2", " h i j"), sep: " ", n: -1, expected: []*MakeString{ genMakeString("a"), genMakeString("b"), genMakeString("c", "var1", "d"), genMakeString("e"), genMakeString("f", "var2", ""), genMakeString("h"), genMakeString("i"), genMakeString("j"), }, }, { // "a b c$(var1)d e f$(var2) h i j" in: genMakeString("a b c", "var1", "d e f", "var2", " h i j"), sep: " ", n: 3, expected: []*MakeString{ genMakeString("a"), genMakeString("b"), genMakeString("c", "var1", "d e f", "var2", " h i j"), }, }, { // "$(var1) $(var2)" in: genMakeString("", "var1", " ", "var2", ""), sep: " ", n: -1, expected: []*MakeString{ genMakeString("", "var1", ""), genMakeString("", "var2", ""), }, }, { // "a,,b,c," in: genMakeString("a,,b,c,"), sep: ",", n: -1, expected: []*MakeString{ genMakeString("a"), genMakeString(""), genMakeString("b"), genMakeString("c"), genMakeString(""), }, }, { // "x$(var1)y bar" in: genMakeString("x", "var1", "y bar"), sep: " ", n: 2, expected: []*MakeString{ genMakeString("x", "var1", "y"), genMakeString("bar"), }, }, } func TestMakeStringSplitN(t *testing.T) { for _, test := range splitNTestCases { got := test.in.SplitN(test.sep, test.n) gotString := dumpArray(got) expectedString := dumpArray(test.expected) if gotString != expectedString { t.Errorf("expected:\n%s\ngot:\n%s", expectedString, gotString) } } } var valueTestCases = []struct { in *MakeString expected string }{ { in: genMakeString("a b"), expected: "a b", }, { in: genMakeString("a\\ \\\tb\\\\"), expected: "a \tb\\", }, { in: genMakeString("a\\b\\"), expected: "a\\b\\", }, } func TestMakeStringValue(t *testing.T) { for _, test := range valueTestCases { got := test.in.Value(nil) if got != test.expected { t.Errorf("\nwith: %q\nwant: %q\n got: %q", test.in.Dump(), test.expected, got) } } } var splitWordsTestCases = []struct { in *MakeString expected []*MakeString }{ { in: genMakeString(""), expected: []*MakeString{}, }, { in: genMakeString(` a b\ c d`), expected: []*MakeString{ genMakeString("a"), genMakeString(`b\ c`), genMakeString("d"), }, }, { in: SimpleMakeString(" a\tb"+`\`+"\t"+`\ c d `, NoPos), expected: []*MakeString{ genMakeString("a"), genMakeString("b" + `\` + "\t" + `\ c`), genMakeString("d"), }, }, { in: genMakeString(`a\\ b\\\ c d`), expected: []*MakeString{ genMakeString(`a\\`), genMakeString(`b\\\ c`), genMakeString("d"), }, }, { in: genMakeString(`\\ a`), expected: []*MakeString{ genMakeString(`\\`), genMakeString("a"), }, }, { // " " in: &MakeString{ Strings: []string{" \t \t"}, Variables: nil, }, expected: []*MakeString{}, }, { // " a $(X)b c " in: genMakeString(" a ", "X", "b c "), expected: []*MakeString{ genMakeString("a"), genMakeString("", "X", "b"), genMakeString("c"), }, }, { // " a b$(X)c d" in: genMakeString(" a b", "X", "c d"), expected: []*MakeString{ genMakeString("a"), genMakeString("b", "X", "c"), genMakeString("d"), }, }, { // "$(X) $(Y)" in: genMakeString("", "X", " ", "Y", ""), expected: []*MakeString{ genMakeString("", "X", ""), genMakeString("", "Y", ""), }, }, { // " a$(X) b" in: genMakeString(" a", "X", " b"), expected: []*MakeString{ genMakeString("a", "X", ""), genMakeString("b"), }, }, { // "a$(X) b$(Y) " in: genMakeString("a", "X", " b", "Y", " "), expected: []*MakeString{ genMakeString("a", "X", ""), genMakeString("b", "Y", ""), }, }, } func TestMakeStringWords(t *testing.T) { for _, test := range splitWordsTestCases { got := test.in.Words() gotString := dumpArray(got) expectedString := dumpArray(test.expected) if gotString != expectedString { t.Errorf("with:\n%q\nexpected:\n%s\ngot:\n%s", test.in.Dump(), expectedString, gotString) } } } var endsWithTestCases = []struct { in *MakeString endsWith rune expected bool }{ { in: genMakeString("foo", "X", "bar ="), endsWith: '=', expected: true, }, { in: genMakeString("foo", "X", "bar ="), endsWith: ':', expected: false, }, { in: genMakeString("foo", "X", ""), endsWith: '=', expected: false, }, } func TestMakeStringEndsWith(t *testing.T) { for _, test := range endsWithTestCases { if test.in.EndsWith(test.endsWith) != test.expected { t.Errorf("with:\n%q\nexpected:\n%t\ngot:\n%t", test.in.Dump(), test.expected, !test.expected) } } } func dumpArray(a []*MakeString) string { ret := make([]string, len(a)) for i, s := range a { ret[i] = s.Dump() } return strings.Join(ret, "|||") } // generates MakeString from alternating string chunks and variable names, // e.g., genMakeString("a", "X", "b") returns MakeString for "a$(X)b" func genMakeString(items ...string) *MakeString { n := len(items) / 2 if len(items) != (2*n + 1) { panic("genMakeString expects odd number of arguments") } ms := &MakeString{Strings: make([]string, n+1), Variables: make([]Variable, n)} ms.Strings[0] = items[0] for i := 1; i <= n; i++ { ms.Variables[i-1] = Variable{Name: SimpleMakeString(items[2*i-1], NoPos)} ms.Strings[i] = items[2*i] } return ms }