convert tests to ava tests

This commit is contained in:
Florian Dold 2017-05-27 19:20:27 +02:00
parent 592fd62402
commit 9a1b2c8ccc
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
34 changed files with 59 additions and 26592 deletions

View File

@ -1,43 +0,0 @@
/*
This file is part of TALER
(C) 2016 Inria
TALER 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, or (at your option) any later version.
TALER 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
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
*
* @author Florian Dold
*/
"use strict";
let vm = require("vm");
let fs = require("fs");
let process = require("process");
let path = require("path");
let testFile = path.resolve(process.argv[2]);
console.log("TAP version 13");
console.log("running test", testFile);
process.on('unhandledRejection', function(reason, p){
console.log("Possibly Unhandled Rejection at: Promise ", p, " reason: ", reason);
process.exit(1);
});
let tt = require("../talertest");
require(testFile);
tt.run();

19
node_modules/talertest/package.json generated vendored
View File

@ -1,19 +0,0 @@
{
"name": "talertest",
"version": "1.0.0",
"main": "talertest.js",
"types": "talertest.d.ts",
"author": "Florian Dold",
"license": "GPL-2.0+",
"scripts": {
"build": "tsc"
},
"files": [
"node/",
"selenium/",
"talertest.d.ts"
],
"devDependencies": {
"typescript": "^2.2.2"
}
}

View File

@ -1,2 +0,0 @@
coverage/
coveage-*.json

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,206 +0,0 @@
/*
This file is part of TALER
(C) 2016 Inria
TALER 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, or (at your option) any later version.
TALER 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
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
*
* @author Florian Dold
*/
"use strict";
var webdriver = require('selenium-webdriver');
var chrome = require('selenium-webdriver/chrome');
var path = require("path");
var process = require("process");
var fs = require("fs");
var globSync = require("glob").sync;
var connect = require('connect');
var serveStatic = require('serve-static');
// Port of the web server used to serve the test files
var httpPort = 8080;
var p = `http://localhost:${httpPort}/testlib/selenium/testhost.html`;
var argv = require('minimist')(process.argv.slice(2), {"boolean": ["keep-open", "coverage"]});
function printUsage() {
console.log(`Usage: [--keep-open] TESTSCRIPT`);
}
function randId(n) {
let s = "";
var choices = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (let i = 0; i < n; i++) {
s += choices.charAt(Math.floor(Math.random() * choices.length));
}
return s;
}
if (argv._.length != 1) {
console.log("exactly one test script must be given");
printUsage();
process.exit(1);
}
var testScriptName = path.resolve(argv._[0]);
var testName = path.basename(testScriptName, ".js");
var projectRoot = path.resolve(__dirname, "../../") + "/";
if (!testScriptName.startsWith(projectRoot)) {
console.log("test file must be inside wallet project root");
process.exit(1);
}
var testScript = testScriptName.substring(projectRoot.length);
try {
var stats = fs.lstatSync(path.resolve(projectRoot, "./" + testScript));
if (!stats.isFile()) {
throw Error("test must be a file");
}
} catch (e) {
console.log("can't execute test");
console.log(e);
process.exit(e);
}
var script = `
function onStatus(s) {
document.body.appendChild(document.createTextNode(s));
document.body.appendChild(document.createElement("br"));
}
function f() {
if ("undefined" == typeof System) {
console.log("can't access module loader");
return
}
System.import("testlib/talertest")
.then(tt => {
SystemJS.import("http://localhost:${httpPort}/${testScript}")
.then(() => {
return tt.run(onStatus);
})
.then(() => {
window.__test_over = true;
})
.catch((e) => {
window.__test_over = true;
});
})
.catch((e) => {
console.error("can't locate talertest");
console.error(e);
});
}
if (document.readyState == "complete") {
f();
} else {
document.addEventListener("DOMContentLoaded", f);
}
`;
function untilTestOver() {
return driver.executeScript("return window.__test_over");
}
console.log("TAP version 13");
let srv = connect().use(serveStatic(__dirname + "/../../"));
let l = srv.listen(8080);
var driver = new webdriver.Builder()
.setLoggingPrefs({browser: 'ALL'})
.forBrowser('chrome')
.build();
driver.get(p);
if (argv["coverage"]) {
driver.executeScript("window.requestCoverage = true;");
}
driver.executeScript(script);
driver.wait(untilTestOver);
/**
* Instrument and get a coverage stub for all
* files we don't have coverage for, so they show
* up in the report.
*/
function augmentCoverage(cov) {
for (let file of globSync(projectRoot + "/src/**/*.js")) {
let suffix = file.substring(0, projectRoot.lenth);
if (/.*\/vendor\/.*/.test(suffix)) {
continue;
}
if (/.*\/taler-emscripten-lib.js/.test(suffix)) {
continue;
}
if (file in cov) {
continue;
}
let instrumenter = new (require("istanbul").Instrumenter)();
let source = fs.readFileSync(file, "utf-8");
let instrumentedSrc = instrumenter.instrumentSync(source, file);
let covStubRE = /\{.*"path".*"fnMap".*"statementMap".*"branchMap".*\}/g;
let covStubMatch = covStubRE.exec(instrumentedSrc);
if (covStubMatch !== null) {
let covStub = JSON.parse(covStubMatch[0]);
cov[file] = covStub;
}
}
}
driver.manage().logs().get("browser").then((logs) => {
for (let l of logs) {
if (l.message.startsWith("{")) {
// format not understood, sometimes messages are logged
// with more structure, just pass it on
console.log(l.message);
continue;
}
let s1 = l.message.indexOf(" ") + 1;
let s2 = l.message.indexOf(" ", s1) + 1;
// Skip file url and LINE:COL
console.log(l.message.substring(s2));
}
let coverage = driver.executeScript("return JSON.stringify(window.__coverage__);");
coverage.then((covStr) => {
let cov = JSON.parse(covStr);
if (cov) {
let covTranslated = {};
for (let f in cov) {
let p = path.resolve(projectRoot, f);
let c = covTranslated[p] = cov[f];
c.path = p;
}
augmentCoverage(covTranslated);
fs.writeFileSync(`coverage-${testName}-${randId(5)}.json`, JSON.stringify(covTranslated));
}
if (!argv["keep-open"]) {
driver.quit();
l.close();
}
})
});

