ObjFW  Check-in [b045cbb9c7]

Overview
Comment:tests: Use dot syntax
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: b045cbb9c7a29152e5bb49275d7e5e7e9226fb40d3db4293dacbc1b99ff1bca6
User & Date: js on 2019-03-25 00:21:30
Other Links: manifest | tags
Context
2019-04-02
21:55
OFURLHandler_file: Fix leaked find handle on Win32 check-in: 103d934719 user: js tags: trunk
2019-03-25
00:21
tests: Use dot syntax check-in: b045cbb9c7 user: js tags: trunk
2019-03-24
22:29
Add support for UNC paths on Windows check-in: a4b719e4e9 user: js tags: trunk
Changes

Modified tests/ForwardingTests.m from [f6fc49c28d] to [ae1df634f6].

198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212







-
+







	target = [[[ForwardingTarget alloc] init] autorelease];
	TEST(@"-[forwardingTargetForSelector:]",
	    [t forwardingTargetTest: 0xDEADBEEF
				   : -1
				   : 1.25
				   : 2.75] == 0x12345678)
	TEST(@"-[forwardingTargetForSelector:] variable arguments",
	   [[t forwardingTargetVarArgTest: FMT, ARGS] isEqual: RESULT])
	    [[t forwardingTargetVarArgTest: FMT, ARGS] isEqual: RESULT])
	/*
	 * Don't try fpret on Win64 if we don't have stret forwarding, as
	 * long double is handled as a struct there.
	 */
# if !defined(OF_WINDOWS) || !defined(OF_X86_64) || \
	defined(OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET)
	TEST(@"-[forwardingTargetForSelector:] fp return",

Modified tests/OFASN1DERValueTests.m from [46d48df370] to [454df6e1d7].

92
93
94
95
96
97
98
99
100
101



102
103
104

105
106
107

108
109
110
111
112
113
114

115
116
117
118
119
120

121
122
123
124
125
126
127
92
93
94
95
96
97
98



99
100
101
102
103

104
105
106

107
108
109
110
111
112
113

114
115
116
117
118
119

120
121
122
123
124
125
126
127







-
-
-
+
+
+


-
+


-
+






-
+





-
+







	    OFTruncatedDataException, [[OFData dataWithItems: "\x02\x02\x00"
						       count: 3] ASN1DERValue])

	/* Bit string */
	TEST(@"Parsing of bit string",
	    (bitString = [[OFData dataWithItems: "\x03\x01\x00"
					  count: 3] ASN1DERValue]) &&
	    [[bitString bitStringValue] isEqual: [OFData dataWithItems: ""
								 count: 0]] &&
	    [bitString bitStringLength] == 0 &&
	    [bitString.bitStringValue isEqual: [OFData dataWithItems: ""
					count: 0]] &&
	    bitString.bitStringLength == 0 &&
	    (bitString = [[OFData dataWithItems: "\x03\x0D\x01Hello World\x80"
					  count: 15] ASN1DERValue]) &&
	    [[bitString bitStringValue]
	    [bitString.bitStringValue
	    isEqual: [OFData dataWithItems: "Hello World\x80"
				     count: 12]] &&
	    [bitString bitStringLength] == 97 &&
	    bitString.bitStringLength == 97 &&
	    (bitString = [[OFData dataWithItems: "\x03\x81\x80\x00xxxxxxxxxxxxx"
						 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
						 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
						 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
						 "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
					  count: 131] ASN1DERValue]) &&
	    [[bitString bitStringValue]
	    [bitString.bitStringValue
	    isEqual: [OFData dataWithItems: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
					    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
					    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
					    "xxxxxxxxxxxxxxxxxxxxxxxxx"
				     count: 127]] &&
	    [bitString bitStringLength] == 127 * 8)
	    bitString.bitStringLength == 127 * 8)

	EXPECT_EXCEPTION(@"Detection of invalid bit string #1",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x03\x00"
						       count: 2] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of invalid bit string #2",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x03\x01\x01"
173
174
175
176
177
178
179
180

181
182
183
184
185

186
187
188
189
190

191
192
193
194
195
196

197
198
199
200
201
202
203
173
174
175
176
177
178
179

180
181
182
183
184

185
186
187
188
189

190
191
192
193
194
195

196
197
198
199
200
201
202
203







-
+




-
+




-
+





-
+







	    OFInvalidFormatException, [[OFData dataWithItems: "\x05\x01\x00"
						       count: 3] ASN1DERValue])

	/* Object Identifier */
	TEST(@"Parsing of Object Identifier",
	    (array = [[[OFData dataWithItems: "\x06\x01\x27"
				       count: 3] ASN1DERValue]
	    subidentifiers]) && [array count] == 2 &&
	    subidentifiers]) && array.count == 2 &&
	    [[array objectAtIndex: 0] uIntMaxValue] == 0 &&
	    [[array objectAtIndex: 1] uIntMaxValue] == 39 &&
	    (array = [[[OFData dataWithItems: "\x06\x01\x4F"
				       count: 3] ASN1DERValue]
	    subidentifiers]) && [array count] == 2 &&
	    subidentifiers]) && array.count == 2 &&
	    [[array objectAtIndex: 0] uIntMaxValue] == 1 &&
	    [[array objectAtIndex: 1] uIntMaxValue] == 39 &&
	    (array = [[[OFData dataWithItems: "\x06\x02\x88\x37"
				       count: 4] ASN1DERValue]
	    subidentifiers]) && [array count] == 2 &&
	    subidentifiers]) && array.count == 2 &&
	    [[array objectAtIndex: 0] uIntMaxValue] == 2 &&
	    [[array objectAtIndex: 1] uIntMaxValue] == 999 &&
	    (array = [[[OFData dataWithItems: "\x06\x09\x2A\x86\x48\x86\xF7\x0D"
					      "\x01\x01\x0B"
				       count: 11] ASN1DERValue]
	    subidentifiers]) && [array count] == 7 &&
	    subidentifiers]) && array.count == 7 &&
	    [[array objectAtIndex: 0] uIntMaxValue] == 1 &&
	    [[array objectAtIndex: 1] uIntMaxValue] == 2 &&
	    [[array objectAtIndex: 2] uIntMaxValue] == 840 &&
	    [[array objectAtIndex: 3] uIntMaxValue] == 113549 &&
	    [[array objectAtIndex: 4] uIntMaxValue] == 1 &&
	    [[array objectAtIndex: 5] uIntMaxValue] == 1 &&
	    [[array objectAtIndex: 6] uIntMaxValue] == 11)
299
300
301
302
303
304
305
306

307
308
309

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326

327
328
329

330
331
332
333
334
335
336
299
300
301
302
303
304
305

306
307
308

309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325

326
327
328

329
330
331
332
333
334
335
336







-
+


-
+
















-
+


-
+







				    "xxxxxxxxxxxxxxxxxx"
			     count: 132] ASN1DERValue])

	/* Sequence */
	TEST(@"Parsing of sequence",
	    (array = [[OFData dataWithItems: "\x30\x00"
				      count: 2] ASN1DERValue]) &&
	    [array isKindOfClass: [OFArray class]] && [array count] == 0 &&
	    [array isKindOfClass: [OFArray class]] && array.count == 0 &&
	    (array = [[OFData dataWithItems: "\x30\x09\x02\x01\x7B\x0C\x04Test"
				      count: 11] ASN1DERValue]) &&
	    [array isKindOfClass: [OFArray class]] && [array count] == 2 &&
	    [array isKindOfClass: [OFArray class]] && array.count == 2 &&
	    [[array objectAtIndex: 0] integerValue] == 123 &&
	    [[[array objectAtIndex: 1] stringValue] isEqual: @"Test"])

	EXPECT_EXCEPTION(@"Detection of truncated sequence #1",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x30\x01"
						       count: 2] ASN1DERValue])

	EXPECT_EXCEPTION(@"Detection of truncated sequence #2",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x30\x04\x02\x01\x01\x00\x00"
			     count: 7] ASN1DERValue])

	/* Set */
	TEST(@"Parsing of set",
	    (set = [[OFData dataWithItems: "\x31\x00"
				    count: 2] ASN1DERValue]) &&
	    [set isKindOfClass: [OFSet class]] && [set count] == 0 &&
	    [set isKindOfClass: [OFSet class]] && set.count == 0 &&
	    (set = [[OFData dataWithItems: "\x31\x09\x02\x01\x7B\x0C\x04Test"
				    count: 11] ASN1DERValue]) &&
	    [set isKindOfClass: [OFSet class]] && [set count] == 2 &&
	    [set isKindOfClass: [OFSet class]] && set.count == 2 &&
	    (enumerator = [set objectEnumerator]) &&
	    [[enumerator nextObject] integerValue] == 123 &&
	    [[[enumerator nextObject] stringValue] isEqual: @"Test"])

	EXPECT_EXCEPTION(@"Detection of invalid set",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x31\x06\x02\x01\x02\x02\x01\x01"

Modified tests/OFArrayTests.m from [d070876349] to [e635773d52].

149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
149
150
151
152
153
154
155

156
157
158
159
160
161
162
163

164

165
166
167
168
169
170
171







-
+







-
+
-








	TEST(@"+[arrayWithObjects:count:]",
	    (a[1] = [arrayClass arrayWithObjects: c_ary
					   count: 3]) &&
	    [a[1] isEqual: a[0]])

	TEST(@"-[description]",
	    [[a[0] description ]isEqual: @"(\n\tFoo,\n\tBar,\n\tBaz\n)"])
	    [a[0].description isEqual: @"(\n\tFoo,\n\tBar,\n\tBaz\n)"])

	TEST(@"-[addObject:]", R([m[0] addObject: c_ary[0]]) &&
	    R([m[0] addObject: c_ary[2]]))

	TEST(@"-[insertObject:atIndex:]", R([m[0] insertObject: c_ary[1]
						       atIndex: 1]))

	TEST(@"-[count]", [m[0] count] == 3 && [a[0] count] == 3 &&
	TEST(@"-[count]", m[0].count == 3 && a[0].count == 3 && a[1].count == 3)
	    [a[1] count] == 3)

	TEST(@"-[isEqual:]", [m[0] isEqual: a[0]] && [a[0] isEqual: a[1]])

	TEST(@"-[objectAtIndex:]",
	    [[m[0] objectAtIndex: 0] isEqual: c_ary[0]] &&
	    [[m[0] objectAtIndex: 1] isEqual: c_ary[1]] &&
	    [[m[0] objectAtIndex: 2] isEqual: c_ary[2]] &&
213
214
215
216
217
218
219
220

221
222
223

224
225
226
227

228
229
230
231
232

233
234
235
236
237
238
239
212
213
214
215
216
217
218

219
220
221

222
223
224
225

226
227
228
229
230

231
232
233
234
235
236
237
238







-
+


-
+



-
+




-
+







	    R([m[0] replaceObjectAtIndex: 0
			      withObject: c_ary[0]]) &&
	    [[m[0] objectAtIndex: 0] isEqual: c_ary[0]] &&
	    [[m[0] objectAtIndex: 1] isEqual: c_ary[0]] &&
	    [[m[0] objectAtIndex: 2] isEqual: c_ary[2]])

	TEST(@"-[removeObject:]",
	    R([m[0] removeObject: c_ary[0]]) && [m[0] count] == 2)
	    R([m[0] removeObject: c_ary[0]]) && m[0].count == 2)

	TEST(@"-[removeObjectIdenticalTo:]",
	    R([m[0] removeObjectIdenticalTo: c_ary[2]]) && [m[0] count] == 1)
	    R([m[0] removeObjectIdenticalTo: c_ary[2]]) && m[0].count == 1)

	m[1] = [[a[0] mutableCopy] autorelease];
	TEST(@"-[removeObjectAtIndex:]", R([m[1] removeObjectAtIndex: 1]) &&
	    [m[1] count] == 2 && [[m[1] objectAtIndex: 1] isEqual: c_ary[2]])
	    m[1].count == 2 && [[m[1] objectAtIndex: 1] isEqual: c_ary[2]])

	m[1] = [[a[0] mutableCopy] autorelease];
	TEST(@"-[removeObjectsInRange:]",
	    R([m[1] removeObjectsInRange: of_range(0, 2)]) &&
	    [m[1] count] == 1 && [[m[1] objectAtIndex: 0] isEqual: c_ary[2]])
	    m[1].count == 1 && [[m[1] objectAtIndex: 0] isEqual: c_ary[2]])

	m[1] = [[a[0] mutableCopy] autorelease];
	[m[1] addObject: @"qux"];
	[m[1] addObject: @"last"];
	TEST(@"-[reverse]",
	    R([m[1] reverse]) && [m[1] isEqual: [arrayClass arrayWithObjects:
	    @"last", @"qux", @"Baz", @"Bar", @"Foo", nil]])
253
254
255
256
257
258
259
260

261
262
263
264

265
266
267
268
269
270
271
252
253
254
255
256
257
258

259
260
261
262

263
264
265
266
267
268
269
270







-
+



-
+







	    @"0", @"Bar", @"Baz", @"Foo", @"z", nil]] &&
	    [[m[1] sortedArrayUsingSelector: @selector(compare:)
				    options: OF_ARRAY_SORT_DESCENDING]
	    isEqual: [arrayClass arrayWithObjects:
	    @"z", @"Foo", @"Baz", @"Bar", @"0", nil]])

	EXPECT_EXCEPTION(@"Detect out of range in -[objectAtIndex:]",
	    OFOutOfRangeException, [a[0] objectAtIndex: [a[0] count]])
	    OFOutOfRangeException, [a[0] objectAtIndex: a[0].count])

	EXPECT_EXCEPTION(@"Detect out of range in -[removeObjectsInRange:]",
	    OFOutOfRangeException, [m[0] removeObjectsInRange:
		of_range(0, [m[0] count] + 1)])
		of_range(0, m[0].count + 1)])

	TEST(@"-[componentsJoinedByString:]",
	    (a[1] = [arrayClass arrayWithObjects: @"", @"a", @"b", @"c",
	    nil]) &&
	    [[a[1] componentsJoinedByString: @" "] isEqual: @" a b c"] &&
	    (a[1] = [arrayClass arrayWithObject: @"foo"]) &&
	    [[a[1] componentsJoinedByString: @" "] isEqual: @"foo"])
286
287
288
289
290
291
292
293

294
295
296
297
298
299
300
285
286
287
288
289
290
291

292
293
294
295
296
297
298
299







-
+







		if (![obj isEqual: c_ary[i]])
			ok = false;
		[m[0] replaceObjectAtIndex: i
				withObject: @""];
		i++;
	}

	if ([m[0] count] != i)
	if (m[0].count != i)
		ok = false;

	TEST(@"OFEnumerator's -[nextObject]", ok)

	[enumerator reset];
	[m[0] removeObjectAtIndex: 0];

309
310
311
312
313
314
315
316

317
318
319
320
321
322
323
308
309
310
311
312
313
314

315
316
317
318
319
320
321
322







-
+







		if (![s isEqual: c_ary[i]])
			ok = false;
		[m[0] replaceObjectAtIndex: i
				withObject: @""];
		i++;
	}

	if ([m[0] count] != i)
	if (m[0].count != i)
		ok = false;

	TEST(@"Fast Enumeration", ok)

	[m[0] replaceObjectAtIndex: 0
			withObject: c_ary[0]];
	[m[0] replaceObjectAtIndex: 1
355
356
357
358
359
360
361
362

363
364
365
366
367
368
369
354
355
356
357
358
359
360

361
362
363
364
365
366
367
368







-
+







		[m[0] enumerateObjectsUsingBlock:
		    ^ (id object, size_t idx, bool *stop) {
			    count++;
			    if (![object isEqual: [cmp objectAtIndex: idx]])
				    blockOk = false;
		}];

		if (count != [cmp count])
		if (count != cmp.count)
			blockOk = false;

		TEST(@"Enumeration using blocks", blockOk)

		blockOk = false;
		a2 = m[0];
		@try {
390
391
392
393
394
395
396
397

398
399
400

401
402
403
404
405
406
407
408
409

410
411
412

413
414

415
416
417
418
419
420
421
389
390
391
392
393
394
395

396
397
398

399
400
401
402
403
404
405
406
407

408
409
410

411
412

413
414
415
416
417
418
419
420







-
+


-
+








-
+


-
+

-
+







		case 0:
			return @"foo";
		case 1:
			return @"bar";
		}

		return nil;
		}]) && [[m[0] description] isEqual: @"(\n\tfoo,\n\tbar\n)"])
	    }]) && [m[0].description isEqual: @"(\n\tfoo,\n\tbar\n)"])

	TEST(@"-[mappedArrayUsingBlock:]",
	    [[[m[0] mappedArrayUsingBlock: ^ id (id object, size_t idx) {
	    [[m[0] mappedArrayUsingBlock: ^ id (id object, size_t idx) {
		switch (idx) {
		case 0:
			return @"foobar";
		case 1:
			return @"qux";
		}

		return nil;
	    }] description] isEqual: @"(\n\tfoobar,\n\tqux\n)"])
	    }].description isEqual: @"(\n\tfoobar,\n\tqux\n)"])

	TEST(@"-[filteredArrayUsingBlock:]",
	    [[[m[0] filteredArrayUsingBlock: ^ bool (id object, size_t idx) {
	    [[m[0] filteredArrayUsingBlock: ^ bool (id object, size_t idx) {
		return [object isEqual: @"foo"];
	    }] description] isEqual: @"(\n\tfoo\n)"])
	    }].description isEqual: @"(\n\tfoo\n)"])

	TEST(@"-[foldUsingBlock:]",
	    [[arrayClass arrayWithObjects: [OFMutableString string], @"foo",
	    @"bar", @"baz", nil] foldUsingBlock: ^ id (id left, id right) {
		[left appendString: right];
		return left;
	    }])

Modified tests/OFCharacterSetTests.m from [d3c984fcae] to [bc8546fbb5].

85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103

104
105
106
107
85
86
87
88
89
90
91

92
93
94
95
96
97
98
99
100
101
102

103
104
105
106
107







-
+










-
+




				ok = false;
		} else if ([cs characterIsMember: c])
			ok = false;
	}
	TEST(@"-[characterIsMember:]", ok);

	ok = true;
	ics = [cs invertedSet];
	ics = cs.invertedSet;
	for (of_unichar_t c = 0; c < 65536; c++) {
		if (c >= '0' && c <= '9') {
			if ([ics characterIsMember: c])
				ok = false;
		} else if (![ics characterIsMember: c])
			ok = false;
	}
	TEST(@"-[invertedSet]", ok);

	TEST(@"Inverting -[invertedSet] returns original set",
	    [ics invertedSet] == cs)
	    ics.invertedSet == cs)

	[pool drain];
}
@end

Modified tests/OFDNSResolverTests.m from [22c6695ef5] to [f214844b74].

24
25
26
27
28
29
30
31

32
33
34

35
36
37

38
39
40
41
42
43
44
45

46
47

48
49
50

51
52

53
54

55
56
57

58
59

60
61
62

63
64
65
66
24
25
26
27
28
29
30

31
32
33

34
35
36

37
38
39
40
41
42
43
44

45
46

47
48
49

50
51

52
53

54
55
56

57
58

59
60
61

62
63
64
65
66







-
+


-
+


-
+







-
+

-
+


-
+

-
+

-
+


-
+

-
+


-
+




@implementation TestsAppDelegate (OFDNSResolverTests)
- (void)DNSResolverTests
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFDNSResolver *resolver = [OFDNSResolver resolver];
	OFMutableString *staticHosts = [OFMutableString string];

	for (OFString *host in [resolver staticHosts]) {
	for (OFString *host in resolver.staticHosts) {
		OFString *IPs;

		if ([staticHosts length] > 0)
		if (staticHosts.length > 0)
			[staticHosts appendString: @"; "];

		IPs = [[[resolver staticHosts] objectForKey: host]
		IPs = [[resolver.staticHosts objectForKey: host]
		    componentsJoinedByString: @", "];

		[staticHosts appendFormat: @"%@=(%@)", host, IPs];
	}
	PRINT(GREEN, @"Static hosts: %@", staticHosts);

	PRINT(GREEN, @"Name servers: %@",
	    [[resolver nameServers] componentsJoinedByString: @", "]);
	    [resolver.nameServers componentsJoinedByString: @", "]);

	PRINT(GREEN, @"Local domain: %@", [resolver localDomain]);
	PRINT(GREEN, @"Local domain: %@", resolver.localDomain);

	PRINT(GREEN, @"Search domains: %@",
	    [[resolver searchDomains] componentsJoinedByString: @", "]);
	    [resolver.searchDomains componentsJoinedByString: @", "]);

	PRINT(GREEN, @"Timeout: %lf", [resolver timeout]);
	PRINT(GREEN, @"Timeout: %lf", resolver.timeout);

	PRINT(GREEN, @"Max attempts: %u", [resolver maxAttempts]);
	PRINT(GREEN, @"Max attempts: %u", resolver.maxAttempts);

	PRINT(GREEN, @"Min number of dots in absolute name: %u",
	    [resolver minNumberOfDotsInAbsoluteName]);
	    resolver.minNumberOfDotsInAbsoluteName);

	PRINT(GREEN, @"Uses TCP: %u", [resolver usesTCP]);
	PRINT(GREEN, @"Uses TCP: %u", resolver.usesTCP);

	PRINT(GREEN, @"Config reload interval: %lf",
	    [resolver configReloadInterval]);
	    resolver.configReloadInterval);

	[pool drain];
}
@end

Modified tests/OFDataTests.m from [4a5c2852b2] to [cec219c44a].

45
46
47
48
49
50
51
52

53
54

55
56
57
58
59



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

77
78
79
80
81
82
83

84
85
86
87

88
89
90
91
92
93


94
95
96
97
98
99
100
45
46
47
48
49
50
51

52
53

54
55
56



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

76
77
78
79
80
81


82
83
84
85

86
87
88
89
90


91
92
93
94
95
96
97
98
99







-
+

-
+


-
-
-
+
+
+
















-
+





-
-
+



-
+




