Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions src/main/java/org/apache/commons/lang3/time/StopWatch.java
Original file line number Diff line number Diff line change
Expand Up @@ -619,11 +619,14 @@ private long nanosToMillis(final long nanos) {
* <p>
* This method clears the internal values to allow the object to be reused.
* </p>
*
* @return this StopWatch.
*/
public void reset() {
public StopWatch reset() {
runningState = State.UNSTARTED;
splitState = SplitState.UNSPLIT;
splits.clear();
return this;
}

/**
Expand All @@ -633,14 +636,16 @@ public void reset() {
* This method resumes the watch after it was suspended. The watch will not include time between the suspend and resume calls in the total time.
* </p>
*
* @return this StopWatch.
* @throws IllegalStateException if this StopWatch has not been suspended.
*/
public void resume() {
public StopWatch resume() {
if (runningState != State.SUSPENDED) {
throw new IllegalStateException("Stopwatch must be suspended to resume.");
}
startTimeNanos += System.nanoTime() - stopTimeNanos;
runningState = State.RUNNING;
return this;
}

/**
Expand Down Expand Up @@ -683,15 +688,17 @@ public <E extends Throwable> void runT(final FailableRunnable<E> runnable) throw
* timing from the original start point.
* </p>
*
* @return this StopWatch.
* @throws IllegalStateException if this StopWatch is not running.
*/
public void split() {
public StopWatch split() {
if (runningState != State.RUNNING) {
throw new IllegalStateException("Stopwatch is not running.");
}
stopSet();
splitState = SplitState.SPLIT;
splits.add(new Split(String.valueOf(splits.size()), Duration.ofNanos(stopTimeNanos - startTimeNanos)));
return this;
}

/**
Expand All @@ -702,17 +709,19 @@ public void split() {
* timing from the original start point.
* </p>
*
* @return this StopWatch.
* @param label A message for string presentation.
* @throws IllegalStateException if the StopWatch is not running.
* @since 3.20.0
*/
public void split(final String label) {
public StopWatch split(final String label) {
if (runningState != State.RUNNING) {
throw new IllegalStateException("Stopwatch is not running.");
}
stopSet();
splitState = SplitState.SPLIT;
splits.add(new Split(label, Duration.ofNanos(stopTimeNanos - startTimeNanos)));
return this;
}

/**
Expand All @@ -722,9 +731,10 @@ public void split(final String label) {
* This method starts a new timing session, clearing any previous values.
* </p>
*
* @return this StopWatch.
* @throws IllegalStateException if this StopWatch is already running.
*/
public void start() {
public StopWatch start() {
if (runningState == State.STOPPED) {
throw new IllegalStateException("Stopwatch must be reset before being restarted.");
}
Expand All @@ -735,6 +745,7 @@ public void start() {
startInstant = Instant.now();
runningState = State.RUNNING;
splits.clear();
return this;
}

/**
Expand All @@ -755,18 +766,23 @@ private void startResume() {
* This method ends a new timing session, allowing the time to be retrieved.
* </p>
*
* @return this StopWatch.
* @throws IllegalStateException if this StopWatch is not running.
*/
public void stop() {
public StopWatch stop() {
if (runningState != State.RUNNING && runningState != State.SUSPENDED) {
throw new IllegalStateException("Stopwatch is not running.");
}
if (runningState == State.RUNNING) {
stopSet();
}
runningState = State.STOPPED;
return this;
}

/**
* Sets the stop time.
*/
private void stopSet() {
stopTimeNanos = System.nanoTime();
stopInstant = Instant.now();
Expand All @@ -779,14 +795,16 @@ private void stopSet() {
* This method suspends the watch until it is resumed. The watch will not include time between the suspend and resume calls in the total time.
* </p>
*
* @return this StopWatch.
* @throws IllegalStateException if this StopWatch is not currently running.
*/
public void suspend() {
public StopWatch suspend() {
if (runningState != State.RUNNING) {
throw new IllegalStateException("Stopwatch must be running to suspend.");
}
stopSet();
runningState = State.SUSPENDED;
return this;
}

/**
Expand Down Expand Up @@ -830,13 +848,15 @@ public String toString() {
* This method clears the stop time. The start time is unaffected, enabling timing from the original start point to continue.
* </p>
*
* @return this StopWatch.
* @throws IllegalStateException if this StopWatch has not been split.
*/
public void unsplit() {
public StopWatch unsplit() {
if (splitState != SplitState.SPLIT) {
throw new IllegalStateException("Stopwatch has not been split.");
}
splitState = SplitState.UNSPLIT;
splits.remove(splits.size() - 1);
return this;
}
}
24 changes: 23 additions & 1 deletion src/test/java/org/apache/commons/lang3/time/StopWatchTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,6 @@ void testToSplitStringWithMessage() throws InterruptedException {

@Test
void testToString() throws InterruptedException {
//
final StopWatch watch = StopWatch.createStarted();
sleepPlus1(MIN_DURATION);
watch.split();
Expand All @@ -574,6 +573,29 @@ void testToStringWithMessage() throws InterruptedException {
final String splitStr = watch.toString();
assertEquals(SPLIT_CLOCK_STR_LEN + MESSAGE.length() + 1, splitStr.length(), "Formatted split string not the correct length");
}

@Test
void testFluentPattern() {
final StopWatch watch = StopWatch.createStarted()
.split()
.stop();
assertTrue(watch.isStopped());
watch
.reset()
.start()
.split()
.suspend();
assertTrue(watch.isSuspended());
watch
.resume()
.split();
assertTrue(watch.isStarted());
assertTrue(watch
.split()
.stop()
.formatTime().startsWith(ZERO_HOURS_PREFIX));
assertTrue(watch.isStopped());
}

private int throwIOException() throws IOException {
throw new IOException("A");
Expand Down
Loading