package com.github.donkirkby.vograbulary.ultraghost; import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.number.OrderingComparison.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import java.util.Arrays; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import com.github.donkirkby.vograbulary.SerializableTools; import com.github.donkirkby.vograbulary.VograbularyPreferences; public class ComputerStudentTest { private WordList wordList; private FocusField focus; @Rule public ExpectedException thrown = ExpectedException.none(); private enum FocusField {Solution, Challenge}; @Before public void setUp() { wordList = new WordList(); wordList.read(Arrays.asList("PRICE", "PIECE", "PIPE")); } private ComputerStudent createStudentWithVocabularySize(int vocabularySize) { VograbularyPreferences preferences = mock(VograbularyPreferences.class); when(preferences.getComputerStudentVocabularySize()).thenReturn( vocabularySize); ComputerStudent student = new ComputerStudent(preferences); student.setWordList(wordList); student.setListener(new Student.StudentListener() { @Override public void showThinking() { focus = null; } @Override public void askForSolution() { focus = FocusField.Solution; } @Override public void askForResponse() { focus = FocusField.Challenge; } }); return student; } private ComputerStudent createStudent() { ComputerStudent student = createStudentWithVocabularySize(Integer.MAX_VALUE); return student; } @Test public void noSolutionFound() { int batchSize = 100; assertThat("word count", wordList.size(), lessThan(batchSize)); ComputerStudent student = createStudent(); student.setSearchBatchSize(batchSize); Puzzle puzzle = new Puzzle("AXR", student, wordList); student.startSolving(puzzle); student.runSearchBatch(); assertThat("solution", puzzle.getSolution(), is("")); } @Test public void noSolutionFoundWhenNotActiveStudent() { int batchSize = 100; assertThat("word count", wordList.size(), lessThan(batchSize)); ComputerStudent student = createStudent(); student.setSearchBatchSize(batchSize); Puzzle puzzle = new Puzzle("AXR", new Student("Bob"), wordList); student.startSolving(puzzle); boolean isFinished = student.runSearchBatch(); assertThat("solution", puzzle.getSolution(), is(Puzzle.NOT_SET)); assertThat("is finished", isFinished, is(true)); } @Test public void maxBatchCount() { ComputerStudent student = createStudent(); student.setMaxSearchBatchCount(1); Puzzle puzzle = new Puzzle("AXR", student, wordList); student.startSolving(puzzle); boolean isFinished = student.runSearchBatch(); assertThat("finished", isFinished, is(true)); } @Test public void ignoreWorseWord() { ComputerStudent student = createStudent(); wordList = new WordList(); wordList.read(Arrays.asList("PIECE", "PRICE")); student.setWordList(wordList); student.setMaxSearchBatchCount(1); Puzzle puzzle = new Puzzle("PIE", student, wordList); student.startSolving(puzzle); student.runSearchBatch(); assertThat("solution", puzzle.getSolution(), is("PIECE")); } @Test public void ignoreShortWord() { wordList = new WordList(); wordList.read(Arrays.asList("PIECE", "PIPE")); ComputerStudent student = createStudent(); student.setMaxSearchBatchCount(1); Puzzle puzzle = new Puzzle("PIE", student, wordList); puzzle.setMinimumWordLength(5); student.startSolving(puzzle); student.runSearchBatch(); assertThat("solution", puzzle.getSolution(), is("PIECE")); } @Test public void ignoreWordsBetterThanPrevious() { wordList = new WordList(); wordList.read(Arrays.asList("PRICE", "PIECE", "PIPE")); ComputerStudent student = createStudent(); student.setMaxSearchBatchCount(1); Puzzle puzzle = new Puzzle("PIE", student, wordList); puzzle.setPreviousWord("piece"); student.startSolving(puzzle); student.runSearchBatch(); assertThat("solution", puzzle.getSolution(), is("PRICE")); } @Test public void vocabularySizeNoMatch() { ComputerStudent student = createStudentWithVocabularySize(1); Puzzle puzzle = new Puzzle("AXR", student, wordList); student.startSolving(puzzle); boolean isFinished = student.runSearchBatch(); assertThat("finished", isFinished, is(true)); } @Test public void prepareResponse() { ComputerStudent student = createStudentWithVocabularySize(1); Puzzle puzzle = new Puzzle("PIE", new Student("Bob"), wordList); student.startSolving(puzzle); student.runSearchBatch(); puzzle.setSolution(""); student.prepareResponse(); assertThat("response", puzzle.getResponse(), is("PRICE")); } @Test public void prepareResponseNotAsGood() { ComputerStudent student = createStudentWithVocabularySize(1); Puzzle puzzle = new Puzzle("PIE", new Student("Bob"), wordList); student.startSolving(puzzle); student.runSearchBatch(); puzzle.setSolution("PIPE"); student.prepareResponse(); assertThat("response", puzzle.getResponse(), is(Puzzle.NO_SOLUTION)); } @Test public void prepareResponseNotReady() { ComputerStudent student = createStudent(); thrown.expect(IllegalStateException.class); thrown.expectMessage("Called prepareResponse() before startSolving()."); student.prepareResponse(); } @Test public void vocabularySizeMatch() { ComputerStudent student = createStudentWithVocabularySize(1); Puzzle puzzle = new Puzzle("PIE", student, wordList); student.startSolving(puzzle); student.runSearchBatch(); assertThat("solution", puzzle.getSolution(), is("PRICE")); } @Test public void batchSize() { int vocabularySize = 100; int maxSearchBatchCount = 20; int expectedBatchSize = vocabularySize / maxSearchBatchCount; ComputerStudent student = createStudentWithVocabularySize(vocabularySize); student.setMaxSearchBatchCount(maxSearchBatchCount); int batchSize = student.getSearchBatchSize(); assertThat("batch size", batchSize, is(expectedBatchSize)); } @Test public void maxBatchCountInactiveStudent() { ComputerStudent student = createStudentWithVocabularySize(2); student.setMaxSearchBatchCount(1); Puzzle puzzle = new Puzzle("AXR", new Student("Bob"), wordList); student.startSolving(puzzle); boolean isFinished = student.runSearchBatch(); assertThat("finished", isFinished, is(false)); } @Test public void createSearchTaskCancelsAfterLastWord() { ComputerStudent student = createStudent(); assertThat("word count", wordList.size(), is(3)); Puzzle puzzle = new Puzzle("PIE", student, wordList); student.startSolving(puzzle); String expectedSolution = "PIPE"; student.runSearchBatch(); boolean isCompleteAfterSecondLast = student.runSearchBatch(); boolean isCompleteAfterLast = student.runSearchBatch(); assertThat( "is complete before last word", isCompleteAfterSecondLast, is(false)); assertThat( "is complete after last word", isCompleteAfterLast, is(true)); assertThat("solution", puzzle.getSolution(), is(expectedSolution)); } @Test public void startThinkingWhenActive() { ComputerStudent student = createStudent(); focus = FocusField.Solution; Puzzle puzzle = new Puzzle("PIE", student, wordList); student.startSolving(puzzle); assertThat("focus", focus, nullValue()); } @Test public void startThinkingWhenInactive() { ComputerStudent student = createStudent(); focus = FocusField.Solution; Puzzle puzzle = new Puzzle("PIE", new Student("Bob"), wordList); student.startSolving(puzzle); assertThat("focus", focus, is(FocusField.Solution)); } @Test public void serialization() throws Exception { ComputerStudent student = createStudent(); student.setSearchBatchSize(50); student.startSolving(new Puzzle("ABC", student)); byte[] bytes = SerializableTools.serialize(student); ComputerStudent student2 = SerializableTools.deserialize( bytes, ComputerStudent.class); assertThat("batch size", student2.getSearchBatchSize(), is(50)); assertThat("puzzle", student2.getCurrentPuzzle(), nullValue()); } }