public static void main(String[] args) throws Exception {

    // Create data source and create the customers, products and purchases tables
    final var dataSource = createDataSource();
    deleteSchema(dataSource);
    createSchema(dataSource);

    // create customer
    var customerDao = new CustomerDaoImpl(dataSource);

    var tom =
        Customer.builder()
            .name("Tom")
            .money(Money.of(USD, 30))
            .customerDao(customerDao)
            .build();

    tom.save();

    // create products
    var productDao = new ProductDaoImpl(dataSource);

    var eggs =
        Product.builder()
            .name("Eggs")
            .price(Money.of(USD, 10.0))
            .expirationDate(LocalDate.now().plusDays(7))
            .productDao(productDao)
            .build();

    var butter =
        Product.builder()
            .name("Butter")
            .price(Money.of(USD, 20.00))
            .expirationDate(LocalDate.now().plusDays(9))
            .productDao(productDao)
            .build();

    var cheese =
        Product.builder()
            .name("Cheese")
            .price(Money.of(USD, 25.0))
            .expirationDate(LocalDate.now().plusDays(2))
            .productDao(productDao)
            .build();

    eggs.save();
    butter.save();
    cheese.save();

    // show money balance of customer after each purchase
    tom.showBalance();
    tom.showPurchases();

    // buy eggs
    tom.buyProduct(eggs);
    tom.showBalance();

    // buy butter
    tom.buyProduct(butter);
    tom.showBalance();

    // trying to buy cheese, but receive a refusal
    // because he didn't have enough money
    tom.buyProduct(cheese);
    tom.showBalance();

    // return butter and get money back
    tom.returnProduct(butter);
    tom.showBalance();

    // Tom can buy cheese now because he has enough money
    // and there is a discount on cheese because it expires in 2 days
    tom.buyProduct(cheese);

    tom.save();

    // show money balance and purchases after shopping
    tom.showBalance();
    tom.showPurchases();
  }
@Test
  void shouldExecuteApplicationWithoutException() {
    assertDoesNotThrow(() -> App.main(new String[] {}));
  }