Percent implements Comparable<Percent> { static double parse(String percent) { Objects.requireNonNull(percent, "Null 'percent' argument"); if (percent.length() == 0) { throw new IllegalArgumentException("Empty 'percent' argument"); } if (percent.charAt(percent.length() - 1) == '%') { percent = percent.substring(0, percent.length() - 1); } if (percent.length() == 0) { throw new IllegalArgumentException("Non-numeric 'percent' argument: '%'"); } return Double.parseDouble(percent); } Percent(String value);  Percent(int value);  Percent(double value); double getValue(); double getPercent(); @Override String toString(); String toString(int precision); @Override boolean equals(Object obj); @Override int hashCode(); @Override int compareTo(Percent o); static final Percent ZERO; static final Percent HUNDRED; }
@Test public void testParse_Null() { assertThrows(NullPointerException.class, () -> Percent.parse(null)); }
@Test public void testParse_Empty() { assertThrows(IllegalArgumentException.class, () -> Percent.parse("")); }
@Test public void testParse_NotANumber() { assertThrows(NumberFormatException.class, () -> Percent.parse("abc%")); }
@Test public void testParse() { assertEquals(4., Percent.parse("4"), 0.0001); assertEquals(4., Percent.parse("4."), 0.0001); assertEquals(4., Percent.parse("4%"), 0.0001); assertEquals(4., Percent.parse("4.0%"), 0.0001); }
@Test public void testParse_Negative() { assertEquals(-4., Percent.parse("-4"), 0.0001); assertEquals(-4., Percent.parse("-4%"), 0.0001); }
@Test public void testParse_Zero() { assertEquals(0., Percent.parse("0"), 0.0001); assertEquals(0., Percent.parse("0.0%"), 0.0001); assertEquals(0., Percent.parse("-0.%"), 0.0001); }
@Test public void testParse_Hundred() { assertEquals(100., Percent.parse("100"), 0.0001); assertEquals(100., Percent.parse("100.0%"), 0.0001); }
@Test public void testParse_Large() { assertEquals(10001.0005, Percent.parse("10001.0005"), 0.000000001); }