Commits

Tuukka Norri committed a6493ae

Unit tests (references #221)
- Renamed some tests.
- Wrote tests for various utility classes.
- Added a check for schema version.

  • Participants
  • Parent commits d8c5807

Comments (0)

Files changed (22)

File UnitTests/Sources/BXDelegateProxyTests.h

+//
+// BXDelegateProxyTests.h
+// BaseTen
+//
+// Copyright (C) 2010 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 "BXTestCase.h"
+
+@class BXDelegateProxy;
+
+
+@interface BXDelegateProxyTests : BXTestCase
+{
+	id mDelegateProxy;
+	id mDelegateImpl;
+	id mDefaultImpl;
+}
+@end

File UnitTests/Sources/BXDelegateProxyTests.m

+//
+// BXDelegateProxyTests.m
+// BaseTen
+//
+// Copyright (C) 2010 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/BXDelegateProxy.h>
+#import <OCMock/OCMock.h>
+#import "BXDelegateProxyTests.h"
+
+
+@implementation BXDelegateProxyTests
+- (void) setUp
+{
+	mDefaultImpl = [[OCMockObject mockForClass: [NSNumber class]] retain];
+	mDelegateImpl = [[OCMockObject mockForClass: [NSValue class]] retain];
+	
+	mDelegateProxy = [[BXDelegateProxy alloc] initWithDelegateDefaultImplementation: mDefaultImpl];
+	[mDelegateProxy setDelegateForBXDelegateProxy: mDelegateImpl];
+}
+
+
+- (void) tearDown
+{
+	[mDelegateProxy release];
+	[mDelegateImpl release];
+	[mDefaultImpl release];
+}
+
+
+- (void) test1
+{
+	[[mDelegateImpl expect] nonretainedObjectValue];
+	[mDelegateProxy nonretainedObjectValue];
+	[mDelegateImpl verify];
+}
+
+
+- (void) test2
+{
+	[[mDefaultImpl expect] stringValue];
+	[mDelegateProxy stringValue];
+	[mDelegateImpl verify];
+}
+@end

File UnitTests/Sources/BXKeyPathComponentTest.h

+//
+// BXKeyPathComponentTest.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 "BXTestCase.h"
+
+
+@interface BXKeyPathComponentTest : BXTestCase 
+{
+}
+@end

File UnitTests/Sources/BXKeyPathComponentTest.m

+//
+// BXKeyPathComponentTest.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 "BXKeyPathComponentTest.h"
+#import "MKCSenTestCaseAdditions.h"
+#import <BaseTen/BXKeyPathParser.h>
+
+
+@implementation BXKeyPathComponentTest
+- (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/Sources/BXPredicateTests.h

+//
+// BXPredicateTests.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 "BXTestCase.h"
+
+
+@class BXPGQueryBuilder;
+@class PGTSConnection;
+
+
+@interface BXPredicateTests : BXTestCase 
+{
+	BXPGQueryBuilder* mQueryBuilder;
+	PGTSConnection* mConnection;
+}
+@end

File UnitTests/Sources/BXPredicateTests.m

+//
+// BXPredicateTests.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 "BXPredicateTests.h"
+#import "MKCSenTestCaseAdditions.h"
+#import <BaseTen/BaseTen.h>
+#import <BaseTen/BXDatabaseContextPrivate.h>
+#import <BaseTen/BXPGInterface.h>
+#import <BaseTen/BXPGQueryBuilder.h>
+#import <BaseTen/BXPredicateVisitor.h>
+
+
+@implementation BXPredicateTests
+- (void) setUp
+{
+	[super setUp];
+	
+	mQueryBuilder = [[BXPGQueryBuilder alloc] init];
+	
+	BXDatabaseContext* ctx = [[BXDatabaseContext alloc] initWithDatabaseURI: [self databaseURI]];
+	[ctx setDelegate: self];
+	BXEntityDescription* entity = [ctx entityForTable: @"test" inSchema: @"public" error: NULL];
+	[mQueryBuilder addPrimaryRelationForEntity: entity];
+	
+	BXPGInterface* interface = (id)[ctx databaseInterface];
+	[interface prepareForConnecting];
+	BXPGTransactionHandler* handler = (id)[interface transactionHandler];
+	[handler prepareForConnecting];
+	mConnection = [[handler connection] retain];
+}
+
+- (void) tearDown
+{
+	[mQueryBuilder release];
+	[mConnection release];
+	[super tearDown];
+}
+
+- (void) testAddition
+{
+	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"1 + 2 == 3"];
+	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
+	MKCAssertEqualObjects (whereClause, @"$1 = ($2 + $3)");
+	NSArray* parameters = [mQueryBuilder parameters];
+	NSArray* expected = [NSArray arrayWithObjects: [NSNumber numberWithInt: 3], [NSNumber numberWithInt: 1], [NSNumber numberWithInt: 2], nil];
+	MKCAssertEqualObjects (parameters, expected);
+}
+
+- (void) testSubtraction
+{
+	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"3 - 2 == 1"];
+	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
+	MKCAssertEqualObjects (whereClause, @"$1 = ($2 - $3)");
+	NSArray* parameters = [mQueryBuilder parameters];
+	NSArray* expected = [NSArray arrayWithObjects: [NSNumber numberWithInt: 1], [NSNumber numberWithInt: 3], [NSNumber numberWithInt: 2], nil];
+	MKCAssertEqualObjects (parameters, expected);
+}
+
+- (void) testBegins
+{
+	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"'foobar' BEGINSWITH 'foo'"];
+	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
+	MKCAssertEqualObjects (whereClause, @"$1 ~~ (regexp_replace ($2, '([%_\\\\])', '\\\\\\1', 'g') || '%')");
+	NSArray* parameters = [mQueryBuilder parameters];
+	NSArray* expected = [NSArray arrayWithObjects: @"foobar", @"foo", nil];
+	MKCAssertEqualObjects (parameters, expected);
+}
+
+- (void) testEndsCase
+{
+	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"'foobar' ENDSWITH[c] 'b%a_r'"];
+	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
+	MKCAssertEqualObjects (whereClause, @"$1 ~~* ('%' || regexp_replace ($2, '([%_\\\\])', '\\\\\\1', 'g'))");
+	NSArray* parameters = [mQueryBuilder parameters];
+	NSArray* expected = [NSArray arrayWithObjects: @"foobar", @"b%a_r", nil];
+	MKCAssertEqualObjects (parameters, expected);
+}
+
+- (void) testBetween
+{
+	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"2 BETWEEN {1, 3}"];
+	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
+	MKCAssertEqualObjects (whereClause, @"ARRAY [$1,$2] OPERATOR (\"baseten\".<<>>) $3");
+	NSArray* parameters = [mQueryBuilder parameters];
+	NSArray* expected = [NSArray arrayWithObjects:
+						 [NSNumber numberWithInt: 1],
+						 [NSNumber numberWithInt: 3],
+						 [NSNumber numberWithInt: 2],
+						 nil];
+	MKCAssertEqualObjects (parameters, expected);
+}
+
+- (void) testGt
+{
+	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"1 < 2"];
+	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
+	MKCAssertEqualObjects (whereClause, @"$1 > $2");
+	NSArray* parameters = [mQueryBuilder parameters];
+	NSArray* expected = [NSArray arrayWithObjects:
+						 [NSNumber numberWithInt: 2],
+						 [NSNumber numberWithInt: 1],
+						 nil];
+	MKCAssertEqualObjects (parameters, expected);
+}
+
+- (void) testContains
+{
+	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"{1, 2, 3} CONTAINS 2"];
+	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
+	MKCAssertEqualObjects (whereClause, @"$1 = ANY (ARRAY [$2,$3,$4])");
+	NSArray* parameters = [mQueryBuilder parameters];
+	NSArray* expected = [NSArray arrayWithObjects:
+						 [NSNumber numberWithInt: 2],
+						 [NSNumber numberWithInt: 1],
+						 [NSNumber numberWithInt: 2],
+						 [NSNumber numberWithInt: 3],
+						 nil];
+	MKCAssertEqualObjects (parameters, expected);
+}
+
+- (void) testIn
+{
+	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"2 IN {1, 2, 3}"];
+	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
+	MKCAssertEqualObjects (whereClause, @"$1 = ANY (ARRAY [$2,$3,$4])");
+	NSArray* parameters = [mQueryBuilder parameters];
+	NSArray* expected = [NSArray arrayWithObjects:
+						 [NSNumber numberWithInt: 2],
+						 [NSNumber numberWithInt: 1],
+						 [NSNumber numberWithInt: 2],
+						 [NSNumber numberWithInt: 3],
+						 nil];
+	MKCAssertEqualObjects (parameters, expected);
+}
+
+- (void) testIn2
+{
+	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"'bb' IN 'aabbccdd'"];
+	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
+	MKCAssertEqualObjects (whereClause, @"(0 != position ($1 in $2))");
+	NSArray* parameters = [mQueryBuilder parameters];
+	NSArray* expected = [NSArray arrayWithObjects: @"bb", @"aabbccdd", nil];
+	MKCAssertEqualObjects (parameters, expected);
+}
+
+- (void) testIn3
+{
+	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"'bb' IN[c] 'aabbccdd'"];
+	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
+	MKCAssertEqualObjects (whereClause, @"$1 ~~* ('%' || regexp_replace ($2, '([%_\\\\])', '\\\\\\1', 'g') || '%')");
+	NSArray* parameters = [mQueryBuilder parameters];
+	NSArray* expected = [NSArray arrayWithObjects: @"aabbccdd", @"bb", nil];
+	MKCAssertEqualObjects (parameters, expected);
+}
+
+- (void) testAndOr
+{
+	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"1 < 2 AND (2 < 3 OR 4 > 5)"];
+	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
+	MKCAssertEqualObjects (whereClause, @"($1 > $2 AND ($3 > $4 OR $5 < $6))");
+	NSArray* parameters = [mQueryBuilder parameters];
+	NSArray* expected = [NSArray arrayWithObjects:
+						 [NSNumber numberWithInt: 2],
+						 [NSNumber numberWithInt: 1],
+						 [NSNumber numberWithInt: 3],
+						 [NSNumber numberWithInt: 2],
+						 [NSNumber numberWithInt: 5],
+						 [NSNumber numberWithInt: 4],
+						 nil];
+	MKCAssertEqualObjects (parameters, expected);
+}
+
+- (void) testNull
+{
+	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"1 == %@", [NSNull null]];
+	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
+	MKCAssertEqualObjects (whereClause, @"$1 IS NULL");
+	NSArray* parameters = [mQueryBuilder parameters];
+	NSArray* expected = [NSArray arrayWithObject: [NSNumber numberWithInt: 1]];
+	MKCAssertEqualObjects (parameters, expected);
+}
+
+//We need a validated entity for this test.
+#if 0
+- (void) testAdditionWithKeyPath
+{
+	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"1 + id == 2"];
+	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
+	MKCAssertEqualObjects (whereClause, @"$1 = ($2 + $3)");
+	NSArray* parameters = [mQueryBuilder parameters];
+	NSArray* expected = [NSArray arrayWithObjects: [NSNumber numberWithInt: 3], [NSNumber numberWithInt: 1], [NSNumber numberWithInt: 2], nil];
+	MKCAssertEqualObjects (parameters, expected);	
+}
+#endif
+
+- (void) testDiacriticInsensitivity
+{
+	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"'a' LIKE[cd] 'b'"];
+	[mQueryBuilder setQueryType: kBXPGQueryTypeSelect];
+	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
+	MKCAssertEqualObjects (whereClause, @"(true)");
+	NSArray* parameters = [mQueryBuilder parameters];
+	MKCAssertEqualObjects (parameters, [NSArray array]);
+}
+
+
+@end

