From 20581ab989c36617ffee528d0e2b24b14141d31b Mon Sep 17 00:00:00 2001 From: Sammy Smallman Date: Tue, 4 Jun 2024 19:53:52 +0100 Subject: [PATCH] 2.0.0 (#15) Signed-off-by: Sam Smallman --- .../xcshareddata/xcschemes/CoreOSC.xcscheme | 2 +- Package.swift | 2 +- README.md | 2 +- Sources/CoreOSC/CoreOSC.swift | 2 +- Sources/CoreOSC/Extensions/Character.swift | 34 ++- Sources/CoreOSC/Extensions/Numeric.swift | 45 ++-- Sources/CoreOSC/Extensions/String.swift | 30 ++- Sources/CoreOSC/Extensions/UInt32.swift | 30 ++- Sources/CoreOSC/LICENSE.md | 2 +- Sources/CoreOSC/OSCAddress.swift | 2 +- Sources/CoreOSC/OSCAddressError.swift | 2 +- Sources/CoreOSC/OSCAddressFilter.swift | 2 +- Sources/CoreOSC/OSCAddressPattern.swift | 4 +- Sources/CoreOSC/OSCAddressSpace.swift | 2 +- Sources/CoreOSC/OSCAnnotation.swift | 42 ++-- Sources/CoreOSC/OSCArgument.swift | 81 ++++++- Sources/CoreOSC/OSCArgumentError.swift | 38 ++++ Sources/CoreOSC/OSCBundle.swift | 45 ++-- Sources/CoreOSC/OSCFilterAddress.swift | 2 +- Sources/CoreOSC/OSCFilterMethod.swift | 2 +- Sources/CoreOSC/OSCMatch.swift | 2 +- Sources/CoreOSC/OSCMessage.swift | 104 +++++++-- Sources/CoreOSC/OSCMethod.swift | 2 +- Sources/CoreOSC/OSCPacket.swift | 19 +- Sources/CoreOSC/OSCParser.swift | 44 ++-- Sources/CoreOSC/OSCParserError.swift | 2 +- Sources/CoreOSC/OSCPatternMatch.swift | 2 +- Sources/CoreOSC/OSCRefractingAddress.swift | 2 +- Sources/CoreOSC/OSCTimeTag.swift | 12 +- Sources/CoreOSC/en.lproj/Localizable.strings | 11 +- Tests/CoreOSCTests/CoreOSCTests.swift | 6 +- .../CoreOSCTests/OSCAddressFilterTests.swift | 2 +- .../CoreOSCTests/OSCAddressPatternTests.swift | 2 +- Tests/CoreOSCTests/OSCAddressSpaceTests.swift | 17 +- Tests/CoreOSCTests/OSCAddressTests.swift | 2 +- Tests/CoreOSCTests/OSCAnnotationTests.swift | 116 ++++------ Tests/CoreOSCTests/OSCBundleTests.swift | 28 +-- .../CoreOSCTests/OSCFilterAddressTests.swift | 2 +- Tests/CoreOSCTests/OSCFilterMethodTests.swift | 14 +- Tests/CoreOSCTests/OSCMatchTests.swift | 2 +- Tests/CoreOSCTests/OSCMessageTests.swift | 204 ++++++++++-------- Tests/CoreOSCTests/OSCMethodTests.swift | 19 +- .../OSCRefractingAddressTests.swift | 2 +- 43 files changed, 593 insertions(+), 394 deletions(-) create mode 100644 Sources/CoreOSC/OSCArgumentError.swift diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/CoreOSC.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/CoreOSC.xcscheme index d72685d..744a4a7 100644 --- a/.swiftpm/xcode/xcshareddata/xcschemes/CoreOSC.xcscheme +++ b/.swiftpm/xcode/xcshareddata/xcschemes/CoreOSC.xcscheme @@ -1,6 +1,6 @@ . +// + import Foundation public extension Character { static let oscTypeTagString: Character = "s" - static let oscTypeTagInt: Character = "i" - static let oscTypeTagFloat: Character = "f" + static let oscTypeTagInt32: Character = "i" + static let oscTypeTagFloat32: Character = "f" static let oscTypeTagBlob: Character = "b" static let oscTypeTagTimeTag: Character = "t" static let oscTypeTagTrue: Character = "T" diff --git a/Sources/CoreOSC/Extensions/Numeric.swift b/Sources/CoreOSC/Extensions/Numeric.swift index 0cc086a..df69fc8 100644 --- a/Sources/CoreOSC/Extensions/Numeric.swift +++ b/Sources/CoreOSC/Extensions/Numeric.swift @@ -3,34 +3,41 @@ // CoreOSC // // Created by Sam Smallman on 18/07/2021. -// Copyright © 2020 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // -// 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: +// This file is part of CoreOSC // -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. +// CoreOSC is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. // -// 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. +// CoreOSC is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. // +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + import Foundation -extension Numeric { +extension UInt32 { + + var data: Data { + var source = self + return Data(bytes: &source, count: MemoryLayout.size) + } + +} + +extension Int32 { - internal var data: Data { + var data: Data { var source = self - return Data(bytes: &source, count: MemoryLayout.size) + return Data(bytes: &source, count: MemoryLayout.size) } } diff --git a/Sources/CoreOSC/Extensions/String.swift b/Sources/CoreOSC/Extensions/String.swift index 6105833..e671b0a 100644 --- a/Sources/CoreOSC/Extensions/String.swift +++ b/Sources/CoreOSC/Extensions/String.swift @@ -3,26 +3,24 @@ // CoreOSC // // Created by Sam Smallman on 18/07/2021. -// Copyright © 2020 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // -// 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: +// This file is part of CoreOSC // -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. +// CoreOSC is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. // -// 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. +// CoreOSC is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. // +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + import Foundation diff --git a/Sources/CoreOSC/Extensions/UInt32.swift b/Sources/CoreOSC/Extensions/UInt32.swift index 1128951..e6abae4 100644 --- a/Sources/CoreOSC/Extensions/UInt32.swift +++ b/Sources/CoreOSC/Extensions/UInt32.swift @@ -3,26 +3,24 @@ // CoreOSC // // Created by Sam Smallman on 18/07/2021. -// Copyright © 2020 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // -// 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: +// This file is part of CoreOSC // -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. +// CoreOSC is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. // -// 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. +// CoreOSC is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. // +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + import Foundation diff --git a/Sources/CoreOSC/LICENSE.md b/Sources/CoreOSC/LICENSE.md index 4e11011..f4a69e4 100644 --- a/Sources/CoreOSC/LICENSE.md +++ b/Sources/CoreOSC/LICENSE.md @@ -1,4 +1,4 @@ -Copyright © 2023 Sam Smallman. https://github.com/SammySmallman +Copyright © 2021 Sam Smallman. https://github.com/SammySmallman This file is part of CoreOSC diff --git a/Sources/CoreOSC/OSCAddress.swift b/Sources/CoreOSC/OSCAddress.swift index be6a022..5386a3a 100644 --- a/Sources/CoreOSC/OSCAddress.swift +++ b/Sources/CoreOSC/OSCAddress.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 26/07/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // diff --git a/Sources/CoreOSC/OSCAddressError.swift b/Sources/CoreOSC/OSCAddressError.swift index 05d0f10..74204b9 100644 --- a/Sources/CoreOSC/OSCAddressError.swift +++ b/Sources/CoreOSC/OSCAddressError.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 29/07/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // diff --git a/Sources/CoreOSC/OSCAddressFilter.swift b/Sources/CoreOSC/OSCAddressFilter.swift index 3b1f556..b294167 100644 --- a/Sources/CoreOSC/OSCAddressFilter.swift +++ b/Sources/CoreOSC/OSCAddressFilter.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 13/08/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // diff --git a/Sources/CoreOSC/OSCAddressPattern.swift b/Sources/CoreOSC/OSCAddressPattern.swift index eb74492..8286867 100644 --- a/Sources/CoreOSC/OSCAddressPattern.swift +++ b/Sources/CoreOSC/OSCAddressPattern.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 29/07/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // @@ -24,7 +24,7 @@ import Foundation /// An object that represents the full path to one or more OSC Methods through pattern matching. -public struct OSCAddressPattern: Hashable, Equatable { +public struct OSCAddressPattern: Hashable, Equatable, Sendable { /// The full path to one or more OSC Methods. public let fullPath: String diff --git a/Sources/CoreOSC/OSCAddressSpace.swift b/Sources/CoreOSC/OSCAddressSpace.swift index 5853e18..1f2dfea 100644 --- a/Sources/CoreOSC/OSCAddressSpace.swift +++ b/Sources/CoreOSC/OSCAddressSpace.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 10/08/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // diff --git a/Sources/CoreOSC/OSCAnnotation.swift b/Sources/CoreOSC/OSCAnnotation.swift index dc28c4e..b73b611 100644 --- a/Sources/CoreOSC/OSCAnnotation.swift +++ b/Sources/CoreOSC/OSCAnnotation.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 22/07/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // @@ -88,7 +88,7 @@ public struct OSCAnnotation { // There should only be one match. Range at index 1 will always be the address pattern. // If there are arguments these will be found at index 2, // prefaced with "=" and index 3 if there are more than one argument. - var arguments: [OSCArgumentProtocol] = [] + var arguments: [OSCArgument] = [] guard let match = matches.first, match.range == annotation.nsrange, let address = annotation.substring(with: match.range(at: 1)) else { return nil } if var argumentString = annotation.substring(with: match.range(at: 2)) { @@ -102,22 +102,22 @@ public struct OSCAnnotation { if let decimal = Decimal(string: argument, locale: Locale(identifier: "en_US")) { if decimal.isZero || (decimal.isNormal && decimal.exponent >= 0), let int = Int32(argument) { - arguments.append(int) + arguments.append(.int32(int)) } else if let float = Float32(argument) { - arguments.append(float) + arguments.append(.float32(float)) } else { - arguments.append(argument) + arguments.append(.string(argument)) } } else { switch argument { case "true": - arguments.append(true) + arguments.append(.true) case "false": - arguments.append(false) + arguments.append(.false) case "nil": - arguments.append(OSCArgument.nil) + arguments.append(.nil) case "impulse": - arguments.append(OSCArgument.impulse) + arguments.append(.impulse) default: // If the argument is prefaced with quotation marks, // the regex dictates the argument should close with them. @@ -126,9 +126,9 @@ public struct OSCAnnotation { var quoationMarkArgument = argument quoationMarkArgument.removeFirst() quoationMarkArgument.removeLast() - arguments.append(quoationMarkArgument) + arguments.append(.string(quoationMarkArgument)) } else { - arguments.append(argument) + arguments.append(.string(argument)) } } @@ -151,7 +151,7 @@ public struct OSCAnnotation { range: annotation.nsrange) // There should only be one match. Range at index 1 will always be the address pattern. // Range at index 2 will be the argument string prefaced with " " - var arguments: [OSCArgumentProtocol] = [] + var arguments: [OSCArgument] = [] guard let match = matches.first, match.range == annotation.nsrange, let address = annotation.substring(with: match.range(at: 1)), let argumentString = annotation.substring(with: match.range(at: 2)) else { @@ -176,22 +176,22 @@ public struct OSCAnnotation { if argument.quoted == false, let decimal = Decimal(string: argument.string, locale: Locale(identifier: "en_US")) { if decimal.isZero || (decimal.isNormal && decimal.exponent >= 0), let int = Int32(argument.string) { - arguments.append(int) + arguments.append(.int32(int)) } else if let float = Float32(argument.string) { - arguments.append(float) + arguments.append(.float32(float)) } else { - arguments.append(argument.string) + arguments.append(.string(argument.string)) } } else { switch argument.string { case "true": - argument.quoted ? arguments.append("true") : arguments.append(true) + argument.quoted ? arguments.append(.string("true")) : arguments.append(.true) case "false": - argument.quoted ? arguments.append("false") : arguments.append(false) + argument.quoted ? arguments.append(.string("false")) : arguments.append(.false) case "nil": - argument.quoted ? arguments.append("nil") : arguments.append(OSCArgument.nil) + argument.quoted ? arguments.append(.string("nil")) : arguments.append(.nil) case "impulse": - argument.quoted ? arguments.append("impulse") : arguments.append(OSCArgument.impulse) + argument.quoted ? arguments.append(.string("impulse")) : arguments.append(.impulse) default: // If the argument is prefaced with quotation marks, // the regex dictates the argument should close with them. @@ -200,9 +200,9 @@ public struct OSCAnnotation { var quoationMarkArgument = argument.string quoationMarkArgument.removeFirst() quoationMarkArgument.removeLast() - arguments.append(quoationMarkArgument) + arguments.append(.string(quoationMarkArgument)) } else { - arguments.append(argument.string) + arguments.append(.string(argument.string)) } } } diff --git a/Sources/CoreOSC/OSCArgument.swift b/Sources/CoreOSC/OSCArgument.swift index 80ee351..b0782c7 100644 --- a/Sources/CoreOSC/OSCArgument.swift +++ b/Sources/CoreOSC/OSCArgument.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 26/07/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // @@ -25,7 +25,7 @@ import Foundation import CoreGraphics /// An OSC Argument. -public protocol OSCArgumentProtocol { +public protocol OSCArgumentProtocol: Sendable { /// The OSC data representation for the argument conforming to the protocol. var oscData: Data { get } @@ -38,29 +38,90 @@ public protocol OSCArgumentProtocol { } -public enum OSCArgument: OSCArgumentProtocol, CustomStringConvertible { +public enum OSCArgument: OSCArgumentProtocol, CustomStringConvertible, Equatable { + case int32(Int32) + case float32(Float32) + case string(String) + case blob(Data) + case `true` + case `false` case `nil` case impulse + case timeTag(OSCTimeTag) public var description: String { switch self { + case let .int32(value): return value.description + case let .float32(value): return value.description + case let .string(value): return value + case let .blob(value): return value.description + case .true: return "true" + case .false: return "false" case .nil: return "nil" case .impulse: return "impulse" + case let .timeTag(value): return value.description } } - public var oscData: Data { Data() } + public var oscData: Data { + switch self { + case .int32(let value): + return value.oscData + case .float32(let value): + return value.oscData + case .string(let value): + return value.oscData + case .blob(let value): + return value.oscData + case .true: + return Data() + case .false: + return Data() + case .nil: + return Data() + case .impulse: + return Data() + case let .timeTag(value): + return value.oscData + } + } public var oscTypeTag: Character { switch self { + case .int32: return .oscTypeTagInt32 + case .float32: return .oscTypeTagFloat32 + case .string: return .oscTypeTagString + case .blob: return .oscTypeTagBlob + case .true: return .oscTypeTagTrue + case .false: return .oscTypeTagFalse case .nil: return .oscTypeTagNil case .impulse: return .oscTypeTagImpulse + case .timeTag: return .oscTypeTagTimeTag } } public func oscAnnotation(withType type: Bool) -> String { - "\(self)\(type ? "(\(oscTypeTag))" : "")" + switch self { + case let .int32(int32): + return int32.oscAnnotation(withType: type) + case let .float32(float32): + return float32.oscAnnotation(withType: type) + case let .string(string): + return string.oscAnnotation(withType: type) + case let .blob(data): + return data.oscAnnotation(withType: type) + case .true: + return "true\(type ? "(\(Character.oscTypeTagTrue))" : "")" + case .false: + return "false\(type ? "(\(Character.oscTypeTagFalse))" : "")" + case .nil: + return "nil\(type ? "(\(Character.oscTypeTagNil))" : "")" + case .impulse: + return "impulse\(type ? "(\(Character.oscTypeTagImpulse))" : "")" + case let .timeTag(timeTag): + return timeTag.oscAnnotation(withType: type) + } } } @@ -69,7 +130,7 @@ extension Int32: OSCArgumentProtocol { public var oscData: Data { self.bigEndian.data } - public var oscTypeTag: Character { .oscTypeTagInt } + public var oscTypeTag: Character { .oscTypeTagInt32 } public func oscAnnotation(withType type: Bool = true) -> String { "\(self)\(type ? "(\(oscTypeTag))" : "")" @@ -86,7 +147,7 @@ extension Int: OSCArgumentProtocol { return int.bigEndian.data } - public var oscTypeTag: Character { .oscTypeTagInt } + public var oscTypeTag: Character { .oscTypeTagInt32 } public func oscAnnotation(withType type: Bool = true) -> String { let int = Int32(exactly: self) ?? 0 @@ -108,7 +169,7 @@ extension Float32: OSCArgumentProtocol { return Data(result) } - public var oscTypeTag: Character { .oscTypeTagFloat } + public var oscTypeTag: Character { .oscTypeTagFloat32 } public func oscAnnotation(withType type: Bool = true) -> String { "\(self)\(type ? "(\(oscTypeTag))" : "")" @@ -130,7 +191,7 @@ extension Double: OSCArgumentProtocol { return Data(result) } - public var oscTypeTag: Character { .oscTypeTagFloat } + public var oscTypeTag: Character { .oscTypeTagFloat32 } public func oscAnnotation(withType type: Bool = true) -> String { "\(self)\(type ? "(\(oscTypeTag))" : "")" @@ -152,7 +213,7 @@ extension CGFloat: OSCArgumentProtocol { return Data(result) } - public var oscTypeTag: Character { .oscTypeTagFloat } + public var oscTypeTag: Character { .oscTypeTagFloat32 } public func oscAnnotation(withType type: Bool = true) -> String { "\(self)\(type ? "(\(oscTypeTag))" : "")" diff --git a/Sources/CoreOSC/OSCArgumentError.swift b/Sources/CoreOSC/OSCArgumentError.swift new file mode 100644 index 0000000..e68c022 --- /dev/null +++ b/Sources/CoreOSC/OSCArgumentError.swift @@ -0,0 +1,38 @@ +// +// OSCArgumentError.swift +// CoreOSC +// +// Created by Sam Smallman on 26/02/2024. +// Copyright © 2024 Sam Smallman. https://github.com/SammySmallman +// +// This file is part of CoreOSC +// +// CoreOSC is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// CoreOSC is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +import Foundation + +public enum OSCArgumentError: Error { + case invalidArgument +} + +extension OSCArgumentError: LocalizedError { + public var errorDescription: String? { + switch self { + case .invalidArgument: + return NSLocalizedString("OSC_ARGUMENT_ERROR_INVALID_ARGUMENT", bundle: .module, comment: "OSC Argument Error: Invalid Argument") + } + } +} + diff --git a/Sources/CoreOSC/OSCBundle.swift b/Sources/CoreOSC/OSCBundle.swift index d9d1b48..98d9501 100644 --- a/Sources/CoreOSC/OSCBundle.swift +++ b/Sources/CoreOSC/OSCBundle.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 22/07/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // @@ -24,16 +24,17 @@ import Foundation /// An OSC Bundle. -public struct OSCBundle: OSCPacket { +public struct OSCBundle: Sendable, Equatable { /// The bundles time tag used to indicate ///when it's contained elements should be invoked public var timeTag: OSCTimeTag - + /// The bundles elements. The contents are either `OSCMessage` or `OSCBundle`. - /// Note that a bundle may contain bundles. + /// + /// - Note: A bundle may contain bundles. public var elements: [OSCPacket] - + /// An OSC Bundle. /// - Parameters: /// - elements: The elements contained by the bundle. @@ -43,24 +44,41 @@ public struct OSCBundle: OSCPacket { self.elements = elements } + public static func == (lhs: OSCBundle, rhs: OSCBundle) -> Bool { + guard lhs.timeTag == rhs.timeTag, + lhs.elements.count == rhs.elements.count + else { return false } + for (index, element) in lhs.elements.enumerated() { + switch element { + case let .message(lhsMessage): + guard case let .message(rhsMessage) = rhs.elements[index], + lhsMessage == rhsMessage else { return false } + continue + case let .bundle(lhsBundle): + guard case let .bundle(rhsBundle) = rhs.elements[index], + lhsBundle == rhsBundle else { return false } + continue + } + } + return true + } + /// The OSC Packet data for the bundle. public func data() -> Data { var result = "#bundle".oscData result.append(timeTag.oscData) for element in elements { - if let message = element as? OSCMessage { + switch element { + case let .message(message): let data = message.data() let size = withUnsafeBytes(of: Int32(data.count).bigEndian) { Data($0) } result.append(size) result.append(data) - continue - } - if let bundle = element as? OSCBundle { + case let .bundle(bundle): let data = bundle.data() let size = withUnsafeBytes(of: Int32(data.count).bigEndian) { Data($0) } result.append(size) result.append(data) - continue } } return result @@ -70,12 +88,11 @@ public struct OSCBundle: OSCPacket { /// - Returns: An array of `OSCMessage`'s. public func flatten() -> [OSCMessage] { elements.reduce([OSCMessage]()) { - if let message = $1 as? OSCMessage { + switch $1 { + case let .message(message): return $0 + [message] - } else if let bundle = $1 as? OSCBundle { + case let .bundle(bundle): return $0 + bundle.flatten() - } else { - return $0 } } } diff --git a/Sources/CoreOSC/OSCFilterAddress.swift b/Sources/CoreOSC/OSCFilterAddress.swift index a9a6ec5..10fa0e6 100644 --- a/Sources/CoreOSC/OSCFilterAddress.swift +++ b/Sources/CoreOSC/OSCFilterAddress.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 13/08/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // diff --git a/Sources/CoreOSC/OSCFilterMethod.swift b/Sources/CoreOSC/OSCFilterMethod.swift index be04978..f382126 100644 --- a/Sources/CoreOSC/OSCFilterMethod.swift +++ b/Sources/CoreOSC/OSCFilterMethod.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 13/08/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // diff --git a/Sources/CoreOSC/OSCMatch.swift b/Sources/CoreOSC/OSCMatch.swift index ee2078b..9b4a4f3 100644 --- a/Sources/CoreOSC/OSCMatch.swift +++ b/Sources/CoreOSC/OSCMatch.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 31/07/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // diff --git a/Sources/CoreOSC/OSCMessage.swift b/Sources/CoreOSC/OSCMessage.swift index a774887..fd586b5 100644 --- a/Sources/CoreOSC/OSCMessage.swift +++ b/Sources/CoreOSC/OSCMessage.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 22/07/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // @@ -24,7 +24,7 @@ import Foundation /// An OSC Message. -public struct OSCMessage: OSCPacket, Equatable { +public struct OSCMessage: Sendable, Equatable { public static func == (lhs: OSCMessage, rhs: OSCMessage) -> Bool { lhs.addressPattern == rhs.addressPattern && @@ -35,29 +35,29 @@ public struct OSCMessage: OSCPacket, Equatable { /// The OSC Address Pattern associated with the message that represents the full path to one /// or more OSC Methods through pattern matching. public private(set) var addressPattern: OSCAddressPattern - + /// A sequence of type tag characters corresponding exactly to the sequence of OSC Arguments in the message. public var typeTagString: String { "\(arguments.map { String($0.oscTypeTag) }.joined())" } - + /// The `Array` of arguments associated with the message. - public let arguments: [OSCArgumentProtocol] - - /// An OSC Message from a raw OSC Address Pattern. + public let arguments: [OSCArgument] + + /// An OSC Message from a raw, not evaluated, OSC Address Pattern. /// - Parameters: /// - addressPattern: The message's OSC Address Pattern. /// - arguments: The message's `Array` of arguments. - internal init(raw addressPattern: String, arguments: [OSCArgumentProtocol] = []) { + public init(raw addressPattern: String, arguments: [OSCArgument] = []) { let fullPath = OSCAddressPattern(raw: addressPattern) self.addressPattern = fullPath self.arguments = arguments } - + /// An OSC Message. /// - Parameters: /// - addressPattern: The messages OSC Address Pattern. /// - arguments: The messages `Array` of arguments. /// - Throws: An `OSCAddressError` if the given `addressPattern` can not be initialized as a `OSCAddressPattern`. - public init(with addressPattern: String, arguments: [OSCArgumentProtocol] = []) throws { + public init(with addressPattern: String, arguments: [OSCArgument] = []) throws { let fullPath = try OSCAddressPattern(addressPattern) self.init(with: fullPath, arguments: arguments) } @@ -66,11 +66,30 @@ public struct OSCMessage: OSCPacket, Equatable { /// - Parameters: /// - addressPattern: The messages OSC Address Pattern. /// - arguments: The messages `Array` of arguments. - public init(with addressPattern: OSCAddressPattern, arguments: [OSCArgumentProtocol] = []) { + /// - Throws: An `OSCAddressError` if the given `addressPattern` can not be initialized as a `OSCAddressPattern`. + public init(with addressPattern: String, arguments anyArguments: [any OSCArgumentProtocol] = []) throws { + let fullPath = try OSCAddressPattern(addressPattern) + self.init(with: fullPath, arguments: try Self.arguments(from: anyArguments)) + } + + /// An OSC Message. + /// - Parameters: + /// - addressPattern: The messages OSC Address Pattern. + /// - arguments: The messages `Array` of arguments. + public init(with addressPattern: OSCAddressPattern, arguments: [OSCArgument] = []) { self.addressPattern = addressPattern self.arguments = arguments } - + + /// An OSC Message. + /// - Parameters: + /// - addressPattern: The messages OSC Address Pattern. + /// - arguments: The messages `Array` of arguments. + public init(with addressPattern: OSCAddressPattern, arguments anyArguments: [OSCArgumentProtocol] = []) throws { + self.addressPattern = addressPattern + self.arguments = try Self.arguments(from: anyArguments) + } + /// Readdress the message to a new OSC Address Pattern. /// - Parameter addressPattern: The new OSC Address Pattern. /// - Throws: An `OSCAddressError` if the given `addressPattern` can not be initialized as a `OSCAddressPattern`. @@ -92,7 +111,7 @@ public struct OSCMessage: OSCPacket, Equatable { arguments.forEach { result.append($0.oscData) } return result } - + /// Pattern match the message against an OSC Address. /// - Parameter address: An OSC Address to be matched against. /// - Returns: A `Result` that represents either the given address matches, returning success, @@ -109,4 +128,63 @@ public struct OSCMessage: OSCPacket, Equatable { } } + private static func arguments(from arguments: [any OSCArgumentProtocol]) throws -> [OSCArgument] { + try arguments.compactMap { argument in + switch argument.oscTypeTag { + case .oscTypeTagString: + guard let value = argument as? String else { + throw OSCArgumentError.invalidArgument + } + return .string(value) + case .oscTypeTagInt32: + if let value = argument as? Int32 { + return .int32(value) + } else if let value = argument as? Int { + return .int32(Int32(value)) + } + throw OSCArgumentError.invalidArgument + case .oscTypeTagFloat32: + if let value = argument as? Float32 { + return .float32(value) + } else if let value = argument as? Double { + return .float32(Float32(value)) + } else if let value = argument as? CGFloat { + return .float32(Float32(value)) + } + throw OSCArgumentError.invalidArgument + case .oscTypeTagBlob: + guard let value = argument as? Data else { + throw OSCArgumentError.invalidArgument + } + return .blob(value) + case .oscTypeTagTimeTag: + guard let value = argument as? OSCTimeTag else { + throw OSCArgumentError.invalidArgument + } + return .timeTag(value) + case .oscTypeTagTrue: + guard let value = argument as? Bool, value == true else { + throw OSCArgumentError.invalidArgument + } + return .true + case .oscTypeTagFalse: + guard let value = argument as? Bool, value == false else { + throw OSCArgumentError.invalidArgument + } + return .false + case .oscTypeTagNil: + guard let value = argument as? OSCArgument, case .nil = value else { + throw OSCArgumentError.invalidArgument + } + return .nil + case .oscTypeTagImpulse: + guard let value = argument as? OSCArgument, case .impulse = value else { + throw OSCArgumentError.invalidArgument + } + return .impulse + default: throw OSCArgumentError.invalidArgument + } + } + } + } diff --git a/Sources/CoreOSC/OSCMethod.swift b/Sources/CoreOSC/OSCMethod.swift index 4370bab..f0ead2d 100644 --- a/Sources/CoreOSC/OSCMethod.swift +++ b/Sources/CoreOSC/OSCMethod.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 10/08/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // diff --git a/Sources/CoreOSC/OSCPacket.swift b/Sources/CoreOSC/OSCPacket.swift index 589ebdd..58eda90 100644 --- a/Sources/CoreOSC/OSCPacket.swift +++ b/Sources/CoreOSC/OSCPacket.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 22/07/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // @@ -24,9 +24,20 @@ import Foundation /// An OSC Packet, either an `OSCMessage` or `OSCBundle`. -public protocol OSCPacket { +@frozen public enum OSCPacket: Sendable, Equatable { + /// An OSC Message. + case message(OSCMessage) + /// An OSC Bundle. + case bundle(OSCBundle) - /// The OSC data representation for the packet conforming to the protocol. - func data() -> Data + /// The OSC data representation for the packet. + public func data() -> Data { + switch self { + case let .message(message): + return message.data() + case let .bundle(bundle): + return bundle.data() + } + } } diff --git a/Sources/CoreOSC/OSCParser.swift b/Sources/CoreOSC/OSCParser.swift index 49a01a2..c0df5fa 100644 --- a/Sources/CoreOSC/OSCParser.swift +++ b/Sources/CoreOSC/OSCParser.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 22/07/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // @@ -66,7 +66,7 @@ public enum OSCParser { /// - startIndex: The index of where to start parsing the `Data` from. /// - Throws: An `OSCParserError` if the `Data` could not be parsed. /// - Returns: An `OSCMessage`. - private static func parseOSCMessage(with data: Data, startIndex: inout Int) throws -> OSCMessage { + private static func parseOSCMessage(with data: Data, startIndex: inout Int) throws -> OSCPacket { guard let addressPattern = parse(string: data, startIndex: &startIndex, characters: .invalid(bytes: [ @@ -94,7 +94,7 @@ public enum OSCParser { // If the Type Tag String starts with "," and has 1 or more characters after, // we possibly have some arguments. - var arguments: [OSCArgumentProtocol] = [] + var arguments: [OSCArgument] = [] if typeTagString.first == "," && typeTagString.count > 1 { // Remove "," as we will iterate over the different type of tags. typeTagString.removeFirst() @@ -105,46 +105,46 @@ public enum OSCParser { startIndex: &startIndex) else { throw OSCParserError.cantParseString } - arguments.append(stringArgument) - case .oscTypeTagInt: + arguments.append(.string(stringArgument)) + case .oscTypeTagInt32: guard let intArgument = parse(int32: data, startIndex: &startIndex) else { throw OSCParserError.cantParseInt32 } - arguments.append(intArgument) - case .oscTypeTagFloat: + arguments.append(.int32(intArgument)) + case .oscTypeTagFloat32: guard let floatArgument = parse(float32: data, startIndex: &startIndex) else { throw OSCParserError.cantParseFloat32 } - arguments.append(floatArgument) + arguments.append(.float32(floatArgument)) case .oscTypeTagBlob: guard let blobArgument = parse(blob: data, startIndex: &startIndex) else { throw OSCParserError.cantParseBlob } - arguments.append(blobArgument) + arguments.append(.blob(blobArgument)) case .oscTypeTagTimeTag: guard let timeTagArgument = parse(timeTag: data, startIndex: &startIndex) else { throw OSCParserError.cantParseTimeTag } - arguments.append(timeTagArgument) + arguments.append(.timeTag(timeTagArgument)) case .oscTypeTagTrue: - arguments.append(true) + arguments.append(.true) case .oscTypeTagFalse: - arguments.append(false) + arguments.append(.false) case .oscTypeTagNil: - arguments.append(OSCArgument.nil) + arguments.append(.nil) case .oscTypeTagImpulse: - arguments.append(OSCArgument.impulse) + arguments.append(.impulse) default: // We shouldn't ever get here as we've checked the type tag string for invalid characters. throw OSCParserError.cantParseTypeTagString } } } - return OSCMessage(raw: addressPattern, arguments: arguments) + return .message(OSCMessage(raw: addressPattern, arguments: arguments)) } /// Parse `OSCBundle` data. @@ -152,7 +152,7 @@ public enum OSCParser { /// - data: The `Data` to parse. /// - Throws: An `OSCParserError` if the `Data` could not be parsed. /// - Returns: An `OSCBundle`. - private static func parseOSCBundle(with data: Data) throws -> OSCBundle { + private static func parseOSCBundle(with data: Data) throws -> OSCPacket { // Check the Bundle has a string prefix of "#bundle" if "#bundle".oscData == data.subdata(in: Range(0...7)) { var startIndex = 8 @@ -168,10 +168,10 @@ public enum OSCParser { let elements = try parseBundleElements(with: 0, data: bundleData, size: size) - return OSCBundle(elements, - timeTag: timeTag) + return .bundle(OSCBundle(elements, + timeTag: timeTag)) } else { - return OSCBundle(timeTag: timeTag) + return .bundle(OSCBundle(timeTag: timeTag)) } } else { throw OSCParserError.unrecognisedData @@ -216,10 +216,10 @@ public enum OSCParser { let bundleElements = try parseBundleElements(with: index, data: bundleData, size: Int32(bundleData.count)) - elements.append(OSCBundle(bundleElements, - timeTag: timeTag)) + elements.append(.bundle(OSCBundle(bundleElements, + timeTag: timeTag))) } else { - elements.append(OSCBundle(timeTag: timeTag)) + elements.append(.bundle(OSCBundle(timeTag: timeTag))) } } else { throw OSCParserError.unrecognisedData diff --git a/Sources/CoreOSC/OSCParserError.swift b/Sources/CoreOSC/OSCParserError.swift index 635f248..efb51f1 100644 --- a/Sources/CoreOSC/OSCParserError.swift +++ b/Sources/CoreOSC/OSCParserError.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 13/08/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // diff --git a/Sources/CoreOSC/OSCPatternMatch.swift b/Sources/CoreOSC/OSCPatternMatch.swift index af778ad..40b01bc 100644 --- a/Sources/CoreOSC/OSCPatternMatch.swift +++ b/Sources/CoreOSC/OSCPatternMatch.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 11/08/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // diff --git a/Sources/CoreOSC/OSCRefractingAddress.swift b/Sources/CoreOSC/OSCRefractingAddress.swift index 9d5f922..d7c7795 100644 --- a/Sources/CoreOSC/OSCRefractingAddress.swift +++ b/Sources/CoreOSC/OSCRefractingAddress.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 29/07/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // diff --git a/Sources/CoreOSC/OSCTimeTag.swift b/Sources/CoreOSC/OSCTimeTag.swift index 6578aab..d7fb6b0 100644 --- a/Sources/CoreOSC/OSCTimeTag.swift +++ b/Sources/CoreOSC/OSCTimeTag.swift @@ -3,7 +3,7 @@ // CoreOSC // // Created by Sam Smallman on 22/07/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // @@ -24,8 +24,8 @@ import Foundation /// An OSC Time Tag. -public struct OSCTimeTag: OSCArgumentProtocol, Equatable { - +public struct OSCTimeTag: OSCArgumentProtocol, Equatable, CustomStringConvertible, Sendable { + /// The OSC data representation for the argument. public var oscData: Data { Data(seconds.bigEndian.data + fraction.bigEndian.data) } @@ -36,7 +36,11 @@ public struct OSCTimeTag: OSCArgumentProtocol, Equatable { public func oscAnnotation(withType type: Bool = true) -> String { "\(self.hex())\(type ? "(\(oscTypeTag))" : "")" } - + + public var description: String { + "\(self.hex())" + } + /// Creates an OSC Time Tag initialized to immediately. public static let immediate: OSCTimeTag = OSCTimeTag() diff --git a/Sources/CoreOSC/en.lproj/Localizable.strings b/Sources/CoreOSC/en.lproj/Localizable.strings index 380caf4..ac4fea7 100644 --- a/Sources/CoreOSC/en.lproj/Localizable.strings +++ b/Sources/CoreOSC/en.lproj/Localizable.strings @@ -1,7 +1,7 @@ -/* OSC Address Error */ - /* OSC Version */ -"OSC_VERSION" = "1.3.1"; +"OSC_VERSION" = "2.0.0"; + +/* OSC Address Error */ /* OSC Address Error: Invalid Address */ "OSC_ADDRESS_ERROR_INVALID_ADDRESS" = "Invalid address"; @@ -79,3 +79,8 @@ /* OSC Parser Error: Can't parse bundle element */ "OSC_PARSER_ERROR_CANT_PARSE_ELEMENT" = "The parser could not parse a bundles element."; + +/* OSC Argument Error */ + +/* OSC Argument Error: Invalid Argument */ +"OSC_ARGUMENT_ERROR_INVALID_ARGUMENT" = "Invalid argument"; diff --git a/Tests/CoreOSCTests/CoreOSCTests.swift b/Tests/CoreOSCTests/CoreOSCTests.swift index fd04a13..d7188c0 100644 --- a/Tests/CoreOSCTests/CoreOSCTests.swift +++ b/Tests/CoreOSCTests/CoreOSCTests.swift @@ -3,7 +3,7 @@ // CoreOSCTests // // Created by Sam Smallman on 03/02/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // @@ -29,13 +29,13 @@ import XCTest class CoreOSCTests: XCTestCase { func testVersion() { - XCTAssertEqual(CoreOSC.version, "1.3.1") + XCTAssertEqual(CoreOSC.version, "2.0.0") XCTAssertEqual(NSLocalizedString("OSC_VERSION", bundle: .module, comment: "OSC Version"), CoreOSC.version) } func testLicense() { let license = CoreOSC.license - XCTAssertTrue(license.hasPrefix("Copyright © 2023 Sam Smallman. https://github.com/SammySmallman")) + XCTAssertTrue(license.hasPrefix("Copyright © 2021 Sam Smallman. https://github.com/SammySmallman")) XCTAssertTrue(license.hasSuffix(".\n")) } diff --git a/Tests/CoreOSCTests/OSCAddressFilterTests.swift b/Tests/CoreOSCTests/OSCAddressFilterTests.swift index a384dcf..3d28caf 100644 --- a/Tests/CoreOSCTests/OSCAddressFilterTests.swift +++ b/Tests/CoreOSCTests/OSCAddressFilterTests.swift @@ -3,7 +3,7 @@ // CoreOSCTests // // Created by Sam Smallman on 13/08/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // diff --git a/Tests/CoreOSCTests/OSCAddressPatternTests.swift b/Tests/CoreOSCTests/OSCAddressPatternTests.swift index 1897bc9..033a957 100644 --- a/Tests/CoreOSCTests/OSCAddressPatternTests.swift +++ b/Tests/CoreOSCTests/OSCAddressPatternTests.swift @@ -3,7 +3,7 @@ // CoreOSCTests // // Created by Sam Smallman on 26/07/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // diff --git a/Tests/CoreOSCTests/OSCAddressSpaceTests.swift b/Tests/CoreOSCTests/OSCAddressSpaceTests.swift index 2cb8d2e..ef69e09 100644 --- a/Tests/CoreOSCTests/OSCAddressSpaceTests.swift +++ b/Tests/CoreOSCTests/OSCAddressSpaceTests.swift @@ -3,7 +3,7 @@ // CoreOSCTests // // Created by Sam Smallman on 11/08/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // @@ -30,31 +30,28 @@ class OSCAddressSpaceTests: XCTestCase { let address1 = try! OSCAddress("/core/osc/1") var value1: Bool = false let method1 = OSCMethod(with: address1, invokedAction: { message, _ in - let boolValue = message.arguments.first as! Bool - value1 = boolValue + value1 = message.arguments.first == .true }) let address2 = try! OSCAddress("/core/osc/2") var value2: Bool = false let method2 = OSCMethod(with: address2, invokedAction: { message, _ in - let boolValue = message.arguments.first as! Bool - value2 = boolValue + value2 = message.arguments.first == .true }) let address3 = try! OSCAddress("/core/osc/3") var value3: Bool = false let method3 = OSCMethod(with: address3, invokedAction: { message, _ in - let boolValue = message.arguments.first as! Bool - value3 = boolValue + value3 = message.arguments.first == .true }) let addressSpace = OSCAddressSpace(methods: [method1, method2, method3]) - addressSpace.invoke(with: OSCMessage(raw: "/core/osc/1", arguments: [true])) + addressSpace.invoke(with: OSCMessage(raw: "/core/osc/1", arguments: [.true])) XCTAssertEqual(value1, true) - addressSpace.invoke(with: OSCMessage(raw: "/core/osc/2", arguments: [true])) + addressSpace.invoke(with: OSCMessage(raw: "/core/osc/2", arguments: [.true])) XCTAssertEqual(value2, true) - addressSpace.invoke(with: OSCMessage(raw: "/core/osc/3", arguments: [true])) + addressSpace.invoke(with: OSCMessage(raw: "/core/osc/3", arguments: [.true])) XCTAssertEqual(value3, true) } diff --git a/Tests/CoreOSCTests/OSCAddressTests.swift b/Tests/CoreOSCTests/OSCAddressTests.swift index d8c0ea3..da50439 100644 --- a/Tests/CoreOSCTests/OSCAddressTests.swift +++ b/Tests/CoreOSCTests/OSCAddressTests.swift @@ -3,7 +3,7 @@ // CoreOSCTests // // Created by Sam Smallman on 26/07/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // diff --git a/Tests/CoreOSCTests/OSCAnnotationTests.swift b/Tests/CoreOSCTests/OSCAnnotationTests.swift index cafae0e..c92bfec 100644 --- a/Tests/CoreOSCTests/OSCAnnotationTests.swift +++ b/Tests/CoreOSCTests/OSCAnnotationTests.swift @@ -3,7 +3,7 @@ // CoreOSCTests // // Created by Sam Smallman on 26/07/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // @@ -137,16 +137,11 @@ final class OSCAnnotationTests: XCTestCase { XCTAssertNotNil(message) XCTAssertEqual(message?.addressPattern.fullPath, "/core/osc") XCTAssertEqual(message?.arguments.count, 5) - let argument1 = message?.arguments[0] as? Int32 - XCTAssertEqual(argument1, 1) - let argument2 = message?.arguments[1] as? Float32 - XCTAssertEqual(argument2, 3.142) - let argument3 = message?.arguments[2] as? String - XCTAssertEqual(argument3, "a string with spaces") - let argument4 = message?.arguments[3] as? String - XCTAssertEqual(argument4, "string") - let argument5 = message?.arguments[4] as? Bool - XCTAssertEqual(argument5, true) + XCTAssertEqual(message?.arguments[0], .int32(1)) + XCTAssertEqual(message?.arguments[1], .float32(3.142)) + XCTAssertEqual(message?.arguments[2], .string("a string with spaces")) + XCTAssertEqual(message?.arguments[3], .string("string")) + XCTAssertEqual(message?.arguments[4], .true) } func testAnnotationToMessageEqualsCommaStyle() { @@ -156,16 +151,11 @@ final class OSCAnnotationTests: XCTestCase { XCTAssertNotNil(message) XCTAssertEqual(message?.addressPattern.fullPath, "/core/osc") XCTAssertEqual(message?.arguments.count, 5) - let argument1 = message?.arguments[0] as? Int32 - XCTAssertEqual(argument1, 1) - let argument2 = message?.arguments[1] as? Float32 - XCTAssertEqual(argument2, 3.142) - let argument3 = message?.arguments[2] as? String - XCTAssertEqual(argument3, "a string with spaces") - let argument4 = message?.arguments[3] as? String - XCTAssertEqual(argument4, "string") - let argument5 = message?.arguments[4] as? Bool - XCTAssertEqual(argument5, true) + XCTAssertEqual(message?.arguments[0], .int32(1)) + XCTAssertEqual(message?.arguments[1], .float32(3.142)) + XCTAssertEqual(message?.arguments[2], .string("a string with spaces")) + XCTAssertEqual(message?.arguments[3], .string("string")) + XCTAssertEqual(message?.arguments[4], .true) } func testAnnotationToMessageSpaceStyleSingleStringWithSpacesArgument() { @@ -175,8 +165,7 @@ final class OSCAnnotationTests: XCTestCase { XCTAssertNotNil(message) XCTAssertEqual(message?.addressPattern.fullPath, "/core/osc") XCTAssertEqual(message?.arguments.count, 1) - let argument = message?.arguments[0] as? String - XCTAssertEqual(argument, "this should be a single string argument") + XCTAssertEqual(message?.arguments[0], .string("this should be a single string argument")) } func testAnnotationToMessageEqualsCommaStyleSingleStringWithSpacesArgument() { @@ -186,8 +175,7 @@ final class OSCAnnotationTests: XCTestCase { XCTAssertNotNil(message) XCTAssertEqual(message?.addressPattern.fullPath, "/core/osc") XCTAssertEqual(message?.arguments.count, 1) - let argument = message?.arguments[0] as? String - XCTAssertEqual(argument, "this should be a single string argument") + XCTAssertEqual(message?.arguments[0], .string("this should be a single string argument")) } func testAnnotationToMessageSpaceStyleQuotedTypes() { @@ -197,30 +185,18 @@ final class OSCAnnotationTests: XCTestCase { XCTAssertNotNil(message) XCTAssertEqual(message?.addressPattern.fullPath, "/core/osc") XCTAssertEqual(message?.arguments.count, 12) - let argument1 = message?.arguments[0] as? Int32 - XCTAssertEqual(argument1, 1) - let argument2 = message?.arguments[1] as? String - XCTAssertEqual(argument2, "1") - let argument3 = message?.arguments[2] as? Float32 - XCTAssertEqual(argument3, 3.142) - let argument4 = message?.arguments[3] as? String - XCTAssertEqual(argument4, "3.142") - let argument5 = message?.arguments[4] as? Bool - XCTAssertEqual(argument5, true) - let argument6 = message?.arguments[5] as? String - XCTAssertEqual(argument6, "true") - let argument7 = message?.arguments[6] as? Bool - XCTAssertEqual(argument7, false) - let argument8 = message?.arguments[7] as? String - XCTAssertEqual(argument8, "false") - let argument9 = message?.arguments[8] as? OSCArgument - XCTAssertEqual(argument9, OSCArgument.nil) - let argument10 = message?.arguments[9] as? String - XCTAssertEqual(argument10, "nil") - let argument11 = message?.arguments[10] as? OSCArgument - XCTAssertEqual(argument11, OSCArgument.impulse) - let argument12 = message?.arguments[11] as? String - XCTAssertEqual(argument12, "impulse") + XCTAssertEqual(message?.arguments[0], .int32(1)) + XCTAssertEqual(message?.arguments[1], .string("1")) + XCTAssertEqual(message?.arguments[2], .float32(3.142)) + XCTAssertEqual(message?.arguments[3], .string("3.142")) + XCTAssertEqual(message?.arguments[4], .true) + XCTAssertEqual(message?.arguments[5], .string("true")) + XCTAssertEqual(message?.arguments[6], .false) + XCTAssertEqual(message?.arguments[7], .string("false")) + XCTAssertEqual(message?.arguments[8], .nil) + XCTAssertEqual(message?.arguments[9], .string("nil")) + XCTAssertEqual(message?.arguments[10], .impulse) + XCTAssertEqual(message?.arguments[11], .string("impulse")) } func testAnnotationToMessageEqualsCommaStyleQuotedTypes() { @@ -230,30 +206,18 @@ final class OSCAnnotationTests: XCTestCase { XCTAssertNotNil(message) XCTAssertEqual(message?.addressPattern.fullPath, "/core/osc") XCTAssertEqual(message?.arguments.count, 12) - let argument1 = message?.arguments[0] as? Int32 - XCTAssertEqual(argument1, 1) - let argument2 = message?.arguments[1] as? String - XCTAssertEqual(argument2, "1") - let argument3 = message?.arguments[2] as? Float32 - XCTAssertEqual(argument3, 3.142) - let argument4 = message?.arguments[3] as? String - XCTAssertEqual(argument4, "3.142") - let argument5 = message?.arguments[4] as? Bool - XCTAssertEqual(argument5, true) - let argument6 = message?.arguments[5] as? String - XCTAssertEqual(argument6, "true") - let argument7 = message?.arguments[6] as? Bool - XCTAssertEqual(argument7, false) - let argument8 = message?.arguments[7] as? String - XCTAssertEqual(argument8, "false") - let argument9 = message?.arguments[8] as? OSCArgument - XCTAssertEqual(argument9, OSCArgument.nil) - let argument10 = message?.arguments[9] as? String - XCTAssertEqual(argument10, "nil") - let argument11 = message?.arguments[10] as? OSCArgument - XCTAssertEqual(argument11, OSCArgument.impulse) - let argument12 = message?.arguments[11] as? String - XCTAssertEqual(argument12, "impulse") + XCTAssertEqual(message?.arguments[0], .int32(1)) + XCTAssertEqual(message?.arguments[1], .string("1")) + XCTAssertEqual(message?.arguments[2], .float32(3.142)) + XCTAssertEqual(message?.arguments[3], .string("3.142")) + XCTAssertEqual(message?.arguments[4], .true) + XCTAssertEqual(message?.arguments[5], .string("true")) + XCTAssertEqual(message?.arguments[6], .false) + XCTAssertEqual(message?.arguments[7], .string("false")) + XCTAssertEqual(message?.arguments[8], .nil) + XCTAssertEqual(message?.arguments[9], .string("nil")) + XCTAssertEqual(message?.arguments[10], .impulse) + XCTAssertEqual(message?.arguments[11], .string("impulse")) } func testAnnotationToMessageSpaceStyleWithSingleDecimalStringArgument() { @@ -263,8 +227,7 @@ final class OSCAnnotationTests: XCTestCase { XCTAssertNotNil(message) XCTAssertEqual(message?.addressPattern.fullPath, "/core/osc") XCTAssertEqual(message?.arguments.count, 1) - let argument2 = message?.arguments[0] as? String - XCTAssertEqual(argument2, "127.0.0.1") + XCTAssertEqual(message?.arguments[0], .string("127.0.0.1")) } func testAnnotationToMessageEqualsCommaStyleWithSingleDecimalStringArgument() { @@ -274,8 +237,7 @@ final class OSCAnnotationTests: XCTestCase { XCTAssertNotNil(message) XCTAssertEqual(message?.addressPattern.fullPath, "/core/osc") XCTAssertEqual(message?.arguments.count, 1) - let argument2 = message?.arguments[0] as? String - XCTAssertEqual(argument2, "127.0.0.1") + XCTAssertEqual(message?.arguments[0], .string("127.0.0.1")) } } diff --git a/Tests/CoreOSCTests/OSCBundleTests.swift b/Tests/CoreOSCTests/OSCBundleTests.swift index eff9ae3..7409138 100644 --- a/Tests/CoreOSCTests/OSCBundleTests.swift +++ b/Tests/CoreOSCTests/OSCBundleTests.swift @@ -34,7 +34,7 @@ final class OSCABundleTests: XCTestCase { try! OSCMessage(with: "/core/osc/3") ] let bundle = OSCBundle( - messages, + messages.map { .message($0) }, timeTag: .immediate ) XCTAssertEqual(bundle.flatten(), messages) @@ -43,26 +43,26 @@ final class OSCABundleTests: XCTestCase { func testRecursiveFlatten() throws { let bundle = OSCBundle( [ - try! OSCMessage(with: "/core/osc/1"), - try! OSCMessage(with: "/core/osc/2"), - try! OSCMessage(with: "/core/osc/3"), - OSCBundle( + .message(try! OSCMessage(with: "/core/osc/1")), + .message(try! OSCMessage(with: "/core/osc/2")), + .message(try! OSCMessage(with: "/core/osc/3")), + .bundle(OSCBundle( [ - try! OSCMessage(with: "/core/osc/4"), - try! OSCMessage(with: "/core/osc/5"), - try! OSCMessage(with: "/core/osc/6"), - OSCBundle( + .message(try! OSCMessage(with: "/core/osc/4")), + .message(try! OSCMessage(with: "/core/osc/5")), + .message(try! OSCMessage(with: "/core/osc/6")), + .bundle(OSCBundle( [ - try! OSCMessage(with: "/core/osc/7"), - try! OSCMessage(with: "/core/osc/8"), - try! OSCMessage(with: "/core/osc/9"), + .message(try! OSCMessage(with: "/core/osc/7")), + .message(try! OSCMessage(with: "/core/osc/8")), + .message(try! OSCMessage(with: "/core/osc/9")), ], timeTag: .immediate - ) + )) ], timeTag: .immediate - ) + )) ], timeTag: .immediate ) diff --git a/Tests/CoreOSCTests/OSCFilterAddressTests.swift b/Tests/CoreOSCTests/OSCFilterAddressTests.swift index 4ec23d7..2bb25be 100644 --- a/Tests/CoreOSCTests/OSCFilterAddressTests.swift +++ b/Tests/CoreOSCTests/OSCFilterAddressTests.swift @@ -3,7 +3,7 @@ // CoreOSCTests // // Created by Sam Smallman on 26/07/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // diff --git a/Tests/CoreOSCTests/OSCFilterMethodTests.swift b/Tests/CoreOSCTests/OSCFilterMethodTests.swift index 67adb22..4748d48 100644 --- a/Tests/CoreOSCTests/OSCFilterMethodTests.swift +++ b/Tests/CoreOSCTests/OSCFilterMethodTests.swift @@ -3,7 +3,7 @@ // CoreOSCTests // // Created by Sam Smallman on 13/08/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // @@ -33,10 +33,9 @@ class OSCFilterMethodTests: XCTestCase { let method = OSCFilterMethod(with: address, invokedAction: { message, _ in XCTAssertEqual(message.addressPattern.fullPath, addressString) XCTAssertEqual(message.arguments.count, 1) - let boolValue = message.arguments.first as! Bool - value = boolValue + value = message.arguments.first == .true }) - let message = OSCMessage(raw: addressString, arguments: [true]) + let message = OSCMessage(raw: addressString, arguments: [.true]) method.invoke(message, nil) XCTAssertEqual(value, true) } @@ -47,10 +46,9 @@ class OSCFilterMethodTests: XCTestCase { var value: Bool = false let method = OSCFilterMethod(with: address, invokedAction: { message, _ in XCTAssertEqual(message.arguments.count, 1) - let boolValue = message.arguments.first as! Bool - value = boolValue + value = message.arguments.first == .true }) - let message = OSCMessage(raw: addressString, arguments: [true]) + let message = OSCMessage(raw: addressString, arguments: [.true]) method.invoke(message, nil) XCTAssertEqual(value, true) } @@ -62,7 +60,7 @@ class OSCFilterMethodTests: XCTestCase { XCTAssertEqual(userInfo?["bool"] as! Bool, true) XCTAssertEqual(userInfo?["string"] as! String, "test") }) - let message = OSCMessage(raw: addressString, arguments: [true]) + let message = OSCMessage(raw: addressString, arguments: [.true]) method.invoke(message, ["bool":true, "string":"test"]) } diff --git a/Tests/CoreOSCTests/OSCMatchTests.swift b/Tests/CoreOSCTests/OSCMatchTests.swift index 29e7b39..bb26d5b 100644 --- a/Tests/CoreOSCTests/OSCMatchTests.swift +++ b/Tests/CoreOSCTests/OSCMatchTests.swift @@ -3,7 +3,7 @@ // CoreOSCTests // // Created by Sam Smallman on 26/07/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // diff --git a/Tests/CoreOSCTests/OSCMessageTests.swift b/Tests/CoreOSCTests/OSCMessageTests.swift index e4a1830..ad4241c 100644 --- a/Tests/CoreOSCTests/OSCMessageTests.swift +++ b/Tests/CoreOSCTests/OSCMessageTests.swift @@ -3,7 +3,7 @@ // CoreOSCTests // // Created by Sam Smallman on 05/08/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // @@ -27,51 +27,61 @@ import XCTest class OSCMessageTests: XCTestCase { func testInitializingRawOSCMessageSucceeds() { - let message = OSCMessage(raw: "/core/osc", arguments: [Int32(1), - Float32(3.142), - "Core OSC", - OSCTimeTag.immediate, - true, - false, - Data([0x01, 0x01]), - OSCArgument.nil, - OSCArgument.impulse]) + let message = OSCMessage( + raw: "/core/osc", + arguments: [ + .int32(1), + .float32(3.142), + .string("Core OSC"), + .timeTag(.immediate), + .true, + .false, + .blob(Data([0x01, 0x01])), + .nil, + .impulse + ] + ) XCTAssertEqual(message.addressPattern.fullPath, "/core/osc") XCTAssertEqual(message.typeTagString, "ifstTFbNI") XCTAssertEqual(message.arguments.count, 9) - XCTAssertEqual(message.arguments[0] as! Int32, 1) - XCTAssertEqual(message.arguments[1] as! Float32, 3.142) - XCTAssertEqual(message.arguments[2] as! String, "Core OSC") - XCTAssertEqual(message.arguments[3] as! OSCTimeTag, OSCTimeTag.immediate) - XCTAssertEqual(message.arguments[4] as! Bool, true) - XCTAssertEqual(message.arguments[5] as! Bool, false) - XCTAssertEqual(message.arguments[6] as! Data, Data([0x01, 0x01])) - XCTAssertEqual(message.arguments[7] as! OSCArgument, OSCArgument.nil) - XCTAssertEqual(message.arguments[8] as! OSCArgument, OSCArgument.impulse) + XCTAssertEqual(message.arguments[0], .int32(1)) + XCTAssertEqual(message.arguments[1], .float32(3.142)) + XCTAssertEqual(message.arguments[2], .string("Core OSC")) + XCTAssertEqual(message.arguments[3], .timeTag(OSCTimeTag.immediate)) + XCTAssertEqual(message.arguments[4], .true) + XCTAssertEqual(message.arguments[5], .false) + XCTAssertEqual(message.arguments[6], .blob(Data([0x01, 0x01]))) + XCTAssertEqual(message.arguments[7], .nil) + XCTAssertEqual(message.arguments[8], .impulse) } func testInitializingOSCMessageWithStringSucceeds() throws { - let message = try OSCMessage(with: "/core/osc", arguments: [Int32(1), - Float32(3.142), - "Core OSC", - OSCTimeTag.immediate, - true, - false, - Data([0x01, 0x01]), - OSCArgument.nil, - OSCArgument.impulse]) + let message = try OSCMessage( + with: "/core/osc", + arguments: [ + .int32(1), + .float32(3.142), + .string("Core OSC"), + .timeTag(.immediate), + .true, + .false, + .blob(Data([0x01, 0x01])), + .nil, + .impulse + ] + ) XCTAssertEqual(message.addressPattern.fullPath, "/core/osc") XCTAssertEqual(message.typeTagString, "ifstTFbNI") XCTAssertEqual(message.arguments.count, 9) - XCTAssertEqual(message.arguments[0] as! Int32, 1) - XCTAssertEqual(message.arguments[1] as! Float32, 3.142) - XCTAssertEqual(message.arguments[2] as! String, "Core OSC") - XCTAssertEqual(message.arguments[3] as! OSCTimeTag, OSCTimeTag.immediate) - XCTAssertEqual(message.arguments[4] as! Bool, true) - XCTAssertEqual(message.arguments[5] as! Bool, false) - XCTAssertEqual(message.arguments[6] as! Data, Data([0x01, 0x01])) - XCTAssertEqual(message.arguments[7] as! OSCArgument, OSCArgument.nil) - XCTAssertEqual(message.arguments[8] as! OSCArgument, OSCArgument.impulse) + XCTAssertEqual(message.arguments[0], .int32(1)) + XCTAssertEqual(message.arguments[1], .float32(3.142)) + XCTAssertEqual(message.arguments[2], .string("Core OSC")) + XCTAssertEqual(message.arguments[3], .timeTag(OSCTimeTag.immediate)) + XCTAssertEqual(message.arguments[4], .true) + XCTAssertEqual(message.arguments[5], .false) + XCTAssertEqual(message.arguments[6], .blob(Data([0x01, 0x01]))) + XCTAssertEqual(message.arguments[7], .nil) + XCTAssertEqual(message.arguments[8], .impulse) } func testInitializingOSCMessageWithStringFails() throws { @@ -80,27 +90,32 @@ class OSCMessageTests: XCTestCase { func testInitializingOSCMessageWithOSCAddressPatternSucceeds() throws { let addressPattern = try OSCAddressPattern("/core/osc") - let message = OSCMessage(with: addressPattern, arguments: [Int32(1), - Float32(3.142), - "Core OSC", - OSCTimeTag.immediate, - true, - false, - Data([0x01, 0x01]), - OSCArgument.nil, - OSCArgument.impulse]) + let message = OSCMessage( + with: addressPattern, + arguments: [ + .int32(1), + .float32(3.142), + .string("Core OSC"), + .timeTag(.immediate), + .true, + .false, + .blob(Data([0x01, 0x01])), + .nil, + .impulse + ] + ) XCTAssertEqual(message.addressPattern.fullPath, "/core/osc") XCTAssertEqual(message.typeTagString, "ifstTFbNI") XCTAssertEqual(message.arguments.count, 9) - XCTAssertEqual(message.arguments[0] as! Int32, 1) - XCTAssertEqual(message.arguments[1] as! Float32, 3.142) - XCTAssertEqual(message.arguments[2] as! String, "Core OSC") - XCTAssertEqual(message.arguments[3] as! OSCTimeTag, OSCTimeTag.immediate) - XCTAssertEqual(message.arguments[4] as! Bool, true) - XCTAssertEqual(message.arguments[5] as! Bool, false) - XCTAssertEqual(message.arguments[6] as! Data, Data([0x01, 0x01])) - XCTAssertEqual(message.arguments[7] as! OSCArgument, OSCArgument.nil) - XCTAssertEqual(message.arguments[8] as! OSCArgument, OSCArgument.impulse) + XCTAssertEqual(message.arguments[0], .int32(1)) + XCTAssertEqual(message.arguments[1], .float32(3.142)) + XCTAssertEqual(message.arguments[2], .string("Core OSC")) + XCTAssertEqual(message.arguments[3], .timeTag(OSCTimeTag.immediate)) + XCTAssertEqual(message.arguments[4], .true) + XCTAssertEqual(message.arguments[5], .false) + XCTAssertEqual(message.arguments[6], .blob(Data([0x01, 0x01]))) + XCTAssertEqual(message.arguments[7], .nil) + XCTAssertEqual(message.arguments[8], .impulse) } func testReaddressWithStringSucceeds() throws { @@ -122,32 +137,39 @@ class OSCMessageTests: XCTestCase { } func testMessageDataAndParsing() throws { - let message = OSCMessage(raw: "/core/osc", arguments: [Int32(1), - Float32(3.142), - "Core OSC", - OSCTimeTag.immediate, - true, - false, - Data([0x01, 0x01, 0x01]), - OSCArgument.nil, - OSCArgument.impulse]) + let message = OSCMessage( + raw: "/core/osc", + arguments: [ + .int32(1), + .float32(3.142), + .string("Core OSC"), + .timeTag(.immediate), + .true, + .false, + .blob(Data([0x01, 0x01, 0x01])), + .nil, + .impulse + ] + ) let data = message.data() - let packet = try OSCParser.packet(from: data) as? OSCMessage - - XCTAssertNotNil(packet) - XCTAssertEqual(packet!.addressPattern.fullPath, message.addressPattern.fullPath) - XCTAssertEqual(packet!.typeTagString, message.typeTagString) - XCTAssertEqual(packet!.arguments.count, message.arguments.count) - XCTAssertEqual(packet!.arguments[0] as! Int32, message.arguments[0] as! Int32) - XCTAssertEqual(packet!.arguments[1] as! Float32, message.arguments[1] as! Float32) - XCTAssertEqual(packet!.arguments[2] as! String, message.arguments[2] as! String) - XCTAssertEqual(packet!.arguments[3] as! OSCTimeTag, message.arguments[3] as! OSCTimeTag) - XCTAssertEqual(packet!.arguments[4] as! Bool, message.arguments[4] as! Bool) - XCTAssertEqual(packet!.arguments[5] as! Bool, message.arguments[5] as! Bool) - XCTAssertEqual(packet!.arguments[6] as! Data, message.arguments[6] as! Data) - XCTAssertEqual(packet!.arguments[7] as! OSCArgument, message.arguments[7] as! OSCArgument) - XCTAssertEqual(packet!.arguments[8] as! OSCArgument, message.arguments[8] as! OSCArgument) + guard case let .message(packet) = try OSCParser.packet(from: data) else { + XCTFail() + return + } + + XCTAssertEqual(packet.addressPattern.fullPath, message.addressPattern.fullPath) + XCTAssertEqual(packet.typeTagString, message.typeTagString) + XCTAssertEqual(packet.arguments.count, message.arguments.count) + XCTAssertEqual(packet.arguments[0], message.arguments[0]) + XCTAssertEqual(packet.arguments[1], message.arguments[1]) + XCTAssertEqual(packet.arguments[2], message.arguments[2]) + XCTAssertEqual(packet.arguments[3], message.arguments[3]) + XCTAssertEqual(packet.arguments[4], message.arguments[4]) + XCTAssertEqual(packet.arguments[5], message.arguments[5]) + XCTAssertEqual(packet.arguments[6], message.arguments[6]) + XCTAssertEqual(packet.arguments[7], message.arguments[7]) + XCTAssertEqual(packet.arguments[8], message.arguments[8]) } func testInvalidMessageDataParsing() throws { @@ -155,7 +177,7 @@ class OSCMessageTests: XCTestCase { let message1 = OSCMessage(raw: "/core/osc/[0- 1]") let data1 = message1.data() - XCTAssertThrowsError(try OSCParser.packet(from: data1) as? OSCMessage) { error in + XCTAssertThrowsError(try OSCParser.packet(from: data1)) { error in XCTAssertEqual(error as! OSCParserError, OSCParserError.cantParseAddressPattern) } @@ -163,7 +185,7 @@ class OSCMessageTests: XCTestCase { let message2 = OSCMessage(raw: "/core/osc/#") let data2 = message2.data() - XCTAssertThrowsError(try OSCParser.packet(from: data2) as? OSCMessage) { error in + XCTAssertThrowsError(try OSCParser.packet(from: data2)) { error in XCTAssertEqual(error as! OSCParserError, OSCParserError.cantParseAddressPattern) } } @@ -184,16 +206,24 @@ class OSCMessageTests: XCTestCase { let message = try! OSCMessage(with: "/core", arguments: [CoreOSC.license]) XCTAssertEqual(message.arguments.count, 1) - let license1 = message.arguments[0] as! String - XCTAssertTrue(license1.hasPrefix("Copyright © 2023 Sam Smallman. https://github.com/SammySmallman")) + guard case let .string(license1) = message.arguments[0] else { + fatalError("Missing LIcense") + } + XCTAssertTrue(license1.hasPrefix("Copyright © 2021 Sam Smallman. https://github.com/SammySmallman")) XCTAssertTrue(license1.hasSuffix(".\n")) let parsedPacket = try OSCParser.packet(from: message.data()) - let parsedMessage = parsedPacket as! OSCMessage - + + guard case let .message(parsedMessage) = parsedPacket else { + XCTFail() + return + } + XCTAssertEqual(parsedMessage.arguments.count, 1) - let license2 = parsedMessage.arguments[0] as! String - XCTAssertTrue(license2.hasPrefix("Copyright © 2023 Sam Smallman. https://github.com/SammySmallman")) + guard case let .string(license2) = parsedMessage.arguments[0] else { + fatalError("Missing LIcense") + } + XCTAssertTrue(license2.hasPrefix("Copyright © 2021 Sam Smallman. https://github.com/SammySmallman")) XCTAssertTrue(license2.hasSuffix(".\n")) } diff --git a/Tests/CoreOSCTests/OSCMethodTests.swift b/Tests/CoreOSCTests/OSCMethodTests.swift index b4f8c5a..1aa2148 100644 --- a/Tests/CoreOSCTests/OSCMethodTests.swift +++ b/Tests/CoreOSCTests/OSCMethodTests.swift @@ -3,7 +3,7 @@ // CoreOSCTests // // Created by Sam Smallman on 10/08/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC // @@ -33,10 +33,9 @@ class OSCMethodTests: XCTestCase { let method = OSCMethod(with: address, invokedAction: { message, _ in XCTAssertEqual(message.addressPattern.fullPath, addressString) XCTAssertEqual(message.arguments.count, 1) - let boolValue = message.arguments.first as! Bool - value = boolValue + value = message.arguments.first == .true }) - let message = OSCMessage(raw: addressString, arguments: [true]) + let message = OSCMessage(raw: addressString, arguments: [.true]) method.invoke(message, nil) XCTAssertEqual(value, true) } @@ -47,10 +46,9 @@ class OSCMethodTests: XCTestCase { var value: Bool = false let method = OSCMethod(with: address, invokedAction: { message, _ in XCTAssertEqual(message.arguments.count, 1) - let boolValue = message.arguments.first as! Bool - value = boolValue + value = message.arguments.first == .true }) - let message = OSCMessage(raw: addressString, arguments: [true]) + let message = OSCMessage(raw: addressString, arguments: [.true]) XCTAssertEqual(method.invoke(with: message), true) XCTAssertEqual(value, true) } @@ -60,10 +58,9 @@ class OSCMethodTests: XCTestCase { var value: Bool = false let method = OSCMethod(with: address, invokedAction: { message, _ in XCTAssertEqual(message.arguments.count, 1) - let boolValue = message.arguments.first as! Bool - value = boolValue + value = message.arguments.first == .true }) - let message = OSCMessage(raw: "/core/test", arguments: [true]) + let message = OSCMessage(raw: "/core/test", arguments: [.true]) XCTAssertEqual(method.invoke(with: message), false) XCTAssertEqual(value, false) } @@ -75,7 +72,7 @@ class OSCMethodTests: XCTestCase { XCTAssertEqual(userInfo?["bool"] as! Bool, true) XCTAssertEqual(userInfo?["string"] as! String, "test") }) - let message = OSCMessage(raw: addressString, arguments: [true]) + let message = OSCMessage(raw: addressString, arguments: [.true]) XCTAssertEqual(method.invoke(with: message, userInfo: ["bool":true, "string":"test"]), true) } diff --git a/Tests/CoreOSCTests/OSCRefractingAddressTests.swift b/Tests/CoreOSCTests/OSCRefractingAddressTests.swift index c4149f6..f203aa7 100644 --- a/Tests/CoreOSCTests/OSCRefractingAddressTests.swift +++ b/Tests/CoreOSCTests/OSCRefractingAddressTests.swift @@ -3,7 +3,7 @@ // CoreOSCTests // // Created by Sam Smallman on 26/07/2021. -// Copyright © 2022 Sam Smallman. https://github.com/SammySmallman +// Copyright © 2021 Sam Smallman. https://github.com/SammySmallman // // This file is part of CoreOSC //