Skip to content

Commit fdeed85

Browse files
committed
Moved Caller tests to CallerSpec
1 parent a4acf04 commit fdeed85

File tree

3 files changed

+109
-102
lines changed

3 files changed

+109
-102
lines changed

source/ports/scala_port/build.sbt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,5 @@ lazy val root = (project in file("."))
3030
.settings(commonSettings: _*)
3131
.settings(
3232
name := "metacall",
33-
fork in (Test / run) := true,
3433
parallelExecution in Test := false
3534
)
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package metacall
2+
3+
import cats.implicits._
4+
import metacall.instances._
5+
import org.scalatest.flatspec.AnyFlatSpec
6+
7+
class CallerSpec extends AnyFlatSpec {
8+
// TODO: This won't work with NodeJS, it is not tolerant a reinitialization.
9+
// Probably we should split this into two tests, one for the caller (event loop based),
10+
// and another for MetaCall without event loop. So each test suite runs in a different process.
11+
"Caller" should "start successfully" in {
12+
Caller.start()
13+
}
14+
15+
"Caller" should "load scripts into global scope successfully" in {
16+
Caller.loadFile(Runtime.Python, "./src/test/scala/scripts/main.py", None)
17+
}
18+
19+
"Caller" should "load scripts into namespaces" in {
20+
Caller.loadFile(Runtime.Python, "./src/test/scala/scripts/s1.py", Some("s1"))
21+
Caller.loadFile(Runtime.Python, "./src/test/scala/scripts/s2.py", Some("s2"))
22+
23+
assert(
24+
Caller.blocking.call("fn_in_s1", (), Some("s1")) == StringValue("Hello from s1")
25+
)
26+
}
27+
28+
"Caller" should "call functions and clean up arguments and returned pointers" in {
29+
val ret = Caller.blocking.callV(
30+
"hello_scala_from_python",
31+
List(StringValue("Hello "), StringValue("Scala!"))
32+
)
33+
34+
assert(ret == StringValue("Hello Scala!"))
35+
}
36+
37+
"FunctionValues" should "be constructed and passed to foreign functions" in {
38+
val fnVal = FunctionValue {
39+
case LongValue(l) :: Nil => LongValue(l + 1L)
40+
case _ => NullValue
41+
}
42+
43+
val ret = Caller.blocking.callV("apply_fn_to_one", fnVal :: Nil)
44+
45+
assert(ret == LongValue(2L))
46+
}
47+
48+
"Generic API" should "operate on primitive Scala values" in {
49+
// with tuples
50+
val ret = Caller.blocking.call("big_fn", (1, "hello", 2.2))
51+
assert(ret == DoubleValue(8.2))
52+
53+
// with single-element products (i.e. the List)
54+
val ret2 = Caller.blocking.call("sumList", List(1, 2, 3))
55+
assert(ret2 == LongValue(6))
56+
57+
// with HLists
58+
import shapeless._
59+
60+
val ret3 = Caller.blocking.call("big_fn", 1 :: "hello" :: 2.2 :: HNil)
61+
assert(ret3 == DoubleValue(8.2))
62+
}
63+
64+
"Using `Caller` from multiple threads" should "work" in {
65+
import scala.concurrent._, duration._
66+
import ExecutionContext.Implicits.global
67+
68+
val rangeValues: List[ArrayValue] =
69+
List.range(1, 50).map(n => ArrayValue(Vector.range(1, n).map(IntValue)))
70+
71+
val resSum = rangeValues
72+
.traverse { range =>
73+
Future(Caller.blocking.callV("sumList", range :: Nil)) map {
74+
case n: NumericValue[_] => n.long.value
75+
case other => fail("Returned value should be a number, but got " + other)
76+
}
77+
}
78+
.map(_.sum)
79+
80+
val result = Await.result(resSum, 10.seconds)
81+
82+
assert(result == 19600)
83+
}
84+
85+
"Calling functions many times in parallel" should "work" in {
86+
import scala.concurrent._, duration._
87+
import ExecutionContext.Implicits.global
88+
89+
val rangeValues: List[ArrayValue] =
90+
List.range(1, 50).map(n => ArrayValue(Vector.range(1, n).map(IntValue)))
91+
92+
val resSum = rangeValues
93+
.traverse { range =>
94+
Caller.callV("sumList", range :: Nil) map {
95+
case n: NumericValue[_] => n.long.value
96+
case other => fail("Returned value should be a number, but got " + other)
97+
}
98+
}
99+
.map(_.sum)
100+
101+
val result = Await.result(resSum, 10.seconds)
102+
103+
assert(result == 19600)
104+
}
105+
106+
"Caller" should "be destroyed correctly" in {
107+
Caller.destroy()
108+
}
109+
}