File UnitTests/Sources/ConnectTest.m

 	}
 }
 
-- (void) testConnect1
+- (void) test1Connect
 {
     MKCAssertNoThrow ([ctx setDatabaseURI: [self databaseURI]]);
     MKCAssertNoThrow ([ctx connectIfNeeded: nil]);
 }
 
-- (void) testConnect2
+- (void) test2Connect
 {
 	NSURL* uri = [self databaseURI];
 	NSString* uriString = [uri absoluteString];
     MKCAssertNoThrow ([ctx connectIfNeeded: nil]);
 }
  
-- (void) testConnectFail1
+- (void) test3ConnectFail
 {
     MKCAssertNoThrow ([ctx setDatabaseURI: [NSURL URLWithString: @"pgsql://localhost/anonexistantdatabase"]]);
     MKCAssertThrows ([ctx connectIfNeeded: nil]);
 }
  
-- (void) testConnectFail2
+- (void) test4ConnectFail
 {
     MKCAssertNoThrow ([ctx setDatabaseURI: 
         [NSURL URLWithString: @"pgsql://user@localhost/basetentest/a/malformed/database/uri"]]);
     MKCAssertThrows ([ctx connectIfNeeded: nil]);
 }
 
-- (void) testConnectFail3
+- (void) test5ConnectFail
 {
     MKCAssertThrows ([ctx setDatabaseURI: [NSURL URLWithString: @"invalid://user@localhost/invalid"]]);
 }
 
-- (void) testNilURI
+- (void) test7NilURI
 {
 	NSError* error = nil;
 	id rval = nil;
 	MKCAssertNotNil (error);
 }
 
