mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 01:07:18 +03:00
LF: Exhaustive test for valueTranslator. (#10927)
* LF: Exhaustive test for value translator. CHANGELOG_BEGIN CHANGELOG_END * cosmetic
This commit is contained in:
parent
409c0b4f60
commit
ac02dbdeb9
@ -79,8 +79,8 @@ private[engine] final class ValueTranslator(
|
|||||||
throw Error.Preprocessing.ValueNesting(value)
|
throw Error.Preprocessing.ValueNesting(value)
|
||||||
} else {
|
} else {
|
||||||
val newNesting = nesting + 1
|
val newNesting = nesting + 1
|
||||||
def typeError(msg: String = s"mismatching type: $ty and value: $value0") =
|
def typeError(msg: String = s"mismatching type: ${ty0.pretty} and value: $value0") =
|
||||||
throw Error.Preprocessing.TypeMismatch(ty, value0, msg)
|
throw Error.Preprocessing.TypeMismatch(ty0, value0, msg)
|
||||||
val (ty1, tyArgs) = AstUtil.destructApp(ty0)
|
val (ty1, tyArgs) = AstUtil.destructApp(ty0)
|
||||||
ty1 match {
|
ty1 match {
|
||||||
case TBuiltin(bt) =>
|
case TBuiltin(bt) =>
|
||||||
|
@ -27,7 +27,7 @@ class CommandPreprocessorSpec
|
|||||||
import com.daml.lf.transaction.test.TransactionBuilder.Implicits.{defaultPackageId => _, _}
|
import com.daml.lf.transaction.test.TransactionBuilder.Implicits.{defaultPackageId => _, _}
|
||||||
private implicit val defaultPackageId = defaultParserParameters.defaultPackageId
|
private implicit val defaultPackageId = defaultParserParameters.defaultPackageId
|
||||||
|
|
||||||
lazy val pkg =
|
private[this] val pkg =
|
||||||
p"""
|
p"""
|
||||||
module Mod {
|
module Mod {
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ class CommandPreprocessorSpec
|
|||||||
private[this] val compiledPackage = ConcurrentCompiledPackages()
|
private[this] val compiledPackage = ConcurrentCompiledPackages()
|
||||||
assert(compiledPackage.addPackage(defaultPackageId, pkg) == ResultDone.Unit)
|
assert(compiledPackage.addPackage(defaultPackageId, pkg) == ResultDone.Unit)
|
||||||
|
|
||||||
val valueParties = ValueList(FrontStack(ValueParty("Alice")))
|
private[this] val valueParties = ValueList(FrontStack(ValueParty("Alice")))
|
||||||
|
|
||||||
"preprocessCommand" should {
|
"preprocessCommand" should {
|
||||||
|
|
||||||
|
@ -180,278 +180,6 @@ class EngineTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
"command translation" should {
|
"command translation" should {
|
||||||
"translate create commands argument including labels" in {
|
|
||||||
val id = Identifier(basicTestsPkgId, "BasicTests:Simple")
|
|
||||||
val command =
|
|
||||||
CreateCommand(id, ValueRecord(Some(id), ImmArray((Some[Name]("p"), ValueParty(party)))))
|
|
||||||
|
|
||||||
val res = preprocessor
|
|
||||||
.preprocessCommands(ImmArray(command))
|
|
||||||
.consume(lookupContract, lookupPackage, lookupKey)
|
|
||||||
res shouldBe a[Right[_, _]]
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
"translate create commands argument without labels" in {
|
|
||||||
val id = Identifier(basicTestsPkgId, "BasicTests:Simple")
|
|
||||||
val command =
|
|
||||||
CreateCommand(id, ValueRecord(Some(id), ImmArray((None, ValueParty(party)))))
|
|
||||||
|
|
||||||
val res = preprocessor
|
|
||||||
.preprocessCommands(ImmArray(command))
|
|
||||||
.consume(lookupContract, lookupPackage, lookupKey)
|
|
||||||
res shouldBe a[Right[_, _]]
|
|
||||||
}
|
|
||||||
|
|
||||||
"not translate create commands argument wrong label" in {
|
|
||||||
val id = Identifier(basicTestsPkgId, "BasicTests:Simple")
|
|
||||||
val command =
|
|
||||||
CreateCommand(
|
|
||||||
id,
|
|
||||||
ValueRecord(Some(id), ImmArray((Some[Name]("this_is_not_the_one"), ValueParty(party)))),
|
|
||||||
)
|
|
||||||
|
|
||||||
val res = preprocessor
|
|
||||||
.preprocessCommands(ImmArray(command))
|
|
||||||
.consume(lookupContract, lookupPackage, lookupKey)
|
|
||||||
inside(res) { case Left(Error.Preprocessing(error)) =>
|
|
||||||
error shouldBe a[Error.Preprocessing.TypeMismatch]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
"translate exercise commands argument including labels" in {
|
|
||||||
val originalCoid = toContractId("BasicTests:CallablePayout:1")
|
|
||||||
val templateId = Identifier(basicTestsPkgId, "BasicTests:CallablePayout")
|
|
||||||
val command = ExerciseCommand(
|
|
||||||
templateId,
|
|
||||||
originalCoid,
|
|
||||||
"Transfer",
|
|
||||||
ValueRecord(None, ImmArray((Some[Name]("newReceiver"), ValueParty(clara)))),
|
|
||||||
)
|
|
||||||
|
|
||||||
val res = preprocessor
|
|
||||||
.preprocessCommands(ImmArray(command))
|
|
||||||
.consume(lookupContract, lookupPackage, lookupKey)
|
|
||||||
res shouldBe a[Right[_, _]]
|
|
||||||
}
|
|
||||||
|
|
||||||
"translate exercise commands argument without labels" in {
|
|
||||||
val originalCoid = toContractId("BasicTests:CallablePayout:1")
|
|
||||||
val templateId = Identifier(basicTestsPkgId, "BasicTests:CallablePayout")
|
|
||||||
val command = ExerciseCommand(
|
|
||||||
templateId,
|
|
||||||
originalCoid,
|
|
||||||
"Transfer",
|
|
||||||
ValueRecord(None, ImmArray((None, ValueParty(clara)))),
|
|
||||||
)
|
|
||||||
|
|
||||||
val res = preprocessor
|
|
||||||
.preprocessCommands(ImmArray(command))
|
|
||||||
.consume(lookupContract, lookupPackage, lookupKey)
|
|
||||||
res shouldBe a[Right[_, _]]
|
|
||||||
}
|
|
||||||
|
|
||||||
"translate exercise-by-key commands with argument with labels" in {
|
|
||||||
val templateId = Identifier(basicTestsPkgId, "BasicTests:WithKey")
|
|
||||||
val command = ExerciseByKeyCommand(
|
|
||||||
templateId,
|
|
||||||
ValueRecord(None, ImmArray((None, ValueParty(alice)), (None, ValueInt64(42)))),
|
|
||||||
"SumToK",
|
|
||||||
ValueRecord(None, ImmArray((Some[Name]("n"), ValueInt64(5)))),
|
|
||||||
)
|
|
||||||
|
|
||||||
val res = preprocessor
|
|
||||||
.preprocessCommands(ImmArray(command))
|
|
||||||
.consume(lookupContract, lookupPackage, lookupKey)
|
|
||||||
res shouldBe a[Right[_, _]]
|
|
||||||
}
|
|
||||||
|
|
||||||
"translate exercise-by-key commands with argument without labels" in {
|
|
||||||
val templateId = Identifier(basicTestsPkgId, "BasicTests:WithKey")
|
|
||||||
val command = ExerciseByKeyCommand(
|
|
||||||
templateId,
|
|
||||||
ValueRecord(None, ImmArray((None, ValueParty(alice)), (None, ValueInt64(42)))),
|
|
||||||
"SumToK",
|
|
||||||
ValueRecord(None, ImmArray((None, ValueInt64(5)))),
|
|
||||||
)
|
|
||||||
|
|
||||||
val res = preprocessor
|
|
||||||
.preprocessCommands(ImmArray(command))
|
|
||||||
.consume(lookupContract, lookupPackage, lookupKey)
|
|
||||||
res shouldBe a[Right[_, _]]
|
|
||||||
}
|
|
||||||
|
|
||||||
"not translate exercise-by-key commands with argument with wrong labels" in {
|
|
||||||
val templateId = Identifier(basicTestsPkgId, "BasicTests:WithKey")
|
|
||||||
val command = ExerciseByKeyCommand(
|
|
||||||
templateId,
|
|
||||||
ValueRecord(None, ImmArray((None, ValueParty(alice)), (None, ValueInt64(42)))),
|
|
||||||
"SumToK",
|
|
||||||
ValueRecord(None, ImmArray((Some[Name]("WRONG"), ValueInt64(5)))),
|
|
||||||
)
|
|
||||||
|
|
||||||
val res = preprocessor
|
|
||||||
.preprocessCommands(ImmArray(command))
|
|
||||||
.consume(lookupContract, lookupPackage, lookupKey)
|
|
||||||
inside(res) { case Left(Error.Preprocessing(error)) =>
|
|
||||||
error shouldBe a[Error.Preprocessing.TypeMismatch]
|
|
||||||
error.message should startWith("Missing record field 'n' for record")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
"not translate exercise-by-key commands if the template specifies no key" in {
|
|
||||||
val templateId = Identifier(basicTestsPkgId, "BasicTests:CallablePayout")
|
|
||||||
val command = ExerciseByKeyCommand(
|
|
||||||
templateId,
|
|
||||||
ValueRecord(None, ImmArray((None, ValueParty(alice)), (None, ValueInt64(42)))),
|
|
||||||
"Transfer",
|
|
||||||
ValueRecord(None, ImmArray((None, ValueParty(clara)))),
|
|
||||||
)
|
|
||||||
|
|
||||||
val res = preprocessor
|
|
||||||
.preprocessCommands(ImmArray(command))
|
|
||||||
.consume(lookupContract, lookupPackage, lookupKey)
|
|
||||||
inside(res) {
|
|
||||||
case Left(Error.Preprocessing(Error.Preprocessing.Lookup(language.LookupError(ref, _)))) =>
|
|
||||||
ref shouldBe a[language.Reference.TemplateKey]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
"not translate exercise-by-key commands if the given key does not match the type specified in the template" in {
|
|
||||||
val templateId = Identifier(basicTestsPkgId, "BasicTests:WithKey")
|
|
||||||
val command = ExerciseByKeyCommand(
|
|
||||||
templateId,
|
|
||||||
ValueRecord(None, ImmArray((None, ValueInt64(42)), (None, ValueInt64(42)))),
|
|
||||||
"SumToK",
|
|
||||||
ValueRecord(None, ImmArray((None, ValueInt64(5)))),
|
|
||||||
)
|
|
||||||
|
|
||||||
val res = preprocessor
|
|
||||||
.preprocessCommands(ImmArray(command))
|
|
||||||
.consume(lookupContract, lookupPackage, lookupKey)
|
|
||||||
inside(res) { case Left(Error.Preprocessing(error)) =>
|
|
||||||
error shouldBe a[Error.Preprocessing.TypeMismatch]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
"translate create-and-exercise commands argument including labels" in {
|
|
||||||
val id = Identifier(basicTestsPkgId, "BasicTests:CallablePayout")
|
|
||||||
val command =
|
|
||||||
CreateAndExerciseCommand(
|
|
||||||
id,
|
|
||||||
ValueRecord(
|
|
||||||
Some(Identifier(basicTestsPkgId, "BasicTests:CallablePayout")),
|
|
||||||
ImmArray(
|
|
||||||
(Some[Ref.Name]("giver"), ValueParty(clara)),
|
|
||||||
(Some[Ref.Name]("receiver"), ValueParty(clara)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
"Transfer",
|
|
||||||
ValueRecord(None, ImmArray((Some[Name]("newReceiver"), ValueParty(clara)))),
|
|
||||||
)
|
|
||||||
|
|
||||||
val res = preprocessor
|
|
||||||
.preprocessCommands(ImmArray(command))
|
|
||||||
.consume(lookupContract, lookupPackage, lookupKey)
|
|
||||||
res shouldBe a[Right[_, _]]
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
"translate create-and-exercise commands argument without labels" in {
|
|
||||||
val id = Identifier(basicTestsPkgId, "BasicTests:CallablePayout")
|
|
||||||
val command =
|
|
||||||
CreateAndExerciseCommand(
|
|
||||||
id,
|
|
||||||
ValueRecord(
|
|
||||||
Some(Identifier(basicTestsPkgId, "BasicTests:CallablePayout")),
|
|
||||||
ImmArray((None, ValueParty(clara)), (None, ValueParty(clara))),
|
|
||||||
),
|
|
||||||
"Transfer",
|
|
||||||
ValueRecord(None, ImmArray((None, ValueParty(clara)))),
|
|
||||||
)
|
|
||||||
|
|
||||||
val res = preprocessor
|
|
||||||
.preprocessCommands(ImmArray(command))
|
|
||||||
.consume(lookupContract, lookupPackage, lookupKey)
|
|
||||||
res shouldBe a[Right[_, _]]
|
|
||||||
}
|
|
||||||
|
|
||||||
"not translate create-and-exercise commands argument wrong label in create arguments" in {
|
|
||||||
val id = Identifier(basicTestsPkgId, "BasicTests:CallablePayout")
|
|
||||||
val command =
|
|
||||||
CreateAndExerciseCommand(
|
|
||||||
id,
|
|
||||||
ValueRecord(
|
|
||||||
Some(Identifier(basicTestsPkgId, "BasicTests:CallablePayout")),
|
|
||||||
ImmArray(
|
|
||||||
(None, ValueParty(clara)),
|
|
||||||
(Some[Ref.Name]("this_is_not_the_one"), ValueParty(clara)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
"Transfer",
|
|
||||||
ValueRecord(None, ImmArray((None, ValueParty(clara)))),
|
|
||||||
)
|
|
||||||
|
|
||||||
val res = preprocessor
|
|
||||||
.preprocessCommands(ImmArray(command))
|
|
||||||
.consume(lookupContract, lookupPackage, lookupKey)
|
|
||||||
inside(res) { case Left(Error.Preprocessing(error)) =>
|
|
||||||
error shouldBe a[Error.Preprocessing.TypeMismatch]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
"not translate create-and-exercise commands argument wrong label in choice arguments" in {
|
|
||||||
val id = Identifier(basicTestsPkgId, "BasicTests:CallablePayout")
|
|
||||||
val command =
|
|
||||||
CreateAndExerciseCommand(
|
|
||||||
id,
|
|
||||||
ValueRecord(
|
|
||||||
Some(Identifier(basicTestsPkgId, "BasicTests:CallablePayout")),
|
|
||||||
ImmArray((None, ValueParty(clara)), (None, ValueParty(clara))),
|
|
||||||
),
|
|
||||||
"Transfer",
|
|
||||||
ValueRecord(None, ImmArray((Some[Name]("this_is_not_the_one"), ValueParty(clara)))),
|
|
||||||
)
|
|
||||||
|
|
||||||
val res = preprocessor
|
|
||||||
.preprocessCommands(ImmArray(command))
|
|
||||||
.consume(lookupContract, lookupPackage, lookupKey)
|
|
||||||
inside(res) { case Left(Error.Preprocessing(error)) =>
|
|
||||||
error shouldBe a[Error.Preprocessing.TypeMismatch]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
"translate Optional values" in {
|
|
||||||
val (optionalPkgId, _, allOptionalPackages) =
|
|
||||||
loadPackage("daml-lf/tests/Optional.dar")
|
|
||||||
|
|
||||||
val translator =
|
|
||||||
new preprocessing.Preprocessor(
|
|
||||||
ConcurrentCompiledPackages(suffixLenientEngine.config.getCompilerConfig)
|
|
||||||
)
|
|
||||||
|
|
||||||
val id = Identifier(optionalPkgId, "Optional:Rec")
|
|
||||||
val someValue =
|
|
||||||
ValueRecord(
|
|
||||||
Some(id),
|
|
||||||
ImmArray(Some[Name]("recField") -> ValueOptional(Some(ValueText("foo")))),
|
|
||||||
)
|
|
||||||
val noneValue =
|
|
||||||
ValueRecord(Some(id), ImmArray(Some[Name]("recField") -> ValueOptional(None)))
|
|
||||||
val typ = TTyConApp(id, ImmArray.Empty)
|
|
||||||
|
|
||||||
translator
|
|
||||||
.translateValue(typ, someValue)
|
|
||||||
.consume(lookupContract, allOptionalPackages.get, lookupKey) shouldEqual
|
|
||||||
Right(SRecord(id, ImmArray("recField"), ArrayList(SOptional(Some(SText("foo"))))))
|
|
||||||
|
|
||||||
translator
|
|
||||||
.translateValue(typ, noneValue)
|
|
||||||
.consume(lookupContract, allOptionalPackages.get, lookupKey) shouldEqual
|
|
||||||
Right(SRecord(id, ImmArray("recField"), ArrayList(SOptional(None))))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
"returns correct error when resuming" in {
|
"returns correct error when resuming" in {
|
||||||
val translator =
|
val translator =
|
||||||
new preprocessing.Preprocessor(
|
new preprocessing.Preprocessor(
|
||||||
|
@ -11,39 +11,47 @@ import com.daml.lf.language.Util._
|
|||||||
import com.daml.lf.speedy.SValue._
|
import com.daml.lf.speedy.SValue._
|
||||||
import com.daml.lf.value.Value
|
import com.daml.lf.value.Value
|
||||||
import com.daml.lf.value.Value._
|
import com.daml.lf.value.Value._
|
||||||
|
import org.scalatest.Inside
|
||||||
import org.scalatest.matchers.should.Matchers
|
import org.scalatest.matchers.should.Matchers
|
||||||
import org.scalatest.prop.TableDrivenPropertyChecks
|
import org.scalatest.prop.TableDrivenPropertyChecks
|
||||||
import org.scalatest.wordspec.AnyWordSpec
|
import org.scalatest.wordspec.AnyWordSpec
|
||||||
|
|
||||||
import scala.util.{Failure, Success, Try}
|
import scala.util.{Failure, Success, Try}
|
||||||
|
|
||||||
class ValueTranslatorSpec extends AnyWordSpec with Matchers with TableDrivenPropertyChecks {
|
class ValueTranslatorSpec
|
||||||
|
extends AnyWordSpec
|
||||||
|
with Inside
|
||||||
|
with Matchers
|
||||||
|
with TableDrivenPropertyChecks {
|
||||||
|
|
||||||
import Preprocessor.ArrayList
|
import Preprocessor.ArrayList
|
||||||
import com.daml.lf.testing.parser.Implicits._
|
import com.daml.lf.testing.parser.Implicits._
|
||||||
import com.daml.lf.transaction.test.TransactionBuilder.Implicits.{defaultPackageId => _, _}
|
import com.daml.lf.transaction.test.TransactionBuilder.Implicits.{defaultPackageId => _, _}
|
||||||
private implicit val defaultPackageId = defaultParserParameters.defaultPackageId
|
private[this] implicit val defaultPackageId: Ref.PackageId =
|
||||||
|
defaultParserParameters.defaultPackageId
|
||||||
|
|
||||||
val aCid =
|
private[this] val aCid =
|
||||||
ContractId.V1.assertBuild(
|
ContractId.V1.assertBuild(
|
||||||
crypto.Hash.hashPrivateKey("a Contract ID"),
|
crypto.Hash.hashPrivateKey("a Contract ID"),
|
||||||
Bytes.assertFromString("00"),
|
Bytes.assertFromString("00"),
|
||||||
)
|
)
|
||||||
|
|
||||||
lazy val pkg =
|
private[this] val pkg =
|
||||||
p"""
|
p"""
|
||||||
module Mod {
|
module Mod {
|
||||||
|
|
||||||
|
record @serializable Tuple (a: *) (b: *) = { x: a, y: b };
|
||||||
record @serializable Record = { field : Int64 };
|
record @serializable Record = { field : Int64 };
|
||||||
variant @serializable Either (a: *) (b: *) = Left : a | Right : b;
|
variant @serializable Either (a: *) (b: *) = Left : a | Right : b;
|
||||||
enum Enum = value1 | value2;
|
enum Color = red | green | blue;
|
||||||
|
|
||||||
record Tricky (b: * -> *) = { x : b Unit };
|
record Tricky (b: * -> *) = { x : b Unit };
|
||||||
|
|
||||||
record MyCons = { head : Int64, tail: Mod:MyList };
|
record MyCons = { head : Int64, tail: Mod:MyList };
|
||||||
variant MyList = MyNil : Unit | MyCons: Mod:MyCons ;
|
variant MyList = MyNil : Unit | MyCons: Mod:MyCons ;
|
||||||
|
|
||||||
record @serializable RecordRef = { owner: Party, cid: (ContractId Mod:Record) };
|
record @serializable Template = { field : Int64 };
|
||||||
|
record @serializable TemplateRef = { owner: Party, cid: (ContractId Mod:Template) };
|
||||||
|
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -85,7 +93,7 @@ class ValueTranslatorSpec extends AnyWordSpec with Matchers with TableDrivenProp
|
|||||||
// ValueNumeric(Numeric.assertFromString("9.000000000")),
|
// ValueNumeric(Numeric.assertFromString("9.000000000")),
|
||||||
(TParty, ValueParty("Alice"), SParty("Alice")),
|
(TParty, ValueParty("Alice"), SParty("Alice")),
|
||||||
(
|
(
|
||||||
TContractId(t"Mod:Record"),
|
TContractId(t"Mod:Template"),
|
||||||
ValueContractId(aCid),
|
ValueContractId(aCid),
|
||||||
SContractId(aCid),
|
SContractId(aCid),
|
||||||
),
|
),
|
||||||
@ -106,16 +114,16 @@ class ValueTranslatorSpec extends AnyWordSpec with Matchers with TableDrivenProp
|
|||||||
),
|
),
|
||||||
(TOptional(TText), ValueOptional(Some(ValueText("text"))), SOptional(Some(SText("text")))),
|
(TOptional(TText), ValueOptional(Some(ValueText("text"))), SOptional(Some(SText("text")))),
|
||||||
(
|
(
|
||||||
t"Mod:Record",
|
t"Mod:Tuple Int64 Text",
|
||||||
ValueRecord("", ImmArray("field" -> ValueInt64(33))),
|
ValueRecord("", ImmArray("x" -> ValueInt64(33), "y" -> ValueText("a"))),
|
||||||
SRecord("Mod:Record", ImmArray("field"), ArrayList(SInt64(33))),
|
SRecord("Mod:Tuple", ImmArray("x", "y"), ArrayList(SInt64(33), SText("a"))),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
t"Mod:Either Text Int64",
|
t"Mod:Either Int64 Text",
|
||||||
ValueVariant("", "Left", ValueText("some test")),
|
ValueVariant("", "Right", ValueText("some test")),
|
||||||
SVariant("Mod:Either", "Left", 0, SText("some test")),
|
SVariant("Mod:Either", "Right", 1, SText("some test")),
|
||||||
),
|
),
|
||||||
(Ast.TTyCon("Mod:Enum"), ValueEnum("", "value1"), SEnum("Mod:Enum", "value1", 0)),
|
(Ast.TTyCon("Mod:Color"), ValueEnum("", "blue"), SEnum("Mod:Color", "blue", 2)),
|
||||||
(
|
(
|
||||||
Ast.TApp(Ast.TTyCon("Mod:Tricky"), Ast.TBuiltin(Ast.BTList)),
|
Ast.TApp(Ast.TTyCon("Mod:Tricky"), Ast.TBuiltin(Ast.BTList)),
|
||||||
ValueRecord("", ImmArray("" -> ValueNil)),
|
ValueRecord("", ImmArray("" -> ValueNil)),
|
||||||
@ -125,7 +133,61 @@ class ValueTranslatorSpec extends AnyWordSpec with Matchers with TableDrivenProp
|
|||||||
|
|
||||||
"succeeds on well type values" in {
|
"succeeds on well type values" in {
|
||||||
forAll(testCases) { (typ, value, svalue) =>
|
forAll(testCases) { (typ, value, svalue) =>
|
||||||
unsafeTranslateValue(typ, value) shouldBe svalue
|
Try(unsafeTranslateValue(typ, value)) shouldBe Success(svalue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"handle different representation of the same record" in {
|
||||||
|
val typ = t"Mod:Tuple Int64 Text"
|
||||||
|
val testCases = Table(
|
||||||
|
"record",
|
||||||
|
ValueRecord("Mod:Tuple", ImmArray("x" -> ValueInt64(33), "y" -> ValueText("a"))),
|
||||||
|
ValueRecord("Mod:Tuple", ImmArray("y" -> ValueText("a"), "x" -> ValueInt64(33))),
|
||||||
|
ValueRecord("", ImmArray("x" -> ValueInt64(33), "y" -> ValueText("a"))),
|
||||||
|
ValueRecord("", ImmArray("" -> ValueInt64(33), "" -> ValueText("a"))),
|
||||||
|
)
|
||||||
|
val svalue = SRecord("Mod:Tuple", ImmArray("x", "y"), ArrayList(SInt64(33), SText("a")))
|
||||||
|
|
||||||
|
forEvery(testCases)(testCase =>
|
||||||
|
Try(unsafeTranslateValue(typ, testCase)) shouldBe Success(svalue)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
"handle different representation of the same variant" in {
|
||||||
|
val typ = t"Mod:Either Text Int64"
|
||||||
|
val testCases = Table(
|
||||||
|
"variant",
|
||||||
|
ValueVariant("Mod:Either", "Left", ValueText("some test")),
|
||||||
|
ValueVariant("", "Left", ValueText("some test")),
|
||||||
|
)
|
||||||
|
val svalue = SVariant("Mod:Either", "Left", 0, SText("some test"))
|
||||||
|
|
||||||
|
forEvery(testCases)(value => Try(unsafeTranslateValue(typ, value)) shouldBe Success(svalue))
|
||||||
|
}
|
||||||
|
|
||||||
|
"handle different representation of the same enum" in {
|
||||||
|
val typ = t"Mod:Color"
|
||||||
|
val testCases = Table("enum", ValueEnum("Mod:Color", "green"), ValueEnum("", "green"))
|
||||||
|
val svalue = SEnum("Mod:Color", "green", 1)
|
||||||
|
forEvery(testCases)(value => Try(unsafeTranslateValue(typ, value)) shouldBe Success(svalue))
|
||||||
|
}
|
||||||
|
|
||||||
|
"return proper mismatch error" in {
|
||||||
|
val res = Try(
|
||||||
|
unsafeTranslateValue(
|
||||||
|
t"Mod:Tuple Int64 Text",
|
||||||
|
ValueRecord(
|
||||||
|
"",
|
||||||
|
ImmArray(
|
||||||
|
"x" -> ValueInt64(33),
|
||||||
|
"y" -> ValueParty("Alice"), // Here the field has type Party instead of Text
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
inside(res) { case Failure(Error.Preprocessing.TypeMismatch(typ, value, _)) =>
|
||||||
|
typ shouldBe t"Text"
|
||||||
|
value shouldBe ValueParty("Alice")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,17 +223,17 @@ class ValueTranslatorSpec extends AnyWordSpec with Matchers with TableDrivenProp
|
|||||||
val cid = ValueContractId(culprit)
|
val cid = ValueContractId(culprit)
|
||||||
Table[Ast.Type, Value](
|
Table[Ast.Type, Value](
|
||||||
("type" -> "value"),
|
("type" -> "value"),
|
||||||
t"ContractId Mod:Record" -> cid,
|
t"ContractId Mod:Template" -> cid,
|
||||||
TList(t"ContractId Mod:Record") -> ValueList(FrontStack(cid)),
|
TList(t"ContractId Mod:Template") -> ValueList(FrontStack(cid)),
|
||||||
TTextMap(t"ContractId Mod:Record") -> ValueTextMap(SortedLookupList(Map("0" -> cid))),
|
TTextMap(t"ContractId Mod:Template") -> ValueTextMap(SortedLookupList(Map("0" -> cid))),
|
||||||
TGenMap(TInt64, t"ContractId Mod:Record") -> ValueGenMap(ImmArray(ValueInt64(1) -> cid)),
|
TGenMap(TInt64, t"ContractId Mod:Template") -> ValueGenMap(ImmArray(ValueInt64(1) -> cid)),
|
||||||
TGenMap(t"ContractId Mod:Record", TInt64) -> ValueGenMap(ImmArray(cid -> ValueInt64(0))),
|
TGenMap(t"ContractId Mod:Template", TInt64) -> ValueGenMap(ImmArray(cid -> ValueInt64(0))),
|
||||||
TOptional(t"ContractId Mod:Record") -> ValueOptional(Some(cid)),
|
TOptional(t"ContractId Mod:Template") -> ValueOptional(Some(cid)),
|
||||||
Ast.TTyCon("Mod:RecordRef") -> ValueRecord(
|
t"Mod:TemplateRef" -> ValueRecord(
|
||||||
"",
|
"",
|
||||||
ImmArray("" -> ValueParty("Alice"), "" -> cid),
|
ImmArray("" -> ValueParty("Alice"), "" -> cid),
|
||||||
),
|
),
|
||||||
TTyConApp("Mod:Either", ImmArray(t"ContractId Mod:Record", TInt64)) -> ValueVariant(
|
TTyConApp("Mod:Either", ImmArray(t"ContractId Mod:Template", TInt64)) -> ValueVariant(
|
||||||
"",
|
"",
|
||||||
"Left",
|
"Left",
|
||||||
cid,
|
cid,
|
||||||
|
Loading…
Reference in New Issue
Block a user