1// Copyright 2017 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package parser 16 17import ( 18 "strings" 19 "testing" 20) 21 22var splitNTestCases = []struct { 23 in *MakeString 24 expected []*MakeString 25 sep string 26 n int 27}{ 28 { 29 // "a b c$(var1)d e f$(var2) h i j" 30 in: genMakeString("a b c", "var1", "d e f", "var2", " h i j"), 31 sep: " ", 32 n: -1, 33 expected: []*MakeString{ 34 genMakeString("a"), 35 genMakeString("b"), 36 genMakeString("c", "var1", "d"), 37 genMakeString("e"), 38 genMakeString("f", "var2", ""), 39 genMakeString("h"), 40 genMakeString("i"), 41 genMakeString("j"), 42 }, 43 }, 44 { 45 // "a b c$(var1)d e f$(var2) h i j" 46 in: genMakeString("a b c", "var1", "d e f", "var2", " h i j"), 47 sep: " ", 48 n: 3, 49 expected: []*MakeString{ 50 genMakeString("a"), 51 genMakeString("b"), 52 genMakeString("c", "var1", "d e f", "var2", " h i j"), 53 }, 54 }, 55 { 56 // "$(var1) $(var2)" 57 in: genMakeString("", "var1", " ", "var2", ""), 58 sep: " ", 59 n: -1, 60 expected: []*MakeString{ 61 genMakeString("", "var1", ""), 62 genMakeString("", "var2", ""), 63 }, 64 }, 65 { 66 // "a,,b,c," 67 in: genMakeString("a,,b,c,"), 68 sep: ",", 69 n: -1, 70 expected: []*MakeString{ 71 genMakeString("a"), 72 genMakeString(""), 73 genMakeString("b"), 74 genMakeString("c"), 75 genMakeString(""), 76 }, 77 }, 78} 79 80func TestMakeStringSplitN(t *testing.T) { 81 for _, test := range splitNTestCases { 82 got := test.in.SplitN(test.sep, test.n) 83 gotString := dumpArray(got) 84 expectedString := dumpArray(test.expected) 85 if gotString != expectedString { 86 t.Errorf("expected:\n%s\ngot:\n%s", expectedString, gotString) 87 } 88 } 89} 90 91var valueTestCases = []struct { 92 in *MakeString 93 expected string 94}{ 95 { 96 in: genMakeString("a b"), 97 expected: "a b", 98 }, 99 { 100 in: genMakeString("a\\ \\\tb\\\\"), 101 expected: "a \tb\\", 102 }, 103 { 104 in: genMakeString("a\\b\\"), 105 expected: "a\\b\\", 106 }, 107} 108 109func TestMakeStringValue(t *testing.T) { 110 for _, test := range valueTestCases { 111 got := test.in.Value(nil) 112 if got != test.expected { 113 t.Errorf("\nwith: %q\nwant: %q\n got: %q", test.in.Dump(), test.expected, got) 114 } 115 } 116} 117 118var splitWordsTestCases = []struct { 119 in *MakeString 120 expected []*MakeString 121}{ 122 { 123 in: genMakeString(""), 124 expected: []*MakeString{}, 125 }, 126 { 127 in: genMakeString(` a b\ c d`), 128 expected: []*MakeString{ 129 genMakeString("a"), 130 genMakeString(`b\ c`), 131 genMakeString("d"), 132 }, 133 }, 134 { 135 in: SimpleMakeString(" a\tb"+`\`+"\t"+`\ c d `, NoPos), 136 expected: []*MakeString{ 137 genMakeString("a"), 138 genMakeString("b" + `\` + "\t" + `\ c`), 139 genMakeString("d"), 140 }, 141 }, 142 { 143 in: genMakeString(`a\\ b\\\ c d`), 144 expected: []*MakeString{ 145 genMakeString(`a\\`), 146 genMakeString(`b\\\ c`), 147 genMakeString("d"), 148 }, 149 }, 150 { 151 in: genMakeString(`\\ a`), 152 expected: []*MakeString{ 153 genMakeString(`\\`), 154 genMakeString("a"), 155 }, 156 }, 157 { 158 // " " 159 in: &MakeString{ 160 Strings: []string{" \t \t"}, 161 Variables: nil, 162 }, 163 expected: []*MakeString{}, 164 }, 165 { 166 // " a $(X)b c " 167 in: genMakeString(" a ", "X", "b c "), 168 expected: []*MakeString{ 169 genMakeString("a"), 170 genMakeString("", "X", "b"), 171 genMakeString("c"), 172 }, 173 }, 174 { 175 // " a b$(X)c d" 176 in: genMakeString(" a b", "X", "c d"), 177 expected: []*MakeString{ 178 genMakeString("a"), 179 genMakeString("b", "X", "c"), 180 genMakeString("d"), 181 }, 182 }, 183 { 184 // "$(X) $(Y)" 185 in: genMakeString("", "X", " ", "Y", ""), 186 expected: []*MakeString{ 187 genMakeString("", "X", ""), 188 genMakeString("", "Y", ""), 189 }, 190 }, 191 { 192 // " a$(X) b" 193 in: genMakeString(" a", "X", " b"), 194 expected: []*MakeString{ 195 genMakeString("a", "X", ""), 196 genMakeString("b"), 197 }, 198 }, 199 { 200 // "a$(X) b$(Y) " 201 in: genMakeString("a", "X", " b", "Y", " "), 202 expected: []*MakeString{ 203 genMakeString("a", "X", ""), 204 genMakeString("b", "Y", ""), 205 }, 206 }, 207} 208 209func TestMakeStringWords(t *testing.T) { 210 for _, test := range splitWordsTestCases { 211 got := test.in.Words() 212 gotString := dumpArray(got) 213 expectedString := dumpArray(test.expected) 214 if gotString != expectedString { 215 t.Errorf("with:\n%q\nexpected:\n%s\ngot:\n%s", test.in.Dump(), expectedString, gotString) 216 } 217 } 218} 219 220func dumpArray(a []*MakeString) string { 221 ret := make([]string, len(a)) 222 223 for i, s := range a { 224 ret[i] = s.Dump() 225 } 226 227 return strings.Join(ret, "|||") 228} 229 230// generates MakeString from alternating string chunks and variable names, 231// e.g., genMakeString("a", "X", "b") returns MakeString for "a$(X)b" 232func genMakeString(items ...string) *MakeString { 233 n := len(items) / 2 234 if len(items) != (2*n + 1) { 235 panic("genMakeString expects odd number of arguments") 236 } 237 238 ms := &MakeString{Strings: make([]string, n+1), Variables: make([]Variable, n)} 239 ms.Strings[0] = items[0] 240 for i := 1; i <= n; i++ { 241 ms.Variables[i-1] = Variable{Name: SimpleMakeString(items[2*i-1], NoPos)} 242 ms.Strings[i] = items[2*i] 243 } 244 return ms 245} 246