// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // // RUN: %target-run-simple-swift // REQUIRES: executable_test // REQUIRES: objc_interop import Foundation #if FOUNDATION_XCTEST import XCTest class TestCharacterSetSuper : XCTestCase { } #else import StdlibUnittest class TestCharacterSetSuper { } #endif class TestCharacterSet : TestCharacterSetSuper { let capitalA = UnicodeScalar(0x0041)! // LATIN CAPITAL LETTER A let capitalB = UnicodeScalar(0x0042)! // LATIN CAPITAL LETTER B let capitalC = UnicodeScalar(0x0043)! // LATIN CAPITAL LETTER C func testBasicConstruction() { // Create a character set let cs = CharacterSet.letters // Use some method from it let invertedCs = cs.inverted expectTrue(!invertedCs.contains(capitalA), "Character set must not contain our letter") // Use another method from it let originalCs = invertedCs.inverted expectTrue(originalCs.contains(capitalA), "Character set must contain our letter") } func testMutability_copyOnWrite() { var firstCharacterSet = CharacterSet(charactersIn: "ABC") expectTrue(firstCharacterSet.contains(capitalA), "Character set must contain our letter") expectTrue(firstCharacterSet.contains(capitalB), "Character set must contain our letter") expectTrue(firstCharacterSet.contains(capitalC), "Character set must contain our letter") // Make a 'copy' (just the struct) var secondCharacterSet = firstCharacterSet // first: ABC, second: ABC // Mutate first and verify that it has correct content firstCharacterSet.remove(charactersIn: "A") // first: BC, second: ABC expectTrue(!firstCharacterSet.contains(capitalA), "Character set must not contain our letter") expectTrue(secondCharacterSet.contains(capitalA), "Copy should not have been mutated") // Make a 'copy' (just the struct) of the second set, mutate it let thirdCharacterSet = secondCharacterSet // first: BC, second: ABC, third: ABC secondCharacterSet.remove(charactersIn: "B") // first: BC, second: AC, third: ABC expectTrue(firstCharacterSet.contains(capitalB), "Character set must contain our letter") expectTrue(!secondCharacterSet.contains(capitalB), "Character set must not contain our letter") expectTrue(thirdCharacterSet.contains(capitalB), "Character set must contain our letter") firstCharacterSet.remove(charactersIn: "C") // first: B, second: AC, third: ABC expectTrue(!firstCharacterSet.contains(capitalC), "Character set must not contain our letter") expectTrue(secondCharacterSet.contains(capitalC), "Character set must not contain our letter") expectTrue(thirdCharacterSet.contains(capitalC), "Character set must contain our letter") } func testMutability_mutableCopyCrash() { let cs = CharacterSet(charactersIn: "ABC") (cs as NSCharacterSet).mutableCopy() // this should not crash } func testMutability_SR_1782() { var nonAlphanumeric = CharacterSet.alphanumerics.inverted nonAlphanumeric.remove(charactersIn: " ") // this should not crash } func testRanges() { // Simple range check let asciiUppercase = CharacterSet(charactersIn: UnicodeScalar(0x41)!...UnicodeScalar(0x5A)!) expectTrue(asciiUppercase.contains(UnicodeScalar(0x49)!)) expectTrue(asciiUppercase.contains(UnicodeScalar(0x5A)!)) expectTrue(asciiUppercase.contains(UnicodeScalar(0x41)!)) expectTrue(!asciiUppercase.contains(UnicodeScalar(0x5B)!)) // Some string filtering tests let asciiLowercase = CharacterSet(charactersIn: UnicodeScalar(0x61)!...UnicodeScalar(0x7B)!) let testString = "helloHELLOhello" let expected = "HELLO" let result = testString.trimmingCharacters(in: asciiLowercase) expectEqual(result, expected) } func testClosedRanges_SR_2988() { // "CharacterSet.insert(charactersIn: ClosedRange) crashes on a closed ClosedRange containing U+D7FF" let problematicChar = UnicodeScalar(0xD7FF)! let range = capitalA...problematicChar var characters = CharacterSet(charactersIn: range) // this should not crash expectTrue(characters.contains(problematicChar)) characters.remove(charactersIn: range) // this should not crash expectTrue(!characters.contains(problematicChar)) characters.insert(charactersIn: range) // this should not crash expectTrue(characters.contains(problematicChar)) } func testUpperBoundaryInsert_SR_2988() { // "CharacterSet.insert(_: Unicode.Scalar) crashes on U+D7FF" let problematicChar = UnicodeScalar(0xD7FF)! var characters = CharacterSet() characters.insert(problematicChar) // this should not crash expectTrue(characters.contains(problematicChar)) characters.remove(problematicChar) // this should not crash expectTrue(!characters.contains(problematicChar)) } func testInsertAndRemove() { var asciiUppercase = CharacterSet(charactersIn: UnicodeScalar(0x41)!...UnicodeScalar(0x5A)!) expectTrue(asciiUppercase.contains(UnicodeScalar(0x49)!)) expectTrue(asciiUppercase.contains(UnicodeScalar(0x5A)!)) expectTrue(asciiUppercase.contains(UnicodeScalar(0x41)!)) asciiUppercase.remove(UnicodeScalar(0x49)!) expectTrue(!asciiUppercase.contains(UnicodeScalar(0x49)!)) expectTrue(asciiUppercase.contains(UnicodeScalar(0x5A)!)) expectTrue(asciiUppercase.contains(UnicodeScalar(0x41)!)) // Zero-length range asciiUppercase.remove(charactersIn: UnicodeScalar(0x41)!..