/* * DataTest.java * Copyright James Dempsey, 2013 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Created on 07/04/2013 9:02:42 AM * * $Id$ */ package pcgen.persistence.lst; import static org.junit.Assert.assertEquals; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.SystemUtils; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import pcgen.cdom.enumeration.ListKey; import pcgen.core.Campaign; import pcgen.core.Globals; import pcgen.persistence.CampaignFileLoader; import pcgen.persistence.GameModeFileLoader; import pcgen.persistence.lst.utils.VariableReport; import pcgen.persistence.lst.utils.VariableReport.ReportFormat; import pcgen.system.ConfigurationSettings; import pcgen.system.Main; import pcgen.system.PCGenTask; import pcgen.system.PropertyContextFactory; import pcgen.util.Logging; import pcgen.util.TestHelper; /** * The Class <code>DataTest</code> checks the data files for known issues. * * <br/> * * @author James Dempsey <jdempsey@users.sourceforge.net> */ public class DataTest { /** The name of our dummy config file. */ private static final String TEST_CONFIG_FILE = "config.ini.junit"; /** * Initialise the plugins and load the game mode and campaign files. */ @BeforeClass public static void onceOnly() { loadGameModes(); } /** * Tidy up the config file we created. */ @AfterClass public static void afterClass() { new File(TEST_CONFIG_FILE).delete(); } /** * Check the data for files with extraordinarily long path names. The files * as at the time of writing are grandfathered in, but any new data files * with path names longer than 150 characters will be flagged. */ @Test public void pathLengthTest() { String dataPath = ConfigurationSettings.getPccFilesDir(); System.out.println("Got datapath of " + new File(dataPath).getAbsolutePath()); Set<String> allowedNames = new HashSet<>(Arrays.asList( "cotct_pg_abilities_pfrpg.lst", "fortress_of_the_stone_giants_pfrpg.pcc", "rise_of_the_runelords_players_guide_pfrpg.pcc")); List<File> newLongPaths = new ArrayList<>(); int dataPathLen = new File(dataPath).getAbsolutePath().length(); List<String> longPaths = new ArrayList<>(); File dataFolder = new File(dataPath); Collection<File> listFiles = FileUtils.listFiles(dataFolder, new String[]{"pcc", "lst"}, true); for (File file : listFiles) { String path = file.getAbsolutePath(); int pathLen = path.length() - dataPathLen; if (pathLen > 150) { longPaths.add(pathLen + " .. " + path.substring(dataPathLen)); if (!allowedNames.contains(file.getName())) { newLongPaths.add(file); } } } // Output the list Collections.sort(longPaths); for (String msg : longPaths) { System.out.println(msg); } // Flag any change for the worse. assertEquals( "New data file(s) with name longer than 150 characters detected.", "[]", newLongPaths.toString()); } /** * Produce the variable report in html and csv formats. * @throws Exception if the report fails. */ @Test public void produceVariableReport() throws Exception { Map<ReportFormat, String> reportNameMap = new HashMap<>(); reportNameMap.put(ReportFormat.HTML, "variable_report.html"); reportNameMap.put(ReportFormat.CSV, "variable_report.csv"); VariableReport vReport = new VariableReport(); vReport.runReport(reportNameMap); for (Entry<ReportFormat, String> repType : reportNameMap.entrySet()) { System.out.println("Variable report in " + repType.getKey() + " format output to " + new File(repType.getValue()).getAbsolutePath()); } } /** * Scan for any campaigns referring to missing data files. * @throws IOException If the data path cannot be found. */ @Test public void missingFilesTest() throws IOException { File dataFolder = new File(ConfigurationSettings.getPccFilesDir()); int dataPathLen = dataFolder.getCanonicalPath().length(); List<Object[]> missingLstFiles = new ArrayList<>(); for (Campaign campaign : Globals.getCampaignList()) { List<CampaignSourceEntry> cseList = getLstFilesForCampaign(campaign); for (CampaignSourceEntry cse : cseList) { File lstFile = new File(cse.getURI()); if (!lstFile.exists()) { missingLstFiles.add(new Object[]{campaign, lstFile}); } } } StringBuilder report = new StringBuilder(); for (Object[] missing : missingLstFiles) { report.append("Missing file "); report.append(((File)missing[1]).getPath().substring(dataPathLen+1)); report.append(" used by "); report.append((new File(((Campaign) missing[0]).getSourceURI())).getPath().substring(dataPathLen+1)); report.append("<br>\r\n"); } // Flag any missing files assertEquals( "Some data files are missing.", "", report.toString()); } /** * Scan for any data files that are not referred to by any campaign. * This test should be activated once DATA-1039 has been actioned. * @throws IOException If a file path cannot be converted. */ @Test public void orphanFilesTest() throws IOException { File dataFolder = new File(ConfigurationSettings.getPccFilesDir()); Collection<File> listFiles = FileUtils.listFiles(dataFolder, new String[]{"lst"}, true); List<String> fileNames = new ArrayList<>(listFiles.size()); for (File file : listFiles) { fileNames.add(file.getCanonicalPath()); } int dataPathLen = dataFolder.getCanonicalPath().length(); for (Campaign campaign : Globals.getCampaignList()) { List<CampaignSourceEntry> cseList = getLstFilesForCampaign(campaign); for (CampaignSourceEntry cse : cseList) { File lstFile = new File(cse.getURI()); fileNames.remove(lstFile.getCanonicalPath()); } } StringBuilder report = new StringBuilder(); for (String orphan : fileNames) { String srcRelPath = orphan.substring(dataPathLen+1); if (!srcRelPath.startsWith("customsources")) { report.append(srcRelPath); report.append("\r\n"); } } // Flag any missing files assertEquals( "Some data files are orphaned.", "", report.toString()); } private List<CampaignSourceEntry> getLstFilesForCampaign(Campaign campaign) { List<CampaignSourceEntry> cseList = new ArrayList<>(); for (ListKey<CampaignSourceEntry> lk : CampaignLoader.OBJECT_FILE_LISTKEY) { cseList.addAll(campaign.getSafeListFor(lk)); } for (ListKey<CampaignSourceEntry> lk : CampaignLoader.OTHER_FILE_LISTKEY) { cseList.addAll(campaign.getSafeListFor(lk)); } cseList.addAll(campaign.getSafeListFor(ListKey.FILE_PCC)); return cseList; } private static void loadGameModes() { String configFolder = "testsuite"; String pccLoc = TestHelper.findDataFolder(); System.out.println("Got data folder of " + pccLoc); try { TestHelper.createDummySettingsFile(TEST_CONFIG_FILE, configFolder, pccLoc); } catch (IOException e) { Logging.errorPrint("DataTest.loadGameModes failed", e); } PropertyContextFactory configFactory = new PropertyContextFactory(SystemUtils.USER_DIR); configFactory.registerAndLoadPropertyContext(ConfigurationSettings.getInstance(TEST_CONFIG_FILE)); Main.loadProperties(false); PCGenTask loadPluginTask = Main.createLoadPluginTask(); loadPluginTask.execute(); GameModeFileLoader gameModeFileLoader = new GameModeFileLoader(); gameModeFileLoader.execute(); CampaignFileLoader campaignFileLoader = new CampaignFileLoader(); campaignFileLoader.execute(); } }