Commits

Tuukka Norri  committed 4c06336

Cleaned up the UnitTests directory

  • Participants
  • Parent commits 5e49c6e

Comments (0)

Files changed (75)

File UnitTests/ConnectTest.h

-//
-// ConnectTest.h
-// BaseTen
-//
-// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import <SenTestingKit/SenTestingKit.h>
-#import "TestLoader.h"
-@class BXDatabaseContext;
-
-@interface ConnectTest : BXTestCase 
-{
-    BXDatabaseContext* ctx;
-	int expectedCount;
-}
-
-@end

File UnitTests/ConnectTest.m

-//
-// ConnectTest.m
-// BaseTen
-//
-// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import "ConnectTest.h"
-#import <BaseTen/BaseTen.h>
-#import "MKCSenTestCaseAdditions.h"
-
-
-@implementation ConnectTest
-
-- (void) setUp
-{
-    ctx = [[BXDatabaseContext alloc] init];
-	[ctx setAutocommits: NO];
-	expectedCount = 0;
-}
-
-- (void) tearDown
-{
-	[ctx disconnect];
-    [ctx release];
-}
-
-- (void) testConnect1
-{
-    MKCAssertNoThrow ([ctx setDatabaseURI: [NSURL URLWithString: @"pgsql://baseten_test_user@localhost/basetentest"]]);
-    MKCAssertNoThrow ([ctx connectIfNeeded: nil]);
-}
-
-- (void) testConnect2
-{
-    MKCAssertNoThrow ([ctx setDatabaseURI: [NSURL URLWithString: @"pgsql://baseten_test_user@localhost/basetentest/"]]);
-    MKCAssertNoThrow ([ctx connectIfNeeded: nil]);
-}
- 
-- (void) testConnectFail1
-{
-    MKCAssertNoThrow ([ctx setDatabaseURI: [NSURL URLWithString: @"pgsql://localhost/anonexistantdatabase"]]);
-    MKCAssertThrows ([ctx connectIfNeeded: nil]);
-}
- 
-- (void) testConnectFail2
-{
-    MKCAssertNoThrow ([ctx setDatabaseURI: 
-        [NSURL URLWithString: @"pgsql://user@localhost/basetentest/a/malformed/database/uri"]]);
-    MKCAssertThrows ([ctx connectIfNeeded: nil]);
-}
-
-- (void) testConnectFail3
-{
-    MKCAssertThrows ([ctx setDatabaseURI: [NSURL URLWithString: @"invalid://user@localhost/invalid"]]);
-}
-
-- (void) testNilURI
-{
-	NSError* error = nil;
-	id rval = nil;
-	BXEntityDescription* entity = [ctx entityForTable: @"test" error: &error];
-	rval = [ctx executeFetchForEntity: entity withPredicate: nil error: &error];
-	MKCAssertNotNil (error);
-	rval = [ctx createObjectForEntity: entity withFieldValues: nil error: &error];
-	MKCAssertNotNil (error);
-}
-
-- (void) testConnectFail4
-{
-	[ctx setDatabaseURI: [NSURL URLWithString: @"pgsql://localhost/anonexistantdatabase"]];
-	[[ctx notificationCenter] addObserver: self selector: @selector (expected:) name: kBXConnectionFailedNotification object: nil];
-	[[ctx notificationCenter] addObserver: self selector: @selector (unexpected:) name: kBXConnectionSuccessfulNotification object: nil];
-	[ctx connectAsync];
-	[[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 1.0]];
-	[ctx connectAsync];
-	[[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 1.0]];
-	[ctx connectAsync];
-	[[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 1.0]];
-	MKCAssertTrue (3 == expectedCount);
-}
-
-- (void) expected: (NSNotification *) n
-{
-	expectedCount++;
-}
-
-- (void) unexpected: (NSNotification *) n
-{
-	STAssertTrue (NO, @"Expected connection not to have been made.");
-}
-
-@end

File UnitTests/CreateTests.h

-//
-// CreateTests.h
-// BaseTen
-//
-// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import <SenTestingKit/SenTestingKit.h>
-#import "TestLoader.h"
-@class BXDatabaseContext;
-@class BXEntityDescription;
-
-@interface CreateTests : BXTestCase 
-{
-    BXDatabaseContext* context;
-    BXEntityDescription* entity;
-}
-
-@end

File UnitTests/CreateTests.m

-//
-// CreateTests.m
-// BaseTen
-//
-// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import "CreateTests.h"
-#import "MKCSenTestCaseAdditions.h"
-#import <BaseTen/BaseTen.h>
-#import <Foundation/Foundation.h>
-
-@interface TestObject : BXDatabaseObject
-{
-}
-@end
-
-
-@implementation TestObject
-@end
-
-
-@implementation CreateTests
-
-- (void) setUp
-{
-    context = [[BXDatabaseContext alloc] initWithDatabaseURI: 
-        [NSURL URLWithString: @"pgsql://baseten_test_user@localhost/basetentest"]];
-    [context setAutocommits: NO];
-    entity = [[context entityForTable: @"test" error: nil] retain];
-    MKCAssertNotNil (context);
-    MKCAssertNotNil (entity);
-}
-
-- (void) tearDown
-{
-    [context rollback];
-	[context disconnect];
-    [context release];
-    [entity release];
-}
-
-- (void) testCreate
-{
-    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-    NSError* error = nil;    
-    MKCAssertNotNil (entity);
-    
-    BXDatabaseObject* object = [context createObjectForEntity: entity withFieldValues: nil error: &error];
-    MKCAssertNotNil (object);
-    STAssertNil (error, [error description]);
-    [context rollback];
-    [pool release];
-}
-
-- (void) testCreateWithFieldValues
-{
-	NSError* error = nil;
-	NSString* key = @"value";
-	NSDictionary* values = [NSDictionary dictionaryWithObjectsAndKeys: @"test", key, nil];
-	BXDatabaseObject* object = [context createObjectForEntity: entity withFieldValues: values error: &error];
-	MKCAssertNotNil (object);
-	STAssertNil (error, [error description]);
-	MKCAssertTrue ([[object valueForKey: key] isEqual: [values valueForKey: key]]);
-	[context rollback];
-}
-
-- (void) testCreateCustom
-{
-    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-    NSError* error = nil;
-    Class objectClass = [TestObject class];
-    
-    [entity setDatabaseObjectClass: objectClass];
-    MKCAssertEqualObjects (objectClass, [entity databaseObjectClass]);
-    
-    BXDatabaseObject* object = [context createObjectForEntity: entity withFieldValues: nil error: &error];
-    MKCAssertNotNil (object);
-    STAssertNil (error, [error description]);
-    MKCAssertTrue ([object isKindOfClass: objectClass]);    
-    [context rollback];
-    [pool release];
-}
-
-@end

File UnitTests/EntityTests.h

-//
-// EntityTests.h
-// BaseTen
-//
-// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import <SenTestingKit/SenTestingKit.h>
-#import "TestLoader.h"
-
-@class BXDatabaseContext;
-
-
-@interface EntityTests : BXTestCase 
-{
-	BXDatabaseContext* ctx;
-}
-
-@end

File UnitTests/EntityTests.m

