1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php 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 package com.android.ide.eclipse.adt.internal.editors.formatting; 17 18 import com.android.ide.common.xml.XmlFormatPreferences; 19 20 import org.eclipse.jface.text.BadLocationException; 21 import org.eclipse.jface.text.Document; 22 import org.eclipse.text.edits.MalformedTreeException; 23 import org.eclipse.text.edits.ReplaceEdit; 24 25 import junit.framework.TestCase; 26 27 @SuppressWarnings("javadoc") 28 public class AndroidXmlFormattingStrategyTest extends TestCase { 29 // In the given before document, replace in the range replaceStart to replaceEnd 30 // the formatted string, and assert that it's identical to the given after string check(String before, int replaceStart, int replaceEnd, String formatted, String expected, XmlFormatPreferences prefs)31 private void check(String before, int replaceStart, int replaceEnd, String formatted, 32 String expected, XmlFormatPreferences prefs) 33 throws MalformedTreeException, BadLocationException { 34 Document document = new Document(); 35 document.set(before); 36 ReplaceEdit edit = AndroidXmlFormattingStrategy.createReplaceEdit(document, replaceStart, 37 replaceEnd, formatted, prefs); 38 assertNotNull(edit); 39 edit.apply(document); 40 String contents = document.get(); 41 // Ensure that we don't have any mangled CRLFs 42 char prev = 0; 43 boolean haveCrlf = false; 44 for (int i = 0, n = contents.length(); i < n; i++) { 45 char c = contents.charAt(i); 46 if (c == '\r') { 47 haveCrlf = true; 48 } 49 if (!(c != '\r' || prev != '\r')) { 50 fail("Mangled document: Found adjacent \\r's starting at " + i 51 + ": " + contents.substring(i - 1, Math.min(contents.length(), i + 10)) 52 + "..."); 53 } 54 if (haveCrlf && c == '\n' && prev != '\r') { 55 fail("Mangled document: In a CRLF document, found \\n without preceeding \\r"); 56 } 57 58 prev = c; 59 } 60 61 assertEquals(expected, contents); 62 } 63 64 // In the given before document, replace the range indicated by [ and ] with the given 65 // formatted string, and assert that it's identical to the given after string check( String before, String insert, String expected, XmlFormatPreferences prefs)66 private void check( 67 String before, String insert, String expected, 68 XmlFormatPreferences prefs) 69 throws MalformedTreeException, BadLocationException { 70 int replaceStart = before.indexOf('['); 71 assertTrue(replaceStart != -1); 72 before = before.substring(0, replaceStart) + before.substring(replaceStart + 1); 73 74 int replaceEnd = before.indexOf(']'); 75 assertTrue(replaceEnd != -1); 76 before = before.substring(0, replaceEnd) + before.substring(replaceEnd + 1); 77 78 check(before, replaceStart, replaceEnd, insert, expected, prefs); 79 } 80 test1()81 public void test1() throws Exception { 82 check( 83 // Before 84 "<root>\n" + 85 "[ <element/>\n" + 86 " <second/>\n" + 87 "]\n" + 88 "</root>\n", 89 90 // Insert 91 " <element/>\n" + 92 " <second/>\n", 93 94 // After 95 "<root>\n" + 96 " <element/>\n" + 97 " <second/>\n" + 98 "\n" + 99 "</root>\n", 100 101 XmlFormatPreferences.defaults()); 102 } 103 test2()104 public void test2() throws Exception { 105 XmlFormatPreferences prefs = XmlFormatPreferences.defaults(); 106 prefs.removeEmptyLines = true; 107 108 check( 109 // Before 110 "<root>\n" + 111 "\n" + 112 "\n" + 113 "[ <element/>\n" + 114 " <second/>\n" + 115 "]\n" + 116 "\n" + 117 "\n" + 118 "</root>\n", 119 120 // Insert 121 " <element/>\n" + 122 " <second/>\n", 123 124 // After 125 "<root>\n" + 126 " <element/>\n" + 127 " <second/>\n" + 128 "</root>\n", 129 130 prefs); 131 } 132 test3()133 public void test3() throws Exception { 134 XmlFormatPreferences prefs = XmlFormatPreferences.defaults(); 135 prefs.removeEmptyLines = true; 136 137 check( 138 // Before 139 "<root>\n" + 140 "\n" + 141 "\n" + 142 " [<element/>\n" + 143 " <second/>]\n" + 144 "\n" + 145 "\n" + 146 "\n" + 147 "</root>\n", 148 149 // Insert 150 " <element/>\n" + 151 " <second/>", 152 153 // After 154 "<root>\n" + 155 " <element/>\n" + 156 " <second/>\n" + 157 "</root>\n", 158 159 prefs); 160 } 161 test4()162 public void test4() throws Exception { 163 check( 164 "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + 165 " xmlns:tools=\"http://schemas.android.com/tools\"\n" + 166 " android:layout_width=\"match_parent\"\n" + 167 " android:layout_height=\"match_parent\" >\n" + 168 "\n" + 169 " [<TextView\n" + 170 " android:layout_width=\"wrap_content\"\n" + 171 " android:layout_height=\"wrap_content\"\n" + 172 " android:layout_centerHorizontal=\"true\"\n" + 173 " android:layout_centerVertical=\"true\"\n" + 174 " android:text=\"foo\"\n" + 175 " tools:context=\".MainActivity\" />]\n" + 176 "\n" + 177 "</RelativeLayout>\n", 178 179 // Insert 180 "\n" + 181 " <TextView\n" + 182 " android:layout_width=\"wrap_content\"\n" + 183 " android:layout_height=\"wrap_content\"\n" + 184 " android:layout_centerHorizontal=\"true\"\n" + 185 " android:layout_centerVertical=\"true\"\n" + 186 " android:text=\"foo\"\n" + 187 " tools:context=\".MainActivity\" />\n", 188 189 // After 190 "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + 191 " xmlns:tools=\"http://schemas.android.com/tools\"\n" + 192 " android:layout_width=\"match_parent\"\n" + 193 " android:layout_height=\"match_parent\" >\n" + 194 "\n" + 195 " <TextView\n" + 196 " android:layout_width=\"wrap_content\"\n" + 197 " android:layout_height=\"wrap_content\"\n" + 198 " android:layout_centerHorizontal=\"true\"\n" + 199 " android:layout_centerVertical=\"true\"\n" + 200 " android:text=\"foo\"\n" + 201 " tools:context=\".MainActivity\" />\n" + 202 "\n" + 203 "</RelativeLayout>\n", 204 205 XmlFormatPreferences.defaults()); 206 } 207 testCrLf1()208 public void testCrLf1() throws Exception { 209 check( 210 // Before 211 "<root>\r\n" + 212 "[ <element/>\r\n" + 213 " <second/>\r\n" + 214 "]\r\n" + 215 "</root>\r\n", 216 217 // Insert 218 " <element/>\r\n" + 219 " <second/>\r\n", 220 221 // After 222 "<root>\r\n" + 223 " <element/>\r\n" + 224 " <second/>\r\n" + 225 "\r\n" + 226 "</root>\r\n", 227 228 XmlFormatPreferences.defaults()); 229 } 230 testCrLf2()231 public void testCrLf2() throws Exception { 232 XmlFormatPreferences prefs = XmlFormatPreferences.defaults(); 233 prefs.removeEmptyLines = true; 234 235 check( 236 // Before 237 "<root>\r\n" + 238 "\r\n" + 239 "\r\n" + 240 "[ <element/>\r\n" + 241 " <second/>\r\n" + 242 "]\r\n" + 243 "\r\n" + 244 "\r\n" + 245 "</root>\r\n", 246 247 // Insert 248 " <element/>\r\n" + 249 " <second/>\r\n", 250 251 // After 252 "<root>\r\n" + 253 " <element/>\r\n" + 254 " <second/>\r\n" + 255 "</root>\r\n", 256 257 prefs); 258 } 259 testCrLf3()260 public void testCrLf3() throws Exception { 261 XmlFormatPreferences prefs = XmlFormatPreferences.defaults(); 262 prefs.removeEmptyLines = true; 263 264 check( 265 // Before 266 "<root>\r\n" + 267 "\r\n" + 268 "\r\n" + 269 " [<element/>\r\n" + 270 " <second/>]\r\n" + 271 "\r\n" + 272 "\r\n" + 273 "\r\n" + 274 "</root>\r\n", 275 276 // Insert 277 " <element/>\r\n" + 278 " <second/>", 279 280 // After 281 "<root>\r\n" + 282 " <element/>\r\n" + 283 " <second/>\r\n" + 284 "</root>\r\n", 285 286 prefs); 287 } 288 289 testCrlf4()290 public void testCrlf4() throws Exception { 291 check( 292 "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n" + 293 " xmlns:tools=\"http://schemas.android.com/tools\"\r\n" + 294 " android:layout_width=\"match_parent\"\r\n" + 295 " android:layout_height=\"match_parent\" >\r\n" + 296 "\r\n" + 297 " [<TextView\r\n" + 298 " android:layout_width=\"wrap_content\"\r\n" + 299 " android:layout_height=\"wrap_content\"\r\n" + 300 " android:layout_centerHorizontal=\"true\"\r\n" + 301 " android:layout_centerVertical=\"true\"\r\n" + 302 " android:text=\"foo\"\r\n" + 303 " tools:context=\".MainActivity\" />]\r\n" + 304 "\r\n" + 305 "</RelativeLayout>\r\n", 306 307 // Insert 308 "\r\n" + 309 " <TextView\r\n" + 310 " android:layout_width=\"wrap_content\"\r\n" + 311 " android:layout_height=\"wrap_content\"\r\n" + 312 " android:layout_centerHorizontal=\"true\"\r\n" + 313 " android:layout_centerVertical=\"true\"\r\n" + 314 " android:text=\"foo\"\r\n" + 315 " tools:context=\".MainActivity\" />\r\n", 316 317 // After 318 "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n" + 319 " xmlns:tools=\"http://schemas.android.com/tools\"\r\n" + 320 " android:layout_width=\"match_parent\"\r\n" + 321 " android:layout_height=\"match_parent\" >\r\n" + 322 "\r\n" + 323 " <TextView\r\n" + 324 " android:layout_width=\"wrap_content\"\r\n" + 325 " android:layout_height=\"wrap_content\"\r\n" + 326 " android:layout_centerHorizontal=\"true\"\r\n" + 327 " android:layout_centerVertical=\"true\"\r\n" + 328 " android:text=\"foo\"\r\n" + 329 " tools:context=\".MainActivity\" />\r\n" + 330 "\r\n" + 331 "</RelativeLayout>\r\n", 332 333 XmlFormatPreferences.defaults()); 334 } 335 } 336