Skip to content

Commit

Permalink
WIP: Issue-#155: Add a regular expression enhancement example
Browse files Browse the repository at this point in the history
  • Loading branch information
dakusui committed Feb 6, 2022
1 parent 9492155 commit a033a57
Show file tree
Hide file tree
Showing 5 changed files with 259 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.github.dakusui.jcunit8.examples.bankaccount2;

public interface BankAccount {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.github.dakusui.jcunit8.examples.bankaccount2;

class BankAccount2 {
static BankAccount2 open() {
return new BankAccount2();
}

private int balance;

void deposit(int amount) {
if (amount <= 0) {
throw new IllegalArgumentException();
}
balance += amount;
}

void withdraw(int amount) {
if (amount <= 0) {
throw new IllegalArgumentException();
}
if (amount > balance)
throw new InsufficientBalance();
balance -= amount;
}

void transferTo(BankAccount2 another, int amount) {
if (amount <= 0) {
throw new IllegalArgumentException();
}
withdraw(amount);
another.deposit(amount);
}

int getBalance() {
return this.balance;
}

static class InsufficientBalance extends RuntimeException {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.github.dakusui.jcunit8.examples.bankaccount2;

import com.github.dakusui.jcunit8.factorspace.Parameter;
import com.github.dakusui.jcunit8.runners.junit4.annotations.From;
import com.github.dakusui.jcunit8.runners.junit4.annotations.ParameterSource;

public interface BankAccountDriver extends RegexScenario {
@ParameterSource
Parameter.Factory<String> accountName();

@ParameterSource
Parameter.Factory<String> recipientAccountName();

@ParameterSource
Parameter.Factory<Integer> amount();

@Handle
BankAccount openAccount(@From("accountName") String name);

@Handle
BankAccount openRecipientAccount(@From("recipientAccountName") String name);

@Handle
void deposit(@From("openAccount") BankAccount bankAccount, @From("amount") int amount);

@Handle
void withdraw(@From("openAccount") BankAccount bankAccount, @From("amount") int amount);

@Handle
void transfer(@From("openAccount") BankAccount from, @From("openRecipientAccount") BankAccount to, int amount);

@Handle
void closeAccount(@From("openAccount") BankAccount bankAccount);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package com.github.dakusui.jcunit8.examples.bankaccount2;

import com.github.dakusui.jcunit8.factorspace.Parameter.Regex;
import com.github.dakusui.jcunit8.factorspace.Parameter.Simple;
import com.github.dakusui.jcunit8.runners.junit4.JCUnit8;
import com.github.dakusui.jcunit8.runners.junit4.annotations.Condition;
import com.github.dakusui.jcunit8.runners.junit4.annotations.From;
import com.github.dakusui.jcunit8.runners.junit4.annotations.Given;
import com.github.dakusui.jcunit8.runners.junit4.annotations.ParameterSource;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.List;

import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;

@RunWith(JCUnit8.class)
public class BankAccountExample2 {

private BankAccount2 myAccount;
private final BankAccount2 anotherAccount = BankAccount2.open();

@ParameterSource
public Regex.Factory<String> scenario() {
return Regex.Factory.of("open deposit(deposit|withdraw|transfer){0,2}getBalance");
}

@ParameterSource
public Simple.Factory<Integer> depositAmount() {
return Simple.Factory.of(asList(100, 200, 300, 400, 500, 600, -1));
}

@ParameterSource
public Simple.Factory<Integer> withdrawAmount() {
return Simple.Factory.of(asList(100, 200, 300, 400, 500, 600, -1));
}

@ParameterSource
public Simple.Factory<Integer> transferAmount() {
return Simple.Factory.of(asList(100, 200, 300, 400, 500, 600, -1));
}

@Condition(constraint = true)
public boolean depositUsed(
@From("scenario") List<String> scenario,
@From("depositAmount") int amount
) {
//noinspection SimplifiableIfStatement
if (!scenario.contains("deposit")) {
return amount == -1;
} else {
return amount != -1;
}
}

@Condition(constraint = true)
public boolean withdrawUsed(
@From("scenario") List<String> scenario,
@From("withdrawAmount") int amount
) {
//noinspection SimplifiableIfStatement
if (!scenario.contains("withdraw")) {
return amount == -1;
} else {
return amount != -1;
}
}

@Condition(constraint = true)
public boolean transferUsed(
@From("scenario") List<String> scenario,
@From("transferAmount") int amount
) {
//noinspection SimplifiableIfStatement
if (!scenario.contains("transfer")) {
return amount == -1;
} else {
return amount != -1;
}
}

@Condition(constraint = true)
public boolean overdraftNotHappens(
@From("scenario") List<String> scenario,
@From("depositAmount") int amountOfDeposit,
@From("withdrawAmount") int amountOfWithdraw,
@From("transferAmount") int amountOfTransfer
) {
return calculateBalance(scenario, amountOfDeposit, amountOfWithdraw, amountOfTransfer) >= 0;
}

private static int calculateBalance(List<String> scenario,
int amountOfDeposit,
int amountOfWithdraw,
int amountOfTransfer) {
int balance = 0;
for (String op : scenario) {
if ("deposit".equals(op)) {
balance += amountOfDeposit;
} else if ("withdraw".equals(op)) {
balance -= amountOfWithdraw;
} else if ("transfer".equals(op)) {
balance -= amountOfTransfer;
}
if (balance < 0) {
return balance;
}
}
return balance;
}

@Test
@Given("overdraftNotHappens")
public void whenPerformScenario$thenBalanceIsCorrect(
@From("scenario") List<String> scenario,
@From("depositAmount") int amountOfDeposit,
@From("withdrawAmount") int amountOfWithdraw,
@From("transferAmount") int amountOfTransfer
) {
int balance = -1;
for (String operation : scenario) {
balance = perform(operation, amountOfDeposit, amountOfWithdraw, amountOfTransfer);
}
assertEquals(calculateBalance(scenario, amountOfDeposit, amountOfWithdraw, amountOfTransfer), balance);
}

@Test
@Given("overdraftNotHappens")
public void printScenario(
@From("scenario") List<String> scenario,
@From("depositAmount") int amountOfDeposit,
@From("withdrawAmount") int amountOfWithdraw,
@From("transferAmount") int amountOfTransfer
) {
System.out.println(scenario + ":" + amountOfDeposit + ":" + amountOfWithdraw + ":" + amountOfTransfer);
}

private int perform(
String operation,
int amountOfDeposit,
int amountOfWithdraw,
int amountOfTransfer
) {
int ret = -1;
switch (operation) {
case "open":
myAccount = BankAccount2.open();
break;
case "deposit":
myAccount.deposit(amountOfDeposit);
break;
case "withdraw":
myAccount.withdraw(amountOfWithdraw);
break;
case "transfer":
myAccount.transferTo(anotherAccount, amountOfTransfer);
break;
case "getBalance":
ret = myAccount.getBalance();
break;
default:
throw new AssertionError();
}
return ret;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.github.dakusui.jcunit8.examples.bankaccount2;

import java.lang.annotation.Retention;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

public interface RegexScenario {
String regularExpression();

@Retention(RUNTIME)
@interface Handle {

}
}

0 comments on commit a033a57

Please sign in to comment.