| 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 /** @fileoverview Suite of tests for media-router-container. */ | 5 /** @fileoverview Suite of tests for media-router-container. */ |
| 6 cr.define('media_router_container', function() { | 6 cr.define('media_router_container', function() { |
| 7 function registerTests() { | 7 function registerTests() { |
| 8 suite('MediaRouterContainer', function() { | 8 suite('MediaRouterContainer', function() { |
| 9 /** | 9 /** |
| 10 * Media Router Container created before each test. | 10 * Media Router Container created before each test. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 'first-run-flow', | 59 'first-run-flow', |
| 60 'first-run-flow-cloud-pref', | 60 'first-run-flow-cloud-pref', |
| 61 'issue-banner', | 61 'issue-banner', |
| 62 'no-search-matches', | 62 'no-search-matches', |
| 63 'route-details', | 63 'route-details', |
| 64 'search-results', | 64 'search-results', |
| 65 'sink-list', | 65 'sink-list', |
| 66 'sink-list-view', | 66 'sink-list-view', |
| 67 ]; | 67 ]; |
| 68 | 68 |
| 69 /** | |
| 70 * Search text that will match all sinks. | |
| 71 * @type {string} | |
| 72 */ | |
| 73 var searchTextAll; | |
| 74 | |
| 75 /** | |
| 76 * Search text that won't match any sink in fakeSinkList. | |
| 77 * @type {string} | |
| 78 */ | |
| 79 var searchTextNone; | |
| 80 | |
| 81 /** | |
| 82 * Search text that will match exactly one sink. | |
| 83 * @type {string} | |
| 84 */ | |
| 85 var searchTextOne; | |
| 86 | |
| 87 // Checks whether |view| matches the current view of |container|. | 69 // Checks whether |view| matches the current view of |container|. |
| 88 var checkCurrentView = function(view) { | 70 var checkCurrentView = function(view) { |
| 89 assertEquals(view, container.currentView_); | 71 assertEquals(view, container.currentView_); |
| 90 }; | 72 }; |
| 91 | 73 |
| 92 // Checks whether the elements specified in |elementIdList| are visible. | 74 // Checks whether the elements specified in |elementIdList| are visible. |
| 93 // Checks whether all other elements are not visible. | 75 // Checks whether all other elements are not visible. |
| 94 var checkElementsVisibleWithId = function(elementIdList) { | 76 var checkElementsVisibleWithId = function(elementIdList) { |
| 95 for (var i = 0; i < elementIdList.length; i++) | 77 for (var i = 0; i < elementIdList.length; i++) |
| 96 checkElementVisibleWithId(true, elementIdList[i]); | 78 checkElementVisibleWithId(true, elementIdList[i]); |
| (...skipping 901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 998 | 980 |
| 999 setTimeout(function() { | 981 setTimeout(function() { |
| 1000 var sinkList = | 982 var sinkList = |
| 1001 container.$['sink-list'].querySelectorAll('paper-item'); | 983 container.$['sink-list'].querySelectorAll('paper-item'); |
| 1002 assertEquals(3, sinkList.length); | 984 assertEquals(3, sinkList.length); |
| 1003 done(); | 985 done(); |
| 1004 }); | 986 }); |
| 1005 }); | 987 }); |
| 1006 }); | 988 }); |
| 1007 }); | 989 }); |
| 1008 | |
| 1009 // Tests that clicking the search icon will cause the container to enter | |
| 1010 // filter view. | |
| 1011 test('click search icon', function(done) { | |
| 1012 MockInteractions.tap(container.$['sink-search-icon']); | |
| 1013 setTimeout(function() { | |
| 1014 checkCurrentView(media_router.MediaRouterView.FILTER); | |
| 1015 assertEquals(container.$['sink-search-input'], | |
| 1016 container.shadowRoot.activeElement); | |
| 1017 done(); | |
| 1018 }); | |
| 1019 }); | |
| 1020 | |
| 1021 // Tests that focusing the sink search input will cause the container to | |
| 1022 // enter filter view. | |
| 1023 test('focus sink search input', function(done) { | |
| 1024 MockInteractions.focus(container.$['sink-search-input']); | |
| 1025 setTimeout(function() { | |
| 1026 checkCurrentView(media_router.MediaRouterView.FILTER); | |
| 1027 assertEquals(container.$['sink-search-input'], | |
| 1028 container.shadowRoot.activeElement); | |
| 1029 done(); | |
| 1030 }); | |
| 1031 }); | |
| 1032 | |
| 1033 // Tests that the back button in the FILTER view returns |container| to | |
| 1034 // the SINK_LIST view. | |
| 1035 test('filter view back button', function(done) { | |
| 1036 MockInteractions.tap(container.$['sink-search-icon']); | |
| 1037 setTimeout(function() { | |
| 1038 MockInteractions.tap( | |
| 1039 container.$['container-header'].$['back-button']); | |
| 1040 checkCurrentView(media_router.MediaRouterView.SINK_LIST); | |
| 1041 done(); | |
| 1042 }); | |
| 1043 }); | |
| 1044 | |
| 1045 // Tests that pressing the Escape key in the FILTER view returns | |
| 1046 // |container| to the SINK_LIST view. | |
| 1047 test('filter view escape key', function(done) { | |
| 1048 MockInteractions.tap(container.$['sink-search-icon']); | |
| 1049 setTimeout(function() { | |
| 1050 MockInteractions.pressAndReleaseKeyOn( | |
| 1051 container, media_router.KEYCODE_ESC); | |
| 1052 checkCurrentView(media_router.MediaRouterView.SINK_LIST); | |
| 1053 done(); | |
| 1054 }); | |
| 1055 }); | |
| 1056 | |
| 1057 // Tests that expected elements are visible when in filter view. | |
| 1058 test('filter view visibility', function(done) { | |
| 1059 checkElementsVisibleWithId(['container-header', | |
| 1060 'device-missing', | |
| 1061 'sink-search', | |
| 1062 'sink-list-view']); | |
| 1063 // Clicking the search icon should transition |container| to FILTER | |
| 1064 // view. | |
| 1065 MockInteractions.tap(container.$['sink-search-icon']); | |
| 1066 setTimeout(function() { | |
| 1067 checkElementsVisibleWithId(['container-header', | |
| 1068 'device-missing', | |
| 1069 'sink-search', | |
| 1070 'sink-list-view']); | |
| 1071 | |
| 1072 // Adding sinks should populate the search list. | |
| 1073 container.allSinks = fakeSinkList; | |
| 1074 setTimeout(function() { | |
| 1075 checkElementsVisibleWithId(['container-header', | |
| 1076 'search-results', | |
| 1077 'sink-search', | |
| 1078 'sink-list-view']); | |
| 1079 // Typing text that doesn't match any sinks should display a 'no | |
| 1080 // matches' message. | |
| 1081 container.$['sink-search-input'].value = searchTextNone; | |
| 1082 checkElementsVisibleWithId(['container-header', | |
| 1083 'no-search-matches', | |
| 1084 'sink-search', | |
| 1085 'sink-list-view']); | |
| 1086 // Changing that text to something that matches at least one sink | |
| 1087 // should show the matching sinks again. | |
| 1088 container.$['sink-search-input'].value = searchTextOne; | |
| 1089 setTimeout(function() { | |
| 1090 checkElementsVisibleWithId(['container-header', | |
| 1091 'search-results', | |
| 1092 'sink-search', | |
| 1093 'sink-list-view']); | |
| 1094 // Clicking the back button should leave |searchTextOne| in the | |
| 1095 // input but return to the SINK_LIST view. | |
| 1096 MockInteractions.tap( | |
| 1097 container.$['container-header'].$['back-button']); | |
| 1098 checkElementsVisibleWithId(['container-header', | |
| 1099 'sink-search', | |
| 1100 'sink-list', | |
| 1101 'sink-list-view']); | |
| 1102 // When the search button is clicked again, the matching sinks | |
| 1103 // should be shown again. This doesn't prove that the matching | |
| 1104 // worked when returning to the FILTER view though, just that it | |
| 1105 // at least shows some sort of sink list as search results. | |
| 1106 MockInteractions.tap(container.$['sink-search-icon']); | |
| 1107 checkElementsVisibleWithId(['container-header', | |
| 1108 'search-results', | |
| 1109 'sink-search', | |
| 1110 'sink-list-view']); | |
| 1111 | |
| 1112 container.$['sink-search-input'].value = searchTextNone; | |
| 1113 // Clicking the back button should leave |searchTextNone| in the | |
| 1114 // input but return to the SINK_LIST view. | |
| 1115 MockInteractions.tap( | |
| 1116 container.$['container-header'].$['back-button']); | |
| 1117 checkElementsVisibleWithId(['container-header', | |
| 1118 'sink-search', | |
| 1119 'sink-list', | |
| 1120 'sink-list-view']); | |
| 1121 // When the search button is clicked again, there should be no | |
| 1122 // matches because |searchTextNone| should still be used to | |
| 1123 // filter. | |
| 1124 MockInteractions.tap(container.$['sink-search-icon']); | |
| 1125 checkElementsVisibleWithId(['container-header', | |
| 1126 'no-search-matches', | |
| 1127 'sink-search', | |
| 1128 'sink-list-view']); | |
| 1129 // Pressing the Escape key in FILTER view should return | |
| 1130 // |container| to SINK_LIST view and not exit the dialog. | |
| 1131 MockInteractions.pressAndReleaseKeyOn( | |
| 1132 container, media_router.KEYCODE_ESC); | |
| 1133 checkElementsVisibleWithId(['container-header', | |
| 1134 'sink-search', | |
| 1135 'sink-list', | |
| 1136 'sink-list-view']); | |
| 1137 done(); | |
| 1138 }); | |
| 1139 }); | |
| 1140 }); | |
| 1141 }); | |
| 1142 | |
| 1143 // Tests that entering filter view with text already in the search input | |
| 1144 // will immediately use that text to filter the sinks. This tests the case | |
| 1145 // that the text matches one sink. | |
| 1146 test('existing search text filters success', function(done) { | |
| 1147 container.allSinks = fakeSinkList; | |
| 1148 container.$['sink-search-input'].value = searchTextOne; | |
| 1149 MockInteractions.tap(container.$['sink-search-icon']); | |
| 1150 setTimeout(function() { | |
| 1151 var searchResults = | |
| 1152 container.$$('#search-results').querySelectorAll('paper-item'); | |
| 1153 assertEquals(1, searchResults.length); | |
| 1154 done(); | |
| 1155 }); | |
| 1156 }); | |
| 1157 | |
| 1158 // Tests that entering filter view with text already in the search input | |
| 1159 // will immediately use that text to filter the sinks. This tests the case | |
| 1160 // that the text doesn't match any sinks. | |
| 1161 test('existing search text filters fail', function(done) { | |
| 1162 container.allSinks = fakeSinkList; | |
| 1163 container.$['sink-search-input'].value = searchTextNone; | |
| 1164 MockInteractions.tap(container.$['sink-search-icon']); | |
| 1165 setTimeout(function() { | |
| 1166 var searchResults = | |
| 1167 container.$$('#search-results').querySelectorAll('paper-item'); | |
| 1168 assertEquals(0, searchResults.length); | |
| 1169 done(); | |
| 1170 }); | |
| 1171 }); | |
| 1172 | |
| 1173 // Tests that the text in the search input is not cleared or altered after | |
| 1174 // leaving filter view by pressing the back button in the header. | |
| 1175 test('search text persists back button', function(done) { | |
| 1176 MockInteractions.tap(container.$['sink-search-icon']); | |
| 1177 setTimeout(function() { | |
| 1178 container.$['sink-search-input'].value = searchTextAll; | |
| 1179 | |
| 1180 MockInteractions.tap( | |
| 1181 container.$['container-header'].$['back-button']); | |
| 1182 assertEquals(searchTextAll, container.$['sink-search-input'].value); | |
| 1183 done(); | |
| 1184 }); | |
| 1185 }); | |
| 1186 | |
| 1187 // Tests that the text in the search input is not cleared or altered after | |
| 1188 // leaving filter view by pressing the Escape key. | |
| 1189 test('search text persists escape key', function(done) { | |
| 1190 MockInteractions.tap(container.$['sink-search-icon']); | |
| 1191 setTimeout(function() { | |
| 1192 container.$['sink-search-input'].value = searchTextAll; | |
| 1193 | |
| 1194 MockInteractions.pressAndReleaseKeyOn( | |
| 1195 container, media_router.KEYCODE_ESC); | |
| 1196 assertEquals(searchTextAll, container.$['sink-search-input'].value); | |
| 1197 done(); | |
| 1198 }); | |
| 1199 }); | |
| 1200 | |
| 1201 // Tests that the correct number of results are returned in the search | |
| 1202 // results. | |
| 1203 test('search text filters correct number', function(done) { | |
| 1204 container.allSinks = fakeSinkList; | |
| 1205 MockInteractions.tap(container.$['sink-search-icon']); | |
| 1206 var searchInput = container.$['sink-search-input']; | |
| 1207 setTimeout(function() { | |
| 1208 searchInput.value = searchTextAll; | |
| 1209 var searchResults = | |
| 1210 container.$$('#search-results').querySelectorAll('paper-item'); | |
| 1211 assertEquals(fakeSinkList.length, searchResults.length); | |
| 1212 | |
| 1213 searchInput.value = searchTextOne; | |
| 1214 setTimeout(function() { | |
| 1215 var searchResults = | |
| 1216 container.$$('#search-results').querySelectorAll('paper-item'); | |
| 1217 assertEquals(1, searchResults.length); | |
| 1218 | |
| 1219 searchInput.value = searchTextNone; | |
| 1220 setTimeout(function() { | |
| 1221 var searchResults = | |
| 1222 container.$$('#search-results') | |
| 1223 .querySelectorAll('paper-item'); | |
| 1224 assertEquals(0, searchResults.length); | |
| 1225 done(); | |
| 1226 }); | |
| 1227 }); | |
| 1228 }); | |
| 1229 }); | |
| 1230 | |
| 1231 // Tests that the correct item is returned when searching using the first | |
| 1232 // fake sink's name. | |
| 1233 test('search text filters correct text', function(done) { | |
| 1234 container.allSinks = fakeSinkList; | |
| 1235 MockInteractions.tap(container.$['sink-search-icon']); | |
| 1236 var testSinkName = fakeSinkList[0].name; | |
| 1237 container.$['sink-search-input'].value = testSinkName; | |
| 1238 setTimeout(function() { | |
| 1239 var searchResults = | |
| 1240 container.$$('#search-results').querySelectorAll('paper-item'); | |
| 1241 assertEquals(1, searchResults.length); | |
| 1242 // This selector works only because there's only one result in the | |
| 1243 // list. | |
| 1244 var searchResultText = | |
| 1245 container.$$('media-router-search-highlighter').text; | |
| 1246 assertEquals(testSinkName.trim(), searchResultText.trim()); | |
| 1247 done(); | |
| 1248 }); | |
| 1249 }); | |
| 1250 | |
| 1251 // Tests that a route can be created from search results the same as in | |
| 1252 // the sink list. | |
| 1253 test('create route from search result without a route', function(done) { | |
| 1254 container.allSinks = fakeSinkList; | |
| 1255 MockInteractions.tap(container.$['sink-search-icon']); | |
| 1256 setTimeout(function() { | |
| 1257 var searchResults = | |
| 1258 container.$$('#search-results').querySelectorAll('paper-item'); | |
| 1259 container.addEventListener('create-route', function(data) { | |
| 1260 assertEquals(fakeSinkList[1].id, data.detail.sinkId); | |
| 1261 done(); | |
| 1262 }); | |
| 1263 MockInteractions.tap(searchResults[1]); | |
| 1264 }); | |
| 1265 }); | |
| 1266 | |
| 1267 // Tests that clicking a sink in the search results that already has an | |
| 1268 // associated route will transition |container| to the ROUTE_DETAILS view. | |
| 1269 test('navigate to route details from search result', function(done) { | |
| 1270 container.allSinks = fakeSinkList; | |
| 1271 container.routeList = fakeRouteList; | |
| 1272 MockInteractions.tap(container.$['sink-search-icon']); | |
| 1273 setTimeout(function() { | |
| 1274 var searchResults = | |
| 1275 container.$$('#search-results').querySelectorAll('paper-item'); | |
| 1276 MockInteractions.tap(searchResults[1]); | |
| 1277 checkCurrentView(media_router.MediaRouterView.ROUTE_DETAILS); | |
| 1278 done(); | |
| 1279 }); | |
| 1280 }); | |
| 1281 | |
| 1282 // Tests that subtext is shown in filter view the same as the sink list. | |
| 1283 // This is basically a copy of 'initial sink list route text' but in | |
| 1284 // filter view. | |
| 1285 test('subtext displayed in filter view', function(done) { | |
| 1286 // Sink 1 - no sink description, no route -> no subtext | |
| 1287 // Sink 2 - sink description, no route -> subtext = sink description | |
| 1288 // Sink 3 - no sink description, route -> subtext = route description | |
| 1289 // Sink 4 - sink description, route -> subtext = route description | |
| 1290 container.allSinks = [ | |
| 1291 new media_router.Sink('sink id 1', 'Sink 1', null, null, | |
| 1292 media_router.SinkIconType.CAST, | |
| 1293 media_router.SinkStatus.ACTIVE, [1, 2, 3]), | |
| 1294 new media_router.Sink('sink id 2', 'Sink 2', | |
| 1295 'Sink 2 description', null, | |
| 1296 media_router.SinkIconType.CAST, | |
| 1297 media_router.SinkStatus.ACTIVE, [1, 2, 3]), | |
| 1298 new media_router.Sink('sink id 3', 'Sink 3', null, null, | |
| 1299 media_router.SinkIconType.CAST, | |
| 1300 media_router.SinkStatus.PENDING, [1, 2, 3]), | |
| 1301 new media_router.Sink('sink id 4', 'Sink 4', | |
| 1302 'Sink 4 description', null, | |
| 1303 media_router.SinkIconType.CAST, | |
| 1304 media_router.SinkStatus.PENDING, [1, 2, 3]) | |
| 1305 ]; | |
| 1306 | |
| 1307 container.routeList = [ | |
| 1308 new media_router.Route('id 3', 'sink id 3', 'Title 3', 0, true), | |
| 1309 new media_router.Route('id 4', 'sink id 4', 'Title 4', 1, false), | |
| 1310 ]; | |
| 1311 | |
| 1312 MockInteractions.tap(container.$['sink-search-icon']); | |
| 1313 setTimeout(function() { | |
| 1314 var sinkSubtextList = | |
| 1315 container.$$('#search-results').querySelectorAll('.sink-subtext'); | |
| 1316 | |
| 1317 // There will only be 3 sink subtext entries, because Sink 1 does not | |
| 1318 // have any subtext. | |
| 1319 assertEquals(3, sinkSubtextList.length); | |
| 1320 | |
| 1321 checkElementText(container.allSinks[1].description, | |
| 1322 sinkSubtextList[0]); | |
| 1323 | |
| 1324 // Route description overrides sink description for subtext. | |
| 1325 checkElementText(container.routeList[0].description, | |
| 1326 sinkSubtextList[1]); | |
| 1327 | |
| 1328 checkElementText(container.routeList[1].description, | |
| 1329 sinkSubtextList[2]); | |
| 1330 done(); | |
| 1331 }); | |
| 1332 }); | |
| 1333 | |
| 1334 // Tests that compareSearchMatches_ works correctly for zero and one | |
| 1335 // substring matches from the filter text. Earlier, longer matches should | |
| 1336 // be ordered first, in that priority order. | |
| 1337 test('compareSearchMatches_ test single substrings', function(done) { | |
| 1338 var checkEqual = function(left, right) { | |
| 1339 assertEquals(0, container.compareSearchMatches_(left, right)); | |
| 1340 assertEquals(0, container.compareSearchMatches_(right, left)); | |
| 1341 }; | |
| 1342 var checkLess = function(left, right) { | |
| 1343 assertEquals(-1, container.compareSearchMatches_(left, right)); | |
| 1344 assertEquals(1, container.compareSearchMatches_(right, left)); | |
| 1345 }; | |
| 1346 | |
| 1347 var noMatches = {sinkItem: null, substrings: []}; | |
| 1348 var oneMatchSectionSingleChar = {sinkItem: null, substrings: [[0, 0]]}; | |
| 1349 | |
| 1350 checkEqual(noMatches, noMatches); | |
| 1351 checkEqual(oneMatchSectionSingleChar, oneMatchSectionSingleChar); | |
| 1352 checkLess(oneMatchSectionSingleChar, noMatches); | |
| 1353 | |
| 1354 var oneMatchSectionBeginningLong = {sinkItem: null, | |
| 1355 substrings: [[0, 2]]}; | |
| 1356 var oneMatchSectionBeginningShort = {sinkItem: null, | |
| 1357 substrings: [[0, 1]]}; | |
| 1358 checkEqual(oneMatchSectionBeginningLong, oneMatchSectionBeginningLong); | |
| 1359 checkEqual(oneMatchSectionBeginningShort, | |
| 1360 oneMatchSectionBeginningShort); | |
| 1361 | |
| 1362 checkLess(oneMatchSectionBeginningLong, oneMatchSectionBeginningShort); | |
| 1363 | |
| 1364 var oneMatchSectionMiddleLong = {sinkItem: null, substrings: [[2, 4]]}; | |
| 1365 var oneMatchSectionMiddleShort = {sinkItem: null, substrings: [[2, 3]]}; | |
| 1366 checkEqual(oneMatchSectionMiddleLong, oneMatchSectionMiddleLong); | |
| 1367 checkEqual(oneMatchSectionMiddleShort, oneMatchSectionMiddleShort); | |
| 1368 | |
| 1369 checkLess(oneMatchSectionMiddleLong, oneMatchSectionMiddleShort); | |
| 1370 | |
| 1371 var oneMatchSectionEndLong = {sinkItem: null, substrings: [[4, 6]]}; | |
| 1372 var oneMatchSectionEndShort = {sinkItem: null, substrings: [[4, 5]]}; | |
| 1373 checkEqual(oneMatchSectionEndLong, oneMatchSectionEndLong); | |
| 1374 checkEqual(oneMatchSectionEndShort, oneMatchSectionEndShort); | |
| 1375 | |
| 1376 checkLess(oneMatchSectionEndLong, oneMatchSectionEndShort); | |
| 1377 | |
| 1378 // Check beginning < middle < end for both short and long matches. | |
| 1379 checkLess(oneMatchSectionBeginningLong, oneMatchSectionMiddleLong); | |
| 1380 checkLess(oneMatchSectionMiddleLong, oneMatchSectionEndLong); | |
| 1381 checkLess(oneMatchSectionBeginningLong, oneMatchSectionEndLong); | |
| 1382 checkLess(oneMatchSectionBeginningShort, oneMatchSectionMiddleShort); | |
| 1383 checkLess(oneMatchSectionMiddleShort, oneMatchSectionEndShort); | |
| 1384 checkLess(oneMatchSectionBeginningShort, oneMatchSectionEndShort); | |
| 1385 | |
| 1386 // Check some long/short transitivity | |
| 1387 // i.e. beginning-long < middle-long, middle-long < middle-short, so | |
| 1388 // check that beginning-long < middle-short | |
| 1389 checkLess(oneMatchSectionBeginningLong, oneMatchSectionMiddleShort); | |
| 1390 checkLess(oneMatchSectionBeginningShort, oneMatchSectionMiddleLong); | |
| 1391 checkLess(oneMatchSectionMiddleLong, oneMatchSectionEndShort); | |
| 1392 checkLess(oneMatchSectionMiddleShort, oneMatchSectionEndLong); | |
| 1393 checkLess(oneMatchSectionBeginningLong, oneMatchSectionEndShort); | |
| 1394 checkLess(oneMatchSectionBeginningShort, oneMatchSectionEndLong); | |
| 1395 | |
| 1396 var oneMatchBeginningOverlap = {sinkItem: null, substrings: [[0, 2]]}; | |
| 1397 var oneMatchMiddleOverlap = {sinkItem: null, substrings: [[1, 3]]}; | |
| 1398 var oneMatchEndOverlap = {sinkItem: null, substrings: [[2, 4]]} | |
| 1399 | |
| 1400 checkEqual(oneMatchBeginningOverlap, oneMatchBeginningOverlap); | |
| 1401 checkEqual(oneMatchMiddleOverlap, oneMatchMiddleOverlap); | |
| 1402 checkEqual(oneMatchEndOverlap, oneMatchEndOverlap); | |
| 1403 | |
| 1404 checkLess(oneMatchBeginningOverlap, oneMatchMiddleOverlap); | |
| 1405 checkLess(oneMatchMiddleOverlap, oneMatchEndOverlap); | |
| 1406 checkLess(oneMatchBeginningOverlap, oneMatchEndOverlap); | |
| 1407 | |
| 1408 done(); | |
| 1409 }); | |
| 1410 | |
| 1411 // Tests that compareSearchMatches_ works correctly for one or more | |
| 1412 // substring matches from the filter text. Earlier, longer matches should | |
| 1413 // be ordered first, in that priority order. | |
| 1414 test('compareSearchMatches_ test multiple substrings', function(done) { | |
| 1415 var checkEqual = function(left, right) { | |
| 1416 assertEquals(0, container.compareSearchMatches_(left, right)); | |
| 1417 assertEquals(0, container.compareSearchMatches_(right, left)); | |
| 1418 }; | |
| 1419 var checkLess = function(left, right) { | |
| 1420 assertEquals(-1, container.compareSearchMatches_(left, right)); | |
| 1421 assertEquals(1, container.compareSearchMatches_(right, left)); | |
| 1422 }; | |
| 1423 | |
| 1424 // Variables are named by number of substring elements followed by their | |
| 1425 // sort order as X_Y where they should be sorted in ascending order by | |
| 1426 // X.Y. For example: 1_1 < 1_2 < 2_1. | |
| 1427 var threeMatches1_1 = { | |
| 1428 sinkItem: null, | |
| 1429 substrings: [[0, 2], [4, 5], [7, 9]], | |
| 1430 }; | |
| 1431 var threeMatches1_2 = { | |
| 1432 sinkItem: null, | |
| 1433 substrings: [[0, 2], [4, 5], [7, 8]], | |
| 1434 }; | |
| 1435 var threeMatches1_3 = { | |
| 1436 sinkItem: null, | |
| 1437 substrings: [[0, 2], [4, 5], [8, 9]], | |
| 1438 }; | |
| 1439 var threeMatches1_4 = { | |
| 1440 sinkItem: null, | |
| 1441 substrings: [[0, 2], [4, 4], [6, 8]], | |
| 1442 }; | |
| 1443 var twoMatches2_1 = { | |
| 1444 sinkItem: null, | |
| 1445 substrings: [[0, 2], [4, 4]], | |
| 1446 }; | |
| 1447 var twoMatches2_2 = { | |
| 1448 sinkItem: null, | |
| 1449 substrings: [[0, 1], [3, 5]], | |
| 1450 }; | |
| 1451 var twoMatches2_3 = { | |
| 1452 sinkItem: null, | |
| 1453 substrings: [[0, 1], [4, 6]], | |
| 1454 }; | |
| 1455 var twoMatches2_4 = { | |
| 1456 sinkItem: null, | |
| 1457 substrings: [[0, 1], [4, 5]], | |
| 1458 }; | |
| 1459 var threeMatches2_5 = { | |
| 1460 sinkItem: null, | |
| 1461 substrings: [[0, 1], [4, 4], [6, 9]], | |
| 1462 }; | |
| 1463 var oneMatch3_1 = { | |
| 1464 sinkItem: null, | |
| 1465 substrings: [[0, 1]], | |
| 1466 }; | |
| 1467 var oneMatch3_2 = { | |
| 1468 sinkItem: null, | |
| 1469 substrings: [[0, 0]], | |
| 1470 }; | |
| 1471 | |
| 1472 var orderedMatches = [ | |
| 1473 threeMatches1_1, | |
| 1474 threeMatches1_2, | |
| 1475 threeMatches1_3, | |
| 1476 threeMatches1_4, | |
| 1477 twoMatches2_1, | |
| 1478 twoMatches2_2, | |
| 1479 twoMatches2_3, | |
| 1480 twoMatches2_4, | |
| 1481 threeMatches2_5, | |
| 1482 oneMatch3_1, | |
| 1483 oneMatch3_2, | |
| 1484 ]; | |
| 1485 | |
| 1486 for (var i = 0; i < orderedMatches.length; ++i) { | |
| 1487 checkEqual(orderedMatches[i], orderedMatches[i]); | |
| 1488 } | |
| 1489 for (var i = 0; i < orderedMatches.length - 1; ++i) { | |
| 1490 checkLess(orderedMatches[i], orderedMatches[i+1]); | |
| 1491 } | |
| 1492 // Check some transitivity. | |
| 1493 for (var i = 0; i < orderedMatches.length - 2; ++i) { | |
| 1494 checkLess(orderedMatches[i], orderedMatches[i+2]); | |
| 1495 } | |
| 1496 for (var i = 0; i < orderedMatches.length - 3; ++i) { | |
| 1497 checkLess(orderedMatches[i], orderedMatches[i+3]); | |
| 1498 } | |
| 1499 | |
| 1500 done(); | |
| 1501 }); | |
| 1502 | |
| 1503 // Tests that computeSearchMatches_ correctly computes the matching | |
| 1504 // substrings of a sink name from search text. | |
| 1505 test('computeSearchMatches_ test', function(done) { | |
| 1506 var sinkName = '012345 789'; | |
| 1507 var checkMatches = function(searchText, answer) { | |
| 1508 proposed = container.computeSearchMatches_(searchText, sinkName); | |
| 1509 | |
| 1510 if (answer == null || proposed == null) { | |
| 1511 assertEquals(answer, proposed); | |
| 1512 return; | |
| 1513 } | |
| 1514 assertEquals(answer.length, proposed.length); | |
| 1515 for (var i = 0; i < proposed.length; ++i) { | |
| 1516 assertEquals(answer[i].length, proposed[i].length); | |
| 1517 for (var j = 0; j < proposed[i].length; ++j) { | |
| 1518 assertEquals(answer[i][j], proposed[i][j]); | |
| 1519 } | |
| 1520 } | |
| 1521 }; | |
| 1522 | |
| 1523 // Check search text against |sinkName| for correct match output. | |
| 1524 checkMatches('', []); | |
| 1525 checkMatches('a', null); | |
| 1526 checkMatches('0', [[0, 0]]); | |
| 1527 checkMatches('1', [[1, 1]]); | |
| 1528 checkMatches('012', [[0, 2]]); | |
| 1529 checkMatches('03', [[0, 0], [3, 3]]); | |
| 1530 checkMatches('210', null); | |
| 1531 checkMatches('01345789', [[0, 1], [3, 5], [7, 9]]); | |
| 1532 checkMatches('024', [[0, 0], [2, 2], [4, 4]]); | |
| 1533 checkMatches('09a', null); | |
| 1534 checkMatches(' ', [[6, 6]]); | |
| 1535 checkMatches('45 ', [[4, 6]]); | |
| 1536 checkMatches(' 78', [[6, 8]]); | |
| 1537 checkMatches('45 7', [[4, 7]]); | |
| 1538 checkMatches(' ', null); | |
| 1539 checkMatches('12 89', [[1, 2], [6, 6], [8, 9]]); | |
| 1540 | |
| 1541 done(); | |
| 1542 }); | |
| 1543 | |
| 1544 // Tests that computeSinkMatchingText_ correctly splits a sink name into | |
| 1545 // |plainText| and |highlightedText| arrays given a sink name and an array | |
| 1546 // of match indices. | |
| 1547 test('computeSinkMatchingText_ test', function(done) { | |
| 1548 var sinkName = '012345 789'; | |
| 1549 var sink = new media_router.Sink('id', sinkName, null, null, | |
| 1550 media_router.SinkIconType.CAST, | |
| 1551 media_router.SinkStatus.ACTIVE, 0); | |
| 1552 var checkMatches = function(matchesAndAnswers) { | |
| 1553 var matches = matchesAndAnswers.matches; | |
| 1554 var plainText = matchesAndAnswers.plainText; | |
| 1555 var highlightedText = matchesAndAnswers.highlightedText; | |
| 1556 | |
| 1557 var proposed = container.computeSinkMatchingText_( | |
| 1558 {sinkItem: sink, substrings: matches}); | |
| 1559 assertEquals(plainText.length, proposed.plainText.length); | |
| 1560 assertEquals(highlightedText.length, proposed.highlightedText.length); | |
| 1561 for (var i = 0; i < plainText.length; ++i) { | |
| 1562 assertEquals(plainText[i], proposed.plainText[i]); | |
| 1563 } | |
| 1564 for (var i = 0; i < highlightedText.length; ++i) { | |
| 1565 assertEquals(highlightedText[i], proposed.highlightedText[i]); | |
| 1566 } | |
| 1567 }; | |
| 1568 | |
| 1569 // Check that |sinkName| is correctly partitioned by |matches|. | |
| 1570 var matchesAndAnswers1 = { | |
| 1571 matches: null, | |
| 1572 plainText: ['012345 789'], | |
| 1573 highlightedText: [null] | |
| 1574 }; | |
| 1575 checkMatches(matchesAndAnswers1); | |
| 1576 | |
| 1577 var matchesAndAnswers2 = { | |
| 1578 matches: [], | |
| 1579 plainText: ['012345 789'], | |
| 1580 highlightedText: [null] | |
| 1581 }; | |
| 1582 checkMatches(matchesAndAnswers2); | |
| 1583 | |
| 1584 var matchesAndAnswers3 = { | |
| 1585 matches: [[0, 0]], | |
| 1586 plainText: [null, '12345 789'], | |
| 1587 highlightedText: ['0', null] | |
| 1588 }; | |
| 1589 checkMatches(matchesAndAnswers3); | |
| 1590 | |
| 1591 var matchesAndAnswers4 = { | |
| 1592 matches: [[9, 9]], | |
| 1593 plainText: ['012345 78'], | |
| 1594 highlightedText: ['9'] | |
| 1595 }; | |
| 1596 checkMatches(matchesAndAnswers4); | |
| 1597 | |
| 1598 var matchesAndAnswers5 = { | |
| 1599 matches: [[1, 1]], | |
| 1600 plainText: ['0', '2345 789'], | |
| 1601 highlightedText: ['1', null] | |
| 1602 }; | |
| 1603 checkMatches(matchesAndAnswers5); | |
| 1604 | |
| 1605 var matchesAndAnswers6 = { | |
| 1606 matches: [[1, 2], [4, 6]], | |
| 1607 plainText: ['0', '3', '789'], | |
| 1608 highlightedText: ['12', '45 ', null] | |
| 1609 }; | |
| 1610 checkMatches(matchesAndAnswers6); | |
| 1611 | |
| 1612 var matchesAndAnswers7 = { | |
| 1613 matches: [[0, 3], [7, 9]], | |
| 1614 plainText: [null, '45 '], | |
| 1615 highlightedText: ['0123', '789'], | |
| 1616 }; | |
| 1617 checkMatches(matchesAndAnswers7); | |
| 1618 | |
| 1619 var matchesAndAnswers8 = { | |
| 1620 matches: [[4, 6], [9, 9]], | |
| 1621 plainText: ['0123', '78'], | |
| 1622 highlightedText: ['45 ', '9'] | |
| 1623 }; | |
| 1624 checkMatches(matchesAndAnswers8); | |
| 1625 | |
| 1626 var matchesAndAnswers9 = { | |
| 1627 matches: [[0, 1], [3, 4], [6, 7], [9, 9]], | |
| 1628 plainText: [null, '2', '5', '8'], | |
| 1629 highlightedText: ['01', '34', ' 7', '9'], | |
| 1630 }; | |
| 1631 checkMatches(matchesAndAnswers9); | |
| 1632 | |
| 1633 var matchesAndAnswers10 = { | |
| 1634 matches: [[0, 1], [3, 4], [6, 6], [9, 9]], | |
| 1635 plainText: [null, '2', '5', '78'], | |
| 1636 highlightedText: ['01', '34', ' ', '9'], | |
| 1637 }; | |
| 1638 checkMatches(matchesAndAnswers10); | |
| 1639 | |
| 1640 var matchesAndAnswers11 = { | |
| 1641 matches: [[5, 7]], | |
| 1642 plainText: ['01234', '89'], | |
| 1643 highlightedText: ['5 7', null], | |
| 1644 }; | |
| 1645 checkMatches(matchesAndAnswers11); | |
| 1646 | |
| 1647 done(); | |
| 1648 }); | |
| 1649 }); | 990 }); |
| 1650 } | 991 } |
| 1651 | 992 |
| 1652 return { | 993 return { |
| 1653 registerTests: registerTests, | 994 registerTests: registerTests, |
| 1654 }; | 995 }; |
| 1655 }); | 996 }); |
| OLD | NEW |