merge of '18bcde63a97bfd2933b370687c939865d8c21d61'

and '32e14dc57c4f6d9a43de5dfdf3c298091cbf84ea'

Monotone-Parent: 18bcde63a97bfd2933b370687c939865d8c21d61
Monotone-Parent: 32e14dc57c4f6d9a43de5dfdf3c298091cbf84ea
Monotone-Revision: 583f127303a07196077a96b395056caf120f4117

Monotone-Author: flachapelle@inverse.ca
Monotone-Date: 2010-01-11T18:25:50
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Francis Lachapelle 2010-01-11 18:25:50 +00:00
commit dad75bbdde
14 changed files with 327 additions and 157 deletions

View file

@ -1,3 +1,21 @@
2010-01-08 Ludovic Marcotte <lmarcotte@inverse.ca>
* 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 <wsourdeau@inverse.ca>
* 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 <flachapelle@inverse.ca>
* SoObjects/SOGo/NSString+Utilities.m (-asCSSIdentifier): replaced
@ -6,6 +24,11 @@
2010-01-07 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* 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".

View file

@ -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;

View file

@ -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];
}

View file

@ -30,7 +30,7 @@
@interface NSArray (SOGoArrayUtilities)
- (id *) asPointersOfObjects;
- (NSString *) jsonRepresentation;
- (NSArray *) stringsWithFormat: (NSString *) format;

View file

@ -290,4 +290,3 @@
}
@end

View file

@ -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];

View file

@ -12,6 +12,7 @@ $(TEST_TOOL)_OBJC_FILES += \
sogo-tests.m \
\
SOGoTest.m \
SOGoTestRunner.m \
\
TestBSJSONAdditions.m

View file

@ -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;

View file

@ -20,7 +20,12 @@
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/Foundation.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSException.h>
#import <Foundation/NSString.h>
#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;
}

View file

@ -0,0 +1,60 @@
/* SOGoTestRunner.h - this file is part of SOGo
*
* Copyright (C) 2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* 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 <Foundation/NSObject.h>
@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 */

162
UnitTests/SOGoTestRunner.m Normal file
View file

@ -0,0 +1,162 @@
/* SOGoTestRunner.m - this file is part of SOGo
*
* Copyright (C) 2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* 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 <Foundation/NSArray.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSException.h>
#import <Foundation/NSString.h>
#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

View file

@ -28,10 +28,10 @@
#import "SOGoTest.h"
@interface TestNSSCannerBSJSONAdditions : SOGoTest
@interface TestNSScannerBSJSONAdditions : SOGoTest
@end
@implementation TestNSSCannerBSJSONAdditions
@implementation TestNSScannerBSJSONAdditions
- (void) test_scanJSONString
{

View file

@ -22,51 +22,7 @@
#import <Foundation/Foundation.h>
#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()
{