From de6f7fcdf6cf7ab471aff1c35a1f6f1a0e167965 Mon Sep 17 00:00:00 2001 From: woolie Date: Sat, 3 Apr 2021 16:36:40 -0700 Subject: [PATCH 1/7] Added validate as a test of how validation would work --- .../XMLIndexer+XMLIndexerDeserializable.swift | 122 +++++++++++++++--- 1 file changed, 104 insertions(+), 18 deletions(-) diff --git a/Source/XMLIndexer+XMLIndexerDeserializable.swift b/Source/XMLIndexer+XMLIndexerDeserializable.swift index b3a8f98d..708b4e1f 100644 --- a/Source/XMLIndexer+XMLIndexerDeserializable.swift +++ b/Source/XMLIndexer+XMLIndexerDeserializable.swift @@ -34,6 +34,8 @@ import Foundation public protocol XMLIndexerDeserializable { /// Method for deserializing elements from XMLIndexer static func deserialize(_ element: XMLIndexer) throws -> Self + /// Method for validating elements post deserialization + func validate() throws } /// Provides XMLIndexer deserialization / type transformation support @@ -50,6 +52,12 @@ public extension XMLIndexerDeserializable { throw XMLDeserializationError.implementationIsMissing( method: "XMLIndexerDeserializable.deserialize(element: XMLIndexer)") } + + /** + A default do nothing implementation of validation. + - throws: nothing + */ + func validate() throws {} } // MARK: - XMLElementDeserializable @@ -58,6 +66,8 @@ public extension XMLIndexerDeserializable { public protocol XMLElementDeserializable { /// Method for deserializing elements from XMLElement static func deserialize(_ element: XMLElement) throws -> Self + /// Method for validating elements from XMLElement post deserialization + func validate() throws } /// Provides XMLElement deserialization / type transformation support @@ -74,13 +84,22 @@ public extension XMLElementDeserializable { throw XMLDeserializationError.implementationIsMissing( method: "XMLElementDeserializable.deserialize(element: XMLElement)") } + + /** + A default do nothing implementation of validation. + - throws: nothing + */ + func validate() throws {} } // MARK: - XMLAttributeDeserializable /// Provides XMLAttribute deserialization / type transformation support public protocol XMLAttributeDeserializable { + /// Method for deserializing elements from XMLAttribute static func deserialize(_ attribute: XMLAttribute) throws -> Self + /// Method for validating elements from XMLAttribute post deserialization + func validate() throws } /// Provides XMLAttribute deserialization / type transformation support @@ -97,6 +116,11 @@ public extension XMLAttributeDeserializable { throw XMLDeserializationError.implementationIsMissing( method: "XMLAttributeDeserializable(element: XMLAttribute)") } + /** + A default do nothing implementation of validation. + - throws: nothing + */ + func validate() throws {} } // MARK: - XMLIndexer Extensions @@ -215,7 +239,9 @@ public extension XMLIndexer { func value() throws -> T { switch self { case .element(let element): - return try T.deserialize(element) + let deserialized = try T.deserialize(element) + try deserialized.validate() + return deserialized case .stream(let opStream): return try opStream.findElements().value() default: @@ -232,7 +258,9 @@ public extension XMLIndexer { func value() throws -> T? { switch self { case .element(let element): - return try T.deserialize(element) + let deserialized = try T.deserialize(element) + try deserialized.validate() + return deserialized case .stream(let opStream): return try opStream.findElements().value() default: @@ -249,9 +277,17 @@ public extension XMLIndexer { func value() throws -> [T] { switch self { case .list(let elements): - return try elements.map { try T.deserialize($0) } + return try elements.map { + let deserialized = try T.deserialize($0) + try deserialized.validate() + return deserialized + } case .element(let element): - return try [element].map { try T.deserialize($0) } + return try [element].map { + let deserialized = try T.deserialize($0) + try deserialized.validate() + return deserialized + } case .stream(let opStream): return try opStream.findElements().value() default: @@ -268,9 +304,17 @@ public extension XMLIndexer { func value() throws -> [T]? { switch self { case .list(let elements): - return try elements.map { try T.deserialize($0) } + return try elements.map { + let deserialized = try T.deserialize($0) + try deserialized.validate() + return deserialized + } case .element(let element): - return try [element].map { try T.deserialize($0) } + return try [element].map { + let deserialized = try T.deserialize($0) + try deserialized.validate() + return deserialized + } case .stream(let opStream): return try opStream.findElements().value() default: @@ -287,9 +331,17 @@ public extension XMLIndexer { func value() throws -> [T?] { switch self { case .list(let elements): - return try elements.map { try T.deserialize($0) } + return try elements.map { + let deserialized = try T.deserialize($0) + try deserialized.validate() + return deserialized + } case .element(let element): - return try [element].map { try T.deserialize($0) } + return try [element].map { + let deserialized = try T.deserialize($0) + try deserialized.validate() + return deserialized + } case .stream(let opStream): return try opStream.findElements().value() default: @@ -308,7 +360,9 @@ public extension XMLIndexer { func value() throws -> T { switch self { case .element: - return try T.deserialize(self) + let deserialized = try T.deserialize(self) + try deserialized.validate() + return deserialized case .stream(let opStream): return try opStream.findElements().value() default: @@ -325,7 +379,9 @@ public extension XMLIndexer { func value() throws -> T? { switch self { case .element: - return try T.deserialize(self) + let deserialized = try T.deserialize(self) + try deserialized.validate() + return deserialized case .stream(let opStream): return try opStream.findElements().value() default: @@ -361,9 +417,17 @@ public extension XMLIndexer { func value() throws -> [T]? { switch self { case .list(let elements): - return try elements.map { try T.deserialize( XMLIndexer($0) ) } + return try elements.map { + let deserialized = try T.deserialize(XMLIndexer($0)) + try deserialized.validate() + return deserialized + } case .element(let element): - return try [element].map { try T.deserialize( XMLIndexer($0) ) } + return try [element].map { + let deserialized = try T.deserialize(XMLIndexer($0)) + try deserialized.validate() + return deserialized + } case .stream(let opStream): return try opStream.findElements().value() default: @@ -380,9 +444,17 @@ public extension XMLIndexer { func value() throws -> [T?] { switch self { case .list(let elements): - return try elements.map { try T.deserialize( XMLIndexer($0) ) } + return try elements.map { + let deserialized = try T.deserialize(XMLIndexer($0)) + try deserialized.validate() + return deserialized + } case .element(let element): - return try [element].map { try T.deserialize( XMLIndexer($0) ) } + return try [element].map { + let deserialized = try T.deserialize(XMLIndexer($0)) + try deserialized.validate() + return deserialized + } case .stream(let opStream): return try opStream.findElements().value() default: @@ -483,8 +555,10 @@ extension XMLElement { */ public func value(ofAttribute attr: String) throws -> T { if let attr = self.attribute(by: attr) { - return try T.deserialize(attr) - } else { + let deserialized = try T.deserialize(attr) + try deserialized.validate() + return deserialized + } else { throw XMLDeserializationError.attributeDoesNotExist(element: self, attribute: attr) } } @@ -497,8 +571,10 @@ extension XMLElement { */ public func value(ofAttribute attr: String) -> T? { if let attr = self.attribute(by: attr) { - return try? T.deserialize(attr) - } else { + let deserialized = try? T.deserialize(attr) + if deserialized != nil { try? deserialized?.validate() } + return deserialized + } else { return nil } } @@ -631,6 +707,8 @@ extension String: XMLElementDeserializable, XMLAttributeDeserializable { public static func deserialize(_ attribute: XMLAttribute) -> String { attribute.text } + + public func validate() {} } extension Int: XMLElementDeserializable, XMLAttributeDeserializable { @@ -664,6 +742,8 @@ extension Int: XMLElementDeserializable, XMLAttributeDeserializable { } return value } + + public func validate() {} } extension Double: XMLElementDeserializable, XMLAttributeDeserializable { @@ -697,6 +777,8 @@ extension Double: XMLElementDeserializable, XMLAttributeDeserializable { } return value } + + public func validate() {} } extension Float: XMLElementDeserializable, XMLAttributeDeserializable { @@ -730,6 +812,8 @@ extension Float: XMLElementDeserializable, XMLAttributeDeserializable { } return value } + + public func validate() {} } extension Bool: XMLElementDeserializable, XMLAttributeDeserializable { @@ -762,4 +846,6 @@ extension Bool: XMLElementDeserializable, XMLAttributeDeserializable { return value } // swiftlint:enable line_length + + public func validate() {} } From 6e7d65d8af1fbcea2ad62f310bbb2e2569d36ad1 Mon Sep 17 00:00:00 2001 From: woolie Date: Tue, 6 Apr 2021 13:32:35 -0700 Subject: [PATCH 2/7] Added preliminary validation support --- SWXMLHash.xcodeproj/project.pbxproj | 8 ++ .../XMLIndexer+XMLIndexerDeserializable.swift | 12 +- .../TypeConversionBasicTypesTests.swift | 2 + .../XMLParsingValidationTests.swift | 107 ++++++++++++++++++ 4 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 Tests/SWXMLHashTests/XMLParsingValidationTests.swift diff --git a/SWXMLHash.xcodeproj/project.pbxproj b/SWXMLHash.xcodeproj/project.pbxproj index ff105a37..45f54f95 100644 --- a/SWXMLHash.xcodeproj/project.pbxproj +++ b/SWXMLHash.xcodeproj/project.pbxproj @@ -65,6 +65,9 @@ CDDEC7711BF632DD00AB138B /* SWXMLHash.h in Headers */ = {isa = PBXBuildFile; fileRef = CD6083F4196CA106000B4F8D /* SWXMLHash.h */; settings = {ATTRIBUTES = (Public, ); }; }; CDEA72731C00B0D900C10B28 /* SWXMLHash.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD60840B196CA11D000B4F8D /* SWXMLHash.swift */; }; CDEA72741C00B0E300C10B28 /* SWXMLHash.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD60840B196CA11D000B4F8D /* SWXMLHash.swift */; }; + E25A0776261CF79300C68B90 /* XMLParsingValidationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E25A0775261CF79300C68B90 /* XMLParsingValidationTests.swift */; }; + E25A0777261CF79300C68B90 /* XMLParsingValidationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E25A0775261CF79300C68B90 /* XMLParsingValidationTests.swift */; }; + E25A0778261CF79300C68B90 /* XMLParsingValidationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E25A0775261CF79300C68B90 /* XMLParsingValidationTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -150,6 +153,7 @@ CDDEC74C1BF6311A00AB138B /* SWXMLHash.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SWXMLHash.framework; sourceTree = BUILT_PRODUCTS_DIR; }; CDDEC7551BF6311B00AB138B /* SWXMLHash tvOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SWXMLHash tvOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; CDDEC7681BF6316C00AB138B /* SWXMLHash.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SWXMLHash.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E25A0775261CF79300C68B90 /* XMLParsingValidationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XMLParsingValidationTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -280,6 +284,7 @@ CDC6D13E1D32D98400570DE5 /* TypeConversionPrimitypeTypesTests.swift */, CDC6D11E1D32D70800570DE5 /* WhiteSpaceParsingTests.swift */, CDC6D11A1D32D6CE00570DE5 /* XMLParsingTests.swift */, + E25A0775261CF79300C68B90 /* XMLParsingValidationTests.swift */, ); name = Tests; path = Tests/SWXMLHashTests; @@ -616,6 +621,7 @@ CDC6D12F1D32D79F00570DE5 /* SWXMLHashConfigTests.swift in Sources */, 6C42BED1205183A100137D31 /* shim.swift in Sources */, CDC6D13F1D32D98400570DE5 /* TypeConversionPrimitypeTypesTests.swift in Sources */, + E25A0776261CF79300C68B90 /* XMLParsingValidationTests.swift in Sources */, CDC6D1431D32D9D200570DE5 /* TypeConversionArrayOfNonPrimitiveTypesTests.swift in Sources */, CDC6D11F1D32D70800570DE5 /* WhiteSpaceParsingTests.swift in Sources */, CDC6D1231D32D73900570DE5 /* MixedTextWithXMLElementsTests.swift in Sources */, @@ -645,6 +651,7 @@ CDC6D1301D32D79F00570DE5 /* SWXMLHashConfigTests.swift in Sources */, 6C42BED2205183A100137D31 /* shim.swift in Sources */, CDC6D1401D32D98400570DE5 /* TypeConversionPrimitypeTypesTests.swift in Sources */, + E25A0777261CF79300C68B90 /* XMLParsingValidationTests.swift in Sources */, CDC6D1441D32D9D200570DE5 /* TypeConversionArrayOfNonPrimitiveTypesTests.swift in Sources */, CDC6D1201D32D70800570DE5 /* WhiteSpaceParsingTests.swift in Sources */, CDC6D1241D32D73900570DE5 /* MixedTextWithXMLElementsTests.swift in Sources */, @@ -674,6 +681,7 @@ CDC6D1311D32D79F00570DE5 /* SWXMLHashConfigTests.swift in Sources */, 6C42BED3205183A100137D31 /* shim.swift in Sources */, CDC6D1411D32D98400570DE5 /* TypeConversionPrimitypeTypesTests.swift in Sources */, + E25A0778261CF79300C68B90 /* XMLParsingValidationTests.swift in Sources */, CDC6D1451D32D9D200570DE5 /* TypeConversionArrayOfNonPrimitiveTypesTests.swift in Sources */, CDC6D1211D32D70800570DE5 /* WhiteSpaceParsingTests.swift in Sources */, CDC6D1251D32D73900570DE5 /* MixedTextWithXMLElementsTests.swift in Sources */, diff --git a/Source/XMLIndexer+XMLIndexerDeserializable.swift b/Source/XMLIndexer+XMLIndexerDeserializable.swift index 708b4e1f..31220952 100644 --- a/Source/XMLIndexer+XMLIndexerDeserializable.swift +++ b/Source/XMLIndexer+XMLIndexerDeserializable.swift @@ -398,9 +398,17 @@ public extension XMLIndexer { func value() throws -> [T] where T: XMLIndexerDeserializable { switch self { case .list(let elements): - return try elements.map { try T.deserialize( XMLIndexer($0) ) } + return try elements.map { + let deserialized = try T.deserialize( XMLIndexer($0) ) + try deserialized.validate() + return deserialized + } case .element(let element): - return try [element].map { try T.deserialize( XMLIndexer($0) ) } + return try [element].map { + let deserialized = try T.deserialize( XMLIndexer($0) ) + try deserialized.validate() + return deserialized + } case .stream(let opStream): return try opStream.findElements().value() default: diff --git a/Tests/SWXMLHashTests/TypeConversionBasicTypesTests.swift b/Tests/SWXMLHashTests/TypeConversionBasicTypesTests.swift index 3e5aa015..1feff29c 100644 --- a/Tests/SWXMLHashTests/TypeConversionBasicTypesTests.swift +++ b/Tests/SWXMLHashTests/TypeConversionBasicTypesTests.swift @@ -616,6 +616,8 @@ class TypeConversionBasicTypesTests: XCTestCase { } } +enum BasicItemValidation: Error { case priceOutOfBounds(Double) } + struct BasicItem: XMLIndexerDeserializable { let name: String let price: Double diff --git a/Tests/SWXMLHashTests/XMLParsingValidationTests.swift b/Tests/SWXMLHashTests/XMLParsingValidationTests.swift new file mode 100644 index 00000000..f0373c2e --- /dev/null +++ b/Tests/SWXMLHashTests/XMLParsingValidationTests.swift @@ -0,0 +1,107 @@ +// +// XMLParsingValidationTests.swift +// SWXMLHash +// +// Copyright (c) 2016 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 +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import SWXMLHash +import XCTest + +// swiftlint:disable line_length +// swiftlint:disable file_length +// swiftlint:disable type_body_length + +extension BasicItem { + func validate() throws { + if price < 0 { throw BasicItemValidation.priceOutOfBounds(price) } + } +} + +class XMLParsingValidationTests: XCTestCase { + let xmlToParseOOB = """ + + the string value + 100 + 100.45 + 44.12 + 0 + true + + + the name of basic item + -99.14 + + + + +""" + let xmlToParseIB = """ + + the string value + 100 + 100.45 + 44.12 + 0 + true + + + the name of basic item + 99.14 + + + + +""" + + func testValidatePriceOutOfBounds() { + do { + let xml = SWXMLHash.parse(xmlToParseOOB) + let _: BasicItem = try xml["root"]["basicItem"].value() + XCTFail("Unexpected lack of exception.") + } catch BasicItemValidation.priceOutOfBounds(let price) { + XCTAssertEqual(price, -99.14, "Unexpected price.") + } catch { + XCTFail("Unexpected exception.") + } + } + + func testValidatePriceInBounds() { + do { + let xml = SWXMLHash.parse(xmlToParseIB) + let value: BasicItem = try xml["root"]["basicItem"].value() + XCTAssertEqual(value.price, 99.14, "Unexpected price.") + } catch BasicItemValidation.priceOutOfBounds(let price) { + XCTFail("Unexpected BasicItemValidation, the value of \(price) should be valid.") + } catch { + XCTFail("Unexpected exception.") + } + } +} + +extension XMLParsingValidationTests { + static var allTests: [(String, (XMLParsingValidationTests) -> () throws -> Void)] { + [ + ("testValidatePriceOutOfBounds", testValidatePriceOutOfBounds), + ("testValidatePriceInBounds", testValidatePriceInBounds) + ] + } +} From 7cc86bc3f86e8693b1d3ac1ee95bb0ae9793ea05 Mon Sep 17 00:00:00 2001 From: woolie Date: Tue, 6 Apr 2021 13:41:21 -0700 Subject: [PATCH 3/7] Removed the TABs I put in by mistake --- .../XMLIndexer+XMLIndexerDeserializable.swift | 188 +++++++++--------- 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/Source/XMLIndexer+XMLIndexerDeserializable.swift b/Source/XMLIndexer+XMLIndexerDeserializable.swift index 31220952..a1f6a06e 100644 --- a/Source/XMLIndexer+XMLIndexerDeserializable.swift +++ b/Source/XMLIndexer+XMLIndexerDeserializable.swift @@ -34,8 +34,8 @@ import Foundation public protocol XMLIndexerDeserializable { /// Method for deserializing elements from XMLIndexer static func deserialize(_ element: XMLIndexer) throws -> Self - /// Method for validating elements post deserialization - func validate() throws + /// Method for validating elements post deserialization + func validate() throws } /// Provides XMLIndexer deserialization / type transformation support @@ -53,11 +53,11 @@ public extension XMLIndexerDeserializable { method: "XMLIndexerDeserializable.deserialize(element: XMLIndexer)") } - /** - A default do nothing implementation of validation. - - throws: nothing - */ - func validate() throws {} + /** + A default do nothing implementation of validation. + - throws: nothing + */ + func validate() throws {} } // MARK: - XMLElementDeserializable @@ -66,8 +66,8 @@ public extension XMLIndexerDeserializable { public protocol XMLElementDeserializable { /// Method for deserializing elements from XMLElement static func deserialize(_ element: XMLElement) throws -> Self - /// Method for validating elements from XMLElement post deserialization - func validate() throws + /// Method for validating elements from XMLElement post deserialization + func validate() throws } /// Provides XMLElement deserialization / type transformation support @@ -85,21 +85,21 @@ public extension XMLElementDeserializable { method: "XMLElementDeserializable.deserialize(element: XMLElement)") } - /** - A default do nothing implementation of validation. - - throws: nothing - */ - func validate() throws {} + /** + A default do nothing implementation of validation. + - throws: nothing + */ + func validate() throws {} } // MARK: - XMLAttributeDeserializable /// Provides XMLAttribute deserialization / type transformation support public protocol XMLAttributeDeserializable { - /// Method for deserializing elements from XMLAttribute + /// Method for deserializing elements from XMLAttribute static func deserialize(_ attribute: XMLAttribute) throws -> Self - /// Method for validating elements from XMLAttribute post deserialization - func validate() throws + /// Method for validating elements from XMLAttribute post deserialization + func validate() throws } /// Provides XMLAttribute deserialization / type transformation support @@ -116,11 +116,11 @@ public extension XMLAttributeDeserializable { throw XMLDeserializationError.implementationIsMissing( method: "XMLAttributeDeserializable(element: XMLAttribute)") } - /** - A default do nothing implementation of validation. - - throws: nothing - */ - func validate() throws {} + /** + A default do nothing implementation of validation. + - throws: nothing + */ + func validate() throws {} } // MARK: - XMLIndexer Extensions @@ -240,8 +240,8 @@ public extension XMLIndexer { switch self { case .element(let element): let deserialized = try T.deserialize(element) - try deserialized.validate() - return deserialized + try deserialized.validate() + return deserialized case .stream(let opStream): return try opStream.findElements().value() default: @@ -258,9 +258,9 @@ public extension XMLIndexer { func value() throws -> T? { switch self { case .element(let element): - let deserialized = try T.deserialize(element) - try deserialized.validate() - return deserialized + let deserialized = try T.deserialize(element) + try deserialized.validate() + return deserialized case .stream(let opStream): return try opStream.findElements().value() default: @@ -278,16 +278,16 @@ public extension XMLIndexer { switch self { case .list(let elements): return try elements.map { - let deserialized = try T.deserialize($0) - try deserialized.validate() - return deserialized - } + let deserialized = try T.deserialize($0) + try deserialized.validate() + return deserialized + } case .element(let element): return try [element].map { - let deserialized = try T.deserialize($0) - try deserialized.validate() - return deserialized - } + let deserialized = try T.deserialize($0) + try deserialized.validate() + return deserialized + } case .stream(let opStream): return try opStream.findElements().value() default: @@ -305,16 +305,16 @@ public extension XMLIndexer { switch self { case .list(let elements): return try elements.map { - let deserialized = try T.deserialize($0) - try deserialized.validate() - return deserialized - } + let deserialized = try T.deserialize($0) + try deserialized.validate() + return deserialized + } case .element(let element): return try [element].map { - let deserialized = try T.deserialize($0) - try deserialized.validate() - return deserialized - } + let deserialized = try T.deserialize($0) + try deserialized.validate() + return deserialized + } case .stream(let opStream): return try opStream.findElements().value() default: @@ -332,16 +332,16 @@ public extension XMLIndexer { switch self { case .list(let elements): return try elements.map { - let deserialized = try T.deserialize($0) - try deserialized.validate() - return deserialized - } + let deserialized = try T.deserialize($0) + try deserialized.validate() + return deserialized + } case .element(let element): return try [element].map { - let deserialized = try T.deserialize($0) - try deserialized.validate() - return deserialized - } + let deserialized = try T.deserialize($0) + try deserialized.validate() + return deserialized + } case .stream(let opStream): return try opStream.findElements().value() default: @@ -360,9 +360,9 @@ public extension XMLIndexer { func value() throws -> T { switch self { case .element: - let deserialized = try T.deserialize(self) - try deserialized.validate() - return deserialized + let deserialized = try T.deserialize(self) + try deserialized.validate() + return deserialized case .stream(let opStream): return try opStream.findElements().value() default: @@ -379,9 +379,9 @@ public extension XMLIndexer { func value() throws -> T? { switch self { case .element: - let deserialized = try T.deserialize(self) - try deserialized.validate() - return deserialized + let deserialized = try T.deserialize(self) + try deserialized.validate() + return deserialized case .stream(let opStream): return try opStream.findElements().value() default: @@ -399,16 +399,16 @@ public extension XMLIndexer { switch self { case .list(let elements): return try elements.map { - let deserialized = try T.deserialize( XMLIndexer($0) ) - try deserialized.validate() - return deserialized - } + let deserialized = try T.deserialize( XMLIndexer($0) ) + try deserialized.validate() + return deserialized + } case .element(let element): return try [element].map { - let deserialized = try T.deserialize( XMLIndexer($0) ) - try deserialized.validate() - return deserialized - } + let deserialized = try T.deserialize( XMLIndexer($0) ) + try deserialized.validate() + return deserialized + } case .stream(let opStream): return try opStream.findElements().value() default: @@ -426,16 +426,16 @@ public extension XMLIndexer { switch self { case .list(let elements): return try elements.map { - let deserialized = try T.deserialize(XMLIndexer($0)) - try deserialized.validate() - return deserialized - } + let deserialized = try T.deserialize(XMLIndexer($0)) + try deserialized.validate() + return deserialized + } case .element(let element): return try [element].map { - let deserialized = try T.deserialize(XMLIndexer($0)) - try deserialized.validate() - return deserialized - } + let deserialized = try T.deserialize(XMLIndexer($0)) + try deserialized.validate() + return deserialized + } case .stream(let opStream): return try opStream.findElements().value() default: @@ -453,16 +453,16 @@ public extension XMLIndexer { switch self { case .list(let elements): return try elements.map { - let deserialized = try T.deserialize(XMLIndexer($0)) - try deserialized.validate() - return deserialized - } + let deserialized = try T.deserialize(XMLIndexer($0)) + try deserialized.validate() + return deserialized + } case .element(let element): return try [element].map { - let deserialized = try T.deserialize(XMLIndexer($0)) - try deserialized.validate() - return deserialized - } + let deserialized = try T.deserialize(XMLIndexer($0)) + try deserialized.validate() + return deserialized + } case .stream(let opStream): return try opStream.findElements().value() default: @@ -563,10 +563,10 @@ extension XMLElement { */ public func value(ofAttribute attr: String) throws -> T { if let attr = self.attribute(by: attr) { - let deserialized = try T.deserialize(attr) - try deserialized.validate() - return deserialized - } else { + let deserialized = try T.deserialize(attr) + try deserialized.validate() + return deserialized + } else { throw XMLDeserializationError.attributeDoesNotExist(element: self, attribute: attr) } } @@ -579,10 +579,10 @@ extension XMLElement { */ public func value(ofAttribute attr: String) -> T? { if let attr = self.attribute(by: attr) { - let deserialized = try? T.deserialize(attr) - if deserialized != nil { try? deserialized?.validate() } - return deserialized - } else { + let deserialized = try? T.deserialize(attr) + if deserialized != nil { try? deserialized?.validate() } + return deserialized + } else { return nil } } @@ -716,7 +716,7 @@ extension String: XMLElementDeserializable, XMLAttributeDeserializable { attribute.text } - public func validate() {} + public func validate() {} } extension Int: XMLElementDeserializable, XMLAttributeDeserializable { @@ -751,7 +751,7 @@ extension Int: XMLElementDeserializable, XMLAttributeDeserializable { return value } - public func validate() {} + public func validate() {} } extension Double: XMLElementDeserializable, XMLAttributeDeserializable { @@ -786,7 +786,7 @@ extension Double: XMLElementDeserializable, XMLAttributeDeserializable { return value } - public func validate() {} + public func validate() {} } extension Float: XMLElementDeserializable, XMLAttributeDeserializable { @@ -821,7 +821,7 @@ extension Float: XMLElementDeserializable, XMLAttributeDeserializable { return value } - public func validate() {} + public func validate() {} } extension Bool: XMLElementDeserializable, XMLAttributeDeserializable { @@ -855,5 +855,5 @@ extension Bool: XMLElementDeserializable, XMLAttributeDeserializable { } // swiftlint:enable line_length - public func validate() {} + public func validate() {} } From 023f71f231b0c1ae06f5110d95fe03ae8978ad8d Mon Sep 17 00:00:00 2001 From: woolie Date: Tue, 6 Apr 2021 16:55:32 -0700 Subject: [PATCH 4/7] Removed the SwiftLint commands that were triggering errors but doing nothing --- Tests/SWXMLHashTests/TypeConversionBasicTypesTests.swift | 2 -- .../SWXMLHashTests/TypeConversionPrimitypeTypesTests.swift | 2 -- Tests/SWXMLHashTests/XMLParsingTests.swift | 6 ------ Tests/SWXMLHashTests/XMLParsingValidationTests.swift | 4 ---- 4 files changed, 14 deletions(-) diff --git a/Tests/SWXMLHashTests/TypeConversionBasicTypesTests.swift b/Tests/SWXMLHashTests/TypeConversionBasicTypesTests.swift index 1feff29c..867a10dd 100644 --- a/Tests/SWXMLHashTests/TypeConversionBasicTypesTests.swift +++ b/Tests/SWXMLHashTests/TypeConversionBasicTypesTests.swift @@ -161,7 +161,6 @@ class TypeConversionBasicTypesTests: XCTestCase { XCTAssertNil(value) } - // swiftlint:disable nesting func testShouldConvertAttributeToNonOptionalWithStringRawRepresentable() { enum Keys: String { case string @@ -201,7 +200,6 @@ class TypeConversionBasicTypesTests: XCTestCase { let value: String? = parser!["root"]["attr"].value(ofAttribute: Keys.missing) XCTAssertNil(value) } - // swiftlint:enable nesting func testIntShouldConvertValueToNonOptional() { do { diff --git a/Tests/SWXMLHashTests/TypeConversionPrimitypeTypesTests.swift b/Tests/SWXMLHashTests/TypeConversionPrimitypeTypesTests.swift index 4ede22c2..218c6d4f 100644 --- a/Tests/SWXMLHashTests/TypeConversionPrimitypeTypesTests.swift +++ b/Tests/SWXMLHashTests/TypeConversionPrimitypeTypesTests.swift @@ -167,7 +167,6 @@ class TypeConversionPrimitypeTypesTests: XCTestCase { } } - // swiftlint:disable nesting func testShouldConvertArrayOfAttributeIntsToNonOptionalWithStringRawRepresentable() { enum Keys: String { case value @@ -206,7 +205,6 @@ class TypeConversionPrimitypeTypesTests: XCTestCase { XCTFail("\(error)") } } - // swiftlint:enable nesting func testShouldConvertEmptyArrayOfIntsToNonOptional() { do { diff --git a/Tests/SWXMLHashTests/XMLParsingTests.swift b/Tests/SWXMLHashTests/XMLParsingTests.swift index 18328105..3611b134 100644 --- a/Tests/SWXMLHashTests/XMLParsingTests.swift +++ b/Tests/SWXMLHashTests/XMLParsingTests.swift @@ -75,14 +75,12 @@ class XMLParsingTests: XCTestCase { XCTAssertEqual(xml!["root"]["header"]["title"].element?.text, "Test Title Header") } - // swiftlint:disable nesting func testShouldBeAbleToParseIndividualElementsWithStringRawRepresentable() { enum Keys: String { case root; case header; case title } XCTAssertEqual(xml![Keys.root][Keys.header][Keys.title].element?.text, "Test Title Header") } - // swiftlint:enable nesting func testShouldBeAbleToParseElementGroups() { XCTAssertEqual(xml!["root"]["catalog"]["book"][1]["author"].element?.text, "Ralls, Kim") @@ -100,7 +98,6 @@ class XMLParsingTests: XCTestCase { XCTAssertEqual(xml!["root"]["catalog"]["book"][1].element?.attribute(by: "id")?.text, "bk102") } - // swiftlint:disable nesting // swiftlint:disable identifier_name func testShouldBeAbleToParseAttributesWithStringRawRepresentable() { enum Keys: String { @@ -130,7 +127,6 @@ class XMLParsingTests: XCTestCase { } } - // swiftlint:enable nesting // swiftlint:enable identifier_name func testShouldBeAbleToLookUpElementsByNameAndAttributeCaseInsensitive() { @@ -264,7 +260,6 @@ class XMLParsingTests: XCTestCase { } catch { err = nil } } - // swiftlint:disable nesting /** Added Only test coverage for: `byKey(_ key: K) throws -> XMLIndexer where K.RawValue == String` @@ -283,7 +278,6 @@ class XMLParsingTests: XCTestCase { err = error } catch { err = nil } } - // swiftlint:enable nesting func testShouldProvideAnErrorElementWhenIndexersDontMatch() { var err: IndexingError? diff --git a/Tests/SWXMLHashTests/XMLParsingValidationTests.swift b/Tests/SWXMLHashTests/XMLParsingValidationTests.swift index f0373c2e..bf37b9f2 100644 --- a/Tests/SWXMLHashTests/XMLParsingValidationTests.swift +++ b/Tests/SWXMLHashTests/XMLParsingValidationTests.swift @@ -26,10 +26,6 @@ import SWXMLHash import XCTest -// swiftlint:disable line_length -// swiftlint:disable file_length -// swiftlint:disable type_body_length - extension BasicItem { func validate() throws { if price < 0 { throw BasicItemValidation.priceOutOfBounds(price) } From c996b3877adacc1853325b0514da5740ea513251 Mon Sep 17 00:00:00 2001 From: Steven Woolgar Date: Mon, 12 Apr 2021 15:46:20 -0700 Subject: [PATCH 5/7] Update lint.yml --- .github/workflows/lint.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ae23d061..84a214a8 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -9,10 +9,8 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - name: GitHub Action for SwiftLint - uses: norio-nomura/action-swiftlint@3.0.1 - - name: GitHub Action for SwiftLint with --strict - uses: norio-nomura/action-swiftlint@3.0.1 + - uses: actions/checkout@v2 + - name: SwiftLint + uses: norio-nomura/action-swiftlint@3.2.1 with: args: --strict From 6ba47d32ede6396809e361e8f5cc5edc2ab55681 Mon Sep 17 00:00:00 2001 From: Steven Woolgar Date: Mon, 12 Apr 2021 15:47:50 -0700 Subject: [PATCH 6/7] Update .swift-version --- .swift-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.swift-version b/.swift-version index a75b92f1..d346e2ab 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -5.1 +5.3 From 82f04ed8ef8bff059f2cbededc3b714f1750b050 Mon Sep 17 00:00:00 2001 From: Steven Woolgar Date: Mon, 12 Apr 2021 16:04:48 -0700 Subject: [PATCH 7/7] Update main.yml --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 90e8fe1d..1e14329f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -18,7 +18,7 @@ jobs: run: | set -o pipefail xcodebuild $ACTION $WORKSPACE -scheme "SWXMLHash OSX" | xcpretty - xcodebuild $ACTION $WORKSPACE -scheme "SWXMLHash iOS" -sdk iphonesimulator -destination "OS=14.3,name=iPhone 12" | xcpretty + xcodebuild $ACTION $WORKSPACE -scheme "SWXMLHash iOS" -sdk iphonesimulator -destination "OS=14.4,name=iPhone 12" | 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}}