From e427700f90ff679b24413f7ee8b4ed08262c5a43 Mon Sep 17 00:00:00 2001 From: Nick Stolbov Date: Thu, 20 Jan 2022 19:10:19 +0100 Subject: [PATCH 01/14] Changed Menumanager implementation from using a single rootMenu to using a ArrayList directly for its submenus --- src/main/java/Application/MenuManager.java | 23 +++++++++++++------ .../java/Application/MenuManagerTest.java | 18 +++++++-------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/main/java/Application/MenuManager.java b/src/main/java/Application/MenuManager.java index 383e5f8..987c88e 100644 --- a/src/main/java/Application/MenuManager.java +++ b/src/main/java/Application/MenuManager.java @@ -1,24 +1,33 @@ package Application; +import java.util.ArrayList; + public class MenuManager { - private Menu rootMenu; + private ArrayList menuList; private Menu currentMenu; - public MenuManager(Menu rootMenu){ - this.rootMenu = rootMenu; - this.currentMenu = rootMenu; + public MenuManager(){ + menuList = new ArrayList<>(); + currentMenu = null; + } + + public void addMenu(Menu menu){ + menuList.add(menu); } public void select(int i){ - this.currentMenu = currentMenu.getMenu(i); + if(currentMenu == null) + this.currentMenu = menuList.get(i); + else + this.currentMenu = currentMenu.getMenu(i); } public void back() throws Exception { if(!this.inRootMenu()) this.currentMenu = this.currentMenu.getPreviousMenu(); else - throw new Exception("Menu is a root menu, a previous menu doesn't exist"); + throw new Exception("Menu is in the root menu, a previous menu doesn't exist"); } public Menu getCurrentMenu(){ @@ -26,7 +35,7 @@ public class MenuManager { } public boolean inRootMenu(){ - return this.currentMenu.equals(this.rootMenu); + return this.currentMenu == null; } } diff --git a/src/test/java/Application/MenuManagerTest.java b/src/test/java/Application/MenuManagerTest.java index d6031de..b1d79c1 100644 --- a/src/test/java/Application/MenuManagerTest.java +++ b/src/test/java/Application/MenuManagerTest.java @@ -10,18 +10,16 @@ import static org.junit.jupiter.api.Assertions.*; class MenuManagerTest { MenuManager mm; - Menu rootMenu; @BeforeEach void setUp() { - rootMenu = new Menu("Root"); Menu menu1 = new Menu("Menu1"); Menu menu2 = new Menu("Menu2"); Menu menu1_1 = new Menu("Menu1.1"); menu1.addMenu(menu1_1); - rootMenu.addMenu(menu1); - rootMenu.addMenu(menu2); - mm = new MenuManager(rootMenu); + mm = new MenuManager(); + mm.addMenu(menu1); + mm.addMenu(menu2); } @AfterEach @@ -30,11 +28,11 @@ class MenuManagerTest { @Test void testSelectFunction() { - assertEquals(mm.getCurrentMenu(), rootMenu); + assertNull(mm.getCurrentMenu()); mm.select(0); - assertEquals(mm.getCurrentMenu(), rootMenu.getMenu(0)); + assertEquals(mm.getCurrentMenu().getName(), "Menu1"); mm.select(0); - assertEquals(mm.getCurrentMenu(), rootMenu.getMenu(0).getMenu(0)); + assertEquals(mm.getCurrentMenu().getName(), "Menu1.1"); } @Test @@ -55,7 +53,7 @@ class MenuManagerTest { mm.select(0); try { mm.back(); - assertEquals(mm.getCurrentMenu(), rootMenu); + assertTrue(mm.inRootMenu()); } catch (Exception e) { Assertions.fail("Test failed: " + e.getMessage()); } @@ -63,7 +61,7 @@ class MenuManagerTest { mm.select(0); try { mm.back(); - assertEquals(mm.getCurrentMenu(), rootMenu.getMenu(0)); + assertEquals(mm.getCurrentMenu().getName(), "Menu1"); } catch (Exception e) { Assertions.fail("Test failed: " + e.getMessage()); } From 691ca536ea046068731c4e9b50185e55386e354a Mon Sep 17 00:00:00 2001 From: Nick Stolbov Date: Thu, 20 Jan 2022 19:26:55 +0100 Subject: [PATCH 02/14] Added getFormattedMenuList method to MenuManager with test for printing to Console --- src/main/java/Application/MenuManager.java | 26 ++++++++++++++----- .../java/Application/MenuManagerTest.java | 7 +++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/main/java/Application/MenuManager.java b/src/main/java/Application/MenuManager.java index 987c88e..539ed66 100644 --- a/src/main/java/Application/MenuManager.java +++ b/src/main/java/Application/MenuManager.java @@ -7,35 +7,47 @@ public class MenuManager { private ArrayList menuList; private Menu currentMenu; - public MenuManager(){ + public MenuManager() { menuList = new ArrayList<>(); currentMenu = null; } - public void addMenu(Menu menu){ + public void addMenu(Menu menu) { menuList.add(menu); } - public void select(int i){ - if(currentMenu == null) + public void select(int i) { + if (currentMenu == null) this.currentMenu = menuList.get(i); else this.currentMenu = currentMenu.getMenu(i); } public void back() throws Exception { - if(!this.inRootMenu()) + if (!this.inRootMenu()) this.currentMenu = this.currentMenu.getPreviousMenu(); else throw new Exception("Menu is in the root menu, a previous menu doesn't exist"); } - public Menu getCurrentMenu(){ + public Menu getCurrentMenu() { return this.currentMenu; } - public boolean inRootMenu(){ + public boolean inRootMenu() { return this.currentMenu == null; } + public String getFormattedMenuList() { + StringBuilder result = new StringBuilder(); + ArrayList baseMenuList = this.menuList; + if(!inRootMenu()) + baseMenuList = currentMenu.getSubMenuList(); + + for(int i = 0; i < baseMenuList.size(); i++) + result.append(i + 1).append(": ").append(baseMenuList.get(i).getName()).append("\n"); + + return result.toString(); + } + } diff --git a/src/test/java/Application/MenuManagerTest.java b/src/test/java/Application/MenuManagerTest.java index b1d79c1..83c632a 100644 --- a/src/test/java/Application/MenuManagerTest.java +++ b/src/test/java/Application/MenuManagerTest.java @@ -66,4 +66,11 @@ class MenuManagerTest { Assertions.fail("Test failed: " + e.getMessage()); } } + + @Test + void getFormattedMenuList(){ + assertEquals(mm.getFormattedMenuList(), "1: Menu1\n2: Menu2\n"); + mm.select(0); + assertEquals(mm.getFormattedMenuList(), "1: Menu1.1\n"); + } } \ No newline at end of file From 298fde40551908d875cfe08d80ac701af86b5f71 Mon Sep 17 00:00:00 2001 From: Nick Stolbov Date: Thu, 20 Jan 2022 19:29:57 +0100 Subject: [PATCH 03/14] Refactored MenuManagerTest for better naming convention --- src/test/java/Application/MenuManagerTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/Application/MenuManagerTest.java b/src/test/java/Application/MenuManagerTest.java index 83c632a..45e7b65 100644 --- a/src/test/java/Application/MenuManagerTest.java +++ b/src/test/java/Application/MenuManagerTest.java @@ -27,7 +27,7 @@ class MenuManagerTest { } @Test - void testSelectFunction() { + void select() { assertNull(mm.getCurrentMenu()); mm.select(0); assertEquals(mm.getCurrentMenu().getName(), "Menu1"); @@ -36,14 +36,14 @@ class MenuManagerTest { } @Test - void testIsRootMenuFunction() { + void inRootMenu() { assertTrue(mm.inRootMenu()); mm.select(0); assertFalse(mm.inRootMenu()); } @Test - void testBackFunction() { + void back() { try { mm.back(); Assertions.fail("Test failed: shouldn't be able to go back in rootMenu"); From 08f8fbc5960501deee15be69eb055f1daeddae0b Mon Sep 17 00:00:00 2001 From: Nick Stolbov Date: Fri, 21 Jan 2022 00:18:55 +0100 Subject: [PATCH 04/14] Added getSize() method to MenuManager with test --- src/main/java/Application/MenuManager.java | 10 ++++++++-- src/test/java/Application/MenuManagerTest.java | 9 +++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/main/java/Application/MenuManager.java b/src/main/java/Application/MenuManager.java index 539ed66..62944b1 100644 --- a/src/main/java/Application/MenuManager.java +++ b/src/main/java/Application/MenuManager.java @@ -16,6 +16,12 @@ public class MenuManager { menuList.add(menu); } + public int getSize() { + if(inRootMenu()) + return menuList.size(); + return currentMenu.getSubMenuList().size(); + } + public void select(int i) { if (currentMenu == null) this.currentMenu = menuList.get(i); @@ -41,10 +47,10 @@ public class MenuManager { public String getFormattedMenuList() { StringBuilder result = new StringBuilder(); ArrayList baseMenuList = this.menuList; - if(!inRootMenu()) + if (!inRootMenu()) baseMenuList = currentMenu.getSubMenuList(); - for(int i = 0; i < baseMenuList.size(); i++) + for (int i = 0; i < baseMenuList.size(); i++) result.append(i + 1).append(": ").append(baseMenuList.get(i).getName()).append("\n"); return result.toString(); diff --git a/src/test/java/Application/MenuManagerTest.java b/src/test/java/Application/MenuManagerTest.java index 45e7b65..111bf13 100644 --- a/src/test/java/Application/MenuManagerTest.java +++ b/src/test/java/Application/MenuManagerTest.java @@ -73,4 +73,13 @@ class MenuManagerTest { mm.select(0); assertEquals(mm.getFormattedMenuList(), "1: Menu1.1\n"); } + + @Test + void getSize() { + assertEquals(mm.getSize(), 2); + mm.select(0); + assertEquals(mm.getSize(), 1); + mm.select(0); + assertEquals(mm.getSize(), 0); + } } \ No newline at end of file From 55f173324acfe0800987d1deefb08b908fe6ca61 Mon Sep 17 00:00:00 2001 From: Nick Stolbov Date: Fri, 21 Jan 2022 00:26:27 +0100 Subject: [PATCH 05/14] Changed select method with test for MenuManager to avoid ArrayIndexOutOfBoundsException --- src/main/java/Application/MenuManager.java | 2 ++ src/test/java/Application/MenuManagerTest.java | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/main/java/Application/MenuManager.java b/src/main/java/Application/MenuManager.java index 62944b1..4aa1be5 100644 --- a/src/main/java/Application/MenuManager.java +++ b/src/main/java/Application/MenuManager.java @@ -23,6 +23,8 @@ public class MenuManager { } public void select(int i) { + if(i < 0 || i >= this.getSize()) + return; if (currentMenu == null) this.currentMenu = menuList.get(i); else diff --git a/src/test/java/Application/MenuManagerTest.java b/src/test/java/Application/MenuManagerTest.java index 111bf13..3ad5701 100644 --- a/src/test/java/Application/MenuManagerTest.java +++ b/src/test/java/Application/MenuManagerTest.java @@ -29,8 +29,18 @@ class MenuManagerTest { @Test void select() { assertNull(mm.getCurrentMenu()); + //Negative index + mm.select(-1); + assertNull(mm.getCurrentMenu()); + mm.select(0); assertEquals(mm.getCurrentMenu().getName(), "Menu1"); + //Dose nothing when index to big + mm.select(1); + assertEquals(mm.getCurrentMenu().getName(), "Menu1"); + + mm.select(0); + assertEquals(mm.getCurrentMenu().getName(), "Menu1.1"); mm.select(0); assertEquals(mm.getCurrentMenu().getName(), "Menu1.1"); } From 823c9d96c4554f541a01a167e380ced04c80b77e Mon Sep 17 00:00:00 2001 From: Nick Stolbov Date: Fri, 21 Jan 2022 00:32:00 +0100 Subject: [PATCH 06/14] Refactored test names for MenuTest class for better naming convention --- src/test/java/Application/MenuTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/Application/MenuTest.java b/src/test/java/Application/MenuTest.java index a0297a6..d0494b6 100644 --- a/src/test/java/Application/MenuTest.java +++ b/src/test/java/Application/MenuTest.java @@ -29,17 +29,17 @@ class MenuTest { } @Test - void testCorrectName() { + void getName() { assertEquals("Root", rootMenu.getName()); } @Test - void testAddMenuFunction() { + void addMenu() { assertTrue(rootMenu.getMenu(0).getName().equals("Menu1") && rootMenu.getMenu(1).getName().equals("Menu2") && rootMenu.getMenu(0).getMenu(0).getName().equals("Menu1.1")); } @Test - void testPreviousMenuFunction(){ + void getPreviousMenu(){ assertTrue(rootMenu.getPreviousMenu() == null && rootMenu.getMenu(0).getPreviousMenu().getName().equals("Root") && rootMenu.getMenu(0).getMenu(0).getPreviousMenu().getName().equals("Menu1")); } From 2ab0579f3cd41030e39f22e67e3841a36e981e5a Mon Sep 17 00:00:00 2001 From: Nick Stolbov Date: Thu, 27 Jan 2022 18:45:14 +0100 Subject: [PATCH 07/14] Added Cli class for centralized I/O management and getPrintStream() method with test. Updated other classes for Cli class integration. --- src/main/java/Application/Cli.java | 16 ++++++++ src/main/java/Application/Menu.java | 10 ++--- src/main/java/Application/MenuManager.java | 4 +- src/main/java/Game/Game.java | 6 ++- src/main/java/Game/TicTacToe/Board.java | 38 +++++++++---------- src/main/java/Main.java | 9 +++-- src/test/java/Application/CliTest.java | 35 +++++++++++++++++ .../java/Application/MenuManagerTest.java | 2 +- src/test/java/Application/MenuTest.java | 4 +- src/test/java/Game/GameTest.java | 29 +------------- src/test/java/Game/TicTacToe/BoardTest.java | 2 - src/test/java/Game/TictactoeTest.java | 7 ---- 12 files changed, 89 insertions(+), 73 deletions(-) create mode 100644 src/main/java/Application/Cli.java create mode 100644 src/test/java/Application/CliTest.java diff --git a/src/main/java/Application/Cli.java b/src/main/java/Application/Cli.java new file mode 100644 index 0000000..a2d787d --- /dev/null +++ b/src/main/java/Application/Cli.java @@ -0,0 +1,16 @@ +package Application; + +import java.io.PrintStream; + +public class Cli { + + private PrintStream printStream; + + public Cli(PrintStream printStream) { + this.printStream = printStream; + } + + public PrintStream getPrintStream() { + return this.printStream; + } +} diff --git a/src/main/java/Application/Menu.java b/src/main/java/Application/Menu.java index 0651965..347d66a 100644 --- a/src/main/java/Application/Menu.java +++ b/src/main/java/Application/Menu.java @@ -8,13 +8,13 @@ public class Menu { private Menu previousMenu; private ArrayList subMenuList; - public Menu(String name){ + public Menu(String name) { setName(name); setPreviousMenu(null); subMenuList = new ArrayList<>(); } - public void addMenu(Menu menu){ + public void addMenu(Menu menu) { menu.setPreviousMenu(this); subMenuList.add(menu); } @@ -27,7 +27,7 @@ public class Menu { this.name = name; } - public Menu getMenu(int i){ + public Menu getMenu(int i) { return getSubMenuList().get(i); } @@ -35,11 +35,11 @@ public class Menu { return this.subMenuList; } - private void setPreviousMenu(Menu menu){ + private void setPreviousMenu(Menu menu) { this.previousMenu = menu; } - public Menu getPreviousMenu(){ + public Menu getPreviousMenu() { return this.previousMenu; } } diff --git a/src/main/java/Application/MenuManager.java b/src/main/java/Application/MenuManager.java index 4aa1be5..36a95fc 100644 --- a/src/main/java/Application/MenuManager.java +++ b/src/main/java/Application/MenuManager.java @@ -17,13 +17,13 @@ public class MenuManager { } public int getSize() { - if(inRootMenu()) + if (inRootMenu()) return menuList.size(); return currentMenu.getSubMenuList().size(); } public void select(int i) { - if(i < 0 || i >= this.getSize()) + if (i < 0 || i >= this.getSize()) return; if (currentMenu == null) this.currentMenu = menuList.get(i); diff --git a/src/main/java/Game/Game.java b/src/main/java/Game/Game.java index 39bc4f8..00f398b 100644 --- a/src/main/java/Game/Game.java +++ b/src/main/java/Game/Game.java @@ -1,5 +1,7 @@ package Game; +import Application.Cli; + import java.util.ArrayList; public abstract class Game { @@ -9,9 +11,9 @@ public abstract class Game { public abstract void update(String input); - public void print() { + public void print(Cli cli) { for (String s : outputBuffer) { - System.out.println(s); + cli.getPrintStream().println(s); } } diff --git a/src/main/java/Game/TicTacToe/Board.java b/src/main/java/Game/TicTacToe/Board.java index daaea57..03dd018 100644 --- a/src/main/java/Game/TicTacToe/Board.java +++ b/src/main/java/Game/TicTacToe/Board.java @@ -1,7 +1,6 @@ package Game.TicTacToe; import java.util.ArrayList; -import java.util.Arrays; public class Board { @@ -28,18 +27,17 @@ public class Board { states[i] = State.EMPTY; } winPatterns = new ArrayList<>(); - winPatterns.add(new int[]{1,1,1,0,0,0,0,0,0}); - winPatterns.add(new int[]{0,0,0,1,1,1,0,0,0}); - winPatterns.add(new int[]{0,0,0,0,0,0,1,1,1}); - winPatterns.add(new int[]{1,0,0,1,0,0,1,0,0}); - winPatterns.add(new int[]{0,1,0,0,1,0,0,1,0}); - winPatterns.add(new int[]{0,0,1,0,0,1,0,0,1}); - winPatterns.add(new int[]{0,0,1,0,1,0,1,0,0}); - winPatterns.add(new int[]{1,0,0,0,1,0,0,0,1}); + winPatterns.add(new int[]{1, 1, 1, 0, 0, 0, 0, 0, 0}); + winPatterns.add(new int[]{0, 0, 0, 1, 1, 1, 0, 0, 0}); + winPatterns.add(new int[]{0, 0, 0, 0, 0, 0, 1, 1, 1}); + winPatterns.add(new int[]{1, 0, 0, 1, 0, 0, 1, 0, 0}); + winPatterns.add(new int[]{0, 1, 0, 0, 1, 0, 0, 1, 0}); + winPatterns.add(new int[]{0, 0, 1, 0, 0, 1, 0, 0, 1}); + winPatterns.add(new int[]{0, 0, 1, 0, 1, 0, 1, 0, 0}); + winPatterns.add(new int[]{1, 0, 0, 0, 1, 0, 0, 0, 1}); } - public static char getStatedChar(State state) { switch (state) { case CIRCLE: @@ -55,15 +53,15 @@ public class Board { public boolean setCellState(int cell, boolean cross) { if (cell <= 9 && cell >= 1) { - if (this.states[cell-1] != State.EMPTY) { + if (this.states[cell - 1] != State.EMPTY) { return false; } if (cross) { - this.states[cell-1] = State.CROSS; + this.states[cell - 1] = State.CROSS; } else { - this.states[cell-1] = State.CIRCLE; + this.states[cell - 1] = State.CIRCLE; } - }else { + } else { return false; } return true; @@ -83,19 +81,19 @@ public class Board { public ArrayList getOutputBoard() { ArrayList outputBoard = new ArrayList<>(); outputBoard.add("1 ║2 ║3"); - outputBoard.add(" " + getStatedChar(states[0]) + " ║ " + getStatedChar(states[1]) + " ║ " + getStatedChar(states[2]) +" "); + outputBoard.add(" " + getStatedChar(states[0]) + " ║ " + getStatedChar(states[1]) + " ║ " + getStatedChar(states[2]) + " "); outputBoard.add("═════╬═════╬═════"); outputBoard.add("4 ║5 ║6"); - outputBoard.add(" " + getStatedChar(states[3]) + " ║ " + getStatedChar(states[4]) + " ║ " + getStatedChar(states[5]) +" "); + outputBoard.add(" " + getStatedChar(states[3]) + " ║ " + getStatedChar(states[4]) + " ║ " + getStatedChar(states[5]) + " "); outputBoard.add("═════╬═════╬═════"); outputBoard.add("7 ║8 ║9"); - outputBoard.add(" " + getStatedChar(states[6]) + " ║ " + getStatedChar(states[7]) + " ║ " + getStatedChar(states[8]) +" "); + outputBoard.add(" " + getStatedChar(states[6]) + " ║ " + getStatedChar(states[7]) + " ║ " + getStatedChar(states[8]) + " "); return outputBoard; } - + public State[] getStates() { return this.states; } @@ -105,7 +103,7 @@ public class Board { if (!(o instanceof Board)) { return false; } - Board x = (Board)o; + Board x = (Board) o; for (int i = 0; i < x.getStates().length; i++) { if (this.getStates()[i] != x.getStates()[i]) { return false; @@ -156,7 +154,7 @@ public class Board { State[] stateArray = new State[9]; for (int i = 0; i < temp.length; i++) { - switch(temp[i]) { + switch (temp[i]) { case 1: stateArray[i] = State.CIRCLE; break; diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 89b9c35..cf9689e 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -1,17 +1,18 @@ +import Application.Cli; import Game.Tictactoe; import java.util.Scanner; public class Main { - public static void main(String[] args){ - System.out.println("Hello world!"); + public static void main(String[] args) { Tictactoe ttt = new Tictactoe(); + Cli cli = new Cli(System.out); Scanner scan = new Scanner(System.in); - ttt.print(); + ttt.print(cli); while (scan.hasNext()) { ttt.update(scan.next()); - ttt.print(); + ttt.print(cli); } } } diff --git a/src/test/java/Application/CliTest.java b/src/test/java/Application/CliTest.java new file mode 100644 index 0000000..747cf61 --- /dev/null +++ b/src/test/java/Application/CliTest.java @@ -0,0 +1,35 @@ +package Application; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class CliTest { + + private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + private final PrintStream originalOut = System.out; + + Cli cli; + + @BeforeEach + void setUp() { + System.setOut(new PrintStream(outContent)); + cli = new Cli(System.out); + } + + @AfterEach + void tearDown() { + System.setOut(originalOut); + } + + @Test + void getPrintStream() { + cli.getPrintStream().println("Hello World!"); + assertEquals("Hello World!\n", outContent.toString().replaceAll("\r", "")); + } +} \ No newline at end of file diff --git a/src/test/java/Application/MenuManagerTest.java b/src/test/java/Application/MenuManagerTest.java index 3ad5701..7497abb 100644 --- a/src/test/java/Application/MenuManagerTest.java +++ b/src/test/java/Application/MenuManagerTest.java @@ -78,7 +78,7 @@ class MenuManagerTest { } @Test - void getFormattedMenuList(){ + void getFormattedMenuList() { assertEquals(mm.getFormattedMenuList(), "1: Menu1\n2: Menu2\n"); mm.select(0); assertEquals(mm.getFormattedMenuList(), "1: Menu1.1\n"); diff --git a/src/test/java/Application/MenuTest.java b/src/test/java/Application/MenuTest.java index d0494b6..04b677a 100644 --- a/src/test/java/Application/MenuTest.java +++ b/src/test/java/Application/MenuTest.java @@ -4,8 +4,6 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.util.ArrayList; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -39,7 +37,7 @@ class MenuTest { } @Test - void getPreviousMenu(){ + void getPreviousMenu() { assertTrue(rootMenu.getPreviousMenu() == null && rootMenu.getMenu(0).getPreviousMenu().getName().equals("Root") && rootMenu.getMenu(0).getMenu(0).getPreviousMenu().getName().equals("Menu1")); } diff --git a/src/test/java/Game/GameTest.java b/src/test/java/Game/GameTest.java index 57c399e..c90b419 100644 --- a/src/test/java/Game/GameTest.java +++ b/src/test/java/Game/GameTest.java @@ -2,42 +2,17 @@ package Game; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.util.ArrayList; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.mock; class GameTest { - private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); - private final PrintStream originalOut = System.out; - - Game game; - @BeforeEach void setUp() { - System.setOut(new PrintStream(outContent)); - game = mock(Game.class, Mockito.CALLS_REAL_METHODS); + } @AfterEach void tearDown() { - System.setOut(originalOut); - } - @Test - public void print() { - ArrayList testOB = new ArrayList<>(); - testOB.add("Hello"); - testOB.add("World"); - testOB.add("!!!"); - game.setOutputBuffer(testOB); - game.print(); - assertEquals("Hello\nWorld\n!!!\n", outContent.toString().replaceAll("\r", "")); } + } \ No newline at end of file diff --git a/src/test/java/Game/TicTacToe/BoardTest.java b/src/test/java/Game/TicTacToe/BoardTest.java index 40218e4..8a5450a 100644 --- a/src/test/java/Game/TicTacToe/BoardTest.java +++ b/src/test/java/Game/TicTacToe/BoardTest.java @@ -1,6 +1,5 @@ package Game.TicTacToe; -import Game.Tictactoe; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -9,7 +8,6 @@ import org.mockito.internal.util.reflection.FieldSetter; import java.util.Arrays; import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.mock; class BoardTest { diff --git a/src/test/java/Game/TictactoeTest.java b/src/test/java/Game/TictactoeTest.java index 5eb08d8..1dc0fb2 100644 --- a/src/test/java/Game/TictactoeTest.java +++ b/src/test/java/Game/TictactoeTest.java @@ -2,13 +2,6 @@ package Game; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.util.ArrayList; - -import static org.junit.jupiter.api.Assertions.*; class TictactoeTest { From 046403eb8fae0d713210aa6023e6a993cb474b3a Mon Sep 17 00:00:00 2001 From: Nick Stolbov Date: Thu, 27 Jan 2022 18:54:25 +0100 Subject: [PATCH 08/14] Added getScanner() method for Cli class with test for testing stream integration --- src/main/java/Application/Cli.java | 12 +++++++++++- src/main/java/Main.java | 4 ++-- src/test/java/Application/CliTest.java | 15 ++++++++++++++- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/main/java/Application/Cli.java b/src/main/java/Application/Cli.java index a2d787d..b786871 100644 --- a/src/main/java/Application/Cli.java +++ b/src/main/java/Application/Cli.java @@ -1,16 +1,26 @@ package Application; +import java.io.InputStream; import java.io.PrintStream; +import java.util.Scanner; public class Cli { private PrintStream printStream; + private InputStream inputStream; + private Scanner scanner; - public Cli(PrintStream printStream) { + public Cli(PrintStream printStream, InputStream inputStream) { this.printStream = printStream; + this.inputStream = inputStream; + this.scanner = new Scanner(inputStream); } public PrintStream getPrintStream() { return this.printStream; } + + public Scanner getScanner(){ + return this.scanner; + } } diff --git a/src/main/java/Main.java b/src/main/java/Main.java index cf9689e..d286686 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -7,8 +7,8 @@ public class Main { public static void main(String[] args) { Tictactoe ttt = new Tictactoe(); - Cli cli = new Cli(System.out); - Scanner scan = new Scanner(System.in); + Cli cli = new Cli(System.out, System.in); + Scanner scan = cli.getScanner(); ttt.print(cli); while (scan.hasNext()) { ttt.update(scan.next()); diff --git a/src/test/java/Application/CliTest.java b/src/test/java/Application/CliTest.java index 747cf61..bc81251 100644 --- a/src/test/java/Application/CliTest.java +++ b/src/test/java/Application/CliTest.java @@ -4,7 +4,9 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.InputStream; import java.io.PrintStream; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -13,23 +15,34 @@ class CliTest { private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); private final PrintStream originalOut = System.out; + private final ByteArrayInputStream inContent = new ByteArrayInputStream("Test".getBytes()); + private final InputStream originalIn = System.in; Cli cli; @BeforeEach void setUp() { System.setOut(new PrintStream(outContent)); - cli = new Cli(System.out); + System.setIn(inContent); + cli = new Cli(System.out, System.in); } @AfterEach void tearDown() { System.setOut(originalOut); + System.setIn(originalIn); } + //Only tests correct stream integration, other methods are provided @Test void getPrintStream() { cli.getPrintStream().println("Hello World!"); assertEquals("Hello World!\n", outContent.toString().replaceAll("\r", "")); } + + //Only tests correct stream integration, other methods are provided + @Test + void getScanner() { + assertEquals(cli.getScanner().next(), "Test"); + } } \ No newline at end of file From f41dacc1f13dea937c6d03042692c414956daa77 Mon Sep 17 00:00:00 2001 From: Nick Stolbov Date: Thu, 27 Jan 2022 19:54:00 +0100 Subject: [PATCH 09/14] Added clearConsole() method to Cli class with test(always true because it uses external processes) --- src/main/java/Application/Cli.java | 19 +++++++++++++++++++ src/test/java/Application/CliTest.java | 7 +++++++ 2 files changed, 26 insertions(+) diff --git a/src/main/java/Application/Cli.java b/src/main/java/Application/Cli.java index b786871..2b93962 100644 --- a/src/main/java/Application/Cli.java +++ b/src/main/java/Application/Cli.java @@ -23,4 +23,23 @@ public class Cli { public Scanner getScanner(){ return this.scanner; } + + public void clearConsole(){ + try{ + String operatingSystem = System.getProperty("os.name");//Check the current operating system + + if(operatingSystem.contains("Windows")){ + ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "cls"); + Process startProcess = pb.inheritIO().start(); + startProcess.waitFor(); + } else { + ProcessBuilder pb = new ProcessBuilder("clear"); + Process startProcess = pb.inheritIO().start(); + + startProcess.waitFor(); + } + }catch(Exception e){ + this.getPrintStream().println(e); + } + } } diff --git a/src/test/java/Application/CliTest.java b/src/test/java/Application/CliTest.java index bc81251..fbc4306 100644 --- a/src/test/java/Application/CliTest.java +++ b/src/test/java/Application/CliTest.java @@ -10,6 +10,7 @@ import java.io.InputStream; import java.io.PrintStream; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; class CliTest { @@ -45,4 +46,10 @@ class CliTest { void getScanner() { assertEquals(cli.getScanner().next(), "Test"); } + + //Cannot test because it uses external processes + @Test + void clearConsole() { + assertTrue(true); + } } \ No newline at end of file From 20220af27862a5e8f3f0dcd4e29eed855a518f9e Mon Sep 17 00:00:00 2001 From: Nick Stolbov Date: Thu, 27 Jan 2022 19:45:47 +0100 Subject: [PATCH 10/14] Added application main loop for updating, printing the games and quiting at anytime with test for correctly terminating. --- src/main/java/Application/App.java | 46 ++++++++++++++++++++++++++ src/main/java/Main.java | 10 ++---- src/test/java/Application/AppTest.java | 42 +++++++++++++++++++++++ 3 files changed, 91 insertions(+), 7 deletions(-) create mode 100644 src/main/java/Application/App.java create mode 100644 src/test/java/Application/AppTest.java diff --git a/src/main/java/Application/App.java b/src/main/java/Application/App.java new file mode 100644 index 0000000..da2f9bd --- /dev/null +++ b/src/main/java/Application/App.java @@ -0,0 +1,46 @@ +package Application; + +import Game.Tictactoe; + +public class App { + + private boolean isRunning = false; + private Cli cli; + + private Tictactoe ttt; + + public App(Cli cli) { + this.cli = cli; + init(); + } + + private void init() { + ttt = new Tictactoe(); + cli.getPrintStream().println("Welcome to the Cli Arcade Service!"); + cli.getPrintStream().println("Press 'q' at any time to stop the application"); + ttt.print(cli); + } + + public void start() { + isRunning = true; + while (isRunning) { + String input = cli.getScanner().next(); + if (input.equals("q")) { + stop(); + return; + } else { + ttt.update(input); + ttt.print(cli); + } + } + } + + public void stop() { + isRunning = false; + cli.getPrintStream().println("Stopping application..."); + } + + public boolean isRunning() { + return isRunning; + } +} diff --git a/src/main/java/Main.java b/src/main/java/Main.java index d286686..7c937c5 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -1,3 +1,4 @@ +import Application.App; import Application.Cli; import Game.Tictactoe; @@ -6,13 +7,8 @@ import java.util.Scanner; public class Main { public static void main(String[] args) { - Tictactoe ttt = new Tictactoe(); Cli cli = new Cli(System.out, System.in); - Scanner scan = cli.getScanner(); - ttt.print(cli); - while (scan.hasNext()) { - ttt.update(scan.next()); - ttt.print(cli); - } + App app = new App(cli); + app.start(); } } diff --git a/src/test/java/Application/AppTest.java b/src/test/java/Application/AppTest.java new file mode 100644 index 0000000..4813ea6 --- /dev/null +++ b/src/test/java/Application/AppTest.java @@ -0,0 +1,42 @@ +package Application; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.*; +import java.nio.charset.StandardCharsets; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class AppTest { + + private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + private final ByteArrayInputStream inContent = new ByteArrayInputStream("1\n2\nq\n".getBytes()); + + App app; + Cli cli; + + @BeforeEach + void setUp() { + cli = new Cli(new PrintStream(outContent), inContent); + app = new App(cli); + } + + @AfterEach + void tearDown() { + } + + //inContent has the 'q' at the end, to terminated the loop and set isRunning to false + @Test + void stop() { + ByteArrayInputStream input = new ByteArrayInputStream("1\n2\nq\n".getBytes()); + cli = new Cli(new PrintStream(outContent), input); + app = new App(cli); + app.start(); + assertFalse(app.isRunning()); + } + +} \ No newline at end of file From 71bce709ab5ccb62f279d706c7cfbd246205a274 Mon Sep 17 00:00:00 2001 From: Nick Stolbov Date: Thu, 27 Jan 2022 20:54:41 +0100 Subject: [PATCH 11/14] Added deactivation for clearConsole() method because it would throw warnings otherwise. --- src/main/java/Application/App.java | 1 + src/main/java/Application/Cli.java | 10 ++++++++++ src/test/java/Application/AppTest.java | 2 ++ 3 files changed, 13 insertions(+) diff --git a/src/main/java/Application/App.java b/src/main/java/Application/App.java index da2f9bd..86c4865 100644 --- a/src/main/java/Application/App.java +++ b/src/main/java/Application/App.java @@ -30,6 +30,7 @@ public class App { return; } else { ttt.update(input); + cli.clearConsole(); ttt.print(cli); } } diff --git a/src/main/java/Application/Cli.java b/src/main/java/Application/Cli.java index 2b93962..0defedf 100644 --- a/src/main/java/Application/Cli.java +++ b/src/main/java/Application/Cli.java @@ -6,6 +6,8 @@ import java.util.Scanner; public class Cli { + private boolean isClearConsoleActive = true; + private PrintStream printStream; private InputStream inputStream; private Scanner scanner; @@ -14,6 +16,7 @@ public class Cli { this.printStream = printStream; this.inputStream = inputStream; this.scanner = new Scanner(inputStream); + isClearConsoleActive = true; } public PrintStream getPrintStream() { @@ -25,6 +28,8 @@ public class Cli { } public void clearConsole(){ + if(!isClearConsoleActive) + return; try{ String operatingSystem = System.getProperty("os.name");//Check the current operating system @@ -42,4 +47,9 @@ public class Cli { this.getPrintStream().println(e); } } + + public void setClearConsoleActive(boolean clearConsoleActive) { + isClearConsoleActive = clearConsoleActive; + } + } diff --git a/src/test/java/Application/AppTest.java b/src/test/java/Application/AppTest.java index 4813ea6..c3b25e2 100644 --- a/src/test/java/Application/AppTest.java +++ b/src/test/java/Application/AppTest.java @@ -22,6 +22,7 @@ class AppTest { @BeforeEach void setUp() { cli = new Cli(new PrintStream(outContent), inContent); + cli.setClearConsoleActive(false); app = new App(cli); } @@ -34,6 +35,7 @@ class AppTest { void stop() { ByteArrayInputStream input = new ByteArrayInputStream("1\n2\nq\n".getBytes()); cli = new Cli(new PrintStream(outContent), input); + cli.setClearConsoleActive(false); app = new App(cli); app.start(); assertFalse(app.isRunning()); From daa43a48564c2e8db20f596aff0f3bd1a33b2eaa Mon Sep 17 00:00:00 2001 From: Nick Stolbov Date: Sat, 29 Jan 2022 00:08:15 +0100 Subject: [PATCH 12/14] Added Menu navigation to App class with weak test case (depending on implementation) --- src/main/java/Application/App.java | 87 +++++++++++++++++++++++--- src/test/java/Application/AppTest.java | 15 +++-- 2 files changed, 91 insertions(+), 11 deletions(-) diff --git a/src/main/java/Application/App.java b/src/main/java/Application/App.java index 86c4865..db7c8c5 100644 --- a/src/main/java/Application/App.java +++ b/src/main/java/Application/App.java @@ -1,13 +1,20 @@ package Application; +import Game.Game; import Game.Tictactoe; +import java.util.ArrayList; +import java.util.Scanner; + public class App { private boolean isRunning = false; private Cli cli; - private Tictactoe ttt; + private boolean inMenu = true; + private MenuManager menuManager; + + private Game currentGame; public App(Cli cli) { this.cli = cli; @@ -15,23 +22,33 @@ public class App { } private void init() { - ttt = new Tictactoe(); + menuManager = initMenuManager(); + + cli.clearConsole(); cli.getPrintStream().println("Welcome to the Cli Arcade Service!"); cli.getPrintStream().println("Press 'q' at any time to stop the application"); - ttt.print(cli); + cli.getPrintStream().println("Select a item by typing the number next to it"); + + cli.getPrintStream().print(menuManager.getFormattedMenuList()); } public void start() { isRunning = true; while (isRunning) { - String input = cli.getScanner().next(); + String input = cli.getScanner().nextLine(); if (input.equals("q")) { stop(); return; } else { - ttt.update(input); - cli.clearConsole(); - ttt.print(cli); + if (inMenu) { + cli.clearConsole(); + cli.getPrintStream().println("Select a item by typing the number next to it"); + selectMenuItem(input); + } else { + cli.clearConsole(); + currentGame.update(input); + currentGame.print(cli); + } } } } @@ -44,4 +61,60 @@ public class App { public boolean isRunning() { return isRunning; } + + public Game getCurrentGame() { + return this.currentGame; + } + + private MenuManager initMenuManager() { + MenuManager mm = new MenuManager(); + ArrayList gameList = new ArrayList<>(); + + gameList.add(new Menu("Tic Tac Toe")); + gameList.add(new Menu("Tic Toe")); + + Menu gameMenu = new Menu("Games"); + + gameMenu.addMenu(new Menu("Back")); + for (Menu game : gameList) { + game.addMenu(new Menu("Back")); + gameMenu.addMenu(game); + } + mm.addMenu(gameMenu); + + return mm; + } + + protected void selectMenuItem(String input) { + Scanner scanner = new Scanner(input); + if (scanner.hasNextInt()) { + int index = scanner.nextInt() - 1; + menuManager.select(index); + if (menuManager.getCurrentMenu() != null) { + switch (menuManager.getCurrentMenu().getName()) { + case "Back": + try { + menuManager.back(); + menuManager.back(); + } catch (Exception e) { + e.printStackTrace(); + } + break; + case "Tic Tac Toe": + setCurrentGame(new Tictactoe()); + return; + default: + break; + } + } + } + cli.getPrintStream().print(menuManager.getFormattedMenuList()); + } + + private void setCurrentGame(Game game) { + inMenu = false; + currentGame = game; + cli.clearConsole(); + currentGame.print(cli); + } } diff --git a/src/test/java/Application/AppTest.java b/src/test/java/Application/AppTest.java index c3b25e2..13f9bac 100644 --- a/src/test/java/Application/AppTest.java +++ b/src/test/java/Application/AppTest.java @@ -4,12 +4,11 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.io.*; -import java.nio.charset.StandardCharsets; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; class AppTest { @@ -41,4 +40,12 @@ class AppTest { assertFalse(app.isRunning()); } + @Test + void selectMenuItem() { + assertNull(app.getCurrentGame()); + app.selectMenuItem("1"); + assertNull(app.getCurrentGame()); + app.selectMenuItem("2"); + assertNotNull(app.getCurrentGame()); + } } \ No newline at end of file From 838b3353238016f7dea203ad9699477a6357391b Mon Sep 17 00:00:00 2001 From: Nick Stolbov Date: Sat, 29 Jan 2022 12:44:41 +0100 Subject: [PATCH 13/14] Change stop command to "exit" and added "q" command for going back for better navigation --- src/main/java/Application/App.java | 44 ++++++++++++++++++++------ src/test/java/Application/AppTest.java | 6 ++-- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/main/java/Application/App.java b/src/main/java/Application/App.java index db7c8c5..751218f 100644 --- a/src/main/java/Application/App.java +++ b/src/main/java/Application/App.java @@ -24,27 +24,25 @@ public class App { private void init() { menuManager = initMenuManager(); - cli.clearConsole(); - cli.getPrintStream().println("Welcome to the Cli Arcade Service!"); - cli.getPrintStream().println("Press 'q' at any time to stop the application"); - cli.getPrintStream().println("Select a item by typing the number next to it"); - - cli.getPrintStream().print(menuManager.getFormattedMenuList()); + goToMenu(); } public void start() { isRunning = true; while (isRunning) { String input = cli.getScanner().nextLine(); - if (input.equals("q")) { + if (input.equals("exit")) { stop(); return; } else { if (inMenu) { cli.clearConsole(); - cli.getPrintStream().println("Select a item by typing the number next to it"); selectMenuItem(input); } else { + if (input.equals("q")) { + goToMenu(); + continue; + } cli.clearConsole(); currentGame.update(input); currentGame.print(cli); @@ -71,7 +69,6 @@ public class App { ArrayList gameList = new ArrayList<>(); gameList.add(new Menu("Tic Tac Toe")); - gameList.add(new Menu("Tic Toe")); Menu gameMenu = new Menu("Games"); @@ -87,6 +84,11 @@ public class App { protected void selectMenuItem(String input) { Scanner scanner = new Scanner(input); + + if (input.equals("q") && !menuManager.inRootMenu()) { + goToMenu(); + } + if (scanner.hasNextInt()) { int index = scanner.nextInt() - 1; menuManager.select(index); @@ -108,7 +110,7 @@ public class App { } } } - cli.getPrintStream().print(menuManager.getFormattedMenuList()); + printMenu(); } private void setCurrentGame(Game game) { @@ -117,4 +119,26 @@ public class App { cli.clearConsole(); currentGame.print(cli); } + + private void goToMenu() { + inMenu = true; + currentGame = null; + while (!menuManager.inRootMenu()) { + try { + menuManager.back(); + } catch (Exception e) { + e.printStackTrace(); + } + } + printMenu(); + } + + private void printMenu() { + cli.clearConsole(); + cli.getPrintStream().println("Welcome to the Cli Arcade Service!"); + cli.getPrintStream().println("Type 'exit' at any time to stop the application"); + cli.getPrintStream().println("Select a item by typing the number next to it"); + + cli.getPrintStream().print(menuManager.getFormattedMenuList()); + } } diff --git a/src/test/java/Application/AppTest.java b/src/test/java/Application/AppTest.java index 13f9bac..8593c9d 100644 --- a/src/test/java/Application/AppTest.java +++ b/src/test/java/Application/AppTest.java @@ -13,7 +13,7 @@ import static org.junit.jupiter.api.Assertions.*; class AppTest { private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); - private final ByteArrayInputStream inContent = new ByteArrayInputStream("1\n2\nq\n".getBytes()); + private final ByteArrayInputStream inContent = new ByteArrayInputStream("1\n2\nexit\n".getBytes()); App app; Cli cli; @@ -32,7 +32,7 @@ class AppTest { //inContent has the 'q' at the end, to terminated the loop and set isRunning to false @Test void stop() { - ByteArrayInputStream input = new ByteArrayInputStream("1\n2\nq\n".getBytes()); + ByteArrayInputStream input = new ByteArrayInputStream("1\n2\nexit\n".getBytes()); cli = new Cli(new PrintStream(outContent), input); cli.setClearConsoleActive(false); app = new App(cli); @@ -47,5 +47,7 @@ class AppTest { assertNull(app.getCurrentGame()); app.selectMenuItem("2"); assertNotNull(app.getCurrentGame()); + app.selectMenuItem("q"); + assertNull(app.getCurrentGame()); } } \ No newline at end of file From 88d236c32832afafcf6bbf149eb02712f46de264 Mon Sep 17 00:00:00 2001 From: Nick Stolbov Date: Sat, 29 Jan 2022 12:50:02 +0100 Subject: [PATCH 14/14] Changed SNAPSHOT Version to 0.1.5 for release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1b41f0b..6f1b0b4 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.example CliArcadeService - 0.1.0-SNAPSHOT + 0.1.5-SNAPSHOT 15