@Override public Amount dividedBy(Amount o, RemainderHandler remainderHandler) { int scale = Math.max(o.asBigDecimal().scale(), mc.getPrecision()); return new DecimalAmount( bd.divide(o.asBigDecimal(), remainderHandler.getRoundingMode()) .setScale(scale, remainderHandler.getRoundingMode())); }
/** Test of getValue method, of class Amount. */ @Test public void testGetValue() { System.out.println("getValue"); Amount instance = new Amount(0); double expResult = 0.0; double result = instance.getValue(); assertEquals(expResult, result, 0.0); }
/** Test of compareTo method, of class Amount. */ @Test public void testCompareTo() { System.out.println("compareTo"); Object o = new Amount(10); Amount instance = new Amount(10); int expResult = 0; int result = instance.compareTo(o); assertEquals(expResult, result); }
/** Test of add method, of class Amount. */ @Test public void testAdd() { System.out.println("add"); Amount amount = new Amount(10); Amount instance = new Amount(11); Amount expResult = new Amount(21); Amount result = instance.add(amount); assertEquals(expResult, result); }
@Test public void amountConstantIsConsistentWithNemesisBlock() { // Act: Amount totalAmount = Amount.ZERO; final Block block = this.loadNemesisBlock(); for (final Transaction transaction : block.getTransactions()) { if (transaction instanceof TransferTransaction) { totalAmount = totalAmount.add(((TransferTransaction) transaction).getAmount()); } } // Assert: Assert.assertThat(totalAmount, IsEqual.equalTo(NEMESIS_BLOCK_INFO.getAmount())); }
@Override public int compareTo(@SuppressWarnings("NullableProblems") Amount o) { if (o instanceof DecimalAmount) { DecimalAmount decimalAmount = (DecimalAmount) o; return bd.compareTo(decimalAmount.bd); } return bd.compareTo(o.asBigDecimal()); }
@RunWith(JMock.class) public class FormatTransactionAsCsvRowTest { private final Mockery mockery = new Mockery(); private final CsvFormat<LocalDate> dateFormat = mockery.mock(CsvFormat.class, "date format"); private final CsvFormat<Category> categoryFormat = mockery.mock(CsvFormat.class, "category format"); private final CsvFormat<Amount> amountFormat = mockery.mock(CsvFormat.class, "amount format"); private final TransactionCsvFormat transactionCsvFormat = new TransactionCsvFormat(dateFormat, categoryFormat, amountFormat); private LocalDate anyNonNullDate = new LocalDate(2012, 11, 14); private Category anyNonNullCategory = new Category("Bowling Winnings"); private Amount anyNonNullAmount = Amount.cents(250); @Test public void happyPath() throws Exception { mockery.checking( new Expectations() { { allowing(dateFormat).format(with(any(LocalDate.class))); will(returnValue("::the date::")); allowing(categoryFormat).format(with(any(Category.class))); will(returnValue("::the category::")); allowing(amountFormat).format(with(any(Amount.class))); will(returnValue("::the amount::")); } }); final Transaction transaction = new Transaction(anyNonNullDate, anyNonNullCategory, anyNonNullAmount); final String rowText = transactionCsvFormat.format(transaction); assertThat( rowText, matches( Pattern.compile( "\\s*\"::the date::\"," + "\\s*\"::the category::\"," + "\\s*\"::the amount::\"\\s*"))); } @Test public void nullTransaction() throws Exception { try { transactionCsvFormat.format(null); fail("How did you format a null transaction?!"); } catch (ProgrammerMistake success) { } } }
@Test public void nemesisBlockCanBeCreated() { // Act: final Block block = this.loadNemesisBlock(); // Assert: Assert.assertThat( block.getSigner().getAddress(), IsEqual.equalTo(NEMESIS_BLOCK_INFO.getAddress())); Assert.assertThat(block.getType(), IsEqual.equalTo(-1)); Assert.assertThat(block.getVersion(), IsEqual.equalTo(EXPECTED_VERSION)); Assert.assertThat(block.getTimeStamp(), IsEqual.equalTo(TimeInstant.ZERO)); // 2 multisig aggregate transactions Assert.assertThat( block.getTotalFee(), IsEqual.equalTo(EXPECTED_MULTISIG_AGGREGATE_FEE.multiply(2))); Assert.assertThat(block.getPreviousBlockHash(), IsEqual.equalTo(Hash.ZERO)); Assert.assertThat(block.getHeight(), IsEqual.equalTo(BlockHeight.ONE)); Assert.assertThat(block.getTransactions().size(), IsEqual.equalTo(NUM_NEMESIS_TRANSACTIONS)); Assert.assertThat(block.getDifficulty(), IsEqual.equalTo(BlockDifficulty.INITIAL_DIFFICULTY)); Assert.assertThat(block.getGenerationHash(), IsNull.notNullValue()); }
@Override public Amount times(Amount o, RemainderHandler remainderHandler) { return new DecimalAmount(bd.multiply(o.asBigDecimal())); }
@Override public Amount minus(Amount o) { return new DecimalAmount(bd.subtract(o.asBigDecimal())); }
@Override public Amount plus(Amount o) { return new DecimalAmount(bd.add(o.asBigDecimal())); }
public static DecimalAmount of(Amount amount) { return new DecimalAmount(amount.asBigDecimal()); }
@RunWith(Enclosed.class) public class NemesisBlockMainnetTest { private static final NetworkInfo NETWORK_INFO = NetworkInfos.getMainNetworkInfo(); private static final NemesisBlockInfo NEMESIS_BLOCK_INFO = NETWORK_INFO.getNemesisBlockInfo(); // users, devs, marketing, contributors + funds (transfer + multisig) private static final int NUM_NEMESIS_TRANSFER_TRANSACTIONS = 1307 + 21 + 5 + 8 + 6; private static final int NUM_NEMESIS_TRANSACTIONS = NUM_NEMESIS_TRANSFER_TRANSACTIONS + 6; private static final Amount EXPECTED_MULTISIG_AGGREGATE_FEE = Amount.fromNem(2 * (5 + 3 * 4) + 2 * (5 + 3 * 5) + 2 * (5 + 3 * 6)); private static final int EXPECTED_VERSION = 0x68000001; @BeforeClass public static void initNetwork() { NetworkInfos.setDefault(NETWORK_INFO); } @AfterClass public static void resetNetwork() { NetworkInfos.setDefault(null); } private abstract static class AbstractNemesisBlockTest { // basic @Test public void nemesisBlockCanBeCreated() { // Act: final Block block = this.loadNemesisBlock(); // Assert: Assert.assertThat( block.getSigner().getAddress(), IsEqual.equalTo(NEMESIS_BLOCK_INFO.getAddress())); Assert.assertThat(block.getType(), IsEqual.equalTo(-1)); Assert.assertThat(block.getVersion(), IsEqual.equalTo(EXPECTED_VERSION)); Assert.assertThat(block.getTimeStamp(), IsEqual.equalTo(TimeInstant.ZERO)); // 2 multisig aggregate transactions Assert.assertThat( block.getTotalFee(), IsEqual.equalTo(EXPECTED_MULTISIG_AGGREGATE_FEE.multiply(2))); Assert.assertThat(block.getPreviousBlockHash(), IsEqual.equalTo(Hash.ZERO)); Assert.assertThat(block.getHeight(), IsEqual.equalTo(BlockHeight.ONE)); Assert.assertThat(block.getTransactions().size(), IsEqual.equalTo(NUM_NEMESIS_TRANSACTIONS)); Assert.assertThat(block.getDifficulty(), IsEqual.equalTo(BlockDifficulty.INITIAL_DIFFICULTY)); Assert.assertThat(block.getGenerationHash(), IsNull.notNullValue()); } @Test public void nemesisBlockIsVerifiable() { // Arrange: final Block block = this.loadNemesisBlock(); // Assert: Assert.assertThat(block.verify(), IsEqual.equalTo(true)); } @Test public void nemesisTransactionsAreVerifiable() { // Arrange: final Block block = this.loadNemesisBlock(); // Assert: for (final Transaction transaction : block.getTransactions()) { Assert.assertThat(transaction.verify(), IsEqual.equalTo(true)); } } @Test public void nemesisTransactionsHaveCorrectFees() { // Arrange: final Block block = this.loadNemesisBlock(); // Assert: for (final Transaction transaction : block.getTransactions()) { final Amount expectedFee = TransactionTypes.TRANSFER == transaction.getType() ? Amount.ZERO : NemGlobals.getTransactionFeeCalculator().calculateMinimumFee(transaction); Assert.assertThat(transaction.getFee(), IsEqual.equalTo(expectedFee)); } } @Test public void nemesisAddressesAreValid() { // Arrange: final Block block = this.loadNemesisBlock(); // Act: final Set<Address> allAddresses = block .getTransactions() .stream() .flatMap(t -> t.getAccounts().stream().map(Account::getAddress)) .collect(Collectors.toSet()); // Assert: for (final Address address : allAddresses) { Assert.assertThat(address.toString(), address.isValid(), IsEqual.equalTo(true)); } } @Test public void nemesisTransactionSignersHavePublicKeys() { // Arrange: final Block block = this.loadNemesisBlock(); // Act: final Set<Address> signerAddresses = block .getTransactions() .stream() .map(t -> t.getSigner().getAddress()) .collect(Collectors.toSet()); // Assert: for (final Address address : signerAddresses) { Assert.assertThat(address.getPublicKey(), IsNull.notNullValue()); } } // endregion // region constants @Test public void amountConstantIsConsistentWithNemesisBlock() { // Act: Amount totalAmount = Amount.ZERO; final Block block = this.loadNemesisBlock(); for (final Transaction transaction : block.getTransactions()) { if (transaction instanceof TransferTransaction) { totalAmount = totalAmount.add(((TransferTransaction) transaction).getAmount()); } } // Assert: Assert.assertThat(totalAmount, IsEqual.equalTo(NEMESIS_BLOCK_INFO.getAmount())); } @Test public void addressConstantIsConsistentWithNemesisBlock() { // Arrange: final Block block = this.loadNemesisBlock(); final Address blockAddress = block.getSigner().getAddress(); // Assert: Assert.assertThat(blockAddress, IsEqual.equalTo(NEMESIS_BLOCK_INFO.getAddress())); Assert.assertThat( blockAddress.getPublicKey(), IsEqual.equalTo(NEMESIS_BLOCK_INFO.getAddress().getPublicKey())); Assert.assertThat(blockAddress.getPublicKey(), IsNull.notNullValue()); } @Test public void generationHashConstantIsConsistentWithNemesisBlock() { // Arrange: final Block block = this.loadNemesisBlock(); // Assert: Assert.assertThat( block.getGenerationHash(), IsEqual.equalTo(NEMESIS_BLOCK_INFO.getGenerationHash())); } // endregion protected abstract Block loadNemesisBlock(final MockAccountLookup accountLookup); protected Block loadNemesisBlock() { return this.loadNemesisBlock(new MockAccountLookup()); } } // region basic public static class ResourceNemesisBlockTest extends AbstractNemesisBlockTest { @Override protected Block loadNemesisBlock(final MockAccountLookup accountLookup) { return NemesisBlock.fromResource( NEMESIS_BLOCK_INFO, new DeserializationContext(accountLookup)); } } public static class BinaryNemesisBlockTest extends AbstractNemesisBlockTest { @Test public void nemesisBlockCannotBeLoadedFromBlobWithIncorrectType() { // Arrange (set type to 1): final byte[] buffer = loadNemesisBlockBlobObject(); buffer[0] = 1; buffer[1] = 0; buffer[2] = 0; buffer[3] = 0; // Act: ExceptionAssert.assertThrows( v -> NemesisBlock.fromBlobObject( NEMESIS_BLOCK_INFO, buffer, new DeserializationContext(new MockAccountLookup())), IllegalArgumentException.class); } @Test public void nemesisBlockCannotBeLoadedFromInvalidBlob() { // Arrange: final byte[] buffer = loadNemesisBlockBlobObject(); final byte[] badBuffer1 = ByteBuffer.allocate(3 + buffer.length).put("bad".getBytes()).put(buffer).array(); final byte[] badBuffer2 = ByteBuffer.allocate(3 + buffer.length) .put(Arrays.copyOfRange(buffer, 0, 100)) .put("bad".getBytes()) .put(Arrays.copyOfRange(buffer, 100, buffer.length)) .array(); // Act: ExceptionAssert.assertThrows( v -> NemesisBlock.fromBlobObject( NEMESIS_BLOCK_INFO, badBuffer1, new DeserializationContext(new MockAccountLookup())), IllegalArgumentException.class); ExceptionAssert.assertThrows( v -> NemesisBlock.fromBlobObject( NEMESIS_BLOCK_INFO, badBuffer2, new DeserializationContext(new MockAccountLookup())), SerializationException.class); } @Override protected Block loadNemesisBlock(final MockAccountLookup accountLookup) { final byte[] blob = loadNemesisBlockBlobObject(); return NemesisBlock.fromBlobObject( NEMESIS_BLOCK_INFO, blob, new DeserializationContext(accountLookup)); } private static byte[] loadNemesisBlockBlobObject() { try (final InputStream fin = NemesisBlock.class .getClassLoader() .getResourceAsStream(NEMESIS_BLOCK_INFO.getDataFileName())) { return IOUtils.toByteArray(fin); } catch (final IOException e) { throw new IllegalStateException( "unexpected exception was thrown when parsing nemesis block resource"); } } } }