{"id":"unit-testing-review","slug":"end-of-part-6","title":"Putting it all together","text":"This module's tools, side by side:\n\n| Tool | Example |\n| --- | --- |\n| Input for a Scanner, written in the code | `new Scanner(\"12\\n8\\n\")` |\n| A test method | `@Test public void parkingTakesOneSpot()` |\n| Compare with the expected value | `assertEquals(2, garage.freeSpots())` |\n| Compare doubles, with a delta | `assertEquals(33.33, garage.percentFull(), 0.01)` |\n| Check a boolean | `assertTrue(garage.park())`, `assertFalse(garage.park())` |\n| The same start for every test | `@Before` |\n\nThe last one is new. When every test starts by making the same object, the test class can do that in one place: a method marked `@Before` runs before each test. It puts the object in an instance variable of the test class, and the tests use it from there.\n\nHere it is in the tests of a coin flip log. Someone flips a coin and writes down each result, `heads` or `tails`, one per line, and the log reads them from a Scanner. The tests give it Strings, so the idea of the second step and JUnit work together:\n\n```java\n// ==== FlipLog.java ====\nimport java.util.Scanner;\n\npublic class FlipLog {\n    private int heads;\n    private int tails;\n\n    public FlipLog() {\n        this.heads = 0;\n        this.tails = 0;\n    }\n\n    public void readFlips(Scanner scanner) {\n        while (scanner.hasNextLine()) {\n            String flip = scanner.nextLine();\n            if (flip.equals(\"heads\")) {\n                this.heads++;\n            } else if (flip.equals(\"tails\")) {\n                this.tails++;\n            }\n        }\n    }\n\n    public int headsCount() {\n        return this.heads;\n    }\n\n    public int tailsCount() {\n        return this.tails;\n    }\n\n    public boolean mostlyHeads() {\n        return this.heads > this.tails;\n    }\n}\n// ==== FlipLogTest.java ====\nimport static org.junit.Assert.*;\n\nimport java.util.Scanner;\nimport org.junit.Before;\nimport org.junit.Test;\n\npublic class FlipLogTest {\n    private FlipLog log;\n\n    @Before\n    public void setUp() {\n        this.log = new FlipLog();\n    }\n\n    @Test\n    public void countsBothSides() {\n        this.log.readFlips(new Scanner(\"heads\\ntails\\nheads\\n\"));\n        assertEquals(2, this.log.headsCount());\n        assertEquals(1, this.log.tailsCount());\n    }\n\n    @Test\n    public void otherLinesAreIgnored() {\n        this.log.readFlips(new Scanner(\"edge\\n\\nheads\\n\"));\n        assertEquals(1, this.log.headsCount());\n        assertEquals(0, this.log.tailsCount());\n    }\n\n    @Test\n    public void moreHeadsIsMostlyHeads() {\n        this.log.readFlips(new Scanner(\"heads\\ntails\\nheads\\n\"));\n        assertTrue(this.log.mostlyHeads());\n    }\n\n    @Test\n    public void tieIsNotMostlyHeads() {\n        this.log.readFlips(new Scanner(\"tails\\nheads\\n\"));\n        assertFalse(this.log.mostlyHeads());\n    }\n}\n```\n\n```output\nFlipLogTest: 4 tests\n  countsBothSides: passed\n  moreHeadsIsMostlyHeads: passed\n  otherLinesAreIgnored: passed\n  tieIsNotMostlyHeads: passed\n4 of 4 tests passed\n```\n\n- `import org.junit.Before;` brings in `@Before`, and `java.util.Scanner` is imported as in any class that uses it.\n- `private FlipLog log;` is an instance variable of the test class, and `setUp()`, marked `@Before`, gives it a new FlipLog.\n- JUnit makes a new FlipLogTest object for every test, and runs `setUp()` on it before the test. So every test gets a new, empty FlipLog of its own: the three flips of `countsBothSides` never reach `tieIsNotMostlyHeads`.\n- Each test gives `readFlips` exactly the input it's about, from an empty line to a tie, with no typing.\n\n### The end of part 6\n\nThis step ends the material of the MOOC's sixth part. Part 6 put lists inside objects: a class kept a list in an instance variable, and its methods decided what could be done with it. Then programs were split in two, with the program's logic in classes of its own and a user interface class that reads the commands and prints the answers, so that each part can change without the other. This module was about knowing that it all works: reading a stack trace, troubleshooting step by step, giving code its input from a String, and unit tests with JUnit, written after the code or before it. Next, part 7 looks at different ways to structure a program, and at algorithms for sorting and searching. Part 6 closes with [the MOOC's page on complex programs](https://java-programming.mooc.fi/part-6/4-complex-programs) on its own site, for reading only.\n","task":"A timesheet reads the hours worked each day, one number per line, until the input ends. Empty lines are skipped, and reading goes on after them. `totalHours()` adds up the hours, and `overtimeDays()` counts the days of more than 8 hours. `TimesheetTest` makes a new Timesheet before each test with `@Before`, and has one test.\n\nWrite tests that give `read` its input as a String, and that catch a Timesheet that counts a day of exactly 8 hours as overtime. Two more versions, hidden, have bugs in how they read the lines.\n","kind":"code","seed":"// ==== TimesheetTest.java ====\nimport static org.junit.Assert.*;\n\nimport java.util.Scanner;\nimport org.junit.Before;\nimport org.junit.Test;\n\npublic class TimesheetTest {\n    private Timesheet sheet;\n\n    @Before\n    public void setUp() {\n        this.sheet = new Timesheet();\n    }\n\n    @Test\n    public void noDaysMeansNoHours() {\n        this.sheet.read(new Scanner(\"\"));\n        assertEquals(0, this.sheet.totalHours());\n    }\n}\n\n// ==== Timesheet.java ====\nimport java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class Timesheet {\n    private ArrayList<Integer> days;\n\n    public Timesheet() {\n        this.days = new ArrayList<>();\n    }\n\n    public void read(Scanner scanner) {\n        while (scanner.hasNextLine()) {\n            String line = scanner.nextLine();\n            if (!line.isEmpty()) {\n                this.days.add(Integer.valueOf(line));\n            }\n        }\n    }\n\n    public int totalHours() {\n        int total = 0;\n        for (int hours : this.days) {\n            total += hours;\n        }\n        return total;\n    }\n\n    public int overtimeDays() {\n        int count = 0;\n        for (int hours : this.days) {\n            if (hours > 8) {\n                count++;\n            }\n        }\n        return count;\n    }\n}\n","solution":"// ==== TimesheetTest.java ====\nimport static org.junit.Assert.*;\n\nimport java.util.Scanner;\nimport org.junit.Before;\nimport org.junit.Test;\n\npublic class TimesheetTest {\n    private Timesheet sheet;\n\n    @Before\n    public void setUp() {\n        this.sheet = new Timesheet();\n    }\n\n    @Test\n    public void noDaysMeansNoHours() {\n        this.sheet.read(new Scanner(\"\"));\n        assertEquals(0, this.sheet.totalHours());\n    }\n\n    @Test\n    public void eightHoursIsNotOvertime() {\n        this.sheet.read(new Scanner(\"8\\n9\\n7\\n\"));\n        assertEquals(1, this.sheet.overtimeDays());\n    }\n\n    @Test\n    public void hoursAddUp() {\n        this.sheet.read(new Scanner(\"8\\n9\\n7\\n\"));\n        assertEquals(24, this.sheet.totalHours());\n    }\n\n    @Test\n    public void readingGoesOnAfterAnEmptyLine() {\n        this.sheet.read(new Scanner(\"6\\n\\n10\\n\"));\n        assertEquals(16, this.sheet.totalHours());\n    }\n}\n\n// ==== Timesheet.java ====\nimport java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class Timesheet {\n    private ArrayList<Integer> days;\n\n    public Timesheet() {\n        this.days = new ArrayList<>();\n    }\n\n    public void read(Scanner scanner) {\n        while (scanner.hasNextLine()) {\n            String line = scanner.nextLine();\n            if (!line.isEmpty()) {\n                this.days.add(Integer.valueOf(line));\n            }\n        }\n    }\n\n    public int totalHours() {\n        int total = 0;\n        for (int hours : this.days) {\n            total += hours;\n        }\n        return total;\n    }\n\n    public int overtimeDays() {\n        int count = 0;\n        for (int hours : this.days) {\n            if (hours > 8) {\n                count++;\n            }\n        }\n        return count;\n    }\n}\n","hints":["Each test reads its own input: `this.sheet.read(new Scanner(\"8\\n9\\n7\\n\"));`, and then checks `overtimeDays()` or `totalHours()`. A day of exactly 8 hours is the limit, and an empty line in the middle of the input is the edge the hidden versions trip on.","For example, after reading `\"8\\n9\\n7\\n\"`, `assertEquals(1, this.sheet.overtimeDays());`. And after reading `\"6\\n\\n10\\n\"`, `assertEquals(16, this.sheet.totalHours());`."],"tests":[{"name":"The Timesheet as it is","stdin":"","junit":"TimesheetTest","outcome":"pass","expect":"","hidden":false},{"name":"A Timesheet that counts a day of exactly 8 hours as overtime","stdin":"","junit":"TimesheetTest","outcome":"fail","replace":{"Timesheet.java":"import java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class Timesheet {\n    private ArrayList<Integer> days;\n\n    public Timesheet() {\n        this.days = new ArrayList<>();\n    }\n\n    public void read(Scanner scanner) {\n        while (scanner.hasNextLine()) {\n            String line = scanner.nextLine();\n            if (!line.isEmpty()) {\n                this.days.add(Integer.valueOf(line));\n            }\n        }\n    }\n\n    public int totalHours() {\n        int total = 0;\n        for (int hours : this.days) {\n            total += hours;\n        }\n        return total;\n    }\n\n    public int overtimeDays() {\n        int count = 0;\n        for (int hours : this.days) {\n            if (hours >= 8) {\n                count++;\n            }\n        }\n        return count;\n    }\n}\n"},"expect":"","hidden":false},{"name":"A Timesheet with a bug in reading","stdin":"","junit":"TimesheetTest","outcome":"fail","replace":{"Timesheet.java":"import java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class Timesheet {\n    private ArrayList<Integer> days;\n\n    public Timesheet() {\n        this.days = new ArrayList<>();\n    }\n\n    public void read(Scanner scanner) {\n        while (scanner.hasNextLine()) {\n            String line = scanner.nextLine();\n            if (line.isEmpty()) {\n                break;\n            }\n            this.days.add(Integer.valueOf(line));\n        }\n    }\n\n    public int totalHours() {\n        int total = 0;\n        for (int hours : this.days) {\n            total += hours;\n        }\n        return total;\n    }\n\n    public int overtimeDays() {\n        int count = 0;\n        for (int hours : this.days) {\n            if (hours > 8) {\n                count++;\n            }\n        }\n        return count;\n    }\n}\n"},"expect":"","hidden":true},{"name":"Another Timesheet with a bug in reading","stdin":"","junit":"TimesheetTest","outcome":"fail","replace":{"Timesheet.java":"import java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class Timesheet {\n    private ArrayList<Integer> days;\n\n    public Timesheet() {\n        this.days = new ArrayList<>();\n    }\n\n    public void read(Scanner scanner) {\n        while (scanner.hasNextLine()) {\n            String line = scanner.nextLine();\n            this.days.add(Integer.valueOf(line));\n        }\n    }\n\n    public int totalHours() {\n        int total = 0;\n        for (int hours : this.days) {\n            total += hours;\n        }\n        return total;\n    }\n\n    public int overtimeDays() {\n        int count = 0;\n        for (int hours : this.days) {\n            if (hours > 8) {\n                count++;\n            }\n        }\n        return count;\n    }\n}\n"},"expect":"","hidden":true}],"require":[],"forbid":[],"more":[{"task":"A quiz gives 10 points for a right answer and nothing for a wrong one. Three right answers in a row give 5 bonus points, and then the count starts over. A wrong answer ends the streak. `QuizScoreTest` is right, but two of its tests fail on `QuizScore`.\n\nRun the tests and read the report: each failing test's name says which rule is broken. Fix `QuizScore` one bug at a time, running the tests after each fix. The checks run the tests of `QuizScoreTest` as they are given here (changing them won't help), and more tests of their own.\n","kind":"code","seed":"// ==== QuizScore.java ====\npublic class QuizScore {\n    private int points;\n    private int streak;\n\n    public QuizScore() {\n        this.points = 0;\n        this.streak = 0;\n    }\n\n    public void answer(boolean correct) {\n        if (correct) {\n            this.points += 10;\n            this.streak++;\n            if (this.streak > 3) {\n                this.points += 5;\n                this.streak = 0;\n            }\n        }\n    }\n\n    public int getPoints() {\n        return this.points;\n    }\n}\n\n// ==== QuizScoreTest.java ====\nimport static org.junit.Assert.*;\n\nimport org.junit.Before;\nimport org.junit.Test;\n\npublic class QuizScoreTest {\n    private QuizScore score;\n\n    @Before\n    public void setUp() {\n        this.score = new QuizScore();\n    }\n\n    @Test\n    public void rightAnswerGivesTenPoints() {\n        this.score.answer(true);\n        assertEquals(10, this.score.getPoints());\n    }\n\n    @Test\n    public void wrongAnswerGivesNothing() {\n        this.score.answer(false);\n        assertEquals(0, this.score.getPoints());\n    }\n\n    @Test\n    public void threeInARowGiveABonus() {\n        this.score.answer(true);\n        this.score.answer(true);\n        this.score.answer(true);\n        assertEquals(35, this.score.getPoints());\n    }\n\n    @Test\n    public void wrongAnswerEndsTheStreak() {\n        this.score.answer(true);\n        this.score.answer(true);\n        this.score.answer(false);\n        this.score.answer(true);\n        this.score.answer(true);\n        assertEquals(40, this.score.getPoints());\n    }\n}\n","solution":"// ==== QuizScore.java ====\npublic class QuizScore {\n    private int points;\n    private int streak;\n\n    public QuizScore() {\n        this.points = 0;\n        this.streak = 0;\n    }\n\n    public void answer(boolean correct) {\n        if (correct) {\n            this.points += 10;\n            this.streak++;\n            if (this.streak == 3) {\n                this.points += 5;\n                this.streak = 0;\n            }\n        } else {\n            this.streak = 0;\n        }\n    }\n\n    public int getPoints() {\n        return this.points;\n    }\n}\n\n// ==== QuizScoreTest.java ====\nimport static org.junit.Assert.*;\n\nimport org.junit.Before;\nimport org.junit.Test;\n\npublic class QuizScoreTest {\n    private QuizScore score;\n\n    @Before\n    public void setUp() {\n        this.score = new QuizScore();\n    }\n\n    @Test\n    public void rightAnswerGivesTenPoints() {\n        this.score.answer(true);\n        assertEquals(10, this.score.getPoints());\n    }\n\n    @Test\n    public void wrongAnswerGivesNothing() {\n        this.score.answer(false);\n        assertEquals(0, this.score.getPoints());\n    }\n\n    @Test\n    public void threeInARowGiveABonus() {\n        this.score.answer(true);\n        this.score.answer(true);\n        this.score.answer(true);\n        assertEquals(35, this.score.getPoints());\n    }\n\n    @Test\n    public void wrongAnswerEndsTheStreak() {\n        this.score.answer(true);\n        this.score.answer(true);\n        this.score.answer(false);\n        this.score.answer(true);\n        this.score.answer(true);\n        assertEquals(40, this.score.getPoints());\n    }\n}\n","hints":["`threeInARowGiveABonus` says `expected:<35> but was:<30>`: no bonus after three right answers. Look at the comparison that decides when the bonus comes: `this.streak > 3` is only true on the fourth.","`wrongAnswerEndsTheStreak` fails because nothing happens to `streak` on a wrong answer. Use `this.streak == 3` for the bonus, and add `else { this.streak = 0; }` to the `if (correct)`."],"tests":[{"name":"Your QuizScore with the tests given","stdin":"","junit":"QuizScoreTest","outcome":"pass","replace":{"QuizScoreTest.java":"import static org.junit.Assert.*;\n\nimport org.junit.Before;\nimport org.junit.Test;\n\npublic class QuizScoreTest {\n    private QuizScore score;\n\n    @Before\n    public void setUp() {\n        this.score = new QuizScore();\n    }\n\n    @Test\n    public void rightAnswerGivesTenPoints() {\n        this.score.answer(true);\n        assertEquals(10, this.score.getPoints());\n    }\n\n    @Test\n    public void wrongAnswerGivesNothing() {\n        this.score.answer(false);\n        assertEquals(0, this.score.getPoints());\n    }\n\n    @Test\n    public void threeInARowGiveABonus() {\n        this.score.answer(true);\n        this.score.answer(true);\n        this.score.answer(true);\n        assertEquals(35, this.score.getPoints());\n    }\n\n    @Test\n    public void wrongAnswerEndsTheStreak() {\n        this.score.answer(true);\n        this.score.answer(true);\n        this.score.answer(false);\n        this.score.answer(true);\n        this.score.answer(true);\n        assertEquals(40, this.score.getPoints());\n    }\n}\n"},"expect":"","hidden":false},{"name":"Your QuizScore with more tests","stdin":"","junit":"QuizScoreTest","outcome":"pass","replace":{"QuizScoreTest.java":"import static org.junit.Assert.*;\n\nimport org.junit.Before;\nimport org.junit.Test;\n\npublic class QuizScoreTest {\n    private QuizScore score;\n\n    @Before\n    public void setUp() {\n        this.score = new QuizScore();\n    }\n\n    @Test\n    public void sixInARowGiveTwoBonuses() {\n        for (int i = 0; i < 6; i++) {\n            this.score.answer(true);\n        }\n        assertEquals(70, this.score.getPoints());\n    }\n\n    @Test\n    public void streakCountsAgainAfterAWrongAnswer() {\n        this.score.answer(true);\n        this.score.answer(false);\n        this.score.answer(true);\n        this.score.answer(true);\n        this.score.answer(true);\n        assertEquals(45, this.score.getPoints());\n    }\n\n    @Test\n    public void onlyWrongAnswersGiveNothing() {\n        this.score.answer(false);\n        this.score.answer(false);\n        this.score.answer(false);\n        assertEquals(0, this.score.getPoints());\n    }\n\n    @Test\n    public void twoRightAnswersGiveNoBonus() {\n        this.score.answer(true);\n        this.score.answer(true);\n        assertEquals(20, this.score.getPoints());\n    }\n}\n"},"expect":"","hidden":true}],"require":[],"forbid":[]},{"task":"On moving day, the list of boxes is read from a Scanner, one box per line, until the input ends. A line that starts with `x ` (an x and a space) is a box that's on the van already, like `x books`, and any other line is a box still to load. Empty lines are skipped. Write `MovingBoxes` so the tests of `MovingBoxesTest` pass:\n\n- `read(Scanner scanner)` reads the lines. Calling it again reads more boxes onto the same list.\n- `loadedCount()` returns how many boxes are on the van, and `leftToLoad()` how many are not.\n- `isDone()` returns `true` when no box is left to load.\n\nThe checks run the tests of `MovingBoxesTest` as they are given here (changing them won't help), and more tests of their own.\n","kind":"code","seed":"// ==== MovingBoxes.java ====\nimport java.util.Scanner;\n\npublic class MovingBoxes {\n    public MovingBoxes() {\n    }\n\n    public void read(Scanner scanner) {\n    }\n\n    public int loadedCount() {\n        return 0;\n    }\n\n    public int leftToLoad() {\n        return 0;\n    }\n\n    public boolean isDone() {\n        return false;\n    }\n}\n\n// ==== MovingBoxesTest.java ====\nimport static org.junit.Assert.*;\n\nimport java.util.Scanner;\nimport org.junit.Before;\nimport org.junit.Test;\n\npublic class MovingBoxesTest {\n    private MovingBoxes boxes;\n\n    @Before\n    public void setUp() {\n        this.boxes = new MovingBoxes();\n    }\n\n    @Test\n    public void countsLoadedAndLeft() {\n        this.boxes.read(new Scanner(\"x books\\nlamp\\nx dishes\\n\"));\n        assertEquals(2, this.boxes.loadedCount());\n        assertEquals(1, this.boxes.leftToLoad());\n    }\n\n    @Test\n    public void emptyLinesAreSkipped() {\n        this.boxes.read(new Scanner(\"plants\\n\\nx chairs\\n\"));\n        assertEquals(1, this.boxes.loadedCount());\n        assertEquals(1, this.boxes.leftToLoad());\n    }\n\n    @Test\n    public void doneWhenEverythingIsLoaded() {\n        this.boxes.read(new Scanner(\"x books\\nx rug\\n\"));\n        assertTrue(this.boxes.isDone());\n    }\n\n    @Test\n    public void notDoneWithSomethingLeft() {\n        this.boxes.read(new Scanner(\"x books\\nmirror\\n\"));\n        assertFalse(this.boxes.isDone());\n    }\n}\n","solution":"// ==== MovingBoxes.java ====\nimport java.util.Scanner;\n\npublic class MovingBoxes {\n    private int loaded;\n    private int left;\n\n    public MovingBoxes() {\n        this.loaded = 0;\n        this.left = 0;\n    }\n\n    public void read(Scanner scanner) {\n        while (scanner.hasNextLine()) {\n            String line = scanner.nextLine();\n            if (line.startsWith(\"x \")) {\n                this.loaded++;\n            } else if (!line.isEmpty()) {\n                this.left++;\n            }\n        }\n    }\n\n    public int loadedCount() {\n        return this.loaded;\n    }\n\n    public int leftToLoad() {\n        return this.left;\n    }\n\n    public boolean isDone() {\n        return this.left == 0;\n    }\n}\n\n// ==== MovingBoxesTest.java ====\nimport static org.junit.Assert.*;\n\nimport java.util.Scanner;\nimport org.junit.Before;\nimport org.junit.Test;\n\npublic class MovingBoxesTest {\n    private MovingBoxes boxes;\n\n    @Before\n    public void setUp() {\n        this.boxes = new MovingBoxes();\n    }\n\n    @Test\n    public void countsLoadedAndLeft() {\n        this.boxes.read(new Scanner(\"x books\\nlamp\\nx dishes\\n\"));\n        assertEquals(2, this.boxes.loadedCount());\n        assertEquals(1, this.boxes.leftToLoad());\n    }\n\n    @Test\n    public void emptyLinesAreSkipped() {\n        this.boxes.read(new Scanner(\"plants\\n\\nx chairs\\n\"));\n        assertEquals(1, this.boxes.loadedCount());\n        assertEquals(1, this.boxes.leftToLoad());\n    }\n\n    @Test\n    public void doneWhenEverythingIsLoaded() {\n        this.boxes.read(new Scanner(\"x books\\nx rug\\n\"));\n        assertTrue(this.boxes.isDone());\n    }\n\n    @Test\n    public void notDoneWithSomethingLeft() {\n        this.boxes.read(new Scanner(\"x books\\nmirror\\n\"));\n        assertFalse(this.boxes.isDone());\n    }\n}\n","hints":["The tests only ask for counts, so two `int` instance variables are enough: how many boxes are loaded and how many are left. `read` goes through the lines with `while (scanner.hasNextLine())`.","For each line: `if (line.startsWith(\"x \")) { this.loaded++; } else if (!line.isEmpty()) { this.left++; }`. `isDone()` is `return this.left == 0;`."],"tests":[{"name":"Your MovingBoxes with the tests given","stdin":"","junit":"MovingBoxesTest","outcome":"pass","replace":{"MovingBoxesTest.java":"import static org.junit.Assert.*;\n\nimport java.util.Scanner;\nimport org.junit.Before;\nimport org.junit.Test;\n\npublic class MovingBoxesTest {\n    private MovingBoxes boxes;\n\n    @Before\n    public void setUp() {\n        this.boxes = new MovingBoxes();\n    }\n\n    @Test\n    public void countsLoadedAndLeft() {\n        this.boxes.read(new Scanner(\"x books\\nlamp\\nx dishes\\n\"));\n        assertEquals(2, this.boxes.loadedCount());\n        assertEquals(1, this.boxes.leftToLoad());\n    }\n\n    @Test\n    public void emptyLinesAreSkipped() {\n        this.boxes.read(new Scanner(\"plants\\n\\nx chairs\\n\"));\n        assertEquals(1, this.boxes.loadedCount());\n        assertEquals(1, this.boxes.leftToLoad());\n    }\n\n    @Test\n    public void doneWhenEverythingIsLoaded() {\n        this.boxes.read(new Scanner(\"x books\\nx rug\\n\"));\n        assertTrue(this.boxes.isDone());\n    }\n\n    @Test\n    public void notDoneWithSomethingLeft() {\n        this.boxes.read(new Scanner(\"x books\\nmirror\\n\"));\n        assertFalse(this.boxes.isDone());\n    }\n}\n"},"expect":"","hidden":false},{"name":"Your MovingBoxes with more tests","stdin":"","junit":"MovingBoxesTest","outcome":"pass","replace":{"MovingBoxesTest.java":"import static org.junit.Assert.*;\n\nimport java.util.Scanner;\nimport org.junit.Before;\nimport org.junit.Test;\n\npublic class MovingBoxesTest {\n    private MovingBoxes boxes;\n\n    @Before\n    public void setUp() {\n        this.boxes = new MovingBoxes();\n    }\n\n    @Test\n    public void emptyListIsDone() {\n        this.boxes.read(new Scanner(\"\"));\n        assertEquals(0, this.boxes.loadedCount());\n        assertEquals(0, this.boxes.leftToLoad());\n        assertTrue(this.boxes.isDone());\n    }\n\n    @Test\n    public void anXInsideAWordIsNotLoaded() {\n        this.boxes.read(new Scanner(\"xmas lights\\ntoys\\n\"));\n        assertEquals(0, this.boxes.loadedCount());\n        assertEquals(2, this.boxes.leftToLoad());\n    }\n\n    @Test\n    public void readingTwiceAddsUp() {\n        this.boxes.read(new Scanner(\"x desk\\nshoes\\n\"));\n        this.boxes.read(new Scanner(\"x bed\\n\\n\"));\n        assertEquals(2, this.boxes.loadedCount());\n        assertEquals(1, this.boxes.leftToLoad());\n    }\n\n    @Test\n    public void onlyEmptyLinesIsDone() {\n        this.boxes.read(new Scanner(\"\\n\\n\"));\n        assertEquals(0, this.boxes.leftToLoad());\n        assertTrue(this.boxes.isDone());\n    }\n}\n"},"expect":"","hidden":true}],"require":[],"forbid":[]}]}