-
-
+
+







	TEST(@"-[addItem:]", R([mutable addItem: raw[0]]) &&
	    R([mutable addItem: raw[1]]))

	TEST(@"-[itemAtIndex:]",
	    memcmp([mutable itemAtIndex: 0], raw[0], 4096) == 0 &&
	    memcmp([mutable itemAtIndex: 1], raw[1], 4096) == 0)

	TEST(@"-[lastItem]", memcmp([mutable lastItem], raw[1], 4096) == 0)
	TEST(@"-[lastItem]", memcmp(mutable.lastItem, raw[1], 4096) == 0)

	TEST(@"-[count]", [mutable count] == 2)
	TEST(@"-[count]", mutable.count == 2)

	TEST(@"-[isEqual:]",
	    (immutable = [OFData dataWithItems: [mutable items]
				      itemSize: [mutable itemSize]
					 count: [mutable count]]) &&
	    (immutable = [OFData dataWithItems: mutable.items
				      itemSize: mutable.itemSize
					 count: mutable.count]) &&
	    [immutable isEqual: mutable] &&
	    R([mutable removeLastItem]) && ![mutable isEqual: immutable])

	TEST(@"-[mutableCopy]",
	    (mutable = [[immutable mutableCopy] autorelease]) &&
	    [mutable isEqual: immutable])

	TEST(@"-[compare]", [mutable compare: immutable] == 0 &&
	    R([mutable removeLastItem]) &&
	    [immutable compare: mutable] == OF_ORDERED_DESCENDING &&
	    [mutable compare: immutable] == OF_ORDERED_ASCENDING &&
	    [[OFData dataWithItems: "aa"
			     count: 2] compare:
	    [OFData dataWithItems: "z"
			    count: 1]] == OF_ORDERED_ASCENDING)

	TEST(@"-[hash]", [immutable hash] == 0x634A529F)
	TEST(@"-[hash]", immutable.hash == 0x634A529F)

	mutable = [OFMutableData dataWithItems: "abcdef"
					 count: 6];

	TEST(@"-[removeLastItem]", R([mutable removeLastItem]) &&
	    [mutable count] == 5 &&
	    memcmp([mutable items], "abcde", 5) == 0)
	    mutable.count == 5 && memcmp(mutable.items, "abcde", 5) == 0)

	TEST(@"-[removeItemsInRange:]",
	    R([mutable removeItemsInRange: of_range(1, 2)]) &&
	    [mutable count] == 3 && memcmp([mutable items], "ade", 3) == 0)
	    mutable.count == 3 && memcmp(mutable.items, "ade", 3) == 0)

	TEST(@"-[insertItems:atIndex:count:]",
	    R([mutable insertItems: "bc"
			   atIndex: 1
			     count: 2]) && [mutable count] == 5 &&
	    memcmp([mutable items], "abcde", 5) == 0)
			     count: 2]) && mutable.count == 5 &&
	    memcmp(mutable.items, "abcde", 5) == 0)

	immutable = [OFData dataWithItems: "aaabaccdacaabb"
				 itemSize: 2
				    count: 7];
	TEST(@"-[rangeOfString:options:range:]",
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "aa"
							   itemSize: 2
162
163
164
165
166
167
168
169

170
171
172


173
174

175
176
177


178
179
180


181
182
183


184
185
186


187
188
189

190
191
192
193
194
195
196
197
198
199

200
201
202

203
204
205
206
207
208
209
210

211
212
213
214
161
162
163
164
165
166
167

168
169


170
171
172

173
174


175
176
177


178
179
180


181
182
183


184
185
186
187

188
189
190
191
192
193
194
195
196
197

198
199
200

201
202
203
204
205
206
207
208

209
210
211
212
213







-
+

-
-
+
+

-
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+


-
+









-
+


-
+







-
+





	EXPECT_EXCEPTION(@"-[subdataWithRange:] failing on out of range #1",
	    OFOutOfRangeException, [immutable subdataWithRange: of_range(7, 1)])

	EXPECT_EXCEPTION(@"-[subdataWithRange:] failing on out of range #2",
	    OFOutOfRangeException, [mutable subdataWithRange: of_range(6, 1)])

	TEST(@"-[MD5Hash]", [[mutable MD5Hash] isEqual: [@"abcde" MD5Hash]])
	TEST(@"-[MD5Hash]", [mutable.MD5Hash isEqual: @"abcde".MD5Hash])

	TEST(@"-[RIPEMD160Hash]", [[mutable RIPEMD160Hash]
	    isEqual: [@"abcde" RIPEMD160Hash]])
	TEST(@"-[RIPEMD160Hash]", [mutable.RIPEMD160Hash
	    isEqual: @"abcde".RIPEMD160Hash])

	TEST(@"-[SHA1Hash]", [[mutable SHA1Hash] isEqual: [@"abcde" SHA1Hash]])
	TEST(@"-[SHA1Hash]", [mutable.SHA1Hash isEqual: @"abcde".SHA1Hash])

	TEST(@"-[SHA224Hash]", [[mutable SHA224Hash]
	    isEqual: [@"abcde" SHA224Hash]])
	TEST(@"-[SHA224Hash]", [mutable.SHA224Hash
	    isEqual: @"abcde".SHA224Hash])

	TEST(@"-[SHA256Hash]", [[mutable SHA256Hash]
	    isEqual: [@"abcde" SHA256Hash]])
	TEST(@"-[SHA256Hash]", [mutable.SHA256Hash
	    isEqual: @"abcde".SHA256Hash])

	TEST(@"-[SHA384Hash]", [[mutable SHA384Hash]
	    isEqual: [@"abcde" SHA384Hash]])
	TEST(@"-[SHA384Hash]", [mutable.SHA384Hash
	    isEqual: @"abcde".SHA384Hash])

	TEST(@"-[SHA512Hash]", [[mutable SHA512Hash]
	    isEqual: [@"abcde" SHA512Hash]])
	TEST(@"-[SHA512Hash]", [mutable.SHA512Hash
	    isEqual: @"abcde".SHA512Hash])

	TEST(@"-[stringByBase64Encoding]",
	    [[mutable stringByBase64Encoding] isEqual: @"YWJjZGU="])
	    [mutable.stringByBase64Encoding isEqual: @"YWJjZGU="])

	TEST(@"+[dataWithBase64EncodedString:]",
	    memcmp([[OFData dataWithBase64EncodedString: @"YWJjZGU="]
	    items], "abcde", 5) == 0)

	TEST(@"Building strings",
	    (mutable = [OFMutableData dataWithItems: str
					       count: 6]) &&
	    R([mutable addItem: ""]) &&
	    strcmp([mutable items], str) == 0)
	    strcmp(mutable.items, str) == 0)

	EXPECT_EXCEPTION(@"Detect out of range in -[itemAtIndex:]",
	    OFOutOfRangeException, [mutable itemAtIndex: [mutable count]])
	    OFOutOfRangeException, [mutable itemAtIndex: mutable.count])

	EXPECT_EXCEPTION(@"Detect out of range in -[addItems:count:]",
	    OFOutOfRangeException, [mutable addItems: raw[0]
					       count: SIZE_MAX])

	EXPECT_EXCEPTION(@"Detect out of range in -[removeItemsInRange:]",
	    OFOutOfRangeException,
	    [mutable removeItemsInRange: of_range([mutable count], 1)])
	    [mutable removeItemsInRange: of_range(mutable.count, 1)])

	[pool drain];
}
@end

Modified tests/OFDateTests.m from [e0e02d2def] to [db640ccf02].

40
41
42
43
44
45
46
47
48


49
50
51
52
53
54
55
40
41
42
43
44
45
46


47
48
49
50
51
52
53
54
55







-
-
+
+







	TEST(@"+[dateWithTimeIntervalSince1970:]",
	    (d1 = [OFDate dateWithTimeIntervalSince1970: 0]))

	TEST(@"-[dateByAddingTimeInterval:]",
	    (d2 = [d1 dateByAddingTimeInterval: 3600 * 25 + 5.000002]))

	TEST(@"-[description]",
	    [[d1 description] isEqual: @"1970-01-01T00:00:00Z"] &&
	    [[d2 description] isEqual: @"1970-01-02T01:00:05Z"])
	    [d1.description isEqual: @"1970-01-01T00:00:00Z"] &&
	    [d2.description isEqual: @"1970-01-02T01:00:05Z"])

	TEST(@"+[dateWithDateString:format:]",
	    [[[OFDate dateWithDateString: @"2000-06-20T12:34:56+0200"
				  format: @"%Y-%m-%dT%H:%M:%S%z"] description]
	    isEqual: @"2000-06-20T10:34:56Z"]);

	EXPECT_EXCEPTION(@"Detection of unparsed in "
73
74
75
76
77
78
79
80

81
82

83
84
85

86
87

88
89

90
91

92
93

94
95

96
97

98
99
100
101
102
103
104
105
73
74
75
76
77
78
79

80
81

82

83

84
85

86
87

88
89

90
91

92
93

94
95

96
97
98
99
100
101
102
103
104







-
+

-
+
-

-
+

-
+

-
+

-
+

-
+

-
+

-
+









	TEST(@"-[isEqual:]",
	    [d1 isEqual: [OFDate dateWithTimeIntervalSince1970: 0]] &&
	    ![d1 isEqual: [OFDate dateWithTimeIntervalSince1970: 0.0000001]])

	TEST(@"-[compare:]", [d1 compare: d2] == OF_ORDERED_ASCENDING)

	TEST(@"-[second]", [d1 second] == 0 && [d2 second] == 5)
	TEST(@"-[second]", d1.second == 0 && d2.second == 5)

	TEST(@"-[microsecond]",
	TEST(@"-[microsecond]", d1.microsecond == 0 && d2.microsecond == 2)
	    [d1 microsecond] == 0 && [d2 microsecond] == 2)

	TEST(@"-[minute]", [d1 minute] == 0 && [d2 minute] == 0)
	TEST(@"-[minute]", d1.minute == 0 && d2.minute == 0)

	TEST(@"-[hour]", [d1 hour] == 0 && [d2 hour] == 1)
	TEST(@"-[hour]", d1.hour == 0 && d2.hour == 1)

	TEST(@"-[dayOfMonth]", [d1 dayOfMonth] == 1 && [d2 dayOfMonth] == 2)
	TEST(@"-[dayOfMonth]", d1.dayOfMonth == 1 && d2.dayOfMonth == 2)

	TEST(@"-[monthOfYear]", [d1 monthOfYear] == 1 && [d2 monthOfYear] == 1)
	TEST(@"-[monthOfYear]", d1.monthOfYear == 1 && d2.monthOfYear == 1)

	TEST(@"-[year]", [d1 year] == 1970 && [d2 year] == 1970)
	TEST(@"-[year]", d1.year == 1970 && d2.year == 1970)

	TEST(@"-[dayOfWeek]", [d1 dayOfWeek] == 4 && [d2 dayOfWeek] == 5)
	TEST(@"-[dayOfWeek]", d1.dayOfWeek == 4 && d2.dayOfWeek == 5)

	TEST(@"-[dayOfYear]", [d1 dayOfYear] == 1 && [d2 dayOfYear] == 2)
	TEST(@"-[dayOfYear]", d1.dayOfYear == 1 && d2.dayOfYear == 2)

	TEST(@"-[earlierDate:]", [[d1 earlierDate: d2] isEqual: d1])

	TEST(@"-[laterDate:]", [[d1 laterDate: d2] isEqual: d2])

	[pool drain];
}
@end

Modified tests/OFDictionaryTests.m from [c54892547e] to [4a69123110].

319
320
321
322
323
324
325
326

327
328
329
330
331
332
333
319
320
321
322
323
324
325

326
327
328
329
330
331
332
333







-
+







	TEST(@"-[filteredDictionaryUsingBlock:]",
	    [[[mutDict filteredDictionaryUsingBlock:
	    ^ bool (id key, id object) {
		return [key isEqual: keys[0]];
	    }] description] isEqual: @"{\n\tkey1 = value_1;\n}"])
#endif

	TEST(@"-[count]", [mutDict count] == 2)
	TEST(@"-[count]", mutDict.count == 2)

	TEST(@"+[dictionaryWithKeysAndObjects:]",
	    (dict = [dictionaryClass dictionaryWithKeysAndObjects:
	    @"foo", @"bar", @"baz", @"qux", nil]) &&
	    [[dict objectForKey: @"foo"] isEqual: @"bar"] &&
	    [[dict objectForKey: @"baz"] isEqual: @"qux"])

347
348
349
350
351
352
353
354

355
356
357
358
359
360
361
347
348
349
350
351
352
353

354
355
356
357
358
359
360
361







-
+







	TEST(@"-[copy]",
	    (dict = [[dict copy] autorelease]) &&
	    [[dict objectForKey: keys[0]] isEqual: values[0]] &&
	    [[dict objectForKey: keys[1]] isEqual: values[1]])

	TEST(@"-[mutableCopy]",
	    (mutDict = [[dict mutableCopy] autorelease]) &&
	    [mutDict count] == [dict count] &&
	    mutDict.count == dict.count &&
	    [[mutDict objectForKey: keys[0]] isEqual: values[0]] &&
	    [[mutDict objectForKey: keys[1]] isEqual: values[1]] &&
	    R([mutDict setObject: @"value3"
			  forKey: @"key3"]) &&
	    [[mutDict objectForKey: @"key3"] isEqual: @"value3"] &&
	    [[mutDict objectForKey: keys[0]] isEqual: values[0]] &&
	    R([mutDict setObject: @"foo"

Modified tests/OFHMACTests.m from [17bf6db694] to [490f0952c5].

90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

118
119

120
121
122
123


124
125
126


127
128
129


130
131
132


133
134
135
136
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

117
118

119

120


121
122
123


124
125
126


127
128
129


130
131
132
133
134
135







-
+



















-
+

-
+
-

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+




	TEST(@"-[setKey:length:] with SHA-384",
	    R([HMAC_SHA384 setKey: key
			   length: key_length]))
	TEST(@"-[setKey:length:] with SHA-512",
	    R([HMAC_SHA512 setKey: key
			   length: key_length]))

	while (![f isAtEndOfStream]) {
	while (!f.atEndOfStream) {
		char buf[64];
		size_t len = [f readIntoBuffer: buf
					length: 64];
		[HMAC_MD5 updateWithBuffer: buf
				    length: len];
		[HMAC_SHA1 updateWithBuffer: buf
				     length: len];
		[HMAC_RMD160 updateWithBuffer: buf
				       length: len];
		[HMAC_SHA256 updateWithBuffer: buf
				       length: len];
		[HMAC_SHA384 updateWithBuffer: buf
				       length: len];
		[HMAC_SHA512 updateWithBuffer: buf
				       length: len];
	}
	[f close];

	TEST(@"-[digest] with MD5",
	    memcmp([HMAC_MD5 digest], digest_md5, [HMAC_MD5 digestSize]) == 0)
	    memcmp(HMAC_MD5.digest, digest_md5, HMAC_MD5.digestSize) == 0)
	TEST(@"-[digest] with SHA-1",
	    memcmp([HMAC_SHA1 digest], digest_sha1,
	    memcmp(HMAC_SHA1.digest, digest_sha1, HMAC_SHA1.digestSize) == 0)
	    [HMAC_SHA1 digestSize]) == 0)
	TEST(@"-[digest] with RIPEMD-160",
	    memcmp([HMAC_RMD160 digest], digest_rmd160,
	    [HMAC_RMD160 digestSize]) == 0)
	    memcmp(HMAC_RMD160.digest, digest_rmd160,
	    HMAC_RMD160.digestSize) == 0)
	TEST(@"-[digest] with SHA-256",
	    memcmp([HMAC_SHA256 digest], digest_sha256,
	    [HMAC_SHA256 digestSize]) == 0)
	    memcmp(HMAC_SHA256.digest, digest_sha256,
	    HMAC_SHA256.digestSize) == 0)
	TEST(@"-[digest] with SHA-384",
	    memcmp([HMAC_SHA384 digest], digest_sha384,
	    [HMAC_SHA384 digestSize]) == 0)
	    memcmp(HMAC_SHA384.digest, digest_sha384,
	    HMAC_SHA384.digestSize) == 0)
	TEST(@"-[digest] with SHA-512",
	    memcmp([HMAC_SHA512 digest], digest_sha512,
	    [HMAC_SHA512 digestSize]) == 0)
	    memcmp(HMAC_SHA512.digest, digest_sha512,
	    HMAC_SHA512.digestSize) == 0)

	[pool drain];
}
@end

Modified tests/OFHTTPClientTests.m from [704975d98c] to [a26978f51b].

126
127
128
129
130
131
132
133

134
135

136
137

138
139
140
141
142
143
144
145
146
147

148
149
150
151

152
153
154
155
156
157
126
127
128
129
130
131
132

133
134

135
136

137
138
139
140
141
142
143
144
145
146

147
148
149
150

151
152
153
154
155
156
157







-
+

-
+

-
+









-
+



-
+






	[cond unlock];

	URL = [OFURL URLWithString:
	    [OFString stringWithFormat: @"http://127.0.0.1:%" @PRIu16 "/foo",
					server->_port]];

	TEST(@"-[asyncPerformRequest:]",
	    (client = [OFHTTPClient client]) && R([client setDelegate: self]) &&
	    (client = [OFHTTPClient client]) && (client.delegate = self) &&
	    (request = [OFHTTPRequest requestWithURL: URL]) &&
	    R([request setHeaders:
	    (request.headers =
	    [OFDictionary dictionaryWithObject: @"5"
					forKey: @"Content-Length"]]) &&
					forKey: @"Content-Length"]) &&
	    R([client asyncPerformRequest: request]))

	[[OFRunLoop mainRunLoop] runUntilDate:
	    [OFDate dateWithTimeIntervalSinceNow: 2]];
	[response autorelease];

	TEST(@"Asynchronous handling of requests", response != nil)

	TEST(@"Normalization of server header keys",
	    [[response headers] objectForKey: @"Content-Length"] != nil)
	    [response.headers objectForKey: @"Content-Length"] != nil)

	TEST(@"Correct parsing of data",
	    (data = [response readDataUntilEndOfStream]) &&
	    [data count] == 7 && memcmp([data items], "foo\nbar", 7) == 0)
	    data.count == 7 && memcmp(data.items, "foo\nbar", 7) == 0)

	[server join];

	[pool drain];
}
@end

Modified tests/OFHTTPCookieManagerTests.m from [75443b8833] to [1acde59a2a].

54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69
70

71
72
73
74

75
76
77
78
79
80
81
54
55
56
57
58
59
60

61
62
63
64
65
66
67
68
69

70
71
72
73

74
75
76
77
78
79
80
81







-
+








-
+



