1 19 20 package org.netbeans.spi.editor.highlighting.support; 21 22 import java.util.ArrayList ; 23 import java.util.Enumeration ; 24 import java.util.Random ; 25 import javax.swing.text.AttributeSet ; 26 import javax.swing.text.PlainDocument ; 27 import javax.swing.text.Position ; 28 import javax.swing.text.SimpleAttributeSet ; 29 import org.netbeans.api.editor.settings.AttributesUtilities; 30 import org.netbeans.junit.NbTestCase; 31 import org.netbeans.spi.editor.highlighting.*; 32 33 37 public class PositionsBagRandomTest extends NbTestCase { 38 39 private static final int START = 0; 40 private static final int END = 100; 41 42 private final Random RAND = new Random (); 43 private String [] layerNames; 44 private HighlightsContainer[] containers; 45 46 public PositionsBagRandomTest(String testName) { 47 super(testName); 48 } 49 50 protected void setUp() { 51 RAND.setSeed(System.currentTimeMillis()); 52 53 layerNames = new String [] { 54 "layer-A", 55 "layer-B", 56 "layer-C", 57 }; 58 59 containers = new HighlightsContainer [layerNames.length]; 60 61 for (int i = 0; i < layerNames.length; i++) { 62 containers[i] = createRandomBag(layerNames[i]); 63 } 64 65 } 66 67 public void testMerging() { 68 HighlightsContainer composite = mergeContainers(true, layerNames, containers); 69 70 for (int pointer = START; pointer <= END; pointer++) { 71 String failMsg = null; 72 Highlight [] highestPair = new Highlight [] { null, null }; 73 Highlight [] compositePair = new Highlight [] { null, null }; 74 75 try { 76 highestPair = new Highlight [] { null, null }; 77 compositePair = new Highlight [] { null, null }; 78 79 ArrayList <AttributeSet > leftHighlights = new ArrayList <AttributeSet >(); 81 ArrayList <AttributeSet > rightHighlights = new ArrayList <AttributeSet >(); 82 for (int i = 0; i < containers.length; i++) { 83 Highlight [] containerPair = findPair(pointer, containers[i].getHighlights(START, END)); 84 if (containerPair[0] != null) { 85 leftHighlights.add(containerPair[0].getAttributes()); 86 } 87 if (containerPair[1] != null) { 88 rightHighlights.add(containerPair[1].getAttributes()); 89 } 90 } 91 92 if (!leftHighlights.isEmpty()) { 93 highestPair[0] = new Highlight(pointer, pointer, AttributesUtilities.createComposite( 94 leftHighlights.toArray(new AttributeSet [leftHighlights.size()]))); 95 } 96 if (!rightHighlights.isEmpty()) { 97 highestPair[1] = new Highlight(pointer, pointer, AttributesUtilities.createComposite( 98 rightHighlights.toArray(new AttributeSet [rightHighlights.size()]))); 99 } 100 101 compositePair = findPair(pointer, composite.getHighlights(START, END)); 103 104 for (int i = 0; i < 2; i++) { 105 if (highestPair[i] != null && compositePair[i] != null) { 106 if (!highestPair[i].getAttributes().isEqual(compositePair[i].getAttributes())) { 108 failMsg = (i == 0 ? "Left" : "Right") + "pair attributes do not match"; 109 } 110 } else if (highestPair[i] != null || compositePair[i] != null) { 111 failMsg = (i == 0 ? "Left" : "Right") + " highlight doesn't match"; 113 } 114 } 115 } catch (Throwable e) { 116 failMsg = e.getMessage(); 117 } 118 119 if (failMsg != null) { 120 dumpAll(pointer, layerNames, containers, composite); 121 122 System.out.println("highest pair (pos = " + pointer + ") : " + dumpHighlight(highestPair[0]) + ", " + dumpHighlight(highestPair[1])); 124 System.out.println(" proxy pair (pos = " + pointer + ") : " + dumpHighlight(compositePair[0]) + ", " + dumpHighlight(compositePair[1])); 125 126 fail(failMsg + " (position = " + pointer + ")"); 127 } 128 } 129 } 130 131 public void testTrimming() { 132 HighlightsContainer composite = mergeContainers(false, layerNames, containers); 133 134 for (int pointer = START; pointer <= END; pointer++) { 135 String failMsg = null; 136 Highlight [] highestPair = new Highlight [] { null, null }; 137 Highlight [] compositePair = new Highlight [] { null, null }; 138 139 try { 140 highestPair = new Highlight [] { null, null }; 141 compositePair = new Highlight [] { null, null }; 142 143 for (int i = containers.length - 1; i >= 0; i--) { 145 Highlight [] containerPair = findPair(pointer, containers[i].getHighlights(START, END)); 146 if (highestPair[0] == null) { 147 highestPair[0] = containerPair[0]; 148 } 149 if (highestPair[1] == null) { 150 highestPair[1] = containerPair[1]; 151 } 152 } 153 154 compositePair = findPair(pointer, composite.getHighlights(START, END)); 156 157 for (int i = 0; i < 2; i++) { 158 if (highestPair[i] != null && compositePair[i] != null) { 159 if (!highestPair[i].getAttributes().isEqual(compositePair[i].getAttributes())) { 161 failMsg = (i == 0 ? "Left" : "Right") + "pair attributes do not match"; 162 } 163 } else if (highestPair[i] != null || compositePair[i] != null) { 164 failMsg = (i == 0 ? "Left" : "Right") + " highlight doesn't match"; 166 } 167 } 168 } catch (Throwable e) { 169 failMsg = e.getMessage(); 170 } 171 172 if (failMsg != null) { 173 dumpAll(pointer, layerNames, containers, composite); 174 175 System.out.println("highest pair (pos = " + pointer + ") : " + dumpHighlight(highestPair[0]) + ", " + dumpHighlight(highestPair[1])); 177 System.out.println(" proxy pair (pos = " + pointer + ") : " + dumpHighlight(compositePair[0]) + ", " + dumpHighlight(compositePair[1])); 178 179 fail(failMsg + " (position = " + pointer + ")"); 180 } 181 } 182 } 183 184 private Highlight [] findPair(int offset, HighlightsSequence highlights) { 185 Highlight left = null; 186 Highlight right = null; 187 188 for ( ; highlights.moveNext(); ) { 189 if (highlights.getStartOffset() == highlights.getEndOffset()) { 190 continue; 192 } 193 194 if (offset > highlights.getStartOffset() && offset < highlights.getEndOffset()) { 195 left = right = copyCurrentHighlight(highlights); 196 } else if (offset == highlights.getEndOffset()) { 197 left = copyCurrentHighlight(highlights); 198 } else if (offset == highlights.getStartOffset()) { 199 right = copyCurrentHighlight(highlights); 200 } 201 } 202 203 return new Highlight [] { left, right }; 204 } 205 206 private Highlight copyCurrentHighlight(HighlightsSequence iterator) { 207 return new Highlight( 208 iterator.getStartOffset(), 209 iterator.getEndOffset(), 210 iterator.getAttributes() 211 ); 212 } 213 214 private String dumpHighlight(Highlight h) { 215 if (h == null) { 216 return "< , , >"; 217 } else { 218 StringBuilder sb = new StringBuilder (); 219 220 sb.append("<"); 221 sb.append(h.getStartOffset()); 222 sb.append(","); 223 sb.append(h.getEndOffset()); 224 sb.append(","); 225 226 Enumeration en = h.getAttributes().getAttributeNames(); 227 while (en.hasMoreElements()) { 228 Object attrName = en.nextElement(); 229 Object attrValue = h.getAttributes().getAttribute(attrName); 230 231 sb.append("'"); 232 sb.append(attrName.toString()); 233 sb.append("' = '"); 234 sb.append(attrValue == null ? "null" : attrValue.toString()); 235 sb.append("'"); 236 if (en.hasMoreElements()) { 237 sb.append(", "); 238 } 239 } 240 241 sb.append(">"); 242 243 return sb.toString(); 244 } 245 } 246 247 private void dumpAll(int position, String [] layerNames, HighlightsContainer[] containers, HighlightsContainer composite) { 248 System.out.println("Dumping containers:"); 250 for (int i = 0; i < containers.length; i++) { 251 System.out.println(" containers[" + i + "] " + layerNames[i] + " {"); 252 for (HighlightsSequence highlights = containers[i].getHighlights(START, END); highlights.moveNext(); ) { 253 Highlight h = copyCurrentHighlight(highlights); 254 System.out.println(" " + dumpHighlight(h)); 255 } 256 System.out.println(" } End of containers[" + i + "] " + layerNames[i] + " -------------------------"); 257 } 258 System.out.println("Dumping composite container: {"); 259 for (HighlightsSequence proxyHighlights = composite.getHighlights(START, END); proxyHighlights.moveNext(); ) { 260 Highlight h = copyCurrentHighlight(proxyHighlights); 261 System.out.println(" " + dumpHighlight(h)); 262 } 263 System.out.println("} End of composite container -----------------------"); 264 } 265 266 private PositionsBag createRandomBag(String bagId) { 267 268 PositionsBag bag = new PositionsBag(new PlainDocument (), false); 269 270 int attrIdx = 0; 271 int startOffset = START; 272 int endOffset = END; 273 274 int maxGapSize = Math.max((int) (endOffset - startOffset) / 10, 1); 275 int maxHighlightSize = Math.max((int) (endOffset - startOffset) / 2, 1); 276 277 for (int pointer = startOffset + RAND.nextInt(maxGapSize); pointer <= endOffset; ) { 278 int highlightSize = RAND.nextInt(maxHighlightSize); 279 SimpleAttributeSet attributes = new SimpleAttributeSet (); 280 attributes.addAttribute("AttrName-" + bagId + "-" + attrIdx, "AttrValue"); 281 attrIdx++; 282 283 if (pointer + highlightSize < endOffset) { 284 bag.addHighlight( 285 new SimplePosition(pointer), new SimplePosition(pointer + highlightSize), attributes); 286 } else { 287 bag.addHighlight( 288 new SimplePosition(pointer), new SimplePosition(endOffset), attributes); 289 } 290 291 pointer += highlightSize + RAND.nextInt(maxGapSize); 293 } 294 295 return bag; 296 } 297 298 private PositionsBag mergeContainers(boolean merge, String [] layerNames, HighlightsContainer[] containers) { 299 PositionsBag bag = new PositionsBag(new PlainDocument (), merge); 300 301 for (int i = 0; i < containers.length; i++) { 302 HighlightsSequence layerHighlights = 303 containers[i].getHighlights(START, END); 304 305 for ( ; layerHighlights.moveNext(); ) { 306 bag.addHighlight( 307 new SimplePosition(layerHighlights.getStartOffset()), 308 new SimplePosition(layerHighlights.getEndOffset()), 309 layerHighlights.getAttributes()); 310 } 311 } 312 313 return bag; 314 } 315 316 private static final class Highlight { 317 private int startOffset; 318 private int endOffset; 319 private AttributeSet attributes; 320 321 public Highlight(int startOffset, int endOffset, AttributeSet attributes) { 322 this.startOffset = startOffset; 323 this.endOffset = endOffset; 324 this.attributes = attributes; 325 } 326 327 public int getStartOffset() { 328 return startOffset; 329 } 330 331 public void setStartOffset(int startOffset) { 332 this.startOffset = startOffset; 333 } 334 335 public int getEndOffset() { 336 return endOffset; 337 } 338 339 public void setEndOffset(int endOffset) { 340 this.endOffset = endOffset; 341 } 342 343 public AttributeSet getAttributes() { 344 return attributes; 345 } 346 347 public void setAttributes(AttributeSet attributes) { 348 this.attributes = attributes; 349 } 350 351 } 353 private static final class SimplePosition implements Position { 354 private int offset; 355 356 public SimplePosition(int offset) { 357 this.offset = offset; 358 } 359 360 public int getOffset() { 361 return offset; 362 } 363 } 365 } 366 | Popular Tags |