TimeSpan { static TimeSpan valueOf(final String value) { if (value.isEmpty()) { return new TimeSpan(0, TimeUnit.NANOSECONDS); } final Matcher matcher = PATTERN.matcher(value); if (!matcher.matches()) { throw new IllegalArgumentException("'" + value + "' is not a valid time span"); } final long amount = Long.parseLong(matcher.group(1)); final TimeUnit unit = fromName(matcher.group(2)); return new TimeSpan(amount, unit); } @SuppressWarnings("unused")  TimeSpan(final String value); private  TimeSpan(final TimeSpan span); @Override String toString();  }
@Test void shouldParseEmpty() { final TimeSpan span = TimeSpan.valueOf(""); assertThat(span.getAmount(), is(0L)); }
@Test void shouldFailOnUnsupportedTimeSpanFormat() { assertThrows(IllegalArgumentException.class, () -> TimeSpan.valueOf("forever")); }
@Test void shouldFailOnUnknownTimeUnit() { assertThrows(IllegalArgumentException.class, () -> TimeSpan.valueOf("1 decade")); }
@Test void shouldRenderToString() { assertThat(TimeSpan.valueOf("17 seconds"), hasToString("17 seconds")); }