-- (void) testConnectFail4
+- (void) test6ConnectFail
 {
 	[ctx setDatabaseURI: [NSURL URLWithString: @"pgsql://localhost/anonexistantdatabase"]];
 	[[ctx notificationCenter] addObserver: self selector: @selector (expected:) name: kBXConnectionFailedNotification object: nil];

File UnitTests/Sources/EntityTests.m

 #import "MKCSenTestCaseAdditions.h"
 #import <BaseTen/BaseTen.h>
 #import <BaseTen/BXEnumerate.h>
+#import <BaseTen/BXDatabaseContextPrivate.h>
+#import <BaseTen/BXPGInterface.h>
+#import <BaseTen/BXPGTransactionHandler.h>
 
 
 @implementation EntityTests
-- (void) testValidName
+- (void) test0SchemaVersion
+{
+	NSNumber *currentVersion = [BXPGVersion currentVersionNumber];
+	NSNumber *currentCompatVersion = [BXPGVersion currentCompatibilityVersionNumber];
+	
+	NSError *error = nil;
+	STAssertTrue ([mContext connectSync: &error], [error description]);
+	
+	BXPGInterface *interface = (id) [mContext databaseInterface];
+	BXPGTransactionHandler *handler = [interface transactionHandler];
+	BXPGDatabaseDescription *desc = [handler databaseDescription];
+	
+	MKCAssertEqualObjects (currentCompatVersion, [desc schemaCompatibilityVersion]);
+	MKCAssertEqualObjects (currentVersion, [desc schemaVersion]);
+}
+
+
+- (void) test1ValidName
 {
 	NSError* error = nil;
 	NSString* schemaName = @"Fkeytest";
 	MKCAssertEqualObjects ([entity schemaName], schemaName);
 }
 
-- (void) testInvalidName
+- (void) test2InvalidName
 {
 	NSError* error = nil;
 	NSString* schemaName = @"public";
 	MKCAssertNil (entity);
 }
 
-- (void) testValidation
+- (void) test3Validation
 {
 	NSError* error = nil;
 	[mContext connectIfNeeded: &error];
 	MKCAssertNotNil ([entity primaryKeyFields]);	
 }
 
-- (void) testSharing
+- (void) test4Sharing
 {
 	NSError* error = nil;
 	NSString* entityName = @"mtocollectiontest1";
 	MKCAssertTrue (entity == entity2);
 }
 
-- (void) testExclusion
+- (void) test5Exclusion
 {
 	[mContext connectSync: NULL];
 	
 	MKCAssertFalse ([attr isExcluded]);
 }
 
-- (void) testHash
+- (void) test6Hash
 {
     BXEntityDescription* e1 = [mContext entityForTable: @"test2" inSchema: @"Fkeytest" error: nil];
     BXEntityDescription* e2 = [mContext entityForTable: @"test2" inSchema: @"Fkeytest" error: nil];
     MKCAssertFalse ([container2 containsObject: e2]);    
 }
 
-- (void) testViewPkey
+- (void) test7ViewPkey
 {
 	NSError* error = nil;
 	[mContext connectIfNeeded: &error];

File UnitTests/Sources/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 "BXTestCase.h"
-
-
-@interface KeyPathComponentTest : BXTestCase 
-{
-}
-@end

File UnitTests/Sources/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/Sources/NSArray+BaseTenAdditionsTests.h

+//
+// NSArray+BaseTenAdditionsTests.h
+// BaseTen
+//
+// Copyright (C) 2010 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 "BXTestCase.h"
+
+
+@interface NSArray_BaseTenAdditionsTests : BXTestCase
+{
+}
+@end

File UnitTests/Sources/NSArray+BaseTenAdditionsTests.m

+//
+// NSArray+BaseTenAdditionsTests.m
+// BaseTen
+//
+// Copyright (C) 2010 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 "NSArray+BaseTenAdditionsTests.h"
+#import "MKCSenTestCaseAdditions.h"
+#import <BaseTen/NSArray+BaseTenAdditions.h>
+
+
+@implementation NSArray_BaseTenAdditionsTests
+- (void) test1
+{
+	NSArray *a = [NSArray arrayWithObjects: @"a", @"b", @"c", nil];
+	NSPredicate *predicate = [NSPredicate predicateWithFormat: @"SELF = %@", @"b"];
+	
+	NSMutableArray *others = [NSMutableArray array];
+	NSArray *filtered = [a BXFilteredArrayUsingPredicate: predicate others: others substitutionVariables: nil];
+	
+	MKCAssertEqualObjects (filtered, [NSArray arrayWithObject: @"b"]);
+	MKCAssertEqualObjects (others, ([NSArray arrayWithObjects: @"a", @"c", nil]));
+}
+
+
+- (void) test2
+{
+	NSArray *a = [NSArray arrayWithObjects: @"a", @"b", @"c", nil];
+	NSPredicate *predicate = [NSPredicate predicateWithFormat: @"SELF = $MY_VAR"];
+	
+	NSMutableArray *others = [NSMutableArray array];
+	NSDictionary *vars = [NSDictionary dictionaryWithObject: @"b" forKey: @"MY_VAR"];
+	NSArray *filtered = [a BXFilteredArrayUsingPredicate: predicate others: others substitutionVariables: vars];
+	
+	MKCAssertEqualObjects (filtered, [NSArray arrayWithObject: @"b"]);
+	MKCAssertEqualObjects (others, ([NSArray arrayWithObjects: @"a", @"c", nil]));
+}
+@end

File UnitTests/Sources/NSPredicate+BaseTenAdditionsTests.h

+//
+// NSPredicate+BaseTenAdditionsTests.h
+// BaseTen
+//
+// Copyright (C) 2010 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 "BXTestCase.h"
+
+
+@interface NSPredicate_BaseTenAdditionsTests : BXTestCase
+{
+}
+@end

File UnitTests/Sources/NSPredicate+BaseTenAdditionsTests.m

+//
+// NSPredicate+BaseTenAdditionsTests.m
+// BaseTen
+//
+// Copyright (C) 2010 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 "NSPredicate+BaseTenAdditionsTests.h"
+#import "MKCSenTestCaseAdditions.h"
+#import <BaseTen/NSPredicate+BaseTenAdditions.h>
+
+
+@implementation NSPredicate_BaseTenAdditionsTests
+- (void) test1
+{
+	NSPredicate *predicate = [NSPredicate predicateWithFormat: @"SELF = $MY_VAR"];
+	NSDictionary *vars = [NSDictionary dictionaryWithObject: @"a" forKey: @"MY_VAR"];
+	MKCAssertTrue ([predicate BXEvaluateWithObject: @"a" substitutionVariables: vars]);
+	MKCAssertFalse ([predicate BXEvaluateWithObject: @"b" substitutionVariables: vars]);
+}
+@end

File UnitTests/Sources/PGTSHOMTests.h

+//
+// PGTSHOMTests.h
+// BaseTen
+//
+// Copyright (C) 2010 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 "BXTestCase.h"
+
+
+@interface PGTSHOMTests : BXTestCase
+{
+}
+@end

File UnitTests/Sources/PGTSHOMTests.m

+//
+// PGTSHOMTests.m
+// BaseTen
+//
+// Copyright (C) 2010 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 "PGTSHOMTests.h"
+#import "MKCSenTestCaseAdditions.h"
+#import <BaseTen/PGTSHOM.h>
+#import <OCMock/OCMock.h>
+
+
+@implementation PGTSHOMTests
+- (void) test01ArrayAny
+{
+	NSArray *array = [NSArray arrayWithObjects: @"a", @"b", @"c", nil];
+	id object = [array PGTSAny];
+	MKCAssertTrue ([array containsObject: object]);
+}
+
+
+- (void) test02SetAny
+{
+	NSSet *set = [NSSet setWithObjects: @"a", @"b", @"c", nil];
+	id object = [set PGTSAny];
+	MKCAssertTrue ([set containsObject: object]);
+}
+
+
+- (void) test03DictAny
+{
+	NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
+						  @"a", @"1",
+						  @"b", @"2",
+						  @"c", @"3",
+						  nil];
+	id object = [dict PGTSAny];
+	MKCAssertTrue ([[dict allValues] containsObject: object]);
+}
+
+
+- (void) test04SetDo
+{
+	OCMockObject *m1 = [OCMockObject mockForClass: [NSNumber class]];
+	OCMockObject *m2 = [OCMockObject mockForClass: [NSNumber class]];
+	[[m1 expect] stringValue];
+	[[m2 expect] stringValue];
+	
+	NSSet *set = [NSSet setWithObjects: m1, m2, nil];
+	[[set PGTSDo] stringValue];
+	
+	[m1 verify];
+	[m2 verify];
+}
+
+
+- (void) test05ArrayDo
+{
+	OCMockObject *m1 = [OCMockObject mockForClass: [NSNumber class]];
+	OCMockObject *m2 = [OCMockObject mockForClass: [NSNumber class]];
+	[[m1 expect] stringValue];
+	[[m2 expect] stringValue];
+	
+	NSArray *array = [NSArray arrayWithObjects: m1, m2, nil];
+	[[array PGTSDo] stringValue];
+	
+	[m1 verify];
+	[m2 verify];
+}
+
+
+- (void) test06DictDo
+{
+	OCMockObject *m1 = [OCMockObject mockForClass: [NSNumber class]];
+	OCMockObject *m2 = [OCMockObject mockForClass: [NSNumber class]];
+	[[m1 expect] stringValue];
+	[[m2 expect] stringValue];
+
+	NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
+						  m1, @"a",
+						  m2, @"b",
+						  nil];
+	[[dict PGTSDo] stringValue];
+	
+	[m1 verify];
+	[m2 verify];
+}
+
+
+- (void) test07ArrayCollect
+{
+	NSArray *array1 = [NSArray arrayWithObjects: @"a", @"b", @"c", nil];
+	NSArray *array2 = (id) [[array1 PGTSCollect] uppercaseString];
+	MKCAssertEqualObjects (array2, ([NSArray arrayWithObjects: @"A", @"B", @"C", nil]));
+}
+
+
+- (void) test08SetCollect
+{
+	NSSet *set1 = [NSSet setWithObjects: @"a", @"b", @"c", nil];
+	NSSet *set2 = (id) [[set1 PGTSCollect] uppercaseString];
+	MKCAssertEqualObjects (set2, ([NSSet setWithObjects: @"A", @"B", @"C", nil]));
+}
+
+
+- (void) test09DictCollect
+{
+	NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
+						  @"a", @"1",
+						  @"b", @"2",
+						  @"c", @"3",
+						  nil];
+	NSArray *array = (id) [[dict PGTSCollect] uppercaseString];
+	MKCAssertEqualObjects (array, ([NSArray arrayWithObjects: @"A", @"B", @"C", nil]));
+}
+
+
+- (void) test10ArrayCollectRet
+{
+	NSArray *array = [NSArray arrayWithObjects: @"a", @"b", @"c", nil];
+	NSSet *set = (id) [[array PGTSCollectReturning: [NSMutableSet class]] uppercaseString];
+	MKCAssertEqualObjects (set, ([NSSet setWithObjects: @"A", @"B", @"C", nil]));
+}
+
+
+- (void) test11SetCollectRet
+{
+	NSSet *set = [NSSet setWithObjects: @"a", @"b", @"c", nil];
+	NSArray *array = (id) [[set PGTSCollectReturning: [NSMutableArray class]] uppercaseString];
+	MKCAssertEqualObjects ([array sortedArrayUsingSelector: @selector (compare:)],
+						   ([NSArray arrayWithObjects: @"A", @"B", @"C", nil]));
+}
+
+
+- (void) test12DictCollectRet
+{
+	NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
+						  @"a", @"1",
+						  @"b", @"2",
+						  @"c", @"3",
+						  nil];
+	NSSet *set = (id) [[dict PGTSCollectReturning: [NSMutableSet class]] uppercaseString];
+	MKCAssertEqualObjects (set, ([NSSet setWithObjects: @"A", @"B", @"C", nil]));
+}
+
+
+- (void) test13ArrayCollectD
+{
+	NSArray *array = [NSArray arrayWithObjects: @"a", @"b", @"c", nil];
+	NSDictionary *dict = (id) [[array PGTSCollectD] uppercaseString];
+	MKCAssertEqualObjects (dict, ([NSDictionary dictionaryWithObjectsAndKeys:
+								   @"a", @"A",
+								   @"b", @"B",
+								   @"c", @"C",
+								   nil]));
+}
+
+
+- (void) test14SetCollectD
+{
+	NSSet *set = [NSSet setWithObjects: @"a", @"b", @"c", nil];
+	NSDictionary *dict = (id) [[set PGTSCollectD] uppercaseString];
+	MKCAssertEqualObjects (dict, ([NSDictionary dictionaryWithObjectsAndKeys:
+								   @"a", @"A",
+								   @"b", @"B",
+								   @"c", @"C",
+								   nil]));
+}
+
+
+- (void) test15DictCollectD
+{
+	NSSet *dict1 = [NSDictionary dictionaryWithObjectsAndKeys:
+					@"a", @"1",
+					@"b", @"2",
+					@"c", @"3",
+					nil];
+	NSDictionary *dict2 = (id) [[dict1 PGTSCollectD] uppercaseString];
+	MKCAssertEqualObjects (dict2, ([NSDictionary dictionaryWithObjectsAndKeys:
+									@"a", @"A",
+									@"b", @"B",
+									@"c", @"C",
+									nil]));
+}
+
+
+- (void) test16ArrayCollectDK
+{
+	NSArray *array = [NSArray arrayWithObjects: @"a", @"b", @"c", nil];
+	NSDictionary *dict = (id) [[array PGTSCollectDK] uppercaseString];
+	MKCAssertEqualObjects (dict, ([NSDictionary dictionaryWithObjectsAndKeys:
+								   @"A", @"a",
+								   @"B", @"b",
+								   @"C", @"c",
+								   nil]));
+}
+
+
+- (void) test17SetCollectDK
+{
+	NSSet *set = [NSSet setWithObjects: @"a", @"b", @"c", nil];
+	NSDictionary *dict = (id) [[set PGTSCollectDK] uppercaseString];
+	MKCAssertEqualObjects (dict, ([NSDictionary dictionaryWithObjectsAndKeys:
+								   @"A", @"a",
+								   @"B", @"b",
+								   @"C", @"c",
+								   nil]));
+}
+
+
+- (void) test18DictCollectDK
+{
+	NSSet *dict1 = [NSDictionary dictionaryWithObjectsAndKeys:
+					@"a", @"1",
+					@"b", @"2",
+					@"c", @"3",
+					nil];
+	NSDictionary *dict2 = (id) [[dict1 PGTSCollectD] uppercaseString];
+	MKCAssertEqualObjects (dict2, ([NSDictionary dictionaryWithObjectsAndKeys:
+									@"A", @"a",
+									@"B", @"b",
+									@"C", @"c",
+									nil]));
+}
+
+
+- (void) test19ArrayVisit
+{	
+	OCMockObject *mock = [OCMockObject mockForClass: [NSUserDefaults class]];
+	[[mock expect] objectIsForcedForKey: @"a" inDomain: @"b"];
+	
+	NSArray *array = [NSArray arrayWithObject: @"a"];
+	[[array PGTSVisit: mock] objectIsForcedForKey: nil inDomain: @"b"];
+	
+	[mock verify];
+}
+
+
+- (void) test20ArrayVisit
+{	
+	OCMockObject *mock = [OCMockObject mockForClass: [NSUserDefaults class]];
+	[[mock expect] objectIsForcedForKey: @"a" inDomain: @"b"];
+	
+	NSSet *set = [NSSet setWithObject: @"a"];
+	[[set PGTSVisit: mock] objectIsForcedForKey: nil inDomain: @"b"];
+	
+	[mock verify];
+}
+
+
+- (void) test21DictVisit
+{	
+	OCMockObject *mock = [OCMockObject mockForClass: [NSUserDefaults class]];
+	[[mock expect] objectIsForcedForKey: @"a" inDomain: @"b"];
+	
+	NSDictionary *dict = [NSDictionary dictionaryWithObject: @"a" forKey: @"1"];
+	[[dict PGTSVisit: mock] objectIsForcedForKey: nil inDomain: @"b"];
+	
+	[mock verify];
+}
+
+
+- (void) test22ArrayReverse
+{
+	NSArray *array = [NSArray arrayWithObjects: @"a", @"b", @"c", nil];
+	MKCAssertEqualObjects ([array PGTSReverse], ([NSArray arrayWithObjects: @"c", @"b", @"a", nil]));
+}
+
+
+- (void) test23DictKeyCollectD
+{
+	NSDictionary *dict1 = [NSDictionary dictionaryWithObjectsAndKeys:
+						   @"1", @"a",
+						   @"2", @"b",
+						   @"3", @"c",
+						   nil];
+	NSDictionary *dict2 = (id) [[dict1 PGTSKeyCollectD] uppercaseString];
+	MKCAssertEqualObjects (dict2, ([NSDictionary dictionaryWithObjectsAndKeys:
+									@"a", @"A",
+									@"b", @"B",
+									@"c", @"C",
+									nil]));	
+}
+
+
+static int
+SelectFunction (id object)
+{
+	int retval = 1;
+	if ([object isEqual: @"b"])
+		retval = 0;
+	return retval;
+}
+
+
+- (void) test24ArraySelectFunction
+{
+	NSArray *array = [NSArray arrayWithObjects: @"a", @"b", @"c", nil];
+	MKCAssertEqualObjects ([array PGTSSelectFunction: &SelectFunction], ([NSArray arrayWithObjects: @"a", @"c", nil]));
+}
+
+
+- (void) test25SetSelectFunction
+{
+	NSSet *set = [NSSet setWithObjects: @"a", @"b", @"c", nil];
+	MKCAssertEqualObjects ([set PGTSSelectFunction: &SelectFunction], ([NSSet setWithObjects: @"a", @"c", nil]));
+}
+
+
+- (void) test26ValueSelectFunction
+{
+	NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
+						  @"a", @"1",
+						  @"b", @"2",
+						  @"c", @"3",
+						  nil];
+	MKCAssertEqualObjects ([dict PGTSValueSelectFunction: &SelectFunction], ([NSArray arrayWithObjects: @"a", @"c", nil]));
+}
+
+
+static int
+SelectFunction2 (id object, void *arg)
+{
+	assert ([(id) arg isEqual: @"k"]);
+	
+	int retval = 1;
+	if ([object isEqual: @"b"])
+		retval = 0;
+	return retval;
+}
+
+
+- (void) test27ArraySelectFunction
+{
+	NSArray *array = [NSArray arrayWithObjects: @"a", @"b", @"c", nil];
+	MKCAssertEqualObjects ([array PGTSSelectFunction: &SelectFunction2 argument: @"k"], ([NSArray arrayWithObjects: @"a", @"c", nil]));
+}
+
+
+- (void) test28SetSelectFunction
+{
+	NSSet *set = [NSSet setWithObjects: @"a", @"b", @"c", nil];
+	MKCAssertEqualObjects ([set PGTSSelectFunction: &SelectFunction2 argument: @"k"], ([NSSet setWithObjects: @"a", @"c", nil]));
+}
+
+
+- (void) test29ValueSelectFunction
+{
+	NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
+						  @"a", @"1",
+						  @"b", @"2",
+						  @"c", @"3",
+						  nil];
+	MKCAssertEqualObjects ([dict PGTSValueSelectFunction: &SelectFunction2 argument: @"k"], ([NSArray arrayWithObjects: @"a", @"c", nil]));
+}
+@end

