func evalProperties()

in pkg/updater/eval.go [163:254]


func evalProperties(rule *evalpb.Rule, testResult TestResult) *tspb.TestStatus {
	for _, cmp := range rule.TestResultComparisons {
		if cmp.Comparison == nil {
			return nil
		}
		var scmp func(string, string) bool
		var fcmp func(float64, float64) bool
		sval := cmp.Comparison.GetStringValue()
		fval := cmp.Comparison.GetNumericalValue()
		switch cmp.Comparison.Op {
		case evalpb.Comparison_OP_CONTAINS:
			scmp = strContains
		case evalpb.Comparison_OP_REGEX:
			scmp = strReg
		case evalpb.Comparison_OP_STARTS_WITH:
			scmp = strStartsWith
		case evalpb.Comparison_OP_EQ:
			scmp = strEQ
			fcmp = numEQ
		case evalpb.Comparison_OP_NE:
			scmp = strNE
			fcmp = numNE
		}

		if p := cmp.GetPropertyKey(); p != "" {
			if scmp == nil {
				return nil
			}
			var good bool
			props := testResult.Properties()
			if props == nil {
				return nil
			}
			for _, val := range props[p] {
				if !scmp(val, sval) {
					continue
				}
				good = true
				break
			}
			if !good {
				return nil
			}
		} else if f := cmp.GetTestResultField(); f != "" {
			var getNum func() int
			var getStr func() string
			switch f {
			case "name":
				getStr = testResult.Name
			case "error_count":
				getNum = testResult.Errors
			case "failure_count":
				getNum = testResult.Failures
			default: // TODO(fejta): drop or support other fields
				return nil
			}
			switch {
			case getNum != nil:
				n := float64(getNum())
				if !fcmp(n, fval) {
					return nil
				}
			case getStr != nil:
				if !scmp(getStr(), sval) {
					return nil
				}
			}
		} else if ef := cmp.GetTestResultErrorField(); ef != "" {
			if scmp == nil {
				return nil
			}
			if ef != "exception_type" {
				return nil
			}
			var good bool
			for _, got := range testResult.Exceptions() {
				if scmp(got, sval) {
					good = true
					break
				}
			}
			if !good {
				return nil
			}
		} else {
			return nil
		}

	}
	want := rule.GetComputedStatus()
	return &want
}