Implemented the "fullyMatch(pattern: )" function for the String+Functions extension in the library target.

This commit is contained in:
2025-10-12 22:58:36 +02:00
parent cdee784fff
commit cd157bc3c3
4 changed files with 151 additions and 27 deletions
@@ -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
/// 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.
///
/// > 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 {
return false
}
guard isValid(input) else {
guard input.fullyMatch(
pattern: .init(format: .Pattern.securityInput, inputType.rawValue)
) else {
switch inputType {
case .consumerKey: throw InputValidationError.inputNotConsumerKey
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
/// A tag that indicates tests for a type extension.
@Tag static var `extension`: Self
/// A tag that indicates tests for a middleware type.
@Tag static var middleware: Self