-
+







	    [[manager cookiesForURL: URL[0]] isEqual:
	    [OFArray arrayWithObject: cookie[0]]] &&
	    [[manager cookiesForURL: URL[3]] isEqual: [OFArray array]])

	cookie[2] = [OFHTTPCookie cookieWithName: @"test"
					   value: @"3"
					  domain: @"heap.zone"];
	[cookie[2] setSecure: true];
	cookie[2].secure = true;
	TEST(@"-[addCookie:forURL:] #3", R([manager addCookie: cookie[2]
						       forURL: URL[1]]))

	TEST(@"-[cookiesForURL:] #3",
	    [[manager cookiesForURL: URL[1]] isEqual:
	    [OFArray arrayWithObject: cookie[2]]] &&
	    [[manager cookiesForURL: URL[0]] isEqual: [OFArray array]])

	[cookie[2] setExpires: [OFDate dateWithTimeIntervalSinceNow: -1]];
	cookie[2].expires = [OFDate dateWithTimeIntervalSinceNow: -1];
	cookie[3] = [OFHTTPCookie cookieWithName: @"test"
					   value: @"4"
					  domain: @"heap.zone"];
	[cookie[3] setDomain: @".heap.zone"];
	cookie[3].domain = @".heap.zone";
	TEST(@"-[addCookie:forURL:] #4", R([manager addCookie: cookie[3]
						       forURL: URL[1]]))

	TEST(@"-[cookiesForURL:] #4",
	    [[manager cookiesForURL: URL[1]] isEqual:
	    [OFArray arrayWithObject: cookie[3]]] &&
	    [[manager cookiesForURL: URL[2]] isEqual:
90
91
92
93
94
95
96
97

98
99
100

101
102
103
104
105
90
91
92
93
94
95
96

97
98
99

100
101
102
103
104
105







-
+


-
+





	TEST(@"-[cookiesForURL:] #5",
	    [[manager cookiesForURL: URL[0]] isEqual:
	    [OFArray arrayWithObject: cookie[3]]] &&
	    [[manager cookiesForURL: URL[2]] isEqual:
	    [OFArray arrayWithObjects: cookie[3], cookie[4], nil]])

	TEST(@"-[purgeExpiredCookies]",
	    [[manager cookies] isEqual:
	    [manager.cookies isEqual:
	    [OFArray arrayWithObjects: cookie[2], cookie[3], cookie[4], nil]] &&
	    R([manager purgeExpiredCookies]) &&
	    [[manager cookies] isEqual:
	    [manager.cookies isEqual:
	    [OFArray arrayWithObjects: cookie[3], cookie[4], nil]])

	[pool drain];
}
@end

Modified tests/OFHTTPCookieTests.m from [13d2c7f00f] to [d0cc5dd06b].

43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60








61
62
63
64
65
66
67
43
44
45
46
47
48
49


50









51
52
53
54
55
56
57
58
59
60
61
62
63
64
65







-
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+







					  domain: @"heap.zone"];
	TEST(@"+[cookiesWithResponseHeaderFields:forURL:] #2",
	    [[OFHTTPCookie cookiesWithResponseHeaderFields: [OFDictionary
	    dictionaryWithObject: @"foo=bar,qux=cookie"
	    forKey: @"Set-Cookie"] forURL: URL]
	    isEqual: [OFArray arrayWithObjects: cookie[0], cookie[1], nil]])

	[cookie[0] setExpires:
	    [OFDate dateWithTimeIntervalSince1970: 1234567890]];
	cookie[0].expires = [OFDate dateWithTimeIntervalSince1970: 1234567890];
	[cookie[1] setExpires:
	    [OFDate dateWithTimeIntervalSince1970: 1234567890]];
	[cookie[0] setPath: @"/x"];
	[cookie[1] setDomain: @"webkeks.org"];
	[cookie[1] setPath: @"/objfw"];
	[cookie[1] setSecure: true];
	[cookie[1] setHTTPOnly: true];
	[[cookie[1] extensions] addObject: @"foo"];
	[[cookie[1] extensions] addObject: @"bar"];
	cookie[1].expires = [OFDate dateWithTimeIntervalSince1970: 1234567890];
	cookie[0].path = @"/x";
	cookie[1].domain = @"webkeks.org";
	cookie[1].path = @"/objfw";
	cookie[1].secure = true;
	cookie[1].HTTPOnly = true;
	[cookie[1].extensions addObject: @"foo"];
	[cookie[1].extensions addObject: @"bar"];
	TEST(@"+[cookiesWithResponseHeaderFields:forURL:] #3",
	    [(cookies = [OFHTTPCookie cookiesWithResponseHeaderFields:
	    [OFDictionary dictionaryWithObject:
	    @"foo=bar; Expires=Fri, 13 Feb 2009 23:31:30 GMT; Path=/x,"
	    @"qux=cookie; Expires=Fri, 13 Feb 2009 23:31:30 GMT; "
	    @"Domain=webkeks.org; Path=/objfw; Secure; HTTPOnly; foo; bar"
	    forKey: @"Set-Cookie"] forURL: URL]) isEqual:

Modified tests/OFJSONTests.m from [4b67f031f6] to [d82a70372d].

26
27
28
29
30
31
32
33
34
35
36
37
38






39
40
41

42
43
44
45
46
47
48
26
27
28
29
30
31
32






33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48







-
-
-
-
-
-
+
+
+
+
+
+


-
+







{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFString *s = @"{\"foo\"\t:'b\\na\\r', \"x\":/*foo*/ [.5\r,0xF,null"
	    @"//bar\n,\"foo\",false]}";
	OFDictionary *d = [OFDictionary dictionaryWithKeysAndObjects:
	    @"foo", @"b\na\r",
	    @"x", [OFArray arrayWithObjects:
		[OFNumber numberWithFloat: .5f],
		[OFNumber numberWithInt: 0xF],
		[OFNull null],
		@"foo",
		[OFNumber numberWithBool: false],
		nil],
	    [OFNumber numberWithFloat: .5f],
	    [OFNumber numberWithInt: 0xF],
	    [OFNull null],
	    @"foo",
	    [OFNumber numberWithBool: false],
	    nil],
	    nil];

	TEST(@"-[JSONValue] #1", [[s JSONValue] isEqual: d])
	TEST(@"-[JSONValue] #1", [s.JSONValue isEqual: d])

	TEST(@"-[JSONRepresentation]", [[d JSONRepresentation] isEqual:
	    @"{\"x\":[0.5,15,null,\"foo\",false],\"foo\":\"b\\na\\r\"}"])

	TEST(@"OF_JSON_REPRESENTATION_PRETTY",
	    [[d JSONRepresentationWithOptions: OF_JSON_REPRESENTATION_PRETTY]
	    isEqual: @"{\n\t\"x\": [\n\t\t0.5,\n\t\t15,\n\t\tnull,\n\t\t"
58
59
60
61
62
63
64
65
66


67
68
69
70
71
72
73
58
59
60
61
62
63
64


65
66
67
68
69
70
71
72
73







-
-
+
+







	    [@"]" JSONValue])
	EXPECT_EXCEPTION(@"-[JSONValue] #4", OFInvalidJSONException,
	    [@"bar" JSONValue])
	EXPECT_EXCEPTION(@"-[JSONValue] #5", OFInvalidJSONException,
	    [@"[\"a\" \"b\"]" JSONValue])

	TEST(@"-[JSONValue] #6",
	    [[@"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
	    JSONValue] isEqual: [OFArray arrayWithObject:
	    [@"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
	    .JSONValue isEqual: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:

Modified tests/OFKernelEventObserverTests.m from [a86e902d78] to [70f44cc10f].

93
94
95
96
97
98
99
100

101
102
103
104
105
106
107
93
94
95
96
97
98
99

100
101
102
103
104
105
106
107







-
+







	bool deadlineExceeded = false;

	[_testsAppDelegate outputTesting: @"-[observe] with listening socket"
				inModule: module];

	deadline = [OFDate dateWithTimeIntervalSinceNow: 1];
	while (_events < EXPECTED_EVENTS) {
		if ([deadline timeIntervalSinceNow] < 0) {
		if (deadline.timeIntervalSinceNow < 0) {
			deadlineExceeded = true;
			break;
		}

		[_observer observeForTimeInterval: 0.01];
	}

202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
202
203
204
205
206
207
208

209
210
211
212
213
214
215
216







-
+







	ObserverTest *test;

	module = [class className];
	test = [[[ObserverTest alloc]
	    initWithTestsAppDelegate: self] autorelease];

	TEST(@"+[observer]", (test->_observer = [class observer]))
	[test->_observer setDelegate: test];
	test->_observer.delegate = test;

	TEST(@"-[addObjectForReading:]",
	    R([test->_observer addObjectForReading: test->_server]))

	[test run];
	_fails += test->_fails;

Modified tests/OFListTests.m from [a586847fd9] to [c2851ea215].

39
40
41
42
43
44
45
46

47
48
49

50
51
52

53
54
55

56
57
58
59
60
61




62
63
64
65
66
67


68
69
70
71
72


73
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88



89
90
91
92
93

94
95
96
97

98
99
100
101
102
103
104
105
106
107
108

109
110
111
112
113
114

115
116
117
118
119
120
121

122
123
124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
142
143

144
145
146
147
148
149
150
151
152
153
39
40
41
42
43
44
45

46
47
48

49
50
51

52
53
54

55
56
57




58
59
60
61

62
63
64


65
66
67
68
69


70
71
72

73
74
75
76
77
78
79
80
81
82
83
84



85
86
87
88
89
90
91

92
93
94
95

96
97
98
99
100
101
102
103
104
105
106

107
108
109
110
111
112

113
114
115
116
117
118
119

120
121
122
123
124
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
149
150
151
152







-
+


-
+


-
+


-
+


-
-
-
-
+
+
+
+
-



-
-
+
+



-
-
+
+

-
+











-
-
-
+
+
+




-
+



-
+










-
+





-
+






-
+











-
+









-
+











	TEST(@"+[list]", (list = [OFList list]))

	TEST(@"-[appendObject:]", [list appendObject: strings[0]] &&
	    [list appendObject: strings[1]] && [list appendObject: strings[2]])

	TEST(@"-[firstListObject]",
	    [[list firstListObject]->object isEqual: strings[0]])
	    [list.firstListObject->object isEqual: strings[0]])

	TEST(@"-[firstListObject]->next",
	    [[list firstListObject]->next->object isEqual: strings[1]])
	    [list.firstListObject->next->object isEqual: strings[1]])

	TEST(@"-[lastListObject]",
	    [[list lastListObject]->object isEqual: strings[2]])
	    [list.lastListObject->object isEqual: strings[2]])

	TEST(@"-[lastListObject]->previous",
	    [[list lastListObject]->previous->object isEqual: strings[1]])
	    [list.lastListObject->previous->object isEqual: strings[1]])

	TEST(@"-[removeListObject:]",
	    R([list removeListObject: [list lastListObject]]) &&
	    [[list lastListObject]->object isEqual: strings[1]] &&
	    R([list removeListObject: [list firstListObject]]) &&
	    [[list firstListObject]->object isEqual:
	    R([list removeListObject: list.lastListObject]) &&
	    [list.lastListObject->object isEqual: strings[1]] &&
	    R([list removeListObject: list.firstListObject]) &&
	    [list.firstListObject->object isEqual: list.lastListObject->object])
	    [list lastListObject]->object])

	TEST(@"-[insertObject:beforeListObject:]",
	    [list insertObject: strings[0]
	      beforeListObject: [list lastListObject]] &&
	    [[list lastListObject]->previous->object isEqual: strings[0]])
	      beforeListObject: list.lastListObject] &&
	    [list.lastListObject->previous->object isEqual: strings[0]])

	TEST(@"-[insertObject:afterListObject:]",
	    [list insertObject: strings[2]
	       afterListObject: [list firstListObject]->next] &&
	    [[list lastListObject]->object isEqual: strings[2]])
	       afterListObject: list.firstListObject->next] &&
	    [list.lastListObject->object isEqual: strings[2]])

	TEST(@"-[count]", [list count] == 3)
	TEST(@"-[count]", list.count == 3)

	TEST(@"-[containsObject:]",
	    [list containsObject: strings[1]] &&
	    ![list containsObject: @"nonexistent"])

	TEST(@"-[containsObjectIdenticalTo:]",
	    [list containsObjectIdenticalTo: strings[1]] &&
	    ![list containsObjectIdenticalTo:
	    [OFString stringWithString: strings[1]]])

	TEST(@"-[copy]", (list = [[list copy] autorelease]) &&
	    [[list firstListObject]->object isEqual: strings[0]] &&
	    [[list firstListObject]->next->object isEqual: strings[1]] &&
	    [[list lastListObject]->object isEqual: strings[2]])
	    [list.firstListObject->object isEqual: strings[0]] &&
	    [list.firstListObject->next->object isEqual: strings[1]] &&
	    [list.lastListObject->object isEqual: strings[2]])

	TEST(@"-[isEqual:]", [list isEqual: [[list copy] autorelease]])

	TEST(@"-[description]",
	    [[list description] isEqual: @"[\n\tFoo,\n\tBar,\n\tBaz\n]"])
	    [list.description isEqual: @"[\n\tFoo,\n\tBar,\n\tBaz\n]"])

	TEST(@"-[objectEnumerator]", (enumerator = [list objectEnumerator]))

	loe = [list firstListObject];
	loe = list.firstListObject;
	i = 0;
	ok = true;
	while ((obj = [enumerator nextObject]) != nil) {
		if (![obj isEqual: loe->object])
			ok = false;

		loe = loe->next;
		i++;
	}

	if ([list count] != i)
	if (list.count != i)
		ok = false;

	TEST(@"OFEnumerator's -[nextObject]", ok);

	[enumerator reset];
	[list removeListObject: [list firstListObject]];
	[list removeListObject: list.firstListObject];

	EXPECT_EXCEPTION(@"Detection of mutation during enumeration",
	    OFEnumerationMutationException, [enumerator nextObject])

	[list prependObject: strings[0]];

	loe = [list firstListObject];
	loe = list.firstListObject;
	i = 0;
	ok = true;

	for (OFString *object in list) {
		if (![object isEqual: loe->object])
			ok = false;

		loe = loe->next;
		i++;
	}

	if ([list count] != i)
	if (list.count != i)
		ok = false;

	TEST(@"Fast Enumeration", ok)

	ok = false;
	@try {
		for (OFString *object in list) {
			(void)object;

			[list removeListObject: [list lastListObject]];
			[list removeListObject: list.lastListObject];
		}
	} @catch (OFEnumerationMutationException *e) {
		ok = true;
	}

	TEST(@"Detection of mutation during Fast Enumeration", ok)

	[pool drain];
}
@end

Modified tests/OFMD5HashTests.m from [bcebec7149] to [c6a6847787].

32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48
49
50
51
52


53
54
55
56
57
58
59
60
61
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46
47
48
49
50


51
52
53
54
55
56
57
58
59
60
61







-
+











-
-
+
+









	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFMD5Hash *md5, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin"
				    mode: @"r"];

	TEST(@"+[cryptoHash]", (md5 = [OFMD5Hash cryptoHash]))

	while (![f isAtEndOfStream]) {
	while (!f.atEndOfStream) {
		char buf[64];
		size_t len = [f readIntoBuffer: buf
					length: 64];
		[md5 updateWithBuffer: buf
			       length: len];
	}
	[f close];

	TEST(@"-[copy]", (copy = [[md5 copy] autorelease]))

	TEST(@"-[digest]",
	    memcmp([md5 digest], testfile_md5, 16) == 0 &&
	    memcmp([copy digest], testfile_md5, 16) == 0)
	    memcmp(md5.digest, testfile_md5, 16) == 0 &&
	    memcmp(copy.digest, testfile_md5, 16) == 0)

	EXPECT_EXCEPTION(@"Detect invalid call of "
	    @"-[updateWithBuffer:length]", OFHashAlreadyCalculatedException,
	    [md5 updateWithBuffer: ""
			   length: 1])

	[pool drain];
}
@end

Modified tests/OFMethodSignatureTests.m from [7e5d27d097] to [919883130b].

75
76
77
78
79
80
81
82
83


84
85
86
87
88

89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104

105
106
107
108
109
110
111
75
76
77
78
79
80
81


82
83
84
85
86
87

88
89
90
91
92
93
94
95
96

97

98
99
100
101
102

103
104
105
106
107
108
109
110







-
-
+
+




-
+








-
+
-





-
+







- (void)methodSignatureTests
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFMethodSignature *ms;

	TEST(@"-[:signatureWithObjCTypes:] #1",
	    (ms = [OFMethodSignature signatureWithObjCTypes:
	    "i28@0:8S16*20"]) && [ms numberOfArguments] == 4 &&
	    strcmp([ms methodReturnType], "i") == 0 &&
	    "i28@0:8S16*20"]) && ms.numberOfArguments == 4 &&
	    strcmp(ms.methodReturnType, "i") == 0 &&
	    strcmp([ms argumentTypeAtIndex: 0], "@") == 0 &&
	    strcmp([ms argumentTypeAtIndex: 1], ":") == 0 &&
	    strcmp([ms argumentTypeAtIndex: 2], "S") == 0 &&
	    strcmp([ms argumentTypeAtIndex: 3], "*") == 0 &&
	    [ms frameLength] == 28 && [ms argumentOffsetAtIndex: 0] == 0 &&
	    ms.frameLength == 28 && [ms argumentOffsetAtIndex: 0] == 0 &&
	    [ms argumentOffsetAtIndex: 1] == 8 &&
	    [ms argumentOffsetAtIndex: 2] == 16 &&
	    [ms argumentOffsetAtIndex: 3] == 20)

	TEST(@"-[signatureWithObjCTypes:] #2",
	    (ms = [OFMethodSignature signatureWithObjCTypes:
	    "{s0=csi(u1={s2=iii{s3=(u4=ic^v*)}})}24@0:8"
	    "^{s0=csi(u1={s2=iii{s3=(u4=ic^v*)}})}16"]) &&
	    [ms numberOfArguments] == 3 &&
	    ms.numberOfArguments == 3 && strcmp(ms.methodReturnType,
	    strcmp([ms methodReturnType],
	    "{s0=csi(u1={s2=iii{s3=(u4=ic^v*)}})}") == 0 &&
	    strcmp([ms argumentTypeAtIndex: 0], "@") == 0 &&
	    strcmp([ms argumentTypeAtIndex: 1], ":") == 0 &&
	    strcmp([ms argumentTypeAtIndex: 2],
	    "^{s0=csi(u1={s2=iii{s3=(u4=ic^v*)}})}") == 0 &&
	    [ms frameLength] == 24 && [ms argumentOffsetAtIndex: 0] == 0 &&
	    ms.frameLength == 24 && [ms argumentOffsetAtIndex: 0] == 0 &&
	    [ms argumentOffsetAtIndex: 1] == 8 &&
	    [ms argumentOffsetAtIndex: 2] == 16)

	EXPECT_EXCEPTION(@"-[signatureWithObjCTypes:] #3",
	    OFInvalidFormatException,
	    [OFMethodSignature signatureWithObjCTypes: "{ii"])

Modified tests/OFNumberTests.m from [e93715a85b] to [174623645b].

29
30
31
32
33
34
35
36

37
38

39
40

41
42
43
44
29
30
31
32
33
34
35

36
37

38
39

40
41
42
43
44







-
+

-
+

-
+





	TEST(@"+[numberWithIntMax:]",
	    (num = [OFNumber numberWithIntMax: 123456789]))

	TEST(@"-[isEqual:]",
	    [num isEqual: [OFNumber numberWithUInt32: 123456789]])

	TEST(@"-[hash]", [num hash] == 0x82D8BC42)
	TEST(@"-[hash]", num.hash == 0x82D8BC42)

	TEST(@"-[charValue]", [num charValue] == 21)
	TEST(@"-[charValue]", num.charValue == 21)

	TEST(@"-[doubleValue]", [num doubleValue] == 123456789.L)
	TEST(@"-[doubleValue]", num.doubleValue == 123456789.L)

	[pool drain];
}
@end

Modified tests/OFObjectTests.m from [d457d186e1] to [e96462b442].

135
136
137
138
139
140
141
142
143


144
145
146


147
148
149
150


151
152
153
154
155
156
157
158
159
160
161


162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179













180
181
182
183
184
185
186
135
136
137
138
139
140
141


142
143
144


145
146
147
148


149
150
151
152
153
154
155
156
157
158
159


160
161
162
163
164
165
166













167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186







-
-
+
+

-
-
+
+


-
-
+
+









-
-
+
+





-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+







	    [[OFObject description] isEqual: @"OFObject"] &&
	    [[MyObj description] isEqual: @"MyObj"])

	o = [[[OFObject alloc] init] autorelease];
	m = [[[MyObj alloc] init] autorelease];

	TEST(@"-[description]",
	    [[o description] isEqual: @"<OFObject>"] &&
	    [[m description] isEqual: @"<MyObj>"])
	    [o.description isEqual: @"<OFObject>"] &&
	    [m.description isEqual: @"<MyObj>"])

	[m setObjectValue: @"Hello"];
	[m setClassValue: [m class]];
	m.objectValue = @"Hello";
	m.classValue = [m class];
	TEST(@"-[valueForKey:]",
	    [[m valueForKey: @"objectValue"] isEqual: @"Hello"] &&
	    [[m valueForKey: @"classValue"] isEqual: [m class]] &&
	    [[m valueForKey: @"class"] isEqual: [m class]])
	    [[m valueForKey: @"classValue"] isEqual: m.class] &&
	    [[m valueForKey: @"class"] isEqual: m.class])

	EXPECT_EXCEPTION(@"-[valueForKey:] with undefined key",
	    OFUndefinedKeyException, [m valueForKey: @"undefined"])

	TEST(@"-[setValue:forKey:]",
	    R([m setValue: @"World"
		   forKey: @"objectValue"]) &&
	    R([m setValue: [OFObject class]
		   forKey: @"classValue"]) &&
	    [[m objectValue] isEqual: @"World"] &&
	    [[m classValue] isEqual: [OFObject class]])
	    [m.objectValue isEqual: @"World"] &&
	    [m.classValue isEqual: [OFObject class]])

	EXPECT_EXCEPTION(@"-[setValue:forKey:] with undefined key",
	    OFUndefinedKeyException, [m setValue: @"x"
					  forKey: @"undefined"])

	[m setBoolValue: 1];
	[m setCharValue: 2];
	[m setShortValue: 3];
	[m setIntValue: 4];
	[m setLongValue: 5 ];
	[m setLongLongValue: 6];
	[m setUnsignedCharValue: 7];
	[m setUnsignedShortValue: 8];
	[m setUnsignedIntValue: 9];
	[m setUnsignedLongValue: 10];
	[m setUnsignedLongLongValue: 11];
	[m setFloatValue: 12];
	[m setDoubleValue: 13];
	m.boolValue = 1;
	m.charValue = 2;
	m.shortValue = 3;
	m.intValue = 4;
	m.longValue = 5;
	m.longLongValue = 6;
	m.unsignedCharValue = 7;
	m.unsignedShortValue = 8;
	m.unsignedIntValue = 9;
	m.unsignedLongValue = 10;
	m.unsignedLongLongValue = 11;
	m.floatValue = 12;
	m.doubleValue = 13;
	TEST(@"Auto-wrapping of -[valueForKey:]",
	    [[m valueForKey: @"boolValue"] isEqual:
	    [OFNumber numberWithBool: 1]] &&
	    [[m valueForKey: @"charValue"] isEqual:
	    [OFNumber numberWithChar: 2]] &&
	    [[m valueForKey: @"shortValue"] isEqual:
	    [OFNumber numberWithShort: 3]] &&
228
229
230
231
232
233
234
235

236
237
238

239
240
241

242
243

244
245

246
247

248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265

266
267
268
269
228
229
230
231
232
233
234

235



236



237


238


239


240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257

258
259
260
261
262







-
+
-
-
-
+
-
-
-
+
-
-
+
-
-
+
-
-
+

















-
+




		   forKey: @"unsignedLongValue"]) &&
	    R([m setValue: [OFNumber numberWithUnsignedLongLong: 100]
		   forKey: @"unsignedLongLongValue"]) &&
	    R([m setValue: [OFNumber numberWithFloat: 110]
		   forKey: @"floatValue"]) &&
	    R([m setValue: [OFNumber numberWithDouble: 120]
		   forKey: @"doubleValue"]) &&
	    [m isBoolValue] == 0 &&
	    m.isBoolValue == 0 && m.charValue == 10 && m.shortValue == 20 &&
	    [m charValue] == 10 &&
	    [m shortValue] == 20 &&
	    [m intValue] == 30 &&
	    m.intValue == 30 && m.longValue == 40 && m.longLongValue == 50 &&
	    [m longValue] == 40 &&
	    [m longLongValue] == 50 &&
	    [m unsignedCharValue] == 60 &&
	    m.unsignedCharValue == 60 && m.unsignedShortValue == 70 &&
	    [m unsignedShortValue] == 70 &&
	    [m unsignedIntValue] == 80 &&
	    m.unsignedIntValue == 80 && m.unsignedLongValue == 90 &&
	    [m unsignedLongValue] == 90 &&
	    [m unsignedLongLongValue] == 100 &&
	    m.unsignedLongLongValue == 100 && m.floatValue == 110 &&
	    [m floatValue] == 110 &&
	    [m doubleValue] == 120)
	    m.doubleValue == 120)

	EXPECT_EXCEPTION(@"Catch -[setValue:forKey:] with nil key for scalar",
	    OFInvalidArgumentException, [m setValue: (id _Nonnull)nil
					     forKey: @"intValue"])

	TEST(@"-[valueForKeyPath:]",
	    (m = [[[MyObj alloc] init] autorelease]) &&
	    (m.objectValue = [[[MyObj alloc] init] autorelease]) &&
	    R([m.objectValue
	    setObjectValue: [[[MyObj alloc] init] autorelease]]) &&
	    R([[m.objectValue objectValue] setDoubleValue: 0.5]) &&
	    [[m valueForKeyPath: @"objectValue.objectValue.doubleValue"]
	    doubleValue] == 0.5)

	TEST(@"[-setValue:forKeyPath:]",
	    R([m setValue: [OFNumber numberWithDouble: 0.75]
	       forKeyPath: @"objectValue.objectValue.doubleValue"]) &&
	    [[[m objectValue] objectValue] doubleValue] == 0.75)
	    [[m.objectValue objectValue] doubleValue] == 0.75)

	[pool drain];
}
@end

Modified tests/OFPropertyListTests.m from [99edbdd865] to [9d7de2772c].

67
68
69
70
71
72
73
74

75
76
77

78
79
80

81
82
83
84
85
86
87
67
68
69
70
71
72
73

74
75
76

77
78
79

80
81
82
83
84
85
86
87







-
+


-
+