-//
-// EntityTests.m
-// BaseTen
-//
-// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import "EntityTests.h"
-#import "MKCSenTestCaseAdditions.h"
-#import <BaseTen/BaseTen.h>
-#import <BaseTen/BXDatabaseAdditions.h>
-
-
-@implementation EntityTests
-
-- (void) setUp
-{
-	ctx = [[BXDatabaseContext contextWithDatabaseURI: 
-        [NSURL URLWithString: @"pgsql://baseten_test_user@localhost/basetentest"]] retain];
-	[ctx setAutocommits: NO];
-}
-
-- (void) tearDown
-{
-	[ctx disconnect];
-	[ctx release];
-}
-
-- (void) testValidName
-{
-	NSError* error = nil;
-	NSString* schemaName = @"Fkeytest";
-	NSString* entityName = @"mtocollectiontest1";
-	BXEntityDescription* entity = [ctx entityForTable: entityName inSchema: schemaName error: &error];
-	STAssertNil (error, [error description]);
-	MKCAssertNotNil (entity);
-	MKCAssertEqualObjects ([entity name], entityName);
-	MKCAssertEqualObjects ([entity schemaName], schemaName);
-}
-
-- (void) testInvalidName
-{
-	NSError* error = nil;
-	NSString* schemaName = @"public";
-	NSString* entityName = @"aNonExistentTable";
-	[ctx connectIfNeeded: &error];
-	BXEntityDescription* entity = [ctx entityForTable: entityName inSchema: schemaName error: &error];
-	MKCAssertNotNil (error);
-	MKCAssertNil (entity);
-}
-
-- (void) testValidation
-{
-	NSError* error = nil;
-	[ctx connectIfNeeded: &error];
-	//This entity has fields only some of which are primary key.
-	BXEntityDescription* entity = [ctx entityForTable: @"mtmtest2" inSchema: @"Fkeytest" error: &error];
-	STAssertNotNil (entity, [NSString stringWithFormat: @"Entity was nil (error: %@)", error]);
-	
-	//The entity should be validated
-	MKCAssertNotNil ([entity fields]);
-	MKCAssertNotNil ([entity primaryKeyFields]);	
-}
-
-- (void) testLazyValidation
-{
-	NSError* error = nil;
-	NSString* entityName = @"mtocollectiontest1";
-	NSString* schemaName = @"Fkeytest";
-	BXEntityDescription* entity = [ctx entityForTable: entityName inSchema: schemaName error: &error];
-	STAssertNotNil (entity, [NSString stringWithFormat: @"Entity was nil (error: %@)", error]);
-	
-	BXDatabaseContext* ctx2 = [BXDatabaseContext contextWithDatabaseURI: [ctx databaseURI]];
-	MKCAssertFalse ([ctx2 isConnected]);
-	BXEntityDescription* entity2 = [ctx2 entityForTable: entityName inSchema: schemaName error: &error];
-	STAssertNotNil (entity, [NSString stringWithFormat: @"Entity was nil (error: %@)", error]);
-	MKCAssertTrue (entity == entity2);
-	
-	//Now the entity should be validated lazily
-	MKCAssertFalse ([ctx2 isConnected]);
-	STAssertNil (error, [error description]);
-}
-
-- (void) testHash
-{
-    BXEntityDescription* e1 = [ctx entityForTable: @"test2" inSchema: @"Fkeytest" error: nil];
-    BXEntityDescription* e2 = [ctx entityForTable: @"test2" inSchema: @"Fkeytest" error: nil];
-
-    NSSet* container3 = [NSSet setWithObject: e1];
-    MKCAssertNotNil ([container3 member: e1]);
-    MKCAssertNotNil ([container3 member: e2]);
-    MKCAssertTrue ([container3 containsObject: e1]);
-    MKCAssertTrue ([container3 containsObject: e2]);
-    MKCAssertEquals ([e1 hash], [e2 hash]);
-    MKCAssertEqualObjects (e1, e2);
-    
-    NSArray* container = [NSArray arrayWithObjects: 
-        [ctx entityForTable: @"mtmrel1"  inSchema: @"Fkeytest" error: nil],
-        [ctx entityForTable: @"mtmtest1" inSchema: @"Fkeytest" error: nil],
-        [ctx entityForTable: @"mtmtest2" inSchema: @"Fkeytest" error: nil],
-        [ctx entityForTable: @"ototest1" inSchema: @"Fkeytest" error: nil],
-        [ctx entityForTable: @"ototest2" inSchema: @"Fkeytest" error: nil],
-        [ctx entityForTable: @"test1"    inSchema: @"Fkeytest" error: nil],
-        nil];
-    NSSet* container2 = [NSSet setWithArray: container];
-
-    TSEnumerate (currentEntity, e, [container objectEnumerator])
-    {
-        MKCAssertFalse ([e1 hash] == [currentEntity hash]);
-        MKCAssertFalse ([e2 hash] == [currentEntity hash]);
-        MKCAssertFalse ([e1 isEqualTo: currentEntity]);
-        MKCAssertFalse ([e2 isEqualTo: currentEntity]);
-        MKCAssertTrue ([container containsObject: currentEntity]);
-        MKCAssertTrue ([container2 containsObject: currentEntity]);
-        MKCAssertNotNil ([container2 member: currentEntity]);
-    }
-
-    MKCAssertFalse ([container containsObject: e1]);
-    MKCAssertFalse ([container containsObject: e2]);
-    MKCAssertFalse ([container2 containsObject: e1]);
-    MKCAssertFalse ([container2 containsObject: e2]);    
-}
-
-@end

File UnitTests/FetchTests.h

-//
-// FetchTests.h
-// BaseTen
-//
-// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import <SenTestingKit/SenTestingKit.h>
-#import "TestLoader.h"
-@class BXDatabaseContext;
-@class BXEntityDescription;
-
-
-@interface FetchTests : BXTestCase 
-{
-    BXDatabaseContext* context;
-    BXEntityDescription* entity;
-}
-
-@end

File UnitTests/FetchTests.m

