From a725921aa116a55ee68cc16bebc9756f78960465 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Fri, 30 Sep 2022 21:28:50 +0800 Subject: [PATCH] Add nested and nested nested collection example --- .../__tests__/test-nested-collections.ava.js | 122 ++++++++++++++++++ examples/package.json | 6 +- examples/src/nested-collections.ts | 66 ++++++++++ 3 files changed, 192 insertions(+), 2 deletions(-) create mode 100644 examples/__tests__/test-nested-collections.ava.js create mode 100644 examples/src/nested-collections.ts diff --git a/examples/__tests__/test-nested-collections.ava.js b/examples/__tests__/test-nested-collections.ava.js new file mode 100644 index 000000000..62ed835c9 --- /dev/null +++ b/examples/__tests__/test-nested-collections.ava.js @@ -0,0 +1,122 @@ +import { Worker } from "near-workspaces"; +import test from "ava"; + +test.before(async (t) => { + // Init the worker and start a Sandbox server + const worker = await Worker.init(); + + // Prepare sandbox for tests, create accounts, deploy contracts, etx. + const root = worker.rootAccount; + + // Deploy the contract. + const nestedCollections = await root.devDeploy( + "./build/nested-collections.wasm" + ); + + // Create test users + const ali = await root.createSubAccount("ali"); + const bob = await root.createSubAccount("bob"); + const carl = await root.createSubAccount("carl"); + + // Save state for test runs + t.context.worker = worker; + t.context.accounts = { root, nestedCollections, ali, bob, carl }; +}); + +test.after.always(async (t) => { + await t.context.worker.tearDown().catch((error) => { + console.log("Failed to tear down the worker:", error); + }); +}); + +test("Ali sets then gets text", async (t) => { + const { ali, nestedCollections } = t.context.accounts; + await ali.call(nestedCollections, "add", { id: "1", text: "hello" }); + await ali.call(nestedCollections, "add", { id: "2", text: "world" }); + + t.is( + await nestedCollections.view("get", { id: "1", accountId: ali.accountId }), + "hello" + ); + + t.is( + await nestedCollections.view("get", { id: "2", accountId: ali.accountId }), + "world" + ); +}); + +test("Bob and Carl have different statuses", async (t) => { + const { nestedCollections, bob, carl } = t.context.accounts; + await bob.call(nestedCollections, "add", { id: "1", text: "hello" }); + await carl.call(nestedCollections, "add", { id: "1", text: "world" }); + + t.is( + await nestedCollections.view("get", { id: "1", accountId: bob.accountId }), + "hello" + ); + + t.is( + await nestedCollections.view("get", { id: "1", accountId: carl.accountId }), + "world" + ); +}); + +test("sets then gets nested nested collection", async (t) => { + const { ali, bob, nestedCollections } = t.context.accounts; + await ali.call(nestedCollections, "add_to_group", { + group: "x", + id: "1", + text: "hello", + }); + await ali.call(nestedCollections, "add_to_group", { + group: "x", + id: "2", + text: "world", + }); + await ali.call(nestedCollections, "add_to_group", { + group: "y", + id: "2", + text: "cat", + }); + await bob.call(nestedCollections, "add_to_group", { + group: "y", + id: "2", + text: "dog", + }); + + t.is( + await nestedCollections.view("get_from_group", { + group: "x", + id: "1", + accountId: ali.accountId, + }), + "hello" + ); + + t.is( + await nestedCollections.view("get_from_group", { + group: "x", + id: "2", + accountId: ali.accountId, + }), + "world" + ); + + t.is( + await nestedCollections.view("get_from_group", { + group: "y", + id: "2", + accountId: ali.accountId, + }), + "cat" + ); + + t.is( + await nestedCollections.view("get_from_group", { + group: "y", + id: "2", + accountId: bob.accountId, + }), + "dog" + ); +}); diff --git a/examples/package.json b/examples/package.json index 071970010..d582ea64f 100644 --- a/examples/package.json +++ b/examples/package.json @@ -6,7 +6,7 @@ "type": "module", "scripts": { "postinstall": "cd .. && yarn link && cd examples && yarn link near-sdk-js", - "build": "yarn build:clean-state && yarn build:counter && yarn build:counter-lowlevel && yarn build:counter-ts && yarn build:cross-contract-call && yarn build:fungible-token-lockable && yarn build:fungible-token && yarn build:non-fungible-token && yarn build:status-message-collections && yarn build:status-message && yarn build:parking-lot", + "build": "yarn build:clean-state && yarn build:counter && yarn build:counter-lowlevel && yarn build:counter-ts && yarn build:cross-contract-call && yarn build:fungible-token-lockable && yarn build:fungible-token && yarn build:non-fungible-token && yarn build:status-message-collections && yarn build:status-message && yarn build:parking-lot && yarn build:nested-collections", "build:status-message": "near-sdk-js build src/status-message.js build/status-message.wasm", "build:clean-state": "near-sdk-js build src/clean-state.js build/clean-state.wasm", "build:counter": "near-sdk-js build src/counter.js build/counter.wasm", @@ -18,6 +18,7 @@ "build:non-fungible-token": "near-sdk-js build src/non-fungible-token-receiver.js build/non-fungible-token-receiver.wasm && near-sdk-js build src/non-fungible-token.js build/non-fungible-token.wasm", "build:status-message-collections": "near-sdk-js build src/status-message-collections.js build/status-message-collections.wasm", "build:parking-lot": "near-sdk-js build src/parking-lot.ts build/parking-lot.wasm", + "build:nested-collections": "near-sdk-js build src/nested-collections.ts build/nested-collections.wasm", "test": "ava && yarn test:counter-lowlevel && yarn test:counter-ts", "test:status-message": "ava __tests__/test-status-message.ava.js", "test:clean-state": "ava __tests__/test-clean-state.ava.js", @@ -29,7 +30,8 @@ "test:fungible-token": "ava __tests__/test-fungible-token.ava.js", "test:non-fungible-token": "ava __tests__/test-non-fungible-token.ava.js", "test:status-message-collections": "ava __tests__/test-status-message-collections.ava.js", - "test:parking-lot": "ava __tests__/test-parking-lot.ava.js" + "test:parking-lot": "ava __tests__/test-parking-lot.ava.js", + "test:nested-collections": "ava __tests__/test-nested-collections.ava.js" }, "author": "Near Inc ", "license": "Apache-2.0", diff --git a/examples/src/nested-collections.ts b/examples/src/nested-collections.ts new file mode 100644 index 000000000..03e0b2a6f --- /dev/null +++ b/examples/src/nested-collections.ts @@ -0,0 +1,66 @@ +import { NearBindgen, near, call, view, UnorderedMap } from "near-sdk-js"; +import { log } from "./log"; + +@NearBindgen({}) +class Contract { + outerMap: UnorderedMap>; + groups: UnorderedMap>>; + + constructor() { + this.outerMap = new UnorderedMap("o"); + this.groups = new UnorderedMap("gs"); + } + + @call({}) + add({ id, text }) { + const innerMap = this.outerMap.get(id, { + reconstructor: UnorderedMap.reconstruct, + defaultValue: new UnorderedMap("i_" + id + "_"), + }); + innerMap.set(near.signerAccountId(), text); + this.outerMap.set(id, innerMap); + } + + @view({}) + get({ id, accountId }) { + const innerMap = this.outerMap.get(id, { + reconstructor: UnorderedMap.reconstruct, + }); + if (innerMap === null) { + return null; + } + return innerMap.get(accountId); + } + + @call({}) + add_to_group({ group, id, text }) { + const groupMap = this.groups.get(group, { + reconstructor: UnorderedMap.reconstruct, + defaultValue: new UnorderedMap>("g_" + group + "_"), + }); + const innerMap = groupMap.get(id, { + reconstructor: UnorderedMap.reconstruct, + defaultValue: new UnorderedMap("gi_" + group + "_" + id + "_"), + }); + innerMap.set(near.signerAccountId(), text); + groupMap.set(id, innerMap); + this.groups.set(group, groupMap); + } + + @view({}) + get_from_group({ group, id, accountId }) { + const groupMap = this.groups.get(group, { + reconstructor: UnorderedMap.reconstruct, + }); + if (groupMap === null) { + return null; + } + const innerMap = groupMap.get(id, { + reconstructor: UnorderedMap.reconstruct, + }); + if (innerMap === null) { + return null; + } + return innerMap.get(accountId); + } +}