1b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio/*
2b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio * Copyright (C) 2013 The Android Open Source Project
3b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio *
4b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio * Licensed under the Apache License, Version 2.0 (the "License");
5b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio * you may not use this file except in compliance with the License.
6b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio * You may obtain a copy of the License at
7b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio *
8b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio *      http://www.apache.org/licenses/LICENSE-2.0
9b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio *
10b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio * Unless required by applicable law or agreed to in writing, software
11b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio * distributed under the License is distributed on an "AS IS" BASIS,
12b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio * See the License for the specific language governing permissions and
14b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio * limitations under the License.
15b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio */
16b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.core.text;
18b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
19754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static org.junit.Assert.assertEquals;
20754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static org.junit.Assert.assertNull;
21754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikas
22754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport android.support.test.filters.SmallTest;
23881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikovimport android.support.test.runner.AndroidJUnit4;
24f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournaderimport android.text.SpannableString;
25f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournaderimport android.text.Spanned;
26f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournaderimport android.text.style.RelativeSizeSpan;
27754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikas
28881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikovimport org.junit.Test;
29881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikovimport org.junit.runner.RunWith;
30b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
31b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglioimport java.util.Locale;
32b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
33881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov@RunWith(AndroidJUnit4.class)
34daea069fe33cc750bcb733ebcb6206d2dcedae76Chris Banes@SmallTest
35881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikovpublic class BidiFormatterTest {
36b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
37b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio    private static final BidiFormatter LTR_FMT = BidiFormatter.getInstance(false /* LTR context */);
38b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio    private static final BidiFormatter RTL_FMT = BidiFormatter.getInstance(true /* RTL context */);
39b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
40b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio    private static final BidiFormatter LTR_FMT_EXIT_RESET =
41b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio            new BidiFormatter.Builder(false /* LTR context */).stereoReset(false).build();
42b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio    private static final BidiFormatter RTL_FMT_EXIT_RESET =
43b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio            new BidiFormatter.Builder(true /* RTL context */).stereoReset(false).build();
44b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
45b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio    private static final String EN = "abba";
46f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader    private static final String HE = "\u05E0\u05E1";
47b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
48b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio    private static final String LRM = "\u200E";
49b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio    private static final String RLM = "\u200F";
50b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio    private static final String LRE = "\u202A";
51b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio    private static final String RLE = "\u202B";
52b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio    private static final String PDF = "\u202C";
53b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
54881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov    @Test
55b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio    public void testIsRtlContext() {
56b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals(false, LTR_FMT.isRtlContext());
57b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals(true, RTL_FMT.isRtlContext());
58b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
59b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals(false, BidiFormatter.getInstance(Locale.ENGLISH).isRtlContext());
60b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals(true, BidiFormatter.getInstance(true).isRtlContext());
61b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio    }
62b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
63881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov    @Test
64b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio    public void testBuilderIsRtlContext() {
65b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals(false, new BidiFormatter.Builder(false).build().isRtlContext());
66b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals(true, new BidiFormatter.Builder(true).build().isRtlContext());
67b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio    }
68b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
69881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov    @Test
70b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio    public void testIsRtl() {
71b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals(true, BidiFormatter.getInstance(true).isRtl(HE));
72b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals(true, BidiFormatter.getInstance(false).isRtl(HE));
73b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
74b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals(false, BidiFormatter.getInstance(true).isRtl(EN));
75b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals(false, BidiFormatter.getInstance(false).isRtl(EN));
76b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio    }
77b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
78881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov    @Test
79b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio    public void testUnicodeWrap() {
80a404677a9abad23c78a35512cd7428f86724b30aRoozbeh Pournader        // Make sure an input of null doesn't crash anything.
81a404677a9abad23c78a35512cd7428f86724b30aRoozbeh Pournader        assertNull(LTR_FMT.unicodeWrap(null));
82a404677a9abad23c78a35512cd7428f86724b30aRoozbeh Pournader
83b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        // Uniform directionality in opposite context.
84b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("uniform dir opposite to LTR context",
85b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RLE + "." + HE + "." + PDF + LRM,
86b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LTR_FMT_EXIT_RESET.unicodeWrap("." + HE + "."));
87b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("uniform dir opposite to LTR context, stereo reset",
88b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LRM + RLE + "." + HE + "." + PDF + LRM,
89b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LTR_FMT.unicodeWrap("." + HE + "."));
90b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("uniform dir opposite to LTR context, stereo reset, no isolation",
91b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RLE + "." + HE + "." + PDF,
92b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LTR_FMT.unicodeWrap("." + HE + ".", false));
93b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("neutral treated as opposite to LTR context",
94b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RLE + "." + PDF + LRM,
95b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LTR_FMT_EXIT_RESET.unicodeWrap(".", TextDirectionHeuristicsCompat.RTL));
96b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("uniform dir opposite to RTL context",
97b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LRE + "." + EN + "." + PDF + RLM,
98b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RTL_FMT_EXIT_RESET.unicodeWrap("." + EN + "."));
99b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("uniform dir opposite to RTL context, stereo reset",
100b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RLM + LRE + "." + EN + "." + PDF + RLM,
101b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RTL_FMT.unicodeWrap("." + EN + "."));
102b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("uniform dir opposite to RTL context, stereo reset, no isolation",
103b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LRE + "." + EN + "." + PDF,
104b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RTL_FMT.unicodeWrap("." + EN + ".", false));
105b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("neutral treated as opposite to RTL context",
106b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LRE + "." + PDF + RLM,
107b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RTL_FMT_EXIT_RESET.unicodeWrap(".", TextDirectionHeuristicsCompat.LTR));
108b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
109b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        // We test mixed-directionality cases only with an explicit overall directionality parameter
110b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        // because the estimation logic is outside the sphere of BidiFormatter, and different
111b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        // estimators will treat them differently.
112b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
113b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        // Overall directionality matching context, but with opposite exit directionality.
114b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("exit dir opposite to LTR context",
115b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                EN + HE + LRM,
116b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LTR_FMT_EXIT_RESET.unicodeWrap(EN + HE, TextDirectionHeuristicsCompat.LTR));
117b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("exit dir opposite to LTR context, stereo reset",
118b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                EN + HE + LRM,
119b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LTR_FMT.unicodeWrap(EN + HE, TextDirectionHeuristicsCompat.LTR));
120b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("exit dir opposite to LTR context, stereo reset, no isolation",
121b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                EN + HE,
122b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LTR_FMT.unicodeWrap(EN + HE, TextDirectionHeuristicsCompat.LTR, false));
123b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
124b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("exit dir opposite to RTL context",
125b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                HE + EN + RLM,
126b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RTL_FMT_EXIT_RESET.unicodeWrap(HE + EN, TextDirectionHeuristicsCompat.RTL));
127b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("exit dir opposite to RTL context, stereo reset",
128b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                HE + EN + RLM,
129b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RTL_FMT.unicodeWrap(HE + EN, TextDirectionHeuristicsCompat.RTL));
130b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("exit dir opposite to RTL context, stereo reset, no isolation",
131b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                HE + EN,
132b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RTL_FMT.unicodeWrap(HE + EN, TextDirectionHeuristicsCompat.RTL, false));
133b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
134b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        // Overall directionality matching context, but with opposite entry directionality.
135b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("entry dir opposite to LTR context",
136b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                HE + EN,
137b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LTR_FMT_EXIT_RESET.unicodeWrap(HE + EN, TextDirectionHeuristicsCompat.LTR));
138b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("entry dir opposite to LTR context, stereo reset",
139b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LRM + HE + EN,
140b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LTR_FMT.unicodeWrap(HE + EN, TextDirectionHeuristicsCompat.LTR));
141b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("entry dir opposite to LTR context, stereo reset, no isolation",
142b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                HE + EN,
143b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LTR_FMT.unicodeWrap(HE + EN, TextDirectionHeuristicsCompat.LTR, false));
144b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
145b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("entry dir opposite to RTL context",
146b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                EN + HE,
147b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RTL_FMT_EXIT_RESET.unicodeWrap(EN + HE, TextDirectionHeuristicsCompat.RTL));
148b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("entry dir opposite to RTL context, stereo reset",
149b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RLM + EN + HE,
150b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RTL_FMT.unicodeWrap(EN + HE, TextDirectionHeuristicsCompat.RTL));
151b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("entry dir opposite to RTL context, stereo reset, no isolation",
152b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                EN + HE,
153b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RTL_FMT.unicodeWrap(EN + HE, TextDirectionHeuristicsCompat.RTL, false));
154b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
155b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        // Overall directionality matching context, but with opposite entry and exit directionality.
156b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("entry and exit dir opposite to LTR context",
157b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                HE + EN + HE + LRM,
158b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LTR_FMT_EXIT_RESET.unicodeWrap(HE + EN + HE, TextDirectionHeuristicsCompat.LTR));
159b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("entry and exit dir opposite to LTR context, stereo reset",
160b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LRM + HE + EN + HE + LRM,
161b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LTR_FMT.unicodeWrap(HE + EN + HE, TextDirectionHeuristicsCompat.LTR));
162b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("entry and exit dir opposite to LTR context, no isolation",
163b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                HE + EN + HE,
164881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov                LTR_FMT_EXIT_RESET.unicodeWrap(HE + EN + HE, TextDirectionHeuristicsCompat.LTR,
165881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov                        false));
166b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
167b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("entry and exit dir opposite to RTL context",
168b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                EN + HE + EN + RLM,
169b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RTL_FMT_EXIT_RESET.unicodeWrap(EN + HE + EN, TextDirectionHeuristicsCompat.RTL));
170b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("entry and exit dir opposite to RTL context, no isolation",
171b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                EN + HE + EN,
172881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov                RTL_FMT_EXIT_RESET.unicodeWrap(EN + HE + EN, TextDirectionHeuristicsCompat.RTL,
173881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov                        false));
174b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
175b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        // Entry and exit directionality matching context, but with opposite overall directionality.
176b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("overall dir (but not entry or exit dir) opposite to LTR context",
177b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RLE + EN + HE + EN + PDF + LRM,
178b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LTR_FMT_EXIT_RESET.unicodeWrap(EN + HE + EN, TextDirectionHeuristicsCompat.RTL));
179b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("overall dir (but not entry or exit dir) opposite to LTR context, stereo reset",
180b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LRM + RLE + EN + HE + EN + PDF + LRM,
181b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LTR_FMT.unicodeWrap(EN + HE + EN, TextDirectionHeuristicsCompat.RTL));
182b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("overall dir (but not entry or exit dir) opposite to LTR context, no isolation",
183b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RLE + EN + HE + EN + PDF,
184881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov                LTR_FMT_EXIT_RESET.unicodeWrap(EN + HE + EN, TextDirectionHeuristicsCompat.RTL,
185881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov                        false));
186b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio
187b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("overall dir (but not entry or exit dir) opposite to RTL context",
188b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LRE + HE + EN + HE + PDF + RLM,
189b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RTL_FMT_EXIT_RESET.unicodeWrap(HE + EN + HE, TextDirectionHeuristicsCompat.LTR));
190b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("overall dir (but not entry or exit dir) opposite to RTL context, stereo reset",
191b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RLM + LRE + HE + EN + HE + PDF + RLM,
192b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                RTL_FMT.unicodeWrap(HE + EN + HE, TextDirectionHeuristicsCompat.LTR));
193b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio        assertEquals("overall dir (but not entry or exit dir) opposite to RTL context, no isolation",
194b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio                LRE + HE + EN + HE + PDF,
195881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov                RTL_FMT_EXIT_RESET.unicodeWrap(HE + EN + HE, TextDirectionHeuristicsCompat.LTR,
196881c193f64d35ea2a106a2f76c30bd711a971bb1Kirill Grouchnikov                        false));
197b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio    }
198f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader
199f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader    @Test
200f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader    public void testCharSequenceApis() {
201f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        final CharSequence CS_HE = new SpannableString(HE);
202f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(true, BidiFormatter.getInstance(true).isRtl(CS_HE));
203f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader
204f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        final SpannableString CS_EN_HE = new SpannableString(EN + HE);
205f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        final Object RELATIVE_SIZE_SPAN = new RelativeSizeSpan(1.2f);
206f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        CS_EN_HE.setSpan(RELATIVE_SIZE_SPAN, 0, EN.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
207f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader
208f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        Spanned wrapped;
209f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        Object[] spans;
210f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader
211f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        wrapped = (Spanned) LTR_FMT.unicodeWrap(CS_EN_HE);
212f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(EN + HE + LRM, wrapped.toString());
213f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        spans = wrapped.getSpans(0, wrapped.length(), Object.class);
214f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(1, spans.length);
215f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(RELATIVE_SIZE_SPAN, spans[0]);
216f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(0, wrapped.getSpanStart(RELATIVE_SIZE_SPAN));
217f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(EN.length(), wrapped.getSpanEnd(RELATIVE_SIZE_SPAN));
218f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader
219f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        wrapped = (Spanned) LTR_FMT.unicodeWrap(CS_EN_HE, TextDirectionHeuristicsCompat.LTR);
220f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(EN + HE + LRM, wrapped.toString());
221f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        spans = wrapped.getSpans(0, wrapped.length(), Object.class);
222f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(1, spans.length);
223f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(RELATIVE_SIZE_SPAN, spans[0]);
224f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(0, wrapped.getSpanStart(RELATIVE_SIZE_SPAN));
225f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(EN.length(), wrapped.getSpanEnd(RELATIVE_SIZE_SPAN));
226f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader
227f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        wrapped = (Spanned) LTR_FMT.unicodeWrap(CS_EN_HE, false);
228f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(EN + HE, wrapped.toString());
229f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        spans = wrapped.getSpans(0, wrapped.length(), Object.class);
230f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(1, spans.length);
231f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(RELATIVE_SIZE_SPAN, spans[0]);
232f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(0, wrapped.getSpanStart(RELATIVE_SIZE_SPAN));
233f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(EN.length(), wrapped.getSpanEnd(RELATIVE_SIZE_SPAN));
234f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader
235f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        wrapped = (Spanned) LTR_FMT.unicodeWrap(CS_EN_HE, TextDirectionHeuristicsCompat.LTR, false);
236f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(EN + HE, wrapped.toString());
237f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        spans = wrapped.getSpans(0, wrapped.length(), Object.class);
238f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(1, spans.length);
239f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(RELATIVE_SIZE_SPAN, spans[0]);
240f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(0, wrapped.getSpanStart(RELATIVE_SIZE_SPAN));
241f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader        assertEquals(EN.length(), wrapped.getSpanEnd(RELATIVE_SIZE_SPAN));
242f695f6a4e4256edf789d3f747d1e6443e1152813Roozbeh Pournader    }
243b37703fef07bb1940fd9d933bb9cc5b6c3959cb2Fabrice Di Meglio}
244