diff --git a/ChangeLog b/ChangeLog index 800371d9b..4b48dc1a9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2010-01-08 Ludovic Marcotte + + * SoObjects/SOGo/LDAPSource.{h,m} - bindFields is now + an array instead of a list of strings separated by commas. + Updated the Installation & Configuration Guide to reflect + this change. + +2010-01-08 Wolfgang Sourdeau + + * UnitTests/SOGoTestRunner.m: separated class "SOGoTestRunner" + from sogo-tests.m. Moved reporting and logging methods from + SOGoTest into SOGoTestRunner.m + + * SoObjects/SOGo/NSString+Utilities.m (-_setupCSSEscaping): we + must initialize cssEscapingCount before using it. Also, fixed a + typo preventing the character buffer from being initialized + completely. + 2010-01-07 Francis Lachapelle * SoObjects/SOGo/NSString+Utilities.m (-asCSSIdentifier): replaced @@ -6,6 +24,11 @@ 2010-01-07 Wolfgang Sourdeau + * SoObjects/SOGo/NSString+Utilities.m (-fromCSSIdentifier): speed + things up a little bit by checking whether the current character + is '_', possibly announcing an escaped sequence, anything else + being treated regularly. + * SoObjects/SOGo/NSDictionary+BSJSONAdditions.m (-jsonStringFromString:): convert "\" to "\\" rather than "\n". diff --git a/Documentation/SOGo Installation Guide.odt b/Documentation/SOGo Installation Guide.odt index 296226d4a..486c72a55 100644 Binary files a/Documentation/SOGo Installation Guide.odt and b/Documentation/SOGo Installation Guide.odt differ diff --git a/SoObjects/SOGo/LDAPSource.h b/SoObjects/SOGo/LDAPSource.h index 0f3cfa34a..ab09c6661 100644 --- a/SoObjects/SOGo/LDAPSource.h +++ b/SoObjects/SOGo/LDAPSource.h @@ -52,7 +52,7 @@ NSString *UIDField; NSArray *mailFields; NSString *IMAPHostField; - NSString *bindFields; + NSArray *bindFields; NSString *domain; NSString *contactInfoAttribute; @@ -74,7 +74,7 @@ UIDField: (NSString *) newUIDField mailFields: (NSArray *) newMailFields IMAPHostField: (NSString *) newIMAPHostField - andBindFields: (NSString *) newBindFields; + andBindFields: (id) newBindFields; - (NGLdapEntry *) lookupGroupEntryByUID: (NSString *) theUID; - (NGLdapEntry *) lookupGroupEntryByEmail: (NSString *) theEmail; diff --git a/SoObjects/SOGo/LDAPSource.m b/SoObjects/SOGo/LDAPSource.m index 9287abaaa..958b9f032 100644 --- a/SoObjects/SOGo/LDAPSource.m +++ b/SoObjects/SOGo/LDAPSource.m @@ -266,7 +266,7 @@ static NSArray *commonSearchFields; UIDField: (NSString *) newUIDField mailFields: (NSArray *) newMailFields IMAPHostField: (NSString *) newIMAPHostField - andBindFields: (NSString *) newBindFields + andBindFields: (id) newBindFields { ASSIGN (baseDN, [newBaseDN lowercaseString]); if (newIDField) @@ -280,7 +280,28 @@ static NSArray *commonSearchFields; if (newMailFields) ASSIGN (mailFields, newMailFields); if (newBindFields) - ASSIGN (bindFields, newBindFields); + { + // Before SOGo v1.2.0, bindFields was a comma-separated list + // of values. So it could be configured as: + // + // bindFields = foo; + // bindFields = "foo, bar, baz"; + // + // SOGo v1.2.0 and upwards redefined that parameter as an array + // so we would have instead: + // + // bindFields = (foo); + // bindFields = (foo, bar, baz); + // + // We check for the old format and we support it. + if ([newBindFields isKindOfClass: [NSArray class]]) + ASSIGN(bindFields, newBindFields); + else + { + [self logWithFormat: @"WARNING: using old bindFields format - please update it"]; + ASSIGN(bindFields, [newBindFields componentsSeparatedByString: @","]); + } + } } - (BOOL) _setupEncryption: (NGLdapConnection *) encryptedConn @@ -351,7 +372,7 @@ static NSArray *commonSearchFields; escapedUid = SafeLDAPCriteria (uid); - fields = [[bindFields componentsSeparatedByString: @","] objectEnumerator]; + fields = [bindFields objectEnumerator]; while ((currentField = [fields nextObject])) [qs appendFormat: @" OR (%@='%@')", currentField, escapedUid]; @@ -482,8 +503,7 @@ static NSArray *commonSearchFields; UIDField, escapedUid, mailFormat]; if (bindFields) { - bindFieldsEnum = [[bindFields componentsSeparatedByString: @","] - objectEnumerator]; + bindFieldsEnum = [bindFields objectEnumerator]; while ((currentField = [bindFieldsEnum nextObject])) [qs appendFormat: @" OR (%@='%@')", [currentField stringByTrimmingSpaces], escapedUid]; } diff --git a/SoObjects/SOGo/NSArray+Utilities.h b/SoObjects/SOGo/NSArray+Utilities.h index 246c4700c..f6213738d 100644 --- a/SoObjects/SOGo/NSArray+Utilities.h +++ b/SoObjects/SOGo/NSArray+Utilities.h @@ -30,7 +30,7 @@ @interface NSArray (SOGoArrayUtilities) - (id *) asPointersOfObjects; - + - (NSString *) jsonRepresentation; - (NSArray *) stringsWithFormat: (NSString *) format; diff --git a/SoObjects/SOGo/NSArray+Utilities.m b/SoObjects/SOGo/NSArray+Utilities.m index 8c7453233..146ad8efc 100644 --- a/SoObjects/SOGo/NSArray+Utilities.m +++ b/SoObjects/SOGo/NSArray+Utilities.m @@ -290,4 +290,3 @@ } @end - diff --git a/SoObjects/SOGo/NSString+Utilities.m b/SoObjects/SOGo/NSString+Utilities.m index ae4bbe2b9..128159130 100644 --- a/SoObjects/SOGo/NSString+Utilities.m +++ b/SoObjects/SOGo/NSString+Utilities.m @@ -42,7 +42,7 @@ static NSMutableCharacterSet *urlStartChars = nil; static NSString **cssEscapingStrings = NULL; static unichar *cssEscapingCharacters = NULL; -static int cssEscapingCount = 0; +static int cssEscapingCount; @implementation NSString (SOGoURLExtension) @@ -321,9 +321,10 @@ static int cssEscapingCount = 0; characters = [NSArray arrayWithObjects: @"_", @".", @"#", @"@", @"*", @":", @",", @" ", nil]; - cssEscapingCharacters - = NSZoneMalloc (NULL, sizeof ((cssEscapingCount + 1) * sizeof (unichar))); cssEscapingCount = [strings count]; + cssEscapingCharacters = NSZoneMalloc (NULL, + (cssEscapingCount + 1) + * sizeof (unichar)); for (count = 0; count < cssEscapingCount; count++) *(cssEscapingCharacters + count) = [[characters objectAtIndex: count] characterAtIndex: 0]; @@ -383,6 +384,7 @@ static int cssEscapingCount = 0; NSMutableString *newString; NSString *currentString; int count, length, max, idx; + unichar currentChar; if (!cssEscapingStrings) [self _setupCSSEscaping]; @@ -391,21 +393,27 @@ static int cssEscapingCount = 0; max = [self length]; for (count = 0; count < max - 2; count++) { - /* The difficulty here is that most escaping strings are 3 chars long - except one. Therefore we must juggle a little bit with the lengths in - order to avoid an overflow exception. */ - length = 4; - if (count + length > max) - length = max - count; - currentString = [self substringFromRange: NSMakeRange (count, length)]; - idx = [self _cssStringIndex: currentString]; - if (idx > -1) + currentChar = [self characterAtIndex: count]; + if (currentChar == '_') { - [newString appendFormat: @"%C", cssEscapingCharacters[idx]]; - count += [cssEscapingStrings[idx] length] - 1; + /* The difficulty here is that most escaping strings are 3 chars + long except one. Therefore we must juggle a little bit with the + lengths in order to avoid an overflow exception. */ + length = 4; + if (count + length > max) + length = max - count; + currentString = [self substringFromRange: NSMakeRange (count, length)]; + idx = [self _cssStringIndex: currentString]; + if (idx > -1) + { + [newString appendFormat: @"%C", cssEscapingCharacters[idx]]; + count += [cssEscapingStrings[idx] length] - 1; + } + else + [newString appendFormat: @"%C", currentChar]; } else - [newString appendFormat: @"%C", [self characterAtIndex: count]]; + [newString appendFormat: @"%C", currentChar]; } currentString = [self substringFromRange: NSMakeRange (count, max - count)]; [newString appendString: currentString]; diff --git a/UnitTests/GNUmakefile b/UnitTests/GNUmakefile index 94a5cf204..a599941a6 100644 --- a/UnitTests/GNUmakefile +++ b/UnitTests/GNUmakefile @@ -12,6 +12,7 @@ $(TEST_TOOL)_OBJC_FILES += \ sogo-tests.m \ \ SOGoTest.m \ + SOGoTestRunner.m \ \ TestBSJSONAdditions.m diff --git a/UnitTests/SOGoTest.h b/UnitTests/SOGoTest.h index 09b289834..3e9e43cb4 100644 --- a/UnitTests/SOGoTest.h +++ b/UnitTests/SOGoTest.h @@ -29,23 +29,18 @@ @class NSArray; @class NSMutableArray; -typedef enum { - SOGoTestFailureSuccess = 0, - SOGoTestFailureFailure = 1, - SOGoTestFailureError = 2, -} SOGoTestFailureCode; +@class SOGoTestRunner; @interface SOGoTest : NSObject { - NSMutableArray *messages; - int testCount; - int failuresCount; - int errorsCount; + SOGoTestRunner *testRunner; BOOL hasFailed; } + (NSArray *) allTestClasses; +- (void) setTestRunner: (SOGoTestRunner *) newTestRunner; + - (void) setUp; - (void) tearDown; diff --git a/UnitTests/SOGoTest.m b/UnitTests/SOGoTest.m index 1015633ca..5c58c9938 100644 --- a/UnitTests/SOGoTest.m +++ b/UnitTests/SOGoTest.m @@ -20,7 +20,12 @@ * Boston, MA 02111-1307, USA. */ -#import +#import +#import +#import +#import + +#import "SOGoTestRunner.h" #import "SOGoTest.h" @@ -52,11 +57,7 @@ static NSString *SOGoTestAssertException = @"SOGoTestAssertException"; { if ((self = [super init])) { - messages = [NSMutableArray new]; - testCount = 0; - failuresCount = 0; - errorsCount = 0; - hasFailed = NO; + testRunner = nil; } return self; @@ -64,10 +65,15 @@ static NSString *SOGoTestAssertException = @"SOGoTestAssertException"; - (void) dealloc { - [messages release]; + [testRunner release]; [super dealloc]; } +- (void) setTestRunner: (SOGoTestRunner *) newTestRunner +{ + ASSIGN (testRunner, newTestRunner); +} + - (void) setUp { } @@ -97,44 +103,8 @@ static NSString *SOGoTestAssertException = @"SOGoTestAssertException"; } } -- (void) reportException: (NSException *) exception - method: (NSString *) methodName - withCode: (SOGoTestFailureCode) failureCode -{ - static NSString *failurePrefixs[] = { @"", @"FAIL", @"ERROR" }; - NSMutableString *message; - NSString *fileInfo; - - hasFailed = YES; - - message = [NSMutableString stringWithFormat: @"%@: %@", - failurePrefixs[failureCode], methodName]; - fileInfo = [[exception userInfo] objectForKey: @"fileInfo"]; - if (fileInfo) - [message appendFormat: @" (%@)\n", fileInfo]; - else - [message appendString: @"\n"]; - [message appendString: @"----------------------------------------------------------------------\n"]; - - if (failureCode == SOGoTestFailureFailure) - { - [message appendString: [exception reason]]; - failuresCount++; - } - else if (failureCode == SOGoTestFailureError) - { - [message appendFormat: @"an exception occured: %@\n" - @" reason: %@", - [exception name], [exception reason]]; - errorsCount++; - } - [message appendString: @"\n"]; - [messages addObject: message]; -} - - (void) performTest: (SEL) testMethod { - static char failureChars[] = { '.', 'F', 'E' }; SOGoTestFailureCode failureCode; failureCode = SOGoTestFailureSuccess; @@ -145,9 +115,9 @@ static NSString *SOGoTestAssertException = @"SOGoTestAssertException"; NS_HANDLER { failureCode = SOGoTestFailureError; - [self reportException: localException - method: @"setUp" - withCode: failureCode]; + [testRunner reportException: localException + method: @"setUp" + withCode: failureCode]; } NS_ENDHANDLER; @@ -164,9 +134,9 @@ static NSString *SOGoTestAssertException = @"SOGoTestAssertException"; failureCode = SOGoTestFailureFailure; else failureCode = SOGoTestFailureError; - [self reportException: localException - method: NSStringFromSelector (testMethod) - withCode: failureCode]; + [testRunner reportException: localException + method: NSStringFromSelector (testMethod) + withCode: failureCode]; } NS_ENDHANDLER; } @@ -178,35 +148,13 @@ static NSString *SOGoTestAssertException = @"SOGoTestAssertException"; NS_HANDLER { failureCode = SOGoTestFailureError; - [self reportException: localException - method: @"tearDown" - withCode: failureCode]; + [testRunner reportException: localException + method: @"tearDown" + withCode: failureCode]; } NS_ENDHANDLER; - testCount++; - fprintf (stderr, "%c", failureChars[failureCode]); -} - -- (void) displayReport -{ - static NSString *separator = @"\n======================================================================\n"; - NSString *reportMessage; - - if ([messages count]) - { - fprintf (stderr, "%s", [separator UTF8String]); - reportMessage = [messages componentsJoinedByString: separator]; - fprintf (stderr, "%s", [reportMessage UTF8String]); - } - fprintf (stderr, - "\n----------------------------------------------------------------------\n" - "Ran %d tests\n\n", testCount); - if (hasFailed) - fprintf (stderr, "FAILED (%d failures, %d errors)\n", - failuresCount, errorsCount); - else - fprintf (stderr, "OK\n"); + [testRunner incrementTestCounter: failureCode]; } - (BOOL) run @@ -229,8 +177,6 @@ static NSString *SOGoTestAssertException = @"SOGoTestAssertException"; } } - [self displayReport]; - return YES; } diff --git a/UnitTests/SOGoTestRunner.h b/UnitTests/SOGoTestRunner.h new file mode 100644 index 000000000..539fb5c33 --- /dev/null +++ b/UnitTests/SOGoTestRunner.h @@ -0,0 +1,60 @@ +/* SOGoTestRunner.h - this file is part of SOGo + * + * Copyright (C) 2010 Inverse inc. + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file 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; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef SOGOTESTRUNNER_H +#define SOGOTESTRUNNER_H + +#import + +@class NSException; +@class NSMutableArray; +@class NSString; + +typedef enum { + SOGoTestFailureSuccess = 0, + SOGoTestFailureFailure = 1, + SOGoTestFailureError = 2, +} SOGoTestFailureCode; + +@interface SOGoTestRunner : NSObject +{ + NSMutableArray *messages; + int testCount; + int failuresCount; + int errorsCount; + BOOL hasFailed; +} + ++ (SOGoTestRunner *) testRunner; + +- (int) run; + +- (void) incrementTestCounter: (SOGoTestFailureCode) failureCode; +- (void) reportException: (NSException *) exception + method: (NSString *) methodName + withCode: (SOGoTestFailureCode) failureCode; + +- (void) displayReport; + +@end + +#endif /* SOGOTESTRUNNER_H */ diff --git a/UnitTests/SOGoTestRunner.m b/UnitTests/SOGoTestRunner.m new file mode 100644 index 000000000..80f5361ea --- /dev/null +++ b/UnitTests/SOGoTestRunner.m @@ -0,0 +1,162 @@ +/* SOGoTestRunner.m - this file is part of SOGo + * + * Copyright (C) 2010 Inverse inc. + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file 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; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import +#import +#import +#import +#import +#import + +#import "SOGoTest.h" + +#import "SOGoTestRunner.h" + +@implementation SOGoTestRunner + ++ (SOGoTestRunner *) testRunner +{ + SOGoTestRunner *testRunner; + + testRunner = [self new]; + [testRunner autorelease]; + + return testRunner; +} + +- (id) init +{ + if ((self = [super init])) + { + testCount = 0; + failuresCount = 0; + errorsCount = 0; + hasFailed = NO; + messages = nil; + } + + return self; +} + +- (void) dealloc +{ + [messages release]; + [super dealloc]; +} + +- (int) run +{ + NSEnumerator *allTestClasses; + NSString *class; + SOGoTest *test; + NSAutoreleasePool *pool; + int rc; + + rc = 0; + pool = [NSAutoreleasePool currentPool]; + + [self retain]; + allTestClasses = [[SOGoTest allTestClasses] objectEnumerator]; + [allTestClasses retain]; + while ((class = [allTestClasses nextObject])) + { + test = [NSClassFromString (class) new]; + [test setTestRunner: self]; + if (![test run]) + rc |= -1; + [test autorelease]; + [pool emptyPool]; + } + + [self displayReport]; + + [allTestClasses autorelease]; + [self autorelease]; + + return rc; +} + +- (void) incrementTestCounter: (SOGoTestFailureCode) failureCode +{ + static char failureChars[] = { '.', 'F', 'E' }; + + testCount++; + fprintf (stderr, "%c", failureChars[failureCode]); +} + +- (void) reportException: (NSException *) exception + method: (NSString *) methodName + withCode: (SOGoTestFailureCode) failureCode +{ + static NSString *failurePrefixs[] = { @"", @"FAIL", @"ERROR" }; + NSMutableString *message; + NSString *fileInfo; + + hasFailed = YES; + + message = [NSMutableString stringWithFormat: @"%@: %@", + failurePrefixs[failureCode], methodName]; + fileInfo = [[exception userInfo] objectForKey: @"fileInfo"]; + if (fileInfo) + [message appendFormat: @" (%@)\n", fileInfo]; + else + [message appendString: @"\n"]; + [message appendString: @"----------------------------------------------------------------------\n"]; + + if (failureCode == SOGoTestFailureFailure) + { + [message appendString: [exception reason]]; + failuresCount++; + } + else if (failureCode == SOGoTestFailureError) + { + [message appendFormat: @"an exception occured: %@\n" + @" reason: %@", + [exception name], [exception reason]]; + errorsCount++; + } + [message appendString: @"\n"]; + [messages addObject: message]; +} + +- (void) displayReport +{ + static NSString *separator = @"\n======================================================================\n"; + NSString *reportMessage; + + if ([messages count]) + { + fprintf (stderr, "%s", [separator UTF8String]); + reportMessage = [messages componentsJoinedByString: separator]; + fprintf (stderr, "%s", [reportMessage UTF8String]); + } + fprintf (stderr, + "\n----------------------------------------------------------------------\n" + "Ran %d tests\n\n", testCount); + if (hasFailed) + fprintf (stderr, "FAILED (%d failures, %d errors)\n", + failuresCount, errorsCount); + else + fprintf (stderr, "OK\n"); +} + +@end diff --git a/UnitTests/TestBSJSONAdditions.m b/UnitTests/TestBSJSONAdditions.m index 1cd5c5583..1384167c5 100644 --- a/UnitTests/TestBSJSONAdditions.m +++ b/UnitTests/TestBSJSONAdditions.m @@ -28,10 +28,10 @@ #import "SOGoTest.h" -@interface TestNSSCannerBSJSONAdditions : SOGoTest +@interface TestNSScannerBSJSONAdditions : SOGoTest @end -@implementation TestNSSCannerBSJSONAdditions +@implementation TestNSScannerBSJSONAdditions - (void) test_scanJSONString { diff --git a/UnitTests/sogo-tests.m b/UnitTests/sogo-tests.m index 67c5a4e8a..35fb4f4ad 100644 --- a/UnitTests/sogo-tests.m +++ b/UnitTests/sogo-tests.m @@ -22,51 +22,7 @@ #import -#import "SOGoTest.h" - -@interface SOGoTestRunner : NSObject -@end - -@implementation SOGoTestRunner - -+ (SOGoTestRunner *) testRunner -{ - SOGoTestRunner *testRunner; - - testRunner = [self new]; - [testRunner autorelease]; - - return testRunner; -} - -- (int) run -{ - NSEnumerator *allTestClasses; - NSString *class; - SOGoTest *test; - NSAutoreleasePool *pool; - int rc; - - rc = 0; - pool = [NSAutoreleasePool currentPool]; - - [self retain]; - allTestClasses = [[SOGoTest allTestClasses] objectEnumerator]; - [allTestClasses retain]; - while ((class = [allTestClasses nextObject])) - { - test = [NSClassFromString (class) new]; - if (![test run]) - rc |= -1; - [pool emptyPool]; - } - [allTestClasses autorelease]; - [self autorelease]; - - return rc; -} - -@end +#import "SOGoTestRunner.h" int main() {