1 <!DOCTYPE html> 2 <!-- 3 Copyright (c) 2013 The Chromium Authors. All rights reserved. 4 Use of this source code is governed by a BSD-style license that can be 5 found in the LICENSE file. 6 --> 7 8 <link rel="import" href="/tracing/base/task.html"> 9 <link rel="import" href="/tracing/core/test_utils.html"> 10 <link rel="import" href="/tracing/model/event_set.html"> 11 <link rel="import" href="/tracing/model/model.html"> 12 <link rel="import" href="/tracing/ui/timeline_view.html"> 13 14 <script> 15 'use strict'; 16 17 tr.b.unittest.testSuite(function() { 18 var Task = tr.b.Task; 19 20 function setupTimeline() { 21 var container = document.createElement('track-view-container'); 22 container.id = 'track_view_container'; 23 24 var view = document.createElement('tr-ui-timeline-view'); 25 view.appendChild(container); 26 view.trackViewContainer_ = container; 27 return view; 28 } 29 30 var createFullyPopulatedModel = function(opt_withError, opt_withMetadata) { 31 var withError = opt_withError !== undefined ? opt_withError : true; 32 var withMetadata = opt_withMetadata !== undefined ? 33 opt_withMetadata : true; 34 35 var num_tests = 50; 36 var testIndex = 0; 37 var startTime = 0; 38 39 var model = new tr.Model(); 40 var io = new tr.importer.ImportOptions(); 41 io.showImportWarnings = false; 42 model.importOptions = io; 43 44 for (testIndex = 0; testIndex < num_tests; ++testIndex) { 45 var process = model.getOrCreateProcess(10000 + testIndex); 46 if (testIndex % 2 == 0) { 47 var thread = process.getOrCreateThread('Thread Name Here'); 48 thread.sliceGroup.pushSlice(new tr.model.Slice( 49 'foo', 'a', 0, startTime, {}, 1)); 50 thread.sliceGroup.pushSlice(new tr.model.Slice( 51 'bar', 'b', 0, startTime + 23, {}, 10)); 52 } else { 53 var thread = process.getOrCreateThread('Name'); 54 thread.sliceGroup.pushSlice(new tr.model.Slice( 55 'foo', 'a', 0, startTime + 4, {}, 11)); 56 thread.sliceGroup.pushSlice(new tr.model.Slice( 57 'bar', 'b', 0, startTime + 22, {}, 14)); 58 } 59 } 60 var p1000 = model.getOrCreateProcess(1000); 61 var objects = p1000.objects; 62 objects.idWasCreated('0x1000', 'tr.e.cc', 'LayerTreeHostImpl', 10); 63 objects.addSnapshot('0x1000', 'tr.e.cc', 'LayerTreeHostImpl', 10, 64 'snapshot-1'); 65 objects.addSnapshot('0x1000', 'tr.e.cc', 'LayerTreeHostImpl', 25, 66 'snapshot-2'); 67 objects.addSnapshot('0x1000', 'tr.e.cc', 'LayerTreeHostImpl', 40, 68 'snapshot-3'); 69 objects.idWasDeleted('0x1000', 'tr.e.cc', 'LayerTreeHostImpl', 45); 70 model.updateCategories_(); 71 72 // Add a known problematic piece of data to test the import errors UI. 73 model.importWarning({ 74 type: 'test_error', 75 message: 'Synthetic Import Error' 76 }); 77 model.updateBounds(); 78 79 // Add data with metadata information stored 80 model.metadata.push({name: 'a', value: 'testA'}); 81 model.metadata.push({name: 'b', value: 'testB'}); 82 model.metadata.push({name: 'c', value: 'testC'}); 83 84 return model; 85 }; 86 87 var visibleTracks = function(trackButtons) { 88 return trackButtons.reduce(function(numVisible, button) { 89 var style = button.parentElement.style; 90 var visible = (style.display.indexOf('none') === -1); 91 return visible ? numVisible + 1 : numVisible; 92 }, 0); 93 }; 94 95 var modelsEquivalent = function(lhs, rhs) { 96 if (lhs.length !== rhs.length) 97 return false; 98 return lhs.every(function(lhsItem, index) { 99 var rhsItem = rhs[index]; 100 return rhsItem.regexpText === lhsItem.regexpText && 101 rhsItem.isOn === lhsItem.isOn; 102 }); 103 }; 104 105 test('instantiate', function() { 106 var model11 = createFullyPopulatedModel(true, true); 107 108 var view = setupTimeline(); 109 view.style.height = '400px'; 110 view.style.border = '1px solid black'; 111 view.model = model11; 112 113 var simpleButton1 = document.createElement('tr-ui-b-toolbar-button'); 114 simpleButton1.textContent = 'M'; 115 view.leftControls.appendChild(simpleButton1); 116 117 var simpleButton2 = document.createElement('tr-ui-b-toolbar-button'); 118 simpleButton2.textContent = 'am button'; 119 view.leftControls.appendChild(simpleButton2); 120 121 this.addHTMLOutput(view); 122 }); 123 124 test('changeModelToSomethingDifferent', function() { 125 var model00 = createFullyPopulatedModel(false, false); 126 var model11 = createFullyPopulatedModel(true, true); 127 128 var view = setupTimeline(); 129 view.style.height = '400px'; 130 view.model = model00; 131 view.model = undefined; 132 view.model = model11; 133 view.model = model00; 134 }); 135 136 test('setModelToSameThingAgain', function() { 137 var model = createFullyPopulatedModel(false, false); 138 139 // Create a view with am model. 140 var view = setupTimeline(); 141 view.style.height = '400px'; 142 view.model = model; 143 var sc = view.brushingStateController; 144 145 // Mutate the model and update the view. 146 var t123 = model.getOrCreateProcess(123).getOrCreateThread(123); 147 t123.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx( 148 {title: 'somethingUnusual', start: 0, duration: 5})); 149 view.model = model; 150 151 // Verify that the new bits of the model show up in the view. 152 var selection = new tr.model.EventSet(); 153 var filter = new tr.c.TitleOrCategoryFilter('somethingUnusual'); 154 var filterTask = sc.addAllEventsMatchingFilterToSelectionAsTask( 155 filter, selection); 156 Task.RunSynchronously(filterTask); 157 assert.equal(selection.length, 1); 158 }); 159 }); 160 </script> 161 162