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