1// Copyright 2018 The Bazel Authors. 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 res 16 17import ( 18 "reflect" 19 "strings" 20 "testing" 21) 22 23func TestNaming(t *testing.T) { 24 tests := []struct { 25 unparsed string 26 resType Type 27 want FullyQualifiedName 28 wantErrPrefix string 29 }{ 30 { 31 "style/InlineProjectStyle", 32 ValueType, 33 FullyQualifiedName{ 34 Name: "InlineProjectStyle", 35 Type: Style, 36 Package: "res-auto", 37 }, 38 "", 39 }, 40 { 41 "android:style/InlineProjectStyle", 42 ValueType, 43 FullyQualifiedName{ 44 Name: "InlineProjectStyle", 45 Type: Style, 46 Package: "android", 47 }, 48 "", 49 }, 50 { 51 "@style/InlineProjectStyle", 52 ValueType, 53 FullyQualifiedName{ 54 Name: "InlineProjectStyle", 55 Type: Style, 56 Package: "res-auto", 57 }, 58 "", 59 }, 60 { 61 "@style/android:InlineProjectStyle", 62 ValueType, 63 FullyQualifiedName{ 64 Name: "InlineProjectStyle", 65 Type: Style, 66 Package: "android", 67 }, 68 "", 69 }, 70 { 71 "?style/InlineProjectStyle", 72 ValueType, 73 FullyQualifiedName{ 74 Name: "InlineProjectStyle", 75 Type: Style, 76 Package: "res-auto", 77 }, 78 "", 79 }, 80 { 81 "?style/android:InlineProjectStyle", 82 ValueType, 83 FullyQualifiedName{ 84 Name: "InlineProjectStyle", 85 Type: Style, 86 Package: "android", 87 }, 88 "", 89 }, 90 { 91 "android:style/Widget.TextView", 92 ValueType, 93 FullyQualifiedName{ 94 Name: "Widget.TextView", 95 Type: Style, 96 Package: "android", 97 }, 98 "", 99 }, 100 { 101 "@android:style/Widget.TextView", 102 ValueType, 103 FullyQualifiedName{ 104 Name: "Widget.TextView", 105 Type: Style, 106 Package: "android", 107 }, 108 "", 109 }, 110 { 111 "?android:style/Widget.TextView", 112 ValueType, 113 FullyQualifiedName{ 114 Name: "Widget.TextView", 115 Type: Style, 116 Package: "android", 117 }, 118 "", 119 }, 120 { 121 "?attr/styleReference", 122 ValueType, 123 FullyQualifiedName{ 124 Name: "styleReference", 125 Type: Attr, 126 Package: "res-auto", 127 }, 128 "", 129 }, 130 { 131 "?android:attr/textAppearance", 132 ValueType, 133 FullyQualifiedName{ 134 Name: "textAppearance", 135 Type: Attr, 136 Package: "android", 137 }, 138 "", 139 }, 140 { 141 "?attr/android:textAppearance", 142 ValueType, 143 FullyQualifiedName{ 144 Name: "textAppearance", 145 Type: Attr, 146 Package: "android", 147 }, 148 "", 149 }, 150 { 151 "@dimen/viewer:progress_bar_height", 152 ValueType, 153 FullyQualifiedName{ 154 Name: "progress_bar_height", 155 Type: Dimen, 156 Package: "viewer", 157 }, 158 "", 159 }, 160 { 161 "drawable/simple", 162 Drawable, 163 FullyQualifiedName{ 164 Name: "simple", 165 Type: Drawable, 166 Package: "res-auto", 167 }, 168 "", 169 }, 170 { 171 "android:fraction/name", 172 ValueType, 173 FullyQualifiedName{ 174 Name: "name", 175 Type: Fraction, 176 Package: "android", 177 }, 178 "", 179 }, 180 { 181 "android:style/foo:with_colon", 182 ValueType, 183 FullyQualifiedName{ 184 Name: "foo:with_colon", 185 Type: Style, 186 Package: "android", 187 }, 188 "", 189 }, 190 { 191 "color/red", 192 ValueType, 193 FullyQualifiedName{ 194 Name: "red", 195 Type: Color, 196 Package: "res-auto", 197 }, 198 "", 199 }, 200 { 201 "style/bright:with_colon", 202 ValueType, 203 FullyQualifiedName{ 204 Name: "with_colon", 205 Type: Style, 206 Package: "bright", 207 }, 208 "", 209 }, 210 { 211 "com.google.android.apps.gmoney:array/available_locales", 212 ValueType, 213 FullyQualifiedName{ 214 Name: "available_locales", 215 Type: Array, 216 Package: "com.google.android.apps.gmoney", 217 }, 218 "", 219 }, 220 { 221 "@android:string/ok", 222 ValueType, 223 FullyQualifiedName{ 224 Name: "ok", 225 Type: String, 226 Package: "android", 227 }, 228 "", 229 }, 230 { 231 "@string/android:ok", 232 ValueType, 233 FullyQualifiedName{ 234 Name: "ok", 235 Type: String, 236 Package: "android", 237 }, 238 "", 239 }, 240 { 241 "name", 242 String, 243 FullyQualifiedName{ 244 Package: "res-auto", 245 Type: String, 246 Name: "name", 247 }, 248 "", 249 }, 250 { 251 "string/name", 252 String, 253 FullyQualifiedName{ 254 Package: "res-auto", 255 Type: String, 256 Name: "name", 257 }, 258 "", 259 }, 260 { 261 "android:Theme.Material.Light", 262 Style, 263 FullyQualifiedName{ 264 Package: "android", 265 Type: Style, 266 Name: "Theme.Material.Light", 267 }, 268 "", 269 }, 270 { 271 "@android:attr/borderlessButtonStyle", 272 Style, 273 FullyQualifiedName{ 274 Package: "android", 275 Type: Attr, 276 Name: "borderlessButtonStyle", 277 }, 278 "", 279 }, 280 { 281 "@id/:packagelessId", 282 Style, 283 FullyQualifiedName{ 284 Package: "res-auto", 285 Type: ID, 286 Name: "packagelessId", 287 }, 288 "", 289 }, 290 { 291 "InlineProjectStyle", 292 UnknownType, 293 FullyQualifiedName{}, 294 "cannot determine type", 295 }, 296 { 297 "android:InlineProjectStyle", 298 UnknownType, 299 FullyQualifiedName{}, 300 "cannot determine type", 301 }, 302 { 303 "res-auto:InlineProjectStyle", 304 UnknownType, 305 FullyQualifiedName{}, 306 "cannot determine type", 307 }, 308 { 309 "style/", 310 ValueType, 311 FullyQualifiedName{}, 312 "cannot determine name", 313 }, 314 { 315 ":style/InlineProjectStyle", 316 ValueType, 317 FullyQualifiedName{}, 318 "malformed name", 319 }, 320 { 321 "/InlineProjectStyle", 322 ValueType, 323 FullyQualifiedName{}, 324 "malformed name", 325 }, 326 } 327 328 for _, tc := range tests { 329 got, gotErr := ParseName(tc.unparsed, tc.resType) 330 if !reflect.DeepEqual(got, tc.want) { 331 t.Errorf("ParseName(%s, %+v): got: %#v want: %#v", tc.unparsed, tc.resType, got, tc.want) 332 } 333 334 if gotErr != nil && ("" == tc.wantErrPrefix || !strings.HasPrefix(gotErr.Error(), tc.wantErrPrefix)) { 335 t.Errorf("ParseName(%s, %+v): %v want prefix: %s", tc.unparsed, tc.resType, gotErr, tc.wantErrPrefix) 336 } 337 if gotErr == nil && "" != tc.wantErrPrefix { 338 t.Errorf("ParseName(%s, %+v): got no err want err prefix: %s", tc.unparsed, tc.resType, tc.wantErrPrefix) 339 } 340 } 341} 342