From 5dee35cb83704dab1158326e680cdee50735cec9 Mon Sep 17 00:00:00 2001 From: Vladimir Enchev Date: Tue, 17 Mar 2015 11:33:34 +0200 Subject: [PATCH] segmented-bar tests & fixes --- CrossPlatformModules.csproj | 10 +- .../segmented-bar-tests-native.android.ts | 5 + .../segmented-bar-tests-native.d.ts | 4 + .../segmented-bar-tests-native.ios.ts | 5 + .../ui/segmented-bar/segmented-bar-tests.ts | 171 ++++++++++++++++++ ui/segmented-bar/segmented-bar-common.ts | 19 +- ui/segmented-bar/segmented-bar.android.ts | 18 +- ui/segmented-bar/segmented-bar.ios.ts | 33 +++- 8 files changed, 243 insertions(+), 22 deletions(-) create mode 100644 apps/tests/ui/segmented-bar/segmented-bar-tests-native.android.ts create mode 100644 apps/tests/ui/segmented-bar/segmented-bar-tests-native.d.ts create mode 100644 apps/tests/ui/segmented-bar/segmented-bar-tests-native.ios.ts create mode 100644 apps/tests/ui/segmented-bar/segmented-bar-tests.ts diff --git a/CrossPlatformModules.csproj b/CrossPlatformModules.csproj index b4ac50cb4..7e4c48402 100644 --- a/CrossPlatformModules.csproj +++ b/CrossPlatformModules.csproj @@ -123,6 +123,14 @@ + + segmented-bar-tests-native.d.ts + + + + segmented-bar-tests-native.d.ts + + list-picker-tests-native.d.ts @@ -1475,7 +1483,7 @@ False - + \ No newline at end of file diff --git a/apps/tests/ui/segmented-bar/segmented-bar-tests-native.android.ts b/apps/tests/ui/segmented-bar/segmented-bar-tests-native.android.ts new file mode 100644 index 000000000..7cc46f59d --- /dev/null +++ b/apps/tests/ui/segmented-bar/segmented-bar-tests-native.android.ts @@ -0,0 +1,5 @@ +import segmentedBarModule = require("ui/segmented-bar"); + +export function getNativeItemsCount(bar: segmentedBarModule.SegmentedBar): number { + return (bar.android).getTabWidget().getTabCount(); +} \ No newline at end of file diff --git a/apps/tests/ui/segmented-bar/segmented-bar-tests-native.d.ts b/apps/tests/ui/segmented-bar/segmented-bar-tests-native.d.ts new file mode 100644 index 000000000..e19fbcac1 --- /dev/null +++ b/apps/tests/ui/segmented-bar/segmented-bar-tests-native.d.ts @@ -0,0 +1,4 @@ +//@private +import segmentedBarModule = require("ui/segmented-bar"); + +export declare function getNativeItemsCount(bar: segmentedBarModule.SegmentedBar): number; diff --git a/apps/tests/ui/segmented-bar/segmented-bar-tests-native.ios.ts b/apps/tests/ui/segmented-bar/segmented-bar-tests-native.ios.ts new file mode 100644 index 000000000..81bc3502f --- /dev/null +++ b/apps/tests/ui/segmented-bar/segmented-bar-tests-native.ios.ts @@ -0,0 +1,5 @@ +import segmentedBarModule = require("ui/segmented-bar"); + +export function getNativeItemsCount(bar: segmentedBarModule.SegmentedBar): number { + return (bar.ios).numberOfSegments; +} \ No newline at end of file diff --git a/apps/tests/ui/segmented-bar/segmented-bar-tests.ts b/apps/tests/ui/segmented-bar/segmented-bar-tests.ts new file mode 100644 index 000000000..c740feeaa --- /dev/null +++ b/apps/tests/ui/segmented-bar/segmented-bar-tests.ts @@ -0,0 +1,171 @@ +import TKUnit = require("../../TKUnit"); +import helper = require("../helper"); +import viewModule = require("ui/core/view"); +import segmentedBarTestsNative = require("./segmented-bar-tests-native"); + +// +// # SegmentedBar + +// Using a SegmentedBar requires the "ui/segmented-bar" module. +// ``` JavaScript +import segmentedBarModule = require("ui/segmented-bar"); + +function _createSegmentedBar(): segmentedBarModule.SegmentedBar { + // + // ## Creating a SegmentedBar + // ``` JavaScript + var segmentedBar = new segmentedBarModule.SegmentedBar(); + // ``` + // + segmentedBar.id = "SegmentedBar"; + return segmentedBar; +} + +function _createItems(count: number): Array { + var items = new Array(); + for (var i = 0; i < count; i++) { + items.push({ title: i + "" }); + } + return items; +} + +export var testWhenSegmentedBarIsCreatedItemsAreUndefined = function () { + helper.buildUIAndRunTest(_createSegmentedBar(), function (views: Array) { + var segmentedBar = views[0]; + var expectedValue = undefined; + var actualValue = segmentedBar.items; + TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue); + }); +} + +export var testWhenSegmentedBarIsCreatedSelectedIndexIsUndefined = function () { + helper.buildUIAndRunTest(_createSegmentedBar(), function (views: Array) { + var segmentedBar = views[0]; + var expectedValue = undefined; + var actualValue = segmentedBar.selectedIndex; + TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue); + }); +} + +export var testWhenSettingItemsToNonEmptyArrayTheSameAmountOfNativeItemsIsCreated = function () { + helper.buildUIAndRunTest(_createSegmentedBar(), function (views: Array) { + var segmentedBar = views[0]; + segmentedBar.items = _createItems(10); + var expectedValue = segmentedBar.items.length; + var actualValue = segmentedBarTestsNative.getNativeItemsCount(segmentedBar); + TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue); + }); +} + +export var testWhenSettingItemsToEmptyArrayZeroNativeItemsAreCreated = function () { + helper.buildUIAndRunTest(_createSegmentedBar(), function (views: Array) { + var segmentedBar = views[0]; + segmentedBar.items = []; + var expectedValue = segmentedBar.items.length; + var actualValue = segmentedBarTestsNative.getNativeItemsCount(segmentedBar); + TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue); + }); +} + +export var testSelectedIndexBecomesZeroWhenItemsBoundToNonEmptyArray = function () { + helper.buildUIAndRunTest(_createSegmentedBar(), function (views: Array) { + var segmentedBar = views[0]; + // + // ### Binding segmentedBar.items + // ``` JavaScript + segmentedBar.items = _createItems(3); + // ``` + // + var expectedValue = 0; + var actualValue = segmentedBar.selectedIndex; + TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue); + }); +} + +export var testSelectedIndexBecomesUndefinedWhenItemsBoundToEmptyArray = function () { + helper.buildUIAndRunTest(_createSegmentedBar(), function (views: Array) { + var segmentedBar = views[0]; + segmentedBar.items = _createItems(10); + // + // ### Selecting an item programmatically + // ``` JavaScript + segmentedBar.selectedIndex = 9; + // ``` + // + segmentedBar.items = []; + var expectedValue = undefined; + var actualValue = segmentedBar.selectedIndex; + TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue); + }); +} + +export var testSelectedIndexBecomesUndefinedWhenItemsBoundToUndefined = function () { + helper.buildUIAndRunTest(_createSegmentedBar(), function (views: Array) { + var segmentedBar = views[0]; + segmentedBar.items = _createItems(10); + segmentedBar.selectedIndex = 9; + segmentedBar.items = undefined; + var expectedValue = undefined; + var actualValue = segmentedBar.selectedIndex; + TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue); + }); +} + +export var testSelectedIndexBecomesUndefinedWhenItemsBoundToNull = function () { + helper.buildUIAndRunTest(_createSegmentedBar(), function (views: Array) { + var segmentedBar = views[0]; + segmentedBar.items = _createItems(10); + segmentedBar.selectedIndex = 9; + segmentedBar.items = null; + var expectedValue = undefined; + var actualValue = segmentedBar.selectedIndex; + TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue); + }); +} + +export var testItemsIsResolvedCorrectlyIfSetBeforeViewIsLoaded = function () { + var segmentedBar = _createSegmentedBar(); + var expectedValue = 10; + segmentedBar.items = _createItems(expectedValue); + segmentedBar.selectedIndex = 9; + helper.buildUIAndRunTest(segmentedBar, function (views: Array) { + var segmentedBar = views[0]; + var actualValue = segmentedBar.items.length; + TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue); + }); +} + +export var testSelectedIndexIsResolvedCorrectlyIfSetBeforeViewIsLoaded = function () { + var segmentedBar = _createSegmentedBar(); + segmentedBar.items = _createItems(10); + var expectedValue = 9; + segmentedBar.selectedIndex = expectedValue; + helper.buildUIAndRunTest(segmentedBar, function (views: Array) { + var segmentedBar = views[0]; + var actualValue = segmentedBar.selectedIndex; + TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue); + }); +} + +export var testSettingNegativeSelectedIndexShouldThrow = function () { + var segmentedBar = _createSegmentedBar(); + helper.buildUIAndRunTest(segmentedBar, function (views: Array) { + var segmentedBar = views[0]; + segmentedBar.items = _createItems(10); + + TKUnit.assertThrows(function () { + segmentedBar.selectedIndex = -1; + }, "Setting selectedIndex to a negative number should throw."); + }); +} + +export var testSettingSelectedIndexLargerThanCountShouldThrow = function () { + var segmentedBar = _createSegmentedBar(); + helper.buildUIAndRunTest(segmentedBar, function (views: Array) { + var segmentedBar = views[0]; + segmentedBar.items = _createItems(10); + TKUnit.assertThrows(function () { + segmentedBar.selectedIndex = 10; + }, "Setting selectedIndex to a larger number should throw."); + }); +} \ No newline at end of file diff --git a/ui/segmented-bar/segmented-bar-common.ts b/ui/segmented-bar/segmented-bar-common.ts index f6309a8a3..a81994929 100644 --- a/ui/segmented-bar/segmented-bar-common.ts +++ b/ui/segmented-bar/segmented-bar-common.ts @@ -3,6 +3,7 @@ import view = require("ui/core/view"); import proxy = require("ui/core/proxy"); import dependencyObservable = require("ui/core/dependency-observable"); import color = require("color"); +import types = require("utils/types"); export module knownCollections { export var items = "items"; @@ -15,9 +16,17 @@ export class SegmentedBar extends view.View implements definition.SegmentedBar { } } - public _adjustSelectedIndex() { - if (this.selectedIndex > this.items.length - 1) { - this._setValue(SegmentedBar.selectedIndexProperty, this.items.length - 1); + public _adjustSelectedIndex(items: Array) { + if (this.items) { + if (this.items.length > 0) { + if (types.isUndefined(this.selectedIndex) || (this.selectedIndex > this.items.length - 1)) { + this._setValue(SegmentedBar.selectedIndexProperty, 0); + } + } else { + this._setValue(SegmentedBar.selectedIndexProperty, undefined); + } + } else { + this._setValue(SegmentedBar.selectedIndexProperty, undefined); } } @@ -39,11 +48,11 @@ export class SegmentedBar extends view.View implements definition.SegmentedBar { return this._getValue(SegmentedBar.selectedBackgroundColorProperty); } set selectedBackgroundColor(value: color.Color) { - this._setValue(SegmentedBar.selectedBackgroundColorProperty, + this._setValue(SegmentedBar.selectedBackgroundColorProperty, value instanceof color.Color ? value : new color.Color(value)); } public static selectedBackgroundColorProperty = new dependencyObservable.Property("selectedBackgroundColor", "SegmentedBar", new proxy.PropertyMetadata(undefined)) - public static selectedIndexProperty = new dependencyObservable.Property("selectedIndex", "SegmentedBar", new proxy.PropertyMetadata(0)) + public static selectedIndexProperty = new dependencyObservable.Property("selectedIndex", "SegmentedBar", new proxy.PropertyMetadata(undefined)) public static itemsProperty = new dependencyObservable.Property("items", "SegmentedBar", new proxy.PropertyMetadata(undefined)) } \ No newline at end of file diff --git a/ui/segmented-bar/segmented-bar.android.ts b/ui/segmented-bar/segmented-bar.android.ts index dcfe550d9..367e66211 100644 --- a/ui/segmented-bar/segmented-bar.android.ts +++ b/ui/segmented-bar/segmented-bar.android.ts @@ -1,4 +1,5 @@ -import common = require("ui/segmented-bar/segmented-bar-common"); +import definition = require("ui/segmented-bar"); +import common = require("ui/segmented-bar/segmented-bar-common"); import dependencyObservable = require("ui/core/dependency-observable"); import proxy = require("ui/core/proxy"); import types = require("utils/types"); @@ -15,8 +16,13 @@ function onSelectedIndexPropertyChanged(data: dependencyObservable.PropertyChang var index = data.newValue; - if (types.isNumber(index) && index >= 0 && index <= view.items.length - 1) { - view.android.setCurrentTab(index); + if (types.isNumber(index)) { + if (index >= 0 && index <= view.items.length - 1) { + view.android.setCurrentTab(index); + } else { + view.selectedIndex = undefined; + throw new Error("selectedIndex should be between [0, items.length - 1]"); + } } } (common.SegmentedBar.selectedIndexProperty.metadata).onSetNativeValue = onSelectedIndexPropertyChanged; @@ -29,7 +35,9 @@ function onItemsPropertyChanged(data: dependencyObservable.PropertyChangeData) { view.android.clearAllTabs(); - var newItems = >data.newValue; + var newItems = >data.newValue; + + view._adjustSelectedIndex(newItems); if (newItems && newItems.length) { for (var i = 0; i < newItems.length; i++) { @@ -49,8 +57,6 @@ function onItemsPropertyChanged(data: dependencyObservable.PropertyChangeData) { view.android.addTab(tab); } - view._adjustSelectedIndex(); - if (view.android.getCurrentTab() !== view.selectedIndex) { view.android.setCurrentTab(view.selectedIndex); } diff --git a/ui/segmented-bar/segmented-bar.ios.ts b/ui/segmented-bar/segmented-bar.ios.ts index 1996e7c3f..588decb02 100644 --- a/ui/segmented-bar/segmented-bar.ios.ts +++ b/ui/segmented-bar/segmented-bar.ios.ts @@ -1,4 +1,5 @@ -import common = require("ui/segmented-bar/segmented-bar-common"); +import definition = require("ui/segmented-bar"); +import common = require("ui/segmented-bar/segmented-bar-common"); import dependencyObservable = require("ui/core/dependency-observable"); import proxy = require("ui/core/proxy"); import types = require("utils/types"); @@ -15,8 +16,13 @@ function onSelectedIndexPropertyChanged(data: dependencyObservable.PropertyChang } var index = data.newValue; - if (types.isNumber(index) && index >= 0 && index <= view.items.length - 1) { - view.ios.selectedSegmentIndex = index; + if (types.isNumber(index)) { + if (index >= 0 && index <= view.items.length - 1) { + view.ios.selectedSegmentIndex = index; + } else { + view.selectedIndex = undefined; + throw new Error("selectedIndex should be between [0, items.length - 1]"); + } } } (common.SegmentedBar.selectedIndexProperty.metadata).onSetNativeValue = onSelectedIndexPropertyChanged; @@ -27,16 +33,22 @@ function onItemsPropertyChanged(data: dependencyObservable.PropertyChangeData) { return; } + var newItems = >data.newValue; + + console.log("SET ITEMS BEFORE: " + view.selectedIndex); + view._adjustSelectedIndex(newItems); + console.log("SET ITEMS AFTER: " + view.selectedIndex); + view.ios.removeAllSegments(); - for (var i = 0; i < view.items.length; i++) { - view.ios.insertSegmentWithTitleAtIndexAnimated(view.items[i].title, i, false); - } + if (newItems && newItems.length) { + for (var i = 0; i < newItems.length; i++) { + view.ios.insertSegmentWithTitleAtIndexAnimated(newItems[i].title, i, false); + } - view._adjustSelectedIndex(); - - if (view.ios.selectedSegmentIndex !== view.selectedIndex) { - view.ios.selectedSegmentIndex = view.selectedIndex; + if (view.ios.selectedSegmentIndex !== view.selectedIndex) { + view.ios.selectedSegmentIndex = view.selectedIndex; + } } } (common.SegmentedBar.itemsProperty.metadata).onSetNativeValue = onItemsPropertyChanged; @@ -60,6 +72,7 @@ export class SegmentedBar extends common.SegmentedBar { constructor() { super(); this._ios = UISegmentedControl.new(); + console.log("CREATE: " + this.selectedIndex); this._selectionHandler = SelectionHandlerImpl.new().initWithOwner(this); this._ios.addTargetActionForControlEvents(this._selectionHandler, "selected", UIControlEvents.UIControlEventValueChanged);