diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a039cb1..f18c110 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,10 +7,10 @@ on: jobs: mac: - runs-on: macos-11 + runs-on: macos-14 strategy: matrix: - xcode: [11.7, 12.5.1, 13.1] + xcode: [14.3.1, 15.2] fail-fast: false name: Xcode ${{ matrix.xcode }} env: @@ -21,9 +21,9 @@ jobs: run: | set -o pipefail xcodebuild build-for-testing test-without-building -scheme Kanna -configuration Release ENABLE_TESTABILITY=YES | xcpretty -c - xcodebuild build-for-testing test-without-building -scheme Kanna -configuration Release -sdk iphonesimulator -destination "name=iPhone 8" ENABLE_TESTABILITY=YES | xcpretty -c + xcodebuild build-for-testing test-without-building -scheme Kanna -configuration Release -sdk iphonesimulator -destination "name=iPhone 15" ENABLE_TESTABILITY=YES | xcpretty -c xcodebuild build-for-testing test-without-building -scheme Kanna -configuration Release -sdk appletvsimulator -destination "name=Apple TV" ENABLE_TESTABILITY=YES | xcpretty -c - xcodebuild -scheme Kanna -configuration Release -sdk watchsimulator -destination "name=Apple Watch Series 4 - 40mm" + xcodebuild -scheme Kanna -configuration Release -sdk watchsimulator -destination "name=Apple Watch Series 8 (45mm)" - name: swiftpm build and test run: | swift build diff --git a/.swift-version b/.swift-version index ef425ca..95ee81a 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -5.2 +5.9 diff --git a/Kanna.podspec b/Kanna.podspec index 14b831f..a088320 100644 --- a/Kanna.podspec +++ b/Kanna.podspec @@ -7,7 +7,7 @@ Pod::Spec.new do |s| s.author = { "Atsushi Kiwaki" => "tid.develop@gmail.com" } s.source = { :git => "https://github.com/tid-kijyun/Kanna.git", :tag => s.version.to_s } s.social_media_url = 'https://twitter.com/_tid_' - s.swift_versions = ["5.0", "5.1", "5.2"] + s.swift_versions = '5' s.ios.deployment_target = '8.0' s.osx.deployment_target = '10.9' @@ -15,6 +15,7 @@ Pod::Spec.new do |s| s.watchos.deployment_target = "2.0" s.requires_arc = true s.source_files = ['Sources/**/*.swift', 'Sources/**/*.h'] + s.resource_bundles = {'kanna_privacy' => ['Kanna/PrivacyInfo.xcprivacy']} s.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(SDKROOT)/usr/include/libxml2', 'OTHER_LDFLAGS' => '-lxml2' diff --git a/Kanna.xcodeproj/project.pbxproj b/Kanna.xcodeproj/project.pbxproj index a7db722..ba9fc78 100644 --- a/Kanna.xcodeproj/project.pbxproj +++ b/Kanna.xcodeproj/project.pbxproj @@ -3,10 +3,12 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ + 1E76C39D2B86F5EA009A89B9 /* Bundle+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E76C39C2B86F5EA009A89B9 /* Bundle+.swift */; }; + 1E76C39F2B86F907009A89B9 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 1E76C39E2B86F907009A89B9 /* PrivacyInfo.xcprivacy */; }; 1E7ADC3D1DF4F3FC006E1815 /* Kanna.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E7ADC331DF4F3FC006E1815 /* Kanna.framework */; }; 1E7ADC561DF4F567006E1815 /* CSS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7ADC4F1DF4F567006E1815 /* CSS.swift */; }; 1E7ADC581DF4F567006E1815 /* Kanna.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E7ADC511DF4F567006E1815 /* Kanna.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -41,6 +43,8 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 1E76C39C2B86F5EA009A89B9 /* Bundle+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundle+.swift"; sourceTree = ""; }; + 1E76C39E2B86F907009A89B9 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; 1E7ADC331DF4F3FC006E1815 /* Kanna.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Kanna.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 1E7ADC3C1DF4F3FC006E1815 /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 1E7ADC4F1DF4F567006E1815 /* CSS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSS.swift; sourceTree = ""; }; @@ -129,6 +133,7 @@ 1E7ADC551DF4F567006E1815 /* libxmlParserOption.swift */, 1EC805F91FA2FB2F0067D3DA /* Deprecated.swift */, 1E7ADC501DF4F567006E1815 /* Info.plist */, + 1E76C39E2B86F907009A89B9 /* PrivacyInfo.xcprivacy */, ); path = Kanna; sourceTree = ""; @@ -152,6 +157,7 @@ 1E7ADC8C1DF55B37006E1815 /* KannaTutorialsTest.swift */, 1E7ADC9A1DF5907F006E1815 /* Data */, 1E7ADC8A1DF55B37006E1815 /* Info.plist */, + 1E76C39C2B86F5EA009A89B9 /* Bundle+.swift */, ); path = KannaTests; sourceTree = ""; @@ -240,8 +246,9 @@ 1E7ADC2A1DF4F3FC006E1815 /* Project object */ = { isa = PBXProject; attributes = { + BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 0810; - LastUpgradeCheck = 1020; + LastUpgradeCheck = 1520; ORGANIZATIONNAME = "Atsushi Kiwaki"; TargetAttributes = { 1E7ADC321DF4F3FC006E1815 = { @@ -281,6 +288,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 1E76C39F2B86F907009A89B9 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -340,6 +348,7 @@ buildActionMask = 2147483647; files = ( 1E7ADC931DF55B37006E1815 /* KannaHTMLTests.swift in Sources */, + 1E76C39D2B86F5EA009A89B9 /* Bundle+.swift in Sources */, 1E7ADC941DF55B37006E1815 /* KannaTutorialsTest.swift in Sources */, 1EB4A01F204C1F240003D7A2 /* KannaCSSTests.swift in Sources */, 1E7E698A204C1D6300516E31 /* KannaXMLModifyingTests.swift in Sources */, @@ -385,6 +394,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -394,9 +404,11 @@ CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -453,6 +465,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -462,9 +475,11 @@ CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -477,8 +492,9 @@ MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; SWIFT_INCLUDE_PATHS = ""; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; TVOS_DEPLOYMENT_TARGET = 12.0; VERSIONING_SYSTEM = "apple-generic"; @@ -493,17 +509,25 @@ buildSettings = { CODE_SIGN_IDENTITY = ""; COMBINE_HIDPI_IMAGES = YES; + DEAD_CODE_STRIPPING = YES; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; FRAMEWORK_VERSION = A; INFOPLIST_FILE = Sources/Kanna/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.13; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11"; OTHER_LDFLAGS = "-lxml2"; PRODUCT_BUNDLE_IDENTIFIER = com.tid.Kanna; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -520,17 +544,25 @@ buildSettings = { CODE_SIGN_IDENTITY = ""; COMBINE_HIDPI_IMAGES = YES; + DEAD_CODE_STRIPPING = YES; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; FRAMEWORK_VERSION = A; INFOPLIST_FILE = Sources/Kanna/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.13; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11"; OTHER_LDFLAGS = "-lxml2"; PRODUCT_BUNDLE_IDENTIFIER = com.tid.Kanna; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -548,9 +580,14 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ENABLE_MODULES = YES; COMBINE_HIDPI_IMAGES = YES; + DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = DP9Q5R8635; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.13; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; PRODUCT_BUNDLE_IDENTIFIER = com.tid.KannaTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -566,9 +603,14 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ENABLE_MODULES = YES; COMBINE_HIDPI_IMAGES = YES; + DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = DP9Q5R8635; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.13; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; PRODUCT_BUNDLE_IDENTIFIER = com.tid.KannaTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; diff --git a/Kanna.xcodeproj/xcshareddata/xcschemes/Kanna.xcscheme b/Kanna.xcodeproj/xcshareddata/xcschemes/Kanna.xcscheme index 56463f1..3515669 100644 --- a/Kanna.xcodeproj/xcshareddata/xcschemes/Kanna.xcscheme +++ b/Kanna.xcodeproj/xcshareddata/xcschemes/Kanna.xcscheme @@ -1,6 +1,6 @@ + + + + @@ -39,17 +48,6 @@ - - - - - - - - + + + + NSPrivacyCollectedDataTypes + + NSPrivacyAccessedAPITypes + + NSPrivacyTrackingDomains + + NSPrivacyTracking + + + diff --git a/Tests/KannaTests/Bundle+.swift b/Tests/KannaTests/Bundle+.swift new file mode 100644 index 0000000..51fca36 --- /dev/null +++ b/Tests/KannaTests/Bundle+.swift @@ -0,0 +1,19 @@ +// +// Bundle+.swift +// Tests +// +// Created by Atsushi Kiwaki on 2024/02/22. +// Copyright © 2024 Atsushi Kiwaki. All rights reserved. +// + +import Foundation + +extension Bundle { + static func testBundle(for aClass: AnyClass) -> Bundle { +#if SWIFT_PACKAGE + module +#else + Bundle(for: aClass) +#endif + } +} diff --git a/Tests/KannaTests/KannaHTMLTests.swift b/Tests/KannaTests/KannaHTMLTests.swift index efe5289..7905fc6 100755 --- a/Tests/KannaTests/KannaHTMLTests.swift +++ b/Tests/KannaTests/KannaHTMLTests.swift @@ -34,7 +34,8 @@ class KannaHTMLTests: XCTestCase { func testHTML4() { // This is an example of a functional test case. let filename = "test_HTML4" - guard let path = Bundle(for: KannaHTMLTests.self).path(forResource: filename, ofType: "html") else { + guard let path = Bundle.testBundle(for: KannaHTMLTests.self).path(forResource: filename, ofType: "html") else { + XCTFail() return } @@ -103,7 +104,8 @@ class KannaHTMLTests: XCTestCase { func testInnerHTML() { let filename = "test_HTML4" - guard let path = Bundle(for: KannaHTMLTests.self).path(forResource: filename, ofType: "html") else { + guard let path = Bundle.testBundle(for: KannaHTMLTests.self).path(forResource: filename, ofType: "html") else { + XCTFail() return } @@ -176,7 +178,8 @@ class KannaHTMLTests: XCTestCase { func testOutOfDocument() { let filename = "test_HTML4" - guard let path = Bundle(for: KannaHTMLTests.self).path(forResource: filename, ofType: "html") else { + guard let path = Bundle.testBundle(for: KannaHTMLTests.self).path(forResource: filename, ofType: "html") else { + XCTFail() return } diff --git a/Tests/KannaTests/KannaTutorialsTest.swift b/Tests/KannaTests/KannaTutorialsTest.swift index db5f119..da79052 100644 --- a/Tests/KannaTests/KannaTutorialsTest.swift +++ b/Tests/KannaTests/KannaTutorialsTest.swift @@ -25,7 +25,8 @@ class KannaTutorialsTests: XCTestCase { func testParsingFromFile() { let filename = "test_HTML4" - guard let filePath = Bundle(for: KannaTutorialsTests.self).path(forResource: filename, ofType: "html") else { + guard let filePath = Bundle.testBundle(for: KannaTutorialsTests.self).path(forResource: filename, ofType: "html") else { + XCTFail() return } if let data = try? Data(contentsOf: URL(fileURLWithPath: filePath)), @@ -76,7 +77,8 @@ class KannaTutorialsTests: XCTestCase { "iOS 8" ] let filename = "versions" - guard let filePath = Bundle(for: KannaTutorialsTests.self).path(forResource: filename, ofType: "xml") else { + guard let filePath = Bundle.testBundle(for: KannaTutorialsTests.self).path(forResource: filename, ofType: "xml") else { + XCTFail() return } if let xml = try? String(contentsOfFile: filePath, encoding: .utf8), @@ -112,8 +114,9 @@ class KannaTutorialsTests: XCTestCase { ] let filename = "libraries" - guard let filePath = Bundle(for: KannaTutorialsTests.self).path(forResource: filename, ofType: "xml"), + guard let filePath = Bundle.testBundle(for: KannaTutorialsTests.self).path(forResource: filename, ofType: "xml"), let xml = try? String(contentsOfFile: filePath, encoding: .utf8) else { + XCTFail() return } @@ -133,8 +136,9 @@ class KannaTutorialsTests: XCTestCase { func testModifyingChangingTextContents() { let TestModifyHTML = "\n

