Skip to content

Commit

Permalink
Move default implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusmelke committed Nov 8, 2017
1 parent cb702e4 commit 269f35d
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 37 deletions.
Expand Up @@ -92,13 +92,6 @@ public TextValue replace( String find, String replace )
return Values.stringValue( value().replace( find, replace ) );
}

@Override
public TextValue reverse()
{
StringBuilder stringBuilder = new StringBuilder( value() );
return Values.stringValue( stringBuilder.reverse().toString() );
}

@Override
public Object asObjectCopy()
{
Expand Down Expand Up @@ -184,6 +177,37 @@ public TextValue rtrim()
return this;
}

@Override
public TextValue reverse()
{
return this;
}

@Override
public TextValue toLower()
{
return this;
}

@Override
public TextValue toUpper()
{
return this;
}

@Override
public TextValue replace( String find, String replace )
{
if ( find.isEmpty() )
{
return Values.stringValue( replace );
}
else
{
return this;
}
}

@Override
public int compareTo( TextValue other )
{
Expand Down
Expand Up @@ -95,6 +95,13 @@ public TextValue rtrim()
return Values.stringValue( value.substring( 0, end ) );
}

@Override
public TextValue reverse()
{
StringBuilder stringBuilder = new StringBuilder( value() );
return Values.stringValue( stringBuilder.reverse().toString() );
}

private int ltrimIndex( String value )
{
int start = 0, length = value.length();
Expand Down
Expand Up @@ -284,16 +284,16 @@ public TextValue reverse()

int i = offset, len = offset + byteLength;
byte[] newValues = new byte[byteLength];
int newIndex = byteLength -1;
while ( i < len )
{
byte b = values[i];
//If high bit is zero (equivalent to the byte being positive in two's complement)
//we are dealing with an ascii value and use a single byte for storing the value.
if ( b >= 0 )
{
newValues[newIndex] = b;
newIndex--;
//a single byte is trivial to reverse
//just put it at the opposite end of the new array
newValues[len - 1 - i] = b;
i++;
continue;
}
Expand All @@ -310,9 +310,11 @@ public TextValue reverse()
bytesNeeded++;
b = (byte) (b << 1);
}
System.arraycopy( values, i, newValues, newIndex - bytesNeeded + 1, bytesNeeded );
//reversing when multiple bytes are needed for the code point we cannot just reverse
//since we need to preserve the code point while moving it,
//e.g. [A, b1,b2, B] -> [B, b1,b2, A]
System.arraycopy( values, i, newValues, len - i - bytesNeeded, bytesNeeded );
i += bytesNeeded;
newIndex -= bytesNeeded;
}

return new UTF8StringValue( newValues, 0, newValues.length );
Expand Down
Expand Up @@ -56,6 +56,8 @@ public void replace()
assertThat( value.apply( "hello" ).replace( "l", "w" ), equalTo( value.apply( "hewwo" ) ) );
assertThat( value.apply( "hello" ).replace( "ell", "ipp" ), equalTo( value.apply( "hippo" ) ) );
assertThat( value.apply( "hello" ).replace( "a", "x" ), equalTo( value.apply( "hello" ) ) );
assertThat( value.apply( "hello" ).replace( "e", "" ), equalTo( value.apply( "hllo" ) ) );
assertThat( value.apply( "" ).replace( "", "⁻" ), equalTo( value.apply( "⁻" ) ) );
}

@Test
Expand All @@ -68,10 +70,10 @@ public void substring()
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.EMTPY ) );
assertThat( value.apply( "\uD83D\uDE21\uD83D\uDE21\uD83D\uDE21" ).substring( 1, 1 ),
equalTo( value.apply( "\uD83D\uDE21" ) ) );
assertThat( value.apply( "\uD83D\uDE21\uD83D\uDE21\uD83D\uDE21" ).substring( 1, 2 ),
equalTo( value.apply( "\uD83D\uDE21\uD83D\uDE21" ) ) );
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 );
Expand All @@ -83,6 +85,7 @@ public void toLower()
assertThat( value.apply( "HELLO" ).toLower(), equalTo( value.apply( "hello" ) ) );
assertThat( value.apply( "Hello" ).toLower(), equalTo( value.apply( "hello" ) ) );
assertThat( value.apply( "hello" ).toLower(), equalTo( value.apply( "hello" ) ) );
assertThat( value.apply( "" ).toLower(), equalTo( value.apply( "" ) ) );
}

