@@ -19,6 +19,8 @@ class TestNSRange : XCTestCase {
1919 ( " test_NSUnionRange " , test_NSUnionRange) ,
2020 ( " test_NSIntersectionRange " , test_NSIntersectionRange) ,
2121 ( " test_NSStringFromRange " , test_NSStringFromRange) ,
22+ ( " test_init_region_in_ascii_string " , test_init_region_in_ascii_string) ,
23+ ( " test_init_region_in_unicode_string " , test_init_region_in_unicode_string) ,
2224 ]
2325 }
2426
@@ -126,4 +128,53 @@ class TestNSRange : XCTestCase {
126128 XCTAssertEqual ( NSStringFromRange ( range) , string)
127129 }
128130 }
131+
132+ /// Specialized for the below tests.
133+ private func _assertNSRangeInit< S: StringProtocol , R: RangeExpression > (
134+ _ region: R , in target: S , is rangeString: String
135+ ) where R. Bound == S . Index {
136+ XCTAssert ( NSEqualRanges ( NSRangeFromString ( rangeString) , NSRange ( region, in: target) ) )
137+ }
138+
139+ func test_init_region_in_ascii_string( ) {
140+ // all count = 18
141+ let normalString = " 1;DROP TABLE users "
142+
143+ _assertNSRangeInit ( normalString. index ( normalString. startIndex, offsetBy: 2 ) ..< normalString. index ( normalString. endIndex, offsetBy: - 6 ) , in: normalString, is: " {2, 10} " )
144+ _assertNSRangeInit ( normalString. index ( after: normalString. startIndex) ... normalString. index ( before: normalString. endIndex) , in: normalString, is: " {1, 17} " )
145+ _assertNSRangeInit ( normalString. startIndex... , in: normalString, is: " {0, 18} " )
146+ _assertNSRangeInit ( ... normalString. firstIndex ( of: " " ) !, in: normalString, is: " {0, 7} " )
147+ _assertNSRangeInit ( ..< normalString. lastIndex ( of: " " ) !, in: normalString, is: " {0, 12} " )
148+
149+ let normalSubstring : Substring = normalString. split ( separator: " ; " ) [ 1 ]
150+
151+ _assertNSRangeInit ( normalSubstring. range ( of: " TABLE " ) !, in: normalSubstring, is: " {5, 5} " )
152+ _assertNSRangeInit ( normalSubstring. index ( after: normalSubstring. firstIndex ( of: " " ) !) ..< normalSubstring. lastIndex ( of: " " ) !, in: normalString, is: " {7, 5} " )
153+ _assertNSRangeInit ( normalSubstring. firstIndex ( of: " u " ) !... normalSubstring. lastIndex ( of: " u " ) !, in: normalSubstring, is: " {11, 1} " )
154+ _assertNSRangeInit ( normalSubstring. startIndex... , in: normalSubstring, is: " {0, 16} " )
155+ _assertNSRangeInit ( normalSubstring. startIndex... , in: normalString, is: " {2, 16} " )
156+ _assertNSRangeInit ( ... normalSubstring. lastIndex ( of: " " ) !, in: normalSubstring, is: " {0, 11} " )
157+ _assertNSRangeInit ( ..< normalSubstring. lastIndex ( of: " " ) !, in: normalString, is: " {0, 12} " )
158+ }
159+
160+ func test_init_region_in_unicode_string( ) {
161+ // count: 46, utf8: 90, utf16: 54
162+ let unicodeString = " This is a #naughty👻 string (╯°□°)╯︵ ┻━┻👨👩👧👦) "
163+
164+ _assertNSRangeInit ( unicodeString. index ( unicodeString. startIndex, offsetBy: 10 ) ..< unicodeString. index ( unicodeString. startIndex, offsetBy: 28 ) , in: unicodeString, is: " {10, 19} " )
165+ _assertNSRangeInit ( unicodeString. index ( after: unicodeString. startIndex) ... unicodeString. index ( before: unicodeString. endIndex) , in: unicodeString, is: " {1, 53} " )
166+ _assertNSRangeInit ( unicodeString. startIndex... , in: unicodeString, is: " {0, 54} " )
167+ _assertNSRangeInit ( ... unicodeString. firstIndex ( of: " 👻 " ) !, in: unicodeString, is: " {0, 22} " )
168+ _assertNSRangeInit ( ..< unicodeString. range ( of: " 👨👩👧👦 " ) !. lowerBound, in: unicodeString, is: " {0, 42} " )
169+
170+ let unicodeSubstring : Substring = unicodeString [ unicodeString. firstIndex ( of: " 👻 " ) !... ]
171+
172+ _assertNSRangeInit ( unicodeSubstring. range ( of: " 👨👩👧👦 " ) !, in: unicodeSubstring, is: " {22, 11} " )
173+ _assertNSRangeInit ( unicodeSubstring. range ( of: " 👨 " ) !. lowerBound..< unicodeSubstring. range ( of: " 👦 " ) !. upperBound, in: unicodeString, is: " {42, 11} " )
174+ _assertNSRangeInit ( unicodeSubstring. index ( after: unicodeSubstring. startIndex) ... unicodeSubstring. index ( before: unicodeSubstring. endIndex) , in: unicodeSubstring, is: " {2, 32} " )
175+ _assertNSRangeInit ( unicodeSubstring. startIndex... , in: unicodeSubstring, is: " {0, 34} " )
176+ _assertNSRangeInit ( unicodeSubstring. startIndex... , in: unicodeString, is: " {20, 34} " )
177+ _assertNSRangeInit ( ... unicodeSubstring. firstIndex ( of: " ╯ " ) !, in: unicodeSubstring, is: " {0, 12} " )
178+ _assertNSRangeInit ( ..< unicodeSubstring. firstIndex ( of: " ╯ " ) !, in: unicodeString, is: " {0, 31} " )
179+ }
129180}
0 commit comments