Index: new_tests/Makefile ================================================================== --- new_tests/Makefile +++ new_tests/Makefile @@ -26,10 +26,11 @@ OFHMACTests.m \ OFINIFileTests.m \ OFIRITests.m \ OFInvocationTests.m \ OFJSONTests.m \ + OFListTests.m \ OFLocaleTests.m \ OFMatrix4x4Tests.m \ OFMethodSignatureTests.m \ OFMutableArrayTests.m \ OFMutableSetTests.m \ ADDED new_tests/OFListTests.m Index: new_tests/OFListTests.m ================================================================== --- new_tests/OFListTests.m +++ new_tests/OFListTests.m @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2008-2024 Jonathan Schleifer + * + * 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.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "ObjFW.h" +#import "ObjFWTest.h" + +@interface OFListTests: OTTestCase +{ + OFList *_list; +} +@end + +@implementation OFListTests +- (void)setUp +{ + [super setUp]; + + _list = [[OFList alloc] init]; + [_list appendObject: @"Foo"]; + [_list appendObject: @"Bar"]; + [_list appendObject: @"Baz"]; +} + +- (void)dealloc +{ + [_list release]; + + [super dealloc]; +} + +- (void)testCount +{ + OTAssertEqual(_list.count, 3); +} + +- (void)testAppendObject +{ + OFListItem item; + + [_list appendObject: @"Qux"]; + + item = _list.firstListItem; + OTAssertEqualObjects(OFListItemObject(item), @"Foo"); + + item = OFListItemNext(item); + OTAssertEqualObjects(OFListItemObject(item), @"Bar"); + + item = OFListItemNext(item); + OTAssertEqualObjects(OFListItemObject(item), @"Baz"); + + item = OFListItemNext(item); + OTAssertEqualObjects(OFListItemObject(item), @"Qux"); + + item = OFListItemNext(item); + OTAssertEqual(item, NULL); +} + +- (void)testFirstListItem +{ + OTAssertEqualObjects(OFListItemObject(_list.firstListItem), @"Foo"); +} + +- (void)testFirstObject +{ + OTAssertEqualObjects(_list.firstObject, @"Foo"); +} + +- (void)testLastListItem +{ + OTAssertEqualObjects(OFListItemObject(_list.lastListItem), @"Baz"); +} + +- (void)testLastObject +{ + OTAssertEqualObjects(_list.lastObject, @"Baz"); +} + +- (void)testListItemNext +{ + OTAssertEqualObjects( + OFListItemObject(OFListItemNext(_list.firstListItem)), @"Bar"); +} + +- (void)testListItemPrevious +{ + OTAssertEqualObjects( + OFListItemObject(OFListItemPrevious(_list.lastListItem)), @"Bar"); +} + +- (void)testRemoveListItem +{ + OFListItem item; + + [_list removeListItem: OFListItemNext(_list.firstListItem)]; + + item = _list.firstListItem; + OTAssertEqualObjects(OFListItemObject(item), @"Foo"); + + item = OFListItemNext(item); + OTAssertEqualObjects(OFListItemObject(item), @"Baz"); + + item = OFListItemNext(item); + OTAssertEqual(item, NULL); +} + +- (void)testInsertObjectBeforeListItem +{ + OFListItem item; + + [_list insertObject: @"Qux" beforeListItem: _list.lastListItem]; + + item = _list.firstListItem; + OTAssertEqualObjects(OFListItemObject(item), @"Foo"); + + item = OFListItemNext(item); + OTAssertEqualObjects(OFListItemObject(item), @"Bar"); + + item = OFListItemNext(item); + OTAssertEqualObjects(OFListItemObject(item), @"Qux"); + + item = OFListItemNext(item); + OTAssertEqualObjects(OFListItemObject(item), @"Baz"); + + item = OFListItemNext(item); + OTAssertEqual(item, NULL); +} + +- (void)testInsertObjectAfterListItem +{ + OFListItem item; + + [_list insertObject: @"Qux" afterListItem: _list.firstListItem]; + + item = _list.firstListItem; + OTAssertEqualObjects(OFListItemObject(item), @"Foo"); + + item = OFListItemNext(item); + OTAssertEqualObjects(OFListItemObject(item), @"Qux"); + + item = OFListItemNext(item); + OTAssertEqualObjects(OFListItemObject(item), @"Bar"); + + item = OFListItemNext(item); + OTAssertEqualObjects(OFListItemObject(item), @"Baz"); + + item = OFListItemNext(item); + OTAssertEqual(item, NULL); +} + +- (void)testContainsObject +{ + OTAssertTrue([_list containsObject: @"Foo"]); + OTAssertFalse([_list containsObject: @"Qux"]); +} + +- (void)testContainsObjectIdenticalTo +{ + OFString *foo = _list.firstObject; + + OTAssertTrue([_list containsObjectIdenticalTo: foo]); + OTAssertFalse( + [_list containsObjectIdenticalTo: [[foo mutableCopy] autorelease]]); +} + +- (void)testIsEqual +{ + OFList *list = [OFList list]; + + [list appendObject: @"Foo"]; + [list appendObject: @"Bar"]; + [list appendObject: @"Baz"]; + + OTAssertEqualObjects(list, _list); + + [list appendObject: @"Qux"]; + + OTAssertNotEqualObjects(list, _list); +} + +- (void)testHash +{ + OFList *list = [OFList list]; + + [list appendObject: @"Foo"]; + [list appendObject: @"Bar"]; + [list appendObject: @"Baz"]; + + OTAssertEqual(list.hash, _list.hash); + + [list appendObject: @"Qux"]; + + OTAssertNotEqual(list.hash, _list.hash); +} + +- (void)testCopy +{ + OTAssertEqualObjects([[_list copy] autorelease], _list); +} + +- (void)testDescription +{ + OTAssertEqualObjects(_list.description, @"[\n\tFoo,\n\tBar,\n\tBaz\n]"); +} + +- (void)testEnumerator +{ + OFEnumerator *enumerator = [_list objectEnumerator]; + + OTAssertEqualObjects([enumerator nextObject], @"Foo"); + OTAssertEqualObjects([enumerator nextObject], @"Bar"); + OTAssertEqualObjects([enumerator nextObject], @"Baz"); + OTAssertNil([enumerator nextObject]); +} + +- (void)testDetectMutationDuringEnumeration +{ + OFEnumerator *enumerator = [_list objectEnumerator]; + + [_list removeListItem: _list.firstListItem]; + + OTAssertThrowsSpecific([enumerator nextObject], + OFEnumerationMutationException); +} + +- (void)testFastEnumeration +{ + size_t i = 0; + + for (OFString *object in _list) { + OTAssertLessThan(i, 3); + + switch (i++) { + case 0: + OTAssertEqualObjects(object, @"Foo"); + break; + case 1: + OTAssertEqualObjects(object, @"Bar"); + break; + case 2: + OTAssertEqualObjects(object, @"Baz"); + break; + } + } + + OTAssertEqual(i, 3); +} + +- (void)testDetectMutationDuringFastEnumeration +{ + bool detected = false; + + @try { + for (OFString *object in _list) { + (void)object; + [_list removeListItem: _list.firstListItem]; + } + } @catch (OFEnumerationMutationException *e) { + detected = true; + } + + OTAssertTrue(detected); +} +@end Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -13,11 +13,10 @@ PROG_NOINST = tests${PROG_SUFFIX} STATIC_LIB_NOINST = ${TESTS_STATIC_LIB} SRCS = OFDataTests.m \ OFDictionaryTests.m \ - OFListTests.m \ OFMemoryStreamTests.m \ OFStreamTests.m \ OFValueTests.m \ OFXMLNodeTests.m \ OFXMLParserTests.m \ DELETED tests/OFListTests.m Index: tests/OFListTests.m ================================================================== --- tests/OFListTests.m +++ tests/OFListTests.m @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2008-2024 Jonathan Schleifer - * - * 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.QPL included in - * the packaging of this file. - * - * Alternatively, it may be distributed under the terms of the GNU General - * Public License, either version 2 or 3, which can be found in the file - * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this - * file. - */ - -#include "config.h" - -#import "TestsAppDelegate.h" - -static OFString *const module = @"OFList"; -static OFString *strings[] = { - @"Foo", - @"Bar", - @"Baz" -}; - -@implementation TestsAppDelegate (OFListTests) -- (void)listTests -{ - void *pool = objc_autoreleasePoolPush(); - OFList *list; - OFEnumerator *enumerator; - OFListItem iter; - OFString *object; - size_t i; - bool ok; - - TEST(@"+[list]", (list = [OFList list])) - - TEST(@"-[appendObject:]", [list appendObject: strings[0]] && - [list appendObject: strings[1]] && [list appendObject: strings[2]]) - - TEST(@"-[firstListItem]", - [OFListItemObject(list.firstListItem) isEqual: strings[0]]) - - TEST(@"OFListItemNext()", - [OFListItemObject(OFListItemNext(list.firstListItem)) - isEqual: strings[1]]) - - TEST(@"-[lastListItem]", - [OFListItemObject(list.lastListItem) isEqual: strings[2]]) - - TEST(@"OFListItemPrevious()", - [OFListItemObject(OFListItemPrevious(list.lastListItem)) - isEqual: strings[1]]) - - TEST(@"-[removeListItem:]", - R([list removeListItem: list.lastListItem]) && - [list.lastObject isEqual: strings[1]] && - R([list removeListItem: list.firstListItem]) && - [list.firstObject isEqual: list.lastObject]) - - TEST(@"-[insertObject:beforeListItem:]", - [list insertObject: strings[0] beforeListItem: list.lastListItem] && - [OFListItemObject(OFListItemPrevious(list.lastListItem)) - isEqual: strings[0]]) - - TEST(@"-[insertObject:afterListItem:]", - [list insertObject: strings[2] - afterListItem: OFListItemNext(list.firstListItem)] && - [list.lastObject isEqual: strings[2]]) - - 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.firstObject isEqual: strings[0]] && - [OFListItemObject(OFListItemNext(list.firstListItem)) - isEqual: strings[1]] && - [list.lastObject isEqual: strings[2]]) - - TEST(@"-[isEqual:]", [list isEqual: [[list copy] autorelease]]) - - TEST(@"-[description]", - [list.description isEqual: @"[\n\tFoo,\n\tBar,\n\tBaz\n]"]) - - TEST(@"-[objectEnumerator]", (enumerator = [list objectEnumerator])) - - iter = list.firstListItem; - i = 0; - ok = true; - while ((object = [enumerator nextObject]) != nil) { - if (![object isEqual: OFListItemObject(iter)]) - ok = false; - - iter = OFListItemNext(iter); - i++; - } - - if (list.count != i) - ok = false; - - TEST(@"OFEnumerator's -[nextObject]", ok); - - [list removeListItem: list.firstListItem]; - - EXPECT_EXCEPTION(@"Detection of mutation during enumeration", - OFEnumerationMutationException, [enumerator nextObject]) - - [list prependObject: strings[0]]; - - iter = list.firstListItem; - i = 0; - ok = true; - - for (OFString *object_ in list) { - if (![object_ isEqual: OFListItemObject(iter)]) - ok = false; - - iter = OFListItemNext(iter); - i++; - } - - if (list.count != i) - ok = false; - - TEST(@"Fast Enumeration", ok) - - ok = false; - @try { - for (OFString *object_ in list) { - (void)object_; - - [list removeListItem: list.lastListItem]; - } - } @catch (OFEnumerationMutationException *e) { - ok = true; - } - - TEST(@"Detection of mutation during Fast Enumeration", ok) - - objc_autoreleasePoolPop(pool); -} -@end Index: tests/TestsAppDelegate.h ================================================================== --- tests/TestsAppDelegate.h +++ tests/TestsAppDelegate.h @@ -65,14 +65,10 @@ @interface TestsAppDelegate (OFDictionaryTests) - (void)dictionaryTests; @end -@interface TestsAppDelegate (OFListTests) -- (void)listTests; -@end - @interface TestsAppDelegate (OFMemoryStreamTests) - (void)memoryStreamTests; @end @interface TestsAppDelegate (OFStreamTests) Index: tests/TestsAppDelegate.m ================================================================== --- tests/TestsAppDelegate.m +++ tests/TestsAppDelegate.m @@ -370,11 +370,10 @@ changeCurrentDirectoryPath: @"/apps/objfw-tests"]; #endif [self dataTests]; [self dictionaryTests]; - [self listTests]; [self valueTests]; [self streamTests]; [self memoryStreamTests]; [self XMLParserTests]; [self XMLNodeTests];