diff --git a/xml_converter/integration_tests/run_tests.py b/xml_converter/integration_tests/run_tests.py
index 4d99b9df..06c50c8a 100755
--- a/xml_converter/integration_tests/run_tests.py
+++ b/xml_converter/integration_tests/run_tests.py
@@ -20,6 +20,7 @@ def run_xml_converter(
input_proto: Optional[List[str]] = None,
output_proto: Optional[List[str]] = None,
split_output_proto: Optional[str] = None,
+ allow_duplicates: Optional[bool] = None,
) -> Tuple[str, str, int]:
# Build the command to execute the C++ program with the desired function and arguments
@@ -35,6 +36,8 @@ def run_xml_converter(
cmd += ["--output-guildpoint-path"] + output_proto
if split_output_proto:
cmd += ["--output-split-guildpoint-path"] + [split_output_proto]
+ if allow_duplicates:
+ cmd += ["--allow-duplicates"]
# Run the C++ program and capture its output
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
@@ -174,6 +177,7 @@ def main() -> bool:
input_proto=testcase.proto_input_paths,
output_xml=[xml_output_dir_path],
output_proto=[proto_output_dir_path],
+ allow_duplicates=testcase.allow_duplicates
)
# Sanitize and denoise the lines
@@ -206,8 +210,10 @@ def main() -> bool:
if testcase.expected_returncode is not None and testcase.expected_returncode != returncode:
print(f"Expected a return code of {testcase.expected_returncode} for {testcase.name} but got {returncode}")
- testcase_passed &= diff_dirs(xml_output_dir_path, testcase.expected_output_xml_path)
- testcase_passed &= diff_dirs(proto_output_dir_path, testcase.expected_output_proto_path)
+ if os.path.exists(testcase.expected_output_xml_path):
+ testcase_passed &= diff_dirs(xml_output_dir_path, testcase.expected_output_xml_path)
+ if os.path.exists(testcase.expected_output_proto_path):
+ testcase_passed &= diff_dirs(proto_output_dir_path, testcase.expected_output_proto_path)
if testcase_passed:
print(f"Success: test {testcase.name}")
diff --git a/xml_converter/integration_tests/src/testcase_loader.py b/xml_converter/integration_tests/src/testcase_loader.py
index aa85b442..b0d4394f 100644
--- a/xml_converter/integration_tests/src/testcase_loader.py
+++ b/xml_converter/integration_tests/src/testcase_loader.py
@@ -21,6 +21,7 @@ class Testcase:
expected_stdout: List[str]
expected_stderr: List[str]
expected_returncode: int
+ allow_duplicates: bool
################################################################################
@@ -58,6 +59,7 @@ def load_testcase(path: str) -> Optional[Testcase]:
# Load all of the input paths into either xml input or proto inputs
xml_input_paths: List[str] = []
proto_input_paths: List[str] = []
+ allow_duplicates: bool = False
for pack_name, pack_type in data["input_paths"].items():
if not isinstance(pack_name, str):
print(f"Invalid pack name, expecting a string but got {pack_name}")
@@ -104,6 +106,13 @@ def load_testcase(path: str) -> Optional[Testcase]:
print(f"Invalid Test, expecting string value for 'expected_returncode' in {path}")
return None
+ if "allow_duplicates" in data:
+ if not isinstance(data["allow_duplicates"], bool):
+ print(f"Invalid Test, expecting bool value for 'allow_duplicates' in {path}")
+ return None
+ else:
+ allow_duplicates = data["allow_duplicates"]
+
return Testcase(
name=os.path.basename(path),
xml_input_paths=xml_input_paths,
@@ -112,7 +121,8 @@ def load_testcase(path: str) -> Optional[Testcase]:
expected_output_proto_path=os.path.join(path, "output_proto"),
expected_stdout=to_lines(data["expected_stdout"]),
expected_stderr=to_lines(data["expected_stderr"]),
- expected_returncode=data["expected_returncode"]
+ expected_returncode=data["expected_returncode"],
+ allow_duplicates=allow_duplicates
)
diff --git a/xml_converter/integration_tests/test_cases/proto_and_xml_input_allow_duplicates/input/pack/xml_file.xml b/xml_converter/integration_tests/test_cases/proto_and_xml_input_allow_duplicates/input/pack/xml_file.xml
new file mode 100644
index 00000000..5cf29494
--- /dev/null
+++ b/xml_converter/integration_tests/test_cases/proto_and_xml_input_allow_duplicates/input/pack/xml_file.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/xml_converter/integration_tests/test_cases/proto_and_xml_input_allow_duplicates/input/pack2/markers.bin b/xml_converter/integration_tests/test_cases/proto_and_xml_input_allow_duplicates/input/pack2/markers.bin
new file mode 100644
index 00000000..50078921
--- /dev/null
+++ b/xml_converter/integration_tests/test_cases/proto_and_xml_input_allow_duplicates/input/pack2/markers.bin
@@ -0,0 +1,4 @@
+
++
+
+MyCategory 2B
\Ï)Cf¦RC{ÔWCB(èÌ“^–
\ No newline at end of file
diff --git a/xml_converter/integration_tests/test_cases/proto_and_xml_input_allow_duplicates/input/pack3/xml_file.xml b/xml_converter/integration_tests/test_cases/proto_and_xml_input_allow_duplicates/input/pack3/xml_file.xml
new file mode 100644
index 00000000..5cf29494
--- /dev/null
+++ b/xml_converter/integration_tests/test_cases/proto_and_xml_input_allow_duplicates/input/pack3/xml_file.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/xml_converter/integration_tests/test_cases/proto_and_xml_input_allow_duplicates/output_proto/markers.bin b/xml_converter/integration_tests/test_cases/proto_and_xml_input_allow_duplicates/output_proto/markers.bin
new file mode 100644
index 00000000..40148278
--- /dev/null
+++ b/xml_converter/integration_tests/test_cases/proto_and_xml_input_allow_duplicates/output_proto/markers.bin
@@ -0,0 +1,4 @@
+
+U
+
+MyCategory 2B
\Ï)Cf¦RC{ÔWC 2B
\Ï)Cf¦RC{ÔWC 2B
\Ï)Cf¦RC{ÔWCB(èÌ“^–
\ No newline at end of file
diff --git a/xml_converter/integration_tests/test_cases/proto_and_xml_input_allow_duplicates/output_xml/xml_file.xml b/xml_converter/integration_tests/test_cases/proto_and_xml_input_allow_duplicates/output_xml/xml_file.xml
new file mode 100644
index 00000000..3638e1e3
--- /dev/null
+++ b/xml_converter/integration_tests/test_cases/proto_and_xml_input_allow_duplicates/output_xml/xml_file.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/xml_converter/integration_tests/test_cases/proto_and_xml_input_allow_duplicates/testcase.yaml b/xml_converter/integration_tests/test_cases/proto_and_xml_input_allow_duplicates/testcase.yaml
new file mode 100644
index 00000000..348087c5
--- /dev/null
+++ b/xml_converter/integration_tests/test_cases/proto_and_xml_input_allow_duplicates/testcase.yaml
@@ -0,0 +1,8 @@
+input_paths:
+ "pack": "xml"
+ "pack2": "proto"
+ "pack3": "xml"
+expected_stdout: |
+expected_stderr: |
+expected_returncode: 0
+allow_duplicates: true
\ No newline at end of file
diff --git a/xml_converter/integration_tests/test_cases/proto_and_xml_input_no_duplicates/input/pack/xml_file.xml b/xml_converter/integration_tests/test_cases/proto_and_xml_input_no_duplicates/input/pack/xml_file.xml
new file mode 100644
index 00000000..5cf29494
--- /dev/null
+++ b/xml_converter/integration_tests/test_cases/proto_and_xml_input_no_duplicates/input/pack/xml_file.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/xml_converter/integration_tests/test_cases/proto_and_xml_input_no_duplicates/input/pack2/markers.bin b/xml_converter/integration_tests/test_cases/proto_and_xml_input_no_duplicates/input/pack2/markers.bin
new file mode 100644
index 00000000..50078921
--- /dev/null
+++ b/xml_converter/integration_tests/test_cases/proto_and_xml_input_no_duplicates/input/pack2/markers.bin
@@ -0,0 +1,4 @@
+
++
+
+MyCategory 2B
\Ï)Cf¦RC{ÔWCB(èÌ“^–
\ No newline at end of file
diff --git a/xml_converter/integration_tests/test_cases/proto_and_xml_input_no_duplicates/input/pack3/xml_file.xml b/xml_converter/integration_tests/test_cases/proto_and_xml_input_no_duplicates/input/pack3/xml_file.xml
new file mode 100644
index 00000000..5cf29494
--- /dev/null
+++ b/xml_converter/integration_tests/test_cases/proto_and_xml_input_no_duplicates/input/pack3/xml_file.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/xml_converter/integration_tests/test_cases/proto_and_xml_input_no_duplicates/testcase.yaml b/xml_converter/integration_tests/test_cases/proto_and_xml_input_no_duplicates/testcase.yaml
new file mode 100644
index 00000000..9f5d0f93
--- /dev/null
+++ b/xml_converter/integration_tests/test_cases/proto_and_xml_input_no_duplicates/testcase.yaml
@@ -0,0 +1,16 @@
+input_paths:
+ "pack": "xml"
+ "pack2": "proto"
+ "pack3": "xml"
+expected_stdout: |
+ Did not write due to duplicates in categories.
+ This commonly occurs when attempting to read the same pack multiple times or when separate packs coincidentally have the same name.
+ Please remove one of the packs or edit the name of the packs' top level category before running the program again.
+ If you want to bypass this stop, use '--allow-duplicates'.
+ The following top level categories were found in more than one pack:
+ "mycategory" in files:
+ pack/xml_file.xml
+ pack2/markers.bin
+ pack3/xml_file.xml
+expected_stderr: |
+expected_returncode: 0
\ No newline at end of file
diff --git a/xml_converter/src/packaging_protobin.cpp b/xml_converter/src/packaging_protobin.cpp
index f4b636f5..00179a41 100644
--- a/xml_converter/src/packaging_protobin.cpp
+++ b/xml_converter/src/packaging_protobin.cpp
@@ -23,7 +23,7 @@ using namespace std;
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
-void parse_guildpoint_categories(
+string parse_guildpoint_categories(
string full_category_name,
::guildpoint::Category proto_category,
map* marker_categories,
@@ -57,16 +57,18 @@ void parse_guildpoint_categories(
for (int i = 0; i < proto_category.children_size(); i++) {
parse_guildpoint_categories(full_category_name + ".", proto_category.children(i), &(this_category->children), parsed_pois, state);
}
+ return category_name;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
-void read_protobuf_file(string proto_filepath, const string marker_pack_root_directory, map* marker_categories, vector* parsed_pois) {
+set read_protobuf_file(string proto_filepath, const string marker_pack_root_directory, map* marker_categories, vector* parsed_pois) {
fstream infile;
guildpoint::Guildpoint proto_message;
ProtoReaderState state;
state.marker_pack_root_directory = marker_pack_root_directory;
+ set category_names;
infile.open(proto_filepath, ios::in | ios::binary);
proto_message.ParseFromIstream(&infile);
@@ -74,8 +76,9 @@ void read_protobuf_file(string proto_filepath, const string marker_pack_root_dir
state.textures = proto_message.textures();
for (int i = 0; i < proto_message.category_size(); i++) {
- parse_guildpoint_categories("", proto_message.category(i), marker_categories, parsed_pois, &state);
+ category_names.insert(parse_guildpoint_categories("", proto_message.category(i), marker_categories, parsed_pois, &state));
}
+ return category_names;
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/xml_converter/src/packaging_protobin.hpp b/xml_converter/src/packaging_protobin.hpp
index 9cdc27a4..6b66cfa5 100644
--- a/xml_converter/src/packaging_protobin.hpp
+++ b/xml_converter/src/packaging_protobin.hpp
@@ -2,6 +2,7 @@
#include
#include