001/* 002 * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games. 003 * Copyright (C) 2000-2010 The Gridarta Developers. 004 * 005 * This program is free software; you can redistribute it and/or modify 006 * it under the terms of the GNU General Public License as published by 007 * the Free Software Foundation; either version 2 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU General Public License for more details. 014 * 015 * You should have received a copy of the GNU General Public License along 016 * with this program; if not, write to the Free Software Foundation, Inc., 017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 018 */ 019 020package net.sf.gridarta.model.index; 021 022import java.io.File; 023import java.io.IOException; 024import java.util.Collection; 025import java.util.Iterator; 026import net.sf.gridarta.model.archetype.TestArchetype; 027import net.sf.gridarta.model.gameobject.TestGameObject; 028import net.sf.gridarta.model.maparchobject.TestMapArchObject; 029import net.sf.gridarta.model.mapcontrol.DefaultMapControl; 030import net.sf.gridarta.model.mapcontrol.TestMapControlCreator; 031import net.sf.gridarta.model.mapmanager.MapManager; 032import net.sf.gridarta.model.mapmodel.MapModel; 033import net.sf.gridarta.model.settings.ProjectSettings; 034import net.sf.gridarta.model.settings.TestProjectSettings; 035import net.sf.gridarta.utils.StringUtils; 036import org.jetbrains.annotations.NotNull; 037import org.jetbrains.annotations.Nullable; 038import org.junit.Assert; 039import org.junit.Test; 040 041/** 042 * Regression tests for {@link MapsIndexer}. 043 * @author Andreas Kirschbaum 044 */ 045public class MapsIndexerTest { 046 047 /** 048 * Checks that basic indexing works as expected. 049 * @throws InterruptedException if the test fails 050 * @throws IOException if the test fails 051 */ 052 @Test 053 public void test1() throws InterruptedException, IOException { 054 final ProjectSettings projectSettings = new TestProjectSettings(); 055 final TestMapControlCreator mapControlCreator = new TestMapControlCreator(); 056 final MapManager<TestGameObject, TestMapArchObject, TestArchetype> mapManager = mapControlCreator.newMapManager(); 057 final File mapsDirectory = createMapsDirectory(mapControlCreator, projectSettings, "map1:Map1", "path/map2:Map Name2"); 058 try { 059 final MapsIndex index = new MapsIndex(); 060 projectSettings.setMapsDirectory(mapsDirectory); 061 final MapsIndexer<TestGameObject, TestMapArchObject, TestArchetype> indexer = new MapsIndexer<TestGameObject, TestMapArchObject, TestArchetype>(index, mapManager, projectSettings); 062 indexer.start(); 063 indexer.waitForIdle(); 064 indexer.stop(); 065 Assert.assertEquals(2, index.findPartialName("").size()); 066 assertEquals(index.findPartialName("Map1"), mapsDirectory, "map1"); 067 assertEquals(index.findPartialName("Map Name2"), mapsDirectory, "path/map2"); 068 } finally { 069 deleteTempDir(mapsDirectory); 070 } 071 } 072 073 /** 074 * Checks that a {@link Collection} of {@link File Files} contains exactly 075 * one expected value. Fails the test otherwise. 076 * @param mapPaths the collection of files 077 * @param mapsDirectory the maps directory 078 * @param mapPath the map path (relative to mapsDirectory) of the expected 079 * value 080 */ 081 private static void assertEquals(@NotNull final Collection<File> mapPaths, @NotNull final File mapsDirectory, @NotNull final String mapPath) { 082 Assert.assertEquals(1, mapPaths.size()); 083 final Iterator<File> it = mapPaths.iterator(); 084 Assert.assertEquals(new File(mapsDirectory, mapPath), it.next()); 085 } 086 087 /** 088 * Creates a maps directory consisting of a set of maps. Each "spec" value 089 * describes a map to create. Its format is "<map path>:<map name>", for 090 * example "path/to/map:Name of Map". 091 * @param mapControlCreator the map control creator for creating the maps 092 * @param projectSettings the project settings to use 093 * @param specs the maps to create 094 * @return the maps directory 095 * @throws IOException if the maps directory could not be created 096 */ 097 @NotNull 098 private static File createMapsDirectory(@NotNull final TestMapControlCreator mapControlCreator, @NotNull final ProjectSettings projectSettings, @NotNull final String... specs) throws IOException { 099 final File mapsDirectory = createTempDir("gridarta"); 100 @Nullable File directoryToDelete = mapsDirectory; 101 try { 102 for (final String spec : specs) { 103 final String[] tmp = StringUtils.PATTERN_COLON.split(spec, 2); 104 if (tmp.length != 2) { 105 throw new IllegalArgumentException(); 106 } 107 108 final File mapFile = new File(mapsDirectory, tmp[0]); 109 final String mapName = tmp[1]; 110 111 if (!mapFile.getParentFile().exists() && !mapFile.getParentFile().mkdirs()) { 112 throw new IOException("cannot create directory: " + mapFile.getParentFile()); 113 } 114 115 final MapModel<TestGameObject, TestMapArchObject, TestArchetype> mapModel = mapControlCreator.getMapModelCreator().newMapModel(5, 5); 116 final DefaultMapControl<TestGameObject, TestMapArchObject, TestArchetype> mapControl = new DefaultMapControl<TestGameObject, TestMapArchObject, TestArchetype>(mapModel, false, mapControlCreator.getMapWriter(), projectSettings); 117 mapControl.getMapModel().getMapArchObject().setMapName(mapName); 118 mapControl.saveAs(mapFile); 119 } 120 directoryToDelete = null; 121 } finally { 122 if (directoryToDelete != null) { 123 deleteTempDir(directoryToDelete); 124 } 125 } 126 return mapsDirectory; 127 } 128 129 /** 130 * Creates an empty directory in the default temporary directory using the 131 * given prefix. 132 * @param prefix the prefix string to be used in generating the directory's 133 * name; must be at least three characters long. 134 * @return a newly-created empty directory 135 * @throws IOException if no directory could be created 136 */ 137 @NotNull 138 private static File createTempDir(@NotNull final String prefix) throws IOException { 139 final String tmpDir = System.getProperty("java.io.tmpdir"); 140 if (tmpDir == null) { 141 throw new IOException("the system property 'java.io.tmpdir' does not exist"); 142 } 143 144 final File tmpFile = new File(tmpDir); 145 if (!tmpFile.exists() && !tmpFile.mkdirs()) { 146 throw new IOException("cannot create temporary directory " + tmpFile); 147 } 148 149 final File result = File.createTempFile(prefix, null); 150 if (!result.delete()) { 151 throw new IOException("cannot delete temporary file " + result); 152 } 153 if (!result.mkdir()) { 154 throw new IOException("cannot create temporary directory " + result); 155 } 156 157 return result; 158 } 159 160 /** 161 * Deletes a temporary directory. 162 * @param dir the directory 163 */ 164 private static void deleteTempDir(final File dir) { 165 final File[] files = dir.listFiles(); 166 if (files != null) { 167 for (final File file : files) { 168 if (file.isDirectory()) { 169 deleteTempDir(file); 170 } else if (!file.delete()) { 171 Assert.fail("cannot delete file " + file); 172 } 173 } 174 } 175 if (!dir.delete()) { 176 Assert.fail("cannot delete directory " + dir); 177 } 178 } 179 180}