Merge pull request #184 from zentyal/master

Fixes from Zentyal since 2015/12/30
This commit is contained in:
extrafu 2016-01-18 09:10:35 -05:00
commit a503b34d7a
28 changed files with 1283 additions and 208 deletions

View file

@ -77,6 +77,17 @@
- (NSArray *) rolesForExchangeRights: (uint32_t) rights
{
/* Limitations
Following rights are not supported by SOGo specifically:
- DeleteOwned : Delete only own objects
- EditOwned : Edit only own objects
- CreateSubfolders: No calendar subfolders
- FolderOwner: No sharing folder ownership?
- FolderContact: No support to store this information
- FolderVisible: It is inferred by other rights when extracting
*/
NSMutableArray *roles;
roles = [NSMutableArray arrayWithCapacity: 6];
@ -121,7 +132,7 @@
if ([roles containsObject: SOGoCalendarRole_PublicModifier]
&& [roles containsObject: SOGoCalendarRole_PrivateModifier]
&& [roles containsObject: SOGoCalendarRole_ConfidentialModifier])
rights |= RightsReadItems | RightsEditAll | RightsEditOwn;
rights |= RightsReadItems | RightsEditAll | RightsEditOwn | RightsFreeBusySimple | RightsFreeBusyDetailed;
else if ([roles containsObject: SOGoCalendarRole_PublicViewer]
&& [roles containsObject: SOGoCalendarRole_PrivateViewer]
&& [roles containsObject: SOGoCalendarRole_ConfidentialViewer])
@ -135,7 +146,7 @@
if ([roles containsObject: SOGoCalendarRole_ConfidentialDAndTViewer])
rights |= RightsFreeBusyDetailed;
if (rights != 0)
if ((rights & RightsReadItems) != 0 || (rights & RightsCreateItems) != 0 || (rights & RightsDeleteAll) != 0)
rights |= RoleNone; /* actually "folder visible" */
// [self logWithFormat: @"rights for roles (%@) = %.8x", roles, rights];

View file

@ -64,11 +64,11 @@ static BOOL initialization_done = NO;
} \
OC_DEBUG(5, "[SOGo] --->");
#define NS_CURRENT_THREAD_TRY_UNREGISTER() \
#define NS_CURRENT_THREAD_TRY_UNREGISTER(rc) \
if (__nsrct_thread_registered) { \
GSUnregisterCurrentThread(); \
} \
OC_DEBUG(6, "[SOGo] <---");
OC_DEBUG(6, "[SOGo] <--- [%s]", mapistore_errstr (rc));
#define TRYCATCH_START @try {
#define TRYCATCH_END(pool) \
@ -76,7 +76,7 @@ static BOOL initialization_done = NO;
enum mapistore_error ret = sogo_backend_handle_objc_exception(e, __PRETTY_FUNCTION__, __LINE__); \
mapiapp_cleanup(); \
[pool release]; \
NS_CURRENT_THREAD_TRY_UNREGISTER(); \
NS_CURRENT_THREAD_TRY_UNREGISTER(ret); \
return ret; \
} \
mapiapp_cleanup();
@ -253,7 +253,7 @@ sogo_backend_create_context(TALLOC_CTX *mem_ctx,
rc = MAPISTORE_ERROR;
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
return rc;
}
@ -291,7 +291,7 @@ sogo_backend_create_root_folder (const char *username,
rc = MAPISTORE_ERROR;
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
return rc;
}
@ -322,7 +322,7 @@ sogo_backend_list_contexts(const char *username, struct indexing_context *indexi
rc = MAPISTORE_ERROR;
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
return rc;
}
@ -363,7 +363,7 @@ sogo_context_get_path(void *backend_object, TALLOC_CTX *mem_ctx,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -397,7 +397,7 @@ sogo_context_get_root_folder(void *backend_object, TALLOC_CTX *mem_ctx,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -439,7 +439,7 @@ sogo_folder_open_folder(void *folder_object, TALLOC_CTX *mem_ctx, uint64_t fid,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -480,7 +480,7 @@ sogo_folder_create_folder(void *folder_object, TALLOC_CTX *mem_ctx,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -519,7 +519,7 @@ sogo_folder_delete(void *folder_object)
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -549,7 +549,7 @@ sogo_folder_get_child_count(void *folder_object, enum mapistore_table_type table
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -588,7 +588,7 @@ sogo_folder_open_message(void *folder_object,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -627,7 +627,7 @@ sogo_folder_create_message(void *folder_object,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -657,7 +657,7 @@ sogo_folder_delete_message(void *folder_object, uint64_t mid, uint8_t flags)
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -705,7 +705,7 @@ sogo_folder_move_copy_messages(void *folder_object,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -753,7 +753,7 @@ sogo_folder_move_folder(void *folder_object, void *target_folder_object,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -795,7 +795,7 @@ sogo_folder_copy_folder(void *folder_object, void *target_folder_object, TALLOC_
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -831,7 +831,7 @@ sogo_folder_get_deleted_fmids(void *folder_object, TALLOC_CTX *mem_ctx,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -869,7 +869,7 @@ sogo_folder_open_table(void *folder_object, TALLOC_CTX *mem_ctx,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -903,7 +903,7 @@ sogo_folder_modify_permissions(void *folder_object, uint8_t flags,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -934,7 +934,7 @@ sogo_folder_preload_message_bodies(void *folder_object, enum mapistore_table_typ
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -967,8 +967,8 @@ sogo_message_get_message_data(void *message_object,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
rc = MAPISTORE_SUCCESS;
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1001,7 +1001,7 @@ sogo_message_create_attachment (void *message_object, TALLOC_CTX *mem_ctx, void
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1035,7 +1035,7 @@ sogo_message_open_attachment (void *message_object, TALLOC_CTX *mem_ctx,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1069,7 +1069,7 @@ sogo_message_get_attachment_table (void *message_object, TALLOC_CTX *mem_ctx, vo
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1104,7 +1104,7 @@ sogo_message_modify_recipients (void *message_object,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1134,7 +1134,7 @@ sogo_message_set_read_flag (void *message_object, uint8_t flag)
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1164,7 +1164,7 @@ sogo_message_save (void *message_object, TALLOC_CTX *mem_ctx)
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1194,7 +1194,7 @@ sogo_message_submit (void *message_object, enum SubmitFlags flags)
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1234,7 +1234,7 @@ sogo_message_attachment_open_embedded_message (void *attachment_object,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1272,7 +1272,7 @@ sogo_message_attachment_create_embedded_message (void *attachment_object,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1302,7 +1302,7 @@ static enum mapistore_error sogo_table_get_available_properties(void *table_obje
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1333,7 +1333,7 @@ sogo_table_set_columns (void *table_object, uint16_t count, enum MAPITAGS *prope
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1366,7 +1366,7 @@ sogo_table_set_restrictions (void *table_object, struct mapi_SRestriction *restr
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1399,7 +1399,7 @@ sogo_table_set_sort_order (void *table_object, struct SSortOrderSet *sort_order,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1432,7 +1432,7 @@ sogo_table_get_row (void *table_object, TALLOC_CTX *mem_ctx,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1465,7 +1465,7 @@ sogo_table_get_row_count (void *table_object,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1495,8 +1495,8 @@ sogo_table_handle_destructor (void *table_object, uint32_t handle_id)
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
rc = MAPISTORE_SUCCESS;
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1527,7 +1527,7 @@ static enum mapistore_error sogo_properties_get_available_properties(void *objec
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1562,7 +1562,7 @@ sogo_properties_get_properties (void *object,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1592,7 +1592,7 @@ sogo_properties_set_properties (void *object, struct SRow *aRow)
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(rc);
}
else
{
@ -1646,7 +1646,7 @@ sogo_manager_generate_uri (TALLOC_CTX *mem_ctx,
TRYCATCH_END(pool)
[pool release];
NS_CURRENT_THREAD_TRY_UNREGISTER();
NS_CURRENT_THREAD_TRY_UNREGISTER(MAPISTORE_SUCCESS);
return MAPISTORE_SUCCESS;
}

View file

@ -28,6 +28,8 @@
//
//
//
@class RTFFontTable;
@interface RTFHandler : NSObject
{
NSMapTable *_charsets;
@ -41,6 +43,11 @@
- (id) initWithData: (NSData *) theData;
- (NSMutableData *) parse;
- (RTFFontTable *) parseFontTable;
- (void) mangleInternalStateWithBytesPtr: (const char*) newBytes
andCurrentPos: (int) newCurrentPos;
@end
//
@ -84,6 +91,7 @@
unsigned int index;
}
- (NSString *) description;
@end
//
@ -97,8 +105,8 @@
- (void) addFontInfo: (RTFFontInfo *) theFontInfo
atIndex: (unsigned int ) theIndex;
- (RTFFontInfo *) fontInfoAtIndex: (unsigned int ) theIndex;
- (NSString *) description;
@end

View file

@ -21,6 +21,7 @@
#include "RTFHandler.h"
#include <Foundation/NSValue.h>
#include <Foundation/NSException.h>
//
// Useful macros
@ -352,6 +353,7 @@ const unsigned short ansicpg874[256] = {
RTFFontInfo *fontInfo;
description = [NSMutableString stringWithFormat: @"Number of fonts: %u\n", [fontInfos count]];
enumerator = [fontInfos objectEnumerator];
while ((fontInfo = [enumerator nextObject]))
{
@ -563,6 +565,9 @@ static void _init_fontCws_table()
[super dealloc];
}
/*
Returns pointer to the control word and in len pointer its length including numeric argument
*/
- (const char *) parseControlWord: (unsigned int *) len
{
const char *start, *end;
@ -1457,4 +1462,12 @@ inline static void parseUl(RTFHandler *self, BOOL hasArg, int arg, RTFFormatting
return [_html autorelease];
}
/* This method is for ease of testing and should not be used in normal operations */
- (void) mangleInternalStateWithBytesPtr: (const char*) newBytes
andCurrentPos: (int) newCurrentPos
{
_bytes = newBytes;
_current_pos = newCurrentPos;
}
@end

View file

@ -23,6 +23,7 @@
#import <NGObjWeb/WOContext+SoObjects.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserManager.h>
#import <SOGo/SOGoSystemDefaults.h>
#import "iCalPerson+SOGo.h"
@ -64,6 +65,10 @@ static SOGoUserManager *um = nil;
return [um getUIDForEmail: [self rfc822Email]];
}
/*
It returns the login if the email of the iCalPerson exists on the
domain of the current active user
*/
- (NSString *) uidInContext: (WOContext *) context
{
NSString *domain;
@ -73,18 +78,29 @@ static SOGoUserManager *um = nil;
return [self uidInDomain: domain];
}
/*
It returns the login if the email of the iCalPerson exists on the
given domain
*/
- (NSString *) uidInDomain: (NSString *) domain
{
NSDictionary *contact;
NSString *uid;
NSString *uid = nil;
if (!um)
um = [SOGoUserManager sharedUserManager];
uid = nil;
contact = [um contactInfosForUserWithUIDorEmail: [self rfc822Email] inDomain: domain];
if (contact)
uid = [contact valueForKey: @"c_uid"];
contact = [um contactInfosForUserWithUIDorEmail: [self rfc822Email]
inDomain: domain];
if (!contact) return nil;
uid = [contact valueForKey: @"c_uid"];
// On multidomain environment without DomainLessLogin enabled the login
// must have the @domain suffix
if ([[SOGoSystemDefaults sharedSystemDefaults] enableDomainBasedUID]
&& ![[contact objectForKey: @"DomainLessLogin"] boolValue])
uid = [NSString stringWithFormat:@"%@@%@", uid, domain];
return uid;
}

View file

@ -24,6 +24,7 @@
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSData.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSKeyValueCoding.h>
#import <Foundation/NSProcessInfo.h>
#import <Foundation/NSURL.h>
@ -1094,7 +1095,7 @@ static NSString *userAgent = nil;
- (NSException *) saveAttachment: (NSData *) _attach
withMetadata: (NSDictionary *) metadata
{
NSString *p, *name, *mimeType;
NSString *p, *pmime, *name, *mimeType;
NSRange r;
if (![_attach isNotNull]) {
@ -1126,14 +1127,13 @@ static NSString *userAgent = nil;
mimeType = [metadata objectForKey: @"mimetype"];
if ([mimeType length] > 0)
{
p = [self pathToAttachmentWithName:
[NSString stringWithFormat: @".%@.mime", name]];
if (![[mimeType dataUsingEncoding: NSUTF8StringEncoding]
writeToFile: p atomically: YES])
{
return [NSException exceptionWithHTTPStatus:500 /* Server Error */
reason: @"Could not write attachment to draft!"];
}
pmime = [self pathToAttachmentWithName: [NSString stringWithFormat: @".%@.mime", name]];
if (![[mimeType dataUsingEncoding: NSUTF8StringEncoding] writeToFile: pmime atomically: YES])
{
[[NSFileManager defaultManager] removeItemAtPath: p error: nil];
return [NSException exceptionWithHTTPStatus: 500 /* Server Error */
reason: @"Could not write attachment to draft!"];
}
}
return nil; /* everything OK */

View file

@ -492,36 +492,7 @@ static int cssEscapingCount;
- (NSString *) asQPSubjectString: (NSString *) encoding
{
NSString *qpString, *subjectString;
NSData *subjectData, *destSubjectData;
NSUInteger length, destLength;
unsigned char *destString;
#warning "encoding" parameter is not useful
subjectData = [self dataUsingEncoding: NSUTF8StringEncoding];
length = [subjectData length];
destLength = length * 3;
destString = calloc (destLength, sizeof (char));
NGEncodeQuotedPrintableMime ([subjectData bytes], length,
destString, destLength);
destSubjectData = [NSData dataWithBytesNoCopy: destString
length: strlen ((char *) destString)
freeWhenDone: YES];
qpString = [[NSString alloc] initWithData: destSubjectData
encoding: NSASCIIStringEncoding];
[qpString autorelease];
if ([qpString length] > [self length])
{
qpString = [qpString stringByReplacingString: @" " withString: @"_"];
subjectString = [NSString stringWithFormat: @"=?%@?q?%@?=",
encoding, qpString];
}
else
subjectString = self;
return subjectString;
return [NGMimeHeaderFieldGenerator encodeQuotedPrintableText: self];
}
- (BOOL) caseInsensitiveMatches: (NSString *) match

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,21 @@
{\rtf1\ansi\deff3\adeflang1025
{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset0 Times New Roman;}{\f4\fs
wiss\fprq2\fcharset0 Arial;}{\f5\fnil\fprq2\fcharset1 Ubuntu;}{\f6\fnil\fprq2\fcharset0 DejaVu Sans;}{\f7\fnil\fprq2\fcharset0 Lohit Hindi;}{\f8\fnil\fprq0\fcharset1 Lohit Hindi
;}}
{\colortbl;\red0\green0\blue0;\red128\green128\blue128;}
{\stylesheet{\s0\snext0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033 Normal;}
{\s15\sbasedon0\snext16\sb240\sa120\keepn\dbch\af6\dbch\af7\afs28\loch\f4\fs28 Heading;}
{\s16\sbasedon0\snext16\sb0\sa120 Text Body;}
{\s17\sbasedon16\snext17\sb0\sa120\dbch\af8 List;}
{\s18\sbasedon0\snext18\sb120\sa120\noline\i\dbch\af8\afs24\ai\fs24 Caption;}
{\s19\sbasedon0\snext19\noline\dbch\af8 Index;}
}{\info{\creatim\yr2014\mo8\dy4\hr16\min16}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment LibreOffice}{\vern67175170}}\deftab709
\viewscale100
{\*\pgdsctbl
{\pgdsc0\pgdscuse451\pgwsxn11906\pghsxn16838\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\pgdscnxt0 Default Style;}}
\formshade\paperh16838\paperw11906\margl1134\margr1134\margt1134\margb1134\sectd\sbknone\sectunlocked1\pgndec\pgwsxn11906\pghsxn16838\marglsxn1134\margrsxn1134\margtsxn1134\marg
bsxn1134\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc
\pgndec\pard\plain \s0\nowidctlpar{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\kerning1\dbch\af6\langfe2052\dbch\af7\afs24\alang1081\loch\f3\fs24\lang1033{\rtlch \ltrch\loch\l
och\f5000
foobar}
\par }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

View file

@ -21,19 +21,24 @@ $(TEST_TOOL)_OBJC_FILES += \
\
TestSBJsonParser.m \
\
TestNGMimeAddressHeaderFieldGenerator.m \
TestNGMimeHeaderFieldGenerator.m \
TestNGMimeMessageGenerator.m \
\
TestNSData+Crypto.m \
TestNSString+Crypto.m \
TestNSString+URLEscaping.m \
TestNSString+Utilities.m \
TestNGMailAddressParser.m
TestNGMailAddressParser.m \
\
TestRTFHandler.m \
../../OpenChange/RTFHandler.m
# I don't know how to link against -l:SOGoBackend \
undefined reference to `__objc_class_name_SOGoMailFolder'
TEST_TOOL_NAME = $(TEST_TOOL)
$(TEST_TOOL)_CPPFLAGS += \
-Wall -D_GNU_SOURCE -I../../SOPE/ -I../../SoObjects/ -I../../UI/
-Wall -D_GNU_SOURCE -I../../SOPE/ -I../../SoObjects/ -I../../UI/ -I../../OpenChange
ADDITIONAL_LIB_DIRS += \
-L../../SoObjects/SOGo/SOGo.framework/Versions/Current/sogo -L../../SOPE/NGCards/obj -L../../SOPE/GDLContentStore/obj -lSOGo -lNGMime -lNGCards -lGDLContentStore -lNGExtensions -lSBJson -lobjc \
@ -47,3 +52,4 @@ include $(GNUSTEP_MAKEFILES)/test-tool.make
check :: $(TEST_TOOL)
./obj/sogo-tests

View file

@ -154,7 +154,8 @@ static NSString *SOGoTestAssertException = @"SOGoTestAssertException";
}
NS_ENDHANDLER;
[testRunner incrementTestCounter: failureCode];
[testRunner incrementTestCounter: failureCode
afterMethod: NSStringFromSelector (testMethod)];
}
- (BOOL) run

View file

@ -35,20 +35,31 @@ typedef enum {
SOGoTestFailureError = 2,
} SOGoTestFailureCode;
typedef enum {
SOGoTestTextOutputFormat = 0,
SOGoTestJUnitOutputFormat
} SOGoTestOutputFormat;
@interface SOGoTestRunner : NSObject
{
NSMutableArray *messages;
/* An array of arrays whose components are the method name and the
failure message if any */
NSMutableArray *performedTests;
int testCount;
int failuresCount;
int errorsCount;
BOOL hasFailed;
SOGoTestOutputFormat reportFormat;
}
+ (SOGoTestRunner *) testRunner;
+ (SOGoTestRunner *) testRunnerWithFormat: (SOGoTestOutputFormat) reportFormat;
- (void) setReportFormat: (SOGoTestOutputFormat) format;
- (int) run;
- (void) incrementTestCounter: (SOGoTestFailureCode) failureCode;
- (void) incrementTestCounter: (SOGoTestFailureCode) failureCode
afterMethod: (NSString *) methodName;
- (void) reportException: (NSException *) exception
method: (NSString *) methodName
withCode: (SOGoTestFailureCode) failureCode;

View file

@ -22,6 +22,7 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSDate.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSException.h>
@ -31,15 +32,16 @@
#import "SOGoTestRunner.h"
#define EXPECTED_FAILURES 3
#define EXPECTED_FAILURES 0
@implementation SOGoTestRunner
+ (SOGoTestRunner *) testRunner
+ (SOGoTestRunner *) testRunnerWithFormat: (SOGoTestOutputFormat) reportFormat
{
SOGoTestRunner *testRunner;
testRunner = [self new];
[testRunner setReportFormat: reportFormat];
[testRunner autorelease];
return testRunner;
@ -53,7 +55,8 @@
failuresCount = 0;
errorsCount = 0;
hasFailed = NO;
messages = [NSMutableArray new];
performedTests = [NSMutableArray new];
reportFormat = SOGoTestTextOutputFormat;
}
return self;
@ -61,10 +64,15 @@
- (void) dealloc
{
[messages release];
[performedTests release];
[super dealloc];
}
- (void) setReportFormat: (SOGoTestOutputFormat) format
{
reportFormat = format;
}
- (int) run
{
NSEnumerator *allTestClasses;
@ -95,11 +103,16 @@
}
- (void) incrementTestCounter: (SOGoTestFailureCode) failureCode
afterMethod: (NSString *) methodName
{
static char failureChars[] = { '.', 'F', 'E' };
testCount++;
fprintf (stderr, "%c", failureChars[failureCode]);
if (reportFormat == SOGoTestTextOutputFormat)
fprintf (stderr, "%c", failureChars[failureCode]);
if (failureCode == SOGoTestFailureSuccess)
[performedTests addObject: [NSArray arrayWithObjects: methodName, @"", nil]];
/* else has been added by reportException method */
}
- (void) reportException: (NSException *) exception
@ -134,13 +147,27 @@
errorsCount++;
}
[message appendString: @"\n"];
[messages addObject: message];
[performedTests addObject:
[NSArray arrayWithObjects: methodName, message, [NSNumber numberWithInt: failureCode], nil]];
}
- (void) displayReport
- (void) displayTextReport
{
static NSString *separator = @"\n======================================================================\n";
NSArray *performedTest;
NSMutableArray *messages;
NSString *reportMessage;
NSUInteger i, max;
messages = [NSMutableArray new];
max = [performedTests count];
for (i = 0; i < max; i++)
{
performedTest = [performedTests objectAtIndex: i];
if ([[performedTest objectAtIndex: 1] length] > 0)
[messages addObject: [performedTest objectAtIndex: 1]];
}
if ([messages count])
{
@ -148,6 +175,9 @@
reportMessage = [messages componentsJoinedByString: separator];
fprintf (stderr, "%s", [reportMessage UTF8String]);
}
[messages release];
fprintf (stderr,
"\n----------------------------------------------------------------------\n"
"Ran %d tests\n\n", testCount);
@ -158,4 +188,58 @@
fprintf (stderr, "OK\n");
}
- (void) displayJUnitReport
{
/* Follow JUnit.xsd defined by Apache-Ant project */
NSArray *performedTest;
NSMutableString *reportMessage;
NSUInteger i, max;
/* Header */
reportMessage = [NSMutableString stringWithFormat: @"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
@"<testsuite "
@"name=\"%@\" id=\"0\" tests=\"%d\" errors=\"%d\" failures=\"%d\" "
@"timestamp=\"%@\">\n"
@"<desc>%@</desc>\n",
@"SOGoUnitTests", testCount, errorsCount, failuresCount,
[NSDate date],
@"SOGo and SOPE Unit tests"];
/* Test cases */
max = [performedTests count];
for (i = 0; i < max; i++)
{
performedTest = [performedTests objectAtIndex: i];
[reportMessage appendFormat: @"<testcase name=\"%@\">\n", [performedTest objectAtIndex: 0]];
if ([[performedTest objectAtIndex: 1] length] > 0)
{
if ([performedTest count] > 2 && [[performedTest objectAtIndex: 2] intValue] == SOGoTestFailureFailure)
[reportMessage appendFormat: @"<failure>%@</failure>\n", [performedTest objectAtIndex: 1]];
else
[reportMessage appendFormat: @"<error>%@</error>\n", [performedTest objectAtIndex: 1]];
}
[reportMessage appendString: @"</testcase>\n"];
}
/* End */
[reportMessage appendString: @"</testsuite>"];
fprintf (stdout, "%s", [reportMessage UTF8String]);
}
- (void) displayReport
{
switch (reportFormat)
{
case SOGoTestTextOutputFormat:
[self displayTextReport];
break;
;;
case SOGoTestJUnitOutputFormat:
[self displayJUnitReport];
break;
;;
}
}
@end

View file

@ -36,7 +36,7 @@
@"johndown@test.com", // email alone
@"<johndown@test.com>", // email between brackets
@"\"<johndown@test.com>\" <johndown@test.com>", // doubled
// @"\"johndown@inverse.ca\" <johndown@test.com>", // with and without br.
@"\"johndown@inverse.ca\" <johndown@test.com>", // with and without br.
@"=?utf-8?q?=C3=80=C3=B1in=C3=A9oblabla?= <johndown@test.com>", // accented full name
@"=?utf-8?q?=C3=80=C3=B1in=C3=A9oblabla_Bla_Bl=C3=A9?= <johndown@test.com>", // accented and multiword
@"John Down \"Bla Bla\" <johndown@test.com>", // partly quoted
@ -45,14 +45,13 @@
@"john", // name only, no domain
nil ];
NSArray *expectedAddresses = [NSArray arrayWithObjects:
@"johndown@test.com", // email alone
@"johndown@test.com", // email between brackets
@"johndown@test.com", // email alone
@"johndown@test.com", // email between brackets
@"johndown@test.com", // doubled
// @"\"johndown@inverse.ca\" <johndown@test.com>", // with and without br.
@"johndown@test.com", // with and without br.
@"johndown@test.com", // accented full name
@"johndown@test.com", // accented
// and multiword
/* NOTE: the following are wrong but tolerated for now */
@"johndown@test.com", // partly quoted
@"johndown@test.com", // full name + email
@ -72,8 +71,8 @@
parsedRecipient = [parser parse];
result = [parsedRecipient address];
error = [NSString
stringWithFormat: @"received '%@' instead of '%@' for '%@'",
result, currentExp, rawAddress];
stringWithFormat: @"[%d] received '%@' instead of '%@' for '%@'",
count, result, currentExp, rawAddress];
testWithMessage([result isEqualToString: currentExp], error);
}
}

View file

@ -0,0 +1,106 @@
/* TestNGMimeHeaderFieldGenerator.m - this file is part of SOGo
*
* Copyright (C) 2015 Jesús García Sáez <jgarcia@zentyal.com>
*
* 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 "SOGoTest.h"
#import <NGMime/NGMimeHeaderFieldGenerator.h>
@interface TestNGMimeHeaderFieldGenerator : SOGoTest
@end
@implementation TestNGMimeHeaderFieldGenerator
/*
This test is actually for SOPE library, not SOGo
*/
- (void) test_encodeQPsubject
{
NSArray *cases = [NSArray arrayWithObjects:
[NSArray arrayWithObjects: @"hello", @"hello", nil],
[NSArray arrayWithObjects: @"holá", @"=?utf-8?q?hol=C3=A1?=", nil],
[NSArray arrayWithObjects:
@"АБВГДЕЁЖЗИАБВГДЕЁЖЗИАБВГДЕЁЖЗИАБВГДЕЁЖЗИ"
@"АБВГДЕЁЖЗИАБВГДЕЁЖЗИАБВГДЕЁЖЗИАБВГДЕЁЖЗИ",
@"=?utf-8?q?=D0=90=D0=91=D0=92=D0=93=D0=94=D0=95=D0=81=D0=96=D0=97=D0=98?=\n"
@" =?utf-8?q?=D0=90=D0=91=D0=92=D0=93=D0=94=D0=95=D0=81=D0=96=D0=97=D0=98=D0=90?=\n"
@" =?utf-8?q?=D0=91=D0=92=D0=93=D0=94=D0=95=D0=81=D0=96=D0=97=D0=98=D0=90=D0=91?=\n"
@" =?utf-8?q?=D0=92=D0=93=D0=94=D0=95=D0=81=D0=96=D0=97=D0=98=D0=90=D0=91=D0=92?=\n"
@" =?utf-8?q?=D0=93=D0=94=D0=95=D0=81=D0=96=D0=97=D0=98=D0=90=D0=91=D0=92=D0=93?=\n"
@" =?utf-8?q?=D0=94=D0=95=D0=81=D0=96=D0=97=D0=98=D0=90=D0=91=D0=92=D0=93=D0=94?=\n"
@" =?utf-8?q?=D0=95=D0=81=D0=96=D0=97=D0=98=D0=90=D0=91=D0=92=D0=93=D0=94=D0=95?=\n"
@" =?utf-8?q?=D0=81=D0=96=D0=97=D0=98?=", nil],
[NSArray arrayWithObjects:
@"hello АБВ hi АБВ hi АБВ hi АБВ hi АБВ",
@"hello =?utf-8?q?=D0=90=D0=91=D0=92?= hi =?utf-8?q?=D0=90=D0=91=D0=92?= hi \n"
@" =?utf-8?q?=D0=90=D0=91=D0=92?= hi =?utf-8?q?=D0=90=D0=91=D0=92?= hi \n"
@" =?utf-8?q?=D0=90=D0=91=D0=92?=", nil],
[NSArray arrayWithObjects:
@"hello АБВ АБВ ",
@"hello =?utf-8?q?=D0=90=D0=91=D0=92?=\n"
@" =?utf-8?q?________________=D0=90=D0=91=D0=92?= ", nil],
[NSArray arrayWithObjects: @" hello", @" hello", nil],
[NSArray arrayWithObjects: @"hello ", @"hello ", nil],
[NSArray arrayWithObjects:
@"hello АБВ ",
@"hello =?utf-8?q?=D0=90=D0=91=D0=92?= ", nil],
[NSArray arrayWithObjects:
@"ьььььььььььььььььььььььььььььььььььььььььььььььььь"
@"ьььььььььььььььььььььььььььььььььььььььььььььььььь"
@"ьььььььььььььььььььььььььььььььььььььььььььььььььь"
@"ьььььььььььььььььььььььььььььььььььььььььььььььььь",
@"=?utf-8?q?=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C?=\n"
@" =?utf-8?q?=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C?=\n"
@" =?utf-8?q?=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C?=\n"
@" =?utf-8?q?=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C?=\n"
@" =?utf-8?q?=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C?=\n"
@" =?utf-8?q?=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C?=\n"
@" =?utf-8?q?=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C?=\n"
@" =?utf-8?q?=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C?=\n"
@" =?utf-8?q?=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C?=\n"
@" =?utf-8?q?=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C?=\n"
@" =?utf-8?q?=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C?=\n"
@" =?utf-8?q?=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C?=\n"
@" =?utf-8?q?=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C?=\n"
@" =?utf-8?q?=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C?=\n"
@" =?utf-8?q?=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C?=\n"
@" =?utf-8?q?=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C?=\n"
@" =?utf-8?q?=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C?=\n"
@" =?utf-8?q?=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C=D1=8C?=\n"
@" =?utf-8?q?=D1=8C=D1=8C=D1=8C?=", nil],
nil
];
NSArray *caseData;
for (caseData in cases)
{
NSString *input = [caseData objectAtIndex: 0];
NSString *expected = [caseData objectAtIndex: 1];
NSString *output = [NGMimeHeaderFieldGenerator encodeQuotedPrintableText: input];
BOOL testResult = [output isEqualToString: expected];
NSString *diff = [self stringFromDiffBetween: output and: expected];
NSString *testErrorMsg = [NSString stringWithFormat:
@">> For input `%@`\n>> We got `%@`\n>> Expected `%@`\n%@",
input, output, expected, diff];
testWithMessage (testResult, testErrorMsg);
}
}
@end

View file

@ -19,113 +19,97 @@
#import "SOGoTest.h"
#import <NGMail/NGMimeMessageGenerator.h>
@interface TestNGMimeMessageGenerator : SOGoTest
@end
@implementation TestNGMimeMessageGenerator
/*
This test is actually for SOPE library, not SOGo
*/
- (void) test_generateDataForHeaderField_value
{
NGMimeMessageGenerator *generator;
NSArray *cases = [NSArray arrayWithObjects:
[NSArray arrayWithObjects: @"Message-ID", @"<CADCKkzo+9X1SniJFY3yc7YGafNrmAts419RmcqNkMzd-PBqNbA@mail.gmail.com>", @"<CADCKkzo+9X1SniJFY3yc7YGafNrmAts419RmcqNkMzd-PBqNbA@mail.gmail.com>", nil],
[NSArray arrayWithObjects: @"Content-Type",
@"text/plain; charset=utf-8; format=flowed",
@"text/plain; charset=utf-8; format=flowed",
nil],
[NSArray arrayWithObjects: @"X-FullHeaderOneHebrewOneLatin",
@"עs",
@"=?utf-8?q?=D7=A2s?=",
nil],
[NSArray arrayWithObjects: @"X-FullHeaderOneLatineOneHebrew",
@"sע",
@"=?utf-8?q?s=D7=A2?=",
nil],
[NSArray arrayWithObjects: @"X-FullHeaderOneCharacterHebrew",
@"ע",
@"=?utf-8?q?=D7=A2?=",
nil],
[NSArray arrayWithObjects: @"X-FullHeaderOneCharacterRussian",
@"Б",
@"=?utf-8?q?=D0=91?=",
nil],
[NSArray arrayWithObjects: @"X-FullHeaderParameter",
@"parameter=ע",
@"parameter==?utf-8?q?=D7=A2?=",
nil],
[NSArray arrayWithObjects: @"X-MixedHeaderParameters",
@"plain; parameter=ע; parameter-plain; parameter2=ea",
@"plain;\n parameter==?utf-8?q?=D7=A2?=;\n parameter-plain; parameter2=ea",
nil],
[NSArray arrayWithObjects: @"X-MixedHeaderAndNoParameter",
@"plain; parameter=ע; parameter-plain; ע",
@"plain;\n parameter==?utf-8?q?=D7=A2?=; parameter-plain;\n =?utf-8?q?=D7=A2?=",
nil],
[NSArray arrayWithObjects: @"X-MixedHeaderAndTwoParameter",
@"plain; parameter=ע; parameter-plain; z=ע",
@"plain;\n parameter==?utf-8?q?=D7=A2?=; parameter-plain;\n z==?utf-8?q?=D7=A2?=",
nil],
[NSArray arrayWithObjects: @"X-MixedHeaderExtrablanks",
@"plain; parameter=ע; parameter 2spaces; parameter2=ea",
@"plain;\n \\ parameter==?utf-8?q?=D7=A2?=;\n parameter 2spaces; parameter2=ea",
nil],
[NSArray arrayWithObjects: @"X-Encoded-Unbalanced-Paramter-Quote",
@"text/plain; name=\"ע",
@"text/plain;\n name==?utf-8?q?=22=D7=A2?=",
nil],
[NSArray arrayWithObjects: @"content-type",
@"text/plain; name=\"АБВГДЕЁЖЗИЙ, КЛМНОПРСТУФ y ЦЧШЩЪЫЬЭЮЯ.txt\"",
@"text/plain;\n name=\"=?utf-8?q?=D0=90=D0=91=D0=92=D0=93=D0=94=D0=95=D0=81=D0=96=D0=97=D0=98=D0=99=2C_=D0=9A=D0=9B=D0=9C=D0=9D=D0=9E=D0=9F=D0=A0=D0=A1=D0=A2=D0=A3=D0=A4_y_=D0=A6=D0=A7=D0=A8=D0=A9=D0=AA=D0=AB=D0=AC=D0=AD=D0=AE=D0=AF=2Etxt?=\"",
nil],
[NSArray arrayWithObjects: @"content-disposition",
@"attachment; filename=\"АБВГДЕЁЖЗИЙ, КЛМНОПРСТУФ y ЦЧШЩЪЫЬЭЮЯ.txt\"",
@"attachment;\n filename=\"=?utf-8?q?=D0=90=D0=91=D0=92=D0=93=D0=94=D0=95=D0=81=D0=96=D0=97=D0=98=D0=99=2C_=D0=9A=D0=9B=D0=9C=D0=9D=D0=9E=D0=9F=D0=A0=D0=A1=D0=A2=D0=A3=D0=A4_y_=D0=A6=D0=A7=D0=A8=D0=A9=D0=AA=D0=AB=D0=AC=D0=AD=D0=AE=D0=AF=2Etxt?=\"",
nil],
[NSArray arrayWithObjects: @"content-length", @"2912", @"2912", nil],
[NSArray arrayWithObjects: @"content-transfer-encoding", @"quoted-printable", @"quoted-printable", nil],
nil
];
NSEnumerator *enumerator;
NSArray *testCase;
[NSArray arrayWithObjects:@"Message-ID",
@"<CADCKkzo+9X1SniJFY3yc7YGafNrmAts419RmcqNkMzd-PBqNbA@mail.gmail.com>",
@"<CADCKkzo+9X1SniJFY3yc7YGafNrmAts419RmcqNkMzd-PBqNbA@mail.gmail.com>", nil],
[NSArray arrayWithObjects:@"Content-Type",
@"text/plain; charset=utf-8; format=flowed",
@"text/plain; charset=utf-8; format=flowed", nil],
[NSArray arrayWithObjects:@"X-FullHeaderOneHebrewOneLatin",
@"עs",
@"=?utf-8?q?=D7=A2s?=", nil],
[NSArray arrayWithObjects:@"X-FullHeaderOneLatineOneHebrew",
@"sע",
@"=?utf-8?q?s=D7=A2?=", nil],
[NSArray arrayWithObjects:@"X-FullHeaderOneCharacterHebrew",
@"ע",
@"=?utf-8?q?=D7=A2?=", nil],
[NSArray arrayWithObjects:@"X-FullHeaderOneCharacterRussian",
@"Б",
@"=?utf-8?q?=D0=91?=", nil],
[NSArray arrayWithObjects:@"X-FullHeaderParameter",
@"parameter=ע",
@"parameter==?utf-8?q?=D7=A2?=", nil],
[NSArray arrayWithObjects:@"X-MixedHeaderParameters",
@"plain; parameter=ע; parameter-plain; parameter2=ea",
@"plain;\n parameter==?utf-8?q?=D7=A2?=;\n parameter-plain; parameter2=ea", nil],
[NSArray arrayWithObjects:@"X-MixedHeaderAndNoParameter",
@"plain; parameter=ע; parameter-plain; ע",
@"plain;\n parameter==?utf-8?q?=D7=A2?=; parameter-plain;\n =?utf-8?q?=D7=A2?=", nil],
[NSArray arrayWithObjects:@"X-MixedHeaderAndTwoParameter",
@"plain; parameter=ע; parameter-plain; z=ע",
@"plain;\n parameter==?utf-8?q?=D7=A2?=; parameter-plain;\n z==?utf-8?q?=D7=A2?=", nil],
[NSArray arrayWithObjects:@"X-MixedHeaderExtrablanks",
@"plain; parameter=ע; parameter 2spaces; parameter2=ea",
@"plain;\n \\ parameter==?utf-8?q?=D7=A2?=;\n parameter 2spaces; parameter2=ea", nil],
[NSArray arrayWithObjects:@"X-Encoded-Unbalanced-Paramter-Quote",
@"text/plain; name=\"ע",
@"text/plain;\n name==?utf-8?q?=22=D7=A2?=", nil],
[NSArray arrayWithObjects:@"content-type",
@"text/plain; name=\"АБВГДЕЁЖЗИЙ, КЛМНОПРСТУФ y ЦЧШЩЪЫЬЭЮЯ.txt\"",
@"text/plain;\n name=\"=?utf-8?q?=D0=90=D0=91=D0=92=D0=93=D0=94=D0=95=D0=81=D0=96=D0=97=D0=98=D0=99=2C_=D0=9A=D0"
@"=9B=D0=9C=D0=9D=D0=9E=D0=9F=D0=A0=D0=A1=D0=A2=D0=A3=D0=A4_y_=D0=A6=D0=A7=D0=A8"
@"=D0=A9=D0=AA=D0=AB=D0=AC=D0=AD=D0=AE=D0=AF=2Etxt?=\"", nil],
[NSArray arrayWithObjects:@"content-disposition",
@"attachment; filename=\"АБВГДЕЁЖЗИЙ, КЛМНОПРСТУФ y ЦЧШЩЪЫЬЭЮЯ.txt\"",
@"attachment;\n filename=\"=?utf-8?q?=D0=90=D0=91=D0=92=D0=93=D0=94=D0=95=D0=81=D0=96=D0=97=D0=98=D0=99=2C_=D0=9A=D0"
@"=9B=D0=9C=D0=9D=D0=9E=D0=9F=D0=A0=D0=A1=D0=A2=D0=A3=D0=A4_y_=D0=A6=D0=A7=D0=A8"
@"=D0=A9=D0=AA=D0=AB=D0=AC=D0=AD=D0=AE=D0=AF=2Etxt?=\"", nil],
[NSArray arrayWithObjects:@"content-length", @"2912", @"2912", nil],
[NSArray arrayWithObjects:@"content-transfer-encoding", @"quoted-printable", @"quoted-printable", nil],
nil
];
[NGMimeMessageGenerator initialize];
generator = [[NGMimeMessageGenerator alloc] init];
NGMimeMessageGenerator *generator = [[NGMimeMessageGenerator alloc] init];
[generator autorelease];
enumerator = [cases objectEnumerator];
while ((testCase = [enumerator nextObject]) != nil)
for (NSArray *testCase in cases)
{
NSData *result;
NSMutableData *resultWithNulByte;
NSString *header = [testCase objectAtIndex: 0];
NSData *headerData = [testCase objectAtIndex: 1];
NSString *expected = [testCase objectAtIndex: 2];
result = [generator generateDataForHeaderField: header
value: headerData];
if (result == nil)
result = [@"[nil]" dataUsingEncoding: NSUTF8StringEncoding];
NSData *result = [generator generateDataForHeaderField: header
value: headerData];
if (result == nil)
result = [@"[nil]" dataUsingEncoding: NSUTF8StringEncoding];
resultWithNulByte = [result mutableCopy];
[resultWithNulByte appendBytes: "\0" length: 1];
NSMutableData *resultWithNulByte = [result mutableCopy];
[resultWithNulByte appendBytes: "\0" length: 1];
NSString *resultString = [NSString stringWithCString:[resultWithNulByte bytes]];
BOOL testResult = [resultString isEqualToString: expected];
NSString *diff = [self stringFromDiffBetween: [NSString stringWithString: resultString]
and: [NSString stringWithString: expected]];
NSString *testErrorMsg = [NSString
stringWithFormat: @">> For %@ header received:\n%@[END]\n>> instead of:\n%@[END]\n>> for:\n%@\n>> diff:\n%@\n>> lengthReceived: %lu lengthExpected: %lu",
header,
resultString,
expected,
headerData,
diff,
[resultString length],
[expected length]
];
NSString *diff = [self stringFromDiffBetween: resultString and: expected];
NSString *testErrorMsg = [NSString stringWithFormat:
@">> For %@ header received:\n%@[END]\n"
@">> instead of:\n%@[END]\n"
@">> for:\n%@\n>> diff:\n%@\n"
@">> lengthReceived: %lu lengthExpected: %lu", header, resultString,
expected, headerData, diff, [resultString length], [expected length]];
testWithMessage(testResult, testErrorMsg);
}

View file

@ -1,8 +1,10 @@
/* TestNSString+Utilities.m - this file is part of SOGo
*
* Copyright (C) 2011 Inverse inc
* Copyright (C) 2014 Zentyal
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Jesús García Sáez <jgarcia@zentyal.com>
*
* 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
@ -23,7 +25,7 @@
/* This file is encoded in utf-8. */
#import <SOGo/NSString+Utilities.h>
#import <Foundation/NSNull.h>
#import "SOGoTest.h"
@interface TestNSString_plus_Utilities : SOGoTest
@ -52,7 +54,7 @@
NSString *secret = @"this is a secret";
NSString *password = @"qwerty";
NSString *encresult, *decresult;
encresult = [secret encryptWithKey: nil];
failIf(encresult != nil);
encresult = [secret encryptWithKey: @""];
@ -70,4 +72,28 @@
failIf(![decresult isEqualToString: secret]);
}
- (void) test_objectFromJSONString_single_values
{
NSString *json, *error;
NSInteger expected = 1;
id result;
// Decode null
json = [NSString stringWithFormat:@"null"];
result = [json objectFromJSONString];
testWithMessage(result == [NSNull null], @"Result should be null");
// Decode number
json = [NSString stringWithFormat:@"1"];
result = [json objectFromJSONString];
error = [NSString stringWithFormat: @"result %@ != expected %d",
result, expected];
testWithMessage((long)result != (long)expected, error);
// Decode string
json = [NSString stringWithFormat:@"\"kill me\""];
result = [json objectFromJSONString];
testEquals(result, @"kill me");
}
@end

308
Tests/Unit/TestRTFHandler.m Normal file
View file

@ -0,0 +1,308 @@
/* TestRTFHandler.m
*
* Copyright (C) 2014 Zentyal
*
* Author: Jesús García Sáez <jgarcia@zentyal.org>
*
* 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.
*/
/* This file is encoded in utf-8. */
#import "RTFHandler.h"
#import "SOGoTest.h"
#import <Foundation/NSFileManager.h>
#import <Foundation/NSException.h>
#include <string.h>
@interface TestRTFHandler : SOGoTest
@end
@implementation TestRTFHandler
- (NSString *) rtf2html: (NSData *) rtf
{
NSString *html;
if (!rtf)
return nil;
RTFHandler *handler = [[RTFHandler alloc] initWithData: rtf];
NSMutableData *data2 = [handler parse];
if (data2 == nil)
{
NSString *error = [NSString stringWithFormat: @"Couldn't parse RTF data:\n %s",
(char *)[rtf bytes]];
testWithMessage(NO, error);
}
html = [[NSString alloc] initWithData: data2 encoding: NSUTF8StringEncoding];
if (html == nil)
{
html = [[NSString alloc] initWithData: data2 encoding: NSASCIIStringEncoding];
}
if (html == nil)
{
html = [[NSString alloc] initWithData: data2 encoding: NSISOLatin1StringEncoding];
}
if (html == nil)
{
NSString *error = [NSString stringWithFormat: @"Couldn't convert parsed data"];
testWithMessage(NO, error);
}
return html;
}
- (NSData *) dataWithContentsOfFixture: (NSString*) name
{
NSString *file_path = [NSString stringWithFormat: @"Fixtures/%@", name];
if(![[NSFileManager defaultManager] fileExistsAtPath: file_path]) {
NSString *error = [NSString stringWithFormat: @"File %@ doesn't exist", file_path];
testWithMessage(false, error);
}
return [NSData dataWithContentsOfFile: file_path];
}
- (NSData *) dataWithContentsOfZentyalCrash: (unsigned int) number
{
NSString *fixture = [NSString stringWithFormat: @"zentyal_crash_%u.rtf", number];
return [self dataWithContentsOfFixture: fixture];
}
- (void) checkDoesNotCrash: (unsigned int) number
{
// FIXME fork
[self rtf2html: [self dataWithContentsOfZentyalCrash: number]];
}
- (void) checkHTMLConversionOfRTFFile: (NSString*) file
againstExpectedHTML: (NSString*) expected
{
NSData *in = nil;
NSString *out = nil, *error = nil;
in = [self dataWithContentsOfFixture: file];
out = [self rtf2html: in];
error = [NSString stringWithFormat:
@"Html from rtf result is not what we expected.\n>> Actual:\n%@\n>> Expected:\n%@\n", out, expected];
testWithMessage([out isEqualToString: expected], error);
}
- (void) checkFonTableParsingOfRTFFile: (NSString*) file
againstExpectedTable: (NSString*) expected
{
NSData *in = nil;
char *in_bytes;
char *table_pointer;
int newCurrentPos;
RTFHandler *handler;
RTFFontTable *out_table;
NSString *out_description, *error = nil;
in = [self dataWithContentsOfFixture: file];
in_bytes = (char *) [in bytes];
table_pointer = strstr(in_bytes, "{\\fonttbl");
if (table_pointer == NULL)
{
[NSException raise: @"NSInvalidArgumentException"
format: @"No font table in RTF file"];
}
newCurrentPos = table_pointer - in_bytes;
handler = [[RTFHandler alloc] initWithData: in];
[handler mangleInternalStateWithBytesPtr: table_pointer
andCurrentPos: newCurrentPos];
out_table = [handler parseFontTable];
out_description = [out_table description];
if ([out_description isEqualToString: expected])
{
testWithMessage(YES, @"no error");
}
else
{
error = [NSString stringWithFormat:
@"Font table is not what we expected.\n>> Actual:\n%@-----\n>> Expected:\n%@-----\n", out_description, expected];
testWithMessage(NO, error);
}
}
- (void) test_zentyal_crash_2058
{
[self checkDoesNotCrash: 2058];
// Output is not correct... but the original issue was segfault
}
- (void) test_zentyal_crash_2089
{
NSData *in = nil;
NSString *out = nil, *error = nil, *expected = nil;
in = [self dataWithContentsOfZentyalCrash: 2089];
expected =@"<html><meta charset='utf-8'><body><font face=\"Calibri\"><font color=\"#000000\">Lorem Ipsum</font><font color=\"#000000\"><br></font></body></html>";
out = [self rtf2html: in];
error = [NSString stringWithFormat:
@"Html from rtf result `%@` is not what we expected", out];
testWithMessage([out isEqualToString: expected], error);
}
- (void) test_zentyal_crash_6330
{
[self checkDoesNotCrash: 6330];
}
- (void) test_zentyal_crash_8346
{
[self checkDoesNotCrash: 8346];
}
- (void) test_zentyal_crash_6977
{
[self checkDoesNotCrash: 6977];
}
- (void) test_zentyal_crash_7067
{
[self checkDoesNotCrash: 7067];
}
- (void) test_mini_russian_font_table
{
NSString *file =@"mini_russian.rtf";
NSMutableString *expected = [NSMutableString stringWithFormat: @"Number of fonts: 84\n"];
[expected appendString: @"0 name=Times New Roman family=roman charset=0 pitch=2\n"];
[expected appendString: @"31500 name=Times New Roman family=roman charset=0 pitch=2\n"];
[expected appendString: @"31501 name=Times New Roman family=roman charset=0 pitch=2\n"];
[expected appendString: @"31502 name=Cambria family=roman charset=0 pitch=2\n"];
[expected appendString: @"37 name=Calibri family=swiss charset=0 pitch=2\n"];
[expected appendString: @"31503 name=Times New Roman family=roman charset=0 pitch=2\n"];
[expected appendString: @"39 name=Times New Roman CE family=roman charset=238 pitch=2\n"];
[expected appendString: @"31504 name=Times New Roman family=roman charset=0 pitch=2\n"];
[expected appendString: @"40 name=Times New Roman Cyr family=roman charset=204 pitch=2\n"];
[expected appendString: @"31505 name=Times New Roman family=roman charset=0 pitch=2\n"];
[expected appendString: @"31506 name=Calibri family=swiss charset=0 pitch=2\n"];
[expected appendString: @"42 name=Times New Roman Greek family=roman charset=161 pitch=2\n"];
[expected appendString: @"31507 name=Times New Roman family=roman charset=0 pitch=2\n"];
[expected appendString: @"31508 name=Times New Roman CE family=roman charset=238 pitch=2\n"];
[expected appendString: @"43 name=Times New Roman Tur family=roman charset=162 pitch=2\n"];
[expected appendString: @"31509 name=Times New Roman Cyr family=roman charset=204 pitch=2\n"];
[expected appendString: @"44 name=Times New Roman (Hebrew) family=roman charset=177 pitch=2\n"];
[expected appendString: @"45 name=Times New Roman (Arabic) family=roman charset=178 pitch=2\n"];
[expected appendString: @"31511 name=Times New Roman Greek family=roman charset=161 pitch=2\n"];
[expected appendString: @"46 name=Times New Roman Baltic family=roman charset=186 pitch=2\n"];
[expected appendString: @"31512 name=Times New Roman Tur family=roman charset=162 pitch=2\n"];
[expected appendString: @"47 name=Times New Roman (Vietnamese) family=roman charset=163 pitch=2\n"];
[expected appendString: @"31513 name=Times New Roman (Hebrew) family=roman charset=177 pitch=2\n"];
[expected appendString: @"31514 name=Times New Roman (Arabic) family=roman charset=178 pitch=2\n"];
[expected appendString: @"31515 name=Times New Roman Baltic family=roman charset=186 pitch=2\n"];
[expected appendString: @"31516 name=Times New Roman (Vietnamese) family=roman charset=163 pitch=2\n"];
[expected appendString: @"31518 name=Times New Roman CE family=roman charset=238 pitch=2\n"];
[expected appendString: @"31519 name=Times New Roman Cyr family=roman charset=204 pitch=2\n"];
[expected appendString: @"31521 name=Times New Roman Greek family=roman charset=161 pitch=2\n"];
[expected appendString: @"31522 name=Times New Roman Tur family=roman charset=162 pitch=2\n"];
[expected appendString: @"31523 name=Times New Roman (Hebrew) family=roman charset=177 pitch=2\n"];
[expected appendString: @"31524 name=Times New Roman (Arabic) family=roman charset=178 pitch=2\n"];
[expected appendString: @"31525 name=Times New Roman Baltic family=roman charset=186 pitch=2\n"];
[expected appendString: @"31526 name=Times New Roman (Vietnamese) family=roman charset=163 pitch=2\n"];
[expected appendString: @"31528 name=Cambria CE family=roman charset=238 pitch=2\n"];
[expected appendString: @"31529 name=Cambria Cyr family=roman charset=204 pitch=2\n"];
[expected appendString: @"31531 name=Cambria Greek family=roman charset=161 pitch=2\n"];
[expected appendString: @"31532 name=Cambria Tur family=roman charset=162 pitch=2\n"];
[expected appendString: @"31535 name=Cambria Baltic family=roman charset=186 pitch=2\n"];
[expected appendString: @"31536 name=Cambria (Vietnamese) family=roman charset=163 pitch=2\n"];
[expected appendString: @"31538 name=Times New Roman CE family=roman charset=238 pitch=2\n"];
[expected appendString: @"31539 name=Times New Roman Cyr family=roman charset=204 pitch=2\n"];
[expected appendString: @"31541 name=Times New Roman Greek family=roman charset=161 pitch=2\n"];
[expected appendString: @"31542 name=Times New Roman Tur family=roman charset=162 pitch=2\n"];
[expected appendString: @"31543 name=Times New Roman (Hebrew) family=roman charset=177 pitch=2\n"];
[expected appendString: @"31544 name=Times New Roman (Arabic) family=roman charset=178 pitch=2\n"];
[expected appendString: @"31545 name=Times New Roman Baltic family=roman charset=186 pitch=2\n"];
[expected appendString: @"31546 name=Times New Roman (Vietnamese) family=roman charset=163 pitch=2\n"];
[expected appendString: @"31548 name=Times New Roman CE family=roman charset=238 pitch=2\n"];
[expected appendString: @"31549 name=Times New Roman Cyr family=roman charset=204 pitch=2\n"];
[expected appendString: @"31551 name=Times New Roman Greek family=roman charset=161 pitch=2\n"];
[expected appendString: @"31552 name=Times New Roman Tur family=roman charset=162 pitch=2\n"];
[expected appendString: @"31553 name=Times New Roman (Hebrew) family=roman charset=177 pitch=2\n"];
[expected appendString: @"31554 name=Times New Roman (Arabic) family=roman charset=178 pitch=2\n"];
[expected appendString: @"31555 name=Times New Roman Baltic family=roman charset=186 pitch=2\n"];
[expected appendString: @"31556 name=Times New Roman (Vietnamese) family=roman charset=163 pitch=2\n"];
[expected appendString: @"31558 name=Times New Roman CE family=roman charset=238 pitch=2\n"];
[expected appendString: @"31559 name=Times New Roman Cyr family=roman charset=204 pitch=2\n"];
[expected appendString: @"31561 name=Times New Roman Greek family=roman charset=161 pitch=2\n"];
[expected appendString: @"31562 name=Times New Roman Tur family=roman charset=162 pitch=2\n"];
[expected appendString: @"31563 name=Times New Roman (Hebrew) family=roman charset=177 pitch=2\n"];
[expected appendString: @"31564 name=Times New Roman (Arabic) family=roman charset=178 pitch=2\n"];
[expected appendString: @"31565 name=Times New Roman Baltic family=roman charset=186 pitch=2\n"];
[expected appendString: @"31566 name=Times New Roman (Vietnamese) family=roman charset=163 pitch=2\n"];
[expected appendString: @"31568 name=Calibri CE family=swiss charset=238 pitch=2\n"];
[expected appendString: @"31569 name=Calibri Cyr family=swiss charset=204 pitch=2\n"];
[expected appendString: @"31571 name=Calibri Greek family=swiss charset=161 pitch=2\n"];
[expected appendString: @"31572 name=Calibri Tur family=swiss charset=162 pitch=2\n"];
[expected appendString: @"31575 name=Calibri Baltic family=swiss charset=186 pitch=2\n"];
[expected appendString: @"31576 name=Calibri (Vietnamese) family=swiss charset=163 pitch=2\n"];
[expected appendString: @"31578 name=Times New Roman CE family=roman charset=238 pitch=2\n"];
[expected appendString: @"31579 name=Times New Roman Cyr family=roman charset=204 pitch=2\n"];
[expected appendString: @"31581 name=Times New Roman Greek family=roman charset=161 pitch=2\n"];
[expected appendString: @"31582 name=Times New Roman Tur family=roman charset=162 pitch=2\n"];
[expected appendString: @"31583 name=Times New Roman (Hebrew) family=roman charset=177 pitch=2\n"];
[expected appendString: @"31584 name=Times New Roman (Arabic) family=roman charset=178 pitch=2\n"];
[expected appendString: @"409 name=Calibri CE family=swiss charset=238 pitch=2\n"];
[expected appendString: @"31585 name=Times New Roman Baltic family=roman charset=186 pitch=2\n"];
[expected appendString: @"410 name=Calibri Cyr family=swiss charset=204 pitch=2\n"];
[expected appendString: @"31586 name=Times New Roman (Vietnamese) family=roman charset=163 pitch=2\n"];
[expected appendString: @"412 name=Calibri Greek family=swiss charset=161 pitch=2\n"];
[expected appendString: @"413 name=Calibri Tur family=swiss charset=162 pitch=2\n"];
[expected appendString: @"416 name=Calibri Baltic family=swiss charset=186 pitch=2\n"];
[expected appendString: @"417 name=Calibri (Vietnamese) family=swiss charset=163 pitch=2\n"];
[self checkFonTableParsingOfRTFFile: file
againstExpectedTable: expected];
}
- (void) test_mini_russian
{
NSString *file =@"mini_russian.rtf";
NSString *expected=@"<html><meta charset='utf-8'><body><font face=\"Calibri\"><font face=\"Calibri Cyr\"><font color=\"#000000\">XXзык польски, польщизнаXX</font></font></font></body></html>";
[self checkHTMLConversionOfRTFFile: file
againstExpectedHTML: expected];
}
- (void) test_escapes
{
NSString *file =@"escapes.rtf";
NSString *expected=@"<html><meta charset='utf-8'><body><font face=\"Calibri\"><font color=\"#000000\">x341x351x372x355x363x361x</font><font color=\"#000000\">S SS-S\\S</font><font color=\"#000000\">U老UřU</font><font color=\"#000000\"><br></font></font></body></html>";
[self checkHTMLConversionOfRTFFile: file
againstExpectedHTML: expected];
}
- (void) test_spanish_accents
{
NSString *file =@"spanish_accents.rtf";
NSString *expected=@"<html><meta charset='utf-8'><body><font face=\"Calibri\"><font color=\"#000000\">xñxáxéxíxóxú</font><font color=\"#000000\"><br></font></font></body></html>";
[self checkHTMLConversionOfRTFFile: file
againstExpectedHTML: expected];
}
@end

View file

@ -21,6 +21,7 @@
*/
#import <Foundation/NSException.h>
#import <Foundation/NSLocale.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
@ -71,6 +72,8 @@
{
SBJsonParser *parser;
id result;
NSDecimalNumber *obtained, *expected;
NSDictionary *locale;
parser = [SBJsonParser new];
[parser autorelease];
@ -80,17 +83,20 @@
result = [parser objectWithString: @"[ 0 ]"];
testEquals (result, [NSArray arrayWithObject: [NSNumber numberWithInt: 0]]);
result = [parser objectWithString: @"[ -1 ]"];
testEquals (result, [NSArray arrayWithObject: [NSNumber numberWithInt: -1]]);
locale = [NSDictionary dictionaryWithObject: @"." forKey: NSLocaleDecimalSeparator];
result = [parser objectWithString: @"[ 12.3456 ]"];
testEquals ([result objectAtIndex: 0],
[NSDecimalNumber decimalNumberWithString: @"12.3456"]);
obtained = [result objectAtIndex: 0];
expected = [NSDecimalNumber decimalNumberWithString: @"12.3456" locale: locale];
test ([obtained compare: expected] == NSOrderedSame);
result = [parser objectWithString: @"[ -312.3456 ]"];
testEquals (result, [NSArray arrayWithObject: [NSNumber numberWithDouble: -312.3456]]);
obtained = [result objectAtIndex: 0];
expected = [NSDecimalNumber decimalNumberWithString: @"-312.3456" locale: locale];
test ([obtained compare: expected] == NSOrderedSame);
}
@end

View file

@ -44,6 +44,7 @@
/* TODO: this test fails for obscure reasons, but test__occurrenceForDate_byRRule_ does not, which
is a good sign */
/*
- (void) test_occurrenceForDate_
{
NSString *periods[] = { (@"BEGIN:DAYLIGHT\r\n"
@ -84,7 +85,7 @@
@" delta = %ld", count, delta]));
}
}
*/
- (void) test__occurrenceForDate_byRRule_
{
/* all rules are happening on 2010-03-14 */

View file

@ -21,15 +21,91 @@
*/
#import <Foundation/Foundation.h>
#import <Foundation/NSProcessInfo.h>
#import "SOGoTestRunner.h"
int main()
static void Usage ()
{
/* Print usage and exit */
NSLog (@"sogo-tests [-h|--help] [-f|--format=text|junit]\n"
@" -h, --help\t\t\tdisplay this help information\n"
@" -f, --format=text|junit\treport format. Default: text\n\n");
exit(0);
}
static SOGoTestOutputFormat ParseArguments (NSArray *args)
{
/* Parse arguments from command line */
BOOL help = NO;
NSString *arg, *format = nil;
NSUInteger i, max;
SOGoTestOutputFormat outFormat;
max = [args count];
/* Skip program name */
i = 1;
while (!help && i < max)
{
arg = [args objectAtIndex: i];
if ([arg isEqualToString: @"-f"] || [arg isEqualToString: @"--format"])
{
NSArray *validFormats = [NSArray arrayWithObjects: @"text", @"junit", nil];
i++;
if (i < max)
{
arg = [args objectAtIndex: i];
if ([validFormats containsObject: arg])
format = arg;
else
{
help = YES;
NSLog (@"Invalid format: '%@'. Use 'text' or 'junit'", arg);
}
}
else
{
NSLog (@"Missing format argument");
help = YES;
}
}
else if ([arg isEqualToString: @"-h"]
|| [arg isEqualToString: @"--help"])
help = YES;
else
{
NSLog (@"Invalid command line argument: '%@'", arg);
help = YES;
}
i++;
}
if (help)
{
Usage ();
}
if (format)
{
if ([format isEqualToString: @"text"])
outFormat = SOGoTestTextOutputFormat;
else if ([format isEqualToString: @"junit"])
outFormat = SOGoTestJUnitOutputFormat;
}
else
outFormat = SOGoTestTextOutputFormat;
return outFormat;
}
int main(int argc, char *argv[], char *env[])
{
NSAutoreleasePool *pool;
int rc;
NSDictionary *defaults;
NSUserDefaults *ud;
SOGoTestOutputFormat reportFormat;
pool = [NSAutoreleasePool new];
@ -42,7 +118,14 @@ int main()
forName: @"sogo-tests-volatile"];
[ud addSuiteNamed: @"sogo-tests-volatile"];
rc = [[SOGoTestRunner testRunner] run];
/* Process arguments */
[NSProcessInfo initializeWithArguments: argv
count: argc
environment: env];
reportFormat = ParseArguments ([[NSProcessInfo processInfo] arguments]);
rc = [[SOGoTestRunner testRunnerWithFormat: reportFormat] run];
[pool release];
return rc;