File UnitTests/Sources/PGTSInvocationRecorderTests.h

+//
+// PGTSInvocationRecorderTests.h
+// BaseTen
+//
+// Copyright (C) 2010 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 "BXTestCase.h"
+
+
+@interface PGTSInvocationRecorderTests : BXTestCase
+{
+}
+@end

File UnitTests/Sources/PGTSInvocationRecorderTests.m

+//
+// PGTSInvocationRecorderTests.m
+// BaseTen
+//
+// Copyright (C) 2010 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 "PGTSInvocationRecorderTests.h"
+#import "MKCSenTestCaseAdditions.h"
+#import <OCMock/OCMock.h>
+#import <BaseTen/PGTSInvocationRecorder.h>
+
+
+@protocol PGTSInvocationRecorderTestCallback
+- (void) myCallback: (NSInvocation *) invocation userInfo: (id) userInfo;
+@end
+
+
+
+@implementation PGTSInvocationRecorderTests
+- (void) test1
+{
+	NSString *s = @"a";
+	PGTSInvocationRecorder *recorder = [[PGTSInvocationRecorder alloc] init];
+	[recorder setTarget: s];
+	[[recorder record] uppercaseString];
+	
+	NSInvocation *invocation = [recorder invocation];
+	SEL selector = @selector (uppercaseString);
+	MKCAssertEquals (s, [invocation target]);
+	MKCAssertTrue (0 == strcmp ((const char *) selector, (const char *) [invocation selector]));
+	MKCAssertEqualObjects ([s methodSignatureForSelector: selector], [invocation methodSignature]);
+}
+
+
+- (void) test2
+{
+	NSString *s = @"a";
+	NSInvocation *invocation = nil;
+	[[PGTSInvocationRecorder recordWithTarget: s outInvocation: &invocation] uppercaseString];
+	
+	SEL selector = @selector (uppercaseString);
+	MKCAssertEquals (s, [invocation target]);
+	MKCAssertTrue (0 == strcmp ((const char *) selector, (const char *) [invocation selector]));
+	MKCAssertEqualObjects ([s methodSignatureForSelector: selector], [invocation methodSignature]);
+}
+
+
+- (void) test3
+{
+	NSString *s = @"a";
+	NSCharacterSet *set = [NSCharacterSet alphanumericCharacterSet];
+	NSStringCompareOptions opts = NSCaseInsensitiveSearch;
+	NSInvocation *invocation = nil;
+	[[PGTSInvocationRecorder recordWithTarget: s outInvocation: &invocation] rangeOfCharacterFromSet: set options: opts];
+	
+	SEL selector = @selector (rangeOfCharacterFromSet:options:);
+	MKCAssertEquals (s, [invocation target]);
+	MKCAssertTrue (0 == strcmp ((const char *) selector, (const char *) [invocation selector]));
+	MKCAssertEqualObjects ([s methodSignatureForSelector: selector], [invocation methodSignature]);
+	
+	NSCharacterSet *invocationSet = nil;
+	NSStringCompareOptions invocationOpts = 0;
+	[invocation getArgument: &invocationSet atIndex: 2];
+	[invocation getArgument: &invocationOpts atIndex: 3];
+	MKCAssertEquals (set, invocationSet);
+	MKCAssertEquals (opts, invocationOpts);
+}
+
+
+- (void) test4
+{
+	NSString *a = @"a";
+	NSString *b = @"b";
+	OCMockObject *callbackTarget = [OCMockObject mockForProtocol: @protocol (PGTSInvocationRecorderTestCallback)];
+	
+	PGTSCallbackInvocationRecorder *recorder = [[PGTSCallbackInvocationRecorder alloc] init];
+	[recorder setCallback: @selector (myCallback:userInfo:)];
+	[recorder setCallbackTarget: callbackTarget];
+	[recorder setUserInfo: b];
+	
+	[[callbackTarget expect] myCallback: OCMOCK_ANY userInfo: b];
+	[[recorder recordWithTarget: a] uppercaseString];
+}
+@end

