From: Stefan F. <ste...@us...> - 2010-03-23 18:46:25
|
Update of /cvsroot/rails/18xx/test In directory sfp-cvsdas-1.v30.ch3.sourceforge.com:/tmp/cvs-serv10916/test Added Files: TestGameBuilder.java test.properties TestGame.java Log Message: Implementation of Rails junit testing. More details see mail to the develop list. --- NEW FILE: TestGameBuilder.java --- package test; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; import java.util.Collections; import java.util.List; import javax.swing.JFileChooser; import javax.swing.JPanel; import javax.swing.filechooser.FileNameExtensionFilter; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import rails.game.Game; import rails.game.ReportBuffer; import rails.util.Config; public final class TestGameBuilder extends TestCase { private static String configFile = "test/test.properties"; private static char extensionSeparator = '.'; private static int maxRecursionLevel = 5; // true = optimal for ant html reports, false = optimal for test runner private static boolean extendedTestNames = true; private static void prepareGameReport(File gameFile, String reportFilename) { Game game = null; if (gameFile.exists()) System.out.println("Found game at " + gameFile.getAbsolutePath()); game = Game.load(gameFile.getAbsolutePath()); if (game != null) { List<String> report = ReportBuffer.getAsList(); PrintWriter reportFile = null; try{ reportFile = new PrintWriter(reportFilename); } catch (IOException e) { System.err.print("Cannot open file " + reportFilename + " to save game report"); } if (reportFile != null) { for (String msg:report){ reportFile.println(msg); } reportFile.close(); System.out.println("Created reportfile at " + reportFilename); } } } // returns gameName if prepararion was successfull private static String prepareTestGame(File gameFile, boolean overrideReport){ // check preconditions if (!gameFile.exists() || !gameFile.isFile()) return null; // check if it is a Rails savefile String fileName = gameFile.getName(); int dot = fileName.lastIndexOf(extensionSeparator); String gameName = null; if (dot != -1 && fileName.substring(dot+1).equals( Config.get("save.filename.extension"))) { gameName = fileName.substring(0,dot); String gamePath = gameFile.getParent(); // check if there is a reportfile String reportFilename = gamePath + File.separator + gameName + "." + Config.get("report.filename.extension"); File reportFile = new File(reportFilename); if (!reportFile.exists() || overrideReport) prepareGameReport(gameFile, reportFilename); } return gameName; } private static TestSuite recursiveTestSuite(String rootPath, String dirPath, int level, boolean overrideReport){ // completeDirPath String combinedDirPath = rootPath + File.separator + dirPath; // assign directory File directory = new File(combinedDirPath); // check if directory exists otherwise return null if (!directory.exists() || !directory.isDirectory()) return null; // create new testsuite TestSuite suite; if (level == 0) suite = new TestSuite("Rails Tests"); else suite = new TestSuite(directory.getName()); // use filelist to sort List<String> filenameList = Arrays.asList(directory.list()); Collections.sort(filenameList); // add deeper directories for (String fn:filenameList) { File f = new File(combinedDirPath + File.separator + fn); String nextDirPath; if (dirPath.equals("")) nextDirPath = f.getName(); else nextDirPath = dirPath + File.separator + f.getName(); if (f.isDirectory() && level <= maxRecursionLevel) { TestSuite newSuite = recursiveTestSuite(rootPath, nextDirPath, level+1, overrideReport); if (newSuite != null) suite.addTest(newSuite); } } // add files of directory for (String fn:filenameList) { File f = new File(combinedDirPath + File.separator + fn); String gameName = prepareTestGame(f, overrideReport); if (gameName != null) { String extendedGameName; if (extendedTestNames) extendedGameName = dirPath + File.separator + gameName; else extendedGameName = gameName; suite.addTest(new TestGame(extendedGameName, rootPath)); System.out.println("Added TestGame "+ extendedGameName); } } return suite; } /** * Builds test suite of all test games below the main test directory * @return created test suite for junit */ public static Test suite() { // Activate logger System.setProperty("log4j.configuration", configFile); /* Tell the properties loader to read this file. */ Config.setConfigFile(configFile); System.out.println("Configuration file = " + configFile); // Main test directory File testDir = new File(Config.get("save.directory")); // Create tests TestSuite suite = null; if (testDir.exists() && testDir.isDirectory()) { System.out.println("Test directory = " + testDir.getAbsolutePath()); suite = recursiveTestSuite(testDir.getAbsolutePath(), "", 0, false); } return suite; } /** * Run main to rebuild the report files. * Only use this if you know what you are doing * * @param args a list of directories below the main test directory */ public static void main(String[] args) { // Activate logger System.setProperty("log4j.configuration", configFile); /* Tell the properties loader to read this file. */ Config.setConfigFile(configFile); System.out.println("Configuration file = " + configFile); // Main test directory String rootPath = Config.get("save.directory"); if (args != null && args.length > 0) { // commandline argument: only directories are possible System.out.println("Number of args: "+ args.length); for (String arg : args) // discard testsuite, only override the report files recursiveTestSuite(rootPath, arg, 0, true); } else { // ask for directories to ovrerride JPanel panel = new JPanel(); JFileChooser chooser = new JFileChooser(); chooser.setDialogTitle("Select directories and/or files to reset game reports"); chooser.setCurrentDirectory(new File(rootPath)); chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); chooser.setMultiSelectionEnabled(true); chooser.setFileFilter(new FileNameExtensionFilter("Rails save files (*.rails)", "rails")); chooser.setAcceptAllFileFilterUsed(false); chooser.showDialog(panel, "Select"); File[] files = chooser.getSelectedFiles(); for (File f : files) if (f.isDirectory()) // discard testsuite, only override the report files recursiveTestSuite(f.getAbsolutePath(), "", 0, true); else if (f.isFile()) prepareTestGame(f, true); } } } --- NEW FILE: TestGame.java --- package test; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import org.apache.log4j.Logger; import rails.game.Game; import rails.game.ReportBuffer; import rails.util.Config; import junit.framework.TestCase; public class TestGame extends TestCase { private String gamePath; private String gameName; private List<String> testReport = null; private List<String> expectedReport = null; protected static Logger log = Logger.getLogger(TestGame.class.getPackage().getName()); public TestGame(String gameName, String gamePath) { super(gameName); this.gameName = gameName; this.gamePath = gamePath; log.debug("Creates TestGame gameName = " + gameName + ", gamePath = " + gamePath); } protected void runTest() throws Throwable { gameReportTest(); } /** * a method that test that the game report is identical to the one created before */ private void gameReportTest() { // compares the two reports line by line int line = 0; while (true) { // test for size of reports if (line >= expectedReport.size()) if (line >= testReport.size()) break; // test succesfull else fail("Test report exceeeds expected report." + " Last line (" + line + "): " + testReport.get(line-1)); else if (line >= testReport.size()) fail("Expected report exceeds test report." + " Last line (" + line + "): " + expectedReport.get(line-1)); assertEquals("Reports differ in line " + line+1, expectedReport.get(line), testReport.get(line)); line = line + 1; } } protected void setUp() throws Exception { super.setUp(); // tries to load the game report String reportFilename = gamePath + File.separator + gameName + "." + Config.get("report.filename.extension"); File reportFile = new File(reportFilename); if (reportFile.exists()) { log.debug("Found reportfile at " + reportFilename); Scanner reportScanner = new Scanner(new FileReader(reportFilename)); expectedReport = new ArrayList<String>(); while (reportScanner.hasNext()) expectedReport.add(reportScanner.nextLine()); reportScanner.close(); } else { log.debug("Did not find reportfile at " + reportFilename); } // tries to load the game and run String gameFilename = gamePath + File.separator + gameName + "." + Config.get("save.filename.extension"); File gameFile = new File(gameFilename); if (gameFile.exists()) { log.debug("Found gamefile at " + gameFilename); Game testGame = Game.load(gameFilename); if (testGame != null) testReport = ReportBuffer.getAsList(); } else { log.error("Did not find gamefile at " + gameFilename); } } protected void tearDown() throws Exception { super.tearDown(); testReport.clear(); expectedReport.clear(); } } --- NEW FILE: test.properties --- ####################### Test preferences ################################ # # Those are the settings used for automated testing # ######################################################################## # # Preferred tile format. # The only currently supported format is svg. Anything else is ignored. #tile.format_preference=svg # Root directory for the tile images (just above directory 'tiles'). # Not required if tile images are provided included in the Rails jar file. #tile.root_directory= ### Locale #### # Language: two-letter ISO code (lower case; default is en=English). # Country: two-letter ISO code (upper case; specifies country # (implying a language variant of that country; no default). # Locale: concatenation of the above. If present, overrides any of the above. # Examples: en, en_US, en_UK, fr_FR, fr_CA. locale=te_st0 #language= #country= ### Money display ### # Each game has a specific format for monetary amounts (e.g. $100, 100M). # An overriding format can be specified here, but then applies to all games. # The @ character must be present and is replaced by the amount. # Example: £@ to specify a pound sign prefix: £100. #money_format=$@ ### Save file directory # If the below entry exists, is not empty, and specifies an existing # directory, that directory is used as a starting point for any # file choosing action for the Save and Load commands. # The path may be relative or absolute. save.directory=test/data # The default Save filename is <gamename>_<datetimepattern>.<extension> # This name will be initially proposed. # As soon as that proposal has been changed once in a Save action, # the last used name is always proposed in stead. # The default date/time pattern is yyyyMMdd_HHmm # The pattern codes are as defined in the Java class # SimpleDateFormat (just Google that name to find the codes). #save.filename.date_time_pattern=yyyyMMdd_HHmm # The default timezone is local time. # A specific timezone (such as UTC) can be set; the value must be a Java timezone ID #save.filename.date_time_zone=UTC # Optionally, a suffix (e.g. player name) can be added after the time stamp # with a preceding underscore (which is automatically added) # The special value NEXT_PLAYER puts the next moving player name into this spot. #save.filename.suffix=NEXT_PLAYER # The default extension is .rails save.filename.extension=rails ### Game report directory # If the below entry exists, is not empty, and specifies an existing # directory, a copy of the Game Report (as displayed in the Report Window) # will be saved there. The path may be relative or absolute. #report.directory=log # The default file name includes the game name and the game start time: # 18XX_yyyymmdd_hhmm.txt where 18XX is the game name. # You can specify different values for the date/time part and teh extension here. # The date/time pattern must be as defined in the Java SimpleDateFormat class. #report.filename.date_time_pattern=yyyyMMdd report.filename.extension=report ### Windows ## Report window visibility # By default the report window is hidden when starting or loading a game. # This property allows to open it automatically. # Valid values are yes and no (default). #report.window.open=yes ## Report window editability # Specify if the report window is editable, so you can add your own comments. # Valid values are yes and no (default). #report.window.editable=yes ## Stock Chart window visibility # By default the stock chart hides at the end of an SR. # By specifying "yes" here, the window will not be automatically hidden any more #stockchart.window.open=yes ### Player info ## Default players # Comma-separated list of player names. # Useful for game testing purposes. #default_players=Alice,Bob,Charlie # ## Local player name # Useful for distributed usage (Internet, PBEM, cloud storage/dropbox) # Required for "request turn" facility with cloud storage (dropbox) #local.player.name=Alice ### Default game # Name of game selected in the game selection window. # Useful for game testing purposes. #default_game=1830 ### Various options # Show simple (ORx) or composite (ORx.x) OR number. # Valid values: "simple" and "composite" (default) #or.number_format=simple ####################### Log4J properties ############################## # For information on how to customise log4j logging, see for instance # http://www.vipan.com/htdocs/log4jhelp.html # It's a bit outdated: Category is now named Logger, # and Priority is now named Level. # But it's the best intro I know on how to configure Appenders. (EV) ####################################################################### # Set root logger level to DEBUG and use appender F(file) #log4j.debug=true log4j.rootLogger=DEBUG, F # Define the Log file appender log4j.appender.F=org.apache.log4j.FileAppender # Log file properties log4j.appender.F.File=test/test.log log4j.appender.F.append=false # Log file layout log4j.appender.F.layout=org.apache.log4j.PatternLayout log4j.appender.F.layout.ConversionPattern=%-5p %m%n ################## End of Log4J properties ############################# |