github.com/haraldrudell/parl@v0.4.176/iters/slice-interface_test.go (about)

     1  /*
     2  © 2023–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
     3  ISC License
     4  */
     5  
     6  package iters
     7  
     8  import (
     9  	"testing"
    10  
    11  	"github.com/haraldrudell/parl/internal/cyclebreaker"
    12  )
    13  
    14  // tests Init Cond Next Same Cancel
    15  func TestSliceInterface(t *testing.T) {
    16  	var sliceOfConcreteType = make([]siiType, 1)
    17  
    18  	var iterator, iter Iterator[siiInterface]
    19  	var value, zeroValue siiInterface
    20  	var hasValue, condition bool
    21  
    22  	// Cancel-Next should return no value
    23  	iterator = NewSliceInterfaceIterator[siiInterface](sliceOfConcreteType)
    24  	iterator.Cancel()
    25  	value, hasValue = iterator.Next()
    26  	if hasValue {
    27  		t.Error("Cancel-Same hasValue true")
    28  	}
    29  	if value != zeroValue {
    30  		t.Error("Cancel-Same value not zero-value")
    31  	}
    32  
    33  	// Cancel-Cond should return no value
    34  	iterator = NewSliceInterfaceIterator[siiInterface](sliceOfConcreteType)
    35  	iterator.Cancel()
    36  	condition = iterator.Cond(&value)
    37  	if condition {
    38  		t.Error("Cancel-Cond condition true")
    39  	}
    40  	if value != zeroValue {
    41  		t.Error("Cancel-Cond value not zero-value")
    42  	}
    43  
    44  	// Next should return first value
    45  	iterator = NewSliceInterfaceIterator[siiInterface](sliceOfConcreteType)
    46  	value, hasValue = iterator.Next()
    47  	if !hasValue {
    48  		t.Error("Nex hasValue false")
    49  	}
    50  	if value != &sliceOfConcreteType[0] {
    51  		t.Error("Next value bad")
    52  	}
    53  
    54  	// Next-Next should return no value
    55  	iterator = NewSliceInterfaceIterator[siiInterface](sliceOfConcreteType)
    56  	value, hasValue = iterator.Next()
    57  	_ = value
    58  	_ = hasValue
    59  	value, hasValue = iterator.Next()
    60  	if hasValue {
    61  		t.Error("Cancel-Same hasValue true")
    62  	}
    63  	if value != zeroValue {
    64  		t.Error("Cancel-Same value not zero-value")
    65  	}
    66  
    67  	// Init should return zero-value and iterator
    68  	iterator = NewSliceInterfaceIterator[siiInterface](sliceOfConcreteType)
    69  	value, iter = iterator.Init()
    70  	if value != zeroValue {
    71  		t.Error("Init value not zero-value")
    72  	}
    73  	if iter != iterator {
    74  		t.Error("Init iterator bad")
    75  	}
    76  
    77  	// Init-Cond should return first value and true
    78  	iterator = NewSliceInterfaceIterator[siiInterface](sliceOfConcreteType)
    79  	value, iter = iterator.Init()
    80  	_ = value
    81  	_ = iter
    82  	condition = iterator.Cond(&value)
    83  	if value != &sliceOfConcreteType[0] {
    84  		t.Errorf("Init-Cond bad value: 0x%x exp 0x%x",
    85  			cyclebreaker.Uintptr(value),
    86  			cyclebreaker.Uintptr(&sliceOfConcreteType[0]),
    87  		)
    88  	}
    89  	if !condition {
    90  		t.Error("Init-Cond condition false")
    91  	}
    92  
    93  	// Init-Cond-Cond should return no value
    94  	iterator = NewSliceInterfaceIterator[siiInterface](sliceOfConcreteType)
    95  	value, iter = iterator.Init()
    96  	_ = value
    97  	_ = iter
    98  	condition = iterator.Cond(&value)
    99  	_ = condition
   100  	condition = iterator.Cond(&value)
   101  	if value != zeroValue {
   102  		t.Error("Init-Cond-Cond not zero-value")
   103  	}
   104  	if condition {
   105  		t.Error("Init-Cond-Cond condition true")
   106  	}
   107  
   108  }
   109  
   110  // tests interface I that does not implement E
   111  func TestSliceInterfaceIteratorBad(t *testing.T) {
   112  
   113  	isPanic, err := invokeNewSliceInterfaceIterator()
   114  	if !isPanic {
   115  		t.Error("NewSliceInterfaceIterator bad type no panic")
   116  	}
   117  	if err == nil {
   118  		t.Error("NewSliceInterfaceIterator bad type no error")
   119  	}
   120  }
   121  
   122  // invokes NewSliceInterfaceIterator recovering and returning an expected panic
   123  func invokeNewSliceInterfaceIterator() (isPanic bool, err error) {
   124  	defer cyclebreaker.RecoverErr(func() cyclebreaker.DA { return cyclebreaker.A() }, &err, &isPanic)
   125  
   126  	var sliceOfBadType = make([]siiBadType, 1)
   127  	NewSliceInterfaceIterator[siiInterface](sliceOfBadType)
   128  	return
   129  }
   130  
   131  type siiInterface interface {
   132  	siiMethod()
   133  }
   134  
   135  type siiType struct{}
   136  
   137  func (t *siiType) siiMethod() {}
   138  
   139  var _ siiInterface = &siiType{}
   140  
   141  type siiBadType struct{}
   142  
   143  // cannot use &siiBadType{} (value of type *siiBadType)
   144  // as siiInterface value in variable declaration:
   145  // *siiBadType does not implement siiInterface (missing method siiMethod)
   146  // var _ siiInterface = &siiBadType{}