File UnitTests/Sources/PredicateTests.h

-//
-// PredicateTests.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 "BXTestCase.h"
-
-
-@class BXPGQueryBuilder;
-@class PGTSConnection;
-
-
-@interface PredicateTests : BXTestCase 
-{
-	BXPGQueryBuilder* mQueryBuilder;
-	PGTSConnection* mConnection;
-}
-@end

File UnitTests/Sources/PredicateTests.m

-//
-// PredicateTests.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 "PredicateTests.h"
-#import "MKCSenTestCaseAdditions.h"
-#import <BaseTen/BaseTen.h>
-#import <BaseTen/BXDatabaseContextPrivate.h>
-#import <BaseTen/BXPGInterface.h>
-#import <BaseTen/BXPGQueryBuilder.h>
-#import <BaseTen/BXPredicateVisitor.h>
-
-
-@implementation PredicateTests
-- (void) setUp
-{
-	[super setUp];
-	
-	mQueryBuilder = [[BXPGQueryBuilder alloc] init];
-	
-	BXDatabaseContext* ctx = [[BXDatabaseContext alloc] initWithDatabaseURI: [self databaseURI]];
-	[ctx setDelegate: self];
-	BXEntityDescription* entity = [ctx entityForTable: @"test" inSchema: @"public" error: NULL];
-	[mQueryBuilder addPrimaryRelationForEntity: entity];
-	
-	BXPGInterface* interface = (id)[ctx databaseInterface];
-	[interface prepareForConnecting];
-	BXPGTransactionHandler* handler = (id)[interface transactionHandler];
-	[handler prepareForConnecting];
-	mConnection = [[handler connection] retain];
-}
-
-- (void) tearDown
-{
-	[mQueryBuilder release];
-	[mConnection release];
-	[super tearDown];
-}
-
-- (void) testAddition
-{
-	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"1 + 2 == 3"];
-	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
-	MKCAssertEqualObjects (whereClause, @"$1 = ($2 + $3)");
-	NSArray* parameters = [mQueryBuilder parameters];
-	NSArray* expected = [NSArray arrayWithObjects: [NSNumber numberWithInt: 3], [NSNumber numberWithInt: 1], [NSNumber numberWithInt: 2], nil];
-	MKCAssertEqualObjects (parameters, expected);
-}
-
-- (void) testSubtraction
-{
-	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"3 - 2 == 1"];
-	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
-	MKCAssertEqualObjects (whereClause, @"$1 = ($2 - $3)");
-	NSArray* parameters = [mQueryBuilder parameters];
-	NSArray* expected = [NSArray arrayWithObjects: [NSNumber numberWithInt: 1], [NSNumber numberWithInt: 3], [NSNumber numberWithInt: 2], nil];
-	MKCAssertEqualObjects (parameters, expected);
-}
-
-- (void) testBegins
-{
-	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"'foobar' BEGINSWITH 'foo'"];
-	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
-	MKCAssertEqualObjects (whereClause, @"$1 ~~ (regexp_replace ($2, '([%_\\\\])', '\\\\\\1', 'g') || '%')");
-	NSArray* parameters = [mQueryBuilder parameters];
-	NSArray* expected = [NSArray arrayWithObjects: @"foobar", @"foo", nil];
-	MKCAssertEqualObjects (parameters, expected);
-}
-
-- (void) testEndsCase
-{
-	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"'foobar' ENDSWITH[c] 'b%a_r'"];
-	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
-	MKCAssertEqualObjects (whereClause, @"$1 ~~* ('%' || regexp_replace ($2, '([%_\\\\])', '\\\\\\1', 'g'))");
-	NSArray* parameters = [mQueryBuilder parameters];
-	NSArray* expected = [NSArray arrayWithObjects: @"foobar", @"b%a_r", nil];
-	MKCAssertEqualObjects (parameters, expected);
-}
-
-- (void) testBetween
-{
-	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"2 BETWEEN {1, 3}"];
-	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
-	MKCAssertEqualObjects (whereClause, @"ARRAY [$1,$2] OPERATOR (\"baseten\".<<>>) $3");
-	NSArray* parameters = [mQueryBuilder parameters];
-	NSArray* expected = [NSArray arrayWithObjects:
-						 [NSNumber numberWithInt: 1],
-						 [NSNumber numberWithInt: 3],
-						 [NSNumber numberWithInt: 2],
-						 nil];
-	MKCAssertEqualObjects (parameters, expected);
-}
-
-- (void) testGt
-{
-	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"1 < 2"];
-	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
-	MKCAssertEqualObjects (whereClause, @"$1 > $2");
-	NSArray* parameters = [mQueryBuilder parameters];
-	NSArray* expected = [NSArray arrayWithObjects:
-						 [NSNumber numberWithInt: 2],
-						 [NSNumber numberWithInt: 1],
-						 nil];
-	MKCAssertEqualObjects (parameters, expected);
-}
-
-- (void) testContains
-{
-	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"{1, 2, 3} CONTAINS 2"];
-	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
-	MKCAssertEqualObjects (whereClause, @"$1 = ANY (ARRAY [$2,$3,$4])");
-	NSArray* parameters = [mQueryBuilder parameters];
-	NSArray* expected = [NSArray arrayWithObjects:
-						 [NSNumber numberWithInt: 2],
-						 [NSNumber numberWithInt: 1],
-						 [NSNumber numberWithInt: 2],
-						 [NSNumber numberWithInt: 3],
-						 nil];
-	MKCAssertEqualObjects (parameters, expected);
-}
-
-- (void) testIn
-{
-	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"2 IN {1, 2, 3}"];
-	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
-	MKCAssertEqualObjects (whereClause, @"$1 = ANY (ARRAY [$2,$3,$4])");
-	NSArray* parameters = [mQueryBuilder parameters];
-	NSArray* expected = [NSArray arrayWithObjects:
-						 [NSNumber numberWithInt: 2],
-						 [NSNumber numberWithInt: 1],
-						 [NSNumber numberWithInt: 2],
-						 [NSNumber numberWithInt: 3],
-						 nil];
-	MKCAssertEqualObjects (parameters, expected);
-}
-
-- (void) testIn2
-{
-	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"'bb' IN 'aabbccdd'"];
-	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
-	MKCAssertEqualObjects (whereClause, @"(0 != position ($1 in $2))");
-	NSArray* parameters = [mQueryBuilder parameters];
-	NSArray* expected = [NSArray arrayWithObjects: @"bb", @"aabbccdd", nil];
-	MKCAssertEqualObjects (parameters, expected);
-}
-
-- (void) testIn3
-{
-	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"'bb' IN[c] 'aabbccdd'"];
-	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
-	MKCAssertEqualObjects (whereClause, @"$1 ~~* ('%' || regexp_replace ($2, '([%_\\\\])', '\\\\\\1', 'g') || '%')");
-	NSArray* parameters = [mQueryBuilder parameters];
-	NSArray* expected = [NSArray arrayWithObjects: @"aabbccdd", @"bb", nil];
-	MKCAssertEqualObjects (parameters, expected);
-}
-
-- (void) testAndOr
-{
-	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"1 < 2 AND (2 < 3 OR 4 > 5)"];
-	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
-	MKCAssertEqualObjects (whereClause, @"($1 > $2 AND ($3 > $4 OR $5 < $6))");
-	NSArray* parameters = [mQueryBuilder parameters];
-	NSArray* expected = [NSArray arrayWithObjects:
-						 [NSNumber numberWithInt: 2],
-						 [NSNumber numberWithInt: 1],
-						 [NSNumber numberWithInt: 3],
-						 [NSNumber numberWithInt: 2],
-						 [NSNumber numberWithInt: 5],
-						 [NSNumber numberWithInt: 4],
-						 nil];
-	MKCAssertEqualObjects (parameters, expected);
-}
-
-- (void) testNull
-{
-	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"1 == %@", [NSNull null]];
-	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
-	MKCAssertEqualObjects (whereClause, @"$1 IS NULL");
-	NSArray* parameters = [mQueryBuilder parameters];
-	NSArray* expected = [NSArray arrayWithObject: [NSNumber numberWithInt: 1]];
-	MKCAssertEqualObjects (parameters, expected);
-}
-
-//We need a validated entity for this test.
-#if 0
-- (void) testAdditionWithKeyPath
-{
-	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"1 + id == 2"];
-	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
-	MKCAssertEqualObjects (whereClause, @"$1 = ($2 + $3)");
-	NSArray* parameters = [mQueryBuilder parameters];
-	NSArray* expected = [NSArray arrayWithObjects: [NSNumber numberWithInt: 3], [NSNumber numberWithInt: 1], [NSNumber numberWithInt: 2], nil];
-	MKCAssertEqualObjects (parameters, expected);	
-}
-#endif
-
-- (void) testDiacriticInsensitivity
-{
-	NSPredicate* predicate = [NSPredicate predicateWithFormat: @"'a' LIKE[cd] 'b'"];
-	[mQueryBuilder setQueryType: kBXPGQueryTypeSelect];
-	NSString* whereClause = [mQueryBuilder whereClauseForPredicate: predicate entity: nil connection: mConnection].p_where_clause;
-	MKCAssertEqualObjects (whereClause, @"(true)");
-	NSArray* parameters = [mQueryBuilder parameters];
-	MKCAssertEqualObjects (parameters, [NSArray array]);
-}
-
-
-@end

