import testModule = require("../../ui-test"); import TKUnit = require("../../TKUnit"); import app = require("application"); import observable = require("data/observable"); import types = require("utils/types"); import platform = require("platform"); import utils = require("utils/utils"); import { Label } from "ui/label"; import helper = require("../helper"); import { Page } from "ui/page"; // >> article-require-listview-module import listViewModule = require("ui/list-view"); // << article-require-listview-module // >> article-require-modules-listview import observableArray = require("data/observable-array"); import labelModule = require("ui/label"); // << article-require-modules-listview // >> article-item-tap function listViewItemTap(args) { var itemIndex = args.index; // >> (hide) console.dump(itemIndex); // << (hide) } exports.listViewItemTap = listViewItemTap; // << article-item-tap // >> article-load-items function listViewLoadMoreItems(args) { // Expand your collection bound to the ListView with more items here! } // << article-load-items listViewLoadMoreItems("test"); // function loaded(args) { // args.object.bindingContext = { items: [1,2,3,4,5] }; // } // exports.loaded = loaded; var FEW_ITEMS = [0, 1, 2]; var MANY_ITEMS = new Array(100); for (var i = 0; i < 100; i++) { MANY_ITEMS.push(i); } export class ListViewTest extends testModule.UITest { public create(): listViewModule.ListView { return new listViewModule.ListView(); } public test_default_TNS_values() { // >> article-create-listview var listView = new listViewModule.ListView(); // << article-create-listview TKUnit.assertEqual(listView.isScrolling, false, "Default listView.isScrolling"); TKUnit.assert(types.isUndefined(listView.items), "Default listView.items should be undefined"); } public test_set_items_to_array_loads_all_items(done) { var listView = this.testView; var indexes = {}; // >> article-listview-array var colors = ["red", "green", "blue"]; listView.items = colors; listView.on(listViewModule.ListView.itemLoadingEvent, function (args: listViewModule.ItemEventData) { if (!args.view) { // Create label if it is not already created. args.view = new labelModule.Label(); } (args.view).text = colors[args.index]; // >> (hide) indexes[args.index] = true; if (args.index === (colors.length - 1)) { try { if (app.android) { TKUnit.assert(listView.android instanceof android.widget.ListView, "android property is android.widget.ListView"); } else if (app.ios) { TKUnit.assert(listView.ios instanceof UITableView, "ios property is UITableView"); } TKUnit.assert(indexes[0], "itemLoading not called for index 0"); TKUnit.assert(indexes[1], "itemLoading not called for index 1"); TKUnit.assert(indexes[2], "itemLoading not called for index 2"); done(null); } catch (e) { done(e); } } // << (hide) }); // << article-listview-array } public test_set_native_item_exposed() { let listView = this.testView; let indexes = {}; let colors = ["red", "green", "blue"]; listView.items = colors; listView.on(listViewModule.ListView.itemLoadingEvent, function (args: listViewModule.ItemEventData) { if (platform.device.os === platform.platformNames.ios) { indexes[args.index] = args.ios; } else if (platform.device.os === platform.platformNames.android) { indexes[args.index] = args.android; } }); this.waitUntilListViewReady(); for (var item in indexes) { if (platform.device.os === platform.platformNames.ios) { TKUnit.assert(indexes[item] instanceof UITableViewCell, "itemLoading not called for index " + item); } else if (platform.device.os === platform.platformNames.android) { TKUnit.assert(indexes[item] instanceof android.view.ViewGroup, "itemLoading not called for index " + item); } } } public test_cell_selection_ios() { if (platform.device.os === platform.platformNames.ios) { let listView = this.testView; let colors = ["red", "green", "blue"]; listView.items = colors; this.waitUntilListViewReady(); var index = 1; this.performNativeItemTap(listView, index); var uiTableView = listView.ios; var cellIndexPath = NSIndexPath.indexPathForItemInSection(index, 0); var cell = uiTableView.cellForRowAtIndexPath(cellIndexPath); uiTableView.selectRowAtIndexPathAnimatedScrollPosition(cellIndexPath, false, 0); TKUnit.assertTrue(cell.selected, "cell is selected"); } } public test_set_items_to_array_creates_native_views() { var listView = this.testView; listView.on(listViewModule.ListView.itemLoadingEvent, this.loadViewWithItemNumber); listView.items = FEW_ITEMS; this.waitUntilListViewReady(); TKUnit.assertEqual(this.getNativeViewCount(listView), FEW_ITEMS.length, "Native views count."); } public test_refresh_after_adding_items_to_array_loads_new_items() { var listView = this.testView; listView.on(listViewModule.ListView.itemLoadingEvent, this.loadViewWithItemNumber); var colors = ["red", "green", "blue"]; listView.items = colors; this.waitUntilListViewReady(); TKUnit.assertEqual(this.getNativeViewCount(listView), colors.length, "Native views count."); // >> article-change-refresh-listview colors.push("yellow"); // Manually trigger the update so that the new color is shown. listView.refresh(); // << article-change-refresh-listview this.waitUntilListViewReady(); TKUnit.assertEqual(this.getNativeViewCount(listView), colors.length, "Native views count."); } public test_refresh_reloads_all_items() { let listView = this.testView; let indexes = {}; let completed = false; listView.items = FEW_ITEMS; listView.on(listViewModule.ListView.itemLoadingEvent, function (args: listViewModule.ItemEventData) { if (!args.view) { args.view = new labelModule.Label(); } (args.view).text = "item " + args.index; indexes[args.index] = indexes[args.index] ? indexes[args.index] + 1 : 1; completed = args.index === (listView.items.length - 1); }); // iOS7 needs to know the size of the cell before it is generated so we first measure them using fake cell // then we generate the real cells. This cause itemLoading to be called twice per index. let expected = (platform.device.os === platform.platformNames.ios && utils.ios.MajorVersion === 7) ? 2 : 1; TKUnit.waitUntilReady(() => completed); TKUnit.assertEqual(indexes[0], expected, "itemLoading called more than once"); TKUnit.assertEqual(indexes[1], expected, "itemLoading called more than once"); TKUnit.assertEqual(indexes[2], expected, "itemLoading called more than once"); completed = false; listView.refresh(); // again calling refresh will generate itemLoading twice per item. expected += expected; TKUnit.waitUntilReady(() => completed); TKUnit.assertEqual(indexes[0], expected, "itemLoading not called for index 0"); TKUnit.assertEqual(indexes[1], expected, "itemLoading not called for index 1"); TKUnit.assertEqual(indexes[2], expected, "itemLoading not called for index 2"); } public test_set_itmes_to_null_clears_native_items() { var listView = this.testView; listView.on(listViewModule.ListView.itemLoadingEvent, this.loadViewWithItemNumber); listView.items = FEW_ITEMS; this.waitUntilListViewReady(); TKUnit.assertEqual(this.getNativeViewCount(listView), FEW_ITEMS.length, "Native views count."); listView.items = null; TKUnit.waitUntilReady(() => this.getNativeViewCount(listView) === 0); TKUnit.assertEqual(this.getNativeViewCount(listView), 0, "Native views count."); } public test_set_itmes_to_undefiend_clears_native_items() { var listView = this.testView; listView.on(listViewModule.ListView.itemLoadingEvent, this.loadViewWithItemNumber); listView.items = FEW_ITEMS; this.waitUntilListViewReady(); TKUnit.assertEqual(this.getNativeViewCount(listView), FEW_ITEMS.length, "Native views count."); listView.items = undefined; TKUnit.waitUntilReady(() => this.getNativeViewCount(listView) === 0); TKUnit.assertEqual(this.getNativeViewCount(listView), 0, "Native views count."); } public test_set_itmes_to_different_source_loads_new_items() { var listView = this.testView; listView.on(listViewModule.ListView.itemLoadingEvent, this.loadViewWithItemNumber); listView.items = [1, 2, 3]; this.waitUntilListViewReady(); TKUnit.assertEqual(this.getNativeViewCount(listView), 3, "Native views count."); listView.items = ["a", "b", "c", "d"]; this.waitUntilListViewReady(); TKUnit.assertEqual(this.getNativeViewCount(listView), 4, "Native views count."); } public test_set_items_to_observable_array_loads_all_items() { var listView = this.testView; var indexes = {}; // >> article-listview-observablearray var colors = new observableArray.ObservableArray(["red", "green", "blue"]); listView.items = colors; listView.on(listViewModule.ListView.itemLoadingEvent, function (args: listViewModule.ItemEventData) { if (!args.view) { // Create label if it is not already created. args.view = new labelModule.Label(); } (args.view).text = colors.getItem(args.index); indexes[args.index] = true; }); // << article-listview-observablearray this.waitUntilListViewReady(); TKUnit.assert(indexes[0], "itemLoading not called for index 0"); TKUnit.assert(indexes[1], "itemLoading not called for index 1"); TKUnit.assert(indexes[2], "itemLoading not called for index 2"); } public test_add_to_observable_array_refreshes_the_listview() { var listView = this.testView; listView.on(listViewModule.ListView.itemLoadingEvent, this.loadViewWithItemNumber); var colors = new observableArray.ObservableArray(["red", "green", "blue"]); listView.items = colors; this.waitUntilListViewReady(); TKUnit.assertEqual(this.getNativeViewCount(listView), 3, "getNativeViewCount"); // >> article-push-in-observablearray colors.push("yellow"); // The ListView will be updated automatically. // << article-push-in-observablearray this.waitUntilListViewReady(); TKUnit.assertEqual(this.getNativeViewCount(listView), 4, "getNativeViewCount"); } public test_remove_from_observable_array_refreshes_the_listview() { var listView = this.testView; var data = new observableArray.ObservableArray([1, 2, 3]); listView.items = data; listView.on(listViewModule.ListView.itemLoadingEvent, this.loadViewWithItemNumber); this.waitUntilListViewReady(); TKUnit.assertEqual(this.getNativeViewCount(listView), 3, "getNativeViewCount"); data.pop(); this.waitUntilListViewReady(); TKUnit.assertEqual(this.getNativeViewCount(listView), 2, "getNativeViewCount"); } public test_splice_observable_array_refreshes_the_listview() { var listView = this.testView; var data = new observableArray.ObservableArray(["a", "b", "c"]); listView.items = data; listView.on(listViewModule.ListView.itemLoadingEvent, this.loadViewWithItemNumber); this.waitUntilListViewReady(); TKUnit.assertEqual(this.getNativeViewCount(listView), 3, "getNativeViewCount"); // Remove the first 2 elements and add data.splice(0, 2, "d", "e", "f"); this.waitUntilListViewReady(); TKUnit.assertEqual(this.getNativeViewCount(listView), 4, "getNativeViewCount"); } public test_nativeTap_is_raised() { var listView = this.testView; listView.on(listViewModule.ListView.itemLoadingEvent, this.loadViewWithItemNumber); listView.items = FEW_ITEMS; var nativeTapRaised = false; var itemIndex = -1; /* tslint:disable:no-unused-variable */ // >> article-itemtap-event listView.on(listViewModule.ListView.itemTapEvent, function (args: listViewModule.ItemEventData) { var tappedItemIndex = args.index; var tappedItemView = args.view; // Do someting // >> (hide) nativeTapRaised = true; itemIndex = args.index; // << (hide) }); // << article-itemtap-event /* tslint:enable:no-unused-variable */ this.waitUntilListViewReady(); this.performNativeItemTap(listView, 1); TKUnit.assert(nativeTapRaised, "itemTap not raised."); TKUnit.assertEqual(itemIndex, 1, "tappedItemIndex"); } public test_loadMoreItems_raised_when_showing_few_items() { var listView = this.testView; var loadMoreItemsCount = 0; listView.items = FEW_ITEMS; listView.on(listViewModule.ListView.itemLoadingEvent, this.loadViewWithItemNumber); // >> article-loadmoreitems-event listView.on(listViewModule.ListView.loadMoreItemsEvent, function (data: observable.EventData) { // Do something. // >> (hide) loadMoreItemsCount++; // << (hide) }); // ``` // << article-loadmoreitems-event this.waitUntilListViewReady(); TKUnit.assertEqual(loadMoreItemsCount, 1, "loadMoreItemsCount"); } public test_loadMoreItems_not_raised_when_showing_many_items() { var listView = this.testView; listView.on(listViewModule.ListView.itemLoadingEvent, this.loadViewWithItemNumber); var loadMoreItemsCount = 0; listView.items = MANY_ITEMS; listView.on(listViewModule.ListView.loadMoreItemsEvent, function (data: observable.EventData) { loadMoreItemsCount++; }); // We can't use waitUntilReady because we don't know what to wait for. if (platform.device.os === platform.platformNames.android) { this.waitUntilTestElementLayoutIsValid(); } else { TKUnit.wait(0.2); } TKUnit.assertEqual(loadMoreItemsCount, 0, "loadMoreItemsCount"); } public test_loadMoreItems_is_raised_when_scroll_to_last_item() { var listView = this.testView; listView.on(listViewModule.ListView.itemLoadingEvent, this.loadViewWithItemNumber); var loadMoreItemsCount = 0; listView.items = MANY_ITEMS; listView.on(listViewModule.ListView.loadMoreItemsEvent, function (data: observable.EventData) { loadMoreItemsCount++; }); listView.scrollToIndex(MANY_ITEMS.length - 1); // We can't use waitUntilReady because we don't know what to wait for. if (platform.device.os === platform.platformNames.android) { this.waitUntilTestElementLayoutIsValid(); } else { TKUnit.wait(0.2); } TKUnit.assert(loadMoreItemsCount > 0, "loadMoreItemsCount"); } public test_usingAppLevelConvertersInListViewItems() { var listView = this.testView; var dateConverter = function (value, format) { var result = format; var day = value.getDate(); result = result.replace("DD", day < 10 ? "0" + day : day); var month = value.getMonth() + 1; result = result.replace("MM", month < 10 ? "0" + month : month); result = result.replace("YYYY", value.getFullYear()); return result; }; app.resources["dateConverter"] = dateConverter; var data = new observableArray.ObservableArray(); data.push({ date: new Date(2020, 2, 7) }); listView.itemTemplate = "