package uk.co.bytemark.vm.enigma.inquisition.questions;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import uk.co.bytemark.vm.enigma.inquisition.misc.Utils;
public class MultipleChoiceQuestionCorrectAndAnsweredTest {
private MultipleChoiceQuestion question;
private final Option option1 = new Option("Option a", false, 1);
private final Option option2 = new Option("Option b", false, 2);
private final Option option3 = new Option("Option c", true, 3);
private final Option option4 = new Option("Option d", false, 4);
private final Option option5 = new Option("Option e", true, 5);
@Before
public void setUp() throws Exception {
List<Option> options = Arrays.asList(option1, option2, option3, option4, option5);
question = new MultipleChoiceQuestion("Question", "Explanation", options, true, false);
}
@Test(expected = NullPointerException.class)
public void shouldThrowNullPointerExceptionIfOptionSetContainsNulls() throws Exception {
new MultipleChoiceAnswer(Collections.<Option> singleton(null));
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionsIfNullsInConstructor() throws Exception {
new MultipleChoiceAnswer(null);
}
@Test
public void shouldRecogniseCorrectAnswer() {
assertTrue(isAnswerCorrect(option3, option5));
}
@Test
public void shouldRecogniseIncorrectAnswer() {
assertFalse(isAnswerCorrect(option3, option5, option1));
assertFalse(isAnswerCorrect(option5));
assertFalse(isAnswerCorrect(option3));
assertFalse(isAnswerCorrect());
assertFalse(isAnswerCorrect(option2));
assertFalse(isAnswerCorrect(option1, option2, option3, option4, option5));
}
private boolean isAnswerCorrect(Option... options) {
Set<Option> optionSet = Utils.makeSet(options);
MultipleChoiceAnswer answer = new MultipleChoiceAnswer(optionSet);
return question.isCorrect(answer);
}
@Test
public void shouldRecognisedWhenQuestionHasBeenAnsweredWhenNumberOfOptionsIsKnown() throws Exception {
assertTrue(isQuestionAnswered(true, option1, option2));
assertTrue(isQuestionAnswered(true, option3, option2));
assertTrue(isQuestionAnswered(true, option3, option5));
assertTrue(isQuestionAnswered(true, option4, option5));
assertFalse(isQuestionAnswered(true));
assertFalse(isQuestionAnswered(true, option1));
assertFalse(isQuestionAnswered(true, option3));
assertFalse(isQuestionAnswered(true, option5));
assertFalse(isQuestionAnswered(true, option1, option3, option5));
assertFalse(isQuestionAnswered(true, option1, option2, option4));
assertFalse(isQuestionAnswered(true, option1, option5, option4));
}
@Test
public void shouldRecognisedWhenQuestionHasBeenAnsweredWhenNumberOfOptionsIsUnknown() throws Exception {
assertTrue(isQuestionAnswered(false, option1));
assertTrue(isQuestionAnswered(false, option1, option2));
assertTrue(isQuestionAnswered(false, option1, option2, option3));
assertTrue(isQuestionAnswered(false, option1, option2, option3, option4));
assertTrue(isQuestionAnswered(false, option1, option2, option3, option4, option5));
assertFalse(isQuestionAnswered(false));
}
private boolean isQuestionAnswered(boolean stateNumberOfOptionsNeeded, Option... options) {
Set<Option> optionSet = Utils.makeSet(options);
MultipleChoiceAnswer answer = new MultipleChoiceAnswer(optionSet);
return question.isAnswered(answer, stateNumberOfOptionsNeeded);
}
@Test
public void shouldAcceptEmptyOptionSet() throws Exception {
MultipleChoiceAnswer answer = new MultipleChoiceAnswer(new HashSet<Option>());
assertFalse(question.isAnswered(answer, true));
assertFalse(question.isAnswered(answer, false));
assertFalse(question.isCorrect(answer));
}
@Test
public void shouldThrowExceptionIfOptionsNotConsistentWithQuestion() throws Exception {
Option faultyOption1 = new Option("Not an option", false, 1);
Option faultyOption2 = new Option("Option a", true, 1);
Option faultyOption3 = new Option("Option c", true, 4);
checkThrowsExceptionWithTheseOptions(faultyOption1);
checkThrowsExceptionWithTheseOptions(faultyOption2);
checkThrowsExceptionWithTheseOptions(faultyOption3);
checkThrowsExceptionWithTheseOptions(faultyOption1, faultyOption2);
checkThrowsExceptionWithTheseOptions(faultyOption1, faultyOption2, faultyOption3);
checkThrowsExceptionWithTheseOptions(faultyOption1, option1);
checkThrowsExceptionWithTheseOptions(faultyOption1, option2);
checkThrowsExceptionWithTheseOptions(faultyOption1, faultyOption2, option1, option2);
}
private void checkThrowsExceptionWithTheseOptions(Option... options) {
Set<Option> optionSet = Utils.makeSet(options);
MultipleChoiceAnswer answer = new MultipleChoiceAnswer(optionSet);
try {
question.isAnswered(answer, false);
fail("Should not allow options which are not part of question");
} catch (IllegalArgumentException e) {
// Exception expected from test
}
try {
question.isCorrect(answer);
fail("Should not allow options which are not part of question");
} catch (IllegalArgumentException e) {
// Exception expected from test
}
}
}