/** @file presentationTests.cpp * @brief Unit tests for the presentation layer of a Rally-X game. * * The BitmapStore class is tested in its ability to return a bitmap for * each image. The appearance of the bitmaps need to be tested manually * by running the game and inspecting the various objects. * * The ColourStore class is tested in its ability to return a colour for * each image. The appearance of the colours need to be tested manually * by running the game and inspecting the various objects. * * The GamePanel and InfoPanel classes depend on their visual appearance in * the game. Therefore, they should be tested manually. The technical part * of their functionality, creating the back and front buffers and changing * between them, is handled by their superclass, ScreenPanel. * * The KeyboardHandler depends on user inputs. It should be tested manually * by testing that the player's direction can be controlled, and that smokescreens * can be created. * * The Screen class's creation with various resolutions and fullscreen settings is * tested. An exception should be thrown if the fullscreen resolution is not supported * by the current hardware, but not otherwise. The visual appearance and creation of * ScreenPanels should be tested manually by running the game. * * The ScreenPanel class is tested by creating a false back and front display buffer. The buffer * that is being drawn to is tested by sampling a pixel in the middle of the buffer. * * @author Justin Wernick * @author David Schneider */ #include #include using namespace std; #include #include "../source/presentation/BitmapStore.h" #include "../source/presentation/ColourStore.h" #include "../source/presentation/GamePanel.h" #include "../source/presentation/Screen.h" #include "../source/logic/PlayerCar.h" #include "../source/logic/EnemyCar.h" #include "../source/logic/Checkpoint.h" #include "../source/logic/Rock.h" #include "../source/logic/Smokescreen.h" #include "../source/logic/Maze.h" #include "../source/logic/DestroyedObjectPopup.h" /** * @brief Tests that all images can be requested without failure occuring. */ TEST(BitmapStore, returnsBitmapForAllImages) { BitmapStore testStore(50); ALLEGRO_BITMAP* testBitmap = NULL; EXPECT_NO_FATAL_FAILURE(testBitmap = testStore.getBitmap(BitmapStore::PLAYER)); EXPECT_NO_FATAL_FAILURE(testBitmap = testStore.getBitmap(BitmapStore::ENEMY)); EXPECT_NO_FATAL_FAILURE(testBitmap = testStore.getBitmap(BitmapStore::CHECKPOINT)); EXPECT_NO_FATAL_FAILURE(testBitmap = testStore.getBitmap(BitmapStore::ROCK)); EXPECT_NO_FATAL_FAILURE(testBitmap = testStore.getBitmap(BitmapStore::MAZE_WALL)); EXPECT_NO_FATAL_FAILURE(testBitmap = testStore.getBitmap(BitmapStore::MAZE_FLOOR)); EXPECT_NO_FATAL_FAILURE(testBitmap = testStore.getBitmap(BitmapStore::SMOKE)); EXPECT_NO_FATAL_FAILURE(testBitmap = testStore.getBitmap(BitmapStore::CRASHED_CAR)); EXPECT_NO_FATAL_FAILURE(testBitmap = testStore.getBitmap(BitmapStore::CLAIMED_CHECKPOINT)); } /** * @brief Tests that all colours can be requested without failure occuring. */ TEST(ColourStore, returnsColourForAllImages) { ColourStore testStore; ALLEGRO_COLOR testColour; EXPECT_NO_FATAL_FAILURE(testColour = testStore.getColour(BitmapStore::PLAYER)); EXPECT_NO_FATAL_FAILURE(testColour = testStore.getColour(BitmapStore::ENEMY)); EXPECT_NO_FATAL_FAILURE(testColour = testStore.getColour(BitmapStore::CHECKPOINT)); EXPECT_NO_FATAL_FAILURE(testColour = testStore.getColour(BitmapStore::ROCK)); EXPECT_NO_FATAL_FAILURE(testColour = testStore.getColour(BitmapStore::MAZE_WALL)); EXPECT_NO_FATAL_FAILURE(testColour = testStore.getColour(BitmapStore::MAZE_FLOOR)); EXPECT_NO_FATAL_FAILURE(testColour = testStore.getColour(BitmapStore::SMOKE)); EXPECT_NO_FATAL_FAILURE(testColour = testStore.getColour(BitmapStore::CRASHED_CAR)); EXPECT_NO_FATAL_FAILURE(testColour = testStore.getColour(BitmapStore::CLAIMED_CHECKPOINT)); } /** * Tests that an exception is thrown if fullscreen mode is requested on an unsupported monitor resolution. */ TEST(Screen, exceptionOnBadResolution) { //resolution should be unsupported on most displays int badWidth = 1000; int badHeight = 5; EXPECT_ANY_THROW(Screen(badWidth, badHeight, true)); } /** * Tests that an exception is not thrown if windowed mode is requested on an unsupported monitor resolution. */ TEST(Screen, noExceptionOnWindowed) { int badWidth = 1000; int badHeight = 5; EXPECT_NO_THROW(Screen(badWidth, badHeight, false)); } /** * Tests that an exception is not thrown if fullscreen mode is requested on a supported monitor resolution. */ TEST(Screen, noExceptionOnGoodResolution) { //resolution should be supported on most monitors int goodWidth = 800; int goodHeight = 600; EXPECT_NO_THROW(Screen(goodWidth, goodHeight, true)); } /** * @brief Tests that when a ScreenPanel draws to the back buffer provided. */ TEST(ScreenPanel, drawingToCurrentBackBuffer) { al_init(); ALLEGRO_BITMAP* testBitmapBack = al_create_bitmap(500,500); ALLEGRO_BITMAP* testBitmapFront = al_create_bitmap(500,500); ALLEGRO_COLOR blankColour = al_map_rgb(0,0,0); al_set_target_bitmap(testBitmapBack); al_clear_to_color(blankColour); al_set_target_bitmap(testBitmapFront); al_clear_to_color(blankColour); GamePanel testPanel(testBitmapBack, testBitmapFront, 0, 0, 500, 500); Maze testMaze; vector > wallsFull; for (int x=0; x<20; ++x) { for (int y=0; y<20; ++y) { wallsFull.push_back(make_pair(x,y)); } } testMaze.generateMaze(wallsFull,20,20); list players; list enemies; list checkpoints; list rocks; list smokescreens; list popups; testPanel.draw(testMaze, players, enemies, checkpoints, rocks, smokescreens, popups); BitmapStore bitmapStore(50); ALLEGRO_BITMAP* wall = bitmapStore.getBitmap(BitmapStore::MAZE_WALL); ALLEGRO_COLOR mazeColour = al_get_pixel(wall, 25, 25); ALLEGRO_COLOR backSample = al_get_pixel(testBitmapBack, 250, 250); ALLEGRO_COLOR frontSample = al_get_pixel(testBitmapFront, 250, 250); EXPECT_FLOAT_EQ(mazeColour.r, backSample.r); EXPECT_FLOAT_EQ(mazeColour.g, backSample.g); EXPECT_FLOAT_EQ(mazeColour.b, backSample.b); EXPECT_FLOAT_EQ(mazeColour.a, backSample.a); EXPECT_FLOAT_EQ(blankColour.r, frontSample.r); EXPECT_FLOAT_EQ(blankColour.g, frontSample.g); EXPECT_FLOAT_EQ(blankColour.b, frontSample.b); EXPECT_FLOAT_EQ(blankColour.a, frontSample.a); al_destroy_bitmap(testBitmapBack); al_destroy_bitmap(testBitmapFront); } /** * @brief Tests that when a ScreenPanel draws to the front buffer provided after a flip has been called. */ TEST(ScreenPanel, drawingToCurrentBackBufferAfterFlip) { al_init(); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); //removes dependency on display existing ALLEGRO_BITMAP* testBitmapBack = al_create_bitmap(500,500); ALLEGRO_BITMAP* testBitmapFront = al_create_bitmap(500,500); ALLEGRO_COLOR blankColour = al_map_rgb(0,0,0); al_set_target_bitmap(testBitmapBack); al_clear_to_color(blankColour); al_set_target_bitmap(testBitmapFront); al_clear_to_color(blankColour); GamePanel testPanel(testBitmapBack, testBitmapFront, 0, 0, 500, 500); Maze testMaze; vector > wallsFull; for (int x=0; x<20; ++x) { for (int y=0; y<20; ++y) { wallsFull.push_back(make_pair(x,y)); } } testMaze.generateMaze(wallsFull,20,20); list players; list enemies; list checkpoints; list rocks; list smokescreens; list popups; testPanel.flip(); testPanel.draw(testMaze, players, enemies, checkpoints, rocks, smokescreens, popups); BitmapStore bitmapStore(50); ALLEGRO_BITMAP* wall = bitmapStore.getBitmap(BitmapStore::MAZE_WALL); ALLEGRO_COLOR mazeColour = al_get_pixel(wall, 25, 25); ALLEGRO_COLOR backSample = al_get_pixel(testBitmapBack, 250, 250); ALLEGRO_COLOR frontSample = al_get_pixel(testBitmapFront, 250, 250); EXPECT_FLOAT_EQ(mazeColour.r, frontSample.r); EXPECT_FLOAT_EQ(mazeColour.g, frontSample.g); EXPECT_FLOAT_EQ(mazeColour.b, frontSample.b); EXPECT_FLOAT_EQ(mazeColour.a, frontSample.a); EXPECT_FLOAT_EQ(blankColour.r, backSample.r); EXPECT_FLOAT_EQ(blankColour.g, backSample.g); EXPECT_FLOAT_EQ(blankColour.b, backSample.b); EXPECT_FLOAT_EQ(blankColour.a, backSample.a); al_destroy_bitmap(testBitmapBack); al_destroy_bitmap(testBitmapFront); }