-//
-// FetchTests.m
-// BaseTen
-//
-// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import "FetchTests.h"
-#import "MKCSenTestCaseAdditions.h"
-
-#import <BaseTen/BaseTen.h>
-#import <BaseTen/BXDatabaseObjectIDPrivate.h>
-#import <BaseTen/BXDatabaseAdditions.h>
-#import <BaseTen/BXEntityDescriptionPrivate.h>
-
-
-@interface BXDatabaseObject (BXKVC)
-- (id) id1;
-- (id) id2;
-- (id) value1;
-@end
-
-
-@interface FetchTestObject : BXDatabaseObject
-{
-	@public
-	BOOL didTurnIntoFault;
-}
-@end
-
-
-@implementation FetchTestObject
-- (void) didTurnIntoFault
-{
-	didTurnIntoFault = YES;
-}
-@end
-
-
-@implementation FetchTests
-
-- (void) setUp
-{
-    context = [[BXDatabaseContext alloc] initWithDatabaseURI: 
-        [NSURL URLWithString: @"pgsql://baseten_test_user@localhost/basetentest"]];
-	[context setAutocommits: NO];
-	NSError* error = nil;
-    entity = [context entityForTable: @"test" error: &error];
-	STAssertNil (error, [error localizedDescription]);
-    MKCAssertNotNil (entity);
-}
-
-- (void) tearDown
-{
-	[context disconnect];
-    [context release];
-}
-
-- (void) testObjectWithID
-{
-    NSError* error = nil;
-	NSURL* objectURI = [NSURL URLWithString: @"pgsql://localhost/basetentest/public/test?id,n=1"];
-	BXDatabaseObjectID* anId = [[[BXDatabaseObjectID alloc] initWithURI: objectURI
-																context: context 
-																  error: &error] autorelease];
-	STAssertNil (error, [error localizedDescription]);
-    BXDatabaseObject* object = [context objectWithID: anId error: &error];
-	STAssertNil (error, [error localizedDescription]);
-    MKCAssertEqualObjects ([object primitiveValueForKey: @"id"], [NSNumber numberWithInt: 1]);
-    //if this is not nil, then another test has failed or the database is not in known state
-    STAssertEqualObjects ([object valueForKey: @"value"], nil, @"Database is not in known state!");
-}
-
-- (void) testMultiColumnPkey
-{
-    NSError* error = nil;
-    [context connectIfNeeded: nil];
-    
-    BXEntityDescription* multicolumnpkey = [context entityForTable: @"multicolumnpkey" error: nil];
-    MKCAssertNotNil (multicolumnpkey);
-    NSArray* multicolumnpkeys = [context executeFetchForEntity: multicolumnpkey withPredicate: nil error: &error];
-    MKCAssertNotNil (multicolumnpkeys);
-    MKCAssertTrue (3 == [multicolumnpkeys  count]);
-    STAssertNil (error, @"Error: %@", error);
-    
-    NSSortDescriptor* s1 = [[[NSSortDescriptor alloc] initWithKey: @"id1" ascending: YES] autorelease];
-    NSSortDescriptor* s2 = [[[NSSortDescriptor alloc] initWithKey: @"id2" ascending: YES] autorelease];
-    multicolumnpkeys = [multicolumnpkeys sortedArrayUsingDescriptors: [NSArray arrayWithObjects: s1, s2, nil]];
-    
-    id r1 = [multicolumnpkeys objectAtIndex: 0];
-    id r2 = [multicolumnpkeys objectAtIndex: 1];
-    id r3 = [multicolumnpkeys objectAtIndex: 2];
-    
-    NSNumber* id1 = [r1 id1];
-    MKCAssertEqualObjects (id1, [NSNumber numberWithInt: 1]);
-    MKCAssertEqualObjects ([r1 id2], [NSNumber numberWithInt: 1]);
-    MKCAssertEqualObjects ([r1 value1], @"thevalue1");
-    MKCAssertEqualObjects ([r2 id1], [NSNumber numberWithInt: 1]);
-    MKCAssertEqualObjects ([r2 id2], [NSNumber numberWithInt: 2]);
-    MKCAssertEqualObjects ([r2 value1], @"thevalue2");
-    MKCAssertEqualObjects ([r3 id1], [NSNumber numberWithInt: 2]);
-    MKCAssertEqualObjects ([r3 id2], [NSNumber numberWithInt: 3]);
-    MKCAssertEqualObjects ([r3 value1], @"thevalue3");
-}
-
-- (void) testDates
-{
-    NSError* error = nil;
-    [context connectIfNeeded: nil];
-    
-    BXEntityDescription* datetest = [context entityForTable: @"datetest" error: nil];
-    MKCAssertNotNil (datetest);
-    NSArray* dateobjects = [context executeFetchForEntity: datetest withPredicate: nil error: &error];
-    STAssertNil (error, [error localizedDescription]);
-    MKCAssertNotNil (dateobjects);
-}
-
-- (void) testQuery
-{
-	NSError* error = nil;
-	NSArray* result = [context executeQuery: [NSString stringWithUTF8String: "SELECT * FROM ♨"] error: &error];
-	STAssertNil (error, [error localizedDescription]);
-	MKCAssertTrue (3 == [result count]);
-	TSEnumerate (currentRow, e, [result objectEnumerator])
-		MKCAssertTrue (2 == [currentRow count]);
-}
-
-- (void) testCommand
-{
-	NSError* error = nil;
-	unsigned long long count = [context executeCommand: [NSString stringWithUTF8String: "UPDATE ♨ SET value = 'test'"] error: &error];
-	STAssertNil (error, [error localizedDescription]);
-	MKCAssertTrue (3 == count);
-}
-
-- (void) testNullValidation
-{
-	NSError* error = nil;
-	BXEntityDescription* person = [context entityForTable: @"person" error: &error];
-	NSArray* people = [context executeFetchForEntity: person withPredicate: nil error: &error];
-	BXDatabaseObject* personObject = [people objectAtIndex: 0];
-	
-	//soulmate has a non-null constraint.
-	id value = nil;
-	[personObject validateValue: &value forKey: @"soulmate" error: &error];
-	STAssertEqualObjects ([error domain], kBXErrorDomain, [error localizedDescription]);
-	STAssertTrue ([error code] == kBXErrorNullConstraintNotSatisfied, [error localizedDescription]);
-	
-	error = nil;
-	value = [NSNull null];
-	[personObject validateValue: &value forKey: @"soulmate" error: &error];
-	STAssertEqualObjects ([error domain], kBXErrorDomain, [error localizedDescription]);
-	STAssertTrue ([error code] == kBXErrorNullConstraintNotSatisfied, [error localizedDescription]);
-	
-	error = nil;
-	value = [NSNumber numberWithInt: 1];
-	[personObject validateValue: &value forKey: @"soulmate" error: &error];
-	STAssertNil (error, [error localizedDescription]);
-}
-
-- (void) testExclusion
-{
-	NSError* error = nil;
-	NSString* fieldname = @"value";
-	[context connectIfNeeded: &error];
-	STAssertNil (error, [error localizedDescription]);
-	BXAttributeDescription* property = [[entity attributesByName] objectForKey: fieldname];
-	MKCAssertFalse ([property isExcluded]);
-
-	NSArray* result = [context executeFetchForEntity: entity withPredicate: nil 
-									 excludingFields: [NSArray arrayWithObject: fieldname]
-											   error: &error];
-	STAssertNil (error, [error localizedDescription]);
-	MKCAssertTrue ([property isExcluded]);
-	
-	//Quite the same, which object we get
-	BXDatabaseObject* object = [result objectAtIndex: 0]; 
-	MKCAssertTrue (1 == [object isFaultKey: fieldname]);
-	[context fireFault: object key: fieldname error: &error];
-	STAssertNil (error, [error localizedDescription]);
-	MKCAssertTrue (0 == [object isFaultKey: fieldname]);
-	
-	[entity resetAttributeExclusion];
-}
-
-- (void) testJoin
-{
-	NSError* error = nil;
-	[context connectIfNeeded: &error];
-	STAssertNil (error, [error localizedDescription]);
-	
-	BXEntityDescription* person = [context entityForTable: @"person" error: &error];
-	STAssertNil (error, [error localizedDescription]);
-	
-	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"person_address.address = 'Mannerheimintie 1'"];
-	MKCAssertNotNil (predicate);
-	
-	//Make another predicate just to test compound predicates.
-	NSPredicate* truePredicate = [NSPredicate predicateWithFormat: @"TRUEPREDICATE"];
-	MKCAssertNotNil (truePredicate);
-	NSPredicate* compound = [NSCompoundPredicate andPredicateWithSubpredicates: 
-		[NSArray arrayWithObjects: predicate, truePredicate, nil]];
-	
-	NSArray* res = [context executeFetchForEntity: person withPredicate: compound error: &error];
-	STAssertNil (error, [error localizedDescription]);
-	
-	MKCAssertTrue (1 == [res count]);
-	MKCAssertEqualObjects ([[res objectAtIndex: 0] valueForKey: @"name"], @"nzhuk");
-}
-
-#if 0
-- (void) testJoin2
-{
-	NSError* error = nil;	
-	[context connectIfNeeded: &error];
-	STAssertNil (error, [error localizedDescription]);
-	
-	BXEntityDescription* order = [context entityForTable: @"order" error: &error];
-	STAssertNil (error, [error localizedDescription]);
-	BXEntityDescription* supplier = [context entityForTable: @"supplier" error: &error];
-	STAssertNil (error, [error localizedDescription]);
-	
-	BXPropertyDescription* supplierName = [[supplier attributesByName] objectForKey: @"supplier_name"];
-	BXPropertyDescription* poNumber = [[order attributesByName] objectForKey: @"po_number"];
-	BXPropertyDescription* supplierId = [[supplier attributesByName] objectForKey: @"supplier_id"];
-	BXPropertyDescription* orderSupplierId = [[order attributesByName] objectForKey: @"supplier_id"];
-	MKCAssertNotNil (supplierName);
-	MKCAssertNotNil (poNumber);
-	MKCAssertNotNil (supplierId);
-	MKCAssertNotNil (orderSupplierId);
-	
-    NSPredicate* predicate = [NSPredicate predicateWithFormat: 
-        @"%@ == %@ AND ((NOT %@ MATCHES[c] \"test\") OR %@ MATCHES[c] \"ferg\")", 
-		supplierId, orderSupplierId, poNumber, supplierName];
-    
-	NSArray* res = [context executeFetchForEntity: order withPredicate: predicate error: &error];
-	res = nil;
-}
-#endif
-
-- (void) testFault
-{
-	NSError* error = nil;
-	[entity setDatabaseObjectClass: [FetchTestObject class]];
-	NSArray* res = [context executeFetchForEntity: entity withPredicate: [NSPredicate predicateWithFormat: @"id = 1"]
-								  returningFaults: NO error: &error];
-	STAssertNil (error, [error localizedDescription]);
-	
-	FetchTestObject* object = [res objectAtIndex: 0];
-	MKCAssertFalse ([object isFaultKey: @"value"]);
-	
-	object->didTurnIntoFault = NO;
-	[object faultKey: @"value"];
-	MKCAssertTrue (object->didTurnIntoFault);
-	MKCAssertTrue ([object isFaultKey: nil]);
-	MKCAssertTrue ([object isFaultKey: @"value"]);
-	MKCAssertFalse ([object isFaultKey: @"id"]);
-	
-	object->didTurnIntoFault = NO;
-	[object primitiveValueForKey: @"value"];
-	[object faultKey: nil];
-	MKCAssertTrue (object->didTurnIntoFault);	
-	MKCAssertTrue ([object isFaultKey: nil]);
-	MKCAssertTrue ([object isFaultKey: @"value"]);
-	
-	object->didTurnIntoFault = NO;
-	[object valueForKey: @"value"];
-	[context refreshObject: object mergeChanges: YES];
-	MKCAssertFalse (object->didTurnIntoFault);
-	MKCAssertFalse ([object isFaultKey: @"value"]);
-	
-	object->didTurnIntoFault = NO;
-	[object valueForKey: @"value"];
-	[context refreshObject: object mergeChanges: NO];
-	MKCAssertTrue (object->didTurnIntoFault);
-	MKCAssertTrue ([object isFaultKey: nil]);
-	MKCAssertTrue ([object isFaultKey: @"value"]);
-		
-	[entity setDatabaseObjectClass: nil];
-}
-@end

