Home | History | Annotate | Download | only in ring
      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 
      5 package ring
      6 
      7 import (
      8 	"fmt"
      9 	"testing"
     10 )
     11 
     12 // For debugging - keep around.
     13 func dump(r *Ring) {
     14 	if r == nil {
     15 		fmt.Println("empty")
     16 		return
     17 	}
     18 	i, n := 0, r.Len()
     19 	for p := r; i < n; p = p.next {
     20 		fmt.Printf("%4d: %p = {<- %p | %p ->}\n", i, p, p.prev, p.next)
     21 		i++
     22 	}
     23 	fmt.Println()
     24 }
     25 
     26 func verify(t *testing.T, r *Ring, N int, sum int) {
     27 	// Len
     28 	n := r.Len()
     29 	if n != N {
     30 		t.Errorf("r.Len() == %d; expected %d", n, N)
     31 	}
     32 
     33 	// iteration
     34 	n = 0
     35 	s := 0
     36 	r.Do(func(p interface{}) {
     37 		n++
     38 		if p != nil {
     39 			s += p.(int)
     40 		}
     41 	})
     42 	if n != N {
     43 		t.Errorf("number of forward iterations == %d; expected %d", n, N)
     44 	}
     45 	if sum >= 0 && s != sum {
     46 		t.Errorf("forward ring sum = %d; expected %d", s, sum)
     47 	}
     48 
     49 	if r == nil {
     50 		return
     51 	}
     52 
     53 	// connections
     54 	if r.next != nil {
     55 		var p *Ring // previous element
     56 		for q := r; p == nil || q != r; q = q.next {
     57 			if p != nil && p != q.prev {
     58 				t.Errorf("prev = %p, expected q.prev = %p\n", p, q.prev)
     59 			}
     60 			p = q
     61 		}
     62 		if p != r.prev {
     63 			t.Errorf("prev = %p, expected r.prev = %p\n", p, r.prev)
     64 		}
     65 	}
     66 
     67 	// Next, Prev
     68 	if r.Next() != r.next {
     69 		t.Errorf("r.Next() != r.next")
     70 	}
     71 	if r.Prev() != r.prev {
     72 		t.Errorf("r.Prev() != r.prev")
     73 	}
     74 
     75 	// Move
     76 	if r.Move(0) != r {
     77 		t.Errorf("r.Move(0) != r")
     78 	}
     79 	if r.Move(N) != r {
     80 		t.Errorf("r.Move(%d) != r", N)
     81 	}
     82 	if r.Move(-N) != r {
     83 		t.Errorf("r.Move(%d) != r", -N)
     84 	}
     85 	for i := 0; i < 10; i++ {
     86 		ni := N + i
     87 		mi := ni % N
     88 		if r.Move(ni) != r.Move(mi) {
     89 			t.Errorf("r.Move(%d) != r.Move(%d)", ni, mi)
     90 		}
     91 		if r.Move(-ni) != r.Move(-mi) {
     92 			t.Errorf("r.Move(%d) != r.Move(%d)", -ni, -mi)
     93 		}
     94 	}
     95 }
     96 
     97 func TestCornerCases(t *testing.T) {
     98 	var (
     99 		r0 *Ring
    100 		r1 Ring
    101 	)
    102 	// Basics
    103 	verify(t, r0, 0, 0)
    104 	verify(t, &r1, 1, 0)
    105 	// Insert
    106 	r1.Link(r0)
    107 	verify(t, r0, 0, 0)
    108 	verify(t, &r1, 1, 0)
    109 	// Insert
    110 	r1.Link(r0)
    111 	verify(t, r0, 0, 0)
    112 	verify(t, &r1, 1, 0)
    113 	// Unlink
    114 	r1.Unlink(0)
    115 	verify(t, &r1, 1, 0)
    116 }
    117 
    118 func makeN(n int) *Ring {
    119 	r := New(n)
    120 	for i := 1; i <= n; i++ {
    121 		r.Value = i
    122 		r = r.Next()
    123 	}
    124 	return r
    125 }
    126 
    127 func sumN(n int) int { return (n*n + n) / 2 }
    128 
    129 func TestNew(t *testing.T) {
    130 	for i := 0; i < 10; i++ {
    131 		r := New(i)
    132 		verify(t, r, i, -1)
    133 	}
    134 	for i := 0; i < 10; i++ {
    135 		r := makeN(i)
    136 		verify(t, r, i, sumN(i))
    137 	}
    138 }
    139 
    140 func TestLink1(t *testing.T) {
    141 	r1a := makeN(1)
    142 	var r1b Ring
    143 	r2a := r1a.Link(&r1b)
    144 	verify(t, r2a, 2, 1)
    145 	if r2a != r1a {
    146 		t.Errorf("a) 2-element link failed")
    147 	}
    148 
    149 	r2b := r2a.Link(r2a.Next())
    150 	verify(t, r2b, 2, 1)
    151 	if r2b != r2a.Next() {
    152 		t.Errorf("b) 2-element link failed")
    153 	}
    154 
    155 	r1c := r2b.Link(r2b)
    156 	verify(t, r1c, 1, 1)
    157 	verify(t, r2b, 1, 0)
    158 }
    159 
    160 func TestLink2(t *testing.T) {
    161 	var r0 *Ring
    162 	r1a := &Ring{Value: 42}
    163 	r1b := &Ring{Value: 77}
    164 	r10 := makeN(10)
    165 
    166 	r1a.Link(r0)
    167 	verify(t, r1a, 1, 42)
    168 
    169 	r1a.Link(r1b)
    170 	verify(t, r1a, 2, 42+77)
    171 
    172 	r10.Link(r0)
    173 	verify(t, r10, 10, sumN(10))
    174 
    175 	r10.Link(r1a)
    176 	verify(t, r10, 12, sumN(10)+42+77)
    177 }
    178 
    179 func TestLink3(t *testing.T) {
    180 	var r Ring
    181 	n := 1
    182 	for i := 1; i < 100; i++ {
    183 		n += i
    184 		verify(t, r.Link(New(i)), n, -1)
    185 	}
    186 }
    187 
    188 func TestUnlink(t *testing.T) {
    189 	r10 := makeN(10)
    190 	s10 := r10.Move(6)
    191 
    192 	sum10 := sumN(10)
    193 
    194 	verify(t, r10, 10, sum10)
    195 	verify(t, s10, 10, sum10)
    196 
    197 	r0 := r10.Unlink(0)
    198 	verify(t, r0, 0, 0)
    199 
    200 	r1 := r10.Unlink(1)
    201 	verify(t, r1, 1, 2)
    202 	verify(t, r10, 9, sum10-2)
    203 
    204 	r9 := r10.Unlink(9)
    205 	verify(t, r9, 9, sum10-2)
    206 	verify(t, r10, 9, sum10-2)
    207 }
    208 
    209 func TestLinkUnlink(t *testing.T) {
    210 	for i := 1; i < 4; i++ {
    211 		ri := New(i)
    212 		for j := 0; j < i; j++ {
    213 			rj := ri.Unlink(j)
    214 			verify(t, rj, j, -1)
    215 			verify(t, ri, i-j, -1)
    216 			ri.Link(rj)
    217 			verify(t, ri, i, -1)
    218 		}
    219 	}
    220 }
    221 
    222 // Test that calling Move() on an empty Ring initializes it.
    223 func TestMoveEmptyRing(t *testing.T) {
    224 	var r Ring
    225 
    226 	r.Move(1)
    227 	verify(t, &r, 1, 0)
    228 }
    229