Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 120 additions & 0 deletions apps/tests/ui/time-picker/time-picker-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,24 @@ export function test_WhenCreated_HourIsUndefined() {
});
}

export function test_WhenCreated_MinHourIs1() {
helper.buildUIAndRunTest(_createTimePicker(), function (views: Array<viewModule.View>) {
var timePicker = <timePickerModule.TimePicker>views[0];
var actualValue = timePicker.minHour;
var expectedValue = 1;
TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue);
});
}

export function test_WhenCreated_MaxHourIs23() {
helper.buildUIAndRunTest(_createTimePicker(), function (views: Array<viewModule.View>) {
var timePicker = <timePickerModule.TimePicker>views[0];
var actualValue = timePicker.maxHour;
var expectedValue = 23;
TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue);
});
}

export function test_WhenCreated_MinuteIsUndefined() {
helper.buildUIAndRunTest(_createTimePicker(), function (views: Array<viewModule.View>) {
var timePicker = <timePickerModule.TimePicker>views[0];
Expand All @@ -76,6 +94,108 @@ export function test_WhenCreated_MinuteIsUndefined() {
});
}

export function test_WhenCreated_MinMinuteIs0() {
helper.buildUIAndRunTest(_createTimePicker(), function (views: Array<viewModule.View>) {
var timePicker = <timePickerModule.TimePicker>views[0];
var actualValue = timePicker.minMinute;
var expectedValue = 0;
TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue);
});
}

export function test_WhenCreated_MaxMinuteIs59() {
helper.buildUIAndRunTest(_createTimePicker(), function (views: Array<viewModule.View>) {
var timePicker = <timePickerModule.TimePicker>views[0];
var actualValue = timePicker.maxMinute;
var expectedValue = 59;
TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue);
});
}

export function testHourThrowExceptionWhenLessThanMinHour() {
helper.buildUIAndRunTest(_createTimePicker(), function (views: Array<viewModule.View>) {
var timePicker = <timePickerModule.TimePicker>views[0];
timePicker.minHour = 13;
TKUnit.assertThrows(function () {
timePicker.hour = timePicker.minHour - 1;
}, "Setting hour property to a value less than minHour property value should throw.");
});
}

export function testHourThrowExceptionWhenGreaterThanMaxHour() {
helper.buildUIAndRunTest(_createTimePicker(), function (views: Array<viewModule.View>) {
var timePicker = <timePickerModule.TimePicker>views[0];
timePicker.maxHour = 13;
TKUnit.assertThrows(function () {
timePicker.hour = timePicker.maxHour + 1;;
}, "Setting hour property to a value greater than maxHour property value should throw.");
});
}

export function testMinuteThrowExceptionWhenLessThanMinMinute() {
helper.buildUIAndRunTest(_createTimePicker(), function (views: Array<viewModule.View>) {
var timePicker = <timePickerModule.TimePicker>views[0];
timePicker.minMinute = 13;
TKUnit.assertThrows(function () {
timePicker.minute = timePicker.minMinute - 1;
}, "Setting hour property to a value less than minHour property value should throw.");
});
}

export function testMinuteThrowExceptionWhenGreaterThanMaxMinute() {
helper.buildUIAndRunTest(_createTimePicker(), function (views: Array<viewModule.View>) {
var timePicker = <timePickerModule.TimePicker>views[0];
timePicker.maxMinute = 13;
TKUnit.assertThrows(function () {
timePicker.minute = timePicker.maxMinute + 1;;
}, "Setting hour property to a value greater than maxHour property value should throw.");
});
}

export function testHourFromNativeEqualToMinHourWhenLessThanMinHour() {
helper.buildUIAndRunTest(_createTimePicker(), function (views: Array<viewModule.View>) {
var timePicker = <timePickerModule.TimePicker>views[0];
var expectedValue = 13;
timePicker.minHour = expectedValue;
timePickerTestsNative.setNativeHour(timePicker, expectedValue - 1);
var actualValue = timePickerTestsNative.getNativeHour(timePicker);
TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue);
});
}

export function testHourFromNativeEqualToMaxHourWhenGreaterThanMaxHour() {
helper.buildUIAndRunTest(_createTimePicker(), function (views: Array<viewModule.View>) {
var timePicker = <timePickerModule.TimePicker>views[0];
var expectedValue = 13;
timePicker.maxHour = expectedValue;
timePickerTestsNative.setNativeHour(timePicker, expectedValue + 1);
var actualValue = timePickerTestsNative.getNativeHour(timePicker);
TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue);
});
}

