| // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'package:meta/meta.dart'; |
| import 'package:test/test.dart'; |
| |
| /// Returns a [DateTime] with an exact second-precision by removing the |
| /// milliseconds and microseconds from the specified [time]. |
| /// |
| /// If [time] is not specified, it will default to the current time. |
| DateTime floor([DateTime time]) { |
| time ??= new DateTime.now(); |
| return time.subtract(new Duration( |
| milliseconds: time.millisecond, |
| microseconds: time.microsecond, |
| )); |
| } |
| |
| /// Returns a [DateTime] with an exact second precision by adding just enough |
| /// milliseconds and microseconds to the specified [time] to reach the next |
| /// second. |
| /// |
| /// If [time] is not specified, it will default to the current time. |
| DateTime ceil([DateTime time]) { |
| time ??= new DateTime.now(); |
| int microseconds = (1000 * time.millisecond) + time.microsecond; |
| return time.add(new Duration(microseconds: 1000000 - microseconds)); |
| } |
| |
| /// Successfully matches against a [DateTime] that is the same moment or before |
| /// the specified [time]. |
| Matcher isSameOrBefore(DateTime time) => new _IsSameOrBefore(time); |
| |
| /// Successfully matches against a [DateTime] that is the same moment or after |
| /// the specified [time]. |
| Matcher isSameOrAfter(DateTime time) => new _IsSameOrAfter(time); |
| |
| /// Successfully matches against a [DateTime] that is after the specified |
| /// [time]. |
| Matcher isAfter(DateTime time) => new _IsAfter(time); |
| |
| abstract class _CompareDateTime extends Matcher { |
| final DateTime _time; |
| final Matcher _matcher; |
| |
| const _CompareDateTime(this._time, this._matcher); |
| |
| @override |
| bool matches(dynamic item, Map<dynamic, dynamic> matchState) { |
| return item is DateTime && |
| _matcher.matches(item.compareTo(_time), <dynamic, dynamic>{}); |
| } |
| |
| @protected |
| String get descriptionOperator; |
| |
| @override |
| Description describe(Description description) => |
| description.add('a DateTime $descriptionOperator $_time'); |
| |
| @protected |
| String get mismatchAdjective; |
| |
| @override |
| Description describeMismatch( |
| dynamic item, |
| Description description, |
| Map<dynamic, dynamic> matchState, |
| bool verbose, |
| ) { |
| if (item is DateTime) { |
| Duration diff = item.difference(_time).abs(); |
| return description.add('is $mismatchAdjective $_time by $diff'); |
| } else { |
| return description.add('is not a DateTime'); |
| } |
| } |
| } |
| |
| class _IsSameOrBefore extends _CompareDateTime { |
| const _IsSameOrBefore(DateTime time) : super(time, isNonPositive); |
| |
| @override |
| String get descriptionOperator => '<='; |
| |
| @override |
| String get mismatchAdjective => 'after'; |
| } |
| |
| class _IsSameOrAfter extends _CompareDateTime { |
| const _IsSameOrAfter(DateTime time) : super(time, isNonNegative); |
| |
| @override |
| String get descriptionOperator => '>='; |
| |
| @override |
| String get mismatchAdjective => 'before'; |
| } |
| |
| class _IsAfter extends _CompareDateTime { |
| const _IsAfter(DateTime time) : super(time, isPositive); |
| |
| @override |
| String get descriptionOperator => '>'; |
| |
| @override |
| String get mismatchAdjective => 'before'; |
| } |