// MultipleChoice computes the score of a multiple choice exercise // with student answers provided in fileName, and the answers provided // in the answerKey object. The function requires a Score object, and // will produce both string output and JSON output. func MultipleChoice(t *testing.T, sc *score.Score, fileName string, answers Choices) { defer sc.WriteString(os.Stdout) defer sc.WriteJSON(os.Stdout) // Read the whole file bytes, err := ioutil.ReadFile(fileName) if err != nil { sc.Score = 0 t.Fatalf(fmt.Sprintf("%v: error reading the file: %v", fileName, err)) return } for i := range answers { // Find the user's answer to the corresponding question number regexStr := "\n" + strconv.Itoa(answers[i].Number) + "[.)]*[ \t\v\r\n\f]*[A-Za-z]*" regex := regexp.MustCompile(regexStr) userAnswer := regex.Find(bytes) if userAnswer == nil { t.Errorf("%v %d: Answer not found.\n", sc.TestName, answers[i].Number) sc.Dec() } else { r, _ := utf8.DecodeLastRune(userAnswer) got, _ := utf8.DecodeLastRuneInString(strings.ToUpper(string(r))) if got != answers[i].Want { t.Errorf("%v %d: %q is incorrect.\n", sc.TestName, answers[i].Number, got) sc.Dec() } } } }
// CommandLine computes the score for a set of command line exercises // that students provided. The function requires the list of commands // and their expected answers, and a Score object. The function // will produce both string output and JSON output. func CommandLine(t *testing.T, sc *score.Score, answers Commands) { defer sc.WriteString(os.Stdout) defer sc.WriteJSON(os.Stdout) for i := range answers { cmdArgs := strings.Split(answers[i].Command, " ") cmd := exec.Command(cmdArgs[0]) cmd.Args = cmdArgs var sout, serr bytes.Buffer cmd.Stdout, cmd.Stderr = &sout, &serr err := cmd.Run() if err != nil { t.Errorf("%v\n%v: %v.\n", sc.TestName, err, serr.String()) sc.Dec() continue } outStr := sout.String() // Compare output with expected output switch answers[i].Search { case ResultEquals: if outStr != answers[i].Result { t.Errorf("%v: \ngot: %v \nwant: %v \nfor command: %v\n", sc.TestName, outStr, answers[i].Result, answers[i].Command) sc.Dec() } case ResultContains: if !strings.Contains(outStr, answers[i].Result) { t.Errorf("%v: \nResult does not contain: %v \nfor command: %v\n", sc.TestName, answers[i].Result, answers[i].Command) sc.Dec() } case ResultDoesNotContain: if strings.Contains(outStr, answers[i].Result) { t.Errorf("%v: \nResult contains: %v \nfor command: %v\n", sc.TestName, answers[i].Result, answers[i].Command) sc.Dec() } } } }