Beispiel #1
0
// 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()
			}
		}
	}
}
Beispiel #2
0
func logOutput(s string, l *BuildResult, opt DaemonOptions) {
	if !utf8.ValidString(s) {
		v := make([]rune, 0, len(s))
		for i, r := range s {
			if r == utf8.RuneError {
				_, size := utf8.DecodeRuneInString(s[i:])
				if size == 1 {
					continue
				}
			}
			v = append(v, r)
		}
		s = string(v)
	}

	s = strings.Trim(s, string(0))
	s = strings.TrimSpace(s)

	//TODO: Move this code to a new function in kit/score package? Reason: easier to test.
	if strings.Contains(s, opt.Secret) {
		// TODO: must be a better way of detecting JSON data!  TODO: Hein@Heine: Why?
		var testscore score.Score
		err := json.Unmarshal([]byte(s), &testscore)
		if err == nil {
			if testscore.Secret == opt.Secret {
				testscore.Secret = "Sanitized"
				l.TestScores = append(l.TestScores, testscore)
			}
			return
		}
		// ensure that the error message does not reveal the secret token
		es := strings.Replace(err.Error(), opt.Secret, "Sanitized", -1)
		log.Printf("Parse error: %s\n", es)
	}
	s = strings.Replace(s, opt.Secret, "Sanitized", -1)
	s = strings.Replace(s, opt.AdminToken, "Sanitized", -1)

	l.Log = append(l.Log, strings.TrimSpace(s))
	fmt.Println(s)
}
Beispiel #3
0
// 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()
			}
		}
	}
}