package vals

import (
	
	

	
)

// ValueTester is a helper for testing properties of a value.
type ValueTester struct {
	t *testing.T
	v interface{}
}

// TestValue returns a ValueTester.
func ( *testing.T,  interface{}) ValueTester {
	return ValueTester{, }
}

// Kind tests the Kind of the value.
func ( ValueTester) ( string) ValueTester {
	.t.Helper()
	 := Kind(.v)
	if  !=  {
		.t.Errorf("Kind(v) = %s, want %s", , )
	}
	return 
}

// Bool tests the Boool of the value.
func ( ValueTester) ( bool) ValueTester {
	.t.Helper()
	 := Bool(.v)
	if  !=  {
		.t.Errorf("Bool(v) = %v, want %v", , )
	}
	return 
}

// Hash tests the Hash of the value.
func ( ValueTester) ( uint32) ValueTester {
	.t.Helper()
	 := Hash(.v)
	if  !=  {
		.t.Errorf("Hash(v) = %v, want %v", , )
	}
	return 
}

// Len tests the Len of the value.
func ( ValueTester) ( int) ValueTester {
	.t.Helper()
	 := Len(.v)
	if  !=  {
		.t.Errorf("Len(v) = %v, want %v", , )
	}
	return 
}

// Repr tests the Repr of the value.
func ( ValueTester) ( string) ValueTester {
	.t.Helper()
	 := Repr(.v, NoPretty)
	if  !=  {
		.t.Errorf("Repr(v) = %s, want %s", , )
	}
	return 
}

// Equal tests that the value is Equal to every of the given values.
func ( ValueTester) ( ...interface{}) ValueTester {
	.t.Helper()
	for ,  := range  {
		 := Equal(.v, )
		if ! {
			.t.Errorf("Equal(v, %v) = false, want true", )
		}
	}
	return 
}

// NotEqual tests that the value is not Equal to any of the given values.
func ( ValueTester) ( ...interface{}) ValueTester {
	.t.Helper()
	for ,  := range  {
		 := Equal(.v, )
		if  {
			.t.Errorf("Equal(v, %v) = true, want false", )
		}
	}
	return 
}

// HasKey tests that the value has each of the given keys.
func ( ValueTester) ( ...interface{}) ValueTester {
	.t.Helper()
	for ,  := range  {
		 := HasKey(.v, )
		if ! {
			.t.Errorf("HasKey(v, %v) = false, want true", )
		}
	}
	return 
}

// HasNoKey tests that the value does not have any of the given keys.
func ( ValueTester) ( ...interface{}) ValueTester {
	.t.Helper()
	for ,  := range  {
		 := HasKey(.v, )
		if  {
			.t.Errorf("HasKey(v, %v) = true, want false", )
		}
	}
	return 
}

// AllKeys tests that the given keys match what the result of IterateKeys on the
// value.
//
// NOTE: This now checks equality using reflect.DeepEqual, since all the builtin
// types have string keys. This can be changed in future to use Equal is the
// need arises.
func ( ValueTester) ( ...interface{}) ValueTester {
	.t.Helper()
	,  := collectKeys(.v)
	if  != nil {
		.t.Errorf("IterateKeys(v, f) -> err %v, want nil", )
	}
	if !reflect.DeepEqual(, ) {
		.t.Errorf("IterateKeys(v, f) calls f with %v, want %v", , )
	}
	return 
}

func ( interface{}) ([]interface{}, error) {
	var  []interface{}
	 := IterateKeys(, func( interface{}) bool {
		 = append(, )
		return true
	})
	return , 
}

// Index tests that Index'ing the value with the given key returns the wanted value
// and no error.
func ( ValueTester) (,  interface{}) ValueTester {
	.t.Helper()
	,  := Index(.v, )
	if  != nil {
		.t.Errorf("Index(v, %v) -> err %v, want nil", , )
	}
	if !Equal(, ) {
		.t.Errorf("Index(v, %v) -> %v, want %v", , , )
	}
	return 
}

// IndexError tests that Index'ing the value with the given key returns the given
// error.
func ( ValueTester) ( interface{},  error) ValueTester {
	.t.Helper()
	,  := Index(.v, )
	if !reflect.DeepEqual(, ) {
		.t.Errorf("Index(v, %v) -> err %v, want %v", , , )
	}
	return 
}

// Assoc tests that Assoc'ing the value with the given key-value pair returns
// the wanted new value and no error.
func ( ValueTester) (, ,  interface{}) ValueTester {
	.t.Helper()
	,  := Assoc(.v, , )
	if  != nil {
		.t.Errorf("Assoc(v, %v) -> err %v, want nil", , )
	}
	if !Equal(, ) {
		.t.Errorf("Assoc(v, %v) -> %v, want %v", , , )
	}
	return 
}

// AssocError tests that Assoc'ing the value with the given key-value pair
// returns the given error.
func ( ValueTester) (,  interface{},  error) ValueTester {
	.t.Helper()
	,  := Assoc(.v, , )
	if !reflect.DeepEqual(, ) {
		.t.Errorf("Assoc(v, %v) -> err %v, want %v", , , )
	}
	return 
}

// Eq returns a tt.Matcher that matches using the Equal function.
func ( interface{}) tt.Matcher { return equalMatcher{} }

type equalMatcher struct{ want interface{} }

func ( equalMatcher) ( tt.RetValue) bool { return Equal(, .want) }