UNPKG

scriptable-testlab

Version:

A lightweight, efficient tool designed to manage and update scripts for Scriptable.

155 lines (131 loc) 4.51 kB
import {AbsDatePicker} from 'scriptable-abstract'; interface DatePickerState { minimumDate: Date | null; maximumDate: Date | null; countdownDuration: number; minuteInterval: number; initialDate: Date; } const DEFAULT_STATE: DatePickerState = { minimumDate: null, maximumDate: null, countdownDuration: 0, minuteInterval: 1, initialDate: new Date(), }; /** * Mock implementation of Scriptable's DatePicker. * Provides a user interface for selecting dates and times. * @implements DatePicker */ export class MockDatePicker extends AbsDatePicker<DatePickerState> { constructor() { super(DEFAULT_STATE); } private validateDateRange(date: Date): void { if (this.state.minimumDate && date.getTime() < this.state.minimumDate.getTime()) { throw new Error('Initial date cannot be earlier than minimum date'); } if (this.state.maximumDate && date.getTime() > this.state.maximumDate.getTime()) { throw new Error('Initial date cannot be later than maximum date'); } } private validateMinMaxDates(min: Date | null, max: Date | null): void { if (min && max && min.getTime() > max.getTime()) { throw new Error('Minimum date cannot be later than maximum date'); } } get minimumDate(): Date | null { return this.state.minimumDate ? new Date(this.state.minimumDate) : null; } set minimumDate(value: Date | null) { if (value) { const newMin = new Date(value); this.validateMinMaxDates(newMin, this.state.maximumDate); } this.setState({minimumDate: value ? new Date(value) : null}); } get maximumDate(): Date | null { return this.state.maximumDate ? new Date(this.state.maximumDate) : null; } set maximumDate(value: Date | null) { if (value) { const newMax = new Date(value); this.validateMinMaxDates(this.state.minimumDate, newMax); } this.setState({maximumDate: value ? new Date(value) : null}); } get countdownDuration(): number { return this.state.countdownDuration; } set countdownDuration(value: number) { const numValue = Number(value); if (isNaN(numValue) || numValue < 0) { throw new Error('Countdown duration must be a non-negative number'); } this.setState({countdownDuration: numValue}); } get minuteInterval(): number { return this.state.minuteInterval; } set minuteInterval(value: number) { const numValue = Number(value); if (isNaN(numValue) || numValue <= 0) { throw new Error('Minute interval must be a positive number'); } if (numValue > 30) { throw new Error('Minute interval must not exceed 30'); } if (60 % numValue !== 0) { throw new Error('Minute interval must be a factor of 60'); } this.setState({minuteInterval: numValue}); } get initialDate(): Date { return new Date(this.state.initialDate); } set initialDate(value: Date) { this.setState({initialDate: new Date(value)}); } /** * Presents the date picker to the user. * @returns A promise that resolves with the selected date. */ async pickDate(): Promise<Date> { this.validateDateRange(this.state.initialDate); return new Date(this.state.initialDate); } /** * Presents the time picker to the user. * @returns A promise that resolves with the selected date. */ async pickTime(): Promise<Date> { this.validateDateRange(this.state.initialDate); const date = new Date(this.state.initialDate); // Ensure minutes align with interval const minutes = date.getMinutes(); const intervalMinutes = Math.round(minutes / this.state.minuteInterval) * this.state.minuteInterval; date.setMinutes(intervalMinutes); return new Date(date); } /** * Presents the countdown duration picker to the user. * @returns A promise that resolves with the selected duration in seconds. */ async pickCountdownDuration(): Promise<number> { return this.state.countdownDuration; } /** * Presents the date picker displaying date and time. * @returns A promise that resolves with the selected date. */ async pickDateAndTime(): Promise<Date> { this.validateDateRange(this.state.initialDate); const date = new Date(this.state.initialDate); // Ensure minutes align with interval const minutes = date.getMinutes(); const intervalMinutes = Math.round(minutes / this.state.minuteInterval) * this.state.minuteInterval; date.setMinutes(intervalMinutes); return new Date(date); } }