diff --git a/compiler/wasm/fixtures/deps/lib-a/Nargo.toml b/compiler/wasm/fixtures/deps/lib-a/Nargo.toml new file mode 100644 index 00000000000..3a02ccc1086 --- /dev/null +++ b/compiler/wasm/fixtures/deps/lib-a/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name="lib_a" +type="lib" +authors = [""] +compiler_version = "0.1" + +[dependencies] +lib_b = { path = "../lib-b" } diff --git a/compiler/wasm/fixtures/deps/lib-a/src/lib.nr b/compiler/wasm/fixtures/deps/lib-a/src/lib.nr new file mode 100644 index 00000000000..abb4302ba38 --- /dev/null +++ b/compiler/wasm/fixtures/deps/lib-a/src/lib.nr @@ -0,0 +1,7 @@ + +use dep::lib_b::assert_non_zero; + +pub fn divide(a: u64, b: u64) -> u64 { + assert_non_zero(b); + a / b +} diff --git a/compiler/wasm/fixtures/deps/lib-b/Nargo.toml b/compiler/wasm/fixtures/deps/lib-b/Nargo.toml new file mode 100644 index 00000000000..99db61e4bfa --- /dev/null +++ b/compiler/wasm/fixtures/deps/lib-b/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name="lib_b" +type="lib" +authors = [""] +compiler_version = "0.1" + +[dependencies] diff --git a/compiler/wasm/fixtures/deps/lib-b/src/lib.nr b/compiler/wasm/fixtures/deps/lib-b/src/lib.nr new file mode 100644 index 00000000000..ad8b26020e3 --- /dev/null +++ b/compiler/wasm/fixtures/deps/lib-b/src/lib.nr @@ -0,0 +1,4 @@ + +pub fn assert_non_zero(x: u64) { + assert(x != 0); +} diff --git a/compiler/wasm/fixtures/deps/noir-script/Nargo.toml b/compiler/wasm/fixtures/deps/noir-script/Nargo.toml new file mode 100644 index 00000000000..0df22c2be7e --- /dev/null +++ b/compiler/wasm/fixtures/deps/noir-script/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name="noir_wasm_testing" +type="bin" +authors = [""] +compiler_version = "0.1" + +[dependencies] +lib_a = { path="../lib-a" } diff --git a/compiler/wasm/fixtures/deps/noir-script/src/main.nr b/compiler/wasm/fixtures/deps/noir-script/src/main.nr new file mode 100644 index 00000000000..d46597fca2e --- /dev/null +++ b/compiler/wasm/fixtures/deps/noir-script/src/main.nr @@ -0,0 +1,4 @@ +use dep::lib_a::divide; +fn main(x : u64, y : pub u64) { + divide(x, y); +} diff --git a/compiler/wasm/noir-script/Nargo.toml b/compiler/wasm/fixtures/simple/noir-script/Nargo.toml similarity index 100% rename from compiler/wasm/noir-script/Nargo.toml rename to compiler/wasm/fixtures/simple/noir-script/Nargo.toml diff --git a/compiler/wasm/noir-script/src/main.nr b/compiler/wasm/fixtures/simple/noir-script/src/main.nr similarity index 100% rename from compiler/wasm/noir-script/src/main.nr rename to compiler/wasm/fixtures/simple/noir-script/src/main.nr diff --git a/compiler/wasm/test/browser/index.test.ts b/compiler/wasm/test/browser/index.test.ts index 02263d9adfb..cad2ada0c61 100644 --- a/compiler/wasm/test/browser/index.test.ts +++ b/compiler/wasm/test/browser/index.test.ts @@ -1,68 +1,98 @@ import { expect } from '@esm-bundle/chai'; import initNoirWasm, { compile } from '@noir-lang/noir_wasm'; import { initializeResolver } from '@noir-lang/source-resolver'; -import { nargoArtifactPath, noirSourcePath } from '../shared'; +import { + depsScriptExpectedArtifact, + depsScriptSourcePath, + libASourcePath, + libBSourcePath, + simpleScriptExpectedArtifact, + simpleScriptSourcePath, +} from '../shared'; beforeEach(async () => { await initNoirWasm(); }); async function getFileContent(path: string): Promise { - const mainnrSourceURL = new URL(path, import.meta.url); - const response = await fetch(mainnrSourceURL); + const url = new URL(path, import.meta.url); + const response = await fetch(url); return await response.text(); } -async function getSource(): Promise { - return getFileContent(noirSourcePath); -} - // eslint-disable-next-line @typescript-eslint/no-explicit-any -async function getPrecompiledSource(): Promise { - const compiledData = await getFileContent(nargoArtifactPath); +async function getPrecompiledSource(path: string): Promise { + const compiledData = await getFileContent(path); return JSON.parse(compiledData); } -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export async function compileNoirSource(noir_source: string): Promise { - console.log('Compiling Noir source...'); +describe('noir wasm', () => { + describe('can compile script without dependencies', () => { + beforeEach(async () => { + const source = await getFileContent(simpleScriptSourcePath); + initializeResolver((id: string) => { + console.log(`Resolving source ${id}`); - initializeResolver((id: string) => { - console.log(`Resolving source ${id}`); + if (typeof source === 'undefined') { + throw Error(`Could not resolve source for '${id}'`); + } else if (id !== '/main.nr') { + throw Error(`Unexpected id: '${id}'`); + } else { + return source; + } + }); + }); - const source = noir_source; + it('matching nargos compilation', async () => { + const wasmCircuit = await compile('/main.nr'); + const cliCircuit = await getPrecompiledSource(simpleScriptExpectedArtifact); - if (typeof source === 'undefined') { - throw Error(`Could not resolve source for '${id}'`); - } else if (id !== '/main.nr') { - throw Error(`Unexpected id: '${id}'`); - } else { - return source; - } + // We don't expect the hashes to match due to how `noir_wasm` handles dependencies + expect(wasmCircuit.bytecode).to.eq(cliCircuit.bytecode); + expect(wasmCircuit.abi).to.deep.eq(cliCircuit.abi); + expect(wasmCircuit.backend).to.eq(cliCircuit.backend); + }).timeout(20e3); // 20 seconds }); - try { - const compiled_noir = compile('main.nr'); + describe('can compile script with dependencies', () => { + beforeEach(async () => { + const [scriptSource, libASource, libBSource] = await Promise.all([ + getFileContent(depsScriptSourcePath), + getFileContent(libASourcePath), + getFileContent(libBSourcePath), + ]); - console.log('Noir source compilation done.'); + initializeResolver((file: string) => { + switch (file) { + case '/script/main.nr': + return scriptSource; - return compiled_noir; - } catch (e) { - console.log('Error while compiling:', e); - } -} + case '/lib_a/lib.nr': + return libASource; + + case '/lib_b/lib.nr': + return libBSource; -describe('noir wasm compilation', () => { - it('matches nargos compilation', async () => { - const source = await getSource(); + default: + return ''; + } + }); + }); - const wasmCircuit = await compileNoirSource(source); + it('matching nargos compilation', async () => { + const wasmCircuit = await compile('/script/main.nr', false, { + root_dependencies: ['lib_a'], + library_dependencies: { + lib_a: ['lib_b'], + }, + }); - const cliCircuit = await getPrecompiledSource(); + const cliCircuit = await getPrecompiledSource(depsScriptExpectedArtifact); - // We don't expect the hashes to match due to how `noir_wasm` handles dependencies - expect(wasmCircuit.bytecode).to.eq(cliCircuit.bytecode); - expect(wasmCircuit.abi).to.deep.eq(cliCircuit.abi); - expect(wasmCircuit.backend).to.eq(cliCircuit.backend); - }).timeout(20e3); // 20 seconds + // We don't expect the hashes to match due to how `noir_wasm` handles dependencies + expect(wasmCircuit.bytecode).to.eq(cliCircuit.bytecode); + expect(wasmCircuit.abi).to.deep.eq(cliCircuit.abi); + expect(wasmCircuit.backend).to.eq(cliCircuit.backend); + }).timeout(20e3); // 20 seconds + }); }); diff --git a/compiler/wasm/test/node/index.test.ts b/compiler/wasm/test/node/index.test.ts index 4ec6d83c3c3..a491ea4e55b 100644 --- a/compiler/wasm/test/node/index.test.ts +++ b/compiler/wasm/test/node/index.test.ts @@ -1,26 +1,72 @@ import { expect } from 'chai'; -import { nargoArtifactPath, noirSourcePath } from '../shared'; +import { + depsScriptSourcePath, + depsScriptExpectedArtifact, + libASourcePath, + libBSourcePath, + simpleScriptSourcePath, + simpleScriptExpectedArtifact, +} from '../shared'; import { readFileSync } from 'node:fs'; -import { join } from 'node:path'; +import { join, resolve } from 'node:path'; import { compile } from '@noir-lang/noir_wasm'; +import { initializeResolver } from '@noir-lang/source-resolver'; -const absoluteNoirSourcePath = join(__dirname, noirSourcePath); -const absoluteNargoArtifactPath = join(__dirname, nargoArtifactPath); +// const absoluteNoirSourcePath = ; +// const absoluteNargoArtifactPath = join(__dirname, nargoArtifactPath); // eslint-disable-next-line @typescript-eslint/no-explicit-any -async function getPrecompiledSource(): Promise { - const compiledData = readFileSync(absoluteNargoArtifactPath).toString(); +async function getPrecompiledSource(path: string): Promise { + const compiledData = readFileSync(resolve(__dirname, path)).toString(); return JSON.parse(compiledData); } describe('noir wasm compilation', () => { - it('matches nargos compilation', async () => { - const wasmCircuit = await compile(absoluteNoirSourcePath); - const cliCircuit = await getPrecompiledSource(); - - // We don't expect the hashes to match due to how `noir_wasm` handles dependencies - expect(wasmCircuit.bytecode).to.eq(cliCircuit.bytecode); - expect(wasmCircuit.abi).to.deep.eq(cliCircuit.abi); - expect(wasmCircuit.backend).to.eq(cliCircuit.backend); - }).timeout(10e3); + describe('can compile simple scripts', () => { + it('matching nargos compilation', async () => { + const wasmCircuit = await compile(join(__dirname, simpleScriptSourcePath)); + const cliCircuit = await getPrecompiledSource(simpleScriptExpectedArtifact); + + // We don't expect the hashes to match due to how `noir_wasm` handles dependencies + expect(wasmCircuit.bytecode).to.eq(cliCircuit.bytecode); + expect(wasmCircuit.abi).to.deep.eq(cliCircuit.abi); + expect(wasmCircuit.backend).to.eq(cliCircuit.backend); + }).timeout(10e3); + }); + + describe('can compile scripts with dependencies', () => { + beforeEach(() => { + initializeResolver((file) => { + switch (file) { + case '/script/main.nr': + return readFileSync(join(__dirname, depsScriptSourcePath), 'utf-8'); + + case '/lib_a/lib.nr': + return readFileSync(join(__dirname, libASourcePath), 'utf-8'); + + case '/lib_b/lib.nr': + return readFileSync(join(__dirname, libBSourcePath), 'utf-8'); + + default: + return ''; + } + }); + }); + + it('matching nargos compilation', async () => { + const wasmCircuit = await compile('/script/main.nr', false, { + root_dependencies: ['lib_a'], + library_dependencies: { + lib_a: ['lib_b'], + }, + }); + + const cliCircuit = await getPrecompiledSource(depsScriptExpectedArtifact); + + // We don't expect the hashes to match due to how `noir_wasm` handles dependencies + expect(wasmCircuit.bytecode).to.eq(cliCircuit.bytecode); + expect(wasmCircuit.abi).to.deep.eq(cliCircuit.abi); + expect(wasmCircuit.backend).to.eq(cliCircuit.backend); + }).timeout(10e3); + }); }); diff --git a/compiler/wasm/test/shared.ts b/compiler/wasm/test/shared.ts index f726316cd74..6fc370f7ac8 100644 --- a/compiler/wasm/test/shared.ts +++ b/compiler/wasm/test/shared.ts @@ -1,2 +1,8 @@ -export const noirSourcePath = '../../noir-script/src/main.nr'; -export const nargoArtifactPath = '../../noir-script/target/noir_wasm_testing.json'; +export const simpleScriptSourcePath = '../../fixtures/simple/noir-script/src/main.nr'; +export const simpleScriptExpectedArtifact = '../../fixtures/simple/noir-script/target/noir_wasm_testing.json'; + +export const depsScriptSourcePath = '../../fixtures/deps/noir-script/src/main.nr'; +export const depsScriptExpectedArtifact = '../../fixtures/deps/noir-script/target/noir_wasm_testing.json'; + +export const libASourcePath = '../../fixtures/deps/lib-a/src/lib.nr'; +export const libBSourcePath = '../../fixtures/deps/lib-b/src/lib.nr';