// paramsStructMap returns the string representation of a map of values
func (f paramFiller) paramsStructMap(value map[string]interface{}, shape *Shape) string {
	out := f.typeName(shape) + "{\n"
	keys := util.SortedKeys(value)
	for _, k := range keys {
		v := value[k]
		out += fmt.Sprintf("%q: %s,\n", k, f.paramsStructAny(v, shape.ValueRef.Shape))
	}
	out += "}"
	return out
}
// GenerateAssertions builds assertions for a shape based on its type.
//
// The shape's recursive values also will have assertions generated for them.
func GenerateAssertions(out interface{}, shape *api.Shape, prefix string) string {
	switch t := out.(type) {
	case map[string]interface{}:
		keys := util.SortedKeys(t)

		code := ""
		if shape.Type == "map" {
			for _, k := range keys {
				v := t[k]
				s := shape.ValueRef.Shape
				code += GenerateAssertions(v, s, prefix+"[\""+k+"\"]")
			}
		} else {
			for _, k := range keys {
				v := t[k]
				m := findMember(shape, k)
				s := shape.MemberRefs[m].Shape
				code += GenerateAssertions(v, s, prefix+"."+m+"")
			}
		}
		return code
	case []interface{}:
		code := ""
		for i, v := range t {
			s := shape.MemberRef.Shape
			code += GenerateAssertions(v, s, prefix+"["+strconv.Itoa(i)+"]")
		}
		return code
	default:
		switch shape.Type {
		case "timestamp":
			return fmt.Sprintf("assert.Equal(t, time.Unix(%#v, 0).UTC().String(), %s.String())\n", out, prefix)
		case "blob":
			return fmt.Sprintf("assert.Equal(t, %#v, string(%s))\n", out, prefix)
		case "integer", "long":
			return fmt.Sprintf("assert.Equal(t, int64(%#v), *%s)\n", out, prefix)
		default:
			if !reflect.ValueOf(out).IsValid() {
				return fmt.Sprintf("assert.Nil(t, %s)\n", prefix)
			}
			return fmt.Sprintf("assert.Equal(t, %#v, *%s)\n", out, prefix)
		}
	}
}
// SortedKeys returns a sorted slice of keys of a map.
func SortedKeys(m map[string]interface{}) []string {
	return util.SortedKeys(m)
}