From 7fd9ebba821eb26842ff5642f84a4de3b99a67ed Mon Sep 17 00:00:00 2001 From: Michael Liarakos Date: Mon, 6 Jan 2020 20:11:30 -0500 Subject: [PATCH] Implement `java.util.function.Consumer`. --- .../scala/java/util/function/Consumer.scala | 30 ++++++++ .../javalib/util/function/ConsumerTest.scala | 74 +++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 javalib/src/main/scala/java/util/function/Consumer.scala create mode 100644 test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/function/ConsumerTest.scala diff --git a/javalib/src/main/scala/java/util/function/Consumer.scala b/javalib/src/main/scala/java/util/function/Consumer.scala new file mode 100644 index 0000000000..e978992b91 --- /dev/null +++ b/javalib/src/main/scala/java/util/function/Consumer.scala @@ -0,0 +1,30 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package java.util.function + +import scala.scalajs.js.annotation.JavaDefaultMethod + +@FunctionalInterface +trait Consumer[T] { self => + def accept(t: T): Unit + + @JavaDefaultMethod + def andThen(after: Consumer[_ >: T]): Consumer[T] = { + new Consumer[T] { + def accept(t: T): Unit = { + self.accept(t) + after.accept(t) + } + } + } +} diff --git a/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/function/ConsumerTest.scala b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/function/ConsumerTest.scala new file mode 100644 index 0000000000..6c0328850d --- /dev/null +++ b/test-suite/shared/src/test/scala/org/scalajs/testsuite/javalib/util/function/ConsumerTest.scala @@ -0,0 +1,74 @@ +/* + * Scala.js (https://www.scala-js.org/) + * + * Copyright EPFL. + * + * Licensed under Apache License 2.0 + * (https://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package org.scalajs.testsuite.javalib.util.function + +import java.util.function.Consumer + +import org.junit.Assert._ +import org.junit.Test + +import org.scalajs.testsuite.utils.AssertThrows._ + +class ConsumerTest { + import ConsumerTest._ + + @Test def accept(): Unit = { + // Side-effects + var current: Int = 0 + val add = makeConsumer[Int](num => current += num) + + add.accept(1) + assertTrue(current == 1) + + add.accept(2) + assertTrue(current == 3) + } + + @Test def andThen(): Unit = { + // Side-effects + var current: Int = 0 + val add = makeConsumer[Int](num => current += num) + val multiply = makeConsumer[Int](num => current *= num) + val addAndMultiply = add.andThen(multiply) + + addAndMultiply.accept(2) + assertTrue(current == 4) + + addAndMultiply.accept(3) + assertTrue(current == 21) + + // Sequential operations + val throwingConsumer = + makeConsumer[Any](x => throw new ThrowingConsumerException(x)) + val dontCallConsumer = + makeConsumer[Any](x => throw new AssertionError(s"dontCallConsumer.accept($x)")) + + assertThrows(classOf[ThrowingConsumerException], + throwingConsumer.andThen(dontCallConsumer).accept(0)) + + assertThrows(classOf[ThrowingConsumerException], + add.andThen(throwingConsumer).accept(1)) + assertTrue(current == 22) + } +} + +object ConsumerTest { + final class ThrowingConsumerException(x: Any) + extends Exception(s"throwing consumer called with $x") + + def makeConsumer[T](f: T => Unit): Consumer[T] = { + new Consumer[T] { + def accept(t: T): Unit = f(t) + } + } +}