File diff suppressed because one or more lines are too long

View File

@ -1,63 +0,0 @@
<!doctype html>
<html>
<head>
<title>Browser Test Host</title>
<script src="/testlib/selenium/esprima.js"></script>
<script src="/testlib/selenium/escodegen.browser.js"></script>
<script src="/testlib/selenium/instrumenter.js"></script>
<script src="/src/vendor/URI.js"></script>
<!-- for instrumentation to work, we have to use the non-csp version -->
<script src="/testlib/selenium/system.js"></script>
</head>
<body>
<script>
document.body.appendChild(document.createTextNode(`starting test`));
document.body.appendChild(document.createElement("br"));
var requestCoverage = false;
let parser = document.createElement('a');
let oldTranslate = System.translate.bind(System);
System.translate = (load) => {
let srcP = oldTranslate(load);
if (!requestCoverage) {
return srcP;
}
parser.href = load.name;
let modName = parser.pathname.substring(1);
if (/.*\/?taler-emscripten-lib.js/.test(load.name)) {
// don't instrument emscripten
document.body.appendChild(document.createTextNode(`not instrumenting ${modName}`));
document.body.appendChild(document.createElement("br"));
return srcP;
}
let inst = new Instrumenter();
document.body.appendChild(document.createTextNode(`instrumenting ${modName}`));
document.body.appendChild(document.createElement("br"));
return Promise.resolve(srcP).then((src) => {
return inst.instrumentSync(src, modName);
});
}
System.config({
baseURL: "/",
defaultJSExtensions: true,
meta: {
"src/emscripten/taler-emscripten-lib": {
format: "global",
exports: "Module",
},
},
});
</script>
</body>
</html>

View File

@ -1,19 +0,0 @@
/**
*
* @author Florian Dold
*/
export declare type TestFn = (t: TestLib) => void | Promise<void>;
export interface TestLib {
pass(msg?: string): void;
fail(msg?: string): void;
assert(v: any, msg?: string): void;
assertEqualsStrict(v1: any, v2: any, msg?: string): void;
}
/**
* Register a test case.
*/
export declare function test(name: string, testFn: TestFn): void;
/**
* Run all registered test case, producing a TAP stream.
*/
export declare function run(statusCallback?: (m: string) => void): Promise<void>;

111
node_modules/talertest/talertest.js generated vendored
View File

@ -1,111 +0,0 @@
/*
This file is part of TALER
(C) 2016 Inria
TALER 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, or (at your option) any later version.
TALER 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
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
let tests = [];
let testRunner;
/**
* Register a test case.
*/
function test(name, testFn) {
tests.push({ name, testFn });
}
exports.test = test;
/**
* Run all registered test case, producing a TAP stream.
*/
function run(statusCallback) {
return __awaiter(this, void 0, void 0, function* () {
console.log(`1..${tests.length}`);
for (let i in tests) {
let t = tests[i];
let passed = false;
let lastMsg = undefined;
let p = new Promise((resolve, reject) => {
let pass = (msg) => {
if (passed) {
let e = Error("test passed twice");
reject(e);
throw e;
}
passed = true;
lastMsg = msg;
resolve();
};
let fail = (msg) => {
lastMsg = msg;
let e = Error("test failed");
reject(e);
throw e;
};
let assert = (v, msg) => {
if (!v) {
lastMsg = msg;
reject(Error("test failed"));
return;
}
};
let assertEqualsStrict = (v1, v2, msg) => {
if (v1 !== v2) {
console.log(`# expected: ${v1}`);
console.log(`# actual: ${v2}`);
lastMsg = msg;
let e = Error("test failed");
reject(e);
throw e;
}
};
// Test might return a promise. If so, wait for it.
let r = t.testFn({ pass, fail, assert, assertEqualsStrict });
if (r) {
r.then(() => pass(), (e) => fail(e.toString()));
}
});
console.log(`# ${t.name}`);
statusCallback && statusCallback(`starting test ${t.name}`);
if (!lastMsg) {
lastMsg = "-";
}
try {
yield p;
if (!passed) {
throw Error("test did not call 'pass'");
}
console.log(`ok ${Number(i) + 1} ${lastMsg || "-"}`);
statusCallback && statusCallback(`finished test ${t.name}`);
}
catch (e) {
try {
console.error(e.stack);
}
catch (e2) {
console.error(e);
}
console.log(`not ok ${Number(i) + 1} ${lastMsg || "-"}`);
statusCallback && statusCallback(`failed test ${t.name}`);
}
}
});
}
exports.run = run;

