module Parser.GameSpec where import Test.Hspec import RPGEngine.Data import RPGEngine.Parse.Core import RPGEngine.Parse.TextToStructure import RPGEngine.Parse.StructureToGame spec :: Spec spec = do describe "Game" $ do it "Simple game" $ do pendingWith "There is a weird bug that caused this to go in an infinite loop. Fix later." let input = "player: {\n hp: 50,\n inventory: []\n}\n\nlevels: [\n {\n layout: {\n | * * * * * *\n | * s . . e *\n | * * * * * *\n },\n \n items: [],\n\n entities: []\n\n\n }\n]" correct = Game { state = Playing { levels = [], count = 0, level = Level { RPGEngine.Data.layout = [], index = [], items = [], entities = [] }, player = Player { playerHp = Just 50, inventory = [], position = (0, 0), showHp = True, showInventory = False }, restart = Menu } } (Right struct) = parseWith gameFile input structureToGame struct `shouldBe` correct it "More complex game" $ do pendingWith "Still need to write this" it "Game with multiple levels" $ do pendingWith "Still need to write this" describe "Player" $ do it "cannot die" $ do let input = "player: { hp: infinite, inventory: [] }" correct = Player { playerHp = Prelude.Nothing, inventory = [], position = (0, 0), showHp = True, showInventory = False } Right (Entry (Tag "player") struct) = parseWith structure input structureToPlayer struct `shouldBe` correct it "without inventory" $ do let input = "player: { hp: 50, inventory: [] }" correct = Player { playerHp = Just 50, inventory = [], position = (0, 0), showHp = True, showInventory = False } Right (Entry (Tag "player") struct) = parseWith structure input structureToPlayer struct `shouldBe` correct it "with inventory" $ do let input = "player: { hp: 50, inventory: [ { id: \"dagger\", x: 0, y: 0, name: \"Dolk\", description: \"Basis schade tegen monsters\", useTimes: infinite, value: 10, actions: {} } ] }" correct = Player { playerHp = Just 50, inventory = [ Item { itemId = "dagger", itemX = 0, itemY = 0, itemName = "Dolk", itemDescription = "Basis schade tegen monsters", itemActions = [], itemValue = Just 10, useTimes = Prelude.Nothing } ], position = (0, 0), showHp = True, showInventory = False } Right (Entry (Tag "player") struct) = parseWith structure input structureToPlayer struct `shouldBe` correct describe "Items" $ do it "simple" $ do let input = "{ id: \"dagger\", x: 0, y: 0, name: \"Dagger\", description: \"Basic dagger you found somewhere\", useTimes: infinite, value: 10, actions: {} }" correct = Item { itemId = "dagger", itemX = 0, itemY = 0, itemName = "Dagger", itemDescription = "Basic dagger you found somewhere", itemValue = Just 10, itemActions = [], useTimes = Prelude.Nothing } Right struct = parseWith structure input structureToItem struct `shouldBe` correct it "with actions" $ do let input = "{ id: \"key\", x: 3, y: 1, name: \"Doorkey\", description: \"Unlocks a secret door\", useTimes: 1, value: 0, actions: { [not(inventoryFull())] retrieveItem(key), [] leave() } }" correct = Item { itemId = "key", itemX = 3, itemY = 1, itemName = "Doorkey", itemDescription = "Unlocks a secret door", itemActions = [ ([], Leave), ([Not InventoryFull], RetrieveItem "key") ], itemValue = Just 0, useTimes = Just 1 } Right struct = parseWith structure input structureToItem struct `shouldBe` correct describe "Actions" $ do it "no conditions" $ do let input = "{[] leave()}" correct = [([], Leave)] Right struct = parseWith structure input structureToActions struct `shouldBe` correct it "single condition" $ do let input = "{ [inventoryFull()] useItem(itemId)}" correct = [([InventoryFull], UseItem "itemId")] Right struct = parseWith structure input structureToActions struct `shouldBe` correct it "multiple conditions" $ do let input = "{ [not(inventoryFull()), inventoryContains(itemId)] increasePlayerHp(itemId)}" correct = [([Not InventoryFull, InventoryContains "itemId"], IncreasePlayerHp "itemId")] Right struct = parseWith structure input structureToActions struct `shouldBe` correct it "DecreaseHp(entityid, itemid)" $ do let input = "{ [] decreaseHp(devil, sword) }" correct = [([], DecreaseHp "devil" "sword")] Right struct = parseWith structure input structureToActions struct `shouldBe` correct describe "Entities" $ do it "Simple entity" $ do pendingWith "still need to write this" describe "Level" $ do it "Simple layout" $ do let input = "{ layout: { | * * * * * *\n| * s . . e *\n| * * * * * *\n }, items: [], entities: [] }" correct = Level { RPGEngine.Data.layout = [ [Blocked, Blocked, Blocked, Blocked, Blocked, Blocked], [Blocked, Entrance, Walkable, Walkable, Exit, Blocked], [Blocked, Blocked, Blocked, Blocked, Blocked, Blocked] ], index = [ (0, 0, Blocked), (1, 0, Blocked), (2, 0, Blocked), (3, 0, Blocked), (4, 0, Blocked), (5, 0, Blocked), (0, 1, Blocked), (1, 1, Entrance), (2, 1, Walkable), (3, 1, Walkable), (4, 1, Exit), (5, 1, Blocked), (0, 2, Blocked), (1, 2, Blocked), (2, 2, Blocked), (3, 2, Blocked), (4, 2, Blocked), (5, 2, Blocked) ], items = [], entities = [] } Right struct = parseWith structure input structureToLevel struct `shouldBe` correct