View Javadoc

1   package net.sourceforge.pmd.properties;
2   
3   import static org.junit.Assert.assertNotNull;
4   import static org.junit.Assert.assertNull;
5   import static org.junit.Assert.assertTrue;
6   import junit.framework.Assert;
7   import net.sourceforge.pmd.PropertyDescriptor;
8   import net.sourceforge.pmd.util.CollectionUtil;
9   
10  import org.junit.Test;
11  
12  /**
13   * Base functionality for all concrete subclasses that evaluate type-specific property descriptors.
14   * Checks for error conditions during construction, error value detection, serialization, etc. 
15   *  
16   * @author Brian Remedios
17   */
18  public abstract class AbstractPropertyDescriptorTester {
19  
20  	private static final int multiValueCount = 10;
21  	
22  	public static final String punctuationChars  = "!@#$%^&*()_-+=[]{}\\|;:'\",.<>/?`~";
23  	public static final String whitespaceChars   = " \t\n";
24  	public static final String digitChars 		 = "0123456789";
25  	public static final String alphaChars 		 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmniopqrstuvwxyz";
26  	public static final String alphaNumericChars = digitChars + alphaChars;
27  	public static final String allChars			 = punctuationChars + whitespaceChars + alphaNumericChars;
28  
29  	
30  	/**
31  	 * Return a legal value(s) per the general scope of the descriptor.
32  	 * 
33  	 * @param count int
34  	 * @return Object
35  	 */
36  	protected abstract Object createValue(int count);
37  	
38  	/**
39  	 * Return a value(s) that is known to be faulty per the general scope of the descriptor.
40  	 * 
41  	 * @param count int
42  	 * @return Object
43  	 */
44  	protected abstract Object createBadValue(int count);
45  	
46  	/**
47  	 * Creates and returns a properly configured property descriptor.
48  	 * 
49  	 * @param multiValue boolean
50  	 * @return PropertyDescriptor
51  	 */
52  	protected abstract PropertyDescriptor createProperty(boolean multiValue);
53  	
54  	/**
55  	 * Attempt to create a property with faulty configuration values. This method
56  	 * should throw an IllegalArgumentException if done correctly.
57  	 * 
58  	 * @param multiValue boolean
59  	 * @return PropertyDescriptor
60  	 */
61  	protected abstract PropertyDescriptor createBadProperty(boolean multiValue);
62  	
63  	@Test
64  	public void testConstructors() {
65  		
66  		PropertyDescriptor<?> desc = createProperty(false);
67  		assertNotNull(desc);
68  
69  		try {
70  			createBadProperty(false);
71  
72  		} catch (Exception ex) {
73  			return;	// caught ok
74  		}
75  
76  		Assert.fail("uncaught constructor exception");
77  	}
78  
79      @Test
80      public void testAsDelimitedString() {
81  
82  		Object testValue = createValue(multiValueCount);
83  		PropertyDescriptor pmdProp = createProperty(true);
84  
85  		String storeValue = pmdProp.asDelimitedString(testValue);
86  
87  		Object returnedValue = pmdProp.valueFrom(storeValue);
88  
89  		assertTrue(CollectionUtil.areEqual(returnedValue, testValue));
90  	}
91  
92      @Test
93      public void testValueFrom() {
94  
95  		Object testValue = createValue(1);
96  		PropertyDescriptor pmdProp = createProperty(false);
97  
98  		String storeValue = pmdProp.asDelimitedString(testValue);
99  
100 		Object returnedValue = pmdProp.valueFrom(storeValue);
101 
102 		assertTrue(CollectionUtil.areEqual(returnedValue, testValue));
103 	}
104 	
105 	
106     @Test
107     public void testErrorFor() {
108 
109 		Object testValue = createValue(1);
110 		PropertyDescriptor<?> pmdProp = createProperty(false);		// plain vanilla property & valid test value
111 		String errorMsg = pmdProp.errorFor(testValue);
112 		assertNull(errorMsg, errorMsg);			
113 
114 		testValue = createValue(multiValueCount);				// multi-value property, all valid test values
115 		pmdProp = createProperty(true);
116 		errorMsg = pmdProp.errorFor(testValue);
117 		assertNull(errorMsg, errorMsg);
118 
119     }
120     
121     @Test
122     public void testErrorForBad() {
123 
124     	PropertyDescriptor<?> pmdProp = createProperty(false);    	
125 		Object testValue = createBadValue(1);
126 		String errorMsg = pmdProp.errorFor(testValue);			// bad value should result in an error
127 		if (errorMsg == null) {
128 			Assert.fail("uncaught bad value: " + testValue);
129 		}
130 
131 		testValue = createBadValue(multiValueCount);			// multi-value prop, several bad values
132 		pmdProp = createProperty(true);
133 		errorMsg = pmdProp.errorFor(testValue);
134 		if (errorMsg == null) {
135 			Assert.fail("uncaught bad value in: " + testValue);
136 		}
137 	}
138 
139     @Test
140     public void testType() {
141 
142 		PropertyDescriptor<?> pmdProp = createProperty(false);
143 
144 		assertNotNull(pmdProp.type());
145 	}
146 
147     public static boolean randomBool() {
148     	return ((Math.random() * 100) % 2) == 0;
149     }
150 
151 	/**
152 	 * Method randomInt.
153 	 * @return int
154 	 */
155 	public static int randomInt() {
156 
157 		int randomVal = (int) (Math.random() * 100 + 1D);
158 		return randomVal + (int) (Math.random() * 100000D);
159 	}
160 
161 	/**
162 	 * Method randomInt.
163 	 * @param min int
164 	 * @param max int
165 	 * @return int
166 	 */
167 	public static int randomInt(int min, int max) {
168 		if (max < min) max = min;
169 		int range = Math.abs(max - min);
170 		int x = (int) (range * Math.random());
171 		return x + min;
172 	}
173 	
174 	public static String randomString(int length) {
175 		
176 		final char[] chars = alphaChars.toCharArray();
177 		
178 		StringBuilder sb = new StringBuilder(length);
179 		for (int i=0; i<length; i++) sb.append(randomChar(chars));
180 		return sb.toString();
181 	}
182 	
183 	/**
184 	 * Method randomFloat.
185 	 * @param min float
186 	 * @param max float
187 	 * @return float
188 	 */
189 	public static float randomFloat(float min, float max) {
190 		
191 		return (float)randomDouble(min, max);
192 	}
193 	
194 	/**
195 	 * Method randomDouble.
196 	 * @param min double
197 	 * @param max double
198 	 * @return double
199 	 */
200 	public static double randomDouble(double min, double max) {
201 		if (max < min) max = min;
202 		double range = Math.abs(max - min);
203 		double x = range * Math.random();
204 		return x + min;
205 	}
206 	
207 	/**
208 	 * Method randomChar.
209 	 * @param characters char[]
210 	 * @return char
211 	 */
212 	public static char randomChar(char[] characters) {
213 		return characters[randomInt(0, characters.length-1)];
214 	}
215 	
216 	/**
217 	 * Method randomChoice.
218 	 * @param items Object[]
219 	 * @return Object
220 	 */
221 	public static Object randomChoice(Object[] items) {
222 		return items[randomInt(0, items.length-1)];
223 	}
224 	
225 	/**
226 	 * Method filter.
227 	 * @param chars char[]
228 	 * @param removeChar char
229 	 * @return char[]
230 	 */
231 	protected static final char[] filter(char[] chars, char removeChar) {
232 		int count = 0;
233 		for (int i=0; i<chars.length; i++) if (chars[i] == removeChar) count++;
234 		char[] results = new char[chars.length - count];
235 		
236 		int index = 0;
237 		for (int i=0; i<chars.length; i++) {
238 			if (chars[i] != removeChar) results[index++] = chars[i];		
239 		}
240 		return results;
241 	}
242 }