You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
2.2 KiB

  1. package clist_test
  2. import (
  3. "testing"
  4. "github.com/stretchr/testify/require"
  5. "pgregory.net/rapid"
  6. "github.com/tendermint/tendermint/internal/libs/clist"
  7. )
  8. func TestCListProperties(t *testing.T) {
  9. rapid.Check(t, rapid.Run(&clistModel{}))
  10. }
  11. // clistModel is used by the rapid state machine testing framework.
  12. // clistModel contains both the clist that is being tested and a slice of *clist.CElements
  13. // that will be used to model the expected clist behavior.
  14. type clistModel struct {
  15. clist *clist.CList
  16. model []*clist.CElement
  17. }
  18. // Init is a method used by the rapid state machine testing library.
  19. // Init is called when the test starts to initialize the data that will be used
  20. // in the state machine test.
  21. func (m *clistModel) Init(t *rapid.T) {
  22. m.clist = clist.New()
  23. m.model = []*clist.CElement{}
  24. }
  25. // PushBack defines an action that will be randomly selected across by the rapid state
  26. // machines testing library. Every call to PushBack calls PushBack on the clist and
  27. // performs a similar action on the model data.
  28. func (m *clistModel) PushBack(t *rapid.T) {
  29. value := rapid.String().Draw(t, "value").(string)
  30. el := m.clist.PushBack(value)
  31. m.model = append(m.model, el)
  32. }
  33. // Remove defines an action that will be randomly selected across by the rapid state
  34. // machine testing library. Every call to Remove selects an element from the model
  35. // and calls Remove on the CList with that element. The same element is removed from
  36. // the model to keep the objects in sync.
  37. func (m *clistModel) Remove(t *rapid.T) {
  38. if len(m.model) == 0 {
  39. return
  40. }
  41. ix := rapid.IntRange(0, len(m.model)-1).Draw(t, "index").(int)
  42. value := m.model[ix]
  43. m.model = append(m.model[:ix], m.model[ix+1:]...)
  44. m.clist.Remove(value)
  45. }
  46. // Check is a method required by the rapid state machine testing library.
  47. // Check is run after each action and is used to verify that the state of the object,
  48. // in this case a clist.CList matches the state of the objec.
  49. func (m *clistModel) Check(t *rapid.T) {
  50. require.Equal(t, len(m.model), m.clist.Len())
  51. if len(m.model) == 0 {
  52. return
  53. }
  54. require.Equal(t, m.model[0], m.clist.Front())
  55. require.Equal(t, m.model[len(m.model)-1], m.clist.Back())
  56. iter := m.clist.Front()
  57. for _, val := range m.model {
  58. require.Equal(t, val, iter)
  59. iter = iter.Next()
  60. }
  61. }