1 use crate::RingBuffer;
2 use core::sync::atomic::Ordering;
3 #[cfg(feature = "std")]
4 use std::thread;
5 
head_tail<T>(rb: &RingBuffer<T>) -> (usize, usize)6 fn head_tail<T>(rb: &RingBuffer<T>) -> (usize, usize) {
7     (
8         rb.head.load(Ordering::Acquire),
9         rb.tail.load(Ordering::Acquire),
10     )
11 }
12 
13 #[test]
capacity()14 fn capacity() {
15     let cap = 13;
16     let buf = RingBuffer::<i32>::new(cap);
17     assert_eq!(buf.capacity(), cap);
18 }
19 #[test]
split_capacity()20 fn split_capacity() {
21     let cap = 13;
22     let buf = RingBuffer::<i32>::new(cap);
23     let (prod, cons) = buf.split();
24 
25     assert_eq!(prod.capacity(), cap);
26     assert_eq!(cons.capacity(), cap);
27 }
28 
29 #[cfg(feature = "std")]
30 #[test]
split_threads()31 fn split_threads() {
32     let buf = RingBuffer::<i32>::new(10);
33     let (prod, cons) = buf.split();
34 
35     let pjh = thread::spawn(move || {
36         let _ = prod;
37     });
38 
39     let cjh = thread::spawn(move || {
40         let _ = cons;
41     });
42 
43     pjh.join().unwrap();
44     cjh.join().unwrap();
45 }
46 
47 #[test]
push()48 fn push() {
49     let cap = 2;
50     let buf = RingBuffer::<i32>::new(cap);
51     let (mut prod, _) = buf.split();
52 
53     assert_eq!(head_tail(&prod.rb), (0, 0));
54 
55     assert_eq!(prod.push(123), Ok(()));
56     assert_eq!(head_tail(&prod.rb), (0, 1));
57 
58     assert_eq!(prod.push(234), Ok(()));
59     assert_eq!(head_tail(&prod.rb), (0, 2));
60 
61     assert_eq!(prod.push(345), Err(345));
62     assert_eq!(head_tail(&prod.rb), (0, 2));
63 }
64 
65 #[test]
pop_empty()66 fn pop_empty() {
67     let cap = 2;
68     let buf = RingBuffer::<i32>::new(cap);
69     let (_, mut cons) = buf.split();
70 
71     assert_eq!(head_tail(&cons.rb), (0, 0));
72 
73     assert_eq!(cons.pop(), None);
74     assert_eq!(head_tail(&cons.rb), (0, 0));
75 }
76 
77 #[test]
push_pop_one()78 fn push_pop_one() {
79     let cap = 2;
80     let buf = RingBuffer::<i32>::new(cap);
81     let (mut prod, mut cons) = buf.split();
82 
83     let vcap = cap + 1;
84     let values = [12, 34, 56, 78, 90];
85     assert_eq!(head_tail(&cons.rb), (0, 0));
86 
87     for (i, v) in values.iter().enumerate() {
88         assert_eq!(prod.push(*v), Ok(()));
89         assert_eq!(head_tail(&cons.rb), (i % vcap, (i + 1) % vcap));
90 
91         assert_eq!(cons.pop().unwrap(), *v);
92         assert_eq!(head_tail(&cons.rb), ((i + 1) % vcap, (i + 1) % vcap));
93 
94         assert_eq!(cons.pop(), None);
95         assert_eq!(head_tail(&cons.rb), ((i + 1) % vcap, (i + 1) % vcap));
96     }
97 }
98 
99 #[test]
push_pop_all()100 fn push_pop_all() {
101     let cap = 2;
102     let buf = RingBuffer::<i32>::new(cap);
103     let (mut prod, mut cons) = buf.split();
104 
105     let vcap = cap + 1;
106     let values = [(12, 34, 13), (56, 78, 57), (90, 10, 91)];
107     assert_eq!(head_tail(&cons.rb), (0, 0));
108 
109     for (i, v) in values.iter().enumerate() {
110         assert_eq!(prod.push(v.0), Ok(()));
111         assert_eq!(head_tail(&cons.rb), (cap * i % vcap, (cap * i + 1) % vcap));
112 
113         assert_eq!(prod.push(v.1), Ok(()));
114         assert_eq!(head_tail(&cons.rb), (cap * i % vcap, (cap * i + 2) % vcap));
115 
116         assert_eq!(prod.push(v.2).unwrap_err(), v.2);
117         assert_eq!(head_tail(&cons.rb), (cap * i % vcap, (cap * i + 2) % vcap));
118 
119         assert_eq!(cons.pop().unwrap(), v.0);
120         assert_eq!(
121             head_tail(&cons.rb),
122             ((cap * i + 1) % vcap, (cap * i + 2) % vcap)
123         );
124 
125         assert_eq!(cons.pop().unwrap(), v.1);
126         assert_eq!(
127             head_tail(&cons.rb),
128             ((cap * i + 2) % vcap, (cap * i + 2) % vcap)
129         );
130 
131         assert_eq!(cons.pop(), None);
132         assert_eq!(
133             head_tail(&cons.rb),
134             ((cap * i + 2) % vcap, (cap * i + 2) % vcap)
135         );
136     }
137 }
138 
139 #[test]
empty_full()140 fn empty_full() {
141     let buf = RingBuffer::<i32>::new(1);
142     let (mut prod, cons) = buf.split();
143 
144     assert!(prod.is_empty());
145     assert!(cons.is_empty());
146     assert!(!prod.is_full());
147     assert!(!cons.is_full());
148 
149     assert_eq!(prod.push(123), Ok(()));
150 
151     assert!(!prod.is_empty());
152     assert!(!cons.is_empty());
153     assert!(prod.is_full());
154     assert!(cons.is_full());
155 }
156 
157 #[test]
len_remaining()158 fn len_remaining() {
159     let buf = RingBuffer::<i32>::new(2);
160     let (mut prod, mut cons) = buf.split();
161 
162     assert_eq!(prod.len(), 0);
163     assert_eq!(cons.len(), 0);
164     assert_eq!(prod.remaining(), 2);
165     assert_eq!(cons.remaining(), 2);
166 
167     assert_eq!(prod.push(123), Ok(()));
168 
169     assert_eq!(prod.len(), 1);
170     assert_eq!(cons.len(), 1);
171     assert_eq!(prod.remaining(), 1);
172     assert_eq!(cons.remaining(), 1);
173 
174     assert_eq!(prod.push(456), Ok(()));
175 
176     assert_eq!(prod.len(), 2);
177     assert_eq!(cons.len(), 2);
178     assert_eq!(prod.remaining(), 0);
179     assert_eq!(cons.remaining(), 0);
180 
181     assert_eq!(cons.pop(), Some(123));
182 
183     assert_eq!(prod.len(), 1);
184     assert_eq!(cons.len(), 1);
185     assert_eq!(prod.remaining(), 1);
186     assert_eq!(cons.remaining(), 1);
187 
188     assert_eq!(cons.pop(), Some(456));
189 
190     assert_eq!(prod.len(), 0);
191     assert_eq!(cons.len(), 0);
192     assert_eq!(prod.remaining(), 2);
193     assert_eq!(cons.remaining(), 2);
194 
195     // now head is at 2, so tail will be at 0. This caught an overflow error
196     // when tail+1 < head because of the substraction of usize.
197     assert_eq!(prod.push(789), Ok(()));
198 
199     assert_eq!(prod.len(), 1);
200     assert_eq!(cons.len(), 1);
201     assert_eq!(prod.remaining(), 1);
202     assert_eq!(cons.remaining(), 1);
203 }
204