Skip to content

Commit 79b9e84

Browse files
committed
Fixing bug where AttributedSpans.collapseSpans could throw a StateError
1 parent 53efa73 commit 79b9e84

File tree

2 files changed

+36
-9
lines changed

2 files changed

+36
-9
lines changed

attributed_text/lib/src/attributed_spans.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -897,7 +897,7 @@ class AttributedSpans {
897897
}
898898
}
899899

900-
if (collapsedSpans.last.end < contentLength) {
900+
if (collapsedSpans.isEmpty || collapsedSpans.last.end < contentLength) {
901901
// The last span committed during the loop does not reach the end of the requested content range. We either ran
902902
// out of markers or the remaining markers are outside the content range. In both cases the value in currentSpan
903903
// should already have the correct start, end, and attributions values to cover the remaining content.

attributed_text/test/attributed_spans_test.dart

+35-8
Original file line numberDiff line numberDiff line change
@@ -486,19 +486,46 @@ void main() {
486486
expect(collapsedSpans.first.attributions, isEmpty);
487487
});
488488

489-
test('single continuous attribution', () {
490-
final collapsedSpans = AttributedSpans(
489+
group('single continuous attribution', () {
490+
final spans = AttributedSpans(
491491
attributions: [
492492
const SpanMarker(attribution: ExpectedSpans.bold, offset: 0, markerType: SpanMarkerType.start),
493493
const SpanMarker(attribution: ExpectedSpans.bold, offset: 16, markerType: SpanMarkerType.end),
494494
],
495-
).collapseSpans(contentLength: 16);
495+
);
496496

497-
expect(collapsedSpans.length, 1);
498-
expect(collapsedSpans.first.start, 0);
499-
expect(collapsedSpans.first.end, 16);
500-
expect(collapsedSpans.first.attributions.length, 1);
501-
expect(collapsedSpans.first.attributions.first, ExpectedSpans.bold);
497+
test('collapse at span end', () {
498+
final collapsedSpans = spans.collapseSpans(contentLength: 16);
499+
500+
expect(collapsedSpans.length, 1);
501+
expect(collapsedSpans.first.start, 0);
502+
expect(collapsedSpans.first.end, 16);
503+
expect(collapsedSpans.first.attributions.length, 1);
504+
expect(collapsedSpans.first.attributions.first, ExpectedSpans.bold);
505+
});
506+
507+
test('collapse before span end', () {
508+
final collapsedSpans = spans.collapseSpans(contentLength: 10);
509+
510+
expect(collapsedSpans.length, 1);
511+
expect(collapsedSpans.first.start, 0);
512+
expect(collapsedSpans.first.end, 10);
513+
expect(collapsedSpans.first.attributions.length, 1);
514+
expect(collapsedSpans.first.attributions.first, ExpectedSpans.bold);
515+
});
516+
517+
test('collapse after span end', () {
518+
final collapsedSpans = spans.collapseSpans(contentLength: 20);
519+
520+
expect(collapsedSpans.length, 2);
521+
expect(collapsedSpans[0].start, 0);
522+
expect(collapsedSpans[0].end, 16);
523+
expect(collapsedSpans[0].attributions.length, 1);
524+
expect(collapsedSpans[0].attributions.first, ExpectedSpans.bold);
525+
expect(collapsedSpans[1].start, 16);
526+
expect(collapsedSpans[1].end, 20);
527+
expect(collapsedSpans[1].attributions, isEmpty);
528+
});
502529
});
503530

504531
test('single fractured attribution', () {

0 commit comments

Comments
 (0)