package lab.games; import static org.junit.Assert.*; import java.awt.event.ActionEvent; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.lang.reflect.Field; import java.util.List; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JOptionPane; import org.junit.Test; public class ControllerTest { static class FilledModel extends Model { public FilledModel() { super(); } public boolean filled(int column) { try { Class clazz = Model.class; Field field = clazz.getDeclaredField("slots"); field.setAccessible(true); int[][] slots = (int[][]) field.get(this); return slots[0][column] == Model.PLAYER || slots[0][column] == Model.COMPUTER; } catch (NoSuchFieldException | IllegalAccessException e) { fail("Something went wrong. Please contact your instructor."); return true; } } public int move() { int column = 0; while (this.filled(column)) { column++; } return column; } } static class TieModel extends FilledModel { public TieModel() { super(); } public boolean hasWon(int player) { return false; } } static class PlayerModel extends FilledModel { public PlayerModel() { super(); } public boolean hasWon(int player) { return player == Model.PLAYER; } } static class ComputerModel extends FilledModel { public ComputerModel() { super(); } public boolean hasWon(int player) { return player == Model.COMPUTER; } } @Test public void testFilledColumn() { Controller controller = new Controller(); View view = new View(controller); Model model = new FilledModel(); controller.setModel(model); controller.setView(view); try { Class clazz = view.getClass(); Field field = clazz.getDeclaredField("slots"); field.setAccessible(true); List> viewSlots = (List>) field.get(view); field = clazz.getDeclaredField("PLAYER"); field.setAccessible(true); ImageIcon PLAYER = (ImageIcon) field.get(view); field = clazz.getDeclaredField("COMPUTER"); field.setAccessible(true); ImageIcon COMPUTER = (ImageIcon) field.get(view); clazz = Model.class; field = clazz.getDeclaredField("slots"); field.setAccessible(true); int[][] modelSlots = (int[][]) field.get(model); ByteArrayOutputStream output = new ByteArrayOutputStream(); PrintStream stream = new PrintStream(output); System.setOut(stream); ActionEvent event = new ActionEvent(view, 0, "0"); controller.actionPerformed(event); // check that the view is updated assertEquals("view has not been updated correctly", PLAYER, viewSlots.get(5).get(0).getIcon()); assertEquals("view has not been updated correctly", COMPUTER, viewSlots.get(4).get(0).getIcon()); // check that the model is updated assertEquals("model has not been updated correctly", Model.PLAYER, modelSlots[5][0]); assertEquals("model has not been updated correctly", Model.COMPUTER, modelSlots[4][0]); // check that nothing has been printed String actual = output.toString(); assertEquals("printed output incorrect", "", actual); event = new ActionEvent(view, 0, "0"); controller.actionPerformed(event); // check that the view is updated assertEquals("view has not been updated correctly", PLAYER, viewSlots.get(3).get(0).getIcon()); assertEquals("view has not been updated correctly", COMPUTER, viewSlots.get(2).get(0).getIcon()); // check that the model is updated assertEquals("model has not been updated correctly", Model.PLAYER, modelSlots[3][0]); assertEquals("model has not been updated correctly", Model.COMPUTER, modelSlots[2][0]); // check that nothing has been printed actual = output.toString(); assertEquals("printed output incorrect", "", actual); event = new ActionEvent(view, 0, "0"); controller.actionPerformed(event); // check that the view is updated assertEquals("view has not been updated correctly", PLAYER, viewSlots.get(1).get(0).getIcon()); assertEquals("view has not been updated correctly", COMPUTER, viewSlots.get(0).get(0).getIcon()); // check that the model is updated assertEquals("model has not been updated correctly", Model.PLAYER, modelSlots[1][0]); assertEquals("model has not been updated correctly", Model.COMPUTER, modelSlots[0][0]); // check that nothing has been printed actual = output.toString(); assertEquals("printed output incorrect", "", actual); event = new ActionEvent(view, 0, "0"); controller.actionPerformed(event); // check if something has been printed actual = output.toString().trim(); assertEquals("printed output incorrect", "You cannot drop a coin in this column", actual); } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); fail("Something went wrong. Please contact your instructor."); } } @Test public void testTie() { Controller controller = new Controller(); View view = new View(controller); Model model = new TieModel(); controller.setModel(model); controller.setView(view); ByteArrayOutputStream output = new ByteArrayOutputStream(); PrintStream stream = new PrintStream(output); System.setOut(stream); for (int column = 0; column < Model.COLUMN; column++) { for (int row = 0; row < Model.ROW / 2; row++) { ActionEvent event = new ActionEvent(view, 0, "" + column); controller.actionPerformed(event); } } // check if something has been printed String actual = output.toString().trim(); assertEquals("printed output incorrect", "It is a tie", actual); } @Test public void testPlayer() { Controller controller = new Controller(); View view = new View(controller); Model model = new PlayerModel(); controller.setModel(model); controller.setView(view); ByteArrayOutputStream output = new ByteArrayOutputStream(); PrintStream stream = new PrintStream(output); System.setOut(stream); ActionEvent event = new ActionEvent(view, 0, "0"); controller.actionPerformed(event); // check if something has been printed String actual = output.toString().trim(); assertEquals("printed output incorrect", "You have won", actual); } @Test public void testComputer() { Controller controller = new Controller(); View view = new View(controller); Model model = new ComputerModel(); controller.setModel(model); controller.setView(view); ByteArrayOutputStream output = new ByteArrayOutputStream(); PrintStream stream = new PrintStream(output); System.setOut(stream); ActionEvent event = new ActionEvent(view, 0, "0"); controller.actionPerformed(event); // check if something has been printed String actual = output.toString().trim(); assertEquals("printed output incorrect", "You have lost", actual); } }