1--  Copyright 1994 Grady Booch
2--  Copyright 1994-1997 David Weller
3--  Copyright 1998-2014 Simon Wright <simon@pushface.org>
4
5--  This package is free software; you can redistribute it and/or
6--  modify it under terms of the GNU General Public License as
7--  published by the Free Software Foundation; either version 2, or
8--  (at your option) any later version. This package is distributed in
9--  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
10--  even the implied warranty of MERCHANTABILITY or FITNESS FOR A
11--  PARTICULAR PURPOSE. See the GNU General Public License for more
12--  details. You should have received a copy of the GNU General Public
13--  License distributed with this package; see file COPYING.  If not,
14--  write to the Free Software Foundation, 59 Temple Place - Suite
15--  330, Boston, MA 02111-1307, USA.
16
17with Ada.Exceptions;
18with Ada.Text_IO;
19with BC;
20with Deque_Test_Support;
21
22procedure Deque_Test is
23   use Ada.Text_IO;
24   use Deque_Test_Support;
25   use Containers;
26   use Deques;
27
28   procedure Process (C : Character; OK : out Boolean);
29   procedure Process (C : Character; OK : out Boolean) is
30   begin
31      Put_Line ("Item: " & C);
32      OK := True;
33   end Process;
34
35   procedure Assertion (Cond : Boolean; Message : String);
36   procedure Assertion (Cond : Boolean; Message : String) is
37   begin
38      if not Cond then
39         Put_Line (Message);
40      end if;
41   end Assertion;
42
43   procedure Test_Active_Iterator (D : Container'Class);
44   procedure Test_Active_Iterator (D : Container'Class) is
45      Iter : Iterator'Class := New_Iterator (D);
46      Success : Boolean;
47      Temp : Character;
48   begin
49      while not Is_Done (Iter) loop
50         Temp := Current_Item (Iter);
51         Process (Temp, Success);
52         Next (Iter);
53      end loop;
54   end Test_Active_Iterator;
55
56   procedure Test_Primitive (D1, D2 : in out Abstract_Deque'Class);
57   procedure Test_Primitive (D1, D2 : in out Abstract_Deque'Class) is
58   begin
59      Assertion (Is_Empty (D1), "** P01: Deque is not initially empty");
60      Assertion (Length (D1) = 0,
61                 "** P02: Deque length is not initially zero");
62      Append (D1, '2');
63      Append (D1, '3');
64      Append (D1, '1', Front);
65      Assertion (not (Is_Empty (D1)), "** P03: Deque is empty");
66      Assertion ((Length (D1) = 3), "** P04: Deque length is not correct");
67      Assertion ((Front (D1) = '1'), "** P05: Deque front is not correct");
68      Clear (D1);
69      Assertion (Is_Empty (D1), "** P06: Deque is not empty");
70      Assertion ((Length (D1) = 0), "** P07: Deque length is not zero");
71      Append (D1, '5');
72      Append (D1, '6');
73      Append (D1, '4', Front);
74      Assertion (not (Is_Empty (D1)), "** P08: Deque is empty");
75      Assertion ((Length (D1) = 3), "** P09: Deque length is not correct");
76      Assertion ((Front (D1) = '4'), "** P10: Deque front is not correct");
77      Assertion ((Back (D1) = '6'), "** P10a: Deque back is not correct");
78      Pop (D1);
79      Pop (D1, Back);
80      Assertion (not (Is_Empty (D1)), "** P11: Deque is empty");
81      Assertion ((Length (D1) = 1), "** P12: Deque length is not correct");
82      Assertion ((Front (D1) = '5'), "** P13: Deque front is not correct");
83      Pop (D1);
84      Assertion (Is_Empty (D1), "** P14: Deque is not empty");
85      Assertion ((Length (D1) = 0), "** P15: Deque length is not zero");
86      Append (D1, '7');
87      Append (D1, '8');
88      Append (D1, '9');
89      Pop (D1);
90      Pop (D1);
91      Assertion (not (Is_Empty (D1)), "** P16: Deque is empty");
92      Assertion ((Length (D1) = 1), "** P17: Deque length is not correct");
93      Assertion ((Front (D1) = '9'), "** P18: Deque front is not correct");
94      D2 := D1;
95      Assertion (not (Is_Empty (D1)), "** P19: Deque is empty");
96      Assertion ((Length (D1) = 1), "** P20: Deque length is not correct");
97      Assertion ((Front (D1) = '9'), "** P21: Deque front is not correct");
98      Assertion (not (Is_Empty (D2)), "** P22: Deque is empty");
99      Assertion ((Length (D2) = 1), "** P23: Deque length is not correct");
100      Assertion ((Front (D2) = '9'), "** P24: Deque front is not correct");
101      Assertion ((D1 = D2), "** P25: Deques are not equal");
102      Clear (D2);
103      Assertion ((not (Is_Empty (D1))), "** P26: Deque is empty");
104      Assertion ((Length (D1) = 1), "** P27: Deque length is not correct");
105      Assertion ((Front (D1) = '9'), "** P28: Deque front is not correct");
106      Assertion (Is_Empty (D2), "** P29: Deque is not empty");
107      Assertion ((Length (D2) = 0), "** P30: Deque length is not correct");
108      Assertion ((D1 /= D2), "** P31: Deques not equal");
109      Append (D2, '1');
110      Append (D2, '2');
111      Append (D2, '3');
112      Append (D2, '4');
113      Assertion (Location (D2, '1') = 1,
114                 "** P32: Deque location is not correct");
115      Assertion (Location (D2, '2') = 2,
116                 "** P33: Deque location is not correct");
117      Assertion (Location (D2, '4') = 4,
118                 "** P34: Deque location is not correct");
119      Remove (D2, 1);
120      Remove (D2, 2);
121      Remove (D2, 2);
122      Assertion ((Length (D2) = 1), "** P35: Deque length is not correct");
123      Assertion ((Front (D2) = '2'), "** P36: Deque front is not correct");
124      Remove (D2, 1);
125      Assertion ((Length (D2) = 0), "** P37: Deque length is not correct");
126      Append (D2, 'a');
127      Append (D2, 'z');
128      declare
129         procedure P (Ch : in out Character);
130         procedure P (Ch : in out Character) is
131         begin
132            Ch := Character'Succ (Ch);
133         end P;
134         procedure Acc is new Deques.Process_Front (P);
135      begin
136         Acc (D2);
137      end;
138      Assertion (Length (D2) = 2, "** P38: Deque length is not correct");
139      Assertion (Front (D2) = 'b', "** P39: Deque front is not correct");
140      Assertion (Back (D2) = 'z', "** P40: Deque front is not correct");
141      Clear (D2);
142      Append (D2, 'A');
143      Append (D2, 'Y');
144      declare
145         procedure P (Ch : in out Character);
146         procedure P (Ch : in out Character) is
147         begin
148            Ch := Character'Succ (Ch);
149         end P;
150         procedure Acc is new Deques.Process_Back (P);
151      begin
152         Acc (D2);
153      end;
154      Assertion (Length (D2) = 2, "** P41: Deque length is not correct");
155      Assertion (Front (D2) = 'A', "** P42: Deque front is not correct");
156      Assertion (Back (D2) = 'Z', "** P43: Deque front is not correct");
157      Clear (D2);
158      Append (D1, 'z');
159   end Test_Primitive;
160
161   procedure Test_Passive_Iterator (D : Container'Class);
162   procedure Test_Passive_Iterator (D : Container'Class) is
163      procedure Iterate is new Visit (Apply => Process);
164      Iter : Iterator'Class := New_Iterator (D);
165   begin
166      Iterate (Using => Iter);
167   end Test_Passive_Iterator;
168
169   procedure Test_Iterator_Deletion (D : in out Abstract_Deque'Class);
170   procedure Test_Iterator_Deletion (D : in out Abstract_Deque'Class) is
171      Iter : Iterator'Class := New_Iterator (D);
172      Delete : Boolean;
173   begin
174      Clear (D);
175      Append (D, '1');
176      Append (D, '2');
177      Append (D, '3');
178      Append (D, '4');
179      Append (D, '5');
180      Append (D, '6');
181      Delete := False;
182      Reset (Iter);
183      while not Is_Done (Iter) loop
184         if Delete then
185            Delete_Item_At (Iter);
186            Delete := False;
187         else
188            Next (Iter);
189            Delete := True;
190         end if;
191      end loop;
192      begin
193         Delete_Item_At (Iter);
194         Assertion (False, "** I01: Deletion succeeded");
195      exception
196         when BC.Not_Found => null;
197         when others =>
198            Assertion (False, "** I02: Unexpected exception");
199      end;
200      Assertion (Length (D) = 3, "** I03: Deque length is not correct");
201      Assertion (Front (D) = '1', "** I04: Deque item is not correct");
202      Pop (D);
203      Assertion (Front (D) = '3', "** I05: Deque item is not correct");
204      Pop (D);
205      Assertion (Front (D) = '5', "** I06: Deque item is not correct");
206      Pop (D);
207      Assertion (Length (D) = 0, "** I07: Deque length is not zero");
208   end Test_Iterator_Deletion;
209
210   Deque_B_P1, Deque_B_P2 : DB.Deque;
211   Deque_D_P1, Deque_D_P2 : DD.Deque;
212   Deque_U_P1, Deque_U_P2 : DU.Deque;
213   Deque_UM_P1, Deque_UM_P2 : DUM.Deque;
214
215begin
216   Put_Line ("Starting deque tests");
217
218   Put_Line ("...Bounded Deque");
219   Test_Primitive (Deque_B_P1, Deque_B_P2);
220
221   Put_Line ("...Dynamic Deque");
222   DD.Preallocate (Deque_D_P1, 50);
223   Test_Primitive (Deque_D_P1, Deque_D_P2);
224
225   Put_Line ("...Unbounded Deque");
226   Test_Primitive (Deque_U_P1, Deque_U_P2);
227
228   Put_Line ("...Unmanaged Deque");
229   Test_Primitive (Deque_UM_P1, Deque_UM_P2);
230
231   Put_Line ("...Deque Active Iterator");
232   Put_Line ("   Bounded:");
233   Test_Active_Iterator (Deque_B_P1);
234   Put_Line ("   Dynamic:");
235   Test_Active_Iterator (Deque_D_P1);
236   Put_Line ("   Unbounded:");
237   Test_Active_Iterator (Deque_U_P1);
238   Put_Line ("   Unmanaged:");
239   Test_Active_Iterator (Deque_UM_P1);
240
241   Put_Line ("...Deque Passive Iterator");
242   Put_Line ("   Bounded:");
243   Test_Passive_Iterator (Deque_B_P1);
244   Put_Line ("   Dynamic:");
245   Test_Passive_Iterator (Deque_D_P1);
246   Put_Line ("   Unbounded:");
247   Test_Passive_Iterator (Deque_U_P1);
248   Put_Line ("   Unmanaged:");
249   Test_Passive_Iterator (Deque_UM_P1);
250
251   Assertion (DB.Front (Deque_B_P1) = '9',
252              "** M01: Deque front is not correct");
253   Assertion (DB.Length (Deque_B_P2) = 0,
254              "** M02: Deque length is not correct");
255   Assertion (DD.Front (Deque_D_P1) = '9',
256              "** M05: Deque front is not correct");
257   Assertion (DD.Length (Deque_D_P2) = 0,
258              "** M06: Deque length is not correct");
259   Assertion (DU.Front (Deque_U_P1) = '9',
260              "** M09: Deque front is not correct");
261   Assertion (DUM.Front (Deque_UM_P1) = '9',
262              "** M09a: Deque front is not correct");
263   Assertion (DU.Length (Deque_U_P2) = 0,
264              "** M10: Deque length is not correct");
265   Assertion (DUM.Length (Deque_UM_P2) = 0,
266              "** M10a: Deque length is not correct");
267
268   Assertion (DB.Available (Deque_B_P1) = 98,
269              "** M13: Available space not correct");
270   Assertion
271     (DB.Available (Deque_B_P2) = 100, "** M14: Available space not correct");
272
273   Put_Line ("...Deque Iterator Deletion");
274   Put_Line ("   Bounded:");
275   Test_Iterator_Deletion (Deque_B_P1);
276   Put_Line ("   Dynamic:");
277   Test_Iterator_Deletion (Deque_D_P1);
278   Put_Line ("   Unbounded:");
279   Test_Iterator_Deletion (Deque_U_P1);
280   Put_Line ("   Unmanaged:");
281   Test_Iterator_Deletion (Deque_UM_P1);
282
283   Put_Line ("Completed deque tests");
284
285exception
286   when E : others =>
287      Put_Line ("                                   EXCEPTION "
288                & Ada.Exceptions.Exception_Name (E)
289                & " OCCURRED.");
290end Deque_Test;
291