Java tutorial
/* * Copyright (C) 1995-2016Dal Solutions, Inc. * All Rights Reserved * Inquire at License@dal-solutions.com */ package com.dal.unity; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import com.dal.unity.test.TestType; import com.github.javaparser.ast.ImportDeclaration; import com.github.javaparser.ast.expr.NameExpr; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.DefaultParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.MissingOptionException; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author Dan Adams */ public class Config { private static final Logger LOG = LoggerFactory.getLogger(Config.class); private final Properties fileProperties = new Properties(); private File sinkFile; private File sourceFile; private File targetFile; private Map<String, String> javaOptions; private String classPath; private String methodSuffix; private String sink; private String source; private String target; private String testSuffix; private boolean compile = false; private boolean maxTests = true; private boolean minTests = true; private boolean nullTests = true; private boolean recursive = true; private boolean regression = false; private static final Config INSTANCE = new Config(); private static final String DEFAULT_CLASSPATH = ".\\target\\classes"; private static final String PROPERTIES_FILE = "Unity.properties"; private static final String DEFAULT_SINK = ".\\src\\test\\java"; private static final String DEFAULT_SOURCE = ".\\src\\main\\java"; private static final String DEFAULT_TARGET = ".\\target\\classes"; private static final String DEFAULT_TEST_FILE_SUFFIX = "UnityTest"; private static final String DEFAULT_TEST_METHOD_SUFFIX = "UTest"; private static final String FLAG_CLASSPATH_FILE = "p"; private static final String FLAG_COMPILE = "c"; private static final String FLAG_HELP = "h"; private static final String FLAG_OPTIONS_COMPILER = "D"; private static final String FLAG_RECURSION = "r"; private static final String FLAG_REGRESSION = "R"; private static final String FLAG_SINK = "k"; private static final String FLAG_SOURCE = "s"; private static final String FLAG_FILE_SUFFIX = "T"; private static final String FLAG_METHOD_SUFFIX = "t"; private static final String FLAG_TARGET = "d"; private static final String FLAG_TESTS_NULL = "n"; private static final String FLAG_VALUES_MAX = "M"; private static final String FLAG_VALUES_MIN = "m"; private static final String MAJOR_VERSION = "1"; private static final String MINOR_VERSION = "0"; private static final String BUG_VERSION = "0"; private static final ImportDeclaration[] DEFAULT_IMPORTS = new ImportDeclaration[] { new ImportDeclaration(new NameExpr("org.junit.After"), false, false), new ImportDeclaration(new NameExpr("org.junit.AfterClass"), false, false), new ImportDeclaration(new NameExpr("org.junit.Before"), false, false), new ImportDeclaration(new NameExpr("org.junit.BeforeClass"), false, false), new ImportDeclaration(new NameExpr("org.junit.Test"), false, false), new ImportDeclaration(new NameExpr("org.junit.Assert"), true, true) }; private Config() { InputStream propertiesFile = Config.class.getClassLoader().getResourceAsStream(PROPERTIES_FILE); try { fileProperties.load(propertiesFile); } catch (IOException ex) { LOG.warn("Unable to read properties file", ex); } } public static Config get() { return INSTANCE; } public String getTestMethodSuffix() { return methodSuffix; } @SuppressWarnings("unchecked") void set(String[] args) { CommandLineParser parser; @SuppressWarnings("UnusedAssignment") CommandLine cmd = null; try { parser = new DefaultParser(); try { cmd = parser.parse(getOptions(), args); } catch (MissingOptionException x) { System.out.println(x.getMessage()); HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("unity", getOptions()); System.exit(-20); } if (cmd.hasOption(FLAG_HELP)) { // automatically generate the help statement HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("unity", getOptions()); System.exit(0); } if (cmd.hasOption(FLAG_CLASSPATH_FILE)) { classPath = readClasspath(cmd.getOptionValue(FLAG_CLASSPATH_FILE)); } else { classPath = DEFAULT_CLASSPATH; } if (cmd.hasOption(FLAG_COMPILE)) { compile = true; } if (cmd.hasOption(FLAG_VALUES_MAX)) { maxTests = true; } if (cmd.hasOption(FLAG_VALUES_MIN)) { minTests = true; } if (cmd.hasOption(FLAG_TESTS_NULL)) { nullTests = true; } if (cmd.hasOption(FLAG_RECURSION)) { recursive = true; } if (cmd.hasOption(FLAG_REGRESSION)) { regression = true; } if (cmd.hasOption(FLAG_SOURCE)) { source = cmd.getOptionValue(FLAG_SOURCE); } else { source = DEFAULT_SOURCE; } sourceFile = new File(source); if (cmd.hasOption(FLAG_TARGET)) { target = cmd.getOptionValue(FLAG_TARGET); } targetFile = new File(target); classPath += File.pathSeparator + target + File.pathSeparator + DEFAULT_TARGET; if (cmd.hasOption(FLAG_SINK)) { sink = cmd.getOptionValue(FLAG_SINK); } else { sink = DEFAULT_SINK; } sinkFile = new File(sink); if (cmd.hasOption(FLAG_OPTIONS_COMPILER)) { Object result = cmd.getParsedOptionValue(FLAG_OPTIONS_COMPILER); if (result instanceof Map) { javaOptions = (Map<String, String>) result; } else { throw new ParseException("Java Options is not MAP, parsed to " + result.getClass().getName()); } } if (cmd.hasOption(FLAG_FILE_SUFFIX)) { testSuffix = cmd.getOptionValue(FLAG_FILE_SUFFIX); } else { testSuffix = DEFAULT_TEST_FILE_SUFFIX; } if (cmd.hasOption(FLAG_METHOD_SUFFIX)) { methodSuffix = cmd.getOptionValue(FLAG_METHOD_SUFFIX); } else { methodSuffix = DEFAULT_TEST_METHOD_SUFFIX; } } catch (ParseException x) { LOG.error("Parsing failed: {}", x, x); System.err.println("Parsing failed. Reason: " + x.getMessage()); HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("ant", getOptions()); System.exit(-1); } } public Map<String, String> getJavaOptions() { return Collections.unmodifiableMap(javaOptions); } public boolean isRecursive() { return recursive; } public boolean isRegression() { return regression; } public boolean isNullTests() { return nullTests; } public boolean isMaxTests() { return maxTests; } public boolean isMinTests() { return minTests; } public boolean isCompile() { return compile; } public String getSource() { return source; } public String getSink() { return sink; } public String getTarget() { return target; } public String getVersion() { return MAJOR_VERSION + "." + MINOR_VERSION + "." + BUG_VERSION; } public List<ImportDeclaration> getDefaultImports() { return Arrays.asList(DEFAULT_IMPORTS); } public String getClassPath() { return classPath; } public File getSourceFile() { return sourceFile; } public File getSinkFile() { return sinkFile; } public File getTargetFile() { return targetFile; } public String getTestSuffix() { return testSuffix; } public Set<TestType> getTestTypes() { Set<TestType> result = EnumSet.allOf(TestType.class); if (!maxTests) { result.remove(TestType.Max); } if (!minTests) { result.remove(TestType.Min); } if (!nullTests) { result.remove(TestType.Nulls); } return result; } private Options getOptions() { Options ops = new Options(); Option compileOpt = new Option(FLAG_COMPILE, "compile", false, "Compile source files and ignore any current class files."); Option maxOpt = new Option(FLAG_VALUES_MAX, "max", false, "Generate max value tests."); Option minOpt = new Option(FLAG_VALUES_MIN, "min", false, "Generate min value tests."); Option nullOpt = new Option(FLAG_TESTS_NULL, "null", false, "Generate null tests."); Option recurseOpt = new Option(FLAG_RECURSION, "recurse", false, "Process files recursively from initial source."); Option regressionOpt = new Option(FLAG_REGRESSION, "regress", false, "Produce regression tests based on current behavior."); Option helpOpt = new Option(FLAG_HELP, "help", false, "Prints this help information."); Option classpathOpt = Option.builder(FLAG_CLASSPATH_FILE).longOpt("classpath").hasArg().argName("file") .desc("File that contains additional class path entries, used if compiling. File will have all lines concatonated with a path seperator between each.") .build(); Option javaOpts = Option.builder(FLAG_OPTIONS_COMPILER).hasArgs().valueSeparator().argName("property=value") .type((Class<? super Map<String, String>>) Map.class) .desc("Additional command line arguments to pass to the compiler.").build(); Option sourceOpt = Option.builder(FLAG_SOURCE).longOpt("sourcepath").hasArg().argName("source") .desc("Source file/directory to process.").build(); Option sinkOpt = Option.builder(FLAG_SINK).longOpt("sink").hasArg().argName("sink") .desc("Location where the generated unit test files are written.").build(); Option targetOpt = Option.builder(FLAG_TARGET).longOpt("target").hasArg().argName("target") .desc("Location where the compiled classes are written, if compile is choosen").build(); Option suffixOpt = Option.builder(FLAG_FILE_SUFFIX).longOpt("testSuffix").hasArg().argName("suffix") .desc("Suffix for the generated test file (text before .java)").build(); Option methodOpt = Option.builder(FLAG_METHOD_SUFFIX).longOpt("methodSuffix").hasArg().argName("suffix") .desc("Suffix added to each test method").build(); ops.addOption(compileOpt); ops.addOption(maxOpt); ops.addOption(minOpt); ops.addOption(nullOpt); ops.addOption(recurseOpt); ops.addOption(regressionOpt); ops.addOption(classpathOpt); ops.addOption(javaOpts); ops.addOption(targetOpt); ops.addOption(methodOpt); ops.addOption(sinkOpt); ops.addOption(sourceOpt); ops.addOption(suffixOpt); ops.addOption(helpOpt); return ops; } private String readClasspath(String classpathFile) { StringBuilder result = new StringBuilder(128); try (InputStream is = Config.class.getClassLoader().getResourceAsStream(classpathFile); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr);) { String line; while (null != (line = br.readLine())) { if (result.length() > 0 && File.pathSeparatorChar != result.charAt(result.length() - 1)) { result.append(File.pathSeparatorChar); } result.append(line); } } catch (IOException x) { LOG.error("Failure attempting to read classpath file {}", classpathFile, x); } return result.toString(); } }