don't overwrite interface properties with template properties (#13720)

* test for all varieties of mistaken interface assignment
* fresh object for templates, do not mutate interfaces

CHANGELOG_BEGIN
- [daml codegen js] Some interface IDs were overwritten with template
  IDs, making exercise by interface ID impossible in those cases; this
  has been fixed.  Prior codegen output is invalid; codegen must be
  re-run to get the fix.
  See `issue #13720 <https://github.com/digital-asset/daml/pull/13720>`__.
CHANGELOG_END
This commit is contained in:
Stephen Compall 2022-04-27 11:43:06 -04:00 committed by GitHub
parent 04f991a340
commit 782f90a77d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 1 deletions

View File

@ -391,8 +391,11 @@ renderTemplateDef TemplateDef {..} =
T.unlines $ T.unlines $
concat concat
[ ["exports." <> tplName <> " = Object.assign("] [ ["exports." <> tplName <> " = Object.assign("]
-- defining the template directly here would overwrite the template ID
-- with an interface ID
, ["{},"]
, [impl <> "," | (_, JsSerializerConRef impl) <- tplImplements'] , [impl <> "," | (_, JsSerializerConRef impl) <- tplImplements']
-- we spread in the interface choices, the templateId field of the interface will be overwritten by the template object. -- template ID and directly-defined choices are always top-priority
, [ T.unlines $ , [ T.unlines $
concat concat
[ ["{"] [ ["{"]

View File

@ -547,6 +547,28 @@ test("create + fetch & exercise", async () => {
expect(nonTopLevelContracts).toEqual([nonTopLevelContract]); expect(nonTopLevelContracts).toEqual([nonTopLevelContract]);
}); });
describe("interface definition", () => {
const tpl = buildAndLint.Main.Asset;
const if1 = buildAndLint.Main.Token;
const if2 = buildAndLint.Lib.Mod.Other;
test("separate object from template", () => {
expect(if1).not.toBe(tpl);
expect(if2).not.toBe(tpl);
});
test("template IDs not overwritten", () => {
expect(if1.templateId).not.toEqual(tpl.templateId);
expect(if2.templateId).not.toEqual(tpl.templateId);
});
test("choices not copied to interfaces", () => {
const key1 = "Transfer";
const key2 = "Something";
expect(if1).toHaveProperty(key1);
expect(if2).toHaveProperty(key2);
expect(if1).not.toHaveProperty(key2);
expect(if2).not.toHaveProperty(key1);
});
});
test("interfaces", async () => { test("interfaces", async () => {
const aliceLedger = new Ledger({ const aliceLedger = new Ledger({
token: ALICE_TOKEN, token: ALICE_TOKEN,