Snap, Crackle & Pop

\n
A love triangle.
\n" let filename = "sample" - guard let filePath = Bundle(for: KannaTutorialsTests.self).path(forResource: filename, ofType: "html"), + guard let filePath = Bundle.testBundle(for: KannaTutorialsTests.self).path(forResource: filename, ofType: "html"), let html = try? String(contentsOfFile: filePath, encoding: .utf8) else { + XCTFail() return } @@ -152,8 +156,9 @@ class KannaTutorialsTests: XCTestCase { let TestModifyHTML = "\n \n
A love triangle.

Three\'s Company

\n
\n" let TestModifyArrangeHTML = "\n \n
A love triangle.
\n

Three\'s Company

\n" let filename = "sample" - guard let filePath = Bundle(for: KannaTutorialsTests.self).path(forResource: filename, ofType: "html"), + guard let filePath = Bundle.testBundle(for: KannaTutorialsTests.self).path(forResource: filename, ofType: "html"), let html = try? String(contentsOfFile: filePath, encoding: .utf8) else { + XCTFail() return } @@ -175,8 +180,9 @@ class KannaTutorialsTests: XCTestCase { func testModifyingNodesAndAttributes() { let TestModifyHTML = "\n

Three\'s Company

\n
A love triangle.
\n" let filename = "sample" - guard let filePath = Bundle(for: KannaTutorialsTests.self).path(forResource: filename, ofType: "html"), + guard let filePath = Bundle.testBundle(for: KannaTutorialsTests.self).path(forResource: filename, ofType: "html"), let html = try? String(contentsOfFile: filePath, encoding: .utf8) else { + XCTFail() return } diff --git a/Tests/KannaTests/KannaXMLTests.swift b/Tests/KannaTests/KannaXMLTests.swift index ac001e3..e0299b4 100644 --- a/Tests/KannaTests/KannaXMLTests.swift +++ b/Tests/KannaTests/KannaXMLTests.swift @@ -30,7 +30,8 @@ import CoreFoundation class KannaXMLTests: XCTestCase { func testXml() { let filename = "test_XML_ExcelWorkbook" - guard let path = Bundle(for: KannaXMLTests.self).path(forResource: filename, ofType: "xml") else { + guard let path = Bundle.testBundle(for: KannaXMLTests.self).path(forResource: filename, ofType: "xml") else { + XCTFail() return } if let xml = try? Data(contentsOf: URL(fileURLWithPath: path)), @@ -53,8 +54,7 @@ class KannaXMLTests: XCTestCase { } for row in doc.xpath("//ss:Row", namespaces: namespaces) { - for cell in row.xpath("//ss:Data", namespaces: namespaces) { - print(cell.text!) + for _ in row.xpath("//ss:Data", namespaces: namespaces) { } } } else { @@ -74,7 +74,8 @@ class KannaXMLTests: XCTestCase { func testNamespaces() { let filename = "test_XML_ExcelWorkbook" - guard let path = Bundle(for: KannaXMLTests.self).path(forResource: filename, ofType: "xml") else { + guard let path = Bundle.testBundle(for: KannaXMLTests.self).path(forResource: filename, ofType: "xml") else { + XCTFail() return } if let xml = try? Data(contentsOf: URL(fileURLWithPath: path)), @@ -91,9 +92,11 @@ class KannaXMLTests: XCTestCase { func testNamespaces_multipleNamespaces() { // namespaces: "xmlns:a", "xmlns:r", "xmlns:p" - let url = Bundle(for: KannaXMLTests.self).url(forResource: "pptx-presentation", withExtension: "xml") - XCTAssertNotNil(url) - let doc = try? XML(url: url!, encoding: .utf8) + guard let url = Bundle.testBundle(for: KannaXMLTests.self).url(forResource: "pptx-presentation", withExtension: "xml") else { + XCTFail() + return + } + let doc = try? XML(url: url, encoding: .utf8) XCTAssertNotNil(doc) let nodes = Array(doc!.xpath("//p:sldId")) XCTAssert(nodes.count == 1) @@ -104,10 +107,11 @@ class KannaXMLTests: XCTestCase { } func testNamespaces_singleNamespace() { - // namespaces: "xmlns" - let url = Bundle(for: KannaXMLTests.self).url(forResource: "pptx-presentation", withExtension: "xml.rels") - XCTAssertNotNil(url) - let doc = try? XML(url: url!, encoding: .utf8) + guard let url = Bundle.testBundle(for: KannaXMLTests.self).url(forResource: "pptx-presentation", withExtension: "xml.rels") else { + XCTFail() + return + } + let doc = try? XML(url: url, encoding: .utf8) XCTAssertNotNil(doc) let nodes1 = Array(doc!.xpath("//Relationship")) XCTAssert(nodes1.count == 0)