/** * Test that all of the methods in the tested class have at least some testing methods for them. */ public void testAllMethodsBeingTested() { Method[] methods = testedClass.getDeclaredMethods(); SortedSet<String> missingMethods = new TreeSet<String>(); for (Method m : methods) { String methodName = m.getName(); if (!Modifier.isPublic(m.getModifiers())) { continue; } if (methodName.startsWith("_")) { continue; } String testMethodName = "test" + Strings.upperCaseFirst(methodName); boolean found = false; Method[] testMethods = getClass().getMethods(); for (Method testMethod : testMethods) { if (testMethod.getName().startsWith(testMethodName)) { found = true; break; } } if (!found) { missingMethods.add(methodName); } } String missing = Strings.join(String.valueOf(COMMA) + SPACE, missingMethods); assertTrue("Missing test methods for: " + missing, missingMethods.isEmpty()); }
/** * Initialisation routine to get the options Map synced up with the .properties file which defines * the legal options and their values. To avoid having to throw exceptions for nearly every method * this routine guarantees that the options stash will be initialised, however it does NOT * guarantee that there will be anything in it. */ private static void init() { // Make sure this only really runs if needed. if (options != null && !options.isEmpty()) { return; } Log.debug(Message.OPTIONS_INITIALISING()); // The store for the options stash Map<String, Option<?>> initOptions = new HashMap<String, Option<?>>(); // Load the options definitions from the properties file. Map<String, String> optionsDefinitions = Resources.get(Options.class); // Get the option names Set<String> optionNames = new HashSet<String>(); for (String optionProp : optionsDefinitions.keySet()) { optionNames.add(optionProp.substring(0, optionProp.indexOf((int) FULL_STOP))); } // Go through the options by name and create Option objects for each of // them. Then store the Option objects in the stash. for (String optionName : optionNames) { // Get the type of the option String optionType = optionsDefinitions.get(Strings.join(FULL_STOP, optionName, TYPE_PROPERTY)); // Get the description of the option String optionDesc = optionsDefinitions.get(Strings.join(FULL_STOP, optionName, DESCRIPTION_PROPERTY)); // Get the default value(s) for the option String optionDefault = optionsDefinitions.get(Strings.join(FULL_STOP, optionName, DEFAULT_PROPERTY)); // Find out if the option is mandatory or not. boolean optionMandatory = Resources.getBoolean( Options.class, Strings.join(FULL_STOP, optionName, MANDATORY_PROPERTY), false); // Find out if the option takes multiple values or not boolean optionMultiValue = Resources.getBoolean( Options.class, Strings.join(FULL_STOP, optionName, MULTIVALUE_PROPERTY), false); // Find out if the option is case sensitive or not. boolean optionCaseSensitive = Resources.getBoolean( Options.class, Strings.join(FULL_STOP, optionName, CASESENSITIVE_PROPERTY), true); Option<?> newOption = null; if (optionType.equalsIgnoreCase(ENUM)) { // If the Enum is set from a method this is set with the name // of the method and its non-null status is used as a flag to // indicate the fact that the Enum is dynamic. String dynamicMethod = null; // Get the allowed values Map<String, String> allowedValues; allowedValues = new HashMap<String, String>(); for (String entry : optionsDefinitions.keySet()) { String prefix = Strings.join(FULL_STOP, optionName, VALUE_PROPERTY); if (entry.startsWith(prefix)) { if (entry.equals(prefix)) { // This is a dynamically set method dynamicMethod = optionsDefinitions.get(entry); } else { // Get the value String entryValue = optionsDefinitions.get(entry); entry = entry.substring(prefix.length() + 1); allowedValues.put(entry, entryValue); } } } if (dynamicMethod != null) { if (allowedValues.isEmpty()) { String dynamicMethodClass = dynamicMethod.substring(0, dynamicMethod.lastIndexOf((int) FULL_STOP)); String dynamicMethodMethod = dynamicMethod.substring(dynamicMethodClass.length() + 1); try { // Get the class and method to call to get the // values Class<?> dMClass; dMClass = Class.forName(dynamicMethodClass); Method dMMethod = dMClass.getMethod(dynamicMethodMethod, (Class<?>[]) null); // Ensure the method is public static int modifiers = dMMethod.getModifiers(); DBC.ASSERT(Modifier.isPublic(modifiers)); DBC.ASSERT(Modifier.isStatic(modifiers)); // Ensure the method returns a SortedMap DBC.ASSERT(SortedMap.class.equals(dMMethod.getReturnType())); // Ensure that the method requires no parameters. DBC.ASSERT(dMMethod.getParameterTypes().length == 0); // Now call the method try { SortedMap<?, ?> dynValues; dynValues = SortedMap.class.cast(dMMethod.invoke(null)); for (Object key : dynValues.keySet()) { allowedValues.put(key.toString(), dynValues.get(key).toString()); } } catch (IllegalAccessException e) { DBC.IGNORED_EXCEPTION(e); DBC.UNREACHABLE_CODE(); } catch (InvocationTargetException e) { DBC.IGNORED_EXCEPTION(e); DBC.UNREACHABLE_CODE(); } } catch (ClassNotFoundException e) { DBC.IGNORED_EXCEPTION(e); } catch (NoSuchMethodException e) { DBC.IGNORED_EXCEPTION(e); } } else { // Should never get here. DBC.UNREACHABLE_CODE(); } } // Get the default values Set<String> defaultValues = null; if (optionDefault != null) { String[] defVal = optionDefault.split(String.valueOf(COMMA)); defaultValues = new HashSet<String>(defVal.length, 1.0f); for (String defValue : defVal) { if (allowedValues.containsKey(defValue)) { defaultValues.add(defValue); } } } // Create the Enum newOption = new Enum( optionName, optionDesc, allowedValues, optionMandatory, optionMultiValue, optionCaseSensitive, defaultValues); } else if (optionType.equalsIgnoreCase(SWITCH)) { // Convert the default value to a boolean boolean defaultValue = Boolean.valueOf(optionDefault); // Create the new Switch newOption = new Switch(optionName, optionDesc, defaultValue); } else if (optionType.equalsIgnoreCase(ARGUMENT)) { // Create the new Argument newOption = new Argument( optionName, optionDesc, optionMandatory, optionCaseSensitive, optionDefault); } if (newOption != null) { initOptions.put(optionName, newOption); } } // Make the option stash creation an "almost atomic" operation. options = initOptions; }