@@ -5,132 +5,84 @@ import "testing"
5
5
/*
6
6
TestCircularQueue tests solution(s) with the following signature and problem description:
7
7
8
- func (queue *UsingCircularArray) enqueue(n int) error
9
- func (queue *UsingCircularArray) dequeue() (int, error)
8
+ func (queue *CircularQueue) enqueue(n int) error
9
+ func (queue *CircularQueue) dequeue() (int, error)
10
+
11
+ Given a size, implement a circular queue using a slice.
10
12
11
- Given a size, implement a circular queue using an array.
12
13
A circular queue also called a ring buffer is different from a normal queue in that
13
14
the last element is connected to the first element.
15
+
16
+ For example given a circular array of size 4 if we enqueue integers {1,2,3,4,5,6} and then dequeue 2 times
17
+ we should get 3 and 4.
18
+
19
+ , - ~ - , , - ~ - , , - ~ - , , - ~ - ,
20
+ , ' ... ' , , ' ... ' , , ' ... ' , , ' ... ' ,
21
+ , ... , , ... , , ... , , ... ,
22
+ , 1 ... , , 1 ... 2 , , 1 ... 2 , , 1 ... 2 ,
23
+ , ... , , ... , , ... , , ... ,
24
+ , ................... , , ................... , , ................... , , ................... ,
25
+ , ................... , , ................... , , ................... , , ................... ,
26
+ , ... , , ... , , ... , , ... ,
27
+ , ... , , ... , , ... 3 , , 4 ... 3 ,
28
+ , ... , ' , ... , ' , ... , ' , ... , '
29
+ ' - ,..., ' ' - ,..., ' ' - ,..., ' ' - ,..., '
30
+
31
+ , - ~ - , , - ~ - , , - ~ - , , - ~ - ,
32
+ , ' ... ' , , ' ... ' , , ' ... ' , , ' ... ' ,
33
+ , ... , , ... , , ... , , ... ,
34
+ , 5 ... 2 , , 5 ... 6 , , 5 ... 6 , , 5 ... 6 ,
35
+ , ... , , ... , , ... , , ... ,
36
+ , ................... , , ................... , , ................... , , ................... ,
37
+ , ................... , , ................... , , ................... , , ................... ,
38
+ , ... , , ... , , ... , , ... ,
39
+ , 4 ... 3 , , 4 ... 3 , , 4 ... , , ... ,
40
+ , ... , ' , ... , ' , ... , ' , ... , '
41
+ ' - ,..., ' ' - ,..., ' ' - ,..., ' ' - ,..., '
42
+
43
+ As shown in the above example the circular queue does not run out of capacity and still allows FIFO operations.
14
44
*/
15
45
func TestCircularQueue (t * testing.T ) {
16
- // Tests a queue by enqueues given items,
17
- // then dequeues a number of times and finally checks the value from the last dequeue.
18
- // The same process then may be repeated for a second time with different values.
46
+ type testRound struct {
47
+ enqueueStart int
48
+ enqueueEnd int
49
+ dequeueStart int
50
+ dequeueEnd int
51
+ expectedErr error
52
+ }
53
+
19
54
tests := []struct {
20
- size int
21
- firstRound * testCase
22
- secondRound * testCase
55
+ size int
56
+ testRounds []testRound
23
57
}{
24
- {0 , & testCase {[]int {1 , 2 , 3 , 4 }, - 1 , - 1 , true , false }, nil },
25
- {4 , & testCase {[]int {1 , 2 , 3 , 4 }, 1 , 1 , false , false }, nil },
26
- {4 , & testCase {[]int {1 , 2 , 3 , 4 }, 2 , 2 , false , false }, nil },
27
- {4 , & testCase {[]int {1 , 2 , 3 , 4 }, 3 , 3 , false , false }, nil },
28
- {4 , & testCase {[]int {1 , 2 , 2 , 3 }, 2 , 2 , false , false }, nil },
29
- {2 , & testCase {[]int {1 , 2 , 2 , 3 }, 2 , 2 , true , false }, nil },
30
- {2 , & testCase {[]int {1 , 2 }, 3 , - 1 , false , true }, nil },
31
- {2 , & testCase {[]int {1 , 2 }, 2 , 2 , false , false }, & testCase {[]int {1 , 2 }, 1 , 1 , false , false }},
32
- {2 , & testCase {[]int {1 , 2 }, 1 , 1 , false , false }, & testCase {[]int {1 }, 2 , 1 , false , false }},
58
+ {1 , []testRound {{1 , 6 , 6 , 6 , nil }}},
59
+ {2 , []testRound {{1 , 6 , 5 , 5 , nil }}},
60
+ {4 , []testRound {{1 , 6 , 3 , 6 , nil }}},
61
+ {4 , []testRound {{1 , 6 , 3 , 6 , nil }, {1 , 6 , 3 , 6 , nil }}},
62
+ {4 , []testRound {{1 , 6 , 3 , 7 , ErrQueueEmpty }}},
33
63
}
34
64
35
65
for i , test := range tests {
36
66
queue := NewCircularQueue (test .size )
37
67
38
- enqueueDequeueAndCheckValue (t , queue , i , test .firstRound )
39
- if test .secondRound != nil {
40
- enqueueDequeueAndCheckValue (t , queue , i , test .secondRound )
41
- }
42
- }
43
- }
44
-
45
- type testCase struct {
46
- enqueue []int
47
- dequeueTimes int
48
- expectedLastDequeuedItem int
49
- expectEnqueueErr bool
50
- expectDequeueErr bool
51
- }
52
-
53
- const (
54
- operationTypeEnqueue = iota
55
- operationTypeDequeue
56
- )
57
-
58
- var queueOperations = []struct {
59
- operationType int
60
- operationValue int
61
- }{
62
- {operationTypeEnqueue , 3 },
63
- {operationTypeEnqueue , 2 },
64
- {operationTypeEnqueue , 1 },
65
- {operationTypeDequeue , 0 },
66
- {operationTypeDequeue , 0 },
67
- {operationTypeDequeue , 0 },
68
- {operationTypeEnqueue , 3 },
69
- {operationTypeEnqueue , 2 },
70
- {operationTypeEnqueue , 1 },
71
- {operationTypeDequeue , 0 },
72
- {operationTypeDequeue , 0 },
73
- {operationTypeDequeue , 0 },
74
- {operationTypeEnqueue , 5 },
75
- {operationTypeDequeue , 0 },
76
- {operationTypeEnqueue , 1 },
77
- {operationTypeDequeue , 0 },
78
- {operationTypeEnqueue , 1 },
79
- }
80
-
81
- func enqueueDequeueAndCheckValue (t * testing.T , queue * CircularQueue , testID int , test * testCase ) {
82
- t .Helper ()
83
- for _ , n := range test .enqueue {
84
- if err := queue .enqueue (n ); err != nil {
85
- if test .expectEnqueueErr {
86
- t .Skipf ("Skipping test case #%d. Expected error occurred. Error %s" , testID , err )
68
+ for j , testRound := range test .testRounds {
69
+ for i := testRound .enqueueStart ; i <= testRound .enqueueEnd ; i ++ {
70
+ queue .enqueue (i )
87
71
}
88
- t .Fatalf ("Failed test case #%d. Did not expect enqueuing error. Error %s" , testID , err )
89
- }
90
- }
91
72
92
- var n int
93
- var err error
94
- for j := 1 ; j <= test .dequeueTimes ; j ++ {
95
- n , err = queue .dequeue ()
96
- if err != nil {
97
- if test .expectDequeueErr {
98
- t .Skipf ("Skipping test case #%d. Expected error occurred. Error %s" , testID , err )
73
+ for want := testRound .dequeueStart ; want <= testRound .dequeueEnd ; want ++ {
74
+ got , err := queue .dequeue ()
75
+ if err != nil {
76
+ if err != testRound .expectedErr {
77
+ t .Fatalf ("Failed test case #%d round #%d. Unexpected error %s" , i , j , err )
78
+ }
79
+ break
80
+ }
81
+
82
+ if got != want {
83
+ t .Fatalf ("Failed test case #%d round #%d. Want %d, got %d" , i , j , want , got )
84
+ }
99
85
}
100
- t .Fatalf ("Failed test case #%d. Did not expect dequeuing error. Error %s" , testID , err )
101
86
}
102
87
}
103
- if n != test .expectedLastDequeuedItem {
104
- t .Fatalf ("Failed test case #%d. Want %d got %d" , testID , test .expectedLastDequeuedItem , n )
105
- }
106
- }
107
-
108
- func TestMultipleOperations (t * testing.T ) {
109
- queue := NewCircularQueue (3 )
110
-
111
- if _ , err := queue .dequeue (); err == nil {
112
- t .Fatal ("Expected error for dequeue-ing an empty queue" )
113
- }
114
-
115
- for i , queueOperation := range queueOperations {
116
- switch queueOperation .operationType {
117
- case operationTypeEnqueue :
118
- if err := queue .enqueue (queueOperation .operationValue ); err != nil {
119
- t .Fatalf ("operation #%d, unexpected error: %s" , i , err )
120
- }
121
- case operationTypeDequeue :
122
- if _ , err := queue .dequeue (); err != nil {
123
- t .Fatalf ("operation #%d, unexpected error: %s" , i , err )
124
- }
125
- }
126
- }
127
-
128
- n , err := queue .dequeue ()
129
- if err != nil {
130
- t .Fatalf ("Failed to dequeue. Error %s" , err )
131
- }
132
-
133
- if n != 1 {
134
- t .Fatalf ("Wanted %d, got %d" , 1 , n )
135
- }
136
88
}
0 commit comments