| OLD | NEW |
| (Empty) |
| 1 <!DOCTYPE HTML> | |
| 2 <html> | |
| 3 <!-- | |
| 4 Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 5 Use of this source code is governed by a BSD-style license that can be | |
| 6 found in the LICENSE file. | |
| 7 --> | |
| 8 <head i18n-values="dir:textdirection;"> | |
| 9 <title>TimelineTrack tests</title> | |
| 10 <script | |
| 11 src="http://closure-library.googlecode.com/svn/trunk/closure/goog/base.js"> | |
| 12 </script> | |
| 13 <script> | |
| 14 goog.require('goog.testing.jsunit'); | |
| 15 </script> | |
| 16 <style> | |
| 17 * { | |
| 18 box-sizing: border-box; | |
| 19 -webkit-user-select: none; | |
| 20 } | |
| 21 | |
| 22 .timeline-container { | |
| 23 border: 1px solid red; | |
| 24 } | |
| 25 | |
| 26 </style> | |
| 27 <link rel="stylesheet" href="timeline.css"> | |
| 28 <script src="../shared/js/cr.js"></script> | |
| 29 <script src="../shared/js/cr/event_target.js"></script> | |
| 30 <script src="../shared/js/cr/ui.js"></script> | |
| 31 <script src="../shared/js/util.js"></script> | |
| 32 <script src="timeline_model.js"></script> | |
| 33 <script src="sorted_array_utils.js"></script> | |
| 34 <script src="measuring_stick.js"></script> | |
| 35 <script src="timeline.js"></script> | |
| 36 <script src="timeline_track.js"></script> | |
| 37 <script src="fast_rect_renderer.js"></script> | |
| 38 </head> | |
| 39 <body> | |
| 40 <script> | |
| 41 </script> | |
| 42 <script> | |
| 43 'use strict'; | |
| 44 | |
| 45 var TimelineAsyncSlice = tracing.TimelineAsyncSlice; | |
| 46 var TimelineAsyncSliceGroup = tracing.TimelineAsyncSliceGroup; | |
| 47 var TimelineCounter = tracing.TimelineCounter; | |
| 48 var TimelineCounterTrack = tracing.TimelineCounterTrack; | |
| 49 var TimelineCpu = tracing.TimelineCpu; | |
| 50 var TimelineCpuTrack = tracing.TimelineCpuTrack; | |
| 51 var TimelineProcess = tracing.TimelineProcess; | |
| 52 var TimelineSelection = tracing.TimelineSelection; | |
| 53 var TimelineSliceTrack = tracing.TimelineSliceTrack; | |
| 54 var TimelineSlice = tracing.TimelineSlice; | |
| 55 var TimelineThread = tracing.TimelineThread; | |
| 56 var TimelineThreadSlice = tracing.TimelineThreadSlice; | |
| 57 var TimelineThreadTrack = tracing.TimelineThreadTrack; | |
| 58 var TimelineViewport = tracing.TimelineViewport; | |
| 59 var testDivs = {}; | |
| 60 | |
| 61 // Helper function to create a slice. | |
| 62 function newAsyncSlice(start, duration, startThread, endThread) { | |
| 63 var s = new TimelineAsyncSlice('a', 0, start); | |
| 64 s.duration = duration; | |
| 65 s.startThread = startThread; | |
| 66 s.endThread = endThread; | |
| 67 return s; | |
| 68 } | |
| 69 | |
| 70 function getTestDiv(name) { | |
| 71 if (!testDivs[name]) { | |
| 72 testDivs[name] = document.createElement('div'); | |
| 73 document.body.appendChild(testDivs[name]); | |
| 74 } | |
| 75 testDivs[name].textContent = ''; | |
| 76 return testDivs[name]; | |
| 77 } | |
| 78 | |
| 79 function testBasicSlices() { | |
| 80 var testEl = getTestDiv('testBasicSlices'); | |
| 81 var track = TimelineSliceTrack(); | |
| 82 testEl.appendChild(track); | |
| 83 track.heading = 'testBasicSlices'; | |
| 84 track.slices = [ | |
| 85 new TimelineSlice('a', 0, 1, {}, 1), | |
| 86 new TimelineSlice('b', 1, 2.1, {}, 4.8), | |
| 87 new TimelineSlice('b', 1, 7, {}, 0.5), | |
| 88 new TimelineSlice('c', 2, 7.6, {}, 0.4) | |
| 89 ]; | |
| 90 track.viewport = new TimelineViewport(testEl); | |
| 91 track.viewport.xSetWorldRange(0, 8.8, track.clientWidth); | |
| 92 } | |
| 93 | |
| 94 function testFindAllObjectsMatchingInSliceTrack() { | |
| 95 var track = TimelineSliceTrack(); | |
| 96 track.slices = [ | |
| 97 new TimelineSlice('a', 0, 1, {}, 1), | |
| 98 new TimelineSlice('b', 1, 2.1, {}, 4.8), | |
| 99 new TimelineSlice('b', 1, 7, {}, 0.5), | |
| 100 new TimelineSlice('c', 2, 7.6, {}, 0.4) | |
| 101 ]; | |
| 102 var selection = new TimelineSelection(); | |
| 103 track.addAllObjectsMatchingFilterToSelection( | |
| 104 new tracing.TimelineFilter("b"), selection); | |
| 105 | |
| 106 assertEquals(2, selection.length); | |
| 107 assertEquals(track.slices[1], selection[0].slice); | |
| 108 assertEquals(track.slices[2], selection[1].slice); | |
| 109 } | |
| 110 | |
| 111 function testShrinkingSliceSizes() { | |
| 112 var testEl = getTestDiv('testShrinkingSliceSizes'); | |
| 113 var track = TimelineSliceTrack(); | |
| 114 testEl.appendChild(track); | |
| 115 track.heading = 'testShrinkingSliceSizes'; | |
| 116 var x = 0; | |
| 117 var widths = [10, 5, 4, 3, 2, 1, 0.5, 0.4, 0.3, 0.2, 0.1, 0.05]; | |
| 118 var slices = []; | |
| 119 for (var i = 0; i < widths.length; i++) { | |
| 120 var s = new TimelineSlice('a', 1, x, {}, widths[i]); | |
| 121 x += s.duration + 0.5; | |
| 122 slices.push(s); | |
| 123 } | |
| 124 track.slices = slices; | |
| 125 track.viewport = new TimelineViewport(testEl); | |
| 126 track.viewport.xSetWorldRange(0, 1.1 * x, track.clientWidth); | |
| 127 } | |
| 128 | |
| 129 function testSelectionHitTesting() { | |
| 130 var testEl = getTestDiv('testSelectionHitTesting'); | |
| 131 var track = new TimelineSliceTrack(); | |
| 132 testEl.appendChild(track); | |
| 133 track.heading = 'testSelectionHitTesting'; | |
| 134 track.headingWidth = '100px'; | |
| 135 track.slices = [ | |
| 136 new TimelineSlice('a', 0, 1, {}, 1), | |
| 137 new TimelineSlice('b', 1, 2.1, {}, 4.8) | |
| 138 ]; | |
| 139 track.style.width = '500px'; | |
| 140 track.viewport = new TimelineViewport(testEl); | |
| 141 track.viewport.xSetWorldRange(0, 7.6, track.clientWidth); | |
| 142 var clientRect = track.getBoundingClientRect(); | |
| 143 | |
| 144 var selection = new TimelineSelection(); | |
| 145 track.addIntersectingItemsToSelection(1.5, clientRect.top + 5, selection); | |
| 146 assertEquals(track.slices[0], selection[0].slice); | |
| 147 | |
| 148 var selection = new TimelineSelection(); | |
| 149 track.addIntersectingItemsToSelection(2, clientRect.top + 5, selection); | |
| 150 assertEquals(0, selection.length); | |
| 151 | |
| 152 var selection = new TimelineSelection(); | |
| 153 track.addIntersectingItemsToSelection(6.8, clientRect.top + 5, selection); | |
| 154 assertEquals(track.slices[1], selection[0].slice); | |
| 155 | |
| 156 var selection = new TimelineSelection(); | |
| 157 track.addIntersectingItemsToSelection(6.9, clientRect.top + 5, selection); | |
| 158 assertEquals(0, selection.length); | |
| 159 } | |
| 160 | |
| 161 function testSelectionHitTestingWithTimelineThreadTrack() { | |
| 162 var model = new tracing.TimelineModel(); | |
| 163 var p1 = model.getOrCreateProcess(1); | |
| 164 var t1 = p1.getOrCreateThread(1); | |
| 165 t1.subRows[0].push(new tracing.TimelineThreadSlice('a', 0, 1, {}, 5)); | |
| 166 t1.subRows[0].push(new tracing.TimelineThreadSlice('b', 0, 5.1, {}, 4)); | |
| 167 | |
| 168 var testEl = getTestDiv('testSelectionHitTestingWithTimelineThreadTrack'); | |
| 169 var track = new tracing.TimelineThreadTrack(); | |
| 170 testEl.appendChild(track); | |
| 171 track.heading = 'testSelectionHitTestingWithTimelineThreadTrack'; | |
| 172 track.headingWidth = '100px'; | |
| 173 track.thread = t1; | |
| 174 | |
| 175 track.style.width = '500px'; | |
| 176 track.viewport = new TimelineViewport(testEl); | |
| 177 track.viewport.xSetWorldRange(0, 10, track.clientWidth); | |
| 178 var clientRect = track.getBoundingClientRect(); | |
| 179 | |
| 180 var selection = new TimelineSelection(); | |
| 181 track.addIntersectingItemsToSelection(1.5, clientRect.top + 5, selection); | |
| 182 assertEquals(t1.subRows[0][0], selection[0].slice); | |
| 183 | |
| 184 var selection = new TimelineSelection(); | |
| 185 track.addIntersectingItemsInRangeToSelection(1.5, 1.8, clientRect.top + 5, c
lientRect.top + 7, selection); | |
| 186 assertEquals(t1.subRows[0][0], selection[0].slice); | |
| 187 } | |
| 188 | |
| 189 function testBasicCpu() { | |
| 190 var testEl = getTestDiv('testBasicCpu'); | |
| 191 | |
| 192 var cpu = new TimelineCpu(7); | |
| 193 cpu.slices = [ | |
| 194 new TimelineSlice('a', 0, 1, {}, 1), | |
| 195 new TimelineSlice('b', 1, 2.1, {}, 4.8) | |
| 196 ]; | |
| 197 cpu.updateBounds(); | |
| 198 | |
| 199 var track = TimelineCpuTrack(); | |
| 200 testEl.appendChild(track); | |
| 201 track.heading = 'CPU ' + cpu.cpuNumber; | |
| 202 track.cpu = cpu; | |
| 203 track.viewport = new TimelineViewport(testEl); | |
| 204 track.viewport.xSetWorldRange(0, 11.1, track.clientWidth); | |
| 205 } | |
| 206 | |
| 207 function testViewport() { | |
| 208 var testEl = getTestDiv('testViewport'); | |
| 209 | |
| 210 var track = tracing.TimelineViewportTrack(); | |
| 211 testEl.appendChild(track); | |
| 212 track.viewport = new TimelineViewport(testEl); | |
| 213 track.viewport.setPanAndScale(0, | |
| 214 track.clientWidth / 1000); | |
| 215 } | |
| 216 | |
| 217 function testBasicCounter() { | |
| 218 var testEl = getTestDiv('testBasicCounter'); | |
| 219 | |
| 220 var ctr = new TimelineCounter(undefined, | |
| 221 'testBasicCounter', 'testBasicCounter'); | |
| 222 ctr.seriesNames = ['value1', 'value2']; | |
| 223 ctr.seriesColors = [tracing.getStringColorId('testBasicCounter.value1'), | |
| 224 tracing.getStringColorId('testBasicCounter.value2')]; | |
| 225 ctr.timestamps = [0, 1, 2, 3, 4, 5, 6, 7]; | |
| 226 ctr.samples = [0, 5, | |
| 227 3, 3, | |
| 228 1, 1, | |
| 229 2, 1.1, | |
| 230 3, 0, | |
| 231 1, 7, | |
| 232 3, 0, | |
| 233 3.1, 0.5]; | |
| 234 ctr.updateBounds(); | |
| 235 | |
| 236 var track = new TimelineCounterTrack(); | |
| 237 testEl.appendChild(track); | |
| 238 track.heading = ctr.name; | |
| 239 track.counter = ctr; | |
| 240 track.viewport = new TimelineViewport(testEl); | |
| 241 track.viewport.xSetWorldRange(0, 7.7, track.clientWidth); | |
| 242 } | |
| 243 | |
| 244 function runOffscreenCounterTest(timestamps, samples, testFn) { | |
| 245 var testEl = document.createElement('div'); | |
| 246 var ctr = new TimelineCounter(undefined, | |
| 247 'foo', 'foo'); | |
| 248 var n = samples.length / timestamps.length; | |
| 249 ctr.timestamps = timestamps; | |
| 250 ctr.samples = samples; | |
| 251 ctr.seriesNames = [] | |
| 252 ctr.seriesColors = [] | |
| 253 for (var i = 0; i < n; ++i) { | |
| 254 ctr.seriesNames.push('value' + i); | |
| 255 ctr.seriesColors.push(tracing.getStringColorId(ctr.seriesNames[i])); | |
| 256 } | |
| 257 ctr.updateBounds(); | |
| 258 | |
| 259 var track = new TimelineCounterTrack(); | |
| 260 testEl.appendChild(track); | |
| 261 document.body.appendChild(testEl); | |
| 262 | |
| 263 track.heading = ctr.name; | |
| 264 track.counter = ctr; | |
| 265 track.viewport = new TimelineViewport(testEl); | |
| 266 track.viewport.xSetWorldRange(0, 10, track.clientWidth); | |
| 267 | |
| 268 try { | |
| 269 testFn(ctr, track); | |
| 270 } finally { | |
| 271 document.body.removeChild(testEl); | |
| 272 } | |
| 273 } | |
| 274 | |
| 275 function testBasicCounterXPointPicking() { | |
| 276 var timestamps = [0, 1, 2, 3, 4, 5, 6, 7]; | |
| 277 var samples = [0, 5, | |
| 278 3, 3, | |
| 279 1, 1, | |
| 280 2, 1.1, | |
| 281 3, 0, | |
| 282 1, 7, | |
| 283 3, 0, | |
| 284 3.1, 0.5]; | |
| 285 runOffscreenCounterTest(timestamps, samples, function(ctr, track) { | |
| 286 var clientRect = track.getBoundingClientRect(); | |
| 287 var y75 = clientRect.top + 0.75 * clientRect.height; | |
| 288 var sel; | |
| 289 | |
| 290 // In bounds. | |
| 291 sel = new tracing.TimelineSelection(); | |
| 292 track.addIntersectingItemsToSelection(1.5, y75, sel); | |
| 293 assertEquals(1, sel.length); | |
| 294 assertEquals(track, sel[0].track); | |
| 295 assertEquals(ctr, sel[0].counter); | |
| 296 assertEquals(1, sel[0].sampleIndex); | |
| 297 | |
| 298 // Outside bouds. | |
| 299 sel = new tracing.TimelineSelection(); | |
| 300 track.addIntersectingItemsToSelection(-1, y75, sel); | |
| 301 assertEquals(0, sel.length); | |
| 302 | |
| 303 sel = new tracing.TimelineSelection(); | |
| 304 track.addIntersectingItemsToSelection(8, y75, sel); | |
| 305 assertEquals(0, sel.length); | |
| 306 }); | |
| 307 } | |
| 308 | |
| 309 /* You'll need visual inspection to test eliding with this one. */ | |
| 310 function testElideVisualInspection() { | |
| 311 var optDicts = [{ trackName: 'elideOff', elide: false }, | |
| 312 { trackName: 'elideOn', elide: true }]; | |
| 313 for (var dictIndex in optDicts) { | |
| 314 var dict = optDicts[dictIndex]; | |
| 315 var testEl = getTestDiv(dict.trackName); | |
| 316 var track = new TimelineSliceTrack(); | |
| 317 if (dict.elide) { | |
| 318 track.SHOULD_ELIDE_TEXT = true; | |
| 319 } else { | |
| 320 track.SHOULD_ELIDE_TEXT = false; | |
| 321 } | |
| 322 var tooLongTitle = 'Unless eliding this SHOULD NOT BE DISPLAYED. '; | |
| 323 var bigTitle = 'Very big title name that goes on longer ' + | |
| 324 'than you may expect'; | |
| 325 testEl.appendChild(track); | |
| 326 track.heading = 'Visual: ' + dict.trackName; | |
| 327 track.slices = [ | |
| 328 // title, colorId, start, args, opt_duration | |
| 329 new TimelineSlice('a ' + tooLongTitle + bigTitle, 0, 1, {}, 1), | |
| 330 new TimelineSlice(bigTitle, 1, 2.1, {}, 4.8), | |
| 331 new TimelineSlice('cccc cccc cccc', 1, 7, {}, 0.5), | |
| 332 new TimelineSlice('d', 2, 7.6, {}, 1.0) | |
| 333 ]; | |
| 334 track.viewport = new TimelineViewport(testEl); | |
| 335 track.viewport.xSetWorldRange(0, 9.5, track.clientWidth); | |
| 336 } | |
| 337 } | |
| 338 | |
| 339 function testElide() { | |
| 340 var testEl = getTestDiv('testElide'); | |
| 341 var track = new TimelineSliceTrack(); | |
| 342 testEl.appendChild(track); | |
| 343 var bigtitle = 'Super duper long long title ' + | |
| 344 'holy moly when did you get so verbose?'; | |
| 345 var smalltitle = 'small'; | |
| 346 track.viewport = new TimelineViewport(testEl); | |
| 347 track.heading = 'testElide'; | |
| 348 track.slices = [ | |
| 349 // title, colorId, start, args, opt_duration | |
| 350 new TimelineSlice(bigtitle, 0, 1, {}, 1), | |
| 351 new TimelineSlice(smalltitle, 1, 2, {}, 1) | |
| 352 ]; | |
| 353 track.viewport = new TimelineViewport(testEl); | |
| 354 track.viewport.xSetWorldRange(0, 3.3, track.clientWidth); | |
| 355 var stringWidthPair = undefined; | |
| 356 var pixWidth = track.viewport_.xViewVectorToWorld(1); | |
| 357 | |
| 358 // Small titles on big slices are not elided. | |
| 359 stringWidthPair = track.elidedTitleCache.get(track, pixWidth, smalltitle, | |
| 360 track.labelWidth(smalltitle), 1); | |
| 361 assertEquals(smalltitle, stringWidthPair.string); | |
| 362 // Keep shrinking the slice until eliding starts. | |
| 363 var elidedWhenSmallEnough = false; | |
| 364 for (var sliceLength = 1; sliceLength >= 0.00001; sliceLength /= 2.0) { | |
| 365 stringWidthPair = track.elidedTitleCache.get(track, pixWidth, smalltitle, | |
| 366 track.labelWidth(smalltitle), sliceLength); | |
| 367 if (stringWidthPair.string.length < smalltitle.length) { | |
| 368 elidedWhenSmallEnough = true; | |
| 369 break; | |
| 370 } | |
| 371 } | |
| 372 assertTrue(elidedWhenSmallEnough); | |
| 373 | |
| 374 // Big titles are elided immediately. | |
| 375 var superBigTitle = ''; | |
| 376 for (var x = 0; x < 10; x++) { | |
| 377 superBigTitle += bigtitle; | |
| 378 } | |
| 379 stringWidthPair = track.elidedTitleCache.get(track, pixWidth, | |
| 380 superBigTitle, track.labelWidth(superBigTitle), 1); | |
| 381 assertTrue(stringWidthPair.string.length < superBigTitle.length); | |
| 382 // And elided text ends with ... | |
| 383 var len = stringWidthPair.string.length; | |
| 384 assertEquals('...', stringWidthPair.string.substring(len - 3, len)); | |
| 385 } | |
| 386 | |
| 387 function testTimelineThreadTrackWithRegularSlices() { | |
| 388 var testEl = getTestDiv('testTimelineThreadTrackWithRegularSlices'); | |
| 389 var track = TimelineThreadTrack(); | |
| 390 testEl.appendChild(track); | |
| 391 track.heading = 'testTimelineThreadTrackWithRegularSlices'; | |
| 392 var thread = new TimelineThread(new TimelineProcess(7), 1); | |
| 393 thread.subRows = [ | |
| 394 [ | |
| 395 new TimelineThreadSlice('a', 0, 1, {}, 1), | |
| 396 new TimelineThreadSlice('b', 1, 2.1, {}, 4.8), | |
| 397 new TimelineThreadSlice('b', 1, 7, {}, 0.5), | |
| 398 new TimelineThreadSlice('c', 2, 7.6, {}, 0.4) | |
| 399 ], | |
| 400 [ | |
| 401 new TimelineThreadSlice('d', 3, 1.1, {}, 0.8), | |
| 402 new TimelineThreadSlice('e', 4, 7.1, {}, 0.3) | |
| 403 ] | |
| 404 ]; | |
| 405 thread.updateBounds(); | |
| 406 track.heading = 'thread regular'; | |
| 407 track.headingWidth = '150px'; | |
| 408 track.toolTip = thread.userFriendlyDetails + ':'; | |
| 409 track.thread = thread; | |
| 410 track.viewport = new TimelineViewport(testEl); | |
| 411 track.viewport.xSetWorldRange(0, 8.2, track.clientWidth); | |
| 412 } | |
| 413 | |
| 414 function testTimelineThreadTrackWithTallSlices() { | |
| 415 var testEl = getTestDiv('testTimelineThreadTrackWithTallSlices'); | |
| 416 var track = TimelineThreadTrack(); | |
| 417 testEl.appendChild(track); | |
| 418 track.heading = 'testTimelineThreadTrackWithTallSlices'; | |
| 419 var thread = new TimelineThread(new TimelineProcess(7), 1); | |
| 420 thread.subRows = [ | |
| 421 [new TimelineThreadSlice('a', 1, 0, {}, 1)], | |
| 422 [new TimelineThreadSlice('b', 2, 0.1, {}, 0.8)], | |
| 423 [new TimelineThreadSlice('c', 3, 0.15, {}, 0.70)], | |
| 424 [new TimelineThreadSlice('d', 4, 0.20, {}, 0.50)], | |
| 425 [new TimelineThreadSlice('e', 5, 0.30, {}, 0.28)], | |
| 426 [new TimelineThreadSlice('e', 6, 0.35, {}, 0.20)], | |
| 427 [new TimelineThreadSlice('f', 7, 0.40, {}, 0.10)] | |
| 428 ]; | |
| 429 thread.updateBounds(); | |
| 430 track.heading = 'thread tall'; | |
| 431 track.headingWidth = '150px'; | |
| 432 track.toolTip = thread.userFriendlyDetails + ':'; | |
| 433 track.thread = thread; | |
| 434 track.viewport = new TimelineViewport(testEl); | |
| 435 track.viewport.xSetWorldRange(0, 1.1, track.clientWidth); | |
| 436 } | |
| 437 | |
| 438 function testTimelineThreadTrackWithRegularAndAsyncSlices() { | |
| 439 var testEl = getTestDiv('testTimelineThreadTrackWithAsyncSlices'); | |
| 440 var track = TimelineThreadTrack(); | |
| 441 testEl.appendChild(track); | |
| 442 var thread = new TimelineThread(new TimelineProcess(7), 1); | |
| 443 thread.subRows = [ | |
| 444 [ | |
| 445 new TimelineThreadSlice('a', 0, 1, {}, 1), | |
| 446 new TimelineThreadSlice('b', 1, 2.1, {}, 4.8), | |
| 447 new TimelineThreadSlice('b', 1, 7, {}, 0.5), | |
| 448 new TimelineThreadSlice('c', 2, 7.6, {}, 0.4) | |
| 449 ], | |
| 450 [ | |
| 451 new TimelineThreadSlice('d', 3, 1.1, {}, 0.8), | |
| 452 new TimelineThreadSlice('e', 4, 7.1, {}, 0.3) | |
| 453 ] | |
| 454 ]; | |
| 455 thread.asyncSlices.push(newAsyncSlice(1.2, 7.2 - 1.2, thread, thread)); | |
| 456 thread.asyncSlices.push(newAsyncSlice(1.3, 7.3 - 1.3, thread, thread)); | |
| 457 thread.updateBounds(); | |
| 458 track.heading = 'thread regular + async'; | |
| 459 track.headingWidth = '150px'; | |
| 460 track.toolTip = thread.userFriendlyDetails + ':'; | |
| 461 track.thread = thread; | |
| 462 track.viewport = new TimelineViewport(testEl); | |
| 463 track.viewport.xSetWorldRange(0, 8.15, track.clientWidth); | |
| 464 } | |
| 465 | |
| 466 function testTimelineSliceTrackAddItemNearToProvidedHit() { | |
| 467 var track = new TimelineSliceTrack(); | |
| 468 track.slices = [ | |
| 469 new TimelineSlice('a', 0, 1, {}, 1), | |
| 470 new TimelineSlice('b', 1, 2.1, {}, 4.8), | |
| 471 new TimelineSlice('b', 1, 7, {}, 0.5), | |
| 472 new TimelineSlice('c', 2, 7.6, {}, 0.4) | |
| 473 ]; | |
| 474 var sel = new tracing.TimelineSelection(); | |
| 475 track.addAllObjectsMatchingFilterToSelection(new tracing.TimelineFilter("b")
, sel); | |
| 476 var ret; | |
| 477 | |
| 478 // Select to the right of B. | |
| 479 var selRight = new tracing.TimelineSelection(); | |
| 480 ret = track.addItemNearToProvidedHitToSelection(sel[0], 1, selRight); | |
| 481 assertTrue(ret); | |
| 482 assertEquals(track.slices[2], selRight[0].slice); | |
| 483 | |
| 484 // Select to the right of the 2nd b. | |
| 485 var selRight2 = new tracing.TimelineSelection(); | |
| 486 ret = track.addItemNearToProvidedHitToSelection(sel[0], 2, selRight2); | |
| 487 assertTrue(ret); | |
| 488 assertEquals(track.slices[3], selRight2[0].slice); | |
| 489 | |
| 490 // Select to 2 to the right of the 2nd b. | |
| 491 var selRightOfRight = new tracing.TimelineSelection(); | |
| 492 ret = track.addItemNearToProvidedHitToSelection(selRight[0], 1, selRightOfRi
ght); | |
| 493 assertTrue(ret); | |
| 494 assertEquals(track.slices[3], selRightOfRight[0].slice); | |
| 495 | |
| 496 // Select to the right of the rightmost slice. | |
| 497 var selNone = new tracing.TimelineSelection(); | |
| 498 ret = track.addItemNearToProvidedHitToSelection(selRightOfRight[0], 1, selNo
ne); | |
| 499 assertFalse(ret); | |
| 500 assertEquals(0, selNone.length); | |
| 501 | |
| 502 // Select A and then select left. | |
| 503 var sel = new tracing.TimelineSelection(); | |
| 504 track.addAllObjectsMatchingFilterToSelection(new tracing.TimelineFilter("a")
, sel); | |
| 505 var ret; | |
| 506 | |
| 507 selNone = new tracing.TimelineSelection(); | |
| 508 ret = track.addItemNearToProvidedHitToSelection(sel[0], -1, selNone); | |
| 509 assertFalse(ret); | |
| 510 assertEquals(0, selNone.length); | |
| 511 | |
| 512 } | |
| 513 </script> | |
| 514 </body> | |
| 515 </html> | |
| OLD | NEW |