@Test
Expand All @@ -91,6 +94,7 @@ public void toUpper()
assertThat( value.apply( "HELLO" ).toUpper(), equalTo( value.apply( "HELLO" ) ) );
assertThat( value.apply( "Hello" ).toUpper(), equalTo( value.apply( "HELLO" ) ) );
assertThat( value.apply( "hello" ).toUpper(), equalTo( value.apply( "HELLO" ) ) );
assertThat( value.apply( "" ).toUpper(), equalTo( value.apply( "" ) ) );
}

@Test
Expand Down Expand Up @@ -124,11 +128,15 @@ public void trim()
@Test
public void reverse()
{
// assertThat( value.apply( "Foo" ).reverse(), equalTo( value.apply( "ooF" ) ) );
// assertThat( value.apply( "" ).reverse(), equalTo( StringValue.EMTPY ) );
// assertThat( value.apply( " L" ).reverse(), equalTo( value.apply( "L " ) ) );
// assertThat( value.apply( "\r\n" ).reverse(), equalTo( value.apply( "\n\r" ) ) );
assertThat( value.apply( "Foo" ).reverse(), equalTo( value.apply( "ooF" ) ) );
assertThat( value.apply( "" ).reverse(), equalTo( StringValue.EMTPY ) );
assertThat( value.apply( " L" ).reverse(), equalTo( value.apply( "L " ) ) );
assertThat( value.apply( "\r\n" ).reverse(), equalTo( value.apply( "\n\r" ) ) );
assertThat( value.apply( "\uD801\uDC37" ).reverse(), equalTo( value.apply( "\uD801\uDC37" ) ) );
assertThat( value.apply( "This is literally a pile of crap \uD83D\uDCA9, it is fantastic" ).reverse(),
equalTo( value.apply( "citsatnaf si ti ,\uD83D\uDCA9 parc fo elip a yllaretil si sihT" ) ) );
assertThat( value.apply( "\uD83D\uDE21\uD83D\uDCA9\uD83D\uDC7B" ).reverse(), equalTo( value.apply(
"\uD83D\uDC7B\uD83D\uDCA9\uD83D\uDE21" ) ) );
}

@Test
Expand All @@ -137,5 +145,7 @@ public void split()
assertThat( value.apply( "HELLO" ).split( "LL" ), equalTo( stringArray( "HE", "O" ) ) );
assertThat( value.apply( "Separating,by,comma,is,a,common,use,case" ).split( "," ),
equalTo( stringArray( "Separating", "by", "comma", "is", "a", "common", "use", "case" ) ) );
assertThat( value.apply( "HELLO" ).split( "HELLO" ), equalTo( stringArray( "", "" ) ) );

}
}
Expand Up @@ -88,25 +88,33 @@ object TextValueSpecification extends Properties("TextValue") with Configuration
equivalent(value.toUpper, utf8.toUpper)
}}

property("replace") = forAll { (x: String, find: String, replace: String) => {
val value = stringValue(x)
val utf8 = utf8Value(x.getBytes(StandardCharsets.UTF_8))
equivalent(stringValue(x.replace(find, replace)), value.replace(find, replace)) &&
equivalent(value.replace(find, replace), utf8.replace(find, replace))
}}
private val replaceGen = for {x <- Arbitrary.arbitrary[String]
find <-Gen.alphaStr
replace <- Arbitrary.arbitrary[String]} yield (x,find, replace)
property("replace") = forAll(replaceGen) {
case (x: String, find: String, replace: String) =>
val value = stringValue(x)
val utf8 = utf8Value(x.getBytes(StandardCharsets.UTF_8))
equivalent(stringValue(x.replace(find, replace)), value.replace(find, replace)) &&
equivalent(value.replace(find, replace), utf8.replace(find, replace))
}

property("split") = forAll { (x: String, find: String) => {
val value = stringValue(x)
val utf8 = utf8Value(x.getBytes(StandardCharsets.UTF_8))
val split = x.split(find)
if (x != find) {
stringArray(split: _*) == value.split(find) &&
value.split(find) == utf8.split(find)
} else {
value.split(find) == utf8.split(find) && value.split(find) == stringArray("", "")
}
private val splitGen = for {x <- Arbitrary.arbitrary[String]
find <-Gen.alphaStr} yield (x,find)

property("split") = forAll(splitGen) {
case (x, find) =>
val value = stringValue(x)
val utf8 = utf8Value(x.getBytes(StandardCharsets.UTF_8))
val split = x.split(find)
if (x != find) {
stringArray(split: _*) == value.split(find) &&
value.split(find) == utf8.split(find)
} else {
value.split(find) == utf8.split(find) && value.split(find) == stringArray("", "")
}

}}
}

property("compareTo") = forAll { (x: String, y: String) =>
val stringX = stringValue(x)
Expand Down

0 comments on commit 269f35d

Please sign in to comment.