Skip to content

Commit

Permalink
zold-io#16 implementing merge
Browse files Browse the repository at this point in the history
  • Loading branch information
Vatavuk committed Aug 8, 2018
1 parent fd61c7a commit 855d64d
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 17 deletions.
68 changes: 55 additions & 13 deletions src/main/java/io/zold/api/Wallet.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,24 @@
import java.io.IOException;
import java.io.Writer;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import org.cactoos.collection.Filtered;
import org.cactoos.iterable.IterableOf;
import org.cactoos.iterable.Joined;
import org.cactoos.iterable.Mapped;
import org.cactoos.iterable.Skipped;
import org.cactoos.list.ListOf;
import org.cactoos.scalar.CheckedScalar;
import org.cactoos.scalar.Or;
import org.cactoos.scalar.UncheckedScalar;
import org.cactoos.text.FormattedText;
import org.cactoos.text.SplitText;
import org.cactoos.text.TextOf;
import org.cactoos.text.UncheckedText;

/**
* Wallet.
*
* @since 0.1
*/
@SuppressWarnings({"PMD.ShortMethodName", "PMD.TooManyMethods"})
Expand All @@ -64,7 +71,7 @@ public interface Wallet {
* @param other Other wallet
* @return The merged wallet
*/
Wallet merge(Wallet other);
Wallet merge(Wallet other) throws IOException;

/**
* This wallet's ledger.
Expand All @@ -74,7 +81,6 @@ public interface Wallet {

/**
* A Fake {@link Wallet}.
*
* @since 1.0
*/
final class Fake implements Wallet {
Expand All @@ -84,13 +90,23 @@ final class Fake implements Wallet {
*/
private final long id;

private final Iterable<Transaction> transactions;

/**
* Ctor.
*
* @param id The wallet id.
*/
public Fake(final long id) {
this(id, new IterableOf<>());
}

public Fake(final long id, final Transaction... transactions) {
this(id, new IterableOf<>(transactions));
}

public Fake(final long id, final Iterable<Transaction> transactions) {
this.id = id;
this.transactions = transactions;
}

@Override
Expand All @@ -110,7 +126,7 @@ public Wallet merge(final Wallet other) {

@Override
public Iterable<Transaction> ledger() {
return new IterableOf<>();
return this.transactions;
}
}

Expand Down Expand Up @@ -158,17 +174,43 @@ public void pay(final long amt, final long bnf) throws IOException {
}
}

// @todo #6:30min Implement merge method. This should merge this wallet
// with a copy of the same wallet. It should throw an error if a
// wallet is provided. Also add a unit test to replace
// WalletTest.mergeIsNotYetImplemented().
@Override
public Wallet merge(final Wallet other) {
throw new UnsupportedOperationException(
"merge() not yet supported"
);
public Wallet merge(final Wallet other) throws IOException {
if (other.id() != this.id()) {
throw new IOException(
new UncheckedText(
new FormattedText(
"Wallet ID mismatch, ours is %d, theirs is %d",
other.id(),
this.id()
)
).asString()
);
}
final Iterable<Transaction> ledger = this.ledger();
final Collection<Transaction> candidates = new ArrayList<>();
for (final Transaction remote : other.ledger()) {
final Collection<Transaction> filtered =
new Filtered<>(
input -> new UncheckedScalar<>(
new Or(
() -> remote.equals(input),
() -> remote.id() == input.id() &&
remote.bnf() == input.bnf(),
() -> remote.id() == input.id() && remote.amount() < 0L,
() -> remote.prefix().equals(input.prefix())
)
).value(),
ledger
);
if (filtered.isEmpty()) {
candidates.add(remote);
}
}
return new Wallet.Fake(this.id(), new Joined<>(ledger, candidates));
}


@Override
public Iterable<Transaction> ledger() {
return new Mapped<>(
Expand Down
59 changes: 55 additions & 4 deletions src/test/java/io/zold/api/WalletTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.cactoos.collection.CollectionOf;
import org.cactoos.list.ListOf;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
Expand Down Expand Up @@ -94,10 +95,60 @@ public void pay() throws IOException {
);
}

@Test(expected = UnsupportedOperationException.class)
public void mergeIsNotYetImplemented() throws IOException {
new Wallet.File(this.folder.newFile().toPath()).merge(
new Wallet.File(this.folder.newFile().toPath())
@Test
public void mergesWallets() throws IOException {
final long id = 5124095577148911L;
final Wallet wallet = new Wallet.File(this.wallet(id));
final Wallet merged = wallet.merge(
new Wallet.Fake(
id,
new RtTransaction("abcd;2017-07-19T21:25:07Z;0000000000a72366;xxsQuJa9;98bb82c81735c4ee;")
)
);
MatcherAssert.assertThat(
new CollectionOf<>(merged.ledger()).size(),
new IsEqual<>(new CollectionOf<>(wallet.ledger()).size() + 1)
);
}

@Test
public void doesNotMergeWalletsWithDifferentId() throws IOException {
this.error.expect(IOException.class);
this.error.expectMessage("Wallet ID mismatch, ours is 123, theirs is 5124095577148911");
final long id = 5124095577148911L;
final Wallet wallet = new Wallet.File(this.wallet(id));
wallet.merge(new Wallet.Fake(123L));
}

@Test
public void doesNotMergeExistingTransactions() throws IOException {
final long id = 5124095577148911L;
final Wallet wallet = new Wallet.File(this.wallet(id));
final Wallet merged = wallet.merge(
new Wallet.Fake(
id,
new RtTransaction("003b;2017-07-19T21:25:07Z;ffffffffffa72367;xksQuJa9;98bb82c81735c4ee;For food;QCuLuVr4...")
)
);
MatcherAssert.assertThat(
new CollectionOf<>(merged.ledger()).size(),
new IsEqual<>(new CollectionOf<>(wallet.ledger()).size())
);
}

@Test
public void doesNotMergeTransactionsWithSameIdAndBnf() throws IOException {
final long id = 5124095577148911L;
final Wallet wallet = new Wallet.File(this.wallet(id));
final Wallet merged = wallet.merge(
new Wallet.Fake(
id,
new RtTransaction("003b;2017-07-18T21:25:07Z;ffffffffffa72367;xxsQuJa9;98bb82c81735c4ee;For food;QCuLuVr4...")
)
);
MatcherAssert.assertThat(
new CollectionOf<>(merged.ledger()).size(),
new IsEqual<>(new CollectionOf<>(wallet.ledger()).size())
);
}

Expand Down

0 comments on commit 855d64d

Please sign in to comment.