File UnitTests/ForeignKeyModificationTests.h

-//
-// ForeignKeyModificationTests.h
-// BaseTen
-//
-// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import <SenTestingKit/SenTestingKit.h>
-#import "TestLoader.h"
-@class BXDatabaseContext;
-
-
-@interface ForeignKeyModificationTests : BXTestCase 
-{
-    BXDatabaseContext* context;
-    BXEntityDescription* test1;
-    BXEntityDescription* test2;
-    BXEntityDescription* ototest1;
-    BXEntityDescription* ototest2;
-    BXEntityDescription* mtmtest1;
-    BXEntityDescription* mtmtest2;
-    
-    BXEntityDescription* test1v;
-    BXEntityDescription* test2v;
-    BXEntityDescription* ototest1v;
-    BXEntityDescription* ototest2v;
-    BXEntityDescription* mtmtest1v;
-    BXEntityDescription* mtmtest2v;
-	BXEntityDescription* mtmrel1;
-}
-
-- (void) modMany: (BXEntityDescription *) manyEntity toOne: (BXEntityDescription *) oneEntity;
-- (void) modOne: (BXEntityDescription *) oneEntity toMany: (BXEntityDescription *) manyEntity;
-- (void) modOne: (BXEntityDescription *) entity1 toOne: (BXEntityDescription *) entity2;
-- (void) remove1: (BXEntityDescription *) oneEntity;
-- (void) remove2: (BXEntityDescription *) oneEntity;
-@end

File UnitTests/ForeignKeyModificationTests.m

