| // 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 |
| } |