runner/run.go
func (r *Runner) assertJSONIsEqualOrSubset(v1 interface{}, v2 interface{}) (bool, error) {
	if (v1 == nil) && (v2 == nil) {
		return true, nil
	}

	// check if both are non nil and that type matches
	if ((v1 == nil) != (v2 == nil)) ||
		(reflect.ValueOf(v1).Type() != reflect.ValueOf(v2).Type()) {
		return false, fmt.Errorf("types do not match")
	}

	switch v1.(type) {
	case map[string]interface{}:
		// recursively check maps
		// v2 is of same type as v1 as check in early return
		v2map := v2.(map[string]interface{})
		for objK, objV := range v1.(map[string]interface{}) {
			if v2map[objK] == nil {
				return false, fmt.Errorf("missing key '%s'", objK)
			}
			equalForKey, errForKey := r.assertJSONIsEqualOrSubset(objV, v2map[objK])
			if !equalForKey {
				return false, fmt.Errorf("mismatch for key '%s': %s", objK, errForKey)
			}
		}

		return true, nil
	default:
		// all non-map types must be deep equal
		if !reflect.DeepEqual(v1, v2) {
			return false, fmt.Errorf("values do not match - %s != %s", v1, v2)
		}
		return true, nil
	}
}
func (r *Runner) assertJSONIsEqualOrSubset(v1 interface{}, v2 interface{}) (bool, error) {
	if (v1 == nil) && (v2 == nil) {
		return true, nil
	}

	// check if both are non nil and that type matches
	if ((v1 == nil) != (v2 == nil)) ||
		(reflect.ValueOf(v1).Type() != reflect.ValueOf(v2).Type()) {
		return false, fmt.Errorf("types do not match")
	}

	switch v1.(type) {
	case map[string]interface{}:
		// recursively check maps
		// v2 is of same type as v1 as check in early return
		v2map := v2.(map[string]interface{})
		for objK, objV := range v1.(map[string]interface{}) {
			if v2map[objK] == nil {
				return false, fmt.Errorf("missing key '%s'", objK)
			}
			equalForKey, errForKey := r.assertJSONIsEqualOrSubset(objV, v2map[objK])
			if !equalForKey {
				return false, fmt.Errorf("mismatch for key '%s': %s", objK, errForKey)
			}
		}

		return true, nil
	default:
		// all non-map types must be deep equal
		if !reflect.DeepEqual(v1, v2) {
			return false, fmt.Errorf("values do not match - %s != %s", v1, v2)
		}
		return true, nil
	}
}
// assertJSONIsEqualOrSubset returns true if v1 and v2 are equal in value
// or if both are maps (of type map[string]interface{}) and v1 is a subset of v2, where
// all keys that are present in v1 are present with the same value in v2.