-//
-// ForeignKeyModificationTests.m
-// BaseTen
-//
-// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import <BaseTen/BaseTen.h>
-#import <BaseTen/BXDatabaseAdditions.h>
-#import <BaseTen/BXEntityDescriptionPrivate.h>
-
-#import "ForeignKeyModificationTests.h"
-#import "MKCSenTestCaseAdditions.h"
-
-
-@implementation ForeignKeyModificationTests
-
-- (void) setUp
-{
-    context = [[BXDatabaseContext alloc] initWithDatabaseURI: 
-        [NSURL URLWithString: @"pgsql://baseten_test_user@localhost/basetentest"]];
-    [context setAutocommits: NO];
-    MKCAssertNotNil (context);
-    
-    test1 		= [[context entityForTable: @"test1" inSchema: @"Fkeytest" error: nil] retain];
-    test2 		= [[context entityForTable: @"test2" inSchema: @"Fkeytest" error: nil] retain];
-    ototest1 	= [[context entityForTable: @"ototest1" inSchema: @"Fkeytest" error: nil] retain];
-    ototest2 	= [[context entityForTable: @"ototest2" inSchema: @"Fkeytest" error: nil] retain];
-    mtmtest1 	= [[context entityForTable: @"mtmtest1" inSchema: @"Fkeytest" error: nil] retain];
-    mtmtest2 	= [[context entityForTable: @"mtmtest2" inSchema: @"Fkeytest" error: nil] retain];
-
-    MKCAssertNotNil (test1);
-    MKCAssertNotNil (test2);
-    MKCAssertNotNil (ototest1);
-    MKCAssertNotNil (ototest2);
-    MKCAssertNotNil (mtmtest1);
-    MKCAssertNotNil (mtmtest2);
-
-    test1v		= [[context entityForTable: @"test1_v" inSchema: @"Fkeytest" error: nil] retain];
-    test2v		= [[context entityForTable: @"test2_v" inSchema: @"Fkeytest" error: nil] retain];
-    ototest1v	= [[context entityForTable: @"ototest1_v" inSchema: @"Fkeytest" error: nil] retain];
-    ototest2v	= [[context entityForTable: @"ototest2_v" inSchema: @"Fkeytest" error: nil] retain];
-    mtmtest1v	= [[context entityForTable: @"mtmtest1_v" inSchema: @"Fkeytest" error: nil] retain];
-    mtmtest2v	= [[context entityForTable: @"mtmtest2_v" inSchema: @"Fkeytest" error: nil] retain];
-	mtmrel1		= [[context entityForTable: @"mtmrel1" inSchema: @"Fkeytest" error: nil] retain];
-    
-    MKCAssertNotNil (test1v);
-    MKCAssertNotNil (test2v);
-    MKCAssertNotNil (ototest1v);
-    MKCAssertNotNil (ototest2v);
-    MKCAssertNotNil (mtmtest1v);
-    MKCAssertNotNil (mtmtest2v);
-	MKCAssertNotNil (mtmrel1);
-}
-
-- (void) tearDown
-{
-	[context disconnect];
-    [context release];
-	[test1 release];
-	[test2 release];	
-	[ototest1 release];
-	[ototest2 release];
-	[mtmtest1 release];
-	[mtmtest2 release];
-	[test1v release];
-	[test2v release];
-	[ototest1v release];
-	[ototest2v release];
-	[mtmtest1v release];
-	[mtmtest2v release];
-	[mtmrel1 release];
-}
-
-- (void) modMany: (BXEntityDescription *) manyEntity toOne: (BXEntityDescription *) oneEntity
-{
-    //Change reference in foreignObject from id=1 to id=2
-    NSError* error = nil;
-    MKCAssertTrue (NO == [context autocommits]);
-    
-    NSArray* res = [context executeFetchForEntity: manyEntity
-                                    withPredicate: [NSPredicate predicateWithFormat: @"id = 1"]
-                                            error: &error];
-    MKCAssertNotNil (res);
-    STAssertNil (error, [error localizedDescription]);
-    MKCAssertTrue (1 == [res count]);
-    BXDatabaseObject* foreignObject = [res objectAtIndex: 0];
-    MKCAssertTrue ([[foreignObject objectID] entity] == manyEntity);
-
-    res = [context executeFetchForEntity: oneEntity
-						   withPredicate: [NSPredicate predicateWithFormat: @"id = 2"]
-								   error: &error];
-    STAssertNil (error, [error localizedDescription]);
-    MKCAssertTrue (1 == [res count]);
-    BXDatabaseObject* object = [res objectAtIndex: 0];
-    MKCAssertTrue ([[object objectID] entity] == oneEntity);
-    
-    MKCAssertFalse ([[foreignObject primitiveValueForKey: [oneEntity name]] isEqual: object]);
-    [foreignObject setPrimitiveValue: object forKey: [oneEntity name]];
-    MKCAssertEqualObjects ([foreignObject primitiveValueForKey: [oneEntity name]], object);
-    
-    [context rollback];
-}
-
-- (void) modOne: (BXEntityDescription *) oneEntity toMany: (BXEntityDescription *) manyEntity
-{
-    //Create an object to oneEntity and add referencing objects to manyEntity
-    NSError* error = nil;
-        
-    BXDatabaseObject* object = [context createObjectForEntity: oneEntity withFieldValues: nil error: &error];
-    STAssertNil (error, [error localizedDescription]);
-    MKCAssertNotNil (object);
-	//If the set proxy wasn't created earlier, here it will be. This might be useful for debugging.
-    STAssertTrue (0 == [[object valueForKey: [manyEntity name]] count], [[object valueForKey: [manyEntity name]] description]);
-    MKCAssertTrue ([[object objectID] entity] == oneEntity);
-    
-    const int count = 2;
-    NSMutableSet* foreignObjects = [NSMutableSet setWithCapacity: count];
-    for (int i = 0; i < count; i++)
-    {
-        BXDatabaseObject* foreignObject = [context createObjectForEntity: manyEntity withFieldValues: nil error: &error];
-        STAssertNil (error, [error localizedDescription]);
-        MKCAssertNotNil (foreignObject);
-        MKCAssertTrue ([[foreignObject objectID] entity] == manyEntity);
-        [foreignObjects addObject: foreignObject];
-    }
-    MKCAssertTrue (count == [foreignObjects count]);
-    
-	[object setPrimitiveValue: foreignObjects forKey: [manyEntity name]];
-    
-    NSSet* referencedObjects = [NSSet setWithSet: [object primitiveValueForKey: [manyEntity name]]];
-    MKCAssertEqualObjects (referencedObjects, foreignObjects);
-
-    [context rollback];
-}
-
-- (void) modOne: (BXEntityDescription *) entity1 toOne: (BXEntityDescription *) entity2
-{
-    //Change a reference in entity1 and entity2
-    
-    NSError* error = nil;
-	[context connectSync: &error];
-    STAssertNil (error, [error localizedDescription]);
-	
-    MKCAssertFalse ([[[entity1 relationshipsByName] objectForKey: [entity2 name]] isToMany]);
-    MKCAssertFalse ([[[entity2 relationshipsByName] objectForKey: [entity1 name]] isToMany]);
-    
-    NSArray* res = [context executeFetchForEntity: entity1
-                                    withPredicate: [NSPredicate predicateWithFormat: @"id = 1"]
-                                            error: &error];
-    STAssertNil (error, [error localizedDescription]);
-    MKCAssertTrue (1 == [res count]);
-    BXDatabaseObject* object = [res objectAtIndex: 0];
-    MKCAssertTrue ([[object objectID] entity] == entity1);
-    
-    res = [context executeFetchForEntity: entity2
-                           withPredicate: [NSPredicate predicateWithFormat: @"id = 1"]
-                                   error: &error];
-    STAssertNil (error, [error localizedDescription]);
-    MKCAssertTrue (1 == [res count]);
-    BXDatabaseObject* foreignObject1 = [res objectAtIndex: 0];
-    MKCAssertTrue ([[foreignObject1 objectID] entity] == entity2);
-    
-    BXDatabaseObject* foreignObject2 = [object valueForKey: [entity2 name]];
-    MKCAssertFalse ([foreignObject1 isEqual: foreignObject2]);
-    MKCAssertFalse (foreignObject1 == foreignObject2);
-    MKCAssertTrue ([[foreignObject2 objectID] entity] == entity2);
-    
-    [object setPrimitiveValue: foreignObject1 forKey: [entity2 name]];
-    NSNumber* n1 = [NSNumber numberWithInt: 1];
-    MKCAssertEqualObjects (n1, [foreignObject1 primitiveValueForKey: @"r1"]);
-    MKCAssertEqualObjects (n1, [object primitiveValueForKey: @"id"]);
-    MKCAssertEqualObjects (n1, [foreignObject1 primitiveValueForKey: @"id"]);
-    MKCAssertTrue (nil == [foreignObject2 primitiveValueForKey: @"r1"]);
-    MKCAssertFalse ([n1 isEqual: [foreignObject2 primitiveValueForKey: @"id"]]);
-
-    [context rollback];
-}
-
-- (BXDatabaseObject *) removeRefObject: (BXEntityDescription *) entity
-{
-    NSError* error = nil;
-    NSArray* res = [context executeFetchForEntity: entity
-                                    withPredicate: [NSPredicate predicateWithFormat: @"id = 1"]
-                                            error: &error];
-    
-    STAssertNil (error, [error localizedDescription]);
-    return [res objectAtIndex: 0];
-}
-
-- (void) remove1: (BXEntityDescription *) oneEntity
-{
-    BXDatabaseObject* object = [self removeRefObject: oneEntity];
-    [object setPrimitiveValue: nil forKey: @"test2"];
-
-    [context rollback];
-}
-
-- (void) remove2: (BXEntityDescription *) oneEntity
-{
-    BXDatabaseObject* object = [self removeRefObject: oneEntity];
-    NSSet* refObjects = [object primitiveValueForKey: @"test2"];
-    TSEnumerate (currentObject, e, [[refObjects allObjects] objectEnumerator])
-        [currentObject setPrimitiveValue: nil forKey: @"test1"];
-    
-    [context rollback];
-}
-
-@end
-
-
-@implementation ForeignKeyModificationTests (Tests)
-
-- (void) testRemove1
-{
-    [self remove1: test1];
-}
-
-- (void) testRemoveView1
-{
-    [self remove1: test1v];
-}
-
-- (void) testRemove2
-{
-    [self remove2: test1];
-}
-
-- (void) testRemoveView2
-{
-    [self remove2: test1v];
-}
-
-- (void) testModMTO
-{
-    [self modMany: test2 toOne: test1];
-}
-
-- (void) testModMTOView
-{
-    [self modMany: test2v toOne: test1v];
-}
-
-- (void) testModOTM
-{
-    [self modOne: test1 toMany: test2];
-}
-
-//FIXME: this doesn't work for views because we don't provide values for the primary key.
-#if 0
-- (void) testModOTMView
-{
-    [self modOne: test1v toMany: test2v];
-}
-#endif
-
-- (void) testModOTM2
-{
-    //FIXME: also write a view test?
-	MKCAssertFalse ([context autocommits]);
-	
-    NSError* error = nil;
-    NSPredicate* predicate = [NSPredicate predicateWithFormat: @"id = %d", 1];
-    MKCAssertNotNil (predicate);
-    NSArray* res = [context executeFetchForEntity: test1
-                                    withPredicate: predicate
-                                            error: &error];
-    STAssertNil (error, [error description]);
-    MKCAssertTrue (1 == [res count]);
-    BXDatabaseObject* object = [res objectAtIndex: 0];
-    //Create a self-updating container to see if it interferes with object creation.
-    id collection = [object valueForKey: @"test2"];
-    
-    NSDictionary* values = [NSDictionary dictionaryWithObjectsAndKeys:
-							[object primitiveValueForKey: @"id"], @"fkt1id",
-							@"test", @"value",
-							nil];
-    [context createObjectForEntity: test2 withFieldValues: values error: &error];
-    STAssertNil (error, [error description]);
-    
-    collection = nil;
-    [context rollback];
-}
-
-- (void) testModOTO
-{
-    [self modOne: ototest1 toOne: ototest2];
-}
-
-- (void) testModOTOView
-{
-    [self modOne: ototest1v toOne: ototest2v];
-}
-
-@end

File UnitTests/ForeignKeyTests.h

-//
-// ForeignKeyTests.h
-// BaseTen
-//
-// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import <SenTestingKit/SenTestingKit.h>
-#import "TestLoader.h"
-@class BXDatabaseContext;
-
-
-@interface ForeignKeyTests : BXTestCase 
-{
-    BXDatabaseContext* context;
-    BXEntityDescription* test1;
-    BXEntityDescription* test2;
-    BXEntityDescription* ototest1;
-    BXEntityDescription* ototest2;
-    BXEntityDescription* mtmtest1;
-    BXEntityDescription* mtmtest2;
-    
-    BXEntityDescription* test1v;
-    BXEntityDescription* test2v;
-    BXEntityDescription* ototest1v;
-    BXEntityDescription* ototest2v;
-    BXEntityDescription* mtmtest1v;
-    BXEntityDescription* mtmtest2v;
-	BXEntityDescription* mtmrel1;
-}
-
-- (void) many: (BXEntityDescription *) manyEntity toOne: (BXEntityDescription *) oneEntity;
-- (void) one: (BXEntityDescription *) oneEntity toMany: (BXEntityDescription *) manyEntity;
-- (void) one: (BXEntityDescription *) entity1 toOne: (BXEntityDescription *) entity2;
-- (void) many: (BXEntityDescription *) entity1 toMany: (BXEntityDescription *) entity2;
-- (void) MTMHelper: (BXEntityDescription *) entity;
-@end

File UnitTests/ForeignKeyTests.m

