summaryrefslogtreecommitdiff
path: root/test-suite/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'test-suite/src/test')
-rw-r--r--test-suite/src/test/require-sam/scala/scalajs/testsuite/jsinterop/ArraySAMTest.scala32
-rw-r--r--test-suite/src/test/resources/SourceMapTestTemplate.scala655
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/compiler/BooleanTest.scala41
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/compiler/ByteTest.scala40
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/compiler/CharTest.scala40
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/compiler/FloatTest.scala73
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala98
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/compiler/IntTest.scala206
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/compiler/InteroperabilityTest.scala528
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/compiler/LongTest.scala159
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/compiler/OptimizerTest.scala43
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/compiler/ReflectionTest.scala69
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/compiler/ReflectiveCallTest.scala330
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/compiler/RegressionTest.scala287
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/compiler/RuntimeTypesTest.scala77
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/compiler/ShortTest.scala38
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/compiler/UnitTest.scala47
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ArraysTest.scala749
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/AtomicTest.scala119
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/BooleanTest.scala62
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ByteTest.scala64
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/CharacterTest.scala672
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ClassTest.scala30
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/DateTest.scala87
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/DoubleTest.scala217
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/FloatTest.scala221
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/FormatterTest.scala241
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/IntegerTest.scala161
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/LongTest.scala178
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/MathTest.scala142
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/MockByteArrayOutputStream.scala47
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ObjectTest.scala72
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/OutputStreamWriterTest.scala134
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/PrintStreamTest.scala296
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/PrintWriterTest.scala287
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/RandomTest.scala225
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ReadersTest.scala244
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ReferenceTest.scala28
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/RegexTest.scala397
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ShortTest.scala66
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/StackTraceElementTest.scala29
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/StreamsTest.scala308
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/StringBufferTest.scala219
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/StringTest.scala237
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/SystemTest.scala118
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ThrowablesTest.scala90
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/TimeUnitTest.scala135
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/URITest.scala312
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/javalib/UUIDTest.scala180
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ArrayTest.scala94
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/AsyncTest.scala121
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/DictionaryTest.scala79
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/DynamicTest.scala187
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ExportsTest.scala1075
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/FunctionTest.scala41
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/MiscInteropTest.scala89
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/RuntimeLongTest.scala140
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/StrangeNamedTests.scala28
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ThisFunctionTest.scala70
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/UndefOrTest.scala191
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/library/ArrayOpsTest.scala117
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/library/WrappedArrayTest.scala118
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/library/WrappedDictionaryTest.scala106
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/niobuffer/BaseBufferTest.scala178
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/niobuffer/ByteBufferTest.scala330
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/niobuffer/CharBufferTest.scala388
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/BaseCharsetTest.scala234
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/CharsetTest.scala74
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/Latin1Test.scala91
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/USASCIITest.scala93
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/UTF16Test.scala155
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/UTF8Test.scala240
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/scalalib/EnumerationTest.scala95
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/scalalib/RangesTest.scala27
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/scalalib/SymbolTest.scala63
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/ArrayBufferInputStreamTest.scala36
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/ArrayBufferTest.scala39
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/ArraysTest.scala45
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/DataViewTest.scala275
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/TypedArrayConversionTest.scala197
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/TypedArrayTest.scala332
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/utils/JSUtils.scala26
-rw-r--r--test-suite/src/test/scala/scala/scalajs/testsuite/utils/TestDetector.scala33
83 files changed, 14537 insertions, 0 deletions
diff --git a/test-suite/src/test/require-sam/scala/scalajs/testsuite/jsinterop/ArraySAMTest.scala b/test-suite/src/test/require-sam/scala/scalajs/testsuite/jsinterop/ArraySAMTest.scala
new file mode 100644
index 0000000..534d203
--- /dev/null
+++ b/test-suite/src/test/require-sam/scala/scalajs/testsuite/jsinterop/ArraySAMTest.scala
@@ -0,0 +1,32 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.jsinterop
+
+import scala.scalajs.js
+
+import org.scalajs.jasminetest.JasmineTest
+
+object ArraySAMTest extends JasmineTest {
+
+ import js.JSArrayOps._
+
+ describe("scala.scalajs.js.Array with SAM support") {
+
+ it("should provide jsMap") {
+ expect(js.Array("Sc", "ala", ".", "js").jsMap(_.length)).toEqual(
+ js.Array(2, 3, 1, 2))
+ }
+
+ it("should provide jsFilter") {
+ expect(js.Array(56, 30, -20, 33, 54, 86).jsFilter(_ % 3 != 0)).toEqual(
+ js.Array(56, -20, 86))
+ }
+
+ }
+
+}
diff --git a/test-suite/src/test/resources/SourceMapTestTemplate.scala b/test-suite/src/test/resources/SourceMapTestTemplate.scala
new file mode 100644
index 0000000..2b135ef
--- /dev/null
+++ b/test-suite/src/test/resources/SourceMapTestTemplate.scala
@@ -0,0 +1,655 @@
+package scala.scalajs.testsuite.compiler
+
+import org.scalajs.jasminetest.{JasmineTest, JasmineTestFramework}
+
+/** The test counter */
+private[testsuite] object TC {
+ var testNum: Int = _
+
+ def is(x: Int): Boolean = testNum == x
+}
+
+/** Exception to test source maps. Not a ControlThrowable, because it has
+ * NoStackTrace which would defeat its purpose
+ */
+case class TestException(lineNo: Int) extends Exception
+
+/**
+ * Template to generate source-map tests, verifying that the line numbers
+ * reported in the source-mapped stacktraces match up with the line number
+ * that the error originated from.
+ *
+ * /two-star/s in this file are replaced with a code-snippet to throw
+ * an exception if `testNum` is set to the /two-star/'s index. The
+ * exception is then caught and its stacktrace checked to see
+ * that it reports the line number expected (stored in the error
+ * message). /three-star/s in are replaced with a dangling else (to
+ * allow throwing in expression position).
+ * `0/*<testCount>*/` is replaced by the number of /n-star/s in the
+ * file.
+ */
+object SourceMapTest extends JasmineTest {
+
+ val testCount: Int = 0/*<testCount>*/
+
+ if (JasmineTestFramework.hasTag("nodejs")) {
+ scalajs.js.Dynamic.global.require("source-map-support").install()
+ }
+
+ when("source-maps").
+ describe("Source Maps") {
+
+ for (i <- 0 until testCount) {
+ it(s"work (test $i)") {
+ TC.testNum = i
+
+ try {
+ run()
+ sys.error("No exception thrown")
+ } catch {
+ case e @ TestException(lineNo) =>
+ val trace0 = e.getStackTrace.toList
+ val trace1 = trace0.dropWhile(
+ _.getFileName.endsWith("/scala/scalajs/runtime/StackTrace.scala"))
+ val trace2 = trace1.dropWhile(
+ _.getFileName.endsWith("/java/lang/Throwables.scala"))
+
+ val exSte :: throwSte :: _ = trace2
+
+ expect(exSte.getFileName).toContain("/SourceMapTest.scala")
+ // line where `case class TestException is written` above
+ expect(exSte.getLineNumber).toBe(15)
+
+ expect(throwSte.getFileName).toContain("/SourceMapTest.scala")
+ expect(throwSte.getLineNumber).toBe(lineNo)
+ }
+ }
+ }
+ }
+
+ def get(json: JsValue, index: Int) = {
+ /**/
+ /**/json.asInstanceOf[JsArray].value(index).value
+ }
+
+ def get(json: JsValue, index: Int, fieldName: String) = {
+ /**/
+ /**//***/json.asInstanceOf[JsArray].value(index).asInstanceOf[JsObject].value(fieldName).value
+ }
+ def run() = {
+ /**/
+ /**/val ugly =
+ """
+ |[
+ | "JSON Test Pattern pass1",
+ | {"object with 1 member":["array with 1 element"]},
+ | {},
+ | [],
+ | -42,
+ | true,
+ | false,
+ | null,
+ | {
+ | "integer": 1234567890,
+ | "real": -9876.543210,
+ | "e": 0.123456789e-12,
+ | "E": 1.234567890E+34,
+ | "": 23456789012E66,
+ | "zero": 0,
+ | "one": 1,
+ | "space": " ",
+ | "quote": "\"",
+ | "backslash": "\\",
+ | "controls": "\b\f\n\r\t",
+ | "slash": "/ & \/",
+ | "alpha": "abcdefghijklmnopqrstuvwyz",
+ | "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
+ | "digit": "0123456789",
+ | "0123456789": "digit",
+ | "special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
+ | "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
+ | "true": true,
+ | "false": false,
+ | "null": null,
+ | "array":[ ],
+ | "object":{ },
+ | "address": "50 St. James Street",
+ | "url": "http://www.JSON.org/",
+ | "comment": "// /* <!-- --",
+ | "# -- --> */": " ",
+ | " s p a c e d " :[1,2 , 3
+ |
+ |,
+ |
+ |4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7],
+ | "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
+ | "quotes": "&#34; \u005Cu0022 %22 0x22 034 &#x22;",
+ | "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
+ |: "A key can be any string"
+ | },
+ | 0.5 ,98.6
+ |,
+ |99.44
+ |,
+ |
+ |1066,
+ |1e1,
+ |0.1e1,
+ |1e-1,
+ |1e00,2e+00,2e-00
+ |,"rosebud"]
+ """.stripMargin/**/
+ /**/val json = new Json()/**/
+ /**/val parsed = json.read(ugly)/**/
+ /**/
+ /**/val unparsed = json.write(parsed)/**/
+ /**/val reparsed = json.read(unparsed)/**/
+
+ for (json <- Seq(parsed, reparsed)){/**/
+ assert(get(json, 0) == "JSON Test Pattern pass1")
+ /**/
+ assert(get(json, 5) == true)
+ assert(get(json, 6) == false)
+ assert(get(json, 8, "real") == "-9876.543210")/**/
+ /**/assert(get(json, 8, "comment") == "// /* <!-- --")
+ assert(get(json, 8, "jsontext") == "{\"object with 1 member\":[\"array with 1 element\"]}")
+ assert(get(json, 19) == "rosebud")/**/
+ }
+ /**/
+ }
+}
+
+
+
+sealed trait JsValue {
+ def value: Any
+}
+
+case class JsString(value: java.lang.String) extends JsValue
+
+case class JsObject(value: Map[String, JsValue]) extends JsValue
+
+case class JsArray(value: Seq[JsValue]) extends JsValue
+
+case class JsNumber(value: java.lang.String) extends JsValue
+
+sealed trait JsBoolean extends JsValue {
+ def value: Boolean
+}
+
+case object JsFalse extends JsBoolean {
+ def value = {/**/false}
+}
+
+case object JsTrue extends JsBoolean {
+ def value = {/**/true}
+}
+
+case object JsNull extends JsValue {
+ def value = {null}
+}
+
+trait Writer{
+ /**/
+ def writeToBuffer(v: JsValue, sb: StringBuffer): Unit = v match {
+ case JsString(s) =>
+ /**/sb.append('"')/**/
+ /**/var i = 0/**/
+ while(i < s.length){/**/
+ /**/s.charAt(i) match {
+ case '\\' => /**/sb.append("\\\\")/**/
+ case '"' => sb.append("\\\"")
+ case '/' => /**/sb.append("\\/")/**/
+ case '\b' => sb.append("\\b")
+ case '\t' => sb.append("\\t")
+ case '\n' => /**/sb.append("\\n")/**/
+ case '\f' => sb.append("\\f")
+ case '\r' => sb.append("\\r")
+ case c =>
+ if (c < ' '){
+ val t = "000" + Integer.toHexString(c)
+ sb.append("\\u" + t.takeRight(4))
+ }else{
+ sb.append(c.toString)
+ }
+ }
+ i += 1
+ }
+ /**/
+ sb.append('"')
+ /**/
+ case JsObject(kvs) =>
+ /**/
+ sb.append("{")
+ /**/
+ var first = true
+ kvs.foreach(kv => {
+ /**/
+ val (k, v) = kv
+ if (first)
+ first = false
+ else
+ sb.append(", ")
+
+ /**/
+ writeToBuffer(JsString(k), sb)
+ sb.append(": ")
+ /**/
+ writeToBuffer(v, sb)
+ })
+ sb.append("}")
+
+ case JsArray(vs) => /**/
+ sb.append("[")
+ if (vs.length > 0) writeToBuffer(vs(0), sb)
+ var i = 1
+ while(i < vs.length){
+ sb.append(", ")
+ writeToBuffer(vs(i), sb)
+ i += 1
+ }
+ sb.append("]")
+ case JsNumber(d) => sb.append(d)
+ case JsFalse => sb.append("false")
+ case JsTrue => sb.append("true")
+ case JsNull => sb.append("null")
+ }
+ /**/
+}
+class Writer2 extends Writer{
+ /**/
+ def write(v: JsValue): String = {
+ /**/
+ val sb = new StringBuffer()
+ writeToBuffer(v, sb)
+ sb.toString
+ }
+ /**/
+}
+class Json extends Writer2{
+
+ /**
+ * Self-contained JSON parser adapted from
+ *
+ * https://github.com/nestorpersist/json
+ */
+ def read(s: String): JsValue = {
+
+ // *** Character Kinds
+ /**/
+ type CharKind = Int
+ val Letter = 0
+ val Digit = 1
+ val Minus = 2
+ val Quote = 3
+ val Colon = 4
+ val Comma = 5
+ val Lbra = 6
+ val Rbra = 7
+ val Larr = 8
+ val Rarr = 9
+ val Blank = 10
+ val Other = 11
+ val Eof = 12
+ val Slash = 13
+
+ // *** Token Kinds
+
+ type TokenKind = Int
+ val ID = 0
+ val STRING = 1
+ val NUMBER = 2
+ val BIGNUMBER = 3
+ val FLOATNUMBER = 4
+ val COLON = 5
+ val COMMA = 6
+ val LOBJ = 7
+ val ROBJ = 8
+ val LARR = 9
+ val RARR = 10
+ val BLANK = 11
+ val EOF = 12
+ /**/
+ // *** Character => CharKind Map ***
+
+ val charKind = (0 to 255).toArray.map {
+ case c if 'a'.toInt <= c && c <= 'z'.toInt => Letter
+ case c if 'A'.toInt <= c && c <= 'Z'.toInt => Letter
+ case c if '0'.toInt <= c && c <= '9'.toInt => Digit
+ case '-' => /**/Minus
+ case ',' => /**/Comma
+ case '"' => /**/Quote
+ case ':' => /**/Colon
+ case '{' => /**/Lbra
+ case '}' => Rbra
+ case '[' => Larr
+ case ']' => Rarr
+ case ' ' => Blank
+ case '\t' => Blank
+ case '\n' => Blank
+ case '\r' => Blank
+ case '/' => Slash
+ case _ => Other
+ }
+
+ // *** Character Escapes
+ /**/
+ val escapeMap = Map[Int, String](
+ '\\'.toInt -> "\\",
+ '/'.toInt -> "/",
+ '\"'.toInt -> "\"",
+ 'b'.toInt -> "\b",
+ 'f'.toInt -> "\f",
+ 'n'.toInt -> "\n",
+ 'r'.toInt -> "\r",
+ 't'.toInt -> "\t"
+ )
+ // *** Import Shared Data ***
+
+ // *** INPUT STRING ***
+
+ // array faster than accessing string directly using charAt
+ //final val s1 = s.toCharArray()
+ val size = s.size
+
+ // *** CHARACTERS ***
+
+ var pos = 0
+
+ var ch: Int = 0
+ var chKind: CharKind = 0
+ var chLinePos: Int = 0
+ var chCharPos: Int = 0
+
+ def chNext() = {/**/
+ if (pos < size) {/**/
+ //ch = s1(pos).toInt
+ /**/ch = s.charAt(pos)/**/
+ /**/chKind = /***/if (ch < 255) {/**/
+ /**//***/charKind(ch)
+ } else {/**/
+ /**//***/Other
+ }/**/
+ pos += 1
+ if (ch == '\n'.toInt) {
+ chLinePos += 1
+ chCharPos = 1
+ } else {/**/
+ chCharPos += 1/**/
+ }
+ } else {
+ ch = -1
+ pos = size + 1
+ chKind = Eof
+ }
+ }/**/
+ /**/
+ /**/
+ /**/def chError(msg: String): Nothing = {
+ throw new Json.Exception(msg, s, chLinePos, chCharPos)
+ }
+
+ def chMark = pos - 1
+
+ def chSubstr(first: Int, delta: Int = 0) = {
+ s.substring(first, pos - 1 - delta)
+ }
+
+ // *** LEXER ***
+
+ var tokenKind = BLANK
+ var tokenValue = ""
+ var linePos = 1
+ var charPos = 1
+
+ def getDigits() = {
+ while (chKind == Digit) chNext()
+ }
+
+ def handleDigit() {
+ val first = chMark
+ getDigits()
+ val k1 = if (ch == '.'.toInt) {
+ chNext()
+ getDigits()
+ BIGNUMBER
+ } else {
+ NUMBER
+ }
+ val k2 = if (ch == 'E'.toInt || ch == 'e'.toInt) {
+ chNext()
+ if (ch == '+'.toInt) {
+ chNext()
+ } else if (ch == '-'.toInt) {
+ chNext()
+ }
+ getDigits()
+ FLOATNUMBER
+ } else {
+ k1
+ }
+ /**/tokenKind = k2/**/
+ /**/tokenValue = chSubstr(first)/**/
+ /**/}/**/
+ /**/
+ def handleRaw() {
+ chNext()
+ val first = chMark
+ var state = 0
+ do {
+ if (chKind == Eof) chError("EOF encountered in raw string")
+ state = (ch, state) match {
+ case ('}', _) => 1
+ case ('"', 1) => 2
+ case ('"', 2) => 3
+ case ('"', 3) => 0
+ case _ => 0
+ }
+
+ chNext()
+ } while (state != 3)
+ tokenKind = STRING
+ tokenValue = chSubstr(first, 3)
+ }
+
+ def handle(i: Int) = {
+ chNext()
+ tokenKind = i
+ tokenValue = ""
+ }
+
+ def tokenNext() {
+ do {
+ linePos = chLinePos
+ charPos = chCharPos
+ val kind: Int = chKind
+ kind match {
+ case Letter =>
+ val first = chMark
+ while (chKind == Letter || chKind == Digit) {
+ chNext()
+ }
+ tokenKind = ID
+ tokenValue = chSubstr(first)
+
+ case Digit => handleDigit()
+ case Minus =>
+ chNext()
+ handleDigit()
+ tokenValue = "-" + tokenValue
+
+ case Quote =>
+ val sb = new StringBuilder(50)
+ chNext()
+ var first = chMark
+ while (ch != '"'.toInt && ch >= 32) {
+ if (ch == '\\'.toInt) {
+ sb.append(chSubstr(first))
+ chNext()
+ escapeMap.get(ch) match {
+ case Some(s) =>
+ sb.append(s)
+ chNext()
+
+ case None =>
+ if (ch != 'u'.toInt) chError("Illegal escape")
+ chNext()
+ var code = 0
+ for (i <- 1 to 4) {
+ val ch1 = ch.toChar.toString
+ val i = "0123456789abcdef".indexOf(ch1.toLowerCase)
+ if (i == -1) chError("Illegal hex character")
+ code = code * 16 + i
+ chNext()
+ }
+ sb.append(code.toChar.toString)
+ }
+ first = chMark
+ } else {
+ chNext()
+ }
+ }
+ if (ch != '"') chError("Unexpected string character: " + ch.toChar)
+
+ sb.append(chSubstr(first))
+
+ tokenKind = STRING
+
+ tokenValue = sb.toString()
+ chNext()
+ if (tokenValue.length() == 0 && ch == '{') {
+ handleRaw()
+ }
+
+ case Colon => handle(COLON)/**/
+ case Comma => handle(COMMA)/**/
+ case Lbra => handle(LOBJ)/**/
+ case Rbra => handle(ROBJ)/**/
+ case Larr => handle(LARR)/**/
+ case Rarr => handle(RARR)/**/
+ case Blank =>
+ do chNext() while (chKind == Blank)
+ tokenKind = BLANK
+ tokenValue = ""
+
+ case Other => chError("Unexpected character: " + ch.toChar + " " + ch)
+ case Eof =>
+ chNext()
+ tokenKind = EOF
+ tokenValue = ""
+
+ case Slash =>
+ if (chKind != Slash) chError("Expecting Slash")
+ do chNext() while (ch != '\n' && chKind != Eof)
+ tokenKind = BLANK
+ tokenValue = ""
+
+ }
+ } while (tokenKind == BLANK)
+ }
+ /**/
+ def tokenError(msg: String): Nothing = {
+ throw new Json.Exception(msg, s, linePos, charPos)
+ }
+ /**/
+ // *** PARSER ***
+
+ def handleEof() = tokenError("Unexpected eof")
+ def handleUnexpected(i: String) = tokenError(s"Unexpected input: [$i]")
+
+ def handleArray(): JsArray = {
+ tokenNext()
+ var result = List.empty[JsValue]
+ while (tokenKind != RARR) {/**/
+ result = getJson() :: result
+ /**/tokenKind match{
+ case COMMA => /**/tokenNext()
+ case RARR => // do nothing
+ case _ => tokenError("Expecting , or ]")
+ }
+ }
+ tokenNext()
+ JsArray(result.reverse)
+ }
+
+ def handleObject(): JsObject = {
+ tokenNext()
+ var result = List.empty[(String, JsValue)]
+ /**/
+ while (tokenKind != ROBJ) {
+ if (tokenKind != STRING && tokenKind != ID) tokenError("Expecting string or name")
+ val name = tokenValue
+ tokenNext()
+ if (tokenKind != COLON) tokenError("Expecting :")
+ tokenNext()
+ result = (name -> getJson()) :: result
+ tokenKind match{
+ case COMMA => tokenNext()
+ case ROBJ => // do nothing
+ case _ => tokenError("Expecting , or }")
+ }
+ }
+ tokenNext()
+ JsObject(result.toMap)
+ }
+ def handleNumber(name: String, f: String => Unit) = {
+ try {
+ f(tokenValue)
+ } catch {
+ case _: Throwable => tokenError("Bad " + name)
+ }
+ val old = tokenValue
+ tokenNext()
+
+ JsNumber(old)
+ }
+ def getJson(): JsValue = {
+ val kind: Int = tokenKind
+ val result: JsValue = kind match {
+ case ID =>
+ val result: JsValue = tokenValue match {
+ case "true" => JsTrue
+ case "false" => JsFalse
+ case "null" => JsNull
+ case _ => tokenError("Not true, false, or null")
+ }
+
+ tokenNext()
+ result
+
+ case STRING =>
+ val result = tokenValue
+ tokenNext()
+ JsString(result)
+
+ case NUMBER => handleNumber("NUMBER", _.toLong)
+ case BIGNUMBER => handleNumber("BIGNUMBER", _.toDouble)
+ case FLOATNUMBER => handleNumber("FLOATNUMBER", _.toDouble)
+ case COLON => handleUnexpected(":")
+ case COMMA => handleUnexpected(",")
+ case LOBJ => handleObject()
+ case ROBJ => handleUnexpected("}")
+ case LARR => handleArray()
+ case RARR => handleUnexpected("]")
+ case EOF => handleEof()
+ }
+ result
+ }
+ def parse(): JsValue = {
+ chNext()
+ tokenNext()
+ val result = getJson
+ if (tokenKind != EOF) tokenError("Excess input")
+ result
+ }
+ parse()
+ }
+}
+
+object Json {
+ class Exception(val msg: String,
+ val input: String,
+ val line: Int,
+ val char: Int)
+ extends scala.Exception(s"JsonParse Error: $msg line $line [$char] in $input")
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/BooleanTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/BooleanTest.scala
new file mode 100644
index 0000000..8343244
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/BooleanTest.scala
@@ -0,0 +1,41 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.compiler
+
+import org.scalajs.jasminetest.JasmineTest
+import scala.scalajs.js
+
+object BooleanTest extends JasmineTest {
+
+ describe("Boolean primitives") {
+
+ it("&, | and ^ on booleans should return booleans") {
+ expect(js.typeOf(true & false)).toEqual("boolean")
+ expect(js.typeOf(true | false)).toEqual("boolean")
+ expect(js.typeOf(true ^ false)).toEqual("boolean")
+ }
+
+ it("&, | and ^ on booleans should return correct results") {
+ expect(false & false).toBeFalsy
+ expect(false & true).toBeFalsy
+ expect(true & false).toBeFalsy
+ expect(true & true).toBeTruthy
+
+ expect(false | false).toBeFalsy
+ expect(true | false).toBeTruthy
+ expect(false | true).toBeTruthy
+ expect(true | true).toBeTruthy
+
+ expect(false ^ false).toBeFalsy
+ expect(true ^ false).toBeTruthy
+ expect(false ^ true).toBeTruthy
+ expect(true ^ true).toBeFalsy
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/ByteTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/ByteTest.scala
new file mode 100644
index 0000000..9f48993
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/ByteTest.scala
@@ -0,0 +1,40 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.compiler
+
+import org.scalajs.jasminetest.JasmineTest
+import scala.scalajs.js
+
+object ByteTest extends JasmineTest {
+
+ describe("Byte primitives") {
+
+ it("should always be in their range") {
+ def test(x: Int, y: Byte): Unit =
+ expect(x.toByte).toEqual(y)
+
+ test(0, 0)
+ test(127, 127)
+ test(128, -128)
+ test(-128, -128)
+ test(-500, 12)
+ test(-90000, 112)
+ test(123456789, 21)
+ test(-40000, -64)
+ test(65536, 0)
+ test(32768, 0)
+
+ def testC(x: Char, y: Byte): Unit =
+ expect(x.toByte).toEqual(y)
+
+ testC(-1.toChar, -1)
+ testC(200.toChar, -56)
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/CharTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/CharTest.scala
new file mode 100644
index 0000000..edc2660
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/CharTest.scala
@@ -0,0 +1,40 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.compiler
+
+import org.scalajs.jasminetest.JasmineTest
+import scala.scalajs.js.Any.fromInt
+
+object CharTest extends JasmineTest {
+
+ describe("Char primitives") {
+
+ it("should always be positive (when coerced)") {
+ expect(-3.toByte.toChar.toInt).toEqual(65533)
+ expect(-100.toShort.toChar.toInt).toEqual(65436)
+ expect(-66000.toChar.toInt).toEqual(65072)
+ expect(-4567L.toChar.toInt).toEqual(60969)
+ expect(-5.3f.toChar.toInt).toEqual(65531)
+ expect(-7.9.toChar.toInt).toEqual(65529)
+ }
+
+ it("should overflow (when coerced)") {
+ expect(347876543.toChar.toInt).toEqual(11455)
+ expect(34234567876543L.toChar.toInt).toEqual(57279)
+ }
+
+ it("should overflow with *") {
+ def test(a: Char, b: Char, expected: Int): Unit =
+ expect(a * b).toEqual(expected)
+
+ // note: expected values are constant-folded by the compiler on the JVM
+ test(Char.MaxValue, Char.MaxValue, Char.MaxValue * Char.MaxValue)
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/FloatTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/FloatTest.scala
new file mode 100644
index 0000000..5eda04a
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/FloatTest.scala
@@ -0,0 +1,73 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.compiler
+
+import org.scalajs.jasminetest.JasmineTest
+
+object FloatTest extends JasmineTest {
+
+ def froundNotInlined(x: Double): Float = {
+ val y = x // so you don't inline me
+ y.toFloat
+ }
+
+ when("strict-floats").
+ describe("Strict floats") {
+
+ it("fround for special values") {
+ expect(froundNotInlined(Double.NaN).isNaN).toBeTruthy
+ expect(1 / froundNotInlined(0.0).toDouble).toBe(Double.PositiveInfinity)
+ expect(1 / froundNotInlined(-0.0).toDouble).toBe(Double.NegativeInfinity)
+ expect(froundNotInlined(Double.PositiveInfinity)).toBe(Float.PositiveInfinity)
+ expect(froundNotInlined(Double.NegativeInfinity)).toBe(Float.NegativeInfinity)
+ }
+
+ it("fround overflows") {
+ expect(froundNotInlined(1e200)).toBe(Double.PositiveInfinity)
+ expect(froundNotInlined(-1e200)).toBe(Double.NegativeInfinity)
+ }
+
+ it("fround underflows") {
+ expect(1 / froundNotInlined(1e-300).toDouble).toBe(Double.PositiveInfinity)
+ expect(1 / froundNotInlined(-1e-300).toDouble).toBe(Double.NegativeInfinity)
+ }
+
+ it("fround normal cases") {
+ def test(input: Double, expected: Double): Unit =
+ expect(input.toFloat.toDouble).toBe(expected)
+
+ // From MDN documentation
+ test(0.0, 0.0)
+ test(1.0, 1.0)
+ test(1.5, 1.5)
+ test(1.337, 1.3370000123977661)
+ test(-4.3, -4.300000190734863)
+
+ // Some bounds
+ test(Float.MinPositiveValue.toDouble, Float.MinPositiveValue.toDouble)
+ test(Float.MaxValue.toDouble, Float.MaxValue.toDouble)
+ test(Float.MinValue.toDouble, Float.MinValue.toDouble)
+
+ // Randomly generated Doubles
+ test(2.705609035558863E20, 2.7056090763400262E20)
+ test(-1.447710531503027E15, -1.447710532042752E15)
+ test(-5.1970024617732836E13, -5.1970022834176E13)
+ test(1.627661085098256E31, 1.6276610930768024E31)
+ test(-3.7731947682593834E-32, -3.7731946313230934E-32)
+ test(34.48229849163326, 34.4822998046875)
+ test(26.62034396181652, 26.620344161987305)
+ test(8.198435190113375E-24, 8.198434961596576E-24)
+ test(-6.079928908440255E-23, -6.079928963558556E-23)
+ test(3.3756949828462674E-13, 3.37569490589662E-13)
+ test(-1.2599049874324274E33, -1.2599049641449257E33)
+ test(6.08574575776438E-10, 6.085745796191588E-10)
+ test(1.973497969450596E-21, 1.973498047135062E-21)
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala
new file mode 100644
index 0000000..1379b80
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/InstanceTestsHijackedBoxedClassesTest.scala
@@ -0,0 +1,98 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.compiler
+
+import org.scalajs.jasminetest.JasmineTest
+import scala.scalajs.js
+
+object InstanceTestsHijackedBoxedClassesTest extends JasmineTest {
+
+ describe("Instance tests for hijacked boxed classes") {
+
+ it("should support isInstanceOf (positive)") {
+ expect((() : Any).isInstanceOf[Unit] ).toBeTruthy
+ expect((false : Any).isInstanceOf[Boolean]).toBeTruthy
+ expect(('a' : Any).isInstanceOf[Char] ).toBeTruthy
+ expect((65.toByte : Any).isInstanceOf[Byte] ).toBeTruthy
+ expect((654.toShort: Any).isInstanceOf[Short] ).toBeTruthy
+ expect((-4321 : Any).isInstanceOf[Int] ).toBeTruthy
+ expect((684321L : Any).isInstanceOf[Long] ).toBeTruthy
+ expect((3.14f : Any).isInstanceOf[Float] ).toBeTruthy
+ expect((3.14 : Any).isInstanceOf[Double] ).toBeTruthy
+ }
+
+ it("should support isInstanceOf (negative)") {
+ expect((12345: Any).isInstanceOf[Unit] ).toBeFalsy
+ expect((12345: Any).isInstanceOf[Boolean]).toBeFalsy
+ expect((12345: Any).isInstanceOf[Char] ).toBeFalsy
+ expect(('a' : Any).isInstanceOf[Byte] ).toBeFalsy
+ expect(('b' : Any).isInstanceOf[Short] ).toBeFalsy
+ expect(('c' : Any).isInstanceOf[Int] ).toBeFalsy
+ expect(('d' : Any).isInstanceOf[Long] ).toBeFalsy
+ expect(('f' : Any).isInstanceOf[Float] ).toBeFalsy
+ expect(('g' : Any).isInstanceOf[Double] ).toBeFalsy
+ }
+
+ it("should support asInstanceOf (positive)") {
+ def swallow(x: Any): Unit = ()
+ swallow((() : Any).asInstanceOf[Unit] )
+ swallow((false : Any).asInstanceOf[Boolean])
+ swallow(('a' : Any).asInstanceOf[Char] )
+ swallow((65.toByte : Any).asInstanceOf[Byte] )
+ swallow((654.toShort: Any).asInstanceOf[Short] )
+ swallow((-4321 : Any).asInstanceOf[Int] )
+ swallow((684321L : Any).asInstanceOf[Long] )
+ swallow((3.14f : Any).asInstanceOf[Float] )
+ swallow((3.14 : Any).asInstanceOf[Double] )
+ }
+
+ when("compliant-asinstanceof").
+ it("should support asInstanceOf (negative)") {
+ expect(() => (12345: Any).asInstanceOf[Unit] ).toThrow
+ expect(() => (12345: Any).asInstanceOf[Boolean]).toThrow
+ expect(() => (12345: Any).asInstanceOf[Char] ).toThrow
+ expect(() => ('a' : Any).asInstanceOf[Byte] ).toThrow
+ expect(() => ('b' : Any).asInstanceOf[Short] ).toThrow
+ expect(() => ('c' : Any).asInstanceOf[Int] ).toThrow
+ expect(() => ('d' : Any).asInstanceOf[Long] ).toThrow
+ expect(() => ('f' : Any).asInstanceOf[Float] ).toThrow
+ expect(() => ('g' : Any).asInstanceOf[Double] ).toThrow
+ }
+
+ it("should support isInstanceOf via java.lang.Class (positive)") {
+ def test(x: Any, clazz: Class[_]): Unit =
+ expect(clazz.isInstance(x)).toBeTruthy
+
+ test(() , classOf[scala.runtime.BoxedUnit])
+ test(false , classOf[java.lang.Boolean])
+ test('a' , classOf[java.lang.Character])
+ test(65.toByte , classOf[java.lang.Byte])
+ test(654.toShort, classOf[java.lang.Short])
+ test(-4321 , classOf[java.lang.Integer])
+ test(684321L , classOf[java.lang.Long])
+ test(3.14f , classOf[java.lang.Float])
+ test(3.14 , classOf[java.lang.Double])
+ }
+
+ it("should support isInstanceOf via java.lang.Class (negative)") {
+ def test(x: Any, clazz: Class[_]): Unit =
+ expect(clazz.isInstance(x)).toBeFalsy
+
+ test(12345, classOf[scala.runtime.BoxedUnit])
+ test(12345, classOf[java.lang.Boolean])
+ test(12345, classOf[java.lang.Character])
+ test('a' , classOf[java.lang.Byte])
+ test('b' , classOf[java.lang.Short])
+ test('c' , classOf[java.lang.Integer])
+ test('d' , classOf[java.lang.Long])
+ test('e' , classOf[java.lang.Float])
+ test('f' , classOf[java.lang.Double])
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/IntTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/IntTest.scala
new file mode 100644
index 0000000..60f8773
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/IntTest.scala
@@ -0,0 +1,206 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.compiler
+
+import org.scalajs.jasminetest.JasmineTest
+
+object IntTest extends JasmineTest {
+
+ /* General note on the way these tests are written:
+ * We leverage the constant folding applied by the Scala compiler to write
+ * sound tests. We always perform the same operation, on the same operands,
+ * once in a way constant folding understands, and once in a way it doesn't.
+ * Since constant folding is performed on the JVM, we know it has the right
+ * semantics.
+ */
+
+ // final val without type ascription to make sure these are constant-folded
+ final val MinVal = Int.MinValue
+ final val MaxVal = Int.MaxValue
+ final val AlmostMinVal = Int.MinValue + 43
+ final val AlmostMaxVal = Int.MaxValue - 36
+
+ describe("Int primitives") {
+
+ it("should support unary -") {
+ def test(a: Int, expected: Int): Unit =
+ expect(-a).toEqual(expected)
+
+ test(56, -56)
+ test(0, 0)
+ test(-36, 36)
+
+ test(MaxVal, -MaxVal)
+ test(MinVal, -MinVal)
+ test(-MaxVal, MaxVal)
+ test(AlmostMinVal, -AlmostMinVal)
+ test(AlmostMaxVal, -AlmostMaxVal)
+ }
+
+ it("should support +") {
+ def test(a: Int, b: Int, expected: Int): Unit =
+ expect(a + b).toEqual(expected)
+
+ test(56, 654, 56 + 654)
+ test(0, 25, 0 + 25)
+ test(-36, 13, -36 + 13)
+
+ test(MaxVal, 1, MaxVal + 1)
+ test(MinVal, -1, MinVal - 1)
+ test(MaxVal, MinVal, MaxVal + MinVal)
+ test(AlmostMinVal, -100, AlmostMinVal - 100)
+ test(AlmostMaxVal, 123, AlmostMaxVal + 123)
+ }
+
+ it("should support -") {
+ def test(a: Int, b: Int, expected: Int): Unit =
+ expect(a - b).toEqual(expected)
+
+ test(56, 654, 56 - 654)
+ test(0, 25, 0 - 25)
+ test(-36, 13, -36 - 13)
+
+ test(MaxVal, -1, MaxVal + 1)
+ test(MinVal, 1, MinVal - 1)
+ test(MaxVal, MinVal, MaxVal - MinVal)
+ test(AlmostMinVal, 100, AlmostMinVal - 100)
+ test(AlmostMaxVal, -123, AlmostMaxVal + 123)
+ }
+
+ it("should support *") {
+ def test(a: Int, b: Int, expected: Int): Unit =
+ expect(a * b).toEqual(expected)
+
+ test(56, 654, 56 * 654)
+ test(0, 25, 0 * 25)
+ test(-36, 13, -36 * 13)
+ test(-5, -6, -5 * -6)
+
+ test(MinVal, 1, MinVal * 1)
+ test(MinVal, -1, MinVal * -1)
+ test(MaxVal, 1, MaxVal * 1)
+ test(MaxVal, -1, MaxVal * -1)
+
+ test(MaxVal, MinVal, MaxVal * MinVal)
+ test(MaxVal, MaxVal, MaxVal * MaxVal)
+ test(MinVal, MaxVal, MinVal * MaxVal)
+ test(MinVal, MinVal, MinVal * MinVal)
+
+ test(AlmostMaxVal, 2, AlmostMaxVal * 2)
+ test(AlmostMaxVal, 5, AlmostMaxVal * 5)
+ test(AlmostMaxVal, -7, AlmostMaxVal * -7)
+ test(AlmostMaxVal, -14, AlmostMaxVal * -14)
+ test(AlmostMinVal, 100, AlmostMinVal * 100)
+ test(AlmostMaxVal, -123, AlmostMaxVal * -123)
+ }
+
+ it("should support /") {
+ def test(a: Int, b: Int, expected: Int): Unit =
+ expect(a / b).toEqual(expected)
+
+ test(654, 56, 654 / 56)
+ test(0, 25, 0 / 25)
+ test(-36, 13, -36 / 13)
+ test(-55, -6, -55 / -6)
+
+ test(MinVal, 1, MinVal / 1)
+ test(MinVal, -1, MinVal / -1)
+ test(MaxVal, 1, MaxVal / 1)
+ test(MaxVal, -1, MaxVal / -1)
+
+ test(MaxVal, MinVal, MaxVal / MinVal)
+ test(MaxVal, MaxVal, MaxVal / MaxVal)
+ test(MinVal, MaxVal, MinVal / MaxVal)
+ test(MinVal, MinVal, MinVal / MinVal)
+
+ test(AlmostMaxVal, 2, AlmostMaxVal / 2)
+ test(AlmostMaxVal, 5, AlmostMaxVal / 5)
+ test(AlmostMaxVal, -7, AlmostMaxVal / -7)
+ test(AlmostMaxVal, -14, AlmostMaxVal / -14)
+ test(AlmostMinVal, 100, AlmostMinVal / 100)
+ test(AlmostMaxVal, -123, AlmostMaxVal / -123)
+ }
+
+ unless("phantomjs"). // see #593
+ it("should support %") {
+ def test(a: Int, b: Int, expected: Int): Unit =
+ expect(a % b).toEqual(expected)
+
+ test(654, 56, 654 % 56)
+ test(0, 25, 0 % 25)
+ test(-36, 13, -36 % 13)
+ test(-55, -6, -55 % -6)
+
+ test(MinVal, 1, MinVal % 1)
+ test(MinVal, -1, MinVal % -1)
+ test(MaxVal, 1, MaxVal % 1)
+ test(MaxVal, -1, MaxVal % -1)
+
+ test(MaxVal, MinVal, MaxVal % MinVal)
+ test(MaxVal, MaxVal, MaxVal % MaxVal)
+ test(MinVal, MaxVal, MinVal % MaxVal)
+ test(MinVal, MinVal, MinVal % MinVal)
+
+ test(AlmostMaxVal, 2, AlmostMaxVal % 2)
+ test(AlmostMaxVal, 5, AlmostMaxVal % 5)
+ test(AlmostMaxVal, -7, AlmostMaxVal % -7)
+ test(AlmostMaxVal, -14, AlmostMaxVal % -14)
+ test(AlmostMinVal, 100, AlmostMinVal % 100)
+ test(AlmostMaxVal, -123, AlmostMaxVal % -123)
+ }
+
+ it("should support <<") {
+ def test(a: Int, b: Int, expected: Int): Unit =
+ expect(a << b).toEqual(expected)
+
+ test(0, 5, 0 << 5)
+ test(1, 5, 1 << 5)
+ test(13, 4, 13 << 4)
+ test(-35, 5, -35 << 5)
+ test(345, 0, 345 << 0)
+
+ test(MinVal, 0, MinVal << 0)
+ test(MaxVal, 0, MaxVal << 0)
+ test(MinVal, 1, MinVal << 1)
+ test(MaxVal, 1, MaxVal << 1)
+ }
+
+ it("should support >>") {
+ def test(a: Int, b: Int, expected: Int): Unit =
+ expect(a >> b).toEqual(expected)
+
+ test(0, 5, 0 >> 5)
+ test(32, 5, 32 >> 5)
+ test(31, 4, 31 >> 4)
+ test(-355, 5, -355 >> 5)
+ test(345, 0, 345 >> 0)
+
+ test(MinVal, 0, MinVal >> 0)
+ test(MaxVal, 0, MaxVal >> 0)
+ test(MinVal, 1, MinVal >> 1)
+ test(MaxVal, 1, MaxVal >> 1)
+ }
+
+ it("should support >>>") {
+ def test(a: Int, b: Int, expected: Int): Unit =
+ expect(a >>> b).toEqual(expected)
+
+ test(0, 5, 0 >>> 5)
+ test(32, 5, 32 >>> 5)
+ test(31, 4, 31 >>> 4)
+ test(-355, 5, -355 >>> 5)
+ test(345, 0, 345 >>> 0)
+
+ test(MinVal, 0, MinVal >>> 0)
+ test(MaxVal, 0, MaxVal >>> 0)
+ test(MinVal, 1, MinVal >>> 1)
+ test(MaxVal, 1, MaxVal >>> 1)
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/InteroperabilityTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/InteroperabilityTest.scala
new file mode 100644
index 0000000..594345a
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/InteroperabilityTest.scala
@@ -0,0 +1,528 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.compiler
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.{JasmineTest, JasmineTestFramework}
+import scala.scalajs.js.annotation._
+
+/*
+ * Based on examples in:
+ * http://lampwww.epfl.ch/~doeraene/scala-js/doc/js-interoperability.html
+ */
+object InteroperabilityTest extends JasmineTest {
+
+ describe("JavaScript interoperability") {
+
+ it("should support backquotes to escape Scala fields") {
+ val obj = js.eval("""
+ var interoperabilityTestFieldEscape = {
+ def: 0,
+ val: function(x) { if (x) this.def = x; return this.def; }
+ };
+ interoperabilityTestFieldEscape;
+ """).asInstanceOf[InteroperabilityTestFieldEscape]
+
+ obj.`def` = 7357
+ expect(obj.`def`).toEqual(7357)
+ expect(obj.`val`()).toEqual(7357)
+ expect(obj.`val`(42)).toEqual(42)
+ }
+
+ it("should support @JSName to specify the JavaScript name for fields") {
+ val obj = js.eval("""
+ var interoperabilityTestJSName = {
+ def: 42,
+ val: function(x) { if (x) this.def = x; return this.def; }
+ };
+ interoperabilityTestJSName;
+ """).asInstanceOf[InteroperabilityTestJSName]
+
+ expect(obj.value()).toEqual(42)
+ expect(obj.value(7357)).toEqual(7357)
+ }
+
+ it("should translate explicit getter and setter names to field access") {
+ val obj = js.eval("""
+ var interoperabilityTestProperty = { a: 1 };
+ interoperabilityTestProperty;
+ """).asInstanceOf[InteroperabilityTestProperty]
+
+ expect(obj.a).toEqual(1)
+ obj.a = 100
+ expect(obj.a).toEqual(100)
+ }
+
+ it("should support @JSName together with field access") {
+ val obj = js.eval("""
+ var interoperabilityTestProperty = { b: 1 };
+ interoperabilityTestProperty;
+ """).asInstanceOf[InteroperabilityTestPropertyNamed]
+
+ expect(obj.a).toEqual(1)
+ obj.a = 100
+ expect(obj.a).toEqual(100)
+ expect(obj.b).toEqual(100)
+ }
+
+ it("should support @JSBracketAccess to specify access using []-subscription") {
+ val obj = js.eval("""
+ var interoperabilityTestJSBracketAccess = [ 0, 1, 7357 ];
+ interoperabilityTestJSBracketAccess;
+ """).asInstanceOf[InteroperabilityTestJSBracketAccess]
+
+ expect(obj(2)).toEqual(7357)
+ obj(2) = 42
+ expect(obj(2)).toEqual(42)
+ }
+
+ it("should allow instanciation of JS classes inheriting from js.Object") {
+ js.eval("""
+ var InteroperabilityTestInherit = {
+ Pattern: function(x) {
+ this.field = 42;
+ this.method = function() {
+ return '42';
+ };
+ this.getConstructorParam = function() {
+ return x;
+ };
+ }
+ }
+ """)
+
+ val obj = new InteroperabilityTestPattern("Scala.js")
+ expect(obj.field).toEqual(42)
+ expect(obj.method).toEqual("42")
+ expect(obj.getConstructorParam).toEqual("Scala.js")
+ }
+
+ it("should acces top-level JS objects via Scala objects inheriting from js.Object") {
+ js.eval("""
+ var InteroperabilityTestTopLevelObject = function(value) {
+ return {
+ value: value,
+ valueAsInt: function() {
+ return parseInt(value);
+ }
+ };
+ }
+ """)
+
+ // Use alias for convenience: see end of file for definition
+ val TopLevel = InteroperabilityTestTopLevel
+
+ val obj = TopLevel("7357")
+ expect(obj.value).toEqual("7357")
+ expect(obj.valueAsInt).toEqual(7357)
+ }
+
+ it("should allow to call JS methods with variadic parameters") {
+ val obj = js.eval("""
+ var obj = {
+ foo: function() {
+ var args = new Array(arguments.length);
+ for (var i = 0; i < arguments.length; i++)
+ args[i] = arguments[i];
+ return args;
+ }
+ };
+ obj;
+ """)
+
+ val elems = Seq[js.Any]("plop", 42, 51)
+
+ val dyn = obj.asInstanceOf[js.Dynamic]
+ expect(dyn.foo()).toEqual(js.Array())
+ expect(dyn.foo(3, 6)).toEqual(js.Array(3, 6))
+ expect(dyn.foo("hello", false)).toEqual(js.Array("hello", false))
+ expect(dyn.applyDynamic("foo")(elems: _*)).toEqual(js.Array("plop", 42, 51))
+
+ val stat = obj.asInstanceOf[InteroperabilityTestVariadicMethod]
+ expect(stat.foo()).toEqual(js.Array())
+ expect(stat.foo(3, 6)).toEqual(js.Array(3, 6))
+ expect(stat.foo("hello", false)).toEqual(js.Array("hello", false))
+ expect(stat.foo(elems: _*)).toEqual(js.Array("plop", 42, 51))
+ }
+
+ it("should allow to call JS constructors with variadic parameters") {
+ import js.Dynamic.{newInstance => jsnew}
+
+ js.eval("""
+ var InteroperabilityTestVariadicCtor = function() {
+ var args = new Array(arguments.length);
+ for (var i = 0; i < arguments.length; i++)
+ args[i] = arguments[i];
+ this.args = args;
+ };
+ """)
+
+ val elems = Seq[js.Any]("plop", 42, 51)
+
+ val ctor = js.Dynamic.global.InteroperabilityTestVariadicCtor
+ expect(jsnew(ctor)().args).toEqual(js.Array())
+ expect(jsnew(ctor)(3, 6).args).toEqual(js.Array(3, 6))
+ expect(jsnew(ctor)("hello", false).args).toEqual(js.Array("hello", false))
+ expect(jsnew(ctor)(elems: _*).args).toEqual(js.Array("plop", 42, 51))
+
+ import scala.scalajs.testsuite.compiler.{InteroperabilityTestVariadicCtor => C}
+ expect(new C().args).toEqual(js.Array())
+ expect(new C(3, 6).args).toEqual(js.Array(3, 6))
+ expect(new C("hello", false).args).toEqual(js.Array("hello", false))
+ expect(new C(elems: _*).args).toEqual(js.Array("plop", 42, 51))
+ }
+
+ it("should acces top-level JS objects via Scala object inheriting from js.GlobalScope") {
+ js.eval("""
+ var interoperabilityTestGlobalScopeValue = "7357";
+ var interoperabilityTestGlobalScopeValueAsInt = function() {
+ return parseInt(interoperabilityTestGlobalScopeValue);
+ };
+ """)
+
+ // Use alias for convenience: see end of file for definition
+ val Global = InteroperabilityTestGlobalScope
+
+ expect(Global.interoperabilityTestGlobalScopeValue).toEqual("7357")
+ expect(Global.interoperabilityTestGlobalScopeValueAsInt).toEqual(7357)
+
+ Global.interoperabilityTestGlobalScopeValue = "42"
+ expect(Global.interoperabilityTestGlobalScopeValueAsInt).toEqual(42)
+ }
+
+ it("should protect receiver of raw JS apply if it's a select - #804") {
+ val rawReceiver = js.eval("""
+ var interoperabilityTestRawReceiver = {
+ member: 0xbad,
+ check: function(raw) { return this.member ? this.member : raw; }
+ };
+ interoperabilityTestRawReceiver;
+ """).asInstanceOf[InteroperabilityTestRawReceiver]
+
+ expect(rawReceiver.check(7357)).toEqual(7357)
+
+ val check = rawReceiver.check
+ expect(check(0x600d)).toEqual(0x600d)
+
+ class InScalaSelect(check: js.Function1[Int, Int]) {
+ @JSExport
+ val member: Int = 0xbad2
+ def test(): Unit = expect(check(5894)).toEqual(5894)
+ }
+ new InScalaSelect(check).test()
+ }
+
+ it("should properly handle default parameters") {
+ val obj = js.eval("""
+ var interoperabilityTestDefaultParam = {
+ fun: function() { return arguments; }
+ };
+ interoperabilityTestDefaultParam;
+ """).asInstanceOf[InteroperabilityTestDefaultParam]
+
+ // Helpers
+ import js.Dynamic.{literal => args}
+ val undef = js.undefined
+
+ expect(obj.simple(1)).toEqual(args(`0` = 1))
+ expect(obj.simple(1,5)).toEqual(args(`0` = 1, `1` = 5))
+ expect(obj.named(y = 5)).toEqual(args(`0` = undef, `1` = 5))
+ expect(obj.named(x = 5)).toEqual(args(`0` = 5))
+ expect(obj.multi()(1,2,3,4)()).toEqual(args(
+ `0` = undef,
+ `1` = 1,
+ `2` = 2,
+ `3` = 3,
+ `4` = 4))
+ expect(obj.multi(2)()(5)).toEqual(args(
+ `0` = 2,
+ `1` = 5))
+ }
+
+ it("should properly handle default parameters for constructors - #791") {
+ js.eval("""
+ var InteroperabilityTestCtor = function(x,y) {
+ this.values = Array(x || 6, y || 8)
+ }
+ """);
+
+ expect(new InteroperabilityTestCtor().values).toEqual(js.Array(6,8))
+ expect(new InteroperabilityTestCtor(y = 7).values).toEqual(js.Array(6,7))
+ expect(new InteroperabilityTestCtor(3).values).toEqual(js.Array(3,8))
+ expect(new InteroperabilityTestCtor(10, 2).values).toEqual(js.Array(10,2))
+ }
+
+ it("should generate exports for methods inherited from traits - #178") {
+ import js.annotation.JSExport
+
+ trait Foo {
+ @JSExport
+ def theValue = 1
+ }
+ class Bar extends Foo
+
+ val x = (new Bar).asInstanceOf[js.Dynamic]
+
+ // Call the export by using js.Dynamic
+ expect(x.theValue).toEqual(1)
+ }
+
+ it("should allow constructor params that are vals/vars in facades - #1277") {
+ js.eval("""
+ var InteroparabilityCtorInlineValue = function(x,y) {
+ this.x = x;
+ this.y = y;
+ }
+ """)
+
+ val obj = new InteroparabilityCtorInlineValue(10, -1)
+
+ expect(obj.x).toEqual(10)
+ expect(obj.y).toEqual(-1)
+
+ obj.y = 100
+
+ expect(obj.x).toEqual(10)
+ expect(obj.y).toEqual(100)
+ }
+
+ it("should unbox Chars received from calling a JS interop method") {
+ val obj = js.eval("""
+ var obj = {
+ get: function() { return JSUtils().stringToChar('e'); }
+ };
+ obj;
+ """).asInstanceOf[InteroperabilityTestCharResult]
+
+ expect(obj.get().toInt).toEqual('e'.toInt)
+ }
+
+ it("should box Chars given to a JS interop method") {
+ val obj = js.eval("""
+ var obj = {
+ twice: function(c) { c = JSUtils().charToString(c); return c+c; }
+ };
+ obj;
+ """).asInstanceOf[InteroperabilityTestCharParam]
+
+ expect(obj.twice('x')).toEqual("xx")
+ }
+
+ it("should unbox value classes received from calling a JS interop method") {
+ val obj = js.eval("""
+ var obj = {
+ test: function(vc) { return vc; }
+ };
+ obj;
+ """).asInstanceOf[InteroperabilityTestValueClassResult]
+
+ val r = obj.test(new SomeValueClass(5))
+ expect(r.i).toEqual(5)
+ }
+
+ it("should box value classes given to a JS interop method") {
+ val obj = js.eval("""
+ var obj = {
+ stringOf: function(vc) { return vc.toString(); }
+ };
+ obj;
+ """).asInstanceOf[InteroperabilityTestValueClassParam]
+
+ val vc = new SomeValueClass(7)
+ expect(obj.stringOf(vc)).toEqual("SomeValueClass(7)")
+ }
+
+ it("should not unbox values received from JS method in statement position") {
+ /* To test this, we verify that a purposefully ill-typed facade does not
+ * throw a ClassCastException when called in statement position.
+ */
+ val obj = js.eval("""
+ var obj = {
+ test: function() { return 4; } // typed as String in the trait
+ };
+ obj;
+ """).asInstanceOf[InteroperabilityTestNoUnboxResultInStatement]
+ obj.test() // in statement position, should not throw
+ if (JasmineTestFramework.hasTag("compliant-asinstanceof"))
+ expect(() => obj.test()).toThrow // in expression position, should throw
+ }
+
+ when("compliant-asinstanceof").
+ it("should protect conversions from JS types to Scala types") {
+ class Foo
+ val foo: Any = new Foo
+
+ val invalidNumber: js.prim.Number = foo.asInstanceOf[js.prim.Number]
+ val nullNumber: js.prim.Number = null
+ expect(() => invalidNumber: Double).toThrow
+ expect(nullNumber: Double).toEqual(0)
+
+ val invalidBoolean: js.prim.Boolean = foo.asInstanceOf[js.prim.Boolean]
+ val nullBoolean: js.prim.Boolean = null
+ expect(() => invalidBoolean: Boolean).toThrow
+ expect(nullBoolean: Boolean).toEqual(false)
+
+ val invalidString: js.prim.String = foo.asInstanceOf[js.prim.String]
+ val nullString: js.prim.String = null
+ expect(() => invalidString: String).toThrow
+ expect(nullString: String).toBeNull
+ }
+
+ when("compliant-asinstanceof").
+ it("should asInstanceOf values received from calling a JS interop method") {
+ val obj = js.eval("""
+ var obj = {
+ testChar: function() { return 5; },
+ testInt: function() { return 6.4; },
+ testShort: function() { return 60000; },
+ testDouble: function() { return JSUtils().stringToChar('e'); },
+ testString: function() { return {}; },
+ testValueClass: function() { return "hello"; },
+ testNormalClass: function() { return 45; },
+ testAny: function() { return {}; }
+ };
+ obj;
+ """).asInstanceOf[InteroperabilityTestAsInstanceOfResult]
+
+ expect(() => obj.testChar()).toThrow
+ expect(() => obj.testInt()).toThrow
+ expect(() => obj.testShort()).toThrow
+ expect(() => obj.testDouble()).toThrow
+ expect(() => obj.testString()).toThrow
+ expect(() => obj.testValueClass()).toThrow
+ expect(() => obj.testNormalClass()).toThrow
+ expect(() => obj.testAny()).not.toThrow
+ }
+
+ }
+
+ trait InteroperabilityTestFieldEscape extends js.Object {
+ var `def`: Int = js.native
+ def `val`(): Int = js.native
+ def `val`(n: Int): Int = js.native
+ }
+
+ trait InteroperabilityTestJSName extends js.Object {
+ @JSName("val")
+ def value(): Int = js.native
+ @JSName("val")
+ def value(n: Int): Int = js.native
+ }
+
+ trait InteroperabilityTestProperty extends js.Object {
+ def a_=(x: Int): Unit = js.native
+ def a: Int = js.native
+ }
+
+ trait InteroperabilityTestPropertyNamed extends js.Object {
+ @JSName("b")
+ def a_=(x: Int): Unit = js.native
+ @JSName("b")
+ def a: Int = js.native
+ def b: Int = js.native
+ }
+
+ trait InteroperabilityTestJSBracketAccess extends js.Object {
+ @JSBracketAccess
+ def apply(index: Int): Int = js.native
+ @JSBracketAccess
+ def update(index: Int, v: Int): Unit = js.native
+ }
+
+ trait InteroperabilityTestRawReceiver extends js.Object {
+ val check: js.Function1[Int, Int] = js.native
+ }
+
+ /** Trait with different method signatures, all forwarded to the same
+ * JS raw function that returns the argument list for inspection
+ */
+ trait InteroperabilityTestDefaultParam extends js.Object {
+ @JSName("fun")
+ def simple(x: Int, y: Int = 5): js.Any = js.native
+ @JSName("fun")
+ def named(x: Int = 1, y: Int = 1, z: Int = 1): js.Any = js.native
+ @JSName("fun")
+ def multi(x: Int = 1)(ys: Int*)(z: Int = 1): js.Any = js.native
+ }
+
+ trait InteroperabilityTestCharResult extends js.Object {
+ def get(): Char = js.native
+ }
+
+ trait InteroperabilityTestCharParam extends js.Object {
+ def twice(c: Char): String = js.native
+ }
+
+ trait InteroperabilityTestValueClassResult extends js.Object {
+ def test(vc: Any): SomeValueClass = js.native
+ }
+
+ trait InteroperabilityTestValueClassParam extends js.Object {
+ def stringOf(vc: SomeValueClass): String = js.native
+ }
+
+ trait InteroperabilityTestNoUnboxResultInStatement extends js.Object {
+ def test(): String = js.native
+ }
+
+ trait InteroperabilityTestAsInstanceOfResult extends js.Object {
+ def testChar(): Char = js.native
+ def testInt(): Int = js.native
+ def testShort(): Short = js.native
+ def testDouble(): Double = js.native
+ def testString(): String = js.native
+ def testValueClass(): SomeValueClass = js.native
+ def testNormalClass(): List[Int] = js.native
+ def testAny(): Any = js.native
+ }
+}
+
+/*
+ * Helper classes, traits and objects defined here since they cannot be nested.
+ */
+
+@JSName("InteroperabilityTestInherit.Pattern")
+class InteroperabilityTestPattern protected () extends js.Object {
+ def this(pattern: String) = this()
+ val field: Int = js.native
+ def method(): String = js.native
+ def getConstructorParam(): String = js.native
+}
+
+trait InteroperabilityTestTopLevel extends js.Object {
+ val value: String = js.native
+ def valueAsInt(): Int = js.native
+}
+
+@JSName("InteroperabilityTestTopLevelObject")
+object InteroperabilityTestTopLevel extends js.Object {
+ def apply(value: String): InteroperabilityTestTopLevel = js.native
+}
+
+trait InteroperabilityTestVariadicMethod extends js.Object {
+ def foo(args: Any*): js.Array[Any] = js.native
+}
+
+class InteroperabilityTestVariadicCtor(inargs: Any*) extends js.Object {
+ val args: js.Array[Any] = js.native
+}
+
+object InteroperabilityTestGlobalScope extends js.GlobalScope {
+ var interoperabilityTestGlobalScopeValue: String = js.native
+ def interoperabilityTestGlobalScopeValueAsInt(): Int = js.native
+}
+
+class SomeValueClass(val i: Int) extends AnyVal {
+ override def toString(): String = s"SomeValueClass($i)"
+}
+
+class InteroperabilityTestCtor(x: Int = 5, y: Int = ???) extends js.Object {
+ def values: js.Array[Int] = js.native
+}
+
+class InteroparabilityCtorInlineValue(val x: Int, var y: Int) extends js.Object
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/LongTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/LongTest.scala
new file mode 100644
index 0000000..01d6f6e
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/LongTest.scala
@@ -0,0 +1,159 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.compiler
+
+import scala.scalajs.js
+
+import org.scalajs.jasminetest.JasmineTest
+
+/**
+ * tests the compiler re-patching of native longs to
+ * scala.scalajs.runtime.Long
+ * see scala.scalajs.testsuite.jsinterop.RuntimeLongTest
+ * for a test of the implementation itself
+ */
+object LongTest extends JasmineTest {
+
+ describe("JavaScript 64-bit long compatibility") {
+ it("should correctly handle literals") {
+ expect(5L + 100L == 105L).toBeTruthy
+ expect(2147483649L + 2L == 2147483651L).toBeTruthy
+ expect(-2147483648L * 4 == -8589934592L).toBeTruthy
+ expect(4503599627370510L * (-4) == -18014398509482040L).toBeTruthy
+ }
+
+ it("should correctly dispatch unary ops on Longs") {
+ val x = 10L
+ expect(-x == -10L).toBeTruthy
+ val y = 5L
+ expect(-y == -5L).toBeTruthy
+ expect(+y == 5L).toBeTruthy
+ expect(~y == -6L).toBeTruthy
+ }
+
+ it("should correctly dispatch binary ops on Longs") {
+ expect(5L * 5F == 25F).toBeTruthy
+ expect(5L % 4F == 1F).toBeTruthy
+ expect(5F * 4L == 20F).toBeTruthy
+ }
+
+ it("should support shifts with Longs - #622") {
+ def l(x: Long): Long = x
+ def i(x: Int): Int = x
+
+ expect(l(-7L) >>> 100L == 268435455L).toBeTruthy
+ expect(l(-7L) >> 100L == -1L).toBeTruthy
+ expect(l(-7L) >> 100 == -1L).toBeTruthy
+ expect(l(-7L) >>> 100 == 268435455).toBeTruthy
+ expect(l(-7L) << 100L == -481036337152L).toBeTruthy
+ expect(l(-7L) << 100 == -481036337152L).toBeTruthy
+ expect(l(7L) << 100L == 481036337152L).toBeTruthy
+ expect(l(8L) << 100L == 549755813888L).toBeTruthy
+ expect(l(-7L) >>> 4 == 1152921504606846975L).toBeTruthy
+
+ expect(i(7) << 100).toEqual(112)
+ expect(i(-7) >> 100).toEqual(-1)
+ expect(i(-7) >>> 100).toEqual(268435455)
+ expect(i(-65) >> 100).toEqual(-5)
+ expect(i(-65) >> 4).toEqual(-5)
+ }
+
+ it("primitives should convert to Long") {
+ // Byte
+ expect(112.toByte.toLong == 112L).toBeTruthy
+ // Short
+ expect((-10).toShort.toLong == -10L).toBeTruthy
+ // Char
+ expect('A'.toLong == 65L).toBeTruthy
+ // Int
+ expect(5.toLong == 5L).toBeTruthy
+ // Long
+ expect(10L.toLong == 10L).toBeTruthy
+ // Float
+ expect(100000.6f.toLong == 100000L).toBeTruthy
+ // Double
+ expect(100000.6.toLong == 100000L).toBeTruthy
+ }
+
+ it("should support hashCode()") {
+ expect(0L .hashCode()).toEqual(0)
+ expect(55L .hashCode()).toEqual(55)
+ expect((-12L) .hashCode()).toEqual(11)
+ expect(10006548L .hashCode()).toEqual(10006548)
+ expect((-1098748L).hashCode()).toEqual(1098747)
+
+ expect(613354684553L .hashCode()).toEqual(-825638905)
+ expect(9863155567412L .hashCode()).toEqual(1910653900)
+ expect(3632147899696541255L.hashCode()).toEqual(1735398658)
+ expect(7632147899696541255L.hashCode()).toEqual(-1689438124)
+ }
+
+ it("should support ##") {
+ expect(0L .##).toEqual(0)
+ expect(55L .##).toEqual(55)
+ expect((-12L) .##).toEqual(-12)
+ expect(10006548L .##).toEqual(10006548)
+ expect((-1098748L).##).toEqual(-1098748)
+
+ expect(9863155567412L .##).toEqual(1910653900)
+ expect(3632147899696541255L.##).toEqual(1735398658)
+
+ // These two (correctly) give different results on 2.10 and 2.11
+ //expect(613354684553L .##).toEqual(-825638905) // xx06 on 2.10
+ //expect(7632147899696541255L.##).toEqual(-1689438124) // xx25 on 2.10
+ }
+
+ it("should correctly concat to string") {
+ val x = 20L
+ expect("asdf" + 5L + x + "hello").toEqual("asdf520hello")
+ expect(x + "hello").toEqual("20hello")
+ }
+
+ it("string should convert to Long") {
+ expect("45678901234567890".toLong == 45678901234567890L).toBeTruthy
+ }
+
+ it("should convert from and to js.prim.Number") {
+ val x = 5: js.prim.Number
+ expect((5L: js.prim.Number) == x).toBeTruthy
+ expect(x.toLong == 5L).toBeTruthy
+ }
+
+ it("should correctly implement is/asInstanceOf Longs") {
+ val dyn: Any = 5L
+ val stat: Long = 5L
+
+ expect(stat.asInstanceOf[Long]).toEqual(5L)
+ // models current scala behavior. See SI-1448
+ expect(stat.asInstanceOf[Int]).toEqual(5)
+
+ expect(stat.isInstanceOf[Long]).toBeTruthy
+ expect(stat.isInstanceOf[Int]).toBeFalsy
+
+ expect(dyn.asInstanceOf[Long]).toEqual(5L)
+
+ expect(dyn.isInstanceOf[Long]).toBeTruthy
+ expect(dyn.isInstanceOf[Int]).toBeFalsy
+ }
+
+ when("compliant-asinstanceof").
+ it("should correctly implement asInstanceOf Longs (negative)") {
+ val dyn: Any = 5L
+
+ expect(() => dyn.asInstanceOf[Int]).toThrow
+ }
+
+ it("should correctly compare to other numeric types") {
+ expect(5L == 5).toBeTruthy
+ expect(5 == 5L).toBeTruthy
+ expect(4 == 5l).toBeFalsy
+ expect('A' == 65L).toBeTruthy
+ }
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/OptimizerTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/OptimizerTest.scala
new file mode 100644
index 0000000..986c25a
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/OptimizerTest.scala
@@ -0,0 +1,43 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.compiler
+
+import org.scalajs.jasminetest.JasmineTest
+
+object OptimizerTest extends JasmineTest {
+
+ describe("Inlineable classes") {
+
+ it("must update fields of `this` in the computation of other fields - #1153") {
+ val foo = new InlineClassDependentFields(5)
+ expect(foo.x).toEqual(5)
+ expect(foo.b).toBeTruthy
+ expect(foo.y).toEqual(11)
+ }
+
+ it("must not break code that assigns `this` to a field") {
+ val foo = new InlineClassThisAlias(5)
+ expect(foo.z).toEqual(5)
+ }
+
+ }
+
+ @inline
+ class InlineClassDependentFields(val x: Int) {
+ val b = x > 3
+ val y = if (b) x + 6 else x-2
+ }
+
+ @inline
+ class InlineClassThisAlias(val x: Int) {
+ val t = this
+ val y = x
+ val z = t.y
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/ReflectionTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/ReflectionTest.scala
new file mode 100644
index 0000000..3e1d7a2
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/ReflectionTest.scala
@@ -0,0 +1,69 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.compiler
+
+import scala.language.implicitConversions
+
+import scala.scalajs.js
+
+import org.scalajs.jasminetest.JasmineTest
+
+/** Tests the little reflection we support */
+object ReflectionTest extends JasmineTest {
+
+ describe("Scala.js Reflection (through java.lang.Class)") {
+ it("should append $ to class name of objects") {
+ expect(TestObject.getClass.getName).toEqual(
+ "scala.scalajs.testsuite.compiler.ReflectionTest$TestObject$")
+ }
+
+ it("should support isInstance") {
+ class A
+ class B extends A
+ val b = new B
+ expect(classOf[A].isInstance(b)).toBeTruthy
+ expect(classOf[A].isInstance("hello")).toBeFalsy
+ }
+
+ it("getClass() for normal types") {
+ class Foo {
+ def bar() = super.getClass()
+ }
+ val foo = new Foo
+ expect(foo.getClass() eq classOf[Foo]).toBeTruthy
+ expect(foo.bar() eq classOf[Foo]).toBeTruthy
+ }
+
+ it("getClass() for anti-boxed primitive types") {
+ implicit def classAsAny(c: java.lang.Class[_]): js.Any =
+ c.asInstanceOf[js.Any]
+ expect((false: Any).getClass).toBe(classOf[java.lang.Boolean])
+ expect(('a': Any).getClass).toBe(classOf[java.lang.Character])
+ expect((1.toByte: Any).getClass).toBe(classOf[java.lang.Byte])
+ expect((1.toShort: Any).getClass).toBe(classOf[java.lang.Byte])
+ expect((1: Any).getClass).toBe(classOf[java.lang.Byte])
+ expect((1L: Any).getClass).toBe(classOf[java.lang.Long])
+ expect((1.5f: Any).getClass).toBe(classOf[java.lang.Float])
+ expect((1.5: Any).getClass).toBe(classOf[java.lang.Float])
+ expect(((): Any).getClass).toBe(classOf[scala.runtime.BoxedUnit])
+ }
+
+ it("Class.isAssignableFrom should mimic runtime type tests behavior - #879") {
+ expect(classOf[Short].isAssignableFrom(classOf[Byte])).toBeTruthy
+ expect(classOf[Byte].isAssignableFrom(classOf[Byte])).toBeTruthy
+ expect(classOf[Byte].isAssignableFrom(classOf[Short])).toBeFalsy
+ expect(classOf[Int].isAssignableFrom(classOf[Byte])).toBeTruthy
+ expect(classOf[Double].isAssignableFrom(classOf[Int])).toBeTruthy
+ expect(classOf[Int].isAssignableFrom(classOf[Double])).toBeFalsy
+ expect(classOf[Long].isAssignableFrom(classOf[Int])).toBeFalsy
+ }
+ }
+
+ object TestObject
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/ReflectiveCallTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/ReflectiveCallTest.scala
new file mode 100644
index 0000000..6020a5f
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/ReflectiveCallTest.scala
@@ -0,0 +1,330 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.compiler
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+import language.reflectiveCalls
+
+import java.lang.{Float => JFloat, Double => JDouble}
+
+object ReflectiveCallTest extends JasmineTest {
+
+ describe("Reflective Calls") {
+ it("should allow subtyping in return types") {
+ class A { def x = 1 }
+ class B extends A { override def x = 2 }
+
+ object Generator {
+ def generate(): B = new B
+ }
+
+ def f(x: { def generate(): A }) = x.generate
+
+ expect(f(Generator).x).toEqual(2)
+ }
+
+ it("should allow this.type in return types") {
+ type valueType = { def value: this.type }
+ def f(x: valueType) = x.value
+
+ class StringValue(x: String) {
+ def value: this.type = this
+ override def toString = s"StringValue($x)"
+ }
+
+ expect(f(new StringValue("foo")).toString).toEqual("StringValue(foo)")
+ }
+
+ it("should allow generic return types") {
+ case class Tata(name: String)
+
+ object Rec {
+ def e(x: Tata) = new Tata("iei")
+ }
+
+ def m[T](r: Object { def e(x: Tata): T}) =
+ r.e(new Tata("foo"))
+
+ expect(m[Tata](Rec).toString).toEqual("Tata(iei)")
+ }
+
+ it("should work with unary methods on primitive types") {
+ def fInt(x: Any { def unary_- :Int }) = -x
+ expect(fInt(1.toByte)).toEqual(-1)
+ expect(fInt(1.toShort)).toEqual(-1)
+ expect(fInt(1.toChar)).toEqual(-1)
+ expect(fInt(1)).toEqual(-1)
+
+ def fLong(x: Any { def unary_- :Long }) = -x
+ expect(fLong(1L)).toEqual(-1L)
+
+ def fFloat(x: Any { def unary_- :Float}) = -x
+ expect(fFloat(1.5f)).toEqual(-1.5f)
+
+ def fDouble(x: Any { def unary_- :Double }) = -x
+ expect(fDouble(1.5)).toEqual(-1.5)
+
+ def fBoolean(x: Any { def unary_! :Boolean }) = !x
+ expect(fBoolean(false)).toBeTruthy
+ expect(fBoolean(true)).toBeFalsy
+ }
+
+ it("should work with binary operators on primitive types") {
+ def fLong(x: Any { def +(x: Long): Long }) = x + 5L
+ expect(fLong(5.toByte)).toEqual(10L)
+ expect(fLong(10.toShort)).toEqual(15L)
+ expect(fLong(10.toChar)).toEqual(15L)
+ expect(fLong(-1)).toEqual(4L)
+ expect(fLong(17L)).toEqual(22L)
+
+ def fInt(x: Any { def /(x: Int): Int }) = x / 7
+ expect(fInt(65.toByte)).toEqual(9)
+ expect(fInt(15.toShort)).toEqual(2)
+ expect(fInt(25.toChar)).toEqual(3)
+ expect(fInt(-40)).toEqual(-5)
+
+ def fShort(x: Any { def +(x: Short): Int }) = x + 6.toShort
+ expect(fShort(65.toByte)).toEqual(71)
+ expect(fShort(15.toShort)).toEqual(21)
+ expect(fShort(25.toChar)).toEqual(31)
+ expect(fShort(-40)).toEqual(-34)
+
+ def fFloat(x: Any { def %(x: Float): Float}) = x % 3.4f
+ expect(fFloat(5.5f)).toEqual(2.1f)
+
+ def fDouble(x: Any { def /(x: Double): Double }) = x / 1.4
+ expect(fDouble(-1.5)).toEqual(-1.0714285714285714)
+
+ def fBoolean(x: Any { def &&(x: Boolean): Boolean }) = x && true
+ expect(fBoolean(false)).toBeFalsy
+ expect(fBoolean(true)).toBeTruthy
+ }
+
+ it("should work with equality operators on primitive types") {
+ def fNum(obj: Any { def ==(x: Int): Boolean }) = obj == 5
+ expect(fNum(5.toByte)).toBeTruthy
+ expect(fNum(6.toByte)).toBeFalsy
+ expect(fNum(5.toShort)).toBeTruthy
+ expect(fNum(7.toShort)).toBeFalsy
+ expect(fNum(5.toChar)).toBeTruthy
+ expect(fNum('r')).toBeFalsy
+ expect(fNum(5)).toBeTruthy
+ expect(fNum(-4)).toBeFalsy
+ expect(fNum(5L)).toBeTruthy
+ expect(fNum(400L)).toBeFalsy
+ expect(fNum(5.0f)).toBeTruthy
+ expect(fNum(5.6f)).toBeFalsy
+ expect(fNum(5.0)).toBeTruthy
+ expect(fNum(7.9)).toBeFalsy
+ def fBool(obj: Any { def ==(x: Boolean): Boolean }) = obj == false
+ expect(fBool(true)).toBeFalsy
+ expect(fBool(false)).toBeTruthy
+
+ def fNumN(obj: Any { def !=(x: Int): Boolean }) = obj != 5
+ expect(fNumN(5.toByte)).toBeFalsy
+ expect(fNumN(6.toByte)).toBeTruthy
+ expect(fNumN(5.toShort)).toBeFalsy
+ expect(fNumN(7.toShort)).toBeTruthy
+ expect(fNumN(5.toChar)).toBeFalsy
+ expect(fNumN('r')).toBeTruthy
+ expect(fNumN(5)).toBeFalsy
+ expect(fNumN(-4)).toBeTruthy
+ expect(fNumN(5L)).toBeFalsy
+ expect(fNumN(400L)).toBeTruthy
+ expect(fNumN(5.0f)).toBeFalsy
+ expect(fNumN(5.6f)).toBeTruthy
+ expect(fNumN(5.0)).toBeFalsy
+ expect(fNumN(7.9)).toBeTruthy
+ def fBoolN(obj: Any { def !=(x: Boolean): Boolean }) = obj != false
+ expect(fBoolN(true)).toBeTruthy
+ expect(fBoolN(false)).toBeFalsy
+
+ }
+
+ it("should work with Arrays") {
+ type UPD = { def update(i: Int, x: String): Unit }
+ type APL = { def apply(i: Int): String }
+ type LEN = { def length: Int }
+ type CLONE = Any { def clone(): Object }
+ def upd(obj: UPD, i: Int, x: String) = obj.update(i,x)
+ def apl(obj: APL, i: Int) = obj.apply(i)
+ def len(obj: LEN) = obj.length
+ def clone(obj: CLONE) = obj.clone
+
+ val x = Array("asdf","foo","bar")
+ val y = clone(x).asInstanceOf[Array[String]]
+
+ expect(len(x)).toEqual(3)
+ expect(apl(x,0)).toEqual("asdf")
+ upd(x,1,"2foo")
+ expect(x(1)).toEqual("2foo")
+ expect(y(1)).toEqual("foo")
+ }
+
+ it("should work with Arrays of primitive values") {
+ type UPD = { def update(i: Int, x: Int): Unit }
+ type APL = { def apply(i: Int): Int}
+ type LEN = { def length: Int }
+ type CLONE = Any { def clone(): Object }
+ def upd(obj: UPD, i: Int, x: Int) = obj.update(i,x)
+ def apl(obj: APL, i: Int) = obj.apply(i)
+ def len(obj: LEN) = obj.length
+ def clone(obj: CLONE) = obj.clone
+
+ val x = Array(5,2,8)
+ val y = clone(x).asInstanceOf[Array[Int]]
+
+ expect(len(x)).toEqual(3)
+ expect(apl(x,0)).toEqual(5)
+ upd(x,1,1000)
+ expect(x(1)).toEqual(1000)
+ expect(y(1)).toEqual(2)
+ }
+
+ it("should work with Strings") {
+ def get(obj: { def codePointAt(str: Int): Int }) =
+ obj.codePointAt(1)
+ expect(get("Hi")).toEqual('i'.toInt)
+
+ def sub(x: { def substring(x: Int): AnyRef }) = x.substring(5)
+ expect(sub("asdfasdfasdf") == "sdfasdf").toBeTruthy
+
+ type LEN_A = { def length: Any }
+ def lenA(x: LEN_A) = x.length
+ expect(lenA("asdf") == 4).toBeTruthy
+ }
+
+ it("should properly generate forwarders for inherited methods") {
+ trait A {
+ def foo: Int
+ }
+
+ abstract class B extends A
+
+ class C extends B {
+ def foo = 1
+ }
+
+ def call(x: { def foo: Int }) = x.foo
+
+ expect(call(new C)).toEqual(1)
+ }
+
+ it("should work on java.lang.Object.{ notify, notifyAll } - #303") {
+ type ObjNotifyLike = Any {
+ def notify(): Unit
+ def notifyAll(): Unit
+ }
+ def objNotifyTest(obj: ObjNotifyLike) = {
+ obj.notify()
+ obj.notifyAll()
+ 1
+ }
+
+ class A
+
+ expect(objNotifyTest(new A())).toEqual(1)
+ }
+
+ it("should work on java.lang.Object.clone - #303") {
+ type ObjCloneLike = Any { def clone(): AnyRef }
+ def objCloneTest(obj: ObjCloneLike) = obj.clone()
+
+ class B(val x: Int) extends Cloneable {
+ override def clone() = super.clone
+ }
+
+ val b = new B(1)
+ val bClone = objCloneTest(b).asInstanceOf[B]
+
+ expect(b eq bClone).toBeFalsy
+ expect(bClone.x).toEqual(1)
+ }
+
+ it("should work on scala.AnyRef.{ eq, ne } - #303") {
+ type ObjEqLike = Any {
+ def eq(that: AnyRef): Boolean
+ def ne(that: AnyRef): Boolean
+ }
+ def objEqTest(obj: ObjEqLike, that: AnyRef) = obj eq that
+ def objNeTest(obj: ObjEqLike, that: AnyRef) = obj ne that
+
+ class A
+
+ val a1 = new A
+ val a2 = new A
+
+ expect(objEqTest(a1,a2)).toBeFalsy
+ expect(objEqTest(a1,a1)).toBeTruthy
+
+ expect(objNeTest(a1,a2)).toBeTruthy
+ expect(objNeTest(a1,a1)).toBeFalsy
+ }
+
+ it("should work on java.lang.{Float,Double}.{isNaN,isInfinite}") {
+ type FloatingNumberLike = Any {
+ def isNaN(): Boolean
+ def isInfinite(): Boolean
+ }
+ def test(x: FloatingNumberLike, isNaN: Boolean,
+ isInfinite: Boolean) = {
+ expect(x.isNaN()).toEqual(isNaN)
+ expect(x.isInfinite()).toEqual(isInfinite)
+ }
+
+ test(new JFloat(Float.NaN), true, false)
+ test(new JFloat(Float.PositiveInfinity), false, true)
+ test(new JFloat(Float.NegativeInfinity), false, true)
+ test(new JFloat(54.67), false, false)
+
+ test(new JDouble(Double.NaN), true, false)
+ test(new JDouble(Double.PositiveInfinity), false, true)
+ test(new JDouble(Double.NegativeInfinity), false, true)
+ test(new JDouble(54.67), false, false)
+ }
+
+ it("should work with default arguments - #390") {
+ def pimpIt(a: Int) = new {
+ def foo(b: Int, c: Int = 1): Int = a + b + c
+ }
+
+ expect(pimpIt(1).foo(2)).toEqual(4)
+ expect(pimpIt(2).foo(2,4)).toEqual(8)
+ }
+
+ it("should unbox all types of arguments - #899") {
+ class Foo {
+ def makeInt: Int = 5
+ def testInt(x: Int): Unit = expect(x).toEqual(5)
+
+ def makeRef: Option[String] = Some("hi")
+ def testRef(x: Option[String]): Unit = expect(x == Some("hi")).toBeTruthy
+ }
+
+ /* Note: we should also test with value classes, except that Scala itself
+ * does not support value classes as parameters or result type of
+ * methods in structural types.
+ */
+
+ def test(foo: {
+ def makeInt: Int
+ def testInt(x: Int): Unit
+ def makeRef: Option[String]
+ def testRef(x: Option[String]): Unit
+ }): Unit = {
+ foo.testInt(foo.makeInt)
+ foo.testRef(foo.makeRef)
+ }
+
+ test(new Foo)
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/RegressionTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/RegressionTest.scala
new file mode 100644
index 0000000..19cceb2
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/RegressionTest.scala
@@ -0,0 +1,287 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.compiler
+
+import scala.annotation.tailrec
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+object RegressionTest extends JasmineTest {
+
+ class Bug218Foo[T](val x: T) extends AnyVal
+
+ describe("Scala.js compiler regression tests") {
+
+ it("Wrong division conversion (7 / 2.0) - #18") {
+ val div = 7 / 2.0
+ expect(div).toEqual(3.5)
+ expect(div.getClass.getName).toEqual("double")
+
+ val mod = 7 % 2.0
+ expect(mod).toEqual(1.0)
+ expect(mod.getClass.getName).toEqual("double")
+ }
+
+ it("js.prim.String + js.prim.String is ambiguous - #20") {
+ val a: js.prim.String = "a"
+ val b: js.prim.String = "b"
+ val c: js.prim.String = a + b
+ expect(c).toEqual("ab")
+ }
+
+ it("Abort with some pattern match guards - #22") {
+ object PatternMatchGuards {
+ def go(f: Int => Int) = f(1)
+ def main(): Unit = {
+ go {
+ case x if false => x
+ }
+ }
+ }
+ // Nothing to check
+ }
+
+ it("Bad encoding for characters spanning 2 UTF-16 chars - #23") {
+ val str = "A∀\uD835\uDCAB"
+ var s: String = ""
+ for (c <- str) {
+ val code: Int = c
+ s = s + code + " "
+ }
+ expect(s).toEqual("65 8704 55349 56491 ")
+ }
+
+ it("String concatenation with null - #26") {
+ val x: Object = null
+ expect(x + "check").toEqual("nullcheck")
+ }
+
+ class Bug66A(s: String, e: Object) {
+ def this(e: Object) = this("", e)
+ def this(s: String) = this(s, "")
+ }
+ class Bug66B(s: String, e: Object) extends Bug66A(s)
+
+ it("should emit static calls when forwarding to another constructor - #66") {
+ new Bug66B("", "")
+ }
+
+ it("should not swallow Unit expressions when converting to js.prim.Undefined - #83") {
+ var effectHappened = false
+ def doEffect(): Unit = effectHappened = true
+ def f(): js.prim.Undefined = doEffect()
+ f()
+ expect(effectHappened).toBeTruthy
+ }
+
+ it("should correctly call subSequence on non-string CharSequences - #55") {
+ val arr: CharSequence = Array('a','b','c','d')
+ val ss = arr.subSequence(2,3)
+ expect(ss.length()).toEqual(1)
+ expect(ss.charAt(0)).toEqual('c')
+ }
+
+ it("should correctly concat primitive values to strings - #113") {
+ expect(4 + "foo").toEqual("4foo")
+ expect('a' + "foo").toEqual("afoo")
+ }
+
+ it("should resolve overloads on scala.Function.apply when converting to js.Function - #125") {
+ class Fct extends Function1[Int,Any] {
+ def apply(n: Int) = n
+ }
+
+ val scalaFunction = new Fct
+ val jsFunction: js.Any = scalaFunction
+ val thisFunction: js.ThisFunction = scalaFunction
+ }
+
+ it("should correctly dispatch calls on private functions - #165") {
+ class A {
+ private def x = 1
+ def value = x
+ }
+ class B extends A {
+ private def x = 2
+ }
+ expect(new B().value).toEqual(1)
+ }
+
+ it("should correctly mangle JavaScript reserved identifiers - #153") {
+ // Class name
+ class break {
+ // class variable
+ var continue = 1
+ // method name
+ def switch = {
+ // local name
+ val default = 2
+ default
+ }
+ }
+ trait Foo {
+ // static member (through mixin)
+ def function = 3
+ }
+
+ val x = new break with Foo
+ expect(x.continue).toEqual(1)
+ expect(x.switch).toEqual(2)
+ expect(x.function).toEqual(3)
+ }
+
+ it("should correctly mangle identifiers starting with a digit - #153") {
+ // Class name
+ class `0` {
+ // class variable
+ var `1` = 1
+ // method name
+ def `2` = {
+ // local name
+ val `22` = 2
+ `22`
+ }
+ }
+ trait Foo {
+ // static member (through mixin)
+ def `3` = 3
+ }
+
+ val x = new `0` with Foo
+ expect(x.`1`).toEqual(1)
+ expect(x.`2`).toEqual(2)
+ expect(x.`3`).toEqual(3)
+ }
+
+ it("should reserve `eval` and `arguments` - #743") {
+ val eval = 5
+ expect(eval).toEqual(5)
+ val arguments = "hello"
+ expect(arguments).toEqual("hello")
+ }
+
+ it("should support class literals for existential value types - #218") {
+ expect(scala.reflect.classTag[Bug218Foo[_]].toString).toEqual(
+ "scala.scalajs.testsuite.compiler.RegressionTest$Bug218Foo")
+ }
+
+ it("should support Buffer - #268") {
+ val a = scala.collection.mutable.Buffer.empty[Int]
+ a.insert(0, 0)
+ a.remove(0)
+ for (i <- 0 to 10) {
+ a.insert(a.length / 2, i)
+ }
+ expect(a.mkString(", ")).toEqual("1, 3, 5, 7, 9, 10, 8, 6, 4, 2, 0")
+ }
+
+ it("should not call equals when comparing with a literal null - #362") {
+ class A { override def equals(x: Any) = !(this == null) }
+
+ val x = new A
+ val y = new A
+
+ // If the null comparisons actually call equals, the following two will
+ // cause infinite recursion
+ expect(x == y).toBeTruthy
+ expect(y == x).toBeTruthy
+ }
+
+ it("should unbox null to the zero of types - #674") {
+ class Box[A] {
+ var value: A = _
+ }
+ def zero[A]: A = new Box[A].value
+
+ /* Note: the same shape of test for Unit does not work, but it seems to
+ * be a problem in scalac because it does not work on the JVM either.
+ */
+
+ val bool = zero[Boolean]
+ expect((bool: Any).isInstanceOf[Boolean]).toBeTruthy
+ expect(bool == false).toBeTruthy
+
+ val char = zero[Char]
+ expect((char: Any).isInstanceOf[Char]).toBeTruthy
+ expect(char == '\u0000').toBeTruthy
+
+ val byte = zero[Byte]
+ expect((byte: Any).isInstanceOf[Byte]).toBeTruthy
+ expect(byte == 0.toByte).toBeTruthy
+
+ val short = zero[Short]
+ expect((short: Any).isInstanceOf[Short]).toBeTruthy
+ expect(short == 0.toShort).toBeTruthy
+
+ val int = zero[Int]
+ expect((int: Any).isInstanceOf[Int]).toBeTruthy
+ expect(int == 0).toBeTruthy
+
+ val long = zero[Long]
+ expect((long: Any).isInstanceOf[Long]).toBeTruthy
+ expect(long == 0L).toBeTruthy
+
+ val float = zero[Float]
+ expect((float: Any).isInstanceOf[Float]).toBeTruthy
+ expect(float == 0.0f).toBeTruthy
+
+ val double = zero[Double]
+ expect((double: Any).isInstanceOf[Double]).toBeTruthy
+ expect(double == 0.0).toBeTruthy
+
+ val ref = zero[AnyRef]
+ expect(ref == null).toBeTruthy
+ }
+
+ it("Param defs in tailrec methods should be considered mutable - #825") {
+ @tailrec
+ def foo(x: Int, y: Int): Unit = {
+ if (x < y) foo(y, x)
+ else {
+ expect(x).toEqual(4)
+ expect(y).toEqual(2)
+ }
+ }
+ foo(2, 4)
+ }
+
+ it("null.synchronized should throw - #874") {
+ expect(() => null.synchronized(5)).toThrow
+ }
+
+ it("x.synchronized should preserve side-effects of x") {
+ var c = 0
+ def x = { c += 1; this }
+ expect(x.synchronized(5)).toEqual(5)
+ expect(c).toEqual(1)
+ }
+
+ it("IR checker should allow Apply/Select on NullType and NothingType - #1123") {
+ def giveMeANull(): Null = null
+ expect(() => (giveMeANull(): StringBuilder).append(5)).toThrow
+ expect(() => (giveMeANull(): scala.runtime.IntRef).elem).toThrow
+
+ def giveMeANothing(): Nothing = sys.error("boom")
+ expect(() => (giveMeANothing(): StringBuilder).append(5)).toThrow
+ expect(() => (giveMeANothing(): scala.runtime.IntRef).elem).toThrow
+ }
+
+ it("should not put bad flags on caseaccessor export forwarders - #1191") {
+ // This test used to choke patmat
+
+ @scala.scalajs.js.annotation.JSExportAll
+ case class T(one: Int, two: Int)
+
+ val T(a, b) = T(1, 2)
+
+ expect(a).toEqual(1)
+ expect(b).toEqual(2)
+ }
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/RuntimeTypesTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/RuntimeTypesTest.scala
new file mode 100644
index 0000000..b1a32c4
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/RuntimeTypesTest.scala
@@ -0,0 +1,77 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.compiler
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+import scala.util.{ Try, Failure }
+
+object RuntimeTypesTest extends JasmineTest {
+
+ describe("scala.Nothing") {
+
+ when("compliant-asinstanceof").
+ it("casts to scala.Nothing should fail") {
+ val msg = Try("a".asInstanceOf[Nothing]) match {
+ case Failure(thr: ClassCastException) => thr.getMessage
+ case _ => "not failed"
+ }
+ expect(msg).toEqual("a is not an instance of scala.runtime.Nothing$")
+ }
+
+ it("Array[Nothing] should be allowed to exists and be castable") {
+ val arr = Array[Nothing]()
+ arr.asInstanceOf[Array[Nothing]]
+ }
+
+ it("Array[Array[Nothing]], too") {
+ val arr = Array[Array[Nothing]]()
+ arr.asInstanceOf[Array[Array[Nothing]]]
+ // This apparently works too... Dunno why
+ arr.asInstanceOf[Array[Nothing]]
+ }
+
+ }
+
+ describe("scala.Null") {
+
+ when("compliant-asinstanceof").
+ it("casts to scala.Null should fail for everything else but null") {
+ val msg = Try("a".asInstanceOf[Null]) match {
+ case Failure(thr: ClassCastException) => thr.getMessage
+ case _ => "not failed"
+ }
+ expect(msg).toEqual("a is not an instance of scala.runtime.Null$")
+ }
+
+ it("classTag of scala.Null should contain proper Class[_] - #297") {
+ val tag = scala.reflect.classTag[Null]
+ expect(tag.runtimeClass != null).toBeTruthy
+ expect(tag.runtimeClass.getName).toEqual("scala.runtime.Null$")
+ }
+
+ it("casts to scala.Null should succeed on null") {
+ null.asInstanceOf[Null]
+ }
+
+ it("Array[Null] should be allowed to exist and be castable") {
+ val arr = Array.fill[Null](5)(null)
+ arr.asInstanceOf[Array[Null]]
+ }
+
+ it("Array[Array[Null]] too") {
+ val arr = Array.fill[Null](5,5)(null)
+ arr.asInstanceOf[Array[Array[Null]]]
+ // This apparently works too... Dunno why
+ arr.asInstanceOf[Array[Null]]
+ }
+
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/ShortTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/ShortTest.scala
new file mode 100644
index 0000000..10746ba
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/ShortTest.scala
@@ -0,0 +1,38 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.compiler
+
+import org.scalajs.jasminetest.JasmineTest
+import scala.scalajs.js
+
+object ShortTest extends JasmineTest {
+
+ describe("Short primitives") {
+
+ it("should always be in their range") {
+ def test(x: Int, y: Short): Unit =
+ expect(x.toShort).toEqual(y)
+
+ test(0, 0)
+ test(-500, -500)
+ test(-90000, -24464)
+ test(123456789, -13035)
+ test(-40000, 25536)
+ test(65536, 0)
+ test(32768, -32768)
+
+ def testC(x: Char, y: Short): Unit =
+ expect(x.toShort).toEqual(y)
+
+ testC(-1.toChar, -1)
+ testC(200.toChar, 200)
+ testC(60000.toChar, -5536)
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/UnitTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/UnitTest.scala
new file mode 100644
index 0000000..8e2be64
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/compiler/UnitTest.scala
@@ -0,0 +1,47 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.compiler
+
+import org.scalajs.jasminetest.JasmineTest
+import scala.scalajs.js
+
+object UnitTest extends JasmineTest {
+
+ describe("Unit primitive") {
+
+ it("should have toString()") {
+ expect(().toString()).toEqual("undefined")
+ expect(((): Any).toString()).toEqual("undefined")
+ }
+
+ it("should have hashCode()") {
+ expect(().hashCode()).toEqual(0)
+ expect(((): Any).hashCode()).toEqual(0)
+ expect(().##).toEqual(0)
+ }
+
+ it("should equal itself") {
+ expect(().equals(())).toBeTruthy
+ expect(((): Any).equals((): Any)).toBeTruthy
+ }
+
+ it("should not equal other values") {
+ def testAgainst(v: Any): Unit = {
+ expect(().equals(v)).toBeFalsy
+ expect(((): Any).equals(v)).toBeFalsy
+ }
+
+ testAgainst(0)
+ testAgainst(1)
+ testAgainst(null)
+ testAgainst(false)
+ testAgainst("")
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ArraysTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ArraysTest.scala
new file mode 100644
index 0000000..d0d97f1
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ArraysTest.scala
@@ -0,0 +1,749 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import language.implicitConversions
+
+import scala.scalajs.js
+import scala.scalajs.js.JSConverters._
+
+import org.scalajs.jasminetest.JasmineTest
+
+import java.util.{ Arrays, Comparator }
+
+import scala.reflect.ClassTag
+
+object ArraysTest extends ArraysTest
+
+/** This is also used in the typedarray package to test scala.Arrays backed
+ * by TypedArrays
+ */
+trait ArraysTest extends JasmineTest {
+
+ // Just in here, we allow ourselves to do this
+ implicit def array2jsArray[T](arr: Array[T]): js.Array[T] = arr.toJSArray
+
+ /** Overridden by typedarray tests */
+ def Array[T : ClassTag](v: T*): scala.Array[T] = scala.Array(v: _*)
+
+ /** Overridden by typedarray tests */
+ def testBody(suite: => Unit) = describe("java.util.Arrays")(suite)
+
+ val stringComparator = new Comparator[String]() {
+ def compare(s1: String, s2: String) = s1.compareTo(s2)
+ }
+
+ val intComparator = new Comparator[Int]() {
+ def compare(i1: Int, i2: Int) = i1 - i2
+ }
+
+ testBody {
+
+ it("should respond to `sort` for Int") {
+ val scalaInts = Array(5, 3, 6, 1, 2, 4)
+ val ints = new Array[Object](scalaInts.length)
+ for (i <- 0 until scalaInts.length)
+ ints(i) = scalaInts(i).asInstanceOf[Object]
+ val sorted = Array(1, 2, 3, 4, 5, 6)
+
+ Arrays.sort(ints, intComparator.asInstanceOf[Comparator[Object]])
+ expect(ints).toEqual(Array(1, 2, 3, 4, 5, 6))
+ }
+
+ it("should respond to `sort` for String") {
+ val scalajs: Array[Object] = Array("S", "c", "a", "l", "a", ".", "j", "s")
+ val sorted = Array(".", "S", "a", "a", "c", "j", "l", "s")
+
+ Arrays.sort(scalajs, stringComparator.asInstanceOf[Comparator[Object]])
+ expect(scalajs).toEqual(sorted)
+ }
+
+ it("should respond to `fill` for Boolean") {
+ val booleans = new Array[Boolean](6)
+ Arrays.fill(booleans, false)
+ expect(booleans).toEqual(Array(false, false, false, false, false, false))
+
+ Arrays.fill(booleans, true)
+ expect(booleans).toEqual(Array(true, true, true, true, true, true))
+ }
+
+ it("should respond to `fill` with start and end index for Boolean") {
+ val booleans = new Array[Boolean](6)
+ Arrays.fill(booleans, 1, 4, true)
+ expect(booleans).toEqual(Array(false, true, true, true, false, false))
+ }
+
+ it("should respond to `fill` for Byte") {
+ val bytes = new Array[Byte](6)
+ Arrays.fill(bytes, 42.toByte)
+ expect(bytes).toEqual(Array[Byte](42, 42, 42, 42, 42, 42))
+
+ Arrays.fill(bytes, -1.toByte)
+ expect(bytes).toEqual(Array[Byte](-1, -1, -1, -1, -1, -1))
+ }
+
+ it("should respond to `fill` with start and end index for Byte") {
+ val bytes = new Array[Byte](6)
+ Arrays.fill(bytes, 1, 4, 42.toByte)
+ expect(bytes).toEqual(Array[Byte](0, 42, 42, 42, 0, 0))
+
+ Arrays.fill(bytes, 2, 5, -1.toByte)
+ expect(bytes).toEqual(Array[Byte](0, 42, -1, -1, -1, 0))
+ }
+
+ it("should respond to `fill` for Short") {
+ val shorts = new Array[Short](6)
+ Arrays.fill(shorts, 42.toShort)
+ expect(shorts).toEqual(Array[Short](42, 42, 42, 42, 42, 42))
+
+ Arrays.fill(shorts, -1.toShort)
+ expect(shorts).toEqual(Array[Short](-1, -1, -1, -1, -1, -1))
+ }
+
+ it("should respond to `fill` with start and end index for Short") {
+ val shorts = new Array[Short](6)
+ Arrays.fill(shorts, 1, 4, 42.toShort)
+ expect(shorts).toEqual(Array[Short](0, 42, 42, 42, 0, 0))
+
+ Arrays.fill(shorts, 2, 5, -1.toShort)
+ expect(shorts).toEqual(Array[Short](0, 42, -1, -1, -1, 0))
+ }
+
+ it("should respond to `fill` for Int") {
+ val ints = new Array[Int](6)
+ Arrays.fill(ints, 42)
+ expect(ints).toEqual(Array(42, 42, 42, 42, 42, 42))
+
+ Arrays.fill(ints, -1)
+ expect(ints).toEqual(Array(-1, -1, -1, -1, -1, -1))
+ }
+
+ it("should respond to `fill` with start and end index for Int") {
+ val ints = new Array[Int](6)
+ Arrays.fill(ints, 1, 4, 42)
+ expect(ints).toEqual(Array(0, 42, 42, 42, 0, 0))
+
+ Arrays.fill(ints, 2, 5, -1)
+ expect(ints).toEqual(Array(0, 42, -1, -1, -1, 0))
+ }
+
+ it("should respond to `fill` for Long") {
+ val longs = new Array[Long](6)
+ Arrays.fill(longs, 42L)
+ expect(longs).toEqual(Array(42L, 42L, 42L, 42L, 42L, 42L))
+
+ Arrays.fill(longs, -1L)
+ expect(longs).toEqual(Array(-1L, -1L, -1L, -1L, -1L, -1L))
+ }
+
+ it("should respond to `fill` with start and end index for Long") {
+ val longs = new Array[Long](6)
+ Arrays.fill(longs, 1, 4, 42L)
+ expect(longs).toEqual(Array(0L, 42L, 42L, 42L, 0L, 0L))
+
+ Arrays.fill(longs, 2, 5, -1L)
+ expect(longs).toEqual(Array(0L, 42L, -1L, -1L, -1L, 0L))
+ }
+
+ it("should respond to `fill` for Float") {
+ val floats = new Array[Float](6)
+ Arrays.fill(floats, 42.0f)
+ expect(floats).toEqual(Array(42.0f, 42.0f, 42.0f, 42.0f, 42.0f, 42.0f))
+
+ Arrays.fill(floats, -1.0f)
+ expect(floats).toEqual(Array(-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f))
+ }
+
+ it("should respond to `fill` with start and end index for Float") {
+ val floats = new Array[Float](6)
+ Arrays.fill(floats, 1, 4, 42.0f)
+ expect(floats).toEqual(Array(0.0f, 42.0f, 42.0f, 42.0f, 0.0f, 0.0f))
+
+ Arrays.fill(floats, 2, 5, -1.0f)
+ expect(floats).toEqual(Array(0.0f, 42.0f, -1.0f, -1.0f, -1.0f, 0.0f))
+ }
+
+ it("should respond to `fill` for Double") {
+ val doubles = new Array[Double](6)
+ Arrays.fill(doubles, 42.0)
+ expect(doubles).toEqual(Array(42.0, 42.0, 42.0, 42.0, 42.0, 42.0))
+
+ Arrays.fill(doubles, -1.0f)
+ expect(doubles).toEqual(Array(-1.0, -1.0, -1.0, -1.0, -1.0, -1.0))
+ }
+
+ it("should respond to `fill` with start and end index for Double") {
+ val doubles = new Array[Double](6)
+ Arrays.fill(doubles, 1, 4, 42.0)
+ expect(doubles).toEqual(Array(0.0, 42.0, 42.0, 42.0, 0.0, 0.0))
+
+ Arrays.fill(doubles, 2, 5, -1.0)
+ expect(doubles).toEqual(Array(0.0, 42.0, -1.0, -1.0, -1.0, 0.0))
+ }
+
+ it("should respond to `fill` for AnyRef") {
+ val array = new Array[AnyRef](6)
+ Arrays.fill(array, "a")
+ expect(array).toEqual(Array[AnyRef]("a", "a", "a", "a", "a", "a"))
+
+ Arrays.fill(array, "b")
+ expect(array).toEqual(Array[AnyRef]("b", "b", "b", "b", "b", "b"))
+ }
+
+ it("should respond to `fill` with start and end index for AnyRef") {
+ val bytes = new Array[AnyRef](6)
+ Arrays.fill(bytes, 1, 4, "a")
+ expect(bytes).toEqual(Array[AnyRef](null, "a", "a", "a", null, null))
+
+ Arrays.fill(bytes, 2, 5, "b")
+ expect(bytes).toEqual(Array[AnyRef](null, "a", "b", "b", "b", null))
+ }
+
+ it("should respond to `binarySearch` with start index, end index and key for Long") {
+ val longs: Array[Long] = Array(1, 2, 3, 5, 6, 7)
+ var ret = Arrays.binarySearch(longs, 0, 6, 5)
+ expect(ret).toEqual(3)
+
+ ret = Arrays.binarySearch(longs, 0, 6, 0)
+ expect(ret).toEqual(-1)
+
+ ret = Arrays.binarySearch(longs, 0, 6, 4)
+ expect(ret).toEqual(-4)
+
+ ret = Arrays.binarySearch(longs, 0, 6, 8)
+ expect(ret).toEqual(-7)
+ }
+
+ it("should respond to `binarySearch` with key for Long") {
+ val longs: Array[Long] = Array(1, 2, 3, 5, 6, 7)
+ var ret = Arrays.binarySearch(longs, 5)
+ expect(ret).toEqual(3)
+
+ ret = Arrays.binarySearch(longs, 0)
+ expect(ret).toEqual(-1)
+
+ ret = Arrays.binarySearch(longs, 4)
+ expect(ret).toEqual(-4)
+
+ ret = Arrays.binarySearch(longs, 8)
+ expect(ret).toEqual(-7)
+ }
+
+ it("should respond to `binarySearch` with start index, end index and key for Int") {
+ val ints: Array[Int] = Array(1, 2, 3, 5, 6, 7)
+ var ret = Arrays.binarySearch(ints, 0, 6, 5)
+ expect(ret).toEqual(3)
+
+ ret = Arrays.binarySearch(ints, 0, 6, 0)
+ expect(ret).toEqual(-1)
+
+ ret = Arrays.binarySearch(ints, 0, 6, 4)
+ expect(ret).toEqual(-4)
+
+ ret = Arrays.binarySearch(ints, 0, 6, 8)
+ expect(ret).toEqual(-7)
+ }
+
+ it("should respond to `binarySearch` with key for Int") {
+ val ints: Array[Int] = Array(1, 2, 3, 5, 6, 7)
+ var ret = Arrays.binarySearch(ints, 5)
+ expect(ret).toEqual(3)
+
+ ret = Arrays.binarySearch(ints, 0)
+ expect(ret).toEqual(-1)
+
+ ret = Arrays.binarySearch(ints, 4)
+ expect(ret).toEqual(-4)
+
+ ret = Arrays.binarySearch(ints, 8)
+ expect(ret).toEqual(-7)
+ }
+
+ it("should respond to `binarySearch` with start index, end index and key for Short") {
+ val shorts: Array[Short] = Array(1, 2, 3, 5, 6, 7)
+ var ret = Arrays.binarySearch(shorts, 0, 6, 5.toShort)
+ expect(ret).toEqual(3)
+
+ ret = Arrays.binarySearch(shorts, 0, 6, 0.toShort)
+ expect(ret).toEqual(-1)
+
+ ret = Arrays.binarySearch(shorts, 0, 6, 4.toShort)
+ expect(ret).toEqual(-4)
+
+ ret = Arrays.binarySearch(shorts, 0, 6, 8.toShort)
+ expect(ret).toEqual(-7)
+ }
+
+ it("should respond to `binarySearch` with key for Short") {
+ val shorts: Array[Short] = Array(1, 2, 3, 5, 6, 7)
+ var ret = Arrays.binarySearch(shorts, 5.toShort)
+ expect(ret).toEqual(3)
+
+ ret = Arrays.binarySearch(shorts, 0.toShort)
+ expect(ret).toEqual(-1)
+
+ ret = Arrays.binarySearch(shorts, 4.toShort)
+ expect(ret).toEqual(-4)
+
+ ret = Arrays.binarySearch(shorts, 8.toShort)
+ expect(ret).toEqual(-7)
+ }
+
+ it("should respond to `binarySearch` with start index, end index and key for Char") {
+ val chars: Array[Char] = Array('b', 'c', 'd', 'f', 'g', 'h')
+ var ret = Arrays.binarySearch(chars, 0, 6, 'f')
+ expect(ret).toEqual(3)
+
+ ret = Arrays.binarySearch(chars, 0, 6, 'a')
+ expect(ret).toEqual(-1)
+
+ ret = Arrays.binarySearch(chars, 0, 6, 'e')
+ expect(ret).toEqual(-4)
+
+ ret = Arrays.binarySearch(chars, 0, 6, 'i')
+ expect(ret).toEqual(-7)
+ }
+
+ it("should respond to `binarySearch` with key for Char") {
+ val chars: Array[Char] = Array('b', 'c', 'd', 'f', 'g', 'h')
+ var ret = Arrays.binarySearch(chars, 'f')
+ expect(ret).toEqual(3)
+
+ ret = Arrays.binarySearch(chars, 'a')
+ expect(ret).toEqual(-1)
+
+ ret = Arrays.binarySearch(chars, 'e')
+ expect(ret).toEqual(-4)
+
+ ret = Arrays.binarySearch(chars, 'i')
+ expect(ret).toEqual(-7)
+ }
+
+ it("should respond to `binarySearch` with start index, end index and key for Double") {
+ val doubles: Array[Double] = Array(0.1, 0.2, 0.3, 0.5, 0.6, 0.7)
+ var ret = Arrays.binarySearch(doubles, 0, 6, 0.5)
+ expect(ret).toEqual(3)
+
+ ret = Arrays.binarySearch(doubles, 0, 6, 0.0)
+ expect(ret).toEqual(-1)
+
+ ret = Arrays.binarySearch(doubles, 0, 6, 0.4)
+ expect(ret).toEqual(-4)
+
+ ret = Arrays.binarySearch(doubles, 0, 6, 0.8)
+ expect(ret).toEqual(-7)
+ }
+
+ it("should respond to `binarySearch` with key for Double") {
+ val doubles: Array[Double] = Array(0.1, 0.2, 0.3, 0.5, 0.6, 0.7)
+ var ret = Arrays.binarySearch(doubles, 0.5)
+ expect(ret).toEqual(3)
+
+ ret = Arrays.binarySearch(doubles, 0.0)
+ expect(ret).toEqual(-1)
+
+ ret = Arrays.binarySearch(doubles, 0.4)
+ expect(ret).toEqual(-4)
+
+ ret = Arrays.binarySearch(doubles, 0.8)
+ expect(ret).toEqual(-7)
+ }
+
+ it("should respond to `binarySearch` with start index, end index and key for Float") {
+ val floats: Array[Float] = Array(0.1f, 0.2f, 0.3f, 0.5f, 0.6f, 0.7f)
+ var ret = Arrays.binarySearch(floats, 0, 6, 0.5f)
+ expect(ret).toEqual(3)
+
+ ret = Arrays.binarySearch(floats, 0, 6, 0.0f)
+ expect(ret).toEqual(-1)
+
+ ret = Arrays.binarySearch(floats, 0, 6, 0.4f)
+ expect(ret).toEqual(-4)
+
+ ret = Arrays.binarySearch(floats, 0, 6, 0.8f)
+ expect(ret).toEqual(-7)
+ }
+
+ it("should respond to `binarySearch` with key for Float") {
+ val floats: Array[Float] = Array(0.1f, 0.2f, 0.3f, 0.5f, 0.6f, 0.7f)
+ var ret = Arrays.binarySearch(floats, 0.5f)
+ expect(ret).toEqual(3)
+
+ ret = Arrays.binarySearch(floats, 0.0f)
+ expect(ret).toEqual(-1)
+
+ ret = Arrays.binarySearch(floats, 0.4f)
+ expect(ret).toEqual(-4)
+
+ ret = Arrays.binarySearch(floats, 0.8f)
+ expect(ret).toEqual(-7)
+ }
+
+ it("should respond to `binarySearch` with start index, end index and key for AnyRef") {
+ val strings: Array[AnyRef] = Array("aa", "abc", "cc", "zz", "zzzs", "zzzt")
+ var ret = Arrays.binarySearch(strings, 0, 6, "zz")
+ expect(ret).toEqual(3)
+
+ ret = Arrays.binarySearch(strings, 0, 6, "a")
+ expect(ret).toEqual(-1)
+
+ ret = Arrays.binarySearch(strings, 0, 6, "cd")
+ expect(ret).toEqual(-4)
+
+ ret = Arrays.binarySearch(strings, 0, 6, "zzzz")
+ expect(ret).toEqual(-7)
+ }
+
+ it("should respond to `binarySearch` with key for AnyRef") {
+ val strings: Array[AnyRef] = Array("aa", "abc", "cc", "zz", "zzzs", "zzzt")
+ var ret = Arrays.binarySearch(strings, "zz")
+ expect(ret).toEqual(3)
+
+ ret = Arrays.binarySearch(strings, "a")
+ expect(ret).toEqual(-1)
+
+ ret = Arrays.binarySearch(strings, "cd")
+ expect(ret).toEqual(-4)
+
+ ret = Arrays.binarySearch(strings, "zzzz")
+ expect(ret).toEqual(-7)
+ }
+
+ it("should check ranges of input to `binarySearch`") {
+ def expectException(block: => Unit)(expected: PartialFunction[Throwable, Unit]): Unit = {
+ val catchAll: PartialFunction[Throwable, Unit] = {
+ case e: Throwable => expect(e.getClass.getName).toBe("not thrown")
+ }
+
+ try {
+ block
+ expect("exception").toBe("thrown")
+ } catch expected orElse catchAll
+ }
+
+ val array = Array(0, 1, 3, 4)
+
+ expectException({ Arrays.binarySearch(array, 3, 2, 2) }) {
+ case exception: IllegalArgumentException =>
+ expect(exception.getMessage).toBe("fromIndex(3) > toIndex(2)")
+ }
+
+ // start/end comparison is made before index ranges checks
+ expectException({ Arrays.binarySearch(array, 7, 5, 2) }) {
+ case exception: IllegalArgumentException =>
+ expect(exception.getMessage).toBe("fromIndex(7) > toIndex(5)")
+ }
+
+ expectException({ Arrays.binarySearch(array, -1, 4, 2) }) {
+ case exception: ArrayIndexOutOfBoundsException =>
+ expect(exception.getMessage).toBe("Array index out of range: -1")
+ }
+
+ expectException({ Arrays.binarySearch(array, 0, 5, 2) }) {
+ case exception: ArrayIndexOutOfBoundsException =>
+ expect(exception.getMessage).toBe("Array index out of range: 5")
+ }
+ }
+
+ it("should respond to `copyOf` with key for Int") {
+ val ints: Array[Int] = Array(1, 2, 3)
+ val intscopy = Arrays.copyOf(ints, 5)
+ expect(intscopy).toEqual(Array(1, 2, 3, 0, 0))
+ }
+
+ it("should respond to `copyOf` with key for Long") {
+ val longs: Array[Long] = Array(1, 2, 3)
+ val longscopy = Arrays.copyOf(longs, 5)
+ expect(longscopy).toEqual(Array[Long](1, 2, 3, 0, 0))
+ }
+
+ it("should respond to `copyOf` with key for Short") {
+ val shorts: Array[Short] = Array(1, 2, 3)
+ val shortscopy = Arrays.copyOf(shorts, 5)
+ expect(shortscopy).toEqual(Array[Short](1, 2, 3, 0, 0))
+ }
+
+ it("should respond to `copyOf` with key for Byte") {
+ val bytes: Array[Byte] = Array(42, 43, 44)
+ val floatscopy = Arrays.copyOf(bytes, 5)
+ expect(floatscopy).toEqual(Array[Byte](42, 43, 44, 0, 0))
+ }
+
+ it("should respond to `copyOf` with key for Char") {
+ val chars: Array[Char] = Array('a', 'b', '0')
+ val charscopy = Arrays.copyOf(chars, 5)
+ expect(charscopy(4)).toEqual(0.toChar)
+ }
+
+ it("should respond to `copyOf` with key for Double") {
+ val doubles: Array[Double] = Array(0.1, 0.2, 0.3)
+ val doublescopy = Arrays.copyOf(doubles, 5)
+ expect(doublescopy).toEqual(Array[Double](0.1, 0.2, 0.3, 0, 0))
+ }
+
+ it("should respond to `copyOf` with key for Float") {
+ val floats: Array[Float] = Array(0.1f, 0.2f, 0.3f)
+ val floatscopy = Arrays.copyOf(floats, 5)
+ expect(floatscopy).toEqual(Array[Float](0.1f, 0.2f, 0.3f, 0f, 0f))
+ }
+
+ it("should respond to `copyOf` with key for Boolean") {
+ val bools: Array[Boolean] = Array(false, true, false)
+ val boolscopy = Arrays.copyOf(bools, 5)
+ expect(boolscopy).toEqual(Array[Boolean](false, true, false, false, false))
+ }
+
+ it("should respond to `copyOf` with key for AnyRef") {
+ val anyrefs: Array[AnyRef] = Array("a", "b", "c")
+ val anyrefscopy = Arrays.copyOf(anyrefs, 5)
+ expect(anyrefscopy.getClass() == classOf[Array[AnyRef]]).toBeTruthy
+ expect(anyrefscopy).toEqual(Array[AnyRef]("a", "b", "c", null, null))
+
+ val sequences: Array[CharSequence] = Array("a", "b", "c")
+ val sequencescopy = Arrays.copyOf(sequences, 2)
+ expect(sequencescopy.getClass() == classOf[Array[CharSequence]])
+ expect(sequencescopy).toEqual(Array[CharSequence]("a", "b"))
+ }
+
+ it("should respond to `copyOfRange` for AnyRef") {
+ val anyrefs: Array[AnyRef] = Array("a", "b", "c", "d", "e")
+ val anyrefscopy = Arrays.copyOfRange(anyrefs, 2, 4)
+ expect(anyrefscopy.getClass() == classOf[Array[AnyRef]]).toBeTruthy
+ expect(anyrefscopy).toEqual(Array[AnyRef]("c", "d"))
+
+ val sequences: Array[CharSequence] = Array("a", "b", "c", "d", "e")
+ val sequencescopy = Arrays.copyOfRange(sequences, 1, 5)
+ expect(sequencescopy.getClass() == classOf[Array[CharSequence]])
+ expect(sequencescopy).toEqual(Array[CharSequence]("b", "c", "d", "e"))
+ }
+
+ it("should respond to `hashCode` for Boolean") {
+ expect(Arrays.hashCode(null: Array[Boolean])).toEqual(0)
+ expect(Arrays.hashCode(Array[Boolean]())).toEqual(1)
+ expect(Arrays.hashCode(Array[Boolean](false))).toEqual(1268)
+ expect(Arrays.hashCode(Array[Boolean](true, false))).toEqual(40359)
+ }
+
+ it("should respond to `hashCode` for Chars") {
+ expect(Arrays.hashCode(null: Array[Char])).toEqual(0)
+ expect(Arrays.hashCode(Array[Char]())).toEqual(1)
+ expect(Arrays.hashCode(Array[Char]('a'))).toEqual(128)
+ expect(Arrays.hashCode(Array[Char]('c', '&'))).toEqual(4068)
+ expect(Arrays.hashCode(Array[Char]('-', '5', 'q'))).toEqual(74792)
+ expect(Arrays.hashCode(Array[Char]('.', ' ', '\u4323', 'v', '~'))).toEqual(88584920)
+ }
+
+ it("should respond to `hashCode` for Bytes") {
+ expect(Arrays.hashCode(null: Array[Byte])).toEqual(0)
+ expect(Arrays.hashCode(Array[Byte]())).toEqual(1)
+ expect(Arrays.hashCode(Array[Byte](1))).toEqual(32)
+ expect(Arrays.hashCode(Array[Byte](7, -125))).toEqual(1053)
+ expect(Arrays.hashCode(Array[Byte](3, 0, 45))).toEqual(32719)
+ expect(Arrays.hashCode(Array[Byte](0, 45, 100, 1, 1))).toEqual(30065878)
+ }
+
+ it("should respond to `hashCode` for Shorts") {
+ expect(Arrays.hashCode(null: Array[Short])).toEqual(0)
+ expect(Arrays.hashCode(Array[Short]())).toEqual(1)
+ expect(Arrays.hashCode(Array[Short](1))).toEqual(32)
+ expect(Arrays.hashCode(Array[Short](7, -125))).toEqual(1053)
+ expect(Arrays.hashCode(Array[Short](3, 0, 4534))).toEqual(37208)
+ expect(Arrays.hashCode(Array[Short](0, 45, 100, 1, 1))).toEqual(30065878)
+ }
+
+ it("should respond to `hashCode` for Ints") {
+ expect(Arrays.hashCode(null: Array[Int])).toEqual(0)
+ expect(Arrays.hashCode(Array[Int]())).toEqual(1)
+ expect(Arrays.hashCode(Array[Int](1))).toEqual(32)
+ expect(Arrays.hashCode(Array[Int](7, -125))).toEqual(1053)
+ expect(Arrays.hashCode(Array[Int](3, 0, 4534))).toEqual(37208)
+ expect(Arrays.hashCode(Array[Int](0, 45, 100, 1, 1, Int.MaxValue))).toEqual(-1215441431)
+ }
+
+ it("should respond to `hashCode` for Longs") {
+ expect(Arrays.hashCode(null: Array[Long])).toEqual(0)
+ expect(Arrays.hashCode(Array[Long]())).toEqual(1)
+ expect(Arrays.hashCode(Array[Long](1L))).toEqual(32)
+ expect(Arrays.hashCode(Array[Long](7L, -125L))).toEqual(1302)
+ expect(Arrays.hashCode(Array[Long](3L, 0L, 4534L))).toEqual(37208)
+ expect(Arrays.hashCode(Array[Long](0L, 45L, 100L, 1L, 1L, Int.MaxValue))).toEqual(-1215441431)
+ expect(Arrays.hashCode(Array[Long](0L, 34573566354545L, 100L, 1L, 1L, Int.MaxValue))).toEqual(-1952288964)
+ }
+
+ it("should respond to `hashCode` for Floats") {
+ expect(Arrays.hashCode(null: Array[Float])).toEqual(0)
+ expect(Arrays.hashCode(Array[Float]())).toEqual(1)
+ expect(Arrays.hashCode(Array[Float](1f))).toEqual(32)
+ expect(Arrays.hashCode(Array[Float](7.2f, -125.2f))).toEqual(-2082726591)
+ expect(Arrays.hashCode(Array[Float](302.1f, 0.0f, 4534f))).toEqual(-1891539602)
+ expect(Arrays.hashCode(Array[Float](0.0f, 45f, -100f, 1.1f, -1f, 3567f))).toEqual(-1591440133)
+ }
+
+ it("should respond to `hashCode` for Doubles") {
+ expect(Arrays.hashCode(null: Array[Double])).toEqual(0)
+ expect(Arrays.hashCode(Array[Double]())).toEqual(1)
+ expect(Arrays.hashCode(Array[Double](1.1))).toEqual(-1503133662)
+ expect(Arrays.hashCode(Array[Double](7.3, -125.23))).toEqual(-2075734168)
+ expect(Arrays.hashCode(Array[Double](3.9, 0.2, 4534.9))).toEqual(-557562564)
+ expect(Arrays.hashCode(Array[Double](0.1, 45.1, -100.0, 1.1, 1.7))).toEqual(-1750344582)
+ expect(Arrays.hashCode(Array[Double](0.0, 34573566354545.9, 100.2, 1.1, 1.2, Int.MaxValue))).toEqual(-1764602991)
+ }
+
+ it("should respond to `hashCode` for AnyRef") {
+ expect(Arrays.hashCode(null: Array[AnyRef])).toEqual(0)
+ expect(Arrays.hashCode(Array[AnyRef]())).toEqual(1)
+ expect(Arrays.hashCode(Array[AnyRef](null, null))).toEqual(961)
+ expect(Arrays.hashCode(Array[AnyRef]("a", "b", null))).toEqual(126046)
+ expect(Arrays.hashCode(Array[AnyRef](null, "a", "b", null, "fooooo"))).toEqual(-1237252983)
+ }
+
+ it("should respond to `equals` for Booleans") {
+ val a1 = Array(true, false)
+
+ expect(Arrays.equals(a1, a1)).toBeTruthy
+ expect(Arrays.equals(a1, Array(true, false))).toBeTruthy
+
+ expect(Arrays.equals(a1, Array(true))).toBeFalsy
+ expect(Arrays.equals(a1, Array(false))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Boolean]())).toBeFalsy
+ expect(Arrays.equals(a1, Array(false, true))).toBeFalsy
+ expect(Arrays.equals(a1, Array(false, true, false))).toBeFalsy
+ }
+
+ it("should respond to `equals` for Bytes") {
+ val a1 = Array[Byte](1, -7, 10)
+
+ expect(Arrays.equals(null: Array[Byte], null: Array[Byte])).toBeTruthy
+ expect(Arrays.equals(a1, a1)).toBeTruthy
+ expect(Arrays.equals(a1, Array[Byte](1, -7, 10))).toBeTruthy
+
+ expect(Arrays.equals(a1, null)).toBeFalsy
+ expect(Arrays.equals(a1, Array[Byte](3))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Byte](1))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Byte]())).toBeFalsy
+ expect(Arrays.equals(a1, Array[Byte](1, -7, 11))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Byte](1, -7, 11, 20))).toBeFalsy
+ }
+
+ it("should respond to `equals` for Chars") {
+ val a1 = Array[Char]('a', '0', '-')
+
+ expect(Arrays.equals(null: Array[Char], null: Array[Char])).toBeTruthy
+ expect(Arrays.equals(a1, a1)).toBeTruthy
+ expect(Arrays.equals(a1, Array[Char]('a', '0', '-'))).toBeTruthy
+
+ expect(Arrays.equals(a1, null)).toBeFalsy
+ expect(Arrays.equals(a1, Array[Char]('z'))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Char]('a'))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Char]())).toBeFalsy
+ expect(Arrays.equals(a1, Array[Char]('a', '0', '+'))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Char]('a', '0', '-', 'z'))).toBeFalsy
+ }
+
+ it("should respond to `equals` for Shorts") {
+ val a1 = Array[Short](1, -7, 10)
+
+ expect(Arrays.equals(null: Array[Short], null: Array[Short])).toBeTruthy
+ expect(Arrays.equals(a1, a1)).toBeTruthy
+ expect(Arrays.equals(a1, Array[Short](1, -7, 10))).toBeTruthy
+
+ expect(Arrays.equals(a1, null)).toBeFalsy
+ expect(Arrays.equals(a1, Array[Short](3))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Short](1))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Short]())).toBeFalsy
+ expect(Arrays.equals(a1, Array[Short](1, -7, 11))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Short](1, -7, 11, 20))).toBeFalsy
+ }
+
+ it("should respond to `equals` for Ints") {
+ val a1 = Array[Int](1, -7, 10)
+
+ expect(Arrays.equals(null: Array[Int], null: Array[Int])).toBeTruthy
+ expect(Arrays.equals(a1, a1)).toBeTruthy
+ expect(Arrays.equals(a1, Array[Int](1, -7, 10))).toBeTruthy
+
+ expect(Arrays.equals(a1, null)).toBeFalsy
+ expect(Arrays.equals(a1, Array[Int](3))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Int](1))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Int]())).toBeFalsy
+ expect(Arrays.equals(a1, Array[Int](1, -7, 11))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Int](1, -7, 11, 20))).toBeFalsy
+ }
+
+ it("should respond to `equals` for Longs") {
+ val a1 = Array[Long](1L, -7L, 10L)
+
+ expect(Arrays.equals(null: Array[Long], null: Array[Long])).toBeTruthy
+ expect(Arrays.equals(a1, a1)).toBeTruthy
+ expect(Arrays.equals(a1, Array[Long](1L, -7L, 10L))).toBeTruthy
+
+ expect(Arrays.equals(a1, null)).toBeFalsy
+ expect(Arrays.equals(a1, Array[Long](3L))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Long](1L))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Long]())).toBeFalsy
+ expect(Arrays.equals(a1, Array[Long](1L, -7L, 11L))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Long](1L, -7L, 11L, 20L))).toBeFalsy
+ }
+
+ it("should respond to `equals` for Floats") {
+ val a1 = Array[Float](1.1f, -7.4f, 10.0f)
+
+ expect(Arrays.equals(null: Array[Float], null: Array[Float])).toBeTruthy
+ expect(Arrays.equals(a1, a1)).toBeTruthy
+ expect(Arrays.equals(a1, Array[Float](1.1f, -7.4f, 10.0f))).toBeTruthy
+
+ expect(Arrays.equals(a1, null)).toBeFalsy
+ expect(Arrays.equals(a1, Array[Float](3.0f))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Float](1.1f))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Float]())).toBeFalsy
+ expect(Arrays.equals(a1, Array[Float](1.1f, -7.4f, 11.0f))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Float](1.1f, -7.4f, 10.0f, 20.0f))).toBeFalsy
+ }
+
+ it("should respond to `equals` for Doubles") {
+ val a1 = Array[Double](1.1, -7.4, 10.0)
+
+ expect(Arrays.equals(null: Array[Double], null: Array[Double])).toBeTruthy
+ expect(Arrays.equals(a1, a1)).toBeTruthy
+ expect(Arrays.equals(a1, Array[Double](1.1, -7.4, 10.0))).toBeTruthy
+
+ expect(Arrays.equals(a1, null)).toBeFalsy
+ expect(Arrays.equals(a1, Array[Double](3.0))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Double](1.1))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Double]())).toBeFalsy
+ expect(Arrays.equals(a1, Array[Double](1.1, -7.4, 11.0))).toBeFalsy
+ expect(Arrays.equals(a1, Array[Double](1.1, -7.4, 10.0, 20.0))).toBeFalsy
+ }
+
+ it("should respond to `equals` for AnyRefs") {
+ class A(private val x: Int) {
+ override def equals(that: Any) = that match {
+ case that: A => this.x == that.x
+ case _ => false
+ }
+ }
+
+ def A(x: Int) = new A(x)
+
+ val a1 = Array[AnyRef](A(1), A(-7), A(10))
+
+ expect(Arrays.equals(null: Array[AnyRef], null: Array[AnyRef])).toBeTruthy
+ expect(Arrays.equals(a1, a1)).toBeTruthy
+ expect(Arrays.equals(a1, Array[AnyRef](A(1), A(-7), A(10)))).toBeTruthy
+
+ expect(Arrays.equals(a1, null)).toBeFalsy
+ expect(Arrays.equals(a1, Array[AnyRef](A(3)))).toBeFalsy
+ expect(Arrays.equals(a1, Array[AnyRef](A(1)))).toBeFalsy
+ expect(Arrays.equals(a1, Array[AnyRef]())).toBeFalsy
+ expect(Arrays.equals(a1, Array[AnyRef](A(1), null, A(11)))).toBeFalsy
+ expect(Arrays.equals(a1, Array[AnyRef](A(1), A(-7), A(11), A(20)))).toBeFalsy
+ }
+
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/AtomicTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/AtomicTest.scala
new file mode 100644
index 0000000..c4f065a
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/AtomicTest.scala
@@ -0,0 +1,119 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import scala.language.implicitConversions
+
+import scala.scalajs.js
+
+import org.scalajs.jasminetest.JasmineTest
+
+object AtomicTest extends JasmineTest {
+
+ describe("java.util.concurrent.AtomicLong") {
+
+ it("Should have all the normal operations") {
+ val atomic = new java.util.concurrent.atomic.AtomicLong(10)
+ expect(atomic.get()).toEqual(10)
+ atomic.set(20)
+ expect(atomic.get()).toEqual(20)
+ expect(atomic.getAndIncrement()).toEqual(20)
+ expect(atomic.get()).toEqual(21)
+ expect(atomic.getAndDecrement()).toEqual(21)
+ expect(atomic.get()).toEqual(20)
+ expect(atomic.getAndSet(0)).toEqual(20)
+ expect(atomic.get()).toEqual(0)
+ expect(atomic.incrementAndGet()).toEqual(1)
+ expect(atomic.get()).toEqual(1)
+ expect(atomic.decrementAndGet()).toEqual(0)
+ expect(atomic.get()).toEqual(0)
+ expect(atomic.addAndGet(10)).toEqual(10)
+ expect(atomic.get()).toEqual(10)
+ expect(atomic.intValue).toEqual(10)
+ expect(atomic.longValue).toEqual(10L)
+ expect(atomic.floatValue).toEqual(10.0f)
+ expect(atomic.doubleValue).toEqual(10)
+ expect(atomic.compareAndSet(1, 20)).toEqual(false)
+ expect(atomic.get()).toEqual(10)
+ expect(atomic.compareAndSet(10, 20)).toEqual(true)
+ expect(atomic.get()).toEqual(20)
+ }
+ }
+ describe("java.util.concurrent.AtomicInteger") {
+ it("Should have all the normal operations") {
+ val atomic = new java.util.concurrent.atomic.AtomicInteger(10)
+ expect(atomic.get()).toEqual(10)
+ atomic.set(20)
+ expect(atomic.get()).toEqual(20)
+ expect(atomic.getAndIncrement()).toEqual(20)
+ expect(atomic.get()).toEqual(21)
+ expect(atomic.getAndDecrement()).toEqual(21)
+ expect(atomic.get()).toEqual(20)
+ expect(atomic.getAndSet(0)).toEqual(20)
+ expect(atomic.get()).toEqual(0)
+ expect(atomic.incrementAndGet()).toEqual(1)
+ expect(atomic.get()).toEqual(1)
+ expect(atomic.decrementAndGet()).toEqual(0)
+ expect(atomic.get()).toEqual(0)
+ expect(atomic.addAndGet(10)).toEqual(10)
+ expect(atomic.get()).toEqual(10)
+ expect(atomic.intValue).toEqual(10)
+ expect(atomic.longValue).toEqual(10L)
+ expect(atomic.floatValue).toEqual(10.0f)
+ expect(atomic.doubleValue).toEqual(10)
+ expect(atomic.compareAndSet(1, 20)).toEqual(false)
+ expect(atomic.get()).toEqual(10)
+ expect(atomic.compareAndSet(10, 20)).toEqual(true)
+ expect(atomic.get()).toEqual(20)
+ }
+ }
+ describe("java.util.concurrent.AtomicBoolean") {
+ it("Should have all the normal operations") {
+ val atomic = new java.util.concurrent.atomic.AtomicBoolean(true)
+ expect(atomic.get()).toEqual(true)
+ atomic.set(false)
+ expect(atomic.get()).toEqual(false)
+ expect(atomic.compareAndSet(true, true)).toEqual(false)
+ expect(atomic.get()).toEqual(false)
+ expect(atomic.compareAndSet(false, true)).toEqual(true)
+ expect(atomic.get()).toEqual(true)
+ expect(atomic.getAndSet(false)).toEqual(true)
+ expect(atomic.get()).toEqual(false)
+ }
+ }
+ describe("java.util.concurrent.AtomicReference") {
+ it("Should have all the normal operations") {
+ val thing1 = Foo(5)
+ val thing1bis = Foo(5) // equals(), but not the same reference
+ val thing2 = Foo(10)
+
+ implicit def foo2js(foo: Foo): js.Any = foo.asInstanceOf[js.Any]
+
+ // sanity
+ expect(thing1 == thing1bis).toBeTruthy
+ expect(thing1 == thing2).toBeFalsy
+ expect(thing1).toBe(thing1)
+ expect(thing1).not.toBe(thing1bis)
+
+ // actual test
+ val atomic = new java.util.concurrent.atomic.AtomicReference(thing1)
+ expect(atomic.get()).toBe(thing1)
+ atomic.set(thing2)
+ expect(atomic.get()).toBe(thing2)
+ expect(atomic.compareAndSet(thing1, thing1)).toEqual(false)
+ expect(atomic.get()).toBe(thing2)
+ expect(atomic.compareAndSet(thing2, thing1)).toEqual(true)
+ expect(atomic.get()).toBe(thing1)
+ expect(atomic.compareAndSet(thing1bis, thing2)).toEqual(false)
+ expect(atomic.getAndSet(thing2)).toBe(thing1)
+ expect(atomic.get()).toBe(thing2)
+ }
+ }
+
+ case class Foo(i: Int)
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/BooleanTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/BooleanTest.scala
new file mode 100644
index 0000000..87c65e9
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/BooleanTest.scala
@@ -0,0 +1,62 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import java.lang.{Boolean => JBoolean}
+
+import org.scalajs.jasminetest.JasmineTest
+
+/**
+ * tests the implementation of the java standard library Boolean
+ */
+object BooleanTest extends JasmineTest {
+
+ describe("java.lang.Boolean") {
+
+ it("should provide `booleanValue`") {
+ expect(JBoolean.TRUE.booleanValue()).toBe(true)
+ expect(JBoolean.FALSE.booleanValue()).toBe(false)
+ expect(() => (null: JBoolean).booleanValue()).toThrow
+ }
+
+ it("should provide `compareTo`") {
+ def compare(x: Boolean, y: Boolean): Int =
+ new JBoolean(x).compareTo(new JBoolean(y))
+
+ expect(compare(false, false)).toEqual(0)
+ expect(compare(false, true)).toBeLessThan(0)
+ expect(compare(true, false)).toBeGreaterThan(0)
+ expect(compare(true, true)).toEqual(0)
+ }
+
+ it("should be a Comparable") {
+ def compare(x: Any, y: Any): Int =
+ x.asInstanceOf[Comparable[Any]].compareTo(y)
+
+ expect(compare(false, false)).toEqual(0)
+ expect(compare(false, true)).toBeLessThan(0)
+ expect(compare(true, false)).toBeGreaterThan(0)
+ expect(compare(true, true)).toEqual(0)
+ }
+
+ it("should parse strings") {
+ def test(s: String, v: Boolean): Unit = {
+ expect(JBoolean.parseBoolean(s)).toEqual(v)
+ expect(JBoolean.valueOf(s).booleanValue()).toEqual(v)
+ expect(new JBoolean(s).booleanValue()).toEqual(v)
+ }
+
+ test("false", false)
+ test("true", true)
+ test("TrUe", true)
+ test(null, false)
+ test("truee", false)
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ByteTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ByteTest.scala
new file mode 100644
index 0000000..b033c59
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ByteTest.scala
@@ -0,0 +1,64 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import java.lang.{Byte => JByte}
+
+import org.scalajs.jasminetest.JasmineTest
+
+/**
+ * tests the implementation of the java standard library Byte
+ */
+object ByteTest extends JasmineTest {
+
+ describe("java.lang.Byte") {
+
+ it("should provide `compareTo`") {
+ def compare(x: Byte, y: Byte): Int =
+ new JByte(x).compareTo(new JByte(y))
+
+ expect(compare(0.toByte, 5.toByte)).toBeLessThan(0)
+ expect(compare(10.toByte, 9.toByte)).toBeGreaterThan(0)
+ expect(compare(-2.toByte, -1.toByte)).toBeLessThan(0)
+ expect(compare(3.toByte, 3.toByte)).toEqual(0)
+ }
+
+ it("should be a Comparable") {
+ def compare(x: Any, y: Any): Int =
+ x.asInstanceOf[Comparable[Any]].compareTo(y)
+
+ expect(compare(0.toByte, 5.toByte)).toBeLessThan(0)
+ expect(compare(10.toByte, 9.toByte)).toBeGreaterThan(0)
+ expect(compare(-2.toByte, -1.toByte)).toBeLessThan(0)
+ expect(compare(3.toByte, 3.toByte)).toEqual(0)
+ }
+
+ it("should parse strings") {
+ def test(s: String, v: Byte): Unit = {
+ expect(JByte.parseByte(s)).toEqual(v)
+ expect(JByte.valueOf(s).byteValue()).toEqual(v)
+ expect(new JByte(s).byteValue()).toEqual(v)
+ }
+
+ test("0", 0)
+ test("5", 5)
+ test("127", 127)
+ test("-100", -100)
+ }
+
+ it("should reject invalid strings when parsing") {
+ def test(s: String): Unit =
+ expect(() => JByte.parseByte(s)).toThrow
+
+ test("abc")
+ test("")
+ test("200") // out of range
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/CharacterTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/CharacterTest.scala
new file mode 100644
index 0000000..f206221
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/CharacterTest.scala
@@ -0,0 +1,672 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import org.scalajs.jasminetest.JasmineTest
+import scala.scalajs.js
+
+object CharacterTest extends JasmineTest {
+
+ describe("java.lang.Character") {
+
+ it("should provide `isISOControl`") {
+ val isoControlChars = (('\u0000' to '\u001F') ++ ('\u007F' to '\u009F')).map(_.toInt).toSet
+ isoControlChars foreach { c =>
+ expect(Character.isISOControl(c)).toEqual(true)
+ }
+
+ val randomInts = List.fill(100)(scala.util.Random.nextInt)
+ ((-1000 to 1000) ++ randomInts).filterNot(isoControlChars) foreach { c =>
+ expect(Character.isISOControl(c)).toEqual(false)
+ }
+ }
+
+ it("should provide `digit`") {
+ expect(Character.digit('a', 16)).toEqual(10)
+ expect(Character.digit('}', 5)).toEqual(-1)
+ expect(Character.digit('1', 50)).toEqual(-1)
+ expect(Character.digit('1', 36)).toEqual(1)
+ expect(Character.digit('Z', 36)).toEqual(35)
+ expect(Character.digit('\uFF22', 20)).toEqual(11)
+ }
+
+ it("should provide isDigit") {
+ expect(Character.isDigit('a')).toBeFalsy
+ expect(Character.isDigit('0')).toBeTruthy
+ expect(Character.isDigit('5')).toBeTruthy
+ expect(Character.isDigit('9')).toBeTruthy
+ expect(Character.isDigit('z')).toBeFalsy
+ expect(Character.isDigit(' ')).toBeFalsy
+ }
+
+ it("should provide `compareTo`") {
+ def compare(x: Char, y: Char): Int =
+ new Character(x).compareTo(new Character(y))
+
+ expect(compare('0', '5')).toBeLessThan(0)
+ expect(compare('o', 'g')).toBeGreaterThan(0)
+ expect(compare('A', 'a')).toBeLessThan(0)
+ expect(compare('b', 'b')).toEqual(0)
+ }
+
+ it("should be a Comparable") {
+ def compare(x: Any, y: Any): Int =
+ x.asInstanceOf[Comparable[Any]].compareTo(y)
+
+ expect(compare('0', '5')).toBeLessThan(0)
+ expect(compare('o', 'g')).toBeGreaterThan(0)
+ expect(compare('A', 'a')).toBeLessThan(0)
+ expect(compare('b', 'b')).toEqual(0)
+ }
+
+ it("should provide isIdentifierIgnorable") {
+ for (c <- '\u0000' to '\u0008')
+ expect(Character.isIdentifierIgnorable(c)).toBeTruthy
+
+ for (c <- '\u000E' to '\u001B')
+ expect(Character.isIdentifierIgnorable(c)).toBeTruthy
+
+ for (c <- '\u007F' to '\u009F')
+ expect(Character.isIdentifierIgnorable(c)).toBeTruthy
+
+ // Exhaustive list of Cf category. Unicode 7.0.0
+ expect(Character.isIdentifierIgnorable('\u00AD')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u0600')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u0601')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u0602')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u0603')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u0604')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u0605')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u061C')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u06DD')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u070F')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u180E')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u200B')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u200C')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u200D')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u200E')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u200F')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u202A')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u202B')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u202C')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u202D')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u202E')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u2060')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u2061')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u2062')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u2063')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u2064')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u2066')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u2067')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u2068')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u2069')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u206A')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u206B')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u206C')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u206D')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u206E')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\u206F')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\uFEFF')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\uFFF9')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\uFFFA')).toBeTruthy
+ expect(Character.isIdentifierIgnorable('\uFFFB')).toBeTruthy
+
+ // BUG in JDK? 17B4 should be "Mn", Java says "Cf"
+ //expect(Character.isIdentifierIgnorable('\u17b4')).toBeTruthy
+
+ // 100 randomly generated negatives
+ expect(Character.isIdentifierIgnorable('\u745a')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ub445')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ub23a')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ub029')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ufb5c')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u1b67')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u943b')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ue766')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uad12')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ub80b')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u7341')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ubc73')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uabb9')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ub34b')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u1063')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u272f')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u3801')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u53a6')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u2ec2')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u540c')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uc85f')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ud2c8')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u551b')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uc0a1')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ud25a')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u2b98')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u398b')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ubc77')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u54cc')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uc9a0')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ud10f')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uf7e1')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u0f29')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uafcd')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uf187')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u6287')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uacb6')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uff99')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ub59e')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uf630')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ufaec')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ua7d7')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u3eab')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u54a5')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u393a')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uc621')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u766c')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ud64c')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u8beb')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u44e2')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ub6f6')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u58b6')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u3bad')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u3c28')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ufbfd')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u585f')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u7227')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ucea7')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u2c82')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u686d')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u120d')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uf3db')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u320a')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ud96e')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u85eb')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u9648')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u08a4')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u9db7')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u82c7')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ufe12')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u0eaf')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u96dc')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u3a2a')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uc72e')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u3745')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ubcf9')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u5f66')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u9be1')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ud81d')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u3ca3')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u3e82')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u7ce4')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u33ca')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ue725')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uef49')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ue2cf')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\udcf0')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u5f2e')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u2a63')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ud2d2')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u8023')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ua957')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u10ba')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uf85f')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uc40d')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u2509')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u0d8e')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u9db8')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u824d')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u5670')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u6005')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ub8de')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uff5c')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\ub36d')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u0cf2')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u82f6')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u9206')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u95e1')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u990f')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u9fc7')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\udffb')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u0ecb')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u7563')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uf0ff')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u6b2e')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u894c')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u8f06')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\uffa9')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u37b0')).toBeFalsy
+ expect(Character.isIdentifierIgnorable('\u3e04')).toBeFalsy
+
+ }
+
+ it("should provide isUnicodeIdentifierStart") {
+ // 100 randomly generated positives and 100 randomly generated negatives
+
+ expect(Character.isUnicodeIdentifierStart('\ud6d5')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u3f9c')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u3a40')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u53af')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u1636')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u4884')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ucba4')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u1ee4')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u6dec')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u10d4')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u631f')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u3661')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u55f8')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ub4ef')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ud509')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u65b5')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u316b')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ub270')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u7f0f')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\uff84')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u11cc')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u0294')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u51b1')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u9ae2')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u304a')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ud5c7')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u3b4b')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u5e42')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u51fc')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\uc148')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\uc1ae')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u7372')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\uc116')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u5d29')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u8753')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u50f8')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u3f9d')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u1f44')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ucd43')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u9126')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u8d2e')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u4f5c')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u66d7')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ua30b')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u140b')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ub264')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u7b35')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u15e4')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ubb37')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u34e3')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\uac3e')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ubd0e')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ub641')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u1580')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u30c1')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ub0c8')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u8681')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u7f14')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u4142')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u56c1')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u0444')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u9964')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ub5c0')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u43d8')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u479e')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u0853')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ube08')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u9346')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\uf9c1')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u0e8a')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u212c')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u810c')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u8089')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u1331')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ua5f7')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u5e5e')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u613b')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u34a7')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ud15b')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\uc1fc')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u92f1')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u3ae6')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ufceb')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u7584')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ufe98')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ubb23')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u7961')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u4445')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u4d5f')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u61cb')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u5176')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ub987')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u906a')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u4317')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u93ad')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u825a')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u7ff8')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u533a')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\u5617')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ufcc6')).toBeTruthy
+ expect(Character.isUnicodeIdentifierStart('\ue398')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ueab6')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ue7bc')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uf8ab')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ue27f')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uebea')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ueedc')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uf091')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u2785')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u287b')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uf042')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u20f9')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u23d6')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\udc5b')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ued16')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u1b6b')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ue7ba')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uf7fa')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u2125')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uea97')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ue624')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ufbb8')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u2730')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\udb89')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ue30d')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u2e24')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uf03e')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uda27')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u28fc')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u9ffe')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ude19')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u0b70')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uddfc')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ued53')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ue8cb')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\udccc')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u00a3')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u0bed')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u0c68')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uf47b')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u0f96')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ue9c3')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uf784')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uef4b')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\udee1')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u2f61')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uf622')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u19f9')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ud86a')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ued83')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uf7e4')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uecce')).toBeFalsy
+
+ // BUG in JDK? A699 should be "Ll", Java says "Cn"
+ // expect(Character.isUnicodeIdentifierStart('\ua699')).toBeFalsy
+
+ expect(Character.isUnicodeIdentifierStart('\uaa5f')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\udf24')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u2e0e')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uf322')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ue137')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ued19')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u21ab')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ue972')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\udbf2')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uf54c')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u4dd3')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u2769')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ue363')).toBeFalsy
+
+ // BUG in JDK? 1BBB should be "Lo", Java says "Cn"
+ // expect(Character.isUnicodeIdentifierStart('\u1bbb')).toBeFalsy
+
+ expect(Character.isUnicodeIdentifierStart('\ueae7')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u2bf3')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ue704')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u1c7f')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uf52b')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ue9e3')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u259b')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uf250')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uf42f')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ue244')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u20d9')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ua881')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u0ee6')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u2203')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u0fc7')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u07fc')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\udb86')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u2a70')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u2bb7')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uecf0')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ude48')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u0a3b')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u20b8')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uf898')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u23e6')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ud8ba')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uda1e')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\udc12')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u2a06')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\u0888')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\ud9ec')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uf81f')).toBeFalsy
+ expect(Character.isUnicodeIdentifierStart('\uf817')).toBeFalsy
+ }
+
+ it("should provide isUnicodeIdentifierPart") {
+ // 100 randomly generated positives and 100 randomly generated negatives
+
+ expect(Character.isUnicodeIdentifierPart('\u48d3')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u0905')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u8f51')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u9bcb')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\ud358')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u1538')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\uffcf')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u83ec')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u3a89')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\ub63a')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\ufe24')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u2d62')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u15ca')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u4fa4')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u47d1')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u831c')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u84e6')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u7783')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\ua03c')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u6ecf')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u147f')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u67a9')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u8b6c')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u3410')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u2cc0')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\ua332')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u9733')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u5df3')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u3fd7')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u6611')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u55b4')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u8bc8')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u6f74')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u6c97')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u6a86')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u6000')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u614f')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u206e')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\ua801')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u9edf')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\ub42c')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u7fcd')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u8a60')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u182f')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u5d0a')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\uaf9c')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u9d4b')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u5088')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\uc1a6')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\ubbe4')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\uad25')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u4653')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u8add')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u3d1c')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u80a8')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u810e')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\uc1d2')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\ub984')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u9d13')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u37c2')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u13cd')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u53f9')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u98b7')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u57f3')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\ub554')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u0176')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\ua318')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u9704')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u8d52')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u940a')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u0fa5')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u38d1')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u3b33')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u93bb')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u03bd')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u4c88')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\ud67d')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\ubcbf')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u3867')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u4368')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u8f2d')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u049a')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u4c01')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u5589')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u5e71')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\ua1fd')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u3a4a')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\uc111')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\ub465')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u95af')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\ubf2c')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u8488')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u4317')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u6b77')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u8995')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u7467')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u16b7')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u3ca0')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u5332')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\u8654')).toBeTruthy
+ expect(Character.isUnicodeIdentifierPart('\ua8c8')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ue3ca')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uebee')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u270e')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uf0ac')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ue9ec')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u296a')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u33fd')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ue5f4')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ueb01')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uf38b')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u2e6f')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uea69')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uf155')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u0f0e')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ueb80')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ud959')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ue25e')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uf566')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ue4a3')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uec44')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u3297')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u3214')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u1bfd')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u4dd0')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uea99')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u309b')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uf592')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uf4dd')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\udfaf')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\udd38')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uf820')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uaacd')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uff5b')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ude36')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ue33b')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\udbce')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ue1f6')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uf78a')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ueb44')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uebd4')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u1df7')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u2f10')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u1cbf')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u2362')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uebeb')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u2ede')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u221d')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u2021')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\udf41')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u05f5')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u24ab')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uee15')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uf175')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uf35c')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\udc7b')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ud883')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uf341')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ueec6')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u2f57')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uff64')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ue6a4')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uec34')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u22a5')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uf5ac')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u3360')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u28b0')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uf678')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ue0e4')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u233f')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u0afa')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u2013')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ud7af')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ud98e')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ud8a5')).toBeFalsy
+
+ // BUG in JDK? A79E should be "Lu", Java says "Cn"
+ // expect(Character.isUnicodeIdentifierPart('\ua79e')).toBeFalsy
+
+ expect(Character.isUnicodeIdentifierPart('\u1806')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ue07a')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u2748')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uabad')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uec5c')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ue832')).toBeFalsy
+
+ // BUG in JDK? 08A9 should be "Lo", Java says "Cn"
+ // expect(Character.isUnicodeIdentifierPart('\u08a9')).toBeFalsy
+
+ expect(Character.isUnicodeIdentifierPart('\ue4bd')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u208a')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uf840')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uf570')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uef1e')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u2bd4')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ue385')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\udc18')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u0af0')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u244a')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uf01e')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\uf114')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\ue9c4')).toBeFalsy
+
+ // BUG in JDK? AAF4 should be "Lm", Java says "Cn"
+ // expect(Character.isUnicodeIdentifierPart('\uaaf4')).toBeFalsy
+
+ expect(Character.isUnicodeIdentifierPart('\uf7b9')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\udd2f')).toBeFalsy
+ expect(Character.isUnicodeIdentifierPart('\u2d2c')).toBeFalsy
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ClassTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ClassTest.scala
new file mode 100644
index 0000000..424edd6
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ClassTest.scala
@@ -0,0 +1,30 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import org.scalajs.jasminetest.JasmineTest
+import scala.scalajs.js
+
+object ClassTest extends JasmineTest {
+
+ describe("java.lang.Class") {
+
+ it("should provide getSimpleName()") {
+ expect(classOf[java.lang.Integer].getSimpleName()).toEqual("Integer")
+ expect(classOf[java.lang.Class[_]].getSimpleName()).toEqual("Class")
+ expect(classOf[scala.collection.Map[_, _]].getSimpleName()).toEqual("Map")
+ expect(classOf[ClassTestClass#InnerClass].getSimpleName()).toEqual("InnerClass")
+ }
+
+ }
+
+}
+
+class ClassTestClass {
+ class InnerClass
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/DateTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/DateTest.scala
new file mode 100644
index 0000000..f62f926
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/DateTest.scala
@@ -0,0 +1,87 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import java.util.Date
+
+import org.scalajs.jasminetest.JasmineTest
+
+/**
+ * tests the implementation of the java standard library Date
+ */
+object DateTest extends JasmineTest {
+
+ describe("java.lang.Date") {
+
+ it("should provide `compareTo`") {
+ def compare(x: Date, y: Date): Int = {
+ x.compareTo(y)
+ }
+
+ expect(compare(new Date(97, 11, 5, 0, 0), new Date(98, 11, 5, 0, 0))).toBeLessThan(0)
+ expect(compare(new Date(98, 11, 5, 0, 0), new Date(97, 11, 5, 0, 0))).toBeGreaterThan(0)
+ expect(compare(new Date(97, 11, 5, 0, 0), new Date(97, 11, 5))).toEqual(0)
+ expect(compare(new Date(97, 11, 5, 0, 0), new Date(97, 11, 5, 0, 1))).toBeLessThan(0)
+ expect(compare(new Date(97, 11, 5), new Date(97, 11, 5, 0, 0))).toEqual(0)
+ }
+
+ it("should be a Comparable") {
+ def compare(x: Any, y: Any): Int =
+ x.asInstanceOf[Comparable[Any]].compareTo(y)
+
+ expect(compare(new Date(97, 11, 5, 0, 0), new Date(98, 11, 5, 0, 0))).toBeLessThan(0)
+ expect(compare(new Date(98, 11, 5, 0, 0), new Date(97, 11, 5, 0, 0))).toBeGreaterThan(0)
+ expect(compare(new Date(97, 11, 5, 0, 0), new Date(97, 11, 5))).toEqual(0)
+ expect(compare(new Date(97, 11, 5, 0, 0), new Date(97, 11, 5, 0, 1))).toBeLessThan(0)
+ expect(compare(new Date(97, 11, 5), new Date(97, 11, 5, 0, 0))).toEqual(0)
+ }
+
+ it("should parse strings") {
+ def test(s: String, v: Date): Unit =
+ expect(new Date(s).compareTo(v)).toEqual(0)
+
+ test("Nov 5 1997 5:23:27 GMT", new Date(Date.UTC(97, 10, 5, 5, 23, 27)))
+ test("Nov 1 1997 GMT", new Date(Date.UTC(97,10,1, 0, 0, 0)))
+ test("Jan 1 1970 18:11:01 GMT", new Date(Date.UTC(70,0,1,18,11,1)))
+ }
+
+ it("should provide after") {
+ expect(new Date(97, 11, 5, 0, 0).after(new Date(98, 11, 5, 0, 0))).toBe(false)
+ expect(new Date(99, 11, 5, 0, 0).after(new Date(98, 11, 5, 0, 0))).toBe(true)
+ expect(new Date(99, 11, 5, 0, 0).after(new Date(99, 11, 5, 0, 0))).toBe(false)
+ }
+
+ it("should provide before") {
+ expect(new Date(97, 11, 5, 0, 0).before(new Date(98, 11, 5, 0, 0))).toBe(true)
+ expect(new Date(99, 11, 5, 0, 0).before(new Date(98, 11, 5, 0, 0))).toBe(false)
+ expect(new Date(99, 11, 5, 0, 0).before(new Date(99, 11, 5, 0, 0))).toBe(false)
+ }
+
+ it("should provide clone") {
+ def testClone(date: Date) = {
+ val cloned = date.clone()
+ date == cloned
+ }
+
+ expect(testClone(new Date(97, 11, 5, 0, 0))).toBe(true)
+ expect(testClone(new Date(92, 14, 6, 2, 1))).toBe(true)
+ expect(testClone(new Date(4, 1, 2, 3, 0, 0))).toBe(true)
+ }
+
+ it("should respond to getYear") {
+ def testYear(year: Int) = {
+ val date = new Date()
+ date.setYear(year)
+ expect(date.getYear).toEqual(year)
+ }
+ testYear(1940)
+ testYear(1920)
+ testYear(2030)
+ }
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/DoubleTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/DoubleTest.scala
new file mode 100644
index 0000000..59c6e10
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/DoubleTest.scala
@@ -0,0 +1,217 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import org.scalajs.jasminetest.JasmineTest
+import scala.scalajs.js
+
+import java.lang.{Double => JDouble}
+
+import scala.util.Try
+
+object DoubleTest extends JasmineTest {
+
+ describe("java.lang.Double") {
+
+ it("should provide proper `equals`") {
+ expect(Double.box(0.0) == Double.box(-0.0)).toBeTruthy
+ expect(Double.box(Double.NaN) == Double.box(Double.NaN)).toBeTruthy
+ }
+
+ it("hashCode") {
+ def hashCodeNotInlined(x: Any): Int = {
+ var y = x // do not inline
+ y.hashCode
+ }
+
+ def test(x: Double, expected: Int): Unit = {
+ expect(x.hashCode).toEqual(expected)
+ expect(hashCodeNotInlined(x)).toEqual(expected)
+ }
+
+ test(0.0, 0)
+ test(-0.0, 0)
+ test(1234.0, 1234)
+ test(1.5, 1073217536)
+ test(Math.PI, 340593891)
+ test(-54.0, -54)
+
+ test(Double.MinPositiveValue, 1)
+ test(Double.MinValue, 1048576)
+ test(Double.MaxValue, -2146435072)
+
+ test(Double.NaN, 2146959360)
+ test(Double.PositiveInfinity, 2146435072)
+ test(Double.NegativeInfinity, -1048576)
+ }
+
+ it("should provide `toString` with integer values when an integer") {
+ expect(0.0.toString).toEqual("0")
+ expect(-0.0.toString).toEqual("0")
+ expect(Double.NaN.toString).toEqual("NaN")
+ expect(Double.PositiveInfinity.toString).toEqual("Infinity")
+ expect(Double.NegativeInfinity.toString).toEqual("-Infinity")
+ expect(5.0.toString).toEqual("5")
+ expect(-5.0.toString).toEqual("-5")
+ expect(1.2.toString).toEqual("1.2")
+ }
+
+ it("should parse strings") {
+ expect("0.0".toDouble).toEqual(0.0f)
+ expect("NaN".toDouble.isNaN).toBeTruthy
+ expect(Try("asdf".toDouble).isFailure).toBeTruthy
+
+ def test(s: String, v: Double): Unit = {
+ expect(JDouble.parseDouble(s)).toBeCloseTo(v)
+ expect(JDouble.valueOf(s).doubleValue()).toBeCloseTo(v)
+ expect(new JDouble(s).doubleValue()).toBeCloseTo(v)
+ }
+
+ test("0", 0.0)
+ test("5.3", 5.3)
+ test("127e2", 12700.0)
+ test("127E-2", 1.27)
+ test("1E+1", 10)
+ test("-123.4", -123.4)
+ test("65432.1", 65432.10)
+ test("-87654.321", -87654.321)
+ test("+.3f", 0.3)
+ }
+
+ it("should reject invalid strings when parsing") {
+ def test(s: String): Unit =
+ expect(() => JDouble.parseDouble(s)).toThrow
+
+ test("4.3.5")
+ test("4e3.5")
+ test("hello world")
+ test("--4")
+ test("4E-3.2")
+ }
+
+ it("should provide `compareTo`") {
+ def compare(x: Double, y: Double): Int =
+ new JDouble(x).compareTo(new JDouble(y))
+
+ expect(compare(0.0, 5.5)).toBeLessThan(0)
+ expect(compare(10.5, 10.2)).toBeGreaterThan(0)
+ expect(compare(-2.1, -1.0)).toBeLessThan(0)
+ expect(compare(3.14, 3.14)).toEqual(0)
+
+ // From compareTo's point of view, NaN is equal to NaN
+ expect(compare(Double.NaN, Double.NaN)).toEqual(0)
+ }
+
+ it("should be a Comparable") {
+ def compare(x: Any, y: Any): Int =
+ x.asInstanceOf[Comparable[Any]].compareTo(y)
+
+ expect(compare(0.0, 5.5)).toBeLessThan(0)
+ expect(compare(10.5, 10.2)).toBeGreaterThan(0)
+ expect(compare(-2.1, -1.0)).toBeLessThan(0)
+ expect(compare(3.14, 3.14)).toEqual(0)
+
+ // From compareTo's point of view, NaN is equal to NaN
+ expect(compare(Double.NaN, Double.NaN)).toEqual(0)
+ }
+
+ it("should provide isInfinite - #515") {
+ expect(Double.PositiveInfinity.isInfinite).toBeTruthy
+ expect(Double.NegativeInfinity.isInfinite).toBeTruthy
+ expect((1.0/0).isInfinite).toBeTruthy
+ expect((-1.0/0).isInfinite).toBeTruthy
+ expect((0.0).isInfinite).toBeFalsy
+ }
+
+ it("isNaN") {
+ def f(v: Double): Boolean = {
+ var v2 = v // do not inline
+ v2.isNaN
+ }
+
+ expect(f(Double.NaN)).toBeTruthy
+
+ expect(f(Double.PositiveInfinity)).toBeFalsy
+ expect(f(Double.NegativeInfinity)).toBeFalsy
+ expect(f(1.0 / 0)).toBeFalsy
+ expect(f(-1.0 / 0)).toBeFalsy
+ expect(f(0.0)).toBeFalsy
+ expect(f(3.0)).toBeFalsy
+ expect(f(-1.5)).toBeFalsy
+ }
+
+ it("longBitsToDouble") {
+ def isZero(v: Double, neg: Boolean): Boolean = {
+ (v == 0.0) && (1 / v == (
+ if (neg) Double.NegativeInfinity
+ else Double.PositiveInfinity))
+ }
+
+ import JDouble.{longBitsToDouble => f}
+
+ // Specials
+ expect(f(0x7ff0000000000000L)).toEqual(Double.PositiveInfinity)
+ expect(f(0xfff0000000000000L)).toEqual(Double.NegativeInfinity)
+ expect(isZero(f(0x0000000000000000L), false)).toBeTruthy
+ expect(isZero(f(0x8000000000000000L), true)).toBeTruthy
+ expect(f(0x7ff8000000000000L).isNaN).toBeTruthy // canonical NaN
+
+ // Non-canonical NaNs
+ expect(f(0x7ff0000000000001L).isNaN).toBeTruthy // smallest positive NaN
+ expect(f(0x7ff15ab515d3cca1L).isNaN).toBeTruthy // an arbitrary positive NaN
+ expect(f(0x7fffffffffffffffL).isNaN).toBeTruthy // largest positive NaN
+ expect(f(0xfff0000000000001L).isNaN).toBeTruthy // smallest negative NaN
+ expect(f(0xfff15ab515d3cca1L).isNaN).toBeTruthy // an arbitrary negative NaN
+ expect(f(0xffffffffffffffffL).isNaN).toBeTruthy // largest negative NaN
+
+ // Normal forms
+ expect(f(0x0010000000000000L)).toEqual(2.2250738585072014e-308) // smallest pos normal form
+ expect(f(0x7fefffffffffffffL)).toEqual(1.7976931348623157e308) // largest pos normal form
+ expect(f(0x4d124568bc6584caL)).toEqual(1.8790766677624813e63) // an arbitrary pos normal form
+ expect(f(0x8010000000000000L)).toEqual(-2.2250738585072014e-308) // smallest neg normal form
+ expect(f(0xffefffffffffffffL)).toEqual(-1.7976931348623157e308) // largest neg normal form
+ expect(f(0xcd124568bc6584caL)).toEqual(-1.8790766677624813e63) // an arbitrary neg normal form
+
+ // Subnormal forms
+ expect(f(0x0000000000000001L)).toEqual(Double.MinPositiveValue) // smallest pos subnormal form
+ expect(f(0x000fffffffffffffL)).toEqual(2.225073858507201e-308) // largest pos subnormal form
+ expect(f(0x000c5d44ae45cb60L)).toEqual(1.719471609939382e-308) // an arbitrary pos subnormal form
+ expect(f(0x8000000000000001L)).toEqual(-Double.MinPositiveValue) // smallest neg subnormal form
+ expect(f(0x800fffffffffffffL)).toEqual(-2.225073858507201e-308) // largest neg subnormal form
+ expect(f(0x800c5d44ae45cb60L)).toEqual(-1.719471609939382e-308) // an arbitrary neg subnormal form
+ }
+
+ it("doubleToLongBits") {
+ import JDouble.{doubleToLongBits => f}
+
+ // Specials
+ expect(f(Double.PositiveInfinity) == 0x7ff0000000000000L).toBeTruthy
+ expect(f(Double.NegativeInfinity) == 0xfff0000000000000L)
+ expect(f(0.0) == 0x0000000000000000L).toBeTruthy
+ expect(f(-0.0) == 0x8000000000000000L).toBeTruthy
+ expect(f(Double.NaN) == 0x7ff8000000000000L).toBeTruthy // canonical NaN
+
+ // Normal forms
+ expect(f(2.2250738585072014e-308) == 0x0010000000000000L).toBeTruthy // smallest pos normal form
+ expect(f(1.7976931348623157e308) == 0x7fefffffffffffffL).toBeTruthy // largest pos normal form
+ expect(f(1.8790766677624813e63) == 0x4d124568bc6584caL).toBeTruthy // an arbitrary pos normal form
+ expect(f(-2.2250738585072014e-308) == 0x8010000000000000L).toBeTruthy // smallest neg normal form
+ expect(f(-1.7976931348623157e308) == 0xffefffffffffffffL).toBeTruthy // largest neg normal form
+ expect(f(-1.8790766677624813e63) == 0xcd124568bc6584caL).toBeTruthy // an arbitrary neg normal form
+
+ // Subnormal forms
+ expect(f(Double.MinPositiveValue) == 0x0000000000000001L).toBeTruthy // smallest pos subnormal form
+ expect(f(2.225073858507201e-308) == 0x000fffffffffffffL).toBeTruthy // largest pos subnormal form
+ expect(f(1.719471609939382e-308) == 0x000c5d44ae45cb60L).toBeTruthy // an arbitrary pos subnormal form
+ expect(f(-Double.MinPositiveValue) == 0x8000000000000001L).toBeTruthy // smallest neg subnormal form
+ expect(f(-2.225073858507201e-308) == 0x800fffffffffffffL).toBeTruthy // largest neg subnormal form
+ expect(f(-1.719471609939382e-308) == 0x800c5d44ae45cb60L).toBeTruthy // an arbitrary neg subnormal form
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/FloatTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/FloatTest.scala
new file mode 100644
index 0000000..e45a34a
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/FloatTest.scala
@@ -0,0 +1,221 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import org.scalajs.jasminetest.JasmineTest
+import scala.scalajs.js
+
+import java.lang.{Float => JFloat}
+
+import scala.util.Try
+
+object FloatTest extends JasmineTest {
+
+ describe("java.lang.Float") {
+
+ it("should provide proper `equals`") {
+ expect(Float.box(0.0f) == Float.box(-0.0f)).toBeTruthy
+ expect(Float.box(Float.NaN) == Float.box(Float.NaN)).toBeTruthy
+ }
+
+ it("hashCode") {
+ def hashCodeNotInlined(x: Any): Int = {
+ var y = x // do not inline
+ y.hashCode
+ }
+
+ def test(x: Float, expected: Int): Unit = {
+ expect(x.hashCode).toEqual(expected)
+ expect(hashCodeNotInlined(x)).toEqual(expected)
+ }
+
+ test(0.0f, 0)
+ test(-0.0f, 0)
+ test(1234.0f, 1234)
+ test(1.5f, 1073217536)
+ test(-54f, -54)
+
+ test(Float.MinPositiveValue, 916455424)
+ test(Float.MinValue, 670040063)
+ test(Float.MaxValue, -1477443585)
+
+ test(Float.NaN, 2146959360)
+ test(Float.PositiveInfinity, 2146435072)
+ test(Float.NegativeInfinity, -1048576)
+ }
+
+ it("should provide `toString` with integer values when an integer") {
+ expect(0.0f.toString).toEqual("0")
+ expect(-0.0f.toString).toEqual("0")
+ expect(Float.NaN.toString).toEqual("NaN")
+ expect(Float.PositiveInfinity.toString).toEqual("Infinity")
+ expect(Float.NegativeInfinity.toString).toEqual("-Infinity")
+ expect(5.0f.toString).toEqual("5")
+ expect(-5.0f.toString).toEqual("-5")
+
+ // We need to explicitly cut the string here, since floats are
+ // represented by doubles (but the literal is emitted as
+ // float). Therefore there may be some imprecision. This is
+ // documented as semantic difference.
+ expect(1.2f.toString.substring(0,3)).toEqual("1.2")
+ }
+
+ it("should parse strings") {
+ expect("0.0".toFloat).toEqual(0.0f)
+ expect("NaN".toFloat.isNaN).toBeTruthy
+ expect(Try("asdf".toFloat).isFailure).toBeTruthy
+
+ def test(s: String, v: Float): Unit = {
+ expect(JFloat.parseFloat(s)).toBeCloseTo(v)
+ expect(JFloat.valueOf(s).floatValue()).toBeCloseTo(v)
+ expect(new JFloat(s).floatValue()).toBeCloseTo(v)
+ }
+
+ test("0", 0.0f)
+ test("5.3", 5.3f)
+ test("127e2", 12700.0f)
+ test("127E-2", 1.27f)
+ test("1E+1", 10f)
+ test("-123.4", -123.4f)
+ test("65432.1", 65432.10f)
+ test("-87654.321", -87654.321f)
+ test("+.3f", 0.3f)
+ }
+
+ it("should reject invalid strings when parsing") {
+ def test(s: String): Unit =
+ expect(() => JFloat.parseFloat(s)).toThrow
+
+ test("4.3.5")
+ test("4e3.5")
+ test("hello world")
+ test("--4")
+ test("4E-3.2")
+ }
+
+ it("should provide `compareTo`") {
+ def compare(x: Float, y: Float): Int =
+ new JFloat(x).compareTo(new JFloat(y))
+
+ expect(compare(0.0f, 5.5f)).toBeLessThan(0)
+ expect(compare(10.5f, 10.2f)).toBeGreaterThan(0)
+ expect(compare(-2.1f, -1.0f)).toBeLessThan(0)
+ expect(compare(3.14f, 3.14f)).toEqual(0)
+
+ // From compareTo's point of view, NaN is equal to NaN
+ expect(compare(Float.NaN, Float.NaN)).toEqual(0)
+ }
+
+ it("should be a Comparable") {
+ def compare(x: Any, y: Any): Int =
+ x.asInstanceOf[Comparable[Any]].compareTo(y)
+
+ expect(compare(0.0f, 5.5f)).toBeLessThan(0)
+ expect(compare(10.5f, 10.2f)).toBeGreaterThan(0)
+ expect(compare(-2.1f, -1.0f)).toBeLessThan(0)
+ expect(compare(3.14f, 3.14f)).toEqual(0)
+
+ // From compareTo's point of view, NaN is equal to NaN
+ expect(compare(Float.NaN, Float.NaN)).toEqual(0)
+ }
+
+ it("should provide isInfinite - #515") {
+ expect(Float.PositiveInfinity.isInfinite).toBeTruthy
+ expect(Float.NegativeInfinity.isInfinite).toBeTruthy
+ expect((1f/0).isInfinite).toBeTruthy
+ expect((-1f/0).isInfinite).toBeTruthy
+ expect(0f.isInfinite).toBeFalsy
+ }
+
+ it("isNaN") {
+ def f(v: Float): Boolean = {
+ var v2 = v // do not inline
+ v2.isNaN
+ }
+
+ expect(f(Float.NaN)).toBeTruthy
+
+ expect(f(Float.PositiveInfinity)).toBeFalsy
+ expect(f(Float.NegativeInfinity)).toBeFalsy
+ expect(f(1f / 0)).toBeFalsy
+ expect(f(-1f / 0)).toBeFalsy
+ expect(f(0f)).toBeFalsy
+ expect(f(3f)).toBeFalsy
+ expect(f(-1.5f)).toBeFalsy
+ }
+
+ it("intBitsToFloat") {
+ def isZero(v: Float, neg: Boolean): Boolean = {
+ (v == 0.0f) && (1 / v == (
+ if (neg) Float.NegativeInfinity
+ else Float.PositiveInfinity))
+ }
+
+ import JFloat.{intBitsToFloat => f}
+
+ // Specials
+ expect(f(0x7f800000)).toEqual(Float.PositiveInfinity)
+ expect(f(0xff800000)).toEqual(Float.NegativeInfinity)
+ expect(isZero(f(0x00000000), false)).toBeTruthy
+ expect(isZero(f(0x80000000), true)).toBeTruthy
+ expect(f(0x7fc00000).isNaN).toBeTruthy // canonical NaN
+
+ // Non-canonical NaNs
+ expect(f(0x7f800001).isNaN).toBeTruthy // smallest positive NaN
+ expect(f(0x7f915ab5).isNaN).toBeTruthy // an arbitrary positive NaN
+ expect(f(0x7fffffff).isNaN).toBeTruthy // largest positive NaN
+ expect(f(0xff800001).isNaN).toBeTruthy // smallest negative NaN
+ expect(f(0xff915ab5).isNaN).toBeTruthy // an arbitrary negative NaN
+ expect(f(0xffffffff).isNaN).toBeTruthy // largest negative NaN
+
+ // Normal forms
+ expect(f(0x00800000)).toEqual(1.17549435e-38f) // smallest pos normal form
+ expect(f(0x7f7fffff)).toEqual(3.4028234e38f) // largest pos normal form
+ expect(f(0x4d124568)).toEqual(1.53376384e8f) // an arbitrary pos normal form
+ expect(f(0x80800000)).toEqual(-1.17549435e-38f) // smallest neg normal form
+ expect(f(0xff7fffff)).toEqual(-3.4028234e38f) // largest neg normal form
+ expect(f(0xcd124568)).toEqual(-1.53376384e8f) // an arbitrary neg normal form
+
+ // Subnormal forms
+ expect(f(0x00000001)).toEqual(Float.MinPositiveValue) // smallest pos subnormal form
+ expect(f(0x007fffff)).toEqual(1.1754942e-38f) // largest pos subnormal form
+ expect(f(0x007c5d44)).toEqual(1.1421059e-38f) // an arbitrary pos subnormal form
+ expect(f(0x80000001)).toEqual(-Float.MinPositiveValue) // smallest neg subnormal form
+ expect(f(0x807fffff)).toEqual(-1.1754942e-38f) // largest neg subnormal form
+ expect(f(0x807c5d44)).toEqual(-1.1421059e-38f) // an arbitrary neg subnormal form
+ }
+
+ it("floatToIntBits") {
+ import JFloat.{floatToIntBits => f}
+
+ // Specials
+ expect(f(Float.PositiveInfinity)).toEqual(0x7f800000)
+ expect(f(Float.NegativeInfinity)).toEqual(0xff800000)
+ expect(f(0.0f)).toEqual(0x00000000)
+ expect(f(-0.0f)).toEqual(0x80000000)
+ expect(f(Float.NaN)).toEqual(0x7fc00000) // canonical NaN
+
+ // Normal forms
+ expect(f(1.17549435e-38f)).toEqual(0x00800000) // smallest pos normal form
+ expect(f(3.4028234e38f)).toEqual(0x7f7fffff) // largest pos normal form
+ expect(f(1.53376384e8f)).toEqual(0x4d124568) // an arbitrary pos normal form
+ expect(f(-1.17549435e-38f)).toEqual(0x80800000) // smallest neg normal form
+ expect(f(-3.4028234e38f)).toEqual(0xff7fffff) // largest neg normal form
+ expect(f(-1.53376384e8f)).toEqual(0xcd124568) // an arbitrary neg normal form
+
+ // Subnormal forms
+ expect(f(Float.MinPositiveValue)).toEqual(0x00000001) // smallest pos subnormal form
+ expect(f(1.1754942e-38f)).toEqual(0x007fffff) // largest pos subnormal form
+ expect(f(1.1421059e-38f)).toEqual(0x007c5d44) // an arbitrary pos subnormal form
+ expect(f(-Float.MinPositiveValue)).toEqual(0x80000001) // smallest neg subnormal form
+ expect(f(-1.1754942e-38f)).toEqual(0x807fffff) // largest neg subnormal form
+ expect(f(-1.1421059e-38f)).toEqual(0x807c5d44) // an arbitrary neg subnormal form
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/FormatterTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/FormatterTest.scala
new file mode 100644
index 0000000..e7a705c
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/FormatterTest.scala
@@ -0,0 +1,241 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+import java.util.{ Formatter, Formattable, FormattableFlags }
+
+import java.lang.{
+ Double => JDouble,
+ Float => JFloat,
+ Integer => JInteger,
+ Long => JLong,
+ Byte => JByte,
+ Short => JShort,
+ Boolean => JBoolean,
+ String => JString
+}
+
+
+object FormatterTest extends JasmineTest {
+
+ class HelperClass
+ class FormattableClass extends Formattable {
+ var frm: Formatter = _
+ var flags: Int = _
+ var width: Int = _
+ var precision: Int = _
+ var calls = 0
+ def formatTo(frm: Formatter, flags: Int, width: Int, precision: Int) = {
+ this.calls += 1
+ this.flags = flags
+ this.width = width
+ this.precision = precision
+ frm.out().append("foobar")
+ }
+
+ def expectCalled(times: Int, flags: Int, width: Int, precision: Int) = {
+ expect(this.calls).toEqual(times)
+ expect(this.flags).toEqual(flags)
+ expect(this.width).toEqual(width)
+ expect(this.precision).toEqual(precision)
+ }
+
+ }
+
+ def expectF(format: String, args: AnyRef*) = {
+ val fmt = new Formatter()
+ val res = fmt.format(format, args:_*).toString()
+ fmt.close()
+ expect(res)
+ }
+
+ def expectFC(format: String, flags: Int, width: Int, precision: Int) = {
+ val fc = new FormattableClass
+ val exp = expectF(format, fc)
+ fc.expectCalled(1, flags, width, precision)
+ exp
+ }
+
+ def expectThrow(format: String, args: AnyRef*) = {
+ val fmt = new Formatter()
+ expect(() => fmt.format(format, args:_*)).toThrow
+ }
+
+ describe("java.util.Formatter") {
+
+ // Explicitly define these as `var`'s to avoid any compile-time constant folding
+ var IntMax: Int = Int.MaxValue
+ var IntMin: Int = Int.MinValue
+ var ByteMax: Byte = Byte.MaxValue
+ var ByteMin: Byte = Byte.MinValue
+ var ShortMax: Short = Short.MaxValue
+ var ShortMin: Short = Short.MinValue
+
+ it("should provide 'b' conversion") {
+ expectF("%b", null).toEqual("false")
+ expectF("%b", true: JBoolean).toEqual(JString.valueOf(true))
+ expectF("%b", false: JBoolean).toEqual(JString.valueOf(false))
+ expectF("%b", new HelperClass).toEqual("true")
+ }
+
+ it("should provide 'h' conversion") {
+ val x = new HelperClass
+ expectF("%h", x).toEqual(Integer.toHexString(x.hashCode()))
+ expectF("%H", x).toEqual(Integer.toHexString(x.hashCode()).toUpperCase())
+ expectF("%h", null).toEqual("null")
+ }
+
+ it("should provide 's' conversion") {
+ expectFC("%s", 0, -1, -1).toEqual("foobar")
+ expectFC("%-s", FormattableFlags.LEFT_JUSTIFY, -1, -1).toEqual("foobar")
+ expectFC("%-10s", FormattableFlags.LEFT_JUSTIFY, 10, -1).toEqual("foobar")
+ expectFC("%#-10.2s", FormattableFlags.LEFT_JUSTIFY |
+ FormattableFlags.ALTERNATE, 10, 2).toEqual("foobar")
+ expectFC("%#10.2S", FormattableFlags.UPPERCASE |
+ FormattableFlags.ALTERNATE, 10, 2).toEqual("foobar")
+ expectF("%10s", "hello").toEqual(" hello")
+ expectF("%-10s", "hello").toEqual("hello ")
+ expectThrow("%#s", "hello")
+ }
+
+ it("should provide 'c' conversion") {
+ expectF("%-5c", new Character('!')).toEqual("! ")
+ }
+
+ it("should provide 'd' conversion") {
+ expectF("%d", new Integer(5)).toEqual("5")
+ expectF("%05d", new Integer(5)).toEqual("00005")
+ expectF("%5d", new Integer(-10)).toEqual(" -10")
+ expectF("%05d", new Integer(-10)).toEqual("-0010")
+ }
+
+ it("should provide 'o' conversion") {
+ expectF("%o", new JInteger(8)).toEqual("10")
+ expectF("%05o", new JInteger(16)).toEqual("00020")
+ expectF("%5o", new JInteger(-10)).toEqual("37777777766")
+ expectF("%05o", new JInteger(-10)).toEqual("37777777766")
+ expectF("%o", new JByte(8.toByte)).toEqual("10")
+ expectF("%05o", new JByte(16.toByte)).toEqual("00020")
+ expectF("%14o", new JByte(-10.toByte)).toEqual(" 37777777766")
+ expectF("%05o", new JByte(-10.toByte)).toEqual("37777777766")
+ expectF("%o", new JShort(8.toShort)).toEqual("10")
+ expectF("%05o", new JShort(16.toShort)).toEqual("00020")
+ expectF("%5o", new JShort(-10.toShort)).toEqual("37777777766")
+ expectF("%015o",new JShort(-10.toShort)).toEqual("000037777777766")
+ expectF("%05o", new JLong(-5L)).toEqual("1777777777777777777773")
+ }
+
+ it("should provide 'x' conversion") {
+ expectF("%0#5x", new JInteger(5)).toEqual("0x005")
+ expectF("%#5x", new JInteger(5)).toEqual(" 0x5")
+ expectF("%#5X", new JInteger(5)).toEqual(" 0X5")
+ expectF("%x", new JInteger(-3)).toEqual("fffffffd")
+ expectF("%x", new JByte(-4.toByte)).toEqual("fffffffc")
+ expectF("%0#5x", new JByte(5.toByte)).toEqual("0x005")
+ expectF("%#5x", new JByte(5.toByte)).toEqual(" 0x5")
+ expectF("%#5X", new JByte(5.toByte)).toEqual(" 0X5")
+ expectF("%x", new JByte(-3.toByte)).toEqual("fffffffd")
+ expectF("%0#5x", new JShort(5.toShort)).toEqual("0x005")
+ expectF("%#5x", new JShort(5.toShort)).toEqual(" 0x5")
+ expectF("%#5X", new JShort(5.toShort)).toEqual(" 0X5")
+ expectF("%x", new JShort(-3.toShort)).toEqual("fffffffd")
+ expectF("%x", new JLong(-5L)).toEqual("fffffffffffffffb")
+ expectF("%X", new JLong(26L)).toEqual("1A")
+ }
+
+ it("should provide 'e' conversion") {
+ expectF("%e", new JDouble(1000)).toEqual("1.000000e+03")
+ expectF("%.0e", new JDouble(1.2e100)).toEqual("1e+100")
+ // We use 1.51e100 in this test, since we seem to have a floating
+ // imprecision at exactly 1.5e100 that yields to a rounding error
+ // towards (1e+100 instead of 2e+100)
+ expectF("%.0e", new JDouble(1.51e100)).toEqual("2e+100")
+ expectF("%10.2e", new JDouble(1.2e100)).toEqual(" 1.20e+100")
+ expectF("%012.4e", new JFloat(1.2e-21f)).toEqual("001.2000e-21")
+ expectF("%012.4E", new JFloat(1.2e-21f)).toEqual("001.2000E-21")
+ expectF("%(015.4e", new JFloat(-1.2e-21f)).toEqual("(0001.2000e-21)")
+
+ // Tests with infinity and NaN
+ expectF("%e", new JDouble(Double.PositiveInfinity)).toEqual("Infinity")
+ expectF("%e", new JDouble(Double.NegativeInfinity)).toEqual("-Infinity")
+ expectF("%010e", new JDouble(Double.PositiveInfinity)).toEqual(" Infinity")
+ expectF("%-10e", new JDouble(Double.PositiveInfinity)).toEqual("Infinity ")
+ expectF("%(e", new JDouble(Double.NegativeInfinity)).toEqual("(Infinity)")
+ expectF("%010e", new JDouble(Double.NaN)).toEqual(" NaN")
+ }
+
+ it("should provide 'g' conversion") {
+ expectF("%g", new JDouble(.5e-4)).toEqual("5.00000e-05")
+ expectF("%g", new JDouble(3e-4)).toEqual("0.000300000")
+ expectF("%.3g", new JDouble(3e-4)).toEqual("0.000300")
+ expectF("%.2g", new JDouble(1e-3)).toEqual("0.0010")
+ expectF("%g", new JDouble(3e5)).toEqual("300000")
+ expectF("%.3g", new JDouble(3e5)).toEqual("3.00e+05")
+ expectF("%04g", new JDouble(Double.NaN)).toEqual(" NaN")
+ }
+
+ it("should provide 'f' conversion") {
+ expectF("%f", new JDouble(3.3)).toEqual("3.300000")
+ expectF("%0(9.4f", new JDouble(-4.6)).toEqual("(04.6000)")
+ expectF("%f", new JFloat(3e10f)).toEqual("30000001024.000000")
+ expectF("%f", new JDouble(3e10)).toEqual("30000000000.000000")
+ expectF("%04f", new JDouble(Double.NaN)).toEqual(" NaN")
+ }
+
+ it("should support '%%'") {
+ expectF("%d%%%d", new JInteger(1), new JInteger(2)).toEqual("1%2")
+ }
+
+ it("should support '%n'") {
+ expectF("%d%n%d", new JInteger(1), new JInteger(2)).toEqual("1\n2")
+ }
+
+ it("should survive `null` and `undefined`") {
+ expectF("%s", null).toEqual("null")
+ expectF("%s", js.undefined).toEqual("undefined")
+ }
+
+ it("should allow 'f' string interpolation to survive `null` and `undefined`") {
+ expect(f"${null}%s").toEqual("null")
+ expect(f"${js.undefined}%s").toEqual("undefined")
+ }
+
+ it("should allow positional arguments") {
+ expectF("%2$d %1$d", new JInteger(1), new JInteger(2)).toEqual("2 1")
+ expectF("%2$d %2$d %d", new JInteger(1), new JInteger(2)).toEqual("2 2 1")
+ expectF("%2$d %<d %d", new JInteger(1), new JInteger(2)).toEqual("2 2 1")
+ }
+
+ it("should fail when called after close") {
+ val f = new Formatter()
+ f.close()
+ expect(() => f.toString()).toThrow
+ }
+
+ it("should fail with bad format specifier") {
+ expectThrow("hello world%")
+ expectThrow("%%%")
+ expectThrow("%q")
+ expectThrow("%1")
+ expectThrow("%_f")
+ }
+
+ it("should fail with not enough arguments") {
+ expectThrow("%f")
+ expectThrow("%d%d%d", new JInteger(1), new JInteger(1))
+ expectThrow("%10$d", new JInteger(1))
+ }
+
+ }
+
+
+}
+
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/IntegerTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/IntegerTest.scala
new file mode 100644
index 0000000..5a01de4
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/IntegerTest.scala
@@ -0,0 +1,161 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import org.scalajs.jasminetest.JasmineTest
+import scala.scalajs.js
+
+object IntegerTest extends JasmineTest {
+
+ describe("java.lang.Integer") {
+
+ // Explicitly define these as `var`'s to avoid any compile-time constant folding
+ var MaxValue: Int = Int.MaxValue
+ var MinValue: Int = Int.MinValue
+
+ it("should provide `reverseBytes` used by scala.Enumeration") {
+ expect(Integer.reverseBytes(0xdeadbeef)).toEqual(0xefbeadde)
+ }
+
+ it("should provide `rotateLeft`") {
+ expect(Integer.rotateLeft(0x689cd401, 0)).toEqual(0x689cd401)
+ expect(Integer.rotateLeft(0x689cd401, 1)).toEqual(0xd139a802)
+ expect(Integer.rotateLeft(0x689cd401, 8)).toEqual(0x9cd40168)
+ expect(Integer.rotateLeft(0x689cd401, 13)).toEqual(0x9a802d13)
+ expect(Integer.rotateLeft(0x689cd401, 32)).toEqual(0x689cd401)
+ expect(Integer.rotateLeft(0x689cd401, 33)).toEqual(0xd139a802)
+ expect(Integer.rotateLeft(0x689cd401, 43)).toEqual(0xe6a00b44)
+ expect(Integer.rotateLeft(0x689cd401, -1)).toEqual(0xb44e6a00)
+ expect(Integer.rotateLeft(0x689cd401, -28)).toEqual(0x89cd4016)
+ expect(Integer.rotateLeft(0x689cd401, -39)).toEqual(0x2d139a8)
+ }
+
+ it("should provide `rotateRight`") {
+ expect(Integer.rotateRight(0x689cd401, 0)).toEqual(0x689cd401)
+ expect(Integer.rotateRight(0x689cd401, 1)).toEqual(0xb44e6a00)
+ expect(Integer.rotateRight(0x689cd401, 8)).toEqual(0x1689cd4)
+ expect(Integer.rotateRight(0x689cd401, 13)).toEqual(0xa00b44e6)
+ expect(Integer.rotateRight(0x689cd401, 32)).toEqual(0x689cd401)
+ expect(Integer.rotateRight(0x689cd401, 33)).toEqual(0xb44e6a00)
+ expect(Integer.rotateRight(0x689cd401, 43)).toEqual(0x802d139a)
+ expect(Integer.rotateRight(0x689cd401, -1)).toEqual(0xd139a802)
+ expect(Integer.rotateRight(0x689cd401, -28)).toEqual(0x1689cd40)
+ expect(Integer.rotateRight(0x689cd401, -39)).toEqual(0x4e6a00b4)
+ }
+
+ it("should provide `bitCount` used by Map") {
+ abstract sealed class Status
+ case object Used extends Status
+ case object Current extends Status
+ case object OneMove extends Status
+ case object MultipleMoves extends Status
+ case object Other extends Status
+
+ val map = Map(Used -> 0, Other -> 0, Current -> 0, MultipleMoves -> 1, OneMove -> 2)
+
+ expect(map.size).toEqual(5)
+ expect(map(MultipleMoves)).toEqual(1)
+ }
+
+ it("should provide `numberOfTrailingZeros`") {
+ expect(Integer.numberOfTrailingZeros(0xa3c49000)).toEqual(12)
+ expect(Integer.numberOfTrailingZeros(0x43f49020)).toEqual(5)
+ expect(Integer.numberOfTrailingZeros(0x43c08000)).toEqual(15)
+ expect(Integer.numberOfTrailingZeros(0)).toEqual(32)
+ }
+
+ it("should provide `toBinaryString` for values in range") {
+ expect(Integer.toBinaryString(-1)).toEqual("11111111111111111111111111111111")
+ expect(Integer.toBinaryString(-10001)).toEqual("11111111111111111101100011101111")
+ expect(Integer.toBinaryString(MinValue)).toEqual("10000000000000000000000000000000")
+ expect(Integer.toBinaryString(MaxValue)).toEqual("1111111111111111111111111111111")
+ }
+
+ it("should provide `toHexString` for values in range") {
+ expect(Integer.toHexString(-1)).toEqual("ffffffff")
+ expect(Integer.toHexString(-10001)).toEqual("ffffd8ef")
+ expect(Integer.toHexString(MinValue)).toEqual("80000000")
+ expect(Integer.toHexString(-2147000002)).toEqual("8007613e")
+ expect(Integer.toHexString(MaxValue)).toEqual("7fffffff")
+ }
+
+ it("should provide `toOctalString` for values in range") {
+ expect(Integer.toOctalString(-1)).toEqual("37777777777")
+ expect(Integer.toOctalString(-10001)).toEqual("37777754357")
+ expect(Integer.toOctalString(MinValue)).toEqual("20000000000")
+ expect(Integer.toOctalString(MaxValue)).toEqual("17777777777")
+ }
+
+ it("should provide `compareTo`") {
+ def compare(x: Int, y: Int): Int =
+ new Integer(x).compareTo(new Integer(y))
+
+ expect(compare(0, 5)).toBeLessThan(0)
+ expect(compare(10, 9)).toBeGreaterThan(0)
+ expect(compare(-2, -1)).toBeLessThan(0)
+ expect(compare(3, 3)).toEqual(0)
+ }
+
+ it("should be a Comparable") {
+ def compare(x: Any, y: Any): Int =
+ x.asInstanceOf[Comparable[Any]].compareTo(y)
+
+ expect(compare(0, 5)).toBeLessThan(0)
+ expect(compare(10, 9)).toBeGreaterThan(0)
+ expect(compare(-2, -1)).toBeLessThan(0)
+ expect(compare(3, 3)).toEqual(0)
+ }
+
+ it("should parse strings") {
+ def test(s: String, v: Int, radix: Int = 10): Unit = {
+ expect(Integer.parseInt(s, radix)).toEqual(v)
+ expect(Integer.valueOf(s, radix).intValue()).toEqual(v)
+ if (radix == 10)
+ expect(new Integer(s).intValue()).toEqual(v)
+ }
+
+ test("0", 0)
+ test("5", 5)
+ test("127", 127)
+ test("-100", -100)
+ test("30000", 30000)
+ test("-90000", -90000)
+ test("Kona", 411787, 27)
+ test("+42", 42)
+ test("-0", 0)
+ test("-FF", -255, 16)
+ }
+
+ it("should reject invalid strings when parsing") {
+ def test(s: String, radix: Int = 10): Unit =
+ expect(() => Integer.parseInt(s, radix)).toThrow
+
+ test("abc")
+ test("5a")
+ test("2147483648")
+ test("99", 8)
+ test("-")
+ test("")
+ }
+
+ it("should parse strings in base 16") {
+ def test(s: String, v: Int): Unit = {
+ expect(Integer.parseInt(s, 16)).toEqual(v)
+ expect(Integer.valueOf(s, 16).intValue()).toEqual(v)
+ }
+
+ test("0", 0x0)
+ test("5", 0x5)
+ test("ff", 0xff)
+ test("-24", -0x24)
+ test("30000", 0x30000)
+ test("-90000", -0x90000)
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/LongTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/LongTest.scala
new file mode 100644
index 0000000..86783c3
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/LongTest.scala
@@ -0,0 +1,178 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import java.lang.{Long => JLong}
+
+import org.scalajs.jasminetest.JasmineTest
+
+/**
+ * tests the implementation of the java standard library Long
+ * requires jsinterop/LongTest to work to make sense
+ */
+object LongTest extends JasmineTest {
+
+ describe("java.lang.Long") {
+ it("should provide `reverseBytes`") {
+ expect(JLong.reverseBytes(0xf5ab689cd401ff14L) == 0x14ff01d49c68abf5L).toBeTruthy
+ }
+
+ it("should provide `rotateLeft`") {
+ expect(JLong.rotateLeft(0xf5ab689cd401ff14L, 0) == 0xf5ab689cd401ff14L).toBeTruthy
+ expect(JLong.rotateLeft(0xf5ab689cd401ff14L, 1) == 0xeb56d139a803fe29L).toBeTruthy
+ expect(JLong.rotateLeft(0xf5ab689cd401ff14L, 8) == 0xab689cd401ff14f5L).toBeTruthy
+ expect(JLong.rotateLeft(0xf5ab689cd401ff14L, 13) == 0x6d139a803fe29eb5L).toBeTruthy
+ expect(JLong.rotateLeft(0xf5ab689cd401ff14L, 64) == 0xf5ab689cd401ff14L).toBeTruthy
+ expect(JLong.rotateLeft(0xf5ab689cd401ff14L, 65) == 0xeb56d139a803fe29L).toBeTruthy
+ expect(JLong.rotateLeft(0xf5ab689cd401ff14L, 80) == 0x689cd401ff14f5abL).toBeTruthy
+ expect(JLong.rotateLeft(0xf5ab689cd401ff14L, -1) == 0x7ad5b44e6a00ff8aL).toBeTruthy
+ expect(JLong.rotateLeft(0xf5ab689cd401ff14L, -56) == 0xab689cd401ff14f5L).toBeTruthy
+ expect(JLong.rotateLeft(0xf5ab689cd401ff14L, -70) == 0x53d6ada2735007fcL).toBeTruthy
+ }
+
+ it("should provide `rotateRight`") {
+ expect(JLong.rotateRight(0xf5ab689cd401ff14L, 0) == 0xf5ab689cd401ff14L).toBeTruthy
+ expect(JLong.rotateRight(0xf5ab689cd401ff14L, 1) == 0x7ad5b44e6a00ff8aL).toBeTruthy
+ expect(JLong.rotateRight(0xf5ab689cd401ff14L, 8) == 0x14f5ab689cd401ffL).toBeTruthy
+ expect(JLong.rotateRight(0xf5ab689cd401ff14L, 13) == 0xf8a7ad5b44e6a00fL).toBeTruthy
+ expect(JLong.rotateRight(0xf5ab689cd401ff14L, 64) == 0xf5ab689cd401ff14L).toBeTruthy
+ expect(JLong.rotateRight(0xf5ab689cd401ff14L, 65) == 0x7ad5b44e6a00ff8aL).toBeTruthy
+ expect(JLong.rotateRight(0xf5ab689cd401ff14L, 80) == 0xff14f5ab689cd401L).toBeTruthy
+ expect(JLong.rotateRight(0xf5ab689cd401ff14L, -1) == 0xeb56d139a803fe29L).toBeTruthy
+ expect(JLong.rotateRight(0xf5ab689cd401ff14L, -56) == 0x14f5ab689cd401ffL).toBeTruthy
+ expect(JLong.rotateRight(0xf5ab689cd401ff14L, -70) == 0x6ada2735007fc53dL).toBeTruthy
+ }
+
+ it("should implement bitCount") {
+ expect(JLong.bitCount(0L)).toEqual(0)
+ expect(JLong.bitCount(35763829229342837L)).toEqual(26)
+ expect(JLong.bitCount(-350003829229342837L)).toEqual(32)
+ }
+
+ it("should provide `compareTo`") {
+ def compare(x: Long, y: Long): Int =
+ new JLong(x).compareTo(new JLong(y))
+
+ expect(compare(0L, 5L)).toBeLessThan(0)
+ expect(compare(10L, 9L)).toBeGreaterThan(0)
+ expect(compare(-2L, -1L)).toBeLessThan(0)
+ expect(compare(3L, 3L)).toEqual(0)
+ }
+
+ it("should be a Comparable") {
+ def compare(x: Any, y: Any): Int =
+ x.asInstanceOf[Comparable[Any]].compareTo(y)
+
+ expect(compare(0L, 5L)).toBeLessThan(0)
+ expect(compare(10L, 9L)).toBeGreaterThan(0)
+ expect(compare(-2L, -1L)).toBeLessThan(0)
+ expect(compare(3L, 3L)).toEqual(0)
+ }
+
+ it("should parse strings") {
+ def test(s: String, v: Long): Unit = {
+ expect(JLong.parseLong(s)).toEqual(v)
+ expect(JLong.valueOf(s).longValue()).toEqual(v)
+ expect(new JLong(s).longValue()).toEqual(v)
+ }
+
+ test("0", 0L)
+ test("5", 5L)
+ test("127", 127L)
+ test("-100", -100L)
+ test("30000", 30000L)
+ test("-90000", -90000L)
+ test("4", 4L)
+ test("-4", -4L)
+ test("4000000000", 4000000000L)
+ test("-18014398509482040", -18014398509482040L)
+ }
+
+ it("should reject invalid strings when parsing") {
+ def test(s: String): Unit =
+ expect(() => JLong.parseLong(s)).toThrow
+
+ test("abc")
+ test("asdf")
+ test("")
+ }
+
+ it("should parse strings in base 16") {
+ def test(s: String, v: Long): Unit = {
+ expect(JLong.parseLong(s, 16)).toEqual(v)
+ expect(JLong.valueOf(s, 16).longValue()).toEqual(v)
+ }
+
+ test("0", 0x0L)
+ test("5", 0x5L)
+ test("ff", 0xffL)
+ test("-24", -0x24L)
+ test("30000", 0x30000L)
+ test("-90000", -0x90000L)
+ }
+
+ it("should implement toString") {
+ expect(Int.MaxValue.toLong.toString).toEqual("2147483647")
+ expect((-50L).toString).toEqual("-50")
+ expect((-1000000000L).toString).toEqual("-1000000000")
+ expect((Int.MaxValue.toLong+1L).toString).toEqual("2147483648")
+ expect(Int.MinValue.toLong.toString).toEqual("-2147483648")
+ }
+
+ it("should implement toBinaryString") {
+ expect(JLong.toBinaryString( 0L)).toEqual("0")
+ expect(JLong.toBinaryString( -1L)).toEqual("1111111111111111111111111111111111111111111111111111111111111111")
+ expect(JLong.toBinaryString( 456324454L)).toEqual("11011001100101111010101100110")
+ expect(JLong.toBinaryString( -456324454L)).toEqual("1111111111111111111111111111111111100100110011010000101010011010")
+ expect(JLong.toBinaryString( 98765432158845L)).toEqual("10110011101001110011110011111111111101001111101")
+ expect(JLong.toBinaryString(-49575304457780L)).toEqual("1111111111111111110100101110100101011001100101101001000111001100")
+ expect(JLong.toBinaryString(Long.MinValue )).toEqual("1000000000000000000000000000000000000000000000000000000000000000")
+ expect(JLong.toBinaryString(Long.MaxValue )).toEqual("111111111111111111111111111111111111111111111111111111111111111")
+ }
+
+ it("should implement toHexString") {
+ expect(JLong.toHexString( 0L)).toEqual("0")
+ expect(JLong.toHexString( -1L)).toEqual("ffffffffffffffff")
+ expect(JLong.toHexString( 456324454L)).toEqual("1b32f566")
+ expect(JLong.toHexString( -456324454L)).toEqual("ffffffffe4cd0a9a")
+ expect(JLong.toHexString( 98765432158845L)).toEqual("59d39e7ffa7d")
+ expect(JLong.toHexString(-49575304457780L)).toEqual("ffffd2e9599691cc")
+ expect(JLong.toHexString(Long.MinValue )).toEqual("8000000000000000")
+ expect(JLong.toHexString(Long.MaxValue )).toEqual("7fffffffffffffff")
+ }
+
+ it("should implement toOctalString") {
+ expect(JLong.toOctalString( 0L)).toEqual("0")
+ expect(JLong.toOctalString( -1L)).toEqual("1777777777777777777777")
+ expect(JLong.toOctalString( 456324454L)).toEqual("3314572546")
+ expect(JLong.toOctalString( -456324454L)).toEqual("1777777777774463205232")
+ expect(JLong.toOctalString( 98765432158845L)).toEqual("2635163637775175")
+ expect(JLong.toOctalString(-49575304457780L)).toEqual("1777776456453145510714")
+ expect(JLong.toOctalString(Long.MinValue )).toEqual("1000000000000000000000")
+ expect(JLong.toOctalString(Long.MaxValue )).toEqual("777777777777777777777")
+ }
+
+ it("should correctly compute trailing zeros") {
+ expect(JLong.numberOfTrailingZeros(0xff10000000000000L)).toEqual(52)
+ expect(JLong.numberOfTrailingZeros(0xff20000000000000L)).toEqual(53)
+ expect(JLong.numberOfTrailingZeros(0xff40000000000000L)).toEqual(54)
+ expect(JLong.numberOfTrailingZeros(0xff80000000000000L)).toEqual(55)
+
+ expect(JLong.numberOfTrailingZeros(0x0000010000000000L)).toEqual(40)
+ expect(JLong.numberOfTrailingZeros(0x0000020000000000L)).toEqual(41)
+ expect(JLong.numberOfTrailingZeros(0x0000040000000000L)).toEqual(42)
+ expect(JLong.numberOfTrailingZeros(0x0000080000000000L)).toEqual(43)
+
+ expect(JLong.numberOfTrailingZeros(0x0000000000010000L)).toEqual(16)
+ expect(JLong.numberOfTrailingZeros(0x0000000000020000L)).toEqual(17)
+ expect(JLong.numberOfTrailingZeros(0x0000000000040000L)).toEqual(18)
+ expect(JLong.numberOfTrailingZeros(0x0000000000080000L)).toEqual(19)
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/MathTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/MathTest.scala
new file mode 100644
index 0000000..a3c887a
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/MathTest.scala
@@ -0,0 +1,142 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+import java.lang.Math
+
+object MathTest extends JasmineTest {
+
+ describe("java.lang.Math") {
+
+ it("should respond to `cbrt`") {
+ expect(1 / Math.cbrt(-0.0) < 0).toBeTruthy
+ expect(Math.cbrt(27.0)).toEqual(3.0)
+ expect(Math.cbrt(1000000.0)).toEqual(100.0)
+ expect(Math.cbrt(1000000000.0)).toEqual(1000.0)
+ expect(Math.cbrt(-1.0E24)).toEqual(-100000000.0)
+ expect(Math.cbrt(-65890311319.0E24)).toEqual(-4039.0E8)
+ }
+
+ it("should respond to `log1p`") {
+ expect(Math.log1p(-2.0).isNaN).toBeTruthy
+ expect(Math.log1p(js.Number.NaN.toDouble).isNaN).toBeTruthy
+ expect(Math.log1p(0.0)).toEqual(0.0)
+ }
+
+ it("should respond to `log10`") {
+ expect(Math.log10(-230.0).isNaN).toBeTruthy
+ expect(Math.log10(js.Number.NaN.toDouble).isNaN).toBeTruthy
+ }
+
+ it("should respond to `signum` for Double") {
+ expect(Math.signum(234394.2198273)).toEqual(1.0)
+ expect(Math.signum(-124937498.58)).toEqual(-1.0)
+
+ expect(Math.signum(+0.0)).toEqual(0.0)
+ expect(1 / Math.signum(+0.0) > 0).toBeTruthy
+
+ expect(Math.signum(-0.0)).toEqual(-0.0)
+ expect(1 / Math.signum(-0.0) < 0).toBeTruthy
+
+ expect(Math.signum(js.Number.NaN.toDouble).isNaN).toBeTruthy
+ }
+
+ it("should respond to `signum` for Float") {
+ expect(Math.signum(234394.2198273f)).toEqual(1.0f)
+ expect(Math.signum(-124937498.58f)).toEqual(-1.0f)
+
+ expect(Math.signum(+0.0f)).toEqual(0.0f)
+ expect(1 / Math.signum(+0.0f) > 0).toBeTruthy
+
+ expect(Math.signum(-0.0f)).toEqual(-0.0f)
+ expect(1 / Math.signum(-0.0f) < 0).toBeTruthy
+
+ expect(Math.signum(js.Number.NaN.toFloat).isNaN).toBeTruthy
+ }
+
+ it("should respond to `nextUp` for Double") {
+ expect(Math.nextUp(Double.PositiveInfinity)).toEqual(Double.PositiveInfinity)
+ expect(Math.nextUp(Double.NegativeInfinity)).toEqual(-Double.MaxValue)
+ expect(Math.nextUp(Double.MaxValue)).toEqual(Double.PositiveInfinity)
+ expect(Math.nextUp(-Double.MaxValue)).toEqual(-1.7976931348623155e+308)
+ expect(Math.nextUp(-Double.MinValue)).toEqual(Double.PositiveInfinity)
+ expect(Math.nextUp(0.0)).toEqual(Double.MinValue)
+ expect(Math.nextUp(-0.0)).toEqual(Double.MinValue)
+ expect(Math.nextUp(9007199254740991.0)).toEqual(9007199254740992.0)
+ expect(Math.nextUp(9007199254740992.0)).toEqual(9007199254740994.0)
+ expect(Math.nextUp(1.0)).toEqual(1 + 2.2204460492503130808472633361816E-16)
+ }
+
+ it("should respond to `nextAfter` for Double") {
+ expect(Math.nextAfter(1.0, js.Number.NaN.toDouble).isNaN).toBeTruthy
+ expect(Math.nextAfter(js.Number.NaN.toDouble, 1.0).isNaN).toBeTruthy
+ expect(Math.nextAfter(0.0, 0.0)).toEqual(0.0)
+ expect(Math.nextAfter(0.0, -0.0)).toEqual(-0.0)
+ expect(Math.nextAfter(-0.0, 0.0)).toEqual(0.0)
+ expect(Math.nextAfter(-0.0, -0.0)).toEqual(-0.0)
+ expect(Math.nextAfter(Double.MinValue, Double.NegativeInfinity)).toEqual(Double.NegativeInfinity)
+ expect(Math.nextAfter(-Double.MinValue, Double.PositiveInfinity)).toEqual(Double.PositiveInfinity)
+ expect(Math.nextAfter(Double.PositiveInfinity, Double.NegativeInfinity)).toEqual(Double.MaxValue)
+ expect(Math.nextAfter(Double.NegativeInfinity, Double.PositiveInfinity)).toEqual(-Double.MaxValue)
+ expect(Math.nextAfter(Double.MaxValue, Double.PositiveInfinity)).toEqual(Double.PositiveInfinity)
+ expect(Math.nextAfter(-Double.MaxValue, Double.NegativeInfinity)).toEqual(Double.NegativeInfinity)
+ expect(Math.nextAfter(1.0, 1.0)).toEqual(1.0)
+ }
+
+ it("should respond to `ulp` for Double") {
+ expect(Math.ulp(3.4)).toEqual(4.440892098500626E-16)
+ expect(Math.ulp(3.423E109)).toEqual(4.1718496795330275E93)
+ expect(Math.ulp(0.0)).toEqual(Double.MinValue)
+ }
+
+ it("should respond to `hypot`") {
+ expect(Math.hypot(0.0, 0.0)).toBeCloseTo(0.0)
+ expect(Math.hypot(3.0, 4.0)).toBeCloseTo(5.0)
+ expect(Math.hypot(3.0, js.Number.NaN.toDouble).isNaN).toBeTruthy
+ expect(Math.hypot(Double.NegativeInfinity, 4.0)).toEqual(Double.PositiveInfinity)
+ }
+
+ it("should respond to `expm1`") {
+ expect(1 / Math.expm1(-0.0) < 0).toBeTruthy
+ expect(Math.expm1(-0.0)).toBeCloseTo(0.0)
+ expect(Math.expm1(3.0)).toBeCloseTo(19.085536923187668)
+ expect(Math.expm1(15.0)).toBeCloseTo(3269016.3724721107)
+ expect(Math.expm1(1.8E10)).toEqual(Double.PositiveInfinity)
+ expect(Math.expm1(Double.PositiveInfinity)).toEqual(Double.PositiveInfinity)
+ expect(Math.expm1(Double.NegativeInfinity)).toBeCloseTo(-1.0)
+ expect(Math.expm1(4.9E-324)).toBeCloseTo(4.9E-324)
+ }
+
+ it("should respond to `sinh`") {
+ expect(Math.sinh(-1234.56)).toEqual(Double.NegativeInfinity)
+ expect(Math.sinh(1234.56)).toEqual(Double.PositiveInfinity)
+ expect(Math.sinh(0.0)).toBeCloseTo(0.0)
+ expect(Math.sinh(Double.PositiveInfinity)).toEqual(Double.PositiveInfinity)
+ }
+
+ it("should respond to `cosh`") {
+ expect(Math.cosh(-1234.56)).toEqual(Double.PositiveInfinity)
+ expect(Math.cosh(1234.56)).toEqual(Double.PositiveInfinity)
+ expect(Math.cosh(-0.0)).toBeCloseTo(1.0)
+ expect(Math.cosh(Double.PositiveInfinity)).toEqual(Double.PositiveInfinity)
+ }
+
+ it("should respond to `tanh`") {
+ expect(Math.tanh(-1234.56)).toBeCloseTo(-1.0)
+ expect(Math.tanh(-120.56)).toBeCloseTo(-1.0)
+ expect(Math.tanh(1234.56)).toBeCloseTo(1.0)
+ expect(Math.tanh(0.0)).toBeCloseTo(0.0)
+ expect(Math.tanh(Double.PositiveInfinity)).toBeCloseTo(1.0)
+ expect(Math.tanh(Double.NegativeInfinity)).toBeCloseTo(-1.0)
+ }
+
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/MockByteArrayOutputStream.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/MockByteArrayOutputStream.scala
new file mode 100644
index 0000000..3356a85
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/MockByteArrayOutputStream.scala
@@ -0,0 +1,47 @@
+package scala.scalajs.testsuite.javalib
+
+import java.io._
+
+/** A ByteArrayOutputStream that exposes various hooks for testing purposes. */
+class MockByteArrayOutputStream extends ByteArrayOutputStream {
+ private var _flushed: Boolean = true
+ private var _closed: Boolean = false
+
+ var throwing: Boolean = false
+
+ def flushed: Boolean = _flushed
+ def closed: Boolean = _closed
+
+ private def maybeThrow(): Unit = {
+ if (throwing)
+ throw new IOException("MockByteArrayOutputStream throws")
+ }
+
+ private def writeOp[A](op: => A): A = {
+ maybeThrow()
+ _flushed = false
+ op
+ }
+
+ override def flush(): Unit = {
+ maybeThrow()
+ super.flush()
+ _flushed = true
+ }
+
+ override def close(): Unit = {
+ maybeThrow()
+ super.close()
+ _closed = true
+ }
+
+ override def write(c: Int): Unit =
+ writeOp(super.write(c))
+
+ override def write(b: Array[Byte]): Unit =
+ writeOp(super.write(b))
+
+ override def write(b: Array[Byte], off: Int, len: Int): Unit =
+ writeOp(super.write(b, off, len))
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ObjectTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ObjectTest.scala
new file mode 100644
index 0000000..3584454
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ObjectTest.scala
@@ -0,0 +1,72 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import org.scalajs.jasminetest.JasmineTest
+
+import scala.scalajs.js
+
+object ObjectTest extends JasmineTest {
+
+ describe("java.lang.Object") {
+
+ it("should provide `equals`") {
+ case class xy(x: Int, y: Int)
+
+ val l = List(xy(1, 2), xy(2, 1))
+ val xy12 = xy(1, 2)
+
+ expect(l.contains(xy12)).toBeTruthy
+ expect(l.exists(_ == xy12)).toBeTruthy // the workaround
+ }
+
+ it("everything but null should be an Object") {
+ expect((() : Any).isInstanceOf[Object]).toBeTruthy
+ expect((true : Any).isInstanceOf[Object]).toBeTruthy
+ expect(('a' : Any).isInstanceOf[Object]).toBeTruthy
+ expect((1.toByte : Any).isInstanceOf[Object]).toBeTruthy
+ expect((658.toShort : Any).isInstanceOf[Object]).toBeTruthy
+ expect((60000 : Any).isInstanceOf[Object]).toBeTruthy
+ expect((12345678910112L: Any).isInstanceOf[Object]).toBeTruthy
+ expect((6.5f : Any).isInstanceOf[Object]).toBeTruthy
+ expect((12.4 : Any).isInstanceOf[Object]).toBeTruthy
+ expect((new Object : Any).isInstanceOf[Object]).toBeTruthy
+ expect(("hello" : Any).isInstanceOf[Object]).toBeTruthy
+ expect((List(1) : Any).isInstanceOf[Object]).toBeTruthy
+ expect((Array(1) : Any).isInstanceOf[Object]).toBeTruthy
+ expect((Array(Nil) : Any).isInstanceOf[Object]).toBeTruthy
+ expect((new js.Object : Any).isInstanceOf[Object]).toBeTruthy
+ expect((js.Array(5) : Any).isInstanceOf[Object]).toBeTruthy
+ }
+
+ it("null should not be an Object") {
+ expect((null: Any).isInstanceOf[Object]).toBeFalsy
+ }
+
+ it("everything should cast to Object successfully, including null") {
+ expect(() => (() : Any).asInstanceOf[Object]).not.toThrow
+ expect(() => (true : Any).asInstanceOf[Object]).not.toThrow
+ expect(() => ('a' : Any).asInstanceOf[Object]).not.toThrow
+ expect(() => (1.toByte : Any).asInstanceOf[Object]).not.toThrow
+ expect(() => (658.toShort : Any).asInstanceOf[Object]).not.toThrow
+ expect(() => (60000 : Any).asInstanceOf[Object]).not.toThrow
+ expect(() => (12345678910112L: Any).asInstanceOf[Object]).not.toThrow
+ expect(() => (6.5f : Any).asInstanceOf[Object]).not.toThrow
+ expect(() => (12.4 : Any).asInstanceOf[Object]).not.toThrow
+ expect(() => (new Object : Any).asInstanceOf[Object]).not.toThrow
+ expect(() => ("hello" : Any).asInstanceOf[Object]).not.toThrow
+ expect(() => (List(1) : Any).asInstanceOf[Object]).not.toThrow
+ expect(() => (Array(1) : Any).asInstanceOf[Object]).not.toThrow
+ expect(() => (Array(Nil) : Any).asInstanceOf[Object]).not.toThrow
+ expect(() => (new js.Object : Any).asInstanceOf[Object]).not.toThrow
+ expect(() => (js.Array(5) : Any).asInstanceOf[Object]).not.toThrow
+ expect(() => (null : Any).asInstanceOf[Object]).not.toThrow
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/OutputStreamWriterTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/OutputStreamWriterTest.scala
new file mode 100644
index 0000000..7987a4c
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/OutputStreamWriterTest.scala
@@ -0,0 +1,134 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import java.io._
+
+import scala.scalajs.js
+import js.JSConverters._
+import org.scalajs.jasminetest.JasmineTest
+
+object OutputStreamWriterTest extends JasmineTest {
+ private def newOSWriter(): (OutputStreamWriter, MockByteArrayOutputStream) = {
+ val bos = new MockByteArrayOutputStream
+ val osw = new OutputStreamWriter(bos)
+ (osw, bos)
+ }
+
+ describe("java.io.OutputStreamWriter") {
+ it("flush") {
+ val (osw, bos) = newOSWriter()
+ bos.write(1)
+ osw.write("ABC")
+ expect(bos.flushed).toBeFalsy
+ osw.flush()
+ expect(bos.flushed).toBeTruthy
+ }
+
+ it("close") {
+ val (osw, bos) = newOSWriter()
+ bos.write(1)
+ osw.write("ABC")
+ expect(bos.flushed).toBeFalsy
+
+ osw.close()
+ expect(bos.flushed).toBeTruthy
+ expect(bos.closed).toBeTruthy
+
+ // can double-close without error
+ osw.close()
+
+ // when closed, other operations cause error
+ expect(() => osw.write('A')).toThrow
+ expect(() => osw.write("never printed")).toThrow
+ expect(() => osw.write(Array('a', 'b'))).toThrow
+ expect(() => osw.append("hello", 1, 3)).toThrow
+ expect(() => osw.flush()).toThrow
+
+ // at the end of it all, bos is still what it was when it was closed
+ expect(bos.toByteArray().toJSArray).toEqual(js.Array(1, 65, 66, 67))
+ }
+
+ def testW(body: OutputStreamWriter => Unit,
+ expected: js.Array[Int], alreadyFlushed: Boolean = false): Unit = {
+ val (osw, bos) = newOSWriter()
+ body(osw)
+ if (!alreadyFlushed) {
+ expect(bos.size).toEqual(0) // write() methods should buffer
+ osw.flush()
+ }
+ expect(bos.flushed).toBeTruthy
+ expect(bos.toByteArray.toJSArray).toEqual(expected.map(_.toByte))
+ }
+
+ it("write(), ASCII repertoire") {
+ // Pure ASCII
+ testW(_.write('\n'), js.Array('\n'))
+ testW(_.write("hello\n"), js.Array('h', 'e', 'l', 'l', 'o', '\n'))
+ testW(_.write("hello\nworld", 3, 4), js.Array('l', 'o', '\n', 'w'))
+ testW(_.write(Array('A', '\n')), js.Array('A', '\n'))
+ testW(_.write(Array('A', 'B', '\n', 'C'), 1, 2), js.Array('B', '\n'))
+ }
+
+ it("write(), Unicode repertoire without surrogates") {
+ testW(_.write('é'), js.Array(0xc3, 0xa9))
+ testW(_.write("こんにちは"), js.Array(
+ 0xe3, 0x81, 0x93, 0xe3, 0x82, 0x93, 0xe3, 0x81, 0xab, 0xe3, 0x81, 0xa1, 0xe3, 0x81, 0xaf))
+ testW(_.write("Καλημέρα", 3, 4), js.Array(
+ 0xce, 0xb7, 0xce, 0xbc, 0xce, 0xad, 0xcf, 0x81))
+ }
+
+ it("write(), surrogate pairs") {
+ testW(_.write("\ud83d\udca9"), js.Array(0xf0, 0x9f, 0x92, 0xa9))
+ testW(_.write("ab\ud83d\udca9cd", 1, 3), js.Array('b', 0xf0, 0x9f, 0x92, 0xa9))
+ }
+
+ it("write(), surrogate pairs spread across multiple writes") {
+ testW({ osw => osw.write('\ud83d'); osw.write('\udca9') },
+ js.Array(0xf0, 0x9f, 0x92, 0xa9))
+
+ testW({ osw => osw.write('\ud83d'); osw.flush(); osw.write('\udca9') },
+ js.Array(0xf0, 0x9f, 0x92, 0xa9))
+
+ testW({ osw => osw.write("ab\ud83d"); osw.write('\udca9') },
+ js.Array('a', 'b', 0xf0, 0x9f, 0x92, 0xa9))
+
+ testW({ osw => osw.write("ab\ud83d"); osw.write("\udca9cd") },
+ js.Array('a', 'b', 0xf0, 0x9f, 0x92, 0xa9, 'c', 'd'))
+
+ testW({ osw => osw.write("ab\ud83dzz", 1, 2); osw.write("ww\udca9cd", 2, 2) },
+ js.Array('b', 0xf0, 0x9f, 0x92, 0xa9, 'c'))
+ }
+
+ it("write(), malformed surrogates") {
+ testW(_.write("\ud83da"), js.Array('?', 'a'))
+ testW(_.write("\udca9"), js.Array('?'))
+ }
+
+ it("write(), malformed surrogates spread across multiple writes") {
+ testW({ osw => osw.write('\ud83d'); osw.write('a') },
+ js.Array('?', 'a'))
+
+ testW({ osw => osw.write("ab\ud83d"); osw.write("\ud83d") },
+ js.Array('a', 'b', '?'))
+
+ testW({ osw => osw.write("ab\ud83d"); osw.write("\ud83dc") },
+ js.Array('a', 'b', '?', '?', 'c'))
+ }
+
+ it("write(), malformed surrogates at end of input") {
+ testW({ osw => osw.write('\ud83d'); osw.close() },
+ js.Array('?'), alreadyFlushed = true)
+
+ testW({ osw => osw.write("ab\ud83d"); osw.close() },
+ js.Array('a', 'b', '?'), alreadyFlushed = true)
+ }
+
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/PrintStreamTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/PrintStreamTest.scala
new file mode 100644
index 0000000..01c872b
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/PrintStreamTest.scala
@@ -0,0 +1,296 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import java.io._
+
+import scala.scalajs.js
+import js.JSConverters._
+import org.scalajs.jasminetest.JasmineTest
+
+object PrintStreamTest extends JasmineTest {
+ private def newPrintStream(
+ autoFlush: Boolean = false): (MockPrintStream, MockByteArrayOutputStream) = {
+ val bos = new MockByteArrayOutputStream
+ val ps = new MockPrintStream(bos, autoFlush)
+ (ps, bos)
+ }
+
+ describe("java.io.PrintStream") {
+ it("flush") {
+ val (ps, bos) = newPrintStream()
+ ps.print("hello")
+ expect(bos.flushed).toBeFalsy
+ ps.flush()
+ expect(bos.flushed).toBeTruthy
+ }
+
+ it("close") {
+ val (ps, bos) = newPrintStream()
+ ps.write(Array[Byte](1))
+ expect(bos.flushed).toBeFalsy
+
+ ps.close()
+ expect(bos.flushed).toBeTruthy
+ expect(bos.closed).toBeTruthy
+ expect(ps.checkError()).toBeFalsy
+
+ // can double-close without error
+ ps.close()
+ expect(ps.checkError()).toBeFalsy
+ ps.clearError()
+
+ // when closed, other operations cause error
+ def expectCausesError(body: => Unit): Unit = {
+ body
+ expect(ps.checkError()).toBeTruthy
+ ps.clearError()
+ }
+ expectCausesError(ps.print("never printed"))
+ expectCausesError(ps.write(Array[Byte]('a', 'b')))
+ expectCausesError(ps.append("hello", 1, 3))
+ expectCausesError(ps.flush())
+
+ // at the end of it all, bos is still what it was when it was closed
+ expect(bos.toByteArray.toJSArray).toEqual(js.Array(1))
+ }
+
+ it("write, pass the bytes through") {
+ def test(body: PrintStream => Unit, expected: js.Array[Int],
+ testFlushed: Boolean = false): Unit = {
+ val (ps, bos) = newPrintStream(autoFlush = true)
+ body(ps)
+ if (testFlushed)
+ expect(bos.flushed).toBeTruthy
+ expect(ps.checkError()).toBeFalsy
+ expect(bos.toByteArray.toJSArray).toEqual(expected.map(_.toByte))
+ }
+
+ test(_.write('a'), js.Array('a'))
+ test(_.write('\n'), js.Array('\n'), testFlushed = true)
+ test(_.write(Array[Byte]('A', '\n')),
+ js.Array('A', '\n'), testFlushed = true)
+ test(_.write(Array[Byte]('A', 'B', '\n', 'C'), 1, 2),
+ js.Array('B', '\n'), testFlushed = true)
+
+ test(_.write('é'.toByte), js.Array('é'))
+ test(_.write(Array[Byte]('é'.toByte, 'à'.toByte)), js.Array('é', 'à'))
+ }
+
+ it("print") {
+ def test(body: PrintStream => Unit, expected: String,
+ testFlushed: Boolean = false): Unit = {
+ val (ps, bos) = newPrintStream(autoFlush = true)
+ body(ps)
+ if (testFlushed)
+ expect(bos.flushed).toBeTruthy
+ expect(ps.checkError()).toBeFalsy
+ expect(bos.toString()).toBe(expected)
+ }
+
+ test(_.print(true), "true")
+ test(_.print('Z'), "Z")
+ test(_.print('\n'), "\n", testFlushed = true)
+ test(_.print(5), "5")
+ test(_.print(1234567891011L), "1234567891011")
+ test(_.print(1.5f), "1.5")
+ test(_.print(Math.PI), "3.141592653589793")
+ test(_.print(Array('A', '\n')), "A\n", testFlushed = true)
+ test(_.print("hello\n"), "hello\n", testFlushed = true)
+ test(_.print(null: String), "null")
+ test(_.print((1, 2)), "(1,2)")
+ test(_.print(null: AnyRef), "null")
+ }
+
+ it("print encodes in UTF-8") {
+ def test(body: PrintStream => Unit, expected: js.Array[Int]): Unit = {
+ val (ps, bos) = newPrintStream(autoFlush = false)
+ body(ps)
+ expect(ps.checkError()).toBeFalsy
+ expect(bos.toByteArray.toJSArray).toEqual(expected.map(_.toByte))
+ }
+
+ test(_.print('é'), js.Array(0xc3, 0xa9))
+ test(_.print("こんにちは"), js.Array(
+ 0xe3, 0x81, 0x93, 0xe3, 0x82, 0x93, 0xe3, 0x81, 0xab, 0xe3, 0x81, 0xa1, 0xe3, 0x81, 0xaf))
+ test(_.print("ημέρ"), js.Array(
+ 0xce, 0xb7, 0xce, 0xbc, 0xce, 0xad, 0xcf, 0x81))
+
+ test(_.print("\ud83d\udca9"), js.Array(0xf0, 0x9f, 0x92, 0xa9))
+ test(_.print("b\ud83d\udca9c"), js.Array('b', 0xf0, 0x9f, 0x92, 0xa9, 'c'))
+
+ test({ osw => osw.print("ab\ud83d"); osw.print('\udca9') },
+ js.Array('a', 'b', 0xf0, 0x9f, 0x92, 0xa9))
+
+ test({ osw => osw.print("ab\ud83d"); osw.print("\udca9cd") },
+ js.Array('a', 'b', 0xf0, 0x9f, 0x92, 0xa9, 'c', 'd'))
+
+ // Start of malformed sequences
+
+ test(_.print("\ud83da"), js.Array('?', 'a'))
+ test(_.print("\udca9"), js.Array('?'))
+
+ test({ osw => osw.print('\ud83d'); osw.print('a') },
+ js.Array('?', 'a'))
+
+ test({ osw => osw.print("ab\ud83d"); osw.print("\ud83d") },
+ js.Array('a', 'b', '?'))
+
+ test({ osw => osw.print("ab\ud83d"); osw.print("\ud83dc") },
+ js.Array('a', 'b', '?', '?', 'c'))
+
+ test({ osw => osw.print('\ud83d'); osw.close() },
+ js.Array('?'))
+
+ test({ osw => osw.print("ab\ud83d"); osw.close() },
+ js.Array('a', 'b', '?'))
+ }
+
+ for (autoFlush <- Seq(true, false)) {
+ val title =
+ if (autoFlush) "println forwards and flushes when autoFlush is true"
+ else "println forwards, does not flush when autoFlush is false"
+ it(title) {
+ def test(body: PrintStream => Unit, expected: String): Unit = {
+ val (ps, bos) = newPrintStream(autoFlush = autoFlush)
+ body(ps)
+ if (autoFlush) expect(bos.flushed).toBeTruthy
+ else expect(bos.flushed).toBeFalsy
+ expect(ps.checkError()).toBeFalsy
+ expect(bos.toString()).toBe(expected)
+ }
+
+ test(_.println(), "\n")
+ test(_.println(true), "true\n")
+ test(_.println('Z'), "Z\n")
+ test(_.println('\n'), "\n\n")
+ test(_.println(5), "5\n")
+ test(_.println(1234567891011L), "1234567891011\n")
+ test(_.println(1.5f), "1.5\n")
+ test(_.println(Math.PI), "3.141592653589793\n")
+ test(_.println(Array('A', '\n')), "A\n\n")
+ test(_.println("hello\n"), "hello\n\n")
+ test(_.println(null: String), "null\n")
+ test(_.println((1, 2)), "(1,2)\n")
+ test(_.println(null: AnyRef), "null\n")
+ }
+ }
+
+ for (autoFlush <- Seq(true, false)) {
+ val title =
+ if (autoFlush) "printf/format, which flushes when autoFlush is true"
+ else "printf/format, does not flush when autoFlush is false"
+ it(title) {
+ def test(body: PrintStream => Unit, expected: String): Unit = {
+ val (ps, bos) = newPrintStream(autoFlush = autoFlush)
+ body(ps)
+ if (autoFlush) expect(bos.flushed).toBeTruthy
+ else expect(bos.flushed).toBeFalsy
+ expect(ps.checkError()).toBeFalsy
+ expect(bos.toString()).toBe(expected)
+ }
+
+ test(_.printf("%04d", Int.box(5)), "0005")
+ test(_.format("%.5f", Double.box(Math.PI)), "3.14159")
+ }
+ }
+
+ it("append") {
+ def test(body: PrintStream => Unit, expected: String,
+ testFlushed: Boolean = false): Unit = {
+ val (ps, bos) = newPrintStream(autoFlush = true)
+ body(ps)
+ if (testFlushed)
+ expect(bos.flushed).toBeTruthy
+ expect(ps.checkError()).toBeFalsy
+ expect(bos.toString()).toBe(expected)
+ }
+
+ test(_.append("hello\n"), "hello\n", testFlushed = true)
+ test(_.append(null: CharSequence), "null")
+ test(_.append("hello\nworld", 3, 6), "lo\n", testFlushed = true)
+ test(_.append(null: CharSequence, 1, 2), "u")
+ test(_.append('A'), "A")
+ test(_.append('\n'), "\n", testFlushed = true)
+ }
+
+ it("traps all IOException and updates checkError") {
+ def test(body: PrintStream => Unit): Unit = {
+ val (ps, bos) = newPrintStream()
+ bos.throwing = true
+ body(ps)
+ expect(ps.checkError()).toBeTruthy
+ }
+
+ test(_.flush())
+ test(_.close())
+
+ test(_.write('Z'))
+ test(_.write(Array[Byte]('A', 'B')))
+ test(_.write(Array[Byte]('A', 'B'), 1, 1))
+
+ test(_.print(true))
+ test(_.print('Z'))
+ test(_.print('\n'))
+ test(_.print(5))
+ test(_.print(1234567891011L))
+ test(_.print(1.5f))
+ test(_.print(Math.PI))
+ test(_.print(Array('A', '\n')))
+ test(_.print("hello\n"))
+ test(_.print(null: String))
+ test(_.print((1, 2)))
+ test(_.print(null: AnyRef))
+
+ test(_.println())
+ test(_.println(true))
+ test(_.println('Z'))
+ test(_.println('\n'))
+ test(_.println(5))
+ test(_.println(1234567891011L))
+ test(_.println(1.5f))
+ test(_.println(Math.PI))
+ test(_.println(Array('A', '\n')))
+ test(_.println("hello\n"))
+ test(_.println(null: String))
+ test(_.println((1, 2)))
+ test(_.println(null: AnyRef))
+
+ test(_.append("hello\n"))
+ test(_.append(null: CharSequence))
+ test(_.append("hello\nworld", 3, 6))
+ test(_.append(null: CharSequence, 1, 2))
+ test(_.append('A'))
+ test(_.append('\n'))
+ }
+
+ it("write short-circuits pending high surrogates in print") {
+ val (ps, bos) = newPrintStream()
+ ps.print('A')
+ expect(bos.toByteArray.toJSArray).toEqual(js.Array[Byte]('A'))
+ ps.print('\ud83d')
+ expect(bos.toByteArray.toJSArray).toEqual(js.Array[Byte]('A'))
+ ps.flush()
+ expect(bos.toByteArray.toJSArray).toEqual(js.Array[Byte]('A'))
+ ps.write('Z')
+ expect(bos.toByteArray.toJSArray).toEqual(js.Array[Byte]('A', 'Z'))
+ ps.print('\udca9')
+ expect(bos.toByteArray.toJSArray).toEqual(js.Array[Byte](
+ 'A', 'Z', -16, -97, -110, -87))
+ }
+ }
+
+ /** A PrintStream that exposes various hooks for testing purposes. */
+ private class MockPrintStream(out: OutputStream,
+ autoFlush: Boolean) extends PrintStream(out, autoFlush) {
+ def this(out: OutputStream) = this(out, false)
+
+ override def clearError(): Unit = super.clearError()
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/PrintWriterTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/PrintWriterTest.scala
new file mode 100644
index 0000000..b2b3309
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/PrintWriterTest.scala
@@ -0,0 +1,287 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import scala.language.implicitConversions
+
+import java.io._
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+object PrintWriterTest extends JasmineTest {
+ private def newPrintWriter(
+ autoFlush: Boolean = false): (MockPrintWriter, MockStringWriter) = {
+ val sw = new MockStringWriter
+ val pw = new MockPrintWriter(sw, autoFlush)
+ (pw, sw)
+ }
+
+ describe("java.io.PrintWriter") {
+ it("flush") {
+ val (pw, sw) = newPrintWriter()
+ pw.print("hello")
+ expect(sw.flushed).toBeFalsy
+ pw.flush()
+ expect(sw.flushed).toBeTruthy
+ }
+
+ it("close") {
+ val (pw, sw) = newPrintWriter()
+ pw.write("begin")
+ expect(sw.flushed).toBeFalsy
+
+ pw.close()
+ expect(sw.flushed).toBeTruthy
+ expect(sw.closed).toBeTruthy
+ expect(pw.checkError()).toBeFalsy
+
+ // can double-close without error
+ pw.close()
+ expect(pw.checkError()).toBeFalsy
+ pw.clearError()
+
+ // when closed, other operations cause error
+ def expectCausesError(body: => Unit): Unit = {
+ body
+ expect(pw.checkError()).toBeTruthy
+ pw.clearError()
+ }
+ expectCausesError(pw.print("never printed"))
+ expectCausesError(pw.write(Array('a', 'b')))
+ expectCausesError(pw.append("hello", 1, 3))
+ expectCausesError(pw.flush())
+
+ // at the end of it all, sw is still what it was when it was closed
+ expect(sw.toString()).toBe("begin")
+ }
+
+ it("write, does not flush even with \\n") {
+ def test(body: PrintWriter => Unit, expected: String): Unit = {
+ val (pw, sw) = newPrintWriter(autoFlush = true)
+ body(pw)
+ expect(sw.flushed).toBeFalsy
+ expect(pw.checkError()).toBeFalsy
+ expect(sw.toString()).toBe(expected)
+ }
+
+ test(_.write('\n'), "\n")
+ test(_.write("hello\n"), "hello\n")
+ test(_.write("hello\nworld", 3, 3), "lo\n")
+ test(_.write(Array('A', '\n')), "A\n")
+ test(_.write(Array('A', 'B', '\n', 'C'), 1, 2), "B\n")
+ }
+
+ it("print, does not flush even with \\n") {
+ def test(body: PrintWriter => Unit, expected: String): Unit = {
+ val (pw, sw) = newPrintWriter(autoFlush = true)
+ body(pw)
+ expect(sw.flushed).toBeFalsy
+ expect(pw.checkError()).toBeFalsy
+ expect(sw.toString()).toBe(expected)
+ }
+
+ test(_.print(true), "true")
+ test(_.print('Z'), "Z")
+ test(_.print('\n'), "\n")
+ test(_.print(5), "5")
+ test(_.print(1234567891011L), "1234567891011")
+ test(_.print(1.5f), "1.5")
+ test(_.print(Math.PI), "3.141592653589793")
+ test(_.print(Array('A', '\n')), "A\n")
+ test(_.print("hello\n"), "hello\n")
+ test(_.print(null: String), "null")
+ test(_.print((1, 2)), "(1,2)")
+ test(_.print(null: AnyRef), "null")
+ }
+
+ for (autoFlush <- Seq(true, false)) {
+ val title =
+ if (autoFlush) "println forwards and flushes when autoFlush is true"
+ else "println forwards, does not flush when autoFlush is false"
+ it(title) {
+ def test(body: PrintWriter => Unit, expected: String): Unit = {
+ val (pw, sw) = newPrintWriter(autoFlush = autoFlush)
+ body(pw)
+ if (autoFlush) expect(sw.flushed).toBeTruthy
+ else expect(sw.flushed).toBeFalsy
+ expect(pw.checkError()).toBeFalsy
+ expect(sw.toString()).toBe(expected)
+ }
+
+ test(_.println(), "\n")
+ test(_.println(true), "true\n")
+ test(_.println('Z'), "Z\n")
+ test(_.println('\n'), "\n\n")
+ test(_.println(5), "5\n")
+ test(_.println(1234567891011L), "1234567891011\n")
+ test(_.println(1.5f), "1.5\n")
+ test(_.println(Math.PI), "3.141592653589793\n")
+ test(_.println(Array('A', '\n')), "A\n\n")
+ test(_.println("hello\n"), "hello\n\n")
+ test(_.println(null: String), "null\n")
+ test(_.println((1, 2)), "(1,2)\n")
+ test(_.println(null: AnyRef), "null\n")
+ }
+ }
+
+ for (autoFlush <- Seq(true, false)) {
+ val title =
+ if (autoFlush) "printf/format, which flushes when autoFlush is true"
+ else "printf/format, does not flush when autoFlush is false"
+ it(title) {
+ def test(body: PrintWriter => Unit, expected: String): Unit = {
+ val (pw, sw) = newPrintWriter(autoFlush = autoFlush)
+ body(pw)
+ if (autoFlush) expect(sw.flushed).toBeTruthy
+ else expect(sw.flushed).toBeFalsy
+ expect(pw.checkError()).toBeFalsy
+ expect(sw.toString()).toBe(expected)
+ }
+
+ test(_.printf("%04d", Int.box(5)), "0005")
+ test(_.format("%.5f", Double.box(Math.PI)), "3.14159")
+ }
+ }
+
+ it("append, does not flush even with \\n") {
+ def test(body: PrintWriter => Unit, expected: String): Unit = {
+ val (pw, sw) = newPrintWriter(autoFlush = true)
+ body(pw)
+ expect(sw.flushed).toBeFalsy
+ expect(pw.checkError()).toBeFalsy
+ expect(sw.toString()).toBe(expected)
+ }
+
+ test(_.append("hello\n"), "hello\n")
+ test(_.append(null: CharSequence), "null")
+ test(_.append("hello\nworld", 3, 6), "lo\n")
+ test(_.append(null: CharSequence, 1, 2), "u")
+ test(_.append('A'), "A")
+ test(_.append('\n'), "\n")
+ }
+
+ it("traps all IOException and updates checkError") {
+ def test(body: PrintWriter => Unit): Unit = {
+ val (pw, sw) = newPrintWriter()
+ sw.throwing = true
+ body(pw)
+ expect(pw.checkError()).toBeTruthy
+ }
+
+ test(_.flush())
+ test(_.close())
+
+ test(_.write('Z'))
+ test(_.write("booh"))
+ test(_.write("booh", 1, 1))
+ test(_.write(Array('A', 'B')))
+ test(_.write(Array('A', 'B'), 1, 1))
+
+ test(_.print(true))
+ test(_.print('Z'))
+ test(_.print('\n'))
+ test(_.print(5))
+ test(_.print(1234567891011L))
+ test(_.print(1.5f))
+ test(_.print(Math.PI))
+ test(_.print(Array('A', '\n')))
+ test(_.print("hello\n"))
+ test(_.print(null: String))
+ test(_.print((1, 2)))
+ test(_.print(null: AnyRef))
+
+ test(_.println())
+ test(_.println(true))
+ test(_.println('Z'))
+ test(_.println('\n'))
+ test(_.println(5))
+ test(_.println(1234567891011L))
+ test(_.println(1.5f))
+ test(_.println(Math.PI))
+ test(_.println(Array('A', '\n')))
+ test(_.println("hello\n"))
+ test(_.println(null: String))
+ test(_.println((1, 2)))
+ test(_.println(null: AnyRef))
+
+ test(_.append("hello\n"))
+ test(_.append(null: CharSequence))
+ test(_.append("hello\nworld", 3, 6))
+ test(_.append(null: CharSequence, 1, 2))
+ test(_.append('A'))
+ test(_.append('\n'))
+ }
+ }
+
+ /** A PrintWriter that exposes various hooks for testing purposes. */
+ private class MockPrintWriter(out: Writer,
+ autoFlush: Boolean) extends PrintWriter(out, autoFlush) {
+ def this(out: Writer) = this(out, false)
+
+ override def clearError(): Unit = super.clearError()
+ }
+
+ /** A StringWriter that exposes various hooks for testing purposes. */
+ private class MockStringWriter extends StringWriter {
+ private var _flushed: Boolean = true
+ private var _closed: Boolean = false
+
+ var throwing: Boolean = false
+
+ def flushed: Boolean = _flushed
+ def closed: Boolean = _closed
+
+ private def maybeThrow(): Unit = {
+ if (throwing)
+ throw new IOException("MockStringWriter throws")
+ }
+
+ private def writeOp[A](op: => A): A = {
+ maybeThrow()
+ _flushed = false
+ op
+ }
+
+ override def flush(): Unit = {
+ maybeThrow()
+ super.flush()
+ _flushed = true
+ }
+
+ override def close(): Unit = {
+ maybeThrow()
+ super.close()
+ _closed = true
+ }
+
+ override def append(c: Char): StringWriter =
+ writeOp(super.append(c))
+
+ override def append(csq: CharSequence): StringWriter =
+ writeOp(super.append(csq))
+
+ override def append(csq: CharSequence, start: Int, end: Int): StringWriter =
+ writeOp(super.append(csq, start, end))
+
+ override def write(c: Int): Unit =
+ writeOp(super.write(c))
+
+ override def write(cbuf: Array[Char]): Unit =
+ writeOp(super.write(cbuf))
+
+ override def write(cbuf: Array[Char], off: Int, len: Int): Unit =
+ writeOp(super.write(cbuf, off, len))
+
+ override def write(str: String): Unit =
+ writeOp(super.write(str))
+
+ override def write(str: String, off: Int, len: Int): Unit =
+ writeOp(super.write(str, off, len))
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/RandomTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/RandomTest.scala
new file mode 100644
index 0000000..1794d4a
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/RandomTest.scala
@@ -0,0 +1,225 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import org.scalajs.jasminetest.JasmineTest
+
+import java.util.Random
+
+import scala.scalajs.js
+import scala.scalajs.js.JSConverters._
+
+object RandomTest extends JasmineTest {
+
+ describe("java.util.Random") {
+
+ it("should produce bits according to spec with seed=10") {
+ val random = new HackRandom(10)
+
+ expect(random.next(10)).toBe(747)
+ expect(random.next(1)).toBe(0)
+ expect(random.next(6)).toBe(16)
+ expect(random.next(20)).toBe(432970)
+ expect(random.next(32)).toBe(254270492)
+ }
+
+ it("should produce bits according to spec with seed=-5") {
+ val random = new HackRandom(-5)
+
+ expect(random.next(10)).toBe(275)
+ expect(random.next(1)).toBe(0)
+ expect(random.next(6)).toBe(21)
+ expect(random.next(20)).toBe(360349)
+ expect(random.next(32)).toBe(1635930704)
+ }
+
+ it("should produce bits according to spec with seed=MaxLong") {
+ val random = new HackRandom(Long.MaxValue)
+
+ expect(random.next(10)).toBe(275)
+ expect(random.next(1)).toBe(0)
+ expect(random.next(6)).toBe(0)
+ expect(random.next(20)).toBe(574655)
+ expect(random.next(32)).toBe(-1451336087)
+ }
+
+ it("should produce bits according to spec with seed=MinInt") {
+ val random = new HackRandom(Int.MinValue)
+
+ expect(random.next(10)).toBe(388)
+ expect(random.next(1)).toBe(0)
+ expect(random.next(6)).toBe(25)
+ expect(random.next(20)).toBe(352095)
+ expect(random.next(32)).toBe(-2140124682)
+ }
+
+ it("should allow resetting the seed") {
+ val random = new HackRandom(11)
+ expect(random.next(10)).toBe(747)
+ expect(random.next(1)).toBe(1)
+ expect(random.next(6)).toBe(27)
+
+ random.setSeed(11)
+ expect(random.next(10)).toBe(747)
+ expect(random.next(1)).toBe(1)
+ expect(random.next(6)).toBe(27)
+ }
+
+ it("should reset nextNextGaussian when setting the seed") {
+ val random = new Random(-1)
+ expect(random.nextGaussian()).toBe(1.7853314409882288)
+ random.setSeed(-1)
+ expect(random.nextGaussian()).toBe(1.7853314409882288)
+ }
+
+ it("should correctly implement nextDouble") {
+ val random = new Random(-45)
+ expect(random.nextDouble()).toBe(0.27288421395636253)
+ expect(random.nextDouble()).toBe(0.5523165360074201)
+ expect(random.nextDouble()).toBe(0.5689979434708298)
+ expect(random.nextDouble()).toBe(0.9961166166874871)
+ expect(random.nextDouble()).toBe(0.5368984665202684)
+ expect(random.nextDouble()).toBe(0.19849067496547423)
+ expect(random.nextDouble()).toBe(0.6021019223595357)
+ expect(random.nextDouble()).toBe(0.06132131151816378)
+ expect(random.nextDouble()).toBe(0.7303867762743866)
+ expect(random.nextDouble()).toBe(0.7426529384056163)
+ }
+
+ it("should correctly implement nextBoolean") {
+ val random = new Random(4782934)
+ expect(random.nextBoolean()).toBe(false)
+ expect(random.nextBoolean()).toBe(true)
+ expect(random.nextBoolean()).toBe(true)
+ expect(random.nextBoolean()).toBe(false)
+ expect(random.nextBoolean()).toBe(false)
+ expect(random.nextBoolean()).toBe(false)
+ expect(random.nextBoolean()).toBe(true)
+ expect(random.nextBoolean()).toBe(false)
+ }
+
+ it("should correctly implement nextInt") {
+ val random = new Random(-84638)
+ expect(random.nextInt()).toBe(-1217585344)
+ expect(random.nextInt()).toBe(1665699216)
+ expect(random.nextInt()).toBe(382013296)
+ expect(random.nextInt()).toBe(1604432482)
+ expect(random.nextInt()).toBe(-1689010196)
+ expect(random.nextInt()).toBe(1743354032)
+ expect(random.nextInt()).toBe(454046816)
+ expect(random.nextInt()).toBe(922172344)
+ expect(random.nextInt()).toBe(-1890515287)
+ expect(random.nextInt()).toBe(1397525728)
+ }
+
+ it("should correctly implement nextInt(n)") {
+ val random = new Random(7)
+ expect(random.nextInt(76543)).toBe(32736)
+ expect(() => random.nextInt(0)).toThrow
+ expect(random.nextInt(45)).toBe(29)
+ expect(random.nextInt(945)).toBe(60)
+ expect(random.nextInt(35694839)).toBe(20678044)
+ expect(random.nextInt(35699)).toBe(23932)
+ expect(random.nextInt(3699)).toBe(2278)
+ expect(random.nextInt(10)).toBe(8)
+ }
+
+ it("should correctly implement nextInt(n) for powers of 2") {
+ val random = new Random(-56938)
+
+ expect(random.nextInt(32)).toBe(8)
+ expect(random.nextInt(8)).toBe(3)
+ expect(random.nextInt(128)).toBe(3)
+ expect(random.nextInt(4096)).toBe(1950)
+ expect(random.nextInt(8192)).toBe(3706)
+ expect(random.nextInt(8192)).toBe(4308)
+ expect(random.nextInt(8192)).toBe(3235)
+ expect(random.nextInt(8192)).toBe(7077)
+ expect(random.nextInt(8192)).toBe(2392)
+ expect(random.nextInt(32)).toBe(31)
+ }
+
+ it("should correctly implement nextLong") {
+ val random = new Random(205620432625028L)
+ expect(random.nextLong()).toBe(3710537363280377478L)
+ expect(random.nextLong()).toBe(4121778334981170700L)
+ expect(random.nextLong()).toBe(289540773990891960L)
+ expect(random.nextLong()).toBe(307008980197674441L)
+ expect(random.nextLong()).toBe(7527069864796025013L)
+ expect(random.nextLong()).toBe(-4563192874520002144L)
+ expect(random.nextLong()).toBe(7619507045427546529L)
+ expect(random.nextLong()).toBe(-7888117030898487184L)
+ expect(random.nextLong()).toBe(-3499168703537933266L)
+ expect(random.nextLong()).toBe(-1998975913933474L)
+ }
+
+ it("should correctly implement nextFloat") {
+ val random = new Random(-3920005825473L)
+ expect(random.nextFloat()).toBeCloseTo(0.059591234, 7)
+ expect(random.nextFloat()).toBeCloseTo(0.7007871, 7)
+ expect(random.nextFloat()).toBeCloseTo(0.39173192, 7)
+ expect(random.nextFloat()).toBeCloseTo(0.0647918, 7)
+ expect(random.nextFloat()).toBeCloseTo(0.9029677, 7)
+ expect(random.nextFloat()).toBeCloseTo(0.18226051, 7)
+ expect(random.nextFloat()).toBeCloseTo(0.94444054, 7)
+ expect(random.nextFloat()).toBeCloseTo(0.008844078, 7)
+ expect(random.nextFloat()).toBeCloseTo(0.08891684, 7)
+ expect(random.nextFloat()).toBeCloseTo(0.06482434, 7)
+ }
+
+ it("should correctly implement nextBytes") {
+ val random = new Random(7399572013373333L)
+
+ def test(exps: Int*) = {
+ val exp = js.Array(exps.map(_.toByte): _*)
+ val buf = new Array[Byte](exp.length)
+ random.nextBytes(buf)
+ expect(buf.toJSArray).toEqual(exp)
+ }
+
+ test(62, 89, 68, -91, 10, 0, 85)
+ test(-89, -76, 88, 121, -25, 47, 58, -8, 78, 20, -77, 84, -3,
+ -33, 58, -9, 11, 57, -118, 40, -74, -86, 78, 123, 58)
+ test(-77, 112, -116)
+ test()
+ test(-84, -96, 108)
+ test(57, -106, 42, -100, -47, -84, 67, -48, 45)
+ }
+
+ it("should correctly implement nextGaussian") {
+ val random = new Random(2446004)
+ expect(random.nextGaussian()).toBe(-0.5043346938630431)
+ expect(random.nextGaussian()).toBe(-0.3250983270156675)
+ expect(random.nextGaussian()).toBe(-0.23799457294994966)
+ expect(random.nextGaussian()).toBe(0.4164610631507695)
+ expect(random.nextGaussian()).toBe(0.22086348814760687)
+ expect(random.nextGaussian()).toBe(-0.706833209972521)
+ expect(random.nextGaussian()).toBe(0.6730758289772553)
+ expect(random.nextGaussian()).toBe(0.2797393696191283)
+ expect(random.nextGaussian()).toBe(-0.2979099632667685)
+ expect(random.nextGaussian()).toBe(0.37443415981434314)
+ expect(random.nextGaussian()).toBe(0.9584801742918951)
+ expect(random.nextGaussian()).toBe(1.1762179112229345)
+ expect(random.nextGaussian()).toBe(0.8736960092848826)
+ expect(random.nextGaussian()).toBe(0.12301554931271008)
+ expect(random.nextGaussian()).toBe(-0.6052081187207353)
+ expect(random.nextGaussian()).toBe(-0.2015925608755316)
+ expect(random.nextGaussian()).toBe(-1.0071216119742104)
+ expect(random.nextGaussian()).toBe(0.6734222041441913)
+ expect(random.nextGaussian()).toBe(0.3990565555091522)
+ expect(random.nextGaussian()).toBe(2.0051627385915154)
+ }
+
+ }
+
+ /** Helper class to access next */
+ class HackRandom(seed: Long) extends Random(seed) {
+ override def next(bits: Int): Int = super.next(bits)
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ReadersTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ReadersTest.scala
new file mode 100644
index 0000000..f970141
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ReadersTest.scala
@@ -0,0 +1,244 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import scala.annotation.tailrec
+
+import java.io._
+
+import scala.scalajs.js
+import scala.scalajs.js.JSConverters._
+
+import org.scalajs.jasminetest.JasmineTest
+
+/** Tests for our implementation of java.io._ reader classes */
+object ReadersTest extends JasmineTest {
+
+ describe("java.io.StringReader") {
+ val str = "asdf"
+ def newReader = new StringReader(str)
+
+ it("should provide read()") {
+ val r = newReader
+
+ for (c <- str) {
+ expect(r.read().toChar).toEqual(c)
+ }
+
+ expect(r.read()).toEqual(-1)
+ }
+
+ it("should provide read(buf: Array[Char], off: Int, len: Int)") {
+ val r = newReader
+ val buf = new Array[Char](10)
+
+ expect(r.read(buf, 2, 8)).toBe(4)
+ expect(buf.map(_.toInt).toJSArray).toEqual(
+ js.Array[Int](0,0,'a','s','d','f',0,0,0,0))
+ }
+
+ it("should provide read(java.nio.CharBuffer)") {
+ val r = newReader
+ val buf0 = java.nio.CharBuffer.allocate(25)
+ buf0.position(3)
+ val buf = buf0.slice()
+ buf.position(4)
+ buf.limit(14)
+
+ expect(r.read(buf)).toBe(4)
+ expect(buf.position()).toBe(8)
+ buf.flip()
+ expect(buf.toString().map(_.toInt).toJSArray).toEqual(
+ js.Array[Int](0, 0, 0, 0, 'a', 's', 'd', 'f'))
+ }
+
+ it("should provide ready") {
+ val r = newReader
+
+ for (c <- str) {
+ expect(r.ready()).toBeTruthy
+ expect(r.read().toChar).toEqual(c)
+ }
+
+ expect(r.ready()).toBeFalsy
+ expect(r.read()).toEqual(-1)
+ }
+
+ it("should provide mark/reset") {
+ val r = newReader
+ r.mark(str.length)
+
+ for (c <- str) {
+ expect(r.read().toChar).toEqual(c)
+ }
+ expect(r.read()).toEqual(-1)
+
+ r.reset()
+
+ for (c <- str) {
+ expect(r.read().toChar).toEqual(c)
+ }
+ expect(r.read()).toEqual(-1)
+ }
+
+ it("should provide skip") {
+ val r = newReader
+
+ expect(r.read()).toEqual('a')
+ expect(r.skip(2L).toInt).toBe(2)
+
+ expect(r.read()).toEqual('f')
+ expect(r.read()).toEqual(-1)
+ }
+
+ it("should provide close") {
+ val r = newReader
+
+ r.close()
+ expect(() => r.read()).toThrow
+ }
+
+ it("should support marking") {
+ expect(newReader.markSupported).toBeTruthy
+ }
+ }
+
+ describe("java.io.BufferedReader") {
+ val str = "line1\nline2\r\n\nline4\rline5"
+ def newReader = new BufferedReader(new StringReader(str), 3)
+
+ it("should provide read()") {
+ val r = newReader
+
+ for (c <- str) {
+ expect(r.read().toChar).toEqual(c)
+ }
+ expect(r.read()).toEqual(-1)
+ }
+
+ it("should provide read(cbuf)") {
+ var read = 0
+ val r = newReader
+ val buf = new Array[Char](15)
+
+ // twice to force filling internal buffer
+ for (_ <- 0 to 1) {
+ val len = r.read(buf)
+ expect(len).toBeGreaterThan(0)
+
+ for (i <- 0 until len)
+ expect(buf(i)).toEqual(str.charAt(i+read))
+
+ read += len
+ }
+ }
+
+ it("should provide read(cbuf, off, len)") {
+ var read = 0
+ val r = newReader
+ val buf = new Array[Char](15)
+
+ // twice to force filling internal buffer
+ for (_ <- 0 to 1) {
+ val len = r.read(buf, 1, 10)
+ expect(len).toBeGreaterThan(0)
+ expect(len).toBeLessThan(11)
+
+ for (i <- 0 until len)
+ expect(buf(i+1)).toEqual(str.charAt(i+read))
+
+ read += len
+ }
+ }
+
+ it("should provide mark/reset") {
+ val r = newReader
+ expect(r.read()).toEqual('l')
+
+ // force moving and resizing buffer
+ r.mark(10)
+
+ for (i <- 0 until 10) {
+ expect(r.read()).toEqual(str.charAt(i+1))
+ }
+
+ r.reset()
+
+ for (i <- 1 until str.length) {
+ expect(r.read()).toEqual(str.charAt(i))
+ }
+ }
+
+ it("should provide readLine") {
+ val r = newReader
+
+ expect(r.readLine()).toEqual("line1")
+ expect(r.readLine()).toEqual("line2")
+ expect(r.readLine()).toEqual("")
+ expect(r.readLine()).toEqual("line4")
+ expect(r.readLine()).toEqual("line5")
+ expect(r.readLine()).toEqual(null)
+ }
+
+ it("should readLine on an empty stream") {
+ val r = new BufferedReader(new StringReader(""))
+
+ expect(r.readLine()).toEqual(null)
+ }
+
+ it("should readline with empty lines only") {
+ val r = new BufferedReader(new StringReader("\n\r\n\r\r\n"), 1)
+
+ for (_ <- 1 to 4)
+ expect(r.readLine()).toEqual("")
+
+ expect(r.readLine()).toEqual(null)
+ }
+
+ it("should support marking") {
+ expect(newReader.markSupported).toBeTruthy
+ }
+ }
+
+ describe("java.io.InputStreamReader") {
+
+ it("should read UTF8") {
+
+ val buf = Array[Byte](72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100,
+ 46, -29, -127, -109, -29, -126, -109, -29, -127, -85, -29, -127, -95,
+ -29, -127, -81, -26, -105, -91, -26, -100, -84, -24, -86, -98, -29,
+ -126, -110, -24, -86, -83, -29, -126, -127, -29, -127, -66, -29, -127,
+ -103, -29, -127, -117, -29, -128, -126)
+
+ val r = new InputStreamReader(new ByteArrayInputStream(buf))
+
+ def expectRead(str: String) = {
+ val buf = new Array[Char](str.length)
+ @tailrec
+ def readAll(readSoFar: Int): Int = {
+ if (readSoFar == buf.length) readSoFar
+ else {
+ val newlyRead = r.read(buf, readSoFar, buf.length - readSoFar)
+ if (newlyRead == -1) readSoFar
+ else readAll(readSoFar + newlyRead)
+ }
+ }
+ expect(readAll(0)).toBe(str.length)
+ expect(new String(buf)).toEqual(str)
+ }
+
+ expectRead("Hello World.")
+ expectRead("こんにちは")
+ expectRead("日本語を読めますか。")
+ expect(r.read()).toBe(-1)
+
+ }
+
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ReferenceTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ReferenceTest.scala
new file mode 100644
index 0000000..cf0fd0c
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ReferenceTest.scala
@@ -0,0 +1,28 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import org.scalajs.jasminetest.JasmineTest
+
+object ReferenceTest extends JasmineTest {
+
+ describe("java.land.ref.Reference") {
+
+ it("Should have all the normal operations") {
+ val s = "string"
+ val ref = new java.lang.ref.WeakReference(s)
+ expect(ref.get).toEqual(s)
+ expect(ref.enqueue).toEqual(false)
+ expect(ref.isEnqueued).toEqual(false)
+ ref.clear
+ // can't use `expect` because it tries to be clever and .toString things,
+ // which makes it blow up when you pass in null
+ assert(ref.get == null)
+ }
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/RegexTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/RegexTest.scala
new file mode 100644
index 0000000..a27584a
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/RegexTest.scala
@@ -0,0 +1,397 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import scala.scalajs.js
+import scala.scalajs.js.JSConverters._
+
+import org.scalajs.jasminetest.JasmineTest
+
+import java.util.regex.Pattern
+
+object RegexTest extends JasmineTest {
+
+ describe("java.util.regex.Pattern") {
+
+ it("should respond to `matches`") {
+ expect(Pattern.matches("[Scal]*\\.js", "Scala.js")).toBeTruthy
+ expect(Pattern.matches(".[cal]*\\.j.", "Scala.js")).toBeTruthy
+ expect(Pattern.matches(".*\\.js", "Scala.js")).toBeTruthy
+ expect(Pattern.matches("S[a-z]*", "Scala.js")).toBeFalsy
+ }
+
+ it("should respond to `matches` with flags") {
+ matches("scala.js", "Scala.js")
+ matches("SCALA.JS", "Scala.js")
+ matches("waz*up", "WAZZZZZZZZZZZUP")
+
+ def matches(regex: String, input: String): Unit = {
+ val result = Pattern.compile(regex, Pattern.CASE_INSENSITIVE).matcher(input)
+ expect(result.matches()).toBeTruthy
+ }
+ }
+
+ it("should respond to `split`") {
+ val result = Pattern.compile("[aj]").split("Scala.js")
+ val expected = js.Array("Sc", "l", ".", "s")
+ expect(result.length).toEqual(4)
+ expect(result.toJSArray).toEqual(expected)
+
+ // Tests from JavaDoc
+ split("boo:and:foo", ":", Array("boo", "and", "foo"))
+ split("boo:and:foo", "o", Array("b", "", ":and:f"))
+
+ // Splitting the empty string must return 1 element - #987
+ split("", "a", Array(""))
+ split("", "\\*", Array(""))
+ split("", "\n", Array(""))
+ split("", "", Array(""))
+
+ // Should remove leading empty match under some conditions - #1171
+ // These tests are "measured" on the JVM since the spec is unclear
+ split("abc", "(?=a)", Array("abc"))
+ split("abc", "(?=b)", Array("a", "bc"))
+ split("abc", "(?=a)|b", Array("", "a", "c"))
+ split("abc", "", Array("", "a", "b", "c"))
+ split("abc", "(?=a)|(?=b)", Array("", "a", "bc"))
+ split("abc", "(?=a)|(?=a)", Array("abc"))
+ split("abc", "(?=a|b)", Array("", "a", "bc"))
+ split("abc", "(?=a|d)", Array("abc"))
+ split("abc", "^d*", Array("abc"))
+ split("abc", "d*", Array("", "a", "b", "c"))
+ split("a", "", Array("", "a"))
+ split("a", "^d*", Array("a"))
+ split("a", "d*", Array("", "a"))
+ split("a", "(?=a)", Array("a"))
+ split("ab", "a", Array("", "b"))
+
+ def split(input: String, regex: String, expected: Array[String]): Unit = {
+ val result = Pattern.compile(regex).split(input)
+ expect(result.toJSArray).toEqual(expected.toJSArray)
+ }
+ }
+
+ it("should respond to `split` with limit") {
+ // Tests from JavaDoc
+ splitWithLimit("boo:and:foo", ":", 2, Array("boo", "and:foo"))
+ splitWithLimit("boo:and:foo", ":", 5, Array("boo", "and", "foo"))
+ splitWithLimit("boo:and:foo", ":", -2, Array("boo", "and", "foo"))
+ splitWithLimit("boo:and:foo", "o", 5, Array("b", "", ":and:f", "", ""))
+ splitWithLimit("boo:and:foo", "o", -2, Array("b", "", ":and:f", "", ""))
+ splitWithLimit("boo:and:foo", "o", 0, Array("b", "", ":and:f"))
+
+ // Splitting the empty string must return 1 element - #987
+ splitWithLimit("", "a", 0, Array(""))
+ splitWithLimit("", "\\*", 5, Array(""))
+ splitWithLimit("", "\n", -2, Array(""))
+ splitWithLimit("", "", 1, Array(""))
+
+ // Should remove leading empty match under some conditions - #1171
+ splitWithLimit("abc", "", 2, Array("", "abc"))
+ splitWithLimit("abc", "(?=a)", 2, Array("abc"))
+ splitWithLimit("ab", "a", 1, Array("ab"))
+
+ def splitWithLimit(input: String, regex: String, limit: Int, expected: Array[String]): Unit = {
+ val result = Pattern.compile(regex).split(input, limit)
+ expect(result.toJSArray).toEqual(expected.toJSArray)
+ }
+ }
+
+ it("should respond to `flags`") {
+ val pattern0 = Pattern.compile("a")
+ val pattern1 = Pattern.compile("a", 0)
+ val flags2 = Pattern.CASE_INSENSITIVE | Pattern.DOTALL
+ val pattern2 = Pattern.compile("a", flags2)
+
+ expect(pattern0.flags).toEqual(0)
+ expect(pattern1.flags).toEqual(0)
+ expect(pattern2.flags).toEqual(flags2)
+ }
+
+ it("should respond to `pattern` and `toString`") {
+ def checkPatternAndToString(regex: String): Unit = {
+ val pattern0 = Pattern.compile(regex)
+ expect(pattern0.pattern).toEqual(regex)
+ expect(pattern0.toString).toEqual(regex)
+
+ val pattern1 = Pattern.compile(regex, Pattern.CASE_INSENSITIVE)
+ expect(pattern1.pattern).toEqual(regex)
+ expect(pattern1.toString).toEqual(regex)
+ }
+
+ checkPatternAndToString("a*b+c")
+ checkPatternAndToString("\\S[(a1]a.js")
+ }
+
+ it("should respond to `quote`") {
+ val splitWithQuote = Pattern.compile(Pattern.quote("$1&$2")).split("Scala$1&$2.js")
+ val splitNoQuote = Pattern.compile("$1&$2").split("Scala$1&$2.js")
+ expect(splitWithQuote.mkString).toEqual("Scala.js")
+ expect(splitNoQuote.mkString).toEqual("Scala$1&$2.js")
+ }
+
+ }
+
+ describe("java.util.regex.Matcher") {
+
+ it("should respond to `find`") {
+ val matcher = Pattern.compile("a").matcher("Scala.js")
+
+ expect(matcher.find()).toBeTruthy
+ expect(matcher.find()).toBeTruthy
+ expect(matcher.find()).toBeFalsy
+ expect(matcher.find(4)).toBeTruthy
+ expect(matcher.find()).toBeFalsy
+ }
+
+ it("should respond to `start`, `end`, `group`, and `toMatchResult`") {
+ val matcher = Pattern.compile("\\s(([A-Za-z]{5}(hum)?).js)\\s").matcher("Write Scala.js everyday!")
+
+ def checkGroup0(start: Int, end: Int, group: String) =
+ checkGroup(start, 5, end, 15, group, " Scala.js ")
+
+ def checkGroup1(start: Int, end: Int, group: String) =
+ checkGroup(start, 6, end, 14, group, "Scala.js")
+
+ def checkGroup2(start: Int, end: Int, group: String) =
+ checkGroup(start, 6, end, 11, group, "Scala")
+
+ def checkGroup3(start: Int, end: Int, group: String) =
+ checkGroup(start, -1, end, -1, group, null)
+
+ def checkGroup(start: Int, startExpected: Int, end: Int, endExpected: Int,
+ group: String, groupExpected: String): Unit = {
+ expect(start).toEqual(startExpected)
+ expect(end).toEqual(endExpected)
+ expect(group).toEqual(groupExpected)
+ }
+
+ expect(matcher.find()).toBeTruthy
+ expect(matcher.groupCount).toEqual(3)
+ checkGroup0(matcher.start, matcher.end, matcher.group)
+ checkGroup0(matcher.start(0), matcher.end(0), matcher.group(0))
+ checkGroup1(matcher.start(1), matcher.end(1), matcher.group(1))
+ checkGroup2(matcher.start(2), matcher.end(2), matcher.group(2))
+ checkGroup3(matcher.start(3), matcher.end(3), matcher.group(3))
+
+ val matchResult = matcher.toMatchResult
+ expect(matchResult.groupCount).toEqual(3)
+ checkGroup0(matchResult.start, matchResult.end, matchResult.group)
+ checkGroup0(matchResult.start(0), matchResult.end(0), matchResult.group(0))
+ checkGroup1(matchResult.start(1), matchResult.end(1), matchResult.group(1))
+ checkGroup2(matchResult.start(2), matchResult.end(2), matchResult.group(2))
+ checkGroup3(matchResult.start(3), matchResult.end(3), matchResult.group(3))
+ }
+
+ it("should respond to `matches`") {
+ val matcher0 = Pattern.compile("S[a-z]+").matcher("Scala")
+ val matcher1 = Pattern.compile("S[a-z]+").matcher("Scala.js")
+
+ expect(matcher0.matches()).toBeTruthy
+ expect(matcher1.matches()).toBeFalsy
+ }
+
+ it("should respond to `reset`") {
+ val matcher = Pattern.compile("S[a-z]+").matcher("Scalable")
+
+ expect(matcher.find()).toBeTruthy
+ expect(matcher.find()).toBeFalsy
+ matcher.reset()
+ expect(matcher.find()).toBeTruthy
+ }
+
+ it("should respond to `reset(String)`") {
+ val matcher = Pattern.compile("S[a-z]+").matcher("Scalable")
+
+ expect(matcher.matches()).toBeTruthy
+ matcher.reset("Scala.js")
+ expect(matcher.matches()).toBeFalsy
+ }
+
+ it("should respond to `usePattern`") {
+ val patternNoDots = Pattern.compile("S[a-z]+")
+ val patternWithDots = Pattern.compile("S[a-z.]+")
+
+ val matcher0 = patternNoDots.matcher("Scala.js")
+ expect(matcher0.matches()).toBeFalsy
+ matcher0.usePattern(patternWithDots)
+ expect(matcher0.matches()).toBeTruthy
+
+ val matcher1 = patternWithDots.matcher("Scala.js")
+ expect(matcher1.matches()).toBeTruthy
+ matcher1.usePattern(patternNoDots)
+ expect(matcher1.matches()).toBeFalsy
+ }
+
+ it("should respond to `lookingAt`") {
+ val matcher0 = Pattern.compile("S[a-z]+").matcher("Scala")
+ val matcher1 = Pattern.compile("S[a-z]+").matcher("Scala.js")
+ val matcher2 = Pattern.compile("[a-z]+").matcher("Scala.js")
+
+ expect(matcher0.lookingAt()).toBeTruthy
+ expect(matcher1.lookingAt()).toBeTruthy
+ expect(matcher2.lookingAt()).toBeFalsy
+
+ val matcher3 = Pattern.compile("S[a-z]+").matcher("Scala.js")
+ expect(matcher3.find()).toBeTruthy
+ expect(matcher3.lookingAt()).toBeTruthy
+ }
+
+ it("should respond to `hitEnd`") {
+ val matcher0 = Pattern.compile("S[a-z]*").matcher("Scala.js")
+ expect(matcher0.find()).toBeTruthy
+ expect(matcher0.hitEnd).toBeFalsy
+ expect(matcher0.find()).toBeFalsy
+ expect(matcher0.hitEnd).toBeTruthy
+
+ val matcher1 = Pattern.compile("[A-Za-z]+").matcher("Scala.js")
+ expect(matcher1.find()).toBeTruthy
+ expect(matcher1.hitEnd).toBeFalsy
+ expect(matcher1.group).toBe("Scala")
+ expect(matcher1.find()).toBeTruthy
+ expect(matcher1.hitEnd).toBeTruthy
+ expect(matcher1.group).toBe("js")
+ expect(matcher1.lookingAt()).toBeTruthy
+ expect(matcher1.group).toBe("Scala")
+ expect(matcher1.hitEnd).toBeFalsy
+ }
+
+ it("should respond to `region`") {
+ val matcher0 = Pattern.compile("S[a-z]+").matcher("A Scalable Solution")
+
+ val region0to3 = matcher0.region(0, 3)
+ expect(region0to3.regionStart).toBe(0)
+ expect(region0to3.regionEnd).toBe(3)
+ expect(region0to3.find()).toBeFalsy
+
+ val region0to15 = matcher0.region(0, 15)
+ expect(region0to15.regionStart).toBe(0)
+ expect(region0to15.regionEnd).toBe(15)
+ expect(region0to15.find()).toBeTruthy
+ expect(region0to15.group).toEqual("Scalable")
+
+ val region2to7 = region0to15.region(2, 7)
+ expect(region2to7.regionStart).toBe(2)
+ expect(region2to7.regionEnd).toBe(7)
+ expect(region2to7.find()).toBeTruthy
+ expect(region2to7.group).toEqual("Scala")
+
+ val region5toEnd = matcher0.region(5, matcher0.regionEnd)
+ expect(region5toEnd.regionStart).toBe(5)
+ expect(region5toEnd.regionEnd).toBe(19)
+ expect(region5toEnd.find()).toBeTruthy
+ expect(region5toEnd.group).toEqual("Solution")
+
+ val matcher1 = Pattern.compile("0[xX][A-Fa-f0-9]{3}$").matcher("In CSS, 0xc4fe is not a color")
+
+ val region5to13 = matcher1.region(5, 13)
+ expect(region5to13.regionStart).toBe(5)
+ expect(region5to13.regionEnd).toBe(13)
+ expect(region5to13.find()).toBeTruthy
+ expect(region5to13.group).toEqual("0xc4f")
+
+ val region5to20 = matcher1.region(5, 20)
+ expect(region5to20.regionStart).toBe(5)
+ expect(region5to20.regionEnd).toBe(20)
+ expect(region5to20.find()).toBeFalsy
+ }
+
+ it("should respond to `appendReplacement` and `appendTail`") {
+ // From the JavaDoc
+ val matcher = Pattern.compile("cat").matcher("one cat two cats in the yard")
+ val sb = new StringBuffer
+
+ while (matcher.find()) {
+ matcher.appendReplacement(sb, "dog")
+ }
+ matcher.appendTail(sb)
+
+ expect(sb.toString).toBe("one dog two dogs in the yard")
+ }
+
+ it("should respond to `replaceAll`") {
+ // From the JavaDoc
+ val matcher = Pattern.compile("a*b").matcher("aabfooaabfooabfoob")
+ expect(matcher.replaceAll("-")).toBe("-foo-foo-foo-")
+ }
+
+ it("should respond to `replaceFirst`") {
+ // From the JavaDoc
+ val matcher = Pattern.compile("dog").matcher("zzzdogzzzdogzzz")
+ expect(matcher.replaceFirst("cat")).toBe("zzzcatzzzdogzzz")
+ }
+
+ it("should throw exception if match accessors are called before `find`") {
+ def checkInvalidAccess(block: => Unit): Unit = {
+ val exception: Throwable = try {
+ block
+ throw new Error("No exception thrown")
+ } catch {
+ case e: Throwable => e
+ }
+
+ expect(exception.getClass.getName).toBe("java.lang.IllegalStateException")
+ expect(exception.getMessage).toBe("No match available")
+ }
+
+ val matcher = Pattern.compile("(Sc([a-z]*))").matcher("Scala.js")
+
+ checkInvalidAccess { matcher.start }
+ checkInvalidAccess { matcher.end }
+ checkInvalidAccess { matcher.group }
+ checkInvalidAccess { matcher.group(42) }
+
+ val matchResult = matcher.toMatchResult
+
+ checkInvalidAccess { matchResult.start }
+ checkInvalidAccess { matchResult.end }
+ checkInvalidAccess { matchResult.group }
+ checkInvalidAccess { matchResult.group(42) }
+ }
+
+ it("should correctly handle zero-length matches") {
+ val pat = Pattern.compile("a*?")
+ val mat = pat.matcher("aaaaa")
+ for (i <- 0 to 5) {
+ expect(mat.find()).toBeTruthy
+ expect(mat.start).toEqual(i)
+ expect(mat.end).toEqual(i)
+ }
+
+ // Make sure we don't suddenly re-match
+ for (i <- 0 to 5) {
+ expect(mat.find()).toBeFalsy
+ }
+ }
+
+ it("should support in-pattern flags - #997") {
+ val p0 = Pattern.compile("(?i)abc")
+
+ expect(p0.flags() & Pattern.CASE_INSENSITIVE).not.toBe(0)
+
+ val m0 = p0.matcher("abcABC")
+
+ expect(m0.find()).toBeTruthy
+ expect(m0.group()).toEqual("abc")
+ expect(m0.find()).toBeTruthy
+ expect(m0.group()).toEqual("ABC")
+ expect(m0.find()).toBeFalsy
+
+ val p1 = Pattern.compile("(?-i)abc", Pattern.CASE_INSENSITIVE)
+
+ expect(p1.flags() & Pattern.CASE_INSENSITIVE).toBe(0)
+
+ val m1 = p1.matcher("abcABC")
+
+ expect(m1.find()).toBeTruthy
+ expect(m1.group()).toEqual("abc")
+ expect(m1.find()).toBeFalsy
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ShortTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ShortTest.scala
new file mode 100644
index 0000000..e59f2e9
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ShortTest.scala
@@ -0,0 +1,66 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import java.lang.{Short => JShort}
+
+import org.scalajs.jasminetest.JasmineTest
+
+/**
+ * tests the implementation of the java standard library Short
+ */
+object ShortTest extends JasmineTest {
+
+ describe("java.lang.Short") {
+
+ it("should provide `compareTo`") {
+ def compare(x: Short, y: Short): Int =
+ new JShort(x).compareTo(new JShort(y))
+
+ expect(compare(0.toShort, 5.toShort)).toBeLessThan(0)
+ expect(compare(10.toShort, 9.toShort)).toBeGreaterThan(0)
+ expect(compare(-2.toShort, -1.toShort)).toBeLessThan(0)
+ expect(compare(3.toShort, 3.toShort)).toEqual(0)
+ }
+
+ it("should be a Comparable") {
+ def compare(x: Any, y: Any): Int =
+ x.asInstanceOf[Comparable[Any]].compareTo(y)
+
+ expect(compare(0.toShort, 5.toShort)).toBeLessThan(0)
+ expect(compare(10.toShort, 9.toShort)).toBeGreaterThan(0)
+ expect(compare(-2.toShort, -1.toShort)).toBeLessThan(0)
+ expect(compare(3.toShort, 3.toShort)).toEqual(0)
+ }
+
+ it("should parse strings") {
+ def test(s: String, v: Short): Unit = {
+ expect(JShort.parseShort(s)).toEqual(v)
+ expect(JShort.valueOf(s).shortValue()).toEqual(v)
+ expect(new JShort(s).shortValue()).toEqual(v)
+ }
+
+ test("0", 0)
+ test("5", 5)
+ test("127", 127)
+ test("-100", -100)
+ test("30000", 30000)
+ }
+
+ it("should reject invalid strings when parsing") {
+ def test(s: String): Unit =
+ expect(() => JShort.parseShort(s)).toThrow
+
+ test("abc")
+ test("")
+ test("60000") // out of range
+ test("-90000") // out of range
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/StackTraceElementTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/StackTraceElementTest.scala
new file mode 100644
index 0000000..b02a889
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/StackTraceElementTest.scala
@@ -0,0 +1,29 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import scala.scalajs.js
+
+import org.scalajs.jasminetest.JasmineTest
+
+object StackTraceElementTest extends JasmineTest {
+
+ describe("java.lang.StackTraceElement") {
+ it("should use the magic columnNumber field in its toString") {
+ val st = new StackTraceElement("MyClass", "myMethod", "myFile.scala", 1)
+ st.asInstanceOf[js.Dynamic].columnNumber = 5
+ expect(st.toString).toEqual("MyClass.myMethod(myFile.scala:1:5)")
+ }
+
+ it("should leave toString unmodified without magic columnNumber") {
+ val st = new StackTraceElement("MyClass", "myMethod", "myFile.scala", 1)
+ expect(st.toString).toEqual("MyClass.myMethod(myFile.scala:1)")
+ }
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/StreamsTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/StreamsTest.scala
new file mode 100644
index 0000000..6975614
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/StreamsTest.scala
@@ -0,0 +1,308 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import java.io._
+
+import scala.language.implicitConversions
+
+import scala.scalajs.js
+
+import org.scalajs.jasminetest.JasmineTest
+
+/** Tests for our implementation of java.io._ stream classes */
+object StreamsTest extends JasmineTest with CommonStreamsTests {
+
+ // Need to define this again, otherwise conversion on function
+ // triggers for Seqs
+ override implicit def traversable2array[T](
+ a: TraversableOnce[T]): js.Array[T] = super.traversable2array(a)
+
+ describe("java.io.InputStream") {
+
+ class DummyInputStream(val length: Int) extends InputStream {
+ private var i: Int = 0
+ def read(): Int = if (i < length) { i += 1; i } else -1
+ }
+
+ it("should provide a default implementation of `read` to an array") {
+ val stream = new DummyInputStream(200)
+
+ val buf = new Array[Byte](50)
+
+ // Should read first 50 bytes (next: 51)
+ expect(stream.read(buf)).toBe(50)
+ expect(buf).toEqual((1 to 50))
+
+ // Should read another 20 (next: 71)
+ expect(stream.read(buf, 10, 20)).toBe(20)
+ expect(buf).toEqual((1 to 10) ++ (51 to 70) ++ (31 to 50))
+
+ // Test some Exception conditions
+ expect(() => stream.read(null, 0, 10)).toThrow
+ expect(() => stream.read(buf, -1, 10)).toThrow
+ expect(() => stream.read(buf, 0, -1)).toThrow
+ expect(() => stream.read(buf, 10, 100)).toThrow
+ // Buffer should be unmodified
+ expect(buf).toEqual((1 to 10) ++ (51 to 70) ++ (31 to 50))
+
+ // Should read nothing (next: 71)
+ expect(stream.read(buf, 10, 0)).toBe(0)
+ expect(buf).toEqual((1 to 10) ++ (51 to 70) ++ (31 to 50))
+
+ // Skip 40 bytes (next: 111)
+ expect(stream.skip(40)).toBe(40)
+
+ // Read 50 bytes, should wrap (next: 161)
+ expect(stream.read(buf)).toBe(50)
+ expect(buf).toEqual((111 to 127) ++ (-128 to -96))
+
+ // Read 45 bytes, should read 40 (next: EOF)
+ expect(stream.read(buf, 5, 45)).toBe(40)
+ expect(buf).toEqual((111 to 115) ++ (-95 to -56) ++ (-100 to -96))
+
+ // Read 50 bytes, should read nothing
+ expect(stream.read(buf)).toBe(-1)
+ expect(stream.read(buf, 0, 0)).toBe(0)
+ expect(buf).toEqual((111 to 115) ++ (-95 to -56) ++ (-100 to -96))
+ }
+
+ it("should provide a default implementation of `skip`") {
+ val stream = new DummyInputStream(10)
+
+ expect(stream.skip(5)).toBe(5)
+ expect(stream.read()).toBe(6)
+ expect(stream.skip(1)).toBe(1)
+ expect(stream.read()).toBe(8)
+ expect(stream.skip(-5)).toBe(0)
+ expect(stream.read()).toBe(9)
+ expect(stream.skip(0)).toBe(0)
+ expect(stream.read()).toBe(10)
+ expect(stream.skip(10)).toBe(0)
+ }
+
+ }
+
+ describe("java.io.ByteArrayInputStream") {
+ byteArrayInputStreamLikeTests(seq =>
+ new ByteArrayInputStream(seq.map(_.toByte).toArray))
+ }
+
+ describe("java.io.ByteArrayOutputStream") {
+
+ it("should support simple write(x: Int)") {
+ val out = new ByteArrayOutputStream()
+
+ for (i <- 0 to 9)
+ out.write(i)
+
+ expect(out.toByteArray).toEqual(js.Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))
+ }
+
+ it("should support simple write(x: Array[Byte])") {
+ val out = new ByteArrayOutputStream()
+ val arr = Array[Byte](0, 1, 2, 3, 4, 5)
+
+ out.write(arr, 1, 4)
+ out.write(arr)
+
+ expect(out.toByteArray).toEqual(js.Array(1, 2, 3, 4, 0, 1, 2, 3, 4, 5))
+ }
+
+ it("should support write(x: Array[Byte]) with buffer resize") {
+ val out = new ByteArrayOutputStream(16)
+ val arr = Array[Byte](0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
+
+ out.write(arr)
+ out.write(arr)
+
+ expect(out.toByteArray).toEqual(arr ++ arr)
+ }
+
+ it("should support toString (with UTF8)") {
+ val buf = Array[Byte](72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100,
+ 46, -29, -127, -109, -29, -126, -109, -29, -127, -85, -29, -127, -95,
+ -29, -127, -81, -26, -105, -91, -26, -100, -84, -24, -86, -98, -29,
+ -126, -110, -24, -86, -83, -29, -126, -127, -29, -127, -66, -29, -127,
+ -103, -29, -127, -117, -29, -128, -126)
+
+ val out = new ByteArrayOutputStream()
+ out.write(buf)
+
+ expect(out.toString).toEqual("Hello World.こんにちは日本語を読めますか。")
+ }
+
+ it("should support reset()") {
+ val out = new ByteArrayOutputStream()
+ for (i <- 0 to 9) out.write(i)
+ out.reset()
+ for (i <- 0 to 9) out.write(i)
+
+ expect(out.toByteArray).toEqual(js.Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))
+ }
+
+ }
+
+}
+
+/** tests also used by typedarray.ArrayBufferInputStreamTests */
+trait CommonStreamsTests extends JasmineTest {
+
+ implicit def traversable2array[T](a: TraversableOnce[T]): js.Array[T] = {
+ import js.JSConverters._
+ a.toJSArray
+ }
+
+ implicit def array2array[T](a: Array[T]): js.Array[T] = {
+ import js.JSConverters._
+ a.toJSArray
+ }
+
+ def byteArrayInputStreamLikeTests(mkStream: Seq[Int] => InputStream): Unit = {
+ val length = 50
+ def newStream = mkStream(1 to length)
+
+ it("should provide `read()`") {
+ val stream = newStream
+
+ for (i <- 1 to length)
+ expect(stream.read()).toBe(i)
+
+ for (_ <- 1 to 5)
+ expect(stream.read()).toBe(-1)
+ }
+
+ it("should provide `read(buf)`") {
+ val stream = newStream
+ val buf = new Array[Byte](10)
+
+ expect(stream.read(buf)).toBe(10)
+ expect(buf).toEqual(1 to 10)
+
+ expect(stream.skip(35)).toBe(35)
+
+ expect(stream.read(buf)).toBe(5)
+ expect(buf).toEqual((46 to 50) ++ (6 to 10))
+
+ expect(stream.read(buf)).toBe(-1)
+ expect(stream.read()).toBe(-1)
+ }
+
+ it("should provide full-argument `read`") {
+ val stream = newStream
+ val buf = new Array[Byte](20)
+
+ expect(stream.read(buf, 10, 5)).toBe(5)
+ expect(buf).toEqual(Seq.fill(10)(0) ++ (1 to 5) ++ Seq.fill(5)(0))
+
+ expect(stream.read(buf, 0, 20)).toBe(20)
+ expect(buf).toEqual(6 to 25)
+
+ expect(stream.read(buf, 10, 0)).toBe(0)
+ expect(buf).toEqual(6 to 25)
+
+ expect(() => stream.read(buf, -1, 0)).toThrow
+ expect(() => stream.read(buf, 0, -1)).toThrow
+ expect(() => stream.read(buf, 100, 0)).toThrow
+ expect(() => stream.read(buf, 10, 100)).toThrow
+ expect(buf).toEqual(6 to 25)
+
+ expect(stream.skip(20)).toBe(20)
+
+ expect(stream.read(buf, 0, 10)).toBe(5)
+ expect(buf).toEqual((46 to 50) ++ (11 to 25))
+
+ expect(stream.read(buf, 0, 10)).toBe(-1)
+ expect(stream.read(buf, 0, 0)).toBe(0)
+ expect(buf).toEqual((46 to 50) ++ (11 to 25))
+
+ }
+
+ it("should provide `available`") {
+ val stream = newStream
+
+ def mySkip(n: Int) = for (_ <- 1 to n) expect(stream.read()).not.toBe(-1)
+ def check(n: Int) = expect(stream.available).toBe(n)
+
+ check(50)
+ mySkip(5)
+ check(45)
+ expect(stream.skip(10)).toBe(10)
+ check(35)
+ mySkip(30)
+ check(5)
+ expect(stream.skip(20)).toBe(5)
+ check(0)
+ }
+
+ it("should provide `skip`") {
+ val stream = newStream
+
+ expect(stream.skip(7)).toBe(7)
+
+ for (i <- 8 to 32)
+ expect(stream.read()).toBe(i)
+
+ expect(stream.skip(0)).toBe(0)
+ expect(stream.read()).toBe(33)
+ expect(stream.skip(-4)).toBe(0)
+ expect(stream.read()).toBe(34)
+
+ expect(stream.skip(30)).toBe(16)
+ expect(stream.skip(30)).toBe(0)
+ }
+
+ it("should return true from `markSupported`") {
+ expect(newStream.markSupported).toBe(true)
+ }
+
+ it("should provide no-op `close`") {
+ val stream = newStream
+
+ for (i <- 1 to length) {
+ stream.close()
+ expect(stream.read()).toBe(i)
+ }
+ }
+
+ it("should provide `mark`/`reset`") {
+ val stream = newStream
+
+ def read(range: Range) = for (i <- range) expect(stream.read()).toBe(i)
+
+ read(1 to 10)
+ stream.reset() // mark must be 0 at creation
+ read(1 to 5)
+ stream.mark(length)
+ read(6 to 22)
+ stream.reset()
+ read(6 to 20)
+ stream.reset()
+ read(6 to 25)
+ stream.reset()
+ expect(stream.skip(40)).toBe(40)
+ stream.mark(length)
+ read(46 to 50)
+ stream.reset()
+ read(46 to 50)
+ stream.mark(length)
+ expect(stream.read()).toBe(-1)
+ stream.reset()
+ expect(stream.read()).toBe(-1)
+ }
+
+ it("should return positive integers when calling read") {
+ val stream = mkStream(Seq(-1, -2, -3))
+ expect(stream.read()).toBe(255)
+ expect(stream.read()).toBe(254)
+ expect(stream.read()).toBe(253)
+ expect(stream.read()).toBe(-1)
+ }
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/StringBufferTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/StringBufferTest.scala
new file mode 100644
index 0000000..a034ce6
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/StringBufferTest.scala
@@ -0,0 +1,219 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import scala.reflect.{classTag, ClassTag}
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+object StringBufferTest extends JasmineTest {
+
+ def shouldThrow[T : ClassTag](fn: => Unit) =
+ try {
+ fn
+ expect("exception").toBe("thrown")
+ } catch {
+ case e: T =>
+ case x: Throwable => expect(x.toString).toBe(classTag[T].runtimeClass.getSimpleName)
+ }
+
+ describe("java.lang.StringBuffer") {
+
+ def newBuf = new java.lang.StringBuffer
+ def initBuf(str: String) = new java.lang.StringBuffer(str)
+
+ it("should respond to `append`") {
+ expect(newBuf.append("asdf").toString).toEqual("asdf")
+ expect(newBuf.append(null: AnyRef).toString).toEqual("null")
+ expect(newBuf.append(null: String).toString).toEqual("null")
+ expect(newBuf.append(null: CharSequence,0,2).toString).toEqual("nu")
+ expect(newBuf.append(js.undefined).toString).toEqual("undefined")
+ expect(newBuf.append(true).toString).toEqual("true")
+ expect(newBuf.append('a').toString).toEqual("a")
+ expect(newBuf.append(Array('a','b','c','d')).toString).toEqual("abcd")
+ expect(newBuf.append(Array('a','b','c','d'), 1, 2).toString).toEqual("bc")
+ expect(newBuf.append(4.toByte).toString).toEqual("4")
+ expect(newBuf.append(304.toShort).toString).toEqual("304")
+ expect(newBuf.append(100000).toString).toEqual("100000")
+ expect(newBuf.append(2.5f).toString).toEqual("2.5")
+ expect(newBuf.append(3.5).toString).toEqual("3.5")
+ }
+
+ it("should respond to `insert`") {
+ expect(newBuf.insert(0, "asdf").toString).toEqual("asdf")
+ expect(newBuf.insert(0, null: AnyRef).toString).toEqual("null")
+ expect(newBuf.insert(0, null: String).toString).toEqual("null")
+ expect(newBuf.insert(0, null: CharSequence,0,2).toString).toEqual("nu")
+ expect(newBuf.insert(0, js.undefined).toString).toEqual("undefined")
+ expect(newBuf.insert(0, true).toString).toEqual("true")
+ expect(newBuf.insert(0, 'a').toString).toEqual("a")
+ expect(newBuf.insert(0, Array('a','b','c','d')).toString).toEqual("abcd")
+ expect(newBuf.insert(0, Array('a','b','c','d'), 1, 2).toString).toEqual("bc")
+ expect(newBuf.insert(0, 4.toByte).toString).toEqual("4")
+ expect(newBuf.insert(0, 304.toShort).toString).toEqual("304")
+ expect(newBuf.insert(0, 100000).toString).toEqual("100000")
+ expect(newBuf.insert(0, 2.5f).toString).toEqual("2.5")
+ expect(newBuf.insert(0, 3.5).toString).toEqual("3.5")
+
+ expect(initBuf("adef").insert(1, "bc")).toEqual("abcdef")
+ expect(initBuf("abcd").insert(4, "ef")).toEqual("abcdef")
+ expect(initBuf("adef").insert(1, Array('b','c'))).toEqual("abcdef")
+ expect(initBuf("adef").insert(1, initBuf("bc"))).toEqual("abcdef")
+ expect(initBuf("abef").insert(2, Array('a','b','c','d','e'), 2, 2)).toEqual("abcdef")
+ expect(initBuf("abef").insert(2, initBuf("abcde"), 2, 4)).toEqual("abcdef")
+
+ shouldThrow[StringIndexOutOfBoundsException](initBuf("abcd").insert(5, "whatever"))
+ shouldThrow[StringIndexOutOfBoundsException](initBuf("abcd").insert(-1, "whatever"))
+ }
+
+ it("should respond to `deleteCharAt`") {
+ expect(initBuf("0123").deleteCharAt(1).toString).toEqual("023")
+ expect(initBuf("0123").deleteCharAt(0).toString).toEqual("123")
+ expect(initBuf("0123").deleteCharAt(3).toString).toEqual("012")
+ shouldThrow[StringIndexOutOfBoundsException](initBuf("0123").deleteCharAt(-1))
+ shouldThrow[StringIndexOutOfBoundsException](initBuf("0123").deleteCharAt(4))
+ }
+
+ it("should respond to `replace`") {
+ expect(initBuf("0123").replace(1,3,"bc").toString).toEqual("0bc3")
+ expect(initBuf("0123").replace(0,4,"abcd").toString).toEqual("abcd")
+ expect(initBuf("0123").replace(0,10,"abcd").toString).toEqual("abcd")
+ expect(initBuf("0123").replace(3,10,"defg").toString).toEqual("012defg")
+ expect(initBuf("0123").replace(0,1,"xxxx").toString).toEqual("xxxx123")
+ expect(initBuf("0123").replace(1,1,"xxxx").toString).toEqual("0xxxx123")
+
+ shouldThrow[StringIndexOutOfBoundsException](initBuf("0123").replace(-1,3,"x"))
+ shouldThrow[StringIndexOutOfBoundsException](initBuf("0123").replace(4,5,"x"))
+ }
+
+ it("should respond to `setCharAt`") {
+ val buf = newBuf
+ buf.append("foobar")
+
+ buf.setCharAt(2, 'x')
+ expect(buf.toString).toEqual("foxbar")
+
+ buf.setCharAt(5, 'h')
+ expect(buf.toString).toEqual("foxbah")
+
+ expect(() => buf.setCharAt(-1, 'h')).toThrow
+ expect(() => buf.setCharAt(6, 'h')).toThrow
+ }
+
+ it("should properly setLength") {
+ val buf = newBuf
+ buf.append("foobar")
+
+ expect(() => buf.setLength(-3)).toThrow
+
+ expect({ buf.setLength(3); buf.toString }).toEqual("foo")
+ expect({ buf.setLength(6); buf.toString }).toEqual("foo\u0000\u0000\u0000")
+ }
+
+ }
+
+ describe("java.lang.StringBuilder") {
+
+ def newBuilder = new java.lang.StringBuilder
+ def initBuilder(str: String) = new java.lang.StringBuilder(str)
+
+ it("should respond to `append`") {
+ expect(newBuilder.append("asdf").toString).toEqual("asdf")
+ expect(newBuilder.append(null: AnyRef).toString).toEqual("null")
+ expect(newBuilder.append(null: String).toString).toEqual("null")
+ expect(newBuilder.append(null: CharSequence,0,2).toString).toEqual("nu")
+ expect(newBuilder.append(js.undefined).toString).toEqual("undefined")
+ expect(newBuilder.append(true).toString).toEqual("true")
+ expect(newBuilder.append('a').toString).toEqual("a")
+ expect(newBuilder.append(Array('a','b','c','d')).toString).toEqual("abcd")
+ expect(newBuilder.append(Array('a','b','c','d'), 1, 2).toString).toEqual("bc")
+ expect(newBuilder.append(4.toByte).toString).toEqual("4")
+ expect(newBuilder.append(304.toShort).toString).toEqual("304")
+ expect(newBuilder.append(100000).toString).toEqual("100000")
+ expect(newBuilder.append(2.5f).toString).toEqual("2.5")
+ expect(newBuilder.append(3.5).toString).toEqual("3.5")
+ }
+
+ it("should respond to `insert`") {
+ expect(newBuilder.insert(0, "asdf").toString).toEqual("asdf")
+ expect(newBuilder.insert(0, null: AnyRef).toString).toEqual("null")
+ expect(newBuilder.insert(0, null: String).toString).toEqual("null")
+ expect(newBuilder.insert(0, null: CharSequence,0,2).toString).toEqual("nu")
+ expect(newBuilder.insert(0, js.undefined).toString).toEqual("undefined")
+ expect(newBuilder.insert(0, true).toString).toEqual("true")
+ expect(newBuilder.insert(0, 'a').toString).toEqual("a")
+ expect(newBuilder.insert(0, Array('a','b','c','d')).toString).toEqual("abcd")
+ expect(newBuilder.insert(0, Array('a','b','c','d'), 1, 2).toString).toEqual("bc")
+ expect(newBuilder.insert(0, 4.toByte).toString).toEqual("4")
+ expect(newBuilder.insert(0, 304.toShort).toString).toEqual("304")
+ expect(newBuilder.insert(0, 100000).toString).toEqual("100000")
+ expect(newBuilder.insert(0, 2.5f).toString).toEqual("2.5")
+ expect(newBuilder.insert(0, 3.5).toString).toEqual("3.5")
+
+ expect(initBuilder("adef").insert(1, "bc")).toEqual("abcdef")
+ expect(initBuilder("abcd").insert(4, "ef")).toEqual("abcdef")
+ expect(initBuilder("adef").insert(1, Array('b','c'))).toEqual("abcdef")
+ expect(initBuilder("adef").insert(1, initBuilder("bc"))).toEqual("abcdef")
+ expect(initBuilder("abef").insert(2, Array('a','b','c','d','e'), 2, 2)).toEqual("abcdef")
+ expect(initBuilder("abef").insert(2, initBuilder("abcde"), 2, 4)).toEqual("abcdef")
+
+ shouldThrow[StringIndexOutOfBoundsException](initBuilder("abcd").insert(5, "whatever"))
+ shouldThrow[StringIndexOutOfBoundsException](initBuilder("abcd").insert(-1, "whatever"))
+ }
+
+ it("should allow string interpolation to survive `null` and `undefined`") {
+ expect(s"${null}").toEqual("null")
+ expect(s"${js.undefined}").toEqual("undefined")
+ }
+
+ it("should respond to `deleteCharAt`") {
+ expect(initBuilder("0123").deleteCharAt(1).toString).toEqual("023")
+ expect(initBuilder("0123").deleteCharAt(0).toString).toEqual("123")
+ expect(initBuilder("0123").deleteCharAt(3).toString).toEqual("012")
+ shouldThrow[StringIndexOutOfBoundsException](initBuilder("0123").deleteCharAt(-1))
+ shouldThrow[StringIndexOutOfBoundsException](initBuilder("0123").deleteCharAt(4))
+ }
+
+ it("should respond to `replace`") {
+ expect(initBuilder("0123").replace(1,3,"bc").toString).toEqual("0bc3")
+ expect(initBuilder("0123").replace(0,4,"abcd").toString).toEqual("abcd")
+ expect(initBuilder("0123").replace(0,10,"abcd").toString).toEqual("abcd")
+ expect(initBuilder("0123").replace(3,10,"defg").toString).toEqual("012defg")
+ expect(initBuilder("0123").replace(0,1,"xxxx").toString).toEqual("xxxx123")
+ expect(initBuilder("0123").replace(1,1,"xxxx").toString).toEqual("0xxxx123")
+
+ shouldThrow[StringIndexOutOfBoundsException](initBuilder("0123").replace(-1,3,"x"))
+ shouldThrow[StringIndexOutOfBoundsException](initBuilder("0123").replace(4,5,"x"))
+ }
+
+ it("should respond to `setCharAt`") {
+ val b = newBuilder
+ b.append("foobar")
+
+ b.setCharAt(2, 'x')
+ expect(b.toString).toEqual("foxbar")
+
+ b.setCharAt(5, 'h')
+ expect(b.toString).toEqual("foxbah")
+
+ expect(() => b.setCharAt(-1, 'h')).toThrow
+ expect(() => b.setCharAt(6, 'h')).toThrow
+ }
+
+ it("should properly setLength") {
+ val b = newBuilder
+ b.append("foobar")
+
+ expect(() => b.setLength(-3)).toThrow
+
+ expect({ b.setLength(3); b.toString }).toEqual("foo")
+ expect({ b.setLength(6); b.toString }).toEqual("foo\u0000\u0000\u0000")
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/StringTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/StringTest.scala
new file mode 100644
index 0000000..a49e521
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/StringTest.scala
@@ -0,0 +1,237 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import scala.scalajs.js
+import scala.scalajs.js.JSConverters._
+
+import org.scalajs.jasminetest.JasmineTest
+
+object StringTest extends JasmineTest {
+
+ describe("java.lang.String") {
+
+ it("should respond to `length`") {
+ expect("Scala.js".length).toEqual(8)
+ expect("".length).toEqual(0)
+ }
+
+ it("should respond to `intern`") {
+ val s = "Scala.js"
+ expect(s.intern).toEqual(s)
+ }
+
+ it("should respond to `equals`") {
+ expect("Scala.js".equals("Scala.js")).toBeTruthy
+ expect("Scala.js".equals("Java")).toBeFalsy
+ }
+
+ it("should respond to `equalsIgnoreCase`") {
+ expect("Scala.JS".equalsIgnoreCase("Scala.js")).toBeTruthy
+ expect("åløb".equalsIgnoreCase("ÅLØb")).toBeTruthy
+ expect("Scala.js".equalsIgnoreCase("Java")).toBeFalsy
+ expect("Scala.js".equalsIgnoreCase(null)).toBeFalsy
+ }
+
+ it("should respond to `compareTo`") {
+ expect("Scala.js".compareTo("Scala")).toBeGreaterThan(0)
+ expect("Scala.js".compareTo("Scala.js")).toBe(0)
+ expect("Scala.js".compareTo("banana")).toBeLessThan(0)
+ }
+
+ it("should respond to `compareToIgnoreCase`") {
+ expect("Scala.JS".compareToIgnoreCase("Scala.js")).toBe(0)
+ expect("Scala.JS".compareToIgnoreCase("scala")).toBeGreaterThan(0)
+ expect("åløb".compareToIgnoreCase("ÅLØB")).toBe(0)
+ expect("Java".compareToIgnoreCase("Scala")).toBeLessThan(0)
+ }
+
+ it("should respond to `isEmpty`") {
+ expect("Scala.js".isEmpty).toBeFalsy
+ expect("".isEmpty).toBeTruthy
+ }
+
+ it("should respond to `contains`") {
+ expect("Scala.js".contains("Scala")).toBeTruthy
+ expect("Scala.js".contains("Scala.js")).toBeTruthy
+ expect("ananas".contains("na")).toBeTruthy
+ expect("Scala.js".contains("scala")).toBeFalsy
+ }
+
+ it("should respond to `startWith`") {
+ expect("Scala.js".startsWith("Scala")).toBeTruthy
+ expect("Scala.js".startsWith("Scala.js")).toBeTruthy
+ expect("Scala.js".startsWith("scala")).toBeFalsy
+ expect("ananas".startsWith("an")).toBeTruthy
+ }
+
+ it("should respond to `endsWith`") {
+ expect("Scala.js".endsWith("js")).toBeTruthy
+ expect("Scala.js".endsWith("Scala.js")).toBeTruthy
+ expect("Scala.js".endsWith("JS")).toBeFalsy
+ expect("banana".endsWith("na")).toBeTruthy
+ }
+
+ it("should respond to `indexOf(String)`") {
+ expect("Scala.js".indexOf("js")).toBe(6)
+ expect("Scala.js".indexOf("Scala.js")).toBe(0)
+ expect("ananas".indexOf("na")).toBe(1)
+ expect("Scala.js".indexOf("Java")).toBe(-1)
+ }
+
+ it("should respond to `indexOf(int)`") {
+ expect("abc\uD834\uDF06def\uD834\uDF06def".indexOf(0x61)).toEqual(0)
+ expect("abc\uD834\uDF06def\uD834\uDF06def".indexOf(0x1D306)).toEqual(3)
+ expect("abc\uD834\uDF06def\uD834\uDF06def".indexOf(0xD834)).toEqual(3)
+ expect("abc\uD834\uDF06def\uD834\uDF06def".indexOf(0xDF06)).toEqual(4)
+ expect("abc\uD834\uDF06def\uD834\uDF06def".indexOf(0x64)).toEqual(5)
+ }
+
+ it("should respond to `lastIndexOf(String)`") {
+ expect("Scala.js".lastIndexOf("Scala.js")).toBe(0)
+ expect("ananas".lastIndexOf("na")).toBe(3)
+ expect("Scala.js".lastIndexOf("Java")).toBe(-1)
+ }
+
+ it("should respond to `lastIndexOf(int)`") {
+ expect("abc\uD834\uDF06def\uD834\uDF06def".lastIndexOf(0x61)).toEqual(0)
+ expect("abc\uD834\uDF06def\uD834\uDF06def".lastIndexOf(0x1D306)).toEqual(8)
+ expect("abc\uD834\uDF06def\uD834\uDF06def".lastIndexOf(0xD834)).toEqual(8)
+ expect("abc\uD834\uDF06def\uD834\uDF06def".lastIndexOf(0xDF06)).toEqual(9)
+ expect("abc\uD834\uDF06def\uD834\uDF06def".lastIndexOf(0x64)).toEqual(10)
+ }
+
+ it("should respond to `toUpperCase`") {
+ expect("Scala.js".toUpperCase()).toBe("SCALA.JS")
+ }
+
+ it("should respond to `toLowerCase`") {
+ expect("Scala.js".toLowerCase()).toBe("scala.js")
+ }
+
+ it("should respond to `charAt`") {
+ expect("Scala.js".charAt(5)).toBe('.')
+ expect("Scala.js".charAt(6)).not.toBe('.')
+ }
+
+ when("compliant-asinstanceofs").
+ it("charAt() should throw with out-of-bound indices") {
+ // Type Strings both as CharSequence and String. One will invoke the
+ // helper, the other directly the method on RuntimeString.
+ expect(() => ("Scala.js": CharSequence).charAt(-3)).toThrow
+ expect(() => ("Scala.js": CharSequence).charAt(20)).toThrow
+ expect(() => "Scala.js".charAt(-3)).toThrow
+ expect(() => "Scala.js".charAt(20)).toThrow
+ }
+
+ it("should respond to `codePointAt`") {
+ // String that starts with a BMP symbol
+ expect("abc\uD834\uDF06def".codePointAt(0)).toEqual(0x61)
+ expect("abc\uD834\uDF06def".codePointAt(3)).toEqual(0x1D306)
+ expect("abc\uD834\uDF06def".codePointAt(4)).toEqual(0xDF06)
+ expect("abc\uD834\uDF06def".codePointAt(5)).toEqual(0x64)
+
+ // String that starts with an astral symbol
+ expect("\uD834\uDF06def".codePointAt(0)).toEqual(0x1D306)
+ expect("\uD834\uDF06def".codePointAt(1)).toEqual(0xDF06)
+
+ // Lone high surrogates
+ expect("\uD834abc".codePointAt(0)).toEqual(0xD834)
+
+ // Lone low surrogates
+ expect("\uDF06abc".codePointAt(0)).toEqual(0xDF06)
+ }
+
+ it("should respond to `subSequence`") {
+ expect("Scala.js".subSequence(0, 5)).toBe("Scala")
+ expect("Scala.js".subSequence(6, 8)).toBe("js")
+ expect("Scala.js".subSequence(3, 5)).toBe("la")
+ expect("Scala.js".subSequence(3, 3)).toBe("")
+ }
+
+ it("should respond to `replace`") {
+ expect("Scala.js".replace(".js", "")).toBe("Scala")
+ expect("Scala.js".replace("JS", "")).toBe("Scala.js")
+ expect("aa".replace('a', 'b')).toBe("bb") // #25
+ }
+
+ it("should respond to `matches`") {
+ expect("Scala.js".matches(".*js")).toBeTruthy
+ expect("Scala.js".matches(".*JS")).toBeFalsy
+ }
+
+ it("should respond to `split`") {
+ expect("Scala.js".split("a").toJSArray).toEqual(js.Array("Sc", "l", ".js"))
+ expect("asdf".split("").toJSArray).toEqual(js.Array("","a","s","d","f"))
+ expect("asdf".split("", -1).toJSArray).toEqual(js.Array("","a","s","d","f", ""))
+ }
+
+ it("should respond to `split` with char as argument") {
+ expect("Scala.js".split('.').toJSArray).toEqual(js.Array("Scala","js"))
+ for (i <- 0 to 32) {
+ val c = i.toChar
+ expect(s"blah${c}blah${c}blah${c}blah".split(c).toJSArray).toEqual(
+ js.Array("blah", "blah", "blah", "blah"))
+ }
+ }
+
+ it("should respond to `toCharArray`") {
+ expect("Scala.js".toCharArray()(5)).toEqual('.')
+ }
+
+ it("should respond to `hashCode`") {
+ expect("a`jkxzcbfaslkjfbkj,289oinkasdf".hashCode()).toEqual(-1395193631)
+ expect("-34".hashCode()).toEqual(44878)
+ expect("".hashCode()).toEqual(0)
+ }
+
+ it("should respond to `getChars`") {
+ val trg = new Array[Char](10)
+ "asdf_foo".getChars(2, 6, trg, 3)
+ val exp = Array(0,0,0,'d','f','_','f',0,0,0)
+
+ for ((i,e) <- trg zip exp) {
+ expect(i).toEqual(e)
+ }
+ }
+
+
+ it("should respond to `concat`") {
+ expect("asdf".concat("fdsa")).toEqual("asdffdsa")
+ }
+
+ it("should respond to constructors") {
+ val charArray =
+ Array('a', 'b', 'c', 'd', '\uD834', '\uDF06', 'e', 'f', 'g', 'h', 'i')
+ val codePointArray =
+ Array(65, 0x1D306, 67, 68, 0xD834, 69, 72, 0xDF06)
+
+ expect(new String()).toEqual("")
+ expect(new String(charArray)).toEqual("abcd\uD834\uDF06efghi")
+ expect(new String(charArray, 3, 5)).toEqual("d\uD834\uDF06ef")
+ expect(new String(codePointArray, 1, 5)).toEqual("\uD834\uDF06CD\uD834E")
+ expect(new String("foo")).toEqual("foo")
+ expect(new String(new StringBuffer("buffer-foo"))).toEqual("buffer-foo")
+ expect(new String(new java.lang.StringBuilder("builder-foo"))
+ ).toEqual("builder-foo")
+ }
+
+ it("should provide `format`") {
+ expect(String.format("%d", new Integer(5))).toEqual("5")
+ expect(String.format("%05d", new Integer(5))).toEqual("00005")
+ expect(String.format("%0#5x", new Integer(5))).toEqual("0x005")
+ expect(String.format("%#5x", new Integer(5))).toEqual(" 0x5")
+ expect(String.format("%#5X", new Integer(5))).toEqual(" 0X5")
+ expect(String.format("%5d", new Integer(-10))).toEqual(" -10")
+ expect(String.format("%05d", new Integer(-10))).toEqual("-0010")
+ expect(String.format("%x", new Integer(-3))).toEqual("fffffffd")
+ expect(String.format("%x", new java.lang.Byte(-4.toByte))).toEqual("fffffffc")
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/SystemTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/SystemTest.scala
new file mode 100644
index 0000000..4435e00
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/SystemTest.scala
@@ -0,0 +1,118 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import language.implicitConversions
+
+import scala.scalajs.js
+import scala.scalajs.js.JSConverters._
+
+import org.scalajs.jasminetest.JasmineTest
+
+object SystemTest extends JasmineTest {
+
+ // Just in here, we allow ourselves to do this
+ implicit def array2jsArray[T](arr: Array[T]): js.Array[T] = arr.toJSArray
+
+ describe("java.lang.System") {
+
+ it("should respond to `arraycopy`") {
+ val object0 = Array[Any]("[", "b", "c", "d", "e", "f", "]")
+ val object1 = Array[Any](() => true, 1, "2", '3', 4.0, true, object0)
+
+ System.arraycopy(object1, 1, object0, 1, 5)
+ expect(object0.mkString).toEqual("[1234true]")
+
+ val string0 = Array("a", "b", "c", "d", "e", "f")
+ val string1 = Array("1", "2", "3", "4")
+
+ System.arraycopy(string1, 0, string0, 3, 3)
+ expect(string0.mkString).toEqual("abc123")
+
+ val ab01Chars = Array("ab".toCharArray, "01".toCharArray)
+ val chars = new Array[Array[Char]](32)
+ System.arraycopy(ab01Chars, 0, chars, 0, 2)
+ for (i <- Seq(0, 2, 4, 8, 16)) {
+ System.arraycopy(chars, i / 4, chars, i, i)
+ }
+
+ expect(chars.filter(_ == null).length).toEqual(12)
+ expect(chars.filter(_ != null).map(_.mkString).mkString).
+ toEqual("ab01ab0101ab01ab0101ab0101ab01ab0101ab01")
+ }
+
+ it("should respond to `arraycopy` with range overlaps for the same array") {
+ val array = new Array[Int](10)
+
+ for (i <- 1 to 6) {
+ array(i) = i
+ }
+
+ expect(array).toEqual(Array(0, 1, 2, 3, 4, 5, 6, 0, 0, 0))
+ System.arraycopy(array, 0, array, 3, 7)
+ expect(array).toEqual(Array(0, 1, 2, 0, 1, 2, 3, 4, 5, 6))
+
+ System.arraycopy(array, 0, array, 1, 0)
+ expect(array).toEqual(Array(0, 1, 2, 0, 1, 2, 3, 4, 5, 6))
+
+ System.arraycopy(array, 0, array, 1, 9)
+ expect(array).toEqual(Array(0, 0, 1, 2, 0, 1, 2, 3, 4, 5))
+
+ System.arraycopy(array, 1, array, 0, 9)
+ expect(array).toEqual(Array(0, 1, 2, 0, 1, 2, 3, 4, 5, 5))
+
+ System.arraycopy(array, 0, array, 0, 10)
+ expect(array).toEqual(Array(0, 1, 2, 0, 1, 2, 3, 4, 5, 5))
+
+ val reversed = array.reverse
+ System.arraycopy(reversed, 5, array, 5, 5)
+ expect(array).toEqual(Array(0, 1, 2, 0, 1, 1, 0, 2, 1, 0))
+ }
+
+ it("should provide identityHashCode") {
+ /* This test is more restrictive than the spec, but we know our
+ * implementation will always pass the test.
+ */
+ class HasIDHashCode
+
+ val x1 = new HasIDHashCode
+ val x2 = new HasIDHashCode
+ val x1FirstHash = x1.hashCode()
+ expect(x1.hashCode()).toEqual(x1FirstHash)
+ expect(x1.hashCode()).not.toEqual(x2.hashCode())
+ expect(x1.hashCode()).toEqual(x1FirstHash)
+
+ expect(System.identityHashCode(x1)).toEqual(x1FirstHash)
+ expect(System.identityHashCode(x2)).toEqual(x2.hashCode())
+ }
+
+ it("identityHashCode should by-pass .hashCode()") {
+ val list1 = List(1, 3, 5)
+ val list2 = List(1, 3, 5)
+ expect(list1 == list2).toBeTruthy
+ expect(list1.hashCode()).toEqual(list2.hashCode())
+ expect(System.identityHashCode(list1)).not.toEqual(System.identityHashCode(list2))
+ }
+
+ it("identityHashCode(null)") {
+ expect(System.identityHashCode(null)).toEqual(0)
+ }
+
+ it("identityHashCode of values implemented as JS primitives") {
+ expect(System.identityHashCode("foo")).toEqual("foo".hashCode())
+ expect(System.identityHashCode("")).toEqual("".hashCode())
+
+ expect(System.identityHashCode(false)).toEqual(false.hashCode())
+ expect(System.identityHashCode(true)).toEqual(true.hashCode())
+
+ expect(System.identityHashCode(5)).toEqual(5.hashCode())
+ expect(System.identityHashCode(789456)).toEqual(789456.hashCode())
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ThrowablesTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ThrowablesTest.scala
new file mode 100644
index 0000000..7e53975
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/ThrowablesTest.scala
@@ -0,0 +1,90 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import org.scalajs.jasminetest.JasmineTest
+
+object ThrowablesTest extends JasmineTest {
+ describe("java.lang.Throwables, java.util.Throwables") {
+
+ it("should define all java.lang and java.util Errors/Exceptions") {
+ new ArithmeticException()
+ new ArrayIndexOutOfBoundsException()
+ new ArrayStoreException()
+ new ClassCastException()
+ new ClassNotFoundException()
+ new CloneNotSupportedException()
+ // Needs an instance of java.lang.Enum.
+ // import scala.language.existentials
+ // new EnumConstantNotPresentException(null.asInstanceOf[Class[_ <: Enum[T] forSome { type T <: Enum[T] }]], null)
+ new Exception()
+ new IllegalAccessException()
+ new IllegalArgumentException()
+ new IllegalMonitorStateException()
+ new IllegalStateException()
+ new IllegalThreadStateException()
+ new IndexOutOfBoundsException()
+ new InstantiationException()
+ new InterruptedException()
+ new NegativeArraySizeException()
+ new NoSuchFieldException()
+ new NoSuchMethodException()
+ new NullPointerException()
+ new NumberFormatException()
+ new RuntimeException()
+ new SecurityException()
+ new StringIndexOutOfBoundsException()
+ new TypeNotPresentException(null, null)
+ new UnsupportedOperationException()
+ new AbstractMethodError()
+ new AssertionError()
+ new ClassCircularityError()
+ new ClassFormatError()
+ new Error()
+ new ExceptionInInitializerError()
+ new IllegalAccessError()
+ new IncompatibleClassChangeError()
+ new InstantiationError()
+ new InternalError()
+ new LinkageError()
+ new NoClassDefFoundError()
+ new NoSuchFieldError()
+ new NoSuchMethodError()
+ new OutOfMemoryError()
+ new StackOverflowError()
+ new UnknownError()
+ new UnsatisfiedLinkError()
+ new UnsupportedClassVersionError()
+ new VerifyError()
+ new VirtualMachineError() {}
+
+ import java.util._
+ new ServiceConfigurationError("")
+ new ConcurrentModificationException()
+ new DuplicateFormatFlagsException("")
+ new EmptyStackException()
+ new FormatFlagsConversionMismatchException("", '\u0000')
+ new FormatterClosedException()
+ new IllegalFormatCodePointException(0)
+ new IllegalFormatConversionException('\u0000', new Object().getClass)
+ new IllegalFormatFlagsException("")
+ new IllegalFormatPrecisionException(0)
+ new IllegalFormatWidthException(0)
+ new InputMismatchException()
+ // Needs java.io.IOException.
+ // new InvalidPropertiesFormatException("")
+ new MissingFormatArgumentException("")
+ new MissingFormatWidthException("")
+ new MissingResourceException(null, null, null)
+ new NoSuchElementException()
+ new TooManyListenersException()
+ new UnknownFormatConversionException("")
+ new UnknownFormatFlagsException("")
+ }
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/TimeUnitTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/TimeUnitTest.scala
new file mode 100644
index 0000000..79cd8a8
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/TimeUnitTest.scala
@@ -0,0 +1,135 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+import java.util.concurrent.TimeUnit
+
+object TimeUnitTest extends JasmineTest {
+
+ describe("java.util.concurrent.TimeUnit") {
+
+ it("should respond to `toNanos`") {
+ expect(TimeUnit.NANOSECONDS.toNanos(42L)).toEqual(42L)
+ expect(TimeUnit.MICROSECONDS.toNanos(42L)).toEqual(42000L)
+ expect(TimeUnit.MILLISECONDS.toNanos(42L)).toEqual(42000000L)
+ expect(TimeUnit.SECONDS.toNanos(42L)).toEqual(42000000000L)
+ expect(TimeUnit.MINUTES.toNanos(42L)).toEqual(2520000000000L)
+ expect(TimeUnit.HOURS.toNanos(42L)).toEqual(151200000000000L)
+ expect(TimeUnit.DAYS.toNanos(42L)).toEqual(3628800000000000L)
+ }
+
+ it("should respond to `toMicros`") {
+ expect(TimeUnit.NANOSECONDS.toMicros(42L)).toEqual(0L)
+ expect(TimeUnit.NANOSECONDS.toMicros(42123L)).toEqual(42L)
+ expect(TimeUnit.MICROSECONDS.toMicros(42L)).toEqual(42L)
+ expect(TimeUnit.MILLISECONDS.toMicros(42L)).toEqual(42000L)
+ expect(TimeUnit.SECONDS.toMicros(42L)).toEqual(42000000L)
+ expect(TimeUnit.MINUTES.toMicros(42L)).toEqual(2520000000L)
+ expect(TimeUnit.HOURS.toMicros(42L)).toEqual(151200000000L)
+ expect(TimeUnit.DAYS.toMicros(42L)).toEqual(3628800000000L)
+ }
+
+ it("should respond to `toMillis`") {
+ expect(TimeUnit.NANOSECONDS.toMillis(42L)).toEqual(0L)
+ expect(TimeUnit.NANOSECONDS.toMillis(42000123L)).toEqual(42L)
+ expect(TimeUnit.MICROSECONDS.toMillis(42L)).toEqual(0L)
+ expect(TimeUnit.MICROSECONDS.toMillis(42123L)).toEqual(42L)
+ expect(TimeUnit.MILLISECONDS.toMillis(42L)).toEqual(42L)
+ expect(TimeUnit.SECONDS.toMillis(42L)).toEqual(42000L)
+ expect(TimeUnit.MINUTES.toMillis(42L)).toEqual(2520000L)
+ expect(TimeUnit.HOURS.toMillis(42L)).toEqual(151200000L)
+ expect(TimeUnit.DAYS.toMillis(42L)).toEqual(3628800000L)
+ }
+
+ it("should respond to `toSeconds`") {
+ expect(TimeUnit.NANOSECONDS.toSeconds(42L)).toEqual(0L)
+ expect(TimeUnit.NANOSECONDS.toSeconds(42000000123L)).toEqual(42L)
+ expect(TimeUnit.MICROSECONDS.toSeconds(42L)).toEqual(0L)
+ expect(TimeUnit.MICROSECONDS.toSeconds(42000123L)).toEqual(42L)
+ expect(TimeUnit.MILLISECONDS.toSeconds(42L)).toEqual(0L)
+ expect(TimeUnit.MILLISECONDS.toSeconds(42123L)).toEqual(42L)
+ expect(TimeUnit.SECONDS.toSeconds(42L)).toEqual(42L)
+ expect(TimeUnit.MINUTES.toSeconds(42L)).toEqual(2520L)
+ expect(TimeUnit.HOURS.toSeconds(42L)).toEqual(151200L)
+ expect(TimeUnit.DAYS.toSeconds(42L)).toEqual(3628800L)
+ }
+
+ it("should respond to `toMinutes`") {
+ expect(TimeUnit.NANOSECONDS.toMinutes(42L)).toEqual(0L)
+ expect(TimeUnit.NANOSECONDS.toMinutes(2520000007380L)).toEqual(42L)
+ expect(TimeUnit.MICROSECONDS.toMinutes(42L)).toEqual(0L)
+ expect(TimeUnit.MICROSECONDS.toMinutes(2520007380L)).toEqual(42L)
+ expect(TimeUnit.MILLISECONDS.toMinutes(42L)).toEqual(0L)
+ expect(TimeUnit.MILLISECONDS.toMinutes(2520738L)).toEqual(42L)
+ expect(TimeUnit.SECONDS.toMinutes(42L)).toEqual(0L)
+ expect(TimeUnit.SECONDS.toMinutes(2520L)).toEqual(42L)
+ expect(TimeUnit.MINUTES.toMinutes(42L)).toEqual(42L)
+ expect(TimeUnit.HOURS.toMinutes(42L)).toEqual(2520L)
+ expect(TimeUnit.DAYS.toMinutes(42L)).toEqual(60480L)
+ }
+
+ it("should respond to `toHours`") {
+ expect(TimeUnit.NANOSECONDS.toHours(42L)).toEqual(0L)
+ expect(TimeUnit.NANOSECONDS.toHours(151200000442800L)).toEqual(42L)
+ expect(TimeUnit.MICROSECONDS.toHours(42L)).toEqual(0L)
+ expect(TimeUnit.MICROSECONDS.toHours(151200442800L)).toEqual(42L)
+ expect(TimeUnit.MILLISECONDS.toHours(42L)).toEqual(0L)
+ expect(TimeUnit.MILLISECONDS.toHours(151244280L)).toEqual(42L)
+ expect(TimeUnit.SECONDS.toHours(42L)).toEqual(0L)
+ expect(TimeUnit.SECONDS.toHours(151200L)).toEqual(42L)
+ expect(TimeUnit.MINUTES.toHours(42L)).toEqual(0L)
+ expect(TimeUnit.MINUTES.toHours(2520L)).toEqual(42L)
+ expect(TimeUnit.HOURS.toHours(42L)).toEqual(42L)
+ expect(TimeUnit.DAYS.toHours(42L)).toEqual(1008L)
+ }
+
+ it("should respond to `toDays`") {
+ expect(TimeUnit.NANOSECONDS.toDays(42L)).toEqual(0L)
+ expect(TimeUnit.NANOSECONDS.toDays(3628800010627200L)).toEqual(42L)
+ expect(TimeUnit.MICROSECONDS.toDays(42L)).toEqual(0L)
+ expect(TimeUnit.MICROSECONDS.toDays(3628810627200L)).toEqual(42L)
+ expect(TimeUnit.MILLISECONDS.toDays(42L)).toEqual(0L)
+ expect(TimeUnit.MILLISECONDS.toDays(3629862720L)).toEqual(42L)
+ expect(TimeUnit.SECONDS.toDays(42L)).toEqual(0L)
+ expect(TimeUnit.SECONDS.toDays(3628800L)).toEqual(42L)
+ expect(TimeUnit.MINUTES.toDays(42L)).toEqual(0L)
+ expect(TimeUnit.MINUTES.toDays(60480L)).toEqual(42L)
+ expect(TimeUnit.HOURS.toDays(42L)).toEqual(1L)
+ expect(TimeUnit.HOURS.toDays(1008L)).toEqual(42L)
+ expect(TimeUnit.DAYS.toDays(42L)).toEqual(42L)
+ }
+
+ it("should respond to `values`") {
+ val values = TimeUnit.values()
+ expect(values.length).toEqual(7)
+ expectTimeUnit(values(0), TimeUnit.NANOSECONDS)
+ expectTimeUnit(values(1), TimeUnit.MICROSECONDS)
+ expectTimeUnit(values(2), TimeUnit.MILLISECONDS)
+ expectTimeUnit(values(3), TimeUnit.SECONDS)
+ expectTimeUnit(values(4), TimeUnit.MINUTES)
+ expectTimeUnit(values(5), TimeUnit.HOURS)
+ expectTimeUnit(values(6), TimeUnit.DAYS)
+ }
+
+ it("should respond to `valueOf`") {
+ expectTimeUnit(TimeUnit.valueOf("NANOSECONDS"), TimeUnit.NANOSECONDS)
+ expectTimeUnit(TimeUnit.valueOf("MICROSECONDS"), TimeUnit.MICROSECONDS)
+ expectTimeUnit(TimeUnit.valueOf("MILLISECONDS"), TimeUnit.MILLISECONDS)
+ expectTimeUnit(TimeUnit.valueOf("SECONDS"), TimeUnit.SECONDS)
+ expectTimeUnit(TimeUnit.valueOf("MINUTES"), TimeUnit.MINUTES)
+ expectTimeUnit(TimeUnit.valueOf("HOURS"), TimeUnit.HOURS)
+ expectTimeUnit(TimeUnit.valueOf("DAYS"), TimeUnit.DAYS)
+ }
+
+ }
+
+ def expectTimeUnit(actual: TimeUnit, expected: TimeUnit): Unit =
+ expect(actual.asInstanceOf[js.Any]).toEqual(expected.asInstanceOf[js.Any])
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/URITest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/URITest.scala
new file mode 100644
index 0000000..65a049f
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/URITest.scala
@@ -0,0 +1,312 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+import java.net.URI
+
+object URITest extends JasmineTest {
+
+ def expectURI(uri: URI, isAbsolute: Boolean, isOpaque: Boolean)(
+ authority: String = null, fragment: String = null,
+ host: String = null, path: String = null, port: Int = -1,
+ query: String = null, scheme: String = null, userInfo: String = null,
+ schemeSpecificPart: String = null)(rawAuthority: String = authority,
+ rawFragment: String = fragment, rawPath: String = path,
+ rawQuery: String = query, rawUserInfo: String = userInfo,
+ rawSchemeSpecificPart: String = schemeSpecificPart): Unit = {
+
+ expect(uri.getAuthority()).toBe(authority)
+ expect(uri.getFragment()).toBe(fragment)
+ expect(uri.getHost()).toBe(host)
+ expect(uri.getPath()).toBe(path)
+ expect(uri.getPort()).toBe(port)
+ expect(uri.getQuery()).toBe(query)
+ expect(uri.getRawAuthority()).toBe(rawAuthority)
+ expect(uri.getRawFragment()).toBe(rawFragment)
+ expect(uri.getRawPath()).toBe(rawPath)
+ expect(uri.getRawQuery()).toBe(rawQuery)
+ expect(uri.getRawSchemeSpecificPart()).toBe(rawSchemeSpecificPart)
+ expect(uri.getRawUserInfo()).toBe(rawUserInfo)
+ expect(uri.getScheme()).toBe(scheme)
+ expect(uri.getSchemeSpecificPart()).toBe(schemeSpecificPart)
+ expect(uri.getUserInfo()).toBe(userInfo)
+ expect(uri.isAbsolute()).toBe(isAbsolute)
+ expect(uri.isOpaque()).toBe(isOpaque)
+
+ }
+
+ describe("java.net.URI") {
+
+ it("should parse vanilla absolute URIs") {
+ expectURI(new URI("http://java.sun.com/j2se/1.3/"), true, false)(
+ scheme = "http",
+ host = "java.sun.com",
+ path = "/j2se/1.3/",
+ authority = "java.sun.com",
+ schemeSpecificPart = "//java.sun.com/j2se/1.3/")()
+ }
+
+ it("should parse absolute URIs with IPv6") {
+ val uri = new URI("http://hans@[ffff::0:128.4.5.3]:345/~hans/")
+ expectURI(uri, true, false)(
+ scheme = "http",
+ host = "[ffff::0:128.4.5.3]",
+ userInfo = "hans",
+ port = 345,
+ path = "/~hans/",
+ authority = "hans@[ffff::0:128.4.5.3]:345",
+ schemeSpecificPart = "//hans@[ffff::0:128.4.5.3]:345/~hans/"
+ )()
+ }
+
+ it("should parse absolute URIs without authority") {
+ expectURI(new URI("file:/~/calendar"), true, false)(
+ scheme = "file",
+ path = "/~/calendar",
+ schemeSpecificPart = "/~/calendar")()
+ }
+
+ it("should parse absolute URIs with empty authority") {
+ expectURI(new URI("file:///~/calendar"), true, false)(
+ authority = "",
+ scheme = "file",
+ path = "/~/calendar",
+ schemeSpecificPart = "///~/calendar")()
+ }
+
+ it("should parse opaque URIs") {
+ expectURI(new URI("mailto:java-net@java.sun.com"), true, true)(
+ scheme = "mailto",
+ schemeSpecificPart = "java-net@java.sun.com")()
+
+ expectURI(new URI("news:comp.lang.java"), true, true)(
+ scheme = "news",
+ schemeSpecificPart = "comp.lang.java")()
+
+ expectURI(new URI("urn:isbn:096139210x"), true, true)(
+ scheme = "urn",
+ schemeSpecificPart = "isbn:096139210x")()
+ }
+
+ it("should parse relative URIs") {
+ expectURI(new URI("docs/guide/collections/designfaq.html#28"), false, false)(
+ path = "docs/guide/collections/designfaq.html",
+ fragment = "28",
+ schemeSpecificPart = "docs/guide/collections/designfaq.html#28"
+ )()
+ expectURI(new URI("../../../demo/jfc/SwingSet2/src/SwingSet2.java"), false, false)(
+ path = "../../../demo/jfc/SwingSet2/src/SwingSet2.java",
+ schemeSpecificPart = "../../../demo/jfc/SwingSet2/src/SwingSet2.java"
+ )()
+ }
+
+ it("should parse relative URIs with IPv4") {
+ expectURI(new URI("//123.5.6.3:45/bar"), false, false)(
+ authority = "123.5.6.3:45",
+ host = "123.5.6.3",
+ port = 45,
+ path = "/bar",
+ schemeSpecificPart = "//123.5.6.3:45/bar"
+ )()
+ }
+
+ it("should parse relative URIs with registry-based authority") {
+ expectURI(new URI("//foo:bar"), false, false)(
+ authority = "foo:bar",
+ schemeSpecificPart = "//foo:bar"
+ )()
+ }
+
+ it("should parse relative URIs with escapes") {
+ expectURI(new URI("//ma%5dx:secret@example.com:8000/foo"), false, false)(
+ authority = "ma]x:secret@example.com:8000",
+ userInfo = "ma]x:secret",
+ host = "example.com",
+ port = 8000,
+ path = "/foo",
+ schemeSpecificPart = "//ma]x:secret@example.com:8000/foo")(
+ rawUserInfo = "ma%5dx:secret",
+ rawAuthority = "ma%5dx:secret@example.com:8000",
+ rawSchemeSpecificPart = "//ma%5dx:secret@example.com:8000/foo")
+ }
+
+ it("should parse relative URIs with fragment only") {
+ expectURI(new URI("#foo"), false, false)(
+ fragment = "foo",
+ path = "",
+ schemeSpecificPart = "#foo"
+ )()
+ }
+
+ it("should provide compareTo") {
+ val x = new URI("http://example.com/asdf%6a")
+ val y = new URI("http://example.com/asdf%6A")
+ val z = new URI("http://example.com/asdfj")
+ val rel = new URI("/foo/bar")
+
+ expect(x.compareTo(y)).toBeGreaterThan(0)
+ expect(x.compareTo(z)).toBeLessThan(0)
+ expect(y.compareTo(z)).toBeLessThan(0)
+ expect(x.compareTo(x)).toBe(0)
+ expect(y.compareTo(y)).toBe(0)
+ expect(z.compareTo(z)).toBe(0)
+ expect(x.compareTo(rel)).toBeGreaterThan(0)
+ expect(y.compareTo(rel)).toBeGreaterThan(0)
+ expect(z.compareTo(rel)).toBeGreaterThan(0)
+ expect(rel.compareTo(rel)).toBe(0)
+ }
+
+ it("should provide equals") {
+ val x = new URI("http://example.com/asdf%6a")
+ val y = new URI("http://example.com/asdf%6A")
+ val z = new URI("http://example.com/asdfj")
+
+ expect(x == y).toBeTruthy
+ expect(x == z).toBeFalsy
+ expect(y == z).toBeFalsy
+ expect(x == x).toBeTruthy
+ expect(y == y).toBeTruthy
+ expect(z == z).toBeTruthy
+
+ expect(new URI("foo:helloWorld%6b%6C") == new URI("foo:helloWorld%6C%6b"))
+ }
+
+ it("should provide normalize") {
+ expectURI(new URI("http://example.com/../asef/../../").normalize, true, false)(
+ scheme = "http",
+ host = "example.com",
+ authority = "example.com",
+ path = "/../../",
+ schemeSpecificPart = "//example.com/../../")()
+ expectURI(new URI("http://example.com/../as/./ef/foo/../../").normalize, true, false)(
+ scheme = "http",
+ host = "example.com",
+ authority = "example.com",
+ path = "/../as/",
+ schemeSpecificPart = "//example.com/../as/")()
+ expectURI(new URI("bar/../fo:o/./bar").normalize, false, false)(
+ path = "./fo:o/bar",
+ schemeSpecificPart = "./fo:o/bar")()
+ expectURI(new URI("bar/..//fo:o//./bar").normalize, false, false)(
+ path = "./fo:o/bar",
+ schemeSpecificPart = "./fo:o/bar")()
+
+ val x = new URI("http://www.example.com/foo/bar")
+ expect(x.normalize eq x).toBeTruthy
+ }
+
+ it("should provide resolve - JavaDoc examples") {
+ val base = "http://java.sun.com/j2se/1.3/"
+ val relative1 = "docs/guide/collections/designfaq.html#28"
+ val resolved1 =
+ "http://java.sun.com/j2se/1.3/docs/guide/collections/designfaq.html#28"
+ val relative2 = "../../../demo/jfc/SwingSet2/src/SwingSet2.java"
+ val resolved2 =
+ "http://java.sun.com/j2se/1.3/demo/jfc/SwingSet2/src/SwingSet2.java"
+
+ expect(new URI(base).resolve(relative1).toString).toEqual(resolved1)
+ expect(new URI(resolved1).resolve(relative2).toString).toEqual(resolved2)
+ }
+
+ it("should provide resolve - RFC2396 examples") {
+ val base = new URI("http://a/b/c/d;p?q")
+ def resTest(ref: String, trg: String) =
+ expect(base.resolve(ref).toString).toEqual(trg)
+
+ // Normal examples
+ resTest("g:h" , "g:h")
+ resTest("g" , "http://a/b/c/g")
+ resTest("./g" , "http://a/b/c/g")
+ resTest("g/" , "http://a/b/c/g/")
+ resTest("/g" , "http://a/g")
+ resTest("//g" , "http://g")
+ resTest("?y" , "http://a/b/c/?y")
+ resTest("g?y" , "http://a/b/c/g?y")
+ resTest("#s" , "http://a/b/c/d;p?q#s")
+ resTest("g#s" , "http://a/b/c/g#s")
+ resTest("g?y#s" , "http://a/b/c/g?y#s")
+ resTest(";x" , "http://a/b/c/;x")
+ resTest("g;x" , "http://a/b/c/g;x")
+ resTest("g;x?y#s", "http://a/b/c/g;x?y#s")
+ resTest("." , "http://a/b/c/")
+ resTest("./" , "http://a/b/c/")
+ resTest(".." , "http://a/b/")
+ resTest("../" , "http://a/b/")
+ resTest("../g" , "http://a/b/g")
+ resTest("../.." , "http://a/")
+ resTest("../../" , "http://a/")
+ resTest("../../g", "http://a/g")
+
+ // Abnormal examples
+ resTest("../../../g" , "http://a/../g")
+ resTest("../../../../g", "http://a/../../g")
+ resTest("/./g" , "http://a/./g")
+ resTest("/../g" , "http://a/../g")
+ resTest("g." , "http://a/b/c/g.")
+ resTest(".g" , "http://a/b/c/.g")
+ resTest("g.." , "http://a/b/c/g..")
+ resTest("..g" , "http://a/b/c/..g")
+ resTest("./../g" , "http://a/b/g")
+ resTest("./g/." , "http://a/b/c/g/")
+ resTest("g/./h" , "http://a/b/c/g/h")
+ resTest("g/../h" , "http://a/b/c/h")
+ resTest("g;x=1/./y" , "http://a/b/c/g;x=1/y")
+ resTest("g;x=1/../y" , "http://a/b/c/y")
+ resTest("g?y/./x" , "http://a/b/c/g?y/./x")
+ resTest("g?y/../x" , "http://a/b/c/g?y/../x")
+ resTest("g#s/./x" , "http://a/b/c/g#s/./x")
+ resTest("g#s/../x" , "http://a/b/c/g#s/../x")
+ resTest("http:g" , "http:g")
+ }
+
+ it("should provide normalize - examples derived from RFC relativize") {
+ expectURI(new URI("http://a/b/c/..").normalize, true, false)(
+ scheme = "http",
+ host = "a",
+ authority = "a",
+ path = "/b/",
+ schemeSpecificPart = "//a/b/")()
+
+ expectURI(new URI("http://a/b/c/.").normalize, true, false)(
+ scheme = "http",
+ host = "a",
+ authority = "a",
+ path = "/b/c/",
+ schemeSpecificPart = "//a/b/c/")()
+ }
+
+ it("should provide relativize") {
+ val x = new URI("http://f%4Aoo@asdf/a")
+ val y = new URI("http://fJoo@asdf/a/b/")
+ val z = new URI("http://f%4aoo@asdf/a/b/")
+ expect(x.relativize(y) eq y).toBeTruthy
+ expect(x.relativize(z).toString()).toEqual("b/")
+
+ def relTest(base: String, trg: String, exp: String) =
+ expect(new URI(base).relativize(new URI(trg)).toString()).toEqual(exp)
+
+ relTest("http://a.ch/a", "http://a.ch/a/b", "b")
+ relTest("http://a.ch/a/", "http://a.ch/a/b", "b")
+ relTest("https://a.ch/a", "http://a.ch/a/b", "http://a.ch/a/b")
+ relTest("/a/b/c", "/a/b/c/d/e", "d/e")
+ relTest("/a/b/c/", "/a/b/c/d/e", "d/e")
+ relTest("/a/b/c/", "/a/b/c/foo:e/d", "foo:e/d") // see bug JDK-7037120
+ relTest("../a/b", "../a/b/c", "c")
+ }
+
+ it("should provide hashCode") {
+ expect(new URI("http://example.com/asdf%6a").hashCode).toEqual(
+ new URI("http://example.com/asdf%6A").hashCode)
+ }
+
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/UUIDTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/UUIDTest.scala
new file mode 100644
index 0000000..b22fe02
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/javalib/UUIDTest.scala
@@ -0,0 +1,180 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.javalib
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+import java.util.UUID
+
+object UUIDTest extends JasmineTest {
+ describe("java.util.UUID") {
+ it("constructor") {
+ val uuid = new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf6L)
+ expect(uuid.getMostSignificantBits() == 0xf81d4fae7dec11d0L).toBeTruthy
+ expect(uuid.getLeastSignificantBits() == 0xa76500a0c91e6bf6L).toBeTruthy
+ expect(uuid.variant()).toEqual(2)
+ expect(uuid.version()).toEqual(1)
+ expect(uuid.timestamp() == 0x1d07decf81d4faeL).toBeTruthy
+ expect(uuid.clockSequence()).toEqual(0x2765)
+ expect(uuid.node() == 0xA0C91E6BF6L).toBeTruthy
+ }
+
+ it("getLeastSignificantBits") {
+ expect(new UUID(0L, 0L).getLeastSignificantBits() == 0L).toBeTruthy
+ expect(new UUID(0L, Long.MinValue).getLeastSignificantBits() == Long.MinValue).toBeTruthy
+ expect(new UUID(0L, Long.MaxValue).getLeastSignificantBits() == Long.MaxValue).toBeTruthy
+ }
+
+ it("getMostSignificantBits") {
+ expect(new UUID(0L, 0L).getMostSignificantBits() == 0L).toBeTruthy
+ expect(new UUID(Long.MinValue, 0L).getMostSignificantBits() == Long.MinValue).toBeTruthy
+ expect(new UUID(Long.MaxValue, 0L).getMostSignificantBits() == Long.MaxValue).toBeTruthy
+ }
+
+ it("version") {
+ expect(new UUID(0L, 0L).version()).toEqual(0)
+ expect(new UUID(0x0000000000001000L, 0L).version()).toEqual(1)
+ expect(new UUID(0x00000000000f2f00L, 0L).version()).toEqual(2)
+ }
+
+ it("variant") {
+ expect(new UUID(0L, 0L).variant()).toEqual(0)
+ expect(new UUID(0L, 0x7000000000000000L).variant()).toEqual(0)
+ expect(new UUID(0L, 0x3ff0000000000000L).variant()).toEqual(0)
+ expect(new UUID(0L, 0x1ff0000000000000L).variant()).toEqual(0)
+
+ expect(new UUID(0L, 0x8000000000000000L).variant()).toEqual(2)
+ expect(new UUID(0L, 0xb000000000000000L).variant()).toEqual(2)
+ expect(new UUID(0L, 0xaff0000000000000L).variant()).toEqual(2)
+ expect(new UUID(0L, 0x9ff0000000000000L).variant()).toEqual(2)
+
+ expect(new UUID(0L, 0xc000000000000000L).variant()).toEqual(6)
+ expect(new UUID(0L, 0xdf00000000000000L).variant()).toEqual(6)
+ }
+
+ it("timestamp") {
+ expect(new UUID(0x0000000000001000L,
+ 0x8000000000000000L).timestamp() == 0L).toBeTruthy
+ expect(new UUID(0x7777777755551333L,
+ 0x8000000000000000L).timestamp() == 0x333555577777777L).toBeTruthy
+
+ expect(() => new UUID(0x0000000000000000L, 0x8000000000000000L).timestamp()).toThrow
+ expect(() => new UUID(0x0000000000002000L, 0x8000000000000000L).timestamp()).toThrow
+ }
+
+ it("clockSequence") {
+ expect(new UUID(0x0000000000001000L, 0x8000000000000000L).clockSequence()).toEqual(0)
+ expect(new UUID(0x0000000000001000L, 0x8fff000000000000L).clockSequence()).toEqual(0x0fff)
+ expect(new UUID(0x0000000000001000L, 0xBfff000000000000L).clockSequence()).toEqual(0x3fff)
+
+ expect(() => new UUID(0x0000000000000000L, 0x8000000000000000L).clockSequence()).toThrow
+ expect(() => new UUID(0x0000000000002000L, 0x8000000000000000L).clockSequence()).toThrow
+ }
+
+ it("node") {
+ expect(new UUID(0x0000000000001000L, 0x8000000000000000L).node() == 0L).toBeTruthy
+ expect(new UUID(0x0000000000001000L, 0x8000ffffffffffffL).node() == 0xffffffffffffL).toBeTruthy
+
+ expect(() => new UUID(0x0000000000000000L, 0x8000000000000000L).node()).toThrow
+ expect(() => new UUID(0x0000000000002000L, 0x8000000000000000L).node()).toThrow
+ }
+
+ it("compareTo") {
+ val uuid0101 = new UUID(1L, 1L)
+ val uuid0111 = new UUID(1L, 0x100000001L)
+ val uuid1000 = new UUID(0x100000000L, 0L)
+
+ expect(uuid0101.compareTo(uuid0101)).toEqual(0)
+ expect(uuid0111.compareTo(uuid0111)).toEqual(0)
+ expect(uuid1000.compareTo(uuid1000)).toEqual(0)
+
+ expect(uuid0101.compareTo(uuid0111)).toBeLessThan(0)
+ expect(uuid0101.compareTo(uuid1000)).toBeLessThan(0)
+ expect(uuid0111.compareTo(uuid1000)).toBeLessThan(0)
+
+ expect(uuid0111.compareTo(uuid0101)).toBeGreaterThan(0)
+ expect(uuid1000.compareTo(uuid0101)).toBeGreaterThan(0)
+ expect(uuid1000.compareTo(uuid0111)).toBeGreaterThan(0)
+ }
+
+ it("hashCode") {
+ expect(new UUID(0L, 0L).hashCode()).toEqual(0)
+ expect(new UUID(123L, 123L).hashCode()).toEqual(new UUID(123L, 123L).hashCode())
+ }
+
+ it("equals") {
+ val uuid1 = new UUID(0L, 0L)
+ expect(uuid1.equals(uuid1)).toBeTruthy
+ expect(uuid1.equals(null)).toBeFalsy
+ expect(uuid1.equals("something else")).toBeFalsy
+
+ val uuid2 = new UUID(0L, 0L)
+ expect(uuid1.equals(uuid2)).toBeTruthy
+
+ val uuid3 = new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf6L)
+ val uuid4 = new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf6L)
+ expect(uuid3.equals(uuid4)).toBeTruthy
+ expect(uuid3.equals(uuid1)).toBeFalsy
+
+ expect(uuid3.equals(new UUID(0x781d4fae7dec11d0L, 0xa76500a0c91e6bf6L))).toBeFalsy
+ expect(uuid3.equals(new UUID(0xf81d4fae7dec11d1L, 0xa76500a0c91e6bf6L))).toBeFalsy
+ expect(uuid3.equals(new UUID(0xf81d4fae7dec11d0L, 0xa76530a0c91e6bf6L))).toBeFalsy
+ expect(uuid3.equals(new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6cf6L))).toBeFalsy
+ }
+
+ it("toString") {
+ expect(new UUID(0xf81d4fae7dec11d0L,
+ 0xa76500a0c91e6bf6L).toString()).toEqual("f81d4fae-7dec-11d0-a765-00a0c91e6bf6")
+ expect(new UUID(0x0000000000001000L,
+ 0x8000000000000000L).toString()).toEqual("00000000-0000-1000-8000-000000000000")
+ }
+
+ it("randomUUID") {
+ val uuid = UUID.randomUUID()
+ expect(uuid.variant()).toEqual(2)
+ expect(uuid.version()).toEqual(4)
+ }
+
+ it("fromString") {
+ val uuid1 = UUID.fromString("f81d4fae-7dec-11d0-a765-00a0c91e6bf6")
+ expect(uuid1.equals(new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf6L))).toBeTruthy
+ expect(uuid1.getMostSignificantBits() == 0xf81d4fae7dec11d0L).toBeTruthy
+ expect(uuid1.getLeastSignificantBits() == 0xa76500a0c91e6bf6L).toBeTruthy
+ expect(uuid1.variant()).toEqual(2)
+ expect(uuid1.version()).toEqual(1)
+ expect(uuid1.timestamp() == 130742845922168750L).toBeTruthy
+ expect(uuid1.clockSequence()).toEqual(10085)
+ expect(uuid1.node() == 690568981494L).toBeTruthy
+
+ val uuid2 = UUID.fromString("00000000-0000-1000-8000-000000000000")
+ expect(uuid2.equals(new UUID(0x0000000000001000L, 0x8000000000000000L)))
+ expect(uuid2.getMostSignificantBits() == 0x0000000000001000L).toBeTruthy
+ expect(uuid2.getLeastSignificantBits() == 0x8000000000000000L).toBeTruthy
+ expect(uuid2.variant()).toEqual(2)
+ expect(uuid2.version()).toEqual(1)
+ expect(uuid2.timestamp() == 0L).toBeTruthy
+ expect(uuid2.clockSequence()).toEqual(0)
+ expect(uuid2.node() == 0L).toBeTruthy
+
+ expect(() => UUID.fromString(null)).toThrow
+ expect(() => UUID.fromString("")).toThrow
+ expect(() => UUID.fromString("f81d4fae_7dec-11d0-a765-00a0c91e6bf6")).toThrow
+ expect(() => UUID.fromString("f81d4fae-7dec_11d0-a765-00a0c91e6bf6")).toThrow
+ expect(() => UUID.fromString("f81d4fae-7dec-11d0_a765-00a0c91e6bf6")).toThrow
+ expect(() => UUID.fromString("f81d4fae-7dec-11d0-a765_00a0c91e6bf6")).toThrow
+ expect(() => UUID.fromString("-7dec-11d0-a765-00a0c91e6bf6")).toThrow
+ expect(() => UUID.fromString("f81d4fae--11d0-a765-00a0c91e6bf6")).toThrow
+ expect(() => UUID.fromString("f81d4fae-7dec--a765-00a0c91e6bf6")).toThrow
+ expect(() => UUID.fromString("f81d4fae-7dec-11d0--00a0c91e6bf6")).toThrow
+ expect(() => UUID.fromString("f81d4fae-7dec-11d0-a765-")).toThrow
+ expect(() => UUID.fromString("f81d4fae-7dec-11d0-a765")).toThrow
+ expect(() => UUID.fromString("f81d4fae-7dZc-11d0-a765-00a0c91e6bf6")).toThrow
+ }
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ArrayTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ArrayTest.scala
new file mode 100644
index 0000000..2ffd6b7
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ArrayTest.scala
@@ -0,0 +1,94 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.jsinterop
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+object ArrayTest extends JasmineTest {
+
+ describe("scala.scalajs.js.Array") {
+
+ it("should provide implicit conversion from js.Array to ArrayOps - String") {
+ var propCount = 0
+ var propString = ""
+
+ for (item <- js.Array("Sc", "ala", ".", "js")) {
+ expect(item.isInstanceOf[String]).toBeTruthy
+ propCount += 1
+ propString += item
+ }
+
+ expect(propCount).toEqual(4)
+ expect(propString).toEqual("Scala.js")
+ }
+
+ it("should provide implicit conversion from js.Array to ArrayOps - Int") {
+ var propCount = 0
+ var propString = ""
+
+ for (item <- js.Array(7, 3, 5, 7)) {
+ expect(item.isInstanceOf[Int]).toBeTruthy
+ propCount += 1
+ propString += item
+ }
+
+ expect(propCount).toEqual(4)
+ expect(propString).toEqual("7357")
+ }
+
+ it("should provide implicit conversion from js.Array to ArrayOps - Char") {
+ var propCount = 0
+ var propString = ""
+
+ for (item <- js.Array('S', 'c', 'a', 'l', 'a')) {
+ expect(item.isInstanceOf[Char]).toBeTruthy
+ propCount += 1
+ propString += item
+ }
+
+ expect(propCount).toEqual(5)
+ expect(propString).toEqual("Scala")
+ }
+
+ it("should provide implicit conversion from js.Array to ArrayOps - value class") {
+ var propCount = 0
+ var propString = ""
+
+ for (item <- js.Array(new VC(5), new VC(-4))) {
+ expect(item.isInstanceOf[VC]).toBeTruthy
+ propCount += 1
+ propString += item
+ }
+
+ expect(propCount).toEqual(2)
+ expect(propString).toEqual("VC(5)VC(-4)")
+ }
+
+ }
+
+ describe("scala.scalajs.js.JSConverters.JSRichGenTraversableOnce") {
+
+ import js.JSConverters._
+
+ it("should provide toJSArray") {
+ expect(List("foo", "bar").toJSArray).toEqual(js.Array("foo", "bar"))
+ expect(Iterator(1, 2, 3).toJSArray).toEqual(js.Array(1, 2, 3))
+ expect(Array(0.3, 7.3, 8.9).toJSArray).toEqual(js.Array(0.3, 7.3, 8.9))
+ expect(None.toJSArray).toEqual(js.Array())
+ // The following fails on 2.10.x
+ //expect(Some("Hello World").toJSArray).toEqual(js.Array("Hello World"))
+ }
+
+ }
+
+ private class VC(val x: Int) extends AnyVal {
+ override def toString(): String = s"VC($x)"
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/AsyncTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/AsyncTest.scala
new file mode 100644
index 0000000..e37c89e
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/AsyncTest.scala
@@ -0,0 +1,121 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.jsinterop
+
+import scala.scalajs.js
+import scala.scalajs.js.JSConverters._
+
+import org.scalajs.jasminetest.JasmineTest
+
+import scala.concurrent.{Future, ExecutionContext}
+import scala.scalajs.concurrent.JSExecutionContext
+
+import scala.collection.mutable.ArrayBuffer
+
+import org.scalajs.jasmine.JasmineExpectation
+
+object AsyncTest extends JasmineTest {
+
+ def asyncTest(implicit executor: ExecutionContext) = {
+ val steps = new ArrayBuffer[String]
+
+ steps += "prep-future"
+
+ val f1 = Future {
+ steps += "future"
+ 1 + 2 + 3
+ }
+
+ steps += "prep-map"
+
+ val f2 = f1 map { x =>
+ steps += "map"
+ x * 2
+ }
+
+ steps += "prep-foreach"
+
+ f2 foreach { _ => steps += "foreach" }
+
+ steps += "done"
+
+ steps
+ }
+
+ def expect(abuf: ArrayBuffer[String]): JasmineExpectation =
+ expect(abuf.toJSArray)
+
+ describe("scala.scalajs.concurrent.JSExecutionContext.queue") {
+
+ beforeEach {
+ jasmine.Clock.useMock()
+ }
+
+ it("should correctly order future calls") {
+ val res = asyncTest(JSExecutionContext.queue)
+
+ expect(res).toEqual(js.Array(
+ "prep-future",
+ "prep-map",
+ "prep-foreach",
+ "done"))
+
+ jasmine.Clock.tick(1)
+
+ expect(res).toEqual(js.Array(
+ "prep-future",
+ "prep-map",
+ "prep-foreach",
+ "done",
+ "future",
+ "map",
+ "foreach"))
+ }
+
+ }
+
+ describe("scala.scalajs.concurrent.JSExecutionContext.runNow") {
+
+ it("should correctly order future calls") {
+ val res = asyncTest(JSExecutionContext.runNow)
+
+ expect(res).toEqual(js.Array(
+ "prep-future",
+ "future",
+ "prep-map",
+ "map",
+ "prep-foreach",
+ "foreach",
+ "done"))
+ }
+
+ }
+
+ describe("scala.concurrent.Future") {
+
+ it("should support map") {
+ implicit val ec = JSExecutionContext.runNow
+ val f = Future(3).map(x => x*2)
+ expect(f.value.get.get).toEqual(6)
+ }
+
+ it("should support flatMap") {
+ implicit val ec = JSExecutionContext.runNow
+ val f = Future(Future(3)).flatMap(x => x)
+ expect(f.value.get.get).toEqual(3)
+ }
+
+ it("should support sequence") {
+ implicit val ec = JSExecutionContext.runNow
+ val f = Future.sequence(Seq(Future(3), Future(5)))
+ expect(f.value.get.get.toJSArray).toEqual(js.Array(3, 5))
+ }
+
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/DictionaryTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/DictionaryTest.scala
new file mode 100644
index 0000000..8b45395
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/DictionaryTest.scala
@@ -0,0 +1,79 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.jsinterop
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+object DictionaryTest extends JasmineTest {
+
+ describe("scala.scalajs.js.Dictionary") {
+
+ it("should provide an equivalent of the JS delete keyword - #255") {
+ val obj = js.Dictionary.empty[js.Any]
+ obj("foo") = 42
+ obj("bar") = "foobar"
+
+ expect(obj("foo")).toEqual(42)
+ expect(obj("bar")).toEqual("foobar")
+ obj.delete("foo")
+ expect(obj("foo")).toBeUndefined
+ expect(obj.asInstanceOf[js.Object].hasOwnProperty("foo")).toBeFalsy
+ expect(obj("bar")).toEqual("foobar")
+ }
+
+ // This doesn't work on Rhino due to lack of full strict mode support - #679
+ unless("rhino").
+ it("should behave as specified when deleting a non-configurable property - #461 - #679") {
+ val obj = js.Dictionary.empty[js.Any]
+ js.Object.defineProperty(obj.asInstanceOf[js.Object], "nonconfig",
+ js.Dynamic.literal(value = 4, writable = false).asInstanceOf[js.PropertyDescriptor])
+ expect(obj("nonconfig")).toEqual(4)
+ expect(() => obj.delete("nonconfig")).toThrow
+ expect(obj("nonconfig")).toEqual(4)
+ }
+
+ it("should provide `get`") {
+ val obj = js.Dictionary.empty[Int]
+ obj("hello") = 1
+
+ expect(obj.get("hello").isDefined).toBeTruthy
+ expect(obj.get("world").isDefined).toBeFalsy
+ }
+
+ it("should treat delete as a statement - #907") {
+ val obj = js.Dictionary("a" -> "A")
+ obj.delete("a")
+ }
+
+ it("should desugar arguments to delete statements - #908") {
+ val kh = js.Dynamic.literal( key = "a" ).asInstanceOf[KeyHolder]
+ val dict = js.Dictionary[String]("a" -> "A")
+ def a[T](foo: String) = dict.asInstanceOf[T]
+ a[js.Dictionary[String]]("foo").delete(kh.key)
+ }
+
+ }
+
+ trait KeyHolder extends js.Object {
+ def key: String = js.native
+ }
+
+ describe("scala.scalajs.js.JSConverters.JSRichGenMap") {
+
+ import js.JSConverters._
+
+ it("should provide toJSDictionary") {
+ expect(Map("a" -> 1, "b" -> 2).toJSDictionary).toEqual(
+ js.Dynamic.literal(a = 1, b = 2))
+ expect(Map("a" -> "foo", "b" -> "bar").toJSDictionary).toEqual(
+ js.Dynamic.literal(a = "foo", b = "bar"))
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/DynamicTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/DynamicTest.scala
new file mode 100644
index 0000000..2b6942f
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/DynamicTest.scala
@@ -0,0 +1,187 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.jsinterop
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+import js.annotation.JSExport
+
+object DynamicTest extends JasmineTest {
+
+ describe("scala.scalajs.js.Dynamic") {
+
+ it("should workaround Scala 2.10 issue with implicit conversion for dynamic fields named x - #8") {
+ class Point(val x: Int, val y: Int)
+
+ def jsonToPoint(json: js.Dynamic) = {
+ new Point(json.x.toString.toInt, json.y.toString.toInt)
+ }
+
+ val json = js.eval("var dynamicTestPoint = { x: 1, y: 2 }; dynamicTestPoint;")
+ val point = jsonToPoint(json.asInstanceOf[js.Dynamic])
+
+ expect(point.x).toEqual(1)
+ expect(point.y).toEqual(2)
+ }
+
+ it("should allow to call functions with arguments named x") {
+ class A {
+ def a = 1
+ }
+
+ class B extends A {
+ @JSExport
+ def x(par: Int) = a + par // make sure `this` is bound correctly in JS
+ }
+
+ val b = (new B).asInstanceOf[js.Dynamic]
+
+ expect(b.x(10)).toEqual(11)
+ }
+
+ it("should allow instanciating JS classes dynamically - #10") {
+ val DynamicTestClass = js.eval("""
+ var DynamicTestClass = function(x) {
+ this.x = x;
+ };
+ DynamicTestClass;
+ """).asInstanceOf[js.Dynamic]
+ val obj = js.Dynamic.newInstance(DynamicTestClass)("Scala.js")
+ expect(obj.x).toEqual("Scala.js")
+ }
+
+ it("should allow instantiating JS classes dynamically with varargs - #708") {
+ val DynamicTestClassVarArgs = js.eval("""
+ var DynamicTestClassVarArgs = function() {
+ this.count = arguments.length;
+ for (var i = 0; i < arguments.length; i++)
+ this['elem'+i] = arguments[i];
+ };
+ DynamicTestClassVarArgs;
+ """).asInstanceOf[js.Dynamic]
+
+ val obj1 = js.Dynamic.newInstance(DynamicTestClassVarArgs)("Scala.js")
+ expect(obj1.count).toEqual(1)
+ expect(obj1.elem0).toEqual("Scala.js")
+
+ val obj2 = js.Dynamic.newInstance(DynamicTestClassVarArgs)(
+ "Scala.js", 42, true)
+ expect(obj2.count).toEqual(3)
+ expect(obj2.elem0).toEqual("Scala.js")
+ expect(obj2.elem1).toEqual(42)
+ expect(obj2.elem2).toEqual(true)
+
+ def obj3Args: Seq[js.Any] = Seq("Scala.js", 42, true)
+ val obj3 = js.Dynamic.newInstance(DynamicTestClassVarArgs)(obj3Args: _*)
+ expect(obj3.count).toEqual(3)
+ expect(obj3.elem0).toEqual("Scala.js")
+ expect(obj3.elem1).toEqual(42)
+ expect(obj3.elem2).toEqual(true)
+ }
+
+ it("should provide an object literal construction") {
+ import js.Dynamic.{ literal => obj }
+ val x = obj(foo = 3, bar = "foobar")
+ expect(x.foo).toEqual(3)
+ expect(x.bar).toEqual("foobar")
+ expect(x.unknown).toBeUndefined()
+
+ val y = obj(
+ inner = obj(name = "inner obj"),
+ fun = { () => 42 }
+ )
+ expect(y.inner.name).toEqual("inner obj")
+ expect(y.fun()).toEqual(42)
+
+ expect(obj().anything).toBeUndefined()
+ }
+
+ it("should provide object literal construction with dynamic naming") {
+ import js.Dynamic.{ literal => obj }
+ val x = obj("foo" -> 3, "bar" -> "foobar")
+ expect(x.foo).toEqual(3)
+ expect(x.bar).toEqual("foobar")
+ expect(x.unknown).toBeUndefined()
+
+ val tup1 = ("hello1", 3: js.Any)
+ val tup2 = ("hello2", 10: js.Any)
+
+ val y = obj(tup1, tup2)
+ expect(y.hello1).toEqual(3)
+ expect(y.hello2).toEqual(10)
+
+ var count = 0
+ val z = obj({ count += 1; ("foo", "bar")})
+ expect(z.foo).toEqual("bar")
+ expect(count).toEqual(1)
+ }
+
+ it("should allow to create an empty object with the literal syntax") {
+ import js.Dynamic.{ literal => obj }
+ val x = obj()
+ expect(x.isInstanceOf[js.Object]).toBeTruthy()
+ }
+
+ it("should properly encode object literal property names") {
+ import js.Dynamic.{ literal => obj }
+
+ val obj0 = obj("3-" -> 42)
+ expect(obj0.`3-`).toEqual(42)
+
+ val obj0Dict = obj0.asInstanceOf[js.Dictionary[js.Any]]
+ expect(obj0Dict("3-")).toEqual(42)
+
+ val checkEvilProperties = js.eval("""
+ function dynamicLiteralNameEncoding_checkEvilProperties(x) {
+ return x['.o[3√!|-pr()per7:3$];'] === ' such eval ';
+ }
+ dynamicLiteralNameEncoding_checkEvilProperties
+ """).asInstanceOf[js.Function1[js.Any, Boolean]]
+ val obj1 = obj(
+ ".o[3√!|-pr()per7:3$];" -> " such eval ").asInstanceOf[js.Dictionary[js.Any]]
+ expect(obj1(".o[3√!|-pr()per7:3$];")).toEqual(" such eval ")
+ expect(checkEvilProperties(obj1)).toEqual(true)
+
+ val checkQuotesProperty = js.eval("""
+ function dynamicLiteralNameEncoding_quote(x) {
+ return x["'" + '"'] === 7357;
+ }
+ dynamicLiteralNameEncoding_quote
+ """).asInstanceOf[js.Function1[js.Any, Boolean]]
+
+ val quote = '"'
+
+ Seq(
+ obj("'" + quote -> 7357),
+ obj(s"'$quote" -> 7357),
+ obj("'\"" -> 7357),
+ obj("'" + quote -> 7357)
+ ).foreach { o =>
+ val dict = o.asInstanceOf[js.Dictionary[js.Any]]
+ expect(dict("'\"")).toEqual(7357)
+ expect(dict("'" + quote)).toEqual(7357)
+ expect(dict(s"'$quote")).toEqual(7357)
+ expect(checkQuotesProperty(o)).toEqual(true)
+ }
+ }
+
+ it("should return subclasses of js.Object in literal construction - #783") {
+ import js.Dynamic.{ literal => obj }
+
+ val a: js.Object = obj(theValue = 1)
+ expect(a.hasOwnProperty("theValue")).toBeTruthy
+ expect(a.hasOwnProperty("noValue")).toBeFalsy
+
+ val b: js.Object = obj("theValue" -> 2)
+ expect(b.hasOwnProperty("theValue")).toBeTruthy
+ expect(b.hasOwnProperty("noValue")).toBeFalsy
+
+ }
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ExportsTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ExportsTest.scala
new file mode 100644
index 0000000..d577d8d
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ExportsTest.scala
@@ -0,0 +1,1075 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.jsinterop
+
+import scala.scalajs.js
+import js.annotation._
+import org.scalajs.jasminetest.{JasmineTest, JasmineTestFramework}
+
+import scala.annotation.meta
+
+object ExportsTest extends JasmineTest {
+
+ /** This package in the JS (export) namespace */
+ val jsPackage = js.Dynamic.global.scala.scalajs.testsuite.jsinterop
+
+ describe("@JSExport") {
+
+ it("should offer exports for methods with implicit name") {
+ class Foo {
+ @JSExport
+ def bar(): Int = 42
+ @JSExport
+ def double(x: Int): Int = x*2
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+ expect(js.typeOf(foo.bar)).toBe("function")
+ expect(foo.bar()).toEqual(42)
+ expect(foo.double(3)).toEqual(6)
+ }
+
+ it("should offer exports for methods with explicit name") {
+ class Foo {
+ @JSExport("theAnswer")
+ def bar(): Int = 42
+ @JSExport("doubleTheParam")
+ def double(x: Int): Int = x*2
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+ expect(foo.bar).toBeUndefined
+ expect(js.typeOf(foo.theAnswer)).toBe("function")
+ expect(foo.theAnswer()).toEqual(42)
+ expect(foo.doubleTheParam(3)).toEqual(6)
+ }
+
+ it("should offer exports for methods with constant folded name") {
+ class Foo {
+ @JSExport(ExportNameHolder.methodName)
+ def bar(): Int = 42
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+ expect(foo.bar).toBeUndefined
+ expect(foo.myMethod()).toEqual(42)
+ }
+
+ it("should offer exports for protected methods") {
+ class Foo {
+ @JSExport
+ protected def bar(): Int = 42
+
+ @JSExport
+ protected[testsuite] def foo(): Int = 100
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+ expect(js.typeOf(foo.bar)).toBe("function")
+ expect(foo.bar()).toEqual(42)
+ expect(js.typeOf(foo.foo)).toBe("function")
+ expect(foo.foo()).toEqual(100)
+ }
+
+ it("should offer exports for properties with implicit name") {
+ class Foo {
+ private[this] var myY: String = "hello"
+ @JSExport
+ val answer: Int = 42
+ @JSExport
+ var x: Int = 3
+ @JSExport
+ def doubleX: Int = x*2
+ @JSExport
+ def y: String = myY + " get"
+ @JSExport
+ def y_=(v: String): Unit = myY = v + " set"
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+ expect(js.typeOf(foo.answer)).toBe("number")
+ expect(foo.answer).toEqual(42)
+ expect(foo.x).toEqual(3)
+ expect(foo.doubleX).toEqual(6)
+ foo.x = 23
+ expect(foo.x).toEqual(23)
+ expect(foo.doubleX).toEqual(46)
+ expect(foo.y).toEqual("hello get")
+ foo.y = "world"
+ expect(foo.y).toEqual("world set get")
+ }
+
+ it("should offer exports for properties with explicit name") {
+ class Foo {
+ private[this] var myY: String = "hello"
+ @JSExport("answer")
+ val answerScala: Int = 42
+ @JSExport("x")
+ var xScala: Int = 3
+ @JSExport("doubleX")
+ def doubleXScala: Int = xScala*2
+ @JSExport("y")
+ def yGetter: String = myY + " get"
+ @JSExport("y")
+ def ySetter_=(v: String): Unit = myY = v + " set"
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+ expect(foo.answerScala).toBeUndefined
+ expect(js.typeOf(foo.answer)).toBe("number")
+ expect(foo.answer).toEqual(42)
+ expect(foo.x).toEqual(3)
+ expect(foo.doubleX).toEqual(6)
+ foo.x = 23
+ expect(foo.x).toEqual(23)
+ expect(foo.doubleX).toEqual(46)
+ expect(foo.y).toEqual("hello get")
+ foo.y = "world"
+ expect(foo.y).toEqual("world set get")
+ }
+
+ it("should offer exports for protected properties") {
+ class Foo {
+ @JSExport
+ protected val x: Int = 42
+ @JSExport
+ protected[testsuite] val y: Int = 43
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+ expect(foo.x).toEqual(42)
+ expect(foo.y).toEqual(43)
+ }
+
+ it("should offer overloaded exports for methods") {
+ class Foo {
+ @JSExport("foobar")
+ def foo(): Int = 42
+ @JSExport("foobar")
+ def bar(x: Int): Int = x*2
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+ expect(js.typeOf(foo.foobar)).toBe("function")
+ expect(foo.foobar()).toEqual(42)
+ expect(foo.foobar(3)).toEqual(6)
+ }
+
+ it("should offer multiple exports for the same method") {
+ class Foo {
+ @JSExport
+ @JSExport("b")
+ @JSExport("c")
+ def a(): Int = 1
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+ expect(js.typeOf(foo.a)).toBe("function")
+ expect(js.typeOf(foo.b)).toBe("function")
+ expect(js.typeOf(foo.c)).toBe("function")
+
+ expect(foo.a()).toEqual(1)
+ expect(foo.b()).toEqual(1)
+ expect(foo.c()).toEqual(1)
+ }
+
+ it("should inherit exports from traits") {
+ trait Foo {
+ @JSExport
+ def x: Int
+
+ @JSExport
+ def method(x: Int): Int
+ }
+
+ class Bar extends Foo {
+ val x = 1
+ def method(x: Int) = 2 * x
+ }
+
+ val bar = (new Bar).asInstanceOf[js.Dynamic]
+ expect(bar.x).toEqual(1)
+ expect(js.typeOf(bar.method)).toBe("function")
+ expect(bar.method(2)).toEqual(4)
+ }
+
+ it("should offer overloading with inherited exports") {
+ class A {
+ @JSExport
+ def foo(x: Int) = 2*x
+ }
+
+ class B extends A{
+ @JSExport("foo")
+ def bar(x: String) = s"Hello $x"
+ }
+
+ val b = (new B).asInstanceOf[js.Dynamic]
+ expect(js.typeOf(b.foo)).toBe("function")
+ expect(b.foo(1)).toEqual(2)
+ expect(b.foo("World")).toEqual("Hello World")
+ }
+
+ it("should offer exports for generic methods") {
+ class Foo {
+ @JSExport
+ def gen[T <: AnyRef](x: T) = x
+ }
+
+ val x = (new Object).asInstanceOf[js.Any]
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+ expect(js.typeOf(foo.gen)).toBe("function")
+ expect(foo.gen(x)).toBe(x)
+ }
+
+ it("should offer exports for lambda return types") {
+ class Foo {
+ @JSExport
+ def lambda(x: Int) = (y: Int) => x + y
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+ expect(js.typeOf(foo.lambda)).toBe("function")
+
+ val lambda = foo.lambda(5).asInstanceOf[Function1[Int,Int]]
+
+ expect(lambda(4)).toEqual(9)
+ }
+
+ it("should offer exports for multi parameter lists") {
+ class Foo {
+ @JSExport
+ def multiParam(x: Int)(y: Int): Int = x + y
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+ expect(js.typeOf(foo.multiParam)).toBe("function")
+ expect(foo.multiParam(5,6)).toEqual(11)
+ }
+
+ it("should offer exports for default arguments") {
+ class Foo {
+ @JSExport
+ def defArg(x: Int = 1) = x
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+ expect(js.typeOf(foo.defArg)).toBe("function")
+ expect(foo.defArg(5)).toEqual(5)
+ }
+
+ it("should offer exports for weird stuff") {
+ class UhOh {
+ // Something no one should export
+ @JSExport
+ def ahem[T : Comparable](x: T)(implicit y: Int) = ???
+ }
+
+ val x = (new UhOh).asInstanceOf[js.Dynamic]
+ expect(js.typeOf(x.ahem)).toBe("function")
+ }
+
+ it("should offer exports with value class return types") {
+ class Foo {
+ @JSExport
+ def vc(x: Int) = new SomeValueClass(x)
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+ expect(js.typeOf(foo.vc)).toBe("function")
+
+ // The result should be a boxed SomeValueClass
+ val result = foo.vc(5)
+ expect(js.typeOf(result)).toEqual("object")
+ expect((result: Any).isInstanceOf[SomeValueClass]).toBeTruthy
+ expect((result: Any) == (new SomeValueClass(5))).toBeTruthy
+ }
+
+ it("should allow exports with Any as return type") {
+ class A
+ class Foo {
+ @JSExport
+ def foo(switch: Boolean): Any =
+ if (switch) 1 else new A
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+ expect(foo.foo(true).isInstanceOf[Int]).toBeTruthy
+ expect(foo.foo(false).isInstanceOf[A]).toBeTruthy
+ }
+
+ it("should accept boxed value classes as parameter") {
+ class Foo {
+ @JSExport
+ def vc(x: SomeValueClass) = x.i
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+ expect(js.typeOf(foo.vc)).toBe("function")
+
+ // The parameter should be a boxed SomeValueClass
+ val valueCls = new SomeValueClass(7)
+ val result = foo.vc(valueCls.asInstanceOf[js.Any])
+ expect(js.typeOf(result)).toEqual("number")
+ expect(result).toEqual(7)
+ }
+
+ it("should offer exports for overridden methods with refined return type") {
+ class A
+ class B extends A
+
+ class C1 {
+ @JSExport
+ def x: A = new A
+ }
+
+ class C2 extends C1 {
+ override def x: B = new B
+ }
+
+ val c2 = (new C2).asInstanceOf[js.Dynamic]
+ expect(c2.x.isInstanceOf[B]).toBeTruthy
+ }
+
+ it("should offer exports for methods with refined types as return type") {
+ class A {
+ @JSExport
+ def foo(x: String): js.Object with js.Dynamic =
+ js.Dynamic.literal(arg = x)
+ }
+
+ val a = (new A).asInstanceOf[js.Dynamic]
+ expect(a.foo("hello")).toEqual(js.Dynamic.literal(arg = "hello"))
+ }
+
+ it("should offer exports for variable argument methods - #393") {
+ class A {
+ @JSExport
+ def foo(i: String*) = i.mkString("|")
+ }
+
+ val a = (new A).asInstanceOf[js.Dynamic]
+
+ expect(a.foo()).toEqual("")
+ expect(a.foo("a", "b", "c")).toEqual("a|b|c")
+ expect(a.foo("a", "b", "c", "d")).toEqual("a|b|c|d")
+ }
+
+ it("should correctly overload in view of difficult repeated parameter lists") {
+ class A {
+ @JSExport
+ def foo(a: String, b: String, i: Int, c: String) = 1
+
+ @JSExport
+ def foo(a: String*) = 2
+
+ @JSExport
+ def foo(x: Int)(a: Int*) = x * 100000 + a.sum
+ }
+
+ val a = (new A).asInstanceOf[js.Dynamic]
+
+ expect(a.foo()).toEqual(2)
+ expect(a.foo("asdf")).toEqual(2)
+ expect(a.foo("asdf", "foo")).toEqual(2)
+ expect(a.foo("asdf", "foo", "bar")).toEqual(2)
+ expect(a.foo("asdf", "foo", 1, "bar")).toEqual(1)
+ expect(a.foo("asdf", "foo", "foo", "bar")).toEqual(2)
+ expect(a.foo(5, 1, 2, 3, 10)).toEqual(500016)
+ expect(a.foo(1)).toEqual(100000)
+ }
+
+ it("should offer exports with default arguments") {
+ class A {
+ var oneCount: Int = 0
+ def one = {
+ oneCount += 1
+ 1
+ }
+ @JSExport
+ def foo(a: Int = one)(b: Int = a + one)(c: Int = b + one) =
+ a + b + c
+ }
+
+ val a = new A
+ val jsa = a.asInstanceOf[js.Dynamic]
+
+ expect(jsa.foo()).toEqual(6)
+ expect(a.oneCount).toEqual(3)
+
+ expect(jsa.foo(2)).toEqual(9)
+ expect(a.oneCount).toEqual(5)
+
+ expect(jsa.foo(2,4)).toEqual(11)
+ expect(a.oneCount).toEqual(6)
+
+ expect(jsa.foo(2,4,10)).toEqual(16)
+ expect(a.oneCount).toEqual(6)
+
+ expect(jsa.foo((),4,10)).toEqual(15)
+ expect(a.oneCount).toEqual(7)
+
+ expect(jsa.foo((),4)).toEqual(10)
+ expect(a.oneCount).toEqual(9)
+ }
+
+ it("should correctly overload methods in presence of default parameters") {
+ class A {
+ @JSExport
+ def foo(a: Int)(b: Int = 5)(c: Int = 7) = 1000 + a + b + c
+
+ @JSExport
+ def foo(a: Int, b: String) = 2
+
+ @JSExport
+ def foo(a: Int, b: Int, c: String) = 3
+ }
+
+ val a = (new A).asInstanceOf[js.Dynamic]
+
+ expect(a.foo(1)).toEqual(1013)
+ expect(a.foo(1, 4)).toEqual(1012)
+ expect(a.foo(1, 4, 5)).toEqual(1010)
+ expect(a.foo(1, "foo")).toEqual(2)
+ expect(a.foo(1, 2, "foo")).toEqual(3)
+
+ }
+
+ it("should prefer overloads taking a js.Undefined over methods with default parameters") {
+ class A {
+ @JSExport
+ def foo(a: Int)(b: String = "asdf") = s"$a $b"
+
+ @JSExport
+ def foo(a: Int, b: js.prim.Undefined) = "woot"
+ }
+
+ val a = (new A).asInstanceOf[js.Dynamic]
+
+ expect(a.foo(1)).toEqual("1 asdf")
+ expect(a.foo(2, "omg")).toEqual("2 omg")
+ expect(a.foo(1, ())).toEqual("woot")
+
+ }
+
+ it("should correctly overload methods in presence of default parameters and repeated parameters") {
+ class A {
+ @JSExport
+ def foo(x: Int, y: Int = 1) = x + y
+ @JSExport
+ def foo(x: String*) = x.mkString("|")
+ }
+
+ val a = (new A).asInstanceOf[js.Dynamic]
+
+ expect(a.foo(1)).toEqual(2)
+ expect(a.foo(1, 2)).toEqual(3)
+ expect(a.foo()).toEqual("")
+ expect(a.foo("foo")).toEqual("foo")
+ expect(a.foo("foo","bar")).toEqual("foo|bar")
+
+ }
+
+ it("should correctly overload exports called `toString`") {
+ class A {
+ override def toString(): String = "no arg"
+ @JSExport
+ def toString(x: Int): String = s"with arg: $x"
+ }
+
+ val a = (new A).asInstanceOf[js.Dynamic]
+ expect(a.applyDynamic("toString")()).toEqual("no arg")
+ expect(a.applyDynamic("toString")(1)).toEqual("with arg: 1")
+ }
+
+ it("should allow to explicitly export toString") {
+ class A {
+ @JSExport("toString")
+ override def toString(): String = "called"
+ }
+
+ val a = (new A).asInstanceOf[js.Dynamic]
+ expect(a.applyDynamic("toString")()).toEqual("called")
+ }
+
+ it("should correctly box repeated parameter lists with value classes") {
+ class A {
+ @JSExport
+ def foo(vcs: SomeValueClass*) = vcs.map(_.i).sum
+ }
+
+ val vc1 = new SomeValueClass(1)
+ val vc2 = new SomeValueClass(2)
+ val a = (new A).asInstanceOf[js.Dynamic]
+
+ expect(a.foo(vc1.asInstanceOf[js.Any], vc2.asInstanceOf[js.Any])).toEqual(3)
+ }
+
+ it("should offer exports for objects with implicit name") {
+ val accessor = jsPackage.ExportedObject
+ expect(accessor).toBeDefined
+ expect(js.typeOf(accessor)).toEqual("function")
+ val obj = accessor()
+ expect(obj).toBeDefined
+ expect(js.typeOf(obj)).toEqual("object")
+ expect(obj.witness).toEqual("witness")
+ }
+
+ it("should offer exports for objects with explicit name") {
+ val accessor = js.Dynamic.global.TheExportedObject
+ expect(accessor).toBeDefined
+ expect(js.typeOf(accessor)).toEqual("function")
+ val obj = accessor()
+ expect(obj).toBeDefined
+ expect(js.typeOf(obj)).toEqual("object")
+ expect(obj.witness).toEqual("witness")
+ }
+
+ it("should offer exports for objects with qualified name") {
+ val accessor = js.Dynamic.global.qualified.testobject.ExportedObject
+ expect(accessor).toBeDefined
+ expect(js.typeOf(accessor)).toEqual("function")
+ val obj = accessor()
+ expect(obj).toBeDefined
+ expect(js.typeOf(obj)).toEqual("object")
+ expect(obj.witness).toEqual("witness")
+ }
+
+ it("should offer exports for objects with constant folded name") {
+ val accessor = js.Dynamic.global.ConstantFoldedObjectExport
+ expect(accessor).toBeDefined
+ expect(js.typeOf(accessor)).toEqual("function")
+ val obj = accessor()
+ expect(obj).toBeDefined
+ expect(js.typeOf(obj)).toEqual("object")
+ expect(obj.witness).toEqual("witness")
+ }
+
+ it("should offer exports for protected objects") {
+ val accessor = jsPackage.ProtectedExportedObject
+ expect(accessor).toBeDefined
+ expect(js.typeOf(accessor)).toEqual("function")
+ val obj = accessor()
+ expect(obj).toBeDefined
+ expect(js.typeOf(obj)).toEqual("object")
+ expect(obj.witness).toEqual("witness")
+ }
+
+ it("should offer exports for classes with implicit name") {
+ val constr = jsPackage.ExportedClass
+ expect(constr).toBeDefined
+ expect(js.typeOf(constr)).toEqual("function")
+ val obj = js.Dynamic.newInstance(constr)(5)
+ expect(obj.x).toEqual(5)
+ }
+
+ it("should offer exports for classes with explicit name") {
+ val constr = js.Dynamic.global.TheExportedClass
+ expect(constr).toBeDefined
+ expect(js.typeOf(constr)).toEqual("function")
+ val obj = js.Dynamic.newInstance(constr)(5)
+ expect(obj.x).toEqual(5)
+ }
+
+ it("should offer exports for classes with qualified name") {
+ val constr = js.Dynamic.global.qualified.testclass.ExportedClass
+ expect(constr).toBeDefined
+ expect(js.typeOf(constr)).toEqual("function")
+ val obj = js.Dynamic.newInstance(constr)(5)
+ expect(obj.x).toEqual(5)
+ }
+
+ it("should offer exports for classes with constant folded name") {
+ val constr = js.Dynamic.global.ConstantFoldedClassExport
+ expect(constr).toBeDefined
+ expect(js.typeOf(constr)).toEqual("function")
+ val obj = js.Dynamic.newInstance(constr)(5)
+ expect(obj.x).toEqual(5)
+ }
+
+ it("should offer exports for protected classes") {
+ val constr = jsPackage.ProtectedExportedClass
+ expect(constr).toBeDefined
+ expect(js.typeOf(constr)).toEqual("function")
+ val obj = js.Dynamic.newInstance(constr)(5)
+ expect(obj.x).toEqual(5)
+ }
+
+ it("should offer export for classes with repeated parameters in ctor") {
+ val constr = jsPackage.ExportedVarArgClass
+ expect(js.Dynamic.newInstance(constr)().result).toEqual("")
+ expect(js.Dynamic.newInstance(constr)("a").result).toEqual("a")
+ expect(js.Dynamic.newInstance(constr)("a", "b").result).toEqual("a|b")
+ expect(js.Dynamic.newInstance(constr)("a", "b", "c").result).toEqual("a|b|c")
+ expect(js.Dynamic.newInstance(constr)(5, "a").result).toEqual("Number: <5>|a")
+ }
+
+ it("should offer export for classes with default parameters in ctor") {
+ val constr = jsPackage.ExportedDefaultArgClass
+ expect(js.Dynamic.newInstance(constr)(1,2,3).result).toEqual(6)
+ expect(js.Dynamic.newInstance(constr)(1).result).toEqual(106)
+ expect(js.Dynamic.newInstance(constr)(1,2).result).toEqual(103)
+ }
+
+ it("should correctly disambiguate overloads involving longs") {
+
+ class Foo {
+ @JSExport
+ def foo(x: Int) = 1
+ @JSExport
+ def foo(x: Long) = 2
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+
+ // Create a long factory we can call dynamically to retrieve an unboxed
+ // long which is typed as a js.Any
+ object LongFactory {
+ @JSExport
+ def aLong = 1L
+ }
+ val trueJsLong = LongFactory.asInstanceOf[js.Dynamic].aLong
+
+ expect(foo.foo(1)).toEqual(1)
+ expect(foo.foo(trueJsLong)).toEqual(2)
+ }
+
+ it("should return boxed Chars") {
+ class Foo {
+ @JSExport
+ def bar(x: Int): Char = x.toChar
+ }
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+
+ val funs = js.eval("""
+ var funs = {
+ testIsChar: function(foo) { return JSUtils().isChar(foo.bar(65)); },
+ testCharValue: function(foo) { return JSUtils().charToString(foo.bar(65)); }
+ }; funs;
+ """).asInstanceOf[js.Dynamic]
+
+ expect(funs.testIsChar(foo)).toBeTruthy
+ expect(funs.testCharValue(foo)).toEqual("A")
+ }
+
+ it("should take boxed Chars as parameter") {
+ class Foo {
+ @JSExport
+ def bar(x: Char): Int = x.toInt
+ }
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+
+ val f = js.eval("""
+ var f = function(foo) { return foo.bar(JSUtils().stringToChar('e')); };
+ f;
+ """).asInstanceOf[js.Dynamic]
+
+ expect(f(foo)).toEqual('e'.toInt)
+ }
+
+ it("should be able to disambiguate an Int from a Char") {
+ class Foo {
+ @JSExport
+ def bar(x: Char): String = "char: "+x
+ @JSExport
+ def bar(x: Int): String = "int: "+x
+ }
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+
+ val funs = js.eval("""
+ var funs = {
+ testChar: function(foo) { return foo.bar(JSUtils().stringToChar('S')); },
+ testInt: function(foo) { return foo.bar(68); }
+ }; funs;
+ """).asInstanceOf[js.Dynamic]
+
+ expect(funs.testChar(foo)).toEqual("char: S")
+ expect(funs.testInt(foo)).toEqual("int: 68")
+ }
+
+ it("should support exporting constructor parameter fields - #970") {
+ class Foo(@(JSExport @meta.field) val x: Int)
+ val foo = (new Foo(1)).asInstanceOf[js.Dynamic]
+ expect(foo.x).toEqual(1)
+ }
+
+ it("should support exporting case class fields - #970") {
+ case class Foo(@(JSExport @meta.field) x: Int)
+ val foo = (new Foo(1)).asInstanceOf[js.Dynamic]
+ expect(foo.x).toEqual(1)
+ }
+
+ it("should support exporting lazy values - #977") {
+ class Foo {
+ @JSExport
+ lazy val x = 1
+ }
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+ expect(foo.x).toEqual(1)
+ }
+
+ it("should support exporting all members of a class") {
+ @JSExportAll
+ class Foo {
+ val a = 1
+
+ @JSExport // double annotation allowed
+ def b = 2
+
+ lazy val c = 3
+
+ class Bar // not exported, but should not fail
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+
+ expect(foo.a).toEqual(1)
+ expect(foo.b).toEqual(2)
+ expect(foo.c).toEqual(3)
+ }
+
+ it("should not export synthetic members with @JSExportAll - #1195") {
+ @JSExportAll
+ case class Foo(x: Int)
+
+ val foo = Foo(1).asInstanceOf[js.Dynamic]
+
+ expect(foo.x).toEqual(1)
+ expect(foo.copy).toBeUndefined
+ }
+
+ it("should allow mutliple equivalent JSExport annotations") {
+ class Foo {
+ @JSExport
+ @JSExport("a")
+ @JSExport
+ @JSExport("a")
+ def b = 1
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+
+ expect(foo.b).toEqual(1)
+ }
+
+ it("should support named exports") {
+ import js.Dynamic.{literal => lit}
+
+ class FooNamed {
+ @JSExportNamed("bar1")
+ def bar(x: Int, y: Int) = x + y
+
+ @JSExportNamed("bar2")
+ @JSExport
+ def bar(x: Int = 1)(y: Int = x)(z: Int = y) = x + y + z
+ }
+
+ val foo = (new FooNamed).asInstanceOf[js.Dynamic]
+
+ expect(foo.bar1(lit(x = 1, y = 2))).toEqual(3)
+ if (JasmineTestFramework.hasTag("compliant-asinstanceof"))
+ expect(() => foo.bar1(lit(x = 1))).toThrow // missing arg
+ expect(foo.bar2(lit())).toEqual(3)
+ expect(foo.bar2(lit(x = 2))).toEqual(6)
+ expect(foo.bar2(lit(y = 2))).toEqual(5)
+ expect(foo.bar2(lit(y = 2, z = 1))).toEqual(4)
+ expect(foo.bar(2)).toEqual(6)
+ expect(foo.bar(2,3)).toEqual(8)
+ }
+
+ it("should support named constructor exports") {
+ import js.Dynamic.{literal => lit}
+
+ val constr = jsPackage.ExportedNamedArgClass
+ expect(js.Dynamic.newInstance(constr)(lit(x = 2)).result).toEqual("22true")
+ expect(js.Dynamic.newInstance(constr)(lit(y = "foo")).result).toEqual("1foofalse")
+ expect(js.Dynamic.newInstance(constr)(lit(z = true, y = "foo")).result).toEqual("1footrue")
+ }
+
+ it("should support exporting under 'org' namespace - #364") {
+ val accessor = js.Dynamic.global.org.ExportedUnderOrgObject
+ expect(js.typeOf(accessor)).toEqual("function")
+ val obj = accessor()
+ expect(obj).toBe(ExportedUnderOrgObject.asInstanceOf[js.Any])
+ }
+
+ when("compliant-asinstanceof").
+ it("should reject bad values for arguments of primitive value type") {
+ class Foo {
+ @JSExport
+ def doBool(x: Boolean) = x
+ @JSExport
+ def doChar(x: Char) = x
+ @JSExport
+ def doByte(x: Byte) = x
+ @JSExport
+ def doShort(x: Short) = x
+ @JSExport
+ def doInt(x: Int) = x
+ @JSExport
+ def doLong(x: Long) = x
+ @JSExport
+ def doFloat(x: Float) = x
+ @JSExport
+ def doDouble(x: Double) = x
+ @JSExport
+ def doUnit(x: Unit) = x
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+
+ // Nulls
+ expect(() => foo.doBool(null)).toThrow
+ expect(() => foo.doChar(null)).toThrow
+ expect(() => foo.doByte(null)).toThrow
+ expect(() => foo.doShort(null)).toThrow
+ expect(() => foo.doInt(null)).toThrow
+ expect(() => foo.doLong(null)).toThrow
+ expect(() => foo.doFloat(null)).toThrow
+ expect(() => foo.doDouble(null)).toThrow
+ expect(() => foo.doUnit(null)).toThrow
+
+ // Class type
+ expect(() => foo.doBool(foo)).toThrow
+ expect(() => foo.doChar(foo)).toThrow
+ expect(() => foo.doByte(foo)).toThrow
+ expect(() => foo.doShort(foo)).toThrow
+ expect(() => foo.doInt(foo)).toThrow
+ expect(() => foo.doLong(foo)).toThrow
+ expect(() => foo.doFloat(foo)).toThrow
+ expect(() => foo.doDouble(foo)).toThrow
+ expect(() => foo.doUnit(foo)).toThrow
+
+ // Bad values
+ expect(() => foo.doBool(1)).toThrow
+ expect(() => foo.doBool("a")).toThrow
+
+ expect(() => foo.doChar(1)).toThrow
+ expect(() => foo.doChar("a")).toThrow
+
+ expect(() => foo.doByte(300)).toThrow
+ expect(() => foo.doByte("a")).toThrow
+
+ expect(() => foo.doShort(32768)).toThrow
+ expect(() => foo.doShort("a")).toThrow
+
+ expect(() => foo.doInt(3.2)).toThrow
+ expect(() => foo.doInt("a")).toThrow
+
+ expect(() => foo.doLong(3.2)).toThrow
+ expect(() => foo.doLong(3)).toThrow
+ expect(() => foo.doLong("a")).toThrow
+
+ expect(() => foo.doFloat("a")).toThrow
+ }
+
+ when("compliant-asinstanceof").
+ it("should reject bad values for arguments of value class type - #613") {
+ class Foo {
+ @JSExport
+ def doVC(x: SomeValueClass) = x
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+
+ expect(() => foo.doVC(null)).toThrow
+ expect(() => foo.doVC(foo)).toThrow
+ expect(() => foo.doVC(1)).toThrow
+ expect(() => foo.doVC("a")).toThrow
+ }
+
+ when("compliant-asinstanceof").
+ it("should reject bad values for arguments of class type") {
+ class A
+ class B
+
+ class Foo {
+ @JSExport
+ def doA(x: A) = x
+ }
+
+ val foo = (new Foo).asInstanceOf[js.Dynamic]
+
+ expect(() => foo.doA(1)).toThrow
+ expect(() => foo.doA((new B).asInstanceOf[js.Any])).toThrow
+ expect(() => foo.doA("a")).toThrow
+ }
+
+ it("should offer exports for classes ending in _= - #1090") {
+ val constr = jsPackage.ExportClassSetterNamed_=
+ val obj = js.Dynamic.newInstance(constr)()
+ expect(obj.x).toBe(1)
+ }
+
+ it("should offer exports for objects ending in _= - #1090") {
+ expect(jsPackage.ExportObjSetterNamed_=().x).toBe(1)
+ }
+
+ } // describe
+
+ describe("@JSExportDescendentObjects") {
+
+ it("should offer auto exports for objects extending a trait") {
+ val accessor =
+ js.Dynamic.global.scala.scalajs.testsuite.jsinterop.AutoExportedTraitObject
+ expect(accessor).toBeDefined
+ expect(js.typeOf(accessor)).toEqual("function")
+ val obj = accessor()
+ expect(obj).toBeDefined
+ expect(obj).toBe(AutoExportedTraitObject.asInstanceOf[js.Any])
+ }
+
+ it("should offer auto exports for objects extending a class") {
+ val accessor =
+ js.Dynamic.global.scala.scalajs.testsuite.jsinterop.AutoExportedClassObject
+ expect(accessor).toBeDefined
+ expect(js.typeOf(accessor)).toEqual("function")
+ val obj = accessor()
+ expect(obj).toBeDefined
+ expect(obj).toBe(AutoExportedClassObject.asInstanceOf[js.Any])
+ }
+
+ }
+
+ describe("@JSExportDescendentClasses") {
+
+ it("should offer auto exports for classes extending a trait") {
+ val ctor =
+ js.Dynamic.global.scala.scalajs.testsuite.jsinterop.AutoExportedTraitClass
+ expect(ctor).toBeDefined
+ expect(js.typeOf(ctor)).toEqual("function")
+
+ val obj1 = js.Dynamic.newInstance(ctor)()
+ expect(obj1).toBeDefined
+ expect(obj1.x).toBe(5)
+
+ val obj2 = js.Dynamic.newInstance(ctor)(100)
+ expect(obj2).toBeDefined
+ expect(obj2.x).toBe(100)
+ }
+
+ it("should offer auto exports for classes extending a class") {
+ val ctor =
+ js.Dynamic.global.scala.scalajs.testsuite.jsinterop.AutoExportedClassClass
+ expect(ctor).toBeDefined
+ expect(js.typeOf(ctor)).toEqual("function")
+
+ val obj1 = js.Dynamic.newInstance(ctor)()
+ expect(obj1).toBeDefined
+ expect(obj1.x).toBe(5)
+
+ val obj2 = js.Dynamic.newInstance(ctor)(100)
+ expect(obj2).toBeDefined
+ expect(obj2.x).toBe(100)
+ }
+
+ }
+
+}
+
+object ExportNameHolder {
+ final val className = "ConstantFoldedClassExport"
+ final val objectName = "ConstantFoldedObjectExport"
+ final val methodName = "myMethod"
+}
+
+@JSExport
+@JSExport("TheExportedObject")
+@JSExport("qualified.testobject.ExportedObject") // purposefully halfway the same as ExportedClass
+@JSExport(ExportNameHolder.objectName)
+object ExportedObject {
+ @JSExport
+ def witness: String = "witness"
+}
+
+@JSExport
+protected object ProtectedExportedObject {
+ @JSExport
+ def witness: String = "witness"
+}
+
+@JSExport
+@JSExport("TheExportedClass")
+@JSExport("qualified.testclass.ExportedClass") // purposefully halfway the same as ExportedObject
+@JSExport(ExportNameHolder.className)
+class ExportedClass(_x: Int) {
+ @JSExport
+ val x = _x
+}
+
+@JSExport
+protected class ProtectedExportedClass(_x: Int) {
+ @JSExport
+ val x = _x
+}
+
+@JSExport
+class ExportedVarArgClass(x: String*) {
+
+ @JSExport
+ def this(x: Int, y: String) = this(s"Number: <$x>", y)
+
+ @JSExport
+ def result = x.mkString("|")
+}
+
+@JSExport
+class ExportedDefaultArgClass(x: Int, y: Int, z: Int) {
+
+ @JSExport
+ def this(x: Int, y: Int = 5) = this(x, y, 100)
+
+ @JSExport
+ def result = x + y + z
+}
+
+@JSExport("org.ExportedUnderOrgObject")
+object ExportedUnderOrgObject
+
+@JSExportDescendentClasses
+@JSExportDescendentObjects
+trait AutoExportTrait
+
+object AutoExportedTraitObject extends AutoExportTrait
+class AutoExportedTraitClass(_x: Int) extends AutoExportTrait {
+ def this() = this(5)
+ @JSExport
+ def x: Int = _x
+}
+
+@JSExportDescendentClasses
+@JSExportDescendentObjects
+class AutoExportClass
+
+object AutoExportedClassObject extends AutoExportClass
+class AutoExportedClassClass(_x: Int) extends AutoExportTrait {
+ def this() = this(5)
+ @JSExport
+ def x: Int = _x
+}
+
+class SomeValueClass(val i: Int) extends AnyVal
+
+@JSExportNamed
+class ExportedNamedArgClass(x: Int = 1)(y: String = x.toString)(z: Boolean = y != "foo") {
+ @JSExport
+ val result = x + y + z
+}
+
+@JSExport
+class ExportClassSetterNamed_= {
+ @JSExport
+ val x = 1
+}
+
+@JSExport
+object ExportObjSetterNamed_= {
+ @JSExport
+ val x = 1
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/FunctionTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/FunctionTest.scala
new file mode 100644
index 0000000..4973e64
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/FunctionTest.scala
@@ -0,0 +1,41 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.jsinterop
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+object FunctionTest extends JasmineTest {
+
+ import js.Dynamic.{literal => lit}
+
+ describe("scala.scalajs.js.Function") {
+
+ it("should support call() with expanded arguments") {
+ val f = js.eval("""
+ var f = function() { return arguments; }; f;
+ """).asInstanceOf[js.Function]
+
+ expect(f.call(null, 42, true)).toEqual(lit(
+ `0` = 42,
+ `1` = true))
+ }
+
+ it("should support call() with the :_* notation to expand a Seq") {
+ val f = js.eval("""
+ var f = function() { return arguments; }; f;
+ """).asInstanceOf[js.Function]
+
+ val args = Seq[js.Any](42, true)
+ expect(f.call(null, args: _*)).toEqual(lit(
+ `0` = 42,
+ `1` = true))
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/MiscInteropTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/MiscInteropTest.scala
new file mode 100644
index 0000000..08211c3
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/MiscInteropTest.scala
@@ -0,0 +1,89 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.jsinterop
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+object MiscInteropTest extends JasmineTest {
+
+ describe("scala.scalajs.js.package") {
+
+ it("should provide an equivalent to `typeof x`") {
+ import js.typeOf
+ expect(typeOf(5)).toEqual("number")
+ expect(typeOf(false)).toEqual("boolean")
+ expect(typeOf("hello")).toEqual("string")
+ expect(typeOf(null)).toEqual("object")
+ expect(typeOf(new js.Object)).toEqual("object")
+ expect(typeOf(())).toEqual("undefined")
+ expect(typeOf(() => 42)).toEqual("function")
+ }
+ }
+
+ describe("scala.scalajs.js.Object") {
+
+ it("should provide an equivalent to `p in o`") {
+ import js.Object.{ hasProperty => hasProp }
+ val o = js.Dynamic.literal(foo = 5, bar = "foobar").asInstanceOf[js.Object]
+ expect(hasProp(o, "foo")).toBeTruthy
+ expect(hasProp(o, "foobar")).toBeFalsy
+ expect(hasProp(o, "toString")).toBeTruthy // in prototype
+ }
+
+ it("should respect evaluation order for `hasProperty`") {
+ import js.Object.{ hasProperty => hasProp }
+ var indicator = 3
+ def o() = {
+ indicator += 4
+ js.Dynamic.literal(x = 5).asInstanceOf[js.Object]
+ }
+ def p() = {
+ indicator *= 2
+ "x"
+ }
+ expect(hasProp(o(), p())).toBeTruthy
+ expect(indicator).toEqual(14)
+ }
+
+ it("should provide equivalent of JS for-in loop of {} - #13") {
+ val obj = js.eval("var dictionaryTest13 = { a: 'Scala.js', b: 7357 }; dictionaryTest13;")
+ val dict = obj.asInstanceOf[js.Dictionary[js.Any]]
+ var propCount = 0
+ var propString = ""
+
+ for (prop <- js.Object.properties(dict)) {
+ propCount += 1
+ propString += dict(prop)
+ }
+
+ expect(propCount).toEqual(2)
+ expect(propString).toEqual("Scala.js7357")
+ }
+
+ it("should provide equivalent of JS for-in loop of [] - #13") {
+ val obj = js.eval("var arrayTest13 = [ 7, 3, 5, 7 ]; arrayTest13;")
+ val array = obj.asInstanceOf[js.Dictionary[js.Any]]
+ var propCount = 0
+ var propString = ""
+
+ for (prop <- js.Object.properties(array)) {
+ propCount += 1
+ propString += array(prop)
+ }
+
+ expect(propCount).toEqual(4)
+ expect(propString).toEqual("7357")
+ }
+
+ it("should compile js.undefined") {
+ expect(() => js.undefined.asInstanceOf[js.prim.Number].toString(10)).toThrow
+ }
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/RuntimeLongTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/RuntimeLongTest.scala
new file mode 100644
index 0000000..589f379
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/RuntimeLongTest.scala
@@ -0,0 +1,140 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.jsinterop
+
+import scala.scalajs.runtime.RuntimeLong
+
+import org.scalajs.jasmine.JasmineExpectation
+import org.scalajs.jasminetest.JasmineTest
+
+import scala.util.Try
+
+/**
+ * test the runtime Long implementation directly
+ * does not depend on magic compiler Long rewriting
+ */
+object RuntimeLongTest extends JasmineTest {
+
+ import RuntimeLong.fromDouble
+
+ /** overload expect for long to add toString */
+ def expect(l: RuntimeLong): JasmineExpectation = expect(l.toHexString)
+
+ describe("scala.scalajs.runtime.RuntimeLong") {
+
+ def fromInt(x: Int): RuntimeLong = new RuntimeLong(x)
+
+ val maxInt = fromInt(Int.MaxValue)
+ val minInt = fromInt(Int.MinValue)
+ val one = fromInt(1)
+ val billion = fromInt(1000000000)
+
+ val `4503599627370510L` = new RuntimeLong( 14, 0, 256)
+ val `613354684553L` = new RuntimeLong( 639113, 146235, 0)
+ val `9863155567412L` = new RuntimeLong(2247476, 2351559, 0)
+ val `3632147899696541255L` = new RuntimeLong(1568327, 2954580, 206463)
+ val `7632147899696541255L` = new RuntimeLong(2616903, 1593290, 433837)
+
+ it("should correctly implement negation") {
+ expect(-fromInt(5)).toEqual("fffffffffffffffb")
+ expect(-fromInt(0)).toEqual("0")
+ expect(-minInt ).toEqual("80000000")
+ }
+
+ it("should correctly implement comparison") {
+ expect(fromInt(7) < fromInt(15)).toBe(true)
+ expect(fromInt(15) < fromInt(15)).toBe(false)
+ expect(fromInt(15) <= fromInt(15)).toBe(true)
+ expect(fromInt(14) <= fromInt(15)).toBe(true)
+ expect(fromInt(15) > fromInt(15)).toBe(false)
+ expect(fromInt(14) > fromInt(15)).toBe(false)
+ expect(fromInt(16) > fromInt(15)).toBe(true)
+ expect(fromInt(15) >= fromInt(15)).toBe(true)
+ expect(fromInt(14) >= fromInt(15)).toBe(false)
+ expect(fromInt(16) >= fromInt(15)).toBe(true)
+ }
+
+ it("should correctly implement addition") {
+ expect(fromInt(7) + fromInt(15)).toEqual("16")
+ expect( maxInt + maxInt ).toEqual("fffffffe")
+ expect( maxInt + one ).toEqual("80000000")
+ }
+
+ it("should correctly implement subtraction") {
+ expect(fromInt(7) - fromInt(15)).toEqual("fffffffffffffff8")
+ expect( maxInt - maxInt ).toEqual("0")
+ }
+
+ it("should correctly implement multiplication") {
+ expect(fromInt(7) * fromInt(15)).toEqual("69")
+ expect(fromInt(-7) * fromInt(15)).toEqual("ffffffffffffff97")
+ expect( maxInt * maxInt ).toEqual("3fffffff00000001")
+ expect(`4503599627370510L` * fromInt(-4)).toEqual("ffbfffffffffffc8")
+ }
+
+ it("should correctly implement division") {
+ expect( fromInt(7) / fromInt(15)).toEqual("0")
+ expect( fromInt(24) / fromInt(5) ).toEqual("4")
+ expect( fromInt(24) / fromInt(-5)).toEqual("fffffffffffffffc")
+ expect( maxInt / fromInt(-5)).toEqual("ffffffffe6666667")
+ expect( maxInt / billion ).toEqual("2")
+ expect((maxInt+one) / billion ).toEqual("2")
+ }
+
+ it("should correctly implement modulus") {
+ expect( fromInt(7) % fromInt(15)).toEqual("7")
+ expect( fromInt(24) % fromInt(5) ).toEqual("4")
+ expect( fromInt(24) % fromInt(-5)).toEqual("4")
+ expect( maxInt % billion ).toEqual("8ca6bff")
+ expect((maxInt+one) % billion ).toEqual("8ca6c00")
+ expect( maxInt % fromInt(-5)).toEqual("2")
+ }
+
+ it("should correctly implement toString") {
+ expect(maxInt.toString).toEqual("2147483647")
+ expect(fromInt(-50).toString).toEqual("-50")
+ expect(fromInt(-1000000000).toString).toEqual("-1000000000")
+ expect((maxInt+one).toString).toEqual("2147483648")
+ expect(minInt.toString).toEqual("-2147483648")
+ }
+
+ it("should correctly implement fromDouble") {
+ expect(fromDouble( 4.5)).toEqual("4")
+ expect(fromDouble(-4.5)).toEqual("fffffffffffffffc")
+ }
+
+ it("should correctly implement toDouble") {
+ expect(fromInt(5).toDouble).toEqual(5.0)
+ expect((maxInt+one).toDouble).toEqual(2147483648.0)
+ }
+
+ it("should correctly implement numberOfLeadingZeros") {
+ expect(fromInt( 0).numberOfLeadingZeros).toEqual(64)
+ expect(fromInt( 1).numberOfLeadingZeros).toEqual(63)
+ expect(fromInt(-1).numberOfLeadingZeros).toEqual(0)
+ expect(fromInt( 2).numberOfLeadingZeros).toEqual(62)
+ }
+
+ it("should implement hashCode() according to spec in j.l.Long") {
+ expect(fromInt(0 ).hashCode()).toEqual(0)
+ expect(fromInt(55 ).hashCode()).toEqual(55)
+ expect(fromInt(-12 ).hashCode()).toEqual(11)
+ expect(fromInt(10006548).hashCode()).toEqual(10006548)
+ expect(fromInt(-1098748).hashCode()).toEqual(1098747)
+
+ expect(`613354684553L` .hashCode()).toEqual(-825638905)
+ expect(`9863155567412L` .hashCode()).toEqual(1910653900)
+ expect(`3632147899696541255L`.hashCode()).toEqual(1735398658)
+ expect(`7632147899696541255L`.hashCode()).toEqual(-1689438124)
+ }
+
+ }
+
+}
+
+
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/StrangeNamedTests.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/StrangeNamedTests.scala
new file mode 100644
index 0000000..846c80b
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/StrangeNamedTests.scala
@@ -0,0 +1,28 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.jsinterop
+
+import org.scalajs.jasminetest.JasmineTest
+
+object `1_TestName` extends JasmineTest {
+ describe("a test with name 1_TestName") {
+ it("should run") {}
+ }
+}
+
+object eval extends JasmineTest {
+ describe("a test with name eval") {
+ it("should run") {}
+ }
+}
+
+object `\u1f4a7` extends JasmineTest {
+ describe("a test with name \u1f4a9") {
+ it("should run") {}
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ThisFunctionTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ThisFunctionTest.scala
new file mode 100644
index 0000000..4ac9058
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/ThisFunctionTest.scala
@@ -0,0 +1,70 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.jsinterop
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+object ThisFunctionTest extends JasmineTest {
+
+ describe("scala.scalajs.js.ThisFunctionN") {
+
+ it("should provide an implicit conversion from Scala function to js.ThisFunction") {
+ val g = js.eval("""
+ var g = function(f, x) { return f.call(x, 42, x.foo); }; g;
+ """).asInstanceOf[js.Function2[js.ThisFunction2[
+ js.Dynamic, Int, String, String], js.Dynamic, String]]
+
+ val f = { (thiz: js.Dynamic, v: Int, u: String) =>
+ expect(thiz).toBeTruthy()
+ expect(thiz.foobar).toEqual("foobar")
+ u + v
+ }
+ val obj = js.Object().asInstanceOf[js.Dynamic]
+ obj.foo = "foo"
+ obj.foobar = "foobar"
+ expect(g(f, obj)).toEqual("foo42")
+ }
+
+ it("should accept a lambda where a js.ThisFunction is expected") {
+ val g = js.eval("""
+ var g = function(f, x) { return f.call(x, 42, x.foo); }; g;
+ """).asInstanceOf[js.Function2[js.ThisFunction2[
+ js.Dynamic, Int, String, String], js.Dynamic, String]]
+
+ val obj = js.Object().asInstanceOf[js.Dynamic]
+ obj.foo = "foo"
+ obj.foobar = "foobar"
+ expect(g({ (thiz: js.Dynamic, v: Int, u: String) =>
+ expect(thiz).toBeTruthy()
+ expect(thiz.foobar).toEqual("foobar")
+ u + v
+ }, obj)).toEqual("foo42")
+ }
+
+ it("should bind the first argument to this when applying js.ThisFunctionN") {
+ val g = js.eval("""
+ var g = function(x) { return this.foo + ":" + x; }; g;
+ """).asInstanceOf[js.ThisFunction1[js.Dynamic, Int, String]]
+ val obj = js.Object().asInstanceOf[js.Dynamic]
+ obj.foo = "foo"
+ expect(g(obj, 42)).toEqual("foo:42")
+ }
+
+ it("should provide an implicit conversion from js.ThisFunction to Scala function") {
+ val g = js.eval("""
+ var g = function(x) { return this.foo + ":" + x; }; g;
+ """).asInstanceOf[js.ThisFunction1[js.Dynamic, Int, String]]
+ val f: scala.Function2[js.Dynamic, Int, String] = g
+ val obj = js.Object().asInstanceOf[js.Dynamic]
+ obj.foo = "foo"
+ expect(f(obj, 42)).toEqual("foo:42")
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/UndefOrTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/UndefOrTest.scala
new file mode 100644
index 0000000..28eae15
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/jsinterop/UndefOrTest.scala
@@ -0,0 +1,191 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.jsinterop
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+import js.annotation.JSExport
+
+object UndefOrTest extends JasmineTest {
+
+ def some[A](v: A): js.UndefOr[A] = v
+ def none[A]: js.UndefOr[A] = js.undefined
+
+ describe("scala.scalajs.js.UndefOr[A]") {
+
+ it("convert A to js.UndefOr[A]") {
+ val x: js.UndefOr[Int] = 42
+ expect(x.isEmpty).toBeFalsy
+ expect(x.isDefined).toBeTruthy
+ expect(x.nonEmpty).toBeTruthy
+ expect(x.get).toEqual(42)
+ }
+
+ it("convert undefined to js.UndefOr[A]") {
+ val x: js.UndefOr[Int] = js.undefined
+ expect(x.isEmpty).toBeTruthy
+ expect(x.isDefined).toBeFalsy
+ expect(x.nonEmpty).toBeFalsy
+ expect(() => x.get).toThrow
+ }
+
+ it("convert to js.Any when A <% js.Any") {
+ val x: js.UndefOr[Int] = 42
+ expect(x).toEqual(42)
+
+ val y: js.UndefOr[String] = js.undefined
+ expect(y).toBeUndefined
+ }
+
+ it("getOrElse") {
+ expect(some("hello").getOrElse("ko")).toEqual("hello")
+ expect(none[String].getOrElse("ok")).toEqual("ok")
+
+ var defaultComputed = false
+ expect(some("test") getOrElse {
+ defaultComputed = true
+ "ko"
+ }).toEqual("test")
+ expect(defaultComputed).toBeFalsy
+ }
+
+ it("orNull") {
+ expect(some("hello").orNull).toEqual("hello")
+ expect(none[String].orNull).toBeNull
+ }
+
+ it("map") {
+ expect(some(62).map(_ / 3)).toEqual(62 / 3)
+ expect(none[Int].map(_ / 3)).toBeUndefined
+ }
+
+ it("fold") {
+ expect(some(3).fold(10)(_ * 2)).toEqual(6)
+ expect(none[Int].fold(10)(_ * 2)).toEqual(10)
+ }
+
+ it("flatMap") {
+ def f(x: Int): js.UndefOr[Int] = if (x > 0) x+3 else js.undefined
+ expect(some(6).flatMap(f)).toEqual(9)
+ expect(some(-6).flatMap(f)).toBeUndefined
+ expect(none[Int].flatMap(f)).toBeUndefined
+ }
+
+ it("flatten") {
+ expect(some(some(7)).flatten.isDefined).toBeTruthy
+ expect(some(some(7)).flatten.get).toEqual(7)
+ expect(some(none[Int]).flatten.isDefined).toBeFalsy
+ expect(none[js.UndefOr[Int]].flatten.isDefined).toBeFalsy
+ }
+
+ it("filter") {
+ expect(some(7).filter(_ > 0).isDefined).toBeTruthy
+ expect(some(7).filter(_ > 0).get).toEqual(7)
+ expect(some(7).filter(_ < 0).isDefined).toBeFalsy
+ expect(none[Int].filter(_ < 0).isDefined).toBeFalsy
+ }
+
+ it("filterNot") {
+ expect(some(7).filterNot(_ < 0).isDefined).toBeTruthy
+ expect(some(7).filterNot(_ < 0).get).toEqual(7)
+ expect(some(7).filterNot(_ > 0).isDefined).toBeFalsy
+ expect(none[Int].filterNot(_ > 0).isDefined).toBeFalsy
+ }
+
+ it("exists") {
+ expect(some(7).exists(_ > 0)).toBeTruthy
+ expect(some(7).exists(_ < 0)).toBeFalsy
+ expect(none[Int].exists(_ > 0)).toBeFalsy
+ }
+
+ it("forall") {
+ expect(some(7).forall(_ > 0)).toBeTruthy
+ expect(some(7).forall(_ < 0)).toBeFalsy
+ expect(none[Int].forall(_ > 0)).toBeTruthy
+ }
+
+ it("foreach") {
+ var witness1 = 3
+ some(42).foreach(witness1 = _)
+ expect(witness1).toEqual(42)
+
+ var witness2 = 3
+ none[Int].foreach(witness2 = _)
+ expect(witness2).toEqual(3)
+ }
+
+ it("collect") {
+ expect(some("hello") collect {
+ case "hello" => "ok"
+ }).toEqual("ok")
+ expect(some("hello") collect {
+ case "notthis" => "ko"
+ }).toBeUndefined
+ expect(none[String] collect {
+ case "hello" => "ko"
+ }).toBeUndefined
+ }
+
+ it("collect should call guard at most once") {
+ var witness = 0
+ def guard(x: String) = {
+ witness += 1
+ true
+ }
+ expect(some("hello") collect {
+ case x @ "hello" if guard(x) => "ok"
+ }).toEqual("ok")
+ expect(witness).toEqual(1)
+ }
+
+ it("orElse") {
+ expect(some(true) orElse some(false)).toBeTruthy
+ expect(some("ok") orElse none).toEqual("ok")
+ expect(none orElse some("yes")).toEqual("yes")
+ expect(none orElse none).toBeUndefined
+ }
+
+ it("toList") {
+ import scala.scalajs.js.JSConverters._
+
+ expect(some("hello").toList.toJSArray).toEqual(js.Array("hello"))
+ expect(none[String].toList.toJSArray).toEqual(js.Array())
+ }
+
+ it("toLeft and toRight") {
+ expect(some("left").toLeft("right").isInstanceOf[Left[_, _]]).toBeTruthy
+ expect(none[String].toLeft("right").isInstanceOf[Right[_, _]]).toBeTruthy
+ expect(some("right").toRight("left").isInstanceOf[Right[_, _]]).toBeTruthy
+ expect(none[String].toRight("left").isInstanceOf[Left[_, _]]).toBeTruthy
+ }
+
+ it("toOption") {
+ expect(some("foo").toOption == Some("foo")).toBeTruthy
+ expect(none.toOption == None).toBeTruthy
+ }
+
+ }
+
+ describe("scala.scalajs.js.JSConverters.JSRichOption") {
+
+ import js.JSConverters._
+
+ it("should provide orUndefined") {
+ expect(Some("asdf").orUndefined).toEqual("asdf")
+ expect((None: Option[String]).orUndefined).toBeUndefined
+
+ // This doesn't work on 2.10, since it doesn't infer
+ // Nothing <:< js.Any to implicitly convert UndefOr[Nothing] to
+ // js.Any
+ // expect(None.orUndefined).toBeUndefined
+ }
+
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/library/ArrayOpsTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/library/ArrayOpsTest.scala
new file mode 100644
index 0000000..a1957a5
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/library/ArrayOpsTest.scala
@@ -0,0 +1,117 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.library
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+import scala.reflect.ClassTag
+
+import js.JSConverters._
+
+object ArrayOpsTest extends JasmineTest {
+
+ describe("scala.scalajs.js.ArrayOps") {
+
+ // Methods we actually implement
+
+ it("should implement apply") {
+ val array = js.Array(3,4,5,6,3,4)
+ val ops: js.ArrayOps[Int] = array
+
+ expect(ops(0)).toEqual(3)
+ expect(ops(3)).toEqual(6)
+
+ array(0) = 4
+ expect(ops(0)).toEqual(4)
+ }
+
+ it("should implement update") {
+ val array = js.Array(3,4,5,6,3,4)
+ val ops: js.ArrayOps[Int] = array
+
+ expect(array(1)).toEqual(4)
+ ops(1) = 5
+ expect(array(1)).toEqual(5)
+
+ ops(5) = 10
+ expect(array(5)).toEqual(10)
+ }
+
+ it("should implement length") {
+ val array = js.Array(3,4,5,6,3,4)
+ val ops: js.ArrayOps[Int] = array
+
+ expect(ops.length).toEqual(6)
+ array.push(1)
+ expect(ops.length).toEqual(7)
+ }
+
+ it("should implement seq") {
+ val array = js.Array(3,4,5,6,3,4)
+ val ops: js.ArrayOps[Int] = array
+ val seq = ops.seq
+
+ expect(seq.toList == List(3,4,5,6,3,4)).toBeTruthy
+ }
+
+ it("should implement reduceLeft") {
+ val array = js.Array(100, 6, 2, 56, -1)
+ expect(array.reduceLeft(_ - _)).toEqual(37)
+ expect(() => js.Array[Int]().reduceLeft(_ + _)).toThrow
+ }
+
+ it("should implement reduceRight") {
+ val array = js.Array("hello", "world")
+ expect(array.reduceRight(_ + ", " + _)).toEqual("hello, world")
+ expect(() => js.Array[Int]().reduceRight(_ + _)).toThrow
+ }
+
+ it("should implement ++") {
+ val left = js.Array("hello", "world")
+ val right = js.Array("and", "everyone", "else")
+ expect(left ++ right).toEqual(
+ js.Array("hello", "world", "and", "everyone", "else"))
+
+ val ints = js.Array(4, 3)
+ expect(left ++ ints).toEqual(js.Array("hello", "world", 4, 3))
+ }
+
+ // Some arbitrary methods to test the builders
+
+ it("should implement collect") {
+ def ct[A : ClassTag](x: A) = implicitly[ClassTag[A]]
+ val array = js.Array(3,4,5,6,3,4)
+ val res = array.collect {
+ case x if x > 4 => 2*x
+ }
+
+ expect(ct(res).runtimeClass == classOf[js.Array[Int]]).toBeTruthy
+ expect(res).toEqual(js.Array(10, 12))
+ }
+
+ it("should implement diff") {
+ val array = js.Array(1,2,1,3,1,10,9)
+ val diff = array.diff(Seq(1,3,9))
+ expect(diff).toEqual(js.Array(2,1,1,10))
+ }
+
+ it("should implement toList - #843") {
+ val array = js.Array(1,2,1,3,1,10,9)
+ val list = array.toList
+ expect(list.toJSArray).toEqual(array)
+ }
+
+ it("should implement to[T] - #843") {
+ val array = js.Array(1,2,1,3,1,10,9)
+ val list = array.to[List]
+ expect(list.toJSArray).toEqual(array)
+ }
+
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/library/WrappedArrayTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/library/WrappedArrayTest.scala
new file mode 100644
index 0000000..e4fed0a
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/library/WrappedArrayTest.scala
@@ -0,0 +1,118 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.library
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+import scala.collection.mutable
+
+object WrappedArrayTest extends JasmineTest {
+
+ describe("scala.scalajs.js.WrappedArray") {
+
+ // Methods we actually implement
+
+ it("should implement apply") {
+ val array = js.Array(3,4,5,6,3,4)
+ val seq: Seq[Int] = array
+
+ expect(seq(0)).toEqual(3)
+ expect(seq(3)).toEqual(6)
+
+ array(0) = 4
+ expect(seq(0)).toEqual(4)
+ }
+
+ it("should implement update") {
+ val array = js.Array(3,4,5,6,3,4)
+ val seq: mutable.Seq[Int] = array
+
+ expect(array(1)).toEqual(4)
+ seq(1) = 5
+ expect(array(1)).toEqual(5)
+
+ seq(5) = 10
+ expect(array(5)).toEqual(10)
+ }
+
+ it("should implement length") {
+ val array = js.Array(3,4,5,6,3,4)
+ val seq: Seq[Int] = array
+
+ expect(seq.length).toEqual(6)
+ array.push(1)
+ expect(seq.length).toEqual(7)
+ }
+
+ it("should implement +=:") {
+ val array = js.Array(5, 8, 9)
+ 3 +=: array
+ expect(array).toEqual(js.Array(3, 5, 8, 9))
+ }
+
+ it("should implement ++=:") {
+ val array = js.Array(5, 8, 9)
+ js.Array(2, 0) ++=: array
+ expect(array).toEqual(js.Array(2, 0, 5, 8, 9))
+ Seq(-3, -45, 1) ++=: array
+ expect(array).toEqual(js.Array(-3, -45, 1, 2, 0, 5, 8, 9))
+ }
+
+ it("should implement insertAll") {
+ val array = js.Array(5, 8, 9)
+ array.insertAll(2, js.Array(2, 0))
+ expect(array).toEqual(js.Array(5, 8, 2, 0, 9))
+ array.insertAll(1, Seq(-3, -45, 1))
+ expect(array).toEqual(js.Array(5, -3, -45, 1, 8, 2, 0, 9))
+ }
+
+ it("should implement remove") {
+ val array = js.Array(5, 8, 2, 0, 9)
+ expect(array.remove(1)).toEqual(8)
+ expect(array).toEqual(js.Array(5, 2, 0, 9))
+
+ array.remove(0, 3)
+ expect(array).toEqual(js.Array(9))
+ }
+
+ // Some arbitrary methods to test the builders
+
+ it("should implement collect") {
+ // Ascribe to right type here, so we'll actually produce a WrappedArray
+ val seq: js.WrappedArray[Int] = js.Array(3,4,5,6,3,4)
+ val res = seq.collect {
+ case x if x > 4 => 2*x
+ }
+
+ expect(res.getClass == classOf[js.WrappedArray[Int]]).toBeTruthy
+ expect(res.toList == List(10,12)).toBeTruthy
+ expect(res.array).toEqual(js.Array(10,12))
+ }
+
+ it("should implement diff") {
+ val seq: Seq[Int] = js.Array(1,2,1,3,1,10,9)
+ val diff = seq.diff(Seq(1,3,9))
+ expect(diff.toList == List(2,1,1,10)).toBeTruthy
+ }
+
+ it("should implement toList") {
+ val seq: Seq[Int] = js.Array(1,2,1,3,1,10,9)
+ val list = seq.toList
+ expect(list == List(1,2,1,3,1,10,9)).toBeTruthy
+ }
+
+ it("should implement to[T]") {
+ val seq: Seq[Int] = js.Array(1,2,1,3,1,10,9)
+ val list = seq.to[List]
+ expect(list == List(1,2,1,3,1,10,9)).toBeTruthy
+ }
+
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/library/WrappedDictionaryTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/library/WrappedDictionaryTest.scala
new file mode 100644
index 0000000..3b95f55
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/library/WrappedDictionaryTest.scala
@@ -0,0 +1,106 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.library
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+import scala.collection.mutable
+
+import scala.reflect.ClassTag
+
+object WrappedDictionaryTest extends JasmineTest {
+
+ describe("scala.scalajs.js.WrappedDictionary") {
+
+ // Methods we actually implement
+
+ it("should implement get") {
+ val map: mutable.Map[String, Any] =
+ js.Dictionary("a" -> "a", "b" -> 6, "e" -> js.undefined)
+ expect(map.get("a") == Some("a")).toBeTruthy
+ expect(map.get("b") == Some(6)).toBeTruthy
+ expect(map.get("e") == Some(())).toBeTruthy
+ expect(map.get("f") == None).toBeTruthy
+ }
+
+ it("should implement += and -=") {
+ val dict = js.Dictionary[String]()
+ val map: mutable.Map[String, String] = dict
+
+ expect(js.Object.properties(dict)).toEqual(js.Array())
+
+ map += "hello" -> "world"
+ expect(dict("hello")).toEqual("world")
+ map += "foo" -> "bar"
+ expect(dict("foo")).toEqual("bar")
+ map -= "hello"
+ expect(dict.get("hello").isDefined).toBeFalsy
+ expect(js.Object.properties(dict)).toEqual(js.Array("foo"))
+ }
+
+ it("should implement iterator") {
+ val elems = ('a' to 'e').map(_.toString).zip(1 to 5)
+ val dict = js.Dictionary[Int]()
+ val map: mutable.Map[String, Int] = dict
+
+ dict ++= elems
+
+ expect(map.iterator.toList.sorted.sameElements(elems)).toBeTruthy
+ }
+
+ // Some arbitrary methods to test the builders
+
+ it("should implement map") {
+ def ct[A : ClassTag](x: A) = implicitly[ClassTag[A]]
+ val dict = js.Dictionary[Int]()
+ dict ++= Seq("one" -> 1, "two" -> 2, "three" -> 3)
+
+ val mapChr = dict.map { case (k,v) => k(0) -> v * 2 }
+ val mapStr = dict.map { case (k,v) => k(0).toString -> v * 2 }
+
+ expect(ct(mapChr).runtimeClass == classOf[js.WrappedDictionary[_]]).toBeFalsy
+ expect(ct(mapStr).runtimeClass == classOf[js.WrappedDictionary[_]]).toBeTruthy
+
+ expect(mapChr.size).toBe(2)
+ expect(mapStr.size).toBe(2)
+ }
+
+ it("should implement withFilter") {
+ val dict = js.Dictionary[Int]()
+ val flt = dict.withFilter { case (k,v) => v > 5 || k == "a" }
+ def size = flt.map(x => x).size
+
+ expect(size).toBe(0)
+ dict += "a" -> 1
+ expect(size).toBe(1)
+ dict += "b" -> 2
+ expect(size).toBe(1)
+ dict += "c" -> 6
+ expect(size).toBe(2)
+ dict += "b" -> 7
+ expect(size).toBe(3)
+ dict -= "a"
+ expect(size).toBe(2)
+ }
+
+ it("should implement toList") {
+ val dict = js.Dictionary("a" -> "a", "b" -> 6, "e" -> js.undefined)
+ val list = dict.toList
+ expect(list.size).toBe(3)
+ }
+
+ it("should implement to[T]") {
+ val dict = js.Dictionary("a" -> "a", "b" -> 6, "e" -> js.undefined)
+ val list = dict.to[List]
+ expect(list.size).toBe(3)
+ }
+
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/niobuffer/BaseBufferTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/niobuffer/BaseBufferTest.scala
new file mode 100644
index 0000000..a1f1b71
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/niobuffer/BaseBufferTest.scala
@@ -0,0 +1,178 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.niobuffer
+
+import org.scalajs.jasminetest.JasmineTest
+
+import java.nio._
+
+abstract class BaseBufferTest extends JasmineTest {
+ trait BaseFactory {
+ type BufferType <: Buffer
+
+ val createsReadOnly: Boolean = false
+
+ def allocBuffer(capacity: Int): BufferType
+
+ def allocBuffer(pos: Int, limit: Int, capacity: Int): BufferType = {
+ val buf = allocBuffer(capacity)
+ buf.limit(limit).position(pos)
+ buf
+ }
+ }
+
+ type Factory <: BaseFactory
+
+ def commonTests(factory: Factory): Unit = {
+ import factory._
+
+ it("allocate") {
+ val buf = allocBuffer(10)
+ expect(buf.position).toEqual(0)
+ expect(buf.limit).toEqual(10)
+ expect(buf.capacity).toEqual(10)
+
+ expect(allocBuffer(0).capacity).toEqual(0)
+
+ expect(() => allocBuffer(-1)).toThrow
+
+ val buf2 = allocBuffer(1, 5, 9)
+ expect(buf2.position()).toEqual(1)
+ expect(buf2.limit()).toEqual(5)
+ expect(buf2.capacity()).toEqual(9)
+ }
+
+ it("isReadOnly()") {
+ val buf = allocBuffer(10)
+ if (createsReadOnly)
+ expect(buf.isReadOnly()).toBeTruthy
+ else
+ expect(buf.isReadOnly()).toBeFalsy
+ }
+
+ it("position") {
+ val buf = allocBuffer(10)
+ buf.position(3)
+ expect(buf.position()).toEqual(3)
+ buf.position(10)
+ expect(buf.position()).toEqual(10)
+ buf.position(0)
+ expect(buf.position()).toEqual(0)
+
+ expect(() => buf.position(-1)).toThrow
+ expect(() => buf.position(11)).toThrow
+ expect(buf.position()).toEqual(0)
+
+ val buf2 = allocBuffer(1, 5, 9)
+ expect(buf2.position()).toEqual(1)
+ buf2.position(5)
+ expect(buf2.position()).toEqual(5)
+ expect(() => buf2.position(6)).toThrow
+ expect(buf2.position()).toEqual(5)
+ }
+
+ it("limit") {
+ val buf = allocBuffer(10)
+ buf.position(3)
+ buf.limit(7)
+ expect(buf.limit()).toEqual(7)
+ expect(buf.position()).toEqual(3)
+ expect(() => buf.limit(11)).toThrow
+ expect(buf.limit()).toEqual(7)
+ expect(() => buf.limit(-1)).toThrow
+ expect(buf.limit()).toEqual(7)
+ expect(buf.position()).toEqual(3)
+
+ buf.position(5)
+ buf.limit(4)
+ expect(buf.limit()).toEqual(4)
+ expect(buf.position()).toEqual(4)
+ }
+
+ it("mark() and reset()") {
+ val buf = allocBuffer(10)
+
+ // Initially, the mark should not be set
+ expect(() => buf.reset()).toThrow
+
+ // Simple test
+ buf.position(3)
+ buf.mark()
+ buf.position(8)
+ buf.reset()
+ expect(buf.position()).toEqual(3)
+
+ // reset() should not have cleared the mark
+ buf.position(5)
+ buf.reset()
+ expect(buf.position()).toEqual(3)
+
+ // setting position() below the mark should clear the mark
+ buf.position(2)
+ expect(() => buf.reset()).toThrow
+ }
+
+ it("clear()") {
+ val buf = allocBuffer(3, 6, 10)
+ buf.mark()
+ buf.position(4)
+
+ buf.clear()
+ expect(buf.position()).toEqual(0)
+ expect(buf.limit()).toEqual(10) // the capacity
+ expect(buf.capacity()).toEqual(10)
+ expect(() => buf.reset()).toThrow
+ }
+
+ it("flip()") {
+ val buf = allocBuffer(3, 6, 10)
+ buf.mark()
+ buf.position(4)
+
+ buf.flip()
+ expect(buf.position()).toEqual(0)
+ expect(buf.limit()).toEqual(4) // old position
+ expect(buf.capacity()).toEqual(10)
+ expect(() => buf.reset()).toThrow
+ }
+
+ it("rewind()") {
+ val buf = allocBuffer(3, 6, 10)
+ buf.mark()
+ buf.position(4)
+
+ buf.rewind()
+ expect(buf.position()).toEqual(0)
+ expect(buf.limit()).toEqual(6) // unchanged
+ expect(buf.capacity()).toEqual(10)
+ expect(() => buf.reset()).toThrow
+ }
+
+ it("remaining() and hasRemaining()") {
+ val buf = allocBuffer(3, 7, 10)
+ expect(buf.remaining()).toEqual(7-3)
+ expect(buf.hasRemaining()).toBeTruthy
+
+ buf.position(6)
+ expect(buf.remaining()).toEqual(7-6)
+ expect(buf.hasRemaining()).toBeTruthy
+
+ buf.limit(9)
+ expect(buf.remaining()).toEqual(9-6)
+ expect(buf.hasRemaining()).toBeTruthy
+
+ buf.limit(2)
+ expect(buf.remaining()).toEqual(0)
+ expect(buf.hasRemaining()).toBeFalsy
+
+ buf.position(0)
+ expect(buf.remaining()).toEqual(2)
+ expect(buf.hasRemaining()).toBeTruthy
+ }
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/niobuffer/ByteBufferTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/niobuffer/ByteBufferTest.scala
new file mode 100644
index 0000000..9ec831f
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/niobuffer/ByteBufferTest.scala
@@ -0,0 +1,330 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.niobuffer
+
+import java.nio._
+
+import scala.scalajs.js
+import js.JSConverters._
+
+object ByteBufferTest extends BaseBufferTest {
+ trait Factory extends BaseFactory {
+ type BufferType = ByteBuffer
+
+ def withContent(capacity: Int, content: Byte*): ByteBuffer =
+ withContent(0, capacity, capacity, content: _*)
+
+ def withContent(pos: Int, limit: Int, capacity: Int,
+ content: Byte*): ByteBuffer = {
+ val buf = allocBuffer(pos, limit, capacity)
+ buf.put(content.toArray)
+ buf.position(pos)
+ buf
+ }
+ }
+
+ def byteRange(start: Int, end: Int): Array[Byte] =
+ (start until end).map(_.toByte).toArray
+
+ def defineTests(factory: Factory): Unit = {
+ import factory._
+
+ commonTests(factory)
+
+ it("absolute get()") {
+ val buf = withContent(10, byteRange(0, 10): _*)
+ expect(buf.get(0)).toEqual(0)
+ expect(buf.position()).toEqual(0)
+ expect(buf.get(3)).toEqual(3)
+ expect(buf.position()).toEqual(0)
+
+ expect(() => buf.get(-1)).toThrow
+ expect(() => buf.get(15)).toThrow
+
+ buf.limit(4)
+ expect(() => buf.get(5)).toThrow
+ }
+
+
+ if (!createsReadOnly) {
+ it("absolute put()") {
+ val buf = allocBuffer(10)
+ buf.put(5, 42)
+ expect(buf.position()).toEqual(0)
+ buf.put(3, 2)
+ expect(buf.get(3)).toEqual(2)
+ expect(buf.get(5)).toEqual(42)
+ expect(buf.get(7)).toEqual(0)
+
+ expect(() => buf.put(-1, 2)).toThrow
+ expect(() => buf.put(14, 9)).toThrow
+
+ buf.limit(4)
+ expect(() => buf.put(4, 1)).toThrow
+ }
+ } else {
+ it("absolute put() - read-only") {
+ val buf = allocBuffer(10)
+ expect(() => buf.put(2, 1)).toThrow
+ expect(buf.get(2)).toEqual(0)
+ expect(buf.position()).toEqual(0)
+
+ expect(() => buf.put(-2, 1)).toThrow
+ expect(() => buf.put(12, 1)).toThrow
+ }
+ }
+
+ it("relative get()") {
+ val buf = withContent(10, byteRange(0, 10): _*)
+ expect(buf.get()).toEqual(0)
+ expect(buf.position()).toEqual(1)
+ buf.position(3)
+ expect(buf.get()).toEqual(3)
+ expect(buf.position()).toEqual(4)
+
+ buf.limit(4)
+ expect(() => buf.get()).toThrow
+ }
+
+ if (!createsReadOnly) {
+ it("relative put()") {
+ val buf = allocBuffer(10)
+ buf.put(5.toByte)
+ expect(buf.position()).toEqual(1)
+ expect(buf.get(0)).toEqual(5)
+
+ buf.position(3)
+ buf.put(36.toByte)
+ expect(buf.position()).toEqual(4)
+ expect(buf.get(3)).toEqual(36)
+
+ buf.position(10)
+ expect(() => buf.put(3.toByte)).toThrow
+ }
+ } else {
+ it("relative put() - read-only") {
+ val buf = allocBuffer(10)
+ expect(() => buf.put(5.toByte)).toThrow
+ expect(buf.position()).toEqual(0)
+ expect(buf.get(0)).toEqual(0)
+
+ buf.position(10)
+ expect(() => buf.put(3.toByte)).toThrow
+ }
+ }
+
+ it("relative bulk get()") {
+ val buf = withContent(10, byteRange(0, 10): _*)
+ val a = new Array[Byte](4)
+ buf.get(a)
+ expect(a.toJSArray).toEqual(js.Array(0, 1, 2, 3))
+ expect(buf.position()).toEqual(4)
+
+ buf.position(6)
+ buf.get(a, 1, 2)
+ expect(a.toJSArray).toEqual(js.Array(0, 6, 7, 3))
+ expect(buf.position()).toEqual(8)
+
+ expect(() => buf.get(a)).toThrow
+ expect(buf.position()).toEqual(8)
+ expect(a.toJSArray).toEqual(js.Array(0, 6, 7, 3))
+ }
+
+ if (!createsReadOnly) {
+ it("relative bulk put()") {
+ val buf = allocBuffer(10)
+ buf.put(Array[Byte](6, 7, 12))
+ expect((0 to 3).map(buf.get(_)).toJSArray).toEqual(js.Array(6, 7, 12, 0))
+ expect(buf.position()).toEqual(3)
+
+ buf.position(2)
+ buf.put(Array[Byte](44, 55, 66, 77, 88), 2, 2)
+ expect((0 to 4).map(buf.get(_)).toJSArray).toEqual(js.Array(6, 7, 66, 77, 0))
+ expect(buf.position()).toEqual(4)
+
+ expect(() => buf.put(Array.fill[Byte](10)(0))).toThrow
+ expect(buf.position()).toEqual(4)
+ expect((0 to 4).map(buf.get(_)).toJSArray).toEqual(js.Array(6, 7, 66, 77, 0))
+ }
+ } else {
+ it("relative bulk put() - read-only") {
+ val buf = allocBuffer(10)
+ expect(() => buf.put(Array[Byte](6, 7, 12))).toThrow
+ expect(buf.position()).toEqual(0)
+ expect(buf.get(0)).toEqual(0)
+
+ buf.position(8)
+ expect(() => buf.put(Array[Byte](6, 7, 12))).toThrow
+ expect(buf.position()).toEqual(8)
+ expect(buf.get(8)).toEqual(0)
+ }
+ }
+
+ if (!createsReadOnly) {
+ it("compact()") {
+ val buf = withContent(10, byteRange(0, 10): _*)
+ buf.position(6)
+ buf.mark()
+
+ buf.compact()
+ expect(buf.position()).toEqual(4)
+ expect(buf.limit()).toEqual(10)
+ expect(() => buf.reset()).toThrow
+
+ for (i <- 0 until 4)
+ expect(buf.get(i)).toEqual(i + 6)
+ }
+ } else {
+ it("compact() - read-only") {
+ val buf = allocBuffer(10)
+ expect(() => buf.compact()).toThrow
+ }
+ }
+
+ it("slice()" + (if (createsReadOnly) " - read-only" else "")) {
+ val buf1 = withContent(10, byteRange(0, 10): _*)
+ buf1.position(3)
+ buf1.limit(7)
+ buf1.mark()
+ val buf2 = buf1.slice()
+ expect(buf2.position()).toEqual(0)
+ expect(buf2.limit()).toEqual(4)
+ expect(buf2.capacity()).toEqual(4)
+ expect(() => buf2.reset()).toThrow
+ expect(buf2.get(1)).toEqual(4)
+
+ buf2.position(2)
+ expect(buf1.position()).toEqual(3)
+
+ if (!createsReadOnly) {
+ buf2.put(89.toByte)
+ expect(buf1.get(5)).toEqual(89)
+ expect(buf2.position()).toEqual(3)
+ expect(buf1.position()).toEqual(3)
+ }
+
+ expect(() => buf2.limit(5)).toThrow
+ expect(buf2.limit()).toEqual(4)
+
+ buf2.limit(3)
+ expect(buf1.limit()).toEqual(7)
+
+ if (!createsReadOnly) {
+ buf1.put(3, 23)
+ expect(buf2.get(0)).toEqual(23)
+ }
+ }
+
+ it("duplicate()" + (if (createsReadOnly) " - read-only" else "")) {
+ val buf1 = withContent(10, byteRange(0, 10): _*)
+ buf1.position(3)
+ buf1.limit(7)
+ buf1.mark()
+ val buf2 = buf1.duplicate()
+ expect(buf2.position()).toEqual(3)
+ expect(buf2.limit()).toEqual(7)
+ expect(buf2.capacity()).toEqual(10)
+ expect(buf2.get(4)).toEqual(4)
+
+ buf2.position(4)
+ expect(buf1.position()).toEqual(3)
+ expect(buf2.position()).toEqual(4)
+
+ buf2.reset()
+ expect(buf2.position()).toEqual(3)
+ buf2.position(4)
+
+ if (!createsReadOnly) {
+ buf2.put(89.toByte)
+ expect(buf1.get(4)).toEqual(89)
+ expect(buf2.position()).toEqual(5)
+ expect(buf1.position()).toEqual(3)
+ }
+
+ buf2.limit(5)
+ expect(buf1.limit()).toEqual(7)
+
+ if (!createsReadOnly) {
+ buf1.put(6, 23)
+ buf2.limit(10)
+ expect(buf2.get(6)).toEqual(23)
+ }
+ }
+ }
+
+ describe("Allocated ByteBuffer") {
+ defineTests(new Factory {
+ def allocBuffer(capacity: Int): ByteBuffer =
+ ByteBuffer.allocate(capacity)
+ })
+ }
+
+ class WrappedByteBufferFactory extends Factory {
+ def allocBuffer(capacity: Int): ByteBuffer =
+ ByteBuffer.wrap(new Array[Byte](capacity))
+
+ override def allocBuffer(pos: Int, limit: Int, capacity: Int): ByteBuffer =
+ ByteBuffer.wrap(new Array[Byte](capacity), pos, limit-pos)
+
+ override def withContent(pos: Int, limit: Int, capacity: Int,
+ content: Byte*): ByteBuffer = {
+ val after = capacity - (pos + content.size)
+ ByteBuffer.wrap(
+ (Seq.fill(pos)(0.toByte) ++ content ++ Seq.fill(after)(0.toByte)).toArray,
+ pos, limit-pos)
+ }
+ }
+
+ describe("Wrapped ByteBuffer") {
+ defineTests(new WrappedByteBufferFactory)
+ }
+
+ describe("Read-only wrapped ByteBuffer") {
+ defineTests(new WrappedByteBufferFactory {
+ override val createsReadOnly = true
+
+ override def allocBuffer(capacity: Int): ByteBuffer =
+ super.allocBuffer(capacity).asReadOnlyBuffer()
+
+ override def allocBuffer(pos: Int, limit: Int, capacity: Int): ByteBuffer =
+ super.allocBuffer(pos, limit, capacity).asReadOnlyBuffer()
+
+ override def withContent(pos: Int, limit: Int, capacity: Int,
+ content: Byte*): ByteBuffer =
+ super.withContent(pos, limit, capacity, content: _*).asReadOnlyBuffer()
+ })
+ }
+
+ describe("Sliced ByteBuffer") {
+ defineTests(new Factory {
+ def allocBuffer(capacity: Int): ByteBuffer = {
+ if (capacity < 0)
+ throw new IllegalArgumentException
+ val buf = ByteBuffer.allocate(capacity+25)
+ buf.position(17)
+ buf.limit(17+capacity)
+ buf.slice()
+ }
+
+ override def withContent(pos: Int, limit: Int, capacity: Int,
+ content: Byte*): ByteBuffer = {
+ if (!(0 <= pos && pos <= limit && limit <= capacity))
+ throw new IllegalArgumentException
+ val buf = ByteBuffer.allocate(capacity+25)
+ buf.position(9+pos)
+ buf.put(content.toArray)
+ buf.position(9)
+ buf.limit(9+capacity)
+ val buf2 = buf.slice()
+ buf2.position(pos)
+ buf2.limit(limit)
+ buf2
+ }
+ })
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/niobuffer/CharBufferTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/niobuffer/CharBufferTest.scala
new file mode 100644
index 0000000..b13c478
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/niobuffer/CharBufferTest.scala
@@ -0,0 +1,388 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.niobuffer
+
+import java.nio._
+
+import scala.scalajs.js
+import js.JSConverters._
+
+object CharBufferTest extends BaseBufferTest {
+ trait Factory extends BaseFactory {
+ type BufferType = CharBuffer
+
+ def withContent(capacity: Int, content: Char*): CharBuffer =
+ withContent(0, capacity, capacity, content: _*)
+
+ def withContent(pos: Int, limit: Int, capacity: Int,
+ content: Char*): CharBuffer = {
+ val buf = allocBuffer(pos, limit, capacity)
+ buf.put(content.toArray)
+ buf.position(pos)
+ buf
+ }
+ }
+
+ def zeros(n: Int): String =
+ "\u0000"*n
+
+ def charRange(start: Int, end: Int): Array[Char] =
+ (start until end).map(_.toChar).toArray
+
+ def defineTests(factory: Factory): Unit = {
+ import factory._
+
+ commonTests(factory)
+
+ it("absolute get()") {
+ val buf = withContent(10, charRange(0, 10): _*)
+ expect(buf.get(0)).toEqual(0)
+ expect(buf.position()).toEqual(0)
+ expect(buf.get(3)).toEqual(3)
+ expect(buf.position()).toEqual(0)
+
+ expect(() => buf.get(-1)).toThrow
+ expect(() => buf.get(15)).toThrow
+
+ buf.limit(4)
+ expect(() => buf.get(5)).toThrow
+ }
+
+
+ if (!createsReadOnly) {
+ it("absolute put()") {
+ val buf = allocBuffer(10)
+ buf.put(5, 42)
+ expect(buf.position()).toEqual(0)
+ buf.put(3, 2)
+ expect(buf.get(3)).toEqual(2)
+ expect(buf.get(5)).toEqual(42)
+ expect(buf.get(7)).toEqual(0)
+
+ expect(() => buf.put(-1, 2)).toThrow
+ expect(() => buf.put(14, 9)).toThrow
+
+ buf.limit(4)
+ expect(() => buf.put(4, 1)).toThrow
+ }
+ } else {
+ it("absolute put() - read-only") {
+ val buf = allocBuffer(10)
+ expect(() => buf.put(2, 1)).toThrow
+ expect(buf.get(2)).toEqual(0)
+ expect(buf.position()).toEqual(0)
+
+ expect(() => buf.put(-2, 1)).toThrow
+ expect(() => buf.put(12, 1)).toThrow
+ }
+ }
+
+ it("relative get()") {
+ val buf = withContent(10, charRange(0, 10): _*)
+ expect(buf.get()).toEqual(0)
+ expect(buf.position()).toEqual(1)
+ buf.position(3)
+ expect(buf.get()).toEqual(3)
+ expect(buf.position()).toEqual(4)
+
+ buf.limit(4)
+ expect(() => buf.get()).toThrow
+ }
+
+ if (!createsReadOnly) {
+ it("relative put()") {
+ val buf = allocBuffer(10)
+ buf.put(5.toChar)
+ expect(buf.position()).toEqual(1)
+ expect(buf.get(0)).toEqual(5)
+
+ buf.position(3)
+ buf.put(36.toChar)
+ expect(buf.position()).toEqual(4)
+ expect(buf.get(3)).toEqual(36)
+
+ buf.position(10)
+ expect(() => buf.put(3.toChar)).toThrow
+ }
+ } else {
+ it("relative put() - read-only") {
+ val buf = allocBuffer(10)
+ expect(() => buf.put(5.toChar)).toThrow
+ expect(buf.position()).toEqual(0)
+ expect(buf.get(0)).toEqual(0)
+
+ buf.position(10)
+ expect(() => buf.put(3.toChar)).toThrow
+ }
+ }
+
+ it("relative bulk get()") {
+ val buf = withContent(10, charRange(0, 10): _*)
+ val a = new Array[Char](4)
+ buf.get(a)
+ expect(a.map(_.toInt).toJSArray).toEqual(js.Array(0, 1, 2, 3))
+ expect(buf.position()).toEqual(4)
+
+ buf.position(6)
+ buf.get(a, 1, 2)
+ expect(a.map(_.toInt).toJSArray).toEqual(js.Array(0, 6, 7, 3))
+ expect(buf.position()).toEqual(8)
+
+ expect(() => buf.get(a)).toThrow
+ expect(buf.position()).toEqual(8)
+ expect(a.map(_.toInt).toJSArray).toEqual(js.Array(0, 6, 7, 3))
+ }
+
+ if (!createsReadOnly) {
+ it("relative bulk put()") {
+ val buf = allocBuffer(10)
+ buf.put(Array[Char](6, 7, 12))
+ expect((0 to 3).map(buf.get(_).toInt).toJSArray).toEqual(js.Array(6, 7, 12, 0))
+ expect(buf.position()).toEqual(3)
+
+ buf.position(2)
+ buf.put(Array[Char](44, 55, 66, 77, 88), 2, 2)
+ expect((0 to 4).map(buf.get(_).toInt).toJSArray).toEqual(js.Array(6, 7, 66, 77, 0))
+ expect(buf.position()).toEqual(4)
+
+ expect(() => buf.put(Array.fill[Char](10)(0))).toThrow
+ expect(buf.position()).toEqual(4)
+ expect((0 to 4).map(buf.get(_).toInt).toJSArray).toEqual(js.Array(6, 7, 66, 77, 0))
+ }
+ } else {
+ it("relative bulk put() - read-only") {
+ val buf = allocBuffer(10)
+ expect(() => buf.put(Array[Char](6, 7, 12))).toThrow
+ expect(buf.position()).toEqual(0)
+ expect(buf.get(0)).toEqual(0)
+
+ buf.position(8)
+ expect(() => buf.put(Array[Char](6, 7, 12))).toThrow
+ expect(buf.position()).toEqual(8)
+ expect(buf.get(8)).toEqual(0)
+ }
+ }
+
+ if (!createsReadOnly) {
+ it("compact()") {
+ val buf = withContent(10, charRange(0, 10): _*)
+ buf.position(6)
+ buf.mark()
+
+ buf.compact()
+ expect(buf.position()).toEqual(4)
+ expect(buf.limit()).toEqual(10)
+ expect(() => buf.reset()).toThrow
+
+ for (i <- 0 until 4)
+ expect(buf.get(i).toInt).toEqual(i + 6)
+ }
+ } else {
+ it("compact() - read-only") {
+ val buf = allocBuffer(10)
+ expect(() => buf.compact()).toThrow
+ }
+ }
+
+ it("slice()" + (if (createsReadOnly) " - read-only" else "")) {
+ val buf1 = withContent(10, charRange(0, 10): _*)
+ buf1.position(3)
+ buf1.limit(7)
+ buf1.mark()
+ val buf2 = buf1.slice()
+ expect(buf2.position()).toEqual(0)
+ expect(buf2.limit()).toEqual(4)
+ expect(buf2.capacity()).toEqual(4)
+ expect(() => buf2.reset()).toThrow
+ expect(buf2.get(1)).toEqual(4)
+
+ buf2.position(2)
+ expect(buf1.position()).toEqual(3)
+
+ if (!createsReadOnly) {
+ buf2.put(89.toChar)
+ expect(buf1.get(5)).toEqual(89)
+ expect(buf2.position()).toEqual(3)
+ expect(buf1.position()).toEqual(3)
+ }
+
+ expect(() => buf2.limit(5)).toThrow
+ expect(buf2.limit()).toEqual(4)
+
+ buf2.limit(3)
+ expect(buf1.limit()).toEqual(7)
+
+ if (!createsReadOnly) {
+ buf1.put(3, 23)
+ expect(buf2.get(0)).toEqual(23)
+ }
+ }
+
+ it("duplicate()" + (if (createsReadOnly) " - read-only" else "")) {
+ val buf1 = withContent(10, charRange(0, 10): _*)
+ buf1.position(3)
+ buf1.limit(7)
+ buf1.mark()
+ val buf2 = buf1.duplicate()
+ expect(buf2.position()).toEqual(3)
+ expect(buf2.limit()).toEqual(7)
+ expect(buf2.capacity()).toEqual(10)
+ expect(buf2.get(4)).toEqual(4)
+
+ buf2.position(4)
+ expect(buf1.position()).toEqual(3)
+ expect(buf2.position()).toEqual(4)
+
+ buf2.reset()
+ expect(buf2.position()).toEqual(3)
+ buf2.position(4)
+
+ if (!createsReadOnly) {
+ buf2.put(89.toChar)
+ expect(buf1.get(4)).toEqual(89)
+ expect(buf2.position()).toEqual(5)
+ expect(buf1.position()).toEqual(3)
+ }
+
+ buf2.limit(5)
+ expect(buf1.limit()).toEqual(7)
+
+ if (!createsReadOnly) {
+ buf1.put(6, 23)
+ buf2.limit(10)
+ expect(buf2.get(6)).toEqual(23)
+ }
+ }
+ }
+
+ describe("Allocated CharBuffer") {
+ defineTests(new Factory {
+ def allocBuffer(capacity: Int): CharBuffer =
+ CharBuffer.allocate(capacity)
+ })
+ }
+
+ class WrappedCharBufferFactory extends Factory {
+ def allocBuffer(capacity: Int): CharBuffer =
+ CharBuffer.wrap(new Array[Char](capacity))
+
+ override def allocBuffer(pos: Int, limit: Int, capacity: Int): CharBuffer =
+ CharBuffer.wrap(new Array[Char](capacity), pos, limit-pos)
+
+ override def withContent(pos: Int, limit: Int, capacity: Int,
+ content: Char*): CharBuffer = {
+ val after = capacity - (pos + content.size)
+ CharBuffer.wrap(
+ (Seq.fill(pos)(0.toChar) ++ content ++ Seq.fill(after)(0.toChar)).toArray,
+ pos, limit-pos)
+ }
+ }
+
+ describe("Wrapped CharBuffer") {
+ defineTests(new WrappedCharBufferFactory)
+ }
+
+ describe("Read-only wrapped CharBuffer") {
+ defineTests(new WrappedCharBufferFactory {
+ override val createsReadOnly = true
+
+ override def allocBuffer(capacity: Int): CharBuffer =
+ super.allocBuffer(capacity).asReadOnlyBuffer()
+
+ override def allocBuffer(pos: Int, limit: Int, capacity: Int): CharBuffer =
+ super.allocBuffer(pos, limit, capacity).asReadOnlyBuffer()
+
+ override def withContent(pos: Int, limit: Int, capacity: Int,
+ content: Char*): CharBuffer =
+ super.withContent(pos, limit, capacity, content: _*).asReadOnlyBuffer()
+ })
+ }
+
+ describe("CharBuffer wrapping a CharSequence") {
+ defineTests(new Factory {
+ override val createsReadOnly = true
+
+ def allocBuffer(capacity: Int): CharBuffer = {
+ if (capacity < 0)
+ throw new IllegalArgumentException
+ CharBuffer.wrap(zeros(capacity))
+ }
+
+ override def allocBuffer(pos: Int, limit: Int, capacity: Int): CharBuffer = {
+ if (capacity < 0)
+ throw new IllegalArgumentException
+ CharBuffer.wrap(zeros(capacity), pos, limit-pos)
+ }
+
+ override def withContent(pos: Int, limit: Int, capacity: Int,
+ content: Char*): CharBuffer = {
+ val after = capacity - (pos + content.size)
+ CharBuffer.wrap(
+ zeros(pos) + content.mkString + zeros(after),
+ pos, limit-pos)
+ }
+ })
+ }
+
+ describe("Sliced CharBuffer") {
+ defineTests(new Factory {
+ def allocBuffer(capacity: Int): CharBuffer = {
+ if (capacity < 0)
+ throw new IllegalArgumentException
+ val buf = CharBuffer.allocate(capacity+25)
+ buf.position(17)
+ buf.limit(17+capacity)
+ buf.slice()
+ }
+
+ override def withContent(pos: Int, limit: Int, capacity: Int,
+ content: Char*): CharBuffer = {
+ if (!(0 <= pos && pos <= limit && limit <= capacity))
+ throw new IllegalArgumentException
+ val buf = CharBuffer.allocate(capacity+25)
+ buf.position(9+pos)
+ buf.put(content.toArray)
+ buf.position(9)
+ buf.limit(9+capacity)
+ val buf2 = buf.slice()
+ buf2.position(pos)
+ buf2.limit(limit)
+ buf2
+ }
+ })
+ }
+
+ describe("Sliced CharBuffer wrapping a CharSequence") {
+ defineTests(new Factory {
+ override val createsReadOnly = true
+
+ def allocBuffer(capacity: Int): CharBuffer = {
+ if (capacity < 0)
+ throw new IllegalArgumentException
+ val buf = CharBuffer.wrap(zeros(capacity+25))
+ buf.position(17)
+ buf.limit(17+capacity)
+ buf.slice()
+ }
+
+ override def withContent(pos: Int, limit: Int, capacity: Int,
+ content: Char*): CharBuffer = {
+ if (!(0 <= pos && pos <= limit && limit <= capacity))
+ throw new IllegalArgumentException
+ val after = (25+capacity) - (9+pos+content.size)
+ val buf = CharBuffer.wrap(zeros(9+pos) + content.mkString + zeros(after))
+ buf.position(9)
+ buf.limit(9+capacity)
+ val buf2 = buf.slice()
+ buf2.position(pos)
+ buf2.limit(limit)
+ buf2
+ }
+ })
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/BaseCharsetTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/BaseCharsetTest.scala
new file mode 100644
index 0000000..adda838
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/BaseCharsetTest.scala
@@ -0,0 +1,234 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.niocharset
+
+import scala.language.implicitConversions
+
+import scala.util._
+
+import java.nio._
+import java.nio.charset._
+
+import scala.scalajs.js
+import js.JSConverters._
+
+import org.scalajs.jasminetest.JasmineTest
+
+class BaseCharsetTest(val charset: Charset) extends JasmineTest {
+ import BaseCharsetTest._
+
+ protected val AllErrorActions = Seq(
+ CodingErrorAction.IGNORE,
+ CodingErrorAction.REPLACE,
+ CodingErrorAction.REPORT)
+
+ protected val ReportActions = Seq(
+ CodingErrorAction.REPORT)
+
+ protected def testDecode(in: ByteBuffer)(
+ outParts: OutPart[CharBuffer]*): Unit = {
+
+ def testOneConfig(malformedAction: CodingErrorAction,
+ unmappableAction: CodingErrorAction): Unit = {
+
+ val decoder = charset.newDecoder()
+ decoder.onMalformedInput(malformedAction)
+ decoder.onUnmappableCharacter(unmappableAction)
+
+ val actualTry = Try {
+ in.mark()
+ val buf =
+ try decoder.decode(in)
+ finally in.reset()
+ val actualChars = new Array[Char](buf.remaining())
+ buf.get(actualChars)
+ actualChars
+ }
+
+ val expectedTry = Try {
+ val expectedChars = Array.newBuilder[Char]
+ outParts foreach {
+ case BufferPart(buf) =>
+ val bufArray = new Array[Char](buf.remaining)
+ buf.mark()
+ try buf.get(bufArray)
+ finally buf.reset()
+ expectedChars ++= bufArray
+ case Malformed(len) =>
+ malformedAction match {
+ case CodingErrorAction.IGNORE =>
+ case CodingErrorAction.REPLACE =>
+ expectedChars ++= decoder.replacement()
+ case CodingErrorAction.REPORT =>
+ throw new MalformedInputException(len)
+ }
+ case Unmappable(len) =>
+ unmappableAction match {
+ case CodingErrorAction.IGNORE =>
+ case CodingErrorAction.REPLACE =>
+ expectedChars ++= decoder.replacement()
+ case CodingErrorAction.REPORT =>
+ throw new UnmappableCharacterException(len)
+ }
+ }
+ expectedChars.result()
+ }
+
+ (actualTry, expectedTry) match {
+ case (Failure(actualEx: MalformedInputException),
+ Failure(expectedEx: MalformedInputException)) =>
+ expect(actualEx.getInputLength()).toEqual(expectedEx.getInputLength())
+
+ case (Failure(actualEx: UnmappableCharacterException),
+ Failure(expectedEx: UnmappableCharacterException)) =>
+ expect(actualEx.getInputLength()).toEqual(expectedEx.getInputLength())
+
+ case (Success(actualChars), Success(expectedChars)) =>
+ expect(actualChars.map(_.toInt).toJSArray).toEqual(
+ expectedChars.map(_.toInt).toJSArray)
+
+ case _ =>
+ // For the error message
+ expect(actualTry.asInstanceOf[js.Any]).toBe(
+ expectedTry.asInstanceOf[js.Any])
+ }
+ }
+
+ val hasAnyMalformed = outParts.exists(_.isInstanceOf[Malformed])
+ val hasAnyUnmappable = outParts.exists(_.isInstanceOf[Unmappable])
+
+ for {
+ malformedAction <- if (hasAnyMalformed) AllErrorActions else ReportActions
+ unmappableAction <- if (hasAnyUnmappable) AllErrorActions else ReportActions
+ } {
+ testOneConfig(malformedAction, unmappableAction)
+ }
+ }
+
+ protected def testEncode(in: CharBuffer)(
+ outParts: OutPart[ByteBuffer]*): Unit = {
+
+ def testOneConfig(malformedAction: CodingErrorAction,
+ unmappableAction: CodingErrorAction): Unit = {
+
+ val encoder = charset.newEncoder()
+ encoder.onMalformedInput(malformedAction)
+ encoder.onUnmappableCharacter(unmappableAction)
+
+ val actualTry = Try {
+ in.mark()
+ val buf =
+ try encoder.encode(in)
+ finally in.reset()
+ val actualBytes = new Array[Byte](buf.remaining())
+ buf.get(actualBytes)
+ actualBytes
+ }
+
+ val expectedTry = Try {
+ val expectedBytes = Array.newBuilder[Byte]
+ outParts foreach {
+ case BufferPart(buf) =>
+ val bufArray = new Array[Byte](buf.remaining)
+ buf.mark()
+ try buf.get(bufArray)
+ finally buf.reset()
+ expectedBytes ++= bufArray
+ case Malformed(len) =>
+ malformedAction match {
+ case CodingErrorAction.IGNORE =>
+ case CodingErrorAction.REPLACE =>
+ expectedBytes ++= encoder.replacement()
+ case CodingErrorAction.REPORT =>
+ throw new MalformedInputException(len)
+ }
+ case Unmappable(len) =>
+ unmappableAction match {
+ case CodingErrorAction.IGNORE =>
+ case CodingErrorAction.REPLACE =>
+ expectedBytes ++= encoder.replacement()
+ case CodingErrorAction.REPORT =>
+ throw new UnmappableCharacterException(len)
+ }
+ }
+ expectedBytes.result()
+ }
+
+ (actualTry, expectedTry) match {
+ case (Failure(actualEx: MalformedInputException),
+ Failure(expectedEx: MalformedInputException)) =>
+ expect(actualEx.getInputLength()).toEqual(expectedEx.getInputLength())
+
+ case (Failure(actualEx: UnmappableCharacterException),
+ Failure(expectedEx: UnmappableCharacterException)) =>
+ expect(actualEx.getInputLength()).toEqual(expectedEx.getInputLength())
+
+ case (Success(actualBytes), Success(expectedBytes)) =>
+ expect(actualBytes.toJSArray).toEqual(expectedBytes.toJSArray)
+
+ case _ =>
+ // For the error message
+ expect(actualTry.asInstanceOf[js.Any]).toBe(
+ expectedTry.asInstanceOf[js.Any])
+ }
+ }
+
+ val hasAnyMalformed = outParts.exists(_.isInstanceOf[Malformed])
+ val hasAnyUnmappable = outParts.exists(_.isInstanceOf[Unmappable])
+
+ for {
+ malformedAction <- if (hasAnyMalformed) AllErrorActions else ReportActions
+ unmappableAction <- if (hasAnyUnmappable) AllErrorActions else ReportActions
+ } {
+ testOneConfig(malformedAction, unmappableAction)
+ }
+ }
+}
+
+object BaseCharsetTest {
+ sealed abstract class OutPart[+BufferType <: Buffer]
+ final case class BufferPart[BufferType <: Buffer](buf: BufferType) extends OutPart[BufferType]
+ final case class Malformed(length: Int) extends OutPart[Nothing]
+ final case class Unmappable(length: Int) extends OutPart[Nothing]
+
+ object OutPart {
+ implicit def fromBuffer[BufferType <: Buffer](buf: BufferType): BufferPart[BufferType] =
+ BufferPart(buf)
+ }
+
+ implicit class Interpolators(val sc: StringContext) extends AnyVal {
+ def bb(args: Any*): ByteBuffer = {
+ val strings = sc.parts.iterator
+ val expressions = args.iterator
+ val buf = Array.newBuilder[Byte]
+
+ def appendStr(s: String): Unit = {
+ val s1 = s.replace(" ", "")
+ require(s1.length % 2 == 0)
+ for (i <- 0 until s1.length by 2)
+ buf += java.lang.Integer.parseInt(s1.substring(i, i+2), 16).toByte
+ }
+
+ appendStr(strings.next())
+ while (strings.hasNext) {
+ expressions.next() match {
+ case b: Byte => buf += b
+ case bytes: Array[Byte] => buf ++= bytes
+ case bytes: Seq[_] =>
+ buf ++= bytes.map(_.asInstanceOf[Number].byteValue())
+ }
+ appendStr(strings.next())
+ }
+
+ ByteBuffer.wrap(buf.result())
+ }
+
+ def cb(args: Any*): CharBuffer =
+ CharBuffer.wrap(sc.s(args: _*))
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/CharsetTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/CharsetTest.scala
new file mode 100644
index 0000000..15b0150
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/CharsetTest.scala
@@ -0,0 +1,74 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.niocharset
+
+import scala.language.implicitConversions
+
+import java.nio._
+import java.nio.charset._
+
+import scala.scalajs.js
+import scala.scalajs.niocharset.StandardCharsets._
+
+import org.scalajs.jasminetest.JasmineTest
+
+object CharsetTest extends JasmineTest {
+ implicit def charsetAsJSAny(charset: Charset): js.Any =
+ charset.asInstanceOf[js.Any]
+
+ describe("java.nio.charset.Charset") {
+ it("defaultCharset") {
+ expect(Charset.defaultCharset()).toBe(UTF_8)
+ }
+
+ it("forName") {
+ expect(Charset.forName("ISO-8859-1")).toBe(ISO_8859_1)
+ expect(Charset.forName("Iso8859-1")).toBe(ISO_8859_1)
+ expect(Charset.forName("iso_8859_1")).toBe(ISO_8859_1)
+ expect(Charset.forName("LaTin1")).toBe(ISO_8859_1)
+ expect(Charset.forName("l1")).toBe(ISO_8859_1)
+
+ expect(Charset.forName("US-ASCII")).toBe(US_ASCII)
+ expect(Charset.forName("Default")).toBe(US_ASCII)
+
+ expect(Charset.forName("UTF-8")).toBe(UTF_8)
+ expect(Charset.forName("utf-8")).toBe(UTF_8)
+ expect(Charset.forName("UtF8")).toBe(UTF_8)
+ expect(Charset.forName("UTF_8")).toBe(UTF_8)
+ expect(Charset.forName("UTF-8")).toBe(UTF_8)
+
+ expect(Charset.forName("UTF-16BE")).toBe(UTF_16BE)
+ expect(Charset.forName("Utf_16BE")).toBe(UTF_16BE)
+ expect(Charset.forName("UnicodeBigUnmarked")).toBe(UTF_16BE)
+
+ expect(Charset.forName("UTF-16le")).toBe(UTF_16LE)
+ expect(Charset.forName("Utf_16le")).toBe(UTF_16LE)
+ expect(Charset.forName("UnicodeLittleUnmarked")).toBe(UTF_16LE)
+
+ expect(Charset.forName("UTF-16")).toBe(UTF_16)
+ expect(Charset.forName("Utf_16")).toBe(UTF_16)
+ expect(Charset.forName("unicode")).toBe(UTF_16)
+ expect(Charset.forName("UnicodeBig")).toBe(UTF_16)
+
+ expect(() => Charset.forName("this-charset-does-not-exist")).toThrow
+ }
+
+ it("isSupported") {
+ expect(Charset.isSupported("ISO-8859-1")).toBeTruthy
+ expect(Charset.isSupported("US-ASCII")).toBeTruthy
+ expect(Charset.isSupported("Default")).toBeTruthy
+ expect(Charset.isSupported("utf-8")).toBeTruthy
+ expect(Charset.isSupported("UnicodeBigUnmarked")).toBeTruthy
+ expect(Charset.isSupported("Utf_16le")).toBeTruthy
+ expect(Charset.isSupported("UTF-16")).toBeTruthy
+ expect(Charset.isSupported("unicode")).toBeTruthy
+
+ expect(Charset.isSupported("this-charset-does-not-exist")).toBeFalsy
+ }
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/Latin1Test.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/Latin1Test.scala
new file mode 100644
index 0000000..f6ddc36
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/Latin1Test.scala
@@ -0,0 +1,91 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.niocharset
+
+import java.nio._
+import java.nio.charset._
+
+import scala.scalajs.niocharset.StandardCharsets
+
+import BaseCharsetTest._
+
+object Latin1Test extends BaseCharsetTest(StandardCharsets.ISO_8859_1) {
+ describe("ISO-8859-1") {
+ it("decode") {
+ // Simple tests
+
+ testDecode(bb"48 65 6c 6c 6f")(cb"Hello")
+ testDecode(bb"42 6f 6e 6a 6f 75 72")(cb"Bonjour")
+
+ testDecode(bb"00 01 0a 10 20")(cb"\u0000\u0001\u000a\u0010 ")
+ testDecode(bb"7f 7f")(cb"\u007f\u007f")
+
+ testDecode(bb"c8 e5 ec ec ef")(cb"Èåììï")
+ testDecode(bb"c2 ef ee ea ef f5 f2")(cb"Âïîêïõò")
+
+ testDecode(bb"80 81 8a 90 a0")(cb"\u0080\u0081\u008a\u0090\u00a0")
+ testDecode(bb"ff ff")(cb"ÿÿ")
+ }
+
+ it("encode") {
+ // Simple tests
+
+ testEncode(cb"Hello")(bb"48 65 6c 6c 6f")
+ testEncode(cb"Bonjour")(bb"42 6f 6e 6a 6f 75 72")
+
+ testEncode(cb"\u0000\u0001\u000a\u0010 ")(bb"00 01 0a 10 20")
+ testEncode(cb"\u007f\u007f")(bb"7f 7f")
+
+ testEncode(cb"Èåììï")(bb"c8 e5 ec ec ef")
+ testEncode(cb"Âïîêïõò")(bb"c2 ef ee ea ef f5 f2")
+
+ testEncode(cb"\u0080\u0081\u008a\u0090\u00a0")(bb"80 81 8a 90 a0")
+ testEncode(cb"ÿÿ")(bb"ff ff")
+
+ // Unmappable characters
+
+ testEncode(cb"\u0100")(Unmappable(1))
+ testEncode(cb"\u07ff")(Unmappable(1))
+ testEncode(cb"\ue000")(Unmappable(1))
+ testEncode(cb"\uffff")(Unmappable(1))
+ testEncode(cb"\ud835\udcd7")(Unmappable(2))
+
+ testEncode(cb"\u0100A")(Unmappable(1), bb"41")
+ testEncode(cb"\u07ffA")(Unmappable(1), bb"41")
+ testEncode(cb"\ue000A")(Unmappable(1), bb"41")
+ testEncode(cb"\uffffA")(Unmappable(1), bb"41")
+ testEncode(cb"\ud835\udcd7A")(Unmappable(2), bb"41")
+
+ // Single UTF-16 surrogates
+ testEncode(cb"\ud800")(Malformed(1))
+ testEncode(cb"\udaff")(Malformed(1))
+ testEncode(cb"\udb80")(Malformed(1))
+ testEncode(cb"\udbff")(Malformed(1))
+ testEncode(cb"\udc00")(Malformed(1))
+ testEncode(cb"\udf80")(Malformed(1))
+ testEncode(cb"\udfff")(Malformed(1))
+
+ // High UTF-16 surrogates not followed by low surrogates
+ testEncode(cb"\ud800A")(Malformed(1), bb"41")
+ testEncode(cb"\ud800\ud800")(Malformed(1), Malformed(1))
+ testEncode(cb"\ud800\ud835\udcd7")(Malformed(1), Unmappable(2))
+ testEncode(cb"\udbffA")(Malformed(1), bb"41")
+ testEncode(cb"\udbff\udb8f")(Malformed(1), Malformed(1))
+ testEncode(cb"\udbff\ud835\udcd7")(Malformed(1), Unmappable(2))
+ }
+
+ it("isLegalReplacement") {
+ val encoder = charset.newEncoder
+ expect(encoder.isLegalReplacement(Array(0x00.toByte))).toBeTruthy
+ expect(encoder.isLegalReplacement(Array(0x41.toByte))).toBeTruthy
+ expect(encoder.isLegalReplacement(Array('?'.toByte))).toBeTruthy
+ expect(encoder.isLegalReplacement(Array(0x80.toByte))).toBeTruthy
+ expect(encoder.isLegalReplacement(Array(0xff.toByte))).toBeTruthy
+ }
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/USASCIITest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/USASCIITest.scala
new file mode 100644
index 0000000..2352d3e
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/USASCIITest.scala
@@ -0,0 +1,93 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.niocharset
+
+import java.nio._
+import java.nio.charset._
+
+import scala.scalajs.niocharset.StandardCharsets
+
+import BaseCharsetTest._
+
+object USASCIITest extends BaseCharsetTest(StandardCharsets.US_ASCII) {
+ describe("US-ASCII") {
+ it("decode") {
+ // Simple tests
+
+ testDecode(bb"48 65 6c 6c 6f")(cb"Hello")
+ testDecode(bb"42 6f 6e 6a 6f 75 72")(cb"Bonjour")
+
+ testDecode(bb"00 01 0a 10 20")(cb"\u0000\u0001\u000a\u0010 ")
+ testDecode(bb"7f 7f")(cb"\u007f\u007f")
+
+ // Bit 7 is ignored, giving the same results as above
+
+ testDecode(bb"c8 e5 ec ec ef")(cb"Hello")
+ testDecode(bb"c2 ef ee ea ef f5 f2")(cb"Bonjour")
+
+ testDecode(bb"80 81 8a 90 a0")(cb"\u0000\u0001\u000a\u0010 ")
+ testDecode(bb"ff ff")(cb"\u007f\u007f")
+ }
+
+ it("encode") {
+ // Simple tests
+
+ testEncode(cb"Hello")(bb"48 65 6c 6c 6f")
+ testEncode(cb"Bonjour")(bb"42 6f 6e 6a 6f 75 72")
+
+ testEncode(cb"\u0000\u0001\u000a\u0010 ")(bb"00 01 0a 10 20")
+ testEncode(cb"\u007f\u007f")(bb"7f 7f")
+
+ // Unmappable characters
+
+ testEncode(cb"é")(Unmappable(1))
+ testEncode(cb"\u0080")(Unmappable(1))
+ testEncode(cb"\u00ff")(Unmappable(1))
+ testEncode(cb"\u0100")(Unmappable(1))
+ testEncode(cb"\u07ff")(Unmappable(1))
+ testEncode(cb"\ue000")(Unmappable(1))
+ testEncode(cb"\uffff")(Unmappable(1))
+ testEncode(cb"\ud835\udcd7")(Unmappable(2))
+
+ testEncode(cb"éA")(Unmappable(1), bb"41")
+ testEncode(cb"\u0080A")(Unmappable(1), bb"41")
+ testEncode(cb"\u00ffA")(Unmappable(1), bb"41")
+ testEncode(cb"\u0100A")(Unmappable(1), bb"41")
+ testEncode(cb"\u07ffA")(Unmappable(1), bb"41")
+ testEncode(cb"\ue000A")(Unmappable(1), bb"41")
+ testEncode(cb"\uffffA")(Unmappable(1), bb"41")
+ testEncode(cb"\ud835\udcd7A")(Unmappable(2), bb"41")
+
+ // Single UTF-16 surrogates
+ testEncode(cb"\ud800")(Malformed(1))
+ testEncode(cb"\udaff")(Malformed(1))
+ testEncode(cb"\udb80")(Malformed(1))
+ testEncode(cb"\udbff")(Malformed(1))
+ testEncode(cb"\udc00")(Malformed(1))
+ testEncode(cb"\udf80")(Malformed(1))
+ testEncode(cb"\udfff")(Malformed(1))
+
+ // High UTF-16 surrogates not followed by low surrogates
+ testEncode(cb"\ud800A")(Malformed(1), bb"41")
+ testEncode(cb"\ud800\ud800")(Malformed(1), Malformed(1))
+ testEncode(cb"\ud800\ud835\udcd7")(Malformed(1), Unmappable(2))
+ testEncode(cb"\udbffA")(Malformed(1), bb"41")
+ testEncode(cb"\udbff\udb8f")(Malformed(1), Malformed(1))
+ testEncode(cb"\udbff\ud835\udcd7")(Malformed(1), Unmappable(2))
+ }
+
+ it("isLegalReplacement") {
+ val encoder = charset.newEncoder
+ expect(encoder.isLegalReplacement(Array(0x00.toByte))).toBeTruthy
+ expect(encoder.isLegalReplacement(Array(0x41.toByte))).toBeTruthy
+ expect(encoder.isLegalReplacement(Array('?'.toByte))).toBeTruthy
+ expect(encoder.isLegalReplacement(Array(0x80.toByte))).toBeTruthy
+ expect(encoder.isLegalReplacement(Array(0xff.toByte))).toBeTruthy
+ }
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/UTF16Test.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/UTF16Test.scala
new file mode 100644
index 0000000..85d4eff
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/UTF16Test.scala
@@ -0,0 +1,155 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.niocharset
+
+import java.nio._
+import java.nio.charset._
+
+import scala.scalajs.niocharset.StandardCharsets
+
+import BaseCharsetTest._
+
+abstract class BaseUTF16Test(charset: Charset) extends BaseCharsetTest(charset) {
+ describe(charset.name) {
+ it("decode") {
+ // ASCII characters
+ testDecode(bb"0042 006f 006e 006a 006f 0075 0072")(cb"Bonjour")
+
+ // Other characters without surrogate pairs
+ testDecode(bb"0047 0072 00fc 00df 0020 0047 006f 0074 0074")(cb"Grüß Gott")
+ testDecode(bb"039a 03b1 03bb 03b7 03bc 03ad 03c1 03b1")(cb"Καλημέρα")
+ testDecode(bb"0635 0628 0627 062d 0020 0627 0644 062e 064a 0631")(cb"صباح الخير")
+ testDecode(bb"3053 3093 306b 3061 306f")(cb"こんにちは")
+ testDecode(bb"0414 043e 0431 0440 044b 0439 0020 0434 0435 043d 044c")(cb"Добрый день")
+ testDecode(bb"4f60 597d")(cb"你好")
+
+ // 4-byte characters
+ testDecode(bb"d835 dcd7 d835 dcee d835 dcf5 d835 dcf5 d835 dcf8")(
+ cb"\ud835\udcd7\ud835\udcee\ud835\udcf5\ud835\udcf5\ud835\udcf8")
+
+ testDecode(bb"")(cb"")
+
+ // Here begin the sequences with at least one error
+
+ // Single UTF-16 surrogates
+ testDecode(bb"d800")(Malformed(2))
+ testDecode(bb"daff")(Malformed(2))
+ testDecode(bb"db80")(Malformed(2))
+ testDecode(bb"dbff")(Malformed(2))
+ testDecode(bb"dc00")(Malformed(2))
+ testDecode(bb"df80")(Malformed(2))
+ testDecode(bb"dfff")(Malformed(2))
+
+ // High UTF-16 surrogates not followed by low surrogates
+ testDecode(bb"d800 0041")(Malformed(2), cb"A")
+ testDecode(bb"d800 d800")(Malformed(2), Malformed(2))
+ testDecode(bb"d800 d835 dcd7")(Malformed(2), cb"\ud835\udcd7")
+ testDecode(bb"dbff 0041")(Malformed(2), cb"A")
+ testDecode(bb"dbff db8f")(Malformed(2), Malformed(2))
+ testDecode(bb"dbff d835 dcd7")(Malformed(2), cb"\ud835\udcd7")
+
+ // Lonely byte at the end
+ testDecode(bb"0041 41")(cb"A", Malformed(1))
+ }
+
+ it("encode") {
+ // ASCII characters
+ testEncode(cb"Bonjour")(bb"0042 006f 006e 006a 006f 0075 0072")
+
+ // Other characters without surrogate pairs
+ testEncode(cb"Grüß Gott")(bb"0047 0072 00fc 00df 0020 0047 006f 0074 0074")
+ testEncode(cb"Καλημέρα")(bb"039a 03b1 03bb 03b7 03bc 03ad 03c1 03b1")
+ testEncode(cb"صباح الخير")(bb"0635 0628 0627 062d 0020 0627 0644 062e 064a 0631")
+ testEncode(cb"こんにちは")(bb"3053 3093 306b 3061 306f")
+ testEncode(cb"Добрый день")(bb"0414 043e 0431 0440 044b 0439 0020 0434 0435 043d 044c")
+ testEncode(cb"你好")(bb"4f60 597d")
+
+ // 4-byte characters
+ testEncode(cb"\ud835\udcd7\ud835\udcee\ud835\udcf5\ud835\udcf5\ud835\udcf8")(
+ bb"d835 dcd7 d835 dcee d835 dcf5 d835 dcf5 d835 dcf8")
+
+ testEncode(cb"")(bb"")
+
+ // Here begin the sequences with at least one error
+
+ // Single UTF-16 surrogates
+ testEncode(cb"\ud800")(Malformed(1))
+ testEncode(cb"\udaff")(Malformed(1))
+ testEncode(cb"\udb80")(Malformed(1))
+ testEncode(cb"\udbff")(Malformed(1))
+ testEncode(cb"\udc00")(Malformed(1))
+ testEncode(cb"\udf80")(Malformed(1))
+ testEncode(cb"\udfff")(Malformed(1))
+
+ // High UTF-16 surrogates not followed by low surrogates
+ testEncode(cb"\ud800A")(Malformed(1), bb"0041")
+ testEncode(cb"\ud800\ud800")(Malformed(1), Malformed(1))
+ testEncode(cb"\ud800\ud835\udcd7")(Malformed(1), bb"d835 dcd7")
+ testEncode(cb"\udbffA")(Malformed(1), bb"0041")
+ testEncode(cb"\udbff\udb8f")(Malformed(1), Malformed(1))
+ testEncode(cb"\udbff\ud835\udcd7")(Malformed(1), bb"d835 dcd7")
+ }
+ }
+}
+
+object UTF16BETest extends BaseUTF16Test(StandardCharsets.UTF_16BE)
+
+object UTF16LETest extends BaseUTF16Test(StandardCharsets.UTF_16LE) {
+ override protected def testDecode(in: ByteBuffer)(
+ outParts: OutPart[CharBuffer]*): Unit = {
+ flipByteBuffer(in)
+ super.testDecode(in)(outParts: _*)
+ }
+
+ override protected def testEncode(in: CharBuffer)(
+ outParts: OutPart[ByteBuffer]*): Unit = {
+ for (BufferPart(buf) <- outParts)
+ flipByteBuffer(buf)
+ super.testEncode(in)(outParts: _*)
+ }
+
+ /** Flips all pairs of bytes in a byte buffer, except a potential lonely
+ * last byte.
+ */
+ def flipByteBuffer(buf: ByteBuffer): Unit = {
+ buf.mark()
+ while (buf.remaining() >= 2) {
+ val high = buf.get()
+ val low = buf.get()
+ buf.position(buf.position - 2)
+ buf.put(low)
+ buf.put(high)
+ }
+ buf.reset()
+ }
+}
+
+object UTF16Test extends BaseUTF16Test(StandardCharsets.UTF_16) {
+ def BigEndianBOM = ByteBuffer.wrap(Array(0xfe.toByte, 0xff.toByte))
+
+ override protected def testDecode(in: ByteBuffer)(
+ outParts: OutPart[CharBuffer]*): Unit = {
+ // Without BOM, big endian is assumed
+ super.testDecode(in)(outParts: _*)
+
+ // With BOM, big endian
+ val inWithBOM = ByteBuffer.allocate(2+in.remaining)
+ inWithBOM.put(BigEndianBOM).put(in).flip()
+ super.testDecode(inWithBOM)(outParts: _*)
+
+ // With BOM, little endian
+ UTF16LETest.flipByteBuffer(inWithBOM)
+ super.testDecode(inWithBOM)(outParts: _*)
+ }
+
+ override protected def testEncode(in: CharBuffer)(
+ outParts: OutPart[ByteBuffer]*): Unit = {
+ if (in.remaining == 0) super.testEncode(in)(outParts: _*)
+ else super.testEncode(in)(BufferPart(BigEndianBOM) +: outParts: _*)
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/UTF8Test.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/UTF8Test.scala
new file mode 100644
index 0000000..fbb6a9c
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/niocharset/UTF8Test.scala
@@ -0,0 +1,240 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.niocharset
+
+import java.nio._
+import java.nio.charset._
+
+import scala.scalajs.niocharset.StandardCharsets
+
+import BaseCharsetTest._
+
+object UTF8Test extends BaseCharsetTest(StandardCharsets.UTF_8) {
+ describe("UTF-8") {
+ it("decode") {
+ def OutSeq(elems: OutPart[CharBuffer]*): Seq[OutPart[CharBuffer]] =
+ Seq[OutPart[CharBuffer]](elems: _*)
+
+ // 1-byte characters
+ testDecode(bb"42 6f 6e 6a 6f 75 72")(cb"Bonjour")
+
+ // 2-byte characters
+ testDecode(bb"47 72 c3 bc c3 9f 20 47 6f 74 74")(cb"Grüß Gott")
+ testDecode(bb"ce 9a ce b1 ce bb ce b7 ce bc ce ad cf 81 ce b1")(cb"Καλημέρα")
+ testDecode(bb"d8 b5 d8 a8 d8 a7 d8 ad 20 d8 a7 d9 84 d8 ae d9 8a d8 b1")(cb"صباح الخير")
+
+ // 3-byte characters
+ testDecode(bb"e3 81 93 e3 82 93 e3 81 ab e3 81 a1 e3 81 af")(cb"こんにちは")
+ testDecode(bb"d0 94 d0 be d0 b1 d1 80 d1 8b d0 b9 20 d0 b4 d0 b5 d0 bd d1 8c")(cb"Добрый день")
+ testDecode(bb"e4 bd a0 e5 a5 bd")(cb"你好")
+
+ // 4-byte characters
+ testDecode(bb"f0 9d 93 97 f0 9d 93 ae f0 9d 93 b5 f0 9d 93 b5 f0 9d 93 b8")(
+ cb"\ud835\udcd7\ud835\udcee\ud835\udcf5\ud835\udcf5\ud835\udcf8")
+
+ testDecode(bb"")(cb"")
+
+ // First sequence of a certain length
+ testDecode(bb"00")(cb"\u0000")
+ testDecode(bb"c2 80")(cb"\u0080")
+ testDecode(bb"e0 a0 80")(cb"\u0800")
+ testDecode(bb"f0 90 80 80")(cb"\ud800\udc00")
+
+ // Last sequence of a certain length
+ testDecode(bb"7f")(cb"\u007f")
+ testDecode(bb"df bf")(cb"\u07ff")
+ testDecode(bb"ef bf bf")(cb"\uffff")
+ testDecode(bb"f4 8f bf bf")(cb"\udbff\udfff")
+
+ // Other boundary conditions
+ testDecode(bb"ed 9f bf")(cb"\ud7ff")
+ testDecode(bb"ee 80 80")(cb"\ue000")
+ testDecode(bb"ef bf bd")(cb"\ufffd")
+
+ // Here begin the sequences with at least one error
+
+ // Code point too big
+ testDecode(bb"f4 90 80 80")(Malformed(4))
+ testDecode(bb"41 f4 90 80 80 42")(cb"A", Malformed(4), cb"B")
+
+ // Unexpected continuation bytes (each is reported separately)
+ testDecode(bb"80")(Malformed(1))
+ testDecode(bb"bf")(Malformed(1))
+ testDecode(bb"80 80")(Malformed(1), Malformed(1))
+ testDecode(bb"80 80 80")(Malformed(1), Malformed(1), Malformed(1))
+ testDecode(bb"80 80 80 80")(Malformed(1), Malformed(1), Malformed(1), Malformed(1))
+ testDecode(bb"80 80 80 80 80")(Malformed(1), Malformed(1), Malformed(1), Malformed(1), Malformed(1))
+ testDecode(bb"41 80 80 42 80 43")(cb"A", Malformed(1), Malformed(1), cb"B", Malformed(1), cb"C")
+
+ // Lonely start characters, separated by spaces
+ /* We add 2 spaces at the end so that the last 4-byte start does not
+ * swallow the last space as an underflow. */
+ testDecode(bb"${(0xc0 to 0xf4).flatMap(c => Seq(c, 32)) ++ Seq[Byte](32, 32)}")(
+ (0xc0 to 0xf4).flatMap(i => OutSeq(Malformed(1), cb" ")) ++ OutSeq(cb" "): _*)
+ // Now we let it swallow the last space
+ testDecode(bb"${Seq[Byte](32) ++ (0xc0 to 0xf4).flatMap(c => Seq(c, 32))}")(
+ (0xc0 to 0xf4).flatMap(i => OutSeq(cb" ", Malformed(1))): _*)
+
+ // Sequences with some continuation bytes missing
+ testDecode(bb"c2")(Malformed(1))
+ testDecode(bb"e0")(Malformed(1))
+ testDecode(bb"e0 a0")(Malformed(2))
+ testDecode(bb"f0")(Malformed(1))
+ testDecode(bb"f0 90")(Malformed(2))
+ testDecode(bb"f0 90 80")(Malformed(3))
+ // and all of them concatenated
+ testDecode(bb"c2 e0 e0 a0 f0 f0 90 f0 90 80")(
+ Seq(1, 1, 2, 1, 2, 3).map(Malformed(_)): _*)
+ // and with normal sequences interspersed
+ testDecode(bb"c2 41 e0 41 e0 a0 41 f0 41 f0 90 41 f0 90 80 41")(
+ Seq(1, 1, 2, 1, 2, 3).flatMap(l => Seq[OutPart[CharBuffer]](Malformed(l), cb"A")): _*)
+
+ // Impossible bytes
+ testDecode(bb"fe")(Malformed(1))
+ testDecode(bb"ff")(Malformed(1))
+ testDecode(bb"fe fe ff ff")(Malformed(1), Malformed(1), Malformed(1), Malformed(1))
+ // Old 5-byte and 6-byte starts
+ testDecode(bb"f8 80 80 80 af")(
+ Malformed(1), Malformed(1), Malformed(1), Malformed(1), Malformed(1))
+ testDecode(bb"fc 80 80 80 80 af")(
+ Malformed(1), Malformed(1), Malformed(1), Malformed(1), Malformed(1), Malformed(1))
+
+ // Overlong sequences (encoded with more bytes than necessary)
+ // Overlong '/'
+ testDecode(bb"c0 af")(Malformed(2))
+ testDecode(bb"e0 80 af")(Malformed(3))
+ testDecode(bb"f0 80 80 af")(Malformed(4))
+ // Maximum overlong sequences
+ testDecode(bb"c1 bf")(Malformed(2))
+ testDecode(bb"e0 9f bf")(Malformed(3))
+ testDecode(bb"f0 8f bf bf")(Malformed(4))
+ // Overlong NUL
+ testDecode(bb"c0 80")(Malformed(2))
+ testDecode(bb"e0 80 80")(Malformed(3))
+ testDecode(bb"f0 80 80 80")(Malformed(4))
+
+ // Single UTF-16 surrogates
+ testDecode(bb"ed a0 80")(Malformed(3))
+ testDecode(bb"ed ad bf")(Malformed(3))
+ testDecode(bb"ed ae 80")(Malformed(3))
+ testDecode(bb"ed af bf")(Malformed(3))
+ testDecode(bb"ed b0 80")(Malformed(3))
+ testDecode(bb"ed be 80")(Malformed(3))
+ testDecode(bb"ed bf bf")(Malformed(3))
+
+ // Paired UTF-16 surrogates
+ testDecode(bb"ed a0 80 ed b0 80")(Malformed(3), Malformed(3))
+ testDecode(bb"ed a0 80 ed bf bf")(Malformed(3), Malformed(3))
+ testDecode(bb"ed ad bf ed b0 80")(Malformed(3), Malformed(3))
+ testDecode(bb"ed ad bf ed bf bf")(Malformed(3), Malformed(3))
+ testDecode(bb"ed ae 80 ed b0 80")(Malformed(3), Malformed(3))
+ testDecode(bb"ed ae 80 ed bf bf")(Malformed(3), Malformed(3))
+ testDecode(bb"ed af bf ed b0 80")(Malformed(3), Malformed(3))
+ testDecode(bb"ed af bf ed bf bf")(Malformed(3), Malformed(3))
+ }
+
+ it("encode") {
+ def OutSeq(elems: OutPart[ByteBuffer]*): Seq[OutPart[ByteBuffer]] =
+ Seq[OutPart[ByteBuffer]](elems: _*)
+
+ // 1-byte characters
+ testEncode(cb"Bonjour")(bb"42 6f 6e 6a 6f 75 72")
+
+ // 2-byte characters
+ testEncode(cb"Grüß Gott")(bb"47 72 c3 bc c3 9f 20 47 6f 74 74")
+ testEncode(cb"Καλημέρα")(bb"ce 9a ce b1 ce bb ce b7 ce bc ce ad cf 81 ce b1")
+ testEncode(cb"صباح الخير")(bb"d8 b5 d8 a8 d8 a7 d8 ad 20 d8 a7 d9 84 d8 ae d9 8a d8 b1")
+
+ // 3-byte characters
+ testEncode(cb"こんにちは")(bb"e3 81 93 e3 82 93 e3 81 ab e3 81 a1 e3 81 af")
+ testEncode(cb"Добрый день")(bb"d0 94 d0 be d0 b1 d1 80 d1 8b d0 b9 20 d0 b4 d0 b5 d0 bd d1 8c")
+ testEncode(cb"你好")(bb"e4 bd a0 e5 a5 bd")
+
+ // 4-byte characters
+ testEncode(cb"\ud835\udcd7\ud835\udcee\ud835\udcf5\ud835\udcf5\ud835\udcf8")(
+ bb"f0 9d 93 97 f0 9d 93 ae f0 9d 93 b5 f0 9d 93 b5 f0 9d 93 b8")
+
+ testEncode(cb"")(bb"")
+
+ // First sequence of a certain length
+ testEncode(cb"\u0000")(bb"00")
+ testEncode(cb"\u0080")(bb"c2 80")
+ testEncode(cb"\u0800")(bb"e0 a0 80")
+ testEncode(cb"\ud800\udc00")(bb"f0 90 80 80")
+
+ // Last sequence of a certain length
+ testEncode(cb"\u007f")(bb"7f")
+ testEncode(cb"\u07ff")(bb"df bf")
+ testEncode(cb"\uffff")(bb"ef bf bf")
+ testEncode(cb"\udbff\udfff")(bb"f4 8f bf bf")
+
+ // Other boundary conditions
+ testEncode(cb"\ud7ff")(bb"ed 9f bf")
+ testEncode(cb"\ue000")(bb"ee 80 80")
+ testEncode(cb"\ufffd")(bb"ef bf bd")
+
+ // Here begin the sequences with at least one error
+
+ // Single UTF-16 surrogates
+ testEncode(cb"\ud800")(Malformed(1))
+ testEncode(cb"\udaff")(Malformed(1))
+ testEncode(cb"\udb80")(Malformed(1))
+ testEncode(cb"\udbff")(Malformed(1))
+ testEncode(cb"\udc00")(Malformed(1))
+ testEncode(cb"\udf80")(Malformed(1))
+ testEncode(cb"\udfff")(Malformed(1))
+
+ // High UTF-16 surrogates not followed by low surrogates
+ testEncode(cb"\ud800A")(Malformed(1), bb"41")
+ testEncode(cb"\ud800\ud800")(Malformed(1), Malformed(1))
+ testEncode(cb"\ud800\ud835\udcd7")(Malformed(1), bb"f0 9d 93 97")
+ testEncode(cb"\udbffA")(Malformed(1), bb"41")
+ testEncode(cb"\udbff\udb8f")(Malformed(1), Malformed(1))
+ testEncode(cb"\udbff\ud835\udcd7")(Malformed(1), bb"f0 9d 93 97")
+ }
+
+ it("isLegalReplacement") {
+ val encoder = charset.newEncoder
+
+ // The good ones
+
+ expect(encoder.isLegalReplacement(Array(0x00.toByte))).toBeTruthy
+ expect(encoder.isLegalReplacement(Array(0x41.toByte))).toBeTruthy
+ expect(encoder.isLegalReplacement(Array('?'.toByte))).toBeTruthy
+ expect(encoder.isLegalReplacement(Array(0x7f.toByte))).toBeTruthy
+
+ expect(encoder.isLegalReplacement(
+ Array(0xc2.toByte, 0x80.toByte))).toBeTruthy
+ expect(encoder.isLegalReplacement(
+ Array(0xdf.toByte, 0xbf.toByte))).toBeTruthy
+
+ expect(encoder.isLegalReplacement(
+ Array(0xe0.toByte, 0xa0.toByte, 0x80.toByte))).toBeTruthy
+ expect(encoder.isLegalReplacement(
+ Array(0xef.toByte, 0xbf.toByte, 0xbf.toByte))).toBeTruthy
+
+ expect(encoder.isLegalReplacement(
+ Array(0xf0.toByte, 0x90.toByte, 0x80.toByte, 0x80.toByte))).toBeTruthy
+ expect(encoder.isLegalReplacement(
+ Array(0xf4.toByte, 0x8f.toByte, 0xbf.toByte, 0xbf.toByte))).toBeTruthy
+
+ // The bad ones
+
+ expect(encoder.isLegalReplacement(Array(0x80.toByte))).toBeFalsy
+ expect(encoder.isLegalReplacement(Array(0xbf.toByte))).toBeFalsy
+ expect(encoder.isLegalReplacement(Array(0xc2.toByte))).toBeFalsy
+ expect(encoder.isLegalReplacement(Array(0xdf.toByte))).toBeFalsy
+ expect(encoder.isLegalReplacement(Array(0xe0.toByte))).toBeFalsy
+ expect(encoder.isLegalReplacement(Array(0xef.toByte))).toBeFalsy
+ expect(encoder.isLegalReplacement(Array(0xf4.toByte))).toBeFalsy
+
+ expect(encoder.isLegalReplacement(
+ Array(0xe0.toByte, 0x80.toByte))).toBeFalsy
+ }
+ }
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/scalalib/EnumerationTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/scalalib/EnumerationTest.scala
new file mode 100644
index 0000000..f5b17d9
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/scalalib/EnumerationTest.scala
@@ -0,0 +1,95 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.scalalib
+
+import org.scalajs.jasminetest.JasmineTest
+
+object EnumerationTest extends JasmineTest {
+
+ describe("scala.Enumeration") {
+
+ it("should use explicit naming for enumerated values - #38") {
+ object HelpLevel extends Enumeration {
+ type HelpLevel = Value
+ val None = Value("None")
+ val Basic = Value("Basic")
+ val Medium = Value("Medium")
+ val Full = Value("Full")
+ }
+
+ val h = HelpLevel.None
+
+ expect(h.toString).toEqual("None")
+ }
+
+ it("should allow implicit naming for values") {
+ object HelpLevel extends Enumeration {
+ type HelpLevel = Value
+ val None, Basic, Medium, Full = Value
+ val Special = Value(100)
+ val / = Value
+ }
+
+ val h = HelpLevel.Medium
+ expect(h.toString).toEqual("Medium")
+ expect(HelpLevel.Special.toString).toEqual("Special")
+ expect(HelpLevel./.toString).toEqual("$div")
+ }
+
+ it("should give a pseudo toString to unnamed values") {
+ object Test extends Enumeration {
+ private val nullStr: String = null
+ val A = Value(nullStr) // Circumvent compiler replacement and warning
+ }
+
+ expect(Test.A.toString.startsWith(
+ "<Unknown name for enum field #0 of class ")).toBeTruthy
+ }
+
+ it("should give a graceful error message upon name based query when unnamed fields are present") {
+ object Test extends Enumeration {
+ private val nullStr: String = null
+ val A = Value(nullStr) // Circumvent compiler replacement and warning
+ }
+
+ expect(() => Test.withName("A")).toThrow
+ expect {
+ try { Test.withName("A"); ??? }
+ catch { case e: NoSuchElementException => e.getMessage }
+ } toContain {
+ """Couldn't find enum field with name A.
+ |However, there were the following unnamed fields:""".stripMargin
+ }
+ }
+
+ it("should respond to `toString`") {
+ expect(FooBarEnum.toString).toEqual("FooBarEnum")
+ }
+
+ it("should respond to `values`") {
+ expect(FooBarEnum.values.toString).toEqual(
+ "FooBarEnum.ValueSet(A, B, C, D, E, F)")
+ }
+
+ it("should allow setting nextName") {
+ object Test extends Enumeration {
+ nextName = Iterator("x","y","z")
+ val a,b,c = Value
+ }
+
+ expect(Test.values.mkString("|")).toEqual("x|y|z")
+ }
+
+ }
+
+ /** Object is here due to issues with Enumeration.toString inside closures */
+ object FooBarEnum extends Enumeration {
+ val A,B,C,D,E,F = Value
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/scalalib/RangesTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/scalalib/RangesTest.scala
new file mode 100644
index 0000000..511e183
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/scalalib/RangesTest.scala
@@ -0,0 +1,27 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.scalalib
+
+import org.scalajs.jasminetest.JasmineTest
+
+object RangesTest extends JasmineTest {
+
+ describe("Collection ranges") {
+
+ it("Iterable.range should not emit dce warnings - #650") {
+ Iterable.range(1, 10)
+ }
+
+ it("Iterable.range and simple range should be equal") {
+ // Mostly to exercise more methods of ranges for dce warnings
+ expect(Iterable.range(0, 10).toList == (0 until 10).toList).toBeTruthy
+ }
+
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/scalalib/SymbolTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/scalalib/SymbolTest.scala
new file mode 100644
index 0000000..3612629
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/scalalib/SymbolTest.scala
@@ -0,0 +1,63 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.scalalib
+
+import scala.scalajs.js
+import org.scalajs.jasminetest.JasmineTest
+
+object SymbolTest extends JasmineTest {
+
+ describe("scala.Symbol") {
+
+ it("should ensure unique identity") {
+ def expectEqual(sym1: Symbol, sym2: Symbol): Unit = {
+ expect(sym1 eq sym2).toBeTruthy
+ expect(sym1 == sym2).toBeTruthy
+ expect(sym1.equals(sym2)).toBeTruthy
+ expect(sym1.## == sym2.##).toBeTruthy
+ }
+
+ expectEqual('ScalaJS, Symbol("ScalaJS"))
+ expectEqual('$, Symbol("$"))
+ expectEqual('-, Symbol("-"))
+
+ val `42` = Symbol("42")
+ val map = Map[Symbol, js.Any](Symbol("ScalaJS") -> "Scala.js", '$ -> 1.2, `42` -> 42)
+ expect(map('ScalaJS)).toEqual("Scala.js")
+ expect(map(Symbol("$"))).toEqual(1.2)
+ expect(map(Symbol("42"))).toEqual(42)
+ expect(map(`42`)).toEqual(42)
+ }
+
+ it("should support `name`") {
+ val scalajs = 'ScalaJS
+
+ expect(scalajs.name).toEqual("ScalaJS")
+ expect(Symbol("$").name).toEqual("$")
+ expect('$$.name).toEqual("$$")
+ expect('-.name).toEqual("-")
+ expect('*.name).toEqual("*")
+ expect(Symbol("'").name).toEqual("'")
+ expect(Symbol("\"").name).toEqual("\"")
+ }
+
+ it("should support `toString`") {
+ val scalajs = 'ScalaJS
+
+ expect(scalajs.toString).toEqual("'ScalaJS")
+ expect(Symbol("$").toString).toEqual("'$")
+ expect('$$.toString).toEqual("'$$")
+ expect('-.toString).toEqual("'-")
+ expect('*.toString).toEqual("'*")
+ expect(Symbol("'").toString).toEqual("''")
+ expect(Symbol("\"").toString).toEqual("'\"")
+ }
+
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/ArrayBufferInputStreamTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/ArrayBufferInputStreamTest.scala
new file mode 100644
index 0000000..7c49d0c
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/ArrayBufferInputStreamTest.scala
@@ -0,0 +1,36 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.typedarray
+
+import scala.scalajs.testsuite.javalib.CommonStreamsTests
+
+import scala.scalajs.js.typedarray._
+
+import org.scalajs.jasminetest.JasmineTest
+
+/** Tests for our implementation of java.io._ stream classes */
+object ArrayBufferInputStreamTest extends JasmineTest with CommonStreamsTests {
+
+ when("typedarray").
+ describe("scala.scalajs.js.typedarray.ArrayBufferInputStream") {
+ byteArrayInputStreamLikeTests(seq => new ArrayBufferInputStream(
+ new Int8Array(seq).buffer))
+ }
+
+ when("typedarray").
+ describe("scala.scalajs.js.typedarray.ArrayBufferInputStream - with offset") {
+ byteArrayInputStreamLikeTests { seq =>
+ val off = 100
+ val data = new Int8Array(seq.size + off)
+ data.set(seq, off)
+
+ new ArrayBufferInputStream(data.buffer, off, seq.size)
+ }
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/ArrayBufferTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/ArrayBufferTest.scala
new file mode 100644
index 0000000..9e64c7f
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/ArrayBufferTest.scala
@@ -0,0 +1,39 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.typedarray
+
+import org.scalajs.jasminetest.JasmineTest
+
+import scala.scalajs.js.typedarray._
+
+object ArrayBufferTest extends JasmineTest {
+
+ when("typedarry").
+ describe("ArrayBuffer") {
+
+ it("should provide a length constructor") {
+ val x = new ArrayBuffer(100)
+ expect(x.isInstanceOf[ArrayBuffer]).toBeTruthy
+ expect(x.byteLength).toBe(100)
+ }
+
+ it("should provide `slice` with one argument") {
+ val x = new ArrayBuffer(100)
+ val y = x.slice(10)
+ expect(y.byteLength).toBe(90)
+ }
+
+ it("should provide `slice` with two arguments") {
+ val x = new ArrayBuffer(100)
+ val y = x.slice(10, 20)
+ expect(y.byteLength).toBe(10)
+ }
+
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/ArraysTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/ArraysTest.scala
new file mode 100644
index 0000000..1976f3f
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/ArraysTest.scala
@@ -0,0 +1,45 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.typedarray
+
+import scala.scalajs.js.typedarray._
+import scala.scalajs.js.JSConverters._
+
+import scala.reflect._
+
+import org.scalajs.jasminetest.JasmineTest
+
+import scala.scalajs.testsuite.javalib
+
+object ArraysTest extends javalib.ArraysTest {
+
+ override def Array[T : ClassTag](v: T*): scala.Array[T] = classTag[T] match {
+ case ClassTag.Byte =>
+ new Int8Array(v.asInstanceOf[Seq[Byte]].toJSArray)
+ .toArray.asInstanceOf[scala.Array[T]]
+ case ClassTag.Short =>
+ new Int16Array(v.asInstanceOf[Seq[Short]].toJSArray)
+ .toArray.asInstanceOf[scala.Array[T]]
+ case ClassTag.Int =>
+ new Int32Array(v.asInstanceOf[Seq[Int]].toJSArray)
+ .toArray.asInstanceOf[scala.Array[T]]
+ case ClassTag.Float =>
+ new Float32Array(v.asInstanceOf[Seq[Float]].toJSArray)
+ .toArray.asInstanceOf[scala.Array[T]]
+ case ClassTag.Double =>
+ new Float64Array(v.asInstanceOf[Seq[Double]].toJSArray)
+ .toArray.asInstanceOf[scala.Array[T]]
+ case _ => scala.Array(v: _*)
+ }
+
+ override def testBody(suite: => Unit) = {
+ when("typedarray").
+ describe("java.util.Arrays backed with TypedArrays")(suite)
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/DataViewTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/DataViewTest.scala
new file mode 100644
index 0000000..76c5639
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/DataViewTest.scala
@@ -0,0 +1,275 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.typedarray
+
+import org.scalajs.jasminetest.JasmineTest
+
+import scala.scalajs.js.typedarray._
+
+object DataViewTest extends JasmineTest {
+
+ when("typedarray").
+ describe("DataView") {
+
+ it("should provide an ArrayBuffer only constructor") {
+ val buf = new ArrayBuffer(10)
+ val view = new DataView(buf)
+ expect(view.isInstanceOf[DataView]).toBeTruthy
+ expect(view.byteLength).toBe(10)
+ expect(view.byteOffset).toBe(0)
+ expect(view.getInt8(0)).toBe(0)
+ }
+
+ it("should provide an ArrayBuffer and offset constructor") {
+ val buf = new ArrayBuffer(10)
+ val view = new DataView(buf, 2)
+ expect(view.isInstanceOf[DataView]).toBeTruthy
+ expect(view.byteLength).toBe(8)
+ expect(view.byteOffset).toBe(2)
+ expect(view.getInt8(0)).toBe(0)
+ }
+
+ it("should provide an ArrayBuffer, offset and length constructor") {
+ val buf = new ArrayBuffer(10)
+ val view = new DataView(buf, 3, 2)
+ expect(view.isInstanceOf[DataView]).toBeTruthy
+ expect(view.byteLength).toBe(2)
+ expect(view.byteOffset).toBe(3)
+ expect(view.getInt8(0)).toBe(0)
+ }
+
+ it("should provide `getInt8`") {
+ val view = new DataView(new ArrayBuffer(4))
+
+ view.setInt8(0, 1)
+ view.setInt8(1, 127)
+ view.setInt8(3, -50)
+
+ expect(view.getInt8(0)).toBe(1)
+ expect(view.getInt8(1)).toBe(127)
+ expect(view.getInt8(2)).toBe(0)
+ expect(view.getInt8(3)).toBe(-50)
+ }
+
+ it("should provide `getUint8`") {
+ val view = new DataView(new ArrayBuffer(4))
+
+ view.setInt8(0, 1)
+ view.setInt8(1, -127)
+
+ expect(view.getUint8(0)).toBe(1)
+ expect(view.getUint8(1)).toBe(129)
+ expect(view.getUint8(2)).toBe(0)
+ }
+
+ it("should provide `getInt16`") {
+ val view = new DataView(new ArrayBuffer(4))
+
+ view.setUint8(0, 0x01)
+ view.setUint8(1, 0xFF)
+ view.setUint8(2, 0xB3)
+ view.setUint8(3, 0x30)
+
+ expect(view.getInt16(0)).toBe(0x01FF)
+ expect(view.getInt16(0, true)).toBe(-255)
+ expect(view.getInt16(1)).toBe(-77)
+ expect(view.getInt16(2, true)).toBe(0x30B3)
+ }
+
+ it("should provide `getUint16`") {
+ val view = new DataView(new ArrayBuffer(4))
+
+ view.setUint8(0, 0x01)
+ view.setUint8(1, 0xFF)
+ view.setUint8(2, 0xB3)
+ view.setUint8(3, 0x30)
+
+ expect(view.getUint16(0)).toBe(0x01FF)
+ expect(view.getUint16(0, true)).toBe(0xFF01)
+ expect(view.getUint16(1)).toBe(0xFFB3)
+ expect(view.getUint16(2, true)).toBe(0x30B3)
+ }
+
+ it("should provide `getInt32`") {
+ val view = new DataView(new ArrayBuffer(5))
+
+ view.setUint8(0, 0x01)
+ view.setUint8(1, 0xFF)
+ view.setUint8(2, 0xB3)
+ view.setUint8(3, 0x30)
+ view.setUint8(4, 0x1A)
+
+ expect(view.getInt32(0)).toBe(0x01FFB330)
+ expect(view.getInt32(0, true)).toBe(0x30B3FF01)
+ expect(view.getInt32(1)).toBe(0xFFB3301A) // is negative since Int
+ expect(view.getInt32(1, true)).toBe(0x1A30B3FF)
+ }
+
+ it("should provide `getUint32`") {
+ val view = new DataView(new ArrayBuffer(5))
+
+ view.setUint8(0, 0x01)
+ view.setUint8(1, 0xFF)
+ view.setUint8(2, 0xB3)
+ view.setUint8(3, 0x30)
+ view.setUint8(4, 0x1A)
+
+ expect(view.getUint32(0)).toBe(0x01FFB330)
+ expect(view.getUint32(0, true)).toBe(0x30B3FF01)
+ expect(view.getUint32(1)).toBe(0xFFB3301AL.toDouble)
+ expect(view.getUint32(1, true)).toBe(0x1A30B3FF)
+ }
+
+ it("should provide `getFloat32`") {
+ val view = new DataView(new ArrayBuffer(5))
+
+ view.setFloat32(0, 0.1f)
+
+ expect(view.getFloat32(0)).toBeCloseTo(0.1, 7)
+ expect(view.getFloat32(1)).not.toBeCloseTo(0.1, 7)
+ expect(view.getFloat32(0, true)).not.toBeCloseTo(0.1, 7)
+ expect(view.getFloat32(1, true)).not.toBeCloseTo(0.1, 7)
+ }
+
+ it("should provide `getFloat64`") {
+ val view = new DataView(new ArrayBuffer(9))
+
+ view.setFloat64(0, 0.5)
+
+ expect(view.getFloat64(0)).toBe(0.5)
+ expect(view.getFloat64(1)).not.toBe(0.5)
+ expect(view.getFloat64(0, true)).not.toBe(0.5)
+ expect(view.getFloat64(1, true)).not.toBe(0.5)
+ }
+
+ it("should provide `setInt8`") {
+ val view = new DataView(new ArrayBuffer(4))
+
+ view.setInt8(0, 1)
+ view.setInt8(1, 127)
+ view.setInt8(2, -20)
+ view.setInt8(3, -50)
+
+ expect(view.getUint8(0)).toBe(0x01)
+ expect(view.getUint8(1)).toBe(0x7F)
+ expect(view.getUint8(2)).toBe(0xEC)
+ expect(view.getUint8(3)).toBe(0xCE)
+ }
+
+ it("should provide `setUint8`") {
+ val view = new DataView(new ArrayBuffer(4))
+
+ view.setUint8(0, 0x01)
+ view.setUint8(1, 0xFC)
+ view.setUint8(2, 0x4D)
+ view.setUint8(3, 0x8C)
+
+ expect(view.getInt8(0)).toBe(1)
+ expect(view.getInt8(1)).toBe(-4)
+ expect(view.getInt8(2)).toBe(0x4D)
+ expect(view.getInt8(3)).toBe(-116)
+ }
+
+ it("should provide `setInt16`") {
+ val view = new DataView(new ArrayBuffer(4))
+
+ view.setInt16(0, 0x7F3B, true)
+ view.setInt16(2, -1)
+
+ expect(view.getUint8(0)).toBe(0x3B)
+ expect(view.getUint8(1)).toBe(0x7F)
+ expect(view.getUint8(2)).toBe(0xFF)
+ expect(view.getUint8(3)).toBe(0xFF)
+ }
+
+ it("should provide `setUint16`") {
+ val view = new DataView(new ArrayBuffer(4))
+
+ view.setUint16(0, 0x7F3B, true)
+ view.setUint16(2, 0xFCBA)
+
+ expect(view.getUint8(0)).toBe(0x3B)
+ expect(view.getUint8(1)).toBe(0x7F)
+ expect(view.getUint8(2)).toBe(0xFC)
+ expect(view.getUint8(3)).toBe(0xBA)
+
+ view.setUint16(1, 0x03BC)
+
+ expect(view.getUint8(0)).toBe(0x3B)
+ expect(view.getUint8(1)).toBe(0x03)
+ expect(view.getUint8(2)).toBe(0xBC)
+ expect(view.getUint8(3)).toBe(0xBA)
+ }
+
+ it("should provide `setInt32`") {
+ val view = new DataView(new ArrayBuffer(8))
+
+ view.setInt32(0, 0x7F3B8342, true)
+ view.setInt32(3, 0xFCBA1020)
+
+ expect(view.getUint8(0)).toBe(0x42)
+ expect(view.getUint8(1)).toBe(0x83)
+ expect(view.getUint8(2)).toBe(0x3B)
+ expect(view.getUint8(3)).toBe(0xFC)
+ expect(view.getUint8(4)).toBe(0xBA)
+ expect(view.getUint8(5)).toBe(0x10)
+ expect(view.getUint8(6)).toBe(0x20)
+ expect(view.getUint8(7)).toBe(0x00)
+ }
+
+ it("should provide `setUint32`") {
+ val view = new DataView(new ArrayBuffer(8))
+
+ view.setUint32(0, 0x7F3B8342, true)
+ view.setUint32(3, 0xFCBA1020L.toDouble)
+
+ expect(view.getUint8(0)).toBe(0x42)
+ expect(view.getUint8(1)).toBe(0x83)
+ expect(view.getUint8(2)).toBe(0x3B)
+ expect(view.getUint8(3)).toBe(0xFC)
+ expect(view.getUint8(4)).toBe(0xBA)
+ expect(view.getUint8(5)).toBe(0x10)
+ expect(view.getUint8(6)).toBe(0x20)
+ expect(view.getUint8(7)).toBe(0x00)
+ }
+
+ it("should provide `setFloat32`") {
+ val view = new DataView(new ArrayBuffer(5))
+
+ view.setFloat32(0, 0.1f)
+ view.setFloat32(1, 0.4f)
+
+ expect(view.getFloat32(1)).toBeCloseTo(0.4, 7)
+ expect(view.getFloat32(0)).not.toBeCloseTo(0.1, 7)
+
+ view.setFloat32(0, 0.1f, true)
+ view.setFloat32(1, 0.4f, true)
+
+ expect(view.getFloat32(0, true)).not.toBeCloseTo(0.1, 7)
+ expect(view.getFloat32(1, true)).toBeCloseTo(0.4, 7)
+ }
+
+ it("should provide `getFloat64`") {
+ val view = new DataView(new ArrayBuffer(9))
+
+ view.setFloat64(0, 0.5)
+ view.setFloat64(1, 0.6)
+
+ expect(view.getFloat64(0)).not.toBe(0.5)
+ expect(view.getFloat64(1)).toBe(0.6)
+
+ view.setFloat64(0, 0.5, true)
+ view.setFloat64(1, 0.6, true)
+
+ expect(view.getFloat64(0, true)).not.toBe(0.5)
+ expect(view.getFloat64(1, true)).toBe(0.6)
+ }
+
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/TypedArrayConversionTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/TypedArrayConversionTest.scala
new file mode 100644
index 0000000..dc9a056
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/TypedArrayConversionTest.scala
@@ -0,0 +1,197 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.typedarray
+
+import org.scalajs.jasminetest.JasmineTest
+
+import scala.scalajs.js
+import js.typedarray._
+
+object TypedArrayConversionTest extends JasmineTest {
+
+ when("typedarray").
+ describe("TypedArray to scala.Array conversions") {
+
+ def data(factor: Double) = js.Array(-1,1,2,3,4,5,6,7,8).map((_: Int) * factor)
+ def sum(factor: Double) = (8 * 9 / 2 - 1) * factor
+
+ it("should convert an Int8Array to a scala.Array[Byte]") {
+ val x = new Int8Array(data(1))
+ val y = x.toArray
+
+ expect(y.getClass == classOf[scala.Array[Byte]]).toBeTruthy
+ expect(y.sum).toEqual(sum(1))
+
+ // Ensure its a copy
+ x(0) = 0
+ expect(y.sum).toEqual(sum(1))
+ }
+
+ it("should convert an Int16Array to a scala.Array[Short]") {
+ val x = new Int16Array(data(100))
+ val y = x.toArray
+
+ expect(y.getClass == classOf[scala.Array[Short]]).toBeTruthy
+ expect(y.sum).toEqual(sum(100))
+
+ // Ensure its a copy
+ x(0) = 0
+ expect(y.sum).toEqual(sum(100))
+ }
+
+ it("should convert an Uint16Array to a scala.Array[Char]") {
+ val data = js.Array((1 to 6).map(_ * 10000): _*)
+ val sum = (6*7/2*10000).toChar
+
+ val x = new Uint16Array(data)
+ val y = x.toArray
+
+ expect(y.getClass == classOf[scala.Array[Char]]).toBeTruthy
+ expect(y.sum).toEqual(sum)
+
+ // Ensure its a copy
+ x(0) = 0
+ expect(y.sum).toEqual(sum)
+ }
+
+ it("should convert an Int32Array to a scala.Array[Int]") {
+ val x = new Int32Array(data(10000))
+ val y = x.toArray
+
+ expect(y.getClass == classOf[scala.Array[Int]]).toBeTruthy
+ expect(y.sum).toEqual(sum(10000))
+
+ // Ensure its a copy
+ x(0) = 0
+ expect(y.sum).toEqual(sum(10000))
+ }
+
+ it("should convert a Float32Array to a scala.Array[Float]") {
+ val x = new Float32Array(data(0.2))
+ val y = x.toArray
+
+ expect(y.getClass == classOf[scala.Array[Float]]).toBeTruthy
+ expect(y.sum).toBeCloseTo(sum(0.2), 6)
+
+ // Ensure its a copy
+ x(0) = 0
+ expect(y.sum).toBeCloseTo(sum(0.2), 6)
+ }
+
+ it("should convert a Float64Array to a scala.Array[Double]") {
+ val x = new Float64Array(data(0.2))
+ val y = x.toArray
+
+ expect(y.getClass == classOf[scala.Array[Double]]).toBeTruthy
+ expect(y.sum).toEqual(sum(0.2))
+
+ // Ensure its a copy
+ x(0) = 0
+ expect(y.sum).toEqual(sum(0.2))
+ }
+
+ }
+
+ when("typedarray").
+ describe("scala.Array to TypedArray conversions") {
+
+ it("should convert a scala.Array[Byte] to an Int8Array") {
+ val x = (Byte.MinValue to Byte.MaxValue).map(_.toByte).toArray
+ val y = x.toTypedArray
+
+ expect(y.isInstanceOf[Int8Array]).toBeTruthy
+ expect(y.length).toBe(x.length)
+
+ for (i <- 0 until y.length)
+ expect(y(i)).toBe(x(i))
+
+ // Ensure its a copy
+ x(0) = 0
+ expect(y(0)).toBe(Byte.MinValue)
+ }
+
+ it("should convert a scala.Array[Short] to an Int16Array") {
+ val x = ((Short.MinValue to (Short.MinValue + 1000)) ++
+ ((Short.MaxValue - 1000) to Short.MaxValue)).map(_.toShort).toArray
+ val y = x.toTypedArray
+
+ expect(y.isInstanceOf[Int16Array]).toBeTruthy
+ expect(y.length).toBe(x.length)
+
+ for (i <- 0 until y.length)
+ expect(y(i)).toBe(x(i))
+
+ // Ensure its a copy
+ x(0) = 0
+ expect(y(0)).toBe(Short.MinValue)
+ }
+
+ it("should convert a scala.Array[Char] to an Uint16Array") {
+ val x = ((Char.MaxValue - 1000) to Char.MaxValue).map(_.toChar).toArray
+ val y = x.toTypedArray
+
+ expect(y.isInstanceOf[Uint16Array]).toBeTruthy
+ expect(y.length).toBe(x.length)
+
+ for (i <- 0 until y.length)
+ expect(y(i)).toBe(x(i).toInt)
+
+ // Ensure its a copy
+ x(0) = 0
+ expect(y(0)).toBe(Char.MaxValue - 1000)
+ }
+
+ it("should convert a scala.Array[Int] to an Int32Array") {
+ val x = ((Int.MinValue to (Int.MinValue + 1000)) ++
+ ((Int.MaxValue - 1000) to Int.MaxValue)).toArray
+ val y = x.toTypedArray
+
+ expect(y.isInstanceOf[Int32Array]).toBeTruthy
+ expect(y.length).toBe(x.length)
+
+ for (i <- 0 until y.length)
+ expect(y(i)).toBe(x(i))
+
+ // Ensure its a copy
+ x(0) = 0
+ expect(y(0)).toBe(Int.MinValue)
+ }
+
+ it("should convert a scala.Array[Float] to a Float32Array") {
+ val x = Array[Float](1.0f, 2.0f, -2.3f, 5.3f)
+ val y = x.toTypedArray
+
+ expect(y.isInstanceOf[Float32Array]).toBeTruthy
+ expect(y.length).toBe(x.length)
+
+ for (i <- 0 until y.length)
+ expect(y(i)).toBe(x(i))
+
+ // Ensure its a copy
+ x(0) = 0
+ expect(y(0)).toBe(1.0f)
+ }
+
+ it("should convert a scala.Array[Double] to a Float64Array") {
+ val x = Array[Double](1.0, 2.0, -2.3, 5.3)
+ val y = x.toTypedArray
+
+ expect(y.isInstanceOf[Float64Array]).toBeTruthy
+ expect(y.length).toBe(x.length)
+
+ for (i <- 0 until y.length)
+ expect(y(i)).toBe(x(i))
+
+ // Ensure its a copy
+ x(0) = 0
+ expect(y(0)).toBe(1.0)
+ }
+
+ }
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/TypedArrayTest.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/TypedArrayTest.scala
new file mode 100644
index 0000000..1dfbbd4
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/typedarray/TypedArrayTest.scala
@@ -0,0 +1,332 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js Test Suite **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+package scala.scalajs.testsuite.typedarray
+
+import org.scalajs.jasminetest.JasmineTest
+import org.scalajs.jasmine.JasmineExpectation
+
+import scala.scalajs.js
+import js.typedarray._
+
+/** Shallow test for TypedArrays. Basically just tests that the method exist and
+ * return something which could be a right result. It is probably sufficient to
+ * test whether a runtime supports TypedArrays.
+ */
+object TypedArrayTest extends JasmineTest {
+
+ /** Generalized tests for all TypedArrays */
+ def tests[V, T <: TypedArray[V, T]](name: String,
+ bytesPerElement: => Int,
+ lenCtor: Int => T,
+ tarrCtor: TypedArray[_, _] => T,
+ arrCtor: js.Array[_] => T,
+ bufCtor1: (ArrayBuffer) => T,
+ bufCtor2: (ArrayBuffer, Int) => T,
+ bufCtor3: (ArrayBuffer, Int, Int) => T,
+ hasType: Any => Boolean,
+ expectV: V => JasmineExpectation,
+ intToV: Int => V
+ ) = {
+
+ when("typedarray").
+ describe(name) {
+
+ it(s"should allow constructing a new $name with length") {
+ val x = lenCtor(10)
+ expect(hasType(x)).toBeTruthy
+ expect(x.length).toBe(10)
+ }
+
+ it(s"should allow constructing a new $name from an Int8Array") {
+ val x = tarrCtor(new Float32Array(js.Array(3, 7)))
+ expect(hasType(x)).toBeTruthy
+ expect(x.length).toBe(2)
+
+ expectV(x(0)).toEqual(3)
+ expectV(x(1)).toEqual(7)
+ }
+
+ it(s"should allow constructing a new $name from a js.Array") {
+ val x = arrCtor(js.Array(5,6,7))
+ expect(hasType(x)).toBeTruthy
+ expect(x.length).toBe(3)
+
+ expectV(x(0)).toEqual(5)
+ expectV(x(1)).toEqual(6)
+ expectV(x(2)).toEqual(7)
+ }
+
+ it(s"should allow constructing a new $name from an ArrayBuffer (1 arg)") {
+ val buf = arrCtor(js.Array(5, 6, 7, 8)).buffer
+ val x = bufCtor1(buf)
+ expect(hasType(x)).toBeTruthy
+ expect(x.length).toBe(4)
+
+ expectV(x(0)).toEqual(5)
+ expectV(x(1)).toEqual(6)
+ expectV(x(2)).toEqual(7)
+ expectV(x(3)).toEqual(8)
+ }
+
+ it(s"should allow constructing a new $name from an ArrayBuffer (2 arg)") {
+ val buf = arrCtor(js.Array(5, 6, 7, 8)).buffer
+ val x = bufCtor2(buf, bytesPerElement)
+ expect(hasType(x)).toBeTruthy
+ expect(x.length).toBe(3)
+
+ expectV(x(0)).toEqual(6)
+ expectV(x(1)).toEqual(7)
+ expectV(x(2)).toEqual(8)
+ }
+
+ it(s"should allow constructing a new $name from an ArrayBuffer (3 arg)") {
+ val buf = arrCtor(js.Array(5, 6, 7, 8)).buffer
+ val x = bufCtor3(buf, bytesPerElement, 2)
+ expect(hasType(x)).toBeTruthy
+ expect(x.length).toBe(2)
+
+ expectV(x(0)).toEqual(6)
+ expectV(x(1)).toEqual(7)
+ }
+
+ it("should allow retrieving the length") {
+ val x = lenCtor(100)
+ expect(x.length).toBe(100)
+ }
+
+ it("should allow retrieving an element") {
+ val x = arrCtor(js.Array(5))
+ expectV(x(0)).toBe(5)
+ }
+
+ it("should allow setting an element") {
+ val x = lenCtor(2)
+
+ x(0) = intToV(5)
+ x(1) = intToV(10)
+
+ expectV(x(0)).toBe(5)
+ expectV(x(1)).toBe(10)
+ }
+
+ it("should provide `get`") {
+ val x = arrCtor(js.Array(10))
+ expectV(x.get(0)).toBe(10)
+ }
+
+ it("should provide `set` for a single element") {
+ val x = lenCtor(10)
+ x.set(0, intToV(5))
+ x.set(1, intToV(6))
+
+ expectV(x(0)).toBe(5)
+ expectV(x(1)).toBe(6)
+ expectV(x(2)).toBe(0)
+ }
+
+ it("should provide `set` for a js.Array with one arguments") {
+ val x = lenCtor(10)
+ x.set(js.Array(5,6,7))
+ expectV(x(0)).toBe(5)
+ expectV(x(1)).toBe(6)
+ expectV(x(2)).toBe(7)
+ expectV(x(3)).toBe(0)
+ expectV(x(4)).toBe(0)
+ expectV(x(5)).toBe(0)
+ }
+
+ it("should provide `set` for a js.Array with two arguments") {
+ val x = lenCtor(10)
+ x.set(js.Array(5,6,7), 2)
+ expectV(x(0)).toBe(0)
+ expectV(x(1)).toBe(0)
+ expectV(x(2)).toBe(5)
+ expectV(x(3)).toBe(6)
+ expectV(x(4)).toBe(7)
+ expectV(x(5)).toBe(0)
+ }
+
+ it("should provide `set` for a TypedArray with one argument") {
+ val x = lenCtor(10)
+ x.set(new Int8Array(js.Array(5,6,7)))
+ expectV(x(0)).toBe(5)
+ expectV(x(1)).toBe(6)
+ expectV(x(2)).toBe(7)
+ expectV(x(3)).toBe(0)
+ expectV(x(4)).toBe(0)
+ expectV(x(5)).toBe(0)
+ }
+
+ it("should provide `set` for a TypedArray with two arguments") {
+ val x = lenCtor(10)
+ x.set(new Int8Array(js.Array(5,6,7)), 2)
+ expectV(x(0)).toBe(0)
+ expectV(x(1)).toBe(0)
+ expectV(x(2)).toBe(5)
+ expectV(x(3)).toBe(6)
+ expectV(x(4)).toBe(7)
+ expectV(x(5)).toBe(0)
+ }
+
+ it("should provide `subarray` with one argument") {
+ val x = arrCtor(js.Array(1,2,3,4,5,6,7,8,9))
+ val y = x.subarray(2)
+
+ expect(y.length).toBe(7)
+ expectV(y(0)).toBe(3)
+
+ x(2) = intToV(100)
+
+ expectV(y(0)).toBe(100)
+ }
+
+ it("should provide `subarray` with two arguments") {
+ val x = arrCtor(js.Array(1,2,3,4,5,6,7,8,9))
+ val y = x.subarray(2, 4)
+
+ expect(y.length).toBe(2)
+ expectV(y(0)).toBe(3)
+
+ x(2) = intToV(100)
+
+ expectV(y(0)).toBe(100)
+ }
+
+ it("should provide `buffer`") {
+ val x = arrCtor(js.Array(1,2,3,4,5,6,7,8,9))
+ val y = bufCtor3(x.buffer, 0, 2)
+
+ expect(x.buffer eq y.buffer).toBeTruthy
+ }
+
+ it("should provide `byteLength`") {
+ val x = arrCtor(js.Array(0 until bytesPerElement * 4: _*))
+ val y = bufCtor3(x.buffer, bytesPerElement, 3)
+
+ expect(y.byteLength).toBe(3 * bytesPerElement)
+ }
+
+ it("should provide `byteOffset`") {
+ val x = arrCtor(js.Array(0 until bytesPerElement * 4: _*))
+ val y = bufCtor3(x.buffer, bytesPerElement, 3)
+
+ expect(y.byteOffset).toBe(bytesPerElement)
+ }
+
+ }
+ }
+
+ tests("Int8Array",
+ Int8Array.BYTES_PER_ELEMENT,
+ len => new Int8Array(len),
+ tarr => new Int8Array(tarr),
+ arr => new Int8Array(arr),
+ buf => new Int8Array(buf),
+ (buf, start) => new Int8Array(buf, start),
+ (buf, start, end) => new Int8Array(buf, start, end),
+ _.isInstanceOf[Int8Array],
+ expect (_: Byte),
+ _.toByte)
+
+ tests("Uint8Array",
+ Uint8Array.BYTES_PER_ELEMENT,
+ len => new Uint8Array(len),
+ tarr => new Uint8Array(tarr),
+ arr => new Uint8Array(arr),
+ buf => new Uint8Array(buf),
+ (buf, start) => new Uint8Array(buf, start),
+ (buf, start, end) => new Uint8Array(buf, start, end),
+ _.isInstanceOf[Uint8Array],
+ expect (_: Short),
+ _.toShort)
+
+ tests("Uint8ClampedArray",
+ Uint8ClampedArray.BYTES_PER_ELEMENT,
+ len => new Uint8ClampedArray(len),
+ tarr => new Uint8ClampedArray(tarr),
+ arr => new Uint8ClampedArray(arr),
+ buf => new Uint8ClampedArray(buf),
+ (buf, start) => new Uint8ClampedArray(buf, start),
+ (buf, start, end) => new Uint8ClampedArray(buf, start, end),
+ _.isInstanceOf[Uint8ClampedArray],
+ expect (_: Int),
+ _.toInt)
+
+ tests("Int16Array",
+ Int16Array.BYTES_PER_ELEMENT,
+ len => new Int16Array(len),
+ tarr => new Int16Array(tarr),
+ arr => new Int16Array(arr),
+ buf => new Int16Array(buf),
+ (buf, start) => new Int16Array(buf, start),
+ (buf, start, end) => new Int16Array(buf, start, end),
+ _.isInstanceOf[Int16Array],
+ expect (_: Short),
+ _.toShort)
+
+ tests("Uint16Array",
+ Uint16Array.BYTES_PER_ELEMENT,
+ len => new Uint16Array(len),
+ tarr => new Uint16Array(tarr),
+ arr => new Uint16Array(arr),
+ buf => new Uint16Array(buf),
+ (buf, start) => new Uint16Array(buf, start),
+ (buf, start, end) => new Uint16Array(buf, start, end),
+ _.isInstanceOf[Uint16Array],
+ expect (_: Int),
+ _.toInt)
+
+ tests("Int32Array",
+ Int32Array.BYTES_PER_ELEMENT,
+ len => new Int32Array(len),
+ tarr => new Int32Array(tarr),
+ arr => new Int32Array(arr),
+ buf => new Int32Array(buf),
+ (buf, start) => new Int32Array(buf, start),
+ (buf, start, end) => new Int32Array(buf, start, end),
+ _.isInstanceOf[Int32Array],
+ expect (_: Int),
+ _.toInt)
+
+ tests("Uint32Array",
+ Uint32Array.BYTES_PER_ELEMENT,
+ len => new Uint32Array(len),
+ tarr => new Uint32Array(tarr),
+ arr => new Uint32Array(arr),
+ buf => new Uint32Array(buf),
+ (buf, start) => new Uint32Array(buf, start),
+ (buf, start, end) => new Uint32Array(buf, start, end),
+ _.isInstanceOf[Uint32Array],
+ expect (_: Double),
+ _.toDouble)
+
+ tests("Float32Array",
+ Float32Array.BYTES_PER_ELEMENT,
+ len => new Float32Array(len),
+ tarr => new Float32Array(tarr),
+ arr => new Float32Array(arr),
+ buf => new Float32Array(buf),
+ (buf, start) => new Float32Array(buf, start),
+ (buf, start, end) => new Float32Array(buf, start, end),
+ _.isInstanceOf[Float32Array],
+ expect (_: Float),
+ _.toFloat)
+
+ tests("Float64Array",
+ Float64Array.BYTES_PER_ELEMENT,
+ len => new Float64Array(len),
+ tarr => new Float64Array(tarr),
+ arr => new Float64Array(arr),
+ buf => new Float64Array(buf),
+ (buf, start) => new Float64Array(buf, start),
+ (buf, start, end) => new Float64Array(buf, start, end),
+ _.isInstanceOf[Float64Array],
+ expect (_: Double),
+ _.toDouble)
+
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/utils/JSUtils.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/utils/JSUtils.scala
new file mode 100644
index 0000000..4b2ac62
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/utils/JSUtils.scala
@@ -0,0 +1,26 @@
+package scala.scalajs.testsuite.utils
+
+import scala.scalajs.js
+import js.annotation.JSExport
+
+@JSExport("JSUtils")
+object JSUtils {
+ /* We use java.lang.Character explicitly, because this class is used by
+ * tests that check that Chars are actually boxed by the compiler.
+ * If we rely on the compiler doing the job in here, we might have false
+ * positives just because the value was never boxed, and never unboxed.
+ */
+
+ @JSExport
+ def isChar(c: Any): Boolean = c.isInstanceOf[java.lang.Character]
+
+ @JSExport
+ def stringToChar(s: String): java.lang.Character = {
+ assert(s.length == 1, "makeChar() requires a string of length 1")
+ new java.lang.Character(s.charAt(0))
+ }
+
+ @JSExport
+ def charToString(c: Any): String =
+ c.asInstanceOf[java.lang.Character].toString()
+}
diff --git a/test-suite/src/test/scala/scala/scalajs/testsuite/utils/TestDetector.scala b/test-suite/src/test/scala/scala/scalajs/testsuite/utils/TestDetector.scala
new file mode 100644
index 0000000..ad67a95
--- /dev/null
+++ b/test-suite/src/test/scala/scala/scalajs/testsuite/utils/TestDetector.scala
@@ -0,0 +1,33 @@
+package scala.scalajs.testsuite.utils
+
+import scala.scalajs.js
+import js.annotation.JSExport
+import js.JSConverters._
+
+/** An ad-hoc but centralized way to detect tests in this test suite */
+@JSExport("scalajs.TestDetector")
+object TestDetector {
+
+ private final val basePackage = "scala.scalajs.testsuite"
+
+ def detectTestNames(): List[String] = detectTestsInternal().map(_._2).toList
+
+ @JSExport
+ def loadDetectedTests(): Unit = detectTestsInternal().foreach(_._1())
+
+ private def detectTestsInternal() = {
+ val parts = basePackage.split('.')
+ val base = parts.foldLeft(js.Dynamic.global)(_.selectDynamic(_))
+
+ // We make sure to use only exported modules (not classes) by checking
+ // .prototype of the exporters.
+ for {
+ pName <- js.Object.properties(base)
+ testName <- js.Object.properties(base.selectDynamic(pName))
+ test = base.selectDynamic(pName).selectDynamic(testName)
+ if js.Object.getPrototypeOf(test.prototype.asInstanceOf[js.Object]) eq
+ js.Object.asInstanceOf[js.Dynamic].prototype
+ } yield (test, s"$basePackage.$pName.$testName")
+ }
+
+}