CheckIndex.java revision 12857:ecfc81a3741c
1/* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/** 25 * @test 26 * @summary IndexOutOfBoundsException check index tests 27 * @run testng CheckIndex 28 * @bug 8135248 29 */ 30 31import org.testng.annotations.DataProvider; 32import org.testng.annotations.Test; 33 34import java.util.ArrayList; 35import java.util.List; 36import java.util.Objects; 37import java.util.function.BiConsumer; 38import java.util.function.BiFunction; 39import java.util.function.IntSupplier; 40 41import static org.testng.Assert.*; 42 43public class CheckIndex { 44 45 static class AssertingOutOfBoundsException extends RuntimeException { 46 } 47 48 static BiFunction<Integer, Integer, AssertingOutOfBoundsException> assertingOutOfBounds( 49 int expFromIndex, int expToIndexOrSizeOrLength) { 50 return (fromIndex, toIndexOrSizeorLength) -> { 51 assertEquals(fromIndex, Integer.valueOf(expFromIndex)); 52 assertEquals(toIndexOrSizeorLength, Integer.valueOf(expToIndexOrSizeOrLength)); 53 return new AssertingOutOfBoundsException(); 54 }; 55 } 56 57 static final int[] VALUES = {0, 1, Integer.MAX_VALUE - 1, Integer.MAX_VALUE, -1, Integer.MIN_VALUE + 1, Integer.MIN_VALUE}; 58 59 @DataProvider 60 static Object[][] checkIndexProvider() { 61 List<Object[]> l = new ArrayList<>(); 62 for (int index : VALUES) { 63 for (int length : VALUES) { 64 boolean withinBounds = index >= 0 && 65 length >= 0 && 66 index < length; 67 l.add(new Object[]{index, length, withinBounds}); 68 } 69 } 70 return l.toArray(new Object[0][0]); 71 } 72 73 interface X { 74 int apply(int a, int b, int c); 75 } 76 77 @Test(dataProvider = "checkIndexProvider") 78 public void testCheckIndex(int index, int length, boolean withinBounds) { 79 BiConsumer<Class<? extends RuntimeException>, IntSupplier> check = (ec, s) -> { 80 try { 81 int rIndex = s.getAsInt(); 82 if (!withinBounds) 83 fail(String.format( 84 "Index %d is out of bounds of [0, %d), but was reported to be within bounds", index, length)); 85 assertEquals(rIndex, index); 86 } 87 catch (RuntimeException e) { 88 assertTrue(ec.isInstance(e)); 89 if (withinBounds) 90 fail(String.format( 91 "Index %d is within bounds of [0, %d), but was reported to be out of bounds", index, length)); 92 } 93 }; 94 95 check.accept(AssertingOutOfBoundsException.class, 96 () -> Objects.checkIndex(index, length, assertingOutOfBounds(index, length))); 97 check.accept(IndexOutOfBoundsException.class, 98 () -> Objects.checkIndex(index, length, null)); 99 check.accept(IndexOutOfBoundsException.class, 100 () -> Objects.checkIndex(index, length)); 101 } 102 103 104 @DataProvider 105 static Object[][] checkFromToIndexProvider() { 106 List<Object[]> l = new ArrayList<>(); 107 for (int fromIndex : VALUES) { 108 for (int toIndex : VALUES) { 109 for (int length : VALUES) { 110 boolean withinBounds = fromIndex >= 0 && 111 toIndex >= 0 && 112 length >= 0 && 113 fromIndex <= toIndex && 114 toIndex <= length; 115 l.add(new Object[]{fromIndex, toIndex, length, withinBounds}); 116 } 117 } 118 } 119 return l.toArray(new Object[0][0]); 120 } 121 122 @Test(dataProvider = "checkFromToIndexProvider") 123 public void testCheckFromToIndex(int fromIndex, int toIndex, int length, boolean withinBounds) { 124 BiConsumer<Class<? extends RuntimeException>, IntSupplier> check = (ec, s) -> { 125 try { 126 int rIndex = s.getAsInt(); 127 if (!withinBounds) 128 fail(String.format( 129 "Range [%d, %d) is out of bounds of [0, %d), but was reported to be withing bounds", fromIndex, toIndex, length)); 130 assertEquals(rIndex, fromIndex); 131 } 132 catch (RuntimeException e) { 133 assertTrue(ec.isInstance(e)); 134 if (withinBounds) 135 fail(String.format( 136 "Range [%d, %d) is within bounds of [0, %d), but was reported to be out of bounds", fromIndex, toIndex, length)); 137 } 138 }; 139 140 check.accept(AssertingOutOfBoundsException.class, 141 () -> Objects.checkFromToIndex(fromIndex, toIndex, length, assertingOutOfBounds(fromIndex, toIndex))); 142 check.accept(IndexOutOfBoundsException.class, 143 () -> Objects.checkFromToIndex(fromIndex, toIndex, length, null)); 144 check.accept(IndexOutOfBoundsException.class, 145 () -> Objects.checkFromToIndex(fromIndex, toIndex, length)); 146 } 147 148 149 @DataProvider 150 static Object[][] checkFromIndexSizeProvider() { 151 List<Object[]> l = new ArrayList<>(); 152 for (int fromIndex : VALUES) { 153 for (int size : VALUES) { 154 for (int length : VALUES) { 155 // Explicitly convert to long 156 long lFromIndex = fromIndex; 157 long lSize = size; 158 long lLength = length; 159 // Avoid overflow 160 long lToIndex = lFromIndex + lSize; 161 162 boolean withinBounds = lFromIndex >= 0L && 163 lSize >= 0L && 164 lLength >= 0L && 165 lFromIndex <= lToIndex && 166 lToIndex <= lLength; 167 l.add(new Object[]{fromIndex, size, length, withinBounds}); 168 } 169 } 170 } 171 return l.toArray(new Object[0][0]); 172 } 173 174 @Test(dataProvider = "checkFromIndexSizeProvider") 175 public void testCheckFromIndexSize(int fromIndex, int size, int length, boolean withinBounds) { 176 BiConsumer<Class<? extends RuntimeException>, IntSupplier> check = (ec, s) -> { 177 try { 178 int rIndex = s.getAsInt(); 179 if (!withinBounds) 180 fail(String.format( 181 "Range [%d, %d + %d) is out of bounds of [0, %d), but was reported to be withing bounds", fromIndex, fromIndex, size, length)); 182 assertEquals(rIndex, fromIndex); 183 } 184 catch (RuntimeException e) { 185 assertTrue(ec.isInstance(e)); 186 if (withinBounds) 187 fail(String.format( 188 "Range [%d, %d + %d) is within bounds of [0, %d), but was reported to be out of bounds", fromIndex, fromIndex, size, length)); 189 } 190 }; 191 192 check.accept(AssertingOutOfBoundsException.class, 193 () -> Objects.checkFromIndexSize(fromIndex, size, length, assertingOutOfBounds(fromIndex, size))); 194 check.accept(IndexOutOfBoundsException.class, 195 () -> Objects.checkFromIndexSize(fromIndex, size, length, null)); 196 check.accept(IndexOutOfBoundsException.class, 197 () -> Objects.checkFromIndexSize(fromIndex, size, length)); 198 } 199 200 @Test 201 public void checkIndexOutOfBoundsExceptionConstructors() { 202 BiConsumer<Class<? extends RuntimeException>, IntSupplier> check = (ec, s) -> { 203 try { 204 s.getAsInt(); 205 fail("Runtime exception expected"); 206 } 207 catch (RuntimeException e) { 208 assertTrue(ec.isInstance(e)); 209 } 210 }; 211 212 check.accept(IndexOutOfBoundsException.class, 213 () -> Objects.checkIndex(1, 0, IndexOutOfBoundsException::new)); 214 check.accept(StringIndexOutOfBoundsException.class, 215 () -> Objects.checkIndex(1, 0, StringIndexOutOfBoundsException::new)); 216 check.accept(ArrayIndexOutOfBoundsException.class, 217 () -> Objects.checkIndex(1, 0, ArrayIndexOutOfBoundsException::new)); 218 } 219} 220