//
//  OCLinkedListTest.m
//  LinkedList
//
//  Created by Jonathan Lung on 05/03/07.
//  Copyright 2007 Jonathan Lung. All rights reserved.
//	http://www.cs.toronto.edu/~lungj
//

#import "OCLinkedListTest.h"


@implementation OCLinkedListTest
#pragma mark Start/end code
-(void) setUp {
	pool = [[NSAutoreleasePool alloc] init];
	linkedList = [[OCLinkedList alloc] init];
}
-(void) tearDown {
	[linkedList release];
	[pool release];
}

#pragma mark Test insertions

-(void) testEmptyCount {
	unsigned int count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects in empty list should be 0, not %u ",count);

	count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects in empty list should \
								remain 0 after two calls to count:, not %u ",count);
}

-(void) testInsertObject {
	unsigned int count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects in empty list should be 0, not %u ",count);

	NSObject* insertedObject1 = [[NSObject alloc] init];
	NSObject* insertedObject2 = [[NSObject alloc] init];
	NSObject* insertedObject3 = [[NSObject alloc] init];
	NSObject* insertedObject4 = [[NSObject alloc] init];
	
	[linkedList insertObject:insertedObject1 atIndex:0];
	
	count = [linkedList count];
	STAssertEquals(count, 1U, @"Count of objects list after adding an object should \
								be 1, not %u ",count);

	STAssertEqualObjects([linkedList objectAtIndex:0], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");
	// Release the added object to test retention
	[insertedObject1 release];
	
	STAssertTrue([[[linkedList objectAtIndex:0] className] isEqualToString:@"NSObject"],
							@"The stored object was released prematurely.");

	// Retrieve the first object.
	insertedObject1 = [linkedList objectAtIndex:0];
	
	// Insert a second test object.
	[linkedList insertObject:insertedObject2 atIndex:0];
	
	count = [linkedList count];
	STAssertEquals(count, 2U, @"Count of objects list after adding two objects should \
								be 2, not %u ",count);
	
	// Test for ordering
	STAssertEqualObjects([linkedList objectAtIndex:0], insertedObject2,
						@"The objectAtIndex method returns the wrong object.");
	STAssertEqualObjects([linkedList objectAtIndex:1], insertedObject1,
						@"The objectAtIndex method returns the wrong object.");


	// Insert a third test object at the end.
	[linkedList insertObject:insertedObject3 atIndex:2];
	
	count = [linkedList count];
	STAssertEquals(count, 3U, @"Count of objects list after adding three objects should \
								be 3, not %u ",count);
								
	// Test for ordering
	STAssertEqualObjects([linkedList objectAtIndex:0], insertedObject2,
						@"The objectAtIndex method returns the wrong object.");
	STAssertEqualObjects([linkedList objectAtIndex:1], insertedObject1,
						@"The objectAtIndex method returns the wrong object.");
	STAssertEqualObjects([linkedList objectAtIndex:2], insertedObject3,
						@"The objectAtIndex method returns the wrong object.");

	// Insert a fourth test object at the middle.
	[linkedList insertObject:insertedObject4 atIndex:1];
	
	count = [linkedList count];
	STAssertEquals(count, 4U, @"Count of objects list after adding four objects should \
								be 4, not %u ",count);
								
	// Test for ordering
	STAssertEqualObjects([linkedList objectAtIndex:0], insertedObject2,
						@"The objectAtIndex method returns the wrong object.");
	STAssertEqualObjects([linkedList objectAtIndex:1], insertedObject4,
						@"The objectAtIndex method returns the wrong object.");
	STAssertEqualObjects([linkedList objectAtIndex:2], insertedObject1,
						@"The objectAtIndex method returns the wrong object.");
	STAssertEqualObjects([linkedList objectAtIndex:3], insertedObject3,
						@"The objectAtIndex method returns the wrong object.");


	[insertedObject1 release];
	[insertedObject2 release];
	[insertedObject3 release];
	[insertedObject4 release];
}

-(void) testInsertObjectMultipleTimes {
	unsigned int count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects in empty list should be 0, not %u ",count);

	NSObject* insertedObject1 = [[NSObject alloc] init];
	
	[linkedList insertObject:insertedObject1 atIndex:0];
	
	count = [linkedList count];
	STAssertEquals(count, 1U, @"Count of objects list after adding an object should \
								be 1, not %u ",count);

	STAssertEqualObjects([linkedList objectAtIndex:0], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");

	[linkedList insertObject:insertedObject1 atIndex:0];
	
	count = [linkedList count];
	STAssertEquals(count, 2U, @"Count of objects list after adding an object twice should \
								be 2, not %u ",count);

	STAssertEqualObjects([linkedList objectAtIndex:0], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");
	STAssertEqualObjects([linkedList objectAtIndex:1], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");


	[insertedObject1 release];
}

-(void) testInsertObjectManyTimes {
	#define OBJECTS 10000
	unsigned int i = 0;
	unsigned int count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects in empty list should be 0, not %u ",count);

	NSObject* insertedObjects[OBJECTS];
	// Could randomize insertion order...
	for (i = 0; i < OBJECTS; i++) {
		insertedObjects[i] = [[NSObject alloc] init];

		[linkedList insertObject:insertedObjects[i] atIndex:i];
		count = [linkedList count];
		STAssertEquals(count, i+1, @"Count of objects list after adding %i object(s) should \
								be %i, not %u ", i+1, i+1, count);
	}

	for (i = 0; i < OBJECTS; i++) {
		STAssertEqualObjects([linkedList objectAtIndex:i], insertedObjects[i],
							@"The objectAtIndex method does not retrieve the stored object.");
	}
	
	for (i = 0; i< OBJECTS; i++) {
		[insertedObjects[i] release];
	}
	#undef OBJECTS

}
-(void) testAddObject {
	unsigned int count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects in empty list should be 0, not %u ",count);

	NSObject* insertedObject1 = [[NSObject alloc] init];
	NSObject* insertedObject2 = [[NSObject alloc] init];
	
	[linkedList addObject:insertedObject1];
	
	count = [linkedList count];
	STAssertEquals(count, 1U, @"Count of objects list after adding an object should \
								be 1, not %u ",count);

	STAssertEqualObjects([linkedList objectAtIndex:0], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");

	[linkedList addObject:insertedObject1];
	
	count = [linkedList count];
	STAssertEquals(count, 2U, @"Count of objects list after adding an object twice should \
								be 2, not %u ",count);

	STAssertEqualObjects([linkedList objectAtIndex:0], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");

	STAssertEqualObjects([linkedList objectAtIndex:1], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");
							
	[linkedList addObject:insertedObject2];							

	count = [linkedList count];
	STAssertEquals(count, 3U, @"Count of objects list after adding three objects should \
								be 3, not %u ",count);

	STAssertEqualObjects([linkedList objectAtIndex:0], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");

	STAssertEqualObjects([linkedList objectAtIndex:1], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");

	STAssertEqualObjects([linkedList objectAtIndex:2], insertedObject2,
							@"The objectAtIndex method does not retrieve the stored object.");

}

-(void) testAddObjectAtBeginning {
	unsigned int count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects in empty list should be 0, not %u ",count);

	NSObject* insertedObject1 = [[NSObject alloc] init];
	NSObject* insertedObject2 = [[NSObject alloc] init];
	
	[linkedList addObjectAtBeginning:insertedObject1];
	
	count = [linkedList count];
	STAssertEquals(count, 1U, @"Count of objects list after adding an object should \
								be 1, not %u ",count);

	STAssertEqualObjects([linkedList objectAtIndex:0], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");

	[linkedList addObjectAtBeginning:insertedObject1];
	
	count = [linkedList count];
	STAssertEquals(count, 2U, @"Count of objects list after adding an object twice should \
								be 2, not %u ",count);

	STAssertEqualObjects([linkedList objectAtIndex:0], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");

	STAssertEqualObjects([linkedList objectAtIndex:1], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");
							
	[linkedList addObjectAtBeginning:insertedObject2];							

	count = [linkedList count];
	STAssertEquals(count, 3U, @"Count of objects list after adding three objects should \
								be 3, not %u ",count);

	STAssertEqualObjects([linkedList objectAtIndex:0], insertedObject2,
							@"The objectAtIndex method does not retrieve the stored object.");

	STAssertEqualObjects([linkedList objectAtIndex:1], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");

	STAssertEqualObjects([linkedList objectAtIndex:2], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");
}
#pragma mark Test removals
-(void) testRemoveFromIndex {
	unsigned int count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects in empty list should be 0, not %u ",count);

	NSObject* insertedObject1 = [[NSObject alloc] init];
	NSObject* insertedObject2 = [[NSObject alloc] init];
	NSObject* insertedObject3 = [[NSObject alloc] init];
	NSObject* insertedObject4 = [[NSObject alloc] init];
	NSObject* insertedObject5 = [[NSObject alloc] init];

	STAssertEquals([insertedObject4 retainCount], 1U,
				@"New object retain count should be 1, not %u.  Changes to Objective-C runtime?",
				[insertedObject4 retainCount]);
	
	[linkedList addObject:insertedObject1];
	[linkedList addObject:insertedObject2];
	[linkedList addObject:insertedObject3];
	[linkedList addObject:insertedObject4];
	[linkedList addObject:insertedObject5];
	
	STAssertEquals([insertedObject4 retainCount], 2U,
			@"New object retain count should be 2 after adding to linked list, \
			not %u.", [insertedObject4 retainCount]);
	
	count = [linkedList count];
	STAssertEquals(count, 5U, @"Count of objects list after adding five objects should \
								be 5, not %u ",count);

	[linkedList removeFromIndex:3];

	STAssertEquals([insertedObject4 retainCount], 1U,
			@"New object retain count should be 1 after adding to linked list \
			and subsequently being removed, not %u.", [insertedObject4 retainCount]);

	count = [linkedList count];
	STAssertEquals(count, 4U, @"Count of objects list after adding five objects and \
								removing one should be 4, not %u ",count);

	STAssertEqualObjects([linkedList objectAtIndex:0], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");
	STAssertEqualObjects([linkedList objectAtIndex:1], insertedObject2,
							@"The objectAtIndex method does not retrieve the stored object.");
	STAssertEqualObjects([linkedList objectAtIndex:2], insertedObject3,
							@"The objectAtIndex method does not retrieve the stored object.");
	STAssertEqualObjects([linkedList objectAtIndex:3], insertedObject5,
							@"The objectAtIndex method does not retrieve the stored object.");

	[insertedObject1 release];
	[insertedObject2 release];
	[insertedObject3 release];
	[insertedObject4 release];
	[insertedObject5 release];
}
-(void) testRemoveAll {
	unsigned int count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects in empty list should be 0, not %u ",count);

	NSObject* insertedObject1 = [[NSObject alloc] init];
	NSObject* insertedObject2 = [[NSObject alloc] init];
	NSObject* insertedObject3 = [[NSObject alloc] init];

	[linkedList addObject:insertedObject1];
	[linkedList addObject:insertedObject2];
	[linkedList addObject:insertedObject3];
	
	count = [linkedList count];
	STAssertEquals(count, 3U, @"Count of objects list after adding three objects should \
								be 3, not %u ",count);

	[linkedList removeFirstObject];
	[linkedList removeFirstObject];
	[linkedList removeFirstObject];	

	count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects list after adding and removing three objects should \
								be 0, not %u ",count);
	
	[insertedObject1 release];
	[insertedObject2 release];
	[insertedObject3 release];
}
-(void) testRemoveFirstObject {
	unsigned int count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects in empty list should be 0, not %u ",count);

	NSObject* insertedObject1 = [[NSObject alloc] init];
	NSObject* insertedObject2 = [[NSObject alloc] init];
	NSObject* insertedObject3 = [[NSObject alloc] init];
	NSObject* insertedObject4 = [[NSObject alloc] init];
	NSObject* insertedObject5 = [[NSObject alloc] init];

	STAssertEquals([insertedObject4 retainCount], 1U,
				@"New object retain count should be 1, not %u.  Changes to Objective-C runtime?",
				[insertedObject4 retainCount]);
	
	[linkedList addObject:insertedObject1];
	[linkedList addObject:insertedObject2];
	[linkedList addObjectAtBeginning:insertedObject3];
	[linkedList addObjectAtBeginning:insertedObject4];
	[linkedList addObject:insertedObject5];
	
	STAssertEquals([insertedObject4 retainCount], 2U,
			@"New object retain count should be 2 after adding to linked list, \
			not %u.", [insertedObject4 retainCount]);
	
	count = [linkedList count];
	STAssertEquals(count, 5U, @"Count of objects list after adding five objects should \
								be 5, not %u ",count);

	[linkedList removeFirstObject];

	STAssertEquals([insertedObject4 retainCount], 1U,
			@"New object retain count should be 1 after adding to linked list \
			and subsequently being removed, not %u.", [insertedObject4 retainCount]);

	count = [linkedList count];
	STAssertEquals(count, 4U, @"Count of objects list after adding five objects and \
								removing one should be 4, not %u ",count);

	STAssertEqualObjects([linkedList objectAtIndex:0], insertedObject3,
							@"The objectAtIndex method does not retrieve the stored object.");
	STAssertEqualObjects([linkedList objectAtIndex:1], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");
	STAssertEqualObjects([linkedList objectAtIndex:2], insertedObject2,
							@"The objectAtIndex method does not retrieve the stored object.");
	STAssertEqualObjects([linkedList objectAtIndex:3], insertedObject5,
							@"The objectAtIndex method does not retrieve the stored object.");

	[linkedList removeFirstObject];
	count = [linkedList count];
	STAssertEquals(count, 3U, @"Count of objects list after adding five objects and \
								removing two should be 3, not %u ",count);

	STAssertEqualObjects([linkedList objectAtIndex:0], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");
	STAssertEqualObjects([linkedList objectAtIndex:1], insertedObject2,
							@"The objectAtIndex method does not retrieve the stored object.");
	STAssertEqualObjects([linkedList objectAtIndex:2], insertedObject5,
							@"The objectAtIndex method does not retrieve the stored object.");
							
	[insertedObject1 release];
	[insertedObject2 release];
	[insertedObject3 release];
	[insertedObject4 release];
	[insertedObject5 release];
}

-(void) testRemoveLastObject {
	unsigned int count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects in empty list should be 0, not %u ",count);

	NSObject* insertedObject1 = [[NSObject alloc] init];
	NSObject* insertedObject2 = [[NSObject alloc] init];
	NSObject* insertedObject3 = [[NSObject alloc] init];
	NSObject* insertedObject4 = [[NSObject alloc] init];
	NSObject* insertedObject5 = [[NSObject alloc] init];

	STAssertEquals([insertedObject4 retainCount], 1U,
				@"New object retain count should be 1, not %u.  Changes to Objective-C runtime?",
				[insertedObject4 retainCount]);
	
	[linkedList addObject:insertedObject1];
	[linkedList addObject:insertedObject2];
	[linkedList addObjectAtBeginning:insertedObject3];
	[linkedList addObject:insertedObject4];
	[linkedList addObjectAtBeginning:insertedObject5];
	
	STAssertEquals([insertedObject4 retainCount], 2U,
			@"New object retain count should be 2 after adding to linked list, \
			not %u.", [insertedObject4 retainCount]);
	
	count = [linkedList count];
	STAssertEquals(count, 5U, @"Count of objects list after adding five objects should \
								be 5, not %u ",count);

	[linkedList removeLastObject];

	STAssertEquals([insertedObject4 retainCount], 1U,
			@"New object retain count should be 1 after adding to linked list \
			and subsequently being removed, not %u.", [insertedObject4 retainCount]);

	count = [linkedList count];
	STAssertEquals(count, 4U, @"Count of objects list after adding five objects and \
								removing one should be 4, not %u ",count);

	STAssertEqualObjects([linkedList objectAtIndex:0], insertedObject5,
							@"The objectAtIndex method does not retrieve the stored object.");
	STAssertEqualObjects([linkedList objectAtIndex:1], insertedObject3,
							@"The objectAtIndex method does not retrieve the stored object.");
	STAssertEqualObjects([linkedList objectAtIndex:2], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");
	STAssertEqualObjects([linkedList objectAtIndex:3], insertedObject2,
							@"The objectAtIndex method does not retrieve the stored object.");

	[linkedList removeLastObject];
	count = [linkedList count];
	STAssertEquals(count, 3U, @"Count of objects list after adding five objects and \
								removing two should be 3, not %u ",count);

	STAssertEqualObjects([linkedList objectAtIndex:0], insertedObject5,
							@"The objectAtIndex method does not retrieve the stored object.");
	STAssertEqualObjects([linkedList objectAtIndex:1], insertedObject3,
							@"The objectAtIndex method does not retrieve the stored object.");
	STAssertEqualObjects([linkedList objectAtIndex:2], insertedObject1,
							@"The objectAtIndex method does not retrieve the stored object.");
							
	[insertedObject1 release];
	[insertedObject2 release];
	[insertedObject3 release];
	[insertedObject4 release];
	[insertedObject5 release];
}
#pragma mark -
#pragma mark Enumeration tests
-(void) testEnumeratorNextOnEmpty {
	unsigned int count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects list after adding zero objects \
								should be 0, not %u ",count);
	
	NSEnumerator* enumerator = [linkedList objectEnumerator];
	
	STAssertEqualObjects([enumerator nextObject], nil,
							@"The nextObject method should return nil on an empty list.");

	// Test again...
	STAssertEqualObjects([enumerator nextObject], nil,
							@"The nextObject method should return nil on an empty list.");

}

-(void) testEnumeratorAllObjectsOnEmpty {
	unsigned int count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects list after adding zero objects \
								should be 0, not %u ",count);
	
	NSEnumerator* enumerator = [linkedList objectEnumerator];
	
	NSArray* array = [enumerator allObjects];
	STAssertEquals([array count], 0U,
							@"The allObjects method should return an empty NSArray on an empty list.");

	// Test again...
	array = [enumerator allObjects];
	STAssertEquals([array count], 0U,
							@"The allObjects method should return an empty NSArray on an empty list.");
}

-(void) testEnumeratorMixedOnEmpty {
	unsigned int count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects list after adding zero objects \
								should be 0, not %u ",count);
	
	NSEnumerator* enumerator = [linkedList objectEnumerator];

	STAssertEqualObjects([enumerator nextObject], nil,
							@"The nextObject method should return nil on an empty list.");	
							
	NSArray* array = [enumerator allObjects];
	STAssertEquals([array count], 0U,
							@"The allObjects method should return an empty NSArray on an empty list.");

	STAssertEqualObjects([enumerator nextObject], nil,
							@"The nextObject method should return nil on an empty list.");
}
-(void) testEnumeratorNext {
	unsigned int count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects in empty list should be 0, not %u ",count);

	NSObject* insertedObject1 = [[NSObject alloc] init];
	NSObject* insertedObject2 = [[NSObject alloc] init];
	NSObject* insertedObject3 = [[NSObject alloc] init];
	NSObject* insertedObject4 = [[NSObject alloc] init];
	
	[linkedList insertObject:insertedObject1 atIndex:0];		
	[linkedList insertObject:insertedObject2 atIndex:0];
	[linkedList insertObject:insertedObject3 atIndex:2];
	[linkedList insertObject:insertedObject4 atIndex:1];
	
	
	NSEnumerator* enumerator = [linkedList objectEnumerator];
	
	count = [linkedList count];
	STAssertEquals(count, 4U, @"Count of objects list after adding four objects should \
								be 4, not %u ",count);
								
	// Test for ordering
	STAssertEqualObjects([enumerator nextObject], insertedObject2,
						@"The nextObject method returns the wrong object.");
	STAssertEqualObjects([enumerator nextObject], insertedObject4,
						@"The nextObject method returns the wrong object.");
	STAssertEqualObjects([enumerator nextObject], insertedObject1,
						@"The nextObject method returns the wrong object.");
	STAssertEqualObjects([enumerator nextObject], insertedObject3,
						@"The nextObject method returns the wrong object.");
	STAssertEqualObjects([enumerator nextObject], nil,
						@"The nextObject method should return nil because the set is empty.");


	[insertedObject1 release];
	[insertedObject2 release];
	[insertedObject3 release];
	[insertedObject4 release];
}

-(void) testEnumeratorAllObjects {
	unsigned int count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects in empty list should be 0, not %u ",count);

	NSObject* insertedObject1 = [[NSObject alloc] init];
	NSObject* insertedObject2 = [[NSObject alloc] init];
	NSObject* insertedObject3 = [[NSObject alloc] init];
	NSObject* insertedObject4 = [[NSObject alloc] init];
	
	[linkedList insertObject:insertedObject1 atIndex:0];		
	[linkedList insertObject:insertedObject2 atIndex:0];
	[linkedList insertObject:insertedObject3 atIndex:2];
	[linkedList insertObject:insertedObject4 atIndex:1];
	
	
	NSArray* array = [[linkedList objectEnumerator] allObjects];

	count = [array count];
	STAssertEquals(count, 4U, @"Count of objects in array should be 4, not %u ",count);

	// Test for ordering
	STAssertEqualObjects([array objectAtIndex:0], insertedObject2,
						@"The nextObject method returns the wrong object.");
	STAssertEqualObjects([array objectAtIndex:1], insertedObject4,
						@"The nextObject method returns the wrong object.");
	STAssertEqualObjects([array objectAtIndex:2], insertedObject1,
						@"The nextObject method returns the wrong object.");
	STAssertEqualObjects([array objectAtIndex:3], insertedObject3,
						@"The nextObject method returns the wrong object.");

	[insertedObject1 release];
	[insertedObject2 release];
	[insertedObject3 release];
	[insertedObject4 release];
}

-(void) testEnumeratorMixed {
	unsigned int count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects in empty list should be 0, not %u ",count);

	NSObject* insertedObject1 = [[NSObject alloc] init];
	NSObject* insertedObject2 = [[NSObject alloc] init];
	NSObject* insertedObject3 = [[NSObject alloc] init];
	NSObject* insertedObject4 = [[NSObject alloc] init];
	
	[linkedList insertObject:insertedObject1 atIndex:0];		
	[linkedList insertObject:insertedObject2 atIndex:0];
	[linkedList insertObject:insertedObject3 atIndex:2];
	[linkedList insertObject:insertedObject4 atIndex:1];
	

	NSEnumerator* enumerator = [linkedList objectEnumerator];
	
	STAssertEqualObjects([enumerator nextObject], insertedObject2,
						@"The nextObject method returns the wrong object.");
	STAssertEqualObjects([enumerator nextObject], insertedObject4,
						@"The nextObject method returns the wrong object.");
	
	NSArray* array = [enumerator allObjects];

	count = [array count];
	STAssertEquals(count, 2U, @"Count of objects in array should be 2 after retrieving 2 objects, not %u ",count);

	// Test for ordering
	STAssertEqualObjects([array objectAtIndex:0], insertedObject1,
						@"The nextObject method returns the wrong object.");
	STAssertEqualObjects([array objectAtIndex:1], insertedObject3,
						@"The nextObject method returns the wrong object.");

	
	array = [[linkedList objectEnumerator] allObjects];

	count = [array count];
	STAssertEquals(count, 4U, @"Count of objects in array from new enumerator should be 4, not %u ",count);

	[insertedObject1 release];
	[insertedObject2 release];
	[insertedObject3 release];
	[insertedObject4 release];
}

-(void) testEnumeratorWithNils {
	// Note that there is no use of allObjects since NSArrays do not support containing nil objects.
	unsigned int count = [linkedList count];
	STAssertEquals(count, 0U, @"Count of objects in empty list should be 0, not %u ",count);

	NSObject* insertedObject1 = nil;
	NSObject* insertedObject2 = [[NSObject alloc] init];
	NSObject* insertedObject3 = nil;
	NSObject* insertedObject4 = [[NSObject alloc] init];
	
	[linkedList insertObject:insertedObject1 atIndex:0];
	[linkedList insertObject:insertedObject2 atIndex:0];
	[linkedList insertObject:insertedObject3 atIndex:2];
	[linkedList insertObject:insertedObject4 atIndex:1];
	

	NSEnumerator* enumerator = [linkedList objectEnumerator];
	
	STAssertEqualObjects([enumerator nextObject], insertedObject2,
						@"The nextObject method returns the wrong object.");
	STAssertEqualObjects([enumerator nextObject], insertedObject4,
						@"The nextObject method returns the wrong object.");
	STAssertEqualObjects([enumerator nextObject], insertedObject1,
						@"The nextObject method returns the wrong object.");
	STAssertEqualObjects([enumerator nextObject], insertedObject3,
						@"The nextObject method returns the wrong object.");

	
	[insertedObject2 release];
	[insertedObject4 release];
}

@end
