From 82333c2ddcaf6b6c6c6ca637e1e58e5676fb422e Mon Sep 17 00:00:00 2001 From: Stephan February Date: Mon, 21 Aug 2023 12:30:33 +0800 Subject: [PATCH] Refactoring tests for clarity --- test/script/interpreter_test.dart | 193 +++++++++++++------------ test/script/script_builder_test.dart | 1 - test/transaction/transaction_test.dart | 83 +++++------ 3 files changed, 141 insertions(+), 136 deletions(-) diff --git a/test/script/interpreter_test.dart b/test/script/interpreter_test.dart index 9407044..9e40d07 100644 --- a/test/script/interpreter_test.dart +++ b/test/script/interpreter_test.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'dart:typed_data'; import 'package:buffer/buffer.dart'; +import 'package:collection/collection.dart'; import 'package:dartsv/dartsv.dart'; import 'package:dartsv/src/encoding/utils.dart'; import 'package:dartsv/src/script/interpreter.dart'; @@ -209,54 +210,52 @@ void main() { }; - runScripTestFixtures(File fixtureFile) async { + runScripTestFixtures(testData) { + var testName = ""; + List.from(jsonDecode(testData)).forEachIndexed((index, vect) { + if (vect.length == 1) { + testName = vect[0]; + } else { - await fixtureFile - .readAsString() - .then((contents) => jsonDecode(contents)) - .then((jsonData) { - List.from(jsonData).forEach((vect) { - if (vect.length == 1) { - return; + if (vect.length == 5){ + testName = vect[4]; + }else{ + testName = "vector #${index}"; } - var extraData; - if (vect[0] is List) { + test("${testName}",() { + var extraData; + if (vect[0] is List) { extraData = (vect as List).removeAt(0); - } + } - String fullScriptString = "${vect[0]} ${vect[1]}"; - bool expected = vect[3] == 'OK'; - String comment = ""; - if (vect.length > 4) { + String fullScriptString = "${vect[0]} ${vect[1]}"; + bool expected = vect[3] == 'OK'; + String comment = ""; + if (vect.length > 4) { comment = vect[4]; - } + } - var txt = "should ${vect[3]} script_tests vector : ${fullScriptString}${comment}"; - print(txt); + var txt = "should ${vect[3]} script_tests vector : ${fullScriptString}${comment}"; + print(txt); - testFixture(vect, expected, extraData); - }); + testFixture(vect, expected, extraData); + }); + } }); } - test('bitcoin SV Node Test vectors', () async { - await runScripTestFixtures(File("${Directory.current.path}/test/data/bitcoind/script_tests_svnode.json")); - }); - dataDrivenValidTransactions(File testFixtures) async { + dataDrivenValidTransactions(testData){ var testName = ""; - await testFixtures - .readAsString() - .then((contents) => jsonDecode(contents)) - .then((jsonData) { - List.from(jsonData).forEach((vect) { + List.from(jsonDecode(testData)).forEach((vect){ - if (vect.length == 1) { - testName = vect[0]; - print("Testing : ${testName}"); - } + if(vect.length == 1){ + testName = vect[0]; + } + + if (vect.length > 1) { + test("$testName", (){ - if (vect.length > 1) { Transaction spendingTx; try { @@ -283,7 +282,7 @@ void main() { input.prevTxnOutputIndex = -1; } - print("Spending INPUT : [${i}]"); + // print("Spending INPUT : [${i}]"); //reconstruct the key into our Map of Public Keys using the details from //the parsed transaction @@ -307,94 +306,106 @@ void main() { throw e; } - } - }); + + }); + } }); } - dataDrivenInValidTransactions(File testFixtures) async { + dataDrivenInValidTransactions(testData) async { + var testName = ""; - await testFixtures.readAsString().then((contents) => jsonDecode(contents)).then((jsonData) { - List.from(jsonData).forEach((vect) { + List.from(jsonDecode(testData)).forEach((vect){ + if (vect.length == 1) { testName = vect[0]; print("Testing : ${testName}"); } if (vect.length > 1) { - Transaction spendingTx; - bool valid = true; - try { - var inputs = vect[0]; - var map = {}; - inputs.forEach((input) { - var txid = input[0]; - var txoutnum = input[1]; - var scriptPubKeyStr = input[2]; - map[txid + ':' + txoutnum.toString()] = parseScriptString(scriptPubKeyStr); - }); + test("$testName", () + { + Transaction spendingTx; + bool valid = true; - spendingTx = Transaction.fromHex(vect[1]); - spendingTx.version = 1; try { - spendingTx.verify(); - } on Exception catch (ex) { - valid = false; - } + var inputs = vect[0]; + var map = {}; + inputs.forEach((input) { + var txid = input[0]; + var txoutnum = input[1]; + var scriptPubKeyStr = input[2]; + map[txid + ':' + txoutnum.toString()] = parseScriptString(scriptPubKeyStr); + }); + + spendingTx = Transaction.fromHex(vect[1]); + spendingTx.version = 1; + try { + spendingTx.verify(); + } on Exception catch (ex) { + valid = false; + } - ///all this ceremony to extract Verify Flags - var verifyFlags = parseVerifyFlags(vect[2]); + ///all this ceremony to extract Verify Flags + var verifyFlags = parseVerifyFlags(vect[2]); - for (int i = 0; i < spendingTx.inputs.length; i++) { - TransactionInput input = spendingTx.inputs[i]; - if (input.prevTxnOutputIndex == 0xffffffff) { - input.prevTxnOutputIndex = -1; - } + for (int i = 0; i < spendingTx.inputs.length; i++) { + TransactionInput input = spendingTx.inputs[i]; + if (input.prevTxnOutputIndex == 0xffffffff) { + input.prevTxnOutputIndex = -1; + } - print("Spending INPUT : [${i}]"); + print("Spending INPUT : [${i}]"); - //reconstruct the key into our Map of Public Keys using the details from - //the parsed transaction - // String txId = HEX.encode(input.prevTxnId); - String keyName = "${input.prevTxnId}:${input.prevTxnOutputIndex}"; + //reconstruct the key into our Map of Public Keys using the details from + //the parsed transaction + // String txId = HEX.encode(input.prevTxnId); + String keyName = "${input.prevTxnId}:${input.prevTxnOutputIndex}"; - //assert that our parsed transaction has correctly extracted the provided - //UTXO details - // expect(scriptPubKeys.containsKey(keyName), true); - var interp = Interpreter(); - interp.correctlySpends(input.script!, map[keyName], spendingTx, i, verifyFlags, Coin.ZERO); + //assert that our parsed transaction has correctly extracted the provided + //UTXO details + // expect(scriptPubKeys.containsKey(keyName), true); + var interp = Interpreter(); + interp.correctlySpends(input.script!, map[keyName], spendingTx, i, verifyFlags, Coin.ZERO); - //TODO: Would be better to assert expectation that no exception is thrown ? - //Ans: The whole of the Script Interpreter uses Exception-Handling for error-handling. So no, - // not without a deep refactor of the code. + //TODO: Would be better to assert expectation that no exception is thrown ? + //Ans: The whole of the Script Interpreter uses Exception-Handling for error-handling. So no, + // not without a deep refactor of the code. + } + } on Exception catch (e) { + valid = false; } - } on Exception catch (e) { - valid = false; - } - if (valid) fail(testName); + if (valid) fail(testName); + }); } }); - }); } - - test('bitcoin SV Node valid transaction evaluation fixtures', () async { - await dataDrivenValidTransactions(File("${Directory.current.path}/test/data/bitcoind/tx_valid_svnode.json")); + group('bitcoin SV Node Test vectors', () { + var testData = File("${Directory.current.path}/test/data/bitcoind/script_tests_svnode.json").readAsStringSync(); + runScripTestFixtures(testData); }); + group('bitcoin SV Node valid transaction evaluation fixtures', () { + var testData = File("${Directory.current.path}/test/data/bitcoind/tx_valid_svnode.json").readAsStringSync(); + dataDrivenValidTransactions(testData); + }); - test('bitcoin SV Node invalid transaction evaluation fixtures', () async { - await dataDrivenInValidTransactions(File("${Directory.current.path}/test/data/bitcoind/tx_invalid_svnode.json")); + group('bitcoin SV Node invalid transaction evaluation fixtures', () { + var testData = File("${Directory.current.path}/test/data/bitcoind/tx_invalid_svnode.json").readAsStringSync(); + dataDrivenInValidTransactions(testData); }); - test('bitcoind valid transaction evaluation fixtures', () async { - await dataDrivenValidTransactions(File("${Directory.current.path}/test/data/bitcoind/tx_valid.json")); + group('bitcoind valid transaction evaluation fixtures', () { + var testData = File("${Directory.current.path}/test/data/bitcoind/tx_valid.json").readAsStringSync(); + dataDrivenValidTransactions(testData); }); - test('bitcoind invalid transaction evaluation fixtures', () async { - await dataDrivenInValidTransactions(File("${Directory.current.path}/test/data/bitcoind/tx_invalid.json")); + group('bitcoind invalid transaction evaluation fixtures', () { + var testData = File("${Directory.current.path}/test/data/bitcoind/tx_invalid.json").readAsStringSync(); + dataDrivenInValidTransactions(testData); }); diff --git a/test/script/script_builder_test.dart b/test/script/script_builder_test.dart index a96527e..98dfc38 100644 --- a/test/script/script_builder_test.dart +++ b/test/script/script_builder_test.dart @@ -1,4 +1,3 @@ -import 'dart:ffi'; import 'dart:typed_data'; import 'package:dartsv/dartsv.dart'; diff --git a/test/transaction/transaction_test.dart b/test/transaction/transaction_test.dart index 1fad161..b5b3b0f 100644 --- a/test/transaction/transaction_test.dart +++ b/test/transaction/transaction_test.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; +import 'package:collection/collection.dart'; import 'package:dartsv/dartsv.dart'; import 'package:test/test.dart'; @@ -220,13 +221,11 @@ main() { expect(transaction.serialize(), equals(tx1hex)); }); + group('transaction creation/serialization test vectors ', () { + var bipFileContents = File("${Directory.current.path}/test/data/tx_creation.json").readAsStringSync(); + List.from(jsonDecode(bipFileContents)).forEachIndexed((index, item) { - test('transaction creation/serialization test vectors', () async { - await File("${Directory.current.path}/test/data/tx_creation.json") - .readAsString() - .then((contents) => jsonDecode(contents)) - .then((jsonData) { - List.from(jsonData).forEach((item) { + test("Txn Vector #${index}", (){ var privKey = SVPrivateKey.fromWIF(item['sign'][0]); Map utxoMap = item['from'][0][0]; @@ -247,6 +246,7 @@ main() { signer.sign(transaction, TransactionOutput(satoshis, scriptPubKey), 0); expect(transaction.serialize(), equals(item['serialize'])); }); + }); }); @@ -691,52 +691,47 @@ main() { return sorted.map((value) => original.indexOf(value)).toList(); }; - test('input sorting ', () async { - await File("${Directory.current.path}/test/data/bip69.json") - .readAsString() - .then((contents) => jsonDecode(contents)) - .then((jsonData) { - HashMap.from(jsonData)["inputs"].forEach((vector) { - var inputSet = vector["inputs"]; - var tx = new Transaction(); - var txInputs = inputSet.map((input) { - return TransactionInput( + var bipFileContents = File("${Directory.current.path}/test/data/bip69.json").readAsStringSync(); + HashMap.from(jsonDecode(bipFileContents)) + .forEach((key, value) { + if (key == "outputs") { + value.forEach((outputSet) =>{ + test("Input - ${outputSet['description']}", (){ + var tx = new Transaction(); + + var txOutputs = outputSet["outputs"].map((output) { + var txOut = TransactionOutput(BigInt.from(output["value"]), P2PKHDataLockBuilder.fromAddress(fromAddress, utf8.encode(output["script"])).getScriptPubkey()); + return txOut; + }).toList(); + + List outputs = List.from(txOutputs); + tx.outputs.addAll(outputs); + tx.sort(); + expect(getIndexOrder(outputs, tx.outputs), equals(outputSet["expected"])); + }) + }); + }else if(key == "inputs"){ + value.forEach((inputSet) => { + test("Output - ${inputSet['description']}", (){ + + var tx = new Transaction(); + var txInputs = inputSet["inputs"].map((input) { + return TransactionInput( input["txId"], input["vout"], TransactionInput.MAX_SEQ_NUMBER, scriptBuilder: DefaultUnlockBuilder.fromScript(SVScript())); - }).toList(); + }).toList(); - List inputs = List.from(txInputs); - tx.inputs.addAll(inputs); - tx.sort(); - expect(getIndexOrder(inputs, tx.inputs), equals(vector["expected"])); + List inputs = List.from(txInputs); + tx.inputs.addAll(inputs); + tx.sort(); + expect(getIndexOrder(inputs, tx.inputs), equals(inputSet["expected"])); + }) }); - }); + } }); - - test('output sorting ', () async { - await File("${Directory.current.path}/test/data/bip69.json") - .readAsString() - .then((contents) => jsonDecode(contents)) - .then((jsonData) { - HashMap.from(jsonData)["outputs"].forEach((vector) { - var outputSet = vector["outputs"]; - var tx = new Transaction(); - - var txOutputs = outputSet.map((output) { - var txOut = TransactionOutput(BigInt.from(output["value"]), P2PKHDataLockBuilder.fromAddress(fromAddress, utf8.encode(output["script"])).getScriptPubkey()); - return txOut; - }).toList(); - - List outputs = List.from(txOutputs); - tx.outputs.addAll(outputs); - tx.sort(); - expect(getIndexOrder(outputs, tx.outputs), equals(vector["expected"])); - }); - }); - }); });