1 /*
2  * Copyright (c) 2017 Mockito contributors
3  * This program is made available under the terms of the MIT License.
4  */
5 package org.mockitoutil;
6 
7 import static java.lang.String.format;
8 import static java.lang.System.nanoTime;
9 import static java.util.concurrent.TimeUnit.NANOSECONDS;
10 
11 import java.util.concurrent.TimeUnit;
12 import org.mockito.exceptions.base.MockitoAssertionError;
13 
14 /**
15  * This class can be uses as stopwatch to assert that a given time is elapsed or not.
16  */
17 public class Stopwatch {
18 
19     /**
20      * The start time in nano seconds or <code>null</code> if this stop watch was not started yet
21      */
22     private Long startNanos = null;
23 
24     /**
25      * To create an instance use {@link #createNotStarted()}
26      */
27     private Stopwatch() {
28     }
29 
30     /**
31      * Return a new and not started {@link Stopwatch}.
32      */
33     public static Stopwatch createNotStarted() {
34         return new Stopwatch();
35     }
36 
37     public void start() {
38         if (startNanos != null)
39             throw new IllegalStateException("This stop watch is already started!");
40 
41         startNanos = nanoTime();
42     }
43 
44     public void assertElapsedTimeIsMoreThan(long expected, TimeUnit unit) {
45         long elapsedNanos = elapsedNanos();
46         long expectedNanos = unit.toNanos(expected);
47 
48         if (elapsedNanos <= expectedNanos)
49             fail("Expected that more than %dms elapsed! But was: %dms", expectedNanos, elapsedNanos);
50     }
51 
52     public void assertElapsedTimeIsLessThan(long expected, TimeUnit unit) {
53         long elapsedNanos = elapsedNanos();
54         long expectedNanos = unit.toNanos(expected);
55 
56         if (elapsedNanos >= expectedNanos)
57             fail("Expected that less than %dms elapsed! But was: %dms", expectedNanos, elapsedNanos);
58     }
59 
60     private long elapsedNanos() {
61         if (startNanos == null)
62             throw new IllegalStateException("This stop watch is not started!");
63         return nanoTime() - startNanos;
64     }
65 
66     private static void fail(String message, long expectedNanos, long elapsedNanos) {
67         throw new MockitoAssertionError(format(message, NANOSECONDS.toMillis(expectedNanos), NANOSECONDS.toMillis(elapsedNanos)));
68     }
69 }
70