-
+







	    [OFNumber numberWithBool: true],
	    [OFNumber numberWithBool: false],
	    [OFNumber numberWithFloat: 12.25],
	    [OFNumber numberWithInt: -10],
	    nil];

	TEST(@"-[propertyListValue:] #1",
	    [[PLIST1 propertyListValue] isEqual: @"Hello"])
	    [PLIST1.propertyListValue isEqual: @"Hello"])

	TEST(@"-[propertyListValue:] #2",
	    [[PLIST2 propertyListValue] isEqual: array])
	    [PLIST2.propertyListValue isEqual: array])

	TEST(@"-[propertyListValue:] #3",
	    [[PLIST3 propertyListValue] isEqual:
	    [PLIST3.propertyListValue isEqual:
	    [OFDictionary dictionaryWithKeysAndObjects:
	    @"array", array,
	    @"foo", @"bar",
	    nil]])

	EXPECT_EXCEPTION(@"-[propertyListValue] detecting unsupported version",
	    OFUnsupportedVersionException,

Modified tests/OFRIPEMD160HashTests.m from [1890a058e9] to [9aaabddcf7].

33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53


54
55
56
57
58
59
60
61
62
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48
49
50
51


52
53
54
55
56
57
58
59
60
61
62







-
+











-
-
+
+









	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFRIPEMD160Hash *rmd160, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin"
				    mode: @"r"];

	TEST(@"+[cryptoHash]", (rmd160 = [OFRIPEMD160Hash cryptoHash]))

	while (![f isAtEndOfStream]) {
	while (!f.atEndOfStream) {
		char buf[64];
		size_t len = [f readIntoBuffer: buf
					length: 64];
		[rmd160 updateWithBuffer: buf
				  length: len];
	}
	[f close];

	TEST(@"-[copy]", (copy = [[rmd160 copy] autorelease]))

	TEST(@"-[digest]",
	    memcmp([rmd160 digest], testfile_rmd160, 20) == 0 &&
	    memcmp([copy digest], testfile_rmd160, 20) == 0)
	    memcmp(rmd160.digest, testfile_rmd160, 20) == 0 &&
	    memcmp(copy.digest, testfile_rmd160, 20) == 0)

	EXPECT_EXCEPTION(@"Detect invalid call of "
	    @"-[updateWithBuffer:length]", OFHashAlreadyCalculatedException,
	    [rmd160 updateWithBuffer: ""
			      length: 1])

	[pool drain];
}
@end

Modified tests/OFSHA1HashTests.m from [c459854e29] to [8145ea23f0].

33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53


54
55
56
57
58
59
60
61
62
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48
49
50
51


52
53
54
55
56
57
58
59
60
61
62







-
+











-
-
+
+









	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFSHA1Hash *sha1, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin"
				    mode: @"r"];

	TEST(@"+[cryptoHash]", (sha1 = [OFSHA1Hash cryptoHash]))

	while (![f isAtEndOfStream]) {
	while (!f.atEndOfStream) {
		char buf[64];
		size_t len = [f readIntoBuffer: buf
					length: 64];
		[sha1 updateWithBuffer: buf
				length: len];
	}
	[f close];

	TEST(@"-[copy]", (copy = [[sha1 copy] autorelease]))

	TEST(@"-[digest]",
	    memcmp([sha1 digest], testfile_sha1, 20) == 0 &&
	    memcmp([copy digest], testfile_sha1, 20) == 0)
	    memcmp(sha1.digest, testfile_sha1, 20) == 0 &&
	    memcmp(copy.digest, testfile_sha1, 20) == 0)

	EXPECT_EXCEPTION(@"Detect invalid call of "
	    @"-[updateWithBuffer:length:]", OFHashAlreadyCalculatedException,
	    [sha1 updateWithBuffer: ""
			    length: 1])

	[pool drain];
}
@end

Modified tests/OFSHA224HashTests.m from [f07a13f9bd] to [600acd5836].

33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53


54
55
56
57
58
59
60
61
62
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48
49
50
51


52
53
54
55
56
57
58
59
60
61
62







-
+











-
-
+
+









	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFSHA224Hash *sha224, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin"
				    mode: @"r"];

	TEST(@"+[cryptoHash]", (sha224 = [OFSHA224Hash cryptoHash]))

	while (![f isAtEndOfStream]) {
	while (!f.atEndOfStream) {
		char buf[64];
		size_t len = [f readIntoBuffer: buf
					length: 64];
		[sha224 updateWithBuffer: buf
				  length: len];
	}
	[f close];

	TEST(@"-[copy]", (copy = [[sha224 copy] autorelease]))

	TEST(@"-[digest]",
	    memcmp([sha224 digest], testfile_sha224, 28) == 0 &&
	    memcmp([copy digest], testfile_sha224, 28) == 0)
	    memcmp(sha224.digest, testfile_sha224, 28) == 0 &&
	    memcmp(copy.digest, testfile_sha224, 28) == 0)

	EXPECT_EXCEPTION(@"Detect invalid call of "
	    @"-[updateWithBuffer:length:]", OFHashAlreadyCalculatedException,
	    [sha224 updateWithBuffer: ""
			      length: 1])

	[pool drain];
}
@end

Modified tests/OFSHA256HashTests.m from [7c103b0670] to [638be55668].

33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53


54
55
56
57
58
59
60
61
62
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48
49
50
51


52
53
54
55
56
57
58
59
60
61
62







-
+











-
-
+
+









	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFSHA256Hash *sha256, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin"
				    mode: @"r"];

	TEST(@"+[cryptoHash]", (sha256 = [OFSHA256Hash cryptoHash]))

	while (![f isAtEndOfStream]) {
	while (!f.atEndOfStream) {
		char buf[64];
		size_t len = [f readIntoBuffer: buf
					length: 64];
		[sha256 updateWithBuffer: buf
				  length: len];
	}
	[f close];

	TEST(@"-[copy]", (copy = [[sha256 copy] autorelease]))

	TEST(@"-[digest]",
	    memcmp([sha256 digest], testfile_sha256, 32) == 0 &&
	    memcmp([copy digest], testfile_sha256, 32) == 0)
	    memcmp(sha256.digest, testfile_sha256, 32) == 0 &&
	    memcmp(copy.digest, testfile_sha256, 32) == 0)

	EXPECT_EXCEPTION(@"Detect invalid call of "
	    @"-[updateWithBuffer:length:]", OFHashAlreadyCalculatedException,
	    [sha256 updateWithBuffer: ""
			      length: 1])

	[pool drain];
}
@end

Modified tests/OFSHA384HashTests.m from [9656e559f7] to [2c33539498].

34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54


55
56
57
58
59
60
61
62
63
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52


53
54
55
56
57
58
59
60
61
62
63







-
+











-
-
+
+









	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFSHA384Hash *sha384, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin"
				    mode: @"r"];

	TEST(@"+[cryptoHash]", (sha384 = [OFSHA384Hash cryptoHash]))

	while (![f isAtEndOfStream]) {
	while (!f.atEndOfStream) {
		char buf[128];
		size_t len = [f readIntoBuffer: buf
					length: 128];
		[sha384 updateWithBuffer: buf
				  length: len];
	}
	[f close];

	TEST(@"-[copy]", (copy = [[sha384 copy] autorelease]))

	TEST(@"-[digest]",
	    memcmp([sha384 digest], testfile_sha384, 48) == 0 &&
	    memcmp([copy digest], testfile_sha384, 48) == 0)
	    memcmp(sha384.digest, testfile_sha384, 48) == 0 &&
	    memcmp(copy.digest, testfile_sha384, 48) == 0)

	EXPECT_EXCEPTION(@"Detect invalid call of "
	    @"-[updateWithBuffer:length:]", OFHashAlreadyCalculatedException,
	    [sha384 updateWithBuffer: ""
			      length: 1])

	[pool drain];
}
@end

Modified tests/OFSHA512HashTests.m from [19cca253b0] to [a22ba9da74].

35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
51
52
53
54
55


56
57
58
59
60
61
62
63
64
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53


54
55
56
57
58
59
60
61
62
63
64







-
+











-
-
+
+









	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFSHA512Hash *sha512, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin"
				    mode: @"r"];

	TEST(@"+[cryptoHash]", (sha512 = [OFSHA512Hash cryptoHash]))

	while (![f isAtEndOfStream]) {
	while (!f.atEndOfStream) {
		char buf[128];
		size_t len = [f readIntoBuffer: buf
					length: 128];
		[sha512 updateWithBuffer: buf
				  length: len];
	}
	[f close];

	TEST(@"-[copy]", (copy = [[sha512 copy] autorelease]))

	TEST(@"-[digest]",
	    memcmp([sha512 digest], testfile_sha512, 64) == 0 &&
	    memcmp([copy digest], testfile_sha512, 64) == 0)
	    memcmp(sha512.digest, testfile_sha512, 64) == 0 &&
	    memcmp(copy.digest, testfile_sha512, 64) == 0)

	EXPECT_EXCEPTION(@"Detect invalid call of "
	    @"-[updateWithBuffer:length:]", OFHashAlreadyCalculatedException,
	    [sha512 updateWithBuffer: ""
			      length: 1])

	[pool drain];
}
@end

Modified tests/OFSerializationTests.m from [c42ff771c4] to [80594c127a].

56
57
58
59
60
61
62
63

64
65
66

67
68
69
70
71
56
57
58
59
60
61
62

63
64
65

66

67
68
69
70







-
+


-
+
-





	data = [OFData dataWithItems: "0123456789:;<ABCDEFGHJIKLMNOPQRSTUVWXYZ"
			       count: 39];
	[d setObject: @"data"
	      forKey: data];

	TEST(@"-[stringBySerializing]",
	    (s = [d stringBySerializing]) && [s isEqual:
	    (s = d.stringBySerializing) && [s isEqual:
	    [OFString stringWithContentsOfFile: @"serialization.xml"]])

	TEST(@"-[objectByDeserializing]",
	TEST(@"-[objectByDeserializing]", [s.objectByDeserializing isEqual: d])
	    [[s objectByDeserializing] isEqual: d])

	[pool drain];
}
@end

Modified tests/OFSetTests.m from [9e6450868f] to [c26bc92ca5].

100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
100
101
102
103
104
105
106

107
108
109
110
111
112
113
114







-
+







	[_set release];

	[super dealloc];
}

- (size_t)count
{
	return [_set count];
	return _set.count;
}

- (bool)containsObject: (id)object
{
	return [_set containsObject: object];
}

161
162
163
164
165
166
167
168

169
170
171

172
173

174
175
176
177
178
179
180
161
162
163
164
165
166
167

168
169
170

171
172

173
174
175
176
177
178
179
180







-
+


-
+

-
+








	TEST(@"+[setWithObjects:]",
	    (set2 = [setClass setWithObjects: @"foo", @"bar", @"baz", @"bar",
	    @"x", nil]))

	TEST(@"-[isEqual:]", [set1 isEqual: set2])

	TEST(@"-[hash]", [set1 hash] == [set2 hash])
	TEST(@"-[hash]", set1.hash == set2.hash)

	TEST(@"-[description]",
	    [[set1 description]
	    [set1.description
	    isEqual: @"{(\n\tx,\n\tbar,\n\tfoo,\n\tbaz\n)}"] &&
	    [[set1 description] isEqual: [set2 description]])
	    [set1.description isEqual: set2.description])

	TEST(@"-[copy]", [set1 isEqual: [[set1 copy] autorelease]])

	TEST(@"-[mutableCopy]",
	    [set1 isEqual: [[set1 mutableCopy] autorelease]]);

	mutableSet = [mutableSetClass setWithSet: set1];

Modified tests/OFStreamTests.m from [cc7b2ebf4b] to [21aef18599].

72
73
74
75
76
77
78
79
80


81
82
83
84
72
73
74
75
76
77
78


79
80
81
82
83
84







-
-
+
+




	char *cstr;

	cstr = [t allocMemoryWithSize: pageSize - 2];
	memset(cstr, 'X', pageSize - 3);
	cstr[pageSize - 3] = '\0';

	TEST(@"-[readLine]", [[t readLine] isEqual: @"foo"] &&
	    [(str = [t readLine]) length] == pageSize - 3 &&
	    !strcmp([str UTF8String], cstr))
	    (str = [t readLine]).length == pageSize - 3 &&
	    !strcmp(str.UTF8String, cstr))

	[pool drain];
}
@end

Modified tests/OFStringTests.m from [6a603058a6] to [a63c11f262].

168
169
170
171
172
173
174
175

176
177
178
179
180
181
182
168
169
170
171
172
173
174

175
176
177
178
179
180
181
182







-
+







- (of_unichar_t)characterAtIndex: (size_t)idx
{
	return [_string characterAtIndex: idx];
}

- (size_t)length
{
	return [_string length];
	return _string.length;
}
@end

@implementation SimpleMutableString
+ (void)initialize
{
	if (self == [SimpleMutableString class])
219
220
221
222
223
224
225
226

227
228
229
230
231
232
233
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233







-
+







	OFCharacterSet *cs;
	EntityHandler *h;
#ifdef OF_HAVE_BLOCKS
	__block int j;
	__block bool ok;
#endif

#define C(s) [stringClass stringWithString: s]
#define C(s) ((OFString *)[stringClass stringWithString: s])

	s[0] = [mutableStringClass stringWithString: @"täs€"];
	s[1] = [mutableStringClass string];
	s[2] = [[s[0] copy] autorelease];

	TEST(@"-[isEqual:]", [s[0] isEqual: s[2]] &&
	    ![s[0] isEqual: [[[OFObject alloc] init] autorelease]])
258
259
260
261
262
263
264
265

266
267

268
269
270
271
272
273
274
275
276
277
278
279



280
281
282
283
284
285
286
258
259
260
261
262
263
264

265
266

267
268
269
270
271
272
273
274
275
276



277
278
279
280
281
282
283
284
285
286







-
+

-
+









-
-
-
+
+
+







	    [C(@"AA") caseInsensitiveCompare: @"z"] == OF_ORDERED_ASCENDING &&
	    [[stringClass stringWithUTF8String: "ABC"] caseInsensitiveCompare:
	    [stringClass stringWithUTF8String: "AbD"]] ==
	    [C(@"abc") compare: @"abd"])
#endif

	TEST(@"-[hash] is the same if -[isEqual:] is true",
	    [s[0] hash] == [s[2] hash])
	    s[0].hash == s[2].hash)

	TEST(@"-[description]", [[s[0] description] isEqual: s[0]])
	TEST(@"-[description]", [s[0].description isEqual: s[0]])

	TEST(@"-[appendString:] and -[appendUTF8String:]",
	    R([s[1] appendUTF8String: "1𝄞"]) && R([s[1] appendString: @"3"]) &&
	    R([s[0] appendString: s[1]]) && [s[0] isEqual: @"täs€1𝄞3"])

	TEST(@"-[appendCharacters:length:]",
	    R([s[1] appendCharacters: ucstr + 6
			      length: 2]) && [s[1] isEqual: @"1𝄞3r🀺"])

	TEST(@"-[length]", [s[0] length] == 7)
	TEST(@"-[UTF8StringLength]", [s[0] UTF8StringLength] == 13)
	TEST(@"-[hash]", [s[0] hash] == 0x705583C0)
	TEST(@"-[length]", s[0].length == 7)
	TEST(@"-[UTF8StringLength]", s[0].UTF8StringLength == 13)
	TEST(@"-[hash]", s[0].hash == 0x705583C0)

	TEST(@"-[characterAtIndex:]", [s[0] characterAtIndex: 0] == 't' &&
	    [s[0] characterAtIndex: 1] == 0xE4 &&
	    [s[0] characterAtIndex: 3] == 0x20AC &&
	    [s[0] characterAtIndex: 5] == 0x1D11E)

	EXPECT_EXCEPTION(@"Detect out of range in -[characterAtIndex:]",
301
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316
317
318
319

320
321
322
323

324
325

326
327
328
329
330
331
332
301
302
303
304
305
306
307

308
309
310
311
312
313
314
315
316
317
318

319

320
321

322
323

324
325
326
327
328
329
330
331







-
+










-
+
-


-
+

-
+








	TEST(@"-[uppercaseString]",
	    [[s[0] uppercaseString] isEqual: @"3𝄞1€SÄT"])

	TEST(@"-[lowercaseString]", R([s[0] uppercase]) &&
	    [[s[0] lowercaseString] isEqual: @"3𝄞1€sät"])

	TEST(@"-[capitalizedString]", [[C(@"džbla tdžst TDŽST") capitalizedString]
	TEST(@"-[capitalizedString]", [C(@"džbla tdžst TDŽST").capitalizedString
	    isEqual: @"Džbla Tdžst Tdžst"])
#else
	TEST(@"-[uppercase]", R([s[0] uppercase]) &&
	    [s[0] isEqual: @"3𝄞1€SäT"] &&
	    R([s[1] uppercase]) && [s[1] isEqual: @"ABC"])

	TEST(@"-[lowercase]", R([s[0] lowercase]) &&
	    [s[0] isEqual: @"3𝄞1€sät"] &&
	    R([s[1] lowercase]) && [s[1] isEqual: @"abc"])

	TEST(@"-[uppercaseString]",
	TEST(@"-[uppercaseString]", [s[0].uppercaseString isEqual: @"3𝄞1€SäT"])
	    [[s[0] uppercaseString] isEqual: @"3𝄞1€SäT"])

	TEST(@"-[lowercaseString]", R([s[0] uppercase]) &&
	    [[s[0] lowercaseString] isEqual: @"3𝄞1€sät"])
	    [s[0].lowercaseString isEqual: @"3𝄞1€sät"])

	TEST(@"-[capitalizedString]", [[C(@"džbla tdžst TDŽST") capitalizedString]
	TEST(@"-[capitalizedString]", [C(@"džbla tdžst TDŽST").capitalizedString
	    isEqual: @"džbla Tdžst TDŽst"])
#endif

	TEST(@"+[stringWithUTF8String:length:]",
	    (s[0] = [mutableStringClass stringWithUTF8String: "\xEF\xBB\xBF"
							      "foobar"
						      length: 6]) &&
539
540
541
542
543
544
545
546
547
548



549
550
551
552


553
554
555
556


557
558
559
560


561
562
563
564
565


566
567
568
569
570
571
572
538
539
540
541
542
543
544



545
546
547
548
549


550
551
552
553


554
555
556
557


558
559

560
561


562
563
564
565
566
567
568
569
570







-
-
-
+
+
+


-
-
+
+


-
-
+
+


-
-
+
+
-


-
-
+
+








	TEST(@"-[stringByPrependingString:]",
	    [[C(@"foo") stringByPrependingString: @"bar"] isEqual: @"barfoo"])

#ifdef OF_HAVE_FILES
# if defined(OF_WINDOWS)
	TEST(@"-[isAbsolutePath]",
	    [C(@"C:\\foo") isAbsolutePath] && [C(@"a:/foo") isAbsolutePath] &&
	    ![C(@"foo") isAbsolutePath] && ![C(@"b:foo") isAbsolutePath] &&
	    [C(@"\\\\foo") isAbsolutePath])
	    C(@"C:\\foo").absolutePath && C(@"a:/foo").absolutePath &&
	    !C(@"foo").absolutePath && !C(@"b:foo").absolutePath &&
	    C(@"\\\\foo").absolutePath)
# elif  defined(OF_MSDOS)
	TEST(@"-[isAbsolutePath]",
	    [C(@"C:\\foo") isAbsolutePath] && [C(@"a:/foo") isAbsolutePath] &&
	    ![C(@"foo") isAbsolutePath] && ![C(@"b:foo") isAbsolutePath])
	    C(@"C:\\foo").absolutePath && C(@"a:/foo").absolutePath &&
	    !C(@"foo").absolutePath && !C(@"b:foo").absolutePath)
# elif defined(OF_AMIGAOS)
	TEST(@"-[isAbsolutePath]",
	    [C(@"dh0:foo") isAbsolutePath] && [C(@"dh0:a/b") isAbsolutePath] &&
	    ![C(@"foo/bar") isAbsolutePath] && ![C(@"foo") isAbsolutePath])
	    C(@"dh0:foo").absolutePath && C(@"dh0:a/b").absolutePath &&
	    !C(@"foo/bar").absolutePath && !C(@"foo").absolutePath)
# elif defined(OF_NINTENDO_3DS) || defined(OF_WII)
	TEST(@"-[isAbsolutePath]",
	    [C(@"sdmc:/foo") isAbsolutePath] &&
	    ![C(@"sdmc:foo") isAbsolutePath] &&
	    C(@"sdmc:/foo").absolutePath && !C(@"sdmc:foo").absolutePath &&
	    !C(@"foo/bar").absolutePath && !C(@"foo").absolutePath)
	    ![C(@"foo/bar") isAbsolutePath] && ![C(@"foo") isAbsolutePath])
# else
	TEST(@"-[isAbsolutePath]",
	    [C(@"/foo") isAbsolutePath] && [C(@"/foo/bar") isAbsolutePath] &&
	    ![C(@"foo/bar") isAbsolutePath] && ![C(@"foo") isAbsolutePath])
	    C(@"/foo").absolutePath && C(@"/foo/bar").absolutePath &&
	    !C(@"foo/bar").absolutePath && !C(@"foo").absolutePath)
# endif

	s[0] = [mutableStringClass stringWithString: @"foo"];
# if defined(OF_WINDOWS) || defined(OF_MSDOS)
	[s[0] appendString: @"\\"];
# else
	[s[0] appendString: @"/"];
597
598
599
600
601
602
603
604

605
606
607
608
609
610
611
612
613
614

615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633

634
635
636
637
638
639
640
641
642
643

644
645
646
647
648
649
650
595
596
597
598
599
600
601

602
603
604
605
606
607
608
609
610
611

612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630

631
632
633
634
635
636
637
638
639
640

641
642
643
644
645
646
647
648







-
+









-
+


















-
+









