### Question:
TextValue extends ScalarValue { public abstract TextValue substring( int start, int length ); TextValue(); abstract String stringValue(); abstract int length(); abstract TextValue substring( int start, int length ); TextValue substring( int start ); abstract TextValue trim(); abstract TextValue ltrim(); abstract TextValue rtrim(); abstract TextValue toLower(); abstract TextValue toUpper(); abstract ListValue split( String separator ); abstract TextValue replace( String find, String replace ); abstract TextValue reverse(); abstract TextValue plus( TextValue other ); abstract boolean startsWith( TextValue other ); abstract boolean endsWith( TextValue other ); abstract boolean contains( TextValue other ); abstract int compareTo( TextValue other ); @Override final boolean equals( boolean x ); @Override final boolean equals( long x ); @Override final boolean equals( double x ); @Override ValueGroup valueGroup(); @Override NumberType numberType(); @Override T map( ValueMapper<T> mapper );  }### Answer:
@Test public void substring() { assertThat( value.apply( "hello" ).substring( 2, 5 ), equalTo( value.apply( "llo" ) ) ); assertThat( value.apply( "hello" ).substring( 4, 5 ), equalTo( value.apply( "o" ) ) ); assertThat( value.apply( "hello" ).substring( 1, 3 ), equalTo( value.apply( "ell" ) ) ); assertThat( value.apply( "hello" ).substring( 8, 5 ), equalTo( StringValue.EMPTY ) ); assertThat( value.apply( "0123456789" ).substring( 1 ), equalTo( value.apply( "123456789" ) ) ); assertThat( value.apply( "0123456789" ).substring( 5 ), equalTo( value.apply( "56789" ) ) ); assertThat( value.apply( "0123456789" ).substring( 15 ), equalTo( StringValue.EMPTY ) ); assertThat( value.apply( "\uD83D\uDE21\uD83D\uDCA9\uD83D\uDC7B" ).substring( 1, 1 ), equalTo( value.apply( "\uD83D\uDCA9" ) ) ); assertThat( value.apply( "\uD83D\uDE21\uD83D\uDCA9\uD83D\uDC7B" ).substring( 1, 2 ), equalTo( value.apply( "\uD83D\uDCA9\uD83D\uDC7B" ) ) ); exception.expect( IndexOutOfBoundsException.class ); value.apply( "hello" ).substring( -4, 2 ); }