// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information. // // /// // module WinJSTests { "use strict"; var ListView = WinJS.UI.ListView; var testRootEl; function checkTile(listview, index, left, top, caption) { var tile = listview.elementFromIndex(index), container = Helper.ListView.containerFrom(tile); LiveUnit.Assert.areEqual(caption + index, tile.textContent.replace(/ /g, '')); LiveUnit.Assert.areEqual(left, Helper.ListView.offsetLeftFromSurface(listview, container), "Error in tile " + index); LiveUnit.Assert.areEqual(top, Helper.ListView.offsetTopFromSurface(listview, container), "Error in tile " + index); } function setupListview(element, layout) { var myData = []; for (var i = 0; i < 100; ++i) { myData.push({ title: "Tile" + i }); } var list = new WinJS.Binding.List(myData); return new WinJS.UI.ListView(element, { itemDataSource: list.dataSource, itemTemplate: Helper.ListView.createRenderer("simpleTemplate"), layout: new WinJS.UI[layout](), }); } function checkTileSelection(listview, index, selected) { var tile = listview.elementFromIndex(index).parentNode; LiveUnit.Assert.areEqual(selected, WinJS.Utilities.hasClass(tile, WinJS.UI._selectedClass)); } export class ConfigurationTests { // This is the setup function that will be called at the beginning of each test function. setUp() { LiveUnit.LoggingCore.logComment("In setup"); testRootEl = document.createElement("div"); testRootEl.className = "file-listview-css"; var newNode = document.createElement("div"); newNode.id = "ConfigurationTests"; newNode.innerHTML = "
" + "
" + "
" + "
" + "
" + "
" + "
" + "" + "" + "" + ""; testRootEl.appendChild(newNode); document.body.appendChild(testRootEl); } tearDown() { LiveUnit.LoggingCore.logComment("In tearDown"); WinJS.Utilities.disposeSubTree(testRootEl); document.body.removeChild(testRootEl); } testScrollToItemValidation = function (complete) { function test(modification) { var placeholder = document.createElement("div"); testRootEl.appendChild(placeholder); var listView = new WinJS.UI.ListView(placeholder, { itemTemplate: function (itemPromise) { var elem = document.createElement("div"); elem.style.width = elem.style.height = "100px"; itemPromise.then(function (item) { elem.textContent = item.data.title; }); return elem; }, layout: new WinJS.UI.GridLayout() }); return Helper.ListView.waitForReady(listView, -1)().then(function () { modification(listView, 10); return Helper.ListView.waitForReady(listView, -1)(); }).then(function () { var list = new WinJS.Binding.List([{ title: "Tile" }]); listView.itemDataSource = list.dataSource; modification(listView, 10); return Helper.ListView.waitForReady(listView, -1)(); }).then(function () { LiveUnit.Assert.isTrue(!!listView.elementFromIndex(0)); var myData = []; for (var i = 0; i < 100; ++i) { myData.push({ title: "Tile" + i }); } var list = new WinJS.Binding.List(myData); listView.itemDataSource = list.dataSource; modification(listView, 10000); return Helper.ListView.waitForReady(listView, -1)(); }).then(function () { LiveUnit.Assert.isTrue(!!listView.elementFromIndex(99)); LiveUnit.Assert.areEqual(99, listView.indexOfLastVisible); placeholder.parentNode.removeChild(placeholder); }); } test(function (listView, index) { listView.indexOfFirstVisible = index; }).then(function () { return test(function (listView, index) { listView.ensureVisible(index); }); }).done(complete); }; testScrollToHeaderValidation = function (complete) { var placeholder = document.createElement("div"); placeholder.style.width = "320px"; testRootEl.appendChild(placeholder); function renderer(itemPromise) { var elem = document.createElement("div"); elem.style.width = elem.style.height = "100px"; itemPromise.then(function (item) { elem.textContent = item.data.title; }); return elem; } function groupKey(data) { return data.group.toString(); } function groupData(data) { return { title: data.group.toString() }; } function setupDataSources(listView, data) { var list = new WinJS.Binding.List(data); var myGroupedList = list.createGrouped(groupKey, groupData); listView.itemDataSource = myGroupedList.dataSource; listView.groupDataSource = myGroupedList.groups.dataSource; } var listView = new ListView(placeholder, { itemTemplate: renderer, groupHeaderTemplate: renderer, layout: new WinJS.UI.GridLayout() }); setupDataSources(listView, []); return Helper.ListView.waitForReady(listView, -1)(). then(function () { listView.ensureVisible({ type: WinJS.UI.ObjectType.groupHeader, index: 10 }); return Helper.ListView.waitForReady(listView, -1)(); }). then(function () { setupDataSources(listView, [{ title: "Tile", group: 0 }]); listView.ensureVisible({ type: WinJS.UI.ObjectType.groupHeader, index: 10 }); return Helper.ListView.waitForReady(listView, -1)(); }). then(function () { LiveUnit.Assert.isTrue(!!listView.elementFromIndex(0)); var myData = []; for (var i = 0; i < 100; ++i) { myData.push({ title: "Tile" + i, group: Math.floor(i / 10) }); } setupDataSources(listView, myData); listView.ensureVisible({ type: WinJS.UI.ObjectType.groupHeader, index: 10000 }); return Helper.ListView.waitForReady(listView, -1)(); }). done(function () { LiveUnit.Assert.isTrue(!!listView.elementFromIndex(99)); LiveUnit.Assert.areEqual(90, listView.indexOfFirstVisible); placeholder.parentNode.removeChild(placeholder); complete(); }); }; testForceLayoutAndDataSourceChangePriorities = function (complete) { var placeholder = document.getElementById("itemSizeChange"); var myData = []; for (var i = 0; i < 100; ++i) { myData.push({ title: "Tile" + i }); } var listView = new ListView(placeholder, { itemDataSource: (new WinJS.Binding.List(myData)).dataSource, itemTemplate: function (itemPromise) { var elem = document.createElement("div"); elem.style.width = elem.style.height = "100px"; itemPromise.then(function (item) { elem.textContent = item.data.title; }); return elem; }, indexOfFirstVisible: 60 }); Helper.ListView.waitForReady(listView, -1)().then(function () { LiveUnit.Assert.areEqual(2000, listView.scrollPosition); LiveUnit.Assert.areEqual(WinJS.Utilities.getScrollPosition(listView._viewport).scrollLeft, listView.scrollPosition); LiveUnit.Assert.areEqual(60, listView.indexOfFirstVisible); placeholder.style.display = "none"; return WinJS.Promise.timeout(1000); }).then(function () { var newList = new WinJS.Binding.List([]); listView.itemDataSource = newList.dataSource; for (var i = 0; i < 100; ++i) { newList.push({ title: "NewTile" + i }); } placeholder.style.display = "block"; listView.forceLayout(); return Helper.ListView.waitForReady(listView, -1)(); }).then(function () { LiveUnit.Assert.areEqual(0, listView.scrollPosition); LiveUnit.Assert.areEqual(WinJS.Utilities.getScrollPosition(listView._viewport).scrollLeft, listView.scrollPosition); LiveUnit.Assert.areEqual(0, listView.indexOfFirstVisible); LiveUnit.Assert.isTrue(!!listView.elementFromIndex(0)); complete(); }); }; } function generateItemSizeChange(layout) { ConfigurationTests.prototype["testItemSizeChange" + (layout == "GridLayout" ? "" : layout)] = function (complete) { LiveUnit.LoggingCore.logComment("In testItemSizeChange"); var element = document.getElementById("itemSizeChange"); var myData = []; for (var i = 0; i < 100; ++i) { myData.push({ title: "Tile" + i }); } var list = new WinJS.Binding.List(myData); var listView = new WinJS.UI.ListView(element, { itemDataSource: list.dataSource, itemTemplate: Helper.ListView.createRenderer("simpleTemplate"), layout: new WinJS.UI[layout](), }); var tests = [ function () { WinJS.Utilities.setScrollPosition(Helper.ListView.viewport(element), { scrollLeft: 100, scrollTop: 0 }); return true; }, function () { checkTile(listView, 0, 0, 0, "Tile"); checkTile(listView, 1, 0, 100, "Tile"); checkTile(listView, 2, 0, 200, "Tile"); checkTile(listView, 3, 100, 0, "Tile"); listView.itemTemplate = Helper.ListView.createRenderer("smallTemplate"); }, function () { checkTile(listView, 0, 0, 0, "Tile"); checkTile(listView, 1, 0, 50, "Tile"); checkTile(listView, 2, 0, 100, "Tile"); checkTile(listView, 7, 50, 0, "Tile"); listView.itemTemplate = Helper.ListView.createRenderer("bigTemplate"); }, function () { checkTile(listView, 0, 0, 0, "Tile"); checkTile(listView, 1, 200, 0, "Tile"); complete(); } ]; Helper.ListView.runTests(listView, tests); }; }; generateItemSizeChange("GridLayout"); function generate(name, selector, testFunction) { function generateTest(layout) { var fullName = name + (layout == "GridLayout" ? "" : layout); ConfigurationTests.prototype[fullName] = function (complete) { LiveUnit.LoggingCore.logComment("in " + fullName); var element = document.getElementById(selector); var listview = setupListview(element, layout); testFunction(element, listview, complete); }; } generateTest("GridLayout"); } generate("testDatasourceChange", "dataSourceChange", function (element, listView, complete) { var tests = [ function () { WinJS.Utilities.setScrollPosition(Helper.ListView.viewport(element), { scrollLeft: 100, scrollTop: 0 }); return true; }, function () { listView.currentItem = { index: 4 }; LiveUnit.Assert.areEqual(4, listView.currentItem.index, "ListView's currentItem wasn't set properly"); listView.selection._pivot = 1; checkTile(listView, 0, 0, 0, "Tile"); var newData = []; for (var i = 0; i < 100; ++i) { newData.push({ title: "Newtile" + i }); } var newBindingList = new WinJS.Binding.List(newData); listView.itemDataSource = newBindingList.dataSource; }, function () { Helper.ListView.validateResetFocusState(listView, "after changing the itemDataSource"); LiveUnit.Assert.areEqual(WinJS.UI._INVALID_INDEX, listView.selection._pivot, "Selection pivot wasn't reset during data source change"); checkTile(listView, 0, 0, 0, "Newtile"); complete(); } ]; Helper.ListView.runTests(listView, tests); }); generate("testChangeToNullDataSource", "dataSourceChange", function (element, listView, complete) { var tests = [ function () { listView.currentItem = { index: 4 }; LiveUnit.Assert.areEqual(4, listView.currentItem.index, "ListView's currentItem wasn't set properly"); listView.itemDataSource = null; return true; }, function () { Helper.ListView.validateResetFocusState(listView, "after changing the itemDataSource", true); Helper.ListView.validateListView(listView); complete(); } ]; Helper.ListView.runTests(listView, tests); }); generate("testTemplateChange", "templateChange", function (element, listView, complete) { var tests = [ function () { WinJS.Utilities.setScrollPosition(Helper.ListView.viewport(element), { scrollLeft: 100, scrollTop: 0 }); return true; }, function () { checkTile(listView, 0, 0, 0, "Tile"); checkTile(listView, 1, 0, 100, "Tile"); listView.itemTemplate = Helper.ListView.createRenderer("newTemplate"); }, function () { checkTile(listView, 0, 0, 0, "NewTile"); checkTile(listView, 1, 0, 50, "NewTile"); complete(); } ]; Helper.ListView.runTests(listView, tests); }); generate("testLayoutChange", "layoutChange", function (element, listView, complete) { var tests = [ function () { checkTile(listView, 1, 0, 100, "Tile"); checkTile(listView, 3, 100, 0, "Tile"); LiveUnit.Assert.areEqual("auto", window.getComputedStyle(Helper.ListView.viewport(element), null).overflowX); LiveUnit.Assert.areEqual("hidden", window.getComputedStyle(Helper.ListView.viewport(element), null).overflowY); listView.layout = new WinJS.UI.ListLayout(); }, function () { checkTile(listView, 1, 0, 100, "Tile"); checkTile(listView, 3, 0, 300, "Tile"); LiveUnit.Assert.areEqual("hidden", window.getComputedStyle(Helper.ListView.viewport(element), null).overflowX); LiveUnit.Assert.areEqual("auto", window.getComputedStyle(Helper.ListView.viewport(element), null).overflowY); complete(); } ]; Helper.ListView.runTests(listView, tests); }); // When multiple ListView properties are set during a single event loop, ensure that the // highest priority scroll request is honored. There are three classes of scroll requests: // 1. Scroll to a specific location (high priority) // 2. Reset the scroll position to 0 (medium priority) // 3. Maintain the current scroll position (low priority) generate("testScrollToPriority", "scrollToPriority", function (element, listView, complete) { var tests = [ function () { listView.scrollPosition = 500; return true; }, function () { // Verify that the scroll position has been initialized so we can begin the test LiveUnit.Assert.areEqual(500, listView.scrollPosition, "Scroll position should have been set to 500"); // Test high priority scroll request listView.layout.maxRows = 1; // Low priority listView.itemDataSource = listView.itemDataSource; // Med priority listView.indexOfFirstVisible = 9; // High priority listView.itemTemplate = listView.itemTemplate; // Med priority return true; }, function () { // Verify that indexOfFirstVisible's scroll request won. The scroll // position should have changed and it shouldn't have been reset to 0. LiveUnit.Assert.areNotEqual(0, listView.scrollPosition, "Scroll position shouldn't have been reset to 0"); LiveUnit.Assert.areNotEqual(500, listView.scrollPosition, "Scroll position shouldn't have been maintained"); LiveUnit.Assert.areEqual(9, listView.indexOfFirstVisible, "Item 10 should have been the first visible item"); // Test medium priority scroll request listView.layout.maxRows = 2; // Low priority listView.itemDataSource = listView.itemDataSource; // Med priority listView.layout.itemInfo = listView.layout.itemInfo; // Low priority return true; }, function () { // Verify that itemDataSource's scroll request won. The scroll position // should have been reset to 0. LiveUnit.Assert.areEqual(0, listView.scrollPosition, "Scroll position should have been reset to 0"); complete(); } ]; Helper.ListView.runTests(listView, tests); }); function generateModeChange(layout) { ConfigurationTests.prototype["testModeChange" + (layout == "GridLayout" ? "" : layout)] = function () { LiveUnit.LoggingCore.logComment("In testModeChange"); var element = document.getElementById("modeChange"); var listView = setupListview(element, layout); LiveUnit.Assert.isTrue(listView.selectionMode === WinJS.UI.SelectionMode.multi); listView.selectionMode = WinJS.UI.SelectionMode.none; LiveUnit.Assert.isTrue(listView.selectionMode === WinJS.UI.SelectionMode.none); listView.selectionMode = WinJS.UI.SelectionMode.multi; LiveUnit.Assert.isTrue(listView.selectionMode === WinJS.UI.SelectionMode.multi); listView.selectionMode = WinJS.UI.SelectionMode.none; LiveUnit.Assert.isTrue(listView.selectionMode === WinJS.UI.SelectionMode.none); }; }; generateModeChange("GridLayout"); function generateCurrentItem(layout) { ConfigurationTests.prototype["testCurrentItem" + (layout == "GridLayout" ? "" : layout)] = function (complete) { var listView = setupListview(document.getElementById("selectionChange"), layout); Helper.ListView.whenLoadingComplete(listView, function () { var currentItem = listView.currentItem; LiveUnit.Assert.areEqual(currentItem.index, 0); LiveUnit.Assert.areEqual(currentItem.key, "0"); listView.currentItem = { index: 1 }; currentItem = listView.currentItem; LiveUnit.Assert.areEqual(currentItem.index, 1); LiveUnit.Assert.areEqual(currentItem.key, "1"); listView.currentItem = { key: "2" }; currentItem = listView.currentItem; LiveUnit.Assert.areEqual(currentItem.index, 2); LiveUnit.Assert.areEqual(currentItem.key, "2"); // this should do nothing because itemFromKey function is missing. listView.itemDataSource.itemFromKey = undefined; listView.currentItem = { key: "3" }; currentItem = listView.currentItem; LiveUnit.Assert.areEqual(currentItem.index, 2); LiveUnit.Assert.areEqual(currentItem.key, "2"); complete(); }); }; }; generateCurrentItem("GridLayout"); function generateCurrentItemInConstructor(layout) { ConfigurationTests.prototype["testCurrentItemInConstructor" + (layout == "GridLayout" ? "" : layout)] = function (complete) { var myData = []; for (var i = 0; i < 100; ++i) { myData.push({ title: "Tile" + i }); } var newNode = document.createElement("div"); newNode.style.width = "1000px"; newNode.style.height = "600px"; testRootEl.appendChild(newNode); var listView = new WinJS.UI.ListView(newNode, { itemDataSource: (new WinJS.Binding.List(myData)).dataSource, layout: new WinJS.UI[layout](), currentItem: { index: 5 } }); listView.selection.set([1, 3]); Helper.ListView.whenLoadingComplete(listView, function () { var currentItem = listView.currentItem; LiveUnit.Assert.areEqual(currentItem.index, 5); LiveUnit.Assert.areEqual(currentItem.key, "5"); Helper.ListView.elementsEqual(listView.selection.getIndices(), [1, 3]); checkTileSelection(listView, 0, false); checkTileSelection(listView, 1, true); checkTileSelection(listView, 0, false); checkTileSelection(listView, 3, true); WinJS.Utilities.disposeSubTree(newNode); testRootEl.removeChild(newNode); complete(); }); }; }; generateCurrentItemInConstructor("GridLayout"); } LiveUnit.registerTestClass("WinJSTests.ConfigurationTests");