collection_test.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. package ezdb
  2. import (
  3. "errors"
  4. "fmt"
  5. "testing"
  6. )
  7. // Basic struct for testing.
  8. type Student struct {
  9. Name string `json:"name"`
  10. Age int `json:"age"`
  11. }
  12. var invalidStudents = map[string]*Student{
  13. "": {},
  14. }
  15. var nonexistentStudentKey = "nonexistent"
  16. // Basic marshaler for testing.
  17. var studentMarshaler = JSON(func() *Student {
  18. return &Student{}
  19. })
  20. // Sample data.
  21. var students = map[string]*Student{
  22. "annie": {Name: "Annie", Age: 32},
  23. "ben": {Name: "Ben", Age: 50},
  24. "clive": {Name: "Clive", Age: 21},
  25. }
  26. // Sample data (marshaled).
  27. var studentsMarshaled = map[string][]byte{
  28. "annie": []byte("{\"name\":\"Annie\",\"age\":32}"),
  29. "ben": []byte("{\"name\":\"Ben\",\"age\":50}"),
  30. "clive": []byte("{\"name\":\"Clive\",\"age\":21}"),
  31. }
  32. type CollectionTest struct {
  33. C Collection[*Student]
  34. T *testing.T
  35. F map[string]func() error
  36. }
  37. func (c *CollectionTest) open() error {
  38. if err := c.C.Open(); err != nil {
  39. c.T.Errorf("(open) failed to open collection: %v", err)
  40. return err
  41. }
  42. return nil
  43. }
  44. func (c *CollectionTest) put() error {
  45. // Test collection can store all students
  46. for key, value := range students {
  47. if err := c.C.Put(key, value); err != nil {
  48. c.T.Errorf("(put) failed to put student '%s': %v", key, err)
  49. return err
  50. }
  51. c.T.Logf("(put) put student '%s'", key)
  52. }
  53. // Test collection does not accept invalid keys
  54. for key, value := range invalidStudents {
  55. if err := c.C.Put(key, value); err == nil {
  56. c.T.Errorf("(put) should not have put invalid student '%s'", key)
  57. return err
  58. }
  59. c.T.Logf("(put) skipped invalid student '%s'", key)
  60. }
  61. return nil
  62. }
  63. func (c *CollectionTest) has() error {
  64. // Test collection has all students
  65. for key := range students {
  66. has, err := c.C.Has(key)
  67. if err != nil {
  68. c.T.Errorf("(has) failed to test whether collection has student '%s': %v", key, err)
  69. return err
  70. } else if !has {
  71. c.T.Errorf("(has) expected collection to have student '%s'", key)
  72. return err
  73. }
  74. c.T.Logf("(has) found student '%s'", key)
  75. }
  76. // Test collection does claim to have a student that doesn't exist
  77. has, err := c.C.Has(nonexistentStudentKey)
  78. if err != nil {
  79. c.T.Errorf("(has) failed to test whether collection has nonexistent student: %v", err)
  80. } else if has {
  81. c.T.Error("(has) expected collection not to have nonexistent student")
  82. } else {
  83. c.T.Logf("(has) collection does not have nonexistent student")
  84. }
  85. return nil
  86. }
  87. func (c *CollectionTest) get() error {
  88. // Test collection can retrieve all students
  89. for key, expected := range students {
  90. actual, err := c.C.Get(key)
  91. if err != nil {
  92. c.T.Errorf("(get) failed to get student '%s': %v", key, err)
  93. continue
  94. } else if err := compareStudent(key, expected, actual); err != nil {
  95. c.T.Errorf("(get) %v", err)
  96. } else {
  97. c.T.Logf("(get) correctly got student '%s'", key)
  98. }
  99. }
  100. // Test collection does not retrieve a nonexistent student
  101. _, err := c.C.Get(nonexistentStudentKey)
  102. if err == nil {
  103. c.T.Error("(get) expected collection to return an error for nonexistent student")
  104. } else {
  105. c.T.Log("(get) collection did not get a nonexistent student")
  106. }
  107. return nil
  108. }
  109. func (c *CollectionTest) delete() error {
  110. if err := c.C.Delete("annie"); err != nil {
  111. c.T.Errorf("(delete) failed to delete student '%s': %v", "annie", err)
  112. return err
  113. }
  114. // Confirm student has been deleted
  115. has, err := c.C.Has("annie")
  116. if err != nil {
  117. c.T.Errorf("(delete) failed to test whether collection has deleted student 'annie': %v", err)
  118. return err
  119. } else if has {
  120. c.T.Error("(delete) expected collection not to have deleted student 'annie'")
  121. return err
  122. } else {
  123. c.T.Log("(delete) collection did not get the deleted student 'annie'")
  124. }
  125. // Reinsert deleted student
  126. if err := c.C.Put("annie", students["annie"]); err != nil {
  127. c.T.Errorf("(delete) failed to reinsert student 'annie': %v", err)
  128. return err
  129. } else {
  130. c.T.Log("(delete) reinserted student 'annie'")
  131. }
  132. return nil
  133. }
  134. func (c *CollectionTest) iterCount() error {
  135. iter := c.C.Iter()
  136. defer iter.Release()
  137. expected := len(students)
  138. actual := iter.Count()
  139. if expected != actual {
  140. c.T.Errorf("(iterCount) incorrect count of students (expected %d, got %d)", expected, actual)
  141. return errors.New("incorrect count")
  142. } else {
  143. c.T.Logf("(iterCount) correct count of students (expected %d, got %d)", expected, actual)
  144. }
  145. return nil
  146. }
  147. func (c *CollectionTest) iterFirst() error {
  148. iter := c.C.Iter().SortKeys(func(a, b string) bool {
  149. return a < b
  150. })
  151. defer iter.Release()
  152. expectedKey := "annie"
  153. iter.First()
  154. actualKey := iter.Key()
  155. if actualKey != expectedKey {
  156. c.T.Errorf("(iterFirst) incorrect student (expected '%s', got '%s')", expectedKey, actualKey)
  157. return nil
  158. }
  159. expected := students["annie"]
  160. actual, err := iter.Value()
  161. if err != nil {
  162. c.T.Errorf("(iterFirst) failed to get student '%s': %v", actualKey, err)
  163. return err
  164. }
  165. if err := compareStudent(expectedKey, expected, actual); err != nil {
  166. c.T.Errorf("(iterFirst) %v", err)
  167. }
  168. return nil
  169. }
  170. func (c *CollectionTest) iterLast() error {
  171. iter := c.C.Iter().SortKeys(func(a, b string) bool {
  172. return a < b
  173. })
  174. defer iter.Release()
  175. expectedKey := "clive"
  176. iter.Last()
  177. actualKey := iter.Key()
  178. if actualKey != expectedKey {
  179. c.T.Errorf("(iterFirst) incorrect student (expected '%s', got '%s')", expectedKey, actualKey)
  180. return nil
  181. }
  182. expected := students["clive"]
  183. actual, err := iter.Value()
  184. if err != nil {
  185. c.T.Errorf("(iterFirst) failed to get student '%s': %v", actualKey, err)
  186. return err
  187. }
  188. if err := compareStudent(expectedKey, expected, actual); err != nil {
  189. c.T.Errorf("(iterFirst) %v", err)
  190. }
  191. return nil
  192. }
  193. func (c *CollectionTest) close() error {
  194. if c.F["close"] != nil {
  195. if err := c.F["close"](); err != nil {
  196. c.T.Errorf("(close) failed to close collection: %v", err)
  197. return err
  198. }
  199. } else if err := c.C.Close(); err != nil {
  200. c.T.Errorf("(close) failed to close collection: %v", err)
  201. return err
  202. }
  203. c.T.Log("(close) closed database")
  204. return nil
  205. }
  206. func (c *CollectionTest) Run() {
  207. tests := []func() error{
  208. c.open,
  209. c.put,
  210. c.has,
  211. c.get,
  212. c.delete,
  213. c.iterCount,
  214. c.iterFirst,
  215. c.iterLast,
  216. c.close,
  217. }
  218. for _, test := range tests {
  219. if err := test(); err != nil {
  220. return
  221. }
  222. }
  223. }
  224. func compareStudent(expectedKey string, expected, actual *Student) error {
  225. if actual.Name != expected.Name {
  226. return fmt.Errorf("student '%s' has wrong name (expected '%s', got '%s')", expectedKey, expected.Name, actual.Name)
  227. } else if actual.Age != expected.Age {
  228. return fmt.Errorf("student '%s' has wrong age (expected '%s', got '%s')", expectedKey, expected.Name, actual.Name)
  229. }
  230. return nil
  231. }