BidiFormatterTest.java revision b37703fef07bb1940fd9d933bb9cc5b6c3959cb2
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.support.v4.text;
18
19import android.test.AndroidTestCase;
20
21import java.util.Locale;
22
23public class BidiFormatterTest extends AndroidTestCase {
24
25    private static final BidiFormatter LTR_FMT = BidiFormatter.getInstance(false /* LTR context */);
26    private static final BidiFormatter RTL_FMT = BidiFormatter.getInstance(true /* RTL context */);
27
28    private static final BidiFormatter LTR_FMT_EXIT_RESET =
29            new BidiFormatter.Builder(false /* LTR context */).stereoReset(false).build();
30    private static final BidiFormatter RTL_FMT_EXIT_RESET =
31            new BidiFormatter.Builder(true /* RTL context */).stereoReset(false).build();
32
33    private static final String EN = "abba";
34    private static final String HE = "\u05e0\u05e1";
35
36    private static final String LRM = "\u200E";
37    private static final String RLM = "\u200F";
38    private static final String LRE = "\u202A";
39    private static final String RLE = "\u202B";
40    private static final String PDF = "\u202C";
41
42    public void testIsRtlContext() {
43        assertEquals(false, LTR_FMT.isRtlContext());
44        assertEquals(true, RTL_FMT.isRtlContext());
45
46        assertEquals(false, BidiFormatter.getInstance(Locale.ENGLISH).isRtlContext());
47        assertEquals(true, BidiFormatter.getInstance(true).isRtlContext());
48    }
49
50    public void testBuilderIsRtlContext() {
51        assertEquals(false, new BidiFormatter.Builder(false).build().isRtlContext());
52        assertEquals(true, new BidiFormatter.Builder(true).build().isRtlContext());
53    }
54
55    public void testIsRtl() {
56        assertEquals(true, BidiFormatter.getInstance(true).isRtl(HE));
57        assertEquals(true, BidiFormatter.getInstance(false).isRtl(HE));
58
59        assertEquals(false, BidiFormatter.getInstance(true).isRtl(EN));
60        assertEquals(false, BidiFormatter.getInstance(false).isRtl(EN));
61    }
62
63    public void testUnicodeWrap() {
64        // Uniform directionality in opposite context.
65        assertEquals("uniform dir opposite to LTR context",
66                RLE + "." + HE + "." + PDF + LRM,
67                LTR_FMT_EXIT_RESET.unicodeWrap("." + HE + "."));
68        assertEquals("uniform dir opposite to LTR context, stereo reset",
69                LRM + RLE + "." + HE + "." + PDF + LRM,
70                LTR_FMT.unicodeWrap("." + HE + "."));
71        assertEquals("uniform dir opposite to LTR context, stereo reset, no isolation",
72                RLE + "." + HE + "." + PDF,
73                LTR_FMT.unicodeWrap("." + HE + ".", false));
74        assertEquals("neutral treated as opposite to LTR context",
75                RLE + "." + PDF + LRM,
76                LTR_FMT_EXIT_RESET.unicodeWrap(".", TextDirectionHeuristicsCompat.RTL));
77        assertEquals("uniform dir opposite to RTL context",
78                LRE + "." + EN + "." + PDF + RLM,
79                RTL_FMT_EXIT_RESET.unicodeWrap("." + EN + "."));
80        assertEquals("uniform dir opposite to RTL context, stereo reset",
81                RLM + LRE + "." + EN + "." + PDF + RLM,
82                RTL_FMT.unicodeWrap("." + EN + "."));
83        assertEquals("uniform dir opposite to RTL context, stereo reset, no isolation",
84                LRE + "." + EN + "." + PDF,
85                RTL_FMT.unicodeWrap("." + EN + ".", false));
86        assertEquals("neutral treated as opposite to RTL context",
87                LRE + "." + PDF + RLM,
88                RTL_FMT_EXIT_RESET.unicodeWrap(".", TextDirectionHeuristicsCompat.LTR));
89
90        // We test mixed-directionality cases only with an explicit overall directionality parameter
91        // because the estimation logic is outside the sphere of BidiFormatter, and different
92        // estimators will treat them differently.
93
94        // Overall directionality matching context, but with opposite exit directionality.
95        assertEquals("exit dir opposite to LTR context",
96                EN + HE + LRM,
97                LTR_FMT_EXIT_RESET.unicodeWrap(EN + HE, TextDirectionHeuristicsCompat.LTR));
98        assertEquals("exit dir opposite to LTR context, stereo reset",
99                EN + HE + LRM,
100                LTR_FMT.unicodeWrap(EN + HE, TextDirectionHeuristicsCompat.LTR));
101        assertEquals("exit dir opposite to LTR context, stereo reset, no isolation",
102                EN + HE,
103                LTR_FMT.unicodeWrap(EN + HE, TextDirectionHeuristicsCompat.LTR, false));
104
105        assertEquals("exit dir opposite to RTL context",
106                HE + EN + RLM,
107                RTL_FMT_EXIT_RESET.unicodeWrap(HE + EN, TextDirectionHeuristicsCompat.RTL));
108        assertEquals("exit dir opposite to RTL context, stereo reset",
109                HE + EN + RLM,
110                RTL_FMT.unicodeWrap(HE + EN, TextDirectionHeuristicsCompat.RTL));
111        assertEquals("exit dir opposite to RTL context, stereo reset, no isolation",
112                HE + EN,
113                RTL_FMT.unicodeWrap(HE + EN, TextDirectionHeuristicsCompat.RTL, false));
114
115        // Overall directionality matching context, but with opposite entry directionality.
116        assertEquals("entry dir opposite to LTR context",
117                HE + EN,
118                LTR_FMT_EXIT_RESET.unicodeWrap(HE + EN, TextDirectionHeuristicsCompat.LTR));
119        assertEquals("entry dir opposite to LTR context, stereo reset",
120                LRM + HE + EN,
121                LTR_FMT.unicodeWrap(HE + EN, TextDirectionHeuristicsCompat.LTR));
122        assertEquals("entry dir opposite to LTR context, stereo reset, no isolation",
123                HE + EN,
124                LTR_FMT.unicodeWrap(HE + EN, TextDirectionHeuristicsCompat.LTR, false));
125
126        assertEquals("entry dir opposite to RTL context",
127                EN + HE,
128                RTL_FMT_EXIT_RESET.unicodeWrap(EN + HE, TextDirectionHeuristicsCompat.RTL));
129        assertEquals("entry dir opposite to RTL context, stereo reset",
130                RLM + EN + HE,
131                RTL_FMT.unicodeWrap(EN + HE, TextDirectionHeuristicsCompat.RTL));
132        assertEquals("entry dir opposite to RTL context, stereo reset, no isolation",
133                EN + HE,
134                RTL_FMT.unicodeWrap(EN + HE, TextDirectionHeuristicsCompat.RTL, false));
135
136        // Overall directionality matching context, but with opposite entry and exit directionality.
137        assertEquals("entry and exit dir opposite to LTR context",
138                HE + EN + HE + LRM,
139                LTR_FMT_EXIT_RESET.unicodeWrap(HE + EN + HE, TextDirectionHeuristicsCompat.LTR));
140        assertEquals("entry and exit dir opposite to LTR context, stereo reset",
141                LRM + HE + EN + HE + LRM,
142                LTR_FMT.unicodeWrap(HE + EN + HE, TextDirectionHeuristicsCompat.LTR));
143        assertEquals("entry and exit dir opposite to LTR context, no isolation",
144                HE + EN + HE,
145                LTR_FMT_EXIT_RESET.unicodeWrap(HE + EN + HE, TextDirectionHeuristicsCompat.LTR, false));
146
147        assertEquals("entry and exit dir opposite to RTL context",
148                EN + HE + EN + RLM,
149                RTL_FMT_EXIT_RESET.unicodeWrap(EN + HE + EN, TextDirectionHeuristicsCompat.RTL));
150        assertEquals("entry and exit dir opposite to RTL context, no isolation",
151                EN + HE + EN,
152                RTL_FMT_EXIT_RESET.unicodeWrap(EN + HE + EN, TextDirectionHeuristicsCompat.RTL, false));
153
154        // Entry and exit directionality matching context, but with opposite overall directionality.
155        assertEquals("overall dir (but not entry or exit dir) opposite to LTR context",
156                RLE + EN + HE + EN + PDF + LRM,
157                LTR_FMT_EXIT_RESET.unicodeWrap(EN + HE + EN, TextDirectionHeuristicsCompat.RTL));
158        assertEquals("overall dir (but not entry or exit dir) opposite to LTR context, stereo reset",
159                LRM + RLE + EN + HE + EN + PDF + LRM,
160                LTR_FMT.unicodeWrap(EN + HE + EN, TextDirectionHeuristicsCompat.RTL));
161        assertEquals("overall dir (but not entry or exit dir) opposite to LTR context, no isolation",
162                RLE + EN + HE + EN + PDF,
163                LTR_FMT_EXIT_RESET.unicodeWrap(EN + HE + EN, TextDirectionHeuristicsCompat.RTL, false));
164
165        assertEquals("overall dir (but not entry or exit dir) opposite to RTL context",
166                LRE + HE + EN + HE + PDF + RLM,
167                RTL_FMT_EXIT_RESET.unicodeWrap(HE + EN + HE, TextDirectionHeuristicsCompat.LTR));
168        assertEquals("overall dir (but not entry or exit dir) opposite to RTL context, stereo reset",
169                RLM + LRE + HE + EN + HE + PDF + RLM,
170                RTL_FMT.unicodeWrap(HE + EN + HE, TextDirectionHeuristicsCompat.LTR));
171        assertEquals("overall dir (but not entry or exit dir) opposite to RTL context, no isolation",
172                LRE + HE + EN + HE + PDF,
173                RTL_FMT_EXIT_RESET.unicodeWrap(HE + EN + HE, TextDirectionHeuristicsCompat.LTR, false));
174    }
175}
176