mirror of
https://github.com/fluencelabs/aqua.git
synced 2024-12-04 14:40:17 +00:00
fix(compiler): Do not restrict stream args when ability is present [fixes LNG-233] (#902)
Add test
This commit is contained in:
parent
bba6645e7a
commit
54ddcc8b62
@ -4,17 +4,22 @@ import aqua.parser.expr.func.ArrowExpr
|
|||||||
import aqua.parser.lexer.{BasicTypeToken, Name}
|
import aqua.parser.lexer.{BasicTypeToken, Name}
|
||||||
import aqua.raw.Raw
|
import aqua.raw.Raw
|
||||||
import aqua.raw.arrow.ArrowRaw
|
import aqua.raw.arrow.ArrowRaw
|
||||||
import aqua.raw.ops.{FuncOp, RawTag, ReturnTag, SeqTag}
|
import aqua.raw.ops.*
|
||||||
import aqua.raw.value.LiteralRaw
|
import aqua.raw.value.LiteralRaw
|
||||||
import aqua.semantics.expr.func.ArrowSem
|
import aqua.semantics.expr.func.ArrowSem
|
||||||
|
import aqua.semantics.rules.types.TypesState
|
||||||
import aqua.types.*
|
import aqua.types.*
|
||||||
|
import aqua.types.ScalarType.*
|
||||||
|
|
||||||
import cats.Id
|
import cats.Id
|
||||||
import cats.data.{NonEmptyList, State}
|
import cats.syntax.applicative.*
|
||||||
|
import cats.data.{NonEmptyList, NonEmptyMap, State}
|
||||||
import org.scalatest.EitherValues
|
import org.scalatest.EitherValues
|
||||||
import org.scalatest.flatspec.AnyFlatSpec
|
import org.scalatest.flatspec.AnyFlatSpec
|
||||||
import org.scalatest.matchers.should.Matchers
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
import org.scalatest.Inside
|
||||||
|
|
||||||
class ArrowSemSpec extends AnyFlatSpec with Matchers with EitherValues {
|
class ArrowSemSpec extends AnyFlatSpec with Matchers with EitherValues with Inside {
|
||||||
|
|
||||||
import Utils.{given, *}
|
import Utils.{given, *}
|
||||||
|
|
||||||
@ -27,21 +32,19 @@ class ArrowSemSpec extends AnyFlatSpec with Matchers with EitherValues {
|
|||||||
sem.program[State[CompilerState[Id], *]]
|
sem.program[State[CompilerState[Id], *]]
|
||||||
}
|
}
|
||||||
|
|
||||||
"sem" should "create empty model" in {
|
"ArrowSem" should "create empty model" in {
|
||||||
val model = getModel(program("(a: string, b: u32) -> u8"))
|
val model = getModel(program("(a: string, b: u32) -> u8"))
|
||||||
model shouldBe (Raw.Empty("Invalid arrow body"))
|
model shouldBe (Raw.Empty("Invalid arrow body"))
|
||||||
}
|
}
|
||||||
|
|
||||||
"sem" should "create error model" ignore {
|
it should "create error model" ignore {
|
||||||
val model = getModel(RawTag.empty.toFuncOp)(program("(a: string, b: u32) -> u8"))
|
val model = getModel(RawTag.empty.toFuncOp)(program("(a: string, b: u32) -> u8"))
|
||||||
model shouldBe Raw.Empty(
|
model shouldBe Raw.Empty(
|
||||||
"Return type is defined for the arrow, but nothing returned. Use `<- value, ...` as the last expression inside function body."
|
"Return type is defined for the arrow, but nothing returned. Use `<- value, ...` as the last expression inside function body."
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
import aqua.types.ScalarType.*
|
it should "create right model for arrow without return type" ignore {
|
||||||
|
|
||||||
"arrow without return type" should "create right model" ignore {
|
|
||||||
val model = getModel(RawTag.empty.toFuncOp)(program("(a: string, b: u32)"))
|
val model = getModel(RawTag.empty.toFuncOp)(program("(a: string, b: u32)"))
|
||||||
model shouldBe ArrowRaw(
|
model shouldBe ArrowRaw(
|
||||||
ArrowType(labelled("a", string, labelled("b", u32)), NilType),
|
ArrowType(labelled("a", string, labelled("b", u32)), NilType),
|
||||||
@ -50,7 +53,7 @@ class ArrowSemSpec extends AnyFlatSpec with Matchers with EitherValues {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
"arrow with return type and correct state" should "create correct model" ignore {
|
it should "create correct model for arrow with return type and correct state" ignore {
|
||||||
val returnValue = LiteralRaw("123", string)
|
val returnValue = LiteralRaw("123", string)
|
||||||
val returnTag = FuncOp(ReturnTag(NonEmptyList.one(returnValue)).wrap(RawTag.empty))
|
val returnTag = FuncOp(ReturnTag(NonEmptyList.one(returnValue)).wrap(RawTag.empty))
|
||||||
val model = getModel(returnTag)(program("(a: string, b: u32) -> string"))
|
val model = getModel(returnTag)(program("(a: string, b: u32) -> string"))
|
||||||
@ -60,7 +63,7 @@ class ArrowSemSpec extends AnyFlatSpec with Matchers with EitherValues {
|
|||||||
model shouldBe resultModel
|
model shouldBe resultModel
|
||||||
}
|
}
|
||||||
|
|
||||||
"arrow with return type and seq inside" should "create correct model" ignore {
|
it should "create correct model for arrow with return type and seq inside" ignore {
|
||||||
val returnValue = LiteralRaw("123", string)
|
val returnValue = LiteralRaw("123", string)
|
||||||
val seq = FuncOp(SeqTag.wrap(RawTag.empty, ReturnTag(NonEmptyList.one(returnValue)).leaf))
|
val seq = FuncOp(SeqTag.wrap(RawTag.empty, ReturnTag(NonEmptyList.one(returnValue)).leaf))
|
||||||
val model = getModel(seq)(program("(a: string, b: u32) -> string"))
|
val model = getModel(seq)(program("(a: string, b: u32) -> string"))
|
||||||
@ -70,7 +73,7 @@ class ArrowSemSpec extends AnyFlatSpec with Matchers with EitherValues {
|
|||||||
model shouldBe resultModel
|
model shouldBe resultModel
|
||||||
}
|
}
|
||||||
|
|
||||||
"different types in return type and return value" should "create error model" ignore {
|
it should "create error model for different types in return type and return value" ignore {
|
||||||
val returnValue = LiteralRaw("123", string)
|
val returnValue = LiteralRaw("123", string)
|
||||||
val seq = FuncOp(
|
val seq = FuncOp(
|
||||||
SeqTag.wrap(
|
SeqTag.wrap(
|
||||||
@ -86,4 +89,74 @@ class ArrowSemSpec extends AnyFlatSpec with Matchers with EitherValues {
|
|||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it should "not restrict stream arguments" in {
|
||||||
|
val body =
|
||||||
|
PushToStreamTag(
|
||||||
|
LiteralRaw.quote("a"),
|
||||||
|
Call.Export("s", StreamType(ScalarType.string))
|
||||||
|
).leaf
|
||||||
|
|
||||||
|
def test(
|
||||||
|
abilityArgs: List[String],
|
||||||
|
args: List[String],
|
||||||
|
initState: CompilerState[Id]
|
||||||
|
) = {
|
||||||
|
val abilityPart =
|
||||||
|
if (abilityArgs.isEmpty) ""
|
||||||
|
else abilityArgs.mkString("{", ",", "}")
|
||||||
|
val argsPart = args.appended("s: *string").mkString("(", ",", ")")
|
||||||
|
val expr = abilityPart + argsPart
|
||||||
|
|
||||||
|
val (state, raw) = program(expr).apply(body.toFuncOp.pure).run(initState).value
|
||||||
|
|
||||||
|
state.errors shouldBe empty
|
||||||
|
inside(raw) { case ArrowRaw(_, Nil, bodyRes) =>
|
||||||
|
bodyRes shouldBe body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val structType = StructType(
|
||||||
|
"TestStruct",
|
||||||
|
NonEmptyMap.one(
|
||||||
|
"field",
|
||||||
|
ScalarType.string
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val abilityType = AbilityType(
|
||||||
|
"TestAbility",
|
||||||
|
NonEmptyMap.one(
|
||||||
|
"field",
|
||||||
|
ScalarType.string
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val state: CompilerState[Id] = CompilerState(
|
||||||
|
types = TypesState(
|
||||||
|
strict = Map(
|
||||||
|
"FirstAbility" -> abilityType,
|
||||||
|
"SecondAbility" -> abilityType,
|
||||||
|
"DataStruct" -> structType
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val abilityArgs = List(
|
||||||
|
"FirstAbility",
|
||||||
|
"SecondAbility"
|
||||||
|
)
|
||||||
|
|
||||||
|
val args = List(
|
||||||
|
"a: string",
|
||||||
|
"callback: u32 -> string",
|
||||||
|
"data: DataStruct"
|
||||||
|
)
|
||||||
|
|
||||||
|
for {
|
||||||
|
abilityArgs <- abilityArgs.toSet.subsets()
|
||||||
|
args <- args.toSet.subsets()
|
||||||
|
} test(abilityArgs.toList, args.toList, state)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -74,9 +74,10 @@ sealed trait ProductType extends Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lazy val labelledData: List[(String, DataType)] = this match {
|
lazy val labelledData: List[(String, DataType)] = this match {
|
||||||
case LabeledConsType(label, t: DataType, pt) => (label -> t) :: pt.labelledData
|
case LabeledConsType(label, t: DataType, pt) =>
|
||||||
case LabeledConsType(label, t: ArrowType, pt) => pt.labelledData
|
(label -> t) :: pt.labelledData
|
||||||
case UnlabeledConsType(_, pt) => pt.labelledData
|
case ConsType(_, pt) =>
|
||||||
|
pt.labelledData
|
||||||
case _ => Nil
|
case _ => Nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user