diff --git a/.scrutinizer.yml b/.scrutinizer.yml index b87cad9b5..c7a5828ff 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -11,7 +11,7 @@ build: redis: false postgresql: false php: - version: 7.2 + version: 7.3 ini: 'zend.assertions': '1' 'assert.exception': '1' diff --git a/.travis.yml b/.travis.yml index d12523885..4a86c993f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,14 @@ language: php php: - - 7.0 - - 7.1 - - 7.2 - 7.3 + - 7.4 + - 8.0 env: - PHPUNIT=true PHPUNIT_EXT=true BITCOIN_VERSION="0.16.3" SECP256K1_COMMIT="cd329dbc3eaf096ae007e807b86b6f5947621ee3" -dist: trusty +dist: xenial sudo: required cache: @@ -19,14 +18,14 @@ cache: matrix: exclude: - - php: 7.2 + - php: 8.0 env: PHPUNIT=true PHPUNIT_EXT=true BITCOIN_VERSION="0.16.3" SECP256K1_COMMIT="cd329dbc3eaf096ae007e807b86b6f5947621ee3" include: # add extra test runs for php7: coverage, codestyle, examples, rpc tests - - php: 7.2 + - php: 8.0 env: COVERAGE=true CODE_STYLE=true EXAMPLES=true PHPUNIT=true PHPUNIT_EXT=true BITCOIN_VERSION="0.16.3" SECP256K1_COMMIT="cd329dbc3eaf096ae007e807b86b6f5947621ee3" - - php: 7.0 + - php: 7.3 env: RPC_TEST=true BITCOIN_VERSION="0.16.3" SECP256K1_COMMIT="cd329dbc3eaf096ae007e807b86b6f5947621ee3" install: diff --git a/composer.json b/composer.json index 41193ac70..c2c0960d8 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "php-64bit": ">=7.0", "pleonasm/merkle-tree": "1.0.0", "composer/semver": "^1.4.0|^3.2.0", - "lastguest/murmurhash": "v2.0.0", + "lastguest/murmurhash": "^2.0", "mdanter/ecc": "^0.5.0", "bitwasp/buffertools": "^0.5.0", "bitwasp/bech32": "^0.0.1" @@ -37,7 +37,7 @@ }, "require-dev": { "ext-json": "*", - "phpunit/phpunit": "^5.4.0", + "phpunit/phpunit": "^9.0", "squizlabs/php_codesniffer": "^2.0.0", "nbobtc/bitcoind-php": "v2.0.2", "bitwasp/secp256k1-php": "^v0.2.0", diff --git a/phpunit.xml b/phpunit.xml index 8583b2553..2de98f9ed 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -8,11 +8,4 @@ - - - src - src/PaymentProtocol/Protobufs - - - diff --git a/src/Bloom/BloomFilter.php b/src/Bloom/BloomFilter.php index 9c650e675..86c8b3b88 100644 --- a/src/Bloom/BloomFilter.php +++ b/src/Bloom/BloomFilter.php @@ -62,11 +62,11 @@ class BloomFilter extends Serializable private $flags; /** - * @param Math $math + * @param Math $math * @param array $vFilter - * @param int $numHashFuncs - * @param int $nTweak - * @param int $flags + * @param int $numHashFuncs + * @param int $nTweak + * @param int $flags */ public function __construct(Math $math, array $vFilter, int $numHashFuncs, int $nTweak, int $flags) { @@ -91,11 +91,11 @@ public static function emptyFilter(int $size): array * Create the Bloom Filter given the number of elements, a false positive rate, * and the flags governing how the filter should be updated. * - * @param Math $math - * @param int $nElements - * @param float $nFpRate - * @param int $nTweak - * @param int $flags + * @param Math $math + * @param int $nElements + * @param float $nFpRate + * @param int $nTweak + * @param int $flags * @return BloomFilter */ public static function create(Math $math, int $nElements, float $nFpRate, int $nTweak, int $flags): BloomFilter @@ -184,33 +184,15 @@ public function getFlags(): int } /** - * @param int $nElements + * @param int $nElements * @param float $fpRate * @return int */ public static function idealSize(int $nElements, float $fpRate): int { - return (int) floor( - bcdiv( - min( - bcmul( - bcmul( - bcdiv( - '-1', - (string) self::LN2SQUARED - ), - (string) $nElements - ), - (string) log($fpRate) - ), - bcmul( - (string) self::MAX_FILTER_SIZE, - '8' - ) - ), - '8' - ) - ); + $a = (-1/self::LN2SQUARED)*$nElements*log($fpRate); + $b = self::MAX_FILTER_SIZE*8; + return (int) floor(min($a, $b) / 8); } /** @@ -220,28 +202,13 @@ public static function idealSize(int $nElements, float $fpRate): int */ public static function idealNumHashFuncs(int $filterSize, int $nElements) { - return (int) floor( - min( - bcmul( - bcdiv( - bcmul( - (string) $filterSize, - '8' - ), - (string) $nElements - ), - (string) self::LN2 - ), - bcmul( - (string) self::MAX_FILTER_SIZE, - '8' - ) - ) - ); + $a = (($filterSize*8)/$nElements)*self::LN2; + $b = self::MAX_FILTER_SIZE * 8; + return (int) floor(min($a, $b)); } /** - * @param int $nHashNum + * @param int $nHashNum * @param BufferInterface $data * @return string */ diff --git a/src/Locktime.php b/src/Locktime.php index eefef3cfc..17c888ab8 100644 --- a/src/Locktime.php +++ b/src/Locktime.php @@ -12,7 +12,7 @@ class Locktime * Maximum block height that can be used in locktime, as beyond * this is reserved for timestamp locktimes */ - const BLOCK_MAX = 500000000; + const BLOCK_MAX = 500000000-1; /** * Maximum timestamp that can be encoded in locktime @@ -98,8 +98,8 @@ public function fromBlockHeight(int $blockHeight): int */ public function toBlockHeight(int $lockTime): int { - if ($lockTime >= self::BLOCK_MAX) { - throw new \Exception('This locktime is out of range for a block height'); + if ($lockTime > self::BLOCK_MAX) { + throw new \Exception("This locktime is out of range for a block height"); } return $lockTime; diff --git a/src/Mnemonic/Bip39/Wordlist/JapaneseWordList.php b/src/Mnemonic/Bip39/Wordlist/JapaneseWordList.php index 829983b86..0aa504d0b 100644 --- a/src/Mnemonic/Bip39/Wordlist/JapaneseWordList.php +++ b/src/Mnemonic/Bip39/Wordlist/JapaneseWordList.php @@ -42,7 +42,7 @@ public function getIndex(string $word): int } if (!isset($this->wordsFlipped[$word])) { - throw new \InvalidArgumentException(__CLASS__ . ' does not contain word ' . $word); + throw new \InvalidArgumentException('Wordlist does not contain word ' . $word); } return $this->wordsFlipped[$word]; diff --git a/src/Mnemonic/WordList.php b/src/Mnemonic/WordList.php index 670492445..3e0603922 100644 --- a/src/Mnemonic/WordList.php +++ b/src/Mnemonic/WordList.php @@ -14,7 +14,7 @@ public function getWord(int $index): string { $words = $this->getWords(); if (!isset($words[$index])) { - throw new \InvalidArgumentException(__CLASS__ . " does not contain a word for index [{$index}]"); + throw new \InvalidArgumentException("Wordlist does not contain a word for index [{$index}]"); } return $words[$index]; diff --git a/src/Script/Script.php b/src/Script/Script.php index eff156db6..3763f3bb7 100644 --- a/src/Script/Script.php +++ b/src/Script/Script.php @@ -288,10 +288,24 @@ public function isWitness(& $program = null): bool */ public function isP2SH(& $scriptHash): bool { + // +// if (strlen($this->script) == 23) { +// var_dump("{$this->script[0]} | ".ord($this->script[0])." ".Opcodes::OP_HASH160); +// var_dump(ord($this->script[0]) == Opcodes::OP_HASH160); +// var_dump("{$this->script[1]} | ".ord($this->script[1])." 20"); +// var_dump(ord($this->script[1]) == 20); +// var_dump("{$this->script[22]} | ".ord($this->script[22])." ".Opcodes::OP_EQUAL); +// var_dump(ord($this->script[22]) == Opcodes::OP_EQUAL); +// } +// echo "isP2SH?\n"; +// echo "script: ".bin2hex($this->script).PHP_EOL; if (strlen($this->script) === 23 - && $this->script[0] = Opcodes::OP_HASH160 - && $this->script[1] = 20 - && $this->script[22] = Opcodes::OP_EQUAL + && ord($this->script[0]) == Opcodes::OP_HASH160 + && ord($this->script[1]) == 20 + && ord($this->script[22]) == Opcodes::OP_EQUAL +// && $this->script[0] == Opcodes::OP_HASH160 +// && $this->script[1] == 20 +// && $this->script[22] == Opcodes::OP_EQUAL ) { $scriptHash = new Buffer(substr($this->script, 2, 20)); return true; diff --git a/src/Transaction/Mutator/AbstractCollectionMutator.php b/src/Transaction/Mutator/AbstractCollectionMutator.php index 222e69d03..6b5b6f070 100644 --- a/src/Transaction/Mutator/AbstractCollectionMutator.php +++ b/src/Transaction/Mutator/AbstractCollectionMutator.php @@ -7,16 +7,18 @@ abstract class AbstractCollectionMutator implements \Iterator, \ArrayAccess, \Countable { /** - * @var \SplFixedArray + * @var array */ - protected $set; + protected $set = []; + + private $position = 0; /** * @return array */ public function all(): array { - return $this->set->toArray(); + return $this->set; } /** @@ -32,15 +34,12 @@ public function isNull(): bool */ public function count(): int { - return $this->set->count(); + return count($this->set); } - /** - * - */ - public function rewind() + public function rewind(): void { - $this->set->rewind(); + $this->position = 0; } /** @@ -48,40 +47,31 @@ public function rewind() */ public function current() { - return $this->set->current(); + return $this->set[$this->position]; } - /** - * @return int - */ - public function key() + public function key(): int { - return $this->set->key(); + return $this->position; } - /** - * - */ - public function next() + public function next(): void { - $this->set->next(); + ++$this->position; } - /** - * @return bool - */ - public function valid() + public function valid(): bool { - return $this->set->valid(); + return array_key_exists($this->position, $this->set); } /** * @param int $offset * @return bool */ - public function offsetExists($offset) + public function offsetExists($offset): bool { - return $this->set->offsetExists($offset); + return array_key_exists($offset, $this->set); } /** @@ -93,7 +83,7 @@ public function offsetUnset($offset) throw new \InvalidArgumentException('Offset does not exist'); } - $this->set->offsetUnset($offset); + $this->set = array_slice($this->set, 0, $offset - 1) + array_slice($this->set, $offset + 1); } /** @@ -102,10 +92,10 @@ public function offsetUnset($offset) */ public function offsetGet($offset) { - if (!$this->set->offsetExists($offset)) { + if (!array_key_exists($offset, $this->set)) { throw new \OutOfRangeException('Nothing found at this offset'); } - return $this->set->offsetGet($offset); + return $this->set[$offset]; } /** @@ -114,6 +104,9 @@ public function offsetGet($offset) */ public function offsetSet($offset, $value) { - $this->set->offsetSet($offset, $value); + if ($offset > count($this->set)) { + throw new \InvalidArgumentException(); + } + $this->set[$offset] = $value; } } diff --git a/src/Transaction/Mutator/InputCollectionMutator.php b/src/Transaction/Mutator/InputCollectionMutator.php index 8832942d2..b65dcf5a5 100644 --- a/src/Transaction/Mutator/InputCollectionMutator.php +++ b/src/Transaction/Mutator/InputCollectionMutator.php @@ -8,7 +8,6 @@ class InputCollectionMutator extends AbstractCollectionMutator { - /** * @param TransactionInputInterface[] $inputs */ @@ -20,15 +19,12 @@ public function __construct(array $inputs) $set[$i] = new InputMutator($input); } - $this->set = \SplFixedArray::fromArray($set, false); + $this->set = $set; } - /** - * @return InputMutator - */ public function current(): InputMutator { - return $this->set->current(); + return parent::current(); } /** @@ -37,11 +33,7 @@ public function current(): InputMutator */ public function offsetGet($offset): InputMutator { - if (!$this->set->offsetExists($offset)) { - throw new \OutOfRangeException('Input does not exist'); - } - - return $this->set->offsetGet($offset); + return parent::offsetGet($offset); } /** @@ -58,39 +50,30 @@ public function done(): array } /** - * @param int $start - * @param int $length - * @return $this + * Return an array containing values beginning at index $start and ending + * with index $start + $length. An exception is thrown if start or $length + * is out of bounds */ - public function slice(int $start, int $length) + public function slice(int $start, int $length): InputCollectionMutator { - $end = $this->set->getSize(); + $end = $this->count(); if ($start > $end || $length > $end) { throw new \RuntimeException('Invalid start or length'); } - $this->set = \SplFixedArray::fromArray(array_slice($this->set->toArray(), $start, $length), false); + $this->set = array_slice($this->set, $start, $length); return $this; } - /** - * @return $this - */ - public function null() + public function null(): InputCollectionMutator { $this->slice(0, 0); return $this; } - /** - * @param TransactionInputInterface $input - * @return $this - */ - public function add(TransactionInputInterface $input) + public function add(TransactionInputInterface $input): InputCollectionMutator { - $size = $this->set->getSize(); - $this->set->setSize($size + 1); - + $size = $this->count(); $this->set[$size] = new InputMutator($input); return $this; } @@ -100,8 +83,11 @@ public function add(TransactionInputInterface $input) * @param TransactionInputInterface $input * @return $this */ - public function set(int $i, TransactionInputInterface $input) + public function set(int $i, TransactionInputInterface $input): InputCollectionMutator { + if ($i > count($this->set)) { + throw new \InvalidArgumentException(); + } $this->set[$i] = new InputMutator($input); return $this; } diff --git a/src/Transaction/Mutator/OutputCollectionMutator.php b/src/Transaction/Mutator/OutputCollectionMutator.php index 6ef51ad05..9f2b319f9 100644 --- a/src/Transaction/Mutator/OutputCollectionMutator.php +++ b/src/Transaction/Mutator/OutputCollectionMutator.php @@ -14,19 +14,18 @@ class OutputCollectionMutator extends AbstractCollectionMutator public function __construct(array $outputs) { /** @var OutputMutator[] $set */ - $this->set = new \SplFixedArray(count($outputs)); + $set = []; foreach ($outputs as $i => $output) { /** @var int $i */ - $this->set[$i] = new OutputMutator($output); + $set[$i] = new OutputMutator($output); } + + $this->set = $set; } - /** - * @return OutputMutator - */ public function current(): OutputMutator { - return $this->set->current(); + return parent::current(); } /** @@ -35,11 +34,7 @@ public function current(): OutputMutator */ public function offsetGet($offset): OutputMutator { - if (!$this->set->offsetExists($offset)) { - throw new \OutOfRangeException('Nothing found at this offset'); - } - - return $this->set->offsetGet($offset); + return parent::offsetGet($offset); } /** @@ -56,39 +51,30 @@ public function done(): array } /** - * @param int $start - * @param int $length - * @return $this + * Return an array containing values beginning at index $start and ending + * with index $start + $length. An exception is thrown if start or $length + * is out of bounds */ - public function slice(int $start, int $length) + public function slice(int $start, int $length): OutputCollectionMutator { $end = count($this->set); if ($start > $end || $length > $end) { throw new \RuntimeException('Invalid start or length'); } - $this->set = \SplFixedArray::fromArray(array_slice($this->set->toArray(), $start, $length), false); + $this->set = array_slice($this->set, $start, $length); return $this; } - /** - * @return $this - */ - public function null() + public function null(): OutputCollectionMutator { $this->slice(0, 0); return $this; } - /** - * @param TransactionOutputInterface $output - * @return $this - */ - public function add(TransactionOutputInterface $output) + public function add(TransactionOutputInterface $output): OutputCollectionMutator { - $size = $this->set->getSize(); - $this->set->setSize($size + 1); - + $size = $this->count(); $this->set[$size] = new OutputMutator($output); return $this; } @@ -98,8 +84,11 @@ public function add(TransactionOutputInterface $output) * @param TransactionOutputInterface $output * @return $this */ - public function set($i, TransactionOutputInterface $output) + public function set(int $i, TransactionOutputInterface $output): OutputCollectionMutator { + if ($i > count($this->set)) { + throw new \InvalidArgumentException(); + } $this->set[$i] = new OutputMutator($output); return $this; } diff --git a/src/Transaction/Mutator/WitnessCollectionMutator.php b/src/Transaction/Mutator/WitnessCollectionMutator.php deleted file mode 100644 index 4da336936..000000000 --- a/src/Transaction/Mutator/WitnessCollectionMutator.php +++ /dev/null @@ -1,108 +0,0 @@ - $input) { - $set[$i] = new InputMutator($input); - } - - $this->set = \SplFixedArray::fromArray($set, false); - } - - /** - * @return InputMutator - */ - public function current() - { - return $this->set->current(); - } - - /** - * @param int $offset - * @return InputMutator - */ - public function offsetGet($offset): InputMutator - { - if (!$this->set->offsetExists($offset)) { - throw new \OutOfRangeException('Input does not exist'); - } - - return $this->set->offsetGet($offset); - } - - /** - * @return ScriptWitnessInterface[] - */ - public function done(): array - { - $set = []; - foreach ($this->set as $mutator) { - $set[] = $mutator->done(); - } - - return $set; - } - - /** - * @param int $start - * @param int $length - * @return $this - */ - public function slice(int $start, int $length) - { - $end = $this->set->getSize(); - if ($start > $end || $length > $end) { - throw new \RuntimeException('Invalid start or length'); - } - - $this->set = \SplFixedArray::fromArray(array_slice($this->set->toArray(), $start, $length), false); - return $this; - } - - /** - * @return $this - */ - public function null() - { - $this->slice(0, 0); - return $this; - } - - /** - * @param ScriptWitnessInterface $witness - * @return $this - */ - public function add(ScriptWitnessInterface $witness) - { - $size = $this->set->getSize(); - $this->set->setSize($size + 1); - - $this->set[$size] = new InputMutator($witness); - return $this; - } - - /** - * @param int $i - * @param ScriptWitnessInterface $input - * @return $this - */ - public function set(int $i, ScriptWitnessInterface $input) - { - $this->set[$i] = new InputMutator($input); - return $this; - } -} diff --git a/tests-rpc/RbfTransactionTest.php b/tests-rpc/RbfTransactionTest.php index ad594a75c..305f9177b 100644 --- a/tests-rpc/RbfTransactionTest.php +++ b/tests-rpc/RbfTransactionTest.php @@ -35,7 +35,7 @@ public function __construct($name = null, array $data = [], $dataName = '') private function assertSendRawTransaction($result) { - $this->assertInternalType('array', $result); + $this->assertIsArray($result); $this->assertArrayHasKey('error', $result); $this->assertEquals(null, $result['error']); @@ -45,9 +45,9 @@ private function assertSendRawTransaction($result) private function assertBitcoindError($errorCode, $result) { - $this->assertInternalType('array', $result); + $this->assertIsArray($result); $this->assertArrayHasKey('error', $result); - $this->assertInternalType('array', $result['error']); + $this->assertIsArray($result['error']); $this->assertEquals($errorCode, $result['error']['code']); $this->assertArrayHasKey('error', $result); diff --git a/tests-rpc/ServerTest.php b/tests-rpc/ServerTest.php index bd158db03..32c93fa11 100644 --- a/tests-rpc/ServerTest.php +++ b/tests-rpc/ServerTest.php @@ -30,7 +30,7 @@ public function testIfRegtest() $server = $this->rpcFactory->startBitcoind(); $result = $server->makeRpcRequest("getblockchaininfo"); - $this->assertInternalType('array', $result); + $this->assertIsArray($result); $this->assertArrayHasKey('result', $result); $this->assertArrayHasKey('chain', $result['result']); $this->assertEquals('regtest', $result['result']['chain']); @@ -44,12 +44,12 @@ public function testStartStop() // First bitcoind, generate block $result = $bitcoind->request("generate", [1]); - $this->assertInternalType("array", $result['result']); + $this->assertIsArray($result['result']); $this->assertEquals(64, strlen($result['result'][0])); // First bitcoind, get block height - 1 $info = $bitcoind->request("getblockchaininfo"); - $this->assertInternalType("array", $info['result']); + $this->assertIsArray($info['result']); $this->assertEquals(1, $info['result']['blocks']); // Destroy that instance @@ -60,7 +60,7 @@ public function testStartStop() $bitcoind = $this->rpcFactory->startBitcoind(); $info = $bitcoind->request("getblockchaininfo"); - $this->assertInternalType("array", $info['result']); + $this->assertIsArray($info['result']); $this->assertEquals(0, $info['result']['blocks']); $bitcoind->destroy(); diff --git a/tests/Address/AddressTest.php b/tests/Address/AddressTest.php index c88e6d973..2768e6390 100644 --- a/tests/Address/AddressTest.php +++ b/tests/Address/AddressTest.php @@ -178,14 +178,12 @@ public function testFromOutputScriptSuccess() $this->assertInstanceOf(ScriptHashAddress::class, $scriptAddress); } - /** - * @expectedException \RuntimeException - * @expectedExceptionMessage Script type is not associated with an address - */ public function testFromOutputScript() { $unknownScript = ScriptFactory::create()->opcode(Opcodes::OP_0, Opcodes::OP_1)->getScript(); $addressCreator = new AddressCreator(); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage("Script type is not associated with an address"); $addressCreator->fromOutputScript($unknownScript); } diff --git a/tests/AmountTest.php b/tests/AmountTest.php index 4b7c20f7a..92f3e15c9 100644 --- a/tests/AmountTest.php +++ b/tests/AmountTest.php @@ -12,11 +12,11 @@ public function getVectors() { return [ ['0.01000000', 1000000], - ['1', Amount::COIN], + ['1.00000000', Amount::COIN], ['1.12345678', 112345678], - ['21000000', 2100000000000000], - ['0', 0], - ['0.0', 0] + ['21000000.00000000', 2100000000000000], + ['0.00000000', 0], + ['0.00000000', 0] ]; } diff --git a/tests/Base58Test.php b/tests/Base58Test.php index ad887a0b1..9f8b5d854 100644 --- a/tests/Base58Test.php +++ b/tests/Base58Test.php @@ -5,6 +5,8 @@ namespace BitWasp\Bitcoin\Tests; use BitWasp\Bitcoin\Base58; +use BitWasp\Bitcoin\Exceptions\Base58ChecksumFailure; +use BitWasp\Bitcoin\Exceptions\Base58InvalidCharacter; use BitWasp\Buffertools\Buffer; class Base58Test extends AbstractTestCase @@ -64,28 +66,22 @@ public function testEncodeDecodeCheck(Buffer $bs, string $base58) $this->assertTrue($bs->equals(Base58::decodeCheck($encoded))); } - /** - * @expectedException \BitWasp\Bitcoin\Exceptions\Base58ChecksumFailure - */ public function testDecodeCheckChecksumFailure() { // Base58Check encoded data has a checksum at the end. // 12D2adLM3UKy4bH891ZFDkWmXmotrMoF <-- valid // 12D2adLM3UKy4cH891ZFDkWmXmotrMoF <-- has typo, b replaced with c. // ^ - + $this->expectException(Base58ChecksumFailure::class); Base58::decodeCheck('12D2adLM3UKy4cH891ZFDkWmXmotrMoF'); } - /** - * @expectedException \BitWasp\Bitcoin\Exceptions\Base58InvalidCharacter - */ public function testDecodeBadCharacter() { // 12D2adLM3UKy4bH891ZFDkWmXmotrMoF <-- valid // 12D2adLM3UKy4bH891ZFDkWmXmotrM0F <-- 0 is not allowed in base58 strings // ^ - + $this->expectException(Base58InvalidCharacter::class); Base58::decode('12D2adLM3UKy4cH891ZFDkWmXmotrM0F'); } } diff --git a/tests/Block/BlockHeaderTest.php b/tests/Block/BlockHeaderTest.php index 4695b2c5d..d703c1264 100644 --- a/tests/Block/BlockHeaderTest.php +++ b/tests/Block/BlockHeaderTest.php @@ -9,6 +9,7 @@ use BitWasp\Bitcoin\Exceptions\InvalidHashLengthException; use BitWasp\Bitcoin\Tests\AbstractTestCase; use BitWasp\Buffertools\Buffer; +use BitWasp\Buffertools\Exceptions\ParserOutOfRange; class BlockHeaderTest extends AbstractTestCase { @@ -57,7 +58,7 @@ public function testFromParser() $this->assertInstanceOf(Buffer::class, $result->getMerkleRoot()); $this->assertSame('4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b', $result->getMerkleRoot()->getHex()); - $this->assertInternalType('int', $result->getBits()); + $this->assertIsInt($result->getBits()); $this->assertEquals(0x1d00ffff, $result->getBits()); $this->assertEquals(1231006505, $result->getTimestamp()); @@ -77,13 +78,11 @@ public function testGetBlockHash() $this->assertSame('000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f', $result->getHash()->getHex()); } - /** - * @expectedException \BitWasp\Buffertools\Exceptions\ParserOutOfRange - * @expectedExceptionMessage Failed to extract full block header from parser - */ public function testFromParserFailure() { $genesisHeader = '0100000000000000000000003BA3EDFD7A7B12B27AC72C3E67768F617FC81BC3888A51323A9FB8AA4B1E5E4A29AB5F49FFFF001D1DAC2B7C'; + $this->expectException(ParserOutOfRange::class); + $this->expectExceptionMessage("Failed to extract full block header from parser"); BlockHeaderFactory::fromHex($genesisHeader); } diff --git a/tests/Block/BlockTest.php b/tests/Block/BlockTest.php index b4009814f..29b8f3bb5 100644 --- a/tests/Block/BlockTest.php +++ b/tests/Block/BlockTest.php @@ -40,7 +40,7 @@ public function testGetTransactions() $header = $this->getBlockHeader(); $block = new Block(new Math(), $header); - $this->assertInternalType('array', $block->getTransactions()); + $this->assertIsArray($block->getTransactions()); $this->assertEmpty($block->getTransactions()); } @@ -112,7 +112,7 @@ public function testFromParser() $this->assertInstanceOf(Block::class, $newBlock); - $this->assertInternalType('array', $newBlock->getTransactions()); + $this->assertIsArray($newBlock->getTransactions()); $this->assertEquals(1, count($newBlock->getTransactions())); $this->assertInstanceOf(TransactionInterface::class, $newBlock->getTransaction(0)); $this->assertEquals($newBlock->getHeader()->getMerkleRoot(), $newBlock->getMerkleRoot()); diff --git a/tests/Block/MerkleRootTest.php b/tests/Block/MerkleRootTest.php index 673127b48..84e6c53b6 100644 --- a/tests/Block/MerkleRootTest.php +++ b/tests/Block/MerkleRootTest.php @@ -5,6 +5,7 @@ namespace BitWasp\Bitcoin\Tests\Block; use BitWasp\Bitcoin\Block\MerkleRoot; +use BitWasp\Bitcoin\Exceptions\MerkleTreeEmpty; use BitWasp\Bitcoin\Math\Math; use BitWasp\Bitcoin\Tests\AbstractTestCase; use BitWasp\Bitcoin\Transaction\TransactionFactory; @@ -13,35 +14,27 @@ class MerkleRootTest extends AbstractTestCase { - - /** - * @expectedException \BitWasp\Bitcoin\Exceptions\MerkleTreeEmpty - */ public function testCannotUseEmptyCollection() { $math = $this->safeMath(); $root = new MerkleRoot($math, []); + $this->expectException(MerkleTreeEmpty::class); $root->calculateHash(); } /** - * @param array $hexes + * @param string[] $hexes * @return array */ - private function getTransactionCollection(array $hexes) + private function getTransactionCollection(array $hexes): array { return array_map( - function ($value) { - return TransactionFactory::fromHex($value); - }, + [TransactionFactory::class, 'fromHex'], $hexes ); } - /** - * @return array - */ - public function getMerkleVectors() + public function getMerkleVectors(): array { $math = new Math(); $vectors = []; diff --git a/tests/Bloom/BloomFilterTest.php b/tests/Bloom/BloomFilterTest.php index 001f27ccc..9e2f58f11 100644 --- a/tests/Bloom/BloomFilterTest.php +++ b/tests/Bloom/BloomFilterTest.php @@ -25,7 +25,7 @@ class BloomFilterTest extends AbstractTestCase */ private $pubKeyFactory; - public function setUp() + public function setUp(): void { $this->pubKeyFactory = new PublicKeyFactory(); parent::setUp(); diff --git a/tests/Chain/ProofOfWorkTest.php b/tests/Chain/ProofOfWorkTest.php index 3bd89491f..886312ddb 100644 --- a/tests/Chain/ProofOfWorkTest.php +++ b/tests/Chain/ProofOfWorkTest.php @@ -33,8 +33,7 @@ public function getHistoricData() } /** - * @expectedException \RuntimeException - * @expectedExceptionMessage nBits below minimum work + */ public function testWhereBitsBelowMinimum() { @@ -42,6 +41,8 @@ public function testWhereBitsBelowMinimum() $params = new Params($math); $pow = new ProofOfWork(new Math(), $params); $bits = 1; + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage("nBits below minimum work"); $pow->checkPow(Buffer::hex('00000000a3bbe4fd1da16a29dbdaba01cc35d6fc74ee17f794cf3aab94f7aaa0'), $bits); } diff --git a/tests/Collection/StaticCollectionImplTest.php b/tests/Collection/StaticCollectionImplTest.php index 103a03958..518c52b7d 100644 --- a/tests/Collection/StaticCollectionImplTest.php +++ b/tests/Collection/StaticCollectionImplTest.php @@ -17,12 +17,10 @@ public function testArrayAccessOffStaticBufferCollectionGet() $this->assertEquals(new Buffer("\x01"), $collection->offsetGet(0)); } - /** - * @expectedException \OutOfRangeException - */ public function testArrayAccessOffStaticBufferCollectionGetFailure() { $collection = new StaticBufferCollection(new Buffer("\x01")); + $this->expectException(\OutOfRangeException::class); $collection[20]; } @@ -51,12 +49,10 @@ public function testGet() $this->assertEquals(new Buffer("\x01"), $StaticBufferCollection[0]); } - /** - * @expectedException \OutOfRangeException - */ public function testGetInvalid() { $StaticBufferCollection = new StaticBufferCollection(); + $this->expectException(\OutOfRangeException::class); $StaticBufferCollection[0]; } } diff --git a/tests/Crypto/EcAdapter/EcTest.php b/tests/Crypto/EcAdapter/EcTest.php index a2c2e60d9..92b73b41b 100644 --- a/tests/Crypto/EcAdapter/EcTest.php +++ b/tests/Crypto/EcAdapter/EcTest.php @@ -50,10 +50,6 @@ public function mulModN(PrivateKeyInterface $private, \GMP $add, EcAdapterInterf return $math->mod($math->mul($key, $add), $ec->getOrder()); } - /** - * @expectedException \Exception - * @expectedExceptionMessage Failed to find valid recovery factor - */ public function testCalcPubkeyRecidFail() { $math = new Math(); @@ -61,6 +57,8 @@ public function testCalcPubkeyRecidFail() $phpecc = new PhpEcc($math, $g); $private = $this->getFirstPrivateKey($phpecc); + $this->expectException(\Exception::class); + $this->expectExceptionMessage("Failed to find valid recovery factor"); $phpecc->calcPubKeyRecoveryParam(gmp_init(1), gmp_init(1), Buffer::hex('4141414141414141414141414141414141414141414141414141414141414141'), $private->getPublicKey()); } diff --git a/tests/Crypto/HashTest.php b/tests/Crypto/HashTest.php index 7afb3d516..facf36c07 100644 --- a/tests/Crypto/HashTest.php +++ b/tests/Crypto/HashTest.php @@ -51,21 +51,17 @@ public function testPBKDF2() } } - /** - * @expectedException \Exception - * @expectedExceptionMessage PBKDF2 ERROR: Invalid hash algorithm - */ public function testPbkdf2FailsInvalidAlgorithm() { + $this->expectExceptionMessage(\Exception::class); + $this->expectExceptionMessage("PBKDF2 ERROR: Invalid hash algorithm"); Hash::pbkdf2('test', new Buffer('password'), new Buffer('salt'), 100, 128); } - /** - * @expectedException \Exception - * @expectedExceptionMessage PBKDF2 ERROR: Invalid parameters - */ public function testPbkdf2FailsInvalidCount() { + $this->expectExceptionMessage(\Exception::class); + $this->expectExceptionMessage("PBKDF2 ERROR: Invalid parameters"); Hash::pbkdf2('sha512', new Buffer('password'), new Buffer('salt'), 0, 128); } diff --git a/tests/Data/branch_test.json b/tests/Data/branch_test.json index 67ab52472..6e632bf60 100644 --- a/tests/Data/branch_test.json +++ b/tests/Data/branch_test.json @@ -71,7 +71,7 @@ [ false ], - "IF ELSE DUP HASH160 0x14 0x376eb254c19e918752f00420da03a45ff6c9c7f6 ENDIF EQUALVERIFY CHECKSIG ", + "IF ELSE DUP HASH160 0x14 0x376eb254c19e918752f00420da03a45ff6c9c7f6 ENDIF EQUALVERIFY CHECKSIG", "DUP HASH160 0x14 0x376eb254c19e918752f00420da03a45ff6c9c7f6 EQUALVERIFY CHECKSIG" ] ] diff --git a/tests/Data/difficulty.json b/tests/Data/difficulty.json index 9ee60cf14..8776dcf81 100644 --- a/tests/Data/difficulty.json +++ b/tests/Data/difficulty.json @@ -4,7 +4,7 @@ "bits": "1d00ffff", "defaultBits": "1d00ffff", "targetHash": "00000000ffff0000000000000000000000000000000000000000000000000000", - "difficulty": "1" + "difficulty": "1.000000000000" }, { "bits": "1b0404cb", diff --git a/tests/Key/Deterministic/ElectrumKeyTest.php b/tests/Key/Deterministic/ElectrumKeyTest.php index fec3c55fc..567851711 100644 --- a/tests/Key/Deterministic/ElectrumKeyTest.php +++ b/tests/Key/Deterministic/ElectrumKeyTest.php @@ -81,10 +81,6 @@ public function testCKD(EcAdapterInterface $ecAdapter, $mnemonic, $eSecExp, $eMP } } - /** - * @expectedException \RuntimeException - * @expectedExceptionMessage Electrum keys are not compressed - */ public function testFromKey() { $random = new Random(); @@ -96,6 +92,8 @@ public function testFromKey() $this->assertInstanceOf(ElectrumKey::class, $e); $key = $privKeyFactory->generateCompressed($random); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage("Electrum keys are not compressed"); $electrumFactory->fromKey($key); } @@ -108,16 +106,14 @@ public function testGenerate() $this->assertInstanceOf(ElectrumKey::class, $key); } - /** - * @expectedException \RuntimeException - * @expectedExceptionMessage Cannot produce master private key from master public key - */ public function testFailsWithoutMasterPrivateKey() { $pubKeyFactory = new PublicKeyFactory(); $key = $pubKeyFactory->fromHex('045b81f0017e2091e2edcd5eecf10d5bdd120a5514cb3ee65b8447ec18bfc4575c6d5bf415e54e03b1067934a0f0ba76b01c6b9ab227142ee1d543764b69d901e0'); $electrumFactory = new ElectrumKeyFactory(); $e = $electrumFactory->fromKey($key); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage("Cannot produce master private key from master public key"); $e->getMasterPrivateKey(); } } diff --git a/tests/Key/Deterministic/HierarchicalKeySequenceTest.php b/tests/Key/Deterministic/HierarchicalKeySequenceTest.php index cf6663fe3..544cae33c 100644 --- a/tests/Key/Deterministic/HierarchicalKeySequenceTest.php +++ b/tests/Key/Deterministic/HierarchicalKeySequenceTest.php @@ -9,7 +9,7 @@ class HierarchicalKeySequenceTest extends AbstractTestCase { - public function getSequenceVectors() + public function getSequenceVectors(): array { return [ ['0', 0], @@ -22,21 +22,19 @@ public function getSequenceVectors() /** * @dataProvider getSequenceVectors - * @param $node - * @param $eSeq + * @param string $node + * @param int $eSeq */ - public function testGetSequence($node, $eSeq) + public function testGetSequence(string $node, int $eSeq) { $sequence = new HierarchicalKeySequence(); $this->assertEquals([$eSeq], $sequence->decodeRelative($node)); } - /** - * @expectedException \InvalidArgumentException - */ public function testDecodePathFailure() { $sequence = new HierarchicalKeySequence(); + $this->expectException(\InvalidArgumentException::class); $sequence->decodeRelative(''); } @@ -44,16 +42,20 @@ public function testDecodePath() { $sequence = new HierarchicalKeySequence(); - $expected = ['2147483648','2147483649','444','2147526030']; - $this->assertEquals($expected, $sequence->decodeRelative("0'/1'/444/42382'")); + $decodedPath = $sequence->decodeRelative("0'/1'/444/42382'"); + $expected = [2147483648, 2147483649, 444, 2147526030]; + foreach ($decodedPath as $i => $item) { + $this->assertIsInt($item); + $this->assertEquals($expected[$i], $item); + } } /** * @dataProvider getSequenceVectors - * @param $node - * @param $integer + * @param string $node + * @param int $integer */ - public function testDecodePathVectors($node, $integer) + public function testDecodePathVectors(string $node, int $integer) { $sequence = new HierarchicalKeySequence(); diff --git a/tests/Key/Deterministic/HierarchicalKeyTest.php b/tests/Key/Deterministic/HierarchicalKeyTest.php index f1cfa4621..ed7258043 100644 --- a/tests/Key/Deterministic/HierarchicalKeyTest.php +++ b/tests/Key/Deterministic/HierarchicalKeyTest.php @@ -9,6 +9,7 @@ use BitWasp\Bitcoin\Crypto\EcAdapter\Adapter\EcAdapterInterface; use BitWasp\Bitcoin\Crypto\EcAdapter\Key\PrivateKeyInterface; use BitWasp\Bitcoin\Crypto\Random\Random; +use BitWasp\Bitcoin\Exceptions\InvalidDerivationException; use BitWasp\Bitcoin\Key\Deterministic\HierarchicalKey; use BitWasp\Bitcoin\Key\KeyToScript\Decorator\P2shP2wshScriptDecorator; use BitWasp\Bitcoin\Key\KeyToScript\Decorator\P2shScriptDecorator; @@ -44,7 +45,7 @@ class HierarchicalKeyTest extends AbstractTestCase /** * */ - public function setUp() + public function setUp(): void { $this->network = NetworkFactory::bitcoin(); } @@ -78,13 +79,11 @@ public function testGenerateNew(EcAdapterInterface $ecAdapter) $this->assertInstanceOf(HierarchicalKey::class, $key); } - /** - * @expectedException \Exception - * @expectedExceptionMessage A HierarchicalKey must always be compressed - */ public function testFailsWithUncompressed() { $privFactory = new PrivateKeyFactory(); + $this->expectException(\Exception::class); + $this->expectExceptionMessage("A HierarchicalKey must always be compressed"); new HierarchicalKey( Bitcoin::getEcAdapter(), new P2pkhScriptDataFactory(), @@ -149,7 +148,6 @@ public function testTestVectors(EcAdapterInterface $ecAdapter, BufferInterface $ /** * @dataProvider getEcAdapters * @param EcAdapterInterface $ecAdapter - * @throws \Exception */ public function testDerivePath(EcAdapterInterface $ecAdapter) { @@ -215,24 +213,25 @@ public function testCreateHeirarchicalPrivateKey(EcAdapterInterface $ecAdapter) /** * This tests if the key being decoded has bytes which match the network. - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage HD key magic bytes do not match network magic bytes */ public function testCreateWithInvalidNetwork() { $network = new BitcoinTestnet(); $hdFactory = new HierarchicalKeyFactory(); $key = 'xpub661MyMwAqRbcEZ5ScgSxFiTbNQaUwtEzrbMrUqW5VXfZ47PFGgPq46fbhkpYCkxZQRDxhFy53Nip1VJCofd7auHCrPCmP72NV4YWu2HB7ir'; + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("HD key magic bytes do not match network magic bytes"); $hdFactory->fromExtended($key, $network); } /** - * @expectedException \Exception + * @ */ public function testCreateWithInvalidLength() { $key = 'KyQZJyRyxqNBc31iWzZjUf1vDMXpbcUzwND6AANq44M3v38smDkA'; $hdFactory = new HierarchicalKeyFactory(); + $this->expectException(\Exception::class); $hdFactory->fromExtended($key, $this->network); } @@ -257,13 +256,15 @@ public function testFromExtended(EcAdapterInterface $ecAdapter) /** * @dataProvider getEcAdapters * @param EcAdapterInterface $ecAdapter - * @expectedException \Exception + */ public function testGetExtendedPrivateKeyFailure(EcAdapterInterface $ecAdapter) { $xPub = 'xpub6AV8iVdKGa79ExyueSBjnCNKkmwLQsTvaN2N8iWCT5PNX6Xrh3gPgz3gVrxtLiYyCdC9FjwsuTTXmJiuWkxpLoqo8gj7rPWdkDsUCWfQHJB'; $hdFactory = new HierarchicalKeyFactory(); $key = $hdFactory->fromExtended($xPub, $this->network); + $this->expectException(\Exception::class); + $this->expectExceptionMessage("Cannot create extended private key from public"); $key->toExtendedPrivateKey($this->network); } @@ -347,14 +348,15 @@ public function testGetPrivateKey(EcAdapterInterface $ecAdapter) * @dataProvider getEcAdapters * @depends testGetPrivateKey * @param EcAdapterInterface $ecAdapter - * @expectedException \Exception */ public function testGetPrivateKeyFailure(EcAdapterInterface $ecAdapter) { $xPub = 'xpub6AV8iVdKGa79ExyueSBjnCNKkmwLQsTvaN2N8iWCT5PNX6Xrh3gPgz3gVrxtLiYyCdC9FjwsuTTXmJiuWkxpLoqo8gj7rPWdkDsUCWfQHJB'; $hdFactory = new HierarchicalKeyFactory($ecAdapter); $key = $hdFactory->fromExtended($xPub, $this->network); - $this->assertSame('edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea', $key->getPrivateKey()); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage("Unable to get private key, not known"); + $key->getPrivateKey(); }/**/ /** @@ -372,13 +374,14 @@ public function testGetPublicKey(EcAdapterInterface $ecAdapter) /** * @dataProvider getEcAdapters * @param EcAdapterInterface $ecAdapter - * @expectedException \Exception */ public function testDeriveFailure(EcAdapterInterface $ecAdapter) { $k = 'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8'; $factory = new HierarchicalKeyFactory($ecAdapter); $key = $factory->fromExtended($k, $this->network); + $this->expectException(\Exception::class); + $this->expectExceptionMessage("Can't derive a hardened key without the private key"); $key->deriveChild(2147483648); } @@ -394,27 +397,28 @@ public function getInvalidSequences() /** * @dataProvider getInvalidSequences * @param int $sequence - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Sequence is outside valid range */ public function testInvalidSequenceGetHmac($sequence) { $xPrv = 'xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi'; $hdFactory = new HierarchicalKeyFactory(); $key = $hdFactory->fromExtended($xPrv, $this->network); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Sequence is outside valid range"); + $key->getHmacSeed($sequence); } /** * @dataProvider getInvalidSequences * @param int $sequence - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Sequence is outside valid range, must be >= 0 && <= (2^31)-1 */ public function testInvalidSequenceDeriveChild($sequence) { $factory = new HierarchicalKeyFactory(Bitcoin::getEcAdapter()); $key = $factory->fromExtended('xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi', $this->network); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Sequence is outside valid range, must be >= 0 && <= (2^31)-1"); $key->deriveChild($sequence); } @@ -547,6 +551,10 @@ function () { ); $this->assertEquals(0, $this->HK_run_count); + + $this->expectException(InvalidDerivationException::class); + $this->expectExceptionMessage("Derived invalid key for index 1, use next index"); + $key->deriveChild(1); } diff --git a/tests/Key/Deterministic/MultisigHDTest.php b/tests/Key/Deterministic/MultisigHDTest.php index d5955cccd..58fb77d35 100644 --- a/tests/Key/Deterministic/MultisigHDTest.php +++ b/tests/Key/Deterministic/MultisigHDTest.php @@ -28,12 +28,10 @@ class MultisigHDTest extends AbstractTestCase { - /** - * @expectedException \RuntimeException - * @expectedExceptionMessage Must have at least one HierarchicalKey for Multisig HD Script - */ public function testAlwaysProvidesKeys() { + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage("Must have at least one HierarchicalKey for Multisig HD Script"); new MultisigHD(new MultisigScriptDataFactory(2, 2, true)); } diff --git a/tests/Key/Deterministic/Slip132/PrefixRegistryTest.php b/tests/Key/Deterministic/Slip132/PrefixRegistryTest.php index 730ce6e22..611b5a6d6 100644 --- a/tests/Key/Deterministic/Slip132/PrefixRegistryTest.php +++ b/tests/Key/Deterministic/Slip132/PrefixRegistryTest.php @@ -21,7 +21,7 @@ public function testMaps() ]); $res = $registry->getPrefixes($key); - $this->assertInternalType('array', $res); + $this->assertIsArray($res); $this->assertCount(2, $res); $this->assertEquals($priv, $res[0]); $this->assertEquals($pub, $res[1]); diff --git a/tests/Key/PrivateKeyTest.php b/tests/Key/PrivateKeyTest.php index 1104979c5..d93b33023 100644 --- a/tests/Key/PrivateKeyTest.php +++ b/tests/Key/PrivateKeyTest.php @@ -6,6 +6,7 @@ use BitWasp\Bitcoin\Crypto\EcAdapter\Adapter\EcAdapterInterface; use BitWasp\Bitcoin\Crypto\Random\Random; +use BitWasp\Bitcoin\Exceptions\Base58ChecksumFailure; use BitWasp\Bitcoin\Key\Factory\PrivateKeyFactory; use BitWasp\Bitcoin\Network\NetworkFactory; use BitWasp\Bitcoin\Tests\AbstractTestCase; @@ -54,13 +55,13 @@ public function testCreatePrivateKeyCompressed(EcAdapterInterface $ecAdapter) /** * @dataProvider getEcAdapters - * @expectedException \Exception * @param EcAdapterInterface $ecAdapter */ public function testCreatePrivateKeyFailure(EcAdapterInterface $ecAdapter) { $hex = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141'; $factory = new PrivateKeyFactory($ecAdapter); + $this->expectException(\Exception::class); $factory->fromHexCompressed($hex); } @@ -182,11 +183,11 @@ public function testFromWif(EcAdapterInterface $ecAdapter) /** * @dataProvider getEcAdapters - * @expectedException \BitWasp\Bitcoin\Exceptions\Base58ChecksumFailure */ public function testInvalidWif(EcAdapterInterface $ecAdapter) { $factory = new PrivateKeyFactory($ecAdapter); + $this->expectException(Base58ChecksumFailure::class); $factory->fromWif('5akdgashdgkjads'); } } diff --git a/tests/Key/PublicKeyTest.php b/tests/Key/PublicKeyTest.php index 99c15f393..f3da9f661 100644 --- a/tests/Key/PublicKeyTest.php +++ b/tests/Key/PublicKeyTest.php @@ -9,10 +9,11 @@ use BitWasp\Bitcoin\Key\Factory\PublicKeyFactory; use BitWasp\Bitcoin\Tests\AbstractTestCase; use BitWasp\Buffertools\Buffer; +use PhpParser\Builder\Class_; class PublicKeyTest extends AbstractTestCase { - public function getPublicVectors() + public function getPublicVectors(): array { $json = json_decode($this->dataFile('publickey.compressed.json')); $results = []; @@ -70,6 +71,7 @@ public function testFromHexInvalidLength(EcAdapterInterface $ecAdapter) { $hex = '02cffc9fcdc2a4e6f5dd91aee9d8d79828c1c93e7a76949a451aab8be6a0c44febaa'; $pubKeyFactory = new PublicKeyFactory($ecAdapter); + $this->expectException(\Exception::class); $pubKeyFactory->fromHex($hex); } @@ -80,6 +82,7 @@ public function testFromHexInvalidByte() { $hex = '01cffc9fcdc2a4e6f5dd91aee9d8d79828c1c93e7a76949a451aab8be6a0c44feb'; $pubKeyFactory = new PublicKeyFactory(); + $this->expectException(\Exception::class); $pubKeyFactory->fromHex($hex); } @@ -98,17 +101,15 @@ public function testIsCompressedOrUncompressed() $this->assertFalse(PublicKey::isCompressedOrUncompressed(Buffer::hex('050001020304050607080900010203040506070809000102030405060708090001'))); } - /** - * @expectedException \Exception - */ public function testFromHexInvalidByte2() { $hex = '04cffc9fcdc2a4e6f5dd91aee9d8d79828c1c93e7a76949a451aab8be6a0c44feb'; $pubKeyFactory = new PublicKeyFactory(); + $this->expectException(\Exception::class); $pubKeyFactory->fromHex($hex); } - public function getPkHashVectors() + public function getPkHashVectors(): array { $json = json_decode($this->dataFile('publickey.pubkeyhash.json')); $results = []; diff --git a/tests/LocktimeTest.php b/tests/LocktimeTest.php index 79a2533f6..f5e694ada 100644 --- a/tests/LocktimeTest.php +++ b/tests/LocktimeTest.php @@ -41,9 +41,6 @@ public function testToBlockHeight() /** * Test that fromTimestamp rejects timestamps that exceed the max (0xffffffff - 500000000) - * - * @expectedException \Exception - * @expectedExceptionMessage Timestamp out of range */ public function testMaxFromTimestamp() { @@ -56,6 +53,8 @@ public function testMaxFromTimestamp() $this->assertEquals(Locktime::INT_MAX, $nTime); $disallowed = $allowed + 1; + $this->expectException(\Exception::class); + $this->expectExceptionMessage("Timestamp out of range"); $locktime->fromTimestamp($disallowed); } @@ -63,8 +62,6 @@ public function testMaxFromTimestamp() * Test that toTimestamp accepts the maximum locktime int, 0xffffffff, * but rejects anything higher * - * @expectedException \Exception - * @expectedExceptionMessage Lock time too large */ public function testMaxToTimestamp() { @@ -75,34 +72,28 @@ public function testMaxToTimestamp() $this->assertEquals(Locktime::TIME_MAX, $timestamp); $disallowed = $allowed + 1; + $this->expectException(\Exception::class); + $this->expectExceptionMessage("Lock time too large"); $locktime->toTimestamp($disallowed); } - /** - * @expectedException \Exception - * @expectedExceptionMessage Lock time out of range for timestamp - */ public function testToTimeStampButTooLow() { $locktime = new Locktime(); + $this->expectException(\Exception::class); + $this->expectExceptionMessage("Lock time out of range for timestamp"); $locktime->toTimestamp(1); } - /** - * @expectedException \Exception - * @expectedExceptionMessage This block height is too high - */ public function testFromBlockHeightTooHigh() { $locktime = new Locktime(); $disallowed = Locktime::BLOCK_MAX + 1; + $this->expectException(\Exception::class); + $this->expectExceptionMessage("This block height is too high"); $locktime->fromBlockHeight($disallowed); } - /** - * @expectedException \Exception - * @expcetedExceptionMessage This locktime is out of range for a block height - */ public function testToBlockHeightF() { $locktime = new Locktime(); @@ -111,6 +102,8 @@ public function testToBlockHeightF() $this->assertEquals($allowed, $locktime->toBlockHeight($allowed)); $disallowed = $allowed + 1; + $this->expectException(\Exception::class); + $this->expectExceptionMessage("This locktime is out of range for a block height"); $locktime->toBlockHeight($disallowed); } } diff --git a/tests/Mnemonic/Bip39/Bip39MnemonicTest.php b/tests/Mnemonic/Bip39/Bip39MnemonicTest.php index 2ebb7e0cd..cb430b1b1 100644 --- a/tests/Mnemonic/Bip39/Bip39MnemonicTest.php +++ b/tests/Mnemonic/Bip39/Bip39MnemonicTest.php @@ -38,56 +38,46 @@ public function testMnemonicToEntropy(Bip39Mnemonic $bip39, BufferInterface $eEn $this->assertEquals($eEntropy->getBinary(), $entropy->getBinary()); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Invalid mnemonic - */ public function testIncorrectWordCount() { $bip39 = new Bip39Mnemonic(Bitcoin::getEcAdapter(), new EnglishWordList()); $mnemonic = 'letter advice'; + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Invalid mnemonic"); $bip39->mnemonicToEntropy($mnemonic); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Checksum does not match - */ public function testFailsOnInvalidChecksum() { $bip39 = new Bip39Mnemonic(Bitcoin::getEcAdapter(), new EnglishWordList()); $mnemonic = 'jelly better achieve collect unaware mountain thought cargo oxygen act hood oxygen'; + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Checksum does not match"); $bip39->mnemonicToEntropy($mnemonic); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Invalid entropy length - */ public function testFailsOnEntropyMod4() { $bip39 = new Bip39Mnemonic(Bitcoin::getEcAdapter(), new EnglishWordList()); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Invalid entropy length"); $bip39->entropyToMnemonic(Buffer::hex(str_repeat('00', 5))); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Invalid entropy length - */ public function testFailsOnEntropyTooLong() { $bip39 = new Bip39Mnemonic(Bitcoin::getEcAdapter(), new EnglishWordList()); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Invalid entropy length"); $bip39->entropyToMnemonic(Buffer::hex(str_repeat('00', 1028))); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Invalid mnemonic - entropy size is invalid - */ public function testFailsOnMnemonicOfEntropyTooLong() { $bip39 = new Bip39Mnemonic(Bitcoin::getEcAdapter(), new EnglishWordList()); $mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about end grace oxygen maze bright face loan ticket trial leg cruel lizard bread worry reject journey perfect chef section caught neither install industry'; + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Invalid mnemonic - entropy size is invalid"); $bip39->mnemonicToEntropy($mnemonic); } } diff --git a/tests/Mnemonic/Bip39/WordList/EnglishWordListTest.php b/tests/Mnemonic/Bip39/WordList/EnglishWordListTest.php index e619f056a..a934d8516 100644 --- a/tests/Mnemonic/Bip39/WordList/EnglishWordListTest.php +++ b/tests/Mnemonic/Bip39/WordList/EnglishWordListTest.php @@ -16,25 +16,20 @@ public function testGetWordList() $this->assertEquals(2048, count($wl->getWords())); } - /** - * @expectedException \InvalidArgumentException - */ public function testUnknownWord() { $wl = new EnglishWordList(); + $this->expectException(\InvalidArgumentException::class); $wl->getWord(101010101); } - /** - * @expectedException \InvalidArgumentException - */ public function testExceptionOutOfRange() { $wl = new EnglishWordList(); $word = $wl->getIndex('able'); - $this->assertInternalType('integer', $word); - + $this->assertIsInt($word); + $this->expectException(\InvalidArgumentException::class); $wl->getIndex('unknownword'); } } diff --git a/tests/Mnemonic/Bip39/WordList/JapaneseWordListTest.php b/tests/Mnemonic/Bip39/WordList/JapaneseWordListTest.php index 7b0a04057..e32d03230 100644 --- a/tests/Mnemonic/Bip39/WordList/JapaneseWordListTest.php +++ b/tests/Mnemonic/Bip39/WordList/JapaneseWordListTest.php @@ -15,25 +15,23 @@ public function testGetWordList() $this->assertEquals(2048, count($wl->getWords())); } - /** - * @expectedException \InvalidArgumentException - */ public function testUnknownWord() { $wl = new \BitWasp\Bitcoin\Mnemonic\Bip39\Wordlist\JapaneseWordList(); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Wordlist does not contain a word for index [101010101]"); $wl->getWord(101010101); } - /** - * @expectedException \InvalidArgumentException - */ public function testExceptionOutOfRange() { $wl = new \BitWasp\Bitcoin\Mnemonic\Bip39\Wordlist\JapaneseWordList(); $word = $wl->getIndex('あいだ'); - $this->assertInternalType('integer', $word); + $this->assertIsInt($word); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Wordlist does not contain word あいあいあい"); $wl->getIndex('あいあいあい'); } } diff --git a/tests/Mnemonic/Electrum/WordList/EnglishWordListTest.php b/tests/Mnemonic/Electrum/WordList/EnglishWordListTest.php index f7fc8d084..cf1fd7ec3 100644 --- a/tests/Mnemonic/Electrum/WordList/EnglishWordListTest.php +++ b/tests/Mnemonic/Electrum/WordList/EnglishWordListTest.php @@ -16,25 +16,20 @@ public function testGetWordList() $this->assertEquals(1626, count($wl->getWords())); } - /** - * @expectedException \InvalidArgumentException - */ public function testUnknownWord() { $wl = new EnglishWordList(); + $this->expectException(\InvalidArgumentException::class); $wl->getWord(101010101); } - /** - * @expectedException \InvalidArgumentException - */ public function testExceptionOutOfRange() { $wl = new EnglishWordList(); $word = $wl->getIndex('just'); - $this->assertInternalType('integer', $word); - + $this->assertIsInt($word); + $this->expectException(\InvalidArgumentException::class); $wl->getIndex('unknownword'); } } diff --git a/tests/Script/Branch/PathTracerTest.php b/tests/Script/Branch/PathTracerTest.php index 45e26fc4e..e4b8845cf 100644 --- a/tests/Script/Branch/PathTracerTest.php +++ b/tests/Script/Branch/PathTracerTest.php @@ -17,7 +17,7 @@ public function testTraceNoOperations() $tracer = new PathTracer(); $result = $tracer->done(); - $this->assertInternalType('array', $result); + $this->assertIsArray($result); $this->assertEquals(0, count($result)); $resultAgain = $tracer->done(); @@ -33,7 +33,7 @@ public function testTraceJustOneOperation() $result = $tracer->done(); - $this->assertInternalType('array', $result); + $this->assertIsArray($result); $this->assertEquals(1, count($result)); $resultAgain = $tracer->done(); diff --git a/tests/Script/Classifier/OutputClassifierTest.php b/tests/Script/Classifier/OutputClassifierTest.php index 5c28e935a..a71a753ed 100644 --- a/tests/Script/Classifier/OutputClassifierTest.php +++ b/tests/Script/Classifier/OutputClassifierTest.php @@ -156,7 +156,7 @@ public function testCases(OutputClassifier $classifier, ScriptInterface $script, $this->assertEquals($type, $decoded->getType()); $this->assertEquals($script, $decoded->getScript()); if (is_array($eSolution)) { - $this->assertInternalType('array', $solution); + $this->assertIsArray($solution); /** @var BufferInterface[] $solution */ /** @var BufferInterface[] $eSolution */ diff --git a/tests/Script/Factory/OutputScriptFactoryTest.php b/tests/Script/Factory/OutputScriptFactoryTest.php index 22644214f..e727df240 100644 --- a/tests/Script/Factory/OutputScriptFactoryTest.php +++ b/tests/Script/Factory/OutputScriptFactoryTest.php @@ -126,12 +126,10 @@ public function testCoinbaseWitnessCommitment() $this->assertEquals($expected, ScriptFactory::scriptPubKey()->witnessCoinbaseCommitment($hash)); } - /** - * @expectedException \RuntimeException - * @expectedExceptionMessage Witness commitment hash must be exactly 32-bytes - */ public function testBadCoinbaseWitnessCommitment() { + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage("Witness commitment hash must be exactly 32-bytes"); ScriptFactory::scriptPubKey()->witnessCoinbaseCommitment(new Buffer('', 31)); } } diff --git a/tests/Script/Interpreter/CheckerTest.php b/tests/Script/Interpreter/CheckerTest.php index f679658e4..17f3fef3a 100644 --- a/tests/Script/Interpreter/CheckerTest.php +++ b/tests/Script/Interpreter/CheckerTest.php @@ -5,6 +5,7 @@ namespace BitWasp\Bitcoin\Tests\Script\Interpreter; use BitWasp\Bitcoin\Bitcoin; +use BitWasp\Bitcoin\Exceptions\ScriptRuntimeException; use BitWasp\Bitcoin\Script\Interpreter\Checker; use BitWasp\Bitcoin\Script\Interpreter\InterpreterInterface; use BitWasp\Bitcoin\Tests\AbstractTestCase; @@ -14,10 +15,6 @@ class CheckerTest extends AbstractTestCase { - /** - * @expectedException \BitWasp\Bitcoin\Exceptions\ScriptRuntimeException - * @expectedExceptionMessage Signature with invalid hashtype - */ public function testCheckSignatureEncodingInvalidHashtype() { $f = InterpreterInterface::VERIFY_STRICTENC; @@ -25,9 +22,10 @@ public function testCheckSignatureEncodingInvalidHashtype() $buffer = Buffer::hex('3044022029ff6008e57d80619edf3b03b9a69ae1f8a659d9c231cde629c22f97d5bbf7e702200362617c577aa586fca20348f55a59f5ba71f3d6839b66fcfe13a84749b776e891'); + $this->expectException(ScriptRuntimeException::class); + $this->expectExceptionMessage("Signature with invalid hashtype"); $c->checkSignatureEncoding($buffer, $f); - $this->assertTrue(true); - }/**/ + } public function testCheckSignatureSafeWhenFlagNotSet() { @@ -36,21 +34,18 @@ public function testCheckSignatureSafeWhenFlagNotSet() $buffer = new Buffer('obviously incorrect.....?'); try { $c->checkSignatureEncoding($buffer, $f); - $this->assertTrue(true); } catch (\Exception $e) { $this->fail(); } } - /** - * @expectedException \BitWasp\Bitcoin\Exceptions\ScriptRuntimeException - * @expectedExceptionMessage Signature s element was not low - */ public function testCheckSignatureEncodingLowS() { $f = InterpreterInterface::VERIFY_LOW_S; $c = new Checker(Bitcoin::getEcAdapter(), new Transaction(), 0, 0); $buffer = Buffer::hex('30450220377bf4cab9bbdb219f1b0cca56f4a39fbf787d6fa9d04e248101d498de991d30022100b8e0c72dfab9a0d88eb2703c62e0e57ab2cb906e8f156b7641c2f0e24b8bba2b01'); + $this->expectException(ScriptRuntimeException::class); + $this->expectExceptionMessage("Signature s element was not low"); $c->checkSignatureEncoding($buffer, $f); } @@ -61,21 +56,18 @@ public function testCheckEmptySignatureSafeWhenFlagNotSet() $buffer = new Buffer(''); try { $c->checkSignatureEncoding($buffer, $f); - $this->assertTrue(true); } catch (\Exception $e) { $this->fail(); } } - /** - * @expectedException \BitWasp\Bitcoin\Exceptions\ScriptRuntimeException - * @expectedExceptionMessage Signature with incorrect encoding - */ public function testCheckSignatureEncodingWhenFlagSet() { $f = InterpreterInterface::VERIFY_DERSIG; $c = new Checker(Bitcoin::getEcAdapter(), new Transaction(), 0, 0); $buffer = new Buffer('obviously incorrect.....?'); + $this->expectException(ScriptRuntimeException::class); + $this->expectExceptionMessage("Signature with incorrect encoding"); $c->checkSignatureEncoding($buffer, $f); } @@ -86,7 +78,6 @@ public function testCheckSignatureEncodingWhenLowSFlagSet() $buffer = Buffer::hex('3044022029ff6008e57d80619edf3b03b9a69ae1f8a659d9c231cde629c22f97d5bbf7e702200362617c577aa586fca20348f55a59f5ba71f3d6839b66fcfe13a84749b776e801'); try { $c->checkSignatureEncoding($buffer, $f); - $this->assertTrue(true); } catch (\Exception $e) { $this->fail(); } @@ -99,7 +90,6 @@ public function testCheckSignatureEncodingWhenStrictEncFlagSet() $buffer = Buffer::hex('3044022029ff6008e57d80619edf3b03b9a69ae1f8a659d9c231cde629c22f97d5bbf7e702200362617c577aa586fca20348f55a59f5ba71f3d6839b66fcfe13a84749b776e801'); try { $c->checkSignatureEncoding($buffer, $f); - $this->assertTrue(true); } catch (\Exception $e) { $this->fail(); } @@ -112,19 +102,16 @@ public function testCheckPublicKeyEncoding() $pubkey = Buffer::hex('045e9392308b08d0d663961463b6cd056a66b757a2ced9dde197c21362360237f231b80ea66315898969f5c079f0ba3fc1c0661ed8c853ad15043f22f2b7779c95'); try { $c->checkPublicKeyEncoding($pubkey, $f); - $this->assertTrue(true); } catch (\Exception $e) { $this->fail(); } } - /** - * @expectedException \BitWasp\Bitcoin\Exceptions\ScriptRuntimeException - * @expectedExceptionMessage Signature with incorrect encoding - */ public function testIsLowDERFailsWithIncorrectEncoding() { $checker = new Checker(Bitcoin::getEcAdapter(), new Transaction(), 0, 0); + $this->expectException(ScriptRuntimeException::class); + $this->expectExceptionMessage("Signature with incorrect encoding"); $checker->isLowDerSignature(new Buffer('abcd')); } @@ -172,6 +159,8 @@ public function testCheckPublicKeyEncodingFail() $f = InterpreterInterface::VERIFY_STRICTENC; $c = new Checker(Bitcoin::getEcAdapter(), new Transaction(), 0, 0); $pubkey = Buffer::hex('045e9392308b08d0d663961463b6cd056a66b757a2ced9dde197c21362360237f231b80ea66315898969f5c079f0ba3fc1c0661ed8c853ad15043f22b7779c95'); + $this->expectException(ScriptRuntimeException::class); + $this->expectExceptionMessage("Public key with incorrect encoding"); $c->checkPublicKeyEncoding($pubkey, $f); } } diff --git a/tests/Script/Interpreter/StackTest.php b/tests/Script/Interpreter/StackTest.php index 8a708d0e1..b24ce60c5 100644 --- a/tests/Script/Interpreter/StackTest.php +++ b/tests/Script/Interpreter/StackTest.php @@ -11,12 +11,11 @@ class StackTest extends AbstractTestCase { - /** - * @expectedException \RuntimeException - */ public function testPopException() { $stack = new Stack; + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage("Cannot pop from empty stack"); $stack->pop(); } @@ -63,12 +62,11 @@ public function testErase() $this->assertTrue(count($stack) == 0); } - /** - * @expectedException \Exception - */ public function testEraseException() { $stack = new Stack; + $this->expectException(\Exception::class); + $this->expectExceptionMessage("Nothing at this position"); unset($stack[0]); } diff --git a/tests/Script/OpcodesTest.php b/tests/Script/OpcodesTest.php index 954f8f74d..df848b861 100644 --- a/tests/Script/OpcodesTest.php +++ b/tests/Script/OpcodesTest.php @@ -20,13 +20,11 @@ public function testGetOpByName() $this->assertSame($lookupOpName, $op[Opcodes::OP_0]); } - /** - * @expectedException \RuntimeException - * @expectedExceptionMessage Opcode by that name not found - */ public function testGetOpByNameFail() { $op = new Opcodes(); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage("Opcode by that name not found"); $op->getOpByName('OP_DEADBEEF'); } @@ -40,31 +38,25 @@ public function testGetOp() $this->assertSame($expected, $val); } - /** - * @expectedException \RuntimeException - * @expectedExceptionMessage Opcode not found - */ public function testGetOpCodeException() { $op = new Opcodes; + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage("Opcode not found"); $op->getOp(3); } - /** - * @expectedException \RuntimeException - */ public function testNoWriteSet() { $op = new Opcodes(); + $this->expectException(\RuntimeException::class); $op[1] = 2; } - - /** - * @expectedException \RuntimeException - */ + public function testNoWriteUnSet() { $op = new Opcodes(); + $this->expectException(\RuntimeException::class); unset($op[Opcodes::OP_1]); } diff --git a/tests/Script/ScriptCheckTestBase.php b/tests/Script/ScriptCheckTestBase.php index dc87eca18..086ed1cae 100644 --- a/tests/Script/ScriptCheckTestBase.php +++ b/tests/Script/ScriptCheckTestBase.php @@ -128,7 +128,7 @@ public function calcScriptFromString(array $mapOpNames, string $string): ScriptI $item = 'OP_CHECKSEQUENCEVERIFY'; } - if (strlen($item) == '') { + if (strlen($item) == 0) { } else if (preg_match("/^[0-9]*$/", $item) || substr($item, 0, 1) === "-" && preg_match("/^[0-9]*$/", substr($item, 1))) { $builder->int((int) $item); } else if (substr($item, 0, 2) === "0x") { diff --git a/tests/Script/ScriptTest.php b/tests/Script/ScriptTest.php index 7ff5ce1dc..7a7261506 100644 --- a/tests/Script/ScriptTest.php +++ b/tests/Script/ScriptTest.php @@ -113,10 +113,11 @@ public function testOp() /** * @depends testOp - * @expectedException \RuntimeException */ public function testOpFailure() { + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage("Opcode by that name not found"); ScriptFactory::create()->op('OP_HASH666'); } @@ -251,7 +252,7 @@ public function testWitnessVectors(ScriptInterface $script, $valid) public function testDebugInfo() { - $this->assertInternalType('array', (new Script)->__debugInfo()); + $this->assertIsArray((new Script)->__debugInfo()); } public function testBadScriptZeroSigOps() diff --git a/tests/Serializer/Block/BitcoindBlockSerializerTest.php b/tests/Serializer/Block/BitcoindBlockSerializerTest.php index 6b6e19044..5250aef77 100644 --- a/tests/Serializer/Block/BitcoindBlockSerializerTest.php +++ b/tests/Serializer/Block/BitcoindBlockSerializerTest.php @@ -51,9 +51,8 @@ public function testWithInvalidNetBytes() //echo $buffer->getHex() . "\n"; $parser = new Parser($buffer); - $block = $bds->fromParser($parser); - - $this->assertEquals('000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f', $block->getHeader()->getHash()->getHex()); + $this->expectException(\RuntimeException::class); + $bds->fromParser($parser); } diff --git a/tests/Serializer/Block/BlockHeaderSerializerTest.php b/tests/Serializer/Block/BlockHeaderSerializerTest.php index 97440ed51..a14866036 100644 --- a/tests/Serializer/Block/BlockHeaderSerializerTest.php +++ b/tests/Serializer/Block/BlockHeaderSerializerTest.php @@ -7,15 +7,14 @@ use BitWasp\Bitcoin\Serializer\Block\BlockHeaderSerializer; use BitWasp\Bitcoin\Tests\AbstractTestCase; use BitWasp\Buffertools\Buffer; +use BitWasp\Buffertools\Exceptions\ParserOutOfRange; class BlockHeaderSerializerTest extends AbstractTestCase { - /** - * @expectedException \BitWasp\Buffertools\Exceptions\ParserOutOfRange - */ public function testInvalidParse() { $serializer = new BlockHeaderSerializer; + $this->expectException(ParserOutOfRange::class); $serializer->parse(new Buffer()); } } diff --git a/tests/Serializer/Block/BlockSerializerTest.php b/tests/Serializer/Block/BlockSerializerTest.php index 3acda0ca3..fdc7ed61a 100644 --- a/tests/Serializer/Block/BlockSerializerTest.php +++ b/tests/Serializer/Block/BlockSerializerTest.php @@ -10,12 +10,10 @@ use BitWasp\Bitcoin\Serializer\Transaction\TransactionSerializer; use BitWasp\Bitcoin\Tests\AbstractTestCase; use BitWasp\Buffertools\Buffer; +use BitWasp\Buffertools\Exceptions\ParserOutOfRange; class BlockSerializerTest extends AbstractTestCase { - /** - * @expectedException \BitWasp\Buffertools\Exceptions\ParserOutOfRange - */ public function testInvalidParse() { $serializer = new BlockSerializer( @@ -23,6 +21,7 @@ public function testInvalidParse() new BlockHeaderSerializer, new TransactionSerializer() ); + $this->expectException(ParserOutOfRange::class); $serializer->parse(new Buffer()); } } diff --git a/tests/Serializer/Key/HierarchicalKey/ExtendedKeySerializerTest.php b/tests/Serializer/Key/HierarchicalKey/ExtendedKeySerializerTest.php index 5a4ae694d..44ba1b67f 100644 --- a/tests/Serializer/Key/HierarchicalKey/ExtendedKeySerializerTest.php +++ b/tests/Serializer/Key/HierarchicalKey/ExtendedKeySerializerTest.php @@ -9,18 +9,20 @@ use BitWasp\Bitcoin\Serializer\Key\HierarchicalKey\ExtendedKeySerializer; use BitWasp\Bitcoin\Tests\AbstractTestCase; use BitWasp\Buffertools\Buffer; +use BitWasp\Buffertools\Exceptions\ParserOutOfRange; class ExtendedKeySerializerTest extends AbstractTestCase { /** * @dataProvider getEcAdapters * @param EcAdapterInterface $adapter - * @expectedException \BitWasp\Buffertools\Exceptions\ParserOutOfRange */ public function testInvalidKey(EcAdapterInterface $adapter) { $network = NetworkFactory::bitcoinTestnet(); $serializer = new ExtendedKeySerializer($adapter); + $this->expectException(ParserOutOfRange::class); + $this->expectExceptionMessage("Failed to extract HierarchicalKey from parser"); $serializer->parse($network, new Buffer()); } } diff --git a/tests/Serializer/Signature/CompactSignatureSerializerTest.php b/tests/Serializer/Signature/CompactSignatureSerializerTest.php index a558a717f..9721e385d 100644 --- a/tests/Serializer/Signature/CompactSignatureSerializerTest.php +++ b/tests/Serializer/Signature/CompactSignatureSerializerTest.php @@ -16,12 +16,12 @@ class CompactSignatureSerializerTest extends AbstractTestCase /** * @dataProvider getEcAdapters * @param EcAdapterInterface $ecAdapter - * @expectedException \Exception */ public function testFromParserFailure(EcAdapterInterface $ecAdapter) { /** @var CompactSignatureSerializerInterface $serializer */ $serializer = EcSerializer::getSerializer(CompactSignatureSerializerInterface::class, true, $ecAdapter); + $this->expectException(\Exception::class); $serializer->parse(new Buffer()); } diff --git a/tests/Serializer/Signature/DerSignatureSerializerTest.php b/tests/Serializer/Signature/DerSignatureSerializerTest.php index 023613a31..39b4cecdd 100644 --- a/tests/Serializer/Signature/DerSignatureSerializerTest.php +++ b/tests/Serializer/Signature/DerSignatureSerializerTest.php @@ -19,12 +19,12 @@ class DerSignatureSerializerTest extends AbstractTestCase /** * @dataProvider getEcAdapters * @param EcAdapterInterface $adapter - * @expectedException \Exception */ public function testFromParserFailure(EcAdapterInterface $adapter) { /** @var DerSignatureSerializerInterface $serializer */ $serializer = EcSerializer::getSerializer(DerSignatureSerializerInterface::class, true, $adapter); + $this->expectException(\Exception::class); $serializer->parse(new Buffer()); } diff --git a/tests/Serializer/Transaction/TransactionSerializerTest.php b/tests/Serializer/Transaction/TransactionSerializerTest.php index cac19a27e..a73f4f9d1 100644 --- a/tests/Serializer/Transaction/TransactionSerializerTest.php +++ b/tests/Serializer/Transaction/TransactionSerializerTest.php @@ -8,6 +8,7 @@ use BitWasp\Bitcoin\Tests\AbstractTestCase; use BitWasp\Bitcoin\Transaction\TransactionFactory; use BitWasp\Buffertools\Buffer; +use BitWasp\Buffertools\Exceptions\ParserOutOfRange; class TransactionSerializerTest extends AbstractTestCase { @@ -53,14 +54,12 @@ public function testValidTxinVarint() $this->assertEquals($hex, $serialized); } - /** - * @expectedException \BitWasp\Buffertools\Exceptions\ParserOutOfRange - * @expectedExceptionMessage Insufficient data remaining for VarString - */ public function testInvalidTxinVarint() { // not perfect, but gotta explode somewhere $hex = $this->dataFile('biginputtx.invalid.txt'); + $this->expectException(ParserOutOfRange::class); + $this->expectExceptionMessage("Insufficient data remaining for VarString"); TransactionFactory::fromHex($hex); } } diff --git a/tests/Transaction/Factory/SignDataTest.php b/tests/Transaction/Factory/SignDataTest.php index 2e707c86b..c8ea66fff 100644 --- a/tests/Transaction/Factory/SignDataTest.php +++ b/tests/Transaction/Factory/SignDataTest.php @@ -57,33 +57,28 @@ public function testCase(ScriptInterface $rs = null, ScriptInterface $ws = null, } } - /** - * @expectedException \RuntimeException - * @expectedExceptionMessage Witness script requested but not set - */ public function testThrowsIfUnknownWSRequested() { $signData = new SignData(); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage("Witness script requested but not set"); $signData->getWitnessScript(); } - /** - * @expectedException \RuntimeException - * @expectedExceptionMessage Redeem script requested but not set - */ public function testThrowsIfUnknownRSRequested() { $signData = new SignData(); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage("Redeem script requested but not set"); $signData->getRedeemScript(); } - /** - * @expectedException \RuntimeException - * @expectedExceptionMessage Signature policy requested but not set - */ public function testThrowsIfUnknownSignaturePolicyRequested() { $signData = new SignData(); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage("Signature policy requested but not set"); + $signData->getSignaturePolicy(); } } diff --git a/tests/Transaction/Factory/SignerTest.php b/tests/Transaction/Factory/SignerTest.php index 1aced0da2..a199ff3f9 100644 --- a/tests/Transaction/Factory/SignerTest.php +++ b/tests/Transaction/Factory/SignerTest.php @@ -278,7 +278,7 @@ public function getSimpleSpendCases(EcAdapterInterface $ecAdapter) /** * @return array */ - public function getSimpleSpendVectors() + public function getSimpleSpendVectors(): array { $vectors = []; foreach ($this->getEcAdapters() as $adapterFixture) { @@ -295,8 +295,6 @@ public function getSimpleSpendVectors() * @param EcAdapterInterface $ecAdapter * @param ScriptInterface $script * @dataProvider getSimpleSpendVectors - * @expectedException \RuntimeException - * @expectedExceptionMessage Signing with the wrong private key */ public function testRejectsWrongKey(EcAdapterInterface $ecAdapter, ScriptInterface $script) { @@ -312,6 +310,8 @@ public function testRejectsWrongKey(EcAdapterInterface $ecAdapter, ScriptInterfa $txOut = new TransactionOutput(5000000000, $script); $signer = new Signer($tx, $ecAdapter); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage("Signing with the wrong private key"); $signer->input(0, $txOut)->sign($privateKey, SigHash::ALL); } diff --git a/tests/Transaction/Mutator/InputCollectionMutatorTest.php b/tests/Transaction/Mutator/InputCollectionMutatorTest.php index 0a6fed513..be80275c3 100644 --- a/tests/Transaction/Mutator/InputCollectionMutatorTest.php +++ b/tests/Transaction/Mutator/InputCollectionMutatorTest.php @@ -46,6 +46,7 @@ public function testInvalidSlice() ]; $mutator = new InputCollectionMutator($collection); + $this->expectException(\RuntimeException::class); $mutator->slice(0, 1); } @@ -62,4 +63,25 @@ public function testNull() $this->assertEquals(0, count($outputs)); } + + public function testSet() + { + $collection = [ + new TransactionInput(new OutPoint(Buffer::hex('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'), 5), new Script()), + new TransactionInput(new OutPoint(Buffer::hex('baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'), 10), new Script()), + ]; + + $mutator = new InputCollectionMutator($collection); + $new = new TransactionInput(new OutPoint(Buffer::hex('baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'), 11), new Script()); + $mutator->set(1, $new); + $newCollection = $mutator->done(); + $this->assertTrue($newCollection[1]->equals($new)); + } + + public function testInvalidIndex() + { + $mutator = new InputCollectionMutator([]); + $this->expectException(\OutOfRangeException::class); + $mutator->offsetGet(10); + } } diff --git a/tests/Transaction/Mutator/OutputCollectionMutatorTest.php b/tests/Transaction/Mutator/OutputCollectionMutatorTest.php index 5fd6398ca..2debbd6e0 100644 --- a/tests/Transaction/Mutator/OutputCollectionMutatorTest.php +++ b/tests/Transaction/Mutator/OutputCollectionMutatorTest.php @@ -64,15 +64,13 @@ public function testSlice() $this->assertEquals(1, count($outputs)); } - /** - * @expectedException \RuntimeException - */ public function testInvalidSlice() { $collection = [ ]; $mutator = new OutputCollectionMutator($collection); + $this->expectException(\RuntimeException::class); $mutator->slice(0, 1); } @@ -103,12 +101,10 @@ public function testSet() $this->assertEquals(1, $newCollection[0]->getValue()); } - /** - * @expectedException \OutOfRangeException - */ public function testInvalidIndex() { $mutator = new OutputCollectionMutator([]); + $this->expectException(\OutOfRangeException::class); $mutator->offsetGet(10); } } diff --git a/tests/Transaction/TransactionTest.php b/tests/Transaction/TransactionTest.php index 42391c371..e994d81a6 100644 --- a/tests/Transaction/TransactionTest.php +++ b/tests/Transaction/TransactionTest.php @@ -51,6 +51,9 @@ public function testSetVersion() */ public function testSetVersionException() { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Transaction version is outside valid range"); + new Transaction(4294967999); } @@ -69,29 +72,23 @@ public function testSetLockTime() $this->assertEquals($lockTime, $tx->getLockTime()); } - /** - * @expectedException \Exception - */ public function testSetLockTimeException() { + $this->expectException(\InvalidArgumentException::class); new Transaction(1, [], [], [], 4294967297); } - /** - * @expectedException \Exception - */ public function testGetInputException() { $tx = new Transaction(); + $this->expectException(\RuntimeException::class); $tx->getInput(0); } - /** - * @expectedException \Exception - */ public function testGetOutputException() { $tx = new Transaction(); + $this->expectException(\RuntimeException::class); $tx->getOutput(0); } diff --git a/tests/UriTest.php b/tests/UriTest.php index e79e30311..c4ef2d8d3 100644 --- a/tests/UriTest.php +++ b/tests/UriTest.php @@ -77,12 +77,10 @@ public function testRequestUrl() $this->assertEquals('bitcoin:'.$string.'?r=https%3A%2F%2Fexample.com%2Frequest', $uri->uri()); } - /** - * @expectedException \InvalidArgumentException - */ public function testBip21MustProvideAddress() { $address = null; + $this->expectException(\InvalidArgumentException::class); new Uri($address); }