1 /* 2 * [The "BSD license"] 3 * Copyright (c) 2010 Terence Parr 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 package org.antlr.test; 29 30 import org.antlr.analysis.Label; 31 import org.antlr.misc.IntervalSet; 32 import org.junit.Test; 33 34 import java.util.ArrayList; 35 import java.util.List; 36 37 38 public class TestIntervalSet extends BaseTest { 39 40 /** Public default constructor used by TestRig */ 41 public TestIntervalSet() { 42 } 43 44 @Test public void testSingleElement() throws Exception { 45 IntervalSet s = IntervalSet.of(99); 46 String expecting = "99"; 47 assertEquals(s.toString(), expecting); 48 } 49 50 @Test public void testIsolatedElements() throws Exception { 51 IntervalSet s = new IntervalSet(); 52 s.add(1); 53 s.add('z'); 54 s.add('\uFFF0'); 55 String expecting = "{1, 122, 65520}"; 56 assertEquals(s.toString(), expecting); 57 } 58 59 @Test public void testMixedRangesAndElements() throws Exception { 60 IntervalSet s = new IntervalSet(); 61 s.add(1); 62 s.add('a','z'); 63 s.add('0','9'); 64 String expecting = "{1, 48..57, 97..122}"; 65 assertEquals(s.toString(), expecting); 66 } 67 68 @Test public void testSimpleAnd() throws Exception { 69 IntervalSet s = IntervalSet.of(10,20); 70 IntervalSet s2 = IntervalSet.of(13,15); 71 String expecting = "13..15"; 72 String result = (s.and(s2)).toString(); 73 assertEquals(result, expecting); 74 } 75 76 @Test public void testRangeAndIsolatedElement() throws Exception { 77 IntervalSet s = IntervalSet.of('a','z'); 78 IntervalSet s2 = IntervalSet.of('d'); 79 String expecting = "100"; 80 String result = (s.and(s2)).toString(); 81 assertEquals(result, expecting); 82 } 83 84 @Test public void testEmptyIntersection() throws Exception { 85 IntervalSet s = IntervalSet.of('a','z'); 86 IntervalSet s2 = IntervalSet.of('0','9'); 87 String expecting = "{}"; 88 String result = (s.and(s2)).toString(); 89 assertEquals(result, expecting); 90 } 91 92 @Test public void testEmptyIntersectionSingleElements() throws Exception { 93 IntervalSet s = IntervalSet.of('a'); 94 IntervalSet s2 = IntervalSet.of('d'); 95 String expecting = "{}"; 96 String result = (s.and(s2)).toString(); 97 assertEquals(result, expecting); 98 } 99 100 @Test public void testNotSingleElement() throws Exception { 101 IntervalSet vocabulary = IntervalSet.of(1,1000); 102 vocabulary.add(2000,3000); 103 IntervalSet s = IntervalSet.of(50,50); 104 String expecting = "{1..49, 51..1000, 2000..3000}"; 105 String result = (s.complement(vocabulary)).toString(); 106 assertEquals(result, expecting); 107 } 108 109 @Test public void testNotSet() throws Exception { 110 IntervalSet vocabulary = IntervalSet.of(1,1000); 111 IntervalSet s = IntervalSet.of(50,60); 112 s.add(5); 113 s.add(250,300); 114 String expecting = "{1..4, 6..49, 61..249, 301..1000}"; 115 String result = (s.complement(vocabulary)).toString(); 116 assertEquals(result, expecting); 117 } 118 119 @Test public void testNotEqualSet() throws Exception { 120 IntervalSet vocabulary = IntervalSet.of(1,1000); 121 IntervalSet s = IntervalSet.of(1,1000); 122 String expecting = "{}"; 123 String result = (s.complement(vocabulary)).toString(); 124 assertEquals(result, expecting); 125 } 126 127 @Test public void testNotSetEdgeElement() throws Exception { 128 IntervalSet vocabulary = IntervalSet.of(1,2); 129 IntervalSet s = IntervalSet.of(1); 130 String expecting = "2"; 131 String result = (s.complement(vocabulary)).toString(); 132 assertEquals(result, expecting); 133 } 134 135 @Test public void testNotSetFragmentedVocabulary() throws Exception { 136 IntervalSet vocabulary = IntervalSet.of(1,255); 137 vocabulary.add(1000,2000); 138 vocabulary.add(9999); 139 IntervalSet s = IntervalSet.of(50,60); 140 s.add(3); 141 s.add(250,300); 142 s.add(10000); // this is outside range of vocab and should be ignored 143 String expecting = "{1..2, 4..49, 61..249, 1000..2000, 9999}"; 144 String result = (s.complement(vocabulary)).toString(); 145 assertEquals(result, expecting); 146 } 147 148 @Test public void testSubtractOfCompletelyContainedRange() throws Exception { 149 IntervalSet s = IntervalSet.of(10,20); 150 IntervalSet s2 = IntervalSet.of(12,15); 151 String expecting = "{10..11, 16..20}"; 152 String result = (s.subtract(s2)).toString(); 153 assertEquals(result, expecting); 154 } 155 156 @Test public void testSubtractOfOverlappingRangeFromLeft() throws Exception { 157 IntervalSet s = IntervalSet.of(10,20); 158 IntervalSet s2 = IntervalSet.of(5,11); 159 String expecting = "12..20"; 160 String result = (s.subtract(s2)).toString(); 161 assertEquals(result, expecting); 162 163 IntervalSet s3 = IntervalSet.of(5,10); 164 expecting = "11..20"; 165 result = (s.subtract(s3)).toString(); 166 assertEquals(result, expecting); 167 } 168 169 @Test public void testSubtractOfOverlappingRangeFromRight() throws Exception { 170 IntervalSet s = IntervalSet.of(10,20); 171 IntervalSet s2 = IntervalSet.of(15,25); 172 String expecting = "10..14"; 173 String result = (s.subtract(s2)).toString(); 174 assertEquals(result, expecting); 175 176 IntervalSet s3 = IntervalSet.of(20,25); 177 expecting = "10..19"; 178 result = (s.subtract(s3)).toString(); 179 assertEquals(result, expecting); 180 } 181 182 @Test public void testSubtractOfCompletelyCoveredRange() throws Exception { 183 IntervalSet s = IntervalSet.of(10,20); 184 IntervalSet s2 = IntervalSet.of(1,25); 185 String expecting = "{}"; 186 String result = (s.subtract(s2)).toString(); 187 assertEquals(result, expecting); 188 } 189 190 @Test public void testSubtractOfRangeSpanningMultipleRanges() throws Exception { 191 IntervalSet s = IntervalSet.of(10,20); 192 s.add(30,40); 193 s.add(50,60); // s has 3 ranges now: 10..20, 30..40, 50..60 194 IntervalSet s2 = IntervalSet.of(5,55); // covers one and touches 2nd range 195 String expecting = "56..60"; 196 String result = (s.subtract(s2)).toString(); 197 assertEquals(result, expecting); 198 199 IntervalSet s3 = IntervalSet.of(15,55); // touches both 200 expecting = "{10..14, 56..60}"; 201 result = (s.subtract(s3)).toString(); 202 assertEquals(result, expecting); 203 } 204 205 /** The following was broken: 206 {0..113, 115..65534}-{0..115, 117..65534}=116..65534 207 */ 208 @Test public void testSubtractOfWackyRange() throws Exception { 209 IntervalSet s = IntervalSet.of(0,113); 210 s.add(115,200); 211 IntervalSet s2 = IntervalSet.of(0,115); 212 s2.add(117,200); 213 String expecting = "116"; 214 String result = (s.subtract(s2)).toString(); 215 assertEquals(result, expecting); 216 } 217 218 @Test public void testSimpleEquals() throws Exception { 219 IntervalSet s = IntervalSet.of(10,20); 220 IntervalSet s2 = IntervalSet.of(10,20); 221 Boolean expecting = new Boolean(true); 222 Boolean result = new Boolean(s.equals(s2)); 223 assertEquals(result, expecting); 224 225 IntervalSet s3 = IntervalSet.of(15,55); 226 expecting = new Boolean(false); 227 result = new Boolean(s.equals(s3)); 228 assertEquals(result, expecting); 229 } 230 231 @Test public void testEquals() throws Exception { 232 IntervalSet s = IntervalSet.of(10,20); 233 s.add(2); 234 s.add(499,501); 235 IntervalSet s2 = IntervalSet.of(10,20); 236 s2.add(2); 237 s2.add(499,501); 238 Boolean expecting = new Boolean(true); 239 Boolean result = new Boolean(s.equals(s2)); 240 assertEquals(result, expecting); 241 242 IntervalSet s3 = IntervalSet.of(10,20); 243 s3.add(2); 244 expecting = new Boolean(false); 245 result = new Boolean(s.equals(s3)); 246 assertEquals(result, expecting); 247 } 248 249 @Test public void testSingleElementMinusDisjointSet() throws Exception { 250 IntervalSet s = IntervalSet.of(15,15); 251 IntervalSet s2 = IntervalSet.of(1,5); 252 s2.add(10,20); 253 String expecting = "{}"; // 15 - {1..5, 10..20} = {} 254 String result = s.subtract(s2).toString(); 255 assertEquals(result, expecting); 256 } 257 258 @Test public void testMembership() throws Exception { 259 IntervalSet s = IntervalSet.of(15,15); 260 s.add(50,60); 261 assertTrue(!s.member(0)); 262 assertTrue(!s.member(20)); 263 assertTrue(!s.member(100)); 264 assertTrue(s.member(15)); 265 assertTrue(s.member(55)); 266 assertTrue(s.member(50)); 267 assertTrue(s.member(60)); 268 } 269 270 // {2,15,18} & 10..20 271 @Test public void testIntersectionWithTwoContainedElements() throws Exception { 272 IntervalSet s = IntervalSet.of(10,20); 273 IntervalSet s2 = IntervalSet.of(2,2); 274 s2.add(15); 275 s2.add(18); 276 String expecting = "{15, 18}"; 277 String result = (s.and(s2)).toString(); 278 assertEquals(result, expecting); 279 } 280 281 @Test public void testIntersectionWithTwoContainedElementsReversed() throws Exception { 282 IntervalSet s = IntervalSet.of(10,20); 283 IntervalSet s2 = IntervalSet.of(2,2); 284 s2.add(15); 285 s2.add(18); 286 String expecting = "{15, 18}"; 287 String result = (s2.and(s)).toString(); 288 assertEquals(result, expecting); 289 } 290 291 @Test public void testComplement() throws Exception { 292 IntervalSet s = IntervalSet.of(100,100); 293 s.add(101,101); 294 IntervalSet s2 = IntervalSet.of(100,102); 295 String expecting = "102"; 296 String result = (s.complement(s2)).toString(); 297 assertEquals(result, expecting); 298 } 299 300 @Test public void testComplement2() throws Exception { 301 IntervalSet s = IntervalSet.of(100,101); 302 IntervalSet s2 = IntervalSet.of(100,102); 303 String expecting = "102"; 304 String result = (s.complement(s2)).toString(); 305 assertEquals(result, expecting); 306 } 307 308 @Test public void testComplement3() throws Exception { 309 IntervalSet s = IntervalSet.of(1,96); 310 s.add(99,Label.MAX_CHAR_VALUE); 311 String expecting = "97..98"; 312 String result = (s.complement(1,Label.MAX_CHAR_VALUE)).toString(); 313 assertEquals(result, expecting); 314 } 315 316 @Test public void testMergeOfRangesAndSingleValues() throws Exception { 317 // {0..41, 42, 43..65534} 318 IntervalSet s = IntervalSet.of(0,41); 319 s.add(42); 320 s.add(43,65534); 321 String expecting = "0..65534"; 322 String result = s.toString(); 323 assertEquals(result, expecting); 324 } 325 326 @Test public void testMergeOfRangesAndSingleValuesReverse() throws Exception { 327 IntervalSet s = IntervalSet.of(43,65534); 328 s.add(42); 329 s.add(0,41); 330 String expecting = "0..65534"; 331 String result = s.toString(); 332 assertEquals(result, expecting); 333 } 334 335 @Test public void testMergeWhereAdditionMergesTwoExistingIntervals() throws Exception { 336 // 42, 10, {0..9, 11..41, 43..65534} 337 IntervalSet s = IntervalSet.of(42); 338 s.add(10); 339 s.add(0,9); 340 s.add(43,65534); 341 s.add(11,41); 342 String expecting = "0..65534"; 343 String result = s.toString(); 344 assertEquals(result, expecting); 345 } 346 347 @Test public void testMergeWithDoubleOverlap() throws Exception { 348 IntervalSet s = IntervalSet.of(1,10); 349 s.add(20,30); 350 s.add(5,25); // overlaps two! 351 String expecting = "1..30"; 352 String result = s.toString(); 353 assertEquals(result, expecting); 354 } 355 356 @Test public void testSize() throws Exception { 357 IntervalSet s = IntervalSet.of(20,30); 358 s.add(50,55); 359 s.add(5,19); 360 String expecting = "32"; 361 String result = String.valueOf(s.size()); 362 assertEquals(result, expecting); 363 } 364 365 @Test public void testToList() throws Exception { 366 IntervalSet s = IntervalSet.of(20,25); 367 s.add(50,55); 368 s.add(5,5); 369 String expecting = "[5, 20, 21, 22, 23, 24, 25, 50, 51, 52, 53, 54, 55]"; 370 List foo = new ArrayList(); 371 String result = String.valueOf(s.toList()); 372 assertEquals(result, expecting); 373 } 374 375 /** The following was broken: 376 {'\u0000'..'s', 'u'..'\uFFFE'} & {'\u0000'..'q', 's'..'\uFFFE'}= 377 {'\u0000'..'q', 's'}!!!! broken... 378 'q' is 113 ascii 379 'u' is 117 380 */ 381 @Test public void testNotRIntersectionNotT() throws Exception { 382 IntervalSet s = IntervalSet.of(0,'s'); 383 s.add('u',200); 384 IntervalSet s2 = IntervalSet.of(0,'q'); 385 s2.add('s',200); 386 String expecting = "{0..113, 115, 117..200}"; 387 String result = (s.and(s2)).toString(); 388 assertEquals(result, expecting); 389 } 390 391 } 392