122
node_modules/talertest/talertest.ts generated vendored
View File

@ -1,122 +0,0 @@
/*
This file is part of TALER
(C) 2016 Inria
TALER 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, or (at your option) any later version.
TALER 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
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
*
* @author Florian Dold
*/
export type TestFn = (t: TestLib) => void | Promise<void>;
interface Test {
name: string;
testFn: TestFn;
}
export interface TestLib {
pass(msg?: string): void;
fail(msg?: string): void;
assert(v: any, msg?: string): void;
assertEqualsStrict(v1: any, v2: any, msg?: string): void;
}
let tests: Test[] = [];
let testRunner: any;
/**
* Register a test case.
*/
export function test(name: string, testFn: TestFn) {
tests.push({name, testFn});
}
/**
* Run all registered test case, producing a TAP stream.
*/
export async function run(statusCallback?: (m: string) => void) {
console.log(`1..${tests.length}`);
for (let i in tests) {
let t = tests[i];
let passed = false;
let lastMsg: string|undefined = undefined;
let p = new Promise((resolve, reject) => {
let pass = (msg?: string) => {
if (passed) {
let e = Error("test passed twice");
reject(e);
throw e;
}
passed = true;
lastMsg = msg;
resolve();
};
let fail = (msg?: string) => {
lastMsg = msg;
let e = Error("test failed");
reject(e);
throw e;
};
let assert = (v: any, msg?: string) => {
if (!v) {
lastMsg = msg;
reject(Error("test failed"));
return;
}
};
let assertEqualsStrict = (v1: any, v2: any, msg?: string) => {
if (v1 !== v2) {
console.log(`# expected: ${v1}`);
console.log(`# actual: ${v2}`);
lastMsg = msg;
let e = Error("test failed");
reject(e);
throw e;
}
};
// Test might return a promise. If so, wait for it.
let r = t.testFn({pass,fail, assert, assertEqualsStrict});
if (r) {
r.then(() => pass(), (e) => fail(e.toString()));
}
});
console.log(`# ${t.name}`);
statusCallback && statusCallback(`starting test ${t.name}`);
if (!lastMsg) {
lastMsg = "-";
}
try {
await p;
if (!passed) {
throw Error("test did not call 'pass'");
}
console.log(`ok ${Number(i) + 1} ${lastMsg || "-"}`);
statusCallback && statusCallback(`finished test ${t.name}`);
} catch (e) {
try {
console.error(e.stack);
} catch (e2) {
console.error(e);
}
console.log(`not ok ${Number(i) + 1} ${lastMsg || "-"}`);
statusCallback && statusCallback(`failed test ${t.name}`);
}
}
}

19
node_modules/talertest/tsconfig.json generated vendored
View File

@ -1,19 +0,0 @@
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"lib": [
"ES6",
"DOM"
],
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"strictNullChecks": true,
"noImplicitAny": true,
"declaration": true,
"alwaysStrict": true
},
"files": [
"talertest.ts"
]
}

7
node_modules/talertest/yarn.lock generated vendored
View File

@ -1,7 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
typescript@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.2.2.tgz#606022508479b55ffa368b58fee963a03dfd7b0c"

View File

@ -39,7 +39,6 @@
"pogen": "file:tooling/pogen/",
"react": "^15.5.4",
"react-dom": "^15.5.4",
"talertest": "file:tooling/talertest/",
"through2": "^2.0.1",
"tiny-worker": "^2.1.1",
"ts-loader": "^2.0.3",

View File

