/* * Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im> * * 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