Skip to content

Commit

Permalink
(split)Added Jorge Pedroso's enhancements (and unit tests! yay!) for …
Browse files Browse the repository at this point in the history
…#57. Closing bug.
  • Loading branch information
schwa committed May 13, 2009
1 parent 9805ff6 commit 42750a6
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 1 deletion.
1 change: 1 addition & 0 deletions Common/Source/CXMLDocument.h
Expand Up @@ -41,6 +41,7 @@ enum {
}

- (id)initWithData:(NSData *)inData options:(NSUInteger)inOptions error:(NSError **)outError;
- (id)initWithData:(NSData *)inData encoding:(NSStringEncoding)encoding options:(NSUInteger)inOptions error:(NSError **)outError;
- (id)initWithXMLString:(NSString *)inString options:(NSUInteger)inOptions error:(NSError **)outError;
- (id)initWithContentsOfURL:(NSURL *)inURL options:(NSUInteger)inOptions error:(NSError **)outError;

Expand Down
10 changes: 9 additions & 1 deletion Common/Source/CXMLDocument.m
Expand Up @@ -82,6 +82,11 @@ - (id)initWithXMLString:(NSString *)inString options:(NSUInteger)inOptions error
}

- (id)initWithData:(NSData *)inData options:(NSUInteger)inOptions error:(NSError **)outError
{
return [self initWithData:inData encoding:NSUTF8StringEncoding options:inOptions error:outError];
}

- (id)initWithData:(NSData *)inData encoding:(NSStringEncoding)encoding options:(NSUInteger)inOptions error:(NSError **)outError
{
if ((self = [super init]) != NULL)
{
Expand All @@ -103,7 +108,10 @@ - (id)initWithData:(NSData *)inData options:(NSUInteger)inOptions error:(NSError
xmlDocPtr theDoc = NULL;
if (inData && inData.length > 0)
{
theDoc = xmlReadMemory([inData bytes], [inData length], NULL, NULL, XML_PARSE_RECOVER | XML_PARSE_NOWARNING);
CFStringEncoding cfenc = CFStringConvertNSStringEncodingToEncoding(encoding);
CFStringRef cfencstr = CFStringConvertEncodingToIANACharSetName(cfenc);
const char *enc = CFStringGetCStringPtr(cfencstr, 0);
theDoc = xmlReadMemory([inData bytes], [inData length], NULL, enc, XML_PARSE_RECOVER | XML_PARSE_NOWARNING);
}

if (theDoc != NULL)
Expand Down
6 changes: 6 additions & 0 deletions TouchXML.xcodeproj/project.pbxproj
Expand Up @@ -22,6 +22,7 @@
/* End PBXAggregateTarget section */

/* Begin PBXBuildFile section */
4526F4B40FBB52C200781DD8 /* EncodingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4526F4B30FBB52C200781DD8 /* EncodingTests.m */; };
456A5ED10D9F4E4800D1D9CE /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 456A5ED00D9F4E4800D1D9CE /* SenTestingKit.framework */; };
456A848D0D81DB25000E29C9 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
457940F30D82214700EB2D22 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 457940E50D82214700EB2D22 /* main.m */; };
Expand Down Expand Up @@ -72,6 +73,8 @@

/* Begin PBXFileReference section */
1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
4526F4B20FBB52C200781DD8 /* EncodingTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EncodingTests.h; sourceTree = "<group>"; };
4526F4B30FBB52C200781DD8 /* EncodingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EncodingTests.m; sourceTree = "<group>"; };
456A5ED00D9F4E4800D1D9CE /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
457940E50D82214700EB2D22 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
457940E60D82214700EB2D22 /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = "<group>"; };
Expand Down Expand Up @@ -213,6 +216,8 @@
458CE9010F9C0C3D009EF591 /* Prefix.pch */,
457943930D8248DC00EB2D22 /* XPath_Tests.h */,
457943940D8248DC00EB2D22 /* XPath_Tests.m */,
4526F4B20FBB52C200781DD8 /* EncodingTests.h */,
4526F4B30FBB52C200781DD8 /* EncodingTests.m */,
);
path = Source;
sourceTree = "<group>";
Expand Down Expand Up @@ -396,6 +401,7 @@
458CE9CC0F9C12BB009EF591 /* CXMLDocument_CreationExtensions.m in Sources */,
458CE9CD0F9C12BB009EF591 /* CXMLNode_CreationExtensions.m in Sources */,
458CE9CE0F9C12BB009EF591 /* CTidy.m in Sources */,
4526F4B40FBB52C200781DD8 /* EncodingTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
36 changes: 36 additions & 0 deletions UnitTests/Source/EncodingTests.h
@@ -0,0 +1,36 @@
//
// EncodingTests.h
// TouchXML
//
// Created by Jorge Pedroso on 5/10/09.
// Copyright 2009 Unsolicited Feedback. All rights reserved.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//

#import <SenTestingKit/SenTestingKit.h>

@interface EncodingTests : SenTestCase {

}

@end
137 changes: 137 additions & 0 deletions UnitTests/Source/EncodingTests.m
@@ -0,0 +1,137 @@
//
// EncodingTests.m
// TouchXML
//
// Created by Jorge Pedroso on 5/10/09.
// Copyright 2009 Unsolicited Feedback. All rights reserved.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//

#import "EncodingTests.h"

#import "CXMLDocument.h"

static NSString *xmlUTF8Str = @"\n\
<html> \n\
<head> \n\
<title>Новости и аналитика</title> \n\
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=windows-1251\" /> \n\
</head>\n\
</html>";


@implementation EncodingTests

- (void)test_initWithDataReturnsNilWhenInvalidEncoding
{
NSError *error;

NSData *nonUTF8Data = [xmlUTF8Str dataUsingEncoding:NSWindowsCP1251StringEncoding];

CXMLDocument *doc = [[CXMLDocument alloc] initWithData:nonUTF8Data options:0 error:&error];
// STAssertNil(doc, NULL);
// STAssertNotNil(error, NULL);
[doc release];

/* TODO: Unlike NSXMLDocument, CXMLDocument isn't failing parsing when given data with
non UTF-8 encoding, thus the above assertions are commented. */

