Skip to content

Commit

Permalink
fix(pactjs-generator): use parent module namespace if the module doen…
Browse files Browse the repository at this point in the history
… not have a namespace
  • Loading branch information
javadkh2 committed Oct 4, 2023
1 parent 8f22363 commit 3873e73
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/brave-beers-repeat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@kadena/pactjs-generator': patch
---

Fix no namesapce issue for used modules
29 changes: 26 additions & 3 deletions packages/libs/pactjs-generator/src/contract/parsing/pactParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,33 @@ async function loadModuleDependencies(
...(module.usedInterface || []),
];

const parentNamespace = module.namespace;

const mods = await Promise.all(
interfaceOrModule.map(async (usedModule) =>
loadModuleDependencies(getModuleFullName(usedModule), getModule),
),
interfaceOrModule.map(async (usedModule) => {
if (typeof usedModule.namespace === 'string') {
return loadModuleDependencies(getModuleFullName(usedModule), getModule);
}
let moduleName: string;
try {
// if the namespace is not defined, try to load the module with the parent namespace
const withParentNamespace = getModuleFullName({
name: usedModule.name,
namespace: parentNamespace,
});
// this will store the module in the storage so we can use it later
await getModule(withParentNamespace);
moduleName = withParentNamespace;
} catch {
// if the module is not found, continue with without a namespace
moduleName = usedModule.name;
console.log(
`Module ${moduleName} not found. trying to load ${usedModule.name}`,
);
}

return loadModuleDependencies(moduleName, getModule);
}),
);
const dependencies = mods.flat();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,95 @@ describe('pactParser', () => {
expect(getContract.mock.calls[0][0]).toBe('coin');
});

it('should use the parent contract namespace for used contracts if they dont have a namespace', async () => {
const getContract = jest.fn((name: string) => {
switch (name) {
case 'custom-namespace.test':
return Promise.resolve(`
(module test GOVERNANCE
(use l2)
(defun transfer:string (sender:string receiver:string amount:number))
)`);

case 'custom-namespace.l2':
return Promise.resolve(`
(module l2 GOVERNANCE
(defun func:string (sender:string receiver:string amount:number))
)`);
case 'l2':
return Promise.reject('This should not be called');
default:
return Promise.reject(`invalid contract name - ${name}`);
}
});

const modules = await pactParser({
contractNames: ['custom-namespace.test'],
getContract,
});
expect(Object.keys(modules)).toHaveLength(2);
const mod = modules['custom-namespace.test'];
expect(mod).toBeDefined();
expect(mod.name).toBe('test');
expect(mod.namespace).toBe('custom-namespace');
expect(mod.kind).toBe('module');

const l2 = modules['custom-namespace.l2'];
expect(l2).toBeDefined();
expect(l2.name).toBe('l2');
expect(l2.namespace).toBe('custom-namespace');
expect(l2.kind).toBe('module');

expect(getContract.mock.calls).toHaveLength(2);
expect(getContract.mock.calls[0][0]).toBe('custom-namespace.test');
expect(getContract.mock.calls[1][0]).toBe('custom-namespace.l2');
});

it('should try both with and without parent namespace if module does not have namespace', async () => {
const getContract = jest.fn((name: string) => {
switch (name) {
case 'custom-namespace.test':
return Promise.resolve(`
(module test GOVERNANCE
(use l2)
(defun transfer:string (sender:string receiver:string amount:number))
)`);

case 'custom-namespace.l2':
return Promise.reject("This module doesn't exist");
case 'l2':
return Promise.resolve(`
(module l2 GOVERNANCE
(defun func:string (sender:string receiver:string amount:number))
)`);
default:
return Promise.reject(`invalid contract name - ${name}`);
}
});

const modules = await pactParser({
contractNames: ['custom-namespace.test'],
getContract,
});
expect(Object.keys(modules)).toHaveLength(2);
const mod = modules['custom-namespace.test'];
expect(mod).toBeDefined();
expect(mod.name).toBe('test');
expect(mod.namespace).toBe('custom-namespace');
expect(mod.kind).toBe('module');

const l2 = modules['l2'];
expect(l2).toBeDefined();
expect(l2.name).toBe('l2');
expect(l2.namespace).toBe('');
expect(l2.kind).toBe('module');

expect(getContract.mock.calls).toHaveLength(3);
expect(getContract.mock.calls[0][0]).toBe('custom-namespace.test');
expect(getContract.mock.calls[1][0]).toBe('custom-namespace.l2');
expect(getContract.mock.calls[2][0]).toBe('l2');
});

it('should add the relevant namespace to the module', async () => {
const contract = `
(namespace "test_namespace_1")
Expand Down

0 comments on commit 3873e73

Please sign in to comment.