3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-13 10:45:51 +00:00

Added unit tests to cover some (not all) red spots in the Cobertura

report.
This commit is contained in:
Johnathan 2015-03-26 23:25:03 -06:00 committed by Mike Hearn
parent b11c17a5f6
commit 4b6914a39d

View File

@ -1,12 +1,24 @@
package org.bitcoinj.core; package org.bitcoinj.core;
import org.bitcoinj.core.TransactionConfidence.ConfidenceType;
import org.bitcoinj.params.UnitTestParams; import org.bitcoinj.params.UnitTestParams;
import org.bitcoinj.script.Script;
import org.bitcoinj.script.ScriptBuilder; import org.bitcoinj.script.ScriptBuilder;
import org.bitcoinj.testing.FakeTxBuilder; import org.bitcoinj.testing.FakeTxBuilder;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.easymock.EasyMock;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.replay;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
/** /**
* Just check the Transaction.verify() method. Most methods that have complicated logic in Transaction are tested * Just check the Transaction.verify() method. Most methods that have complicated logic in Transaction are tested
@ -24,9 +36,24 @@ public class TransactionTest {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
dummy = FakeTxBuilder.createFakeTx(PARAMS, Coin.COIN, ADDRESS); dummy = FakeTxBuilder.createFakeTx(PARAMS, Coin.COIN, ADDRESS);
tx = new Transaction(PARAMS); tx = newTransaction();
tx.addOutput(Coin.COIN, ADDRESS); }
tx.addInput(dummy.getOutput(0));
private Transaction newTransaction(boolean newToAddress) {
Address addr = newToAddress ? new ECKey().toAddress(PARAMS): ADDRESS;
return newTransaction(new TransactionOutput(PARAMS, null, Coin.COIN, addr));
}
private Transaction newTransaction() {
return newTransaction(new TransactionOutput(PARAMS, null, Coin.COIN, ADDRESS));
}
private Transaction newTransaction(TransactionOutput to) {
Transaction newTx = new Transaction(PARAMS);
newTx.addOutput(to);
newTx.addInput(dummy.getOutput(0));
return newTx;
} }
@Test(expected = VerificationException.EmptyInputsOrOutputs.class) @Test(expected = VerificationException.EmptyInputsOrOutputs.class)
@ -89,4 +116,184 @@ public class TransactionTest {
assertEquals(101, input.getScriptBytes().length); assertEquals(101, input.getScriptBytes().length);
tx.verify(); tx.verify();
} }
@Test
public void isConsistentReturnsFalseAsExpected() {
TransactionBag mockTB = createMock(TransactionBag.class);
TransactionOutput to = createMock(TransactionOutput.class);
EasyMock.expect(to.isAvailableForSpending()).andReturn(true);
EasyMock.expect(to.isMineOrWatched(mockTB)).andReturn(true);
EasyMock.expect(to.getSpentBy()).andReturn(new TransactionInput(PARAMS, null, new byte[0]));
Transaction tx = newTransaction(to);
replay(to);
boolean isConsistent = tx.isConsistent(mockTB, false);
assertEquals(isConsistent, false);
}
@Test
public void isConsistentReturnsFalseAsExpected_WhenAvailableForSpendingEqualsFalse() {
TransactionOutput to = createMock(TransactionOutput.class);
EasyMock.expect(to.isAvailableForSpending()).andReturn(false);
EasyMock.expect(to.getSpentBy()).andReturn(null);
Transaction tx = newTransaction(to);
replay(to);
boolean isConsistent = tx.isConsistent(createMock(TransactionBag.class), false);
assertEquals(isConsistent, false);
}
@Test
public void testEstimatedLockTime_WhenParameterSignifiesBlockHeight() {
int TEST_LOCK_TIME = 20;
Date now = Calendar.getInstance().getTime();
BlockChain mockBlockChain = createMock(BlockChain.class);
EasyMock.expect(mockBlockChain.estimateBlockTime(TEST_LOCK_TIME)).andReturn(now);
Transaction tx = newTransaction();
tx.setLockTime(TEST_LOCK_TIME); // less than five hundred million
replay(mockBlockChain);
assertEquals(tx.estimateLockTime(mockBlockChain), now);
}
@Test
public void testOptimalEncodingMessageSize() {
Transaction tx = new Transaction(PARAMS);
int length = tx.length;
// add basic transaction input, check the length
tx.addOutput(new TransactionOutput(PARAMS, null, Coin.COIN, ADDRESS));
length += getCombinedLength(tx.getOutputs());
// add basic output, check the length
tx.addInput(dummy.getOutput(0));
length += getCombinedLength(tx.getInputs());
// optimal encoding size should equal the length we just calculated
assertEquals(tx.getOptimalEncodingMessageSize(), length);
}
private int getCombinedLength(List<? extends Message> list) {
int sumOfAllMsgSizes = 0;
for (Message m: list) { sumOfAllMsgSizes += m.getMessageSize() + 1; }
return sumOfAllMsgSizes;
}
@Test
public void testIsMatureReturnsFalseIfTransactionIsCoinbaseAndConfidenceTypeIsNotEqualToBuilding() {
Transaction tx = new Transaction(PARAMS);
tx.addInput(dummy.getOutput(0));
// make this into a coinbase transaction
TransactionInput input = tx.getInput(0);
input.getOutpoint().setHash(Sha256Hash.ZERO_HASH);
input.getOutpoint().setIndex(-1);
tx.getConfidence().setConfidenceType(ConfidenceType.UNKNOWN);
assertEquals(tx.isMature(), false);
tx.getConfidence().setConfidenceType(ConfidenceType.PENDING);
assertEquals(tx.isMature(), false);
tx.getConfidence().setConfidenceType(ConfidenceType.DEAD);
assertEquals(tx.isMature(), false);
}
@Test
public void testToStringWhenLockTimeIsSpecifiedInBlockHeight() {
Transaction tx = newTransaction();
TransactionInput input = tx.getInput(0);
input.setSequenceNumber(42);
int TEST_LOCK_TIME = 20;
tx.setLockTime(TEST_LOCK_TIME);
Calendar cal = Calendar.getInstance();
cal.set(2085, 10, 4, 17, 53, 21);
cal.set(Calendar.MILLISECOND, 0);
BlockChain mockBlockChain = createMock(BlockChain.class);
EasyMock.expect(mockBlockChain.estimateBlockTime(TEST_LOCK_TIME)).andReturn(cal.getTime());
replay(mockBlockChain);
String str = tx.toString(mockBlockChain);
assertEquals(str.contains("block " + TEST_LOCK_TIME), true);
assertEquals(str.contains("estimated to be reached at"), true);
}
@Test
public void testToStringWhenIteratingOverAnInputCatchesAnException() {
Transaction tx = newTransaction();
TransactionInput ti = new TransactionInput(PARAMS, tx, new byte[0]) {
@Override
public Script getScriptSig() throws ScriptException {
throw new ScriptException("");
}
};
tx.addInput(ti);
assertEquals(tx.toString().contains("[exception: "), true);
}
@Test
public void testToStringWhenThereAreZeroInputs() {
Transaction tx = new Transaction(PARAMS);
assertEquals(tx.toString().contains("No inputs!"), true);
}
@Test
public void testTheTXByHeightComparator() {
final boolean USE_UNIQUE_ADDRESS = true;
Transaction tx1 = newTransaction(USE_UNIQUE_ADDRESS);
tx1.getConfidence().setAppearedAtChainHeight(1);
Transaction tx2 = newTransaction(USE_UNIQUE_ADDRESS);
tx2.getConfidence().setAppearedAtChainHeight(2);
Transaction tx3 = newTransaction(USE_UNIQUE_ADDRESS);
tx3.getConfidence().setAppearedAtChainHeight(3);
SortedSet<Transaction> set = new TreeSet<Transaction>(Transaction.SORT_TX_BY_HEIGHT);
set.add(tx2);
set.add(tx1);
set.add(tx3);
Iterator<Transaction> iterator = set.iterator();
assertEquals(tx1.equals(tx2), false);
assertEquals(tx1.equals(tx3), false);
assertEquals(tx1.equals(tx1), true);
assertEquals(iterator.next().equals(tx3), true);
assertEquals(iterator.next().equals(tx2), true);
assertEquals(iterator.next().equals(tx1), true);
assertEquals(iterator.hasNext(), false);
}
@Test(expected = ScriptException.class)
public void testAddSignedInputThrowsExceptionWhenScriptIsNotToRawPubKeyAndIsNotToAddress() {
ECKey key = new ECKey();
Address addr = key.toAddress(PARAMS);
Transaction fakeTx = FakeTxBuilder.createFakeTx(PARAMS, Coin.COIN, addr);
Transaction tx = new Transaction(PARAMS);
tx.addOutput(fakeTx.getOutput(0));
Script script = ScriptBuilder.createOpReturnScript(new byte[0]);
tx.addSignedInput(fakeTx.getOutput(0).getOutPointFor(), script, key);
}
} }