File UnitTests/Sources/TestLoader.m

 #import <BaseTen/BXLogger.h>
 #import "MKCSenTestCaseAdditions.h"
 
-#import "KeyPathComponentTest.h"
-#import "PredicateTests.h"
+#import "PGTSInvocationRecorderTests.h"
+#import "PGTSHOMTests.h"
+#import "BXDelegateProxyTests.h"
+#import "NSPredicate+BaseTenAdditionsTests.h"
+#import "NSArray+BaseTenAdditionsTests.h"
+#import "PGTSValueTests.h"
+#import "BXKeyPathComponentTest.h"
+#import "BXPredicateTests.h"
 #import "BXDatabaseContextTests.h"
-#import "PGTSValueTests.h"
 
 #import "PGTSMetadataTests.h"
 #import "PGTSTypeTests.h"
 #import "BXDatabaseObjectTests.h"
 #import "EntityTests.h"
 #import "ObjectIDTests.h"
+#import "CreateTests.h"
 #import "FetchTests.h"
-#import "CreateTests.h"
 #import "ModificationTests.h"
 #import "ForeignKeyTests.h"
 #import "ForeignKeyModificationTests.h"
 #import "MTOCollectionTest.h"
 #import "MTMCollectionTest.h"
 #import "UndoTests.h"
