/ queue / circular_buf_test.go
circular_buf_test.go
  1  package queue
  2  
  3  import (
  4  	"reflect"
  5  	"testing"
  6  )
  7  
  8  // TestNewCircularBuffer tests the size parameter check when creating a circular
  9  // buffer.
 10  func TestNewCircularBuffer(t *testing.T) {
 11  	tests := []struct {
 12  		name          string
 13  		size          int
 14  		expectedError error
 15  	}{
 16  		{
 17  			name:          "zero size",
 18  			size:          0,
 19  			expectedError: errInvalidSize,
 20  		},
 21  		{
 22  			name:          "negative size",
 23  			size:          -1,
 24  			expectedError: errInvalidSize,
 25  		},
 26  		{
 27  			name:          "ok size",
 28  			size:          1,
 29  			expectedError: nil,
 30  		},
 31  	}
 32  
 33  	for _, test := range tests {
 34  		test := test
 35  
 36  		t.Run(test.name, func(t *testing.T) {
 37  			_, err := NewCircularBuffer(test.size)
 38  			if err != test.expectedError {
 39  				t.Fatalf("expected: %v, got: %v",
 40  					test.expectedError, err)
 41  			}
 42  		})
 43  	}
 44  }
 45  
 46  // TestCircularBuffer tests the adding and listing of items in a circular
 47  // buffer.
 48  func TestCircularBuffer(t *testing.T) {
 49  	tests := []struct {
 50  		name          string
 51  		size          int
 52  		itemCount     int
 53  		expectedItems []interface{}
 54  	}{
 55  		{
 56  			name:          "no elements",
 57  			size:          5,
 58  			itemCount:     0,
 59  			expectedItems: nil,
 60  		},
 61  		{
 62  			name:      "single element",
 63  			size:      5,
 64  			itemCount: 1,
 65  			expectedItems: []interface{}{
 66  				0,
 67  			},
 68  		},
 69  		{
 70  			name:      "no wrap, not full",
 71  			size:      5,
 72  			itemCount: 4,
 73  			expectedItems: []interface{}{
 74  				0, 1, 2, 3,
 75  			},
 76  		},
 77  		{
 78  			name:      "no wrap, exactly full",
 79  			size:      5,
 80  			itemCount: 5,
 81  			expectedItems: []interface{}{
 82  				0, 1, 2, 3, 4,
 83  			},
 84  		},
 85  		{
 86  			// The underlying array should contain {5, 1, 2, 3, 4}.
 87  			name:      "wrap, one over",
 88  			size:      5,
 89  			itemCount: 6,
 90  			expectedItems: []interface{}{
 91  				1, 2, 3, 4, 5,
 92  			},
 93  		},
 94  		{
 95  			// The underlying array should contain {5, 6, 2, 3, 4}.
 96  			name:      "wrap, two over",
 97  			size:      5,
 98  			itemCount: 7,
 99  			expectedItems: []interface{}{
100  				2, 3, 4, 5, 6,
101  			},
102  		},
103  	}
104  
105  	for _, test := range tests {
106  		test := test
107  
108  		t.Run(test.name, func(t *testing.T) {
109  			t.Parallel()
110  
111  			buffer, err := NewCircularBuffer(test.size)
112  			if err != nil {
113  				t.Fatalf("unexpected error: %v", err)
114  			}
115  
116  			for i := 0; i < test.itemCount; i++ {
117  				buffer.Add(i)
118  			}
119  
120  			// List the items in the buffer and check that the list
121  			// is as expected.
122  			list := buffer.List()
123  			if !reflect.DeepEqual(test.expectedItems, list) {
124  				t.Fatalf("expected %v, got: %v",
125  					test.expectedItems, list)
126  			}
127  		})
128  	}
129  }
130  
131  // TestLatest tests fetching of the last item added to a circular buffer.
132  func TestLatest(t *testing.T) {
133  	tests := []struct {
134  		name string
135  		size int
136  
137  		// items is the number of items to add to the buffer.
138  		items int
139  
140  		// expectedItem is the value we expect from Latest().
141  		expectedItem interface{}
142  	}{
143  		{
144  			name:         "no items",
145  			size:         3,
146  			items:        0,
147  			expectedItem: nil,
148  		},
149  		{
150  			name:         "one item",
151  			size:         3,
152  			items:        1,
153  			expectedItem: 0,
154  		},
155  		{
156  			name:         "exactly full",
157  			size:         3,
158  			items:        3,
159  			expectedItem: 2,
160  		},
161  		{
162  			name:         "overflow to index 0",
163  			size:         3,
164  			items:        4,
165  			expectedItem: 3,
166  		},
167  		{
168  			name:         "overflow twice to index 0",
169  			size:         3,
170  			items:        7,
171  			expectedItem: 6,
172  		},
173  	}
174  
175  	for _, test := range tests {
176  		test := test
177  
178  		t.Run(test.name, func(t *testing.T) {
179  			//t.Parallel()
180  
181  			buffer, err := NewCircularBuffer(test.size)
182  			if err != nil {
183  				t.Fatalf("unexpected error: %v", err)
184  			}
185  
186  			for i := 0; i < test.items; i++ {
187  				buffer.Add(i)
188  			}
189  
190  			latest := buffer.Latest()
191  
192  			if !reflect.DeepEqual(latest, test.expectedItem) {
193  				t.Fatalf("expected: %v, got: %v",
194  					test.expectedItem, latest)
195  			}
196  		})
197  	}
198  }