package testhelper import ( "reflect" "testing" ) func PropsTester(t *testing.T, model interface{}, lookup map[string]interface{}) { for key, value := range lookup { val := getField(model, key) reflectExpected := reflect.ValueOf(value) Compare(t, key, reflectExpected, val) } } func Compare(t *testing.T, key string, expectedValue, gotValue reflect.Value) bool { // Check if they have the same type, if not thats an issue if expectedValue.Type() != gotValue.Type() { if expectedValue.String() == gotValue.String() { t.Logf("Key %s val %s had mismatched types but string value matched", key, expectedValue) return true } else { t.Errorf("Key %s was of type %s but got %s", key, expectedValue.Type(), gotValue.Type()) } return false } // If they share the same type, and are a comparable type, so int(123) == int(123) if gotValue.Comparable() { if !gotValue.Equal(expectedValue) { t.Errorf(TestErrorTemplate, key, expectedValue, gotValue) return false } } // If they are not comparable, we need to look deeper in the object switch expectedValue.Kind() { case reflect.Slice: if expectedValue.Len() != gotValue.Len() { return false } for x := 0; x < expectedValue.Len(); x++ { Compare(t, key, expectedValue.Index(x), gotValue.Index(x)) } return true } return false } // This whole type of testing is incredibly bunk func getField(v interface{}, field string) reflect.Value { r := reflect.ValueOf(v) f := reflect.Indirect(r).FieldByName(field) return f }