diff --git a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABStateDescription.swift b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABStateDescription.swift index aa5851f5..99757aa6 100644 --- a/OpenHABCore/Sources/OpenHABCore/Model/OpenHABStateDescription.swift +++ b/OpenHABCore/Sources/OpenHABCore/Model/OpenHABStateDescription.swift @@ -29,10 +29,10 @@ public class OpenHABStateDescription { self.options = options ?? [] // Remove transformation instructions (e.g. for 'MAP(foo.map):%s' keep only '%s') - + let regexPattern = /^[A-Z]+(\(.*\))?:(.*)$/.ignoresCase() if let tobeSearched { - if let firstMatch = tobeSearched.firstMatch(of: regexPattern){ + if let firstMatch = tobeSearched.firstMatch(of: regexPattern) { numberPattern = String(firstMatch.2) } else { numberPattern = tobeSearched diff --git a/OpenHABCore/Sources/OpenHABCore/Util/ServerCertificateManager.swift b/OpenHABCore/Sources/OpenHABCore/Util/ServerCertificateManager.swift index a7a7d15b..f5fd819e 100644 --- a/OpenHABCore/Sources/OpenHABCore/Util/ServerCertificateManager.swift +++ b/OpenHABCore/Sources/OpenHABCore/Util/ServerCertificateManager.swift @@ -224,17 +224,11 @@ public class ServerCertificateManager: ServerTrustManager, ServerTrustEvaluating func getLeafCertificate(trust: SecTrust?) -> SecCertificate? { // Returns the leaf certificate from a SecTrust object (that is always the // certificate at index 0). - var result: SecCertificate? - if let trust { - if SecTrustGetCertificateCount(trust) > 0 { - result = SecTrustGetCertificateAtIndex(trust, 0) - return result - } else { - return nil - } + if let trust, SecTrustGetCertificateCount(trust) > 0, let certificates = SecTrustCopyCertificateChain(trust) as? [SecCertificate] { + certificates[0] } else { - return nil + nil } } diff --git a/OpenHABCore/Tests/OpenHABCoreTests/OpenHABCoreGeneralTests.swift b/OpenHABCore/Tests/OpenHABCoreTests/OpenHABCoreGeneralTests.swift index 1ed604ae..a57b3830 100644 --- a/OpenHABCore/Tests/OpenHABCoreTests/OpenHABCoreGeneralTests.swift +++ b/OpenHABCore/Tests/OpenHABCoreTests/OpenHABCoreGeneralTests.swift @@ -28,7 +28,6 @@ final class OpenHABCoreGeneralTests: XCTestCase { XCTAssertEqual(urlc, URL(string: "http://192.169.2.1/icon/switch?state=OFF&format=SVG"), "Check endpoint creation") } - @available(iOS 16.0, *) func testLabelValue() { let widget = OpenHABWidget() widget.label = "llldl [llsl]" @@ -36,4 +35,9 @@ final class OpenHABCoreGeneralTests: XCTestCase { widget.label = "llllsl[kkks] llls" XCTAssertEqual(widget.labelValue, "kkks") } + + func testOpenHABStateDescription() { + let openHABStateDescription = OpenHABStateDescription(minimum: 0.0, maximum: 1.0, step: 0.2, readOnly: true, options: nil, pattern: "MAP(foo.map):%s") + XCTAssertEqual(openHABStateDescription.numberPattern, "%s") + } } diff --git a/openHAB/OpenHABRootViewController.swift b/openHAB/OpenHABRootViewController.swift index 44ae076e..67aa39d1 100644 --- a/openHAB/OpenHABRootViewController.swift +++ b/openHAB/OpenHABRootViewController.swift @@ -212,34 +212,27 @@ class OpenHABRootViewController: UIViewController { private func uiCommandAction(_ command: String) { os_log("navigateCommandAction: %{PUBLIC}@", log: .notifications, type: .info, command) - let pattern = "^(/basicui/app\\?.*|/.*|.*)$" - - do { - let regex = try NSRegularExpression(pattern: pattern, options: []) - let nsString = command as NSString - let results = regex.matches(in: command, options: [], range: NSRange(location: 0, length: nsString.length)) - - if let match = results.first { - let pathRange = match.range(at: 1) - let path = nsString.substring(with: pathRange) - os_log("navigateCommandAction path: %{PUBLIC}@", log: .notifications, type: .info, path) - if currentView != webViewController { - switchView(target: .webview) - } - if path.starts(with: "/basicui/app?") { - // TODO: this is a sitemap, we should use the native renderer - // temp hack right now to just use a webview - webViewController.loadWebView(force: true, path: path) - } else if path.starts(with: "/") { - // have the webview load this path itself - webViewController.loadWebView(force: true, path: path) - } else { - // have the mainUI handle the navigation - webViewController.navigateCommand(path) - } + let regexPattern = /^(\/basicui\/app\\?.*|\/.*|.*)$/ + if let firstMatch = command.firstMatch(of: regexPattern) { + let path = String(firstMatch.1) + os_log("navigateCommandAction path: %{PUBLIC}@", log: .notifications, type: .info, path) + if currentView != webViewController { + switchView(target: .webview) } - } catch { - os_log("Invalid regex: %{PUBLIC}@", log: .notifications, type: .error, error.localizedDescription) + if path.starts(with: "/basicui/app?") { + // TODO: this is a sitemap, we should use the native renderer + // temp hack right now to just use a webview + webViewController.loadWebView(force: true, path: path) + } else if path.starts(with: "/") { + // have the webview load this path itself + webViewController.loadWebView(force: true, path: path) + } else { + // have the mainUI handle the navigation + webViewController.navigateCommand(path) + } + + } else { + os_log("Invalid regex: %{PUBLIC}@", log: .notifications, type: .error, command) } } diff --git a/openHABTestsSwift/LocalizationTests.swift b/openHABTestsSwift/LocalizationTests.swift index e2f54808..16612b05 100644 --- a/openHABTestsSwift/LocalizationTests.swift +++ b/openHABTestsSwift/LocalizationTests.swift @@ -37,22 +37,18 @@ class LocalizationTests: XCTestCase { for language in LocalizationTests.localizations { print("Testing language: '\(language)'.") for tuple in LocalizationTests.localizedFormatStrings { - do { - guard let translation = tuple.key.localized(for: language)?.replacingOccurrences(of: "%%", with: "") else { - XCTFail("Failed to get translation for key '\(tuple.key)' in language '\(language)'.") - continue - } - - XCTAssertNotEqual(translation, "__MISSING__", "Missing translation for key '\(tuple.key)' in language '\(language)'.") - let formatSpecifiersRegEx = try NSRegularExpression(pattern: "%(?:\\d+\\$)?[+-]?(?:[lh]{0,2})(?:[qLztj])?(?:[ 0]|'.{1})?\\d*(?:\\.\\d?)?[@dDiuUxXoOfeEgGcCsSpaAFn]") - let numberOfMatches = formatSpecifiersRegEx.numberOfMatches(in: translation, options: [], range: NSRange(location: 0, length: translation.utf16.count)) - XCTAssertEqual(numberOfMatches, tuple.arguments.count, "Invalid number of format specifiers for key '\(tuple.key)' in language '\(language)'.") - } catch { - XCTFail("Failed to create regular expression for key '\(tuple.key)' in language '\(language)'.") + guard let translation = tuple.key.localized(for: language)?.replacingOccurrences(of: "%%", with: "") else { + XCTFail("Failed to get translation for key '\(tuple.key)' in language '\(language)'.") + continue } - let translation = tuple.key.localizedWithFormat(for: language, arguments: tuple.arguments) - XCTAssertNotNil(translation, "Failed to get translation for key '\(tuple.key)' in language '\(language)'.") - print("Translation: \(tuple.key) = \(translation ?? "FAILED")") + XCTAssertNotEqual(translation, "__MISSING__", "Missing translation for key '\(tuple.key)' in language '\(language)'.") + let regex = /%(?:\d+\$)?[+-]?(?:[lh]{0,2})(?:[qLztj])?(?:[ 0]|'.{1})?\d*(?:\\.\d?)?[@dDiuUxXoOfeEgGcCsSpaAFn]/ + let numberOfMatches = translation.matches(of: regex).count + XCTAssertEqual(numberOfMatches, tuple.arguments.count, "Invalid number of format specifiers for key '\(tuple.key)' in language '\(language)'.") + + let translationResult = tuple.key.localizedWithFormat(for: language, arguments: tuple.arguments) + XCTAssertNotNil(translationResult, "Failed to get translation for key '\(tuple.key)' in language '\(language)'.") + print("Translation: \(tuple.key) = \(translation)") } } }