Пример #1
0
// SliceShrinker creates a slice shrinker from a shrinker for the elements of the slice.
// The length of the slice will be shrinked as well
func SliceShrinker(elementShrinker gopter.Shrinker) gopter.Shrinker {
	return func(v interface{}) gopter.Shrink {
		rv := reflect.ValueOf(v)
		if rv.Kind() != reflect.Slice {
			panic(fmt.Sprintf("%#v is not a slice", v))
		}
		sliceShrink := &sliceShrink{
			original:    rv,
			offset:      0,
			length:      rv.Len(),
			chunkLength: rv.Len() >> 1,
		}

		shrinks := make([]gopter.Shrink, 0, rv.Len()+1)
		shrinks = append(shrinks, sliceShrink.Next)
		for i := 0; i < rv.Len(); i++ {
			sliceShrinkOne := &sliceShrinkOne{
				original:      rv,
				index:         i,
				elementShrink: elementShrinker(rv.Index(i).Interface()),
			}
			shrinks = append(shrinks, sliceShrinkOne.Next)
		}
		return gopter.ConcatShrinks(shrinks...)
	}
}
Пример #2
0
// PtrShrinker convert a value shrinker to a pointer to value shrinker
func PtrShrinker(elementShrinker gopter.Shrinker) gopter.Shrinker {
	return func(v interface{}) gopter.Shrink {
		if v == nil {
			return gopter.NoShrink
		}
		rt := reflect.TypeOf(v)
		elementShink := elementShrinker(reflect.ValueOf(v).Elem().Interface())

		nilShrink := &nilShrink{}
		return gopter.ConcatShrinks(
			nilShrink.Next,
			elementShink.Map(func(elem interface{}) interface{} {
				slice := reflect.MakeSlice(reflect.SliceOf(rt.Elem()), 0, 1)
				slice = reflect.Append(slice, reflect.ValueOf(elem))

				return slice.Index(0).Addr().Interface()
			}),
		)
	}
}