-
+







	    componentsSeparatedByString: @"XX"]) &&
	    [[a objectAtIndex: i++] isEqual: @"foo"] &&
	    [[a objectAtIndex: i++] isEqual: @"bar"] &&
	    [[a objectAtIndex: i++] isEqual: @""] &&
	    [[a objectAtIndex: i++] isEqual: @"baz"] &&
	    [[a objectAtIndex: i++] isEqual: @""] &&
	    [[a objectAtIndex: i++] isEqual: @""] &&
	    [a count] == i)
	    a.count == i)

	i = 0;
	TEST(@"-[componentsSeparatedByString:options:]",
	    (a = [C(@"fooXXbarXXXXbazXXXX")
	    componentsSeparatedByString: @"XX"
				options: OF_STRING_SKIP_EMPTY]) &&
	    [[a objectAtIndex: i++] isEqual: @"foo"] &&
	    [[a objectAtIndex: i++] isEqual: @"bar"] &&
	    [[a objectAtIndex: i++] isEqual: @"baz"] &&
	    [a count] == i)
	    a.count == i)

	cs = [OFCharacterSet characterSetWithCharactersInString: @"XYZ"];

	i = 0;
	TEST(@"-[componentsSeparatedByCharactersInSet:]",
	    (a = [C(@"fooXYbarXYZXbazXYXZx")
	    componentsSeparatedByCharactersInSet: cs]) &&
	    [[a objectAtIndex: i++] isEqual: @"foo"] &&
	    [[a objectAtIndex: i++] isEqual: @""] &&
	    [[a objectAtIndex: i++] isEqual: @"bar"] &&
	    [[a objectAtIndex: i++] isEqual: @""] &&
	    [[a objectAtIndex: i++] isEqual: @""] &&
	    [[a objectAtIndex: i++] isEqual: @""] &&
	    [[a objectAtIndex: i++] isEqual: @"baz"] &&
	    [[a objectAtIndex: i++] isEqual: @""] &&
	    [[a objectAtIndex: i++] isEqual: @""] &&
	    [[a objectAtIndex: i++] isEqual: @""] &&
	    [[a objectAtIndex: i++] isEqual: @"x"] &&
	    [a count] == i)
	    a.count == i)

	i = 0;
	TEST(@"-[componentsSeparatedByCharactersInSet:options:]",
	    (a = [C(@"fooXYbarXYZXbazXYXZ")
	    componentsSeparatedByCharactersInSet: cs
					 options: OF_STRING_SKIP_EMPTY]) &&
	    [[a objectAtIndex: i++] isEqual: @"foo"] &&
	    [[a objectAtIndex: i++] isEqual: @"bar"] &&
	    [[a objectAtIndex: i++] isEqual: @"baz"] &&
	    [a count] == i)
	    a.count == i)

#ifdef OF_HAVE_FILES
# if defined(OF_WINDOWS)
	TEST(@"+[pathWithComponents:]",
	    [[stringClass pathWithComponents: [OFArray arrayWithObjects:
	    @"foo", @"bar", @"baz", nil]] isEqual: @"foo\\bar\\baz"] &&
	    [[stringClass pathWithComponents: [OFArray arrayWithObjects:
711
712
713
714
715
716
717
718

719
720
721
722

723
724
725
726

727
728
729

730
731
732
733

734
735
736
737
738

739
740
741
742

743
744
745


746
747
748
749

750
751
752
753

754
755
756
757

758
759
760

761
762
763
764

765
766
767
768
769

770
771

772


773
774
775

776
777
778
779

780
781
782
783

784
785
786
787

788
789
790
791

792
793
794
795
796

797
798
799

800
801
802
803

804
805
806
807

808
809
810

811
812
813
814

815
816
817
818
819

820
821

822
823
824
825

826
827
828
829

830
831
832
833

834
835
836

837
838
839
840

841
842
843
844
845

846
847

848
849
850
851
852
853
854
855
856
857
858
859
860
861










862
863
864
865
866
867




868
869
870
871




872
873
874
875
876
877
878
879
880







881
882
883
884
885
886




887
888
889
890




891
892
893
894
895
896
897






898
899
900
901
902
903
904




905
906
907
908
909
910
911
912






913
914

915
916
917
918



919
920

921
922

923
924
925
926
927
928
929






930
931

932
933
934


935
936
937
938

939
940

941
942

943
944

945
946
947
948




949
950
951
952


953
954

955
956

957
958
959


960
961
962
963
964



965
966

967
968
969


970
971
972
973
974
975
976



977
978

979
980
981
982



983
984
985
986
987



988
989

990
991

992
993
994
995



996
997

998
999
1000
1001
1002



1003
1004

1005
1006
1007
1008



1009
1010
1011
1012
1013



1014
1015

1016
1017
1018
1019



1020
1021

1022
1023
1024
1025
1026
1027

1028
1029
1030
1031
1032
1033
1034
1035
1036




1037
1038
1039
1040
1041
1042
1043
1044






1045
1046
1047
1048


1049
1050

1051
1052
1053
1054
1055
1056
1057
1058
1059
1060




1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084




1085
1086
1087
1088
1089
1090
1091
709
710
711
712
713
714
715

716
717
718
719

720
721
722
723

724
725
726

727
728
729
730

731
732
733
734
735

736
737

738

739
740
741

742
743
744
745
746

747
748
749
750

751
752
753
754

755
756
757

758
759
760
761

762
763
764
765
766

767
768

769
770
771
772



773
774
775
776

777
778
779
780

781
782
783
784

785
786
787
788

789
790
791
792
793

794
795
796

797
798
799
800

801
802
803
804

805
806
807

808
809
810
811

812
813
814
815
816

817
818

819
820
821
822

823
824
825
826

827
828
829
830

831
832
833

834
835
836
837

838
839
840
841
842

843
844

845
846
847
848
849










850
851
852
853
854
855
856
857
858
859
860
861




862
863
864
865




866
867
868
869
870
871







872
873
874
875
876
877
878
879
880




881
882
883
884




885
886
887
888
889






890
891
892
893
894
895
896
897
898




899
900
901
902
903
904






905
906
907
908
909
910
911

912
913



914
915
916
917

918
919

920
921






922
923
924
925
926
927
928

929
930


931
932
933
934


935


936
937

938
939

940




941
942
943
944
945
946


947
948
949

950
951

952



953
954
955
956



957
958
959
960

961



962
963
964
965
966
967



968
969
970
971

972
973



974
975
976
977
978



979
980
981
982

983
984

985
986



987
988
989
990

991
992
993



994
995
996
997

998
999



1000
1001
1002
1003
1004



1005
1006
1007
1008

1009
1010



1011
1012
1013
1014

1015
1016
1017
1018
1019
1020

1021
1022
1023
1024
1025
1026




1027
1028
1029
1030
1031
1032






1033
1034
1035
1036
1037
1038
1039
1040


1041
1042


1043
1044
1045
1046
1047
1048
1049




1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073




1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084







-
+



-
+



-
+


-
+



-
+




-
+

-

-
+


-
+
+



-
+



-
+



-
+


-
+



-
+




-
+

-
+

+
+
-
-
-
+



-
+



-
+



-
+



-
+




-
+


-
+



-
+



-
+


-
+



-
+




-
+

-
+



-
+



-
+



-
+


-
+



-
+




-
+

-
+




-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+


-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+


-
-
-
-
-
-
-
+
+
+
+
+
+
+


-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+

-
-
-
-
-
-
+
+
+
+
+
+



-
-
-
-
+
+
+
+


-
-
-
-
-
-
+
+
+
+
+
+

-
+

-
-
-
+
+
+

-
+

-
+

-
-
-
-
-
-
+
+
+
+
+
+

-
+

-
-
+
+


-
-
+
-
-
+

-
+

-
+
-
-
-
-
+
+
+
+


-
-
+
+

-
+

-
+
-
-
-
+
+


-
-
-
+
+
+

-
+
-
-
-
+
+




-
-
-
+
+
+

-
+

-
-
-
+
+
+


-
-
-
+
+
+

-
+

-
+

-
-
-
+
+
+

-
+


-
-
-
+
+
+

-
+

-
-
-
+
+
+


-
-
-
+
+
+

-
+

-
-
-
+
+
+

-
+





-
+





-
-
-
-
+
+
+
+


-
-
-
-
-
-
+
+
+
+
+
+


-
-
+
+
-
-
+






-
-
-
-
+
+
+
+




















-
-
-
-
+
+
+
+







	    [[stringClass pathWithComponents: [OFArray arrayWithObjects:
	    @"foo", nil]] isEqual: @"foo"])
# endif

# if defined(OF_WINDOWS)
	TEST(@"-[pathComponents]",
	    /* c:/tmp */
	    (a = [C(@"c:/tmp") pathComponents]) && [a count] == 2 &&
	    (a = C(@"c:/tmp").pathComponents) && a.count == 2 &&
	    [[a objectAtIndex: 0] isEqual: @"c:"] &&
	    [[a objectAtIndex: 1] isEqual: @"tmp"] &&
	    /* c:\tmp\ */
	    (a = [C(@"c:\\tmp\\") pathComponents]) && [a count] == 2 &&
	    (a = C(@"c:\\tmp\\").pathComponents) && a.count == 2 &&
	    [[a objectAtIndex: 0] isEqual: @"c:"] &&
	    [[a objectAtIndex: 1] isEqual: @"tmp"] &&
	    /* c:/ */
	    (a = [C(@"c:/") pathComponents]) && [a count] == 1 &&
	    (a = C(@"c:/").pathComponents) && a.count == 1 &&
	    [[a objectAtIndex: 0] isEqual: @"c:"] &&
	    /* foo\bar */
	    (a = [C(@"foo\\bar") pathComponents]) && [a count] == 2 &&
	    (a = C(@"foo\\bar").pathComponents) && a.count == 2 &&
	    [[a objectAtIndex: 0] isEqual: @"foo"] &&
	    [[a objectAtIndex: 1] isEqual: @"bar"] &&
	    /* foo\bar/baz/ */
	    (a = [C(@"foo\\bar/baz/") pathComponents]) && [a count] == 3 &&
	    (a = C(@"foo\\bar/baz/").pathComponents) && a.count == 3 &&
	    [[a objectAtIndex: 0] isEqual: @"foo"] &&
	    [[a objectAtIndex: 1] isEqual: @"bar"] &&
	    [[a objectAtIndex: 2] isEqual: @"baz"] &&
	    /* foo\/ */
	    (a = [C(@"foo\\/") pathComponents]) && [a count] == 1 &&
	    (a = C(@"foo\\/").pathComponents) && a.count == 1 &&
	    [[a objectAtIndex: 0] isEqual: @"foo"] &&
	    [[C(@"") pathComponents] count] == 0 &&
	    /* \\foo\bar */
	    (a = [C(@"\\\\foo\\bar") pathComponents]) && [a count] == 3 &&
	    (a = C(@"\\\\foo\\bar").pathComponents) && a.count == 3 &&
	    [[a objectAtIndex: 0] isEqual: @"\\\\"] &&
	    [[a objectAtIndex: 1] isEqual: @"foo"] &&
	    [[a objectAtIndex: 2] isEqual: @"bar"])
	    [[a objectAtIndex: 2] isEqual: @"bar"] &&
	    C(@"").pathComponents.count == 0)
# elif defined(OF_MSDOS)
	TEST(@"-[pathComponents]",
	    /* c:/tmp */
	    (a = [C(@"c:/tmp") pathComponents]) && [a count] == 2 &&
	    (a = C(@"c:/tmp").pathComponents) && a.count == 2 &&
	    [[a objectAtIndex: 0] isEqual: @"c:"] &&
	    [[a objectAtIndex: 1] isEqual: @"tmp"] &&
	    /* c:\tmp\ */
	    (a = [C(@"c:\\tmp\\") pathComponents]) && [a count] == 2 &&
	    (a = C(@"c:\\tmp\\").pathComponents) && a.count == 2 &&
	    [[a objectAtIndex: 0] isEqual: @"c:"] &&
	    [[a objectAtIndex: 1] isEqual: @"tmp"] &&
	    /* c:/ */
	    (a = [C(@"c:/") pathComponents]) && [a count] == 1 &&
	    (a = C(@"c:/").pathComponents) && a.count == 1 &&
	    [[a objectAtIndex: 0] isEqual: @"c:"] &&
	    /* foo\bar */
	    (a = [C(@"foo\\bar") pathComponents]) && [a count] == 2 &&
	    (a = C(@"foo\\bar").pathComponents) && a.count == 2 &&
	    [[a objectAtIndex: 0] isEqual: @"foo"] &&
	    [[a objectAtIndex: 1] isEqual: @"bar"] &&
	    /* foo\bar/baz/ */
	    (a = [C(@"foo\\bar/baz/") pathComponents]) && [a count] == 3 &&
	    (a = C(@"foo\\bar/baz/").pathComponents) && a.count == 3 &&
	    [[a objectAtIndex: 0] isEqual: @"foo"] &&
	    [[a objectAtIndex: 1] isEqual: @"bar"] &&
	    [[a objectAtIndex: 2] isEqual: @"baz"] &&
	    /* foo\/ */
	    (a = [C(@"foo\\/") pathComponents]) && [a count] == 1 &&
	    (a = C(@"foo\\/").pathComponents) && a.count == 1 &&
	    [[a objectAtIndex: 0] isEqual: @"foo"] &&
	    [[C(@"") pathComponents] count] == 0)
	    C(@"").pathComponents.count == 0)
# elif defined(OF_AMIGAOS)
	TEST(@"-[pathComponents]",
	    /* dh0:tmp */
	TEST(@"-[pathComponents]",
	    /* dh0:tmp */
	    (a = [C(@"dh0:tmp") pathComponents]) && [a count] == 2 &&
	    (a = C(@"dh0:tmp").pathComponents) && a.count == 2 &&
	    [[a objectAtIndex: 0] isEqual: @"dh0:"] &&
	    [[a objectAtIndex: 1] isEqual: @"tmp"] &&
	    /* dh0:tmp/ */
	    (a = [C(@"dh0:tmp/") pathComponents]) && [a count] == 2 &&
	    (a = C(@"dh0:tmp/").pathComponents) && a.count == 2 &&
	    [[a objectAtIndex: 0] isEqual: @"dh0:"] &&
	    [[a objectAtIndex: 1] isEqual: @"tmp"] &&
	    /* dh0: */
	    (a = [C(@"dh0:/") pathComponents]) && [a count] == 2 &&
	    (a = C(@"dh0:/").pathComponents) && a.count == 2 &&
	    [[a objectAtIndex: 0] isEqual: @"dh0:"] &&
	    [[a objectAtIndex: 1] isEqual: @"/"] &&
	    /* foo/bar */
	    (a = [C(@"foo/bar") pathComponents]) && [a count] == 2 &&
	    (a = C(@"foo/bar").pathComponents) && a.count == 2 &&
	    [[a objectAtIndex: 0] isEqual: @"foo"] &&
	    [[a objectAtIndex: 1] isEqual: @"bar"] &&
	    /* foo/bar/baz/ */
	    (a = [C(@"foo/bar/baz/") pathComponents]) && [a count] == 3 &&
	    (a = C(@"foo/bar/baz/").pathComponents) && a.count == 3 &&
	    [[a objectAtIndex: 0] isEqual: @"foo"] &&
	    [[a objectAtIndex: 1] isEqual: @"bar"] &&
	    [[a objectAtIndex: 2] isEqual: @"baz"] &&
	    /* foo// */
	    (a = [C(@"foo//") pathComponents]) && [a count] == 2 &&
	    (a = C(@"foo//").pathComponents) && a.count == 2 &&
	    [[a objectAtIndex: 0] isEqual: @"foo"] &&
	    [[a objectAtIndex: 1] isEqual: @"/"] &&
	    [[C(@"") pathComponents] count] == 0)
	    C(@"").pathComponents.count == 0)
# elif defined(OF_NINTENDO_3DS) || defined(OF_WII)
	TEST(@"-[pathComponents]",
	    /* sdmc:/tmp */
	    (a = [C(@"sdmc:/tmp") pathComponents]) && [a count] == 2 &&
	    (a = C(@"sdmc:/tmp").pathComponents) && a.count == 2 &&
	    [[a objectAtIndex: 0] isEqual: @"sdmc:"] &&
	    [[a objectAtIndex: 1] isEqual: @"tmp"] &&
	    /* sdmc:/ */
	    (a = [C(@"sdmc:/") pathComponents]) && [a count] == 1 &&
	    (a = C(@"sdmc:/").pathComponents) && a.count == 1 &&
	    [[a objectAtIndex: 0] isEqual: @"sdmc:"] &&
	    /* foo/bar */
	    (a = [C(@"foo/bar") pathComponents]) && [a count] == 2 &&
	    (a = C(@"foo/bar").pathComponents) && a.count == 2 &&
	    [[a objectAtIndex: 0] isEqual: @"foo"] &&
	    [[a objectAtIndex: 1] isEqual: @"bar"] &&
	    /* foo/bar/baz/ */
	    (a = [C(@"foo/bar/baz/") pathComponents]) && [a count] == 3 &&
	    (a = C(@"foo/bar/baz/").pathComponents) && a.count == 3 &&
	    [[a objectAtIndex: 0] isEqual: @"foo"] &&
	    [[a objectAtIndex: 1] isEqual: @"bar"] &&
	    [[a objectAtIndex: 2] isEqual: @"baz"] &&
	    /* foo// */
	    (a = [C(@"foo//") pathComponents]) && [a count] == 1 &&
	    (a = C(@"foo//").pathComponents) && a.count == 1 &&
	    [[a objectAtIndex: 0] isEqual: @"foo"] &&
	    [[C(@"") pathComponents] count] == 0)
	    C(@"").pathComponents.count == 0)
# else
	TEST(@"-[pathComponents]",
	    /* /tmp */
	    (a = [C(@"/tmp") pathComponents]) && [a count] == 2 &&
	    (a = C(@"/tmp").pathComponents) && a.count == 2 &&
	    [[a objectAtIndex: 0] isEqual: @"/"] &&
	    [[a objectAtIndex: 1] isEqual: @"tmp"] &&
	    /* /tmp/ */
	    (a = [C(@"/tmp/") pathComponents]) && [a count] == 2 &&
	    (a = C(@"/tmp/").pathComponents) && a.count == 2 &&
	    [[a objectAtIndex: 0] isEqual: @"/"] &&
	    [[a objectAtIndex: 1] isEqual: @"tmp"] &&
	    /* / */
	    (a = [C(@"/") pathComponents]) && [a count] == 1 &&
	    (a = C(@"/").pathComponents) && a.count == 1 &&
	    [[a objectAtIndex: 0] isEqual: @"/"] &&
	    /* foo/bar */
	    (a = [C(@"foo/bar") pathComponents]) && [a count] == 2 &&
	    (a = C(@"foo/bar").pathComponents) && a.count == 2 &&
	    [[a objectAtIndex: 0] isEqual: @"foo"] &&
	    [[a objectAtIndex: 1] isEqual: @"bar"] &&
	    /* foo/bar/baz/ */
	    (a = [C(@"foo/bar/baz/") pathComponents]) && [a count] == 3 &&
	    (a = C(@"foo/bar/baz/").pathComponents) && a.count == 3 &&
	    [[a objectAtIndex: 0] isEqual: @"foo"] &&
	    [[a objectAtIndex: 1] isEqual: @"bar"] &&
	    [[a objectAtIndex: 2] isEqual: @"baz"] &&
	    /* foo// */
	    (a = [C(@"foo//") pathComponents]) && [a count] == 1 &&
	    (a = C(@"foo//").pathComponents) && a.count == 1 &&
	    [[a objectAtIndex: 0] isEqual: @"foo"] &&
	    [[C(@"") pathComponents] count] == 0)
	    C(@"").pathComponents.count == 0)
# endif

# if defined(OF_WINDOWS)
	TEST(@"-[lastPathComponent]",
	    [[C(@"c:/tmp") lastPathComponent] isEqual: @"tmp"] &&
	    [[C(@"c:\\tmp\\") lastPathComponent] isEqual: @"tmp"] &&
	    [[C(@"c:\\") lastPathComponent] isEqual: @"c:\\"] &&
	    [[C(@"c:/") lastPathComponent] isEqual: @"c:/"] &&
	    [[C(@"\\") lastPathComponent] isEqual: @""] &&
	    [[C(@"foo") lastPathComponent] isEqual: @"foo"] &&
	    [[C(@"foo\\bar") lastPathComponent] isEqual: @"bar"] &&
	    [[C(@"foo/bar/baz/") lastPathComponent] isEqual: @"baz"] &&
	    [[C(@"\\\\foo\\bar") lastPathComponent] isEqual: @"bar"] &&
	    [[C(@"\\\\") lastPathComponent] isEqual: @"\\\\"])
	    [C(@"c:/tmp").lastPathComponent isEqual: @"tmp"] &&
	    [C(@"c:\\tmp\\").lastPathComponent isEqual: @"tmp"] &&
	    [C(@"c:\\").lastPathComponent isEqual: @"c:\\"] &&
	    [C(@"c:/").lastPathComponent isEqual: @"c:/"] &&
	    [C(@"\\").lastPathComponent isEqual: @""] &&
	    [C(@"foo").lastPathComponent isEqual: @"foo"] &&
	    [C(@"foo\\bar").lastPathComponent isEqual: @"bar"] &&
	    [C(@"foo/bar/baz/").lastPathComponent isEqual: @"baz"] &&
	    [C(@"\\\\foo\\bar").lastPathComponent isEqual: @"bar"] &&
	    [C(@"\\\\").lastPathComponent isEqual: @"\\\\"])
# elif defined(OF_MSDOS)
	TEST(@"-[lastPathComponent]",
	    [[C(@"c:/tmp") lastPathComponent] isEqual: @"tmp"] &&
	    [[C(@"c:\\tmp\\") lastPathComponent] isEqual: @"tmp"] &&
	    [[C(@"c:\\") lastPathComponent] isEqual: @"c:\\"] &&
	    [[C(@"c:/") lastPathComponent] isEqual: @"c:/"] &&
	    [C(@"c:/tmp").lastPathComponent isEqual: @"tmp"] &&
	    [C(@"c:\\tmp\\").lastPathComponent isEqual: @"tmp"] &&
	    [C(@"c:\\").lastPathComponent isEqual: @"c:\\"] &&
	    [C(@"c:/").lastPathComponent isEqual: @"c:/"] &&
	    [[C(@"\\") lastPathComponent] isEqual: @""] &&
	    [[C(@"foo") lastPathComponent] isEqual: @"foo"] &&
	    [[C(@"foo\\bar") lastPathComponent] isEqual: @"bar"] &&
	    [[C(@"foo/bar/baz/") lastPathComponent] isEqual: @"baz"])
	    [C(@"\\").lastPathComponent isEqual: @""] &&
	    [C(@"foo").lastPathComponent isEqual: @"foo"] &&
	    [C(@"foo\\bar").lastPathComponent isEqual: @"bar"] &&
	    [C(@"foo/bar/baz/").lastPathComponent isEqual: @"baz"])