-#import "BXDatabaseObjectTests.h"
 #import "ToOneChangeNotificationTests.h"
 
 
 	BXSetLogLevel (kBXLogLevelWarning);
 	
 	NSArray* testClasses = [NSArray arrayWithObjects:
-							[KeyPathComponentTest class],
-							[PredicateTests class],
+							[PGTSInvocationRecorderTests class],
+							[PGTSHOMTests class],
+							[BXDelegateProxyTests class],
+							[NSPredicate_BaseTenAdditionsTests class],
+							[NSArray_BaseTenAdditionsTests class],
+							[PGTSValueTests class],
+							[BXKeyPathComponentTest class],
+							[BXPredicateTests class],
 							[BXDatabaseContextTests class],
-							[PGTSValueTests class],
 							
 							[PGTSMetadataTests class],
 							[PGTSTypeTests class],

File UnitTests/UnitTests.xcodeproj/project.pbxproj

 		5317CEBC0D1ACB1100A48792 /* ConnectTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 530A439E0A5C114E00A4722B /* ConnectTest.m */; };
 		53193F0A0BC51702009A77EC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53193E8D0BC51701009A77EC /* Foundation.framework */; };
 		534C95EC0FAB623F006BBC8A /* relationship-optionality.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = 534C95EB0FAB623F006BBC8A /* relationship-optionality.xcdatamodel */; };
-		535627B90E6E805D002EA3FD /* PredicateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 535627B80E6E805D002EA3FD /* PredicateTests.m */; };
+		535627B90E6E805D002EA3FD /* BXPredicateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 535627B80E6E805D002EA3FD /* BXPredicateTests.m */; };
 		535B3EA1103817FB00A5FB7E /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 535B3EA0103817FB00A5FB7E /* OCMock.framework */; };
 		535B3EAE1038182E00A5FB7E /* OCMock.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 535B3EA0103817FB00A5FB7E /* OCMock.framework */; };
 		536205A40FB84DE800ACAE57 /* PGTSParameterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 536205A30FB84DE800ACAE57 /* PGTSParameterTests.m */; };
 		53A0F85A0FB8EAA100F90FA1 /* PGTSValueTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 53A0F8590FB8EAA100F90FA1 /* PGTSValueTests.m */; };
 		53A59C560E3509CE0026D7E1 /* FetchTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 53BD965B0A5C1BA5001C950C /* FetchTests.m */; };
 		53BCC1D80F5EE90D00BD717A /* PGTSTypeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 53BCC1D70F5EE90D00BD717A /* PGTSTypeTests.m */; };
+		53C4C544119376A5003FB842 /* BXDelegateProxyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 53C4C543119376A5003FB842 /* BXDelegateProxyTests.m */; };
+		53C4C55011937A1F003FB842 /* PGTSHOMTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 53C4C54F11937A1F003FB842 /* PGTSHOMTests.m */; };
+		53C4C61711943369003FB842 /* PGTSInvocationRecorderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 53C4C61611943369003FB842 /* PGTSInvocationRecorderTests.m */; };
+		53C4C61C119439BF003FB842 /* NSArray+BaseTenAdditionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 53C4C61B119439BF003FB842 /* NSArray+BaseTenAdditionsTests.m */; };
+		53C4C62111943C8E003FB842 /* NSPredicate+BaseTenAdditionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 53C4C62011943C8E003FB842 /* NSPredicate+BaseTenAdditionsTests.m */; };
 		53C98A140CF0803A00D6A0A7 /* TestLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 535059B30CDA1CFC00DA25EC /* TestLoader.m */; };
 		53CC51500EC45F0B003D33BF /* ToOneChangeNotificationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 53CC514F0EC45F0B003D33BF /* ToOneChangeNotificationTests.m */; };
 		53D03BA90DE828CB002D14C4 /* BaseTen.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 538B40F50D634EA40009005B /* BaseTen.framework */; };
 		53DA50F40FCC53960044C961 /* people-departments-no-inverse.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = 53DA50F30FCC53960044C961 /* people-departments-no-inverse.xcdatamodel */; };
