Add comprehensive iOS unit and UI test suites for greenfield test plan
- Create unit tests: DataLayerTests (27 tests for DATA-001–007), DataManagerExtendedTests (20 tests for TASK-005, TASK-012, TCOMP-003, THEME-001, QA-002), plus ValidationHelpers, TaskMetrics, StringExtensions, DoubleExtensions, DateUtils, DocumentHelpers, ErrorMessageParser - Create UI tests: AuthenticationTests, PasswordResetTests, OnboardingTests, TaskIntegration, ContractorIntegration, ResidenceIntegration, DocumentIntegration, DataLayer, Stability - Add UI test framework: AuthenticatedTestCase, ScreenObjects, TestFlows, TestAccountManager, TestAccountAPIClient, TestDataCleaner, TestDataSeeder - Add accessibility identifiers to password reset views for UI test support - Add greenfield test plan CSVs and update automated column for 27 test IDs - All 297 unit tests pass across 60 suites Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
203
iosApp/CaseraTests/StringExtensionsTests.swift
Normal file
203
iosApp/CaseraTests/StringExtensionsTests.swift
Normal file
@@ -0,0 +1,203 @@
|
||||
//
|
||||
// StringExtensionsTests.swift
|
||||
// CaseraTests
|
||||
//
|
||||
// Unit tests for String and Optional<String> extensions.
|
||||
//
|
||||
|
||||
import Testing
|
||||
@testable import Casera
|
||||
|
||||
// MARK: - isBlank Tests
|
||||
|
||||
struct IsBlankTests {
|
||||
|
||||
@Test func emptyStringIsBlank() {
|
||||
#expect("".isBlank)
|
||||
}
|
||||
|
||||
@Test func whitespaceOnlyIsBlank() {
|
||||
#expect(" ".isBlank)
|
||||
}
|
||||
|
||||
@Test func nonEmptyIsNotBlank() {
|
||||
#expect(!"hello".isBlank)
|
||||
}
|
||||
|
||||
@Test func stringWithWhitespacePaddingIsNotBlank() {
|
||||
#expect(!" hello ".isBlank)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - nilIfBlank Tests
|
||||
|
||||
struct NilIfBlankTests {
|
||||
|
||||
@Test func emptyReturnsNil() {
|
||||
#expect("".nilIfBlank == nil)
|
||||
}
|
||||
|
||||
@Test func whitespaceOnlyReturnsNil() {
|
||||
#expect(" ".nilIfBlank == nil)
|
||||
}
|
||||
|
||||
@Test func nonEmptyReturnsTrimmed() {
|
||||
#expect(" hello ".nilIfBlank == "hello")
|
||||
}
|
||||
|
||||
@Test func plainStringReturnsSelf() {
|
||||
#expect("test".nilIfBlank == "test")
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - capitalizedFirst Tests
|
||||
|
||||
struct CapitalizedFirstTests {
|
||||
|
||||
@Test func lowercaseFirstCapitalized() {
|
||||
#expect("hello".capitalizedFirst == "Hello")
|
||||
}
|
||||
|
||||
@Test func alreadyCapitalizedUnchanged() {
|
||||
#expect("Hello".capitalizedFirst == "Hello")
|
||||
}
|
||||
|
||||
@Test func allUppercaseOnlyFirstKept() {
|
||||
#expect("hELLO".capitalizedFirst == "HELLO")
|
||||
}
|
||||
|
||||
@Test func emptyStringReturnsEmpty() {
|
||||
#expect("".capitalizedFirst == "")
|
||||
}
|
||||
|
||||
@Test func singleCharCapitalized() {
|
||||
#expect("a".capitalizedFirst == "A")
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - truncated Tests
|
||||
|
||||
struct TruncatedTests {
|
||||
|
||||
@Test func shortStringNotTruncated() {
|
||||
#expect("hi".truncated(to: 10) == "hi")
|
||||
}
|
||||
|
||||
@Test func longStringTruncatedWithEllipsis() {
|
||||
#expect("Hello World".truncated(to: 5) == "Hello...")
|
||||
}
|
||||
|
||||
@Test func longStringTruncatedWithoutEllipsis() {
|
||||
#expect("Hello World".truncated(to: 5, addEllipsis: false) == "Hello")
|
||||
}
|
||||
|
||||
@Test func exactLengthNotTruncated() {
|
||||
#expect("Hello".truncated(to: 5) == "Hello")
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - isValidEmail Tests
|
||||
|
||||
struct IsValidEmailTests {
|
||||
|
||||
@Test func standardEmailValid() {
|
||||
#expect("user@example.com".isValidEmail)
|
||||
}
|
||||
|
||||
@Test func emailWithSubdomainValid() {
|
||||
#expect("user@mail.example.com".isValidEmail)
|
||||
}
|
||||
|
||||
@Test func emailWithPlusValid() {
|
||||
#expect("user+tag@example.com".isValidEmail)
|
||||
}
|
||||
|
||||
@Test func emailWithDotsValid() {
|
||||
#expect("first.last@example.com".isValidEmail)
|
||||
}
|
||||
|
||||
@Test func noAtSignInvalid() {
|
||||
#expect(!"userexample.com".isValidEmail)
|
||||
}
|
||||
|
||||
@Test func noDomainInvalid() {
|
||||
#expect(!"user@".isValidEmail)
|
||||
}
|
||||
|
||||
@Test func noTLDInvalid() {
|
||||
#expect(!"user@example".isValidEmail)
|
||||
}
|
||||
|
||||
@Test func emptyStringInvalid() {
|
||||
#expect(!"".isValidEmail)
|
||||
}
|
||||
|
||||
@Test func numericLocalPartValid() {
|
||||
#expect("123@example.com".isValidEmail)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - isValidPhone Tests
|
||||
|
||||
struct IsValidPhoneTests {
|
||||
|
||||
@Test func tenDigitsValid() {
|
||||
#expect("5551234567".isValidPhone)
|
||||
}
|
||||
|
||||
@Test func formattedUSPhoneValid() {
|
||||
#expect("(555) 123-4567".isValidPhone)
|
||||
}
|
||||
|
||||
@Test func internationalFormatValid() {
|
||||
#expect("+1 555-123-4567".isValidPhone)
|
||||
}
|
||||
|
||||
@Test func tooShortInvalid() {
|
||||
#expect(!"12345".isValidPhone)
|
||||
}
|
||||
|
||||
@Test func lettersInvalid() {
|
||||
#expect(!"555-ABC-DEFG".isValidPhone)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Optional String Tests
|
||||
|
||||
struct OptionalStringTests {
|
||||
|
||||
@Test func nilIsNilOrBlank() {
|
||||
let s: String? = nil
|
||||
#expect(s.isNilOrBlank)
|
||||
}
|
||||
|
||||
@Test func emptyIsNilOrBlank() {
|
||||
let s: String? = ""
|
||||
#expect(s.isNilOrBlank)
|
||||
}
|
||||
|
||||
@Test func whitespaceIsNilOrBlank() {
|
||||
let s: String? = " "
|
||||
#expect(s.isNilOrBlank)
|
||||
}
|
||||
|
||||
@Test func valueIsNotNilOrBlank() {
|
||||
let s: String? = "hello"
|
||||
#expect(!s.isNilOrBlank)
|
||||
}
|
||||
|
||||
@Test func nilNilIfBlankReturnsNil() {
|
||||
let s: String? = nil
|
||||
#expect(s.nilIfBlank == nil)
|
||||
}
|
||||
|
||||
@Test func blankOptionalNilIfBlankReturnsNil() {
|
||||
let s: String? = " "
|
||||
#expect(s.nilIfBlank == nil)
|
||||
}
|
||||
|
||||
@Test func valueOptionalNilIfBlankReturnsTrimmed() {
|
||||
let s: String? = " hello "
|
||||
#expect(s.nilIfBlank == "hello")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user