| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 | // Copyright 2012 Aaron Jacobs. All Rights Reserved.// Author: aaronjjacobs@gmail.com (Aaron Jacobs)//// 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 oglematchersimport (	"errors"	"fmt"	"reflect"	"strings")// Given a list of arguments M, ElementsAre returns a matcher that matches// arrays and slices A where all of the following hold:////  *  A is the same length as M.////  *  For each i < len(A) where M[i] is a matcher, A[i] matches M[i].////  *  For each i < len(A) where M[i] is not a matcher, A[i] matches//     Equals(M[i]).//func ElementsAre(M ...interface{}) Matcher {	// Copy over matchers, or convert to Equals(x) for non-matcher x.	subMatchers := make([]Matcher, len(M))	for i, x := range M {		if matcher, ok := x.(Matcher); ok {			subMatchers[i] = matcher			continue		}		subMatchers[i] = Equals(x)	}	return &elementsAreMatcher{subMatchers}}type elementsAreMatcher struct {	subMatchers []Matcher}func (m *elementsAreMatcher) Description() string {	subDescs := make([]string, len(m.subMatchers))	for i, sm := range m.subMatchers {		subDescs[i] = sm.Description()	}	return fmt.Sprintf("elements are: [%s]", strings.Join(subDescs, ", "))}func (m *elementsAreMatcher) Matches(candidates interface{}) error {	// The candidate must be a slice or an array.	v := reflect.ValueOf(candidates)	if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {		return NewFatalError("which is not a slice or array")	}	// The length must be correct.	if v.Len() != len(m.subMatchers) {		return errors.New(fmt.Sprintf("which is of length %d", v.Len()))	}	// Check each element.	for i, subMatcher := range m.subMatchers {		c := v.Index(i)		if matchErr := subMatcher.Matches(c.Interface()); matchErr != nil {			// Return an errors indicating which element doesn't match. If the			// matcher error was fatal, make this one fatal too.			err := errors.New(fmt.Sprintf("whose element %d doesn't match", i))			if _, isFatal := matchErr.(*FatalError); isFatal {				err = NewFatalError(err.Error())			}			return err		}	}	return nil}
 |