@ -1,6 +1,6 @@
import {CryptoApi} from "./cryptoApi";
import {ReserveRecord, DenominationRecord, DenominationStatus} from "../types";
import {test, TestLib} from "talertest";
import {test} from "ava";
let masterPub1: string = "CQQZ9DY3MZ1ARMN5K1VKDETS04Y2QCKMMCFHZSWJWWVN82BTTH00";
@ -45,15 +45,15 @@ let denomValid1: DenominationRecord = {
let denomInvalid1 = JSON.parse(JSON.stringify(denomValid1));
denomInvalid1.value.value += 1;
test("string hashing", async (t: TestLib) => {
test("string hashing", async t => {
let crypto = new CryptoApi();
let s = await crypto.hashString("hello taler");
let sh = "8RDMADB3YNF3QZBS3V467YZVJAMC2QAQX0TZGVZ6Q5PFRRAJFT70HHN0QF661QR9QWKYMMC7YEMPD679D2RADXCYK8Y669A2A5MKQFR";
t.assert(s == sh);
t.true(s == sh);
t.pass();
});
test("precoin creation", async (t: TestLib) => {
test("precoin creation", async t => {
let crypto = new CryptoApi();
let {priv, pub} = await crypto.createEddsaKeypair();
let r: ReserveRecord = {
@ -73,12 +73,12 @@ test("precoin creation", async (t: TestLib) => {
t.pass();
});
test("denom validation", async (t: TestLib) => {
test("denom validation", async t => {
let crypto = new CryptoApi();
let v: boolean;
v = await crypto.isValidDenom(denomValid1, masterPub1);
t.assert(v);
t.true(v);
v = await crypto.isValidDenom(denomInvalid1, masterPub1);
t.assert(!v);
t.true(!v);
t.pass();
});

View File

@ -1,55 +1,55 @@
import {test, TestLib} from "talertest";
import {test} from "ava";
import * as native from "./emscInterface";
test("string hashing", (t: TestLib) => {
test("string hashing", t => {
let x = native.ByteArray.fromStringWithNull("hello taler");
let h = "8RDMADB3YNF3QZBS3V467YZVJAMC2QAQX0TZGVZ6Q5PFRRAJFT70HHN0QF661QR9QWKYMMC7YEMPD679D2RADXCYK8Y669A2A5MKQFR"
let hc = x.hash().toCrock();
console.log(`# hc ${hc}`);
t.assert(h === hc, "must equal");
t.true(h === hc, "must equal");
t.pass();
});
test("signing", (t: TestLib) => {
test("signing", t => {
let x = native.ByteArray.fromStringWithNull("hello taler");
let priv = native.EddsaPrivateKey.create();
let pub = priv.getPublicKey();
let purpose = new native.EccSignaturePurpose(native.SignaturePurpose.TEST, x);
let sig = native.eddsaSign(purpose, priv);
t.assert(native.eddsaVerify(native.SignaturePurpose.TEST, purpose, sig, pub));
t.true(native.eddsaVerify(native.SignaturePurpose.TEST, purpose, sig, pub));
t.pass();
});
test("signing-fixed-data", (t: TestLib) => {
test("signing-fixed-data", t => {
let x = native.ByteArray.fromStringWithNull("hello taler");
let purpose = new native.EccSignaturePurpose(native.SignaturePurpose.TEST, x);
const privStr = "G9R8KRRCAFKPD0KW7PW48CC2T03VQ8K2AN9J6J6K2YW27J5MHN90";
const pubStr = "YHCZB442FQFJ0ET20MWA8YJ53M61EZGJ6QKV1KTJZMRNXDY45WT0";
const sigStr = "7V6XY4QGC1406GPMT305MZQ1HDCR7R0S5BP02GTGDQFPSXB6YD2YDN5ZS7NJQCNP61Y39MRHXNXQ1Z15JY4CJY4CPDA6CKQ3313WG38";
let priv = native.EddsaPrivateKey.fromCrock(privStr);
t.assert(privStr == priv.toCrock())
t.true(privStr == priv.toCrock())
let pub = priv.getPublicKey();
t.assert(pubStr == pub.toCrock());
t.true(pubStr == pub.toCrock());
let sig = native.EddsaSignature.fromCrock(sigStr);
t.assert(sigStr == sig.toCrock())
t.true(sigStr == sig.toCrock())
let sig2 = native.eddsaSign(purpose, priv);
t.assert(sig.toCrock() == sig2.toCrock());
t.assert(native.eddsaVerify(native.SignaturePurpose.TEST, purpose, sig, pub));
t.true(sig.toCrock() == sig2.toCrock());
t.true(native.eddsaVerify(native.SignaturePurpose.TEST, purpose, sig, pub));
t.pass();
});
const denomPubStr1 = "51R7ARKCD5HJTTV5F4G0M818E9SP280A40G2GVH04CR30G9R64VK6HHS6MW42DSN8MVKJGHK6WR3CGT18MWMCDSM75138E1K8S0MADSQ68W34DHH6MW4CHA270W4CG9J6GW48DHG8MVK4E9S7523GEA56H0K4E1Q891KCCSG752KGC1M88VMCDSQ6D23CHHG8H33AGHG6MSK8GT26CRKAC1M64V3JCJ56CVKCC228MWMCHA26MS30H1J8MVKEDHJ70TMADHK892KJC1H60TKJDHM710KGGT584T38H9K851KCDHG60W30HJ28CT4CC1G8CR3JGJ28H236DJ28H330H9S890M2D9S8S14AGA369344GA36S248CHS70RKEDSS6MWKGDJ26D136GT465348CSS8S232CHM6GS34C9N8CS3GD9H60W36H1R8MSK2GSQ8MSM6C9R70SKCHHN6MW3ACJ28N0K2CA58RS3GCA26MV42G9P891KAG9Q8N0KGD9M850KEHJ16S130CA27124AE1G852KJCHR6S1KGDSJ8RTKED1S8RR3CCHP68W4CH9Q6GT34GT18GS36EA46N24AGSP6933GCHM60VMAE1S8GV3EHHN74W3GC1J651KEH9N8MSK0CSG6S2KEEA460R32C1M8D144GSR6RWKEC218S0KEGJ4611KEEA36CSKJC2564TM4CSJ6H230E1N74TM8C1P61342CSG60WKCGHH64VK2G9S8CRKAHHK88W30HJ388R3CH1Q6X2K2DHK8GSM4D1Q74WM4HA461146H9S6D33JDJ26D234C9Q6923ECSS60RM6CT46CSKCH1M6S13EH9J8S33GCSN4CMGM81051JJ08SG64R30C1H4CMGM81054520A8A00";
test("rsa-encode", (t: TestLib) => {
test("rsa-encode", t => {
const pubHashStr = "JM63YM5X7X547164QJ3MGJZ4WDD47GEQR5DW5SH35G4JFZXEJBHE5JBNZM5K8XN5C4BRW25BE6GSVAYBF790G2BZZ13VW91D41S4DS0"
let denomPub = native.RsaPublicKey.fromCrock(denomPubStr1);
let pubHash = denomPub.encode().hash();
t.assert(pubHashStr == pubHash.toCrock());
t.true(pubHashStr == pubHash.toCrock());
t.pass();
});
test("withdraw-request", (t: TestLib) => {
test("withdraw-request", t => {
const reservePrivStr = "G9R8KRRCAFKPD0KW7PW48CC2T03VQ8K2AN9J6J6K2YW27J5MHN90";
const reservePriv = native.EddsaPrivateKey.fromCrock(reservePrivStr);
const reservePub = reservePriv.getPublicKey();
@ -72,30 +72,30 @@ test("withdraw-request", (t: TestLib) => {
var sigStr = "AD3T8W44NV193J19RAN3NAJHPP6RVB0R3NWV7ZK5G8Q946YDK0B6F8YJBNRRBXSPVTKY31S7BVZPJFFTJJRMY61DH51X4JSXK677428";
var sig = native.eddsaSign(withdrawRequest.toPurpose(), reservePriv);
t.assert(native.eddsaVerify(native.SignaturePurpose.RESERVE_WITHDRAW, withdrawRequest.toPurpose(), sig, reservePub));
t.assert(sig.toCrock() == sigStr);
t.true(native.eddsaVerify(native.SignaturePurpose.RESERVE_WITHDRAW, withdrawRequest.toPurpose(), sig, reservePub));
t.true(sig.toCrock() == sigStr);
t.pass();
});
test("withdraw-request", (t: TestLib) => {
test("withdraw-request", t => {
const a1 = new native.Amount({currency: "KUDOS", value: 1, fraction: 50000000});
const a2 = new native.Amount({currency: "KUDOS", value: 1, fraction: 50000000});
a1.add(a2);
let x = a1.toJson();
t.assert(x.currency == "KUDOS");
t.assert(x.fraction == 0);
t.assert(x.value == 3);
t.true(x.currency == "KUDOS");
t.true(x.fraction == 0);
t.true(x.value == 3);
t.pass();
});
test("ecdsa", (t: TestLib) => {
test("ecdsa", t => {
const priv = native.EcdsaPrivateKey.create();
const pub1 = priv.getPublicKey();
t.pass();
});
test("ecdhe", (t: TestLib) => {
test("ecdhe", t => {
const priv = native.EcdhePrivateKey.create();
const pub = priv.getPublicKey();
t.pass();

View File

@ -1,21 +1,21 @@
import {test, TestLib} from "talertest";
import {test} from "ava";
import * as helpers from "./helpers";
test("URL canonicalization", (t: TestLib) => {
test("URL canonicalization", t => {
// converts to relative, adds https
t.assertEqualsStrict(
t.is(
"https://alice.example.com/exchange/",
helpers.canonicalizeBaseUrl("alice.example.com/exchange"))
helpers.canonicalizeBaseUrl("alice.example.com/exchange"));
// keeps http, adds trailing slash
t.assertEqualsStrict(
t.is(
"http://alice.example.com/exchange/",
helpers.canonicalizeBaseUrl("http://alice.example.com/exchange"))
helpers.canonicalizeBaseUrl("http://alice.example.com/exchange"));
// keeps http, adds trailing slash
t.assertEqualsStrict(
t.is(
"http://alice.example.com/exchange/",
helpers.canonicalizeBaseUrl("http://alice.example.com/exchange#foobar"))
helpers.canonicalizeBaseUrl("http://alice.example.com/exchange#foobar"));
t.pass();
});

View File

@ -1,44 +1,44 @@
import {test, TestLib} from "talertest";
import {test} from "ava";
import {Amounts} from "./types";
import * as types from "./types";
let amt = (value: number, fraction: number, currency: string): types.AmountJson => ({value, fraction, currency});
test("amount addition (simple)", (t: TestLib) => {
test("amount addition (simple)", t => {
let a1 = amt(1,0,"EUR");
let a2 = amt(1,0,"EUR");
let a3 = amt(2,0,"EUR");
t.assert(0 == types.Amounts.cmp(Amounts.add(a1, a2).amount, a3));
t.true(0 == types.Amounts.cmp(Amounts.add(a1, a2).amount, a3));
t.pass();
});
test("amount addition (saturation)", (t: TestLib) => {
test("amount addition (saturation)", t => {
let a1 = amt(1,0,"EUR");
let res = Amounts.add(Amounts.getMaxAmount("EUR"), a1);
t.assert(res.saturated);
t.true(res.saturated);
t.pass();
});
test("amount subtraction (simple)", (t: TestLib) => {
test("amount subtraction (simple)", t => {
let a1 = amt(2,5,"EUR");
let a2 = amt(1,0,"EUR");
let a3 = amt(1,5,"EUR");
t.assert(0 == types.Amounts.cmp(Amounts.sub(a1, a2).amount, a3));
t.true(0 == types.Amounts.cmp(Amounts.sub(a1, a2).amount, a3));
t.pass();
});
test("amount subtraction (saturation)", (t: TestLib) => {
test("amount subtraction (saturation)", t => {
let a1 = amt(0,0,"EUR");
let a2 = amt(1,0,"EUR");
let res = Amounts.sub(a1, a2);
t.assert(res.saturated);
t.true(res.saturated);
res = Amounts.sub(a1, a1);
t.assert(!res.saturated);
t.true(!res.saturated);
t.pass();
});
test("contract validation", (t: TestLib) => {
test("contract validation", t => {
let c = {
H_wire: "123",
summary: "hello",

View File

@ -1,9 +1,9 @@
import {test, TestLib} from "talertest";
import {test} from "ava";
import {mkAmount} from "./types";
import * as wallet from "./wallet";
test("coin selection 1", (t: TestLib) => {
test("coin selection 1", t => {
let cds: any = [];
cds.push({
coin: {
@ -29,12 +29,12 @@ test("coin selection 1", (t: TestLib) => {
t.fail();
return;
}
t.assert(res.length == 2);
t.true(res.length == 2);
t.pass();
});
test("coin selection 2", (t: TestLib) => {
test("coin selection 2", t => {
let cds: any = [];
cds.push({
coin: {
@ -70,12 +70,12 @@ test("coin selection 2", (t: TestLib) => {
t.fail();
return;
}
t.assert(res.length == 2);
t.true(res.length == 2);
t.pass();
});
test("coin selection 2", (t: TestLib) => {
test("coin selection 2", t => {
let cds: any = [];
cds.push({
coin: {
@ -110,13 +110,13 @@ test("coin selection 2", (t: TestLib) => {
t.fail();
return;
}
t.assert(res.length == 2);
t.true(res.length == 2);
t.pass();
});
test("coin selection 3", (t: TestLib) => {
test("coin selection 3", t => {
let cds: any = [];
cds.push({
coin: {
@ -151,12 +151,12 @@ test("coin selection 3", (t: TestLib) => {
t.fail();
return;
}
t.assert(res.length == 3);
t.true(res.length == 3);
t.pass();
});
test("coin selection 3", (t: TestLib) => {
test("coin selection 3", t => {
let cds: any = [];
cds.push({
coin: {
@ -187,7 +187,7 @@ test("coin selection 3", (t: TestLib) => {
});
let res = wallet.selectCoins(cds, mkAmount(4,0,"EUR"), mkAmount(0,2,"EUR"));
t.assert(!res);
t.true(!res);
t.pass();
});

View File

@ -1,43 +0,0 @@
/*
This file is part of TALER
(C) 2016 Inria
TALER 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, or (at your option) any later version.
TALER 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
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
*
* @author Florian Dold
*/
"use strict";
let vm = require("vm");
let fs = require("fs");
let process = require("process");
let path = require("path");
let testFile = path.resolve(process.argv[2]);
console.log("TAP version 13");
console.log("running test", testFile);
process.on('unhandledRejection', function(reason, p){
console.log("Possibly Unhandled Rejection at: Promise ", p, " reason: ", reason);
process.exit(1);
});
let tt = require("../talertest");
require(testFile);
tt.run();

View File

@ -1,19 +0,0 @@
{
"name": "talertest",
"version": "1.0.0",
"main": "talertest.js",
"types": "talertest.d.ts",
"author": "Florian Dold",
"license": "GPL-2.0+",
"scripts": {
"build": "tsc"
},
"files": [
"node/",
"selenium/",
"talertest.d.ts"
],
"devDependencies": {
"typescript": "^2.2.2"
}
}

View File

@ -1,2 +0,0 @@
coverage/
coveage-*.json

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,206 +0,0 @@
/*
This file is part of TALER
(C) 2016 Inria
TALER 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, or (at your option) any later version.
TALER 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
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
*
* @author Florian Dold
*/
"use strict";
var webdriver = require('selenium-webdriver');
var chrome = require('selenium-webdriver/chrome');
var path = require("path");
var process = require("process");
var fs = require("fs");
var globSync = require("glob").sync;
var connect = require('connect');
var serveStatic = require('serve-static');
// Port of the web server used to serve the test files
var httpPort = 8080;
var p = `http://localhost:${httpPort}/testlib/selenium/testhost.html`;
var argv = require('minimist')(process.argv.slice(2), {"boolean": ["keep-open", "coverage"]});
function printUsage() {
console.log(`Usage: [--keep-open] TESTSCRIPT`);
}
function randId(n) {
let s = "";
var choices = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (let i = 0; i < n; i++) {
s += choices.charAt(Math.floor(Math.random() * choices.length));
}
return s;
}
if (argv._.length != 1) {
console.log("exactly one test script must be given");
printUsage();
process.exit(1);
}
var testScriptName = path.resolve(argv._[0]);
var testName = path.basename(testScriptName, ".js");
var projectRoot = path.resolve(__dirname, "../../") + "/";
if (!testScriptName.startsWith(projectRoot)) {
console.log("test file must be inside wallet project root");
process.exit(1);
}
var testScript = testScriptName.substring(projectRoot.length);
try {
var stats = fs.lstatSync(path.resolve(projectRoot, "./" + testScript));
if (!stats.isFile()) {
throw Error("test must be a file");
}
} catch (e) {
console.log("can't execute test");
console.log(e);
process.exit(e);
}
var script = `
function onStatus(s) {
document.body.appendChild(document.createTextNode(s));
document.body.appendChild(document.createElement("br"));
}
function f() {
if ("undefined" == typeof System) {
console.log("can't access module loader");
return
}
System.import("testlib/talertest")
.then(tt => {
SystemJS.import("http://localhost:${httpPort}/${testScript}")
.then(() => {
return tt.run(onStatus);
})
.then(() => {
window.__test_over = true;
})
.catch((e) => {
window.__test_over = true;
});
})
.catch((e) => {
console.error("can't locate talertest");
console.error(e);
});
}
if (document.readyState == "complete") {
f();
} else {
document.addEventListener("DOMContentLoaded", f);
}
`;
function untilTestOver() {
return driver.executeScript("return window.__test_over");
}
console.log("TAP version 13");
let srv = connect().use(serveStatic(__dirname + "/../../"));
let l = srv.listen(8080);
var driver = new webdriver.Builder()
.setLoggingPrefs({browser: 'ALL'})
.forBrowser('chrome')
.build();
driver.get(p);
if (argv["coverage"]) {
driver.executeScript("window.requestCoverage = true;");
}
driver.executeScript(script);
driver.wait(untilTestOver);
/**
* Instrument and get a coverage stub for all
* files we don't have coverage for, so they show
* up in the report.
*/
function augmentCoverage(cov) {
for (let file of globSync(projectRoot + "/src/**/*.js")) {
let suffix = file.substring(0, projectRoot.lenth);
if (/.*\/vendor\/.*/.test(suffix)) {
continue;
}
if (/.*\/taler-emscripten-lib.js/.test(suffix)) {
continue;
}
if (file in cov) {
continue;
}
let instrumenter = new (require("istanbul").Instrumenter)();
let source = fs.readFileSync(file, "utf-8");
let instrumentedSrc = instrumenter.instrumentSync(source, file);
let covStubRE = /\{.*"path".*"fnMap".*"statementMap".*"branchMap".*\}/g;
let covStubMatch = covStubRE.exec(instrumentedSrc);
if (covStubMatch !== null) {
let covStub = JSON.parse(covStubMatch[0]);
cov[file] = covStub;
}
}
}
driver.manage().logs().get("browser").then((logs) => {
for (let l of logs) {
if (l.message.startsWith("{")) {
// format not understood, sometimes messages are logged
// with more structure, just pass it on
console.log(l.message);
continue;
}
let s1 = l.message.indexOf(" ") + 1;
let s2 = l.message.indexOf(" ", s1) + 1;
// Skip file url and LINE:COL
console.log(l.message.substring(s2));
}
let coverage = driver.executeScript("return JSON.stringify(window.__coverage__);");
coverage.then((covStr) => {
let cov = JSON.parse(covStr);
if (cov) {
let covTranslated = {};
for (let f in cov) {
let p = path.resolve(projectRoot, f);
let c = covTranslated[p] = cov[f];
c.path = p;
}
augmentCoverage(covTranslated);
fs.writeFileSync(`coverage-${testName}-${randId(5)}.json`, JSON.stringify(covTranslated));
}
if (!argv["keep-open"]) {
driver.quit();
l.close();
}
})
});

File diff suppressed because one or more lines are too long

View File

@ -1,63 +0,0 @@
<!doctype html>
<html>
<head>
<title>Browser Test Host</title>
<script src="/testlib/selenium/esprima.js"></script>
<script src="/testlib/selenium/escodegen.browser.js"></script>
<script src="/testlib/selenium/instrumenter.js"></script>
<script src="/src/vendor/URI.js"></script>
<!-- for instrumentation to work, we have to use the non-csp version -->
<script src="/testlib/selenium/system.js"></script>
</head>
<body>
<script>
document.body.appendChild(document.createTextNode(`starting test`));
document.body.appendChild(document.createElement("br"));
var requestCoverage = false;
let parser = document.createElement('a');
let oldTranslate = System.translate.bind(System);
System.translate = (load) => {
let srcP = oldTranslate(load);
if (!requestCoverage) {
return srcP;
}
parser.href = load.name;
let modName = parser.pathname.substring(1);
if (/.*\/?taler-emscripten-lib.js/.test(load.name)) {
// don't instrument emscripten
document.body.appendChild(document.createTextNode(`not instrumenting ${modName}`));
document.body.appendChild(document.createElement("br"));
return srcP;
}
let inst = new Instrumenter();
document.body.appendChild(document.createTextNode(`instrumenting ${modName}`));
document.body.appendChild(document.createElement("br"));
return Promise.resolve(srcP).then((src) => {
return inst.instrumentSync(src, modName);
});
}
System.config({
baseURL: "/",
defaultJSExtensions: true,
meta: {
"src/emscripten/taler-emscripten-lib": {
format: "global",
exports: "Module",
},
},
});
</script>
</body>
</html>

View File

@ -1,19 +0,0 @@
/**
*
* @author Florian Dold
*/
export declare type TestFn = (t: TestLib) => void | Promise<void>;
export interface TestLib {
pass(msg?: string): void;
fail(msg?: string): void;
assert(v: any, msg?: string): void;
assertEqualsStrict(v1: any, v2: any, msg?: string): void;
}
/**
* Register a test case.
*/
export declare function test(name: string, testFn: TestFn): void;
/**
* Run all registered test case, producing a TAP stream.
*/
export declare function run(statusCallback?: (m: string) => void): Promise<void>;

View File

@ -1,111 +0,0 @@
/*
This file is part of TALER
(C) 2016 Inria
TALER 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, or (at your option) any later version.
TALER 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
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
let tests = [];
let testRunner;
/**
* Register a test case.
*/
function test(name, testFn) {
tests.push({ name, testFn });
}
exports.test = test;
/**
* Run all registered test case, producing a TAP stream.
*/
function run(statusCallback) {
return __awaiter(this, void 0, void 0, function* () {
console.log(`1..${tests.length}`);
for (let i in tests) {
let t = tests[i];
let passed = false;
let lastMsg = undefined;
let p = new Promise((resolve, reject) => {
let pass = (msg) => {
if (passed) {
let e = Error("test passed twice");
reject(e);
throw e;
}
passed = true;
lastMsg = msg;
resolve();
};
let fail = (msg) => {
lastMsg = msg;
let e = Error("test failed");
reject(e);
throw e;
};
let assert = (v, msg) => {
if (!v) {
lastMsg = msg;
reject(Error("test failed"));
return;
}
};
let assertEqualsStrict = (v1, v2, msg) => {
if (v1 !== v2) {
console.log(`# expected: ${v1}`);
console.log(`# actual: ${v2}`);
lastMsg = msg;
let e = Error("test failed");
reject(e);
throw e;
}
};
// Test might return a promise. If so, wait for it.
let r = t.testFn({ pass, fail, assert, assertEqualsStrict });
if (r) {
r.then(() => pass(), (e) => fail(e.toString()));
}
});
console.log(`# ${t.name}`);
statusCallback && statusCallback(`starting test ${t.name}`);
if (!lastMsg) {
lastMsg = "-";
}
try {
yield p;
if (!passed) {
throw Error("test did not call 'pass'");
}
console.log(`ok ${Number(i) + 1} ${lastMsg || "-"}`);
statusCallback && statusCallback(`finished test ${t.name}`);
}
catch (e) {
try {
console.error(e.stack);
}
catch (e2) {
console.error(e);
}
console.log(`not ok ${Number(i) + 1} ${lastMsg || "-"}`);
statusCallback && statusCallback(`failed test ${t.name}`);
}
}
});
}
exports.run = run;

View File

@ -1,122 +0,0 @@
/*
This file is part of TALER
(C) 2016 Inria
TALER 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, or (at your option) any later version.
TALER 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
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
*
* @author Florian Dold
*/
export type TestFn = (t: TestLib) => void | Promise<void>;
interface Test {
name: string;
testFn: TestFn;
}
export interface TestLib {
pass(msg?: string): void;
fail(msg?: string): void;
assert(v: any, msg?: string): void;
assertEqualsStrict(v1: any, v2: any, msg?: string): void;
}
let tests: Test[] = [];
let testRunner: any;
/**
* Register a test case.
*/
export function test(name: string, testFn: TestFn) {
tests.push({name, testFn});
}
/**
* Run all registered test case, producing a TAP stream.
*/
export async function run(statusCallback?: (m: string) => void) {
console.log(`1..${tests.length}`);
for (let i in tests) {
let t = tests[i];
let passed = false;
let lastMsg: string|undefined = undefined;
let p = new Promise((resolve, reject) => {
let pass = (msg?: string) => {
if (passed) {
let e = Error("test passed twice");
reject(e);
throw e;
}
passed = true;
lastMsg = msg;
resolve();
};
let fail = (msg?: string) => {
lastMsg = msg;
let e = Error("test failed");
reject(e);
throw e;
};
let assert = (v: any, msg?: string) => {
if (!v) {
lastMsg = msg;
reject(Error("test failed"));
return;
}
};
let assertEqualsStrict = (v1: any, v2: any, msg?: string) => {
if (v1 !== v2) {
console.log(`# expected: ${v1}`);
console.log(`# actual: ${v2}`);
lastMsg = msg;
let e = Error("test failed");
reject(e);
throw e;
}
};
// Test might return a promise. If so, wait for it.
let r = t.testFn({pass,fail, assert, assertEqualsStrict});
if (r) {
r.then(() => pass(), (e) => fail(e.toString()));
}
});
console.log(`# ${t.name}`);
statusCallback && statusCallback(`starting test ${t.name}`);
if (!lastMsg) {
lastMsg = "-";
}
try {
await p;
if (!passed) {
throw Error("test did not call 'pass'");
}
console.log(`ok ${Number(i) + 1} ${lastMsg || "-"}`);
statusCallback && statusCallback(`finished test ${t.name}`);
} catch (e) {
try {
console.error(e.stack);
} catch (e2) {
console.error(e);
}
console.log(`not ok ${Number(i) + 1} ${lastMsg || "-"}`);
statusCallback && statusCallback(`failed test ${t.name}`);
}
}
}

View File

@ -1,19 +0,0 @@
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"lib": [
"ES6",
"DOM"
],
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"strictNullChecks": true,
"noImplicitAny": true,
"declaration": true,
"alwaysStrict": true
},
"files": [
"talertest.ts"
]
}

View File

@ -1,7 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
typescript@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.2.2.tgz#606022508479b55ffa368b58fee963a03dfd7b0c"