# elif defined(OF_AMIGAOS)
	TEST(@"-[lastPathComponent]",
	    [[C(@"dh0:tmp") lastPathComponent] isEqual: @"tmp"] &&
	    [[C(@"dh0:tmp/") lastPathComponent] isEqual: @"tmp"] &&
	    [[C(@"dh0:/") lastPathComponent] isEqual: @"/"] &&
	    [[C(@"dh0:") lastPathComponent] isEqual: @"dh0:"] &&
	    [[C(@"foo") lastPathComponent] isEqual: @"foo"] &&
	    [[C(@"foo/bar") lastPathComponent] isEqual: @"bar"] &&
	    [[C(@"foo/bar/baz/") lastPathComponent] isEqual: @"baz"])
	    [C(@"dh0:tmp").lastPathComponent isEqual: @"tmp"] &&
	    [C(@"dh0:tmp/").lastPathComponent isEqual: @"tmp"] &&
	    [C(@"dh0:/").lastPathComponent isEqual: @"/"] &&
	    [C(@"dh0:").lastPathComponent isEqual: @"dh0:"] &&
	    [C(@"foo").lastPathComponent isEqual: @"foo"] &&
	    [C(@"foo/bar").lastPathComponent isEqual: @"bar"] &&
	    [C(@"foo/bar/baz/").lastPathComponent isEqual: @"baz"])
# elif defined(OF_NINTENDO_3DS) || defined(OF_WII)
	TEST(@"-[lastPathComponent]",
	    [[C(@"sdmc:/tmp") lastPathComponent] isEqual: @"tmp"] &&
	    [[C(@"sdmc:/tmp/") lastPathComponent] isEqual: @"tmp"] &&
	    [[C(@"sdmc:/") lastPathComponent] isEqual: @"sdmc:/"] &&
	    [[C(@"sdmc:") lastPathComponent] isEqual: @"sdmc:"] &&
	    [C(@"sdmc:/tmp").lastPathComponent isEqual: @"tmp"] &&
	    [C(@"sdmc:/tmp/").lastPathComponent isEqual: @"tmp"] &&
	    [C(@"sdmc:/").lastPathComponent isEqual: @"sdmc:/"] &&
	    [C(@"sdmc:").lastPathComponent isEqual: @"sdmc:"] &&
	    [[C(@"foo") lastPathComponent] isEqual: @"foo"] &&
	    [[C(@"foo/bar") lastPathComponent] isEqual: @"bar"] &&
	    [[C(@"foo/bar/baz/") lastPathComponent] isEqual: @"baz"])
# else
	    [C(@"foo").lastPathComponent isEqual: @"foo"] &&
	    [C(@"foo/bar").lastPathComponent isEqual: @"bar"] &&
	    [C(@"foo/bar/baz/").lastPathComponent isEqual: @"baz"])
# else
	TEST(@"-[lastPathComponent]",
	    [[C(@"/tmp") lastPathComponent] isEqual: @"tmp"] &&
	    [[C(@"/tmp/") lastPathComponent] isEqual: @"tmp"] &&
	    [[C(@"/") lastPathComponent] isEqual: @"/"] &&
	    [[C(@"foo") lastPathComponent] isEqual: @"foo"] &&
	    [[C(@"foo/bar") lastPathComponent] isEqual: @"bar"] &&
	    [[C(@"foo/bar/baz/") lastPathComponent] isEqual: @"baz"])
	    [C(@"/tmp").lastPathComponent isEqual: @"tmp"] &&
	    [C(@"/tmp/").lastPathComponent isEqual: @"tmp"] &&
	    [C(@"/").lastPathComponent isEqual: @"/"] &&
	    [C(@"foo").lastPathComponent isEqual: @"foo"] &&
	    [C(@"foo/bar").lastPathComponent isEqual: @"bar"] &&
	    [C(@"foo/bar/baz/").lastPathComponent isEqual: @"baz"])
# endif

	TEST(@"-[pathExtension]",
	    [[C(@"foo.bar") pathExtension] isEqual: @"bar"] &&
	    [[C(@"foo/.bar") pathExtension] isEqual: @""] &&
	    [[C(@"foo/.bar.baz") pathExtension] isEqual: @"baz"] &&
	    [[C(@"foo/bar.baz/") pathExtension] isEqual: @"baz"])
	    [C(@"foo.bar").pathExtension isEqual: @"bar"] &&
	    [C(@"foo/.bar").pathExtension isEqual: @""] &&
	    [C(@"foo/.bar.baz").pathExtension isEqual: @"baz"] &&
	    [C(@"foo/bar.baz/").pathExtension isEqual: @"baz"])

