list_test.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package list
  5. import "testing"
  6. func checkListLen(t *testing.T, l *List, len int) bool {
  7. if n := l.Len(); n != len {
  8. t.Errorf("l.Len() = %d, want %d", n, len)
  9. return false
  10. }
  11. return true
  12. }
  13. func checkListPointers(t *testing.T, l *List, es []*Element) {
  14. root := &l.root
  15. if !checkListLen(t, l, len(es)) {
  16. return
  17. }
  18. // zero length lists must be the zero value or properly initialized (sentinel circle)
  19. if len(es) == 0 {
  20. if l.root.next != nil && l.root.next != root || l.root.prev != nil && l.root.prev != root {
  21. t.Errorf("l.root.next = %p, l.root.prev = %p; both should both be nil or %p", l.root.next, l.root.prev, root)
  22. }
  23. return
  24. }
  25. // len(es) > 0
  26. // check internal and external prev/next connections
  27. for i, e := range es {
  28. prev := root
  29. Prev := (*Element)(nil)
  30. if i > 0 {
  31. prev = es[i-1]
  32. Prev = prev
  33. }
  34. if p := e.prev; p != prev {
  35. t.Errorf("elt[%d](%p).prev = %p, want %p", i, e, p, prev)
  36. }
  37. if p := e.Prev(); p != Prev {
  38. t.Errorf("elt[%d](%p).Prev() = %p, want %p", i, e, p, Prev)
  39. }
  40. next := root
  41. Next := (*Element)(nil)
  42. if i < len(es)-1 {
  43. next = es[i+1]
  44. Next = next
  45. }
  46. if n := e.next; n != next {
  47. t.Errorf("elt[%d](%p).next = %p, want %p", i, e, n, next)
  48. }
  49. if n := e.Next(); n != Next {
  50. t.Errorf("elt[%d](%p).Next() = %p, want %p", i, e, n, Next)
  51. }
  52. }
  53. }
  54. func TestList(t *testing.T) {
  55. l := New()
  56. checkListPointers(t, l, []*Element{})
  57. // Single element list
  58. e := l.PushFront("a")
  59. checkListPointers(t, l, []*Element{e})
  60. l.MoveToFront(e)
  61. checkListPointers(t, l, []*Element{e})
  62. l.MoveToBack(e)
  63. checkListPointers(t, l, []*Element{e})
  64. l.Remove(e)
  65. checkListPointers(t, l, []*Element{})
  66. // Bigger list
  67. e2 := l.PushFront(2)
  68. e1 := l.PushFront(1)
  69. e3 := l.PushBack(3)
  70. e4 := l.PushBack("banana")
  71. checkListPointers(t, l, []*Element{e1, e2, e3, e4})
  72. l.Remove(e2)
  73. checkListPointers(t, l, []*Element{e1, e3, e4})
  74. l.MoveToFront(e3) // move from middle
  75. checkListPointers(t, l, []*Element{e3, e1, e4})
  76. l.MoveToFront(e1)
  77. l.MoveToBack(e3) // move from middle
  78. checkListPointers(t, l, []*Element{e1, e4, e3})
  79. l.MoveToFront(e3) // move from back
  80. checkListPointers(t, l, []*Element{e3, e1, e4})
  81. l.MoveToFront(e3) // should be no-op
  82. checkListPointers(t, l, []*Element{e3, e1, e4})
  83. l.MoveToBack(e3) // move from front
  84. checkListPointers(t, l, []*Element{e1, e4, e3})
  85. l.MoveToBack(e3) // should be no-op
  86. checkListPointers(t, l, []*Element{e1, e4, e3})
  87. e2 = l.InsertBefore(2, e1) // insert before front
  88. checkListPointers(t, l, []*Element{e2, e1, e4, e3})
  89. l.Remove(e2)
  90. e2 = l.InsertBefore(2, e4) // insert before middle
  91. checkListPointers(t, l, []*Element{e1, e2, e4, e3})
  92. l.Remove(e2)
  93. e2 = l.InsertBefore(2, e3) // insert before back
  94. checkListPointers(t, l, []*Element{e1, e4, e2, e3})
  95. l.Remove(e2)
  96. e2 = l.InsertAfter(2, e1) // insert after front
  97. checkListPointers(t, l, []*Element{e1, e2, e4, e3})
  98. l.Remove(e2)
  99. e2 = l.InsertAfter(2, e4) // insert after middle
  100. checkListPointers(t, l, []*Element{e1, e4, e2, e3})
  101. l.Remove(e2)
  102. e2 = l.InsertAfter(2, e3) // insert after back
  103. checkListPointers(t, l, []*Element{e1, e4, e3, e2})
  104. l.Remove(e2)
  105. // Check standard iteration.
  106. sum := 0
  107. for e := l.Front(); e != nil; e = e.Next() {
  108. if i, ok := e.Value.(int); ok {
  109. sum += i
  110. }
  111. }
  112. if sum != 4 {
  113. t.Errorf("sum over l = %d, want 4", sum)
  114. }
  115. // Clear all elements by iterating
  116. var next *Element
  117. for e := l.Front(); e != nil; e = next {
  118. next = e.Next()
  119. l.Remove(e)
  120. }
  121. checkListPointers(t, l, []*Element{})
  122. }
  123. func checkList(t *testing.T, l *List, es []any) {
  124. if !checkListLen(t, l, len(es)) {
  125. return
  126. }
  127. i := 0
  128. for e := l.Front(); e != nil; e = e.Next() {
  129. le := e.Value.(int)
  130. if le != es[i] {
  131. t.Errorf("elt[%d].Value = %v, want %v", i, le, es[i])
  132. }
  133. i++
  134. }
  135. }
  136. func TestExtending(t *testing.T) {
  137. l1 := New()
  138. l2 := New()
  139. l1.PushBack(1)
  140. l1.PushBack(2)
  141. l1.PushBack(3)
  142. l2.PushBack(4)
  143. l2.PushBack(5)
  144. l3 := New()
  145. l3.PushBackList(l1)
  146. checkList(t, l3, []any{1, 2, 3})
  147. l3.PushBackList(l2)
  148. checkList(t, l3, []any{1, 2, 3, 4, 5})
  149. l3 = New()
  150. l3.PushFrontList(l2)
  151. checkList(t, l3, []any{4, 5})
  152. l3.PushFrontList(l1)
  153. checkList(t, l3, []any{1, 2, 3, 4, 5})
  154. checkList(t, l1, []any{1, 2, 3})
  155. checkList(t, l2, []any{4, 5})
  156. l3 = New()
  157. l3.PushBackList(l1)
  158. checkList(t, l3, []any{1, 2, 3})
  159. l3.PushBackList(l3)
  160. checkList(t, l3, []any{1, 2, 3, 1, 2, 3})
  161. l3 = New()
  162. l3.PushFrontList(l1)
  163. checkList(t, l3, []any{1, 2, 3})
  164. l3.PushFrontList(l3)
  165. checkList(t, l3, []any{1, 2, 3, 1, 2, 3})
  166. l3 = New()
  167. l1.PushBackList(l3)
  168. checkList(t, l1, []any{1, 2, 3})
  169. l1.PushFrontList(l3)
  170. checkList(t, l1, []any{1, 2, 3})
  171. }
  172. func TestRemove(t *testing.T) {
  173. l := New()
  174. e1 := l.PushBack(1)
  175. e2 := l.PushBack(2)
  176. checkListPointers(t, l, []*Element{e1, e2})
  177. e := l.Front()
  178. l.Remove(e)
  179. checkListPointers(t, l, []*Element{e2})
  180. l.Remove(e)
  181. checkListPointers(t, l, []*Element{e2})
  182. }
  183. func TestIssue4103(t *testing.T) {
  184. l1 := New()
  185. l1.PushBack(1)
  186. l1.PushBack(2)
  187. l2 := New()
  188. l2.PushBack(3)
  189. l2.PushBack(4)
  190. e := l1.Front()
  191. l2.Remove(e) // l2 should not change because e is not an element of l2
  192. if n := l2.Len(); n != 2 {
  193. t.Errorf("l2.Len() = %d, want 2", n)
  194. }
  195. l1.InsertBefore(8, e)
  196. if n := l1.Len(); n != 3 {
  197. t.Errorf("l1.Len() = %d, want 3", n)
  198. }
  199. }
  200. func TestIssue6349(t *testing.T) {
  201. l := New()
  202. l.PushBack(1)
  203. l.PushBack(2)
  204. e := l.Front()
  205. l.Remove(e)
  206. if e.Value != 1 {
  207. t.Errorf("e.value = %d, want 1", e.Value)
  208. }
  209. if e.Next() != nil {
  210. t.Errorf("e.Next() != nil")
  211. }
  212. if e.Prev() != nil {
  213. t.Errorf("e.Prev() != nil")
  214. }
  215. }
  216. func TestMove(t *testing.T) {
  217. l := New()
  218. e1 := l.PushBack(1)
  219. e2 := l.PushBack(2)
  220. e3 := l.PushBack(3)
  221. e4 := l.PushBack(4)
  222. l.MoveAfter(e3, e3)
  223. checkListPointers(t, l, []*Element{e1, e2, e3, e4})
  224. l.MoveBefore(e2, e2)
  225. checkListPointers(t, l, []*Element{e1, e2, e3, e4})
  226. l.MoveAfter(e3, e2)
  227. checkListPointers(t, l, []*Element{e1, e2, e3, e4})
  228. l.MoveBefore(e2, e3)
  229. checkListPointers(t, l, []*Element{e1, e2, e3, e4})
  230. l.MoveBefore(e2, e4)
  231. checkListPointers(t, l, []*Element{e1, e3, e2, e4})
  232. e2, e3 = e3, e2
  233. l.MoveBefore(e4, e1)
  234. checkListPointers(t, l, []*Element{e4, e1, e2, e3})
  235. e1, e2, e3, e4 = e4, e1, e2, e3
  236. l.MoveAfter(e4, e1)
  237. checkListPointers(t, l, []*Element{e1, e4, e2, e3})
  238. e2, e3, e4 = e4, e2, e3
  239. l.MoveAfter(e2, e3)
  240. checkListPointers(t, l, []*Element{e1, e3, e2, e4})
  241. }
  242. // Test PushFront, PushBack, PushFrontList, PushBackList with uninitialized List
  243. func TestZeroList(t *testing.T) {
  244. var l1 = new(List)
  245. l1.PushFront(1)
  246. checkList(t, l1, []any{1})
  247. var l2 = new(List)
  248. l2.PushBack(1)
  249. checkList(t, l2, []any{1})
  250. var l3 = new(List)
  251. l3.PushFrontList(l1)
  252. checkList(t, l3, []any{1})
  253. var l4 = new(List)
  254. l4.PushBackList(l2)
  255. checkList(t, l4, []any{1})
  256. }
  257. // Test that a list l is not modified when calling InsertBefore with a mark that is not an element of l.
  258. func TestInsertBeforeUnknownMark(t *testing.T) {
  259. var l List
  260. l.PushBack(1)
  261. l.PushBack(2)
  262. l.PushBack(3)
  263. l.InsertBefore(1, new(Element))
  264. checkList(t, &l, []any{1, 2, 3})
  265. }
  266. // Test that a list l is not modified when calling InsertAfter with a mark that is not an element of l.
  267. func TestInsertAfterUnknownMark(t *testing.T) {
  268. var l List
  269. l.PushBack(1)
  270. l.PushBack(2)
  271. l.PushBack(3)
  272. l.InsertAfter(1, new(Element))
  273. checkList(t, &l, []any{1, 2, 3})
  274. }
  275. // Test that a list l is not modified when calling MoveAfter or MoveBefore with a mark that is not an element of l.
  276. func TestMoveUnknownMark(t *testing.T) {
  277. var l1 List
  278. e1 := l1.PushBack(1)
  279. var l2 List
  280. e2 := l2.PushBack(2)
  281. l1.MoveAfter(e1, e2)
  282. checkList(t, &l1, []any{1})
  283. checkList(t, &l2, []any{2})
  284. l1.MoveBefore(e1, e2)
  285. checkList(t, &l1, []any{1})
  286. checkList(t, &l2, []any{2})
  287. }