From e89fc5bbc21c76539febcd0456d2853c887cd29d Mon Sep 17 00:00:00 2001 From: Chris Ballinger Date: Mon, 20 May 2019 14:33:59 -0700 Subject: [PATCH 1/8] Fix crash when running tests by eliminating Swift usage of empty XMLNode() init --- KissXML.xcodeproj/project.pbxproj | 7 +- .../xcschemes/KissXML (iOS).xcscheme | 2 +- .../xcschemes/KissXML (macOS).xcscheme | 2 +- .../xcschemes/KissXML (tvOS).xcscheme | 2 +- .../xcschemes/KissXML (watchOS).xcscheme | 2 +- .../KissXMLTests.xcodeproj/project.pbxproj | 25 +- .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcschemes/KissXMLTests (iOS).xcscheme | 4 +- .../xcschemes/KissXMLTests (macOS).xcscheme | 12 +- .../xcschemes/KissXMLTests (tvOS).xcscheme | 4 +- Tests/Shared/KissXMLAssertionTests.m | 414 ++++++++++++++++++ Tests/Shared/KissXMLSwiftTests.swift | 30 +- Tests/Shared/KissXMLTests.m | 386 ---------------- 13 files changed, 472 insertions(+), 426 deletions(-) create mode 100644 Tests/Framework/KissXMLTests.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 Tests/Shared/KissXMLAssertionTests.m diff --git a/KissXML.xcodeproj/project.pbxproj b/KissXML.xcodeproj/project.pbxproj index 566153ba..2dfb7373 100644 --- a/KissXML.xcodeproj/project.pbxproj +++ b/KissXML.xcodeproj/project.pbxproj @@ -343,7 +343,7 @@ 0DCD8DC11E54A3A2001D9832 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0940; + LastUpgradeCheck = 1020; ORGANIZATIONNAME = robbiehanson; TargetAttributes = { 0DCD8DC91E54A3A3001D9832 = { @@ -358,10 +358,11 @@ }; buildConfigurationList = 0DCD8DC41E54A3A2001D9832 /* Build configuration list for PBXProject "KissXML" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 0DCD8DC01E54A3A2001D9832; productRefGroup = 0DCD8DCB1E54A3A3001D9832 /* Products */; @@ -463,6 +464,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -526,6 +528,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; diff --git a/KissXML.xcodeproj/xcshareddata/xcschemes/KissXML (iOS).xcscheme b/KissXML.xcodeproj/xcshareddata/xcschemes/KissXML (iOS).xcscheme index cfd5d079..e3dc47c4 100644 --- a/KissXML.xcodeproj/xcshareddata/xcschemes/KissXML (iOS).xcscheme +++ b/KissXML.xcodeproj/xcshareddata/xcschemes/KissXML (iOS).xcscheme @@ -1,6 +1,6 @@ + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Tests/Framework/KissXMLTests.xcodeproj/xcshareddata/xcschemes/KissXMLTests (iOS).xcscheme b/Tests/Framework/KissXMLTests.xcodeproj/xcshareddata/xcschemes/KissXMLTests (iOS).xcscheme index ce9226fe..dd31740f 100644 --- a/Tests/Framework/KissXMLTests.xcodeproj/xcshareddata/xcschemes/KissXMLTests (iOS).xcscheme +++ b/Tests/Framework/KissXMLTests.xcodeproj/xcshareddata/xcschemes/KissXMLTests (iOS).xcscheme @@ -1,6 +1,6 @@ + + +#import + +@interface DDAssertionHandler : NSAssertionHandler +{ + BOOL shouldLogAssertionFailure; +} + +@property (nonatomic, readwrite, assign) BOOL shouldLogAssertionFailure; + +@end + +@interface KissXMLAssertionTests : XCTestCase +@end + +static NSAssertionHandler *prevAssertionHandler; +static DDAssertionHandler *ddAssertionHandler; + +@implementation KissXMLAssertionTests + +- (void)setUp +{ + [super setUp]; + // We purposefully do bad things to ensure the library is throwing exceptions when it should. + // In other words, DDXML uses the same assertions as NSXML, and we test they both throw the same exceptions + // on bad input. + // + // But the normal assertion handler does an NSLog for every failed assertion, + // even if that assertion is caught. This clogs up our console and makes it difficult to see test cases + // that failed. So we install our own assertion handler, and disable logging of failed assertions immediately + // before we enter those tests designed to trigger the assertion. + // And of course we re-enable the assertion logging when we exit those tests. + // + // See the tryCatch method below. + + prevAssertionHandler = [[[NSThread currentThread] threadDictionary] objectForKey:NSAssertionHandlerKey]; + ddAssertionHandler = [[DDAssertionHandler alloc] init]; + + [[[NSThread currentThread] threadDictionary] setObject:ddAssertionHandler forKey:NSAssertionHandlerKey]; +} + +- (void)tearDown +{ + [super tearDown]; + // Remove our custom assertion handler. + + if (prevAssertionHandler) + [[[NSThread currentThread] threadDictionary] setObject:ddAssertionHandler forKey:NSAssertionHandlerKey]; + else + [[[NSThread currentThread] threadDictionary] removeObjectForKey:NSAssertionHandlerKey]; + + prevAssertionHandler = nil; + ddAssertionHandler = nil; +} + +- (NSException *)tryCatch:(void (^)(void))block +{ + NSException *result = nil; + + ddAssertionHandler.shouldLogAssertionFailure = NO; + @try { + block(); + } + @catch (NSException *e) { + result = e; + } + ddAssertionHandler.shouldLogAssertionFailure = YES; + + return result; +} + +- (void)testDoubleAdd { @autoreleasepool + { + NSLog(@"Starting %@...", NSStringFromSelector(_cmd)); + + NSXMLElement *nsRoot1 = [NSXMLElement elementWithName:@"root1"]; + NSXMLElement *nsRoot2 = [NSXMLElement elementWithName:@"root2"]; + + NSXMLElement *nsNode = [NSXMLElement elementWithName:@"node"]; + NSXMLNode *nsAttr = [NSXMLNode attributeWithName:@"key" stringValue:@"value"]; + NSXMLNode *nsNs = [NSXMLNode namespaceWithName:@"a" stringValue:@"domain.com"]; + + NSException *nsInvalidAddException1 = nil; + NSException *nsInvalidAddException2 = nil; + NSException *nsInvalidAddException3 = nil; + + NSException *nsDoubleAddException1 = nil; + NSException *nsDoubleAddException2 = nil; + NSException *nsDoubleAddException3 = nil; + + nsInvalidAddException1 = [self tryCatch:^{ + // Elements can only have text, elements, processing instructions, and comments as children + [nsRoot1 addChild:nsAttr]; + }]; + + nsInvalidAddException2 = [self tryCatch:^{ + // Not an attribute + [nsRoot1 addAttribute:nsNode]; + }]; + + nsInvalidAddException3 = [self tryCatch:^{ + // Not a namespace + [nsRoot1 addNamespace:nsNode]; + }]; + + [nsRoot1 addChild:nsNode]; + nsDoubleAddException1 = [self tryCatch:^{ + // Cannot add a child that has a parent; detach or copy first + [nsRoot2 addChild:nsNode]; + }]; + + [nsRoot1 addAttribute:nsAttr]; + nsDoubleAddException2 = [self tryCatch:^{ + // Cannot add an attribute with a parent; detach or copy first + [nsRoot2 addAttribute:nsAttr]; + }]; + + [nsRoot1 addNamespace:nsNs]; + nsDoubleAddException3 = [self tryCatch:^{ + // Cannot add a namespace with a parent; detach or copy first + [nsRoot2 addNamespace:nsNs]; + }]; + + XCTAssert(nsInvalidAddException1 != nil, @"Failed CHECK 1"); + XCTAssert(nsInvalidAddException2 != nil, @"Failed CHECK 2"); + XCTAssert(nsInvalidAddException3 != nil, @"Failed CHECK 3"); + + XCTAssert(nsDoubleAddException1 != nil, @"Failed CHECK 4"); + XCTAssert(nsDoubleAddException2 != nil, @"Failed CHECK 5"); + XCTAssert(nsDoubleAddException3 != nil, @"Failed CHECK 6"); + + DDXMLElement *ddRoot1 = [DDXMLElement elementWithName:@"root1"]; + DDXMLElement *ddRoot2 = [DDXMLElement elementWithName:@"root2"]; + + DDXMLElement *ddNode = [DDXMLElement elementWithName:@"node"]; + DDXMLNode *ddAttr = [DDXMLNode attributeWithName:@"key" stringValue:@"value"]; + DDXMLNode *ddNs = [DDXMLNode namespaceWithName:@"a" stringValue:@"domain.com"]; + + NSException *ddInvalidAddException1 = nil; + NSException *ddInvalidAddException2 = nil; + NSException *ddInvalidAddException3 = nil; + + NSException *ddDoubleAddException1 = nil; + NSException *ddDoubleAddException2 = nil; + NSException *ddDoubleAddException3 = nil; + + ddInvalidAddException1 = [self tryCatch:^{ + // Elements can only have text, elements, processing instructions, and comments as children + [ddRoot1 addChild:ddAttr]; + }]; + + ddInvalidAddException2 = [self tryCatch:^{ + // Not an attribute + [ddRoot1 addAttribute:ddNode]; + }]; + + ddInvalidAddException3 = [self tryCatch:^{ + // Not a namespace + [ddRoot1 addNamespace:ddNode]; + }]; + + [ddRoot1 addChild:ddNode]; + ddDoubleAddException1 = [self tryCatch:^{ + // Cannot add a child that has a parent; detach or copy first + [ddRoot2 addChild:ddNode]; + }]; + + [ddRoot1 addAttribute:ddAttr]; + ddDoubleAddException2 = [self tryCatch:^{ + // Cannot add an attribute with a parent; detach or copy first + [ddRoot2 addAttribute:ddAttr]; + }]; + + [ddRoot1 addNamespace:ddNs]; + ddDoubleAddException3 = [self tryCatch:^{ + // Cannot add a namespace with a parent; detach or copy first + [ddRoot2 addNamespace:ddNs]; + }]; + + XCTAssert(ddInvalidAddException1 != nil, @"Failed test 1"); + XCTAssert(ddInvalidAddException2 != nil, @"Failed test 2"); + XCTAssert(ddInvalidAddException3 != nil, @"Failed test 3"); + + XCTAssert(ddDoubleAddException1 != nil, @"Failed test 4"); + XCTAssert(ddDoubleAddException2 != nil, @"Failed test 5"); + XCTAssert(ddDoubleAddException3 != nil, @"Failed test 6"); + }} + +- (void)testInsertChild { @autoreleasepool + { + NSLog(@"Starting %@...", NSStringFromSelector(_cmd)); + + NSXMLElement *nsParent = [NSXMLElement elementWithName:@"parent"]; + DDXMLElement *ddParent = [DDXMLElement elementWithName:@"parent"]; + + NSXMLElement *nsChild2 = [NSXMLElement elementWithName:@"child2"]; + DDXMLElement *ddChild2 = [DDXMLElement elementWithName:@"child2"]; + + [nsParent insertChild:nsChild2 atIndex:0]; + [ddParent insertChild:ddChild2 atIndex:0]; + + XCTAssert([[nsParent XMLString] isEqualToString:[ddParent XMLString]], @"Failed test 1"); + + NSXMLElement *nsChild0 = [NSXMLElement elementWithName:@"child0"]; + DDXMLElement *ddChild0 = [DDXMLElement elementWithName:@"child0"]; + + [nsParent insertChild:nsChild0 atIndex:0]; + [ddParent insertChild:ddChild0 atIndex:0]; + + XCTAssert([[nsParent XMLString] isEqualToString:[ddParent XMLString]], @"Failed test 2"); + + NSXMLElement *nsChild1 = [NSXMLElement elementWithName:@"child1"]; + DDXMLElement *ddChild1 = [DDXMLElement elementWithName:@"child1"]; + + [nsParent insertChild:nsChild1 atIndex:1]; + [ddParent insertChild:ddChild1 atIndex:1]; + + XCTAssert([[nsParent XMLString] isEqualToString:[ddParent XMLString]], @"Failed test 3"); + + NSXMLElement *nsChild3 = [NSXMLElement elementWithName:@"child3"]; + DDXMLElement *ddChild3 = [DDXMLElement elementWithName:@"child3"]; + + [nsParent insertChild:nsChild3 atIndex:3]; + [ddParent insertChild:ddChild3 atIndex:3]; + + XCTAssert([[nsParent XMLString] isEqualToString:[ddParent XMLString]], @"Failed test 4"); + + NSException *nsException; + NSException *ddException; + + NSXMLElement *nsChild5 = [NSXMLElement elementWithName:@"child5"]; + DDXMLElement *ddChild5 = [DDXMLElement elementWithName:@"child5"]; + + nsException = [self tryCatch:^{ + // Exception - index (5) beyond bounds (5) + [nsParent insertChild:nsChild5 atIndex:5]; + }]; + + ddException = [self tryCatch:^{ + // Exception - index (5) beyond bounds (5) + [ddParent insertChild:ddChild5 atIndex:5]; + }]; + + XCTAssert(nsException != nil, @"Failed CHECK 1"); + XCTAssert(ddException != nil, @"Failed test 6"); + }} + + +- (void)testMemoryIssueDebugging { @autoreleasepool + { +#if DDXML_DEBUG_MEMORY_ISSUES + + NSLog(@"Starting %@...", NSStringFromSelector(_cmd)); + + // + // + // + + NSMutableString *xmlStr = [NSMutableString stringWithCapacity:100]; + [xmlStr appendString:@""]; + [xmlStr appendString:@" "]; + [xmlStr appendString:@""]; + + DDXMLDocument *doc = [[DDXMLDocument alloc] initWithXMLString:xmlStr options:0 error:nil]; + DDXMLElement *starbucks = [doc rootElement]; + DDXMLElement *latte = [[starbucks elementsForName:@"latte"] lastObject]; + + [doc release]; + + NSException *exception1; + exception1 = [self tryCatch:^{ + + [starbucks name]; + [latte name]; + }]; + XCTAssert(exception1 == nil, @"Failed test 1"); + + [starbucks removeChildAtIndex:0]; + + NSException *exception2; + exception2 = [self tryCatch:^{ + + [latte name]; + }]; + XCTAssert(exception2 != nil, @"Failed test 2"); + + // + // + // + + DDXMLElement *animals = [[DDXMLElement alloc] initWithName:@"animals"]; + DDXMLElement *duck = [DDXMLElement elementWithName:@"duck"]; + + [animals addChild:duck]; + [animals release]; + + NSException *exception3; + exception3 = [self tryCatch:^{ + + [duck name]; + }]; + XCTAssert(exception3 == nil, @"Failed test 3"); + + // + // + // + + DDXMLElement *colors = [[DDXMLElement alloc] initWithName:@"colors"]; + DDXMLElement *red = [DDXMLElement elementWithName:@"red"]; + + [colors addChild:red]; + [colors setChildren:nil]; + + NSException *exception4; + exception4 = [self tryCatch:^{ + + [red name]; + }]; + XCTAssert(exception4 != nil, @"Failed test 4"); + +#endif + }} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation DDAssertionHandler + +@synthesize shouldLogAssertionFailure; + +- (instancetype)init +{ + if ((self = [super init])) + { + shouldLogAssertionFailure = YES; + } + return self; +} + +- (void)logFailureIn:(NSString *)place + file:(NSString *)fileName + lineNumber:(NSInteger)line +{ + // How Apple's default assertion handler does it (all on one line): + // + // *** Assertion failure in -[NSXMLElement insertChild:atIndex:], + // /SourceCache/Foundation/Foundation-751.53/XML.subproj/XMLTypes.subproj/NSXMLElement.m:823 + + NSLog(@"*** Assertion failure in %@, %@:%li", place, fileName, (long int)line); +} + +- (void)handleFailureInFunction:(NSString *)functionName + file:(NSString *)fileName + lineNumber:(NSInteger)line + description:(NSString *)format, ... +{ + if (shouldLogAssertionFailure) + { + [self logFailureIn:functionName file:fileName lineNumber:line]; + } + + va_list args; + va_start(args, format); + + NSString *reason = [[NSString alloc] initWithFormat:format arguments:args]; + + va_end(args); + + [[NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:nil] raise]; +} + +- (void)handleFailureInMethod:(SEL)selector + object:(id)object + file:(NSString *)fileName + lineNumber:(NSInteger)line + description:(NSString *)format, ... +{ + if (shouldLogAssertionFailure) + { + Class objectClass = [object class]; + + NSString *type; + if (objectClass == object) + type = @"+"; + else + type = @"-"; + + NSString *place = [NSString stringWithFormat:@"%@[%@ %@]", + type, NSStringFromClass(objectClass), NSStringFromSelector(selector)]; + + [self logFailureIn:place file:fileName lineNumber:line]; + } + + va_list args; + va_start(args, format); + + NSString *reason = [[NSString alloc] initWithFormat:format arguments:args]; + + va_end(args); + + [[NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:nil] raise]; +} + +@end diff --git a/Tests/Shared/KissXMLSwiftTests.swift b/Tests/Shared/KissXMLSwiftTests.swift index 6c2fd645..60f39b6f 100644 --- a/Tests/Shared/KissXMLSwiftTests.swift +++ b/Tests/Shared/KissXMLSwiftTests.swift @@ -10,43 +10,33 @@ import XCTest import KissXML class KissXMLSwiftTests: XCTestCase { - + override func setUp() { super.setUp() // Put setup code here. This method is called before the invocation of each test method in the class. } - + override func tearDown() { // Put teardown code here. This method is called after the invocation of each test method in the class. super.tearDown() } - + func testXMLNode() { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct results. - let node = DDXMLNode() - let apple = XMLNode() + let node = DDXMLNode.attribute(withName: "xml:duck", stringValue: "quack") + let apple = XMLNode.attribute(withName: "xml:duck", stringValue: "quack") XCTAssertNotNil(node) XCTAssertNotNil(apple) } - + func testXMLElement() { let expected = "" - var expXml: XMLElement? = nil - do { - expXml = try XMLElement(xmlString: expected) - } catch { - } + let expXml = try? XMLElement(xmlString: expected) XCTAssertNotNil(expXml) XCTAssertNotNil(expXml?.xmlString) - - var expDDXml: DDXMLElement? = nil - do { - expDDXml = try DDXMLElement(xmlString: expected) - } catch { - } + + let expDDXml: DDXMLElement? = try? DDXMLElement(xmlString: expected) XCTAssertNotNil(expDDXml) XCTAssertNotNil(expDDXml?.xmlString) } - + } diff --git a/Tests/Shared/KissXMLTests.m b/Tests/Shared/KissXMLTests.m index 98e7f23b..fd4d381f 100644 --- a/Tests/Shared/KissXMLTests.m +++ b/Tests/Shared/KissXMLTests.m @@ -9,72 +9,19 @@ #import #import -@interface DDAssertionHandler : NSAssertionHandler -{ - BOOL shouldLogAssertionFailure; -} - -@property (nonatomic, readwrite, assign) BOOL shouldLogAssertionFailure; - -@end - @interface KissXMLTests : XCTestCase @end @implementation KissXMLTests -static NSAssertionHandler *prevAssertionHandler; -static DDAssertionHandler *ddAssertionHandler; - - (void)setUp { [super setUp]; - // We purposefully do bad things to ensure the library is throwing exceptions when it should. - // In other words, DDXML uses the same assertions as NSXML, and we test they both throw the same exceptions - // on bad input. - // - // But the normal assertion handler does an NSLog for every failed assertion, - // even if that assertion is caught. This clogs up our console and makes it difficult to see test cases - // that failed. So we install our own assertion handler, and disable logging of failed assertions immediately - // before we enter those tests designed to trigger the assertion. - // And of course we re-enable the assertion logging when we exit those tests. - // - // See the tryCatch method below. - - prevAssertionHandler = [[[NSThread currentThread] threadDictionary] objectForKey:NSAssertionHandlerKey]; - ddAssertionHandler = [[DDAssertionHandler alloc] init]; - - [[[NSThread currentThread] threadDictionary] setObject:ddAssertionHandler forKey:NSAssertionHandlerKey]; } - (void)tearDown { [super tearDown]; - // Remove our custom assertion handler. - - if (prevAssertionHandler) - [[[NSThread currentThread] threadDictionary] setObject:ddAssertionHandler forKey:NSAssertionHandlerKey]; - else - [[[NSThread currentThread] threadDictionary] removeObjectForKey:NSAssertionHandlerKey]; - - prevAssertionHandler = nil; - ddAssertionHandler = nil; -} - -- (NSException *)tryCatch:(void (^)(void))block -{ - NSException *result = nil; - - ddAssertionHandler.shouldLogAssertionFailure = NO; - @try { - block(); - } - @catch (NSException *e) { - result = e; - } - ddAssertionHandler.shouldLogAssertionFailure = YES; - - return result; } - (void)testName { @autoreleasepool @@ -181,123 +128,6 @@ - (void)testPrefixName { @autoreleasepool XCTAssert([nsTest6 isEqualToString:ddTest6], @"Failed test 6"); }} -- (void)testDoubleAdd { @autoreleasepool - { - NSLog(@"Starting %@...", NSStringFromSelector(_cmd)); - - NSXMLElement *nsRoot1 = [NSXMLElement elementWithName:@"root1"]; - NSXMLElement *nsRoot2 = [NSXMLElement elementWithName:@"root2"]; - - NSXMLElement *nsNode = [NSXMLElement elementWithName:@"node"]; - NSXMLNode *nsAttr = [NSXMLNode attributeWithName:@"key" stringValue:@"value"]; - NSXMLNode *nsNs = [NSXMLNode namespaceWithName:@"a" stringValue:@"domain.com"]; - - NSException *nsInvalidAddException1 = nil; - NSException *nsInvalidAddException2 = nil; - NSException *nsInvalidAddException3 = nil; - - NSException *nsDoubleAddException1 = nil; - NSException *nsDoubleAddException2 = nil; - NSException *nsDoubleAddException3 = nil; - - nsInvalidAddException1 = [self tryCatch:^{ - // Elements can only have text, elements, processing instructions, and comments as children - [nsRoot1 addChild:nsAttr]; - }]; - - nsInvalidAddException2 = [self tryCatch:^{ - // Not an attribute - [nsRoot1 addAttribute:nsNode]; - }]; - - nsInvalidAddException3 = [self tryCatch:^{ - // Not a namespace - [nsRoot1 addNamespace:nsNode]; - }]; - - [nsRoot1 addChild:nsNode]; - nsDoubleAddException1 = [self tryCatch:^{ - // Cannot add a child that has a parent; detach or copy first - [nsRoot2 addChild:nsNode]; - }]; - - [nsRoot1 addAttribute:nsAttr]; - nsDoubleAddException2 = [self tryCatch:^{ - // Cannot add an attribute with a parent; detach or copy first - [nsRoot2 addAttribute:nsAttr]; - }]; - - [nsRoot1 addNamespace:nsNs]; - nsDoubleAddException3 = [self tryCatch:^{ - // Cannot add a namespace with a parent; detach or copy first - [nsRoot2 addNamespace:nsNs]; - }]; - - XCTAssert(nsInvalidAddException1 != nil, @"Failed CHECK 1"); - XCTAssert(nsInvalidAddException2 != nil, @"Failed CHECK 2"); - XCTAssert(nsInvalidAddException3 != nil, @"Failed CHECK 3"); - - XCTAssert(nsDoubleAddException1 != nil, @"Failed CHECK 4"); - XCTAssert(nsDoubleAddException2 != nil, @"Failed CHECK 5"); - XCTAssert(nsDoubleAddException3 != nil, @"Failed CHECK 6"); - - DDXMLElement *ddRoot1 = [DDXMLElement elementWithName:@"root1"]; - DDXMLElement *ddRoot2 = [DDXMLElement elementWithName:@"root2"]; - - DDXMLElement *ddNode = [DDXMLElement elementWithName:@"node"]; - DDXMLNode *ddAttr = [DDXMLNode attributeWithName:@"key" stringValue:@"value"]; - DDXMLNode *ddNs = [DDXMLNode namespaceWithName:@"a" stringValue:@"domain.com"]; - - NSException *ddInvalidAddException1 = nil; - NSException *ddInvalidAddException2 = nil; - NSException *ddInvalidAddException3 = nil; - - NSException *ddDoubleAddException1 = nil; - NSException *ddDoubleAddException2 = nil; - NSException *ddDoubleAddException3 = nil; - - ddInvalidAddException1 = [self tryCatch:^{ - // Elements can only have text, elements, processing instructions, and comments as children - [ddRoot1 addChild:ddAttr]; - }]; - - ddInvalidAddException2 = [self tryCatch:^{ - // Not an attribute - [ddRoot1 addAttribute:ddNode]; - }]; - - ddInvalidAddException3 = [self tryCatch:^{ - // Not a namespace - [ddRoot1 addNamespace:ddNode]; - }]; - - [ddRoot1 addChild:ddNode]; - ddDoubleAddException1 = [self tryCatch:^{ - // Cannot add a child that has a parent; detach or copy first - [ddRoot2 addChild:ddNode]; - }]; - - [ddRoot1 addAttribute:ddAttr]; - ddDoubleAddException2 = [self tryCatch:^{ - // Cannot add an attribute with a parent; detach or copy first - [ddRoot2 addAttribute:ddAttr]; - }]; - - [ddRoot1 addNamespace:ddNs]; - ddDoubleAddException3 = [self tryCatch:^{ - // Cannot add a namespace with a parent; detach or copy first - [ddRoot2 addNamespace:ddNs]; - }]; - - XCTAssert(ddInvalidAddException1 != nil, @"Failed test 1"); - XCTAssert(ddInvalidAddException2 != nil, @"Failed test 2"); - XCTAssert(ddInvalidAddException3 != nil, @"Failed test 3"); - - XCTAssert(ddDoubleAddException1 != nil, @"Failed test 4"); - XCTAssert(ddDoubleAddException2 != nil, @"Failed test 5"); - XCTAssert(ddDoubleAddException3 != nil, @"Failed test 6"); - }} - - (void)testNsGeneral { @autoreleasepool { NSLog(@"Starting %@...", NSStringFromSelector(_cmd)); @@ -1579,64 +1409,6 @@ - (void)testNSXMLBugs { @autoreleasepool }} -- (void)testInsertChild { @autoreleasepool - { - NSLog(@"Starting %@...", NSStringFromSelector(_cmd)); - - NSXMLElement *nsParent = [NSXMLElement elementWithName:@"parent"]; - DDXMLElement *ddParent = [DDXMLElement elementWithName:@"parent"]; - - NSXMLElement *nsChild2 = [NSXMLElement elementWithName:@"child2"]; - DDXMLElement *ddChild2 = [DDXMLElement elementWithName:@"child2"]; - - [nsParent insertChild:nsChild2 atIndex:0]; - [ddParent insertChild:ddChild2 atIndex:0]; - - XCTAssert([[nsParent XMLString] isEqualToString:[ddParent XMLString]], @"Failed test 1"); - - NSXMLElement *nsChild0 = [NSXMLElement elementWithName:@"child0"]; - DDXMLElement *ddChild0 = [DDXMLElement elementWithName:@"child0"]; - - [nsParent insertChild:nsChild0 atIndex:0]; - [ddParent insertChild:ddChild0 atIndex:0]; - - XCTAssert([[nsParent XMLString] isEqualToString:[ddParent XMLString]], @"Failed test 2"); - - NSXMLElement *nsChild1 = [NSXMLElement elementWithName:@"child1"]; - DDXMLElement *ddChild1 = [DDXMLElement elementWithName:@"child1"]; - - [nsParent insertChild:nsChild1 atIndex:1]; - [ddParent insertChild:ddChild1 atIndex:1]; - - XCTAssert([[nsParent XMLString] isEqualToString:[ddParent XMLString]], @"Failed test 3"); - - NSXMLElement *nsChild3 = [NSXMLElement elementWithName:@"child3"]; - DDXMLElement *ddChild3 = [DDXMLElement elementWithName:@"child3"]; - - [nsParent insertChild:nsChild3 atIndex:3]; - [ddParent insertChild:ddChild3 atIndex:3]; - - XCTAssert([[nsParent XMLString] isEqualToString:[ddParent XMLString]], @"Failed test 4"); - - NSException *nsException; - NSException *ddException; - - NSXMLElement *nsChild5 = [NSXMLElement elementWithName:@"child5"]; - DDXMLElement *ddChild5 = [DDXMLElement elementWithName:@"child5"]; - - nsException = [self tryCatch:^{ - // Exception - index (5) beyond bounds (5) - [nsParent insertChild:nsChild5 atIndex:5]; - }]; - - ddException = [self tryCatch:^{ - // Exception - index (5) beyond bounds (5) - [ddParent insertChild:ddChild5 atIndex:5]; - }]; - - XCTAssert(nsException != nil, @"Failed CHECK 1"); - XCTAssert(ddException != nil, @"Failed test 6"); - }} - (void)testElementSerialization { @autoreleasepool { @@ -1674,81 +1446,6 @@ - (void)testAttrWithColonInName { @autoreleasepool XCTAssert(dda != nil, @"Failed test 1"); }} -- (void)testMemoryIssueDebugging { @autoreleasepool - { -#if DDXML_DEBUG_MEMORY_ISSUES - - NSLog(@"Starting %@...", NSStringFromSelector(_cmd)); - - // - // - // - - NSMutableString *xmlStr = [NSMutableString stringWithCapacity:100]; - [xmlStr appendString:@""]; - [xmlStr appendString:@" "]; - [xmlStr appendString:@""]; - - DDXMLDocument *doc = [[DDXMLDocument alloc] initWithXMLString:xmlStr options:0 error:nil]; - DDXMLElement *starbucks = [doc rootElement]; - DDXMLElement *latte = [[starbucks elementsForName:@"latte"] lastObject]; - - [doc release]; - - NSException *exception1; - exception1 = [self tryCatch:^{ - - [starbucks name]; - [latte name]; - }]; - XCTAssert(exception1 == nil, @"Failed test 1"); - - [starbucks removeChildAtIndex:0]; - - NSException *exception2; - exception2 = [self tryCatch:^{ - - [latte name]; - }]; - XCTAssert(exception2 != nil, @"Failed test 2"); - - // - // - // - - DDXMLElement *animals = [[DDXMLElement alloc] initWithName:@"animals"]; - DDXMLElement *duck = [DDXMLElement elementWithName:@"duck"]; - - [animals addChild:duck]; - [animals release]; - - NSException *exception3; - exception3 = [self tryCatch:^{ - - [duck name]; - }]; - XCTAssert(exception3 == nil, @"Failed test 3"); - - // - // - // - - DDXMLElement *colors = [[DDXMLElement alloc] initWithName:@"colors"]; - DDXMLElement *red = [DDXMLElement elementWithName:@"red"]; - - [colors addChild:red]; - [colors setChildren:nil]; - - NSException *exception4; - exception4 = [self tryCatch:^{ - - [red name]; - }]; - XCTAssert(exception4 != nil, @"Failed test 4"); - -#endif - }} - - (void)testAttrNs { @autoreleasepool { NSLog(@"Starting %@...", NSStringFromSelector(_cmd)); @@ -2011,86 +1708,3 @@ - (void)testInvalidNode { @autoreleasepool }} @end - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -@implementation DDAssertionHandler - -@synthesize shouldLogAssertionFailure; - -- (instancetype)init -{ - if ((self = [super init])) - { - shouldLogAssertionFailure = YES; - } - return self; -} - -- (void)logFailureIn:(NSString *)place - file:(NSString *)fileName - lineNumber:(NSInteger)line -{ - // How Apple's default assertion handler does it (all on one line): - // - // *** Assertion failure in -[NSXMLElement insertChild:atIndex:], - // /SourceCache/Foundation/Foundation-751.53/XML.subproj/XMLTypes.subproj/NSXMLElement.m:823 - - NSLog(@"*** Assertion failure in %@, %@:%li", place, fileName, (long int)line); -} - -- (void)handleFailureInFunction:(NSString *)functionName - file:(NSString *)fileName - lineNumber:(NSInteger)line - description:(NSString *)format, ... -{ - if (shouldLogAssertionFailure) - { - [self logFailureIn:functionName file:fileName lineNumber:line]; - } - - va_list args; - va_start(args, format); - - NSString *reason = [[NSString alloc] initWithFormat:format arguments:args]; - - va_end(args); - - [[NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:nil] raise]; -} - -- (void)handleFailureInMethod:(SEL)selector - object:(id)object - file:(NSString *)fileName - lineNumber:(NSInteger)line - description:(NSString *)format, ... -{ - if (shouldLogAssertionFailure) - { - Class objectClass = [object class]; - - NSString *type; - if (objectClass == object) - type = @"+"; - else - type = @"-"; - - NSString *place = [NSString stringWithFormat:@"%@[%@ %@]", - type, NSStringFromClass(objectClass), NSStringFromSelector(selector)]; - - [self logFailureIn:place file:fileName lineNumber:line]; - } - - va_list args; - va_start(args, format); - - NSString *reason = [[NSString alloc] initWithFormat:format arguments:args]; - - va_end(args); - - [[NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:nil] raise]; -} - -@end From fae69d21b7d4a58ae818a5e9c830e8808b73dbef Mon Sep 17 00:00:00 2001 From: Chris Ballinger Date: Mon, 20 May 2019 14:34:28 -0700 Subject: [PATCH 2/8] Update Travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index fc60e2d1..b933b296 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -osx_image: xcode9.1 +osx_image: xcode10.2 language: objective-c cache: @@ -10,7 +10,7 @@ cache: before_install: # Fix Travis xcodebuild exited with 65 https://github.com/travis-ci/travis-ci/issues/6675#issuecomment-257964767 - - export IOS_SIMULATOR_UDID=`instruments -s devices | grep -m 1 "iPhone 8 (11" | awk -F '[ ]' '{print $4}' | awk -F '[\[]' '{print $2}' | sed 's/.$//'` + - export IOS_SIMULATOR_UDID=`instruments -s devices | grep -m 1 "iPhone 8 (12" | awk -F '[ ]' '{print $4}' | awk -F '[\[]' '{print $2}' | sed 's/.$//'` - echo $IOS_SIMULATOR_UDID - open -a "simulator" --args -CurrentDeviceUDID $IOS_SIMULATOR_UDID From 1c83f0e8586a376a74f221acb4dbb75f42c3b2c3 Mon Sep 17 00:00:00 2001 From: Chris Ballinger Date: Mon, 20 May 2019 14:36:51 -0700 Subject: [PATCH 3/8] Reset scheme analyzer options --- .../xcshareddata/xcschemes/KissXMLTests (macOS).xcscheme | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Tests/Framework/KissXMLTests.xcodeproj/xcshareddata/xcschemes/KissXMLTests (macOS).xcscheme b/Tests/Framework/KissXMLTests.xcodeproj/xcshareddata/xcschemes/KissXMLTests (macOS).xcscheme index e6b67b23..ce2415d1 100644 --- a/Tests/Framework/KissXMLTests.xcodeproj/xcshareddata/xcschemes/KissXMLTests (macOS).xcscheme +++ b/Tests/Framework/KissXMLTests.xcodeproj/xcshareddata/xcschemes/KissXMLTests (macOS).xcscheme @@ -10,9 +10,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - enableAddressSanitizer = "YES" - enableASanStackUseAfterReturn = "YES" - enableUBSanitizer = "YES" shouldUseLaunchSchemeArgsEnv = "YES"> - - Date: Mon, 20 May 2019 14:40:28 -0700 Subject: [PATCH 4/8] Remove line for opening simulator --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b933b296..874ffa96 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,6 @@ before_install: # Fix Travis xcodebuild exited with 65 https://github.com/travis-ci/travis-ci/issues/6675#issuecomment-257964767 - export IOS_SIMULATOR_UDID=`instruments -s devices | grep -m 1 "iPhone 8 (12" | awk -F '[ ]' '{print $4}' | awk -F '[\[]' '{print $2}' | sed 's/.$//'` - echo $IOS_SIMULATOR_UDID - - open -a "simulator" --args -CurrentDeviceUDID $IOS_SIMULATOR_UDID install: - cd Tests/ From 3a30f175da9364693a70a9c612e6d28e1faebe67 Mon Sep 17 00:00:00 2001 From: Chris Ballinger Date: Mon, 20 May 2019 14:48:43 -0700 Subject: [PATCH 5/8] Replace Foundation module import --- KissXML/KissXML.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KissXML/KissXML.h b/KissXML/KissXML.h index 70b94ac1..cd47c4c7 100644 --- a/KissXML/KissXML.h +++ b/KissXML/KissXML.h @@ -1,4 +1,4 @@ -@import Foundation; +#import #import "DDXMLElementAdditions.h" #import "NSString+DDXML.h" From 5d80f83b7f88d312cf73c49517ef2c615753b067 Mon Sep 17 00:00:00 2001 From: Chris Ballinger Date: Mon, 20 May 2019 14:58:58 -0700 Subject: [PATCH 6/8] Remove Travis workaround for NSXML crash --- .travis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 874ffa96..d964ef19 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,9 +24,7 @@ install: script: - set -o pipefail - # The Swift and Obj-C tests need to be run separately due to a bug in Apple's NSXML code - - xcodebuild -project ./Framework/KissXMLTests.xcodeproj -scheme "KissXMLTests (macOS)" -sdk macosx -arch x86_64 -only-testing:"KissXMLTests (macOS)/KissXMLSwiftTests" test | xcpretty -c - - xcodebuild -project ./Framework/KissXMLTests.xcodeproj -scheme "KissXMLTests (macOS)" -sdk macosx -arch x86_64 -only-testing:"KissXMLTests (macOS)/KissXMLTests" test | xcpretty -c + - xcodebuild -project ./Framework/KissXMLTests.xcodeproj -scheme "KissXMLTests (macOS)" -sdk macosx -arch x86_64 test | xcpretty -c - travis_retry xcodebuild -project ./Framework/KissXMLTests.xcodeproj -scheme "KissXMLTests (iOS)" -sdk iphonesimulator -destination "id=$IOS_SIMULATOR_UDID" test | xcpretty -c - xcodebuild -project ../KissXML.xcodeproj -scheme "KissXML (tvOS)" -sdk appletvsimulator -arch x86_64 build | xcpretty -c - xcodebuild -project ../KissXML.xcodeproj -scheme "KissXML (watchOS)" -sdk watchos build | xcpretty -c From 80784c04e4426dc24194f58bf5557d7d514a44a6 Mon Sep 17 00:00:00 2001 From: Chris Ballinger Date: Mon, 20 May 2019 15:01:53 -0700 Subject: [PATCH 7/8] ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES --- Tests/Framework/KissXMLTests.xcodeproj/project.pbxproj | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Tests/Framework/KissXMLTests.xcodeproj/project.pbxproj b/Tests/Framework/KissXMLTests.xcodeproj/project.pbxproj index 14d39c68..3029d3a0 100644 --- a/Tests/Framework/KissXMLTests.xcodeproj/project.pbxproj +++ b/Tests/Framework/KissXMLTests.xcodeproj/project.pbxproj @@ -375,7 +375,6 @@ D94132131E5CF00B00189BD5 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -425,7 +424,6 @@ D94132141E5CF00B00189BD5 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -467,7 +465,6 @@ D94132241E5CF14400189BD5 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -517,7 +514,6 @@ D94132251E5CF14400189BD5 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -559,6 +555,7 @@ D9AA724E1C56EE9D00002BEE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; @@ -594,6 +591,7 @@ D9AA724F1C56EE9D00002BEE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; @@ -628,7 +626,6 @@ D9AA725A1C56EEF500002BEE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -678,7 +675,6 @@ D9AA725B1C56EEF500002BEE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; From c0e3c84b0d8e658395964788bc95309feb963efa Mon Sep 17 00:00:00 2001 From: Chris Ballinger Date: Mon, 20 May 2019 15:49:02 -0700 Subject: [PATCH 8/8] Use iOS 12.2 simulator for testing --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d964ef19..47c924c1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ cache: before_install: # Fix Travis xcodebuild exited with 65 https://github.com/travis-ci/travis-ci/issues/6675#issuecomment-257964767 - - export IOS_SIMULATOR_UDID=`instruments -s devices | grep -m 1 "iPhone 8 (12" | awk -F '[ ]' '{print $4}' | awk -F '[\[]' '{print $2}' | sed 's/.$//'` + - export IOS_SIMULATOR_UDID=`instruments -s devices | grep -m 1 "iPhone 8 (12.2" | awk -F '[ ]' '{print $4}' | awk -F '[\[]' '{print $2}' | sed 's/.$//'` - echo $IOS_SIMULATOR_UDID install: