From 2933e895e52117bf55b17023767dd6cebf500d86 Mon Sep 17 00:00:00 2001 From: Andrew Chen Date: Fri, 19 Jun 2020 12:18:03 -0700 Subject: [PATCH] Implement Comparable (#59317) --- packages/flutter/lib/src/material/time.dart | 24 +++++-- packages/flutter/test/material/time_test.dart | 65 +++++++++++++++++++ 2 files changed, 83 insertions(+), 6 deletions(-) diff --git a/packages/flutter/lib/src/material/time.dart b/packages/flutter/lib/src/material/time.dart index 33e85b94b16..f496d38bbb9 100644 --- a/packages/flutter/lib/src/material/time.dart +++ b/packages/flutter/lib/src/material/time.dart @@ -48,20 +48,21 @@ enum DayPeriod { /// * [DateTime], which represents date and time, and is subject to eras and /// time zones. @immutable -class TimeOfDay { +class TimeOfDay implements Comparable { /// Creates a time of day. /// /// The [hour] argument must be between 0 and 23, inclusive. The [minute] /// argument must be between 0 and 59, inclusive. - const TimeOfDay({ @required this.hour, @required this.minute }); + const TimeOfDay({ @required this.hour, @required this.minute }) + : assert(hour != null && hour >= 0 && hour < hoursPerDay), + assert(minute != null && minute >= 0 && minute < minutesPerHour); /// Creates a time of day based on the given time. /// /// The [hour] is set to the time's hour and the [minute] is set to the time's /// minute in the timezone of the given [DateTime]. TimeOfDay.fromDateTime(DateTime time) - : hour = time.hour, - minute = time.minute; + : this(hour: time.hour, minute: time.minute); /// Creates a time of day based on the current time. /// @@ -80,8 +81,6 @@ class TimeOfDay { /// Returns a new TimeOfDay with the hour and/or minute replaced. TimeOfDay replacing({ int hour, int minute }) { - assert(hour == null || (hour >= 0 && hour < hoursPerDay)); - assert(minute == null || (minute >= 0 && minute < minutesPerHour)); return TimeOfDay(hour: hour ?? this.hour, minute: minute ?? this.minute); } @@ -136,6 +135,19 @@ class TimeOfDay { return '$TimeOfDay($hourLabel:$minuteLabel)'; } + + static int _inMinutesOf(TimeOfDay time) => minutesPerHour * time.hour + time.minute; + + @override + int compareTo(TimeOfDay other) { + if (other == null) { + return 1; + } + if (other == this) { + return 0; + } + return _inMinutesOf(this).compareTo(_inMinutesOf(other)); + } } /// Determines how the time picker invoked using [showTimePicker] formats and diff --git a/packages/flutter/test/material/time_test.dart b/packages/flutter/test/material/time_test.dart index 9e74ec5186d..c4fede04591 100644 --- a/packages/flutter/test/material/time_test.dart +++ b/packages/flutter/test/material/time_test.dart @@ -28,4 +28,69 @@ void main() { expect(await pumpTest(true), '07:00'); }); }); + + group('TimeOfDay', () { + test('assertions', () { + expect(() => TimeOfDay(hour: null, minute: null), throwsAssertionError); + expect(() => TimeOfDay(hour: null, minute: 0), throwsAssertionError); + expect(() => TimeOfDay(hour: 0, minute: null), throwsAssertionError); + expect(() => TimeOfDay(hour: -1, minute: -1), throwsAssertionError); + expect(() => TimeOfDay(hour: 0, minute: -1), throwsAssertionError); + expect(() => TimeOfDay(hour: -1, minute: 0), throwsAssertionError); + expect(() => TimeOfDay(hour: 24, minute: 0), throwsAssertionError); + expect(() => TimeOfDay(hour: 0, minute: 60), throwsAssertionError); + }); + + test('.==', () { + expect(const TimeOfDay(hour: 0 , minute: 0) + == (const TimeOfDay(hour: 0 , minute: 0)), true); + }); + + test('.replacing', () { + expect( + const TimeOfDay(hour: 23 , minute: 59).replacing(hour: 0), + const TimeOfDay(hour: 0 , minute: 59), + ); + expect( + const TimeOfDay(hour: 23 , minute: 59).replacing(minute: 0), + const TimeOfDay(hour: 23 , minute: 0), + ); + }); + + test('.compareTo', () { + expect( + [ + const TimeOfDay(hour: 12 , minute: 0), + const TimeOfDay(hour: 23 , minute: 59), + const TimeOfDay(hour: 0 , minute: 0), + ]..sort(), + [ + const TimeOfDay(hour: 0 , minute: 0), + const TimeOfDay(hour: 12 , minute: 0), + const TimeOfDay(hour: 23 , minute: 59), + ] + ); + + expect(const TimeOfDay(hour: 0 , minute: 0).compareTo(null) > 0, true); + + const TimeOfDay zero = TimeOfDay(hour: 0 , minute: 0); + expect(zero.compareTo(zero), 0); + + expect(const TimeOfDay(hour: 0 , minute: 0) + .compareTo(const TimeOfDay(hour: 0 , minute: 0)), 0); + + expect( + [ + const TimeOfDay(hour: 0 , minute: 0), + const TimeOfDay(hour: 23 , minute: 59), + const TimeOfDay(hour: 12 , minute: 0), + ]..sort(), + [ + const TimeOfDay(hour: 0 , minute: 0), + const TimeOfDay(hour: 12 , minute: 0), + const TimeOfDay(hour: 23 , minute: 59), + ] + ); + }); + }); }