blob: 5899fafda610052d93615f14b492dfe05c699774 [file] [log] [blame]
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package assert
import (
"bytes"
"fmt"
"reflect"
)
// OnSlice is the result of calling ThatSlice on an Assertion.
// It provides assertion tests that are specific to slice types.
type OnSlice struct {
Assertion
slice interface{}
}
// IsEmpty asserts that the slice was of length 0
func (o OnSlice) IsEmpty() bool {
value := reflect.ValueOf(o.slice)
return o.Assertion.test(value.Len() == 0, expected, value.Len(), "empty slice")
}
// IsNotEmpty asserts that the slice has elements
func (o OnSlice) IsNotEmpty() bool {
value := reflect.ValueOf(o.slice)
return o.Assertion.test(value.Len() > 0, expected, "empty slice", "values")
}
// IsLength asserts that the slice has exactly the specified number of elements
func (o OnSlice) IsLength(length int) bool {
value := reflect.ValueOf(o.slice)
return o.Assertion.test(value.Len() == length, unmatched, value.Len(), "Expected length", length)
}
// Equals asserts the array or slice matches expected.
func (o OnSlice) Equals(expected interface{}) bool {
return o.slicesEqual(expected, func(a, b interface{}) bool { return a == b })
}
// EqualsWithComparator asserts the array or slice matches expected using a comparator function
func (o OnSlice) EqualsWithComparator(expected interface{}, same func(a, b interface{}) bool) bool {
return o.slicesEqual(expected, same)
}
// DeepEquals asserts the array or slice matches expected using a deep-equal comparison.
func (o OnSlice) DeepEquals(expected interface{}) bool {
return o.slicesEqual(expected, reflect.DeepEqual)
}
func (o OnSlice) slicesEqual(expected interface{}, same func(a, b interface{}) bool) bool {
vg, ve := reflect.ValueOf(o.slice), reflect.ValueOf(expected)
cg, ce := vg.Len(), ve.Len()
equal := cg == ce
if equal {
for i := 0; i < cg; i++ {
g, e := vg.Index(i).Interface(), ve.Index(i).Interface()
if !same(g, e) {
equal = false
break
}
}
}
if equal {
return true
}
buf := &bytes.Buffer{}
for i := 0; i < cg || i < ce; i++ {
var g, e interface{}
g, e = "<missing>", "<missing>"
if i < cg {
g = vg.Index(i).Interface()
}
if i < ce {
e = ve.Index(i).Interface()
}
if i > 0 {
fmt.Fprint(buf, "\n")
}
if same(g, e) {
fmt.Fprintf(buf, " %d: %T %+v", i, g, g)
} else {
fmt.Fprintf(buf, "* %d: %T %+v --- EXPECTED: %T %+v", i, g, g, e, e)
}
}
o.Assertion.emit(buf.String())
return false
}