-//
-// ForeignKeyTests.m
-// BaseTen
-//
-// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import <BaseTen/BaseTen.h>
-#import <BaseTen/BXDatabaseAdditions.h>
-#import <BaseTen/BXEntityDescriptionPrivate.h>
-#import <BaseTen/BXRelationshipDescriptionPrivate.h>
-
-#import "ForeignKeyTests.h"
-#import "MKCSenTestCaseAdditions.h"
-
-
-@implementation ForeignKeyTests
-
-- (void) setUp
-{
-    context = [[BXDatabaseContext alloc] initWithDatabaseURI: 
-        [NSURL URLWithString: @"pgsql://baseten_test_user@localhost/basetentest"]];
-    [context setAutocommits: NO];
-    MKCAssertNotNil (context);
-    
-    test1 = [context entityForTable: @"test1" inSchema: @"Fkeytest" error: nil];
-    test2 = [context entityForTable: @"test2" inSchema: @"Fkeytest" error: nil];
-    ototest1 = [context entityForTable: @"ototest1" inSchema: @"Fkeytest" error: nil];
-    ototest2 = [context entityForTable: @"ototest2" inSchema: @"Fkeytest" error: nil];
-    mtmtest1 = [context entityForTable: @"mtmtest1" inSchema: @"Fkeytest" error: nil];
-    mtmtest2 = [context entityForTable: @"mtmtest2" inSchema: @"Fkeytest" error: nil];
-
-    MKCAssertNotNil (test1);
-    MKCAssertNotNil (test2);
-    MKCAssertNotNil (ototest1);
-    MKCAssertNotNil (ototest2);
-    MKCAssertNotNil (mtmtest1);
-    MKCAssertNotNil (mtmtest2);
-
-    test1v = [context entityForTable: @"test1_v" inSchema: @"Fkeytest" error: nil];
-    test2v = [context entityForTable: @"test2_v" inSchema: @"Fkeytest" error: nil];
-    ototest1v = [context entityForTable: @"ototest1_v" inSchema: @"Fkeytest" error: nil];
-    ototest2v = [context entityForTable: @"ototest2_v" inSchema: @"Fkeytest" error: nil];
-    mtmtest1v = [context entityForTable: @"mtmtest1_v" inSchema: @"Fkeytest" error: nil];
-    mtmtest2v = [context entityForTable: @"mtmtest2_v" inSchema: @"Fkeytest" error: nil];
-	mtmrel1 = [context entityForTable: @"mtmrel1" inSchema: @"Fkeytest" error: nil];
-    
-    MKCAssertNotNil (test1v);
-    MKCAssertNotNil (test2v);
-    MKCAssertNotNil (ototest1v);
-    MKCAssertNotNil (ototest2v);
-    MKCAssertNotNil (mtmtest1v);
-    MKCAssertNotNil (mtmtest2v);
-	MKCAssertNotNil (mtmrel1);
-}
-
-- (void) tearDown
-{
-	[context disconnect];
-    [context release];
-}
-
-- (void) test1MTO
-{
-    [self many: test2 toOne: test1];
-}
-
-- (void) test4MTOView
-{
-    [self many: test2v toOne: test1v];
-}
-
-- (void) many: (BXEntityDescription *) manyEntity toOne: (BXEntityDescription *) oneEntity
-{
-    NSError* error = nil;
-    for (int i = 1; i <= 3; i++)
-    {
-        NSPredicate* predicate = [NSPredicate predicateWithFormat: @"id = %d", i];
-        MKCAssertNotNil (predicate);
-        NSArray* res = [context executeFetchForEntity: manyEntity
-                                        withPredicate: predicate
-                                                error: &error];
-        STAssertNil (error, [error description]);
-        MKCAssertTrue (1 == [res count]);
-    
-        BXDatabaseObject* object = [res objectAtIndex: 0];
-		MKCAssertTrue ([object isFaultKey: [oneEntity name]]);
-		
-        BXDatabaseObject* foreignObject = [object primitiveValueForKey: [oneEntity name]];
-
-        //See that the object has the given entity
-        MKCAssertTrue ([[object objectID] entity] == manyEntity);
-        
-        //The row with id == 3 has null value for the foreign key
-        if (3 == i)
-        {
-            MKCAssertNil (foreignObject);
-            MKCAssertNil ([object valueForKeyPath: @"test1.value"]);
-        }
-        else
-        {
-            MKCAssertNotNil (foreignObject);
-            //See that the object has the given entity
-            MKCAssertTrue ([[foreignObject objectID] entity] == oneEntity);
-            MKCAssertTrue ([@"11" isEqualToString: [foreignObject valueForKey: @"value"]]);
-            MKCAssertTrue ([@"11" isEqualToString: [object valueForKeyPath: @"test1.value"]]);
-        }
-    }
-}
-
-- (void) test1OTM
-{
-    [self one: test1 toMany: test2];
-}
-
-- (void) test4OTMView
-{
-    [self one: test1v toMany: test2v];
-}
-
-- (void) one: (BXEntityDescription *) oneEntity toMany: (BXEntityDescription *) manyEntity
-{
-    NSError* error = nil;
-    NSPredicate* predicate = [NSPredicate predicateWithFormat: @"id = %d", 1];
-    MKCAssertNotNil (predicate);
-    NSArray* res = [context executeFetchForEntity: oneEntity
-                                    withPredicate: predicate
-                                            error: &error];
-    STAssertNil (error, [error description]);
-    MKCAssertTrue (1 == [res count]);
-    BXDatabaseObject* object = [res objectAtIndex: 0];
-
-    //See that the object has the given entity
-    MKCAssertTrue ([[object objectID] entity] == oneEntity);
-    
-    BXRelationshipDescription* rel = [[manyEntity relationshipsByName] objectForKey: [oneEntity name]];
-    MKCAssertNotNil (rel);
-    MKCAssertFalse ([rel isToMany]);
-	rel = [rel inverseRelationship];
-    MKCAssertNotNil (rel);
-    MKCAssertTrue ([rel isToMany]);
-        
-    NSSet* foreignObjects = [rel targetForObject: object error: &error];
-    STAssertNil (error, [error description]);
-    MKCAssertTrue (2 == [foreignObjects count]);
-    NSArray* values = [foreignObjects valueForKey: @"value"];
-    MKCAssertTrue ([values containsObject: @"21"]);
-    MKCAssertTrue ([values containsObject: @"22"]);    
-    //See that the objects have the given entities
-    TSEnumerate (currentObject, e, [foreignObjects objectEnumerator])
-        MKCAssertTrue ([[currentObject objectID] entity] == manyEntity);
-
-    foreignObjects = [object valueForKey: [manyEntity name]];
-    STAssertNil (error, [error description]);
-    MKCAssertTrue (2 == [foreignObjects count]);
-    values = [foreignObjects valueForKey: @"value"];
-    MKCAssertTrue ([values containsObject: @"21"]);
-    MKCAssertTrue ([values containsObject: @"22"]);
-    //See that the objects have the given entities
-    TSEnumerate (currentObject, e, [foreignObjects objectEnumerator])
-        MKCAssertTrue ([[currentObject objectID] entity] == manyEntity);
-}
-
-- (void) test2OTO
-{
-    [self one: ototest1 toOne: ototest2];
-}
-
-- (void) test5OTOView
-{
-    [self one: ototest1v toOne: ototest2v];
-}
-
-- (void) one: (BXEntityDescription *) entity1 toOne: (BXEntityDescription *) entity2
-{
-    NSError* error = nil;
-	
-	[context connectIfNeeded: &error];
-	STAssertNil (error, [error localizedDescription]);
-	
-    BXRelationshipDescription* foobar = [[entity1 relationshipsByName] objectForKey: [entity2 name]];
-    MKCAssertNotNil (foobar);
-    MKCAssertFalse ([foobar isToMany]);
-	MKCAssertFalse ([[foobar inverseRelationship] isToMany]);
-
-    NSArray* res = [context executeFetchForEntity: entity1 
-                                    withPredicate: [NSPredicate predicateWithFormat: @"1 <= id && id <= 2"]
-                                            error: &error];
-    STAssertNil (error, [error description]);
-    MKCAssertTrue (2 == [res count]);
-    for (int i = 0; i < 2; i++)
-    {
-        BXDatabaseObject* object = [res objectAtIndex: i];
-        
-        BXDatabaseObject* foreignObject  = [object primitiveValueForKey: [entity2 name]];
-        BXDatabaseObject* foreignObject2 = [foobar targetForObject: object error: &error];
-        STAssertNil (error, [error description]);
-        
-        BXDatabaseObject* object2 = [foreignObject primitiveValueForKey: [entity1 name]];
-        BXDatabaseObject* object3 = [[foobar inverseRelationship] targetForObject: foreignObject error: &error];
-        STAssertNil (error, [error description]);
-        
-        MKCAssertTrue ([[foreignObject  objectID] entity] == entity2);
-        MKCAssertTrue ([[foreignObject2 objectID] entity] == entity2);
-        MKCAssertTrue ([[object  objectID] entity] == entity1);
-        MKCAssertTrue ([[object2 objectID] entity] == entity1);
-        MKCAssertTrue ([[object3 objectID] entity] == entity1);
-        MKCAssertEqualObjects (foreignObject, foreignObject2);
-        MKCAssertEqualObjects (object, object2);
-        MKCAssertEqualObjects (object2, object3);
-
-        //See that the objects have the given entities
-        MKCAssertTrue ([[object  objectID] entity] == entity1);
-        MKCAssertTrue ([[object2 objectID] entity] == entity1);
-        MKCAssertTrue ([[object3 objectID] entity] == entity1);
-        MKCAssertTrue ([[foreignObject  objectID] entity] == entity2);
-        MKCAssertTrue ([[foreignObject2 objectID] entity] == entity2);
-
-        NSNumber* value = [object valueForKey: @"id"];
-        NSNumber* value2 = [foreignObject valueForKey: @"id"];
-        MKCAssertFalse ([value isEqual: value2]);
-    }
-    
-    res = [context executeFetchForEntity: entity2
-                           withPredicate: [NSPredicate predicateWithFormat: @"id = 3"]
-                                   error: &error];
-    STAssertNil (error, [error description]);
-    MKCAssertTrue (1 == [res count]);
-    BXDatabaseObject* object = [res objectAtIndex: 0];
-    MKCAssertNil ([object valueForKey: [entity1 name]]);
-    MKCAssertTrue ([[object objectID] entity] == entity2);
-}
-
-- (void) test3MTM
-{
-    [self many: mtmtest1 toMany: mtmtest2];
-}
-
-- (void) test6MTMView
-{
-    [self many: mtmtest1v toMany: mtmtest2v];
-}
-
-- (void) many: (BXEntityDescription *) entity1 toMany: (BXEntityDescription *) entity2
-{
-    NSError* error = nil;
-    NSArray* res = [context executeFetchForEntity: entity1 withPredicate: nil error: &error];
-    STAssertNil (error, [error description]);
-    MKCAssertTrue (4 == [res count]);
-    
-    NSSet* expected1 = [NSSet setWithObjects: @"a1", @"b1", @"c1", nil];
-    NSSet* expected2 = [NSSet setWithObjects: @"a2", @"b2", @"c2", nil];
-    
-    TSEnumerate (object, e, [res objectEnumerator])
-    {
-        MKCAssertTrue ([[object objectID] entity] == entity1);
-        
-        NSSet* foreignObjects = [object primitiveValueForKey: [entity2 name]];
-        MKCAssertNotNil (foreignObjects);
-        if ([@"d1" isEqualToString: [object valueForKey: @"value1"]])
-        {
-            MKCAssertTrue (1 == [foreignObjects count]);
-            BXDatabaseObject* foreignObject = [foreignObjects anyObject];
-            MKCAssertTrue ([[foreignObject objectID] entity] == entity2);
-
-            MKCAssertEqualObjects ([foreignObject valueForKey: @"value2"], @"d2");
-            NSSet* objects = [foreignObject valueForKey: [entity1 name]];
-            MKCAssertTrue (1 == [objects count]);
-            BXDatabaseObject* backRef = [objects anyObject];
-            MKCAssertTrue ([[backRef objectID] entity] == entity1);
-            MKCAssertEqualObjects ([backRef valueForKey: @"value1"], @"d1");
-        }
-        else
-        {
-            MKCAssertTrue (3 == [foreignObjects count]);
-            
-            NSSet* values2 = [foreignObjects valueForKey: @"value2"];
-            MKCAssertEqualObjects (values2, expected2);
-            
-            TSEnumerate (foreignObject, e, [foreignObjects objectEnumerator])
-            {
-                MKCAssertTrue ([[foreignObject objectID] entity] == entity2);
-                NSArray* objects = [foreignObject valueForKey: [entity1 name]];
-                MKCAssertNotNil (objects);
-                MKCAssertTrue (3 == [objects count]);
-                
-                NSSet* values1 = [objects valueForKey: @"value1"];
-                MKCAssertEqualObjects (values1, expected1);
-                
-                TSEnumerate (backRef, e, [objects objectEnumerator])
-                    MKCAssertTrue ([[backRef objectID] entity] == entity1);
-            }
-        }
-    }
-}
-
-- (void) test3MTMHelper
-{
-	[self MTMHelper: mtmtest1];
-}
-
-- (void) test6MTMHelperView
-{
-	[self MTMHelper: mtmtest1v];
-}
-
-- (void) MTMHelper: (BXEntityDescription *) entity
-{
-	NSError* error = nil;
-	NSArray* res = [context executeFetchForEntity: entity
-									withPredicate: [NSPredicate predicateWithFormat: @"id = 1"]
-											error: &error];
-	STAssertNil (error, [error localizedDescription]);
-	BXDatabaseObject* object = [res objectAtIndex: 0];
-	NSSet* helperObjects = [object primitiveValueForKey: @"mtmrel1"];
-	MKCAssertTrue (3 == [helperObjects count]);
-	TSEnumerate (currentObject, e, [helperObjects objectEnumerator])
-	{
-		MKCAssertTrue ([[currentObject objectID] entity] == mtmrel1);
-		MKCAssertTrue (1 == [[currentObject valueForKey: @"id1"] intValue]);
-	}
-}
-    
-@end

