diff --git a/rsrc/schemas/dialogue.xsd b/rsrc/schemas/dialogue.xsd index c74b1b5e..cbbd07cb 100644 --- a/rsrc/schemas/dialogue.xsd +++ b/rsrc/schemas/dialogue.xsd @@ -40,7 +40,7 @@ - + diff --git a/src/BoE.xcodeproj/project.pbxproj b/src/BoE.xcodeproj/project.pbxproj index 2f8f18e6..84cccc18 100755 --- a/src/BoE.xcodeproj/project.pbxproj +++ b/src/BoE.xcodeproj/project.pbxproj @@ -63,6 +63,9 @@ 910D9CA41B36439100414B17 /* libboost_thread.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 910D9CA31B36439100414B17 /* libboost_thread.dylib */; }; 910D9CA51B36439100414B17 /* libboost_thread.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 910D9CA31B36439100414B17 /* libboost_thread.dylib */; }; 910D9CA61B36439100414B17 /* libboost_thread.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 910D9CA31B36439100414B17 /* libboost_thread.dylib */; }; + 911A14031B8FAFC600900FD9 /* town_read.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91C2A6EC1B8FA91400346948 /* town_read.cpp */; }; + 911A14041B8FB00300900FD9 /* talk_read.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91C2A6EE1B8FAA8E00346948 /* talk_read.cpp */; }; + 911A14051B8FB00600900FD9 /* out_read.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91C2A6ED1B8FA9FB00346948 /* out_read.cpp */; }; 9127903E0F9B7F49007B0D52 /* boe.actions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BF04ACF0BF51923006C0831 /* boe.actions.cpp */; }; 9127903F0F9B7F50007B0D52 /* boe.graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BF04AD30BF51923006C0831 /* boe.graphics.cpp */; }; 91279BAE0F9CFCBA007B0D52 /* boescenario.icns in Resources */ = {isa = PBXBuildFile; fileRef = 91279BAD0F9CFCBA007B0D52 /* boescenario.icns */; }; @@ -739,6 +742,9 @@ 91BFA3DF19033E01001686E4 /* gzstream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gzstream.h; sourceTree = ""; }; 91C2A6E11B823CCD00346948 /* gitrev.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = gitrev.sh; sourceTree = ""; }; 91C2A6E21B8244F700346948 /* gitrev.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = gitrev.hpp; sourceTree = ""; }; + 91C2A6EC1B8FA91400346948 /* town_read.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = town_read.cpp; sourceTree = ""; }; + 91C2A6ED1B8FA9FB00346948 /* out_read.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = out_read.cpp; sourceTree = ""; }; + 91C2A6EE1B8FAA8E00346948 /* talk_read.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = talk_read.cpp; sourceTree = ""; }; 91C688E60FD702B9000F6D01 /* cursors.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = cursors.hpp; sourceTree = ""; }; 91C688E70FD702B9000F6D01 /* cursors.mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cursors.mac.mm; sourceTree = ""; }; 91C749B71A2D6432008E0E10 /* strings */ = {isa = PBXFileReference; lastKnownFileType = folder; path = strings; sourceTree = ""; }; @@ -1329,6 +1335,9 @@ 91EF27781B693D5F00666469 /* item_write.cpp */, 91EF277A1B693D6E00666469 /* monst_read.cpp */, 91EF277C1B693D7D00666469 /* monst_write.cpp */, + 91C2A6EC1B8FA91400346948 /* town_read.cpp */, + 91C2A6EE1B8FAA8E00346948 /* talk_read.cpp */, + 91C2A6ED1B8FA9FB00346948 /* out_read.cpp */, ); name = src; sourceTree = ""; @@ -1843,6 +1852,9 @@ 91EF27791B693D5F00666469 /* item_write.cpp in Sources */, 91EF277B1B693D6E00666469 /* monst_read.cpp in Sources */, 91EF277D1B693D7D00666469 /* monst_write.cpp in Sources */, + 911A14031B8FAFC600900FD9 /* town_read.cpp in Sources */, + 911A14041B8FB00300900FD9 /* talk_read.cpp in Sources */, + 911A14051B8FB00600900FD9 /* out_read.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/tools/fileio_scen.cpp b/src/tools/fileio_scen.cpp index e2926cf2..65ffd076 100644 --- a/src/tools/fileio_scen.cpp +++ b/src/tools/fileio_scen.cpp @@ -48,6 +48,9 @@ void readScenarioFromXml(ticpp::Document&& data, cScenario& scenario); void readTerrainFromXml(ticpp::Document&& data, cScenario& scenario); void readItemsFromXml(ticpp::Document&& data, cScenario& scenario); void readMonstersFromXml(ticpp::Document&& data, cScenario& scenario); +void readOutdoorsFromXml(ticpp::Document&& data, cOutdoors& out); +void readTownFromXml(ticpp::Document&& data, cTown*& town, cScenario& scen); +void readDialogueFromXml(ticpp::Document&& data, cSpeech& talk, int town_num); void loadOutMapData(map_data&& data, location which, cScenario& scen); void loadTownMapData(map_data&& data, int which, cScenario& scen); @@ -1439,7 +1442,7 @@ void readMonstersFromXml(ticpp::Document&& data, cScenario& scenario) { } } -static void readOutdoorsFromXml(ticpp::Document&& data, cOutdoors& out) { +void readOutdoorsFromXml(ticpp::Document&& data, cOutdoors& out) { using namespace ticpp; int maj, min, rev; std::string fname, type, name, val; @@ -1533,7 +1536,7 @@ static void readOutdoorsFromXml(ticpp::Document&& data, cOutdoors& out) { throw xMissingElem("sector", "name", data.FirstChildElement()->Row(), data.FirstChildElement()->Column(), fname); } -static void readTownFromXml(ticpp::Document&& data, cTown*& town, cScenario& scen) { +void readTownFromXml(ticpp::Document&& data, cTown*& town, cScenario& scen) { static const std::string dirs = "nwse"; using namespace ticpp; int maj, min, rev; @@ -1736,10 +1739,10 @@ static void readTownFromXml(ticpp::Document&& data, cTown*& town, cScenario& sce } else throw xBadNode(type, elem->Row(), elem->Column(), fname); } if(!reqs.empty()) - throw xMissingElem("item", *reqs.begin(), data.FirstChildElement()->Row(), data.FirstChildElement()->Column(), fname); + throw xMissingElem("town", *reqs.begin(), data.FirstChildElement()->Row(), data.FirstChildElement()->Column(), fname); } -static void readDialogueFromXml(ticpp::Document&& data, cSpeech& talk, int town_num) { +void readDialogueFromXml(ticpp::Document&& data, cSpeech& talk, int town_num) { using namespace ticpp; int maj, min, rev; std::string fname, type, name, val; diff --git a/test/files/outdoor/bad_root_attr.xml b/test/files/outdoor/bad_root_attr.xml new file mode 100644 index 00000000..b73063cc --- /dev/null +++ b/test/files/outdoor/bad_root_attr.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/files/outdoor/bad_toplevel.xml b/test/files/outdoor/bad_toplevel.xml new file mode 100644 index 00000000..a8c0e423 --- /dev/null +++ b/test/files/outdoor/bad_toplevel.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/test/files/outdoor/encounter_bad_attr.xml b/test/files/outdoor/encounter_bad_attr.xml new file mode 100644 index 00000000..1f53429f --- /dev/null +++ b/test/files/outdoor/encounter_bad_attr.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/test/files/outdoor/encounter_bad_node.xml b/test/files/outdoor/encounter_bad_node.xml new file mode 100644 index 00000000..be305de6 --- /dev/null +++ b/test/files/outdoor/encounter_bad_node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/test/files/outdoor/encounter_empty.xml b/test/files/outdoor/encounter_empty.xml new file mode 100644 index 00000000..f882d37a --- /dev/null +++ b/test/files/outdoor/encounter_empty.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/test/files/outdoor/encounter_too_many.xml b/test/files/outdoor/encounter_too_many.xml new file mode 100644 index 00000000..2e597363 --- /dev/null +++ b/test/files/outdoor/encounter_too_many.xml @@ -0,0 +1,7 @@ + + 0 + 0 + 0 + 0 + 0 + \ No newline at end of file diff --git a/test/files/outdoor/encounter_too_many_monst.xml b/test/files/outdoor/encounter_too_many_monst.xml new file mode 100644 index 00000000..d68880d0 --- /dev/null +++ b/test/files/outdoor/encounter_too_many_monst.xml @@ -0,0 +1,8 @@ + + + 0 + 0 + 0 + 0 + + \ No newline at end of file diff --git a/test/files/outdoor/minimal.xml b/test/files/outdoor/minimal.xml new file mode 100644 index 00000000..abd1e196 --- /dev/null +++ b/test/files/outdoor/minimal.xml @@ -0,0 +1,3 @@ + + Test Sector + \ No newline at end of file diff --git a/test/files/outdoor/missing_toplevel.xml b/test/files/outdoor/missing_toplevel.xml new file mode 100644 index 00000000..5b55870a --- /dev/null +++ b/test/files/outdoor/missing_toplevel.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/files/outdoor/no_version.xml b/test/files/outdoor/no_version.xml new file mode 100644 index 00000000..aeb7902d --- /dev/null +++ b/test/files/outdoor/no_version.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/files/talk/bad_node.xml b/test/files/talk/bad_node.xml new file mode 100644 index 00000000..ad8bf511 --- /dev/null +++ b/test/files/talk/bad_node.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/test/files/talk/bad_root_attr.xml b/test/files/talk/bad_root_attr.xml new file mode 100644 index 00000000..3d87e6be --- /dev/null +++ b/test/files/talk/bad_root_attr.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/files/talk/empty.xml b/test/files/talk/empty.xml new file mode 100644 index 00000000..42f5e9a9 --- /dev/null +++ b/test/files/talk/empty.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/files/talk/no_version.xml b/test/files/talk/no_version.xml new file mode 100644 index 00000000..3042e7ad --- /dev/null +++ b/test/files/talk/no_version.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/files/talk/node_bad_node.xml b/test/files/talk/node_bad_node.xml new file mode 100644 index 00000000..e77693ae --- /dev/null +++ b/test/files/talk/node_bad_node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/test/files/talk/node_missing_for.xml b/test/files/talk/node_missing_for.xml new file mode 100644 index 00000000..90a9bce9 --- /dev/null +++ b/test/files/talk/node_missing_for.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/test/files/talk/node_missing_key.xml b/test/files/talk/node_missing_key.xml new file mode 100644 index 00000000..3c7504b8 --- /dev/null +++ b/test/files/talk/node_missing_key.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/test/files/talk/node_missing_string.xml b/test/files/talk/node_missing_string.xml new file mode 100644 index 00000000..b5f2dc18 --- /dev/null +++ b/test/files/talk/node_missing_string.xml @@ -0,0 +1,6 @@ + + + what + 0 + + \ No newline at end of file diff --git a/test/files/talk/node_missing_type.xml b/test/files/talk/node_missing_type.xml new file mode 100644 index 00000000..0e6fdcf1 --- /dev/null +++ b/test/files/talk/node_missing_type.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/test/files/talk/node_too_many_keys.xml b/test/files/talk/node_too_many_keys.xml new file mode 100644 index 00000000..6216f6ee --- /dev/null +++ b/test/files/talk/node_too_many_keys.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/test/files/talk/node_too_many_params.xml b/test/files/talk/node_too_many_params.xml new file mode 100644 index 00000000..9fcfe469 --- /dev/null +++ b/test/files/talk/node_too_many_params.xml @@ -0,0 +1,9 @@ + + + 0 + 0 + 0 + 0 + 0 + + \ No newline at end of file diff --git a/test/files/talk/node_too_many_strings.xml b/test/files/talk/node_too_many_strings.xml new file mode 100644 index 00000000..7c02c26c --- /dev/null +++ b/test/files/talk/node_too_many_strings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/test/files/talk/who_bad_id.xml b/test/files/talk/who_bad_id.xml new file mode 100644 index 00000000..29efb518 --- /dev/null +++ b/test/files/talk/who_bad_id.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/test/files/talk/who_bad_node.xml b/test/files/talk/who_bad_node.xml new file mode 100644 index 00000000..53a87dd9 --- /dev/null +++ b/test/files/talk/who_bad_node.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/test/files/talk/who_missing_id.xml b/test/files/talk/who_missing_id.xml new file mode 100644 index 00000000..7a38948e --- /dev/null +++ b/test/files/talk/who_missing_id.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/test/files/talk/who_missing_req.xml b/test/files/talk/who_missing_req.xml new file mode 100644 index 00000000..6798b9a3 --- /dev/null +++ b/test/files/talk/who_missing_req.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/test/files/town/bad_creature.xml b/test/files/town/bad_creature.xml new file mode 100644 index 00000000..062c9564 --- /dev/null +++ b/test/files/town/bad_creature.xml @@ -0,0 +1,7 @@ + + 32 + Hello World + + + + \ No newline at end of file diff --git a/test/files/town/bad_exit_dir.xml b/test/files/town/bad_exit_dir.xml new file mode 100644 index 00000000..606148ff --- /dev/null +++ b/test/files/town/bad_exit_dir.xml @@ -0,0 +1,5 @@ + + 32 + Hello World + + \ No newline at end of file diff --git a/test/files/town/bad_flag.xml b/test/files/town/bad_flag.xml new file mode 100644 index 00000000..a2256158 --- /dev/null +++ b/test/files/town/bad_flag.xml @@ -0,0 +1,7 @@ + + 32 + Hello World + + + + \ No newline at end of file diff --git a/test/files/town/bad_item.xml b/test/files/town/bad_item.xml new file mode 100644 index 00000000..0d35f1c7 --- /dev/null +++ b/test/files/town/bad_item.xml @@ -0,0 +1,7 @@ + + 32 + Hello World + + + + \ No newline at end of file diff --git a/test/files/town/bad_onenter_condition.xml b/test/files/town/bad_onenter_condition.xml new file mode 100644 index 00000000..7cfd6f12 --- /dev/null +++ b/test/files/town/bad_onenter_condition.xml @@ -0,0 +1,5 @@ + + 32 + Hello World + + \ No newline at end of file diff --git a/test/files/town/bad_onexit_dir.xml b/test/files/town/bad_onexit_dir.xml new file mode 100644 index 00000000..6a2b28a7 --- /dev/null +++ b/test/files/town/bad_onexit_dir.xml @@ -0,0 +1,5 @@ + + 32 + Hello World + + \ No newline at end of file diff --git a/test/files/town/bad_root_attr.xml b/test/files/town/bad_root_attr.xml new file mode 100644 index 00000000..b085c8b7 --- /dev/null +++ b/test/files/town/bad_root_attr.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/files/town/bad_size.xml b/test/files/town/bad_size.xml new file mode 100644 index 00000000..61e7b538 --- /dev/null +++ b/test/files/town/bad_size.xml @@ -0,0 +1,3 @@ + + 1 + \ No newline at end of file diff --git a/test/files/town/bad_toplevel.xml b/test/files/town/bad_toplevel.xml new file mode 100644 index 00000000..b4894051 --- /dev/null +++ b/test/files/town/bad_toplevel.xml @@ -0,0 +1,4 @@ + + 32 + + \ No newline at end of file diff --git a/test/files/town/bad_wandering.xml b/test/files/town/bad_wandering.xml new file mode 100644 index 00000000..470d3c1e --- /dev/null +++ b/test/files/town/bad_wandering.xml @@ -0,0 +1,7 @@ + + 32 + Hello World + + + + \ No newline at end of file diff --git a/test/files/town/empty_creature.xml b/test/files/town/empty_creature.xml new file mode 100644 index 00000000..a6814df8 --- /dev/null +++ b/test/files/town/empty_creature.xml @@ -0,0 +1,5 @@ + + 32 + Hello World + + \ No newline at end of file diff --git a/test/files/town/empty_item.xml b/test/files/town/empty_item.xml new file mode 100644 index 00000000..df9482b8 --- /dev/null +++ b/test/files/town/empty_item.xml @@ -0,0 +1,5 @@ + + 32 + Hello World + + \ No newline at end of file diff --git a/test/files/town/empty_wandering.xml b/test/files/town/empty_wandering.xml new file mode 100644 index 00000000..ff8346bf --- /dev/null +++ b/test/files/town/empty_wandering.xml @@ -0,0 +1,5 @@ + + 32 + Hello World + + \ No newline at end of file diff --git a/test/files/town/minimal.xml b/test/files/town/minimal.xml new file mode 100644 index 00000000..b4535a17 --- /dev/null +++ b/test/files/town/minimal.xml @@ -0,0 +1,8 @@ + + 32 + Test Town + + 1 + lit + + \ No newline at end of file diff --git a/test/files/town/missing_toplevel.xml b/test/files/town/missing_toplevel.xml new file mode 100644 index 00000000..30bf5377 --- /dev/null +++ b/test/files/town/missing_toplevel.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/files/town/no_version.xml b/test/files/town/no_version.xml new file mode 100644 index 00000000..b4e31f91 --- /dev/null +++ b/test/files/town/no_version.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/files/town/size_not_first.xml b/test/files/town/size_not_first.xml new file mode 100644 index 00000000..f0696b3f --- /dev/null +++ b/test/files/town/size_not_first.xml @@ -0,0 +1,4 @@ + + Hello World + 32 + \ No newline at end of file diff --git a/test/files/town/too_many_comments.xml b/test/files/town/too_many_comments.xml new file mode 100644 index 00000000..7026cdbb --- /dev/null +++ b/test/files/town/too_many_comments.xml @@ -0,0 +1,8 @@ + + 32 + Hello World + This + is + a + comment + \ No newline at end of file diff --git a/test/files/town/too_many_timers.xml b/test/files/town/too_many_timers.xml new file mode 100644 index 00000000..d572f5b7 --- /dev/null +++ b/test/files/town/too_many_timers.xml @@ -0,0 +1,13 @@ + + 32 + Hello World + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + \ No newline at end of file diff --git a/test/out_read.cpp b/test/out_read.cpp new file mode 100644 index 00000000..fbdb97dd --- /dev/null +++ b/test/out_read.cpp @@ -0,0 +1,85 @@ +// +// out_read.cpp +// BoE +// +// Created by Celtic Minstrel on 15-08-27. +// +// + +#include +#include "ticpp.h" +#include "catch.hpp" +#include "dialog.hpp" +#include "scenario.hpp" +#include "outdoors.hpp" + +using namespace std; +using namespace ticpp; + +extern Document xmlDocFromStream(istream& stream, string name); +extern void readOutdoorsFromXml(Document&& data, cOutdoors& out); + +TEST_CASE("Loading an outdoor section definition") { + ifstream fin; + cScenario scen; + cOutdoors sector(scen); + Document doc; + fin.exceptions(ios::badbit); + + SECTION("When the root tag is wrong") { + fin.open("files/bad_root.xml"); + doc = xmlDocFromStream(fin, "bad_root.xml"); + REQUIRE_THROWS_AS(readOutdoorsFromXml(move(doc), sector), xBadNode); + } + SECTION("When the version attribute is missing") { + fin.open("files/outdoor/no_version.xml"); + doc = xmlDocFromStream(fin, "no_version.xml"); + REQUIRE_THROWS_AS(readOutdoorsFromXml(move(doc), sector), xMissingAttr); + } + SECTION("When the root tag has a bad attribute") { + fin.open("files/outdoor/bad_root_attr.xml"); + doc = xmlDocFromStream(fin, "bad_root_attr.xml"); + REQUIRE_THROWS_AS(readOutdoorsFromXml(move(doc), sector), xBadAttr); + } + SECTION("When an essential toplevel element is missing") { + fin.open("files/outdoor/missing_toplevel.xml"); + doc = xmlDocFromStream(fin, "missing_toplevel.xml"); + REQUIRE_THROWS_AS(readOutdoorsFromXml(move(doc), sector), xMissingElem); + } + SECTION("When an invalid toplevel element is present") { + fin.open("files/outdoor/bad_toplevel.xml"); + doc = xmlDocFromStream(fin, "bad_toplevel.xml"); + REQUIRE_THROWS_AS(readOutdoorsFromXml(move(doc), sector), xBadNode); + } + SECTION("When an encounter has an invalid subtag") { + fin.open("files/outdoor/encounter_bad_node.xml"); + doc = xmlDocFromStream(fin, "encounter_bad_node.xml"); + REQUIRE_THROWS_AS(readOutdoorsFromXml(move(doc), sector), xBadNode); + } + SECTION("When an encounter has no monsters") { + fin.open("files/outdoor/encounter_empty.xml"); + doc = xmlDocFromStream(fin, "encounter_empty.xml"); + REQUIRE_THROWS_AS(readOutdoorsFromXml(move(doc), sector), xMissingElem); + } + SECTION("When an encounter has too many monsters") { + fin.open("files/outdoor/encounter_too_many_monst.xml"); + doc = xmlDocFromStream(fin, "encounter_too_many_monst.xml"); + REQUIRE_THROWS_AS(readOutdoorsFromXml(move(doc), sector), xBadNode); + } + SECTION("When an encounter monster has an invalid attribute") { + fin.open("files/outdoor/encounter_bad_attr.xml"); + doc = xmlDocFromStream(fin, "encounter_bad_attr.xml"); + REQUIRE_THROWS_AS(readOutdoorsFromXml(move(doc), sector), xBadAttr); + } + SECTION("When there are too many encounters") { + fin.open("files/outdoor/encounter_too_many.xml"); + doc = xmlDocFromStream(fin, "encounter_too_many.xml"); + REQUIRE_THROWS_AS(readOutdoorsFromXml(move(doc), sector), xBadNode); + } + SECTION("With the minimal required data") { + fin.open("files/outdoor/minimal.xml"); + doc = xmlDocFromStream(fin, "minimal.xml"); + REQUIRE_NOTHROW(readOutdoorsFromXml(move(doc), sector)); + CHECK(sector.out_name == "Test Sector"); + } +} diff --git a/test/talk_read.cpp b/test/talk_read.cpp new file mode 100644 index 00000000..376451ea --- /dev/null +++ b/test/talk_read.cpp @@ -0,0 +1,114 @@ +// +// talk_read.cpp +// BoE +// +// Created by Celtic Minstrel on 15-08-27. +// +// + +#include +#include "ticpp.h" +#include "catch.hpp" +#include "dialog.hpp" +#include "talking.hpp" + +using namespace std; +using namespace ticpp; + +extern Document xmlDocFromStream(istream& stream, string name); +extern void readDialogueFromXml(Document&& data, cSpeech& talk, int town_num); + +TEST_CASE("Loading a town dialogue definition") { + ifstream fin; + cSpeech talk; + Document doc; + fin.exceptions(ios::badbit); + + SECTION("When the root tag is wrong") { + fin.open("files/bad_root.xml"); + doc = xmlDocFromStream(fin, "bad_root.xml"); + REQUIRE_THROWS_AS(readDialogueFromXml(move(doc), talk, 0), xBadNode); + } + SECTION("When the version attribute is missing") { + fin.open("files/talk/no_version.xml"); + doc = xmlDocFromStream(fin, "no_version.xml"); + REQUIRE_THROWS_AS(readDialogueFromXml(move(doc), talk, 0), xMissingAttr); + } + SECTION("When the root tag has a bad attribute") { + fin.open("files/talk/bad_root_attr.xml"); + doc = xmlDocFromStream(fin, "bad_root_attr.xml"); + REQUIRE_THROWS_AS(readDialogueFromXml(move(doc), talk, 0), xBadAttr); + } + SECTION("When an invalid toplevel node is found") { + fin.open("files/talk/bad_node.xml"); + doc = xmlDocFromStream(fin, "bad_node.xml"); + REQUIRE_THROWS_AS(readDialogueFromXml(move(doc), talk, 0), xBadNode); + } + SECTION("When the root tag is empty") { + fin.open("files/talk/empty.xml"); + doc = xmlDocFromStream(fin, "empty.xml"); + REQUIRE_NOTHROW(readDialogueFromXml(move(doc), talk, 0)); + } + + SECTION("When a personality is missing an ID") { + fin.open("files/talk/who_missing_id.xml"); + doc = xmlDocFromStream(fin, "who_missing_id.xml"); + REQUIRE_THROWS_AS(readDialogueFromXml(move(doc), talk, 0), Exception); + } + SECTION("When a personality has an out-of-bounds ID") { + fin.open("files/talk/who_bad_id.xml"); + doc = xmlDocFromStream(fin, "who_bad_id.xml"); + REQUIRE_THROWS_AS(readDialogueFromXml(move(doc), talk, 0), xBadVal); + } + SECTION("When a personality is missing a required subtag") { + fin.open("files/talk/who_missing_req.xml"); + doc = xmlDocFromStream(fin, "who_missing_req.xml"); + REQUIRE_THROWS_AS(readDialogueFromXml(move(doc), talk, 0), xMissingElem); + } + SECTION("When a personality has an invalid subtag") { + fin.open("files/talk/who_bad_node.xml"); + doc = xmlDocFromStream(fin, "who_bad_node.xml"); + REQUIRE_THROWS_AS(readDialogueFromXml(move(doc), talk, 0), xBadNode); + } + + SECTION("When node has an invalid subtag") { + fin.open("files/talk/node_bad_node.xml"); + doc = xmlDocFromStream(fin, "node_bad_node.xml"); + REQUIRE_THROWS_AS(readDialogueFromXml(move(doc), talk, 0), xBadNode); + } + SECTION("When a node is missing the for attribute") { + fin.open("files/talk/node_missing_for.xml"); + doc = xmlDocFromStream(fin, "node_missing_for.xml"); + REQUIRE_THROWS_AS(readDialogueFromXml(move(doc), talk, 0), Exception); + } + SECTION("When a node is missing the subtag") { + fin.open("files/talk/node_missing_key.xml"); + doc = xmlDocFromStream(fin, "node_missing_key.xml"); + REQUIRE_THROWS_AS(readDialogueFromXml(move(doc), talk, 0), xMissingElem); + } + SECTION("When a node is missing the subtag") { + fin.open("files/talk/node_missing_type.xml"); + doc = xmlDocFromStream(fin, "node_missing_type.xml"); + REQUIRE_THROWS_AS(readDialogueFromXml(move(doc), talk, 0), xMissingElem); + } + SECTION("When a node is missing the subtag") { + fin.open("files/talk/node_missing_string.xml"); + doc = xmlDocFromStream(fin, "node_missing_string.xml"); + REQUIRE_THROWS_AS(readDialogueFromXml(move(doc), talk, 0), xMissingElem); + } + SECTION("When a node has too many keys") { + fin.open("files/talk/node_too_many_keys.xml"); + doc = xmlDocFromStream(fin, "node_too_many_keys.xml"); + REQUIRE_THROWS_AS(readDialogueFromXml(move(doc), talk, 0), xBadNode); + } + SECTION("When a node has too many params") { + fin.open("files/talk/node_too_many_params.xml"); + doc = xmlDocFromStream(fin, "node_too_many_params.xml"); + REQUIRE_THROWS_AS(readDialogueFromXml(move(doc), talk, 0), xBadNode); + } + SECTION("When a node has too many strings") { + fin.open("files/talk/node_too_many_strings.xml"); + doc = xmlDocFromStream(fin, "node_too_many_strings.xml"); + REQUIRE_THROWS_AS(readDialogueFromXml(move(doc), talk, 0), xBadNode); + } +} diff --git a/test/town_read.cpp b/test/town_read.cpp new file mode 100644 index 00000000..6a0a9aa9 --- /dev/null +++ b/test/town_read.cpp @@ -0,0 +1,131 @@ +// +// town_read.cpp +// BoE +// +// Created by Celtic Minstrel on 15-08-27. +// +// + +#include +#include "ticpp.h" +#include "catch.hpp" +#include "dialog.hpp" +#include "scenario.hpp" +#include "town.hpp" + +using namespace std; +using namespace ticpp; + +extern Document xmlDocFromStream(istream& stream, string name); +extern void readTownFromXml(Document&& data, cTown*& town, cScenario& scen); + +TEST_CASE("Loading a town definition") { + ifstream fin; + cScenario scen; + cTown* town = nullptr; + Document doc; + fin.exceptions(ios::badbit); + + SECTION("When the root tag is wrong") { + fin.open("files/bad_root.xml"); + doc = xmlDocFromStream(fin, "bad_root.xml"); + REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xBadNode); + } + SECTION("When the version attribute is missing") { + fin.open("files/town/no_version.xml"); + doc = xmlDocFromStream(fin, "no_version.xml"); + REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xMissingAttr); + } + SECTION("When the root tag has a bad attribute") { + fin.open("files/town/bad_root_attr.xml"); + doc = xmlDocFromStream(fin, "bad_root_attr.xml"); + REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xBadAttr); + } + SECTION("When an essential toplevel element is missing") { + fin.open("files/town/missing_toplevel.xml"); + doc = xmlDocFromStream(fin, "missing_toplevel.xml"); + REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xMissingElem); + } + SECTION("When the size is not first") { + fin.open("files/town/size_not_first.xml"); + doc = xmlDocFromStream(fin, "size_not_first.xml"); + REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xBadNode); + } + SECTION("When there is an invalid toplevel node") { + fin.open("files/town/bad_toplevel.xml"); + doc = xmlDocFromStream(fin, "bad_toplevel.xml"); + REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xBadNode); + } + SECTION("When there are too many comments") { + fin.open("files/town/too_many_comments.xml"); + doc = xmlDocFromStream(fin, "too_many_comments.xml"); + REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xBadNode); + } + SECTION("When the onenter condition is invalid") { + fin.open("files/town/bad_onenter_condition.xml"); + doc = xmlDocFromStream(fin, "bad_onenter_condition.xml"); + REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xBadVal); + } + SECTION("When the onexit direction is invalid") { + fin.open("files/town/bad_onexit_dir.xml"); + doc = xmlDocFromStream(fin, "bad_onexit_dir.xml"); + REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xBadVal); + } + SECTION("When the exit direction is invalid") { + fin.open("files/town/bad_exit_dir.xml"); + doc = xmlDocFromStream(fin, "bad_exit_dir.xml"); + REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xBadVal); + } + SECTION("When there are too many timers") { + fin.open("files/town/too_many_timers.xml"); + doc = xmlDocFromStream(fin, "too_many_timers.xml"); + REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xBadNode); + } + SECTION("When there is an invalid flag") { + fin.open("files/town/bad_flag.xml"); + doc = xmlDocFromStream(fin, "bad_flag.xml"); + REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xBadNode); + } + SECTION("When there is a bad wandering definition") { + fin.open("files/town/bad_wandering.xml"); + doc = xmlDocFromStream(fin, "bad_wandering.xml"); + REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xBadNode); + } + SECTION("When there is an empty wandering definition") { + fin.open("files/town/empty_wandering.xml"); + doc = xmlDocFromStream(fin, "empty_wandering.xml"); + REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xMissingElem); + } + SECTION("When there is a preset item with an invalid tag") { + fin.open("files/town/bad_item.xml"); + doc = xmlDocFromStream(fin, "bad_item.xml"); + REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xBadNode); + } + SECTION("When there is a preset item without a type") { + fin.open("files/town/empty_item.xml"); + doc = xmlDocFromStream(fin, "empty_item.xml"); + REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xMissingElem); + } + SECTION("When there is a preset creature with an invalid tag") { + fin.open("files/town/bad_creature.xml"); + doc = xmlDocFromStream(fin, "bad_creature.xml"); + REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xBadNode); + } + SECTION("When there is a preset creature without a type") { + fin.open("files/town/empty_creature.xml"); + doc = xmlDocFromStream(fin, "empty_creature.xml"); + REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xMissingElem); + } + SECTION("With the minimal required data") { + fin.open("files/town/minimal.xml"); + doc = xmlDocFromStream(fin, "minimal.xml"); + REQUIRE_NOTHROW(readTownFromXml(move(doc), town, scen)); + CHECK(town->max_dim() == 32); + CHECK(town->town_name == "Test Town"); + CHECK(town->in_town_rect == rect(4, 4, 28, 28)); + CHECK(town->difficulty == 1); + CHECK(town->lighting_type == LIGHT_NORMAL); + } + + delete town; +}