Last active
December 23, 2015 03:39
-
-
Save tednaleid/6574381 to your computer and use it in GitHub Desktop.
Fixing typos/cut paste error in Spec messages. Also changing toString to be just a passthrough to the object (or safe for null) as I think you'd just want the original object string and wouldn't want to pollute your output with the fact that it's wrapped in an Optional.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import groovy.transform.Canonical | |
import spock.lang.Specification | |
@Canonical | |
class Optional<T> { | |
T reference | |
T get() { | |
if (isPresent()) return reference | |
throw new NoSuchElementException() | |
} | |
Boolean isPresent() { | |
return reference != null | |
} | |
Boolean asBoolean() { | |
return isPresent() | |
} | |
T orElse(T other) { | |
isPresent() ? reference : other | |
} | |
T orElseThrow(Exception e) { | |
if (isPresent()) { | |
return reference | |
} | |
throw e | |
} | |
T orNull() { | |
return reference | |
} | |
def ifPresent(Closure closure) { | |
if (isPresent()) { | |
return closure(reference) | |
} | |
} | |
@Override | |
String toString() { | |
return "$reference" | |
} | |
@Override | |
def methodMissing(String name, args) { | |
reference?.invokeMethod(name, args) | |
} | |
} | |
class OptionalSpec extends Specification { | |
void 'orNull returns the reference'() { | |
given: 'a known reference' | |
Object expectedReference = new Object() | |
expect: 'orNull returns the reference' | |
new Optional<Object>(expectedReference).orNull() == expectedReference | |
} | |
void 'orNull returns null'() { | |
expect: 'orNull returns null if there is no reference' | |
new Optional<Object>().orNull() == null | |
} | |
void 'get returns the reference'() { | |
given: 'a known reference' | |
Object expectedReference = new Object() | |
expect: 'orNull returns the reference' | |
new Optional<Object>(expectedReference).get() == expectedReference | |
} | |
void 'get throws NoSuchElementException if there is no reference'() { | |
when: 'get is called' | |
new Optional<Object>().get() | |
then: 'no reference throws NoSuchElementException' | |
thrown(NoSuchElementException) | |
} | |
void 'isPresent is false when there is no reference'() { | |
expect: 'An instance of optional with no reference returns false for isPresent' | |
!new Optional().isPresent() | |
} | |
void 'isPresent is true when there is a reference'() { | |
expect: 'An instance of optional with no reference returns false for isPresent' | |
new Optional(new Object()).isPresent() | |
} | |
void 'Delegates to the reference'() { | |
given: 'An instance of optional with with a list' | |
Optional<Integer> optionalInteger = new Optional(new Integer(1)) | |
expect: 'doubleValue() is invoked on the reference when called on the optional instance' | |
optionalInteger.doubleValue() == 1.0 | |
} | |
void 'Delegating to a missing reference returns false'() { | |
given: 'An instance of optional with with a list' | |
Optional<Integer> optionalInteger = new Optional() | |
expect: 'doubleValue() is invoked on the reference when called on the optional instance' | |
!optionalInteger.doubleValue() | |
} | |
void 'can use asBoolean to determine lack of presence of the reference'() { | |
expect: 'An instance of optional with no reference returns false for isPresent' | |
!new Optional() | |
} | |
void 'can use asBoolean to determine presence of the reference'() { | |
expect: 'An instance of optional with no reference returns false for isPresent' | |
new Optional(new Object()) | |
} | |
void 'orElse returns the reference if it exists'() { | |
given: 'a known reference' | |
Object expectedReference = new Object() | |
and: 'another reference' | |
Object anotherReference = new Object() | |
expect: 'orElse returns the reference' | |
new Optional<Object>(expectedReference).orElse(anotherReference) == expectedReference | |
} | |
void 'orElse returns an alternate if the reference does not exist'() { | |
given: 'another reference' | |
Object anotherReference = new Object() | |
expect: 'orElse returns the reference' | |
new Optional<Object>().orElse(anotherReference) == anotherReference | |
} | |
void 'orElseThrow returns the reference if it exists'() { | |
given: 'a known reference' | |
Object expectedReference = new Object() | |
and: 'an exception' | |
Exception unexpectedException = new Exception() | |
expect: 'orElse returns the reference' | |
new Optional<Object>(expectedReference).orElseThrow(unexpectedException) == expectedReference | |
} | |
void 'orElseThrow throws the given exception if the reference does not exist'() { | |
given: 'an exception' | |
Exception expectedException = new Exception() | |
when: 'orElse is called' | |
new Optional<Object>().orElseThrow(expectedException) | |
then: 'the wtfException is thrown' | |
Exception exception = thrown() | |
exception == expectedException | |
} | |
void 'ifPresent returns false if there is no reference present'() { | |
expect: 'false when there is no reference present' | |
!new Optional<Object>().ifPresent { return true } | |
} | |
void 'ifPresent invokes the closure and returns the result if there is a reference present'() { | |
given: 'an expected closure result' | |
Integer expectedResult = 10 | |
when: 'ifPresent is called with a reference' | |
Integer result = new Optional<Object>(new Object()).ifPresent { return expectedResult } | |
then: 'the actual result is the expected result' | |
expectedResult == result | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment