blob: 3c39220c0159e141c629721dbaf78cda65fbc810 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart';
import '../html/paragraph/helper.dart';
void main() {
internalBootstrapBrowserTest(() => testMain);
}
Future<void> testMain() async {
group('$BidiFragmenter', () {
test('empty string', () {
expect(split(''), <_Bidi>[
_Bidi('', null, ffPrevious),
]);
});
test('basic cases', () {
expect(split('Lorem 11 $rtlWord1 22 ipsum'), <_Bidi>[
_Bidi('Lorem', ltr, ffLtr),
_Bidi(' ', null, ffSandwich),
_Bidi('11', ltr, ffPrevious),
_Bidi(' ', null, ffSandwich),
_Bidi(rtlWord1, rtl, ffRtl),
_Bidi(' ', null, ffSandwich),
_Bidi('22', ltr, ffPrevious),
_Bidi(' ', null, ffSandwich),
_Bidi('ipsum', ltr, ffLtr),
]);
});
test('text and digits', () {
expect(split('Lorem11 ${rtlWord1}22 33ipsum44dolor ${rtlWord2}55$rtlWord1'), <_Bidi>[
_Bidi('Lorem11', ltr, ffLtr),
_Bidi(' ', null, ffSandwich),
_Bidi(rtlWord1, rtl, ffRtl),
_Bidi('22', ltr, ffPrevious),
_Bidi(' ', null, ffSandwich),
_Bidi('33ipsum44dolor', ltr, ffLtr),
_Bidi(' ', null, ffSandwich),
_Bidi(rtlWord2, rtl, ffRtl),
_Bidi('55', ltr, ffPrevious),
_Bidi(rtlWord1, rtl, ffRtl),
]);
});
test('Mashriqi digits', () {
expect(split('foo ١١ ٢٢ bar'), <_Bidi>[
_Bidi('foo', ltr, ffLtr),
_Bidi(' ', null, ffSandwich),
_Bidi('١١', ltr, ffRtl),
_Bidi(' ', null, ffSandwich),
_Bidi('٢٢', ltr, ffRtl),
_Bidi(' ', null, ffSandwich),
_Bidi('bar', ltr, ffLtr),
]);
expect(split('$rtlWord1 ١١ ٢٢ $rtlWord2'), <_Bidi>[
_Bidi(rtlWord1, rtl, ffRtl),
_Bidi(' ', null, ffSandwich),
_Bidi('١١', ltr, ffRtl),
_Bidi(' ', null, ffSandwich),
_Bidi('٢٢', ltr, ffRtl),
_Bidi(' ', null, ffSandwich),
_Bidi(rtlWord2, rtl, ffRtl),
]);
});
test('spaces', () {
expect(split(' '), <_Bidi>[
_Bidi(' ', null, ffSandwich),
]);
});
test('symbols', () {
expect(split('Calculate 2.2 + 4.5 and write the result'), <_Bidi>[
_Bidi('Calculate', ltr, ffLtr),
_Bidi(' ', null, ffSandwich),
_Bidi('2', ltr, ffPrevious),
_Bidi('.', null, ffSandwich),
_Bidi('2', ltr, ffPrevious),
_Bidi(' + ', null, ffSandwich),
_Bidi('4', ltr, ffPrevious),
_Bidi('.', null, ffSandwich),
_Bidi('5', ltr, ffPrevious),
_Bidi(' ', null, ffSandwich),
_Bidi('and', ltr, ffLtr),
_Bidi(' ', null, ffSandwich),
_Bidi('write', ltr, ffLtr),
_Bidi(' ', null, ffSandwich),
_Bidi('the', ltr, ffLtr),
_Bidi(' ', null, ffSandwich),
_Bidi('result', ltr, ffLtr),
]);
expect(split('Calculate $rtlWord1 2.2 + 4.5 and write the result'), <_Bidi>[
_Bidi('Calculate', ltr, ffLtr),
_Bidi(' ', null, ffSandwich),
_Bidi(rtlWord1, rtl, ffRtl),
_Bidi(' ', null, ffSandwich),
_Bidi('2', ltr, ffPrevious),
_Bidi('.', null, ffSandwich),
_Bidi('2', ltr, ffPrevious),
_Bidi(' + ', null, ffSandwich),
_Bidi('4', ltr, ffPrevious),
_Bidi('.', null, ffSandwich),
_Bidi('5', ltr, ffPrevious),
_Bidi(' ', null, ffSandwich),
_Bidi('and', ltr, ffLtr),
_Bidi(' ', null, ffSandwich),
_Bidi('write', ltr, ffLtr),
_Bidi(' ', null, ffSandwich),
_Bidi('the', ltr, ffLtr),
_Bidi(' ', null, ffSandwich),
_Bidi('result', ltr, ffLtr),
]);
expect(split('12 + 24 = 36'), <_Bidi>[
_Bidi('12', ltr, ffPrevious),
_Bidi(' + ', null, ffSandwich),
_Bidi('24', ltr, ffPrevious),
_Bidi(' = ', null, ffSandwich),
_Bidi('36', ltr, ffPrevious),
]);
});
test('handles new lines', () {
expect(split('Lorem\n12\nipsum \n'), <_Bidi>[
_Bidi('Lorem', ltr, ffLtr),
_Bidi('\n', null, ffSandwich),
_Bidi('12', ltr, ffPrevious),
_Bidi('\n', null, ffSandwich),
_Bidi('ipsum', ltr, ffLtr),
_Bidi(' \n', null, ffSandwich),
]);
expect(split('$rtlWord1\n $rtlWord2 \n'), <_Bidi>[
_Bidi(rtlWord1, rtl, ffRtl),
_Bidi('\n ', null, ffSandwich),
_Bidi(rtlWord2, rtl, ffRtl),
_Bidi(' \n', null, ffSandwich),
]);
});
test('surrogates', () {
expect(split('A\u{1F600}'), <_Bidi>[
_Bidi('A', ltr, ffLtr),
_Bidi('\u{1F600}', null, ffSandwich),
]);
});
});
}
/// Holds information about how a bidi region was split from a string.
class _Bidi {
_Bidi(this.text, this.textDirection, this.fragmentFlow);
factory _Bidi.fromBidiFragment(String text, BidiFragment bidiFragment) {
return _Bidi(
text.substring(bidiFragment.start, bidiFragment.end),
bidiFragment.textDirection,
bidiFragment.fragmentFlow,
);
}
final String text;
final TextDirection? textDirection;
final FragmentFlow fragmentFlow;
@override
int get hashCode => Object.hash(text, textDirection);
@override
bool operator ==(Object other) {
return other is _Bidi &&
other.text == text &&
other.textDirection == textDirection &&
other.fragmentFlow == fragmentFlow;
}
@override
String toString() {
return '"$text" ($textDirection | $fragmentFlow)';
}
}
List<_Bidi> split(String text) {
return <_Bidi>[
for (final BidiFragment bidiFragment in BidiFragmenter(text).fragment())
_Bidi.fromBidiFragment(text, bidiFragment)
];
}