1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17 package android.text; 18 19 import static android.text.Layout.Alignment.*; 20 21 import android.text.DynamicLayout; 22 23 import junit.framework.TestCase; 24 25 /** 26 * Tests DynamciLayout updateBlocks method. 27 * 28 * Requires disabling access checks in the vm since this calls package-private APIs. 29 * 30 * @Suppress 31 */ 32 public class DynamicLayoutBlocksTest extends TestCase { 33 private DynamicLayout dl = new DynamicLayout("", new TextPaint(), 0, ALIGN_NORMAL, 0, 0, false); 34 private static final int ___ = DynamicLayout.INVALID_BLOCK_INDEX; 35 36 private int[] initialBlockEnds; 37 private int[] initialBlockIndices; 38 39 private void defineInitialState(int[] ends, int[] indices) { 40 initialBlockEnds = ends; 41 initialBlockIndices = indices; 42 assertEquals(initialBlockEnds.length, initialBlockIndices.length); 43 } 44 45 public void printBlocks(String message) { 46 System.out.print(message); 47 for (int i = 0; i < dl.getNumberOfBlocks(); i++) { 48 System.out.print(" " + Integer.toString(dl.getBlockEndLines()[i])); 49 } 50 System.out.println(); 51 } 52 53 public void checkInvariants() { 54 assertTrue(dl.getNumberOfBlocks() > 0); 55 assertTrue(dl.getNumberOfBlocks() <= dl.getBlockEndLines().length); 56 assertEquals(dl.getBlockEndLines().length, dl.getBlockIndices().length); 57 58 for (int i = 1; i < dl.getNumberOfBlocks(); i++) { 59 assertTrue(dl.getBlockEndLines()[i] > dl.getBlockEndLines()[i-1]); 60 } 61 } 62 63 private void update(int startLine, int endLine, int newLineCount) { 64 dl.setBlocksDataForTest(initialBlockEnds, initialBlockIndices, initialBlockEnds.length); 65 checkInvariants(); 66 dl.updateBlocks(startLine, endLine, newLineCount); 67 } 68 69 private void assertState(int[] sizes, int[] indices) { 70 checkInvariants(); 71 72 assertEquals(sizes.length, dl.getNumberOfBlocks()); 73 assertEquals(indices.length, dl.getNumberOfBlocks()); 74 75 int[] ends = new int[sizes.length]; 76 for (int i = 0; i < ends.length; i++) { 77 ends[i] = i == 0 ? (sizes[0] == 0 ? 0 : sizes[0] - 1) : ends[i - 1] + sizes[i]; 78 } 79 80 for (int i = 0; i < dl.getNumberOfBlocks(); i++) { 81 assertEquals(ends[i], dl.getBlockEndLines()[i]); 82 assertEquals(indices[i], dl.getBlockIndices()[i]); 83 } 84 } 85 86 private void assertState(int[] sizes) { 87 int[] ids = new int[sizes.length]; 88 for (int i = 0; i < sizes.length; i++) { 89 ids[i] = DynamicLayout.INVALID_BLOCK_INDEX; 90 } 91 assertState(sizes, ids); 92 } 93 94 public void testFrom0() { 95 defineInitialState( new int[] { 0 }, new int[] { 123 }); 96 97 update(0, 0, 0); 98 assertState( new int[] { 0 } ); 99 100 update(0, 0, 1); 101 assertState( new int[] { 0 } ); 102 103 update(0, 0, 10); 104 assertState( new int[] { 10 } ); 105 } 106 107 public void testFrom1ReplaceByEmpty() { 108 defineInitialState( new int[] { 100 }, new int[] { 123 }); 109 110 update(0, 0, 0); 111 assertState( new int[] { 100 } ); 112 113 update(0, 10, 0); 114 assertState( new int[] { 90 } ); 115 116 update(0, 100, 0); 117 assertState( new int[] { 0 } ); 118 119 update(20, 30, 0); 120 assertState( new int[] { 20, 70 } ); 121 122 update(20, 20, 0); 123 assertState( new int[] { 20, 80 } ); 124 125 update(40, 100, 0); 126 assertState( new int[] { 40 } ); 127 128 update(100, 100, 0); 129 assertState( new int[] { 100 } ); 130 } 131 132 public void testFrom1ReplaceFromFirstLine() { 133 defineInitialState( new int[] { 100 }, new int[] { 123 }); 134 135 update(0, 0, 1); 136 assertState( new int[] { 0, 100 } ); 137 138 update(0, 0, 10); 139 assertState( new int[] { 10, 100 } ); 140 141 update(0, 30, 31); 142 assertState( new int[] { 31, 70 } ); 143 144 update(0, 100, 20); 145 assertState( new int[] { 20 } ); 146 } 147 148 public void testFrom1ReplaceFromCenter() { 149 defineInitialState( new int[] { 100 }, new int[] { 123 }); 150 151 update(20, 20, 1); 152 assertState( new int[] { 20, 1, 80 } ); 153 154 update(20, 20, 10); 155 assertState( new int[] { 20, 10, 80 } ); 156 157 update(20, 30, 50); 158 assertState( new int[] { 20, 50, 70 } ); 159 160 update(20, 100, 50); 161 assertState( new int[] { 20, 50 } ); 162 } 163 164 public void testFrom1ReplaceFromEnd() { 165 defineInitialState( new int[] { 100 }, new int[] { 123 }); 166 167 update(100, 100, 0); 168 assertState( new int[] { 100 } ); 169 170 update(100, 100, 1); 171 assertState( new int[] { 100, 1 } ); 172 173 update(100, 100, 10); 174 assertState( new int[] { 100, 10 } ); 175 } 176 177 public void testFrom2ReplaceFromFirstLine() { 178 defineInitialState( new int[] { 10, 20 }, new int[] { 123, 456 }); 179 180 update(0, 4, 50); 181 assertState( new int[] { 50, 10-4, 20-10 }, new int[] { ___, ___, 456 } ); 182 183 update(0, 10, 50); 184 assertState( new int[] { 50, 20-10 }, new int[] { ___, 456 } ); 185 186 update(0, 15, 50); 187 assertState( new int[] { 50, 20-15 }, new int[] { ___, ___ } ); 188 189 update(0, 20, 50); 190 assertState( new int[] { 50 }, new int[] { ___ } ); 191 } 192 193 public void testFrom2ReplaceFromFirstBlock() { 194 defineInitialState( new int[] { 10, 20 }, new int[] { 123, 456 }); 195 196 update(3, 7, 50); 197 assertState( new int[] { 3, 50, 10-7, 20-10 }, new int[] { ___, ___, ___, 456 } ); 198 199 update(3, 10, 50); 200 assertState( new int[] { 3, 50, 20-10 }, new int[] { ___, ___, 456 } ); 201 202 update(3, 14, 50); 203 assertState( new int[] { 3, 50, 20-14 }, new int[] { ___, ___, ___ } ); 204 205 update(3, 20, 50); 206 assertState( new int[] { 3, 50 }, new int[] { ___, ___ } ); 207 } 208 209 public void testFrom2ReplaceFromBottomBoundary() { 210 defineInitialState( new int[] { 10, 20 }, new int[] { 123, 456 }); 211 212 update(10, 10, 50); 213 assertState( new int[] { 10, 50, 20-10 }, new int[] { ___, ___, 456 } ); 214 215 update(10, 14, 50); 216 assertState( new int[] { 10, 50, 20-14 }, new int[] { ___, ___, ___ } ); 217 218 update(10, 20, 50); 219 assertState( new int[] { 10, 50 }, new int[] { ___, ___ } ); 220 } 221 222 public void testFrom2ReplaceFromTopBoundary() { 223 defineInitialState( new int[] { 10, 20 }, new int[] { 123, 456 }); 224 225 update(11, 11, 50); 226 assertState( new int[] { 11, 50, 20-11 }, new int[] { 123, ___, ___ } ); 227 228 update(11, 14, 50); 229 assertState( new int[] { 11, 50, 20-14 }, new int[] { 123, ___, ___ } ); 230 231 update(11, 20, 50); 232 assertState( new int[] { 11, 50 }, new int[] { 123, ___ } ); 233 } 234 235 public void testFrom2ReplaceFromSecondBlock() { 236 defineInitialState( new int[] { 10, 20 }, new int[] { 123, 456 }); 237 238 update(14, 14, 50); 239 assertState( new int[] { 11, 14-11, 50, 20-14 }, new int[] { 123, ___, ___, ___ } ); 240 241 update(14, 17, 50); 242 assertState( new int[] { 11, 14-11, 50, 20-17 }, new int[] { 123, ___, ___, ___ } ); 243 244 update(14, 20, 50); 245 assertState( new int[] { 11, 14-11, 50 }, new int[] { 123, ___, ___ } ); 246 } 247 248 public void testFrom2RemoveFromFirst() { 249 defineInitialState( new int[] { 10, 20 }, new int[] { 123, 456 }); 250 251 update(0, 4, 0); 252 assertState( new int[] { 10-4, 20-10 }, new int[] { ___, 456 } ); 253 254 update(0, 10, 0); 255 assertState( new int[] { 20-10 }, new int[] { 456 } ); 256 257 update(0, 14, 0); 258 assertState( new int[] { 20-14 }, new int[] { ___ } ); 259 260 update(0, 20, 0); 261 assertState( new int[] { 0 }, new int[] { ___ } ); 262 } 263 264 public void testFrom2RemoveFromFirstBlock() { 265 defineInitialState( new int[] { 10, 20 }, new int[] { 123, 456 }); 266 267 update(4, 7, 0); 268 assertState( new int[] { 4, 10-7, 20-10 }, new int[] { ___, ___, 456 } ); 269 270 update(4, 10, 0); 271 assertState( new int[] { 4, 20-10 }, new int[] { ___, 456 } ); 272 273 update(4, 14, 0); 274 assertState( new int[] { 4, 20-14 }, new int[] { ___, ___ } ); 275 276 update(4, 20, 0); 277 assertState( new int[] { 4 }, new int[] { ___ } ); 278 } 279 280 public void testFrom2RemoveFromSecondBlock() { 281 defineInitialState( new int[] { 10, 20 }, new int[] { 123, 456 }); 282 283 update(14, 17, 0); 284 assertState( new int[] { 11, 14-11, 20-17 }, new int[] { 123, ___, ___ } ); 285 286 update(14, 20, 0); 287 assertState( new int[] { 11, 14-11 }, new int[] { 123, ___ } ); 288 } 289 290 public void testFrom3ReplaceFromFirstBlock() { 291 defineInitialState( new int[] { 10, 30, 60 }, new int[] { 123, 456, 789 }); 292 293 update(3, 7, 50); 294 assertState( new int[] { 3, 50, 10-7, 30-10, 60-30 }, new int[] { ___, ___, ___, 456, 789 } ); 295 296 update(3, 10, 50); 297 assertState( new int[] { 3, 50, 30-10, 60-30 }, new int[] { ___, ___, 456, 789 } ); 298 299 update(3, 17, 50); 300 assertState( new int[] { 3, 50, 30-17, 60-30 }, new int[] { ___, ___, ___, 789 } ); 301 302 update(3, 30, 50); 303 assertState( new int[] { 3, 50, 60-30 }, new int[] { ___, ___, 789 } ); 304 305 update(3, 40, 50); 306 assertState( new int[] { 3, 50, 60-40 }, new int[] { ___, ___, ___ } ); 307 308 update(3, 60, 50); 309 assertState( new int[] { 3, 50 }, new int[] { ___, ___ } ); 310 } 311 312 public void testFrom3ReplaceFromSecondBlock() { 313 defineInitialState( new int[] { 10, 30, 60 }, new int[] { 123, 456, 789 }); 314 315 update(13, 17, 50); 316 assertState( new int[] { 11, 2, 50, 30-17, 60-30 }, new int[] { 123, ___, ___, ___, 789 } ); 317 318 update(13, 30, 50); 319 assertState( new int[] { 11, 2, 50, 60-30 }, new int[] { 123, ___, ___, 789 } ); 320 321 update(13, 40, 50); 322 assertState( new int[] { 11, 2, 50, 60-40 }, new int[] { 123, ___, ___, ___ } ); 323 324 update(13, 60, 50); 325 assertState( new int[] { 11, 2, 50 }, new int[] { 123, ___, ___ } ); 326 } 327 } 328