1010//
1111//===----------------------------------------------------------------------===//
1212
13- #if canImport(TestSupport)
14- import TestSupport
13+ import Testing
14+
15+ #if canImport(FoundationEssentials)
16+ import FoundationEssentials
17+ #else
18+ import Foundation
1519#endif
1620
17- class TestAttributedStringConstrainingBehavior : XCTestCase {
21+ @Suite ( " AttributedString Constraining Behavior " )
22+ private struct AttributedStringConstrainingBehaviorTests {
1823
1924 func verify< K: AttributedStringKey > (
2025 string: AttributedString ,
2126 matches expected: [ ( String , K . Value ? ) ] ,
2227 for key: KeyPath < AttributeDynamicLookup , K > ,
23- file : StaticString = #filePath , line : UInt = #line
24- )
28+ sourceLocation : SourceLocation = #_sourceLocation
29+ )
2530 where K. Value : Sendable
2631 {
2732 let runs = string. runs [ key]
28- XCTAssertEqual ( runs. count, expected. count, " Unexpected number of runs " , file : file , line : line )
33+ #expect ( runs. count == expected. count, " Unexpected number of runs " , sourceLocation : sourceLocation )
2934 for (( val, range) , expectation) in zip ( runs, expected) {
3035 let slice = String . UnicodeScalarView ( string. unicodeScalars [ range] )
31- XCTAssertTrue ( slice. elementsEqual ( expectation. 0 . unicodeScalars) , " Unexpected range of run: \( slice. debugDescription) vs \( expectation. 0 . debugDescription) " , file : file , line : line )
32- XCTAssertEqual ( val, expectation. 1 , " Unexpected value of attribute \( K . self) for range \( expectation. 0 ) " , file : file , line : line )
36+ #expect ( slice. elementsEqual ( expectation. 0 . unicodeScalars) , " Unexpected range of run: \( slice. debugDescription) vs \( expectation. 0 . debugDescription) " , sourceLocation : sourceLocation )
37+ #expect ( val == expectation. 1 , " Unexpected value of attribute \( K . self) for range \( expectation. 0 ) " , sourceLocation : sourceLocation )
3338 }
3439 for (( val, range) , expectation) in zip ( runs. reversed ( ) , expected. reversed ( ) ) {
3540 let slice = String . UnicodeScalarView ( string. unicodeScalars [ range] )
36- XCTAssertTrue ( slice. elementsEqual ( expectation. 0 . unicodeScalars) , " Unexpected range of run while reverse iterating: \( slice. debugDescription) vs \( expectation. 0 . debugDescription) " , file : file , line : line )
37- XCTAssertEqual ( val, expectation. 1 , " Unexpected value of attribute \( K . self) for range \( expectation. 0 ) while reverse iterating " , file : file , line : line )
41+ #expect ( slice. elementsEqual ( expectation. 0 . unicodeScalars) , " Unexpected range of run while reverse iterating: \( slice. debugDescription) vs \( expectation. 0 . debugDescription) " , sourceLocation : sourceLocation )
42+ #expect ( val == expectation. 1 , " Unexpected value of attribute \( K . self) for range \( expectation. 0 ) while reverse iterating " , sourceLocation : sourceLocation )
3843 }
3944 }
4045
41- func verify< K: AttributedStringKey , K2: AttributedStringKey > ( string: AttributedString , matches expected: [ ( String , K . Value ? , K2 . Value ? ) ] , for key: KeyPath < AttributeDynamicLookup , K > , _ key2: KeyPath < AttributeDynamicLookup , K2 > , file : StaticString = #filePath , line : UInt = #line )
46+ func verify< K: AttributedStringKey , K2: AttributedStringKey > ( string: AttributedString , matches expected: [ ( String , K . Value ? , K2 . Value ? ) ] , for key: KeyPath < AttributeDynamicLookup , K > , _ key2: KeyPath < AttributeDynamicLookup , K2 > , sourceLocation : SourceLocation = #_sourceLocation )
4247 where K. Value : Sendable , K2. Value : Sendable
4348 {
4449 let runs = string. runs [ key, key2]
45- XCTAssertEqual ( runs. count, expected. count, " Unexpected number of runs " , file : file , line : line )
50+ #expect ( runs. count == expected. count, " Unexpected number of runs " , sourceLocation : sourceLocation )
4651 for (( val1, val2, range) , expectation) in zip ( runs, expected) {
47- XCTAssertEqual ( String ( string. characters [ range] ) , expectation. 0 , " Unexpected range of run " , file : file , line : line )
48- XCTAssertEqual ( val1, expectation. 1 , " Unexpected value of attribute \( K . self) for range \( expectation. 0 ) " , file : file , line : line )
49- XCTAssertEqual ( val2, expectation. 2 , " Unexpected value of attribute \( K2 . self) for range \( expectation. 0 ) " , file : file , line : line )
52+ #expect ( String ( string. characters [ range] ) == expectation. 0 , " Unexpected range of run " , sourceLocation : sourceLocation )
53+ #expect ( val1 == expectation. 1 , " Unexpected value of attribute \( K . self) for range \( expectation. 0 ) " , sourceLocation : sourceLocation )
54+ #expect ( val2 == expectation. 2 , " Unexpected value of attribute \( K2 . self) for range \( expectation. 0 ) " , sourceLocation : sourceLocation )
5055 }
5156 for (( val1, val2, range) , expectation) in zip ( runs. reversed ( ) , expected. reversed ( ) ) {
52- XCTAssertEqual ( String ( string. characters [ range] ) , expectation. 0 , " Unexpected range of run while reverse iterating " , file : file , line : line )
53- XCTAssertEqual ( val1, expectation. 1 , " Unexpected value of attribute \( K . self) for range \( expectation. 0 ) while reverse iterating " , file : file , line : line )
54- XCTAssertEqual ( val2, expectation. 2 , " Unexpected value of attribute \( K2 . self) for range \( expectation. 0 ) while reverse iterating " , file : file , line : line )
57+ #expect ( String ( string. characters [ range] ) == expectation. 0 , " Unexpected range of run while reverse iterating " , sourceLocation : sourceLocation )
58+ #expect ( val1 == expectation. 1 , " Unexpected value of attribute \( K . self) for range \( expectation. 0 ) while reverse iterating " , sourceLocation : sourceLocation )
59+ #expect ( val2 == expectation. 2 , " Unexpected value of attribute \( K2 . self) for range \( expectation. 0 ) while reverse iterating " , sourceLocation : sourceLocation )
5560 }
5661 }
5762
58- func verify< K: AttributedStringKey , K2: AttributedStringKey , K3: AttributedStringKey > ( string: AttributedString , matches expected: [ ( String , K . Value ? , K2 . Value ? , K3 . Value ? ) ] , for key: KeyPath < AttributeDynamicLookup , K > , _ key2: KeyPath < AttributeDynamicLookup , K2 > , _ key3: KeyPath < AttributeDynamicLookup , K3 > , file : StaticString = #filePath , line : UInt = #line )
63+ func verify< K: AttributedStringKey , K2: AttributedStringKey , K3: AttributedStringKey > ( string: AttributedString , matches expected: [ ( String , K . Value ? , K2 . Value ? , K3 . Value ? ) ] , for key: KeyPath < AttributeDynamicLookup , K > , _ key2: KeyPath < AttributeDynamicLookup , K2 > , _ key3: KeyPath < AttributeDynamicLookup , K3 > , sourceLocation : SourceLocation = #_sourceLocation )
5964 where K. Value : Sendable , K2. Value : Sendable , K3. Value : Sendable
6065 {
6166 let runs = string. runs [ key, key2, key3]
62- XCTAssertEqual ( runs. count, expected. count, " Unexpected number of runs " , file : file , line : line )
67+ #expect ( runs. count == expected. count, " Unexpected number of runs " , sourceLocation : sourceLocation )
6368 for (( val1, val2, val3, range) , expectation) in zip ( runs, expected) {
64- XCTAssertEqual ( String ( string. characters [ range] ) , expectation. 0 , " Unexpected range of run " , file : file , line : line )
65- XCTAssertEqual ( val1, expectation. 1 , " Unexpected value of attribute \( K . self) for range \( expectation. 0 ) " , file : file , line : line )
66- XCTAssertEqual ( val2, expectation. 2 , " Unexpected value of attribute \( K2 . self) for range \( expectation. 0 ) " , file : file , line : line )
67- XCTAssertEqual ( val3, expectation. 3 , " Unexpected value of attribute \( K3 . self) for range \( expectation. 0 ) " , file : file , line : line )
69+ #expect ( String ( string. characters [ range] ) == expectation. 0 , " Unexpected range of run " , sourceLocation : sourceLocation )
70+ #expect ( val1 == expectation. 1 , " Unexpected value of attribute \( K . self) for range \( expectation. 0 ) " , sourceLocation : sourceLocation )
71+ #expect ( val2 == expectation. 2 , " Unexpected value of attribute \( K2 . self) for range \( expectation. 0 ) " , sourceLocation : sourceLocation )
72+ #expect ( val3 == expectation. 3 , " Unexpected value of attribute \( K3 . self) for range \( expectation. 0 ) " , sourceLocation : sourceLocation )
6873 }
6974 for (( val1, val2, val3, range) , expectation) in zip ( runs. reversed ( ) , expected. reversed ( ) ) {
70- XCTAssertEqual ( String ( string. characters [ range] ) , expectation. 0 , " Unexpected range of run while reverse iterating " , file : file , line : line )
71- XCTAssertEqual ( val1, expectation. 1 , " Unexpected value of attribute \( K . self) for range \( expectation. 0 ) while reverse iterating " , file : file , line : line )
72- XCTAssertEqual ( val2, expectation. 2 , " Unexpected value of attribute \( K2 . self) for range \( expectation. 0 ) while reverse iterating " , file : file , line : line )
73- XCTAssertEqual ( val3, expectation. 3 , " Unexpected value of attribute \( K3 . self) for range \( expectation. 0 ) while reverse iterating " , file : file , line : line )
75+ #expect ( String ( string. characters [ range] ) == expectation. 0 , " Unexpected range of run while reverse iterating " , sourceLocation : sourceLocation )
76+ #expect ( val1 == expectation. 1 , " Unexpected value of attribute \( K . self) for range \( expectation. 0 ) while reverse iterating " , sourceLocation : sourceLocation )
77+ #expect ( val2 == expectation. 2 , " Unexpected value of attribute \( K2 . self) for range \( expectation. 0 ) while reverse iterating " , sourceLocation : sourceLocation )
78+ #expect ( val3 == expectation. 3 , " Unexpected value of attribute \( K3 . self) for range \( expectation. 0 ) while reverse iterating " , sourceLocation : sourceLocation )
7479 }
7580 }
7681
7782 // MARK: Extending Run Tests
7883
79- func testExtendingRunAddCharacters ( ) {
84+ @ Test func extendingRunAddCharacters ( ) {
8085 let str = AttributedString ( " Hello, world " , attributes: . init( ) . testInt ( 2 ) . testNonExtended ( 1 ) )
8186
8287 var result = str
@@ -103,7 +108,7 @@ class TestAttributedStringConstrainingBehavior: XCTestCase {
103108 verify ( string: result, matches: [ ( " He " , 2 , 1 ) , ( " Hi! " , 2 , nil ) , ( " rld " , 2 , 1 ) ] , for: \. testInt, \. testNonExtended)
104109 }
105110
106- func testExtendingRunAddUnicodeScalars ( ) {
111+ @ Test func extendingRunAddUnicodeScalars ( ) {
107112 let str = AttributedString ( " Hello, world " , attributes: . init( ) . testInt ( 2 ) . testNonExtended ( 1 ) )
108113 let scalarsStr = " A \u{0301} B "
109114
@@ -127,7 +132,7 @@ class TestAttributedStringConstrainingBehavior: XCTestCase {
127132
128133 // MARK: - Paragraph Constrained Tests
129134
130- func testParagraphAttributeExpanding ( ) {
135+ @ Test func paragraphAttributeExpanding ( ) {
131136 var str = AttributedString ( " Hello, world \n Next Paragraph " )
132137 var range = str. index ( afterCharacter: str. startIndex) ..< str. index ( str. startIndex, offsetByCharacters: 3 )
133138 str [ range] . testParagraphConstrained = 2
@@ -148,7 +153,7 @@ class TestAttributedStringConstrainingBehavior: XCTestCase {
148153 verify ( string: str, matches: [ ( " Hello, world \n " , 4 ) , ( " Next Paragraph " , 4 ) ] , for: \. testParagraphConstrained)
149154 }
150155
151- func testParagraphAttributeRemoval ( ) {
156+ @ Test func paragraphAttributeRemoval ( ) {
152157 var str = AttributedString ( " Hello, world \n Next Paragraph " , attributes: . init( ) . testParagraphConstrained ( 2 ) )
153158 var range = str. index ( afterCharacter: str. startIndex) ..< str. index ( str. startIndex, offsetByCharacters: 3 )
154159 str [ range] . testParagraphConstrained = nil
@@ -167,7 +172,7 @@ class TestAttributedStringConstrainingBehavior: XCTestCase {
167172 verify ( string: str, matches: [ ( " Hello, world \n " , nil ) , ( " Next Paragraph " , nil ) ] , for: \. testParagraphConstrained)
168173 }
169174
170- func testParagraphAttributeContainerApplying ( ) {
175+ @ Test func paragraphAttributeContainerApplying ( ) {
171176 var container = AttributeContainer . testParagraphConstrained ( 2 ) . testString ( " Hello " )
172177 var str = AttributedString ( " Hello, world \n Next Paragraph " )
173178 var range = str. index ( afterCharacter: str. startIndex) ..< str. index ( str. startIndex, offsetByCharacters: 3 )
@@ -195,7 +200,7 @@ class TestAttributedStringConstrainingBehavior: XCTestCase {
195200 verify ( string: str, matches: [ ( " H " , 4 , nil , 1 ) , ( " el " , 4 , " Hello " , 1 ) , ( " lo, w " , 4 , nil , 1 ) , ( " orld \n " , 4 , nil , 2 ) , ( " N " , 4 , nil , 2 ) , ( " ext Paragrap " , 4 , nil , 1 ) , ( " h " , 4 , " Hello " , 2 ) ] , for: \. testParagraphConstrained, \. testString, \. testInt)
196201 }
197202
198- func testParagraphAttributeContainerReplacing ( ) {
203+ @ Test func paragraphAttributeContainerReplacing ( ) {
199204 var str = AttributedString ( " Hello, world \n Next Paragraph " )
200205 let range = str. index ( afterCharacter: str. startIndex) ..< str. index ( str. startIndex, offsetByCharacters: 3 )
201206 str [ range] . testInt = 2
@@ -216,7 +221,7 @@ class TestAttributedStringConstrainingBehavior: XCTestCase {
216221 verify ( string: result, matches: [ ( " H " , 3 , 2 , nil ) , ( " el " , 3 , nil , true ) , ( " lo, world \n " , 3 , 2 , nil ) , ( " Next Paragraph " , nil , 2 , nil ) ] , for: \. testParagraphConstrained, \. testInt, \. testBool)
217222 }
218223
219- func testParagraphTextMutation ( ) {
224+ @ Test func paragraphTextMutation ( ) {
220225 let str = AttributedString ( " Hello, world \n " , attributes: . init( ) . testParagraphConstrained ( 1 ) ) + AttributedString( " Next Paragraph " , attributes: . init( ) . testParagraphConstrained ( 2 ) )
221226
222227 var result = str
@@ -260,7 +265,7 @@ class TestAttributedStringConstrainingBehavior: XCTestCase {
260265 verify ( string: result, matches: [ ( " Hello, wTest \n " , 1 ) , ( " Replacementxt Paragraph " , 1 ) ] , for: \. testParagraphConstrained)
261266 }
262267
263- func testParagraphAttributedTextMutation ( ) {
268+ @ Test func paragraphAttributedTextMutation ( ) {
264269 let str = AttributedString ( " Hello, world \n " , attributes: . init( ) . testParagraphConstrained ( 1 ) ) + AttributedString( " Next Paragraph " , attributes: . init( ) . testParagraphConstrained ( 2 ) )
265270 let singleReplacement = AttributedString ( " Test " , attributes: . init( ) . testParagraphConstrained ( 5 ) . testSecondParagraphConstrained ( 6 ) . testBool ( true ) )
266271 let multiReplacement = AttributedString ( " Test \n Inserted " , attributes: . init( ) . testParagraphConstrained ( 5 ) . testSecondParagraphConstrained ( 6 ) . testBool ( true ) )
@@ -311,7 +316,7 @@ class TestAttributedStringConstrainingBehavior: XCTestCase {
311316 }
312317
313318#if FOUNDATION_FRAMEWORK
314- func testParagraphFromUntrustedRuns ( ) throws {
319+ @ Test func paragraphFromUntrustedRuns ( ) throws {
315320 let str = NSMutableAttributedString ( string: " Hello " , attributes: [ . testParagraphConstrained : NSNumber ( 2 ) ] )
316321 str. append ( NSAttributedString ( string: " World " , attributes: [ . testParagraphConstrained : NSNumber ( 3 ) , . testSecondParagraphConstrained : NSNumber ( 4 ) ] ) )
317322
@@ -320,7 +325,7 @@ class TestAttributedStringConstrainingBehavior: XCTestCase {
320325 }
321326#endif // FOUNDATION_FRAMEWORK
322327
323- func testParagraphFromReplacedSubrange ( ) {
328+ @ Test func paragraphFromReplacedSubrange ( ) {
324329 let str = AttributedString ( " Before \n Hello, world \n Next Paragraph \n After " , attributes: . init( ) . testParagraphConstrained ( 1 ) )
325330
326331 // Range of "world\nNext"
@@ -344,7 +349,7 @@ class TestAttributedStringConstrainingBehavior: XCTestCase {
344349
345350 // MARK: - Character Constrained Tests
346351
347- func testCharacterAttributeApply ( ) {
352+ @ Test func characterAttributeApply ( ) {
348353 let str = AttributedString ( " *__*__**__* " )
349354
350355 var result = str
@@ -362,7 +367,7 @@ class TestAttributedStringConstrainingBehavior: XCTestCase {
362367 verify ( string: result, matches: [ ( " * " , nil , 1 ) , ( " __ " , nil , 1 ) , ( " * " , nil , 1 ) , ( " __ " , nil , 1 ) , ( " * " , nil , 1 ) , ( " * " , nil , 1 ) , ( " __ " , nil , 1 ) , ( " * " , 3 , 1 ) ] , for: \. testCharacterConstrained, \. testInt)
363368 }
364369
365- func testCharacterAttributeSubCharacterApply ( ) {
370+ @ Test func characterAttributeSubCharacterApply ( ) {
366371 let str = AttributedString ( " ABC \u{FFFD} DEF " )
367372
368373 var result = str
@@ -394,7 +399,7 @@ class TestAttributedStringConstrainingBehavior: XCTestCase {
394399
395400 }
396401
397- func testCharacterAttributeContainerReplacing ( ) {
402+ @ Test func characterAttributeContainerReplacing ( ) {
398403 var str = AttributedString ( " *__*__**__* " )
399404 let range = str. index ( afterCharacter: str. startIndex) ..< str. index ( str. startIndex, offsetByCharacters: 4 )
400405 str [ range] . testInt = 2
@@ -415,7 +420,7 @@ class TestAttributedStringConstrainingBehavior: XCTestCase {
415420 verify ( string: result, matches: [ ( " * " , nil , 2 , nil ) , ( " __ " , nil , nil , true ) , ( " * " , 3 , nil , true ) , ( " __ " , nil , 2 , nil ) , ( " * " , nil , 2 , nil ) , ( " * " , nil , 2 , nil ) , ( " __ " , nil , 2 , nil ) , ( " * " , nil , 2 , nil ) ] , for: \. testCharacterConstrained, \. testInt, \. testBool)
416421 }
417422
418- func testCharacterTextMutation ( ) {
423+ @ Test func characterTextMutation ( ) {
419424 let str = AttributedString ( " *__*__**__* " , attributes: . init( ) . testCharacterConstrained ( 2 ) )
420425
421426 var result = str
@@ -444,7 +449,7 @@ class TestAttributedStringConstrainingBehavior: XCTestCase {
444449 }
445450
446451#if FOUNDATION_FRAMEWORK
447- func testCharacterFromUntrustedRuns ( ) throws {
452+ @ Test func characterFromUntrustedRuns ( ) throws {
448453 let str = NSMutableAttributedString ( string: " *__*__**__* " , attributes: [ . testCharacterConstrained : NSNumber ( 2 ) ] )
449454 str. append ( NSAttributedString ( string: " _* " ) )
450455
@@ -455,7 +460,7 @@ class TestAttributedStringConstrainingBehavior: XCTestCase {
455460
456461 // MARK: Invalidation Tests
457462
458- func testInvalidationAttributeChange ( ) {
463+ @ Test func invalidationAttributeChange ( ) {
459464 let str = AttributedString ( " Hello, world " , attributes: . init( ) . testInt ( 1 ) . testAttributeDependent ( 2 ) )
460465
461466 var result = str
@@ -489,7 +494,7 @@ class TestAttributedStringConstrainingBehavior: XCTestCase {
489494 verify ( string: result, matches: [ ( " Hello, world " , 2 , nil ) ] , for: \. testInt, \. testAttributeDependent)
490495 }
491496
492- func testInvalidationCharacterChange ( ) {
497+ @ Test func invalidationCharacterChange ( ) {
493498 let str = AttributedString ( " Hello, world " , attributes: . init( ) . testInt ( 1 ) . testCharacterDependent ( 2 ) )
494499
495500 var result = str
@@ -575,7 +580,7 @@ class TestAttributedStringConstrainingBehavior: XCTestCase {
575580 verify ( string: result, matches: [ ( " H " , nil , nil , " Hello " ) , ( " ello, world " , 1 , nil , nil ) ] , for: \. testInt, \. testCharacterDependent, \. testString)
576581 }
577582
578- func testInvalidationCharacterInsertionBetweenRuns ( ) {
583+ @ Test func invalidationCharacterInsertionBetweenRuns ( ) {
579584 var str = AttributedString ( " Hello " , attributes: . init( ) . testInt ( 1 ) . testCharacterDependent ( 2 ) )
580585 str += AttributedString ( " World " , attributes: . init( ) . testInt ( 1 ) . testCharacterDependent ( 3 ) )
581586
0 commit comments