-		53DAA0590E6EEB46001DC1D9 /* KeyPathComponentTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 53DAA0580E6EEB46001DC1D9 /* KeyPathComponentTest.m */; };
+		53DAA0590E6EEB46001DC1D9 /* BXKeyPathComponentTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 53DAA0580E6EEB46001DC1D9 /* BXKeyPathComponentTest.m */; };
 		53E21C280FB49CFA00A52F1A /* BXTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 53E21C270FB49CFA00A52F1A /* BXTestCase.m */; };
 		53E21C330FB49E1800A52F1A /* BXGarbageCollectionRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = 53E21C320FB49E1800A52F1A /* BXGarbageCollectionRunner.m */; };
 		53F8E1DD0CBF7FF100C000C5 /* UnitTestAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 53A494840BD4D92F008E850E /* UnitTestAdditions.m */; };
 		534C95EB0FAB623F006BBC8A /* relationship-optionality.xcdatamodel */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = wrapper.xcdatamodel; name = "relationship-optionality.xcdatamodel"; path = "Sources/relationship-optionality.xcdatamodel"; sourceTree = "<group>"; };
 		535059B20CDA1CFC00DA25EC /* TestLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestLoader.h; path = Sources/TestLoader.h; sourceTree = "<group>"; };
 		535059B30CDA1CFC00DA25EC /* TestLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TestLoader.m; path = Sources/TestLoader.m; sourceTree = "<group>"; };
-		535627B70E6E805D002EA3FD /* PredicateTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PredicateTests.h; path = Sources/PredicateTests.h; sourceTree = "<group>"; };
-		535627B80E6E805D002EA3FD /* PredicateTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PredicateTests.m; path = Sources/PredicateTests.m; sourceTree = "<group>"; };
+		535627B70E6E805D002EA3FD /* BXPredicateTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BXPredicateTests.h; path = Sources/BXPredicateTests.h; sourceTree = "<group>"; };
+		535627B80E6E805D002EA3FD /* BXPredicateTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BXPredicateTests.m; path = Sources/BXPredicateTests.m; sourceTree = "<group>"; };
 		535717AC0CDE69C60084DD92 /* BXDatabaseObjectTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BXDatabaseObjectTests.h; path = Sources/BXDatabaseObjectTests.h; sourceTree = "<group>"; };
 		535717AD0CDE69C60084DD92 /* BXDatabaseObjectTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BXDatabaseObjectTests.m; path = Sources/BXDatabaseObjectTests.m; sourceTree = "<group>"; };
 		535B3EA0103817FB00A5FB7E /* OCMock.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OCMock.framework; path = ../Release/OCMock.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		53BD96750A5C1DC3001C950C /* CreateTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CreateTests.h; path = Sources/CreateTests.h; sourceTree = "<group>"; };
 		53BD96760A5C1DC3001C950C /* CreateTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CreateTests.m; path = Sources/CreateTests.m; sourceTree = "<group>"; };
 		53BD96BE0A5C2501001C950C /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = /System/Library/Frameworks/SenTestingKit.framework; sourceTree = "<absolute>"; };
+		53C4C542119376A5003FB842 /* BXDelegateProxyTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BXDelegateProxyTests.h; path = Sources/BXDelegateProxyTests.h; sourceTree = "<group>"; };
+		53C4C543119376A5003FB842 /* BXDelegateProxyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BXDelegateProxyTests.m; path = Sources/BXDelegateProxyTests.m; sourceTree = "<group>"; };
+		53C4C54E11937A1F003FB842 /* PGTSHOMTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PGTSHOMTests.h; path = Sources/PGTSHOMTests.h; sourceTree = "<group>"; };
+		53C4C54F11937A1F003FB842 /* PGTSHOMTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PGTSHOMTests.m; path = Sources/PGTSHOMTests.m; sourceTree = "<group>"; };
+		53C4C61511943369003FB842 /* PGTSInvocationRecorderTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PGTSInvocationRecorderTests.h; path = Sources/PGTSInvocationRecorderTests.h; sourceTree = "<group>"; };
+		53C4C61611943369003FB842 /* PGTSInvocationRecorderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PGTSInvocationRecorderTests.m; path = Sources/PGTSInvocationRecorderTests.m; sourceTree = "<group>"; };
+		53C4C61A119439BF003FB842 /* NSArray+BaseTenAdditionsTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSArray+BaseTenAdditionsTests.h"; path = "Sources/NSArray+BaseTenAdditionsTests.h"; sourceTree = "<group>"; };
+		53C4C61B119439BF003FB842 /* NSArray+BaseTenAdditionsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSArray+BaseTenAdditionsTests.m"; path = "Sources/NSArray+BaseTenAdditionsTests.m"; sourceTree = "<group>"; };
+		53C4C61F11943C8E003FB842 /* NSPredicate+BaseTenAdditionsTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSPredicate+BaseTenAdditionsTests.h"; path = "Sources/NSPredicate+BaseTenAdditionsTests.h"; sourceTree = "<group>"; };
+		53C4C62011943C8E003FB842 /* NSPredicate+BaseTenAdditionsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSPredicate+BaseTenAdditionsTests.m"; path = "Sources/NSPredicate+BaseTenAdditionsTests.m"; sourceTree = "<group>"; };
 		53CC514E0EC45F0B003D33BF /* ToOneChangeNotificationTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ToOneChangeNotificationTests.h; path = Sources/ToOneChangeNotificationTests.h; sourceTree = "<group>"; };
 		53CC514F0EC45F0B003D33BF /* ToOneChangeNotificationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ToOneChangeNotificationTests.m; path = Sources/ToOneChangeNotificationTests.m; sourceTree = "<group>"; };
 		53CEB9EF0B28516F007DAF0D /* MKCSenTestCaseAdditions.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = MKCSenTestCaseAdditions.h; path = Sources/MKCSenTestCaseAdditions.h; sourceTree = "<group>"; };
 		53D8703B1037521B0062A580 /* release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = release.xcconfig; sourceTree = "<group>"; };
 		53D8715010375CD70062A580 /* coverage.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = coverage.xcconfig; sourceTree = "<group>"; };
 		53DA50F30FCC53960044C961 /* people-departments-no-inverse.xcdatamodel */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = wrapper.xcdatamodel; name = "people-departments-no-inverse.xcdatamodel"; path = "Sources/people-departments-no-inverse.xcdatamodel"; sourceTree = "<group>"; };
-		53DAA0570E6EEB46001DC1D9 /* KeyPathComponentTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KeyPathComponentTest.h; path = Sources/KeyPathComponentTest.h; sourceTree = "<group>"; };
-		53DAA0580E6EEB46001DC1D9 /* KeyPathComponentTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KeyPathComponentTest.m; path = Sources/KeyPathComponentTest.m; sourceTree = "<group>"; };
+		53DAA0570E6EEB46001DC1D9 /* BXKeyPathComponentTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BXKeyPathComponentTest.h; path = Sources/BXKeyPathComponentTest.h; sourceTree = "<group>"; };
+		53DAA0580E6EEB46001DC1D9 /* BXKeyPathComponentTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BXKeyPathComponentTest.m; path = Sources/BXKeyPathComponentTest.m; sourceTree = "<group>"; };
 		53DAE20F0AC4A0D200536DD0 /* MTOCollectionTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MTOCollectionTest.h; path = Sources/MTOCollectionTest.h; sourceTree = "<group>"; };
 		53DAE2100AC4A0D200536DD0 /* MTOCollectionTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MTOCollectionTest.m; path = Sources/MTOCollectionTest.m; sourceTree = "<group>"; };
 		53E21C260FB49CFA00A52F1A /* BXTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BXTestCase.h; path = Sources/BXTestCase.h; sourceTree = "<group>"; };
 		535627B10E6E8015002EA3FD /* Tests not requiring a connection */ = {
 			isa = PBXGroup;
 			children = (
-				53DAA0570E6EEB46001DC1D9 /* KeyPathComponentTest.h */,
-				53DAA0580E6EEB46001DC1D9 /* KeyPathComponentTest.m */,
-				535627B70E6E805D002EA3FD /* PredicateTests.h */,
-				535627B80E6E805D002EA3FD /* PredicateTests.m */,
+				53C4C61511943369003FB842 /* PGTSInvocationRecorderTests.h */,
+				53C4C61611943369003FB842 /* PGTSInvocationRecorderTests.m */,
+				53C4C54E11937A1F003FB842 /* PGTSHOMTests.h */,
+				53C4C54F11937A1F003FB842 /* PGTSHOMTests.m */,
+				53C4C542119376A5003FB842 /* BXDelegateProxyTests.h */,
+				53C4C543119376A5003FB842 /* BXDelegateProxyTests.m */,
+				53C4C61F11943C8E003FB842 /* NSPredicate+BaseTenAdditionsTests.h */,
+				53C4C62011943C8E003FB842 /* NSPredicate+BaseTenAdditionsTests.m */,