diff --git a/src/test/java/com/github/tonivade/vavr/effect/IOTest.java b/src/test/java/com/github/tonivade/vavr/effect/IOTest.java index 6fc39d2..6327c10 100644 --- a/src/test/java/com/github/tonivade/vavr/effect/IOTest.java +++ b/src/test/java/com/github/tonivade/vavr/effect/IOTest.java @@ -4,6 +4,7 @@ */ package com.github.tonivade.vavr.effect; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -15,6 +16,12 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStreamReader; +import java.io.PrintStream; import java.sql.ResultSet; import java.sql.SQLException; import java.time.Duration; @@ -22,10 +29,12 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.Consumer; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; + import io.vavr.CheckedFunction0; import io.vavr.CheckedFunction1; import io.vavr.Function1; @@ -50,7 +59,7 @@ pure.flatMap(string -> IO.task(() -> string.split(" "))).unsafeRunSync()), () -> assertEquals(Integer.valueOf(100), pure.andThen(IO.task(() -> 100)).unsafeRunSync())); } - + @Test void asyncSuccess() { IO async = IO.async(callback -> { @@ -58,37 +67,53 @@ Thread.sleep(100); callback.accept(Try.success("1")); }); - + Future foldMap = IO.forked().andThen(async).runAsync(); - + assertEquals("1", foldMap.get()); } - + @Test void asyncFailure() { IO async = IO.async(callback -> { Thread.sleep(100); callback.accept(Try.failure(new UnsupportedOperationException())); }); - + Future foldMap = IO.forked().andThen(async).runAsync(); - + assertThrows(UnsupportedOperationException.class, foldMap::get); } -// @Test -// void echo() { -// IO echo = narrowK(console.println("write your name")) -// .andThen(narrowK(console.readln())) -// .flatMap(name -> narrowK(console.println("Hello " + name))) -// .andThen(narrowK(console.println("end"))); -// -// ConsoleExecutor executor = new ConsoleExecutor().read("Toni"); -// -// executor.run(echo); -// -// assertEquals("write your name\nHello Toni\nend\n", executor.getOutput()); -// } + @Test + void echo() { + IO echo = IO.exec(() -> System.out.println("write your name")) + .andThen(IO.task(() -> new BufferedReader(new InputStreamReader(System.in)).readLine())) + .flatMap(name -> IO.exec(() -> System.out.println("Hello " + name))) + .andThen(IO.exec(() -> System.out.println("end"))); + + var output = new ByteArrayOutputStream(); + var savedInput = System.in; + var savedOutput = System.out; + try { + System.setIn(mockInput("Toni")); + System.setOut(mockOutput(output)); + echo.unsafeRunSync(); + } finally { + System.setIn(savedInput); + System.setOut(savedOutput); + } + + assertEquals("write your name\nHello Toni\nend\n", output.toString(UTF_8)); + } + + private PrintStream mockOutput(ByteArrayOutputStream output) { + return new PrintStream(output); + } + + private ByteArrayInputStream mockInput(String input) { + return new ByteArrayInputStream(input.getBytes(UTF_8)); + } @Test void safeRunAsync() { @@ -249,24 +274,24 @@ assertEquals(705082704, result._2()); assertTrue(result._1().toMillis() > 0); } - + @Test void timeoutFail() { assertThrows(TimeoutException.class, IO.never().timeout(Duration.ofSeconds(1))::unsafeRunSync); } - + @Test void timeoutSuccess() { assertEquals(1, IO.pure(1).timeout(Duration.ofSeconds(1)).unsafeRunSync()); } - + @Test void traverse() { IO left = IO.task(() -> "left"); IO right = IO.task(() -> "right"); - + IO> traverse = IO.traverse(List.of(left, right)); - + assertEquals(List.of("left", "right"), traverse.unsafeRunSync()); } @@ -275,9 +300,9 @@ IO> race = IO.race( IO.delay(Duration.ofMillis(10), () -> 10), IO.delay(Duration.ofMillis(100), () -> "b")); - + Either orElseThrow = race.unsafeRunSync(); - + assertEquals(Either.left(10), orElseThrow); } @@ -286,39 +311,39 @@ IO> race = IO.race( IO.delay(Duration.ofMillis(100), () -> 10), IO.delay(Duration.ofMillis(10), () -> "b")); - + Either orElseThrow = race.unsafeRunSync(); - + assertEquals(Either.right("b"), orElseThrow); } - + @Test void fork() { IO result = IO.pure("hola") .flatMap(hello -> IO.delay(Duration.ofSeconds(1), () -> hello + " toni").fork()) .flatMap(Fiber::join); - + String orElseThrow = result.runAsync().get(); assertEquals("hola toni", orElseThrow); } - + @Test void memoize(@Mock Function1 toUpperCase) { when(toUpperCase.apply(any())) - .thenAnswer(args -> args.getArgument(0, String.class).toUpperCase()); - + .thenAnswer(args -> args.getArgument(0).toUpperCase()); + IO>> memoized = IO.memoize((String str) -> IO.pure(toUpperCase.apply(str))); - + IO flatMap = memoized.flatMap(x -> x.apply("hola")); flatMap.unsafeRunSync(); flatMap.unsafeRunSync(); flatMap.unsafeRunSync(); flatMap.unsafeRunSync(); - + verify(toUpperCase).apply("hola"); } - + @Test void fibSyncTest() { assertAll( @@ -334,7 +359,7 @@ () -> assertEquals(6765, fibSync(20).unsafeRunSync()) ); } - + @Test void fibAsyncTest() { assertAll(