/* Extra: check NSXMLDocument compatibility — like CXMLDocument, expects failure */
NSXMLDocument *nsdoc = [[NSXMLDocument alloc] initWithData:nonUTF8Data options:0 error:&error];
STAssertNil(nsdoc, NULL);
STAssertNotNil(error, NULL);
[nsdoc release];
}


- (void)test_initWithDataNonUTF8Encoding
{
NSError *error;

NSData *nonUTF8Data = [xmlUTF8Str dataUsingEncoding:NSWindowsCP1251StringEncoding];

/* Check if patch was applied. If not, bail gracefully showing how test will fail
with a non UTF-8 encoding with initWithData:options:error: implementation. */
CXMLDocument *doc;
doc = [CXMLDocument instancesRespondToSelector:@selector(initWithData:encoding:options:error:)]
? [[CXMLDocument alloc] initWithData:nonUTF8Data
encoding:NSWindowsCP1251StringEncoding
options:0
error:&error]
: [[CXMLDocument alloc] initWithData:nonUTF8Data options:0 error:&error];

STAssertNotNil(doc, NULL);
STAssertNil(error, NULL);

NSString *path = @"/html/head/title";
NSArray *nodes = [doc nodesForXPath:path error:&error];
CXMLNode *node = [nodes objectAtIndex:0];
NSString *result = [node stringValue];
STAssertEqualObjects(result, @"Новости и аналитика", nil);

[doc release];

/* Extra: check NSXMLDocument compatibility — like CXMLDocument, expects failure */
NSXMLDocument *nsdoc = [[NSXMLDocument alloc] initWithData:nonUTF8Data options:0 error:&error];
STAssertNil(nsdoc, NULL);
STAssertNotNil(error, NULL);
[nsdoc release];
/* enough, parse went ok */
}


- (void)test_initWithStringNonUTF8Enconding
{
NSError *error;

/* sanity check */
STAssertTrue([xmlUTF8Str canBeConvertedToEncoding:NSWindowsCP1251StringEncoding],
@"XML cannot be converted to windows-1251 without losing data.", nil);

NSData *nonUTF8Data = [xmlUTF8Str dataUsingEncoding:NSWindowsCP1251StringEncoding];
NSString *nonUTF8Str = [[NSString alloc] initWithData:nonUTF8Data encoding:NSWindowsCP1251StringEncoding];

CXMLDocument *doc = [[CXMLDocument alloc] initWithXMLString:nonUTF8Str options:0 error:&error];
STAssertNotNil(doc, NULL);
STAssertNil(error, NULL);

NSString *path = @"/html/head/title";
NSArray *nodes = [doc nodesForXPath:path error:&error];
CXMLNode *node = [nodes objectAtIndex:0];
NSString *result = [node stringValue];
STAssertEqualObjects(result, @"Новости и аналитика", nil);

[doc release];


/* Extra: check NSXMLDocument compatibility — like CXMLDocument, expects correct parsing */
NSXMLDocument *nsdoc = [[NSXMLDocument alloc] initWithXMLString:nonUTF8Str options:0 error:&error];
STAssertNotNil(nsdoc, NULL);
STAssertNil(error, NULL);
[nsdoc release];
/* enough, parse went ok */

[nonUTF8Str release];
}

@end

0 comments on commit 42750a6

Please sign in to comment.