/*
* Copyright (c) 2008 - 2009
* Jonathan Schleifer <js@webkeks.org>
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE included in
* the packaging of this file.
*/
#include "config.h"
#import "OFArray.h"
#import "OFAutoreleasePool.h"
#import "OFString.h"
#import "OFExceptions.h"
#import "main.h"
static OFString *module = @"OFArray";
static OFString *c_ary[] = {
@"Foo",
@"Bar",
@"Baz",
nil
};
void
array_tests()
{
OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
OFArray *a[2];
OFMutableArray *m[2];
OFEnumerator *enumerator;
id obj;
BOOL ok;
size_t i;
TEST(@"+[array]", (m[0] = [OFMutableArray array]))
TEST(@"+[arrayWithObjects:]",
(a[0] = [OFArray arrayWithObjects: @"Foo", @"Bar", @"Baz", nil]))
TEST(@"+[arrayWithCArray:]", (a[1] = [OFArray arrayWithCArray: c_ary]))
TEST(@"-[addObject:]", [m[0] addObject: c_ary[0]] &&
[m[0] addObject: c_ary[2]])
TEST(@"-[addObject:atIndex:]", [m[0] addObject: c_ary[1]
atIndex: 1])
TEST(@"-[count]", [m[0] count] == 3 && [a[0] 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]] &&
[[a[0] objectAtIndex: 0] isEqual: c_ary[0]] &&
[[a[0] objectAtIndex: 1] isEqual: c_ary[1]] &&
[[a[0] objectAtIndex: 2] isEqual: c_ary[2]] &&
[[a[1] objectAtIndex: 0] isEqual: c_ary[0]] &&
[[a[1] objectAtIndex: 1] isEqual: c_ary[1]] &&
[[a[1] objectAtIndex: 2] isEqual: c_ary[2]])
TEST(@"-[indexOfObject:]", [a[0] indexOfObject: c_ary[1]] == 1)
TEST(@"-[indexOfObjectIdenticalTo:]",
[a[1] indexOfObjectIdenticalTo: c_ary[1]] == 1)
TEST(@"-[replaceObject:withObject:]",
[m[0] replaceObject: c_ary[1]
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(@"-[replaceObject:identicalTo:]",
[m[0] replaceObjectIdenticalTo: c_ary[0]
withObject: c_ary[1]] &&
[[m[0] objectAtIndex: 0] isEqual: c_ary[1]] &&
[[m[0] objectAtIndex: 1] isEqual: c_ary[1]] &&
[[m[0] objectAtIndex: 2] isEqual: c_ary[2]])
TEST(@"-[replaceObjectAtIndex:withObject:]",
[m[0] replaceObjectAtIndex: 0
withObject: c_ary[0]] &&
[[m[0] objectAtIndex: 0] isEqual: c_ary[0]] &&
[[m[0] objectAtIndex: 1] isEqual: c_ary[1]] &&
[[m[0] objectAtIndex: 2] isEqual: c_ary[2]])
TEST(@"-[removeObject:]",
[m[0] removeObject: c_ary[1]] && [m[0] count] == 2)
TEST(@"-[removeObjectIdenticalTo:]",
[m[0] removeObjectIdenticalTo: c_ary[2]] && [m[0] count] == 1)
[m[0] addObject: c_ary[0]];
[m[0] addObject: c_ary[1]];
TEST(@"-[removeNObjects:]", [m[0] removeNObjects: 2] &&
[m[0] count] == 1 && [[m[0] objectAtIndex: 0] isEqual: c_ary[0]])
m[1] = [[a[0] mutableCopy] autorelease];
TEST(@"-[removeObjectAtIndex:]", [m[1] removeObjectAtIndex: 1] &&
[m[1] count] == 2 && [[m[1] objectAtIndex: 1] isEqual: c_ary[2]])
m[1] = [[a[0] mutableCopy] autorelease];
TEST(@"-[removeNObjects:atIndex:]", [m[1] removeNObjects: 2
atIndex: 0] &&
[m[1] count] == 1 && [[m[1] objectAtIndex: 0] isEqual: c_ary[2]])
EXPECT_EXCEPTION(@"Detect out of range in -[objectAtIndex:]",
OFOutOfRangeException, [a[0] objectAtIndex: [a[0] count]])
EXPECT_EXCEPTION(@"Detect out of range in -[removeNItems:]",
OFOutOfRangeException, [m[0] removeNObjects: [m[0] count] + 1])
a[1] = [OFArray arrayWithObjects: @"foo", @"bar", @"baz", nil];
TEST(@"-[componentsJoinedByString:]",
[[a[1] componentsJoinedByString: @" "] isEqual: @"foo bar baz"])
m[0] = [[a[0] mutableCopy] autorelease];
ok = YES;
i = 0;
TEST(@"-[enumerator]", (enumerator = [m[0] enumerator]))
while ((obj = [enumerator nextObject]) != nil) {
if (![obj isEqual: c_ary[i]])
ok = NO;
[m[0] replaceObjectAtIndex: i
withObject: @""];
i++;
}
TEST(@"OFEnumerator's -[nextObject]", ok)
[enumerator reset];
[m[0] removeObjectAtIndex: 0];
EXPECT_EXCEPTION(@"Detection of mutation during enumeration",
OFEnumerationMutationException, [enumerator nextObject])
#ifdef OF_HAVE_FAST_ENUMERATION
m[0] = [[a[0] mutableCopy] autorelease];
ok = YES;
i = 0;
for (OFString *s in m[0]) {
if (![s isEqual: c_ary[i]])
ok = NO;
[m[0] replaceObjectAtIndex: i
withObject: @""];
i++;
}
TEST(@"Fast Enumeration", ok)
[m[0] replaceObjectAtIndex: 0
withObject: c_ary[0]];
[m[0] replaceObjectAtIndex: 1
withObject: c_ary[1]];
[m[0] replaceObjectAtIndex: 2
withObject: c_ary[2]];
ok = NO;
@try {
for (OFString *s in m[0])
[m[0] addObject: @""];
} @catch (OFEnumerationMutationException *e) {
ok = YES;
[e dealloc];
}
TEST(@"Detection of mutation during Fast Enumeration", ok)
[m[0] removeNObjects: 1];
#endif
[pool drain];
}