From 6b1f356841828ca6c4747b0dd08a93000dd2a219 Mon Sep 17 00:00:00 2001 From: Toni Sevener Date: Wed, 13 Dec 2023 17:41:29 -0600 Subject: [PATCH] Add tests, fix selection state bug from tests --- .../WKSourceEditorFormatterList.m | 51 ++++++++++++--- ...urceEditorFormatterButtonActionTests.swift | 64 +++++++++++++++++++ ...urceEditorTextFrameworkMediatorTests.swift | 48 ++++++++++++++ 3 files changed, 155 insertions(+), 8 deletions(-) diff --git a/Components/Sources/ComponentsObjC/WKSourceEditorFormatterList.m b/Components/Sources/ComponentsObjC/WKSourceEditorFormatterList.m index 1abd15820d9..de8ef933334 100644 --- a/Components/Sources/ComponentsObjC/WKSourceEditorFormatterList.m +++ b/Components/Sources/ComponentsObjC/WKSourceEditorFormatterList.m @@ -66,11 +66,9 @@ - (void)addSyntaxHighlightingToAttributedString:(nonnull NSMutableAttributedStri [attributedString removeAttribute:WKSourceEditorCustomKeyContentBulletMultiple range:range]; [attributedString removeAttribute:WKSourceEditorCustomKeyContentNumberSingle range:range]; [attributedString removeAttribute:WKSourceEditorCustomKeyContentNumberMultiple range:range]; - - [self enumerateAndHighlightAttributedString:attributedString range:range regex:self.bulletSingleRegex contentAttributes:self.bulletSingleContentAttributes]; - [self enumerateAndHighlightAttributedString:attributedString range:range regex:self.bulletMultipleRegex contentAttributes:self.bulletMultipleContentAttributes]; - [self enumerateAndHighlightAttributedString:attributedString range:range regex:self.numberSingleRegex contentAttributes:self.numberSingleContentAttributes]; - [self enumerateAndHighlightAttributedString:attributedString range:range regex:self.numberMultipleRegex contentAttributes:self.numberMultipleContentAttributes]; + + [self enumerateAndHighlightAttributedString:attributedString range:range singleRegex:self.bulletSingleRegex multipleRegex:self.bulletMultipleRegex singleContentAttributes:self.bulletSingleContentAttributes singleContentAttributes:self.bulletMultipleContentAttributes]; + [self enumerateAndHighlightAttributedString:attributedString range:range singleRegex:self.numberSingleRegex multipleRegex:self.numberMultipleRegex singleContentAttributes:self.numberSingleContentAttributes singleContentAttributes:self.numberMultipleContentAttributes]; } - (void)updateColors:(WKSourceEditorColors *)colors inAttributedString:(NSMutableAttributedString *)attributedString inRange:(NSRange)range { @@ -118,8 +116,32 @@ - (BOOL)attributedString:(NSMutableAttributedString *)attributedString isNumberM #pragma mark - Private -- (void)enumerateAndHighlightAttributedString: (nonnull NSMutableAttributedString *)attributedString range:(NSRange)range regex:(NSRegularExpression *)regex contentAttributes:(NSDictionary *)contentAttributes { - [regex enumerateMatchesInString:attributedString.string +- (void)enumerateAndHighlightAttributedString: (nonnull NSMutableAttributedString *)attributedString range:(NSRange)range singleRegex:(NSRegularExpression *)singleRegex multipleRegex:(NSRegularExpression *)multipleRegex singleContentAttributes:(NSDictionary *)singleContentAttributes singleContentAttributes:(NSDictionary *)multipleContentAttributes { + + NSMutableArray *multipleRanges = [[NSMutableArray alloc] init]; + + [multipleRegex enumerateMatchesInString:attributedString.string + options:0 + range:range + usingBlock:^(NSTextCheckingResult *_Nullable result, NSMatchingFlags flags, BOOL *_Nonnull stop) { + NSRange fullMatch = [result rangeAtIndex:0]; + NSRange orangeRange = [result rangeAtIndex:1]; + NSRange contentRange = [result rangeAtIndex:2]; + + if (fullMatch.location != NSNotFound) { + [multipleRanges addObject:[NSValue valueWithRange:fullMatch]]; + } + + if (orangeRange.location != NSNotFound) { + [attributedString addAttributes:self.orangeAttributes range:orangeRange]; + } + + if (contentRange.location != NSNotFound) { + [attributedString addAttributes:multipleContentAttributes range:contentRange]; + } + }]; + + [singleRegex enumerateMatchesInString:attributedString.string options:0 range:range usingBlock:^(NSTextCheckingResult *_Nullable result, NSMatchingFlags flags, BOOL *_Nonnull stop) { @@ -127,12 +149,25 @@ - (void)enumerateAndHighlightAttributedString: (nonnull NSMutableAttributedStrin NSRange orangeRange = [result rangeAtIndex:1]; NSRange contentRange = [result rangeAtIndex:2]; + BOOL alreadyMultiple = NO; + for (NSValue *value in multipleRanges) { + NSRange multipleRange = value.rangeValue; + if (NSIntersectionRange(multipleRange, fullMatch).length != 0) { + alreadyMultiple = YES; + } + } + + if (alreadyMultiple) { + return; + } + + if (orangeRange.location != NSNotFound) { [attributedString addAttributes:self.orangeAttributes range:orangeRange]; } if (contentRange.location != NSNotFound) { - [attributedString addAttributes:contentAttributes range:contentRange]; + [attributedString addAttributes:singleContentAttributes range:contentRange]; } }]; } diff --git a/Components/Tests/ComponentsTests/WKSourceEditorFormatterButtonActionTests.swift b/Components/Tests/ComponentsTests/WKSourceEditorFormatterButtonActionTests.swift index ee99fe49cd6..2c14d91f95d 100644 --- a/Components/Tests/ComponentsTests/WKSourceEditorFormatterButtonActionTests.swift +++ b/Components/Tests/ComponentsTests/WKSourceEditorFormatterButtonActionTests.swift @@ -122,4 +122,68 @@ final class WKSourceEditorFormatterButtonActionTests: XCTestCase { mediator.templateFormatter?.toggleTemplateFormatting(action: .remove, in: mediator.textView) XCTAssertEqual(mediator.textView.attributedText.string, "One Two Three Four") } + + func testListBulletInsertAndRemove() throws { + let text = "Test" + mediator.textView.attributedText = NSAttributedString(string: text) + mediator.textView.selectedRange = NSRange(location: 2, length: 0) + mediator.listFormatter?.toggleListBullet(action: .add, in: mediator.textView) + XCTAssertEqual(mediator.textView.attributedText.string, "* Test") + mediator.listFormatter?.toggleListBullet(action: .remove, in: mediator.textView) + XCTAssertEqual(mediator.textView.attributedText.string, "Test") + } + + func testListBulletInsertAndIncreaseIndent() throws { + let text = "Test" + mediator.textView.attributedText = NSAttributedString(string: text) + mediator.textView.selectedRange = NSRange(location: 2, length: 0) + mediator.listFormatter?.toggleListBullet(action: .add, in: mediator.textView) + XCTAssertEqual(mediator.textView.attributedText.string, "* Test") + mediator.listFormatter?.tappedIncreaseIndent(currentSelectionState: mediator.selectionState(selectedDocumentRange: mediator.textView.selectedRange), textView: mediator.textView) + XCTAssertEqual(mediator.textView.attributedText.string, "** Test") + } + + func testListBulletDecreaseIndentAndRemove() throws { + let text = "*** Test" + mediator.textView.attributedText = NSAttributedString(string: text) + mediator.textView.selectedRange = NSRange(location: 4, length: 0) + mediator.listFormatter?.tappedDecreaseIndent(currentSelectionState: mediator.selectionState(selectedDocumentRange: mediator.textView.selectedRange), textView: mediator.textView) + XCTAssertEqual(mediator.textView.attributedText.string, "** Test") + mediator.listFormatter?.tappedDecreaseIndent(currentSelectionState: mediator.selectionState(selectedDocumentRange: mediator.textView.selectedRange), textView: mediator.textView) + XCTAssertEqual(mediator.textView.attributedText.string, "* Test") + mediator.listFormatter?.toggleListBullet(action: .remove, in: mediator.textView) + XCTAssertEqual(mediator.textView.attributedText.string, "Test") + } + + func testListNumberInsertAndRemove() throws { + let text = "Test" + mediator.textView.attributedText = NSAttributedString(string: text) + mediator.textView.selectedRange = NSRange(location: 2, length: 0) + mediator.listFormatter?.toggleListNumber(action: .add, in: mediator.textView) + XCTAssertEqual(mediator.textView.attributedText.string, "# Test") + mediator.listFormatter?.toggleListNumber(action: .remove, in: mediator.textView) + XCTAssertEqual(mediator.textView.attributedText.string, "Test") + } + + func testListNumberInsertAndIncreaseIndent() throws { + let text = "Test" + mediator.textView.attributedText = NSAttributedString(string: text) + mediator.textView.selectedRange = NSRange(location: 2, length: 0) + mediator.listFormatter?.toggleListNumber(action: .add, in: mediator.textView) + XCTAssertEqual(mediator.textView.attributedText.string, "# Test") + mediator.listFormatter?.tappedIncreaseIndent(currentSelectionState: mediator.selectionState(selectedDocumentRange: mediator.textView.selectedRange), textView: mediator.textView) + XCTAssertEqual(mediator.textView.attributedText.string, "## Test") + } + + func testListNumberDecreaseIndentAndRemove() throws { + let text = "### Test" + mediator.textView.attributedText = NSAttributedString(string: text) + mediator.textView.selectedRange = NSRange(location: 4, length: 0) + mediator.listFormatter?.tappedDecreaseIndent(currentSelectionState: mediator.selectionState(selectedDocumentRange: mediator.textView.selectedRange), textView: mediator.textView) + XCTAssertEqual(mediator.textView.attributedText.string, "## Test") + mediator.listFormatter?.tappedDecreaseIndent(currentSelectionState: mediator.selectionState(selectedDocumentRange: mediator.textView.selectedRange), textView: mediator.textView) + XCTAssertEqual(mediator.textView.attributedText.string, "# Test") + mediator.listFormatter?.toggleListNumber(action: .remove, in: mediator.textView) + XCTAssertEqual(mediator.textView.attributedText.string, "Test") + } } diff --git a/Components/Tests/ComponentsTests/WKSourceEditorTextFrameworkMediatorTests.swift b/Components/Tests/ComponentsTests/WKSourceEditorTextFrameworkMediatorTests.swift index 5f01b4b4c71..6df7ab65bce 100644 --- a/Components/Tests/ComponentsTests/WKSourceEditorTextFrameworkMediatorTests.swift +++ b/Components/Tests/ComponentsTests/WKSourceEditorTextFrameworkMediatorTests.swift @@ -121,4 +121,52 @@ final class WKSourceEditorTextFrameworkMediatorTests: XCTestCase { let selectionStates1 = mediator.selectionState(selectedDocumentRange: NSRange(location: 1, length: 0)) XCTAssertFalse(selectionStates1.isHorizontalTemplate) } + + func testListBulletSingleSelectionState() throws { + + let text = "* Test" + mediator.textView.attributedText = NSAttributedString(string: text) + + let selectionStates = mediator.selectionState(selectedDocumentRange: NSRange(location: 2, length: 4)) + XCTAssertTrue(selectionStates.isBulletSingleList) + XCTAssertFalse(selectionStates.isBulletMultipleList) + XCTAssertFalse(selectionStates.isNumberSingleList) + XCTAssertFalse(selectionStates.isNumberMultipleList) + } + + func testListBulletMultipleSelectionState() throws { + + let text = "** Test" + mediator.textView.attributedText = NSAttributedString(string: text) + + let selectionStates = mediator.selectionState(selectedDocumentRange: NSRange(location: 3, length: 0)) + XCTAssertFalse(selectionStates.isBulletSingleList) + XCTAssertTrue(selectionStates.isBulletMultipleList) + XCTAssertFalse(selectionStates.isNumberSingleList) + XCTAssertFalse(selectionStates.isNumberMultipleList) + } + + func testListNumberSingleSelectionState() throws { + + let text = "# Test" + mediator.textView.attributedText = NSAttributedString(string: text) + + let selectionStates = mediator.selectionState(selectedDocumentRange: NSRange(location: 2, length: 4)) + XCTAssertFalse(selectionStates.isBulletSingleList) + XCTAssertFalse(selectionStates.isBulletMultipleList) + XCTAssertTrue(selectionStates.isNumberSingleList) + XCTAssertFalse(selectionStates.isNumberMultipleList) + } + + func testListNumberMultipleSelectionState() throws { + + let text = "## Test" + mediator.textView.attributedText = NSAttributedString(string: text) + + let selectionStates = mediator.selectionState(selectedDocumentRange: NSRange(location: 3, length: 0)) + XCTAssertFalse(selectionStates.isBulletSingleList) + XCTAssertFalse(selectionStates.isBulletMultipleList) + XCTAssertFalse(selectionStates.isNumberSingleList) + XCTAssertTrue(selectionStates.isNumberMultipleList) + } }