File UnitTests/KeyPathComponentTest.h

-//
-// KeyPathComponentTest.h
-// BaseTen
-//
-// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import <SenTestingKit/SenTestingKit.h>
-#import "TestLoader.h"
-
-
-@interface KeyPathComponentTest : BXTestCase 
-{
-}
-@end

File UnitTests/KeyPathComponentTest.m

-//
-// KeyPathComponentTest.m
-// BaseTen
-//
-// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import "KeyPathComponentTest.h"
-#import "MKCSenTestCaseAdditions.h"
-#import <BaseTen/BXKeyPathParser.h>
-
-
-@implementation KeyPathComponentTest
-- (void) testKeyPath
-{
-	NSString* keyPath = @"aa.bb.cc";
-	NSArray* components = BXKeyPathComponents (keyPath);
-	MKCAssertEqualObjects (components, ([NSArray arrayWithObjects: @"aa", @"bb", @"cc", nil]));
-}
-
-- (void) testQuotedKeyPAth
-{
-	NSString* keyPath = @"\"aa.bb\".cc";
-	NSArray* components = BXKeyPathComponents (keyPath);
-	MKCAssertEqualObjects (components, ([NSArray arrayWithObjects: @"aa.bb", @"cc", nil]));
-}
-
-- (void) testSingleComponent
-{
-	NSString* keyPath = @"aa";
-	NSArray* components = BXKeyPathComponents (keyPath);
-	MKCAssertEqualObjects (components, ([NSArray arrayWithObjects: @"aa", nil]));
-}
-
-- (void) testRecurringFullStops
-{
-	NSString* keyPath = @"aa..bb";
-	MKCAssertThrowsSpecificNamed (BXKeyPathComponents (keyPath), NSException, NSInvalidArgumentException);
-}
-
-- (void) testEndingFullStop
-{
-	NSString* keyPath = @"aa.";
-	MKCAssertThrowsSpecificNamed (BXKeyPathComponents (keyPath), NSException, NSInvalidArgumentException);
-}
-
-- (void) testBeginningFullStop
-{
-	NSString* keyPath = @".aa";
-	MKCAssertThrowsSpecificNamed (BXKeyPathComponents (keyPath), NSException, NSInvalidArgumentException);
-}
-@end

