From 089ba538e5f546f2e3f7e14e57467aa4e7fc0eb1 Mon Sep 17 00:00:00 2001 From: Jaco Date: Thu, 31 Mar 2022 11:56:47 +0300 Subject: [PATCH] Tests & cleanups --- packages/api-contract/src/base/types.ts | 2 +- packages/api-contract/src/base/util.spec.ts | 40 +++++++++++++++++++++ packages/api-contract/src/base/util.ts | 16 ++++++--- 3 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 packages/api-contract/src/base/util.spec.ts diff --git a/packages/api-contract/src/base/types.ts b/packages/api-contract/src/base/types.ts index db0d3705f477..07324d9ee206 100644 --- a/packages/api-contract/src/base/types.ts +++ b/packages/api-contract/src/base/types.ts @@ -57,5 +57,5 @@ export interface MapMessageQuery { } export interface Namespaced { - [path: string]: T | Namespaced; + [path: string]: (T & Namespaced) | Namespaced; } diff --git a/packages/api-contract/src/base/util.spec.ts b/packages/api-contract/src/base/util.spec.ts new file mode 100644 index 000000000000..3e2f735ca726 --- /dev/null +++ b/packages/api-contract/src/base/util.spec.ts @@ -0,0 +1,40 @@ +// Copyright 2017-2022 @polkadot/api-contract authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { Namespaced } from './types'; + +import { expandNs } from './util'; + +type TestNS = Namespaced; + +describe('expandNs', (): void => { + it('expands into single-namespaced and normal location', (): void => { + const testNs: TestNS = {}; + const test: Record = {}; + + test.a = expandNs(testNs, { path: ['ns_a'] }, 'a'); + + expect(test.a).toEqual('a'); + expect(testNs.ns_a).toEqual('a'); + }); + + it('expands into multi-namespaced and normal location', (): void => { + const testNs: TestNS = {}; + + expect(expandNs(testNs, { path: ['A', 'B', 'a'] }, 'a')).toEqual('a'); + + expect(testNs.A.B.a).toEqual('a'); + }); + + it('it expands multiples', (): void => { + const testNs: TestNS = {}; + + expect(expandNs(testNs, { path: ['A', 'B', 'a'] }, 'a')).toEqual('a'); + expect(expandNs(testNs, { path: ['A', 'B', 'b'] }, 'b')).toEqual('b'); + expect(expandNs(testNs, { path: ['A', 'C', 'c'] }, 'c')).toEqual('c'); + + expect(testNs.A.B.a).toEqual('a'); + expect(testNs.A.B.b).toEqual('b'); + expect(testNs.A.C.c).toEqual('c'); + }); +}); diff --git a/packages/api-contract/src/base/util.ts b/packages/api-contract/src/base/util.ts index 37a63c74818f..d26bab19d56a 100644 --- a/packages/api-contract/src/base/util.ts +++ b/packages/api-contract/src/base/util.ts @@ -16,6 +16,10 @@ import { extractOptions, isOptions } from '../util'; export const EMPTY_SALT = new Uint8Array(); +interface WithPath { + path: string[]; +} + type ConstructorTx = (constructorOrId: AbiConstructor | string | number, options: BlueprintOptions, params: unknown[]) => SubmittableExtrinsic; export function withMeta (meta: AbiMessage, creator: Omit): T { @@ -47,14 +51,18 @@ export function encodeSalt (salt: Uint8Array | string | null = randomAsU8a()): U : EMPTY_SALT; } -export function expandNs (ns: Namespaced, { path }: AbiMessage, call: T): T { +export function expandNs (ns: Namespaced, { path }: WithPath, call: T): T { if (path.length > 1) { - for (let i = 0; i < path.length - 2; i++) { - ns = ns[path[i]] = {} as Namespaced; + for (let i = 0; i < path.length - 1; i++) { + if (!ns[path[i]]) { + ns[path[i]] = {}; + } + + ns = ns[path[i]]; } } - ns[path[path.length - 1]] = call; + ns[path[path.length - 1]] = call as unknown as Namespaced; return call; }