Implemented the "fullyMatch(pattern: )" function for the String+Functions extension in the library target.
This commit is contained in:
@@ -0,0 +1,45 @@
|
|||||||
|
// ===----------------------------------------------------------------------===
|
||||||
|
//
|
||||||
|
// This source file is part of the DiscogsService open source project
|
||||||
|
//
|
||||||
|
// Copyright (c) 2025 Röck+Cöde VoF. and the DiscogsService project authors
|
||||||
|
// Licensed under Apache license v2.0
|
||||||
|
//
|
||||||
|
// See LICENSE for license information
|
||||||
|
// See CONTRIBUTORS for the list of DiscogsService project authors
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
// ===----------------------------------------------------------------------===
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension String {
|
||||||
|
|
||||||
|
// MARK: Functions
|
||||||
|
|
||||||
|
/// Checks whether a regular expression pattern fully matches a string or not.
|
||||||
|
/// - Parameter pattern: A regular expression pattern to match a string against.
|
||||||
|
/// - Returns: A flag that indicates whether a given pattern fully matches a string or not.
|
||||||
|
func fullyMatch(pattern: String) -> Bool {
|
||||||
|
do {
|
||||||
|
if #available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 6.0, *) {
|
||||||
|
let securityInput = try Regex(pattern)
|
||||||
|
let matches = self.wholeMatch(of: securityInput)
|
||||||
|
|
||||||
|
return matches != nil
|
||||||
|
} else {
|
||||||
|
let securityInput = try NSRegularExpression(pattern: pattern)
|
||||||
|
let matches = securityInput.matches(
|
||||||
|
in: self,
|
||||||
|
range: .init(location: 0, length: count)
|
||||||
|
)
|
||||||
|
|
||||||
|
return !matches.isEmpty
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -77,32 +77,6 @@ private extension SecureValidationRule {
|
|||||||
|
|
||||||
// MARK: Functions
|
// MARK: Functions
|
||||||
|
|
||||||
/// Checks if a given input is valid,
|
|
||||||
/// - Parameter input: An input to validate.
|
|
||||||
/// - Returns: A flag that indicates whether a given input is valid or not.
|
|
||||||
func isValid(_ input: String) -> Bool {
|
|
||||||
let regexPattern = String(format: .Pattern.securityInput, inputType.rawValue)
|
|
||||||
|
|
||||||
do {
|
|
||||||
if #available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 6.0, *) {
|
|
||||||
let securityInput = try Regex(regexPattern)
|
|
||||||
let matches = input.matches(of: securityInput)
|
|
||||||
|
|
||||||
return !matches.isEmpty
|
|
||||||
} else {
|
|
||||||
let securityInput = try NSRegularExpression(pattern: regexPattern)
|
|
||||||
let matches = securityInput.matches(
|
|
||||||
in: input,
|
|
||||||
range: .init(location: 0, length: input.count)
|
|
||||||
)
|
|
||||||
|
|
||||||
return !matches.isEmpty
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Validates a given input.
|
/// Validates a given input.
|
||||||
///
|
///
|
||||||
/// > note: This helper function would not be necessary when support for *Swift 5.10* is discontinued.
|
/// > note: This helper function would not be necessary when support for *Swift 5.10* is discontinued.
|
||||||
@@ -114,7 +88,10 @@ private extension SecureValidationRule {
|
|||||||
guard let input else {
|
guard let input else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
guard isValid(input) else {
|
|
||||||
|
guard input.fullyMatch(
|
||||||
|
pattern: .init(format: .Pattern.securityInput, inputType.rawValue)
|
||||||
|
) else {
|
||||||
switch inputType {
|
switch inputType {
|
||||||
case .consumerKey: throw InputValidationError.inputNotConsumerKey
|
case .consumerKey: throw InputValidationError.inputNotConsumerKey
|
||||||
case .consumerSecret: throw InputValidationError.inputNotConsumerSecret
|
case .consumerSecret: throw InputValidationError.inputNotConsumerSecret
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
// ===----------------------------------------------------------------------===
|
||||||
|
//
|
||||||
|
// This source file is part of the DiscogsService open source project
|
||||||
|
//
|
||||||
|
// Copyright (c) 2025 Röck+Cöde VoF. and the DiscogsService project authors
|
||||||
|
// Licensed under Apache license v2.0
|
||||||
|
//
|
||||||
|
// See LICENSE for license information
|
||||||
|
// See CONTRIBUTORS for the list of DiscogsService project authors
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
// ===----------------------------------------------------------------------===
|
||||||
|
|
||||||
|
import Testing
|
||||||
|
|
||||||
|
@testable import DiscogsService
|
||||||
|
|
||||||
|
@Suite("String Functions", .tags(.extension))
|
||||||
|
struct StringFunctionsTests {
|
||||||
|
|
||||||
|
// MARK: Functions tests
|
||||||
|
|
||||||
|
#if swift(>=6.2)
|
||||||
|
@Test(arguments: zip(
|
||||||
|
Input.stringsToMatch,
|
||||||
|
Output.stringsToMatch
|
||||||
|
))
|
||||||
|
func `fully match`(
|
||||||
|
string: String,
|
||||||
|
expects isMatch: Bool
|
||||||
|
) {
|
||||||
|
assertFullyMatch(
|
||||||
|
string: string,
|
||||||
|
pattern: .Pattern.sample,
|
||||||
|
expects: isMatch
|
||||||
|
)
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
@Test("fully match", arguments: zip(
|
||||||
|
Input.stringsToMatch,
|
||||||
|
Output.stringsToMatch
|
||||||
|
))
|
||||||
|
func fullyMatch(
|
||||||
|
string: String,
|
||||||
|
expects isMatch: Bool
|
||||||
|
) {
|
||||||
|
assertFullyMatch(
|
||||||
|
string: string,
|
||||||
|
pattern: .Pattern.sample,
|
||||||
|
expects: isMatch
|
||||||
|
)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Assertions
|
||||||
|
|
||||||
|
private extension StringFunctionsTests {
|
||||||
|
|
||||||
|
// MARK: Functions
|
||||||
|
|
||||||
|
/// Asserts the result of the `fullyMatch` function.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - string: A string to match against a pattern.
|
||||||
|
/// - pattern: A regular expression pattern to match a string against.
|
||||||
|
/// - isMatch: An expected flag that indicates whether there is a match or not.
|
||||||
|
func assertFullyMatch(
|
||||||
|
string: String,
|
||||||
|
pattern: String,
|
||||||
|
expects isMatch: Bool
|
||||||
|
) {
|
||||||
|
// GIVEN
|
||||||
|
// WHEN
|
||||||
|
let result = string.fullyMatch(pattern: pattern)
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
#expect(result == isMatch)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Constants
|
||||||
|
|
||||||
|
private extension Input {
|
||||||
|
/// A list of strings to match against a regular expression pattern in test cases.
|
||||||
|
static let stringsToMatch: [String] = ["Some Pattern", "Some", "Some Other Pattern", "Pattern", .empty]
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension Output {
|
||||||
|
/// A list of expected results from matching a sample string against a sample regular expression pattern in test cases.
|
||||||
|
static let stringsToMatch: [Bool] = [true, false, false, false, false]
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension String.Pattern {
|
||||||
|
/// A sample regular expression pattern to match against.
|
||||||
|
static let sample = "Some Pattern"
|
||||||
|
}
|
||||||
@@ -18,6 +18,9 @@ extension Tag {
|
|||||||
|
|
||||||
// MARK: Constants
|
// MARK: Constants
|
||||||
|
|
||||||
|
/// A tag that indicates tests for a type extension.
|
||||||
|
@Tag static var `extension`: Self
|
||||||
|
|
||||||
/// A tag that indicates tests for a middleware type.
|
/// A tag that indicates tests for a middleware type.
|
||||||
@Tag static var middleware: Self
|
@Tag static var middleware: Self
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user