source/ports/scala_port/src/test/scala/MetaCallSpec.scala

Lines changed: 0 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -465,105 +465,4 @@ class MetaCallSpec extends AnyFlatSpec {
465465
}
466466
}
467467

468-
// TODO: This won't work with NodeJS, it is not tolerant a reinitialization.
469-
// Probably we should split this into two tests, one for the caller (event loop based),
470-
// and another for MetaCall without event loop. So each test suite runs in a different process.
471-
"Caller" should "start successfully" in {
472-
Caller.start()
473-
}
474-
475-
"Caller" should "load scripts into global scope successfully" in {
476-
Caller.loadFile(Runtime.Python, "./src/test/scala/scripts/main.py", None)
477-
}
478-
479-
"Caller" should "load scripts into namespaces" in {
480-
Caller.loadFile(Runtime.Python, "./src/test/scala/scripts/s1.py", Some("s1"))
481-
Caller.loadFile(Runtime.Python, "./src/test/scala/scripts/s2.py", Some("s2"))
482-
483-
assert(
484-
Caller.blocking.call("fn_in_s1", (), Some("s1")) == StringValue("Hello from s1")
485-
)
486-
}
487-
488-
"Caller" should "call functions and clean up arguments and returned pointers" in {
489-
val ret = Caller.blocking.callV(
490-
"hello_scala_from_python",
491-
List(StringValue("Hello "), StringValue("Scala!"))
492-
)
493-
494-
assert(ret == StringValue("Hello Scala!"))
495-
}
496-
497-
"FunctionValues" should "be constructed and passed to foreign functions" in {
498-
val fnVal = FunctionValue {
499-
case LongValue(l) :: Nil => LongValue(l + 1L)
500-
case _ => NullValue
501-
}
502-
503-
val ret = Caller.blocking.callV("apply_fn_to_one", fnVal :: Nil)
504-
505-
assert(ret == LongValue(2L))
506-
}
507-
508-
"Generic API" should "operate on primitive Scala values" in {
509-
// with tuples
510-
val ret = Caller.blocking.call("big_fn", (1, "hello", 2.2))
511-
assert(ret == DoubleValue(8.2))
512-
513-
// with single-element products (i.e. the List)
514-
val ret2 = Caller.blocking.call("sumList", List(1, 2, 3))
515-
assert(ret2 == LongValue(6))
516-
517-
// with HLists
518-
import shapeless._
519-
520-
val ret3 = Caller.blocking.call("big_fn", 1 :: "hello" :: 2.2 :: HNil)
521-
assert(ret3 == DoubleValue(8.2))
522-
}
523-
524-
"Using `Caller` from multiple threads" should "work" in {
525-
import scala.concurrent._, duration._
526-
import ExecutionContext.Implicits.global
527-
528-
val rangeValues: List[ArrayValue] =
529-
List.range(1, 50).map(n => ArrayValue(Vector.range(1, n).map(IntValue)))
530-
531-
val resSum = rangeValues
532-
.traverse { range =>
533-
Future(Caller.blocking.callV("sumList", range :: Nil)) map {
534-
case n: NumericValue[_] => n.long.value
535-
case other => fail("Returned value should be a number, but got " + other)
536-
}
537-
}
538-
.map(_.sum)
539-
540-
val result = Await.result(resSum, 10.seconds)
541-
542-
assert(result == 19600)
543-
}
544-
545-
"Calling functions many times in parallel" should "work" in {
546-
import scala.concurrent._, duration._
547-
import ExecutionContext.Implicits.global
548-
549-
val rangeValues: List[ArrayValue] =
550-
List.range(1, 50).map(n => ArrayValue(Vector.range(1, n).map(IntValue)))
551-
552-
val resSum = rangeValues
553-
.traverse { range =>
554-
Caller.callV("sumList", range :: Nil) map {
555-
case n: NumericValue[_] => n.long.value
556-
case other => fail("Returned value should be a number, but got " + other)
557-
}
558-
}
559-
.map(_.sum)
560-
561-
val result = Await.result(resSum, 10.seconds)
562-
563-
assert(result == 19600)
564-
}
565-
566-
"Caller" should "be destroyed correctly" in {
567-
Caller.destroy()
568-
}
569468
}

0 commit comments

Comments
 (0)