Skip to content

Commit 14d016c

Browse files
authored
Use clock package to allow for easier testing #47
This PR allows the Time package to use the official [clock](https://pub.dev/packages/clock) package published by the Dart tools team. By using `clock.now()` instead of `DateTime.now()`, code which is time-dependent can be easily tested using the clock package's `withClock` test utility function. Here's [a lovely article](https://iiro.dev/controlling-time-with-package-clock/) about using the clock package to test time-dependent code. This also makes the unit tests here a little bit cleaner. If you have any feedback, let me know! Thank you for making this package.
2 parents ced5e28 + fdd0050 commit 14d016c

File tree

3 files changed

+42
-30
lines changed

3 files changed

+42
-30
lines changed

lib/src/extensions.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'package:clock/clock.dart';
2+
13
extension NumTimeExtension<T extends num> on T {
24
/// Returns a Duration represented in weeks
35
Duration get weeks => days * DurationTimeExtension.daysPerWeek;
@@ -136,7 +138,7 @@ extension DateTimeTimeExtension on DateTime {
136138
bool isAtSameMicrosecondAs(DateTime other) => isAtSameMillisecondAs(other) && microsecond == other.microsecond;
137139

138140
static int _calculateDifference(DateTime date) {
139-
final now = DateTime.now();
141+
final now = clock.now();
140142
return DateTime(date.year, date.month, date.day).difference(DateTime(now.year, now.month, now.day)).inDays;
141143
}
142144

@@ -212,10 +214,10 @@ extension DurationTimeExtension on Duration {
212214
int get inWeeks => (inDays / daysPerWeek).ceil();
213215

214216
/// Adds the Duration to the current DateTime and returns a DateTime in the future
215-
DateTime get fromNow => DateTime.now() + this;
217+
DateTime get fromNow => clock.now() + this;
216218

217219
/// Subtracts the Duration from the current DateTime and returns a DateTime in the past
218-
DateTime get ago => DateTime.now() - this;
220+
DateTime get ago => clock.now() - this;
219221

220222
/// Returns a Future.delayed from this
221223
Future<void> get delay => Future.delayed(this);

pubspec.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ homepage: https://github.com/jogboms/time.dart
66
environment:
77
sdk: ">=2.12.0 <3.0.0"
88

9+
dependencies:
10+
clock: ^1.1.0
11+
912
dev_dependencies:
1013
pedantic: ^1.11.0
1114
test: ^1.16.5

test/time_test.dart

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
import 'package:clock/clock.dart';
12
import 'package:test/test.dart';
23
import 'package:time/time.dart';
34

45
void main() {
6+
final date = DateTime(2000, 1, 1);
7+
58
group('TimeExtension', () {
69
group('Integers', () {
710
test('can be converted into weeks', () {
@@ -103,30 +106,36 @@ void main() {
103106
});
104107

105108
test('can handle isToday', () {
106-
final today = DateTime.now();
107-
final yesterday = DateTime.now().subtract(Duration(days: 1));
108-
final tomorrow = DateTime.now().add(Duration(days: 1));
109-
expect(today.isToday, true);
110-
expect(yesterday.isToday, false);
111-
expect(tomorrow.isToday, false);
109+
final today = date;
110+
withClock(Clock.fixed(today), () {
111+
final yesterday = today.subtract(Duration(days: 1));
112+
final tomorrow = today.add(Duration(days: 1));
113+
expect(today.isToday, true);
114+
expect(yesterday.isToday, false);
115+
expect(tomorrow.isToday, false);
116+
});
112117
});
113118

114119
test('can handle isTomorrow', () {
115-
final today = DateTime.now();
116-
final yesterday = DateTime.now().subtract(Duration(days: 1));
117-
final tomorrow = DateTime.now().add(Duration(days: 1));
118-
expect(today.isTomorrow, false);
119-
expect(yesterday.isTomorrow, false);
120-
expect(tomorrow.isTomorrow, true);
120+
final today = date;
121+
withClock(Clock.fixed(today), () {
122+
final yesterday = today.subtract(Duration(days: 1));
123+
final tomorrow = today.add(Duration(days: 1));
124+
expect(today.isTomorrow, false);
125+
expect(yesterday.isTomorrow, false);
126+
expect(tomorrow.isTomorrow, true);
127+
});
121128
});
122129

123130
test('can handle wasYesterday', () {
124-
final today = DateTime.now();
125-
final yesterday = DateTime.now().subtract(Duration(days: 1));
126-
final tomorrow = DateTime.now().add(Duration(days: 1));
127-
expect(today.wasYesterday, false);
128-
expect(yesterday.wasYesterday, true);
129-
expect(tomorrow.wasYesterday, false);
131+
final today = date;
132+
withClock(Clock.fixed(today), () {
133+
final yesterday = today.subtract(Duration(days: 1));
134+
final tomorrow = today.add(Duration(days: 1));
135+
expect(today.wasYesterday, false);
136+
expect(yesterday.wasYesterday, true);
137+
expect(tomorrow.wasYesterday, false);
138+
});
130139
});
131140

132141
test('can handle isLeapYear', () {
@@ -535,11 +544,15 @@ void main() {
535544
});
536545

537546
test('can be converted into a future DateTime', () {
538-
expect(7.days.fromNow, _isAbout(DateTime.now() + 7.days));
547+
withClock(Clock.fixed(date), () {
548+
expect(7.days.fromNow, date + 7.days);
549+
});
539550
});
540551

541552
test('can be converted into a previous DateTime', () {
542-
expect(7.days.ago, _isAbout(DateTime.now() - 7.days));
553+
withClock(Clock.fixed(date), () {
554+
expect(7.days.ago, date - 7.days);
555+
});
543556
});
544557

545558
test('Can be used to pause the program flow', () async {
@@ -551,10 +564,4 @@ void main() {
551564
expect(extraTime >= 0, true);
552565
});
553566
});
554-
}
555-
556-
// Checks if the two times returned a *just* about equal. Since `fromNow` and
557-
// `ago` use DateTime.now(), we can't create an expected condition that is
558-
// exactly equal.
559-
Matcher _isAbout(DateTime expected) =>
560-
predicate<DateTime>((dateTime) => dateTime.millisecondsSinceEpoch - expected.millisecondsSinceEpoch < 1);
567+
}

0 commit comments

Comments
 (0)