From eb46122acb15f93495780e9900e4bdfc64323acc Mon Sep 17 00:00:00 2001 From: David Mohundro Date: Thu, 15 Aug 2024 14:47:41 -0500 Subject: [PATCH] feat: bump to Swift 6, add swift-testing I dropped old deprecation warnings as this is definitely a major version bump. For Swift 6 support, some of the types that were sent with errors are now wrapped in a "sendable" variety so that they're async safe. The GitHub builds also heavily use matrix support for multiple platform builds now, too. --- .github/workflows/lint.yml | 2 +- .github/workflows/main.yml | 125 ++++- .swiftlint.yml | 1 - CHANGELOG.md | 6 + Dockerfile | 2 +- Package.swift | 14 +- ...inuxMain.swift => Package@swift-5.10.swift | 47 +- ...swift-5.1.swift => Package@swift-5.8.swift | 14 +- ...swift-4.2.swift => Package@swift-5.9.swift | 16 +- SWXMLHash.xcodeproj/project.pbxproj | 191 +++++--- .../xcschemes/SWXMLHash OSX.xcscheme | 2 +- .../xcschemes/SWXMLHash iOS.xcscheme | 2 +- .../xcschemes/SWXMLHash tvOS.xcscheme | 2 +- .../xcschemes/SWXMLHash watchOS.xcscheme | 2 +- .../XMLIndexer+XMLDeserialization.swift | 2 +- .../Double+XMLDeserialization.swift | 2 +- .../Float+XMLDeserialization.swift | 2 +- .../Int+XMLDeserialization.swift | 2 +- Source/Errors/IndexingError.swift | 39 +- Source/Errors/XMLDeserializationError.swift | 31 +- Source/FullXMLParser.swift | 7 +- Source/LazyXMLParser.swift | 7 +- Source/XMLAttribute.swift | 2 +- Source/XMLElement.swift | 12 + Source/XMLIndexer.swift | 31 +- .../LazyTypesConversionTests.swift | 43 +- .../LazyWhiteSpaceParsingTests.swift | 34 +- .../SWXMLHashTests/LazyXMLParsingTests.swift | 117 +++-- .../MixedTextWithXMLElementsTests.swift | 20 +- ...versionArrayOfNonPrimitiveTypesTests.swift | 168 +++---- .../TypeConversionBasicTypesTests.swift | 435 ++++++------------ .../TypeConversionComplexTypesTests.swift | 71 ++- .../TypeConversionPrimitiveTypesTests.swift | 186 ++++---- .../WhiteSpaceParsingTests.swift | 35 +- Tests/SWXMLHashTests/XMLHashConfigTests.swift | 20 +- Tests/SWXMLHashTests/XMLParsingTests.swift | 238 +++++----- .../XMLParsingValidationTests.swift | 31 +- docker-compose.yml | 1 - 38 files changed, 908 insertions(+), 1054 deletions(-) rename Tests/LinuxMain.swift => Package@swift-5.10.swift (61%) rename Package@swift-5.1.swift => Package@swift-5.8.swift (85%) rename Package@swift-4.2.swift => Package@swift-5.9.swift (83%) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 84a214a8..29f69c82 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: SwiftLint uses: norio-nomura/action-swiftlint@3.2.1 with: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cd7dcf6a..b4d74a20 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,46 +5,139 @@ on: [push, pull_request] jobs: mac-test: name: Mac Test - runs-on: macOS-latest + runs-on: macos-latest + strategy: + matrix: + include: + - platform: macOS + scheme: "SWXMLHash OSX" + action: "build-for-testing test-without-building" + - platform: iOS + scheme: "SWXMLHash iOS" + action: "build-for-testing test-without-building" + sdk-and-dest: '-sdk iphonesimulator -destination "OS=17.2,name=iPhone 15"' + + - platform: tvOS + scheme: "SWXMLHash tvOS" + sdk-and-dest: '-sdk appletvsimulator -destination "name=Apple TV"' + + - platform: watchOS + scheme: "SWXMLHash watchOS" + action: "build-for-testing test-without-building" + sdk-and-dest: "-sdk watchsimulator" steps: - name: Checkout - uses: actions/checkout@master - - name: Build and test + uses: actions/checkout@v4 + + - uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: "16.0" + + - name: Build and Test env: WORKSPACE: "-workspace SWXMLHash.xcworkspace" - ACTION: "build-for-testing test-without-building" run: | - set -o pipefail - xcodebuild $ACTION $WORKSPACE -scheme "SWXMLHash OSX" | xcpretty - xcodebuild $ACTION $WORKSPACE -scheme "SWXMLHash iOS" -sdk iphonesimulator -destination "OS=17.2,name=iPhone 15" | xcpretty - xcodebuild $ACTION $WORKSPACE -scheme "SWXMLHash tvOS" -sdk appletvsimulator -destination "name=Apple TV" | xcpretty - xcodebuild build $WORKSPACE -scheme "SWXMLHash watchOS" -sdk watchsimulator | xcpretty - bash <(curl -s https://codecov.io/bash) -t ${{secrets.CODECOV_TOKEN}} + xcodebuild ${{ matrix.action }} $WORKSPACE -scheme ${{ matrix.scheme }} ${{ matrix.sdk-and-dest }} | xcpretty + + # TODO: I'd like to use this action instead of the above xcodebuild command, but I'm getting a destination error: + # xcodebuild: error: Unable to find a destination matching the provided destination specifier: + # { id:D918798E-6DEE-48F7-850A-A4C0D9328F0A } + # + # - uses: mxcl/xcodebuild@v3.0.0 + # with: + # platform: ${{ matrix.platform }} + # workspace: "SWXMLHash.xcworkspace" linux-test: name: Linux Test runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - image: swift:5.8-focal + skip-testing: true + + - image: swift:5.8-jammy + skip-testing: true + + - image: swift:5.8-rhel-ubi9 + skip-testing: true + + - image: swift:5.9-focal + skip-testing: true + + - image: swift:5.9-jammy + skip-testing: true + + - image: swift:5.9-rhel-ubi9 + skip-testing: true + - image: swift:5.10-focal + skip-testing: true + + - image: swift:5.10-jammy + skip-testing: true + + - image: swift:5.10-rhel-ubi9 + skip-testing: true + + - image: swift:6.0-focal + perform-testing: true + + - image: swift:6.0-jammy + perform-testing: true + + - image: swift:6.0-rhel-ubi9 + perform-testing: true + container: + image: ${{ matrix.image }} + timeout-minutes: 10 steps: - name: Checkout - uses: actions/checkout@master + uses: actions/checkout@v4 + - name: Build + if: ${{ matrix.skip-testing }} + run: | + swift build - name: Build and test + if: ${{ matrix.perform-testing }} run: | - eval "$(curl -sL https://gist.githubusercontent.com/kylef/5c0475ff02b7c7671d2a/raw/9f442512a46d7a2af7b850d65a7e9bd31edfb09b/swiftenv-install.sh)" + swift build --build-tests swift test windows-test: name: Windows Test runs-on: windows-latest + timeout-minutes: 10 + strategy: + fail-fast: false + matrix: + include: + - branch: swift-5.10-release + tag: 5.10-RELEASE + skip-testing: true + + - branch: swift-6.0-release + tag: 6.0-RELEASE + perform-testing: true steps: - name: Install Swift uses: compnerd/gha-setup-swift@main with: - branch: swift-5.8-release - tag: 5.8-RELEASE + branch: ${{ matrix.branch}} + tag: ${{ matrix.tag }} + - name: Checkout - uses: actions/checkout@master + uses: actions/checkout@v4 + - name: Build + if: ${{ matrix.skip-testing }} + run: | + swift build - name: Build and test - run: swift test + if: ${{ matrix.perform-testing }} + run: | + swift build --build-tests + swift test diff --git a/.swiftlint.yml b/.swiftlint.yml index ac387b2d..ab6d5540 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -3,7 +3,6 @@ included: - Tests - ./Package.swift opt_in_rules: - - anyobject_protocol - array_init - attributes - closure_end_indentation diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ae5c9fd..e91355e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v8.0.0 (September 17, 2024) + +- Added Swift 6.0 support (via [#283](https://github.com/drmohundro/SWXMLHash/pull/283)) + - The tests are now all using swift-testing + - Prior deprecations have been removed + ## v7.0.2 (May 9, 2023) - Added Windows support (via [#273](https://github.com/drmohundro/SWXMLHash/pull/273)) diff --git a/Dockerfile b/Dockerfile index d062e636..9aeeff9b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM swift:5.1 +FROM swiftlang/swift:nightly-6.0-focal ENV APP_HOME ./app RUN mkdir $APP_HOME diff --git a/Package.swift b/Package.swift index aa2f1aaf..0ddfd99a 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.3 +// swift-tools-version:6.0 // // Package.swift @@ -35,6 +35,9 @@ let package = Package( targets: ["SWXMLHash"] ) ], + dependencies: [ + .package(url: "https://github.com/apple/swift-testing.git", from: "0.10.0") + ], targets: [ .target( name: "SWXMLHash", @@ -43,11 +46,14 @@ let package = Package( ), .testTarget( name: "SWXMLHashTests", - dependencies: ["SWXMLHash"], + dependencies: [ + "SWXMLHash", + .product(name: "Testing", package: "swift-testing") + ], exclude: ["Info.plist", "test.xml"] ) ], - swiftLanguageVersions: [ - .v5 + swiftLanguageModes: [ + .v6 ] ) diff --git a/Tests/LinuxMain.swift b/Package@swift-5.10.swift similarity index 61% rename from Tests/LinuxMain.swift rename to Package@swift-5.10.swift index bd9ab170..60fa589a 100644 --- a/Tests/LinuxMain.swift +++ b/Package@swift-5.10.swift @@ -1,9 +1,10 @@ +// swift-tools-version:5.10 + // -// TypesConversionBasicTests.swift +// Package@swift-5.3.swift // SWXMLHash // -// Copyright (c) 2016 Norio Nomura - +// Copyright (c) 2024 David Mohundro // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -24,19 +25,29 @@ // THE SOFTWARE. // -@testable import SWXMLHashTests -import XCTest +import PackageDescription -XCTMain([ - testCase(LazyTypesConversionTests.allTests), - testCase(LazyWhiteSpaceParsingTests.allTests), - testCase(LazyXMLParsingTests.allTests), - testCase(MixedTextWithXMLElementsTests.allTests), - testCase(XMLHashConfigTests.allTests), - testCase(TypeConversionArrayOfNonPrimitiveTypesTests.allTests), - testCase(TypeConversionBasicTypesTests.allTests), - testCase(TypeConversionComplexTypesTests.allTests), - testCase(TypeConversionPrimitiveTypesTests.allTests), - testCase(WhiteSpaceParsingTests.allTests), - testCase(XMLParsingTests.allTests) -]) +let package = Package( + name: "SWXMLHash", + products: [ + .library( + name: "SWXMLHash", + targets: ["SWXMLHash"] + ) + ], + targets: [ + .target( + name: "SWXMLHash", + path: "Source", + exclude: ["Info.plist"] + ), + .testTarget( + name: "SWXMLHashTests", + dependencies: ["SWXMLHash"], + exclude: ["Info.plist", "test.xml"] + ) + ], + swiftLanguageVersions: [ + .v5 + ] +) diff --git a/Package@swift-5.1.swift b/Package@swift-5.8.swift similarity index 85% rename from Package@swift-5.1.swift rename to Package@swift-5.8.swift index ca20132c..f609733b 100644 --- a/Package@swift-5.1.swift +++ b/Package@swift-5.8.swift @@ -1,9 +1,10 @@ -// swift-tools-version:5.1 +// swift-tools-version:5.8 + // -// SWXMLHash.swift +// Package@swift-5.3.swift // SWXMLHash // -// Copyright (c) 2014 David Mohundro +// Copyright (c) 2024 David Mohundro // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -23,6 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // + import PackageDescription let package = Package( @@ -36,11 +38,13 @@ let package = Package( targets: [ .target( name: "SWXMLHash", - path: "Source" + path: "Source", + exclude: ["Info.plist"] ), .testTarget( name: "SWXMLHashTests", - dependencies: ["SWXMLHash"] + dependencies: ["SWXMLHash"], + exclude: ["Info.plist", "test.xml"] ) ], swiftLanguageVersions: [ diff --git a/Package@swift-4.2.swift b/Package@swift-5.9.swift similarity index 83% rename from Package@swift-4.2.swift rename to Package@swift-5.9.swift index be309a5f..494135be 100644 --- a/Package@swift-4.2.swift +++ b/Package@swift-5.9.swift @@ -1,10 +1,10 @@ -// swift-tools-version:4.2 +// swift-tools-version:5.9 // -// SWXMLHash.swift +// Package@swift-5.3.swift // SWXMLHash // -// Copyright (c) 2014 David Mohundro +// Copyright (c) 2024 David Mohundro // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -38,12 +38,16 @@ let package = Package( targets: [ .target( name: "SWXMLHash", - path: "Source" + path: "Source", + exclude: ["Info.plist"] ), .testTarget( name: "SWXMLHashTests", - dependencies: ["SWXMLHash"] + dependencies: ["SWXMLHash"], + exclude: ["Info.plist", "test.xml"] ) ], - swiftLanguageVersions: [.v3, .v4, .v4_2] + swiftLanguageVersions: [ + .v5 + ] ) diff --git a/SWXMLHash.xcodeproj/project.pbxproj b/SWXMLHash.xcodeproj/project.pbxproj index 6e4af1d8..84347780 100644 --- a/SWXMLHash.xcodeproj/project.pbxproj +++ b/SWXMLHash.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -244,7 +244,6 @@ 6C0CE0F01D7440F8005F1248 /* LinuxShims.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinuxShims.swift; sourceTree = ""; }; 6C42BECC2051834B00137D31 /* shim.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = shim.swift; sourceTree = ""; }; 6C42BED4205183AF00137D31 /* shim.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = shim.swift; sourceTree = ""; }; - 6C477A9C1D702C0900D76FCA /* LinuxMain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LinuxMain.swift; path = Tests/LinuxMain.swift; sourceTree = SOURCE_ROOT; }; CD4B5F3919E2C42D005C1F33 /* test.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = test.xml; sourceTree = ""; }; CD6083EF196CA106000B4F8D /* SWXMLHash.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SWXMLHash.framework; sourceTree = BUILT_PRODUCTS_DIR; }; CD6083F3196CA106000B4F8D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -431,7 +430,6 @@ CDC6D1321D32D7C300570DE5 /* LazyTypesConversionTests.swift */, CDC6D12A1D32D77F00570DE5 /* LazyWhiteSpaceParsingTests.swift */, CDC6D1261D32D76400570DE5 /* LazyXMLParsingTests.swift */, - 6C477A9C1D702C0900D76FCA /* LinuxMain.swift */, 6C0CE0F01D7440F8005F1248 /* LinuxShims.swift */, CDC6D1221D32D73900570DE5 /* MixedTextWithXMLElementsTests.swift */, CDC7F33C1B0ACC98006BF6E7 /* OSX */, @@ -647,8 +645,9 @@ CD6083E6196CA106000B4F8D /* Project object */ = { isa = PBXProject; attributes = { + BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 0710; - LastUpgradeCheck = 1240; + LastUpgradeCheck = 1610; TargetAttributes = { CD6083EE196CA106000B4F8D = { CreatedOnToolsVersion = 6.0; @@ -1010,6 +1009,7 @@ CURRENT_PROJECT_VERSION = 1; 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; @@ -1025,13 +1025,12 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -1074,6 +1073,7 @@ CURRENT_PROJECT_VERSION = 1; 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; @@ -1082,12 +1082,12 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -1107,15 +1107,21 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11"; PRODUCT_BUNDLE_IDENTIFIER = "drmohundro.$(PRODUCT_NAME:rfc1034identifier).${PLATFORM_NAME}"; PRODUCT_NAME = SWXMLHash; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; }; name = Debug; }; @@ -1131,15 +1137,22 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11"; PRODUCT_BUNDLE_IDENTIFIER = "drmohundro.$(PRODUCT_NAME:rfc1034identifier).${PLATFORM_NAME}"; PRODUCT_NAME = SWXMLHash; SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 6.0; }; name = Release; }; @@ -1147,6 +1160,7 @@ isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = NO; + DEVELOPMENT_TEAM = X7N53RP8YC; FRAMEWORK_SEARCH_PATHS = ( "$(PLATFORM_DIR)/Developer/Library/Frameworks", "$(inherited)", @@ -1156,10 +1170,15 @@ "$(inherited)", ); INFOPLIST_FILE = Tests/SWXMLHashTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 12.4; PRODUCT_BUNDLE_IDENTIFIER = "drmohundro.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; }; name = Debug; }; @@ -1167,16 +1186,23 @@ isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = NO; + DEVELOPMENT_TEAM = X7N53RP8YC; FRAMEWORK_SEARCH_PATHS = ( "$(PLATFORM_DIR)/Developer/Library/Frameworks", "$(inherited)", ); INFOPLIST_FILE = Tests/SWXMLHashTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 12.4; PRODUCT_BUNDLE_IDENTIFIER = "drmohundro.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 6.0; }; name = Release; }; @@ -1187,10 +1213,12 @@ BITCODE_GENERATION_MODE = marker; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COMBINE_HIDPI_IMAGES = YES; + DEAD_CODE_STRIPPING = YES; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; FRAMEWORK_VERSION = A; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -1198,14 +1226,19 @@ ); INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.10; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 11.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11"; PRODUCT_BUNDLE_IDENTIFIER = "drmohundro.$(PRODUCT_NAME:rfc1034identifier).${PLATFORM_NAME}"; PRODUCT_MODULE_NAME = SWXMLHash; PRODUCT_NAME = SWXMLHash; SDKROOT = macosx; SKIP_INSTALL = YES; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; }; name = Debug; }; @@ -1216,23 +1249,31 @@ BITCODE_GENERATION_MODE = bitcode; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COMBINE_HIDPI_IMAGES = YES; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; FRAMEWORK_VERSION = A; INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.10; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 11.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11"; PRODUCT_BUNDLE_IDENTIFIER = "drmohundro.$(PRODUCT_NAME:rfc1034identifier).${PLATFORM_NAME}"; PRODUCT_MODULE_NAME = SWXMLHash; PRODUCT_NAME = SWXMLHash; SDKROOT = macosx; SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 6.0; }; name = Release; }; @@ -1241,6 +1282,7 @@ buildSettings = { APPLICATION_EXTENSION_API_ONLY = NO; COMBINE_HIDPI_IMAGES = YES; + DEAD_CODE_STRIPPING = YES; FRAMEWORK_SEARCH_PATHS = ( "$(DEVELOPER_FRAMEWORKS_DIR)", "$(inherited)", @@ -1250,12 +1292,16 @@ "$(inherited)", ); INFOPLIST_FILE = Tests/SWXMLHashTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.10; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 11.0; PRODUCT_BUNDLE_IDENTIFIER = "drmohundro.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; }; name = Debug; }; @@ -1264,19 +1310,25 @@ buildSettings = { APPLICATION_EXTENSION_API_ONLY = NO; COMBINE_HIDPI_IMAGES = YES; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = ( "$(DEVELOPER_FRAMEWORKS_DIR)", "$(inherited)", ); INFOPLIST_FILE = Tests/SWXMLHashTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.10; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 11.0; PRODUCT_BUNDLE_IDENTIFIER = "drmohundro.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 6.0; }; name = Release; }; @@ -1284,21 +1336,27 @@ isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + CODE_SIGN_IDENTITY = ""; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11"; PRODUCT_BUNDLE_IDENTIFIER = "drmohundro.SWXMLHash.${PLATFORM_NAME}"; PRODUCT_NAME = SWXMLHash; SDKROOT = appletvos; SKIP_INSTALL = YES; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 12.0; }; @@ -1308,23 +1366,30 @@ isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + CODE_SIGN_IDENTITY = ""; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11"; PRODUCT_BUNDLE_IDENTIFIER = "drmohundro.SWXMLHash.${PLATFORM_NAME}"; PRODUCT_NAME = SWXMLHash; SDKROOT = appletvos; SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 12.0; }; @@ -1338,11 +1403,15 @@ FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = Tests/SWXMLHashTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = "drmohundro.SWXMLHash-tvOS-Tests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 12.0; }; @@ -1357,12 +1426,17 @@ FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = Tests/SWXMLHashTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = "drmohundro.SWXMLHash-tvOS-Tests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 12.0; }; @@ -1372,21 +1446,27 @@ isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CODE_SIGN_IDENTITY = ""; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11"; PRODUCT_BUNDLE_IDENTIFIER = "drmohundro.SWXMLHash.${PLATFORM_NAME}"; PRODUCT_NAME = SWXMLHash; SDKROOT = watchos; SKIP_INSTALL = YES; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 3.0; }; @@ -1396,23 +1476,30 @@ isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CODE_SIGN_IDENTITY = ""; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11"; PRODUCT_BUNDLE_IDENTIFIER = "drmohundro.SWXMLHash.${PLATFORM_NAME}"; PRODUCT_NAME = SWXMLHash; SDKROOT = watchos; SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 3.0; }; diff --git a/SWXMLHash.xcodeproj/xcshareddata/xcschemes/SWXMLHash OSX.xcscheme b/SWXMLHash.xcodeproj/xcshareddata/xcschemes/SWXMLHash OSX.xcscheme index 83395503..d00be9fb 100644 --- a/SWXMLHash.xcodeproj/xcshareddata/xcschemes/SWXMLHash OSX.xcscheme +++ b/SWXMLHash.xcodeproj/xcshareddata/xcschemes/SWXMLHash OSX.xcscheme @@ -1,6 +1,6 @@ Double { guard let value = Double(try element.nonEmptyTextOrThrow()) else { - throw XMLDeserializationError.typeConversionFailed(type: "Double", element: element) + throw XMLDeserializationError.typeConversionFailed(type: "Double", element: XMLElementSendable(element)) } return value } diff --git a/Source/DeserializationTypes/Float+XMLDeserialization.swift b/Source/DeserializationTypes/Float+XMLDeserialization.swift index f7c7e3aa..3660abbe 100644 --- a/Source/DeserializationTypes/Float+XMLDeserialization.swift +++ b/Source/DeserializationTypes/Float+XMLDeserialization.swift @@ -36,7 +36,7 @@ extension Float: XMLValueDeserialization { */ public static func deserialize(_ element: XMLElement) throws -> Float { guard let value = Float(try element.nonEmptyTextOrThrow()) else { - throw XMLDeserializationError.typeConversionFailed(type: "Float", element: element) + throw XMLDeserializationError.typeConversionFailed(type: "Float", element: XMLElementSendable(element)) } return value } diff --git a/Source/DeserializationTypes/Int+XMLDeserialization.swift b/Source/DeserializationTypes/Int+XMLDeserialization.swift index ce07c266..120b09cb 100644 --- a/Source/DeserializationTypes/Int+XMLDeserialization.swift +++ b/Source/DeserializationTypes/Int+XMLDeserialization.swift @@ -36,7 +36,7 @@ extension Int: XMLValueDeserialization { */ public static func deserialize(_ element: XMLElement) throws -> Int { guard let value = Int(try element.nonEmptyTextOrThrow()) else { - throw XMLDeserializationError.typeConversionFailed(type: "Int", element: element) + throw XMLDeserializationError.typeConversionFailed(type: "Int", element: XMLElementSendable(element)) } return value } diff --git a/Source/Errors/IndexingError.swift b/Source/Errors/IndexingError.swift index 044a5070..56410639 100644 --- a/Source/Errors/IndexingError.swift +++ b/Source/Errors/IndexingError.swift @@ -31,42 +31,9 @@ public enum IndexingError: Error { case attributeValue(attr: String, value: String) case key(key: String) case index(idx: Int) - case initialize(instance: AnyObject) + case initialize(description: String) case encoding case error - -// swiftlint:disable identifier_name - // unavailable - @available(*, unavailable, renamed: "attribute(attr:)") - public static func Attribute(attr: String) -> IndexingError { - fatalError("unavailable") - } - - @available(*, unavailable, renamed: "attributeValue(attr:value:)") - public static func AttributeValue(attr: String, value: String) -> IndexingError { - fatalError("unavailable") - } - - @available(*, unavailable, renamed: "key(key:)") - public static func Key(key: String) -> IndexingError { - fatalError("unavailable") - } - - @available(*, unavailable, renamed: "index(idx:)") - public static func Index(idx: Int) -> IndexingError { - fatalError("unavailable") - } - - @available(*, unavailable, renamed: "initialize(instance:)") - public static func Init(instance: AnyObject) -> IndexingError { - fatalError("unavailable") - } - - @available(*, unavailable, renamed: "error") - public static var Error: IndexingError { - fatalError("unavailable") - } -// swiftlint:enable identifier_name } extension IndexingError: CustomStringConvertible { @@ -81,8 +48,8 @@ extension IndexingError: CustomStringConvertible { return "XML Element Error: Incorrect key [\"\(key)\"]" case .index(let index): return "XML Element Error: Incorrect index [\"\(index)\"]" - case .initialize(let instance): - return "XML Indexer Error: initialization with Object [\"\(instance)\"]" + case .initialize(let description): + return "XML Indexer Error: initialization with Object [\"\(description)\"]" case .encoding: return "String Encoding Error" case .error: diff --git a/Source/Errors/XMLDeserializationError.swift b/Source/Errors/XMLDeserializationError.swift index 600ff145..40fb26d6 100644 --- a/Source/Errors/XMLDeserializationError.swift +++ b/Source/Errors/XMLDeserializationError.swift @@ -23,8 +23,6 @@ // THE SOFTWARE. // -// swiftlint:disable line_length - import Foundation /// The error that is thrown if there is a problem with deserialization @@ -32,32 +30,9 @@ public enum XMLDeserializationError: Error { case implementationIsMissing(method: String) case nodeIsInvalid(node: String) case nodeHasNoValue - case typeConversionFailed(type: String, element: XMLElement) - case attributeDoesNotExist(element: XMLElement, attribute: String) + case typeConversionFailed(type: String, element: XMLElementSendable) + case attributeDoesNotExist(element: XMLElementSendable, attribute: String) case attributeDeserializationFailed(type: String, attribute: XMLAttribute) - - // swiftlint:disable identifier_name - @available(*, unavailable, renamed: "implementationIsMissing(method:)") - public static func ImplementationIsMissing(method: String) -> XMLDeserializationError { - fatalError("unavailable") - } - @available(*, unavailable, renamed: "nodeHasNoValue(_:)") - public static func NodeHasNoValue(_: IndexOps) -> XMLDeserializationError { - fatalError("unavailable") - } - @available(*, unavailable, renamed: "typeConversionFailed(_:)") - public static func TypeConversionFailed(_: IndexingError) -> XMLDeserializationError { - fatalError("unavailable") - } - @available(*, unavailable, renamed: "attributeDoesNotExist(_:_:)") - public static func AttributeDoesNotExist(_ attr: String, _ value: String) throws -> XMLDeserializationError { - fatalError("unavailable") - } - @available(*, unavailable, renamed: "attributeDeserializationFailed(_:_:)") - public static func AttributeDeserializationFailed(_ attr: String, _ value: String) throws -> XMLDeserializationError { - fatalError("unavailable") - } - // swiftlint:enable identifier_name } /// Implementation for CustomStringConvertible @@ -101,5 +76,3 @@ extension XMLDeserializationError: LocalizedError { } } } - -// swiftlint:enable line_length diff --git a/Source/FullXMLParser.swift b/Source/FullXMLParser.swift index 6dda44b9..ed91ce4a 100644 --- a/Source/FullXMLParser.swift +++ b/Source/FullXMLParser.swift @@ -87,10 +87,11 @@ class FullXMLParser: NSObject, SimpleXmlParser, XMLParserDelegate { } func parser(_ parser: XMLParser, foundCDATA CDATABlock: Data) { - let cdataText = String(decoding: CDATABlock, as: UTF8.self) - let current = parentStack.top() + if let cdataText = String(data: CDATABlock, encoding: String.Encoding.utf8) { + let current = parentStack.top() - current.addText(cdataText) + current.addText(cdataText) + } } func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) { diff --git a/Source/LazyXMLParser.swift b/Source/LazyXMLParser.swift index bbc993b5..dd9d2ffd 100644 --- a/Source/LazyXMLParser.swift +++ b/Source/LazyXMLParser.swift @@ -95,10 +95,11 @@ class LazyXMLParser: NSObject, SimpleXmlParser, XMLParserDelegate { return } - let cdataText = String(decoding: CDATABlock, as: UTF8.self) - let current = parentStack.top() + if let cdataText = String(data: CDATABlock, encoding: String.Encoding.utf8) { + let current = parentStack.top() - current.addText(cdataText) + current.addText(cdataText) + } } func parser(_ parser: XMLParser, diff --git a/Source/XMLAttribute.swift b/Source/XMLAttribute.swift index 2b58b398..daee8d15 100644 --- a/Source/XMLAttribute.swift +++ b/Source/XMLAttribute.swift @@ -25,7 +25,7 @@ import Foundation -public struct XMLAttribute { +public struct XMLAttribute: Sendable { public let name: String public let text: String } diff --git a/Source/XMLElement.swift b/Source/XMLElement.swift index 1017eaf5..202c14d9 100644 --- a/Source/XMLElement.swift +++ b/Source/XMLElement.swift @@ -176,4 +176,16 @@ extension XMLHash { public typealias XMLElement = XMLHashXMLElement } +public struct XMLElementSendable: Sendable, CustomStringConvertible { + var elemDescription: String + + init(_ elem: XMLElement) { + self.elemDescription = elem.description + } + + public var description: String { + elemDescription + } +} + public typealias XMLHashXMLElement = XMLElement diff --git a/Source/XMLIndexer.swift b/Source/XMLIndexer.swift index d977ec69..3ebe0e87 100644 --- a/Source/XMLIndexer.swift +++ b/Source/XMLIndexer.swift @@ -33,30 +33,6 @@ public enum XMLIndexer { case xmlError(IndexingError) case parsingError(ParsingError) -// swiftlint:disable identifier_name - // unavailable - @available(*, unavailable, renamed: "element(_:)") - public static func Element(_: XMLElement) -> XMLIndexer { - fatalError("unavailable") - } - @available(*, unavailable, renamed: "list(_:)") - public static func List(_: [XMLElement]) -> XMLIndexer { - fatalError("unavailable") - } - @available(*, unavailable, renamed: "stream(_:)") - public static func Stream(_: IndexOps) -> XMLIndexer { - fatalError("unavailable") - } - @available(*, unavailable, renamed: "xmlError(_:)") - public static func XMLError(_: IndexingError) -> XMLIndexer { - fatalError("unavailable") - } - @available(*, unavailable, renamed: "withAttribute(_:_:)") - public static func withAttr(_ attr: String, _ value: String) throws -> XMLIndexer { - fatalError("unavailable") - } -// swiftlint:enable identifier_name - /// The underlying XMLElement at the currently indexed level of XML. public var element: XMLElement? { switch self { @@ -104,11 +80,6 @@ public enum XMLIndexer { return list } - @available(*, unavailable, renamed: "filterChildren(_:)") - public func filter(_ included: (_ elem: XMLElement, _ index: Int) -> Bool) -> XMLIndexer { - filterChildren(included) - } - public func filterChildren(_ included: (_ elem: XMLElement, _ index: Int) -> Bool) -> XMLIndexer { let children = handleFilteredResults(list: childElements, included: included) if let current = element { @@ -185,7 +156,7 @@ public enum XMLIndexer { case let value as LazyXMLParser: self = .stream(IndexOps(parser: value)) default: - throw IndexingError.initialize(instance: rawObject) + throw IndexingError.initialize(description: "\(rawObject)") } } diff --git a/Tests/SWXMLHashTests/LazyTypesConversionTests.swift b/Tests/SWXMLHashTests/LazyTypesConversionTests.swift index eddf00ab..80b96244 100644 --- a/Tests/SWXMLHashTests/LazyTypesConversionTests.swift +++ b/Tests/SWXMLHashTests/LazyTypesConversionTests.swift @@ -24,9 +24,10 @@ // import SWXMLHash -import XCTest +import Testing -class LazyTypesConversionTests: XCTestCase { +@Suite("LazyTypesConversionTests") +struct LazyTypesConversionTests { var parser: XMLIndexer? let xmlWithBasicTypes = """ @@ -45,50 +46,42 @@ class LazyTypesConversionTests: XCTestCase { """ - override func setUp() { - super.setUp() + init() { parser = XMLHash.config { cfg in cfg.shouldProcessLazily = true }.parse(xmlWithBasicTypes) } - func testShouldConvertValueToNonOptional() { + @Test + func shouldConvertValueToNonOptional() { do { let value: String = try parser!["root"]["string"].value() - XCTAssertEqual(value, "the string value") + #expect(value == "the string value") } catch { - XCTFail("\(error)") + Issue.record(error) } } - func testShouldConvertAttributeToNonOptional() { + @Test + func shouldConvertAttributeToNonOptional() { do { let value: Int = try parser!["root"]["attribute"].value(ofAttribute: "int") - XCTAssertEqual(value, 1) + #expect(value == 1) } catch { - XCTFail("\(error)") + Issue.record(error) } } - func testShouldBeAbleToGetUserInfoDuringDeserialization() { - parser = XMLHash.config { config in + @Test + func shouldBeAbleToGetUserInfoDuringDeserialization() { + let parser = XMLHash.config { config in let options = SampleUserInfo(apiVersion: .v1) config.userInfo = [ SampleUserInfo.key: options ] }.parse(xmlWithBasicTypes) do { - let value: BasicItem = try parser!["root"]["basicItem"].value() - XCTAssertEqual(value.name, "the name of basic item (v1)") + let value: BasicItem = try parser["root"]["basicItem"].value() + #expect(value.name == "the name of basic item (v1)") } catch { - XCTFail("\(error)") + Issue.record(error) } } } - -extension LazyTypesConversionTests { - static var allTests: [(String, (LazyTypesConversionTests) -> () throws -> Void)] { - [ - ("testShouldConvertValueToNonOptional", testShouldConvertValueToNonOptional), - ("testShouldConvertAttributeToNonOptional", testShouldConvertAttributeToNonOptional), - ("testShouldBeAbleToGetUserInfoDuringDeserialization", testShouldBeAbleToGetUserInfoDuringDeserialization) - ] - } -} diff --git a/Tests/SWXMLHashTests/LazyWhiteSpaceParsingTests.swift b/Tests/SWXMLHashTests/LazyWhiteSpaceParsingTests.swift index b430d066..4a578ef0 100644 --- a/Tests/SWXMLHashTests/LazyWhiteSpaceParsingTests.swift +++ b/Tests/SWXMLHashTests/LazyWhiteSpaceParsingTests.swift @@ -25,44 +25,30 @@ import Foundation import SWXMLHash -import XCTest +import Testing // swiftlint:disable line_length -class LazyWhiteSpaceParsingTests: XCTestCase { +struct LazyWhiteSpaceParsingTests { var xml: XMLIndexer? - override func setUp() { - super.setUp() - // Put setup code here. This method is called before the invocation of each test method in the class. + init() { + let path = URL(fileURLWithPath: #filePath).deletingLastPathComponent().appendingPathComponent("test.xml").path -#if SWIFT_PACKAGE - let path = URL(fileURLWithPath: #file).deletingLastPathComponent().appendingPathComponent("test.xml").path -#else - let bundle = Bundle(for: WhiteSpaceParsingTests.self) - let path = bundle.path(forResource: "test", ofType: "xml")! -#endif // swiftlint:disable:next force_try let data = try! Data(contentsOf: URL(fileURLWithPath: path)) xml = XMLHash.lazy(data) } // issue #6 - func testShouldBeAbleToPullTextBetweenElementsWithoutWhitespace() { - XCTAssertEqual(xml!["niotemplate"]["section"][0]["constraint"][1].element?.text, "H:|-15-[title]-15-|") + @Test + func shouldBeAbleToPullTextBetweenElementsWithoutWhitespace() { + #expect(xml!["niotemplate"]["section"][0]["constraint"][1].element?.text == "H:|-15-[title]-15-|") } - func testShouldBeAbleToCorrectlyParseCDATASectionsWithWhitespace() { - XCTAssertEqual(xml!["niotemplate"]["other"].element?.text, "\n \n this\n has\n white\n space\n \n ") - } -} - -extension LazyWhiteSpaceParsingTests { - static var allTests: [(String, (LazyWhiteSpaceParsingTests) -> () throws -> Void)] { - [ - ("testShouldBeAbleToPullTextBetweenElementsWithoutWhitespace", testShouldBeAbleToPullTextBetweenElementsWithoutWhitespace), - ("testShouldBeAbleToCorrectlyParseCDATASectionsWithWhitespace", testShouldBeAbleToCorrectlyParseCDATASectionsWithWhitespace) - ] + @Test + func shouldBeAbleToCorrectlyParseCDATASectionsWithWhitespace() { + #expect(xml!["niotemplate"]["other"].element?.text == "\n \n this\n has\n white\n space\n \n ") } } diff --git a/Tests/SWXMLHashTests/LazyXMLParsingTests.swift b/Tests/SWXMLHashTests/LazyXMLParsingTests.swift index 162b0cc3..a4fd1a6b 100644 --- a/Tests/SWXMLHashTests/LazyXMLParsingTests.swift +++ b/Tests/SWXMLHashTests/LazyXMLParsingTests.swift @@ -24,11 +24,11 @@ // import SWXMLHash -import XCTest +import Testing // swiftlint:disable line_length -class LazyXMLParsingTests: XCTestCase { +struct LazyXMLParsingTests { let xmlToParse = """
header mixed contentTest Title Headermore mixed content
@@ -62,120 +62,113 @@ class LazyXMLParsingTests: XCTestCase { var xml: XMLIndexer? - override func setUp() { - super.setUp() + init() { xml = XMLHash.config { config in config.shouldProcessLazily = true }.parse(xmlToParse) } - func testShouldBeAbleToParseIndividualElements() { - XCTAssertEqual(xml!["root"]["header"]["title"].element?.text, "Test Title Header") + @Test + func shouldBeAbleToParseIndividualElements() { + #expect(xml!["root"]["header"]["title"].element?.text == "Test Title Header") } - func testShouldBeAbleToHandleSubsequentParseCalls() { - XCTAssertEqual(xml!["root"]["header"]["title"].element?.text, "Test Title Header") - XCTAssertEqual(xml!["root"]["catalog"]["book"][1]["author"].element?.text, "Ralls, Kim") + @Test + func shouldBeAbleToHandleSubsequentParseCalls() { + #expect(xml!["root"]["header"]["title"].element?.text == "Test Title Header") + #expect(xml!["root"]["catalog"]["book"][1]["author"].element?.text == "Ralls, Kim") } - func testShouldBeAbleToParseElementGroups() { - XCTAssertEqual(xml!["root"]["catalog"]["book"][1]["author"].element?.text, "Ralls, Kim") + @Test + func shouldBeAbleToParseElementGroups() { + #expect(xml!["root"]["catalog"]["book"][1]["author"].element?.text == "Ralls, Kim") } - func testShouldBeAbleToParseAttributes() { - XCTAssertEqual(xml!["root"]["catalog"]["book"][1].element?.attribute(by: "id")?.text, "bk102") + @Test + func shouldBeAbleToParseAttributes() { + #expect(xml!["root"]["catalog"]["book"][1].element?.attribute(by: "id")?.text == "bk102") } - func testShouldBeAbleToLookUpElementsByNameAndAttribute() { + @Test + func shouldBeAbleToLookUpElementsByNameAndAttribute() { do { let value = try xml!["root"]["catalog"]["book"].withAttribute("id", "bk102")["author"].element?.text - XCTAssertEqual(value, "Ralls, Kim") + #expect(value == "Ralls, Kim") } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldBeAbleToIterateElementGroups() { + @Test + func shouldBeAbleToIterateElementGroups() { let result = xml!["root"]["catalog"]["book"].all.map({ $0["genre"].element!.text }).joined(separator: ", ") - XCTAssertEqual(result, "Computer, Fantasy, Fantasy") + #expect(result == "Computer, Fantasy, Fantasy") } - func testShouldBeAbleToIterateElementGroupsEvenIfOnlyOneElementIsFound() { - XCTAssertEqual(xml!["root"]["header"]["title"].all.count, 1) + @Test + func shouldBeAbleToIterateElementGroupsEvenIfOnlyOneElementIsFound() { + #expect(xml!["root"]["header"]["title"].all.count == 1) } - func testShouldBeAbleToIndexElementGroupsEvenIfOnlyOneElementIsFound() { - XCTAssertEqual(xml!["root"]["header"]["title"][0].element?.text, "Test Title Header") + @Test + func shouldBeAbleToIndexElementGroupsEvenIfOnlyOneElementIsFound() { + #expect(xml!["root"]["header"]["title"][0].element?.text == "Test Title Header") } - func testShouldBeAbleToIterateUsingForIn() { + @Test + func shouldBeAbleToIterateUsingForIn() { var count = 0 for _ in xml!["root"]["catalog"]["book"].all { count += 1 } - XCTAssertEqual(count, 3) + #expect(count == 3) } - func testShouldBeAbleToEnumerateChildren() { + @Test + func shouldBeAbleToEnumerateChildren() { let result = xml!["root"]["catalog"]["book"][0].children.map({ $0.element!.name }).joined(separator: ", ") - XCTAssertEqual(result, "author, title, genre, price, publish_date, description") + #expect(result == "author, title, genre, price, publish_date, description") } - func testShouldBeAbleToHandleMixedContent() { - XCTAssertEqual(xml!["root"]["header"].element?.text, "header mixed contentmore mixed content") + @Test + func shouldBeAbleToHandleMixedContent() { + #expect(xml!["root"]["header"].element?.text == "header mixed contentmore mixed content") } - func testShouldHandleInterleavingXMLElements() { + @Test + func shouldHandleInterleavingXMLElements() { let interleavedXml = "

one

two

three

four
" let parsed = XMLHash.parse(interleavedXml) let result = parsed["html"]["body"].children.map({ $0.element!.text }).joined(separator: ", ") - XCTAssertEqual(result, "one, two, three, four") + #expect(result == "one, two, three, four") } - func testShouldBeAbleToProvideADescriptionForTheDocument() { + @Test + func shouldBeAbleToProvideADescriptionForTheDocument() { let descriptionXml = "puppies" let parsed = XMLHash.parse(descriptionXml) - XCTAssertEqual(parsed.description, "puppies") + #expect(parsed.description == "puppies") } - func testShouldReturnNilWhenKeysDontMatch() { - XCTAssertNil(xml!["root"]["what"]["header"]["foo"].element?.name) + @Test + func shouldReturnNilWhenKeysDontMatch() { + #expect(xml!["root"]["what"]["header"]["foo"].element?.name == nil) } - func testShouldBeAbleToFilterOnIndexer() { + @Test + func shouldBeAbleToFilterOnIndexer() { let subIndexer = xml!["root"]["catalog"]["book"] .filterAll { elem, _ in elem.attribute(by: "id")!.text == "bk102" } .filterChildren { _, index in index >= 1 && index <= 3 } - XCTAssertEqual(subIndexer.children[0].element?.name, "title") - XCTAssertEqual(subIndexer.children[1].element?.name, "genre") - XCTAssertEqual(subIndexer.children[2].element?.name, "price") + #expect(subIndexer.children[0].element?.name == "title") + #expect(subIndexer.children[1].element?.name == "genre") + #expect(subIndexer.children[2].element?.name == "price") - XCTAssertEqual(subIndexer.children[0].element?.text, "Midnight Rain") - XCTAssertEqual(subIndexer.children[1].element?.text, "Fantasy") - XCTAssertEqual(subIndexer.children[2].element?.text, "5.95") - } -} - -extension LazyXMLParsingTests { - static var allTests: [(String, (LazyXMLParsingTests) -> () throws -> Void)] { - [ - ("testShouldBeAbleToParseIndividualElements", testShouldBeAbleToParseIndividualElements), - ("testShouldBeAbleToParseElementGroups", testShouldBeAbleToParseElementGroups), - ("testShouldBeAbleToParseAttributes", testShouldBeAbleToParseAttributes), - ("testShouldBeAbleToLookUpElementsByNameAndAttribute", testShouldBeAbleToLookUpElementsByNameAndAttribute), - ("testShouldBeAbleToIterateElementGroups", testShouldBeAbleToIterateElementGroups), - ("testShouldBeAbleToIterateElementGroupsEvenIfOnlyOneElementIsFound", testShouldBeAbleToIterateElementGroupsEvenIfOnlyOneElementIsFound), - ("testShouldBeAbleToIndexElementGroupsEvenIfOnlyOneElementIsFound", testShouldBeAbleToIndexElementGroupsEvenIfOnlyOneElementIsFound), - ("testShouldBeAbleToIterateUsingForIn", testShouldBeAbleToIterateUsingForIn), - ("testShouldBeAbleToEnumerateChildren", testShouldBeAbleToEnumerateChildren), - ("testShouldBeAbleToHandleMixedContent", testShouldBeAbleToHandleMixedContent), - ("testShouldHandleInterleavingXMLElements", testShouldHandleInterleavingXMLElements), - ("testShouldBeAbleToProvideADescriptionForTheDocument", testShouldBeAbleToProvideADescriptionForTheDocument), - ("testShouldReturnNilWhenKeysDontMatch", testShouldReturnNilWhenKeysDontMatch), - ("testShouldBeAbleToFilterOnIndexer", testShouldBeAbleToFilterOnIndexer) - ] + #expect(subIndexer.children[0].element?.text == "Midnight Rain") + #expect(subIndexer.children[1].element?.text == "Fantasy") + #expect(subIndexer.children[2].element?.text == "5.95") } } diff --git a/Tests/SWXMLHashTests/MixedTextWithXMLElementsTests.swift b/Tests/SWXMLHashTests/MixedTextWithXMLElementsTests.swift index c7ee3721..d1d465d7 100644 --- a/Tests/SWXMLHashTests/MixedTextWithXMLElementsTests.swift +++ b/Tests/SWXMLHashTests/MixedTextWithXMLElementsTests.swift @@ -24,29 +24,21 @@ // import SWXMLHash -import XCTest +import Testing // swiftlint:disable line_length -class MixedTextWithXMLElementsTests: XCTestCase { +struct MixedTextWithXMLElementsTests { var xml: XMLIndexer? - override func setUp() { - super.setUp() + init() { let xmlContent = "Here is a cool thing A and second cool thing B" xml = XMLHash.parse(xmlContent) } - func testShouldBeAbleToGetAllContentsInsideOfAnElement() { - XCTAssertEqual(xml!["everything"]["news"]["content"].description, "Here is a cool thing A and second cool thing B") - } -} - -extension MixedTextWithXMLElementsTests { - static var allTests: [(String, (MixedTextWithXMLElementsTests) -> () throws -> Void)] { - [ - ("testShouldBeAbleToGetAllContentsInsideOfAnElement", testShouldBeAbleToGetAllContentsInsideOfAnElement) - ] + @Test + func shouldBeAbleToGetAllContentsInsideOfAnElement() { + #expect(xml!["everything"]["news"]["content"].description == "Here is a cool thing A and second cool thing B") } } diff --git a/Tests/SWXMLHashTests/TypeConversionArrayOfNonPrimitiveTypesTests.swift b/Tests/SWXMLHashTests/TypeConversionArrayOfNonPrimitiveTypesTests.swift index d5f96e5c..a59744f1 100644 --- a/Tests/SWXMLHashTests/TypeConversionArrayOfNonPrimitiveTypesTests.swift +++ b/Tests/SWXMLHashTests/TypeConversionArrayOfNonPrimitiveTypesTests.swift @@ -24,12 +24,12 @@ // import SWXMLHash -import XCTest +import Testing // swiftlint:disable line_length // swiftlint:disable type_name -class TypeConversionArrayOfNonPrimitiveTypesTests: XCTestCase { +struct TypeConversionArrayOfNonPrimitiveTypesTests { var parser: XMLIndexer? let xmlWithArraysOfTypes = """ @@ -86,131 +86,125 @@ class TypeConversionArrayOfNonPrimitiveTypesTests: XCTestCase { AttributeItem(name: "attr 3", price: 3.3) ] - override func setUp() { - super.setUp() + init() { parser = XMLHash.parse(xmlWithArraysOfTypes) } - func testShouldConvertArrayOfGoodBasicItemsToNonOptional() { + @Test + func shouldConvertArrayOfGoodBasicItemsToNonOptional() { do { let value: [BasicItem] = try parser!["root"]["arrayOfGoodBasicItems"]["basicItem"].value() - XCTAssertEqual(value, correctBasicItems) + #expect(value == correctBasicItems) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertArrayOfGoodBasicItemsToOptional() { + @Test + func shouldConvertArrayOfGoodBasicItemsToOptional() { do { let value: [BasicItem]? = try parser!["root"]["arrayOfGoodBasicItems"]["basicItem"].value() - XCTAssertNotNil(value) + #expect(value != nil) if let value = value { - XCTAssertEqual(value, correctBasicItems) + #expect(value == correctBasicItems) } } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertArrayOfGoodBasicItemsToArrayOfOptionals() { + @Test + func shouldConvertArrayOfGoodBasicItemsToArrayOfOptionals() { do { let value: [BasicItem?] = try parser!["root"]["arrayOfGoodBasicItems"]["basicItem"].value() - XCTAssertEqual(value.compactMap({ $0 }), correctBasicItems) + #expect(value.compactMap({ $0 }) == correctBasicItems) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldThrowWhenConvertingArrayOfBadBasicItemsToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["arrayOfBadBasicItems"]["basicItem"].value() as [BasicItem])) { error in - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + @Test + func shouldThrowWhenConvertingArrayOfBadBasicItemsToNonOptional() { + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["arrayOfBadBasicItems"]["basicItem"].value() as [BasicItem]) } } - func testShouldThrowWhenConvertingArrayOfBadBasicItemsToOptional() { - XCTAssertThrowsError(try (parser!["root"]["arrayOfBadBasicItems"]["basicItem"].value() as [BasicItem]?)) { error in - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + @Test + func shouldThrowWhenConvertingArrayOfBadBasicItemsToOptional() { + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["arrayOfBadBasicItems"]["basicItem"].value() as [BasicItem]?) } } - func testShouldThrowWhenConvertingArrayOfBadBasicItemsToArrayOfOptionals() { - XCTAssertThrowsError(try (parser!["root"]["arrayOfBadBasicItems"]["basicItem"].value() as [BasicItem?])) { error in - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + @Test + func shouldThrowWhenConvertingArrayOfBadBasicItemsToArrayOfOptionals() { + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["arrayOfBadBasicItems"]["basicItem"].value() as [BasicItem?]) } } - func testShouldConvertArrayOfEmptyMissingToOptional() { + @Test + func shouldConvertArrayOfEmptyMissingToOptional() { do { let value: [BasicItem]? = try parser!["root"]["arrayOfMissingBasicItems"]["basicItem"].value() - XCTAssertNil(value) + #expect(value == nil) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertArrayOfGoodAttributeItemsToNonOptional() { + @Test + func shouldConvertArrayOfGoodAttributeItemsToNonOptional() { do { let value: [AttributeItem] = try parser!["root"]["arrayOfGoodAttributeItems"]["attributeItem"].value() - XCTAssertEqual(value, correctAttributeItems) + #expect(value == correctAttributeItems) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertArrayOfGoodAttributeItemsToOptional() { + @Test + func shouldConvertArrayOfGoodAttributeItemsToOptional() { do { let value: [AttributeItem]? = try parser!["root"]["arrayOfGoodAttributeItems"]["attributeItem"].value() - XCTAssertNotNil(value) + #expect(value != nil) if let value = value { - XCTAssertEqual(value, correctAttributeItems) + #expect(value == correctAttributeItems) } } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertArrayOfGoodAttributeItemsToArrayOfOptionals() { + @Test + func shouldConvertArrayOfGoodAttributeItemsToArrayOfOptionals() { do { let value: [AttributeItem?] = try parser!["root"]["arrayOfGoodAttributeItems"]["attributeItem"].value() - XCTAssertEqual(value.compactMap({ $0 }), correctAttributeItems) + #expect(value.compactMap({ $0 }) == correctAttributeItems) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldThrowWhenConvertingArrayOfBadAttributeItemsToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["arrayOfBadAttributeItems"]["attributeItem"].value() as [AttributeItem])) { error in - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + @Test + func shouldThrowWhenConvertingArrayOfBadAttributeItemsToNonOptional() { + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["arrayOfBadAttributeItems"]["attributeItem"].value() as [AttributeItem]) } } - func testShouldThrowWhenConvertingArrayOfBadAttributeItemsToOptional() { - XCTAssertThrowsError(try (parser!["root"]["arrayOfBadAttributeItems"]["attributeItem"].value() as [AttributeItem]?)) { error in - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + @Test + func shouldThrowWhenConvertingArrayOfBadAttributeItemsToOptional() { + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["arrayOfBadAttributeItems"]["attributeItem"].value() as [AttributeItem]?) } } - func testShouldThrowWhenConvertingArrayOfBadAttributeItemsToArrayOfOptionals() { - XCTAssertThrowsError(try (parser!["root"]["arrayOfBadAttributeItems"]["attributeItem"].value() as [AttributeItem?])) { error in - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + @Test + func shouldThrowWhenConvertingArrayOfBadAttributeItemsToArrayOfOptionals() { + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["arrayOfBadAttributeItems"]["attributeItem"].value() as [AttributeItem?]) } } @@ -220,13 +214,13 @@ class TypeConversionArrayOfNonPrimitiveTypesTests: XCTestCase { let values: [AttributeItem] = try subParser.value() - XCTAssertNotNil(values) - XCTAssertEqual(values[0].name, "attr 2") - XCTAssertEqual(values[0].price, 2.2) - XCTAssertEqual(values[1].name, "attr 3") - XCTAssertEqual(values[1].price, 3.3) + #expect(values != nil) + #expect(values[0].name == "attr 2") + #expect(values[0].price == 2.2) + #expect(values[1].name == "attr 3") + #expect(values[1].price == 3.3) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } @@ -236,11 +230,10 @@ class TypeConversionArrayOfNonPrimitiveTypesTests: XCTestCase { let value: BasicItem = try subParser.value() - XCTAssertNotNil(value) - XCTAssertEqual(value.id, "1234a") - XCTAssertEqual(value.id, "1234a") + #expect(value != nil) + #expect(value.id == "1234a") } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } @@ -250,35 +243,14 @@ class TypeConversionArrayOfNonPrimitiveTypesTests: XCTestCase { let values: [BasicItem] = try subParser.value() - XCTAssertNotNil(values) - XCTAssertEqual(values[0].id, "1234b") - XCTAssertEqual(values[1].id, "1234c") + #expect(values != nil) + #expect(values[0].id == "1234b") + #expect(values[1].id == "1234c") } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } } -extension TypeConversionArrayOfNonPrimitiveTypesTests { - static var allTests: [(String, (TypeConversionArrayOfNonPrimitiveTypesTests) -> () throws -> Void)] { - [ - ("testShouldConvertArrayOfGoodBasicItemsToNonOptional", testShouldConvertArrayOfGoodBasicItemsToNonOptional), - ("testShouldConvertArrayOfGoodBasicItemsToOptional", testShouldConvertArrayOfGoodBasicItemsToOptional), - ("testShouldConvertArrayOfGoodBasicItemsToArrayOfOptionals", testShouldConvertArrayOfGoodBasicItemsToArrayOfOptionals), - ("testShouldThrowWhenConvertingArrayOfBadBasicItemsToNonOptional", testShouldThrowWhenConvertingArrayOfBadBasicItemsToNonOptional), - ("testShouldThrowWhenConvertingArrayOfBadBasicItemsToOptional", testShouldThrowWhenConvertingArrayOfBadBasicItemsToOptional), - ("testShouldThrowWhenConvertingArrayOfBadBasicItemsToArrayOfOptionals", testShouldThrowWhenConvertingArrayOfBadBasicItemsToArrayOfOptionals), - ("testShouldConvertArrayOfEmptyMissingToOptional", testShouldConvertArrayOfEmptyMissingToOptional), - ("testShouldConvertArrayOfGoodAttributeItemsToNonOptional", testShouldConvertArrayOfGoodAttributeItemsToNonOptional), - ("testShouldConvertArrayOfGoodAttributeItemsToOptional", testShouldConvertArrayOfGoodAttributeItemsToOptional), - ("testShouldConvertArrayOfGoodAttributeItemsToArrayOfOptionals", testShouldConvertArrayOfGoodAttributeItemsToArrayOfOptionals), - ("testShouldThrowWhenConvertingArrayOfBadAttributeItemsToNonOptional", testShouldThrowWhenConvertingArrayOfBadAttributeItemsToNonOptional), - ("testShouldThrowWhenConvertingArrayOfBadAttributeItemsToOptional", testShouldThrowWhenConvertingArrayOfBadAttributeItemsToOptional), - ("testShouldThrowWhenConvertingArrayOfBadAttributeItemsToArrayOfOptionals", testShouldThrowWhenConvertingArrayOfBadAttributeItemsToArrayOfOptionals), - ("testFilterAndSerializationShouldWork", testFilterAndSerializationShouldWork) - ] - } -} - // swiftlint:enable line_length // swiftlint:enable type_name diff --git a/Tests/SWXMLHashTests/TypeConversionBasicTypesTests.swift b/Tests/SWXMLHashTests/TypeConversionBasicTypesTests.swift index 1537bfce..4d64b8ca 100644 --- a/Tests/SWXMLHashTests/TypeConversionBasicTypesTests.swift +++ b/Tests/SWXMLHashTests/TypeConversionBasicTypesTests.swift @@ -24,7 +24,7 @@ // import SWXMLHash -import XCTest +import Testing // swiftlint:disable identifier_name // swiftlint:disable file_length @@ -54,7 +54,7 @@ struct SampleUserInfo { } } -class TypeConversionBasicTypesTests: XCTestCase { +struct TypeConversionBasicTypesTests { var parser: XMLIndexer? let xmlWithBasicTypes = """ @@ -74,422 +74,375 @@ class TypeConversionBasicTypesTests: XCTestCase { """ - override func setUp() { - super.setUp() + init() { parser = XMLHash.parse(xmlWithBasicTypes) } - func testShouldConvertValueToNonOptional() { + @Test + func shouldConvertValueToNonOptional() { do { let value: String = try parser!["root"]["string"].value() - XCTAssertEqual(value, "the string value") + #expect(value == "the string value") } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertEmptyToNonOptional() { + @Test + func shouldConvertEmptyToNonOptional() { do { let value: String = try parser!["root"]["empty"].value() - XCTAssertEqual(value, "") + #expect(value.isEmpty) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldThrowWhenConvertingMissingToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["missing"].value() as String)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + @Test + func shouldThrowWhenConvertingMissingToNonOptional() { + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["missing"].value() as String) } } - func testShouldConvertValueToOptional() { + @Test + func shouldConvertValueToOptional() { do { let value: String? = try parser!["root"]["string"].value() - XCTAssertEqual(value, "the string value") + #expect(value == "the string value") } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertEmptyToOptional() { + @Test + func shouldConvertEmptyToOptional() { do { let value: String? = try parser!["root"]["empty"].value() - XCTAssertEqual(value, "") + #expect(value?.isEmpty == true) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertMissingToOptional() { + @Test + func shouldConvertMissingToOptional() { do { let value: String? = try parser!["root"]["missing"].value() - XCTAssertNil(value) + #expect(value == nil) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertAttributeToNonOptional() { + @Test + func shouldConvertAttributeToNonOptional() { do { let value: String = try parser!["root"]["attr"].value(ofAttribute: "string") - XCTAssertEqual(value, "stringValue") + #expect(value == "stringValue") } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertAttributeToOptional() { + @Test + func shouldConvertAttributeToOptional() { let value: String? = parser!["root"]["attr"].value(ofAttribute: "string") - XCTAssertEqual(value, "stringValue") + #expect(value == "stringValue") } - func testShouldThrowWhenConvertingMissingAttributeToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["attr"].value(ofAttribute: "missing") as String)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + @Test + func shouldThrowWhenConvertingMissingAttributeToNonOptional() { + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["attr"].value(ofAttribute: "missing") as String) } } - func testShouldConvertMissingAttributeToOptional() { + @Test + func shouldConvertMissingAttributeToOptional() { let value: String? = parser!["root"]["attr"].value(ofAttribute: "missing") - XCTAssertNil(value) + #expect(value == nil) } - func testShouldConvertAttributeToNonOptionalWithStringRawRepresentable() { + @Test + func shouldConvertAttributeToNonOptionalWithStringRawRepresentable() { enum Keys: String { case string } do { let value: String = try parser!["root"]["attr"].value(ofAttribute: Keys.string) - XCTAssertEqual(value, "stringValue") + #expect(value == "stringValue") } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertAttributeToOptionalWithStringRawRepresentable() { + @Test + func shouldConvertAttributeToOptionalWithStringRawRepresentable() { enum Keys: String { case string } let value: String? = parser!["root"]["attr"].value(ofAttribute: Keys.string) - XCTAssertEqual(value, "stringValue") + #expect(value == "stringValue") } - func testShouldThrowWhenConvertingMissingAttributeToNonOptionalWithStringRawRepresentable() { + @Test + func shouldThrowWhenConvertingMissingAttributeToNonOptionalWithStringRawRepresentable() { enum Keys: String { case missing } - XCTAssertThrowsError(try (parser!["root"]["attr"].value(ofAttribute: Keys.missing) as String)) { error in - print(error.localizedDescription) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["attr"].value(ofAttribute: Keys.missing) as String) } } - func testShouldConvertMissingAttributeToOptionalWithStringRawRepresentable() { + @Test + func shouldConvertMissingAttributeToOptionalWithStringRawRepresentable() { enum Keys: String { case missing } let value: String? = parser!["root"]["attr"].value(ofAttribute: Keys.missing) - XCTAssertNil(value) + #expect(value == nil) } func testIntShouldConvertValueToNonOptional() { do { let value: Int = try parser!["root"]["int"].value() - XCTAssertEqual(value, 100) + #expect(value == 100) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testIntShouldThrowWhenConvertingEmptyToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["empty"].value() as Int)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["empty"].value() as Int) } } func testIntShouldThrowWhenConvertingMissingToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["missing"].value() as Int)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["missing"].value() as Int) } } func testIntShouldConvertValueToOptional() { do { let value: Int? = try parser!["root"]["int"].value() - XCTAssertEqual(value, 100) + #expect(value == 100) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testIntShouldConvertEmptyToOptional() { - XCTAssertThrowsError(try (parser!["root"]["empty"].value() as Int?)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["empty"].value() as Int?) } } func testIntShouldConvertMissingToOptional() { do { let value: Int? = try parser!["root"]["missing"].value() - XCTAssertNil(value) + #expect(value == nil) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testIntShouldConvertAttributeToNonOptional() { do { let value: Int = try parser!["root"]["attr"].value(ofAttribute: "int") - XCTAssertEqual(value, 200) + #expect(value == 200) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testIntShouldConvertAttributeToOptional() { let value: Int? = parser!["root"]["attr"].value(ofAttribute: "int") - XCTAssertEqual(value, 200) + #expect(value == 200) } func testDoubleShouldConvertValueToNonOptional() { do { let value: Double = try parser!["root"]["double"].value() - XCTAssertEqual(value, 100.45) + #expect(value == 100.45) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testDoubleShouldThrowWhenConvertingEmptyToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["empty"].value() as Double)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["empty"].value() as Double) } } func testDoubleShouldThrowWhenConvertingMissingToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["missing"].value() as Double)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["missing"].value() as Double) } } func testDoubleShouldConvertValueToOptional() { do { let value: Double? = try parser!["root"]["double"].value() - XCTAssertEqual(value, 100.45) + #expect(value == 100.45) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testDoubleShouldConvertEmptyToOptional() { - XCTAssertThrowsError(try (parser!["root"]["empty"].value() as Double?)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["empty"].value() as Double?) } } func testDoubleShouldConvertMissingToOptional() { do { let value: Double? = try parser!["root"]["missing"].value() - XCTAssertNil(value) + #expect(value == nil) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testDoubleShouldConvertAttributeToNonOptional() { do { let value: Double = try parser!["root"]["attr"].value(ofAttribute: "double") - XCTAssertEqual(value, 200.15) + #expect(value == 200.15) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testDoubleShouldConvertAttributeToOptional() { let value: Double? = parser!["root"]["attr"].value(ofAttribute: "double") - XCTAssertEqual(value, 200.15) + #expect(value == 200.15) } func testFloatShouldConvertValueToNonOptional() { do { let value: Float = try parser!["root"]["float"].value() - XCTAssertEqual(value, 44.12) + #expect(value == 44.12) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testFloatShouldThrowWhenConvertingEmptyToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["empty"].value() as Float)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["empty"].value() as Float) } } func testFloatShouldThrowWhenConvertingMissingToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["missing"].value() as Float)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["missing"].value() as Float) } } func testFloatShouldConvertValueToOptional() { do { let value: Float? = try parser!["root"]["float"].value() - XCTAssertEqual(value, 44.12) + #expect(value == 44.12) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testFloatShouldConvertEmptyToOptional() { - XCTAssertThrowsError(try (parser!["root"]["empty"].value() as Float?)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["empty"].value() as Float?) } } func testFloatShouldConvertMissingToOptional() { do { let value: Float? = try parser!["root"]["missing"].value() - XCTAssertNil(value) + #expect(value == nil) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testFloatShouldConvertAttributeToNonOptional() { do { let value: Float = try parser!["root"]["attr"].value(ofAttribute: "float") - XCTAssertEqual(value, 205.42) + #expect(value == 205.42) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testFloatShouldConvertAttributeToOptional() { let value: Float? = parser!["root"]["attr"].value(ofAttribute: "float") - XCTAssertEqual(value, 205.42) + #expect(value == 205.42) } func testBoolShouldConvertValueToNonOptional() { do { let value1: Bool = try parser!["root"]["bool1"].value() let value2: Bool = try parser!["root"]["bool2"].value() - XCTAssertFalse(value1) - XCTAssertTrue(value2) + #expect(!value1) + #expect(value2) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testBoolShouldThrowWhenConvertingEmptyToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["empty"].value() as Bool)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["empty"].value() as Bool) } } func testBoolShouldThrowWhenConvertingMissingToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["missing"].value() as Bool)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["missing"].value() as Bool) } } func testBoolShouldConvertValueToOptional() { do { let value1: Bool? = try parser!["root"]["bool1"].value() - XCTAssertEqual(value1, false) + #expect(value1 == false) let value2: Bool? = try parser!["root"]["bool2"].value() - XCTAssertEqual(value2, true) + #expect(value2 == true) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testBoolShouldConvertEmptyToOptional() { - XCTAssertThrowsError(try (parser!["root"]["empty"].value() as Bool?)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["empty"].value() as Bool?) } } func testBoolShouldConvertMissingToOptional() { do { let value: Bool? = try parser!["root"]["missing"].value() - XCTAssertNil(value) + #expect(value == nil) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testBoolShouldConvertAttributeToNonOptional() { do { let value: Bool = try parser!["root"]["attr"].value(ofAttribute: "bool1") - XCTAssertEqual(value, false) + #expect(!value) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testBoolShouldConvertAttributeToOptional() { let value: Bool? = parser!["root"]["attr"].value(ofAttribute: "bool2") - XCTAssertEqual(value, true) + #expect(value == true) } let correctBasicItem = BasicItem(name: "the name of basic item", price: 99.14, id: "1234") @@ -497,57 +450,45 @@ class TypeConversionBasicTypesTests: XCTestCase { func testBasicItemShouldConvertBasicItemToNonOptional() { do { let value: BasicItem = try parser!["root"]["basicItem"].value() - XCTAssertEqual(value, correctBasicItem) + #expect(value == correctBasicItem) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testBasicItemShouldThrowWhenConvertingEmptyToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["empty"].value() as BasicItem)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["empty"].value() as BasicItem) } } func testBasicItemShouldThrowWhenConvertingMissingToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["missing"].value() as BasicItem)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["missing"].value() as BasicItem) } } func testBasicItemShouldConvertBasicItemToOptional() { do { let value: BasicItem? = try parser!["root"]["basicItem"].value() - XCTAssertEqual(value, correctBasicItem) + #expect(value == correctBasicItem) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testBasicItemShouldConvertEmptyToOptional() { - XCTAssertThrowsError(try (parser!["root"]["empty"].value() as BasicItem?)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["empty"].value() as BasicItem?) } } func testBasicItemShouldConvertMissingToOptional() { do { let value: BasicItem? = try parser!["root"]["missing"].value() - XCTAssertNil(value) + #expect(value == nil) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } @@ -557,80 +498,69 @@ class TypeConversionBasicTypesTests: XCTestCase { func testAttributeItemShouldConvertAttributeItemToNonOptional() { do { let value: AttributeItem = try parser!["root"]["attributeItem"].value() - XCTAssertEqual(value, correctAttributeItem) + #expect(value == correctAttributeItem) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testAttributeItemStringRawRepresentableShouldConvertAttributeItemToNonOptional() { do { let value: AttributeItemStringRawRepresentable = try parser!["root"]["attributeItem"].value() - XCTAssertEqual(value, correctAttributeItemStringRawRepresentable) + #expect(value == correctAttributeItemStringRawRepresentable) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testAttributeItemShouldThrowWhenConvertingEmptyToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["empty"].value() as AttributeItem)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["empty"].value() as AttributeItem) } } func testAttributeItemShouldThrowWhenConvertingMissingToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["missing"].value() as AttributeItem)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["missing"].value() as AttributeItem) } } func testAttributeItemShouldConvertAttributeItemToOptional() { do { let value: AttributeItem? = try parser!["root"]["attributeItem"].value() - XCTAssertEqual(value, correctAttributeItem) + #expect(value == correctAttributeItem) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } func testAttributeItemShouldConvertEmptyToOptional() { - XCTAssertThrowsError(try (parser!["root"]["empty"].value() as AttributeItem?)) { error in - print(error) - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["empty"].value() as AttributeItem?) } } func testAttributeItemShouldConvertMissingToOptional() { do { let value: AttributeItem? = try parser!["root"]["missing"].value() - XCTAssertNil(value) + #expect(value == nil) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldBeAbleToGetUserInfoDuringDeserialization() { - parser = XMLHash.config { config in + @Test + func shouldBeAbleToGetUserInfoDuringDeserialization() { + let parser = XMLHash.config { config in let options = SampleUserInfo(apiVersion: .v1) config.userInfo = [ SampleUserInfo.key: options ] }.parse(xmlWithBasicTypes) do { - let value: BasicItem = try parser!["root"]["basicItem"].value() - XCTAssertEqual(value.name, "the name of basic item (v1)") + let value: BasicItem = try parser["root"]["basicItem"].value() + #expect(value.name == "the name of basic item (v1)") } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } } @@ -706,73 +636,6 @@ extension AttributeItemStringRawRepresentable: Equatable { } } -extension TypeConversionBasicTypesTests { - static var allTests: [(String, (TypeConversionBasicTypesTests) -> () throws -> Void)] { - [ - ("testShouldConvertValueToNonOptional", testShouldConvertValueToNonOptional), - ("testShouldConvertEmptyToNonOptional", testShouldConvertEmptyToNonOptional), - ("testShouldThrowWhenConvertingMissingToNonOptional", testShouldThrowWhenConvertingMissingToNonOptional), - ("testShouldConvertValueToOptional", testShouldConvertValueToOptional), - ("testShouldConvertEmptyToOptional", testShouldConvertEmptyToOptional), - ("testShouldConvertMissingToOptional", testShouldConvertMissingToOptional), - ("testShouldConvertAttributeToNonOptional", testShouldConvertAttributeToNonOptional), - ("testShouldConvertAttributeToOptional", testShouldConvertAttributeToOptional), - ("testShouldThrowWhenConvertingMissingAttributeToNonOptional", testShouldThrowWhenConvertingMissingAttributeToNonOptional), - ("testShouldConvertMissingAttributeToOptional", testShouldConvertMissingAttributeToOptional), - ("testShouldConvertAttributeToNonOptionalWithStringRawRepresentable", testShouldConvertAttributeToNonOptionalWithStringRawRepresentable), - ("testShouldConvertAttributeToOptionalWithStringRawRepresentable", testShouldConvertAttributeToOptionalWithStringRawRepresentable), - ("testShouldThrowWhenConvertingMissingAttributeToNonOptionalWithStringRawRepresentable", testShouldThrowWhenConvertingMissingAttributeToNonOptionalWithStringRawRepresentable), - ("testShouldConvertMissingAttributeToOptionalWithStringRawRepresentable", testShouldConvertMissingAttributeToOptionalWithStringRawRepresentable), - ("testIntShouldConvertValueToNonOptional", testIntShouldConvertValueToNonOptional), - ("testIntShouldThrowWhenConvertingEmptyToNonOptional", testIntShouldThrowWhenConvertingEmptyToNonOptional), - ("testIntShouldThrowWhenConvertingMissingToNonOptional", testIntShouldThrowWhenConvertingMissingToNonOptional), - ("testIntShouldConvertValueToOptional", testIntShouldConvertValueToOptional), - ("testIntShouldConvertEmptyToOptional", testIntShouldConvertEmptyToOptional), - ("testIntShouldConvertMissingToOptional", testIntShouldConvertMissingToOptional), - ("testIntShouldConvertAttributeToNonOptional", testIntShouldConvertAttributeToNonOptional), - ("testIntShouldConvertAttributeToOptional", testIntShouldConvertAttributeToOptional), - ("testDoubleShouldConvertValueToNonOptional", testDoubleShouldConvertValueToNonOptional), - ("testDoubleShouldThrowWhenConvertingEmptyToNonOptional", testDoubleShouldThrowWhenConvertingEmptyToNonOptional), - ("testDoubleShouldThrowWhenConvertingMissingToNonOptional", testDoubleShouldThrowWhenConvertingMissingToNonOptional), - ("testDoubleShouldConvertValueToOptional", testDoubleShouldConvertValueToOptional), - ("testDoubleShouldConvertEmptyToOptional", testDoubleShouldConvertEmptyToOptional), - ("testDoubleShouldConvertMissingToOptional", testDoubleShouldConvertMissingToOptional), - ("testDoubleShouldConvertAttributeToNonOptional", testDoubleShouldConvertAttributeToNonOptional), - ("testDoubleShouldConvertAttributeToOptional", testDoubleShouldConvertAttributeToOptional), - ("testFloatShouldConvertValueToNonOptional", testFloatShouldConvertValueToNonOptional), - ("testFloatShouldThrowWhenConvertingEmptyToNonOptional", testFloatShouldThrowWhenConvertingEmptyToNonOptional), - ("testFloatShouldThrowWhenConvertingMissingToNonOptional", testFloatShouldThrowWhenConvertingMissingToNonOptional), - ("testFloatShouldConvertValueToOptional", testFloatShouldConvertValueToOptional), - ("testFloatShouldConvertEmptyToOptional", testFloatShouldConvertEmptyToOptional), - ("testFloatShouldConvertMissingToOptional", testFloatShouldConvertMissingToOptional), - ("testFloatShouldConvertAttributeToNonOptional", testFloatShouldConvertAttributeToNonOptional), - ("testFloatShouldConvertAttributeToOptional", testFloatShouldConvertAttributeToOptional), - ("testBoolShouldConvertValueToNonOptional", testBoolShouldConvertValueToNonOptional), - ("testBoolShouldThrowWhenConvertingEmptyToNonOptional", testBoolShouldThrowWhenConvertingEmptyToNonOptional), - ("testBoolShouldThrowWhenConvertingMissingToNonOptional", testBoolShouldThrowWhenConvertingMissingToNonOptional), - ("testBoolShouldConvertValueToOptional", testBoolShouldConvertValueToOptional), - ("testBoolShouldConvertEmptyToOptional", testBoolShouldConvertEmptyToOptional), - ("testBoolShouldConvertMissingToOptional", testBoolShouldConvertMissingToOptional), - ("testBoolShouldConvertAttributeToNonOptional", testBoolShouldConvertAttributeToNonOptional), - ("testBoolShouldConvertAttributeToOptional", testBoolShouldConvertAttributeToOptional), - ("testBasicItemShouldConvertBasicItemToNonOptional", testBasicItemShouldConvertBasicItemToNonOptional), - ("testBasicItemShouldThrowWhenConvertingEmptyToNonOptional", testBasicItemShouldThrowWhenConvertingEmptyToNonOptional), - ("testBasicItemShouldThrowWhenConvertingMissingToNonOptional", testBasicItemShouldThrowWhenConvertingMissingToNonOptional), - ("testBasicItemShouldConvertBasicItemToOptional", testBasicItemShouldConvertBasicItemToOptional), - ("testBasicItemShouldConvertEmptyToOptional", testBasicItemShouldConvertEmptyToOptional), - ("testBasicItemShouldConvertMissingToOptional", testBasicItemShouldConvertMissingToOptional), - ("testAttributeItemShouldConvertAttributeItemToNonOptional", testAttributeItemShouldConvertAttributeItemToNonOptional), - ("testAttributeItemStringRawRepresentableShouldConvertAttributeItemToNonOptional", testAttributeItemStringRawRepresentableShouldConvertAttributeItemToNonOptional), - ("testAttributeItemShouldThrowWhenConvertingEmptyToNonOptional", testAttributeItemShouldThrowWhenConvertingEmptyToNonOptional), - ("testAttributeItemShouldThrowWhenConvertingMissingToNonOptional", testAttributeItemShouldThrowWhenConvertingMissingToNonOptional), - ("testAttributeItemShouldConvertAttributeItemToOptional", testAttributeItemShouldConvertAttributeItemToOptional), - ("testAttributeItemShouldConvertEmptyToOptional", testAttributeItemShouldConvertEmptyToOptional), - ("testAttributeItemShouldConvertMissingToOptional", testAttributeItemShouldConvertMissingToOptional), - ("testShouldBeAbleToGetUserInfoDuringDeserialization", testShouldBeAbleToGetUserInfoDuringDeserialization) - ] - } -} - // swiftlint:enable identifier_name // swiftlint:enable line_length // swiftlint:enable type_body_length diff --git a/Tests/SWXMLHashTests/TypeConversionComplexTypesTests.swift b/Tests/SWXMLHashTests/TypeConversionComplexTypesTests.swift index d628651a..97d9195e 100644 --- a/Tests/SWXMLHashTests/TypeConversionComplexTypesTests.swift +++ b/Tests/SWXMLHashTests/TypeConversionComplexTypesTests.swift @@ -24,9 +24,9 @@ // import SWXMLHash -import XCTest +import Testing -class TypeConversionComplexTypesTests: XCTestCase { +struct TypeConversionComplexTypesTests { var parser: XMLIndexer? let xmlWithComplexType = """ @@ -72,62 +72,58 @@ class TypeConversionComplexTypesTests: XCTestCase { ] ) - override func setUp() { - super.setUp() + init() { parser = XMLHash.parse(xmlWithComplexType) } - func testShouldConvertComplexItemToNonOptional() { + @Test + func shouldConvertComplexItemToNonOptional() { do { let value: ComplexItem = try parser!["root"]["complexItem"].value() - XCTAssertEqual(value, correctComplexItem) + #expect(value == correctComplexItem) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldThrowWhenConvertingEmptyToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["empty"].value() as ComplexItem)) { error in - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + @Test + func shouldThrowWhenConvertingEmptyToNonOptional() { + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["empty"].value() as ComplexItem) } } - func testShouldThrowWhenConvertingMissingToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["missing"].value() as ComplexItem)) { error in - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + @Test + func shouldThrowWhenConvertingMissingToNonOptional() { + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["missing"].value() as ComplexItem) } } - func testShouldConvertComplexItemToOptional() { + @Test + func shouldConvertComplexItemToOptional() { do { let value: ComplexItem? = try parser!["root"]["complexItem"].value() - XCTAssertEqual(value, correctComplexItem) + #expect(value == correctComplexItem) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertEmptyToOptional() { - XCTAssertThrowsError(try (parser!["root"]["empty"].value() as ComplexItem?)) { error in - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + @Test + func shouldConvertEmptyToOptional() { + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["empty"].value() as ComplexItem?) } } - func testShouldConvertMissingToOptional() { + @Test + func shouldConvertMissingToOptional() { do { let value: ComplexItem? = try parser!["root"]["missing"].value() - XCTAssertNil(value) + #expect(value == nil) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } } @@ -154,16 +150,3 @@ extension ComplexItem: Equatable { a.name == b.name && a.priceOptional == b.priceOptional && a.basics == b.basics && a.attrs == b.attrs } } - -extension TypeConversionComplexTypesTests { - static var allTests: [(String, (TypeConversionComplexTypesTests) -> () throws -> Void)] { - [ - ("testShouldConvertComplexItemToNonOptional", testShouldConvertComplexItemToNonOptional), - ("testShouldThrowWhenConvertingEmptyToNonOptional", testShouldThrowWhenConvertingEmptyToNonOptional), - ("testShouldThrowWhenConvertingMissingToNonOptional", testShouldThrowWhenConvertingMissingToNonOptional), - ("testShouldConvertComplexItemToOptional", testShouldConvertComplexItemToOptional), - ("testShouldConvertEmptyToOptional", testShouldConvertEmptyToOptional), - ("testShouldConvertMissingToOptional", testShouldConvertMissingToOptional) - ] - } -} diff --git a/Tests/SWXMLHashTests/TypeConversionPrimitiveTypesTests.swift b/Tests/SWXMLHashTests/TypeConversionPrimitiveTypesTests.swift index 0380d6ec..48427a73 100644 --- a/Tests/SWXMLHashTests/TypeConversionPrimitiveTypesTests.swift +++ b/Tests/SWXMLHashTests/TypeConversionPrimitiveTypesTests.swift @@ -24,11 +24,9 @@ // import SWXMLHash -import XCTest +import Testing -// swiftlint:disable line_length - -class TypeConversionPrimitiveTypesTests: XCTestCase { +struct TypeConversionPrimitiveTypesTests { var parser: XMLIndexer? let xmlWithArraysOfTypes = """ @@ -48,215 +46,187 @@ class TypeConversionPrimitiveTypesTests: XCTestCase { """ - override func setUp() { - super.setUp() + init() { parser = XMLHash.parse(xmlWithArraysOfTypes) } - func testShouldConvertArrayOfGoodIntsToNonOptional() { + @Test + func shouldConvertArrayOfGoodIntsToNonOptional() { do { let value: [Int] = try parser!["root"]["arrayOfGoodInts"]["int"].value() - XCTAssertEqual(value, [0, 1, 2, 3]) + #expect(value == [0, 1, 2, 3]) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertArrayOfGoodIntsToOptional() { + @Test + func shouldConvertArrayOfGoodIntsToOptional() { do { let value: [Int]? = try parser!["root"]["arrayOfGoodInts"]["int"].value() - XCTAssertNotNil(value) + #expect(value != nil) if let value = value { - XCTAssertEqual(value, [0, 1, 2, 3]) + #expect(value == [0, 1, 2, 3]) } } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertArrayOfGoodIntsToArrayOfOptionals() { + @Test + func shouldConvertArrayOfGoodIntsToArrayOfOptionals() { do { let value: [Int?] = try parser!["root"]["arrayOfGoodInts"]["int"].value() - XCTAssertEqual(value.compactMap({ $0 }), [0, 1, 2, 3]) + #expect(value.compactMap({ $0 }) == [0, 1, 2, 3]) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldThrowWhenConvertingArrayOfBadIntsToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["arrayOfBadInts"]["int"].value() as [Int])) { error in - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + @Test + func shouldThrowWhenConvertingArrayOfBadIntsToNonOptional() { + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["arrayOfBadInts"]["int"].value() as [Int]) } } - func testShouldThrowWhenConvertingArrayOfBadIntsToOptional() { - XCTAssertThrowsError(try (parser!["root"]["arrayOfBadInts"]["int"].value() as [Int]?)) { error in - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + @Test + func shouldThrowWhenConvertingArrayOfBadIntsToOptional() { + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["arrayOfBadInts"]["int"].value() as [Int]?) } } - func testShouldThrowWhenConvertingArrayOfBadIntsToArrayOfOptionals() { - XCTAssertThrowsError(try (parser!["root"]["arrayOfBadInts"]["int"].value() as [Int?])) { error in - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + @Test + func shouldThrowWhenConvertingArrayOfBadIntsToArrayOfOptionals() { + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["arrayOfBadInts"]["int"].value() as [Int?]) } } - func testShouldThrowWhenConvertingArrayOfMixedIntsToNonOptional() { - XCTAssertThrowsError(try (parser!["root"]["arrayOfMixedInts"]["int"].value() as [Int])) { error in - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + @Test + func shouldThrowWhenConvertingArrayOfMixedIntsToNonOptional() { + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["arrayOfMixedInts"]["int"].value() as [Int]) } } - func testShouldThrowWhenConvertingArrayOfMixedIntsToOptional() { - XCTAssertThrowsError(try (parser!["root"]["arrayOfMixedInts"]["int"].value() as [Int]?)) { error in - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + @Test + func shouldThrowWhenConvertingArrayOfMixedIntsToOptional() { + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["arrayOfMixedInts"]["int"].value() as [Int]?) } } - func testShouldThrowWhenConvertingArrayOfMixedIntsToArrayOfOptionals() { - XCTAssertThrowsError(try (parser!["root"]["arrayOfMixedInts"]["int"].value() as [Int?])) { error in - guard error is XMLDeserializationError else { - XCTFail("Wrong type of error") - return - } + @Test + func shouldThrowWhenConvertingArrayOfMixedIntsToArrayOfOptionals() { + #expect(throws: XMLDeserializationError.self) { + try (parser!["root"]["arrayOfMixedInts"]["int"].value() as [Int?]) } } - func testShouldConvertArrayOfAttributeIntsToNonOptional() { + @Test + func shouldConvertArrayOfAttributeIntsToNonOptional() { do { let value: [Int] = try parser!["root"]["arrayOfAttributeInts"]["int"].value(ofAttribute: "value") - XCTAssertEqual(value, [0, 1, 2, 3]) + #expect(value == [0, 1, 2, 3]) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertArrayOfAttributeIntsToOptional() { + @Test + func shouldConvertArrayOfAttributeIntsToOptional() { do { let value: [Int]? = try parser!["root"]["arrayOfAttributeInts"]["int"].value(ofAttribute: "value") - XCTAssertNotNil(value) + #expect(value != nil) if let value = value { - XCTAssertEqual(value, [0, 1, 2, 3]) + #expect(value == [0, 1, 2, 3]) } } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertArrayOfAttributeIntsToArrayOfOptionals() { + @Test + func shouldConvertArrayOfAttributeIntsToArrayOfOptionals() { do { let value: [Int?] = try parser!["root"]["arrayOfAttributeInts"]["int"].value(ofAttribute: "value") - XCTAssertEqual(value.compactMap({ $0 }), [0, 1, 2, 3]) + #expect(value.compactMap({ $0 }) == [0, 1, 2, 3]) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertArrayOfAttributeIntsToNonOptionalWithStringRawRepresentable() { + @Test + func shouldConvertArrayOfAttributeIntsToNonOptionalWithStringRawRepresentable() { enum Keys: String { case value } do { let value: [Int] = try parser!["root"]["arrayOfAttributeInts"]["int"].value(ofAttribute: Keys.value) - XCTAssertEqual(value, [0, 1, 2, 3]) + #expect(value == [0, 1, 2, 3]) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertArrayOfAttributeIntsToOptionalWithStringRawRepresentable() { + @Test + func shouldConvertArrayOfAttributeIntsToOptionalWithStringRawRepresentable() { enum Keys: String { case value } do { let value: [Int]? = try parser!["root"]["arrayOfAttributeInts"]["int"].value(ofAttribute: Keys.value) - XCTAssertNotNil(value) + #expect(value != nil) if let value = value { - XCTAssertEqual(value, [0, 1, 2, 3]) + #expect(value == [0, 1, 2, 3]) } } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertArrayOfAttributeIntsToArrayOfOptionalsWithStringRawRepresentable() { + @Test + func shouldConvertArrayOfAttributeIntsToArrayOfOptionalsWithStringRawRepresentable() { enum Keys: String { case value } do { let value: [Int?] = try parser!["root"]["arrayOfAttributeInts"]["int"].value(ofAttribute: Keys.value) - XCTAssertEqual(value.compactMap({ $0 }), [0, 1, 2, 3]) + #expect(value.compactMap({ $0 }) == [0, 1, 2, 3]) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertEmptyArrayOfIntsToNonOptional() { + @Test + func shouldConvertEmptyArrayOfIntsToNonOptional() { do { let value: [Int] = try parser!["root"]["empty"]["int"].value() - XCTAssertEqual(value, []) + #expect(value == []) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertEmptyArrayOfIntsToOptional() { + @Test + func shouldConvertEmptyArrayOfIntsToOptional() { do { let value: [Int]? = try parser!["root"]["empty"]["int"].value() - XCTAssertNil(value) + #expect(value == nil) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldConvertEmptyArrayOfIntsToArrayOfOptionals() { + @Test + func shouldConvertEmptyArrayOfIntsToArrayOfOptionals() { do { let value: [Int?] = try parser!["root"]["empty"]["int"].value() - XCTAssertEqual(value.count, 0) + #expect(value.isEmpty) } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } } - -extension TypeConversionPrimitiveTypesTests { - static var allTests: [(String, (TypeConversionPrimitiveTypesTests) -> () throws -> Void)] { - [ - ("testShouldConvertArrayOfGoodIntsToNonOptional", testShouldConvertArrayOfGoodIntsToNonOptional), - ("testShouldConvertArrayOfGoodIntsToOptional", testShouldConvertArrayOfGoodIntsToOptional), - ("testShouldConvertArrayOfGoodIntsToArrayOfOptionals", testShouldConvertArrayOfGoodIntsToArrayOfOptionals), - ("testShouldThrowWhenConvertingArrayOfBadIntsToNonOptional", testShouldThrowWhenConvertingArrayOfBadIntsToNonOptional), - ("testShouldThrowWhenConvertingArrayOfBadIntsToOptional", testShouldThrowWhenConvertingArrayOfBadIntsToOptional), - ("testShouldThrowWhenConvertingArrayOfBadIntsToArrayOfOptionals", testShouldThrowWhenConvertingArrayOfBadIntsToArrayOfOptionals), - ("testShouldThrowWhenConvertingArrayOfMixedIntsToNonOptional", testShouldThrowWhenConvertingArrayOfMixedIntsToNonOptional), - ("testShouldThrowWhenConvertingArrayOfMixedIntsToOptional", testShouldThrowWhenConvertingArrayOfMixedIntsToOptional), - ("testShouldThrowWhenConvertingArrayOfMixedIntsToArrayOfOptionals", testShouldThrowWhenConvertingArrayOfMixedIntsToArrayOfOptionals), - ("testShouldConvertArrayOfAttributeIntsToNonOptional", testShouldConvertArrayOfAttributeIntsToNonOptional), - ("testShouldConvertArrayOfAttributeIntsToOptional", testShouldConvertArrayOfAttributeIntsToOptional), - ("testShouldConvertArrayOfAttributeIntsToArrayOfOptionals", testShouldConvertArrayOfAttributeIntsToArrayOfOptionals), - ("testShouldConvertArrayOfAttributeIntsToNonOptionalWithStringRawRepresentable", testShouldConvertArrayOfAttributeIntsToNonOptionalWithStringRawRepresentable), - ("testShouldConvertArrayOfAttributeIntsToOptionalWithStringRawRepresentable", testShouldConvertArrayOfAttributeIntsToOptionalWithStringRawRepresentable), - ("testShouldConvertArrayOfAttributeIntsToArrayOfOptionalsWithStringRawRepresentable", testShouldConvertArrayOfAttributeIntsToArrayOfOptionalsWithStringRawRepresentable), - ("testShouldConvertEmptyArrayOfIntsToNonOptional", testShouldConvertEmptyArrayOfIntsToNonOptional), - ("testShouldConvertEmptyArrayOfIntsToOptional", testShouldConvertEmptyArrayOfIntsToOptional), - ("testShouldConvertEmptyArrayOfIntsToArrayOfOptionals", testShouldConvertEmptyArrayOfIntsToArrayOfOptionals) - ] - } -} - -// swiftlint:enable line_length diff --git a/Tests/SWXMLHashTests/WhiteSpaceParsingTests.swift b/Tests/SWXMLHashTests/WhiteSpaceParsingTests.swift index 37ed24ad..517fd9fe 100644 --- a/Tests/SWXMLHashTests/WhiteSpaceParsingTests.swift +++ b/Tests/SWXMLHashTests/WhiteSpaceParsingTests.swift @@ -25,43 +25,30 @@ import Foundation import SWXMLHash -import XCTest +import Testing // swiftlint:disable line_length -class WhiteSpaceParsingTests: XCTestCase { +struct WhiteSpaceParsingTests { var xml: XMLIndexer? - override func setUp() { - super.setUp() - // Put setup code here. This method is called before the invocation of each test method in the class. -#if SWIFT_PACKAGE - let path = URL(fileURLWithPath: #file).deletingLastPathComponent().appendingPathComponent("test.xml").path -#else - let bundle = Bundle(for: WhiteSpaceParsingTests.self) - let path = bundle.path(forResource: "test", ofType: "xml")! -#endif + init() { + let path = URL(fileURLWithPath: #filePath).deletingLastPathComponent().appendingPathComponent("test.xml").path + // swiftlint:disable:next force_try let data = try! Data(contentsOf: URL(fileURLWithPath: path)) xml = XMLHash.parse(data) } // issue #6 - func testShouldBeAbleToPullTextBetweenElementsWithoutWhitespace() { - XCTAssertEqual(xml!["niotemplate"]["section"][0]["constraint"][1].element?.text, "H:|-15-[title]-15-|") - } - - func testShouldBeAbleToCorrectlyParseCDATASectionsWithWhitespace() { - XCTAssertEqual(xml!["niotemplate"]["other"].element?.text, "\n \n this\n has\n white\n space\n \n ") + @Test + func shouldBeAbleToPullTextBetweenElementsWithoutWhitespace() { + #expect(xml!["niotemplate"]["section"][0]["constraint"][1].element?.text == "H:|-15-[title]-15-|") } -} -extension WhiteSpaceParsingTests { - static var allTests: [(String, (WhiteSpaceParsingTests) -> () throws -> Void)] { - [ - ("testShouldBeAbleToPullTextBetweenElementsWithoutWhitespace", testShouldBeAbleToPullTextBetweenElementsWithoutWhitespace), - ("testShouldBeAbleToCorrectlyParseCDATASectionsWithWhitespace", testShouldBeAbleToCorrectlyParseCDATASectionsWithWhitespace) - ] + @Test + func shouldBeAbleToCorrectlyParseCDATASectionsWithWhitespace() { + #expect(xml!["niotemplate"]["other"].element?.text == "\n \n this\n has\n white\n space\n \n ") } } diff --git a/Tests/SWXMLHashTests/XMLHashConfigTests.swift b/Tests/SWXMLHashTests/XMLHashConfigTests.swift index 3c45f191..01a097d7 100644 --- a/Tests/SWXMLHashTests/XMLHashConfigTests.swift +++ b/Tests/SWXMLHashTests/XMLHashConfigTests.swift @@ -24,9 +24,9 @@ // import SWXMLHash -import XCTest +import Testing -class XMLHashConfigTests: XCTestCase { +struct XMLHashConfigTests { var parser: XMLIndexer? let xmlWithNamespace = """ """ - override func setUp() { - super.setUp() + init() { parser = XMLHash.config { conf in conf.shouldProcessNamespaces = true }.parse(xmlWithNamespace) } - func testShouldAllowProcessingNamespacesOrNot() { - XCTAssertEqual(parser!["root"]["table"]["tr"]["td"][0].element?.text, "Apples") - } -} - -extension XMLHashConfigTests { - static var allTests: [(String, (XMLHashConfigTests) -> () throws -> Void)] { - [ - ("testShouldAllowProcessingNamespacesOrNot", testShouldAllowProcessingNamespacesOrNot) - ] + @Test + func shouldAllowProcessingNamespacesOrNot() { + #expect(parser!["root"]["table"]["tr"]["td"][0].element?.text == "Apples") } } diff --git a/Tests/SWXMLHashTests/XMLParsingTests.swift b/Tests/SWXMLHashTests/XMLParsingTests.swift index 0a161726..5d9f5129 100644 --- a/Tests/SWXMLHashTests/XMLParsingTests.swift +++ b/Tests/SWXMLHashTests/XMLParsingTests.swift @@ -24,13 +24,13 @@ // import SWXMLHash -import XCTest +import Testing // swiftlint:disable line_length // swiftlint:disable file_length // swiftlint:disable type_body_length -class XMLParsingTests: XCTestCase { +struct XMLParsingTests { let xmlToParse = """
header mixed contentTest Title Headermore mixed content
@@ -64,116 +64,134 @@ class XMLParsingTests: XCTestCase { var xml: XMLIndexer? - override func setUp() { - super.setUp() + init() { // Put setup code here. This method is called before the invocation of each test method in the class. xml = XMLHash.parse(xmlToParse) } - func testShouldBeAbleToParseIndividualElements() { - XCTAssertEqual(xml!["root"]["header"]["title"].element?.text, "Test Title Header") + @Test + func shouldBeAbleToParseIndividualElements() { + #expect(xml!["root"]["header"]["title"].element?.text == "Test Title Header") } - func testShouldBeAbleToParseIndividualElementsWithStringRawRepresentable() { + @Test + func shouldBeAbleToParseIndividualElementsWithStringRawRepresentable() { enum Keys: String { case root; case header; case title } - XCTAssertEqual(xml![Keys.root][Keys.header][Keys.title].element?.text, "Test Title Header") + #expect(xml![Keys.root][Keys.header][Keys.title].element?.text == "Test Title Header") } - func testShouldBeAbleToParseElementGroups() { - XCTAssertEqual(xml!["root"]["catalog"]["book"][1]["author"].element?.text, "Ralls, Kim") + @Test + func shouldBeAbleToParseElementGroups() { + #expect(xml!["root"]["catalog"]["book"][1]["author"].element?.text == "Ralls, Kim") } - func testShouldBeAbleToParseElementGroupsByIndex() { - XCTAssertEqual(try xml!["root"]["catalog"]["book"].byIndex(1)["author"].element?.text, "Ralls, Kim") + @Test + func shouldBeAbleToParseElementGroupsByIndex() { + // swiftlint:disable:next force_try + #expect(try! xml!["root"]["catalog"]["book"].byIndex(1)["author"].element?.text == "Ralls, Kim") } - func testShouldBeAbleToByIndexWithoutGoingOutOfBounds() { - XCTAssertEqual(try xml!["root"]["catalog"]["book"].byIndex(3)["author"].element?.text, nil) + @Test + func shouldBeAbleToByIndexWithoutGoingOutOfBounds() { + // swiftlint:disable:next force_try + #expect(try! xml!["root"]["catalog"]["book"].byIndex(3)["author"].element?.text == nil) } - func testShouldBeAbleToParseAttributes() { - XCTAssertEqual(xml!["root"]["catalog"]["book"][1].element?.attribute(by: "id")?.text, "bk102") + @Test + func shouldBeAbleToParseAttributes() { + #expect(xml!["root"]["catalog"]["book"][1].element?.attribute(by: "id")?.text == "bk102") } - func testShouldBeAbleToParseAttributesWithStringRawRepresentable() { + @Test + func shouldBeAbleToParseAttributesWithStringRawRepresentable() { enum Keys: String { case root; case catalog; case book; case id } - XCTAssertEqual(xml![Keys.root][Keys.catalog][Keys.book][1].element?.attribute(by: Keys.id)?.text, "bk102") + #expect(xml![Keys.root][Keys.catalog][Keys.book][1].element?.attribute(by: Keys.id)?.text == "bk102") } - func testShouldBeAbleToLookUpElementsByNameAndAttribute() { + @Test + func shouldBeAbleToLookUpElementsByNameAndAttribute() { do { let value = try xml!["root"]["catalog"]["book"].withAttribute("id", "bk102")["author"].element?.text - XCTAssertEqual(value, "Ralls, Kim") + #expect(value == "Ralls, Kim") } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldBeAbleToLookUpElementsByNameAndAttributeWithStringRawRepresentable() { + @Test + func shouldBeAbleToLookUpElementsByNameAndAttributeWithStringRawRepresentable() { enum Keys: String { case root; case catalog; case book; case id; case bk102; case author } do { let value = try xml![Keys.root][Keys.catalog][Keys.book].withAttribute(Keys.id, Keys.bk102)[Keys.author].element?.text - XCTAssertEqual(value, "Ralls, Kim") + #expect(value == "Ralls, Kim") } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldBeAbleToLookUpElementsByNameAndAttributeCaseInsensitive() { + @Test + func shouldBeAbleToLookUpElementsByNameAndAttributeCaseInsensitive() { do { let xmlInsensitive = XMLHash.config({ config in config.caseInsensitive = true }).parse(xmlToParse) let value = try xmlInsensitive["rOOt"]["catalOg"]["bOOk"].withAttribute("iD", "Bk102")["authOr"].element?.text - XCTAssertEqual(value, "Ralls, Kim") + #expect(value == "Ralls, Kim") } catch { - XCTFail("\(error)") + Issue.record("\(error)") } } - func testShouldBeAbleToIterateElementGroups() { + @Test + func shouldBeAbleToIterateElementGroups() { let result = xml!["root"]["catalog"]["book"].all.map({ $0["genre"].element!.text }).joined(separator: ", ") - XCTAssertEqual(result, "Computer, Fantasy, Fantasy") + #expect(result == "Computer, Fantasy, Fantasy") } - func testShouldBeAbleToIterateElementGroupsEvenIfOnlyOneElementIsFound() { - XCTAssertEqual(xml!["root"]["header"]["title"].all.count, 1) + @Test + func shouldBeAbleToIterateElementGroupsEvenIfOnlyOneElementIsFound() { + #expect(xml!["root"]["header"]["title"].all.count == 1) } - func testShouldBeAbleToIndexElementGroupsEvenIfOnlyOneElementIsFound() { - XCTAssertEqual(xml!["root"]["header"]["title"][0].element?.text, "Test Title Header") + @Test + func shouldBeAbleToIndexElementGroupsEvenIfOnlyOneElementIsFound() { + #expect(xml!["root"]["header"]["title"][0].element?.text == "Test Title Header") } - func testShouldBeAbleToIterateUsingForIn() { + @Test + func shouldBeAbleToIterateUsingForIn() { var count = 0 for _ in xml!["root"]["catalog"]["book"].all { count += 1 } - XCTAssertEqual(count, 3) + #expect(count == 3) } - func testShouldBeAbleToEnumerateChildren() { + @Test + func shouldBeAbleToEnumerateChildren() { let result = xml!["root"]["catalog"]["book"][0].children.map({ $0.element!.name }).joined(separator: ", ") - XCTAssertEqual(result, "author, title, genre, price, publish_date, description") + #expect(result == "author, title, genre, price, publish_date, description") } - func testShouldBeAbleToHandleMixedContent() { - XCTAssertEqual(xml!["root"]["header"].element?.text, "header mixed contentmore mixed content") + @Test + func shouldBeAbleToHandleMixedContent() { + #expect(xml!["root"]["header"].element?.text == "header mixed contentmore mixed content") } - func testShouldBeAbleToIterateOverMixedContent() { + @Test + func shouldBeAbleToIterateOverMixedContent() { let mixedContentXml = "

mixed content iteration support" let parsed = XMLHash.parse(mixedContentXml) let element = parsed["html"]["body"]["p"].element - XCTAssertNotNil(element) + #expect(element != nil) if let element = element { let result = element.children.reduce("") { acc, child in switch child { @@ -183,16 +201,17 @@ class XMLParsingTests: XCTestCase { case let elm as TextElement: return acc + elm.text default: - XCTAssert(false, "Unknown element type") + Issue.record("Unknown element type") return acc } } - XCTAssertEqual(result, "mixed content iteration support") + #expect(result == "mixed content iteration support") } } - func testShouldBeAbleToRecursiveOutputTextContent() { + @Test + func shouldBeAbleToRecursiveOutputTextContent() { let mixedContentXmlInputs = [ // From SourceKit cursor info key.annotated_decl "typealias SomeHandle = UInt", @@ -213,42 +232,47 @@ class XMLParsingTests: XCTestCase { ] for (index, mixedContentXml) in mixedContentXmlInputs.enumerated() { - XCTAssertEqual(XMLHash.parse(mixedContentXml).element!.recursiveText, recursiveTextOutputs[index]) + #expect(XMLHash.parse(mixedContentXml).element!.recursiveText == recursiveTextOutputs[index]) } } - func testShouldHandleInterleavingXMLElements() { + @Test + func shouldHandleInterleavingXMLElements() { let interleavedXml = "

one

two

three

four
" let parsed = XMLHash.parse(interleavedXml) let result = parsed["html"]["body"].children.map({ $0.element!.text }).joined(separator: ", ") - XCTAssertEqual(result, "one, two, three, four") + #expect(result == "one, two, three, four") } - func testShouldBeAbleToProvideADescriptionForTheDocument() { + @Test + func shouldBeAbleToProvideADescriptionForTheDocument() { let descriptionXml = "puppies" let parsed = XMLHash.parse(descriptionXml) - XCTAssertEqual(parsed.description, "puppies") + #expect(parsed.description == "puppies") } - func testShouldBeAbleToGetInnerXML() { + @Test + func shouldBeAbleToGetInnerXML() { let testXML = "puppies12" let parsed = XMLHash.parse(testXML) - XCTAssertEqual(parsed["root"]["foo"].element!.innerXML, "puppies12") + #expect(parsed["root"]["foo"].element!.innerXML == "puppies12") } // error handling - func testShouldReturnNilWhenKeysDontMatch() { - XCTAssertNil(xml!["root"]["what"]["header"]["foo"].element?.name) + @Test + func shouldReturnNilWhenKeysDontMatch() { + #expect(xml!["root"]["what"]["header"]["foo"].element?.name == nil) } - func testShouldProvideAnErrorObjectWhenKeysDontMatch() { + @Test + func shouldProvideAnErrorObjectWhenKeysDontMatch() { var err: IndexingError? defer { - XCTAssertNotNil(err) + #expect(err != nil) } do { _ = try xml!.byKey("root").byKey("what").byKey("header").byKey("foo") @@ -261,13 +285,14 @@ class XMLParsingTests: XCTestCase { Added Only test coverage for: `byKey(_ key: K) throws -> XMLIndexer where K.RawValue == String` */ - func testShouldProvideAnErrorObjectWhenKeysDontMatchWithStringRawRepresentable() { + @Test + func shouldProvideAnErrorObjectWhenKeysDontMatchWithStringRawRepresentable() { enum Keys: String { case root; case what; case header; case foo } var err: IndexingError? defer { - XCTAssertNotNil(err) + #expect(err != nil) } do { _ = try xml!.byKey(Keys.root).byKey(Keys.what).byKey(Keys.header).byKey(Keys.foo) @@ -276,10 +301,11 @@ class XMLParsingTests: XCTestCase { } catch { err = nil } } - func testShouldProvideAnErrorElementWhenIndexersDontMatch() { + @Test + func shouldProvideAnErrorElementWhenIndexersDontMatch() { var err: IndexingError? defer { - XCTAssertNotNil(err) + #expect(err != nil) } do { _ = try xml!.byKey("what").byKey("subelement").byIndex(5).byKey("nomatch") @@ -288,7 +314,8 @@ class XMLParsingTests: XCTestCase { } catch { err = nil } } - func testShouldStillReturnErrorsWhenAccessingViaSubscripting() { + @Test + func shouldStillReturnErrorsWhenAccessingViaSubscripting() { var err: IndexingError? switch xml!["what"]["subelement"][5]["nomatch"] { case .xmlError(let error): @@ -296,10 +323,11 @@ class XMLParsingTests: XCTestCase { default: err = nil } - XCTAssertNotNil(err) + #expect(err != nil) } - func testShouldBeAbleToCreateASubIndexer() { + @Test + func shouldBeAbleToCreateASubIndexer() { let xmlToParse = """ @@ -319,45 +347,48 @@ class XMLParsingTests: XCTestCase { let subIndexer = parser["root"].filterChildren { _, index in index >= 2 && index <= 5 } - XCTAssertNil(subIndexer["some-weird-element"].element) - XCTAssertNil(subIndexer["another-weird-element"].element) - XCTAssertNotNil(subIndexer["prop1"].element) - XCTAssertNotNil(subIndexer["prop2"].element) - XCTAssertNotNil(subIndexer["basicItem"].element) - XCTAssertNotNil(subIndexer["prop3"].element) - XCTAssertNil(subIndexer["last-weird-element"].element) + #expect(subIndexer["some-weird-element"].element == nil) + #expect(subIndexer["another-weird-element"].element == nil) + #expect(subIndexer["prop1"].element != nil) + #expect(subIndexer["prop2"].element != nil) + #expect(subIndexer["basicItem"].element != nil) + #expect(subIndexer["prop3"].element != nil) + #expect(subIndexer["last-weird-element"].element == nil) } - func testShouldBeAbleToCreateASubIndexerFromFilter() { + @Test + func shouldBeAbleToCreateASubIndexerFromFilter() { let subIndexer = xml!["root"]["catalog"]["book"][1].filterChildren { elem, _ in let filterByNames = ["title", "genre", "price"] return filterByNames.contains(elem.name) } - XCTAssertEqual(subIndexer.children[0].element?.name, "title") - XCTAssertEqual(subIndexer.children[1].element?.name, "genre") - XCTAssertEqual(subIndexer.children[2].element?.name, "price") + #expect(subIndexer.children[0].element?.name == "title") + #expect(subIndexer.children[1].element?.name == "genre") + #expect(subIndexer.children[2].element?.name == "price") - XCTAssertEqual(subIndexer.children[0].element?.text, "Midnight Rain") - XCTAssertEqual(subIndexer.children[1].element?.text, "Fantasy") - XCTAssertEqual(subIndexer.children[2].element?.text, "5.95") + #expect(subIndexer.children[0].element?.text == "Midnight Rain") + #expect(subIndexer.children[1].element?.text == "Fantasy") + #expect(subIndexer.children[2].element?.text == "5.95") } - func testShouldBeAbleToFilterOnIndexer() { + @Test + func shouldBeAbleToFilterOnIndexer() { let subIndexer = xml!["root"]["catalog"]["book"] .filterAll { elem, _ in elem.attribute(by: "id")!.text == "bk102" } .filterChildren { _, index in index >= 1 && index <= 3 } - XCTAssertEqual(subIndexer.children[0].element?.name, "title") - XCTAssertEqual(subIndexer.children[1].element?.name, "genre") - XCTAssertEqual(subIndexer.children[2].element?.name, "price") + #expect(subIndexer.children[0].element?.name == "title") + #expect(subIndexer.children[1].element?.name == "genre") + #expect(subIndexer.children[2].element?.name == "price") - XCTAssertEqual(subIndexer.children[0].element?.text, "Midnight Rain") - XCTAssertEqual(subIndexer.children[1].element?.text, "Fantasy") - XCTAssertEqual(subIndexer.children[2].element?.text, "5.95") + #expect(subIndexer.children[0].element?.text == "Midnight Rain") + #expect(subIndexer.children[1].element?.text == "Fantasy") + #expect(subIndexer.children[2].element?.text == "5.95") } - func testShouldThrowErrorForInvalidXML() { + @Test + func shouldThrowErrorForInvalidXML() { let invalidXML = "what is this" var err: ParsingError? let parser = XMLHash.config { config in @@ -371,50 +402,15 @@ class XMLParsingTests: XCTestCase { err = nil } - XCTAssertNotNil(err) + #expect(err != nil) #if !(os(Linux) || os(Windows)) if err != nil { - XCTAssert(err!.line == 1) + #expect(err!.line == 1) } #endif } } -extension XMLParsingTests { - static var allTests: [(String, (XMLParsingTests) -> () throws -> Void)] { - [ - ("testShouldBeAbleToParseIndividualElements", testShouldBeAbleToParseIndividualElements), - ("testShouldBeAbleToParseIndividualElementsWithStringRawRepresentable", testShouldBeAbleToParseIndividualElementsWithStringRawRepresentable), - ("testShouldBeAbleToParseElementGroups", testShouldBeAbleToParseElementGroups), - ("testShouldBeAbleToParseElementGroupsByIndex", testShouldBeAbleToParseElementGroupsByIndex), - ("testShouldBeAbleToByIndexWithoutGoingOutOfBounds", testShouldBeAbleToByIndexWithoutGoingOutOfBounds), - ("testShouldBeAbleToParseAttributes", testShouldBeAbleToParseAttributes), - ("testShouldBeAbleToParseAttributesWithStringRawRepresentable", testShouldBeAbleToParseAttributesWithStringRawRepresentable), - ("testShouldBeAbleToLookUpElementsByNameAndAttribute", testShouldBeAbleToLookUpElementsByNameAndAttribute), - ("testShouldBeAbleToLookUpElementsByNameAndAttributeWithStringRawRepresentable", testShouldBeAbleToLookUpElementsByNameAndAttributeWithStringRawRepresentable), - ("testShouldBeAbleToLookUpElementsByNameAndAttributeCaseInsensitive", testShouldBeAbleToLookUpElementsByNameAndAttributeCaseInsensitive), - ("testShouldBeAbleToIterateElementGroups", testShouldBeAbleToIterateElementGroups), - ("testShouldBeAbleToIterateElementGroupsEvenIfOnlyOneElementIsFound", testShouldBeAbleToIterateElementGroupsEvenIfOnlyOneElementIsFound), - ("testShouldBeAbleToIndexElementGroupsEvenIfOnlyOneElementIsFound", testShouldBeAbleToIndexElementGroupsEvenIfOnlyOneElementIsFound), - ("testShouldBeAbleToIterateUsingForIn", testShouldBeAbleToIterateUsingForIn), - ("testShouldBeAbleToEnumerateChildren", testShouldBeAbleToEnumerateChildren), - ("testShouldBeAbleToHandleMixedContent", testShouldBeAbleToHandleMixedContent), - ("testShouldBeAbleToIterateOverMixedContent", testShouldBeAbleToIterateOverMixedContent), - ("testShouldBeAbleToRecursiveOutputTextContent", testShouldBeAbleToRecursiveOutputTextContent), - ("testShouldHandleInterleavingXMLElements", testShouldHandleInterleavingXMLElements), - ("testShouldBeAbleToProvideADescriptionForTheDocument", testShouldBeAbleToProvideADescriptionForTheDocument), - ("testShouldReturnNilWhenKeysDontMatch", testShouldReturnNilWhenKeysDontMatch), - ("testShouldProvideAnErrorObjectWhenKeysDontMatch", testShouldProvideAnErrorObjectWhenKeysDontMatch), - ("testShouldProvideAnErrorObjectWhenKeysDontMatchWithStringRawRepresentable", testShouldProvideAnErrorObjectWhenKeysDontMatchWithStringRawRepresentable), - ("testShouldProvideAnErrorElementWhenIndexersDontMatch", testShouldProvideAnErrorElementWhenIndexersDontMatch), - ("testShouldStillReturnErrorsWhenAccessingViaSubscripting", testShouldStillReturnErrorsWhenAccessingViaSubscripting), - ("testShouldBeAbleToCreateASubIndexerFromFilter", testShouldBeAbleToCreateASubIndexerFromFilter), - ("testShouldBeAbleToFilterOnIndexer", testShouldBeAbleToFilterOnIndexer), - ("testShouldThrowErrorForInvalidXML", testShouldThrowErrorForInvalidXML) - ] - } -} - // swiftlint:enable line_length // swiftlint:enable type_body_length diff --git a/Tests/SWXMLHashTests/XMLParsingValidationTests.swift b/Tests/SWXMLHashTests/XMLParsingValidationTests.swift index 5c364df1..c4859cfa 100644 --- a/Tests/SWXMLHashTests/XMLParsingValidationTests.swift +++ b/Tests/SWXMLHashTests/XMLParsingValidationTests.swift @@ -24,7 +24,7 @@ // import SWXMLHash -import XCTest +import Testing extension BasicItem { func validate() throws { @@ -32,7 +32,7 @@ extension BasicItem { } } -class XMLParsingValidationTests: XCTestCase { +struct XMLParsingValidationTests { let xmlToParseOOB = """ the string value @@ -68,36 +68,29 @@ class XMLParsingValidationTests: XCTestCase { """ - func testValidatePriceOutOfBounds() { + @Test + func validatePriceOutOfBounds() { do { let xml = XMLHash.parse(xmlToParseOOB) let _: BasicItem = try xml["root"]["basicItem"].value() - XCTFail("Unexpected lack of exception.") + Issue.record("Unexpected lack of exception.") } catch BasicItemValidation.priceOutOfBounds(let price) { - XCTAssertEqual(price, -99.14, "Unexpected price.") + #expect(price == -99.14, "Unexpected price.") } catch { - XCTFail("Unexpected exception.") + Issue.record("Unexpected exception.") } } - func testValidatePriceInBounds() { + @Test + func validatePriceInBounds() { do { let xml = XMLHash.parse(xmlToParseIB) let value: BasicItem = try xml["root"]["basicItem"].value() - XCTAssertEqual(value.price, 99.14, "Unexpected price.") + #expect(value.price == 99.14, "Unexpected price.") } catch BasicItemValidation.priceOutOfBounds(let price) { - XCTFail("Unexpected BasicItemValidation, the value of \(price) should be valid.") + Issue.record("Unexpected BasicItemValidation, the value of \(price) should be valid.") } catch { - XCTFail("Unexpected exception.") + Issue.record("Unexpected exception.") } } } - -extension XMLParsingValidationTests { - static var allTests: [(String, (XMLParsingValidationTests) -> () throws -> Void)] { - [ - ("testValidatePriceOutOfBounds", testValidatePriceOutOfBounds), - ("testValidatePriceInBounds", testValidatePriceInBounds) - ] - } -} diff --git a/docker-compose.yml b/docker-compose.yml index 2a19da8c..a6ddfde1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,3 @@ -version: '3' services: app: build: .