package com.googlecode.totallylazy.functions; import com.googlecode.totallylazy.Either; import com.googlecode.totallylazy.Pair; import com.googlecode.totallylazy.Sequence; import com.googlecode.totallylazy.matchers.Matchers; import org.hamcrest.CoreMatchers; import org.hamcrest.MatcherAssert; import org.junit.Test; import static com.googlecode.totallylazy.functions.Callables.compose; import static com.googlecode.totallylazy.functions.Callables.uncurry3; import static com.googlecode.totallylazy.Option.some; import static com.googlecode.totallylazy.matchers.NumberMatcher.hasExactly; import static com.googlecode.totallylazy.matchers.NumberMatcher.is; import static com.googlecode.totallylazy.numbers.Numbers.add; import static com.googlecode.totallylazy.numbers.Numbers.multiply; import static com.googlecode.totallylazy.numbers.Numbers.numbers; import static com.googlecode.totallylazy.numbers.Numbers.range; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; public class FunctionsTest { @Test public void supportsApplicativeUsageWithOption() throws Exception { assertThat(add(3).$(some(3)), Matchers.is(some((Number)6))); } @Test public void supportsApplicativeUsageWithEither() throws Exception { MatcherAssert.assertThat(add(3).$(Either.<String, Number>right(3)), CoreMatchers.is(Either.<String, Number>right(6))); } @Test public void supportsApplicativeUsageWithSequence() throws Exception { assertThat(add(3).$(numbers(9, 1)), Matchers.is(numbers(12, 4))); } @Test public void canComposeCurriedFunctions() throws Exception { assertThat(add().then(multiply()).apply(2).apply(10).apply(3), is(36)); assertThat(add().then(multiply().then(add().then(multiply()))).apply(2).apply(10).apply(3).apply(2).apply(10), is(380)); } @Test public void canComposeFunctions() throws Exception { assertThat(compose(add(10), multiply(3)).apply(2), is(36)); assertThat(add(10).map(multiply(3)).apply(2), is(36)); assertThat(add(10).then(multiply(3)).apply(2), is(36)); assertThat(add(10).deferApply(2).map(multiply(3)).apply(), is(36)); assertThat(add(10).deferApply(2).then(multiply(3)).apply(), is(36)); } @Test public void canCallWithAValue() throws Exception { Sequence<Number> computations = range(1, 5).map(multiply()).map(Callables.<Number, Number>callWith(2)); assertThat(computations, hasExactly(2, 4, 6, 8, 10)); } @Test public void canPartiallyApplyAFunction3() throws Exception { assertThat(addThenMultiple().apply(10).apply(2).apply(3), is(36)); assertThat(addThenMultiple().apply(10, 2).apply(3), is(36)); assertThat(addThenMultiple().apply(10, 2, 3), is(36)); } @Test public void canCaptureArgument() throws Exception { assertThat(multiply(10).capturing().apply(1), equalTo(Pair.<Number,Number>pair(1, 10))); } private Curried3<Number, Number, Number, Number> addThenMultiple() { return uncurry3(add().then(multiply())); } }