mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-30 13:42:24 +03:00
adds .ts tests for parser
This commit is contained in:
parent
63cc0b7d05
commit
1ffcede96c
@ -20,7 +20,7 @@ use std::path::PathBuf;
|
|||||||
use crate::{
|
use crate::{
|
||||||
commands::{
|
commands::{
|
||||||
package::{Login, Logout},
|
package::{Login, Logout},
|
||||||
Build, Command, Prove, Run, Setup, Test, Update, UpdateAutomatic,
|
Build, Command, Prove, Run, Setup, Test,
|
||||||
},
|
},
|
||||||
context::{create_context, Context},
|
context::{create_context, Context},
|
||||||
};
|
};
|
||||||
@ -176,6 +176,8 @@ pub fn login_incorrect_credentials_or_token() -> Result<()> {
|
|||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
#[test]
|
#[test]
|
||||||
pub fn leo_update_and_update_automatic() -> Result<()> {
|
pub fn leo_update_and_update_automatic() -> Result<()> {
|
||||||
|
use crate::commands::{Update, UpdateAutomatic};
|
||||||
|
|
||||||
let update = Update {
|
let update = Update {
|
||||||
list: true,
|
list: true,
|
||||||
studio: true,
|
studio: true,
|
||||||
|
@ -37,6 +37,10 @@ path = "../asg"
|
|||||||
version = "1.5.3"
|
version = "1.5.3"
|
||||||
path = "../ast"
|
path = "../ast"
|
||||||
|
|
||||||
|
[dependencies.leo-compiler]
|
||||||
|
version = "1.5.3"
|
||||||
|
path = "../compiler"
|
||||||
|
|
||||||
[dependencies.leo-ast-passes]
|
[dependencies.leo-ast-passes]
|
||||||
version = "1.5.3"
|
version = "1.5.3"
|
||||||
path = "../ast-passes"
|
path = "../ast-passes"
|
||||||
|
2
wasm/tests/.gitignore
vendored
Normal file
2
wasm/tests/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
node_modules
|
||||||
|
dist
|
87
wasm/tests/package-lock.json
generated
Normal file
87
wasm/tests/package-lock.json
generated
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
{
|
||||||
|
"name": "parser-wasm-tests",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"lockfileVersion": 2,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "parser-wasm-tests",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"license": "GNU",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/js-yaml": "^4.0.3",
|
||||||
|
"@types/node": "^16.9.4",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
|
"typescript": "^3.9.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/js-yaml": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-5t9BhoORasuF5uCPr+d5/hdB++zRFUTMIZOzbNkr+jZh3yQht4HYbRDyj9fY8n2TZT30iW9huzav73x4NikqWg=="
|
||||||
|
},
|
||||||
|
"node_modules/@types/node": {
|
||||||
|
"version": "16.9.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.4.tgz",
|
||||||
|
"integrity": "sha512-KDazLNYAGIuJugdbULwFZULF9qQ13yNWEBFnfVpqlpgAAo6H/qnM9RjBgh0A0kmHf3XxAKLdN5mTIng9iUvVLA=="
|
||||||
|
},
|
||||||
|
"node_modules/argparse": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||||
|
},
|
||||||
|
"node_modules/js-yaml": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||||
|
"dependencies": {
|
||||||
|
"argparse": "^2.0.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"js-yaml": "bin/js-yaml.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/typescript": {
|
||||||
|
"version": "3.9.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
|
||||||
|
"integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==",
|
||||||
|
"bin": {
|
||||||
|
"tsc": "bin/tsc",
|
||||||
|
"tsserver": "bin/tsserver"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/js-yaml": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-5t9BhoORasuF5uCPr+d5/hdB++zRFUTMIZOzbNkr+jZh3yQht4HYbRDyj9fY8n2TZT30iW9huzav73x4NikqWg=="
|
||||||
|
},
|
||||||
|
"@types/node": {
|
||||||
|
"version": "16.9.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.4.tgz",
|
||||||
|
"integrity": "sha512-KDazLNYAGIuJugdbULwFZULF9qQ13yNWEBFnfVpqlpgAAo6H/qnM9RjBgh0A0kmHf3XxAKLdN5mTIng9iUvVLA=="
|
||||||
|
},
|
||||||
|
"argparse": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||||
|
},
|
||||||
|
"js-yaml": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||||
|
"requires": {
|
||||||
|
"argparse": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"typescript": {
|
||||||
|
"version": "3.9.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
|
||||||
|
"integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
wasm/tests/package.json
Normal file
25
wasm/tests/package.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "parser-wasm-tests",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "Test Framework implementation for compiler tests in WASM",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"compile": "tsc -p ./"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+ssh://git@github.com/aleohq/leo.git"
|
||||||
|
},
|
||||||
|
"author": "The Aleo Team <hello@aleo.org>",
|
||||||
|
"license": "GNU",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/aleohq/leo/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/aleohq/leo#readme",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/js-yaml": "^4.0.3",
|
||||||
|
"@types/node": "^16.9.4",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
|
"typescript": "^3.9.10"
|
||||||
|
}
|
||||||
|
}
|
180
wasm/tests/src/index.ts
Normal file
180
wasm/tests/src/index.ts
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
// Copyright (C) 2019-2021 Aleo Systems Inc.
|
||||||
|
// This file is part of the Leo library.
|
||||||
|
|
||||||
|
// The Leo library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// The Leo library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as parser from '../../pkg/leo_wasm';
|
||||||
|
import * as yaml from 'js-yaml';
|
||||||
|
import {JSON_SCHEMA, CORE_SCHEMA, DEFAULT_SCHEMA} from 'js-yaml';
|
||||||
|
|
||||||
|
// Path to the parser tests folder
|
||||||
|
const TESTS_PATH: string = path.join(__dirname, '../../../tests/parser');
|
||||||
|
|
||||||
|
// Path to the test expectations for parser tests
|
||||||
|
const EXPECTATIONS_PATH: string = path.join(__dirname, '../../../tests/expectations/parser/parser');
|
||||||
|
|
||||||
|
// List of folders containing parser tests
|
||||||
|
const TEST_FOLDERS: string[] = fs.readdirSync(TESTS_PATH);
|
||||||
|
|
||||||
|
// Test expectations enum, maps to string values: Pass and Fail
|
||||||
|
enum Expectation {
|
||||||
|
Pass = "Pass",
|
||||||
|
Fail = "Fail"
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TestHeader {
|
||||||
|
expectation: Expectation,
|
||||||
|
namespace: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TestResult {
|
||||||
|
filePath: string,
|
||||||
|
expectation: Expectation,
|
||||||
|
received: Expectation,
|
||||||
|
error: string|null
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main function for the tests
|
||||||
|
(function runTests() {
|
||||||
|
let results: TestResult[] = [];
|
||||||
|
|
||||||
|
for (let folder of TEST_FOLDERS) {
|
||||||
|
results.push(...walkDir(folder));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.length !== 0) {
|
||||||
|
results.forEach((result) => {
|
||||||
|
console.log(
|
||||||
|
'Test failed. Path: %s; Expected: %s; Received: %s',
|
||||||
|
result.filePath,
|
||||||
|
result.expectation,
|
||||||
|
result.received
|
||||||
|
);
|
||||||
|
});
|
||||||
|
process.exit(1);
|
||||||
|
} else {
|
||||||
|
console.log('All tests successfully passed.');
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test specific file an compare its outputs to the test expectations.
|
||||||
|
*
|
||||||
|
* @param filePath Path to the tested file
|
||||||
|
* @param outFile Contents of the expectation file of there is one
|
||||||
|
* @returns {TestResult[]} Tests that failed execution, empty means success
|
||||||
|
*/
|
||||||
|
function test(filePath: string, outFile: string|null): TestResult[] {
|
||||||
|
const text = fs.readFileSync(filePath).toString();
|
||||||
|
|
||||||
|
// Process the test's contents by cutting off the header
|
||||||
|
const header = text.slice(text.indexOf('/*') + 2, text.indexOf('*/'));
|
||||||
|
const testBody = text.slice(text.indexOf('*/') + 2);
|
||||||
|
|
||||||
|
const {expectation /* , namespace */} = readHeader(header);
|
||||||
|
|
||||||
|
const mismatches: TestResult[] = [];
|
||||||
|
const outputs: string[] = [];
|
||||||
|
|
||||||
|
// Get the tests by splitting by 2 newlines and sanitize each sample.
|
||||||
|
const samples = testBody
|
||||||
|
.split('\n\n')
|
||||||
|
.map((el) => el.trim())
|
||||||
|
.filter((el) => el.length !== 0);
|
||||||
|
|
||||||
|
// Go through each test and run WASM parse function. Check the results agains expectations
|
||||||
|
// and collect outputs to later compare to saved .out expectations.
|
||||||
|
for (const sample of samples) {
|
||||||
|
try {
|
||||||
|
outputs.push(JSON.parse(parser.parse(sample))); // Parser outputs JSON
|
||||||
|
if (expectation === Expectation.Fail) { // If expectation was Fail and it passed
|
||||||
|
mismatches.push({
|
||||||
|
filePath,
|
||||||
|
expectation: Expectation.Fail,
|
||||||
|
received: Expectation.Pass,
|
||||||
|
error: null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
outputs.push(error.toString());
|
||||||
|
if (expectation === Expectation.Pass) { // If expectation was Pass and it failed
|
||||||
|
mismatches.push({
|
||||||
|
error,
|
||||||
|
filePath,
|
||||||
|
expectation: Expectation.Pass,
|
||||||
|
received: Expectation.Fail,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Todo: After AST spans are removed, figure out a way to canonicalize strings
|
||||||
|
// and get them to the same format as serde's. For now comparing the outputs as
|
||||||
|
// strings is impossible.
|
||||||
|
//
|
||||||
|
// const formedOut = yaml.dump({
|
||||||
|
// expectation: expectation,
|
||||||
|
// namespace: namespace,
|
||||||
|
// outputs: outputs
|
||||||
|
// }, {schema: DEFAULT_SCHEMA});
|
||||||
|
|
||||||
|
return mismatches;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively go through each directory. If a file is met,
|
||||||
|
* then run test function for this file.
|
||||||
|
*
|
||||||
|
* @param fileOrDir
|
||||||
|
*/
|
||||||
|
function walkDir(fileOrDir: string): TestResult[] {
|
||||||
|
const currTarget = path.join(TESTS_PATH, fileOrDir);
|
||||||
|
let results: TestResult[] = []; // collect test results from sub calls
|
||||||
|
|
||||||
|
if (fs.lstatSync(currTarget).isDirectory()) {
|
||||||
|
for (const entry of fs.readdirSync(currTarget)) {
|
||||||
|
results.push(...walkDir(path.join(fileOrDir, entry)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const outFilePath = path.join(EXPECTATIONS_PATH, fileOrDir + '.out');
|
||||||
|
const outFile = fs.existsSync(outFilePath) ? fs.readFileSync(outFilePath).toString() : null;
|
||||||
|
|
||||||
|
return results.concat(test(currTarget, outFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a test header yaml and transform it into an Object.
|
||||||
|
*
|
||||||
|
* @param header
|
||||||
|
* @returns {TestHeader}
|
||||||
|
*/
|
||||||
|
function readHeader(header: string): TestHeader {
|
||||||
|
const parsed: any = yaml.load(header);
|
||||||
|
|
||||||
|
if (!parsed || parsed.constructor !== Object) {
|
||||||
|
throw "Unable to read test expectations: " + header;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
expectation: parsed.namespace,
|
||||||
|
namespace: parsed.expectation,
|
||||||
|
};
|
||||||
|
}
|
13
wasm/tests/tsconfig.json
Normal file
13
wasm/tests/tsconfig.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es2019",
|
||||||
|
"allowJs": true,
|
||||||
|
"lib": ["ES2019"],
|
||||||
|
"outDir": "dist",
|
||||||
|
"sourceMap": true,
|
||||||
|
"strict": true
|
||||||
|
},
|
||||||
|
"exclude": ["node_modules", ".vscode-test"],
|
||||||
|
"include": ["./src/**/*"]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user