### Question:
Line extends AUnboundedLine implements ILine { @Override public IVector2 closestPointOnLine(final IVector2 point) { if (!isValid()) { return supportVector(); } return LineMath.closestPointOnLine(this, point); } private  Line(final IVector2 supportVector, final IVector2 directionVector); static ILine fromPoints(final IVector2 supportPointA, final IVector2 supportPointB); static ILine fromDirection(final IVector2 supportVector, final IVector2 directionVector); @Override ILine copy(); @Override final boolean equals(final Object other); @Override final int hashCode(); @Override Optional<Double> getYIntercept(); @Override Optional<Double> getXValue(final double y); @Override Optional<Double> getYValue(final double x); @Override ILine getOrthogonalLine(); @Override IVector2 closestPointOnLine(final IVector2 point); @Override ILine toLine(); @Override Optional<IVector2> intersectLine(final ILine other); @Override Optional<IVector2> intersectHalfLine(final IHalfLine halfLine); @Override Optional<IVector2> intersectSegment(final ILineSegment segment); @Override String toString();  }### Answer:
@Test public void testClosestPointOnLine() { IVector2 sV = Vector2.fromXY(0, 1); IVector2 dV = Vector2.fromXY(1, 1); ILine line = Line.fromDirection(sV, dV); ILine invalidLine = Line.fromDirection(sV, Vector2f.ZERO_VECTOR); IVector2 curPoint = Vector2.fromXY(0, 0); IVector2 step = Vector2.fromXY(0.1d, 0.1d); for (int i = 0; i <= 100; i++) { curPoint = curPoint.addNew(step); IVector2 leadPoint = line.closestPointOnLine(curPoint); IVector2 leadPointForInvalidLine = invalidLine.closestPointOnLine(curPoint); IVector2 curPointToLead = leadPoint.subtractNew(curPoint); assertThat(curPointToLead.isParallelTo(dV.getNormalVector()), is(true)); assertThat(curPointToLead.getLength(), closeTo(Math.sqrt(2) / 2, ACCURACY)); assertThat(leadPointForInvalidLine, is(sV)); } }