| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package parser | 5 package parser |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "fmt" | 8 "fmt" |
| 9 "mojom/mojom_tool/mojom" | 9 "mojom/mojom_tool/mojom" |
| 10 "mojom/mojom_tool/parser" | 10 "mojom/mojom_tool/parser" |
| (...skipping 1066 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1077 } | 1077 } |
| 1078 | 1078 |
| 1079 if c.testFunc != nil { | 1079 if c.testFunc != nil { |
| 1080 if err := c.testFunc(descriptor); err != nil { | 1080 if err := c.testFunc(descriptor); err != nil { |
| 1081 t.Errorf("%s:\n%s", fileName, err.Error()) | 1081 t.Errorf("%s:\n%s", fileName, err.Error()) |
| 1082 continue | 1082 continue |
| 1083 } | 1083 } |
| 1084 } | 1084 } |
| 1085 } | 1085 } |
| 1086 } | 1086 } |
| 1087 | |
| 1088 //////////////////////////////////////////////// | |
| 1089 /// TestFindReachableTypes | |
| 1090 //////////////////////////////////////////////// | |
| 1091 | |
| 1092 // typeGraphTestCase stores the data for one test case. | |
| 1093 type typeGraphTestCase struct { | |
| 1094 mojomContents string | |
| 1095 typeToSearch string | |
| 1096 expectedReachableTypes []string | |
| 1097 } | |
| 1098 | |
| 1099 // typeGraphTest contains a series of test cases. | |
| 1100 type typeGraphTest struct { | |
| 1101 cases []typeGraphTestCase | |
| 1102 } | |
| 1103 | |
| 1104 // addTestCase() should be invoked at the start of a case in TestFindReachableTy
pes. | |
| 1105 func (test *typeGraphTest) addTestCase(contents, typeToSearch string, expectedRe
achableTypes []string) { | |
| 1106 test.cases = append(test.cases, typeGraphTestCase{contents, typeToSearch
, expectedReachableTypes}) | |
| 1107 } | |
| 1108 | |
| 1109 // TestFindReachableTypes() iterates through a series of test cases. | |
| 1110 // For each case we expect for parsing and resolution to succeed. Then we | |
| 1111 // invoke FindReachableTypes() on |typeToSearch| and compare the result | |
| 1112 // to |expectedReachableTypes|. | |
| 1113 func TestFindReachableTypes(t *testing.T) { | |
| 1114 test := typeGraphTest{} | |
| 1115 | |
| 1116 //////////////////////////////////////////////////////////// | |
| 1117 // Test Case | |
| 1118 //////////////////////////////////////////////////////////// | |
| 1119 { | |
| 1120 contents := ` | |
| 1121 struct Struct1{ | |
| 1122 }; | |
| 1123 | |
| 1124 struct Struct2{ | |
| 1125 Struct1 x; | |
| 1126 }; | |
| 1127 | |
| 1128 struct Struct3{ | |
| 1129 Struct2 x; | |
| 1130 }; | |
| 1131 | |
| 1132 struct Struct4{ | |
| 1133 Struct3 x; | |
| 1134 }; | |
| 1135 | |
| 1136 union Union1 { | |
| 1137 Struct3 x; | |
| 1138 Struct2 y; | |
| 1139 }; | |
| 1140 | |
| 1141 union Union2 { | |
| 1142 Struct2 x; | |
| 1143 }; | |
| 1144 ` | |
| 1145 test.addTestCase(contents, | |
| 1146 "Struct4", | |
| 1147 []string{"Struct1", "Struct2", "Struct3", "Struct4"}, | |
| 1148 ) | |
| 1149 | |
| 1150 test.addTestCase(contents, | |
| 1151 "Union1", | |
| 1152 []string{"Union1", "Struct1", "Struct2", "Struct3"}, | |
| 1153 ) | |
| 1154 | |
| 1155 test.addTestCase(contents, | |
| 1156 "Union2", | |
| 1157 []string{"Union2", "Struct1", "Struct2"}, | |
| 1158 ) | |
| 1159 } | |
| 1160 | |
| 1161 //////////////////////////////////////////////////////////// | |
| 1162 // Test Case | |
| 1163 //////////////////////////////////////////////////////////// | |
| 1164 { | |
| 1165 contents := ` | |
| 1166 struct Struct1{ | |
| 1167 Struct4 x; | |
| 1168 }; | |
| 1169 | |
| 1170 struct Struct2{ | |
| 1171 Struct1 x; | |
| 1172 }; | |
| 1173 | |
| 1174 struct Struct3{ | |
| 1175 Struct2 x; | |
| 1176 }; | |
| 1177 | |
| 1178 struct Struct4{ | |
| 1179 Struct3 x; | |
| 1180 }; | |
| 1181 | |
| 1182 union Union1 { | |
| 1183 Struct2 x; | |
| 1184 }; | |
| 1185 ` | |
| 1186 | |
| 1187 test.addTestCase(contents, | |
| 1188 "Union1", | |
| 1189 []string{"Union1", "Struct1", "Struct2", "Struct3", "Str
uct4"}, | |
| 1190 ) | |
| 1191 } | |
| 1192 | |
| 1193 //////////////////////////////////////////////////////////// | |
| 1194 // Test Cases | |
| 1195 //////////////////////////////////////////////////////////// | |
| 1196 { | |
| 1197 contents := ` | |
| 1198 | |
| 1199 enum Height { | |
| 1200 SHORT, TALL | |
| 1201 }; | |
| 1202 | |
| 1203 struct Struct1{ | |
| 1204 enum Color { | |
| 1205 RED, BLUE | |
| 1206 }; | |
| 1207 }; | |
| 1208 | |
| 1209 struct Struct2{ | |
| 1210 const Struct1.Color FAVORITE = RED; | |
| 1211 }; | |
| 1212 ` | |
| 1213 | |
| 1214 test.addTestCase(contents, | |
| 1215 "Struct1", | |
| 1216 []string{"Struct1", "Struct1.Color"}, | |
| 1217 ) | |
| 1218 | |
| 1219 test.addTestCase(contents, | |
| 1220 "Struct2", | |
| 1221 []string{"Struct2", "Struct1.Color"}, | |
| 1222 ) | |
| 1223 } | |
| 1224 | |
| 1225 //////////////////////////////////////////////////////////// | |
| 1226 // Test Cases | |
| 1227 //////////////////////////////////////////////////////////// | |
| 1228 { | |
| 1229 contents := ` | |
| 1230 enum Color { | |
| 1231 RED, BLUE | |
| 1232 }; | |
| 1233 | |
| 1234 enum Height { | |
| 1235 SHORT, TALL | |
| 1236 }; | |
| 1237 | |
| 1238 struct Struct1{}; | |
| 1239 struct Struct2{}; | |
| 1240 | |
| 1241 interface Interface1 { | |
| 1242 const Color FAVORITE_COLOR = RED; | |
| 1243 | |
| 1244 Foo(int32 x) => (string y); | |
| 1245 }; | |
| 1246 | |
| 1247 interface Interface2 { | |
| 1248 Foo(int32 x) => (Struct1 y); | |
| 1249 Bar(string x); | |
| 1250 }; | |
| 1251 ` | |
| 1252 | |
| 1253 test.addTestCase(contents, | |
| 1254 "Interface1", | |
| 1255 []string{"Interface1", "Color"}, | |
| 1256 ) | |
| 1257 | |
| 1258 test.addTestCase(contents, | |
| 1259 "Interface2", | |
| 1260 []string{"Interface2", "Struct1"}, | |
| 1261 ) | |
| 1262 } | |
| 1263 | |
| 1264 //////////////////////////////////////////////////////////// | |
| 1265 // Test Cases | |
| 1266 //////////////////////////////////////////////////////////// | |
| 1267 | |
| 1268 { | |
| 1269 contents := ` | |
| 1270 enum Color { | |
| 1271 RED, BLUE | |
| 1272 }; | |
| 1273 | |
| 1274 enum Height { | |
| 1275 SHORT, TALL | |
| 1276 }; | |
| 1277 | |
| 1278 struct Struct1{}; | |
| 1279 struct Struct2{}; | |
| 1280 | |
| 1281 interface Interface1 { | |
| 1282 const Color FAVORITE_COLOR = RED; | |
| 1283 | |
| 1284 Foo(map<Height, int8> x) => (string y); | |
| 1285 }; | |
| 1286 | |
| 1287 interface Interface2 { | |
| 1288 Foo(int32 x) => (array<Struct1?> y); | |
| 1289 }; | |
| 1290 ` | |
| 1291 | |
| 1292 test.addTestCase(contents, | |
| 1293 "Interface1", | |
| 1294 []string{"Interface1", "Color", "Height"}, | |
| 1295 ) | |
| 1296 | |
| 1297 test.addTestCase(contents, | |
| 1298 "Interface2", | |
| 1299 []string{"Interface2", "Struct1"}, | |
| 1300 ) | |
| 1301 } | |
| 1302 | |
| 1303 //////////////////////////////////////////////////////////// | |
| 1304 // Test Cases | |
| 1305 //////////////////////////////////////////////////////////// | |
| 1306 | |
| 1307 { | |
| 1308 contents := ` | |
| 1309 enum Color { | |
| 1310 RED, BLUE | |
| 1311 }; | |
| 1312 | |
| 1313 enum Height { | |
| 1314 SHORT, TALL | |
| 1315 }; | |
| 1316 | |
| 1317 struct Struct1{}; | |
| 1318 struct Struct2{}; | |
| 1319 | |
| 1320 interface Interface1 { | |
| 1321 const Color FAVORITE_COLOR = RED; | |
| 1322 | |
| 1323 Foo(int32 x) => (string y); | |
| 1324 Bar(map<string, Height> z) => (); | |
| 1325 }; | |
| 1326 | |
| 1327 interface Interface2 { | |
| 1328 Foo(int32 x) => (map<Height, Struct1?> y); | |
| 1329 }; | |
| 1330 ` | |
| 1331 | |
| 1332 test.addTestCase(contents, | |
| 1333 "Interface1", | |
| 1334 []string{"Interface1", "Color", "Height"}, | |
| 1335 ) | |
| 1336 | |
| 1337 test.addTestCase(contents, | |
| 1338 "Interface2", | |
| 1339 []string{"Interface2", "Height", "Struct1"}, | |
| 1340 ) | |
| 1341 } | |
| 1342 | |
| 1343 //////////////////////////////////////////////////////////// | |
| 1344 // Execute all of the test cases. | |
| 1345 //////////////////////////////////////////////////////////// | |
| 1346 for i, c := range test.cases { | |
| 1347 // Parse and resolve the mojom input. | |
| 1348 descriptor := mojom.NewMojomDescriptor() | |
| 1349 fileName := fmt.Sprintf("file%d", i) | |
| 1350 parser := parser.MakeParser(fileName, fileName, c.mojomContents,
descriptor, nil) | |
| 1351 parser.Parse() | |
| 1352 if !parser.OK() { | |
| 1353 t.Errorf("Parsing error for %s: %s", fileName, parser.Ge
tError().Error()) | |
| 1354 continue | |
| 1355 } | |
| 1356 err := descriptor.Resolve() | |
| 1357 if err != nil { | |
| 1358 t.Errorf("Resolution failed for test case %d: %s", i, er
r.Error()) | |
| 1359 continue | |
| 1360 } | |
| 1361 | |
| 1362 userDefinedType := descriptor.TypesByKey[mojom.ComputeTypeKey(c.
typeToSearch)] | |
| 1363 result := userDefinedType.FindReachableTypes() | |
| 1364 if err := compareTypeSets(descriptor, c.expectedReachableTypes,
result); err != nil { | |
| 1365 t.Errorf("Case %d, unexpected typeset for %s: %s\n", i,
c.typeToSearch, err.Error()) | |
| 1366 continue | |
| 1367 } | |
| 1368 } | |
| 1369 } | |
| 1370 | |
| 1371 func compareTypeSets(descriptor *mojom.MojomDescriptor, expectedTypeNames, actua
lTypeKeys []string) error { | |
| 1372 expectedSet := userDefinedTypeSet(descriptor, expectedTypeNames, false) | |
| 1373 actualSet := userDefinedTypeSet(descriptor, actualTypeKeys, true) | |
| 1374 return expectedSet.Compare(&actualSet) | |
| 1375 } | |
| 1376 | |
| 1377 func userDefinedTypeSet(descriptor *mojom.MojomDescriptor, types []string, types
AreKeys bool) mojom.UserDefinedTypeSet { | |
| 1378 typeSet := mojom.MakeUserDefinedTypeSet() | |
| 1379 for _, t := range types { | |
| 1380 if t == "" { | |
| 1381 panic("Found empty type in types array.") | |
| 1382 } | |
| 1383 var typeKey string | |
| 1384 if typesAreKeys { | |
| 1385 typeKey = t | |
| 1386 } else { | |
| 1387 typeKey = mojom.ComputeTypeKey(t) | |
| 1388 } | |
| 1389 userDefinedType := descriptor.TypesByKey[typeKey] | |
| 1390 if userDefinedType == nil { | |
| 1391 panic(fmt.Sprintf("No type found for: %s", t)) | |
| 1392 } | |
| 1393 typeSet.Add(userDefinedType) | |
| 1394 } | |
| 1395 return typeSet | |
| 1396 } | |
| OLD | NEW |