package rabbitescape.engine; import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.CoreMatchers.*; import static rabbitescape.engine.Tools.*; import static rabbitescape.engine.textworld.TextWorldManip.*; import java.io.FileNotFoundException; import java.io.IOException; import java.util.HashSet; import java.util.Set; import org.junit.Test; import rabbitescape.engine.menu.*; import rabbitescape.engine.solution.Solution; import rabbitescape.engine.solution.SolutionExceptions; import rabbitescape.engine.solution.SolutionExceptions.UnknownProblem; import rabbitescape.engine.solution.SolutionParser; import rabbitescape.engine.solution.SolutionRunner; import rabbitescape.engine.util.FileSystem; public class TestAllActiveLevels { @Test public void All_official_levels_load_and_round_trip() { forEachOfficialLevel( assertItRoundTrips() ); } @Test public void All_official_levels_work_and_have_winning_solutions() { forEachOfficialLevel( assertItsSolutionsWorkAndYouCanWin() ); } @Test public void All_staging_levels_work_and_have_winning_solutions() { forEachStagingLevel( assertItsSolutionsWorkAndYouCanWin() ); } @Test public void All_development_levels_work_and_any_solutions_are_correct() { forEachDevelopmentLevel( assertItsSolutionsWork() ); } @Test public void All_dejavu_levels_work_and_any_solutions_are_correct() { forEachUnofficialLevel( assertItsSolutionsWork(), "07_dejavu" ); } @Test public void All_official_levels_have_unique_names() { final Set<String> names = new HashSet<String>(); forEachOfficialLevel( new T() { @Override public void run( World world, String fileName ) { String name = ByNameConfigBasedLevelsCompleted.canonicalName( world.name ); assertThat( names, not( hasItem( name ) ) ); names.add( name ); } } ); } // -- private T assertItRoundTrips() { return new T() { @Override public void run( World world, String filename ) { String[] lines = renderCompleteWorld( world, true ); assertThat( renderCompleteWorld( createWorld( lines ), true ), equalTo( lines ) ); } }; } private T assertItsSolutionsWork() { return assertTheSolutionsWorkAndYouCanWin( false ); } private T assertItsSolutionsWorkAndYouCanWin() { return assertTheSolutionsWorkAndYouCanWin( true ); } private T assertTheSolutionsWorkAndYouCanWin( final boolean mustWin ) { return new T() { @Override public void run( World world, String fileName ) { boolean solved = false; int i = 1; for ( String s : world.solutions ) { boolean thisS = runSolutionString( world, fileName, i, s ); if ( thisS ) { solved = true; } ++i; } if ( mustWin && !solved ) { throw new AssertionError( "Level " + fileName + " has no solution!" ); } } }; } private void forEachOfficialLevel( T test ) { for ( LevelsList.LevelSetInfo set : LoadLevelsList.load( MenuDefinition.allLevels ) ) { if ( set.hidden ) { continue; } for ( LevelsList.LevelInfo level : set.levels ) { World world = new LoadWorldFile( new NothingExistsFileSystem() ) .load( new IgnoreWorldStatsListener(), set.dirName + "/" + level.fileName + ".rel" ); test.run( world, level.fileName ); } } } private void forEachStagingLevel( T test ) { forEachUnofficialLevel( test, "staging" ); } private void forEachDevelopmentLevel( T test ) { forEachUnofficialLevel( test, "development" ); } private void forEachUnofficialLevel( T test, String levelsDir ) { LevelsList levelsList = LoadLevelsList.load( new LevelsList( new LevelsList.LevelSetInfo( null, levelsDir, null, false ) ) ); for ( LevelsList.LevelSetInfo set : levelsList ) { for ( LevelsList.LevelInfo level : set.levels ) { World world = new LoadWorldFile( new NothingExistsFileSystem() ) .load( new IgnoreWorldStatsListener(), levelsDir + "/" + level.fileName + ".rel" ); test.run( world, level.fileName ); } } } private boolean runSolutionString( World world, String worldFileName, int solutionId, String solutionString ) { try { Solution solution = SolutionParser.parse( solutionString ); return SolutionRunner.runSolution( solution, world ); } catch ( SolutionExceptions.ProblemRunningSolution e ) { e.solutionId = solutionId; e.level = worldFileName; throw e; } catch ( Throwable e ) { UnknownProblem u = new SolutionExceptions.UnknownProblem( e ); u.solutionId = solutionId; u.level = worldFileName; throw u; } } private static class NothingExistsFileSystem implements FileSystem { @Override public boolean exists( String fileName ) { return false; } @Override public String[] readLines( String fileName ) throws FileNotFoundException, IOException { throw new UnsupportedOperationException(); } @Override public String read( String fileName ) throws FileNotFoundException, IOException { throw new UnsupportedOperationException(); } @Override public void write( String fileName, String contents ) throws IOException { throw new UnsupportedOperationException(); } @Override public String parent( String filePath ) { throw new UnsupportedOperationException(); } @Override public void mkdirs( String dirPath ) { throw new UnsupportedOperationException(); } } private static interface T { void run( World world, String filename ); } }