diff --git a/list/list_test.go b/list/list_test.go index 1a8318b..0d39da1 100644 --- a/list/list_test.go +++ b/list/list_test.go @@ -9,6 +9,7 @@ import ( "pgregory.net/rapid" ) +// intListGen returns a generator for either empty list or random ints func intListGen() *rapid.Generator[IList] { return rapid.OneOf(rapid.Custom(func(t *rapid.T) IList { myList := Empty() @@ -21,22 +22,20 @@ func intListGen() *rapid.Generator[IList] { }), rapid.Just(Empty())) } -func TestConjIncreasesLength(t *testing.T) { - rapid.Check(t, func(t *rapid.T) { - myList := intListGen().Draw(t, "myList") - newElem := rapid.Int().Draw(t, "newElem") - assert.Equal(t, myList.Len()+1, myList.Conj(newElem).Len(), "conj increases length") - }) -} - -func TestRestDecreasesLength(t *testing.T) { - rapid.Check(t, func(t *rapid.T) { - myList := intListGen().Draw(t, "myList") - if myList.IsEmpty() { - assert.Equal(t, myList.Len(), myList.Rest().Len(), "rest does not change length for empty list") - } else { - assert.Equal(t, myList.Len()-1, myList.Rest().Len(), "rest decreases length of non-empty list") - } +// descSortedIntListGen returns a generator for list of at least several descending ints +func descSortedIntListGen() *rapid.Generator[IList] { + return rapid.Custom(func(t *rapid.T) IList { + myList := New(0) + i := 1 + t.Repeat(map[string]func(*rapid.T){ + "conj": func(t *rapid.T) { + myList = myList.Conj(i) + i += 1 + }, + }) + return myList + }).Filter(func(l IList) bool { + return l.Len() > 1 }) } @@ -49,6 +48,32 @@ func TestFirstIsNilOnlyWhenEmpty(t *testing.T) { }) } +func TestConj(t *testing.T) { + rapid.Check(t, func(t *rapid.T) { + myList := intListGen().Draw(t, "myList") + newElem := rapid.Int().Draw(t, "newElem") + myList2 := myList.Conj(newElem) + assert.Equal(t, myList.Len()+1, myList2.Len(), "conj increases length") + assert.Equal(t, newElem, myList2.First(), "first after conj returns inserted number") + }) +} + +func TestRest(t *testing.T) { + rapid.Check(t, func(t *rapid.T) { + myList := intListGen().Draw(t, "myList") + if myList.IsEmpty() { + assert.Equal(t, myList.Len(), myList.Rest().Len(), "rest does not change length for empty list") + } else { + assert.Equal(t, myList.Len()-1, myList.Rest().Len(), "rest decreases length of non-empty list") + } + }) + + rapid.Check(t, func(t *rapid.T) { + myList := descSortedIntListGen().Draw(t, "myList") + assert.GreaterOrEqual(t, myList.First(), myList.Rest().First(), "rest decreases value in list head") + }) +} + func TestStringifyIntList(t *testing.T) { assert.Equal(t, "(1 2 3)", New(3).Conj(2).Conj(1).String()) @@ -56,7 +81,7 @@ func TestStringifyIntList(t *testing.T) { myList := intListGen().Draw(t, "myList") s := myList.String() r := regexp.MustCompile(`^\([\d\s-]*\)$`) - assert.Equal(t, true, r.Match([]byte(s)), s + " looks like a stringfied list") + assert.Equal(t, true, r.Match([]byte(s)), s+" looks like a stringified list") if !myList.IsEmpty() { assert.Equal(t, myList.Len(), strings.Count(s, " ")+1, "number of spaces in string should match count of elements") } else {