Colin Cross | d00350c | 2017-11-17 10:55:38 -0800 | [diff] [blame] | 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 | |
Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 15 | package parser |
| 16 | |
| 17 | import ( |
| 18 | "strings" |
| 19 | "testing" |
| 20 | ) |
| 21 | |
| 22 | var splitNTestCases = []struct { |
| 23 | in *MakeString |
| 24 | expected []*MakeString |
| 25 | sep string |
| 26 | n int |
| 27 | }{ |
| 28 | { |
Sasha Smundak | cbc17ee | 2020-11-29 12:51:55 -0800 | [diff] [blame] | 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"), |
Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 31 | sep: " ", |
| 32 | n: -1, |
| 33 | expected: []*MakeString{ |
Sasha Smundak | cbc17ee | 2020-11-29 12:51:55 -0800 | [diff] [blame] | 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"), |
Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 42 | }, |
| 43 | }, |
| 44 | { |
Sasha Smundak | cbc17ee | 2020-11-29 12:51:55 -0800 | [diff] [blame] | 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"), |
Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 47 | sep: " ", |
| 48 | n: 3, |
| 49 | expected: []*MakeString{ |
Sasha Smundak | cbc17ee | 2020-11-29 12:51:55 -0800 | [diff] [blame] | 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(""), |
Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 76 | }, |
| 77 | }, |
| 78 | } |
| 79 | |
| 80 | func 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 | |
Dan Willemsen | 4339853 | 2018-02-21 02:10:29 -0800 | [diff] [blame] | 91 | var valueTestCases = []struct { |
| 92 | in *MakeString |
| 93 | expected string |
| 94 | }{ |
| 95 | { |
Sasha Smundak | cbc17ee | 2020-11-29 12:51:55 -0800 | [diff] [blame] | 96 | in: genMakeString("a b"), |
Dan Willemsen | 4339853 | 2018-02-21 02:10:29 -0800 | [diff] [blame] | 97 | expected: "a b", |
| 98 | }, |
| 99 | { |
Sasha Smundak | cbc17ee | 2020-11-29 12:51:55 -0800 | [diff] [blame] | 100 | in: genMakeString("a\\ \\\tb\\\\"), |
Dan Willemsen | 4339853 | 2018-02-21 02:10:29 -0800 | [diff] [blame] | 101 | expected: "a \tb\\", |
| 102 | }, |
| 103 | { |
Sasha Smundak | cbc17ee | 2020-11-29 12:51:55 -0800 | [diff] [blame] | 104 | in: genMakeString("a\\b\\"), |
Dan Willemsen | 4339853 | 2018-02-21 02:10:29 -0800 | [diff] [blame] | 105 | expected: "a\\b\\", |
| 106 | }, |
| 107 | } |
| 108 | |
| 109 | func 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 | |
| 118 | var splitWordsTestCases = []struct { |
| 119 | in *MakeString |
| 120 | expected []*MakeString |
| 121 | }{ |
| 122 | { |
Sasha Smundak | cbc17ee | 2020-11-29 12:51:55 -0800 | [diff] [blame] | 123 | in: genMakeString(""), |
Dan Willemsen | 4339853 | 2018-02-21 02:10:29 -0800 | [diff] [blame] | 124 | expected: []*MakeString{}, |
| 125 | }, |
| 126 | { |
Sasha Smundak | cbc17ee | 2020-11-29 12:51:55 -0800 | [diff] [blame] | 127 | in: genMakeString(` a b\ c d`), |
Dan Willemsen | 4339853 | 2018-02-21 02:10:29 -0800 | [diff] [blame] | 128 | expected: []*MakeString{ |
Sasha Smundak | cbc17ee | 2020-11-29 12:51:55 -0800 | [diff] [blame] | 129 | genMakeString("a"), |
| 130 | genMakeString(`b\ c`), |
| 131 | genMakeString("d"), |
Dan Willemsen | 4339853 | 2018-02-21 02:10:29 -0800 | [diff] [blame] | 132 | }, |
| 133 | }, |
| 134 | { |
Sasha Smundak | cbc17ee | 2020-11-29 12:51:55 -0800 | [diff] [blame] | 135 | in: SimpleMakeString(" a\tb"+`\`+"\t"+`\ c d `, NoPos), |
Dan Willemsen | 4339853 | 2018-02-21 02:10:29 -0800 | [diff] [blame] | 136 | expected: []*MakeString{ |
Sasha Smundak | cbc17ee | 2020-11-29 12:51:55 -0800 | [diff] [blame] | 137 | genMakeString("a"), |
| 138 | genMakeString("b" + `\` + "\t" + `\ c`), |
| 139 | genMakeString("d"), |
Dan Willemsen | 4339853 | 2018-02-21 02:10:29 -0800 | [diff] [blame] | 140 | }, |
| 141 | }, |
| 142 | { |
Sasha Smundak | cbc17ee | 2020-11-29 12:51:55 -0800 | [diff] [blame] | 143 | in: genMakeString(`a\\ b\\\ c d`), |
Dan Willemsen | 4339853 | 2018-02-21 02:10:29 -0800 | [diff] [blame] | 144 | expected: []*MakeString{ |
Sasha Smundak | cbc17ee | 2020-11-29 12:51:55 -0800 | [diff] [blame] | 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", ""), |
Dan Willemsen | 4339853 | 2018-02-21 02:10:29 -0800 | [diff] [blame] | 205 | }, |
| 206 | }, |
| 207 | } |
| 208 | |
| 209 | func 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 | |
Cole Faust | 35b994e | 2022-04-27 13:37:32 -0700 | [diff] [blame] | 220 | var endsWithTestCases = []struct { |
| 221 | in *MakeString |
| 222 | endsWith rune |
| 223 | expected bool |
| 224 | }{ |
| 225 | { |
| 226 | in: genMakeString("foo", "X", "bar ="), |
| 227 | endsWith: '=', |
| 228 | expected: true, |
| 229 | }, |
| 230 | { |
| 231 | in: genMakeString("foo", "X", "bar ="), |
| 232 | endsWith: ':', |
| 233 | expected: false, |
| 234 | }, |
| 235 | { |
| 236 | in: genMakeString("foo", "X", ""), |
| 237 | endsWith: '=', |
| 238 | expected: false, |
| 239 | }, |
| 240 | } |
| 241 | |
| 242 | func TestMakeStringEndsWith(t *testing.T) { |
| 243 | for _, test := range endsWithTestCases { |
| 244 | if test.in.EndsWith(test.endsWith) != test.expected { |
| 245 | t.Errorf("with:\n%q\nexpected:\n%t\ngot:\n%t", test.in.Dump(), test.expected, !test.expected) |
| 246 | } |
| 247 | } |
| 248 | } |
| 249 | |
Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 250 | func dumpArray(a []*MakeString) string { |
| 251 | ret := make([]string, len(a)) |
| 252 | |
| 253 | for i, s := range a { |
| 254 | ret[i] = s.Dump() |
| 255 | } |
| 256 | |
| 257 | return strings.Join(ret, "|||") |
| 258 | } |
Sasha Smundak | cbc17ee | 2020-11-29 12:51:55 -0800 | [diff] [blame] | 259 | |
| 260 | // generates MakeString from alternating string chunks and variable names, |
| 261 | // e.g., genMakeString("a", "X", "b") returns MakeString for "a$(X)b" |
| 262 | func genMakeString(items ...string) *MakeString { |
| 263 | n := len(items) / 2 |
| 264 | if len(items) != (2*n + 1) { |
| 265 | panic("genMakeString expects odd number of arguments") |
| 266 | } |
| 267 | |
| 268 | ms := &MakeString{Strings: make([]string, n+1), Variables: make([]Variable, n)} |
| 269 | ms.Strings[0] = items[0] |
| 270 | for i := 1; i <= n; i++ { |
| 271 | ms.Variables[i-1] = Variable{Name: SimpleMakeString(items[2*i-1], NoPos)} |
| 272 | ms.Strings[i] = items[2*i] |
| 273 | } |
| 274 | return ms |
| 275 | } |