Consider CRLF in .index(before:) and .index(after:)

This commit is contained in:
1024jp 2022-02-26 12:41:16 +09:00
parent f0db563d55
commit 3af732f804
2 changed files with 32 additions and 5 deletions

View File

@ -8,7 +8,7 @@
//
// ---------------------------------------------------------------------------
//
// © 2016-2020 1024jp
// © 2016-2022 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -120,7 +120,11 @@ extension NSString {
guard location > 0 else { return 0 }
return self.rangeOfComposedCharacterSequence(at: location - 1).lowerBound
// avoid returing index between CRLF
let index = location - 1
let offset = (self.character(at: index) == 0x000A && self.character(at: index - 1) == 0x000D) ? 1 : 0
return self.rangeOfComposedCharacterSequence(at: index - offset).lowerBound
}
@ -132,9 +136,13 @@ extension NSString {
/// or `location` when the given `location` is the last.
func index(after location: Int) -> Int {
guard location < self.length else { return self.length }
guard location < self.length - 1 else { return self.length }
return self.rangeOfComposedCharacterSequence(at: location).upperBound
// avoid returing index between CRLF
let index = location
let offset = (self.character(at: index) == 0x000D && self.character(at: index + 1) == 0x000A) ? 1 : 0
return self.rangeOfComposedCharacterSequence(at: index + offset).upperBound
}

View File

@ -168,7 +168,7 @@ final class StringExtensionsTests: XCTestCase {
}
func testBeforeAfterIndex() {
func testBeforeIndex() {
XCTAssertEqual(("00" as NSString).index(before: 0), 0)
XCTAssertEqual(("00" as NSString).index(before: 1), 0)
@ -178,11 +178,30 @@ final class StringExtensionsTests: XCTestCase {
XCTAssertEqual(("0🇦🇦00" as NSString).index(before: 5), 1)
XCTAssertEqual(("0🇦🇦00" as NSString).index(before: 6), 5)
XCTAssertEqual(("0\r\n0" as NSString).index(before: 3), 1)
XCTAssertEqual(("0\r\n0" as NSString).index(before: 2), 1)
XCTAssertEqual(("0\r\n0" as NSString).index(before: 1), 0)
XCTAssertEqual(("0\n" as NSString).index(before: 1), 0)
XCTAssertEqual(("0\n" as NSString).index(before: 2), 1)
}
func testAfterIndex() {
XCTAssertEqual(("00" as NSString).index(after: 0), 1)
XCTAssertEqual(("00" as NSString).index(after: 1), 2)
XCTAssertEqual(("00" as NSString).index(after: 2), 2)
XCTAssertEqual(("0🇦🇦0" as NSString).index(after: 0), 1)
XCTAssertEqual(("0🇦🇦0" as NSString).index(after: 1), 5)
XCTAssertEqual(("0\r\n0" as NSString).index(after: 1), 3)
XCTAssertEqual(("0\r\n0" as NSString).index(after: 2), 3)
XCTAssertEqual(("0\r\n0" as NSString).index(after: 3), 4)
XCTAssertEqual(("0\r" as NSString).index(after: 1), 2)
XCTAssertEqual(("0\r" as NSString).index(after: 2), 2)
// composed character does not care CRLF
XCTAssertEqual(("\r\n" as NSString).rangeOfComposedCharacterSequence(at: 1), NSRange(1..<2))
}