# if defined(OF_WINDOWS)
	TEST(@"-[stringByDeletingLastPathComponent]",
	    [[C(@"\\tmp") stringByDeletingLastPathComponent] isEqual: @""] &&
	    [[C(@"/tmp/") stringByDeletingLastPathComponent] isEqual: @""] &&
	    [[C(@"c:\\") stringByDeletingLastPathComponent] isEqual: @"c:\\"] &&
	    [[C(@"c:/") stringByDeletingLastPathComponent] isEqual: @"c:/"] &&
	    [[C(@"c:\\tmp/foo/") stringByDeletingLastPathComponent]
	TEST(@"-[stringByDeletingLastPathComponent]",
	    [C(@"\\tmp").stringByDeletingLastPathComponent isEqual: @""] &&
	    [C(@"/tmp/").stringByDeletingLastPathComponent isEqual: @""] &&
	    [C(@"c:\\").stringByDeletingLastPathComponent isEqual: @"c:\\"] &&
	    [C(@"c:/").stringByDeletingLastPathComponent isEqual: @"c:/"] &&
	    [C(@"c:\\tmp/foo/").stringByDeletingLastPathComponent
	    isEqual: @"c:\\tmp"] &&
	    [[C(@"foo\\bar") stringByDeletingLastPathComponent]
	    [C(@"foo\\bar").stringByDeletingLastPathComponent
	    isEqual: @"foo"] &&
	    [[C(@"\\") stringByDeletingLastPathComponent] isEqual: @""] &&
	    [[C(@"foo") stringByDeletingLastPathComponent] isEqual: @"."] &&
	    [[C(@"\\\\foo\\bar") stringByDeletingLastPathComponent]
	    [C(@"\\").stringByDeletingLastPathComponent isEqual: @""] &&
	    [C(@"foo").stringByDeletingLastPathComponent isEqual: @"."] &&
	    [C(@"\\\\foo\\bar").stringByDeletingLastPathComponent
	    isEqual: @"\\\\foo"] &&
	    [[C(@"\\\\foo") stringByDeletingLastPathComponent]
	    [C(@"\\\\foo").stringByDeletingLastPathComponent
	    isEqual: @"\\\\"] &&
	    [[C(@"\\\\") stringByDeletingLastPathComponent] isEqual: @"\\\\"])
	    [C(@"\\\\").stringByDeletingLastPathComponent isEqual: @"\\\\"])
# elif defined(OF_MSDOS)
	TEST(@"-[stringByDeletingLastPathComponent]",
	    [[C(@"\\tmp") stringByDeletingLastPathComponent] isEqual: @""] &&
	    [[C(@"/tmp/") stringByDeletingLastPathComponent] isEqual: @""] &&
	    [[C(@"c:\\") stringByDeletingLastPathComponent] isEqual: @"c:\\"] &&
	    [[C(@"c:/") stringByDeletingLastPathComponent] isEqual: @"c:/"] &&
	    [[C(@"c:\\tmp/foo/") stringByDeletingLastPathComponent]
	TEST(@"-[stringByDeletingLastPathComponent]",
	    [C(@"\\tmp").stringByDeletingLastPathComponent isEqual: @""] &&
	    [C(@"/tmp/").stringByDeletingLastPathComponent isEqual: @""] &&
	    [C(@"c:\\").stringByDeletingLastPathComponent isEqual: @"c:\\"] &&
	    [C(@"c:/").stringByDeletingLastPathComponent isEqual: @"c:/"] &&
	    [C(@"c:\\tmp/foo/").stringByDeletingLastPathComponent
	    isEqual: @"c:\\tmp"] &&
	    [[C(@"foo\\bar") stringByDeletingLastPathComponent]
	    [C(@"foo\\bar").stringByDeletingLastPathComponent
	    isEqual: @"foo"] &&
	    [[C(@"\\") stringByDeletingLastPathComponent] isEqual: @""] &&
	    [[C(@"foo") stringByDeletingLastPathComponent] isEqual: @"."])
	    [C(@"\\").stringByDeletingLastPathComponent isEqual: @""] &&
	    [C(@"foo").stringByDeletingLastPathComponent isEqual: @"."])
# elif defined(OF_AMIGAOS)
	TEST(@"-[stringByDeletingLastPathComponent]",
	    [[C(@"dh0:") stringByDeletingLastPathComponent] isEqual: @"dh0:"] &&
	    [[C(@"dh0:tmp") stringByDeletingLastPathComponent]
	    [C(@"dh0:").stringByDeletingLastPathComponent isEqual: @"dh0:"] &&
	    isEqual: @"dh0:"] &&
	    [[C(@"dh0:tmp/") stringByDeletingLastPathComponent]
	    [C(@"dh0:tmp").stringByDeletingLastPathComponent
	    isEqual: @"dh0:"] &&
	    [[C(@"dh0:/") stringByDeletingLastPathComponent]
	    [C(@"dh0:tmp/").stringByDeletingLastPathComponent
	    isEqual: @"dh0:"] &&
	    [[C(@"dh0:tmp/foo/") stringByDeletingLastPathComponent]
	    [C(@"dh0:/").stringByDeletingLastPathComponent isEqual: @"dh0:"] &&
	    isEqual: @"dh0:tmp"] &&
	    [[C(@"foo/bar") stringByDeletingLastPathComponent]
	    isEqual: @"foo"] &&
	    [[C(@"foo") stringByDeletingLastPathComponent] isEqual: @""])
	    [C(@"dh0:tmp/foo/").stringByDeletingLastPathComponent
	    isEqual: @"dh0:tmp"] &&
	    [C(@"foo/bar").stringByDeletingLastPathComponent isEqual: @"foo"] &&
	    [C(@"foo").stringByDeletingLastPathComponent isEqual: @""])
# elif defined(OF_NINTENDO_3DS) || defined(OF_WII)
	TEST(@"-[stringByDeletingLastPathComponent]",
	    [[C(@"/tmp/") stringByDeletingLastPathComponent] isEqual: @""] &&
	    [[C(@"sdmc:/tmp/foo/") stringByDeletingLastPathComponent]
	    [C(@"/tmp/").stringByDeletingLastPathComponent isEqual: @""] &&
	    [C(@"sdmc:/tmp/foo/").stringByDeletingLastPathComponent
	    isEqual: @"sdmc:/tmp"] &&
	    [[C(@"sdmc:/") stringByDeletingLastPathComponent]
	    [C(@"sdmc:/").stringByDeletingLastPathComponent
	    isEqual: @"sdmc:/"] &&
	    [[C(@"foo/bar") stringByDeletingLastPathComponent]
	    [C(@"foo/bar").stringByDeletingLastPathComponent isEqual: @"foo"] &&
	    isEqual: @"foo"] &&
	    [[C(@"/") stringByDeletingLastPathComponent] isEqual: @""] &&
	    [[C(@"foo") stringByDeletingLastPathComponent] isEqual: @"."])
	    [C(@"/").stringByDeletingLastPathComponent isEqual: @""] &&
	    [C(@"foo").stringByDeletingLastPathComponent isEqual: @"."])
# else
	TEST(@"-[stringByDeletingLastPathComponent]",
	    [[C(@"/tmp") stringByDeletingLastPathComponent] isEqual: @"/"] &&
	    [[C(@"/tmp/") stringByDeletingLastPathComponent] isEqual: @"/"] &&
	    [[C(@"/tmp/foo/") stringByDeletingLastPathComponent]
	    [C(@"/tmp").stringByDeletingLastPathComponent isEqual: @"/"] &&
	    [C(@"/tmp/").stringByDeletingLastPathComponent isEqual: @"/"] &&
	    [C(@"/tmp/foo/").stringByDeletingLastPathComponent
	    isEqual: @"/tmp"] &&
	    [[C(@"foo/bar") stringByDeletingLastPathComponent]
	    [C(@"foo/bar").stringByDeletingLastPathComponent isEqual: @"foo"] &&
	    isEqual: @"foo"] &&
	    [[C(@"/") stringByDeletingLastPathComponent] isEqual: @"/"] &&
	    [[C(@"foo") stringByDeletingLastPathComponent] isEqual: @"."])
	    [C(@"/").stringByDeletingLastPathComponent isEqual: @"/"] &&
	    [C(@"foo").stringByDeletingLastPathComponent isEqual: @"."])
# endif

# if defined(OF_WINDOWS) || defined(OF_MSDOS)
	TEST(@"-[stringByDeletingPathExtension]",
	    [[C(@"foo.bar") stringByDeletingPathExtension] isEqual: @"foo"] &&
	    [[C(@"foo..bar") stringByDeletingPathExtension] isEqual: @"foo."] &&
	    [[C(@"c:/foo.\\bar") stringByDeletingPathExtension]
	    [C(@"foo.bar").stringByDeletingPathExtension isEqual: @"foo"] &&
	    [C(@"foo..bar").stringByDeletingPathExtension isEqual: @"foo."] &&
	    [C(@"c:/foo.\\bar").stringByDeletingPathExtension
	    isEqual: @"c:/foo.\\bar"] &&
	    [[C(@"c:\\foo./bar.baz") stringByDeletingPathExtension]
	    [C(@"c:\\foo./bar.baz").stringByDeletingPathExtension
	    isEqual: @"c:\\foo.\\bar"] &&
	    [[C(@"foo.bar/") stringByDeletingPathExtension] isEqual: @"foo"] &&
	    [[C(@".foo") stringByDeletingPathExtension] isEqual: @".foo"] &&
	    [[C(@".foo.bar") stringByDeletingPathExtension] isEqual: @".foo"])
	    [C(@"foo.bar/").stringByDeletingPathExtension isEqual: @"foo"] &&
	    [C(@".foo").stringByDeletingPathExtension isEqual: @".foo"] &&
	    [C(@".foo.bar").stringByDeletingPathExtension isEqual: @".foo"])
# elif defined(OF_AMIGAOS)
	TEST(@"-[stringByDeletingPathExtension]",
	    [[C(@"foo.bar") stringByDeletingPathExtension] isEqual: @"foo"] &&
	    [[C(@"foo..bar") stringByDeletingPathExtension] isEqual: @"foo."] &&
	    [[C(@"dh0:foo.bar") stringByDeletingPathExtension]
	    [C(@"foo.bar").stringByDeletingPathExtension isEqual: @"foo"] &&
	    [C(@"foo..bar").stringByDeletingPathExtension isEqual: @"foo."] &&
	    [C(@"dh0:foo.bar").stringByDeletingPathExtension
	    isEqual: @"dh0:foo"] &&
	    [[C(@"dh0:foo./bar") stringByDeletingPathExtension]
	    [C(@"dh0:foo./bar").stringByDeletingPathExtension
	    isEqual: @"dh0:foo./bar"] &&
	    [[C(@"dh0:foo./bar.baz") stringByDeletingPathExtension]
	    [C(@"dh0:foo./bar.baz").stringByDeletingPathExtension
	    isEqual: @"dh0:foo./bar"] &&
	    [[C(@"foo.bar/") stringByDeletingPathExtension] isEqual: @"foo"] &&
	    [[C(@".foo") stringByDeletingPathExtension] isEqual: @".foo"] &&
	    [[C(@".foo\\bar") stringByDeletingPathExtension]
	    [C(@"foo.bar/").stringByDeletingPathExtension isEqual: @"foo"] &&
	    [C(@".foo").stringByDeletingPathExtension isEqual: @".foo"] &&
	    [C(@".foo\\bar").stringByDeletingPathExtension
	    isEqual: @".foo\\bar"] &&
	    [[C(@".foo.bar") stringByDeletingPathExtension] isEqual: @".foo"])
	    [C(@".foo.bar").stringByDeletingPathExtension isEqual: @".foo"])
# elif defined(OF_NINTENDO_3DS) || defined(OF_WII)
	TEST(@"-[stringByDeletingPathExtension]",
	    [[C(@"foo.bar") stringByDeletingPathExtension] isEqual: @"foo"] &&
	    [[C(@"foo..bar") stringByDeletingPathExtension] isEqual: @"foo."] &&
	    [[C(@"sdmc:/foo./bar") stringByDeletingPathExtension]
	    [C(@"foo.bar").stringByDeletingPathExtension isEqual: @"foo"] &&
	    [C(@"foo..bar").stringByDeletingPathExtension isEqual: @"foo."] &&
	    [C(@"sdmc:/foo./bar").stringByDeletingPathExtension
	    isEqual: @"sdmc:/foo./bar"] &&
	    [[C(@"sdmc:/foo./bar.baz") stringByDeletingPathExtension]
	    [C(@"sdmc:/foo./bar.baz").stringByDeletingPathExtension
	    isEqual: @"sdmc:/foo./bar"] &&
	    [[C(@"foo.bar/") stringByDeletingPathExtension] isEqual: @"foo"] &&
	    [[C(@".foo") stringByDeletingPathExtension] isEqual: @".foo"] &&
	    [[C(@".foo.bar") stringByDeletingPathExtension] isEqual: @".foo"])
	    [C(@"foo.bar/").stringByDeletingPathExtension isEqual: @"foo"] &&
	    [C(@".foo").stringByDeletingPathExtension isEqual: @".foo"] &&
	    [C(@".foo.bar").stringByDeletingPathExtension isEqual: @".foo"])
# else
	TEST(@"-[stringByDeletingPathExtension]",
	    [[C(@"foo.bar") stringByDeletingPathExtension] isEqual: @"foo"] &&
	    [[C(@"foo..bar") stringByDeletingPathExtension] isEqual: @"foo."] &&
	    [[C(@"/foo./bar") stringByDeletingPathExtension]
	    [C(@"foo.bar").stringByDeletingPathExtension isEqual: @"foo"] &&
	    [C(@"foo..bar").stringByDeletingPathExtension isEqual: @"foo."] &&
	    [C(@"/foo./bar").stringByDeletingPathExtension
	    isEqual: @"/foo./bar"] &&
	    [[C(@"/foo./bar.baz") stringByDeletingPathExtension]
	    [C(@"/foo./bar.baz").stringByDeletingPathExtension
	    isEqual: @"/foo./bar"] &&
	    [[C(@"foo.bar/") stringByDeletingPathExtension] isEqual: @"foo"] &&
	    [[C(@".foo") stringByDeletingPathExtension] isEqual: @".foo"] &&
	    [[C(@".foo\\bar") stringByDeletingPathExtension]
	    [C(@"foo.bar/").stringByDeletingPathExtension isEqual: @"foo"] &&
	    [C(@".foo").stringByDeletingPathExtension isEqual: @".foo"] &&
	    [C(@".foo\\bar").stringByDeletingPathExtension
	    isEqual: @".foo\\bar"] &&
	    [[C(@".foo.bar") stringByDeletingPathExtension] isEqual: @".foo"])
	    [C(@".foo.bar").stringByDeletingPathExtension isEqual: @".foo"])
# endif

# ifdef OF_WINDOWS
	/* TODO: Add more tests */
	TEST(@"-[stringByStandardizingPath]",
	    [[C(@"\\\\foo\\..\\bar\\qux") stringByStandardizingPath]
	    [C(@"\\\\foo\\..\\bar\\qux").stringByStandardizingPath
	    isEqual: @"\\\\bar\\qux"])
# endif
#endif

	TEST(@"-[decimalValue]",
	    [C(@"1234") decimalValue] == 1234 &&
	    [C(@"\r\n+123  ") decimalValue] == 123 &&
	    [C(@"-500\t") decimalValue] == -500 &&
	    [C(@"\t\t\r\n") decimalValue] == 0)
	    C(@"1234").decimalValue == 1234 &&
	    C(@"\r\n+123  ").decimalValue == 123 &&
	    C(@"-500\t").decimalValue == -500 &&
	    C(@"\t\t\r\n").decimalValue == 0)

	TEST(@"-[hexadecimalValue]",
	    [C(@"123f") hexadecimalValue] == 0x123f &&
	    [C(@"\t\n0xABcd\r") hexadecimalValue] == 0xABCD &&
	    [C(@"  xbCDE") hexadecimalValue] == 0xBCDE &&
	    [C(@"$CdEf") hexadecimalValue] == 0xCDEF &&
	    [C(@"\rFeh ") hexadecimalValue] == 0xFE &&
	    [C(@"\r\t") hexadecimalValue] == 0)
	    C(@"123f").hexadecimalValue == 0x123f &&
	    C(@"\t\n0xABcd\r").hexadecimalValue == 0xABCD &&
	    C(@"  xbCDE").hexadecimalValue == 0xBCDE &&
	    C(@"$CdEf").hexadecimalValue == 0xCDEF &&
	    C(@"\rFeh ").hexadecimalValue == 0xFE &&
	    C(@"\r\t").hexadecimalValue == 0)

	TEST(@"-[octalValue]",
	    [C(@"1234567") octalValue] == 01234567 &&
	    [C(@"\r\n123") octalValue] == 0123 &&
	    C(@"1234567").octalValue == 01234567 &&
	    C(@"\r\n123").octalValue == 0123 &&
	    [C(@"765\t") octalValue] == 0765 &&
	    [C(@"\t\t\r\n") octalValue] == 0)
	    C(@"765\t").octalValue == 0765 && C(@"\t\t\r\n").octalValue == 0)

	/*
	 * These test numbers can be generated without rounding if we have IEEE
	 * floating point numbers, thus we can use == on them.
	 */
	TEST(@"-[floatValue]",
	    [C(@"\t-0.25 ") floatValue] == -0.25 &&
	    [C(@"\r\n\tINF\t\n") floatValue] == INFINITY &&
	    [C(@"\r -INFINITY\n") floatValue] == -INFINITY &&
	    isnan([C(@"   NAN\t\t") floatValue]))
	    C(@"\t-0.25 ").floatValue == -0.25 &&
	    C(@"\r\n\tINF\t\n").floatValue == INFINITY &&
	    C(@"\r -INFINITY\n").floatValue == -INFINITY &&
	    isnan(C(@"   NAN\t\t").floatValue))

#if !defined(OF_ANDROID) && !defined(OF_SOLARIS) && !defined(OF_DJGPP) && \
    !defined(OF_AMIGAOS_M68K)
# define INPUT @"\t-0x1.FFFFFFFFFFFFFP-1020 "
# define EXPECTED -0x1.FFFFFFFFFFFFFP-1020
#else
/* Android, Solaris, DJGPP and AmigaOS3 do not accept 0x for strtod() */
# if (!defined(OF_SOLARIS) || !defined(OF_X86)) && !defined(OF_AMIGAOS_M68K)
#  define INPUT @"\t-0.123456789 "
#  define EXPECTED -0.123456789
# else
/*
 * Solaris' strtod() has weird rounding on x86, but not on x86_64/
 * AmigaOS 3 with libnix has weird rounding as well.
 */
#  define INPUT @"\t-0.125 "
#  define EXPECTED -0.125
# endif
#endif
	TEST(@"-[doubleValue]",
	    [INPUT doubleValue] == EXPECTED &&
	    [C(@"\r\n\tINF\t\n") doubleValue] == INFINITY &&
	    [C(@"\r -INFINITY\n") doubleValue] == -INFINITY &&
	    isnan([C(@"   NAN\t\t") doubleValue]))
	    INPUT.doubleValue == EXPECTED &&
	    C(@"\r\n\tINF\t\n").doubleValue == INFINITY &&
	    C(@"\r -INFINITY\n").doubleValue == -INFINITY &&
	    isnan(C(@"   NAN\t\t").doubleValue))
#undef INPUT
#undef EXPECTED

	EXPECT_EXCEPTION(@"Detect invalid characters in -[decimalValue] #1",
	    OFInvalidFormatException, [C(@"abc") decimalValue])
	EXPECT_EXCEPTION(@"Detect invalid characters in -[decimalValue] #2",
	    OFInvalidFormatException, [C(@"0a") decimalValue])
1135
1136
1137
1138
1139
1140
1141
1142

1143
1144
1145
1146
1147
1148
1149
1150

1151
1152
1153
1154
1155
1156

1157
1158

1159
1160
1161
1162
1163
1164
1165

1166
1167
1168

1169
1170
1171

1172
1173
1174

1175
1176
1177
1178

1179
1180
1181
1182

1183
1184
1185
1186

1187
1188
1189
1190
1191
1192
1193
1194
1195
1196

1197
1198
1199
1200
1201
1202
1203
1128
1129
1130
1131
1132
1133
1134

1135
1136
1137
1138
1139
1140
1141
1142

1143
1144
1145
1146
1147
1148

1149
1150

1151
1152
1153
1154
1155
1156
1157

1158
1159
1160

1161
1162
1163

1164
1165
1166

1167
1168
1169
1170

1171
1172
1173
1174

1175
1176
1177
1178

1179
1180
1181
1182
1183
1184
1185
1186
1187
1188

1189
1190
1191
1192
1193
1194
1195
1196







-
+







-
+





-
+

-
+






-
+


-
+


-
+


-
+



-
+



-
+



-
+









-
+








	EXPECT_EXCEPTION(@"Detect out of range in -[hexadecimalValue]",
	    OFOutOfRangeException,
	    [C(@"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"
	       @"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF")
	    hexadecimalValue])

	TEST(@"-[characters]", (ua = [C(@"fööbär🀺") characters]) &&
	TEST(@"-[characters]", (ua = C(@"fööbär🀺").characters) &&
	    !memcmp(ua, ucstr + 1, sizeof(ucstr) - 8))

#ifdef OF_BIG_ENDIAN
# define SWAPPED_BYTE_ORDER OF_BYTE_ORDER_LITTLE_ENDIAN
#else
# define SWAPPED_BYTE_ORDER OF_BYTE_ORDER_BIG_ENDIAN
#endif
	TEST(@"-[UTF16String]", (u16a = [C(@"fööbär🀺") UTF16String]) &&
	TEST(@"-[UTF16String]", (u16a = C(@"fööbär🀺").UTF16String) &&
	    !memcmp(u16a, utf16str + 1, of_string_utf16_length(utf16str) * 2) &&
	    (u16a = [C(@"fööbär🀺")
	    UTF16StringWithByteOrder: SWAPPED_BYTE_ORDER]) &&
	    !memcmp(u16a, sutf16str + 1, of_string_utf16_length(sutf16str) * 2))

	TEST(@"-[UTF16StringLength]", [C(@"fööbär🀺") UTF16StringLength] == 8)
	TEST(@"-[UTF16StringLength]", C(@"fööbär🀺").UTF16StringLength == 8)

	TEST(@"-[UTF32String]", (ua = [C(@"fööbär🀺") UTF32String]) &&
	TEST(@"-[UTF32String]", (ua = C(@"fööbär🀺").UTF32String) &&
	    !memcmp(ua, ucstr + 1, of_string_utf32_length(ucstr) * 4) &&
	    (ua = [C(@"fööbär🀺") UTF32StringWithByteOrder:
	    SWAPPED_BYTE_ORDER]) &&
	    !memcmp(ua, sucstr + 1, of_string_utf32_length(sucstr) * 4))
#undef SWAPPED_BYTE_ORDER

	TEST(@"-[MD5Hash]", [[C(@"asdfoobar") MD5Hash]
	TEST(@"-[MD5Hash]", [C(@"asdfoobar").MD5Hash
	    isEqual: @"184dce2ec49b5422c7cfd8728864db4c"])

	TEST(@"-[RIPEMD160Hash]", [[C(@"asdfoobar") RIPEMD160Hash]
	TEST(@"-[RIPEMD160Hash]", [C(@"asdfoobar").RIPEMD160Hash
	    isEqual: @"021d773b0fac06eb6755ca6aa58a580c980f7f13"])

	TEST(@"-[SHA1Hash]", [[C(@"asdfoobar") SHA1Hash]
	TEST(@"-[SHA1Hash]", [C(@"asdfoobar").SHA1Hash
	    isEqual: @"f5f81ac0a8b5cbfdc4585ec1ad32e7b3a12b9b49"])

	TEST(@"-[SHA224Hash]", [[C(@"asdfoobar") SHA224Hash]
	TEST(@"-[SHA224Hash]", [C(@"asdfoobar").SHA224Hash
	    isEqual:
	    @"5a06822dcbd5a874f67d062b80b9d8a9cb9b5b303960b9da9290c192"])

	TEST(@"-[SHA256Hash]", [[C(@"asdfoobar") SHA256Hash] isEqual:
	TEST(@"-[SHA256Hash]", [C(@"asdfoobar").SHA256Hash isEqual:
	    @"28e65b1dcd7f6ce2ea6277b15f87b913"
	    @"628b5500bf7913a2bbf4cedcfa1215f6"])

	TEST(@"-[SHA384Hash]", [[C(@"asdfoobar") SHA384Hash] isEqual:
	TEST(@"-[SHA384Hash]", [C(@"asdfoobar").SHA384Hash isEqual:
	    @"73286da882ffddca2f45e005cfa6b44f3fc65bfb26db1d08"
	    @"7ded2f9c279e5addf8be854044bca0cece073fce28eec7d9"])

	TEST(@"-[SHA512Hash]", [[C(@"asdfoobar") SHA512Hash] isEqual:
	TEST(@"-[SHA512Hash]", [C(@"asdfoobar").SHA512Hash isEqual:
	    @"0464c427da158b02161bb44a3090bbfc594611ef6a53603640454b56412a9247c"
	    @"3579a329e53a5dc74676b106755e3394f9454a2d42273242615d32f80437d61"])

	cs = [OFCharacterSet characterSetWithCharactersInString: @"abfo'_~$🍏"];
	TEST(@"-[stringByURLEncodingWithAllowedCharacters:]",
	    [[C(@"foo\"ba'_~$]🍏🍌") stringByURLEncodingWithAllowedCharacters:
	    cs] isEqual: @"foo%22ba'_~$%5D🍏%F0%9F%8D%8C"])

	TEST(@"-[stringByURLDecoding]",
	    [[C(@"foo%20bar%22+%24%F0%9F%8D%8C") stringByURLDecoding]
	    [C(@"foo%20bar%22+%24%F0%9F%8D%8C").stringByURLDecoding
	    isEqual: @"foo bar\"+$🍌"])

	TEST(@"-[insertString:atIndex:]",
	    (s[0] = [mutableStringClass stringWithString: @"𝄞öööbä€"]) &&
	    R([s[0] insertString: @"äöü"
			 atIndex: 3]) &&
	    [s[0] isEqual: @"𝄞ööäöüöbä€"])
1304
1305
1306
1307
1308
1309
1310
1311

1312
1313
1314
1315

1316
1317
1318
1319
1320

1321
1322
1323
1324
1325
1326
1327
1328





1329
1330
1331
1332
1333
1334
1335
1297
1298
1299
1300
1301
1302
1303

1304
1305
1306
1307

1308
1309
1310
1311
1312

1313
1314
1315
1316





1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328







-
+



-
+




-
+



-
-
-
-
-
+
+
+
+
+







	    (s[0] = [mutableStringClass stringWithString: whitespace[0]]) &&
	    R([s[0] deleteEnclosingWhitespaces]) && [s[0] isEqual: @"asd"] &&
	    (s[0] = [mutableStringClass stringWithString: whitespace[1]]) &&
	    R([s[0] deleteEnclosingWhitespaces]) && [s[0] isEqual: @""])

#ifdef OF_HAVE_UNICODE_TABLES
	TEST(@"-[decomposedStringWithCanonicalMapping]",
	    [[@"H\xC3\xA4llj\xC3\xB6" decomposedStringWithCanonicalMapping]
	    [C(@"H\xC3\xA4llj\xC3\xB6").decomposedStringWithCanonicalMapping
	    isEqual: @"H\x61\xCC\x88llj\x6F\xCC\x88"]);

	TEST(@"-[decomposedStringWithCompatibilityMapping]",
	    [[@"H\xC3\xA4llj\xC3\xB6" decomposedStringWithCompatibilityMapping]
	    [C(@"H\xC3\xA4llj\xC3\xB6").decomposedStringWithCompatibilityMapping
	    isEqual: @"H\x61\xCC\x88llj\x6F\xCC\x88"]);
#endif

	TEST(@"-[stringByXMLEscaping]",
	    (is = [C(@"<hello> &world'\"!&") stringByXMLEscaping]) &&
	    (is = C(@"<hello> &world'\"!&").stringByXMLEscaping) &&
	    [is isEqual: @"&lt;hello&gt; &amp;world&apos;&quot;!&amp;"])

	TEST(@"-[stringByXMLUnescaping]",
	    [[is stringByXMLUnescaping] isEqual: @"<hello> &world'\"!&"] &&
	    [[C(@"&#x79;") stringByXMLUnescaping] isEqual: @"y"] &&
	    [[C(@"&#xe4;") stringByXMLUnescaping] isEqual: @"ä"] &&
	    [[C(@"&#8364;") stringByXMLUnescaping] isEqual: @"€"] &&
	    [[C(@"&#x1D11E;") stringByXMLUnescaping] isEqual: @"𝄞"])
	    [is.stringByXMLUnescaping isEqual: @"<hello> &world'\"!&"] &&
	    [C(@"&#x79;").stringByXMLUnescaping isEqual: @"y"] &&
	    [C(@"&#xe4;").stringByXMLUnescaping isEqual: @"ä"] &&
	    [C(@"&#8364;").stringByXMLUnescaping isEqual: @"€"] &&
	    [C(@"&#x1D11E;").stringByXMLUnescaping isEqual: @"𝄞"])

	EXPECT_EXCEPTION(@"Detect unknown entities in -[stringByXMLUnescaping]",
	    OFUnknownXMLEntityException, [C(@"&foo;") stringByXMLUnescaping])
	EXPECT_EXCEPTION(@"Detect invalid entities in -[stringByXMLUnescaping] "
	    @"#1", OFInvalidFormatException,
	    [C(@"x&amp") stringByXMLUnescaping])
	EXPECT_EXCEPTION(@"Detect invalid entities in -[stringByXMLUnescaping] "

Modified tests/OFTCPSocketTests.m from [b4140431ce] to [1c451b0231].

43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59
60
61
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58
59
60
61







-
+











	TEST(@"-[connectToHost:port:]",
	    R([client connectToHost: @"127.0.0.1"
			       port: port]))

	TEST(@"-[accept]", (accepted = [server accept]))

	TEST(@"-[remoteAddress]",
	    [of_socket_address_ip_string([accepted remoteAddress], NULL)
	    [of_socket_address_ip_string(accepted.remoteAddress, NULL)
	    isEqual: @"127.0.0.1"])

	TEST(@"-[writeString:]", [client writeString: @"Hello!"])

	TEST(@"-[readIntoBuffer:length:]", [accepted readIntoBuffer: buf
							     length: 6] &&
	    !memcmp(buf, "Hello!", 6))

	[pool drain];
}
@end

Modified tests/OFURLTests.m from [623af6a22a] to [aa94b414c4].

98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126




127
128
129

130
131

132
133
134
135



136
137

138
139
140

141
142

143
144
145
146
147
148
149
150
151
152
153
154

155
156

157
158
159
160
161
162
163

164
165
166
167
168
169
170
171
172

173
174
175
176

177
178
179
180

181
182
183
184

185
186
187
188

189
190
191

192
193
194
195

196
197
198
199

200
201
202

203
204
205
206


207
208
209
210


211
212
213
214

215
216
217
218

219
220
221
222

223
224
225

226
227
228
229


230
231
232
233


234
235
236
237

238
239
240
241


242
243
244
245


246
247
248
249

250
251
252
253
254
255
256
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122




123
124
125
126
127
128

129
130

131
132



133
134
135
136

137

138

139
140

141
142
143
144
145
146
147
148
149
150
151
152

153
154

155
156
157
158
159
160
161

162
163
164
165
166
167
168
169


170
171
172


173
174
175
176

177
178
179


180
181
182


183
184
185

186
187
188


189
190
191


192
193
194

195
196
197


198
199
200
201


202
203
204
205
206

207
208
209


210
211
212


213
214
215

216
217
218


219
220
221
222


223
224
225
226
227

228
229
230


231
232
233
234


235
236
237
238
239

240
241
242
243
244
245
246
247







-
+

















-
-
-
-
+
+
+
+


-
+

-
+

-
-
-
+
+
+

-
+
-

-
+

-
+











-
+

-
+






-
+







-
-
+


-
-
+



-
+


-
-
+


-
-
+


-
+


-
-
+


-
-
+


-
+


-
-
+
+


-
-
+
+



-
+


-
-
+


-
-
+


-
+


-
-
+
+


-
-
+
+



-
+


-
-
+
+


-
-
+
+



-
+







	    OFInvalidFormatException,
	    [OFURL URLWithString: @"#`"
		   relativeToURL: u1])

#ifdef OF_HAVE_FILES
	TEST(@"+[fileURLWithPath:]",
	    [[[OFURL fileURLWithPath: @"testfile.txt"] fileSystemRepresentation]
	    isEqual: [[[OFFileManager defaultManager] currentDirectoryPath]
	    isEqual: [[OFFileManager defaultManager].currentDirectoryPath
	    stringByAppendingPathComponent: @"testfile.txt"]])

# ifdef OF_WINDOWS
	OFURL *tmp;
	TEST(@"+[fileURLWithPath:] with UNC",
	    (tmp = [OFURL fileURLWithPath: @"\\\\foo\\bar"]) &&
	    [tmp.host isEqual: @"foo"] && [tmp.path isEqual: @"/bar"] &&
	    [tmp.string isEqual: @"file://foo/bar"] &&
	    [tmp.fileSystemRepresentation isEqual: @"\\\\foo\\bar"] &&
	    (tmp = [OFURL fileURLWithPath: @"\\\\test"]) &&
	    [tmp.host isEqual: @"test"] && [tmp.path isEqual: @"/"] &&
	    [tmp.string isEqual: @"file://test/"] &&
	    [tmp.fileSystemRepresentation isEqual: @"\\\\test"])
# endif
#endif

	TEST(@"-[string]",
	    [[u1 string] isEqual: url_str] &&
	    [[u2 string] isEqual: @"http://foo:80"] &&
	    [[u3 string] isEqual: @"http://bar/"] &&
	    [[u4 string] isEqual: @"file:///etc/passwd"])
	    [u1.string isEqual: url_str] &&
	    [u2.string isEqual: @"http://foo:80"] &&
	    [u3.string isEqual: @"http://bar/"] &&
	    [u4.string isEqual: @"file:///etc/passwd"])

	TEST(@"-[scheme]",
	    [[u1 scheme] isEqual: @"ht:tp"] && [[u4 scheme] isEqual: @"file"])
	    [u1.scheme isEqual: @"ht:tp"] && [u4.scheme isEqual: @"file"])

	TEST(@"-[user]", [[u1 user] isEqual: @"us:er"] && [u4 user] == nil)
	TEST(@"-[user]", [u1.user isEqual: @"us:er"] && u4.user == nil)
	TEST(@"-[password]",
	    [[u1 password] isEqual: @"p@w"] && [u4 password] == nil)
	TEST(@"-[host]", [[u1 host] isEqual: @"ho:st"] && [u4 port] == 0)
	TEST(@"-[port]", [[u1 port] isEqual: [OFNumber numberWithUInt16: 1234]])
	    [u1.password isEqual: @"p@w"] && u4.password == nil)
	TEST(@"-[host]", [u1.host isEqual: @"ho:st"] && [u4 port] == nil)
	TEST(@"-[port]", [u1.port isEqual: [OFNumber numberWithUInt16: 1234]])
	TEST(@"-[path]",
	    [[u1 path] isEqual: @"/pa?th"] &&
	    [u1.path isEqual: @"/pa?th"] && [u4.path isEqual: @"/etc/passwd"])
	    [[u4 path] isEqual: @"/etc/passwd"])
	TEST(@"-[pathComponents]",
	    [[u1 pathComponents] isEqual:
	    [u1.pathComponents isEqual:
	    [OFArray arrayWithObjects: @"", @"pa?th", nil]] &&
	    [[u4 pathComponents] isEqual:
	    [u4.pathComponents isEqual:
	    [OFArray arrayWithObjects: @"", @"etc", @"passwd", nil]])
	TEST(@"-[lastPathComponent]",
	    [[[OFURL URLWithString: @"http://host/foo//bar/baz"]
	    lastPathComponent] isEqual: @"baz"] &&
	    [[[OFURL URLWithString: @"http://host/foo//bar/baz/"]
	    lastPathComponent] isEqual: @"baz"] &&
	    [[[OFURL URLWithString: @"http://host/foo/"]
	    lastPathComponent] isEqual: @"foo"] &&
	    [[[OFURL URLWithString: @"http://host/"]
	    lastPathComponent] isEqual: @""])
	TEST(@"-[query]",
	    [[u1 query] isEqual: @"que#ry"] && [u4 query] == nil)
	    [u1.query isEqual: @"que#ry"] && u4.query == nil)
	TEST(@"-[fragment]",
	    [[u1 fragment] isEqual: @"frag#ment"] && [u4 fragment] == nil)
	    [u1.fragment isEqual: @"frag#ment"] && u4.fragment == nil)

	TEST(@"-[copy]", R(u4 = [[u1 copy] autorelease]))

	TEST(@"-[isEqual:]", [u1 isEqual: u4] && ![u2 isEqual: u3] &&
	    [[OFURL URLWithString: @"HTTP://bar/"] isEqual: u3])

	TEST(@"-[hash:]", [u1 hash] == [u4 hash] && [u2 hash] != [u3 hash])
	TEST(@"-[hash:]", u1.hash == u4.hash && u2.hash != u3.hash)

	EXPECT_EXCEPTION(@"Detection of invalid format",
	    OFInvalidFormatException, [OFURL URLWithString: @"http"])

	mu = [OFMutableURL URL];

	TEST(@"-[setScheme:]",
	    R([mu setScheme: @"ht:tp"]) &&
	    [[mu URLEncodedScheme] isEqual: @"ht%3Atp"])
	    (mu.scheme = @"ht:tp") && [mu.URLEncodedScheme isEqual: @"ht%3Atp"])

	TEST(@"-[setURLEncodedScheme:]",
	    R([mu setURLEncodedScheme: @"ht%3Atp"]) &&
	    [[mu scheme] isEqual: @"ht:tp"])
	    (mu.URLEncodedScheme = @"ht%3Atp") && [mu.scheme isEqual: @"ht:tp"])

	EXPECT_EXCEPTION(
	    @"-[setURLEncodedScheme:] with invalid characters fails",
	    OFInvalidFormatException, [mu setURLEncodedScheme: @"~"])
	    OFInvalidFormatException, mu.URLEncodedScheme = @"~")

	TEST(@"-[setHost:]",
	    R([mu setHost: @"ho:st"]) &&
	    [[mu URLEncodedHost] isEqual: @"ho%3Ast"])
	    (mu.host = @"ho:st") && [mu.URLEncodedHost isEqual: @"ho%3Ast"])

	TEST(@"-[setURLEncodedHost:]",
	    R([mu setURLEncodedHost: @"ho%3Ast"]) &&
	    [[mu host] isEqual: @"ho:st"])
	    (mu.URLEncodedHost = @"ho%3Ast") && [mu.host isEqual: @"ho:st"])

	EXPECT_EXCEPTION(@"-[setURLEncodedHost:] with invalid characters fails",
	    OFInvalidFormatException, [mu setURLEncodedHost: @"/"])
	    OFInvalidFormatException, mu.URLEncodedHost = @"/")

	TEST(@"-[setUser:]",
	    R([mu setUser: @"us:er"]) &&
	    [[mu URLEncodedUser] isEqual: @"us%3Aer"])
	    (mu.user = @"us:er") && [mu.URLEncodedUser isEqual: @"us%3Aer"])

	TEST(@"-[setURLEncodedUser:]",
	    R([mu setURLEncodedUser: @"us%3Aer"]) &&
	    [[mu user] isEqual: @"us:er"])
	    (mu.URLEncodedUser = @"us%3Aer") && [mu.user isEqual: @"us:er"])

	EXPECT_EXCEPTION(@"-[setURLEncodedUser:] with invalid characters fails",
	    OFInvalidFormatException, [mu setURLEncodedHost: @"/"])
	    OFInvalidFormatException, mu.URLEncodedHost = @"/")

	TEST(@"-[setPassword:]",
	    R([mu setPassword: @"pass:word"]) &&
	    [[mu URLEncodedPassword] isEqual: @"pass%3Aword"])
	    (mu.password = @"pass:word") &&
	    [mu.URLEncodedPassword isEqual: @"pass%3Aword"])

	TEST(@"-[setURLEncodedPassword:]",
	    R([mu setURLEncodedPassword: @"pass%3Aword"]) &&
	    [[mu password] isEqual: @"pass:word"])
	    (mu.URLEncodedPassword = @"pass%3Aword") &&
	    [mu.password isEqual: @"pass:word"])

	EXPECT_EXCEPTION(
	    @"-[setURLEncodedPassword:] with invalid characters fails",
	    OFInvalidFormatException, [mu setURLEncodedPassword: @"/"])
	    OFInvalidFormatException, mu.URLEncodedPassword = @"/")

	TEST(@"-[setPath:]",
	    R([mu setPath: @"pa/th@?"]) &&
	    [[mu URLEncodedPath] isEqual: @"pa/th@%3F"])
	    (mu.path = @"pa/th@?") && [mu.URLEncodedPath isEqual: @"pa/th@%3F"])

	TEST(@"-[setURLEncodedPath:]",
	    R([mu setURLEncodedPath: @"pa/th@%3F"]) &&
	    [[mu path] isEqual: @"pa/th@?"])
	    (mu.URLEncodedPath = @"pa/th@%3F") && [mu.path isEqual: @"pa/th@?"])

	EXPECT_EXCEPTION(@"-[setURLEncodedPath:] with invalid characters fails",
	    OFInvalidFormatException, [mu setURLEncodedPath: @"?"])
	    OFInvalidFormatException, mu.URLEncodedPath = @"?")

	TEST(@"-[setQuery:]",
	    R([mu setQuery: @"que/ry?#"]) &&
	    [[mu URLEncodedQuery] isEqual: @"que/ry?%23"])
	    (mu.query = @"que/ry?#") &&
	    [mu.URLEncodedQuery isEqual: @"que/ry?%23"])

	TEST(@"-[setURLEncodedQuery:]",
	    R([mu setURLEncodedQuery: @"que/ry?%23"]) &&
	    [[mu query] isEqual: @"que/ry?#"])
	    (mu.URLEncodedQuery = @"que/ry?%23") &&
	    [mu.query isEqual: @"que/ry?#"])

	EXPECT_EXCEPTION(
	    @"-[setURLEncodedQuery:] with invalid characters fails",
	    OFInvalidFormatException, [mu setURLEncodedQuery: @"`"])
	    OFInvalidFormatException, mu.URLEncodedQuery = @"`")

	TEST(@"-[setFragment:]",
	    R([mu setFragment: @"frag/ment?#"]) &&
	    [[mu URLEncodedFragment] isEqual: @"frag/ment?%23"])
	    (mu.fragment = @"frag/ment?#") &&
	    [mu.URLEncodedFragment isEqual: @"frag/ment?%23"])

	TEST(@"-[setURLEncodedFragment:]",
	    R([mu setURLEncodedFragment: @"frag/ment?%23"]) &&
	    [[mu fragment] isEqual: @"frag/ment?#"])
	    (mu.URLEncodedFragment = @"frag/ment?%23") &&
	    [mu.fragment isEqual: @"frag/ment?#"])

	EXPECT_EXCEPTION(
	    @"-[setURLEncodedFragment:] with invalid characters fails",
	    OFInvalidFormatException, [mu setURLEncodedFragment: @"`"])
	    OFInvalidFormatException, mu.URLEncodedFragment = @"`")

	TEST(@"-[URLByAppendingPathComponent:isDirectory:]",
	    [[[OFURL URLWithString: @"file:///foo/bar"]
	    URLByAppendingPathComponent: @"qux"
			    isDirectory: false] isEqual:
	    [OFURL URLWithString: @"file:///foo/bar/qux"]] &&
	    [[[OFURL URLWithString: @"file:///foo/bar/"]

Modified tests/OFValueTests.m from [7cd1c82cb9] to [46b74c3a5c].

34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78
79
80
81
82
83

84
85
86

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

104
105
106

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124
125
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

144
145
146

147
148
149
150
151
152
153
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78
79
80
81
82

83
84
85

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102

103
104
105

106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

123
124
125

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

143
144
145

146
147
148
149
150
151
152
153







-
+















-
+












-
+












-
+


-
+
















-
+


-
+
















-
+


-
+
















-
+


-
+







	OFValue *value;
	void *pointer = &value;

	TEST(@"+[valueWithBytes:objCType:]",
	    (value = [OFValue valueWithBytes: &range
				    objCType: @encode(of_range_t)]))

	TEST(@"-[objCType]", strcmp([value objCType], @encode(of_range_t)) == 0)
	TEST(@"-[objCType]", strcmp(value.objCType, @encode(of_range_t)) == 0)

	TEST(@"-[getValue:size:]",
	    R([value getValue: &range2
			 size: sizeof(of_range_t)]) &&
	    of_range_equal(range2, range))

	EXPECT_EXCEPTION(@"-[getValue:size:] with wrong size throws",
	    OFOutOfRangeException,
	    [value getValue: &range
		       size: sizeof(of_range_t) - 1])

	TEST(@"+[valueWithPointer:]",
	    (value = [OFValue valueWithPointer: pointer]))

	TEST(@"-[pointerValue]",
	    [value pointerValue] == pointer &&
	    value.pointerValue == pointer &&
	    [[OFValue valueWithBytes: &pointer
			    objCType: @encode(void *)] pointerValue] == pointer)

	EXPECT_EXCEPTION(@"-[pointerValue] with wrong size throws",
	    OFOutOfRangeException,
	    [[OFValue valueWithBytes: "a"
			    objCType: @encode(char)] pointerValue])

	TEST(@"+[valueWithNonretainedObject:]",
	    (value = [OFValue valueWithNonretainedObject: pointer]))

	TEST(@"-[nonretainedObjectValue]",
	    [value nonretainedObjectValue] == pointer &&
	    value.nonretainedObjectValue == pointer &&
	    [[OFValue valueWithBytes: &pointer
			    objCType: @encode(id)] pointerValue] == pointer)

	EXPECT_EXCEPTION(@"-[nonretainedObjectValue] with wrong size throws",
	    OFOutOfRangeException,
	    [[OFValue valueWithBytes: "a"
			    objCType: @encode(char)] nonretainedObjectValue])

	TEST(@"+[valueWithRange:]",
	    (value = [OFValue valueWithRange: range]))

	TEST(@"-[rangeValue]",
	    of_range_equal([value rangeValue], range) &&
	    of_range_equal(value.rangeValue, range) &&
	    (value = [OFValue valueWithBytes: &range
				    objCType: @encode(of_range_t)]) &&
	    of_range_equal([value rangeValue], range))
	    of_range_equal(value.rangeValue, range))

	TEST(@"-[getValue:size:] for OFValue_range",
	    (value = [OFValue valueWithRange: range]) &&
	    R([value getValue: &range2
			 size: sizeof(range2)]) &&
	    of_range_equal(range2, range))

	EXPECT_EXCEPTION(@"-[rangeValue] with wrong size throws",
	    OFOutOfRangeException,
	    [[OFValue valueWithBytes: "a"
			    objCType: @encode(char)] rangeValue])

	TEST(@"+[valueWithPoint:]",
	    (value = [OFValue valueWithPoint: point]))

	TEST(@"-[pointValue]",
	    of_point_equal([value pointValue], point) &&
	    of_point_equal(value.pointValue, point) &&
	    (value = [OFValue valueWithBytes: &point
				    objCType: @encode(of_point_t)]) &&
	    of_point_equal([value pointValue], point))
	    of_point_equal(value.pointValue, point))

	TEST(@"-[getValue:size:] for OFValue_point",
	    (value = [OFValue valueWithPoint: point]) &&
	    R([value getValue: &point2
			 size: sizeof(point2)]) &&
	    of_point_equal(point2, point))

	EXPECT_EXCEPTION(@"-[pointValue] with wrong size throws",
	    OFOutOfRangeException,
	    [[OFValue valueWithBytes: "a"
			    objCType: @encode(char)] pointValue])

	TEST(@"+[valueWithDimension:]",
	    (value = [OFValue valueWithDimension: dimension]))

	TEST(@"-[dimensionValue]",
	    of_dimension_equal([value dimensionValue], dimension) &&
	    of_dimension_equal(value.dimensionValue, dimension) &&
	    (value = [OFValue valueWithBytes: &dimension
				    objCType: @encode(of_dimension_t)]) &&
	    of_dimension_equal([value dimensionValue], dimension))
	    of_dimension_equal(value.dimensionValue, dimension))

	TEST(@"-[getValue:size:] for OFValue_dimension",
	    (value = [OFValue valueWithDimension: dimension]) &&
	    R([value getValue: &dimension2
			 size: sizeof(dimension2)]) &&
	    of_dimension_equal(dimension2, dimension))

	EXPECT_EXCEPTION(@"-[dimensionValue] with wrong size throws",
	    OFOutOfRangeException,
	    [[OFValue valueWithBytes: "a"
			    objCType: @encode(char)] dimensionValue])

	TEST(@"+[valueWithRectangle:]",
	    (value = [OFValue valueWithRectangle: rectangle]))

	TEST(@"-[rectangleValue]",
	    of_rectangle_equal([value rectangleValue], rectangle) &&
	    of_rectangle_equal(value.rectangleValue, rectangle) &&
	    (value = [OFValue valueWithBytes: &rectangle
				    objCType: @encode(of_rectangle_t)]) &&
	    of_rectangle_equal([value rectangleValue], rectangle))
	    of_rectangle_equal(value.rectangleValue, rectangle))

	TEST(@"-[getValue:size:] for OFValue_rectangle",
	    (value = [OFValue valueWithRectangle: rectangle]) &&
	    R([value getValue: &rectangle2
			 size: sizeof(rectangle2)]) &&
	    of_rectangle_equal(rectangle2, rectangle))

Modified tests/OFXMLElementBuilderTests.m from [e1fe9d51cc] to [959dacaa15].

43
44
45
46
47
48
49
50
51


52
53
54
55

56
57

58
59
60
61
62
63
64
43
44
45
46
47
48
49


50
51
52
53
54

55
56

57
58
59
60
61
62
63
64







-
-
+
+



-
+

-
+







	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFXMLParser *p = [OFXMLParser parser];
	OFXMLElementBuilder *builder = [OFXMLElementBuilder elementBuilder];
	OFString *str = @"<foo>bar<![CDATA[f<oo]]>baz<qux/>"
	    " <qux xmlns:qux='urn:qux'><?asd?><qux:bar/><x qux:y='z'/></qux>"
	    "</foo>";

	[p setDelegate: builder];
	[builder setDelegate: self];
	p.delegate = builder;
	builder.delegate = self;

	TEST(@"Building elements from parsed XML",
	    R([p parseString: str]) &&
	    nodes[0] != nil && [[nodes[0] XMLString] isEqual: str] &&
	    nodes[0] != nil && [nodes[0].XMLString isEqual: str] &&
	    R([p parseString: @"<!--foo-->"]) &&
	    nodes[1] != nil && [[nodes[1] XMLString] isEqual: @"<!--foo-->"] &&
	    nodes[1] != nil && [nodes[1].XMLString isEqual: @"<!--foo-->"] &&
	    i == 2)

	[nodes[0] release];
	[nodes[1] release];
	[pool drain];
}
@end

Modified tests/OFXMLNodeTests.m from [28200bf0d7] to [dfc573ade9].

120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134







-
+







	    @"<?xml version='1.0' encoding='UTF-8'?>\r\n<x>foo<![CDATA[bar]]>"
	    @"<y>b<!-- fooo -->az</y>qux</x>"] stringValue]
	    isEqual: @"foobarbazqux"])

	TEST(@"-[elementsForName:namespace:]",
	    (a = [nodes[2] elementsForName: @"bar"
				 namespace: @"urn:objfw:test"]) &&
	    [a count] == 1 && [[[a firstObject] XMLString] isEqual:
	    a.count == 1 && [[[a firstObject] XMLString] isEqual:
	    @"<bar xmlns='urn:objfw:test'/>"])

	TEST(@"-[isEqual:]",
	    [[OFXMLElement elementWithXMLString: @"<foo bar='asd'/>"] isEqual:
	    [OFXMLElement elementWithXMLString: @"<foo bar='asd'></foo>"]] &&
	    [[OFXMLElement elementWithXMLString: @"<x><y/></x>"] isEqual:
	    [OFXMLElement elementWithXMLString: @"<x><y></y></x>"]])

Modified tests/OFXMLParserTests.m from [cd6a5cb346] to [3b6a87e478].

55
56
57
58
59
60
61
62

63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151

152
153
154
155
156
157
158
55
56
57
58
59
60
61

62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

85
86
87
88
89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150

151
152
153
154
155
156
157
158







-
+






-
+















-
+












-
+














-
+
















-
+




















-
+







		break;
	case 2:
		TEST(msg, type == PROCESSING_INSTRUCTIONS &&
		    [string isEqual: @"p?i"])
		break;
	case 3:
		TEST(msg, type == TAG_START && [name isEqual: @"root"] &&
		    prefix == nil && ns == nil && [attrs count] == 0)
		    prefix == nil && ns == nil && attrs.count == 0)
		break;
	case 4:
		TEST(msg, type == STRING && [string isEqual: @"\n\n "])
		break;
	case 5:
		TEST(msg, type == CDATA && [string isEqual: @"f<]]]oo]"] &&
		    [parser lineNumber] == 3)
		    parser.lineNumber == 3)
		break;
	case 6:
		TEST(msg, type == TAG_START && [name isEqual: @"bar"] &&
		    prefix == nil && ns == nil && attrs == nil)
		break;
	case 7:
		TEST(msg, type == TAG_END && [name isEqual: @"bar"] &&
		    prefix == nil && ns == nil && attrs == nil)
		break;
	case 8:
		TEST(msg, type == STRING && [string isEqual: @"\n "])
		break;
	case 9:
		TEST(msg, type == TAG_START && [name isEqual: @"foobar"] &&
		    prefix == nil && [ns isEqual: @"urn:objfw:test:foobar"] &&
		    [attrs count] == 1 &&
		    attrs.count == 1 &&
		    /* xmlns attr */
		    [[[attrs objectAtIndex: 0] name] isEqual: @"xmlns"] &&
		    [[attrs objectAtIndex: 0] namespace] == nil &&
		    [[[attrs objectAtIndex: 0] stringValue] isEqual:
		    @"urn:objfw:test:foobar"])
		break;
	case 10:
		TEST(msg, type == STRING && [string isEqual: @"\n  "])
		break;
	case 11:
		TEST(msg, type == TAG_START && [name isEqual: @"qux"] &&
		    prefix == nil && [ns isEqual: @"urn:objfw:test:foobar"] &&
		    [attrs count] == 1 &&
		    attrs.count == 1 &&
		    /* xmlns:foo attr */
		    [[[attrs objectAtIndex: 0] name] isEqual: @"foo"] &&
		    [[[attrs objectAtIndex: 0] namespace] isEqual:
		    @"http://www.w3.org/2000/xmlns/"] &&
		    [[[attrs objectAtIndex: 0] stringValue] isEqual:
		    @"urn:objfw:test:foo"])
		break;
	case 12:
		TEST(msg, type == STRING && [string isEqual: @"\n   "])
		break;
	case 13:
		TEST(msg, type == TAG_START && [name isEqual: @"bla"] &&
		    [prefix isEqual: @"foo"] &&
		    [ns isEqual: @"urn:objfw:test:foo"] &&
		    [attrs count] == 2 &&
		    attrs.count == 2 &&
		    /* foo:bla attr */
		    [[[attrs objectAtIndex: 0] name] isEqual: @"bla"] &&
		    [[[attrs objectAtIndex: 0] namespace] isEqual:
		    @"urn:objfw:test:foo"] &&
		    [[[attrs objectAtIndex: 0] stringValue] isEqual: @"bla"] &&
		    /* blafoo attr */
		    [[[attrs objectAtIndex: 1] name] isEqual: @"blafoo"] &&
		    [[attrs objectAtIndex: 1] namespace] == nil &&
		    [[[attrs objectAtIndex: 1] stringValue] isEqual: @"foo"])
		break;
	case 14:
		TEST(msg, type == STRING && [string isEqual: @"\n    "])
		break;
	case 15:
		TEST(msg, type == TAG_START && [name isEqual: @"blup"] &&
		    prefix == nil && [ns isEqual: @"urn:objfw:test:foobar"] &&
		    [attrs count] == 2 &&
		    attrs.count == 2 &&
		    /* foo:qux attr */
		    [[[attrs objectAtIndex: 0] name] isEqual: @"qux"] &&
		    [[[attrs objectAtIndex: 0] namespace] isEqual:
		    @"urn:objfw:test:foo"] &&
		    [[[attrs objectAtIndex: 0] stringValue] isEqual: @"asd"] &&
		    /* quxqux attr */
		    [[[attrs objectAtIndex: 1] name] isEqual: @"quxqux"] &&
		    [[attrs objectAtIndex: 1] namespace] == nil &&
		    [[[attrs objectAtIndex: 1] stringValue] isEqual: @"test"])
		break;
	case 16:
		TEST(msg, type == TAG_END && [name isEqual: @"blup"] &&
		    prefix == nil && [ns isEqual: @"urn:objfw:test:foobar"])
		break;
	case 17:
		TEST(msg, type == STRING && [string isEqual: @"\n    "])
		break;
	case 18:
		TEST(msg, type == TAG_START && [name isEqual: @"bla"] &&
		    [prefix isEqual: @"bla"] &&
		    [ns isEqual: @"urn:objfw:test:bla"] && [attrs count] == 3 &&
		    [ns isEqual: @"urn:objfw:test:bla"] && attrs.count == 3 &&
		    /* xmlns:bla attr */
		    [[[attrs objectAtIndex: 0] name] isEqual: @"bla"] &&
		    [[[attrs objectAtIndex: 0] namespace] isEqual:
		    @"http://www.w3.org/2000/xmlns/"] &&
		    [[[attrs objectAtIndex: 0] stringValue] isEqual:
		    @"urn:objfw:test:bla"] &&
		    /* qux attr */
172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
172
173
174
175
176
177
178

179
180
181
182
183
184
185
186







-
+







		break;
	case 20:
		TEST(msg, type == STRING && [string isEqual: @"\n    "])
		break;
	case 21:
		TEST(msg, type == TAG_START && [name isEqual: @"abc"] &&
		    prefix == nil && [ns isEqual: @"urn:objfw:test:abc"] &&
		    [attrs count] == 3 &&
		    attrs.count == 3 &&
		    /* xmlns attr */
		    [[[attrs objectAtIndex: 0] name] isEqual: @"xmlns"] &&
		    [[attrs objectAtIndex: 0] namespace] == nil &&
		    [[[attrs objectAtIndex: 0] stringValue] isEqual:
		    @"urn:objfw:test:abc"] &&
		    /* abc attr */
		    [[[attrs objectAtIndex: 1] name] isEqual: @"abc"] &&
339
340
341
342
343
344
345
346

347
348
349
350
351
352

353
354
355
356
357
358
359
360
361
362
363
364

365
366

367
368
369
370
371
372
373
339
340
341
342
343
344
345

346
347
348
349
350
351

352
353
354
355
356
357
358
359
360
361
362
363

364
365

366
367
368
369
370
371
372
373







-
+





-
+











-
+

-
+







	    " </foobar>\n"
	    "</root>";
	OFXMLParser *parser;
	size_t j, len;

	TEST(@"+[parser]", (parser = [OFXMLParser parser]))

	TEST(@"-[setDelegate:]", R([parser setDelegate: self]))
	TEST(@"-[setDelegate:]", (parser.delegate = self))

	/* Simulate a stream where we only get chunks */
	len = strlen(str);

	for (j = 0; j < len; j+= 2) {
		if ([parser hasFinishedParsing])
		if (parser.hasFinishedParsing)
			abort();

		if (j + 2 > len)
			[parser parseBuffer: str + j
				     length: 1];
		else
			[parser parseBuffer: str + j
				     length: 2];
	}

	TEST(@"Checking if everything was parsed",
	    i == 32 && [parser lineNumber] == 18)
	    i == 32 && parser.lineNumber == 18)

	TEST(@"-[hasFinishedParsing]", [parser hasFinishedParsing])
	TEST(@"-[hasFinishedParsing]", parser.hasFinishedParsing)

	TEST(@"Parsing whitespaces after the document",
	    R([parser parseString: @" \t\r\n "]))

	TEST(@"Parsing comments after the document",
	    R([parser parseString: @" \t<!-- foo -->\r<!--bar-->\n "]))

Modified tests/RuntimeTests.m from [9b47851fa7] to [b3c5975985].

74
75
76
77
78
79
80
81
82


83
84
85


86
87
88
89
90
74
75
76
77
78
79
80


81
82
83


84
85

86
87
88
89







-
-
+
+

-
-
+
+
-




	TEST(@"Calling a method via a super with self == nil",
	    [rt nilSuperTest] == nil)

	t = [OFMutableString stringWithString: @"foo"];
	foo = @"foo";

	[rt setFoo: t];
	TEST(@"copy, nonatomic properties", [[rt foo] isEqual: foo] &&
	    [rt foo] != foo && [[rt foo] retainCount] == 1)
	TEST(@"copy, nonatomic properties", [rt.foo isEqual: foo] &&
	    rt.foo != foo && rt.foo.retainCount == 1)

	[rt setBar: t];
	TEST(@"retain, atomic properties",
	rt.bar = t;
	TEST(@"retain, atomic properties", rt.bar == t && t.retainCount == 3)
	    [rt bar] == t && [t retainCount] == 3)

	[pool drain];
}
@end

