@@ -1543,7 +1543,7 @@ - (void)testUpdateFirstRectForRange {
1543
1543
[inputView firstRectForRange: range]));
1544
1544
}
1545
1545
1546
- - (void )testFirstRectForRangeReturnsCorrectSelectionRectOnASingleLineLeftToRight {
1546
+ - (void )testFirstRectForRangeReturnsCorrectRectOnASingleLineLeftToRight {
1547
1547
FlutterTextInputView* inputView = [[FlutterTextInputView alloc ] initWithOwner: textInputPlugin];
1548
1548
[inputView setTextInputState: @{@" text" : @" COMPOSING" }];
1549
1549
@@ -1572,7 +1572,7 @@ - (void)testFirstRectForRangeReturnsCorrectSelectionRectOnASingleLineLeftToRight
1572
1572
XCTAssertTrue (CGRectEqualToRect (CGRectZero, [inputView firstRectForRange: rangeOutsideBounds]));
1573
1573
}
1574
1574
1575
- - (void )testFirstRectForRangeReturnsCorrectSelectionRectOnASingleLineRightToLeft {
1575
+ - (void )testFirstRectForRangeReturnsCorrectRectOnASingleLineRightToLeft {
1576
1576
FlutterTextInputView* inputView = [[FlutterTextInputView alloc ] initWithOwner: textInputPlugin];
1577
1577
[inputView setTextInputState: @{@" text" : @" COMPOSING" }];
1578
1578
@@ -1600,7 +1600,7 @@ - (void)testFirstRectForRangeReturnsCorrectSelectionRectOnASingleLineRightToLeft
1600
1600
XCTAssertTrue (CGRectEqualToRect (CGRectZero, [inputView firstRectForRange: rangeOutsideBounds]));
1601
1601
}
1602
1602
1603
- - (void )testFirstRectForRangeReturnsCorrectSelectionRectOnMultipleLinesLeftToRight {
1603
+ - (void )testFirstRectForRangeReturnsCorrectRectOnMultipleLinesLeftToRight {
1604
1604
FlutterTextInputView* inputView = [[FlutterTextInputView alloc ] initWithOwner: textInputPlugin];
1605
1605
[inputView setTextInputState: @{@" text" : @" COMPOSING" }];
1606
1606
@@ -1629,7 +1629,7 @@ - (void)testFirstRectForRangeReturnsCorrectSelectionRectOnMultipleLinesLeftToRig
1629
1629
}
1630
1630
}
1631
1631
1632
- - (void )testFirstRectForRangeReturnsCorrectSelectionRectOnMultipleLinesRightToLeft {
1632
+ - (void )testFirstRectForRangeReturnsCorrectRectOnMultipleLinesRightToLeft {
1633
1633
FlutterTextInputView* inputView = [[FlutterTextInputView alloc ] initWithOwner: textInputPlugin];
1634
1634
[inputView setTextInputState: @{@" text" : @" COMPOSING" }];
1635
1635
@@ -1657,6 +1657,150 @@ - (void)testFirstRectForRangeReturnsCorrectSelectionRectOnMultipleLinesRightToLe
1657
1657
}
1658
1658
}
1659
1659
1660
+ - (void )testFirstRectForRangeReturnsCorrectRectOnSingleLineWithVaryingMinYAndMaxYLeftToRight {
1661
+ FlutterTextInputView* inputView = [[FlutterTextInputView alloc ] initWithOwner: textInputPlugin];
1662
+ [inputView setTextInputState: @{@" text" : @" COMPOSING" }];
1663
+
1664
+ [inputView setSelectionRects: @[
1665
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (0 , 0 , 100 , 100 ) position: 0U ],
1666
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (100 , 10 , 100 , 80 )
1667
+ position: 1U ], // shorter
1668
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (200 , -10 , 100 , 120 )
1669
+ position: 2U ], // taller
1670
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (300 , 0 , 100 , 100 ) position: 3U ],
1671
+ ]];
1672
+
1673
+ FlutterTextRange* multiRectRange = [FlutterTextRange rangeWithNSRange: NSMakeRange (1 , 3 )];
1674
+
1675
+ if (@available (iOS 17 , *)) {
1676
+ XCTAssertTrue (CGRectEqualToRect (CGRectMake (100 , -10 , 300 , 120 ),
1677
+ [inputView firstRectForRange: multiRectRange]));
1678
+ } else {
1679
+ XCTAssertTrue (CGRectEqualToRect (CGRectMake (100 , 10 , 100 , 80 ),
1680
+ [inputView firstRectForRange: multiRectRange]));
1681
+ }
1682
+ }
1683
+
1684
+ - (void )testFirstRectForRangeReturnsCorrectRectOnSingleLineWithVaryingMinYAndMaxYRightToLeft {
1685
+ FlutterTextInputView* inputView = [[FlutterTextInputView alloc ] initWithOwner: textInputPlugin];
1686
+ [inputView setTextInputState: @{@" text" : @" COMPOSING" }];
1687
+
1688
+ [inputView setSelectionRects: @[
1689
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (300 , 0 , 100 , 100 ) position: 0U ],
1690
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (200 , -10 , 100 , 120 )
1691
+ position: 1U ], // taller
1692
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (100 , 10 , 100 , 80 )
1693
+ position: 2U ], // shorter
1694
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (0 , 0 , 100 , 100 ) position: 3U ],
1695
+ ]];
1696
+
1697
+ FlutterTextRange* multiRectRange = [FlutterTextRange rangeWithNSRange: NSMakeRange (1 , 3 )];
1698
+
1699
+ if (@available (iOS 17 , *)) {
1700
+ XCTAssertTrue (CGRectEqualToRect (CGRectMake (0 , -10 , 300 , 120 ),
1701
+ [inputView firstRectForRange: multiRectRange]));
1702
+ } else {
1703
+ XCTAssertTrue (CGRectEqualToRect (CGRectMake (200 , -10 , 100 , 120 ),
1704
+ [inputView firstRectForRange: multiRectRange]));
1705
+ }
1706
+ }
1707
+
1708
+ - (void )testFirstRectForRangeReturnsCorrectRectWithOverlappingRectsExceedingThresholdLeftToRight {
1709
+ FlutterTextInputView* inputView = [[FlutterTextInputView alloc ] initWithOwner: textInputPlugin];
1710
+ [inputView setTextInputState: @{@" text" : @" COMPOSING" }];
1711
+
1712
+ [inputView setSelectionRects: @[
1713
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (0 , 0 , 100 , 100 ) position: 0U ],
1714
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (100 , 0 , 100 , 100 ) position: 1U ],
1715
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (200 , 0 , 100 , 100 ) position: 2U ],
1716
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (300 , 0 , 100 , 100 ) position: 3U ],
1717
+ // y=60 exceeds threshold, so treat it as a new line.
1718
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (0 , 60 , 100 , 100 ) position: 4U ],
1719
+ ]];
1720
+
1721
+ FlutterTextRange* multiRectRange = [FlutterTextRange rangeWithNSRange: NSMakeRange (1 , 4 )];
1722
+
1723
+ if (@available (iOS 17 , *)) {
1724
+ XCTAssertTrue (CGRectEqualToRect (CGRectMake (100 , 0 , 300 , 100 ),
1725
+ [inputView firstRectForRange: multiRectRange]));
1726
+ } else {
1727
+ XCTAssertTrue (CGRectEqualToRect (CGRectMake (100 , 0 , 100 , 100 ),
1728
+ [inputView firstRectForRange: multiRectRange]));
1729
+ }
1730
+ }
1731
+
1732
+ - (void )testFirstRectForRangeReturnsCorrectRectWithOverlappingRectsExceedingThresholdRightToLeft {
1733
+ FlutterTextInputView* inputView = [[FlutterTextInputView alloc ] initWithOwner: textInputPlugin];
1734
+ [inputView setTextInputState: @{@" text" : @" COMPOSING" }];
1735
+
1736
+ [inputView setSelectionRects: @[
1737
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (300 , 0 , 100 , 100 ) position: 0U ],
1738
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (200 , 0 , 100 , 100 ) position: 1U ],
1739
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (100 , 0 , 100 , 100 ) position: 2U ],
1740
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (0 , 0 , 100 , 100 ) position: 3U ],
1741
+ // y=60 exceeds threshold, so treat it as a new line.
1742
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (300 , 60 , 100 , 100 ) position: 4U ],
1743
+ ]];
1744
+
1745
+ FlutterTextRange* multiRectRange = [FlutterTextRange rangeWithNSRange: NSMakeRange (1 , 4 )];
1746
+
1747
+ if (@available (iOS 17 , *)) {
1748
+ XCTAssertTrue (CGRectEqualToRect (CGRectMake (0 , 0 , 300 , 100 ),
1749
+ [inputView firstRectForRange: multiRectRange]));
1750
+ } else {
1751
+ XCTAssertTrue (CGRectEqualToRect (CGRectMake (200 , 0 , 100 , 100 ),
1752
+ [inputView firstRectForRange: multiRectRange]));
1753
+ }
1754
+ }
1755
+
1756
+ - (void )testFirstRectForRangeReturnsCorrectRectWithOverlappingRectsWithinThresholdLeftToRight {
1757
+ FlutterTextInputView* inputView = [[FlutterTextInputView alloc ] initWithOwner: textInputPlugin];
1758
+ [inputView setTextInputState: @{@" text" : @" COMPOSING" }];
1759
+
1760
+ [inputView setSelectionRects: @[
1761
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (0 , 0 , 100 , 100 ) position: 0U ],
1762
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (100 , 0 , 100 , 100 ) position: 1U ],
1763
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (200 , 0 , 100 , 100 ) position: 2U ],
1764
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (300 , 0 , 100 , 100 ) position: 3U ],
1765
+ // y=40 is within line threshold, so treat it as the same line
1766
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (400 , 40 , 100 , 100 ) position: 4U ],
1767
+ ]];
1768
+
1769
+ FlutterTextRange* multiRectRange = [FlutterTextRange rangeWithNSRange: NSMakeRange (1 , 4 )];
1770
+
1771
+ if (@available (iOS 17 , *)) {
1772
+ XCTAssertTrue (CGRectEqualToRect (CGRectMake (100 , 0 , 400 , 140 ),
1773
+ [inputView firstRectForRange: multiRectRange]));
1774
+ } else {
1775
+ XCTAssertTrue (CGRectEqualToRect (CGRectMake (100 , 0 , 100 , 100 ),
1776
+ [inputView firstRectForRange: multiRectRange]));
1777
+ }
1778
+ }
1779
+
1780
+ - (void )testFirstRectForRangeReturnsCorrectRectWithOverlappingRectsWithinThresholdRightToLeft {
1781
+ FlutterTextInputView* inputView = [[FlutterTextInputView alloc ] initWithOwner: textInputPlugin];
1782
+ [inputView setTextInputState: @{@" text" : @" COMPOSING" }];
1783
+
1784
+ [inputView setSelectionRects: @[
1785
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (400 , 0 , 100 , 100 ) position: 0U ],
1786
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (300 , 0 , 100 , 100 ) position: 1U ],
1787
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (200 , 0 , 100 , 100 ) position: 2U ],
1788
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (100 , 0 , 100 , 100 ) position: 3U ],
1789
+ // y=40 is within line threshold, so treat it as the same line
1790
+ [FlutterTextSelectionRect selectionRectWithRect: CGRectMake (0 , 40 , 100 , 100 ) position: 4U ],
1791
+ ]];
1792
+
1793
+ FlutterTextRange* multiRectRange = [FlutterTextRange rangeWithNSRange: NSMakeRange (1 , 4 )];
1794
+
1795
+ if (@available (iOS 17 , *)) {
1796
+ XCTAssertTrue (CGRectEqualToRect (CGRectMake (0 , 0 , 400 , 140 ),
1797
+ [inputView firstRectForRange: multiRectRange]));
1798
+ } else {
1799
+ XCTAssertTrue (CGRectEqualToRect (CGRectMake (300 , 0 , 100 , 100 ),
1800
+ [inputView firstRectForRange: multiRectRange]));
1801
+ }
1802
+ }
1803
+
1660
1804
- (void )testClosestPositionToPoint {
1661
1805
FlutterTextInputView* inputView = [[FlutterTextInputView alloc ] initWithOwner: textInputPlugin];
1662
1806
[inputView setTextInputState: @{@" text" : @" COMPOSING" }];
0 commit comments