1(* test/bytechar.sml -- test cases for Byte and Char, suitable for ASCII
2   PS 1994-12-10, 1995-05-11, 1995-11-10, 1996-09-30 *)
3
4use "auxil.sml";
5
6local
7
8in
9val test1 = checkrange (0,255) (fn i =>
10    (Word8.toInt o Byte.charToByte o Byte.byteToChar o Word8.fromInt) i = i);
11
12val test2 = checkrange (0,Char.maxOrd) (fn i =>
13    (Word8.toInt o Byte.charToByte o Char.chr) i = i);
14
15val test3 = checkrange (0,255)
16    (fn i => (Char.ord o Byte.byteToChar o Word8.fromInt) i = i);
17
18val test4 = checkrange (0, Char.maxOrd)
19    (fn i => (Char.ord o Char.chr) i = i);
20
21val test5 = (Char.chr ~1 seq "WRONG") handle Chr => "OK" | _ => "WRONG";
22
23val test6 = (Char.chr (Char.maxOrd+1) seq "WRONG")
24            handle Chr => "OK" | _ => "WRONG";
25
26val test7 = check("" = Byte.bytesToString (Word8Vector.fromList []));
27
28val test8 =
29    check("ABDC" =
30	  (Byte.bytesToString o Word8Vector.fromList o map Word8.fromInt)
31	   [65, 66, 68, 67]);
32
33val test9 = check("" = Byte.unpackString(Word8Array.fromList [], 0, SOME 0));
34
35local
36    val arr = Word8Array.tabulate(10, fn i => Word8.fromInt(i+65))
37in
38val test10a = check("" = Byte.unpackString(arr, 0, SOME 0));
39val test10b = check("" = Byte.unpackString(arr, 10, SOME 0)
40 		   andalso "" = Byte.unpackString(arr, 10, NONE));
41val test10c = check("BCDE" = Byte.unpackString(arr, 1, SOME 4));
42val test10d = (Byte.unpackString(arr, ~1, SOME 0) seq "WRONG")
43              handle Subscript => "OK" | _ => "WRONG";
44val test10e = (Byte.unpackString(arr, 11, SOME 0) seq "WRONG")
45              handle Subscript => "OK" | _ => "WRONG";
46val test10f = (Byte.unpackString(arr, 0, SOME ~1) seq "WRONG")
47              handle Subscript => "OK" | _ => "WRONG";
48val test10g = (Byte.unpackString(arr, 0, SOME 11) seq "WRONG")
49              handle Subscript => "OK" | _ => "WRONG";
50val test10h = (Byte.unpackString(arr, 10, SOME 1) seq "WRONG")
51              handle Subscript => "OK" | _ => "WRONG";
52val test10i = (Byte.unpackString(arr, ~1, NONE) seq "WRONG")
53              handle Subscript => "OK" | _ => "WRONG";
54val test10j = (Byte.unpackString(arr, 11, NONE) seq "WRONG")
55              handle Subscript => "OK" | _ => "WRONG";
56end
57
58local
59    val vec = Word8Vector.tabulate(10, fn i => Word8.fromInt(i+65))
60in
61val test11a = check("" = Byte.unpackStringVec(vec, 0, SOME 0));
62val test11b = check("" = Byte.unpackStringVec(vec, 10, SOME 0)
63 		   andalso "" = Byte.unpackStringVec(vec, 10, NONE));
64val test11c = check("BCDE" = Byte.unpackStringVec(vec, 1, SOME 4));
65val test11d = (Byte.unpackStringVec(vec, ~1, SOME 0) seq "WRONG")
66              handle Subscript => "OK" | _ => "WRONG";
67val test11e = (Byte.unpackStringVec(vec, 11, SOME 0) seq "WRONG")
68              handle Subscript => "OK" | _ => "WRONG";
69val test11f = (Byte.unpackStringVec(vec, 0, SOME ~1) seq "WRONG")
70              handle Subscript => "OK" | _ => "WRONG";
71val test11g = (Byte.unpackStringVec(vec, 0, SOME 11) seq "WRONG")
72              handle Subscript => "OK" | _ => "WRONG";
73val test11h = (Byte.unpackStringVec(vec, 10, SOME 1) seq "WRONG")
74              handle Subscript => "OK" | _ => "WRONG";
75val test11i = (Byte.unpackStringVec(vec, ~1, NONE) seq "WRONG")
76              handle Subscript => "OK" | _ => "WRONG";
77val test11j = (Byte.unpackStringVec(vec, 11, NONE) seq "WRONG")
78              handle Subscript => "OK" | _ => "WRONG";
79end
80
81val test18 = check(not (Char.contains "" (Char.chr 65))
82                   andalso not (Char.contains "aBCDE" (Char.chr 65))
83                   andalso (Char.contains "ABCD" (Char.chr 67))
84		   andalso not (Char.contains "" #"\000")
85		   andalso not (Char.contains "" #"\255")
86		   andalso not (Char.contains "azAZ09" #"\000")
87		   andalso not (Char.contains "azAZ09" #"\255"));
88
89val test19 = check(Char.notContains "" (Char.chr 65)
90                   andalso Char.notContains "aBCDE" (Char.chr 65)
91                   andalso not (Char.notContains "ABCD" (Char.chr 67))
92                   andalso Char.notContains "" #"\000"
93                   andalso Char.notContains "" #"\255"
94                   andalso Char.notContains "azAZ09" #"\000"
95                   andalso Char.notContains "azAZ09" #"\255");
96
97val test20 = check(Char.ord Char.maxChar = Char.maxOrd);
98
99local
100fun mycontains s c =
101    let val stop = String.size s
102	fun h i = i < stop andalso (c = String.sub(s, i) orelse h(i+1))
103    in h 0 end;
104
105(* Check that p(c) = (mycontains s c) for all characters: *)
106fun equivalent p s =
107    let fun h n =
108	n > 255 orelse
109	(p (chr n) = mycontains s (chr n)) andalso h(n+1)
110    in h 0 end
111
112fun checkset p s = check'(fn _ => equivalent p s);
113
114val graphchars = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\
115 \[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
116
117val ascii = "\^@\^A\^B\^C\^D\^E\^F\^G\^H\t\n\^K\^L\^M\^N\^O\^P\
118 \\^Q\^R\^S\^T\^U\^V\^W\^X\^Y\^Z\^[\^\\^]\^^\^_\
119 \ !\"#$%&'()*+,-./0123456789:;<=>?@\
120 \ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\127"
121
122val lowerascii = "\^@\^A\^B\^C\^D\^E\^F\^G\^H\t\n\^K\^L\^M\^N\^O\^P\
123 \\^Q\^R\^S\^T\^U\^V\^W\^X\^Y\^Z\^[\^\\^]\^^\^_\
124 \ !\"#$%&'()*+,-./0123456789:;<=>?@\
125 \abcdefghijklmnopqrstuvwxyz[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\127"
126
127val upperascii = "\^@\^A\^B\^C\^D\^E\^F\^G\^H\t\n\^K\^L\^M\^N\^O\^P\
128 \\^Q\^R\^S\^T\^U\^V\^W\^X\^Y\^Z\^[\^\\^]\^^\^_\
129 \ !\"#$%&'()*+,-./0123456789:;<=>?@\
130 \ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~\127"
131
132val allchars =
133    let fun h 0 res = chr 0 :: res
134	  | h n res = h (n-1) (chr n :: res)
135    in h 255 [] end
136
137open Char
138in
139
140val test21 =
141    checkset isLower "abcdefghijklmnopqrstuvwxyz";
142val test22 =
143    checkset isUpper "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
144val test23 =
145    checkset isDigit "0123456789";
146val test24 =
147    checkset isAlpha "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
148val test25 =
149    checkset isHexDigit "0123456789abcdefABCDEF";
150val test26 =
151    checkset isAlphaNum
152       "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
153val test27 =
154    checkset isPrint (" " ^ graphchars)
155val test28 =
156    checkset isSpace " \009\010\011\012\013";
157val test29 =
158    checkset isGraph graphchars
159val test30 =
160    checkset isAscii ascii
161
162val test31 =
163    check'(fn _ => map toLower (explode ascii) = explode lowerascii)
164val test32 =
165    check'(fn _ => map toUpper (explode ascii) = explode upperascii)
166val test33 =
167    check'(fn _ =>
168	   map toUpper (explode graphchars)
169	   seq map toLower (explode graphchars)
170	   seq true)
171
172val test34a =
173    check'(fn _ =>
174	   map pred (List.drop(allchars, 1)) = List.take(allchars, 255));
175val test34b = (pred minChar seq "WRONG")
176              handle Chr => "OK" | _ => "WRONG";
177val test35a =
178    check'(fn _ =>
179	   map succ (List.take(allchars, 255)) = List.drop(allchars, 1));
180val test35b = (succ maxChar seq "WRONG")
181              handle Chr => "OK" | _ => "WRONG";
182end
183
184
185(* Test cases for SML character escape functions. *)
186
187val test36 =
188    let fun chk (arg, res) = Char.toString arg = res
189    in check'(fn _ => List.all chk
190	      [(#"\000", "\\^@"),
191	       (#"\001", "\\^A"),
192	       (#"\006", "\\^F"),
193	       (#"\007", "\\a"),
194	       (#"\008", "\\b"),
195	       (#"\009", "\\t"),
196	       (#"\010", "\\n"),
197	       (#"\011", "\\v"),
198	       (#"\012", "\\f"),
199	       (#"\013", "\\r"),
200	       (#"\014", "\\^N"),
201	       (#"\031", "\\^_"),
202	       (#"\032", " "),
203	       (#"\126", "~"),
204	       (#"\\", "\\\\"),
205	       (#"\"", "\\\""),
206	       (#"A", "A"),
207	       (#"\127", "\\127"),
208	       (#"\128", "\\128"),
209	       (#"\255", "\\255")])
210    end;
211
212val test37 =
213    let val chars = List.tabulate(256, chr)
214	fun chk c = Char.fromString(Char.toString c) = SOME c
215    in check'(fn _ => List.all chk chars) end
216
217val test38 =
218    let fun chkFromString (arg, res) = Char.fromString arg = SOME res
219	val argResList =
220	    [("A", #"A"),
221	     ("z", #"z"),
222	     ("@", #"@"),
223	     ("~", #"~"),
224	     ("\\a", #"\007"),
225	     ("\\b", #"\008"),
226	     ("\\t", #"\009"),
227	     ("\\n", #"\010"),
228	     ("\\v", #"\011"),
229	     ("\\f", #"\012"),
230	     ("\\r", #"\013"),
231	     ("\\\\", #"\\"),
232	     ("\\\"", #"\""),
233	     ("\\^@", #"\000"),
234	     ("\\^A", #"\001"),
235	     ("\\^Z", #"\026"),
236	     ("\\^_", #"\031"),
237	     ("\\000", #"\000"),
238	     ("\\097", #"a"),
239	     ("\\255", #"\255"),
240	     ("\\   \t\n\n \\A", #"A"),
241	     ("\\   \t\n\n \\z", #"z"),
242	     ("\\   \t\n\n \\@", #"@"),
243	     ("\\   \t\n\n \\~", #"~"),
244	     ("\\   \t\n\n \\\\n", #"\n"),
245	     ("\\   \t\n\n \\\\t", #"\t"),
246	     ("\\   \t\n\n \\\\\\", #"\\"),
247	     ("\\   \t\n\n \\\\\"", #"\""),
248	     ("\\   \t\n\n \\\\^@", #"\000"),
249	     ("\\   \t\n\n \\\\^A", #"\001"),
250	     ("\\   \t\n\n \\\\^Z", #"\026"),
251	     ("\\   \t\n\n \\\\^_", #"\031"),
252	     ("\\   \t\n\n \\\\000", #"\000"),
253	     ("\\   \t\n\n \\\\097", #"a"),
254	     ("\\   \t\n\n \\\\255", #"\255")]
255    in
256	check'(fn _ => List.all chkFromString argResList)
257    end;
258
259val test39 =
260    check'(fn _ => List.all (fn arg => Char.fromString arg = NONE)
261	   ["\\",
262	    "\\c",
263	    "\\F",
264	    "\\e",
265	    "\\g",
266	    "\\N",
267	    "\\T",
268	    "\\1",
269	    "\\11",
270	    "\\256",
271	    "\\-65",
272	    "\\~65",
273	    "\\?",
274	    "\\^`",
275	    "\\^a",
276	    "\\^z",
277	    "\\   a",
278	    "\\   a\\B",
279	    "\\   \\"]);
280
281(* Test cases for C string escape functions *)
282
283val test40 =
284    let val chars = List.tabulate(256, chr)
285    in check'(fn _ =>
286	      List.map SOME chars
287	      = List.map Char.fromCString (List.map Char.toCString chars))
288    end;
289
290val test41 =
291    let val argResList =
292	    [(#"\010", "\\n"),
293	     (#"\009", "\\t"),
294	     (#"\011", "\\v"),
295	     (#"\008", "\\b"),
296	     (#"\013", "\\r"),
297	     (#"\012", "\\f"),
298	     (#"\007", "\\a"),
299	     (#"\\", "\\\\"),
300	     (#"?", "\\?"),
301	     (#"'", "\\'"),
302	     (#"\"", "\\\"")]
303    in
304	check'(fn _ =>
305	       List.all (fn (arg, res) => Char.toCString arg = res) argResList)
306    end;
307
308val test42 =
309    let fun checkFromCStringSucc (arg, res) =
310            str (valOf (Char.fromCString arg)) = res
311	val argResList =
312	    [("\\n", "\010"),
313	     ("\\t", "\009"),
314	     ("\\v", "\011"),
315	     ("\\b", "\008"),
316	     ("\\r", "\013"),
317	     ("\\f", "\012"),
318	     ("\\a", "\007"),
319	     ("\\\\",  "\\"),
320	     ("\\?", "?"),
321	     ("\\'", "'"),
322	     ("\\\"", "\""),
323	     ("\\1", "\001"),
324	     ("\\11", "\009"),
325	     ("\\111", "\073"),
326	     ("\\1007", "\064"),
327	     ("\\100A", "\064"),
328	     ("\\0",   "\000"),
329	     ("\\377", "\255"),
330	     ("\\18", "\001"),
331	     ("\\178", "\015"),
332	     ("\\1C", "\001"),
333	     ("\\17C", "\015"),
334	     ("\\x0", "\000"),
335	     ("\\xff", "\255"),
336	     ("\\xFF", "\255"),
337	     ("\\x1", "\001"),
338	     ("\\x11", "\017"),
339	     ("\\xag", "\010"),
340	     ("\\xAAg", "\170"),
341	     ("\\x0000000a", "\010"),
342	     ("\\x0000000a2", "\162"),
343	     ("\\x0000000ag", "\010"),
344	     ("\\x0000000A", "\010"),
345	     ("\\x0000000A2", "\162"),
346	     ("\\x0000000Ag", "\010"),
347	     ("\\x00000000000000000000000000000000000000000000000000000000000000011+",
348	      "\017")]
349    in
350	check'(fn _ => List.all checkFromCStringSucc argResList)
351    end;
352
353val test43 =
354    let fun checkFromCStringFail arg = Char.fromCString arg = NONE
355    in
356	check'(fn _ => List.all checkFromCStringFail
357	       ["\\",
358		"\\X",
359		"\\=",
360		"\\400",
361		"\\777",
362		"\\8",
363		"\\9",
364		"\\c",
365		"\\d",
366		"\\x",
367		"\\x100",
368		"\\xG"])
369    end;
370end
371