Modified tests/TestsAppDelegate.m from [b899b58d18] to [5576f97fcf].

144
145
146
147
148
149
150
151

152
153
154
155
156
157
158
144
145
146
147
148
149
150

151
152
153
154
155
156
157
158







-
+







#if defined(OF_WII) || defined(OF_PSP) || defined(OF_NINTENDO_DS) || \
	defined(OF_NINTENDO_3DS)
	@try {
		return of_application_main(&argc, &argv,
		    [[TestsAppDelegate alloc] init]);
	} @catch (id e) {
		TestsAppDelegate *delegate =
		    [[OFApplication sharedApplication] delegate];
		    [OFApplication sharedApplication].delegate;
		OFString *string = [OFString stringWithFormat:
		    @"\nRuntime error: Unhandled exception:\n%@\n", e];
		OFString *backtrace = [OFString stringWithFormat:
		    @"\nBacktrace:\n  %@\n\n",
		    [[e backtrace] componentsJoinedByString: @"\n  "]];

		[delegate outputString: string
226
227
228
229
230
231
232
233

234
235
236
237
238
239
240
226
227
228
229
230
231
232

233
234
235
236
237
238
239
240







-
+







		break;
	case YELLOW:
		pspDebugScreenSetTextColor(0x00FFFF);
		break;
	}

	pspDebugScreenSetXY(0, y);
	pspDebugScreenPrintData([str UTF8String], [str UTF8StringLength]);
	pspDebugScreenPrintData(str.UTF8String, str.UTF8StringLength);
#elif defined(STDOUT)
	switch (color) {
	case NO_COLOR:
		[of_stdout writeString: @"\r\033[K"];
# if defined(OF_WII) || defined(OF_NINTENDO_DS)
		[of_stdout writeString: @"\033[37m"];
# endif