File UnitTests/MKCSenTestCaseAdditions.h

-//
-// MKCSenTestCaseAdditions.h
-// BaseTen
-//
-// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-/*!
-    Some macros which extend SenTestCase.h with assertion methods which don't require a description string.
-    Adds also a macro to run the current runloop in default mode until some condition becomes FALSE or timeout occurs.
-*/
-
-#import <SenTestingKit/SenTestingKit.h>
-
-#define MKC_ASSERT_DESCRIPTION @"Assertion failed"
-
-#define MKCAssertNil(a1) STAssertNil(a1, MKC_ASSERT_DESCRIPTION)
-#define MKCAssertNotNil(a1) STAssertNotNil(a1, MKC_ASSERT_DESCRIPTION)
-#define MKCAssertTrue(expression) STAssertTrue(expression, MKC_ASSERT_DESCRIPTION)
-#define MKCAssertFalse(expression) STAssertFalse(expression, MKC_ASSERT_DESCRIPTION)
-#define MKCAssertEqualObjects(a1, a2) STAssertEqualObjects(a1, a2, MKC_ASSERT_DESCRIPTION)
-#define MKCAssertEquals(a1, a2) STAssertEquals(a1, a2, MKC_ASSERT_DESCRIPTION)
-#define MKCAssertEqualsWithAccuracy(left, right, accuracy) STAssertEqualsWithAccuracy(left, right, accuracy, MKC_ASSERT_DESCRIPTION)
-#define MKCAssertThrows(expression) STAssertThrows(expression, MKC_ASSERT_DESCRIPTION)
-#define MKCAssertThrowsSpecific(expression, specificException) STAssertThrowsSpecific(expression, specificException, MKC_ASSERT_DESCRIPTION)
-#define MKCAssertThrowsSpecificNamed(expr, specificException, aName) STAssertThrowsSpecificNamed(expr, specificException, aName, MKC_ASSERT_DESCRIPTION)
-#define MKCAssertNoThrow(expression) STAssertNoThrow(expression, MKC_ASSERT_DESCRIPTION)
-#define MKCAssertNoThrowSpecific(expression, specificException) STAssertNoThrowSpecific(expression, specificException, MKC_ASSERT_DESCRIPTION)
-#define MKCAssertNoThrowSpecificNamed(expr, specificException, aName) STAssertNoThrowSpecificNamed(expr, specificException, aName, MKC_ASSERT_DESCRIPTION)
-#define MKCFail() STFail(MKC_ASSERT_DESCRIPTION)
-#define MKCAssertTrueNoThrow(expression) STAssertTrueNoThrow(expression, MKC_ASSERT_DESCRIPTION)
-#define MKCAssertFalseNoThrow(expression) STAssertFalseNoThrow(expression, MKC_ASSERT_DESCRIPTION)
-
-#define MKCRunLoopRunWithConditionAndTimeout(loopCondition, timeoutInSeconds) \
-{ \
-    NSDate *runLoopTimeout = [NSDate dateWithTimeIntervalSinceNow: timeoutInSeconds]; \
-    while ((loopCondition) && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:runLoopTimeout]) \
-    { \
-        NSDate *currentDate = [NSDate date]; \
-        if([currentDate compare:runLoopTimeout] != NSOrderedAscending) \
-            break; \
-    } \
-}

File UnitTests/MTMCollectionTest.h

-//
-// MTMCollectionTest.h
-// BaseTen
-//
-// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import <SenTestingKit/SenTestingKit.h>
-#import "TestLoader.h"
-@class BXDatabaseContext;
-@class BXEntityDescription;
-
-
-@interface MTMCollectionTest : BXTestCase 
-{
-    BXDatabaseContext* context;
-    BXEntityDescription* mtmtest1;
-    BXEntityDescription* mtmtest2;    
-    BXEntityDescription* mtmtest1v;
-    BXEntityDescription* mtmtest2v;    
-}
-
-- (void) modMany: (BXEntityDescription *) entity1 toMany: (BXEntityDescription *) entity2;
-
-@end

File UnitTests/MTMCollectionTest.m

-//
-// MTMCollectionTest.m
-// BaseTen
-//
-// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import "MTMCollectionTest.h"
-#import "MKCSenTestCaseAdditions.h"
-#import "UnitTestAdditions.h"
-
-#import <BaseTen/BaseTen.h>
-#import <BaseTen/BXDatabaseAdditions.h>
-
-
-@implementation MTMCollectionTest
-
-- (void) setUp
-{
-    context = [[BXDatabaseContext alloc] initWithDatabaseURI: 
-        [NSURL URLWithString: @"pgsql://baseten_test_user@localhost/basetentest"]];
-    [context setAutocommits: NO];
-    MKCAssertNotNil (context);
-    
-    mtmtest1 = [context entityForTable: @"mtmtest1" inSchema: @"Fkeytest" error: nil];
-    mtmtest2 = [context entityForTable: @"mtmtest2" inSchema: @"Fkeytest" error: nil];
-    MKCAssertNotNil (mtmtest1);
-    MKCAssertNotNil (mtmtest2);
-    
-    mtmtest1v = [context entityForTable: @"mtmtest1_v" inSchema: @"Fkeytest" error: nil];
-    mtmtest2v = [context entityForTable: @"mtmtest2_v" inSchema: @"Fkeytest" error: nil];
-    MKCAssertNotNil (mtmtest1v);
-    MKCAssertNotNil (mtmtest2v);
-}
-
-- (void) tearDown
-{
-	[context disconnect];
-	[context release];
-}
-
-- (void) testModMTM
-{
-    [self modMany: mtmtest1 toMany: mtmtest2];
-}
-
-- (void) testModMTMView
-{
-    [self modMany: mtmtest1v toMany: mtmtest2v];
-}
-
-- (void) modMany: (BXEntityDescription *) entity1 toMany: (BXEntityDescription *) entity2
-{
-    //Once again, try to modify an object and see if another object receives the modification.
-    //This time, use a many-to-many relationship.
-
-    NSError* error = nil;
-    MKCAssertTrue (NO == [context autocommits]);
-	
-    //Execute a fetch
-    NSArray* res = [context executeFetchForEntity: entity1
-                                    withPredicate: nil error: &error];
-	STAssertNil (error, [error localizedDescription]);
-    MKCAssertTrue (4 == [res count]);
-    
-    //Get an object from the result
-    NSPredicate* predicate = [NSPredicate predicateWithFormat: @"value1 = 'a1'"];
-    res =  [res filteredArrayUsingPredicate: predicate];
-    MKCAssertTrue (1 == [res count]);
-    BXDatabaseObject* object = [res objectAtIndex: 0];
-    NSCountedSet* foreignObjects = [object valueForKey: [entity2 name]];
-    NSCountedSet* foreignObjects2 = [object resolveNoncachedRelationshipNamed: [entity2 name]];
-	
-    MKCAssertNotNil (foreignObjects);
-    MKCAssertNotNil (foreignObjects2);
-    MKCAssertTrue (foreignObjects != foreignObjects2);
-    MKCAssertTrue ([foreignObjects isEqualToSet: foreignObjects2]);
-    
-    //Remove the referenced objects (another means than in the previous method)
-    [foreignObjects removeAllObjects];
-    MKCAssertTrue (0 == [foreignObjects count]);
-    MKCAssertTrue ([foreignObjects isEqualToSet: foreignObjects2]);
-    
-    //Get the objects from the second table
-    NSSet* objects2 = [NSSet setWithArray: [context executeFetchForEntity: entity2
-                                                            withPredicate: [NSPredicate predicateWithFormat:  @"value2 != 'd2'"]
-                                                                    error: &error]];
-    STAssertNil (error, [error description]);
-    MKCAssertTrue (3 == [objects2 count]);
-    
-    NSMutableSet* mock = [NSMutableSet set];
-    TSEnumerate (currentObject, e, [objects2 objectEnumerator])
-    {
-        [mock addObject: currentObject];
-        [foreignObjects addObject: currentObject];
-        MKCAssertTrue ([mock isEqualToSet: foreignObjects]);