import {TestBed} from '@angular/core/testing'; import { DateAdapter, MAT_DATE_FORMATS, MatDateFormats, provideNativeDateAdapter, } from '@angular/material/core'; import {generateOptions, parseInterval} from './util'; describe('timepicker utilities', () => { describe('parseInterval', () => { it('should parse null', () => { expect(parseInterval(null)).toBe(null); }); it('should parse a number', () => { expect(parseInterval(75)).toBe(75); }); it('should parse a number in a string', () => { expect(parseInterval('75')).toBe(75); expect(parseInterval('75.50')).toBe(75.5); }); it('should handle invalid strings', () => { expect(parseInterval('')).toBe(null); expect(parseInterval(' ')).toBe(null); expect(parseInterval('abc')).toBe(null); expect(parseInterval('1a')).toBe(null); expect(parseInterval('m1')).toBe(null); expect(parseInterval('10.')).toBe(null); }); it('should parse hours', () => { expect(parseInterval('3h')).toBe(10_800); expect(parseInterval('4.5h')).toBe(16_200); expect(parseInterval('11h')).toBe(39_600); }); it('should parse minutes', () => { expect(parseInterval('3m')).toBe(180); expect(parseInterval('7.5m')).toBe(450); expect(parseInterval('90m')).toBe(5_400); expect(parseInterval('100.5m')).toBe(6_030); }); it('should parse seconds', () => { expect(parseInterval('3s')).toBe(3); expect(parseInterval('7.5s')).toBe(7.5); expect(parseInterval('90s')).toBe(90); expect(parseInterval('100.5s')).toBe(100.5); }); it('should parse uppercase units', () => { expect(parseInterval('3H')).toBe(10_800); expect(parseInterval('3M')).toBe(180); expect(parseInterval('3S')).toBe(3); }); it('should parse interval with space', () => { expect(parseInterval('3 h')).toBe(10_800); expect(parseInterval('6 h')).toBe(21_600); }); it('should handle long versions of units', () => { expect(parseInterval('1 hour')).toBe(3600); expect(parseInterval('3 hours')).toBe(10_800); expect(parseInterval('1 minute')).toBe(60); expect(parseInterval('3 min')).toBe(180); expect(parseInterval('3 minutes')).toBe(180); expect(parseInterval('1 second')).toBe(1); expect(parseInterval('10 seconds')).toBe(10); }); }); describe('generateOptions', () => { let adapter: DateAdapter; let formats: MatDateFormats; beforeEach(() => { TestBed.configureTestingModule({providers: [provideNativeDateAdapter()]}); adapter = TestBed.inject(DateAdapter); formats = TestBed.inject(MAT_DATE_FORMATS); adapter.setLocale('en-US'); }); it('should generate a list of options', () => { const min = new Date(2024, 0, 1, 9, 0, 0, 0); const max = new Date(2024, 0, 1, 22, 0, 0, 0); const options = generateOptions(adapter, formats, min, max, 3600).map(o => o.label); expect(options).toEqual([ '9:00 AM', '10:00 AM', '11:00 AM', '12:00 PM', '1:00 PM', '2:00 PM', '3:00 PM', '4:00 PM', '5:00 PM', '6:00 PM', '7:00 PM', '8:00 PM', '9:00 PM', '10:00 PM', ]); }); it('should generate a list of options with a sub-hour interval', () => { const min = new Date(2024, 0, 1, 9, 0, 0, 0); const max = new Date(2024, 0, 1, 22, 0, 0, 0); const options = generateOptions(adapter, formats, min, max, 43 * 60).map(o => o.label); expect(options).toEqual([ '9:00 AM', '9:43 AM', '10:26 AM', '11:09 AM', '11:52 AM', '12:35 PM', '1:18 PM', '2:01 PM', '2:44 PM', '3:27 PM', '4:10 PM', '4:53 PM', '5:36 PM', '6:19 PM', '7:02 PM', '7:45 PM', '8:28 PM', '9:11 PM', '9:54 PM', ]); }); it('should generate a list of options with a minute interval', () => { const min = new Date(2024, 0, 1, 9, 0, 0, 0); const max = new Date(2024, 0, 1, 9, 16, 0, 0); const options = generateOptions(adapter, formats, min, max, 60).map(o => o.label); expect(options).toEqual([ '9:00 AM', '9:01 AM', '9:02 AM', '9:03 AM', '9:04 AM', '9:05 AM', '9:06 AM', '9:07 AM', '9:08 AM', '9:09 AM', '9:10 AM', '9:11 AM', '9:12 AM', '9:13 AM', '9:14 AM', '9:15 AM', '9:16 AM', ]); }); it('should generate a list of options with a sub-minute interval', () => { const previousFormat = formats.display.timeOptionLabel; formats.display.timeOptionLabel = {hour: 'numeric', minute: 'numeric', second: 'numeric'}; const min = new Date(2024, 0, 1, 9, 0, 0, 0); const max = new Date(2024, 0, 1, 9, 3, 0, 0); const options = generateOptions(adapter, formats, min, max, 12).map(o => o.label); expect(options).toEqual([ '9:00:00 AM', '9:00:12 AM', '9:00:24 AM', '9:00:36 AM', '9:00:48 AM', '9:01:00 AM', '9:01:12 AM', '9:01:24 AM', '9:01:36 AM', '9:01:48 AM', '9:02:00 AM', '9:02:12 AM', '9:02:24 AM', '9:02:36 AM', '9:02:48 AM', '9:03:00 AM', ]); formats.display.timeOptionLabel = previousFormat; }); it('should generate at least one option if the interval is too large', () => { const min = new Date(2024, 0, 1, 0, 0, 0, 0); const max = new Date(2024, 0, 1, 23, 59, 0, 0); const options = generateOptions(adapter, formats, min, max, 60 * 60 * 24).map(o => o.label); expect(options).toEqual(['12:00 AM']); }); it('should generate at least one option if the max is later than the min', () => { const min = new Date(2024, 0, 1, 23, 0, 0, 0); const max = new Date(2024, 0, 1, 13, 0, 0, 0); const options = generateOptions(adapter, formats, min, max, 3600).map(o => o.label); expect(options).toEqual(['1:00 PM']); }); }); });