export function testMinuteFromNativeEqualToMinMinuteWhenLessThanMinMinute() {
helper.buildUIAndRunTest(_createTimePicker(), function (views: Array<viewModule.View>) {
var timePicker = <timePickerModule.TimePicker>views[0];
var expectedValue = 13;
timePicker.minMinute = expectedValue;
timePickerTestsNative.setNativeMinute(timePicker, expectedValue - 1);
var actualValue = timePickerTestsNative.getNativeMinute(timePicker);
TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue);
});
}

export function testMinuteFromNativeEqualToMaxMinuteWhenGreaterThanMaxMinute() {
helper.buildUIAndRunTest(_createTimePicker(), function (views: Array<viewModule.View>) {
var timePicker = <timePickerModule.TimePicker>views[0];
var expectedValue = 13;
timePicker.maxMinute = expectedValue;
timePickerTestsNative.setNativeMinute(timePicker, expectedValue + 1);
var actualValue = timePickerTestsNative.getNativeMinute(timePicker);
TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue);
});
}

export function testHourFromLocalToNative() {
helper.buildUIAndRunTest(_createTimePicker(), function (views: Array<viewModule.View>) {
var timePicker = <timePickerModule.TimePicker>views[0];
Expand Down
84 changes: 82 additions & 2 deletions ui/time-picker/time-picker-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,62 @@
import dependencyObservable = require("ui/core/dependency-observable");
import proxy = require("ui/core/proxy");
import view = require("ui/core/view");
import types = require("utils/types");

function isHourValid(value: number): boolean {
return types.isNumber(value) && value >= 1 && value <= 23;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't 0 a valid hour - probably the check should be value >= 0

}

function isMinuteValid(value: number): boolean {
return types.isNumber(value) && value >= 0 && value <= 59;
}

export function getValidHour(hour: number, minHour: number, maxHour: number): number {
let hourValue = hour;

if (minHour && hour < minHour) {
hourValue = minHour
}

if (maxHour && hour > maxHour) {
hourValue = maxHour
}

return hourValue;
}

export function getValidMinute(minute: number, minMinute: number, maxMinute: number): number {
let minuteValue = minute;

if (minMinute && minute < minMinute) {
minuteValue = minMinute
}

if (maxMinute && minute > maxMinute) {
minuteValue = maxMinute
}

return minuteValue;
}

export class TimePicker extends view.View implements definition.TimePicker {
public static hourProperty = new dependencyObservable.Property("hour", "TimePicker", new proxy.PropertyMetadata(undefined));
public static minuteProperty = new dependencyObservable.Property("minute", "TimePicker", new proxy.PropertyMetadata(undefined));
public static hourProperty = new dependencyObservable.Property("hour", "TimePicker",
new proxy.PropertyMetadata(undefined, dependencyObservable.PropertyMetadataSettings.None, undefined, isHourValid));

public static minHourProperty = new dependencyObservable.Property("minHour", "TimePicker",
new proxy.PropertyMetadata(1, dependencyObservable.PropertyMetadataSettings.None, undefined, isHourValid));

public static maxHourProperty = new dependencyObservable.Property("maxHour", "TimePicker",
new proxy.PropertyMetadata(23, dependencyObservable.PropertyMetadataSettings.None, undefined, isHourValid));

public static minuteProperty = new dependencyObservable.Property("minute", "TimePicker",
new proxy.PropertyMetadata(undefined, dependencyObservable.PropertyMetadataSettings.None, undefined, isMinuteValid));

public static minMinuteProperty = new dependencyObservable.Property("minMinute", "TimePicker",
new proxy.PropertyMetadata(0, dependencyObservable.PropertyMetadataSettings.None, undefined, isMinuteValid));

public static maxMinuteProperty = new dependencyObservable.Property("maxMinute", "TimePicker",
new proxy.PropertyMetadata(59, dependencyObservable.PropertyMetadataSettings.None, undefined, isMinuteValid));

constructor() {
super();
Expand All @@ -24,4 +76,32 @@ export class TimePicker extends view.View implements definition.TimePicker {
set minute(value: number) {
this._setValue(TimePicker.minuteProperty, value);
}

get maxHour(): number {
return this._getValue(TimePicker.maxHourProperty);
}
set maxHour(value: number) {
this._setValue(TimePicker.maxHourProperty, value);
}

get maxMinute(): number {
return this._getValue(TimePicker.maxMinuteProperty);
}
set maxMinute(value: number) {
this._setValue(TimePicker.maxMinuteProperty, value);
}

get minHour(): number {
return this._getValue(TimePicker.minHourProperty);
}
set minHour(value: number) {
this._setValue(TimePicker.minHourProperty, value);
}

get minMinute(): number {
return this._getValue(TimePicker.minMinuteProperty);
}
set minMinute(value: number) {
this._setValue(TimePicker.minMinuteProperty, value);
}
}
88 changes: 51 additions & 37 deletions ui/time-picker/time-picker.android.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,41 @@
import dependencyObservable = require("ui/core/dependency-observable");
import proxy = require("ui/core/proxy");
import utils = require("utils/utils")
import types = require("utils/types")

function onHourPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var picker = <TimePicker>data.object;
picker._setNativeHourSilently(data.newValue);

var validValue = common.getValidHour(data.newValue, picker.minHour, picker.maxHour);
if (validValue === data.newValue) {
picker._setNativeValueSilently(data.newValue, picker.minute);
} else {
throw new Error(`Hour property value (${data.newValue}) is not valid. Min value: (${picker.minHour} ), max value: (${picker.maxHour} ).`);
}
}

(<proxy.PropertyMetadata>common.TimePicker.hourProperty.metadata).onSetNativeValue = onHourPropertyChanged;

function onMinutePropertyChanged(data: dependencyObservable.PropertyChangeData) {
var picker = <TimePicker>data.object;
picker._setNativeMinuteSilently(data.newValue);

var validValue = common.getValidMinute(data.newValue, picker.minMinute, picker.maxMinute);
if (validValue === data.newValue) {
picker._setNativeValueSilently(picker.hour, data.newValue);
} else {
throw new Error(`Minute property value (${data.newValue}) is not valid. Min value: (${picker.minMinute} ), max value: (${picker.maxMinute} ).`);
}
}

(<proxy.PropertyMetadata>common.TimePicker.minuteProperty.metadata).onSetNativeValue = onMinutePropertyChanged;

global.moduleMerge(common, exports);

var SDK = android.os.Build.VERSION.SDK_INT;

export class TimePicker extends common.TimePicker {
private _android: android.widget.TimePicker;
private _listener: android.widget.TimePicker.OnTimeChangedListener;
private _isSettingTime: boolean = false;

get android(): android.widget.TimePicker {
return this._android;
Expand All @@ -35,51 +49,51 @@ export class TimePicker extends common.TimePicker {

this._listener = new android.widget.TimePicker.OnTimeChangedListener(
<utils.Owned & android.widget.TimePicker.IOnTimeChangedListener>{
get owner() {
return that.get();
},
get owner() {
return that.get();
},

onTimeChanged: function (picker: android.widget.TimePicker, hour: number, minute: number) {
if (this.owner && !this.owner._isSettingTime) {
onTimeChanged: function (picker: android.widget.TimePicker, hour: number, minute: number) {
if (this.owner) {

if (hour !== this.owner.hour) {
this.owner._onPropertyChangedFromNative(common.TimePicker.hourProperty, hour);
}
this.owner._setNativeValueSilently(hour, minute);

if (hour !== this.owner.hour) {
this.owner._onPropertyChangedFromNative(common.TimePicker.hourProperty, hour);
}

if (minute !== this.owner.minute) {
this.owner._onPropertyChangedFromNative(common.TimePicker.minuteProperty, minute);
if (minute !== this.owner.minute) {
this.owner._onPropertyChangedFromNative(common.TimePicker.minuteProperty, minute);
}
}
}
}
});
});
this._android.setOnTimeChangedListener(this._listener);
}

public _setNativeHourSilently(newValue: number) {
if (!this.android) {
return;
}
public _setNativeValueSilently(hour: number, minute: number) {
if (this.android) {
this.android.setOnTimeChangedListener(null);

this._isSettingTime = true;
try {
this.android.setCurrentHour(new java.lang.Integer(newValue));
}
finally {
this._isSettingTime = false;
}
}
if (types.isNumber(hour)) {
var h = new java.lang.Integer(common.getValidHour(hour, this.minHour, this.maxHour));
if (SDK >= 23) {
(<any>this.android).setHour(h);
} else {
this.android.setCurrentHour(h);
}
}

public _setNativeMinuteSilently(newValue: number) {
if (!this.android) {
return;
}
if (types.isNumber(minute)) {
var m = new java.lang.Integer(common.getValidMinute(minute, this.minMinute, this.maxMinute));
if (SDK >= 23) {
(<any>this.android).setMinute(m);
} else {
this.android.setCurrentMinute(m);
}
}

this._isSettingTime = true;
try {
this.android.setCurrentMinute(new java.lang.Integer(newValue));
}
finally {
this._isSettingTime = false;
this.android.setOnTimeChangedListener(this._listener);
}
}
}
20 changes: 20 additions & 0 deletions ui/time-picker/time-picker.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,25 @@ declare module "ui/time-picker" {
* Gets or sets the time minute.
*/
minute: number;

/**
* Gets or sets the max time hour.
*/
maxHour: number;

/**
* Gets or sets the max time minute.
*/
maxMinute: number;

/**
* Gets or sets the min time hour.
*/
minHour: number;

/**
* Gets or sets the min time minute.
*/
minMinute: number;
}
}
Loading