diff --git a/dist/datamodel/parser/ProjectParser.d.ts.map b/dist/datamodel/parser/ProjectParser.d.ts.map
index c501e88..ab0395b 100644
--- a/dist/datamodel/parser/ProjectParser.d.ts.map
+++ b/dist/datamodel/parser/ProjectParser.d.ts.map
@@ -1 +1 @@
-{"version":3,"file":"ProjectParser.d.ts","sourceRoot":"","sources":["../../../src/datamodel/parser/ProjectParser.ts"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEhE,gDAAgD;AAChD,MAAM,WAAW,WAAW;IAC1B,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,yDAAyD;IACzD,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,yEAAyE;AACzE,MAAM,WAAW,YAAY;IAC3B,+EAA+E;IAC/E,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,sCAAsC;AACtC,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB;;;;;;;;OAQG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,2DAA2D;IAC3D,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,uFAAuF;IACvF,IAAI,EAAE,MAAM,CAAC;IACb,6FAA6F;IAC7F,OAAO,EAAE,OAAO,CAAC;IACjB,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,8CAA8C;AAC9C,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB;;;;OAIG;IACH,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,oDAAoD;IACpD,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B;;;;;OAKG;IACH,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,gBAAgB,EAAE,sBAAsB,EAAE,CAAC;IAC3C,cAAc,EAAE,oBAAoB,EAAE,CAAC;IACvC;;;;OAIG;IACH,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAkJD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,MAAM,GAAG,aAAa,CA8K9F"}
\ No newline at end of file
+{"version":3,"file":"ProjectParser.d.ts","sourceRoot":"","sources":["../../../src/datamodel/parser/ProjectParser.ts"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEhE,gDAAgD;AAChD,MAAM,WAAW,WAAW;IAC1B,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,yDAAyD;IACzD,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,yEAAyE;AACzE,MAAM,WAAW,YAAY;IAC3B,+EAA+E;IAC/E,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,sCAAsC;AACtC,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB;;;;;;;;OAQG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,2DAA2D;IAC3D,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,uFAAuF;IACvF,IAAI,EAAE,MAAM,CAAC;IACb,6FAA6F;IAC7F,OAAO,EAAE,OAAO,CAAC;IACjB,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,8CAA8C;AAC9C,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB;;;;OAIG;IACH,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,oDAAoD;IACpD,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B;;;;;OAKG;IACH,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,gBAAgB,EAAE,sBAAsB,EAAE,CAAC;IAC3C,cAAc,EAAE,oBAAoB,EAAE,CAAC;IACvC;;;;OAIG;IACH,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAkJD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,MAAM,GAAG,aAAa,CA8L9F"}
\ No newline at end of file
diff --git a/dist/datamodel/parser/ProjectParser.js b/dist/datamodel/parser/ProjectParser.js
index 2973c01..7d8342e 100644
--- a/dist/datamodel/parser/ProjectParser.js
+++ b/dist/datamodel/parser/ProjectParser.js
@@ -215,6 +215,20 @@ export function parseProject(files, projectName) {
}
result.files.sort((a, b) => a.path.localeCompare(b.path));
result.pathFolders.sort((a, b) => a.localeCompare(b));
+ // The same reason as those two, reached by the parity corpus rather than by a
+ // customer: a store's order is its DIRECTORY order, so one project converted
+ // between metadata layouts handed the page its label catalog and its working
+ // folders in two different orders. Neither carries an order worth keeping — the
+ // catalog is a set, which the page re-sorts by use anyway, and the working
+ // folders are keyed by purpose — so they are made deterministic here, where the
+ // layouts meet, instead of in each consumer.
+ //
+ // NOT the entry points, which are in run order (`orderEntryPoints`), and not
+ // the references, whose store order has not been measured against the order
+ // MATLAB reports; sorting either would be inventing an order rather than
+ // settling one.
+ result.labels.sort((a, b) => a.category.localeCompare(b.category) || a.name.localeCompare(b.name));
+ result.workingFolders.sort((a, b) => a.key.localeCompare(b.key));
return result;
}
catch (err) {
@@ -721,11 +735,14 @@ function readCategories(layout, collection) {
const id = labelEnt.location || '';
const name = labelEnt.def?.['@_Name'] || id || '';
if (name) {
- // The attribute spells itself 'READ_ONLY' on a label and '1' on a category,
- // so this tests for PRESENCE rather than for a value — both mean MATLAB owns
- // it, and a project's own label carries no such marking.
+ // The attribute has its own vocabulary per element — 'READ_ONLY'/'WRITABLE'
+ // on a label, '1'/'0' on a category — so test the AFFIRMATIVE values, not
+ // presence. Presence was the old rule, and a real project's `WRITABLE`
+ // disproved it: the label a user added read back as one of MATLAB's own,
+ // which the project page draws as a built-in. A missing attribute is
+ // writable, which is how a hand-made label in an older store spells it.
const ro = labelEnt.def?.['@_ReadOnly'];
- out.push({ id, category: categoryName, name, readOnly: ro !== undefined && ro !== '0' });
+ out.push({ id, category: categoryName, name, readOnly: ro === 'READ_ONLY' || ro === '1' });
}
}
}
@@ -812,13 +829,22 @@ function readWorkingFolders(layout, collection) {
*
* The store encodes the order as a linked list, and only as one: each entry names
* its PREDECESSOR in a nested ``, with `HEAD` marking the first. MATLAB runs the files top-down,
- * so this order is meaningful and no other field recovers it — sorting these by
- * name would silently reorder a shutdown sequence.
+ * Value=""/>`. MATLAB runs the files top-down, so this order is meaningful
+ * and no other field recovers it — sorting these by name would silently reorder a
+ * shutdown sequence.
+ *
+ * THE FIRST ENTRY IS SPELLED TWO WAYS, and that is the whole difficulty. A
+ * long-lived project says `Value="HEAD"` explicitly; a project that just added two
+ * startup files and never reordered them writes no Extension on the first one at
+ * all, and only the SECOND entry carries a link. So "first" is not a value to look
+ * for, it is a position: an entry no other entry of its kind points at. Reading
+ * `HEAD` as the only head left every project of the second shape in document
+ * order, which is the order the store happens to serialize UUIDs in — reversed, in
+ * the parity fixture, against the order MATLAB reports running them.
*
- * Everything unchained keeps its store order and follows: a project with one
- * startup file writes no Extension at all, and a chain that is broken (a missing
- * predecessor, a cycle) must still yield every entry exactly once.
+ * Everything the chains do not reach keeps its store order and follows, so a
+ * broken chain (a missing predecessor, a cycle) still yields every entry exactly
+ * once.
*/
function orderEntryPoints(entries) {
const out = [];
@@ -838,26 +864,32 @@ function orderEntryPoints(entries) {
byPrev.set(e.prev, [e]);
}
}
- // Follow the chain from HEAD. `taken` is what makes this terminate on a cycle:
- // a store whose links form a loop would otherwise spin here forever.
- let cursor = 'HEAD';
- for (;;) {
- const step = (byPrev.get(cursor) ?? []).find((e) => !taken.has(e));
- if (!step) {
- break;
+ const take = (e) => {
+ if (taken.has(e)) {
+ return false;
+ }
+ taken.add(e);
+ out.push(e);
+ return true;
+ };
+ // Every head, in store order, each followed to the end of its chain. A head is
+ // an entry whose `prev` names no entry of this kind: `HEAD`, the empty string,
+ // and a dangling UUID all say the same thing about where it sits. `taken` is
+ // what makes this terminate on a cycle, which nothing in the store prevents.
+ const ids = new Set(hook.map((e) => e.id));
+ for (const head of hook) {
+ if (ids.has(head.prev)) {
+ continue;
+ }
+ let cursor = head;
+ while (cursor && take(cursor)) {
+ cursor = (byPrev.get(cursor.id) ?? []).find((e) => !taken.has(e));
}
- taken.add(step);
- out.push(step);
- cursor = step.id;
}
- // Whatever the chain did not reach, in store order. A project with a single
- // startup file writes no Extension at all and lands here — which is why the
- // fallback is not an error path but the common one.
+ // Whatever is left is in a cycle: no head reaches it. Store order, so it is
+ // reported rather than dropped.
for (const e of hook) {
- if (!taken.has(e)) {
- taken.add(e);
- out.push(e);
- }
+ take(e);
}
}
// Then the shortcuts, which have no order to preserve beyond the store's.
diff --git a/dist/datamodel/parser/ProjectParser.js.map b/dist/datamodel/parser/ProjectParser.js.map
index b123269..4653a58 100644
--- a/dist/datamodel/parser/ProjectParser.js.map
+++ b/dist/datamodel/parser/ProjectParser.js.map
@@ -1 +1 @@
-{"version":3,"file":"ProjectParser.js","sourceRoot":"","sources":["../../../src/datamodel/parser/ProjectParser.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"ProjectParser.js","sourceRoot":"","sources":["../../../src/datamodel/parser/ProjectParser.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/src/datamodel/parser/ProjectParser.ts b/src/datamodel/parser/ProjectParser.ts
index 685842e..5fc6644 100644
--- a/src/datamodel/parser/ProjectParser.ts
+++ b/src/datamodel/parser/ProjectParser.ts
@@ -436,6 +436,22 @@ export function parseProject(files: Record, projectName: string)
result.files.sort((a, b) => a.path.localeCompare(b.path));
result.pathFolders.sort((a, b) => a.localeCompare(b));
+ // The same reason as those two, reached by the parity corpus rather than by a
+ // customer: a store's order is its DIRECTORY order, so one project converted
+ // between metadata layouts handed the page its label catalog and its working
+ // folders in two different orders. Neither carries an order worth keeping — the
+ // catalog is a set, which the page re-sorts by use anyway, and the working
+ // folders are keyed by purpose — so they are made deterministic here, where the
+ // layouts meet, instead of in each consumer.
+ //
+ // NOT the entry points, which are in run order (`orderEntryPoints`), and not
+ // the references, whose store order has not been measured against the order
+ // MATLAB reports; sorting either would be inventing an order rather than
+ // settling one.
+ result.labels.sort(
+ (a, b) => a.category.localeCompare(b.category) || a.name.localeCompare(b.name),
+ );
+ result.workingFolders.sort((a, b) => a.key.localeCompare(b.key));
return result;
} catch (err) {
@@ -985,11 +1001,14 @@ function readCategories(layout: Layout, collection: Entity): ProjectLabel[] {
const id = labelEnt.location || '';
const name = labelEnt.def?.['@_Name'] || id || '';
if (name) {
- // The attribute spells itself 'READ_ONLY' on a label and '1' on a category,
- // so this tests for PRESENCE rather than for a value — both mean MATLAB owns
- // it, and a project's own label carries no such marking.
+ // The attribute has its own vocabulary per element — 'READ_ONLY'/'WRITABLE'
+ // on a label, '1'/'0' on a category — so test the AFFIRMATIVE values, not
+ // presence. Presence was the old rule, and a real project's `WRITABLE`
+ // disproved it: the label a user added read back as one of MATLAB's own,
+ // which the project page draws as a built-in. A missing attribute is
+ // writable, which is how a hand-made label in an older store spells it.
const ro = labelEnt.def?.['@_ReadOnly'];
- out.push({ id, category: categoryName, name, readOnly: ro !== undefined && ro !== '0' });
+ out.push({ id, category: categoryName, name, readOnly: ro === 'READ_ONLY' || ro === '1' });
}
}
}
@@ -1094,13 +1113,22 @@ function readWorkingFolders(layout: Layout, collection: Entity): ProjectWorkingF
*
* The store encodes the order as a linked list, and only as one: each entry names
* its PREDECESSOR in a nested ``, with `HEAD` marking the first. MATLAB runs the files top-down,
- * so this order is meaningful and no other field recovers it — sorting these by
- * name would silently reorder a shutdown sequence.
+ * Value=""/>`. MATLAB runs the files top-down, so this order is meaningful
+ * and no other field recovers it — sorting these by name would silently reorder a
+ * shutdown sequence.
+ *
+ * THE FIRST ENTRY IS SPELLED TWO WAYS, and that is the whole difficulty. A
+ * long-lived project says `Value="HEAD"` explicitly; a project that just added two
+ * startup files and never reordered them writes no Extension on the first one at
+ * all, and only the SECOND entry carries a link. So "first" is not a value to look
+ * for, it is a position: an entry no other entry of its kind points at. Reading
+ * `HEAD` as the only head left every project of the second shape in document
+ * order, which is the order the store happens to serialize UUIDs in — reversed, in
+ * the parity fixture, against the order MATLAB reports running them.
*
- * Everything unchained keeps its store order and follows: a project with one
- * startup file writes no Extension at all, and a chain that is broken (a missing
- * predecessor, a cycle) must still yield every entry exactly once.
+ * Everything the chains do not reach keeps its store order and follows, so a
+ * broken chain (a missing predecessor, a cycle) still yields every entry exactly
+ * once.
*/
function orderEntryPoints(entries: ChainedEntryPoint[]): ProjectEntryPoint[] {
const out: ChainedEntryPoint[] = [];
@@ -1122,27 +1150,34 @@ function orderEntryPoints(entries: ChainedEntryPoint[]): ProjectEntryPoint[] {
}
}
- // Follow the chain from HEAD. `taken` is what makes this terminate on a cycle:
- // a store whose links form a loop would otherwise spin here forever.
- let cursor = 'HEAD';
- for (;;) {
- const step = (byPrev.get(cursor) ?? []).find((e) => !taken.has(e));
- if (!step) {
- break;
+ const take = (e: ChainedEntryPoint): boolean => {
+ if (taken.has(e)) {
+ return false;
+ }
+ taken.add(e);
+ out.push(e);
+ return true;
+ };
+
+ // Every head, in store order, each followed to the end of its chain. A head is
+ // an entry whose `prev` names no entry of this kind: `HEAD`, the empty string,
+ // and a dangling UUID all say the same thing about where it sits. `taken` is
+ // what makes this terminate on a cycle, which nothing in the store prevents.
+ const ids = new Set(hook.map((e) => e.id));
+ for (const head of hook) {
+ if (ids.has(head.prev)) {
+ continue;
+ }
+ let cursor: ChainedEntryPoint | undefined = head;
+ while (cursor && take(cursor)) {
+ cursor = (byPrev.get(cursor.id) ?? []).find((e) => !taken.has(e));
}
- taken.add(step);
- out.push(step);
- cursor = step.id;
}
- // Whatever the chain did not reach, in store order. A project with a single
- // startup file writes no Extension at all and lands here — which is why the
- // fallback is not an error path but the common one.
+ // Whatever is left is in a cycle: no head reaches it. Store order, so it is
+ // reported rather than dropped.
for (const e of hook) {
- if (!taken.has(e)) {
- taken.add(e);
- out.push(e);
- }
+ take(e);
}
}
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/libfun.m b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/libfun.m
new file mode 100644
index 0000000..6f9f9f3
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/libfun.m
@@ -0,0 +1,3 @@
+function y = libfun(x)
+y = 2 * x;
+end
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/parityLib.prj b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/parityLib.prj
new file mode 100644
index 0000000..6b95f98
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/parityLib.prj
@@ -0,0 +1,2 @@
+
+
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml
new file mode 100644
index 0000000..6d1c43c
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml
new file mode 100644
index 0000000..e993c77
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml
new file mode 100644
index 0000000..d47011f
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml
new file mode 100644
index 0000000..91b0acc
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml
new file mode 100644
index 0000000..6c16a34
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml
new file mode 100644
index 0000000..76301e1
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml
new file mode 100644
index 0000000..e228479
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml
new file mode 100644
index 0000000..958c22f
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml
new file mode 100644
index 0000000..b5689bd
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml
new file mode 100644
index 0000000..ffb1fe8
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml
new file mode 100644
index 0000000..646977e
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml
new file mode 100644
index 0000000..2e052d9
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml
new file mode 100644
index 0000000..c67e567
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml
new file mode 100644
index 0000000..880a245
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/Project.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/Project.xml
new file mode 100644
index 0000000..62d05aa
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/Project.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml
new file mode 100644
index 0000000..5de8c3e
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml
new file mode 100644
index 0000000..642c7d7
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYd.xml
new file mode 100644
index 0000000..99772b4
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYd.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYp.xml
new file mode 100644
index 0000000..d1023af
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml
new file mode 100644
index 0000000..7b38161
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml
new file mode 100644
index 0000000..2037c33
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml
new file mode 100644
index 0000000..a4de013
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml
new file mode 100644
index 0000000..8b0d336
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/rootp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/rootp.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityLib/resources/project/rootp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/main.m b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/main.m
new file mode 100644
index 0000000..a1bcf13
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/main.m
@@ -0,0 +1 @@
+disp(helper(1));
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/parityProject.prj b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/parityProject.prj
new file mode 100644
index 0000000..6b95f98
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/parityProject.prj
@@ -0,0 +1,2 @@
+
+
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/-V17xoKMQuak4-chxc1ixTLv0tA/8AEHllJDJXphBkrgA4Qqq-Hbo_sd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/-V17xoKMQuak4-chxc1ixTLv0tA/8AEHllJDJXphBkrgA4Qqq-Hbo_sd.xml
new file mode 100644
index 0000000..433a488
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/-V17xoKMQuak4-chxc1ixTLv0tA/8AEHllJDJXphBkrgA4Qqq-Hbo_sd.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/-V17xoKMQuak4-chxc1ixTLv0tA/8AEHllJDJXphBkrgA4Qqq-Hbo_sp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/-V17xoKMQuak4-chxc1ixTLv0tA/8AEHllJDJXphBkrgA4Qqq-Hbo_sp.xml
new file mode 100644
index 0000000..e46e264
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/-V17xoKMQuak4-chxc1ixTLv0tA/8AEHllJDJXphBkrgA4Qqq-Hbo_sp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/-V17xoKMQuak4-chxc1ixTLv0tA/QJOBPzj8Qgmn1nMVM7YX0Z_g6ysd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/-V17xoKMQuak4-chxc1ixTLv0tA/QJOBPzj8Qgmn1nMVM7YX0Z_g6ysd.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/-V17xoKMQuak4-chxc1ixTLv0tA/QJOBPzj8Qgmn1nMVM7YX0Z_g6ysd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/-V17xoKMQuak4-chxc1ixTLv0tA/QJOBPzj8Qgmn1nMVM7YX0Z_g6ysp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/-V17xoKMQuak4-chxc1ixTLv0tA/QJOBPzj8Qgmn1nMVM7YX0Z_g6ysp.xml
new file mode 100644
index 0000000..01cb34e
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/-V17xoKMQuak4-chxc1ixTLv0tA/QJOBPzj8Qgmn1nMVM7YX0Z_g6ysp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/-V17xoKMQuak4-chxc1ixTLv0tA/pCZlF_r6fbK3kBK8Jml8wIg--rgd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/-V17xoKMQuak4-chxc1ixTLv0tA/pCZlF_r6fbK3kBK8Jml8wIg--rgd.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/-V17xoKMQuak4-chxc1ixTLv0tA/pCZlF_r6fbK3kBK8Jml8wIg--rgd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/-V17xoKMQuak4-chxc1ixTLv0tA/pCZlF_r6fbK3kBK8Jml8wIg--rgp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/-V17xoKMQuak4-chxc1ixTLv0tA/pCZlF_r6fbK3kBK8Jml8wIg--rgp.xml
new file mode 100644
index 0000000..5c82a89
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/-V17xoKMQuak4-chxc1ixTLv0tA/pCZlF_r6fbK3kBK8Jml8wIg--rgp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/0wBrfUYH12txqGQlqTasCq6h2rM/GT7H0L7Cx9NwSymJ505c2XxuFYQd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/0wBrfUYH12txqGQlqTasCq6h2rM/GT7H0L7Cx9NwSymJ505c2XxuFYQd.xml
new file mode 100644
index 0000000..88de170
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/0wBrfUYH12txqGQlqTasCq6h2rM/GT7H0L7Cx9NwSymJ505c2XxuFYQd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/0wBrfUYH12txqGQlqTasCq6h2rM/GT7H0L7Cx9NwSymJ505c2XxuFYQp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/0wBrfUYH12txqGQlqTasCq6h2rM/GT7H0L7Cx9NwSymJ505c2XxuFYQp.xml
new file mode 100644
index 0000000..472dc38
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/0wBrfUYH12txqGQlqTasCq6h2rM/GT7H0L7Cx9NwSymJ505c2XxuFYQp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/8AEHllJDJXphBkrgA4Qqq-Hbo_s/HXw-aa_dKmWJTze_SHyCBePfg_Qd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/8AEHllJDJXphBkrgA4Qqq-Hbo_s/HXw-aa_dKmWJTze_SHyCBePfg_Qd.xml
new file mode 100644
index 0000000..6d15772
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/8AEHllJDJXphBkrgA4Qqq-Hbo_s/HXw-aa_dKmWJTze_SHyCBePfg_Qd.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/8AEHllJDJXphBkrgA4Qqq-Hbo_s/HXw-aa_dKmWJTze_SHyCBePfg_Qp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/8AEHllJDJXphBkrgA4Qqq-Hbo_s/HXw-aa_dKmWJTze_SHyCBePfg_Qp.xml
new file mode 100644
index 0000000..a2c539d
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/8AEHllJDJXphBkrgA4Qqq-Hbo_s/HXw-aa_dKmWJTze_SHyCBePfg_Qp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/RFhxTIcnB4SmlYBV8Mhhn0LDEK0d.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/RFhxTIcnB4SmlYBV8Mhhn0LDEK0d.xml
new file mode 100644
index 0000000..7e58203
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/RFhxTIcnB4SmlYBV8Mhhn0LDEK0d.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/RFhxTIcnB4SmlYBV8Mhhn0LDEK0p.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/RFhxTIcnB4SmlYBV8Mhhn0LDEK0p.xml
new file mode 100644
index 0000000..742bc78
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/EEtUlUb-dLAdf0KpMVivaUlztwA/RFhxTIcnB4SmlYBV8Mhhn0LDEK0p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/6BwEprUVE4ubLW7PJcyabNP9H5cd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/6BwEprUVE4ubLW7PJcyabNP9H5cd.xml
new file mode 100644
index 0000000..add4fe8
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/6BwEprUVE4ubLW7PJcyabNP9H5cd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/6BwEprUVE4ubLW7PJcyabNP9H5cp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/6BwEprUVE4ubLW7PJcyabNP9H5cp.xml
new file mode 100644
index 0000000..b499a35
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/6BwEprUVE4ubLW7PJcyabNP9H5cp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/G-OfIEAKTuhY9ysKLyFN3FrbydMd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/G-OfIEAKTuhY9ysKLyFN3FrbydMd.xml
new file mode 100644
index 0000000..27ba58c
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/G-OfIEAKTuhY9ysKLyFN3FrbydMd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/G-OfIEAKTuhY9ysKLyFN3FrbydMp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/G-OfIEAKTuhY9ysKLyFN3FrbydMp.xml
new file mode 100644
index 0000000..26581b8
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/G-OfIEAKTuhY9ysKLyFN3FrbydMp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/LeJ3wPMJN0YXjVfnyfjZbOkHKVMd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/LeJ3wPMJN0YXjVfnyfjZbOkHKVMd.xml
new file mode 100644
index 0000000..8da7b10
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/LeJ3wPMJN0YXjVfnyfjZbOkHKVMd.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/LeJ3wPMJN0YXjVfnyfjZbOkHKVMp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/LeJ3wPMJN0YXjVfnyfjZbOkHKVMp.xml
new file mode 100644
index 0000000..ffc6fbe
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/LeJ3wPMJN0YXjVfnyfjZbOkHKVMp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/n4JI-XBe6t9pyv2JlWznnUrJNpUd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/n4JI-XBe6t9pyv2JlWznnUrJNpUd.xml
new file mode 100644
index 0000000..721a0a9
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/n4JI-XBe6t9pyv2JlWznnUrJNpUd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/n4JI-XBe6t9pyv2JlWznnUrJNpUp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/n4JI-XBe6t9pyv2JlWznnUrJNpUp.xml
new file mode 100644
index 0000000..d58ecd4
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/KAXfQgCar2Yb8zOxgvf9hdmLP1E/n4JI-XBe6t9pyv2JlWznnUrJNpUp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/LUgSFhI3RPozNzNcutxrczVe6f0/UEIbeCoUPj-6Yix6-tWm7uyxV48d.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/LUgSFhI3RPozNzNcutxrczVe6f0/UEIbeCoUPj-6Yix6-tWm7uyxV48d.xml
new file mode 100644
index 0000000..95adee3
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/LUgSFhI3RPozNzNcutxrczVe6f0/UEIbeCoUPj-6Yix6-tWm7uyxV48d.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/LUgSFhI3RPozNzNcutxrczVe6f0/UEIbeCoUPj-6Yix6-tWm7uyxV48p.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/LUgSFhI3RPozNzNcutxrczVe6f0/UEIbeCoUPj-6Yix6-tWm7uyxV48p.xml
new file mode 100644
index 0000000..3e928e1
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/LUgSFhI3RPozNzNcutxrczVe6f0/UEIbeCoUPj-6Yix6-tWm7uyxV48p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml
new file mode 100644
index 0000000..6d1c43c
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml
new file mode 100644
index 0000000..e993c77
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml
new file mode 100644
index 0000000..d47011f
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml
new file mode 100644
index 0000000..91b0acc
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml
new file mode 100644
index 0000000..6c16a34
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml
new file mode 100644
index 0000000..76301e1
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml
new file mode 100644
index 0000000..e228479
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml
new file mode 100644
index 0000000..958c22f
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml
new file mode 100644
index 0000000..b5689bd
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml
new file mode 100644
index 0000000..ffb1fe8
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml
new file mode 100644
index 0000000..646977e
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml
new file mode 100644
index 0000000..2e052d9
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml
new file mode 100644
index 0000000..c67e567
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml
new file mode 100644
index 0000000..880a245
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/Project.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/Project.xml
new file mode 100644
index 0000000..62d05aa
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/Project.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/WZRuNzqc-Db7NcQAZO8Y-R8U9cc/66WgGCcF5RIH9MCEgPmgjZK9k3Ud.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/WZRuNzqc-Db7NcQAZO8Y-R8U9cc/66WgGCcF5RIH9MCEgPmgjZK9k3Ud.xml
new file mode 100644
index 0000000..124d4e7
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/WZRuNzqc-Db7NcQAZO8Y-R8U9cc/66WgGCcF5RIH9MCEgPmgjZK9k3Ud.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/WZRuNzqc-Db7NcQAZO8Y-R8U9cc/66WgGCcF5RIH9MCEgPmgjZK9k3Up.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/WZRuNzqc-Db7NcQAZO8Y-R8U9cc/66WgGCcF5RIH9MCEgPmgjZK9k3Up.xml
new file mode 100644
index 0000000..2fa153b
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/WZRuNzqc-Db7NcQAZO8Y-R8U9cc/66WgGCcF5RIH9MCEgPmgjZK9k3Up.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/WZRuNzqc-Db7NcQAZO8Y-R8U9cc/AtMjXDrOSm8YDv3_4UFXiyrWqNEd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/WZRuNzqc-Db7NcQAZO8Y-R8U9cc/AtMjXDrOSm8YDv3_4UFXiyrWqNEd.xml
new file mode 100644
index 0000000..c8bf92f
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/WZRuNzqc-Db7NcQAZO8Y-R8U9cc/AtMjXDrOSm8YDv3_4UFXiyrWqNEd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/WZRuNzqc-Db7NcQAZO8Y-R8U9cc/AtMjXDrOSm8YDv3_4UFXiyrWqNEp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/WZRuNzqc-Db7NcQAZO8Y-R8U9cc/AtMjXDrOSm8YDv3_4UFXiyrWqNEp.xml
new file mode 100644
index 0000000..0a55665
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/WZRuNzqc-Db7NcQAZO8Y-R8U9cc/AtMjXDrOSm8YDv3_4UFXiyrWqNEp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/WZRuNzqc-Db7NcQAZO8Y-R8U9cc/haUKcDd7PrBH5j2sypBgBtW0rIcd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/WZRuNzqc-Db7NcQAZO8Y-R8U9cc/haUKcDd7PrBH5j2sypBgBtW0rIcd.xml
new file mode 100644
index 0000000..7e58203
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/WZRuNzqc-Db7NcQAZO8Y-R8U9cc/haUKcDd7PrBH5j2sypBgBtW0rIcd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/WZRuNzqc-Db7NcQAZO8Y-R8U9cc/haUKcDd7PrBH5j2sypBgBtW0rIcp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/WZRuNzqc-Db7NcQAZO8Y-R8U9cc/haUKcDd7PrBH5j2sypBgBtW0rIcp.xml
new file mode 100644
index 0000000..35ed9f5
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/WZRuNzqc-Db7NcQAZO8Y-R8U9cc/haUKcDd7PrBH5j2sypBgBtW0rIcp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/0wBrfUYH12txqGQlqTasCq6h2rMd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/0wBrfUYH12txqGQlqTasCq6h2rMd.xml
new file mode 100644
index 0000000..0f572ee
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/0wBrfUYH12txqGQlqTasCq6h2rMd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/0wBrfUYH12txqGQlqTasCq6h2rMp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/0wBrfUYH12txqGQlqTasCq6h2rMp.xml
new file mode 100644
index 0000000..a61a6a8
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/0wBrfUYH12txqGQlqTasCq6h2rMp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml
new file mode 100644
index 0000000..5de8c3e
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml
new file mode 100644
index 0000000..642c7d7
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/-V17xoKMQuak4-chxc1ixTLv0tAd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/-V17xoKMQuak4-chxc1ixTLv0tAd.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/-V17xoKMQuak4-chxc1ixTLv0tAd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/-V17xoKMQuak4-chxc1ixTLv0tAp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/-V17xoKMQuak4-chxc1ixTLv0tAp.xml
new file mode 100644
index 0000000..6135b61
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/-V17xoKMQuak4-chxc1ixTLv0tAp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QigB_2yZP_51Nh6hTaUq-xislFcd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QigB_2yZP_51Nh6hTaUq-xislFcd.xml
new file mode 100644
index 0000000..99772b4
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QigB_2yZP_51Nh6hTaUq-xislFcd.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QigB_2yZP_51Nh6hTaUq-xislFcp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QigB_2yZP_51Nh6hTaUq-xislFcp.xml
new file mode 100644
index 0000000..1575424
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QigB_2yZP_51Nh6hTaUq-xislFcp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/YE3xmkEYrsw1taWwfDp9CNw56RAd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/YE3xmkEYrsw1taWwfDp9CNw56RAd.xml
new file mode 100644
index 0000000..99772b4
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/YE3xmkEYrsw1taWwfDp9CNw56RAd.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/YE3xmkEYrsw1taWwfDp9CNw56RAp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/YE3xmkEYrsw1taWwfDp9CNw56RAp.xml
new file mode 100644
index 0000000..b18d8bc
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/YE3xmkEYrsw1taWwfDp9CNw56RAp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/ezLoHXkviRk7h4uzBgminH-I1bMd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/ezLoHXkviRk7h4uzBgminH-I1bMd.xml
new file mode 100644
index 0000000..99772b4
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/ezLoHXkviRk7h4uzBgminH-I1bMd.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/ezLoHXkviRk7h4uzBgminH-I1bMp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/ezLoHXkviRk7h4uzBgminH-I1bMp.xml
new file mode 100644
index 0000000..a1ac90b
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/ezLoHXkviRk7h4uzBgminH-I1bMp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/jePc50hmNwSFxyqXBC-RhIn-cFUd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/jePc50hmNwSFxyqXBC-RhIn-cFUd.xml
new file mode 100644
index 0000000..99772b4
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/jePc50hmNwSFxyqXBC-RhIn-cFUd.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/jePc50hmNwSFxyqXBC-RhIn-cFUp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/jePc50hmNwSFxyqXBC-RhIn-cFUp.xml
new file mode 100644
index 0000000..7c89168
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/jePc50hmNwSFxyqXBC-RhIn-cFUp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/EEtUlUb-dLAdf0KpMVivaUlztwAp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/EEtUlUb-dLAdf0KpMVivaUlztwAp.xml
new file mode 100644
index 0000000..fee2cd2
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/EEtUlUb-dLAdf0KpMVivaUlztwAp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml
new file mode 100644
index 0000000..182c0db
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml
new file mode 100644
index 0000000..2037c33
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/KAXfQgCar2Yb8zOxgvf9hdmLP1Ep.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/KAXfQgCar2Yb8zOxgvf9hdmLP1Ep.xml
new file mode 100644
index 0000000..e016e25
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/KAXfQgCar2Yb8zOxgvf9hdmLP1Ep.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/LUgSFhI3RPozNzNcutxrczVe6f0p.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/LUgSFhI3RPozNzNcutxrczVe6f0p.xml
new file mode 100644
index 0000000..cfaf73d
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/LUgSFhI3RPozNzNcutxrczVe6f0p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/WZRuNzqc-Db7NcQAZO8Y-R8U9ccp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/WZRuNzqc-Db7NcQAZO8Y-R8U9ccp.xml
new file mode 100644
index 0000000..a1b57bd
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/WZRuNzqc-Db7NcQAZO8Y-R8U9ccp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml
new file mode 100644
index 0000000..a4de013
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml
new file mode 100644
index 0000000..8b0d336
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/rootp.xml b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/rootp.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/resources/project/rootp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/shutdown_parity.m b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/shutdown_parity.m
new file mode 100644
index 0000000..a5978f2
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/shutdown_parity.m
@@ -0,0 +1 @@
+disp("parity shutdown");
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/startup_one.m b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/startup_one.m
new file mode 100644
index 0000000..87da650
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/startup_one.m
@@ -0,0 +1 @@
+disp("parity startup one");
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/startup_two.m b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/startup_two.m
new file mode 100644
index 0000000..17c821d
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/startup_two.m
@@ -0,0 +1 @@
+disp("parity startup two");
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/utils/helper.m b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/utils/helper.m
new file mode 100644
index 0000000..41a6fe1
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/utils/helper.m
@@ -0,0 +1,3 @@
+function y = helper(x)
+y = x + 1;
+end
diff --git a/test/parity/artifacts/project/FixedPathMultiFile/parityProject/utils/notes.txt b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/utils/notes.txt
new file mode 100644
index 0000000..598f8ad
--- /dev/null
+++ b/test/parity/artifacts/project/FixedPathMultiFile/parityProject/utils/notes.txt
@@ -0,0 +1 @@
+A member that is not code.
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/libfun.m b/test/parity/artifacts/project/MultiFile/parityLib/libfun.m
new file mode 100644
index 0000000..6f9f9f3
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/libfun.m
@@ -0,0 +1,3 @@
+function y = libfun(x)
+y = 2 * x;
+end
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/parityLib.prj b/test/parity/artifacts/project/MultiFile/parityLib/parityLib.prj
new file mode 100644
index 0000000..6b95f98
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/parityLib.prj
@@ -0,0 +1,2 @@
+
+
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml
new file mode 100644
index 0000000..6d1c43c
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml
new file mode 100644
index 0000000..e993c77
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml
new file mode 100644
index 0000000..d47011f
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml
new file mode 100644
index 0000000..91b0acc
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml
new file mode 100644
index 0000000..6c16a34
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml
new file mode 100644
index 0000000..76301e1
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml
new file mode 100644
index 0000000..e228479
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml
new file mode 100644
index 0000000..958c22f
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml
new file mode 100644
index 0000000..b5689bd
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml
new file mode 100644
index 0000000..ffb1fe8
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml
new file mode 100644
index 0000000..646977e
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml
new file mode 100644
index 0000000..2e052d9
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml
new file mode 100644
index 0000000..c67e567
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml
new file mode 100644
index 0000000..880a245
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/Project.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/Project.xml
new file mode 100644
index 0000000..62d05aa
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/Project.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml
new file mode 100644
index 0000000..5de8c3e
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml
new file mode 100644
index 0000000..642c7d7
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYd.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYd.xml
new file mode 100644
index 0000000..99772b4
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYd.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYp.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYp.xml
new file mode 100644
index 0000000..d1023af
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml
new file mode 100644
index 0000000..7b38161
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml
new file mode 100644
index 0000000..2037c33
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml
new file mode 100644
index 0000000..a4de013
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml
new file mode 100644
index 0000000..8b0d336
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityLib/resources/project/rootp.xml b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/rootp.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityLib/resources/project/rootp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/main.m b/test/parity/artifacts/project/MultiFile/parityProject/main.m
new file mode 100644
index 0000000..a1bcf13
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/main.m
@@ -0,0 +1 @@
+disp(helper(1));
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/parityProject.prj b/test/parity/artifacts/project/MultiFile/parityProject/parityProject.prj
new file mode 100644
index 0000000..6b95f98
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/parityProject.prj
@@ -0,0 +1,2 @@
+
+
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Project.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Project.xml
new file mode 100644
index 0000000..bef55ed
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Project.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/ProjectData.type.Info.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/ProjectData.type.Info.xml
new file mode 100644
index 0000000..182c0db
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/ProjectData.type.Info.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/1f00e37e-f779-415c-8b96-5e3f57b00c35.type.Category.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/1f00e37e-f779-415c-8b96-5e3f57b00c35.type.Category.xml
new file mode 100644
index 0000000..0f572ee
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/1f00e37e-f779-415c-8b96-5e3f57b00c35.type.Category.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/1f00e37e-f779-415c-8b96-5e3f57b00c35.type.Category/ac078aad-f263-4f8c-a2a6-ea4a4f8dad95.type.Label.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/1f00e37e-f779-415c-8b96-5e3f57b00c35.type.Category/ac078aad-f263-4f8c-a2a6-ea4a4f8dad95.type.Label.xml
new file mode 100644
index 0000000..88de170
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/1f00e37e-f779-415c-8b96-5e3f57b00c35.type.Category/ac078aad-f263-4f8c-a2a6-ea4a4f8dad95.type.Label.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category.xml
new file mode 100644
index 0000000..5de8c3e
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/artifact.type.Label.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/artifact.type.Label.xml
new file mode 100644
index 0000000..c67e567
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/artifact.type.Label.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/convenience.type.Label.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/convenience.type.Label.xml
new file mode 100644
index 0000000..6c16a34
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/convenience.type.Label.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/derived.type.Label.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/derived.type.Label.xml
new file mode 100644
index 0000000..b5689bd
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/derived.type.Label.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/design.type.Label.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/design.type.Label.xml
new file mode 100644
index 0000000..646977e
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/design.type.Label.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/none.type.Label.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/none.type.Label.xml
new file mode 100644
index 0000000..e228479
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/none.type.Label.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/other.type.Label.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/other.type.Label.xml
new file mode 100644
index 0000000..d47011f
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/other.type.Label.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/test.type.Label.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/test.type.Label.xml
new file mode 100644
index 0000000..6d1c43c
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Categories/FileClassCategory.type.Category/test.type.Label.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.EntryPoints/30b2777f-af37-4333-a3d7-a68eecb802f8.type.EntryPoint.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.EntryPoints/30b2777f-af37-4333-a3d7-a68eecb802f8.type.EntryPoint.xml
new file mode 100644
index 0000000..8da7b10
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.EntryPoints/30b2777f-af37-4333-a3d7-a68eecb802f8.type.EntryPoint.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.EntryPoints/45a99c9f-6fa8-4eca-be28-4dfd51cca0d1.type.EntryPoint.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.EntryPoints/45a99c9f-6fa8-4eca-be28-4dfd51cca0d1.type.EntryPoint.xml
new file mode 100644
index 0000000..add4fe8
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.EntryPoints/45a99c9f-6fa8-4eca-be28-4dfd51cca0d1.type.EntryPoint.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.EntryPoints/61ded932-6fed-4e75-9fa0-4def51703dbf.type.EntryPoint.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.EntryPoints/61ded932-6fed-4e75-9fa0-4def51703dbf.type.EntryPoint.xml
new file mode 100644
index 0000000..721a0a9
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.EntryPoints/61ded932-6fed-4e75-9fa0-4def51703dbf.type.EntryPoint.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.EntryPoints/f03c7c63-31e0-4540-9f36-acacd046434b.type.EntryPoint.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.EntryPoints/f03c7c63-31e0-4540-9f36-acacd046434b.type.EntryPoint.xml
new file mode 100644
index 0000000..27ba58c
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.EntryPoints/f03c7c63-31e0-4540-9f36-acacd046434b.type.EntryPoint.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/main.m.type.File.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/main.m.type.File.xml
new file mode 100644
index 0000000..99772b4
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/main.m.type.File.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/shutdown_parity.m.type.File.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/shutdown_parity.m.type.File.xml
new file mode 100644
index 0000000..99772b4
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/shutdown_parity.m.type.File.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/startup_one.m.type.File.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/startup_one.m.type.File.xml
new file mode 100644
index 0000000..99772b4
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/startup_one.m.type.File.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/startup_two.m.type.File.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/startup_two.m.type.File.xml
new file mode 100644
index 0000000..99772b4
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/startup_two.m.type.File.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/utils.type.File.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/utils.type.File.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/utils.type.File.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/utils.type.File/1.type.DIR_SIGNIFIER.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/utils.type.File/1.type.DIR_SIGNIFIER.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/utils.type.File/1.type.DIR_SIGNIFIER.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/utils.type.File/helper.m.type.File.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/utils.type.File/helper.m.type.File.xml
new file mode 100644
index 0000000..433a488
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/utils.type.File/helper.m.type.File.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/utils.type.File/helper.m.type.File/Data.type.LabelData.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/utils.type.File/helper.m.type.File/Data.type.LabelData.xml
new file mode 100644
index 0000000..6d15772
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/utils.type.File/helper.m.type.File/Data.type.LabelData.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/utils.type.File/notes.txt.type.File.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/utils.type.File/notes.txt.type.File.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.Files/utils.type.File/notes.txt.type.File.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.ProjectPath/96d67236-3566-430d-8c39-263475250d70.type.Reference.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.ProjectPath/96d67236-3566-430d-8c39-263475250d70.type.Reference.xml
new file mode 100644
index 0000000..7e58203
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.ProjectPath/96d67236-3566-430d-8c39-263475250d70.type.Reference.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.References/00504e7b-916d-4ebf-adfe-9c471e63aa29.type.Reference.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.References/00504e7b-916d-4ebf-adfe-9c471e63aa29.type.Reference.xml
new file mode 100644
index 0000000..95adee3
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.References/00504e7b-916d-4ebf-adfe-9c471e63aa29.type.Reference.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.WorkingFolders/ProjectStartupFolder.type.Reference.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.WorkingFolders/ProjectStartupFolder.type.Reference.xml
new file mode 100644
index 0000000..7e58203
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.WorkingFolders/ProjectStartupFolder.type.Reference.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.WorkingFolders/SimulinkCacheFolder.type.Reference.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.WorkingFolders/SimulinkCacheFolder.type.Reference.xml
new file mode 100644
index 0000000..c8bf92f
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.WorkingFolders/SimulinkCacheFolder.type.Reference.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.WorkingFolders/SimulinkCodeGenFolder.type.Reference.xml b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.WorkingFolders/SimulinkCodeGenFolder.type.Reference.xml
new file mode 100644
index 0000000..124d4e7
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/resources/project/Root.type.WorkingFolders/SimulinkCodeGenFolder.type.Reference.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/shutdown_parity.m b/test/parity/artifacts/project/MultiFile/parityProject/shutdown_parity.m
new file mode 100644
index 0000000..a5978f2
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/shutdown_parity.m
@@ -0,0 +1 @@
+disp("parity shutdown");
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/startup_one.m b/test/parity/artifacts/project/MultiFile/parityProject/startup_one.m
new file mode 100644
index 0000000..87da650
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/startup_one.m
@@ -0,0 +1 @@
+disp("parity startup one");
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/startup_two.m b/test/parity/artifacts/project/MultiFile/parityProject/startup_two.m
new file mode 100644
index 0000000..17c821d
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/startup_two.m
@@ -0,0 +1 @@
+disp("parity startup two");
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/utils/helper.m b/test/parity/artifacts/project/MultiFile/parityProject/utils/helper.m
new file mode 100644
index 0000000..41a6fe1
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/utils/helper.m
@@ -0,0 +1,3 @@
+function y = helper(x)
+y = x + 1;
+end
diff --git a/test/parity/artifacts/project/MultiFile/parityProject/utils/notes.txt b/test/parity/artifacts/project/MultiFile/parityProject/utils/notes.txt
new file mode 100644
index 0000000..598f8ad
--- /dev/null
+++ b/test/parity/artifacts/project/MultiFile/parityProject/utils/notes.txt
@@ -0,0 +1 @@
+A member that is not code.
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/libfun.m b/test/parity/artifacts/project/SingleFile/parityLib/libfun.m
new file mode 100644
index 0000000..6f9f9f3
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/libfun.m
@@ -0,0 +1,3 @@
+function y = libfun(x)
+y = 2 * x;
+end
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/parityLib.prj b/test/parity/artifacts/project/SingleFile/parityLib/parityLib.prj
new file mode 100644
index 0000000..6b95f98
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/parityLib.prj
@@ -0,0 +1,2 @@
+
+
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml
new file mode 100644
index 0000000..6d1c43c
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml
new file mode 100644
index 0000000..e993c77
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml
new file mode 100644
index 0000000..d47011f
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml
new file mode 100644
index 0000000..91b0acc
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml
new file mode 100644
index 0000000..6c16a34
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml
new file mode 100644
index 0000000..76301e1
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml
new file mode 100644
index 0000000..e228479
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml
new file mode 100644
index 0000000..958c22f
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml
new file mode 100644
index 0000000..b5689bd
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml
new file mode 100644
index 0000000..ffb1fe8
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml
new file mode 100644
index 0000000..646977e
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml
new file mode 100644
index 0000000..2e052d9
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml
new file mode 100644
index 0000000..c67e567
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml
new file mode 100644
index 0000000..880a245
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/Project.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/Project.xml
new file mode 100644
index 0000000..62d05aa
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/Project.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml
new file mode 100644
index 0000000..5de8c3e
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml
new file mode 100644
index 0000000..642c7d7
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYd.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYd.xml
new file mode 100644
index 0000000..99772b4
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYd.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYp.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYp.xml
new file mode 100644
index 0000000..d1023af
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml
new file mode 100644
index 0000000..7b38161
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml
new file mode 100644
index 0000000..2037c33
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml
new file mode 100644
index 0000000..a4de013
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml
new file mode 100644
index 0000000..8b0d336
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityLib/resources/project/rootp.xml b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/rootp.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityLib/resources/project/rootp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/SingleFile/parityProject/main.m b/test/parity/artifacts/project/SingleFile/parityProject/main.m
new file mode 100644
index 0000000..a1bcf13
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityProject/main.m
@@ -0,0 +1 @@
+disp(helper(1));
diff --git a/test/parity/artifacts/project/SingleFile/parityProject/parityProject.prj b/test/parity/artifacts/project/SingleFile/parityProject/parityProject.prj
new file mode 100644
index 0000000..6b95f98
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityProject/parityProject.prj
@@ -0,0 +1,2 @@
+
+
diff --git a/test/parity/artifacts/project/SingleFile/parityProject/resources/project/Project.xml b/test/parity/artifacts/project/SingleFile/parityProject/resources/project/Project.xml
new file mode 100644
index 0000000..e6a612d
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityProject/resources/project/Project.xml
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/parity/artifacts/project/SingleFile/parityProject/shutdown_parity.m b/test/parity/artifacts/project/SingleFile/parityProject/shutdown_parity.m
new file mode 100644
index 0000000..a5978f2
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityProject/shutdown_parity.m
@@ -0,0 +1 @@
+disp("parity shutdown");
diff --git a/test/parity/artifacts/project/SingleFile/parityProject/startup_one.m b/test/parity/artifacts/project/SingleFile/parityProject/startup_one.m
new file mode 100644
index 0000000..87da650
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityProject/startup_one.m
@@ -0,0 +1 @@
+disp("parity startup one");
diff --git a/test/parity/artifacts/project/SingleFile/parityProject/startup_two.m b/test/parity/artifacts/project/SingleFile/parityProject/startup_two.m
new file mode 100644
index 0000000..17c821d
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityProject/startup_two.m
@@ -0,0 +1 @@
+disp("parity startup two");
diff --git a/test/parity/artifacts/project/SingleFile/parityProject/utils/helper.m b/test/parity/artifacts/project/SingleFile/parityProject/utils/helper.m
new file mode 100644
index 0000000..41a6fe1
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityProject/utils/helper.m
@@ -0,0 +1,3 @@
+function y = helper(x)
+y = x + 1;
+end
diff --git a/test/parity/artifacts/project/SingleFile/parityProject/utils/notes.txt b/test/parity/artifacts/project/SingleFile/parityProject/utils/notes.txt
new file mode 100644
index 0000000..598f8ad
--- /dev/null
+++ b/test/parity/artifacts/project/SingleFile/parityProject/utils/notes.txt
@@ -0,0 +1 @@
+A member that is not code.
diff --git a/test/parity/artifacts/project/Toml/parityLib/libfun.m b/test/parity/artifacts/project/Toml/parityLib/libfun.m
new file mode 100644
index 0000000..6f9f9f3
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/libfun.m
@@ -0,0 +1,3 @@
+function y = libfun(x)
+y = 2 * x;
+end
diff --git a/test/parity/artifacts/project/Toml/parityLib/parityLib.prj b/test/parity/artifacts/project/Toml/parityLib/parityLib.prj
new file mode 100644
index 0000000..6b95f98
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/parityLib.prj
@@ -0,0 +1,2 @@
+
+
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml
new file mode 100644
index 0000000..6d1c43c
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4d.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml
new file mode 100644
index 0000000..e993c77
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/2kj09UetkV_lru3gvSPXnY6-nM4p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml
new file mode 100644
index 0000000..d47011f
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8d.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml
new file mode 100644
index 0000000..91b0acc
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/KKyDJtbdIBOlaeHmIZd5VX6vqx8p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml
new file mode 100644
index 0000000..6c16a34
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4d.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml
new file mode 100644
index 0000000..76301e1
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/QWNDYJD5mGW1bWYvPx9DtKnxzw4p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml
new file mode 100644
index 0000000..e228479
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Id.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml
new file mode 100644
index 0000000..958c22f
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/R1RggVhA72agIvELiuhWPRS8F0Ip.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml
new file mode 100644
index 0000000..b5689bd
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZod.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml
new file mode 100644
index 0000000..ffb1fe8
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/aEHSZBIY-yve10yGis12Zr5DLZop.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml
new file mode 100644
index 0000000..646977e
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml
new file mode 100644
index 0000000..2e052d9
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/j4xwF_j8iFTVayUMfxLgMnTbencp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml
new file mode 100644
index 0000000..c67e567
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml
new file mode 100644
index 0000000..880a245
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/NjSPEMsIuLUyIpr2u1Js5bVPsOs/r8LR4nLmg9ai3oHrW1r_-KocQzkp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/Project.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/Project.xml
new file mode 100644
index 0000000..62d05aa
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/Project.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml
new file mode 100644
index 0000000..5de8c3e
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml
new file mode 100644
index 0000000..642c7d7
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/fjRQtWiSIy7hIlj-Kmk87M7s21k/NjSPEMsIuLUyIpr2u1Js5bVPsOsp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYd.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYd.xml
new file mode 100644
index 0000000..99772b4
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYd.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYp.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYp.xml
new file mode 100644
index 0000000..d1023af
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/qaw0eS1zuuY1ar9TdPn1GMfrjbQ/QklSX2QksSRjMTdSODS1Et8oSKYp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml
new file mode 100644
index 0000000..7b38161
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQd.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml
new file mode 100644
index 0000000..2037c33
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/root/GiiBklLgTxteCEmomM8RCvWT0nQp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml
new file mode 100644
index 0000000..a4de013
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/root/fjRQtWiSIy7hIlj-Kmk87M7s21kp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml
new file mode 100644
index 0000000..8b0d336
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/root/qaw0eS1zuuY1ar9TdPn1GMfrjbQp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityLib/resources/project/rootp.xml b/test/parity/artifacts/project/Toml/parityLib/resources/project/rootp.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityLib/resources/project/rootp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/parity/artifacts/project/Toml/parityProject/main.m b/test/parity/artifacts/project/Toml/parityProject/main.m
new file mode 100644
index 0000000..a1bcf13
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityProject/main.m
@@ -0,0 +1 @@
+disp(helper(1));
diff --git a/test/parity/artifacts/project/Toml/parityProject/matlab.toml b/test/parity/artifacts/project/Toml/parityProject/matlab.toml
new file mode 100644
index 0000000..deca9c3
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityProject/matlab.toml
@@ -0,0 +1,31 @@
+name = "parityProject"
+
+[folders]
+path = [
+ "utils",
+]
+
+[dependencies]
+parityLib = {path = "../parityLib"}
+
+[project]
+startup-folder = "utils"
+startup-files = [
+ "startup_one.m",
+ "startup_two.m",
+]
+shutdown-files = [
+ "shutdown_parity.m",
+]
+
+[project.shortcuts]
+main = {path = "main.m"}
+
+[project.labels.Review]
+Checked = [
+ "utils/helper.m",
+]
+
+[simulink]
+cache-folder = "cache"
+codegen-folder = "codegen"
diff --git a/test/parity/artifacts/project/Toml/parityProject/shutdown_parity.m b/test/parity/artifacts/project/Toml/parityProject/shutdown_parity.m
new file mode 100644
index 0000000..a5978f2
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityProject/shutdown_parity.m
@@ -0,0 +1 @@
+disp("parity shutdown");
diff --git a/test/parity/artifacts/project/Toml/parityProject/startup_one.m b/test/parity/artifacts/project/Toml/parityProject/startup_one.m
new file mode 100644
index 0000000..87da650
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityProject/startup_one.m
@@ -0,0 +1 @@
+disp("parity startup one");
diff --git a/test/parity/artifacts/project/Toml/parityProject/startup_two.m b/test/parity/artifacts/project/Toml/parityProject/startup_two.m
new file mode 100644
index 0000000..17c821d
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityProject/startup_two.m
@@ -0,0 +1 @@
+disp("parity startup two");
diff --git a/test/parity/artifacts/project/Toml/parityProject/utils/helper.m b/test/parity/artifacts/project/Toml/parityProject/utils/helper.m
new file mode 100644
index 0000000..41a6fe1
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityProject/utils/helper.m
@@ -0,0 +1,3 @@
+function y = helper(x)
+y = x + 1;
+end
diff --git a/test/parity/artifacts/project/Toml/parityProject/utils/notes.txt b/test/parity/artifacts/project/Toml/parityProject/utils/notes.txt
new file mode 100644
index 0000000..598f8ad
--- /dev/null
+++ b/test/parity/artifacts/project/Toml/parityProject/utils/notes.txt
@@ -0,0 +1 @@
+A member that is not code.
diff --git a/test/parity/artifacts/project/project_truth.json b/test/parity/artifacts/project/project_truth.json
new file mode 100644
index 0000000..3c99feb
--- /dev/null
+++ b/test/parity/artifacts/project/project_truth.json
@@ -0,0 +1,587 @@
+{
+ "release": "2027a",
+ "version": "27.1.0.3390505 (R2027a) Prerelease",
+ "formats": {
+ "SingleFile": {
+ "name": "parityProject",
+ "definitionFilesType": "SingleFile",
+ "files": [
+ {
+ "path": "main.m",
+ "isFolder": false,
+ "labels": [
+ {
+ "category": "Classification",
+ "name": "Design",
+ "data": ""
+ }
+ ]
+ },
+ {
+ "path": "shutdown_parity.m",
+ "isFolder": false,
+ "labels": [
+ {
+ "category": "Classification",
+ "name": "Design",
+ "data": ""
+ }
+ ]
+ },
+ {
+ "path": "startup_one.m",
+ "isFolder": false,
+ "labels": [
+ {
+ "category": "Classification",
+ "name": "Design",
+ "data": ""
+ }
+ ]
+ },
+ {
+ "path": "startup_two.m",
+ "isFolder": false,
+ "labels": [
+ {
+ "category": "Classification",
+ "name": "Design",
+ "data": ""
+ }
+ ]
+ },
+ {
+ "path": "utils",
+ "isFolder": true,
+ "labels": []
+ },
+ {
+ "path": "utils/helper.m",
+ "isFolder": false,
+ "labels": [
+ {
+ "category": "Review",
+ "name": "Checked",
+ "data": "by parity"
+ },
+ {
+ "category": "Classification",
+ "name": "Design",
+ "data": ""
+ }
+ ]
+ },
+ {
+ "path": "utils/notes.txt",
+ "isFolder": false,
+ "labels": []
+ }
+ ],
+ "pathFolders": [
+ "utils"
+ ],
+ "startupFiles": [
+ "startup_one.m",
+ "startup_two.m"
+ ],
+ "shutdownFiles": [
+ "shutdown_parity.m"
+ ],
+ "shortcuts": [
+ "main.m"
+ ],
+ "references": [
+ {
+ "path": "../parityLib",
+ "storedLocation": "../parityLib",
+ "type": "Relative"
+ }
+ ],
+ "simulinkCacheFolder": "cache",
+ "simulinkCodeGenFolder": "codegen",
+ "projectStartupFolder": "utils",
+ "categories": [
+ {
+ "name": "Classification",
+ "dataType": "none",
+ "singleValued": true,
+ "labels": [
+ {
+ "name": "Artifact",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ },
+ {
+ "name": "Convenience",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ },
+ {
+ "name": "Derived",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ },
+ {
+ "name": "Design",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ },
+ {
+ "name": "None",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ },
+ {
+ "name": "Other",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ },
+ {
+ "name": "Test",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ }
+ ],
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyCategory"
+ },
+ {
+ "name": "Review",
+ "dataType": "char",
+ "singleValued": false,
+ "labels": [
+ {
+ "name": "Checked",
+ "readOnly": false,
+ "removeError": ""
+ }
+ ],
+ "readOnly": false,
+ "removeError": ""
+ }
+ ],
+ "convertWarning": "",
+ "convertWarningId": ""
+ },
+ "FixedPathMultiFile": {
+ "name": "parityProject",
+ "definitionFilesType": "FixedPathMultiFile",
+ "files": [
+ {
+ "path": "main.m",
+ "isFolder": false,
+ "labels": [
+ {
+ "category": "Classification",
+ "name": "Design",
+ "data": ""
+ }
+ ]
+ },
+ {
+ "path": "shutdown_parity.m",
+ "isFolder": false,
+ "labels": [
+ {
+ "category": "Classification",
+ "name": "Design",
+ "data": ""
+ }
+ ]
+ },
+ {
+ "path": "startup_one.m",
+ "isFolder": false,
+ "labels": [
+ {
+ "category": "Classification",
+ "name": "Design",
+ "data": ""
+ }
+ ]
+ },
+ {
+ "path": "startup_two.m",
+ "isFolder": false,
+ "labels": [
+ {
+ "category": "Classification",
+ "name": "Design",
+ "data": ""
+ }
+ ]
+ },
+ {
+ "path": "utils",
+ "isFolder": true,
+ "labels": []
+ },
+ {
+ "path": "utils/helper.m",
+ "isFolder": false,
+ "labels": [
+ {
+ "category": "Review",
+ "name": "Checked",
+ "data": "by parity"
+ },
+ {
+ "category": "Classification",
+ "name": "Design",
+ "data": ""
+ }
+ ]
+ },
+ {
+ "path": "utils/notes.txt",
+ "isFolder": false,
+ "labels": []
+ }
+ ],
+ "pathFolders": [
+ "utils"
+ ],
+ "startupFiles": [
+ "startup_one.m",
+ "startup_two.m"
+ ],
+ "shutdownFiles": [
+ "shutdown_parity.m"
+ ],
+ "shortcuts": [
+ "main.m"
+ ],
+ "references": [
+ {
+ "path": "../parityLib",
+ "storedLocation": "../parityLib",
+ "type": "Relative"
+ }
+ ],
+ "simulinkCacheFolder": "cache",
+ "simulinkCodeGenFolder": "codegen",
+ "projectStartupFolder": "utils",
+ "categories": [
+ {
+ "name": "Classification",
+ "dataType": "none",
+ "singleValued": true,
+ "labels": [
+ {
+ "name": "Artifact",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ },
+ {
+ "name": "Convenience",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ },
+ {
+ "name": "Derived",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ },
+ {
+ "name": "Design",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ },
+ {
+ "name": "None",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ },
+ {
+ "name": "Other",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ },
+ {
+ "name": "Test",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ }
+ ],
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyCategory"
+ },
+ {
+ "name": "Review",
+ "dataType": "char",
+ "singleValued": false,
+ "labels": [
+ {
+ "name": "Checked",
+ "readOnly": false,
+ "removeError": ""
+ }
+ ],
+ "readOnly": false,
+ "removeError": ""
+ }
+ ],
+ "convertWarning": "",
+ "convertWarningId": ""
+ },
+ "MultiFile": {
+ "name": "parityProject",
+ "definitionFilesType": "MultiFile",
+ "files": [
+ {
+ "path": "main.m",
+ "isFolder": false,
+ "labels": [
+ {
+ "category": "Classification",
+ "name": "Design",
+ "data": ""
+ }
+ ]
+ },
+ {
+ "path": "shutdown_parity.m",
+ "isFolder": false,
+ "labels": [
+ {
+ "category": "Classification",
+ "name": "Design",
+ "data": ""
+ }
+ ]
+ },
+ {
+ "path": "startup_one.m",
+ "isFolder": false,
+ "labels": [
+ {
+ "category": "Classification",
+ "name": "Design",
+ "data": ""
+ }
+ ]
+ },
+ {
+ "path": "startup_two.m",
+ "isFolder": false,
+ "labels": [
+ {
+ "category": "Classification",
+ "name": "Design",
+ "data": ""
+ }
+ ]
+ },
+ {
+ "path": "utils",
+ "isFolder": true,
+ "labels": []
+ },
+ {
+ "path": "utils/helper.m",
+ "isFolder": false,
+ "labels": [
+ {
+ "category": "Review",
+ "name": "Checked",
+ "data": "by parity"
+ },
+ {
+ "category": "Classification",
+ "name": "Design",
+ "data": ""
+ }
+ ]
+ },
+ {
+ "path": "utils/notes.txt",
+ "isFolder": false,
+ "labels": []
+ }
+ ],
+ "pathFolders": [
+ "utils"
+ ],
+ "startupFiles": [
+ "startup_one.m",
+ "startup_two.m"
+ ],
+ "shutdownFiles": [
+ "shutdown_parity.m"
+ ],
+ "shortcuts": [
+ "main.m"
+ ],
+ "references": [
+ {
+ "path": "../parityLib",
+ "storedLocation": "../parityLib",
+ "type": "Relative"
+ }
+ ],
+ "simulinkCacheFolder": "cache",
+ "simulinkCodeGenFolder": "codegen",
+ "projectStartupFolder": "utils",
+ "categories": [
+ {
+ "name": "Classification",
+ "dataType": "none",
+ "singleValued": true,
+ "labels": [
+ {
+ "name": "Artifact",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ },
+ {
+ "name": "Convenience",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ },
+ {
+ "name": "Derived",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ },
+ {
+ "name": "Design",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ },
+ {
+ "name": "None",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ },
+ {
+ "name": "Other",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ },
+ {
+ "name": "Test",
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyLabel"
+ }
+ ],
+ "readOnly": true,
+ "removeError": "MATLAB:project:management:CanNotModifyReadOnlyCategory"
+ },
+ {
+ "name": "Review",
+ "dataType": "char",
+ "singleValued": false,
+ "labels": [
+ {
+ "name": "Checked",
+ "readOnly": false,
+ "removeError": ""
+ }
+ ],
+ "readOnly": false,
+ "removeError": ""
+ }
+ ],
+ "convertWarning": "",
+ "convertWarningId": ""
+ },
+ "Toml": {
+ "name": "parityProject",
+ "definitionFilesType": "Toml",
+ "files": [
+ {
+ "path": "cache",
+ "isFolder": true,
+ "labels": []
+ },
+ {
+ "path": "codegen",
+ "isFolder": true,
+ "labels": []
+ },
+ {
+ "path": "main.m",
+ "isFolder": false,
+ "labels": []
+ },
+ {
+ "path": "shutdown_parity.m",
+ "isFolder": false,
+ "labels": []
+ },
+ {
+ "path": "startup_one.m",
+ "isFolder": false,
+ "labels": []
+ },
+ {
+ "path": "startup_two.m",
+ "isFolder": false,
+ "labels": []
+ },
+ {
+ "path": "utils",
+ "isFolder": true,
+ "labels": []
+ },
+ {
+ "path": "utils/helper.m",
+ "isFolder": false,
+ "labels": [
+ {
+ "category": "Review",
+ "name": "Checked",
+ "data": ""
+ }
+ ]
+ },
+ {
+ "path": "utils/notes.txt",
+ "isFolder": false,
+ "labels": []
+ }
+ ],
+ "pathFolders": [
+ "utils"
+ ],
+ "startupFiles": [
+ "startup_one.m",
+ "startup_two.m"
+ ],
+ "shutdownFiles": [
+ "shutdown_parity.m"
+ ],
+ "shortcuts": [
+ "main.m"
+ ],
+ "references": [
+ {
+ "path": "../parityLib",
+ "storedLocation": "../parityLib",
+ "type": "Relative"
+ }
+ ],
+ "simulinkCacheFolder": "cache",
+ "simulinkCodeGenFolder": "codegen",
+ "projectStartupFolder": "utils",
+ "categories": [
+ {
+ "name": "Review",
+ "dataType": "none",
+ "singleValued": false,
+ "labels": [
+ {
+ "name": "Checked",
+ "readOnly": false,
+ "removeError": ""
+ }
+ ],
+ "readOnly": false,
+ "removeError": ""
+ }
+ ],
+ "convertWarning": "\nUnable to preserve label data during the conversion.",
+ "convertWarningId": "MATLAB:Project:Issues:LabelDataLoss"
+ }
+ }
+}
diff --git a/test/parity/matlab/README.md b/test/parity/matlab/README.md
index 5d3cef2..7f73fec 100644
--- a/test/parity/matlab/README.md
+++ b/test/parity/matlab/README.md
@@ -14,9 +14,11 @@ a stale corpus is identifiable without rerunning anything.
Everything under `../artifacts/` is **generated**. Do not hand-edit it, and never
write an expected value by hand when MATLAB can be asked for it.
-There is a second corpus alongside this one, with its own generator and its own
-question: [The `.mdl` corpus](#the-mdl-corpus), which is about containers rather
-than values.
+There are three more corpora alongside this one, each with its own generator and
+its own question. [The `.mdl` corpus](#the-mdl-corpus) is about containers rather
+than values; [the `.slx` layout corpus](#the-slx-layout-corpus) about part layouts
+rather than containers; [the project corpus](#the-project-corpus) about a file that
+holds no values at all.
MATLAB is a fixture generator, not a test dependency. It cannot run in GitHub CI,
so a fully MATLAB-gated suite would never actually run for this repo: MATLAB
@@ -59,10 +61,11 @@ and writes to `../artifacts/mdl/` and nowhere else. Nothing writes to
| `gen_mdl.m` | the entry point for the SECOND, separate corpus: the `.mdl` flavours and their `.slx` twins — see [The `.mdl` corpus](#the-mdl-corpus) |
| `gen_mask.m` | the masked-subsystem fixture — see [The mask fixture](#the-mask-fixture). Writes outside `../artifacts/`: its truth pair goes to `test/fixtures/` |
| `gen_block_params.m` | the option-list parameter table — see [The block-parameter gate](#the-block-parameter-gate). The only generator that writes into **`src/`**, because the parser imports its output at parse time |
+| `gen_project.m` | one project in all four definition-file formats — see [The project corpus](#the-project-corpus). The only generator whose output is a tree of openable projects rather than files |
| `probe_*.m`, `probe_writeback*.mjs` | one-question probes — see the table below. None of them writes to `artifacts/` |
| `wbcompare.m` | the comparison both write-back gates share: `fullsig`, which walks a value to every leaf spelling class, size, complexity and exact value |
| `DESIGN.md` | the display convention, the coverage matrix, and the numbered defects this suite exists to pin |
-| `drift.mjs` | regenerate ALL FOUR into a temp directory and diff `truth.json`, `mdl_truth.json`, `mask_truth.json` and `enumBlockParams.ts` against what is committed — the check for MATLAB-release drift |
+| `drift.mjs` | regenerate ALL FIVE into a temp directory and diff `truth.json`, `mdl_truth.json`, `mask_truth.json`, `enumBlockParams.ts` and `project_truth.json` against what is committed — the check for MATLAB-release drift |
| `STRING_MCOS.md` | how MATLAB stores a `string` in a `.mat`: the metadata segment the parser skipped, the packed `uint64` payload, and what could not be determined |
| `../artifacts/truth.json` | the expectations, for every format at once |
| `../artifacts/meta.json` | `version` and `release` of the MATLAB that wrote the corpus |
@@ -71,6 +74,7 @@ and writes to `../artifacts/mdl/` and nowhere else. Nothing writes to
| `../artifacts/text/cases.sldd` | 73 entries in Design Data, `FileFormat = 'uncompressed-text'` |
| `../artifacts/binary/cases.sldd` | the same 73, `FileFormat = 'compressed-binary'` |
| `../artifacts/mdl/` | the `.mdl` corpus — six model files and `mdl_truth.json`, all written by `gen_mdl.m` |
+| `../artifacts/project/` | the project corpus — four whole project trees and `project_truth.json`, all written by `gen_project.m` |
**`text/params.sldd` and `binary/params.sldd` are not part of this corpus.** They
are the older, hand-made fidelity fixtures used by `test/parity/fidelity/*.test.ts`,
@@ -79,8 +83,10 @@ suites share the `artifacts/` tree only so that
`roundTripHarness.loadModel(format, fixture, uri)`, which resolves
`../artifacts/{text|binary}/`, works on both unchanged.
-`.prj` has no case file: a project carries no data objects, so parity for it is
-structural only.
+`.prj` has no case file in *this* corpus: a project carries no data objects, so
+there is nothing for `truth.json` to say about one. Parity for a project is
+structural, and it has a corpus of its own — see
+[The project corpus](#the-project-corpus).
### The probes
@@ -665,6 +671,148 @@ workspace variables with their exact values, both config sets with the right one
active, the model reference, the linked dictionary, and the external-`.mat` pointer
— reads identically out of all five layouts.
+## The project corpus
+
+A fourth corpus, written by `gen_project.m` into `../artifacts/project/`. It asks the
+question neither value corpus can: a `.prj` holds no data objects, so parity for a
+project is **structural** — does the same project read back the same way out of every
+shape its metadata can be stored in?
+
+There are **four** shapes, chosen by
+`matlab.project.convertDefinitionFiles(root, matlab.project.DefinitionFiles.)`.
+Three are XML trees this package reads; the fourth is a `matlab.toml` it does not.
+Measured by converting one project four times and harvesting the whole tree each time:
+
+| format | `MetadataType` | what is on disk under `resources/project/` | `.prj` | XML docs |
+|---|---|---|---|---|
+| `SingleFile` | `monolithic` | **one** `Project.xml`, every collection inside it, rooted at `` rather than `` | yes | 1 |
+| `FixedPathMultiFile` | `fixedPathV2` | the manifest, `rootp.xml`, and 11 uuid-named directories holding **two** sidecars per entity — `…d.xml` the definition, `…p.xml` the pointer | yes | 66 |
+| `MultiFile` | `distributed` | the manifest, `ProjectData.type.Info.xml`, and `Root.type./` directories holding one human-named doc per entity | yes | 30 |
+| `Toml` | — | **nothing: there is no `resources/`.** A single 423-byte `matlab.toml` at the project root is the entire definition | **no** | 0 |
+
+**The missing `.prj` in the Toml row is MATLAB's doing and is expected.** The conversion
+deletes `resources/` *and* the `.prj` marker; `loadProject` still opens the folder.
+So a Toml project is a missing **file type** for a host registered on `.prj`, not a parse
+gap — which is why the reader's `matlab.toml` branch is reached by no file in this corpus,
+and is asserted as such rather than left looking live.
+
+230 files and 38 KB all told, which is the point of generating a small project rather
+than reusing a real one: the 108 MB project that turned the first defect up cannot be
+committed, and every `/parityProject/parityProject.prj` here is a real project a
+host can be pointed at.
+
+### What is in the project
+
+One of everything the seven collection readers look for, because a collection with no
+entry is a reader with no test: seven members — four files at the root, the `utils/`
+folder, and the two files in it, one of them a non-code `notes.txt` — one built-in label
+assignment and one custom category carrying data, a path folder, a relative reference to
+a second project (`parityLib`, beside the root, so the reference points outside it),
+**two** startup files and a shutdown file, a shortcut, and all three working folders.
+
+Two startup files on purpose. Run order is a linked list in the store and MATLAB reports
+it as an ordered array, so one file of each kind would leave the ordering unasserted —
+and the ordering is exactly where a defect was.
+
+### Ownership is recorded by refusal
+
+The label catalog's interesting bit is who owns each entry: MATLAB's seven built-in
+`Classification` labels, in a read-only category, versus the one `Review/Checked` this
+project added. **There is no property that says.** `properties(matlab.project.Category)` is `{SingleValued, DataType, Name,
+LabelDefinitions}`, and a `LabelDefinition` is `{Name, FilePatterns, CategoryName}`.
+
+What MATLAB does say is a refusal: removing one of its own throws
+`MATLAB:project:management:CanNotModifyReadOnlyLabel`, or `...CanNotModifyReadOnlyCategory`
+for the category. So `recordCategories` asks — on a throwaway copy, after the fixture
+tree has been read, because the attempt that *succeeds* removes the definition it asked
+about — and writes **the error identifier** down beside each answer. A refusal for some
+other reason must not read as "MATLAB owns this", and recording the id is what makes that
+visible in the fixture instead of quietly true.
+
+### What the real bytes disproved
+
+This generator exists because the project suite's stores were hand-typed from reading a
+real project, which is the one thing this README says never to do. Over a thousand lines
+of them agreed with the parser on three things that are false, and the first real store
+disagreed on all three:
+
+- **`ReadOnly` has a vocabulary per element** — `READ_ONLY`/`WRITABLE` on a label
+ ``, `1`/`0` on a category's. The old rule tested the attribute's *presence*, so a
+ real project's explicit `WRITABLE` read as read-only and a user's own label was drawn
+ on the project page as one of MATLAB's built-ins.
+- **"first in the chain" is spelled two ways.** Run order is nested
+ ``, and a freshly built project puts
+ **no Extension at all** on its first entry where an older one writes `Value="HEAD"`. The
+ walk started only at the literal `HEAD`, so the common shape came out in reverse.
+- **Two collections came back in store order**, which differs per layout — so the label
+ catalog and the working-folder list were layout-dependent, and the project page rendered
+ the latter in whatever order the file happened to hold.
+
+All three are fixed, and pinned both here and as unit tests in
+`test/projectParser.test.ts`.
+
+The hand-typed stores in that file **stay**, and are not a duplicate of this corpus: what
+they cover is damage, which a real conversion cannot be made to produce — a document that
+is not XML, a File entity that is its own child, a chain that is a cycle, a store
+declaring a layout nobody can walk. The corpus covers what MATLAB really writes; the unit
+tests cover what a reader must survive. Neither substitutes for the other, and only the
+first kind may state a convention.
+
+### What the Toml conversion loses, in MATLAB's own words
+
+Recorded per format as `convertWarning`/`convertWarningId`, so the lossiness is MATLAB's
+statement rather than our inference from a diff. Three of the four convert silently; the
+fourth warns `MATLAB:Project:Issues:LabelDataLoss`:
+
+> Unable to preserve label data during the conversion.
+
+Which undersells it. Against the `SingleFile` record, the Toml project has: no
+`Classification` category at all — all seven built-in labels and every assignment of
+`Design` gone; `Review` surviving, but with `DataType` `char` demoted to `none` and
+`Checked`'s data `'by parity'` emptied; and `cache/` and `codegen/` promoted to project
+*members*, 7 files becoming 9. Everything else — the startup order, the shutdown file,
+the shortcut, the reference and its `Relative` type, the path folder, all three working
+folders — survives intact.
+
+### Regenerate
+
+```bash
+mw -using Bmain matlab -nodesktop -batch \
+ "addpath('$PWD/test/parity/matlab'); gen_project('$PWD/test/parity/artifacts/project')"
+```
+
+Prints `GEN_PROJECT OK`. It is a **function**, like `gen_mask.m`, so it takes the output
+directory as an argument rather than off a pre-set `outdir`; point it somewhere harmless
+to diff against what is committed, which is what `drift.mjs` does.
+
+**`project_truth.json` is byte-reproducible** — two runs of one release came out
+identical, since it records no uuid and no timestamp — but the stores are not: every
+entity gets a fresh uuid on every conversion, which in `fixedPathV2` is the *file name*
+too. Compare the truth, not the trees.
+
+One thing in the generator's log that looks like a failure and is not: the ownership
+probe copies only `parityProject`, so its `../parityLib` reference no longer resolves and
+MATLAB prints `No project found in the specified location`. The categories are read from
+the loaded project regardless, and the committed fixtures and truth are unaffected.
+
+### What `project.parity.test.ts` asserts
+
+The same three kinds of claim as the `.slx` corpus:
+
+- **the layout is real** — per format, the store's document count, whether a `.prj`
+ exists, whether a `matlab.toml` exists, and the declared `MetadataType` in the place
+ that layout declares it. Without this the cross-layout comparison could pass vacuously
+ on a corpus accidentally regenerated in one format.
+- **against MATLAB truth** — the name (read from the store, with a deliberately wrong
+ `projectName` passed in so the assertion cannot pass on the input), `definitionFilesType`
+ against our `format`, the members and which are folders, each file's labels, the catalog
+ with its ownership, the path folders, the run order of both hooks, the shortcut, the
+ reference and the basename we derive its name from, and the three working folders.
+- **across layouts** — the three XML layouts must parse to **deeply equal** results, and
+ that assertion is licensed by MATLAB itself: it is made only because those three
+ conversions reported no warning. The Toml one did, so it is compared against its own
+ record instead.
+
## Tiers, and which need `DEX_MATLAB_CMD`
**Tier 1 — committed truth, no MATLAB, runs in CI on every PR.** Reads
@@ -679,6 +827,7 @@ format sniffing is exercised too) and `loadTruth.ts`:
| `lossless.test.ts` | the stored value is MATLAB's exact value, and serialize -> reparse is a fixed point |
| `mdl.parity.test.ts` | the `.mdl` corpus: each flavour against MATLAB's truth, and each against its `.slx` twin |
| `slxLayouts.parity.test.ts` | the `.slx` layout corpus: each era's part layout is real, each file against MATLAB's truth, and each against the current release's rows |
+| `project.parity.test.ts` | the project corpus: each definition-file layout is real, each against MATLAB's truth, and the three XML layouts deeply equal to one another |
`lossless` is deliberately separate from `display`: display is lossy by design (a
summary, a threshold), storage must not be, and only a storage-level assertion
diff --git a/test/parity/matlab/drift.mjs b/test/parity/matlab/drift.mjs
index 89c857f..99a5d56 100644
--- a/test/parity/matlab/drift.mjs
+++ b/test/parity/matlab/drift.mjs
@@ -11,17 +11,17 @@
// printing a per-variable diff. A non-zero exit is NOT necessarily a bug in our code — it
// may be a MATLAB behaviour change, which is exactly the thing worth knowing about.
//
-// It compares truth.json and mdl_truth.json, never container bytes. Only the JSON is
-// byte-reproducible; cases.mat, cases.slx, both cases.sldd and every file in mdl/ differ
-// on EVERY run, because MATLAB stamps each entry — and each model save — with a fresh
-// uuid and timestamp. Comparing containers would report drift every single time and train
-// the reader to ignore it.
+// It compares the truth JSON, never container bytes. Only the JSON is byte-reproducible;
+// cases.mat, cases.slx, both cases.sldd, every file in mdl/ and every store document under
+// project/ differ on EVERY run, because MATLAB stamps each entry — and each model save, and
+// each project entity — with a fresh uuid and timestamp. Comparing containers would report
+// drift every single time and train the reader to ignore it.
//
-// All four corpora are regenerated, because each can go stale independently: gen_truth.m
+// All five corpora are regenerated, because each can go stale independently: gen_truth.m
// for the value corpus, gen_mdl.m for the `.mdl` container corpus, gen_mask.m for the mask
-// fixture, and gen_block_params.m for the option-list table. That is four MATLAB launches,
-// three of which load Simulink — and the last one copies every block in two libraries — so
-// expect this to take many minutes.
+// fixture, gen_block_params.m for the option-list table, and gen_project.m for the project
+// corpus. That is five MATLAB launches, three of which load Simulink — and one of those
+// copies every block in two libraries — so expect this to take many minutes.
//
// The mask corpus is the one most worth this check. Its expectations are entirely
// `Simulink.findVars`' behaviour — which mask parameter types hold an expression, which
@@ -50,6 +50,7 @@ const COMMITTED_MDL = join(ARTIFACTS, 'mdl', 'mdl_truth.json');
const COMMITTED_MASK = join(HERE, '..', '..', 'fixtures', 'mask_truth.json');
// The one generated file that is not a fixture: the parser imports it at parse time.
const COMMITTED_ENUM = join(HERE, '..', '..', '..', 'src', 'datamodel', 'parser', 'enumBlockParams.ts');
+const COMMITTED_PROJECT = join(ARTIFACTS, 'project', 'project_truth.json');
const LAUNCH = process.env.DEX_MATLAB_CMD || '';
if (!LAUNCH) {
@@ -96,6 +97,10 @@ regenerate('gen_truth.m');
regenerate('gen_mdl.m');
regenerateFn(`gen_mask('${out}')`);
regenerate('gen_block_params.m');
+// gen_project.m is a function too, and writes a whole directory rather than one file, so
+// it gets the subdirectory the committed copy lives in — which is also what makes the two
+// trees comparable by name below.
+regenerateFn(`gen_project('${join(out, 'project')}')`);
const readJson = (p) => JSON.parse(readFileSync(p, 'utf8'));
const fresh = readJson(join(out, 'truth.json'));
@@ -249,6 +254,36 @@ if (!existsSync(COMMITTED_ENUM)) {
}
}
+// The project corpus. Compared per FORMAT and per section: the claim its suite makes is
+// that all four definition-file shapes describe the same project, so a release that
+// changed one conversion would otherwise print a wall of diffs with no indication of
+// which layout moved. `project_truth.json` holds no uuid and no timestamp — two runs of
+// one release came out byte-identical — so every diff here is a real change of answer.
+if (!existsSync(COMMITTED_PROJECT)) {
+ console.log('\n(no committed project_truth.json; skipping the project corpus)');
+} else {
+ const freshProj = readJson(join(out, 'project', 'project_truth.json'));
+ const oldProj = readJson(COMMITTED_PROJECT);
+ const formats = new Set([
+ ...Object.keys(oldProj.formats ?? {}),
+ ...Object.keys(freshProj.formats ?? {}),
+ ]);
+ for (const fmt of formats) {
+ const a = oldProj.formats?.[fmt] ?? {};
+ const b = freshProj.formats?.[fmt] ?? {};
+ for (const section of new Set([...Object.keys(a), ...Object.keys(b)])) {
+ const sa = JSON.stringify(a[section] ?? null);
+ const sb = JSON.stringify(b[section] ?? null);
+ if (sa !== sb) {
+ drift++;
+ console.log('\nDRIFT project.' + fmt + '.' + section);
+ console.log(' committed: ' + sa);
+ console.log(' regenerated: ' + sb);
+ }
+ }
+ }
+}
+
if (drift === 0) {
console.log('\nno drift: the committed corpus matches this MATLAB.');
process.exit(0);
diff --git a/test/parity/matlab/gen_project.m b/test/parity/matlab/gen_project.m
new file mode 100644
index 0000000..48f55ac
--- /dev/null
+++ b/test/parity/matlab/gen_project.m
@@ -0,0 +1,395 @@
+function gen_project(outDir)
+% GEN_PROJECT Write one small project in all four definition-file formats, and
+% record what MATLAB says each of them holds.
+%
+% A project's metadata has no schema and four on-disk shapes, chosen by
+% `matlab.project.convertDefinitionFiles`. Three are XML trees this package reads;
+% the fourth is `matlab.toml`, which it does not. Until this generator existed the
+% project suite's stores were hand-typed from reading a real project, which is the
+% one thing `README.md` says never to do: a misread convention goes into the
+% fixture and the test then agrees with it.
+%
+% So this builds a project carrying one of everything the seven collection readers
+% look for — files, a folder, a label definition and two labelled files, a path
+% folder, a referenced project, two startup files and a shutdown file, a shortcut,
+% and three working folders — converts it four times, and harvests the whole tree
+% each time. The projects are small enough to commit and complete enough to open:
+% every `/parityProject/parityProject.prj` is a real project a host can be
+% pointed at.
+%
+% Truth is recorded PER FORMAT, from the converted project, not once from the
+% original. That is the part worth having: MATLAB itself saying all four shapes
+% describe the same project is the authority a cross-format parity test needs, and
+% it gives the unread Toml case an expectation too. `definitionFilesType` is
+% MATLAB's own name for the layout, which is what keeps our `format` strings from
+% being labels we invented.
+%
+% TWO STARTUP FILES on purpose: run order is a linked list in the store and
+% MATLAB reports it as an ordered array, so one file of each kind would leave the
+% ordering unasserted.
+%
+% gen_project % writes ../artifacts/project/
+% gen_project('/tmp/scratch') % somewhere harmless, to diff against it
+%
+% Prints GEN_PROJECT OK.
+
+if nargin < 1 || isempty(outDir)
+ outDir = fullfile(fileparts(mfilename('fullpath')), '..', 'artifacts', 'project');
+end
+if ~exist(outDir, 'dir'); mkdir(outDir); end
+
+FORMATS = {'SingleFile', 'FixedPathMultiFile', 'MultiFile', 'Toml'};
+
+scratch = tempname;
+mkdir(scratch);
+src = fullfile(scratch, 'src');
+mkdir(src);
+
+buildProjects(src);
+
+truth = struct();
+truth.release = version('-release');
+truth.version = version();
+truth.formats = struct();
+
+for k = 1:numel(FORMATS)
+ fmt = FORMATS{k};
+
+ % Convert a COPY each time: the conversion is not reversible, and all four
+ % formats have to come from one and the same project for the parity claim to
+ % mean anything.
+ work = fullfile(scratch, fmt);
+ copyfile(src, work);
+ root = fullfile(work, 'parityProject');
+
+ % Capture MATLAB's own warning for the conversion. The Toml conversion is
+ % LOSSY and says so; recording the sentence verbatim makes that MATLAB's
+ % statement rather than our inference from a diff.
+ lastwarn('');
+ matlab.project.convertDefinitionFiles(root, matlab.project.DefinitionFiles.(fmt));
+ [wmsg, wid] = lastwarn();
+
+ truth.formats.(fmt) = recordTruth(root);
+ truth.formats.(fmt).convertWarning = char(wmsg);
+ truth.formats.(fmt).convertWarningId = char(wid);
+
+ target = fullfile(outDir, fmt);
+ if exist(target, 'dir'); rmdir(target, 's'); end
+ copyfile(work, target);
+ fprintf('wrote %s\n', target);
+end
+
+jsonFile = fullfile(outDir, 'project_truth.json');
+fid = fopen(jsonFile, 'w');
+fprintf(fid, '%s\n', jsonencode(truth, 'PrettyPrint', true));
+fclose(fid);
+fprintf('wrote %s\n', jsonFile);
+
+rmdir(scratch, 's');
+fprintf('GEN_PROJECT OK\n');
+end
+
+% -------------------------------------------------------------------------------
+function buildProjects(parent)
+% The referenced project first — a reference needs its target to exist on disk
+% before `addReference` will take it.
+
+libRoot = fullfile(parent, 'parityLib');
+mkdir(libRoot);
+writeFile(fullfile(libRoot, 'libfun.m'), { ...
+ 'function y = libfun(x)', ...
+ 'y = 2 * x;', ...
+ 'end'});
+lib = matlab.project.createProject('Folder', libRoot, 'Name', 'parityLib');
+addFile(lib, fullfile(libRoot, 'libfun.m'));
+close(lib);
+
+root = fullfile(parent, 'parityProject');
+mkdir(root);
+mkdir(fullfile(root, 'utils'));
+mkdir(fullfile(root, 'cache'));
+mkdir(fullfile(root, 'codegen'));
+writeFile(fullfile(root, 'main.m'), {'disp(helper(1));'});
+writeFile(fullfile(root, 'utils', 'helper.m'), { ...
+ 'function y = helper(x)', ...
+ 'y = x + 1;', ...
+ 'end'});
+writeFile(fullfile(root, 'utils', 'notes.txt'), {'A member that is not code.'});
+writeFile(fullfile(root, 'startup_one.m'), {'disp("parity startup one");'});
+writeFile(fullfile(root, 'startup_two.m'), {'disp("parity startup two");'});
+writeFile(fullfile(root, 'shutdown_parity.m'), {'disp("parity shutdown");'});
+
+proj = matlab.project.createProject('Folder', root, 'Name', 'parityProject');
+
+mainFile = addFile(proj, fullfile(root, 'main.m'));
+addFolderIncludingChildFiles(proj, fullfile(root, 'utils'));
+addFile(proj, fullfile(root, 'startup_one.m'));
+addFile(proj, fullfile(root, 'startup_two.m'));
+addFile(proj, fullfile(root, 'shutdown_parity.m'));
+
+% A built-in category, and a custom one carrying data — the two shapes the label
+% catalog reader has to tell apart.
+addLabel(mainFile, 'Classification', 'Design');
+cat = createCategory(proj, 'Review', 'char');
+createLabel(cat, 'Checked');
+helperFile = findFile(proj, fullfile(root, 'utils', 'helper.m'));
+addLabel(helperFile, 'Review', 'Checked', 'by parity');
+
+addPath(proj, fullfile(root, 'utils'));
+
+% Order matters here and is asserted: MATLAB runs startup files top-down.
+addStartupFile(proj, fullfile(root, 'startup_one.m'));
+addStartupFile(proj, fullfile(root, 'startup_two.m'));
+addShutdownFile(proj, fullfile(root, 'shutdown_parity.m'));
+
+% A shortcut, so the entry-point reader's third kind is covered too.
+addShortcut(proj, fullfile(root, 'main.m'));
+
+addReference(proj, libRoot);
+
+proj.SimulinkCacheFolder = fullfile(root, 'cache');
+proj.SimulinkCodeGenFolder = fullfile(root, 'codegen');
+proj.ProjectStartupFolder = fullfile(root, 'utils');
+
+close(proj);
+end
+
+% -------------------------------------------------------------------------------
+function truth = recordTruth(root)
+% What MATLAB says this project holds. Every path is recorded RELATIVE to the
+% project root with forward slashes, so the record is the same on any machine and
+% in any temporary directory — an absolute path here would be a fixture that only
+% ever matches the machine that generated it.
+
+proj = matlab.project.loadProject(root);
+
+truth = struct();
+truth.name = char(proj.Name);
+truth.definitionFilesType = char(string(proj.DefinitionFilesType));
+
+files = {};
+for k = 1:numel(proj.Files)
+ f = proj.Files(k);
+ abs = char(f.Path);
+ entry = struct();
+ entry.path = relPath(root, abs);
+ entry.isFolder = isfolder(abs);
+ labels = {};
+ for j = 1:numel(f.Labels)
+ L = f.Labels(j);
+ lab = struct();
+ lab.category = char(L.CategoryName);
+ lab.name = char(L.Name);
+ if isempty(L.Data)
+ lab.data = '';
+ else
+ lab.data = char(string(L.Data));
+ end
+ labels{end+1} = lab; %#ok
+ end
+ entry.labels = sortByField(labels, 'name');
+ files{end+1} = entry; %#ok
+end
+truth.files = sortByField(files, 'path');
+
+truth.pathFolders = sortCell(relPaths(root, pathsOf(proj.PathFolders)));
+
+% NOT sorted: these two are in MATLAB's run order, which is the thing being
+% asserted. Sorting them would quietly delete the claim.
+truth.startupFiles = relPaths(root, cellstr(string(proj.StartupFiles)));
+truth.shutdownFiles = relPaths(root, cellstr(string(proj.ShutdownFiles)));
+
+truth.shortcuts = sortCell(relPaths(root, pathsOf(proj.Shortcuts)));
+
+refs = {};
+for k = 1:numel(proj.ProjectReferences)
+ r = proj.ProjectReferences(k);
+ entry = struct();
+ entry.path = relPath(root, char(r.File));
+ entry.storedLocation = strrep(char(r.StoredLocation), '\', '/');
+ entry.type = char(string(r.Type));
+ refs{end+1} = entry; %#ok
+end
+truth.references = sortByField(refs, 'path');
+
+truth.simulinkCacheFolder = relPath(root, char(proj.SimulinkCacheFolder));
+truth.simulinkCodeGenFolder = relPath(root, char(proj.SimulinkCodeGenFolder));
+truth.projectStartupFolder = relPath(root, char(proj.ProjectStartupFolder));
+
+% Closed BEFORE the ownership probe: that probe loads a copy of this same project
+% — same name, same UUIDs — and two of those open at once is a question about
+% MATLAB rather than about the fixture.
+close(proj);
+
+truth.categories = recordCategories(root);
+end
+
+% -------------------------------------------------------------------------------
+function cats = recordCategories(root)
+% The label catalog, including WHO OWNS each entry — MATLAB's seven built-in
+% `Classification` labels versus the ones this project added.
+%
+% There is no property to read. `properties(matlab.project.Category)` is
+% {SingleValued, DataType, Name, LabelDefinitions} and a `LabelDefinition` is
+% {Name, FilePatterns, CategoryName}; neither says read-only. What MATLAB does
+% say is a REFUSAL: removing one of its own throws
+% `MATLAB:project:management:CanNotModifyReadOnlyLabel` (or ...Category). So
+% ownership is recorded by ASKING, which is destructive — the attempt that
+% succeeds removes the definition it asked about — and therefore asked of a COPY
+% nobody keeps, after the fixture tree has been read.
+%
+% The error IDENTIFIER goes into the record next to the answer. A refusal for some
+% other reason must not read as "MATLAB owns this", and writing the id down is
+% what makes that visible in the fixture instead of silently true.
+
+work = [tempname '_ownership'];
+copyfile(root, work);
+proj = matlab.project.loadProject(work);
+
+catNames = {};
+for k = 1:numel(proj.Categories)
+ catNames{end+1} = char(proj.Categories(k).Name); %#ok
+end
+
+cats = {};
+for k = 1:numel(catNames)
+ c = findCategory(proj, catNames{k});
+ entry = struct();
+ entry.name = char(c.Name);
+ entry.dataType = char(c.DataType);
+ entry.singleValued = logical(c.SingleValued);
+
+ labNames = {};
+ for j = 1:numel(c.LabelDefinitions)
+ labNames{end+1} = char(c.LabelDefinitions(j).Name); %#ok
+ end
+ labNames = sortCell(labNames);
+
+ labels = {};
+ for j = 1:numel(labNames)
+ lab = struct();
+ lab.name = labNames{j};
+ [lab.readOnly, lab.removeError] = refuses(@() ...
+ removeLabel(findCategory(proj, catNames{k}), labNames{j}), ...
+ 'MATLAB:project:management:CanNotModifyReadOnlyLabel');
+ labels{end+1} = lab; %#ok
+ end
+ entry.labels = labels;
+
+ % The category last: removing it takes its labels with it.
+ [entry.readOnly, entry.removeError] = refuses(@() ...
+ removeCategory(proj, catNames{k}), ...
+ 'MATLAB:project:management:CanNotModifyReadOnlyCategory');
+
+ cats{end+1} = entry; %#ok
+end
+cats = sortByField(cats, 'name');
+
+close(proj);
+rmdir(work, 's');
+end
+
+function out = findCategory(proj, name)
+out = [];
+for k = 1:numel(proj.Categories)
+ if strcmp(char(proj.Categories(k).Name), name)
+ out = proj.Categories(k);
+ return
+ end
+end
+error('gen_project:noCategory', 'category "%s" is gone', name);
+end
+
+function [readOnly, errId] = refuses(fn, expectedId)
+% Did MATLAB refuse, and with which identifier? `readOnly` is true only for the
+% identifier that means ownership; any other failure is reported as itself.
+try
+ fn();
+ readOnly = false;
+ errId = '';
+catch e
+ readOnly = strcmp(e.identifier, expectedId);
+ errId = e.identifier;
+end
+end
+
+% -------------------------------------------------------------------------------
+function writeFile(path, lines)
+fid = fopen(path, 'w');
+for k = 1:numel(lines)
+ fprintf(fid, '%s\n', lines{k});
+end
+fclose(fid);
+end
+
+function out = relPath(root, path)
+root = canon(root);
+path = canon(path);
+if strcmp(path, root)
+ out = '';
+elseif startsWith(path, [root '/'])
+ out = extractAfter(path, [root '/']);
+else
+ % Outside the project root — a referenced project is that case. Keep it
+ % relative to the root's PARENT so the record still says nothing about the
+ % machine that wrote it.
+ parent = canon(fileparts(root));
+ if startsWith(path, [parent '/'])
+ out = ['../' char(extractAfter(path, [parent '/']))];
+ else
+ out = ['/' path];
+ end
+end
+out = char(out);
+end
+
+function out = canon(p)
+% Resolve symlinks before comparing: on macOS `tempname` hands back /var/...,
+% which is a link to /private/var, and MATLAB reports the resolved form for some
+% paths and not others. Comparing unresolved strings makes every path look
+% "outside" the project root.
+p = char(p);
+if isfolder(p)
+ w = what(p);
+ if ~isempty(w); p = w(1).path; end
+end
+out = strrep(p, '\', '/');
+while endsWith(out, '/'); out = char(extractBefore(out, strlength(out))); end
+out = char(out);
+end
+
+function out = pathsOf(v)
+% `PathFolders` and `Shortcuts` are string arrays of absolute paths; the
+% `ProjectPath` and `ProjectReferences` arrays are objects carrying a `File`. Both
+% shapes turn up on the same object, so ask rather than assume.
+if isstring(v) || ischar(v)
+ out = cellstr(string(v));
+elseif isempty(v)
+ out = {};
+else
+ out = cell(1, numel(v));
+ for k = 1:numel(v); out{k} = char(v(k).File); end
+end
+out = reshape(out, 1, numel(out));
+end
+
+function out = relPaths(root, paths)
+out = cell(1, numel(paths));
+for k = 1:numel(paths)
+ out{k} = relPath(root, char(paths{k}));
+end
+end
+
+function out = sortCell(c)
+if isempty(c); out = {}; return; end
+out = sort(c);
+out = reshape(out, 1, numel(out));
+end
+
+function out = sortByField(c, field)
+if isempty(c); out = {}; return; end
+keys = cell(1, numel(c));
+for k = 1:numel(c); keys{k} = c{k}.(field); end
+[~, idx] = sort(keys);
+out = c(idx);
+end
diff --git a/test/parity/project.parity.test.ts b/test/parity/project.parity.test.ts
new file mode 100644
index 0000000..b2e0284
--- /dev/null
+++ b/test/parity/project.parity.test.ts
@@ -0,0 +1,483 @@
+// Copyright 2026 The MathWorks, Inc.
+//
+// The PROJECT DEFINITION-FILE parity suite: one small project, written by MATLAB
+// into all four of its metadata layouts, asserted to read back as the same project.
+//
+// `matlab.project.convertDefinitionFiles(root, matlab.project.DefinitionFiles.)`
+// rewrites a project's metadata in place, and there are four shapes it can take:
+//
+// SingleFile one resources/project/Project.xml, the whole store nested
+// inside it, rooted at
+// rather than at . Read since v1.33.0 — the customer
+// report that got it read is what this corpus exists for.
+// FixedPathMultiFile a sidecar XML per entity under hash-named directories,
+// declared `fixedPathV2` by the manifest. Two docs per
+// entity: a `…d.xml` definition and a `…p.xml` pointer.
+// MultiFile the same idea, declared `distributed`, one doc per entity.
+// Toml a matlab.toml at the project ROOT — and no resources/ and
+// NO .prj marker at all. Not read, and not openable either:
+// with no .prj there is nothing for a host to be pointed at.
+//
+// Everything here is written by test/parity/matlab/gen_project.m; nothing in this
+// file launches MATLAB, and project_truth.json is the only source of expected
+// values that did not come out of our own parse. Each /parityProject is a
+// real project — small enough to commit, complete enough to open — and the
+// generator feeds it one of everything the seven collection readers look for.
+//
+// Three kinds of assertion, and the difference matters:
+// - THE LAYOUT IS REAL: each fixture is asserted to carry the on-disk shape its
+// format writes. Without it the parity comparison could pass vacuously, since
+// a corpus regenerated under one format would compare a project to itself.
+// - AGAINST MATLAB: what MATLAB says this project holds, through the project API
+// (`proj.Files`, `proj.StartupFiles`, `proj.Categories`, …) recorded per
+// format from the CONVERTED project — so MATLAB itself is the one saying all
+// four shapes describe the same project.
+// - ACROSS LAYOUTS: the three XML parses are equal but for the format token.
+// This is the claim multi-layout support makes, and the one a
+// wrong-but-consistent reader cannot satisfy.
+//
+// WHY THIS CORPUS EXISTS AT ALL, given a 1,371-line projectParser.test.ts: every
+// store in that suite is hand-typed from reading a real project, which is the one
+// thing test/parity/matlab/README.md says never to do. Real bytes immediately
+// disproved two expectations those hand-typed stores had agreed with:
+// - `ReadOnly` has a vocabulary per element — 'READ_ONLY'/'WRITABLE' on a label,
+// '1'/'0' on a category — so the old presence test read a user's own
+// `WRITABLE` label as one of MATLAB's, and the project page drew it as a
+// built-in. No fixture had ever contained the word WRITABLE.
+// - the first startup file is spelled two ways. A long-lived project writes
+// `Value="HEAD"`; a project that just added two startup files writes no
+// Extension on the first one at all, and only the second carries a link. The
+// chain walk started at HEAD, found no head, and fell back to document order
+// — which is reversed here against the order MATLAB reports running them.
+// Both were parser defects, and both are pinned below against MATLAB's answers.
+import { describe, it, expect } from 'vitest';
+import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
+import { join, relative } from 'node:path';
+import { fileURLToPath } from 'node:url';
+
+import { parseProject } from '../../src/datamodel/parser/ProjectParser.js';
+import type { ParsedProject } from '../../src/datamodel/parser/ProjectParser.js';
+
+const DIR = fileURLToPath(new URL('./artifacts/project/', import.meta.url));
+
+// ---------------------------------------------------------------------------
+// what MATLAB said
+// ---------------------------------------------------------------------------
+
+/** One label ASSIGNMENT on one file. `data` is '' when the label carries none. */
+interface LabelTruth {
+ category: string;
+ name: string;
+ data: string;
+}
+
+interface FileTruth {
+ /** project-root-relative, forward slashes */
+ path: string;
+ isFolder: boolean;
+ labels: LabelTruth[];
+}
+
+/**
+ * One label DEFINITION in the catalog, and who owns it.
+ *
+ * `readOnly` is not a property MATLAB exposes — `properties` on a
+ * `matlab.project.LabelDefinition` is {Name, FilePatterns, CategoryName}. It is
+ * MATLAB's REFUSAL to remove one of its own, so `removeError` carries the error
+ * identifier that answered. Keeping the identifier is what makes a refusal for
+ * some other reason visible here rather than silently read as ownership.
+ */
+interface LabelDefTruth {
+ name: string;
+ readOnly: boolean;
+ removeError: string;
+}
+
+interface CategoryTruth {
+ name: string;
+ dataType: string;
+ singleValued: boolean;
+ labels: LabelDefTruth[];
+ readOnly: boolean;
+ removeError: string;
+}
+
+interface ReferenceTruth {
+ path: string;
+ storedLocation: string;
+ type: string;
+}
+
+interface FormatTruth {
+ name: string;
+ /** MATLAB's own name for the layout: `proj.DefinitionFilesType`. */
+ definitionFilesType: string;
+ files: FileTruth[];
+ pathFolders: string[];
+ /** in RUN order, not sorted — that is the claim. */
+ startupFiles: string[];
+ shutdownFiles: string[];
+ shortcuts: string[];
+ references: ReferenceTruth[];
+ simulinkCacheFolder: string;
+ simulinkCodeGenFolder: string;
+ projectStartupFolder: string;
+ categories: CategoryTruth[];
+ /** MATLAB's own `lastwarn` for the conversion — '' when it warned about nothing. */
+ convertWarning: string;
+ convertWarningId: string;
+}
+
+interface ProjectTruth {
+ release: string;
+ version: string;
+ formats: Record;
+}
+
+const TRUTH_FILE = DIR + 'project_truth.json';
+const HAVE_TRUTH = existsSync(TRUTH_FILE);
+const TRUTH: ProjectTruth = HAVE_TRUTH
+ ? JSON.parse(readFileSync(TRUTH_FILE, 'utf8'))
+ : ({ formats: {} } as ProjectTruth);
+
+// ---------------------------------------------------------------------------
+// the layout matrix
+// ---------------------------------------------------------------------------
+//
+// Written down rather than sniffed, and then asserted against the fixture. These
+// are the same rows as the table in test/parity/matlab/README.md, and they are
+// what makes this suite a statement about FORMATS rather than about four
+// directories that happen to agree.
+
+interface Layout {
+ /** the `matlab.project.DefinitionFiles` member the generator passed. */
+ format: string;
+ /** what the store DECLARES as its `MetadataType`, and so our `format`. */
+ metadataType: string;
+ /** `*.xml` documents under resources/project/ — 0 when there is no store. */
+ storeDocs: number;
+ /** a `.prj` marker beside the store. */
+ marker: boolean;
+ /** a `matlab.toml` at the project root. */
+ toml: boolean;
+}
+
+const LAYOUTS: Layout[] = [
+ { format: 'SingleFile', metadataType: 'monolithic', storeDocs: 1, marker: true, toml: false },
+ {
+ format: 'FixedPathMultiFile',
+ metadataType: 'fixedPathV2',
+ storeDocs: 66,
+ marker: true,
+ toml: false,
+ },
+ { format: 'MultiFile', metadataType: 'distributed', storeDocs: 30, marker: true, toml: false },
+ { format: 'Toml', metadataType: '', storeDocs: 0, marker: false, toml: true },
+];
+
+/** The three a host can open. Toml has its own section. */
+const XML_LAYOUTS = LAYOUTS.filter((l) => !l.toml);
+
+const rootOf = (format: string): string => join(DIR, format, 'parityProject');
+
+/**
+ * The project store, read the way the host reads it: every `*.xml` under
+ * `resources/project/`, keyed by POSIX relpath from the project ROOT. Mirrors
+ * `readProjectStore` in the vscode extension (src/host/projectStore.ts), which is
+ * the only caller that builds one of these from a directory.
+ */
+function storeOf(root: string): Record {
+ const out: Record = {};
+ const base = join(root, 'resources', 'project');
+ if (!existsSync(base)) {
+ return out;
+ }
+ const walk = (dir: string): void => {
+ for (const name of readdirSync(dir)) {
+ const p = join(dir, name);
+ if (statSync(p).isDirectory()) {
+ walk(p);
+ } else if (/\.xml$/i.test(name)) {
+ out[relative(root, p).split('\\').join('/')] = readFileSync(p, 'utf8');
+ }
+ }
+ };
+ walk(base);
+ return out;
+}
+
+// A name the fixture does NOT contain, so every assertion on `parsed.name` is
+// about what the store says and not about what was passed in. The host passes the
+// `.prj` basename; the store's own Name wins when it has one.
+const FALLBACK_NAME = 'not-the-project-name';
+
+const parse = (format: string): ParsedProject =>
+ parseProject(storeOf(rootOf(format)), FALLBACK_NAME);
+
+/** `Category/Name` per label id, through the catalog the same parse returned. */
+function assignedLabels(parsed: ParsedProject, path: string): string[] {
+ const catalog = new Map(parsed.labels.map((l) => [l.id, l]));
+ const file = parsed.files.find((f) => f.path === path);
+ return (file?.labels ?? [])
+ .map((id) => {
+ const l = catalog.get(id);
+ return l ? `${l.category}/${l.name}` : ``;
+ })
+ .sort();
+}
+
+const truthLabels = (t: FileTruth): string[] =>
+ t.labels.map((l) => `${l.category}/${l.name}`).sort();
+
+const filesOfKind = (parsed: ParsedProject, kind: string): string[] =>
+ parsed.entryPoints.filter((e) => e.kind === kind).map((e) => e.file);
+
+const HAVE_CORPUS = existsSync(DIR) && LAYOUTS.every((l) => existsSync(rootOf(l.format)));
+
+describe('project definition-file parity', () => {
+ if (!HAVE_TRUTH || !HAVE_CORPUS) {
+ it.skip('corpus not generated — run gen_project.m (see test/parity/matlab/README.md)', () => {});
+ return;
+ }
+
+ // ---- the layout is real --------------------------------------------------
+
+ for (const layout of LAYOUTS) {
+ it(`${layout.format} is on disk in the shape that format writes`, () => {
+ const root = rootOf(layout.format);
+ const store = storeOf(root);
+ expect(Object.keys(store).length).toBe(layout.storeDocs);
+
+ const entries = readdirSync(root);
+ expect(entries.some((n) => n.endsWith('.prj'))).toBe(layout.marker);
+ expect(entries.includes('matlab.toml')).toBe(layout.toml);
+ expect(existsSync(join(root, 'resources', 'project'))).toBe(layout.storeDocs > 0);
+ });
+ }
+
+ it('SingleFile is ONE document, and it is the whole store', () => {
+ const store = storeOf(rootOf('SingleFile'));
+ expect(Object.keys(store)).toEqual(['resources/project/Project.xml']);
+ // Rooted at , not at — the trap the customer report turned on.
+ // A reader indexing only `` roots finds nothing here and reports an empty
+ // project, which is exactly what v1.33.0 fixed.
+ const doc = store['resources/project/Project.xml'];
+ expect(doc).toMatch(/');
+ });
+
+ for (const layout of XML_LAYOUTS.filter((l) => l.metadataType !== 'monolithic')) {
+ it(`${layout.format} declares ${layout.metadataType} in a manifest beside its sidecars`, () => {
+ const store = storeOf(rootOf(layout.format));
+ const manifest = store['resources/project/Project.xml'];
+ expect(manifest).toMatch(
+ new RegExp(``),
+ );
+ // A manifest and sidecars, which is what makes this a different layout and
+ // not the monolithic document under another name.
+ expect(Object.keys(store).length).toBeGreaterThan(1);
+ });
+ }
+
+ // ---- against MATLAB ------------------------------------------------------
+
+ for (const layout of XML_LAYOUTS) {
+ const t = TRUTH.formats[layout.format];
+
+ describe(`${layout.format} against MATLAB`, () => {
+ const parsed = parse(layout.format);
+
+ it('reads without warnings, and names itself from the store', () => {
+ expect(parsed.warnings).toEqual([]);
+ expect(parsed.name).toBe(t.name);
+ expect(parsed.name).not.toBe(FALLBACK_NAME);
+ });
+
+ it(`reports the layout MATLAB calls ${layout.format}`, () => {
+ expect(t.definitionFilesType).toBe(layout.format);
+ expect(parsed.format).toBe(layout.metadataType);
+ });
+
+ it('holds the members MATLAB lists, folders marked as folders', () => {
+ expect(parsed.files.map((f) => ({ path: f.path, isFolder: f.isFolder }))).toEqual(
+ t.files.map((f) => ({ path: f.path, isFolder: f.isFolder })),
+ );
+ });
+
+ it('assigns each member the labels MATLAB assigned it', () => {
+ for (const file of t.files) {
+ expect(assignedLabels(parsed, file.path), file.path).toEqual(truthLabels(file));
+ }
+ // The one assignment that is not a built-in: a user's own label, carrying
+ // data. We model the ASSIGNMENT and not the data — `ProjectFile.labels` is
+ // a list of ids — so MATLAB's 'by parity' has nowhere to land here. Stated
+ // rather than asserted away: the project page shows which labels a file
+ // carries, not what each one says.
+ const helper = t.files.find((f) => f.path === 'utils/helper.m');
+ expect(helper?.labels.find((l) => l.name === 'Checked')?.data).toBe('by parity');
+ });
+
+ it('defines the label catalog MATLAB defines, with the same owner per label', () => {
+ const expected = t.categories.flatMap((c) =>
+ c.labels.map((l) => ({ category: c.name, name: l.name, readOnly: l.readOnly })),
+ );
+ const actual = parsed.labels.map((l) => ({
+ category: l.category,
+ name: l.name,
+ readOnly: l.readOnly,
+ }));
+ const key = (l: { category: string; name: string }): string => `${l.category}/${l.name}`;
+ expect([...actual].sort((a, b) => key(a).localeCompare(key(b)))).toEqual(
+ [...expected].sort((a, b) => key(a).localeCompare(key(b))),
+ );
+ });
+
+ it("the ownership expectation is MATLAB's refusal, not a reading of an attribute", () => {
+ // What makes the previous test authoritative. Every read-only label is one
+ // MATLAB refused to remove, by the identifier that means ownership; every
+ // writable one it removed without complaint. A future release refusing for
+ // a different reason fails HERE, where the record is, instead of quietly
+ // becoming the expectation.
+ for (const c of t.categories) {
+ for (const l of c.labels) {
+ expect(l.removeError, `${c.name}/${l.name}`).toBe(
+ l.readOnly ? 'MATLAB:project:management:CanNotModifyReadOnlyLabel' : '',
+ );
+ }
+ }
+ const builtIn = t.categories.find((c) => c.name === 'Classification');
+ expect(builtIn?.labels.every((l) => l.readOnly)).toBe(true);
+ expect(builtIn?.removeError).toBe(
+ 'MATLAB:project:management:CanNotModifyReadOnlyCategory',
+ );
+ const mine = t.categories.find((c) => c.name === 'Review');
+ expect(mine?.labels.map((l) => l.readOnly)).toEqual([false]);
+ });
+
+ it('puts the project path folders MATLAB has on the path', () => {
+ expect(parsed.pathFolders).toEqual(t.pathFolders);
+ });
+
+ it('puts the startup and shutdown files in the order MATLAB runs them', () => {
+ expect(filesOfKind(parsed, 'StartUp')).toEqual(t.startupFiles);
+ expect(filesOfKind(parsed, 'Shutdown')).toEqual(t.shutdownFiles);
+ // Two startup files on purpose: with one, any order is the right order.
+ expect(t.startupFiles.length).toBe(2);
+ // Hooks are hidden and shortcuts are shown — MATLAB's Shortcuts gallery
+ // holds the latter only, and `visible` is how the store says which.
+ for (const e of parsed.entryPoints) {
+ expect(e.visible, e.name).toBe(e.kind === 'Basic');
+ }
+ });
+
+ it('holds the shortcut MATLAB holds', () => {
+ expect(filesOfKind(parsed, 'Basic').sort()).toEqual([...t.shortcuts].sort());
+ });
+
+ it('resolves the referenced project', () => {
+ expect(parsed.references.map((r) => r.path)).toEqual(t.references.map((r) => r.path));
+ // The name is DERIVED — the store element carries `Ref="../parityLib"` and
+ // `Type="Relative"` and no name at all, so the basename is the only name
+ // there is. Not a MATLAB field, which is why this is asserted against the
+ // path and not against the truth record.
+ expect(parsed.references.map((r) => r.name)).toEqual(['parityLib']);
+ expect(t.references.map((r) => r.type)).toEqual(['Relative']);
+ });
+
+ it('designates the working folders MATLAB designates', () => {
+ const wf = new Map(parsed.workingFolders.map((w) => [w.key, w.ref]));
+ expect(wf.get('SimulinkCacheFolder')).toBe(t.simulinkCacheFolder);
+ expect(wf.get('SimulinkCodeGenFolder')).toBe(t.simulinkCodeGenFolder);
+ expect(wf.get('ProjectStartupFolder')).toBe(t.projectStartupFolder);
+ });
+ });
+ }
+
+ // ---- across layouts ------------------------------------------------------
+
+ it('converted losslessly, which is what licenses the comparison below', () => {
+ // MATLAB's own `lastwarn` for each conversion. The three XML formats warn
+ // about nothing; the Toml one does, and is compared separately for that
+ // reason.
+ for (const layout of XML_LAYOUTS) {
+ expect(TRUTH.formats[layout.format].convertWarningId, layout.format).toBe('');
+ }
+ });
+
+ for (const layout of XML_LAYOUTS.filter((l) => l.format !== 'SingleFile')) {
+ it(`${layout.format} reads as the same project as SingleFile`, () => {
+ // Everything, not a field list: the whole parse but for the one field that
+ // is SUPPOSED to differ. Conversion preserves the entities' UUIDs, so even
+ // the ids compare — and a reader that invented an id per layout, or dropped
+ // a collection in one of them, cannot pass this.
+ const reference = { ...parse('SingleFile'), format: '' };
+ const other = { ...parse(layout.format), format: '' };
+ expect(other).toEqual(reference);
+ });
+ }
+
+ // ---- Toml: a format this reader does not read, and need not --------------
+
+ describe('Toml', () => {
+ const root = rootOf('Toml');
+
+ it('has no .prj and no store, so there is nothing for a host to open', () => {
+ // The answer to "where did the .prj go": the conversion deletes it along
+ // with resources/, and `matlab.toml` at the root is the entire project
+ // definition. A project in this shape never reaches this parser, because the
+ // extension is registered against `.prj` — this is a missing FILE TYPE, not
+ // a parse gap.
+ expect(readdirSync(root).some((n) => n.endsWith('.prj'))).toBe(false);
+ expect(existsSync(join(root, 'resources'))).toBe(false);
+ expect(existsSync(join(root, 'matlab.toml'))).toBe(true);
+ expect(readFileSync(join(root, 'matlab.toml'), 'utf8')).toContain('name = "parityProject"');
+ });
+
+ it('reads as empty, through the generic warning and not the matlab.toml one', () => {
+ const parsed = parse('Toml');
+ expect(parsed.files).toEqual([]);
+ expect(parsed.warnings.map((w) => w.code)).toEqual(['source-empty']);
+ // Deliberate: the parser's matlab.toml-specific message is keyed on a
+ // `resources/project/matlab.toml` entry, and R2027a writes the file at the
+ // project ROOT with no resources/ at all. That branch is for a store an
+ // older release wrote, so this case lands on the generic message.
+ expect(parsed.warnings[0].message).toContain('No readable project entries were found');
+ });
+
+ it('is LOSSY, and MATLAB says so in its own words', () => {
+ const t = TRUTH.formats.Toml;
+ expect(t.convertWarningId).toBe('MATLAB:Project:Issues:LabelDataLoss');
+ expect(t.convertWarning).toContain('Unable to preserve label data');
+
+ // What that cost, as MATLAB reports the converted project. Recorded so the
+ // loss stays a measured property of the format rather than folklore:
+ // - the whole built-in Classification category is gone, and with it every
+ // Design assignment the three XML formats keep;
+ const categories = t.categories.map((c) => c.name);
+ expect(categories).toEqual(['Review']);
+ const design = t.files.flatMap((f) => f.labels.filter((l) => l.name === 'Design'));
+ expect(design).toEqual([]);
+ // - the custom category survives but its dataType does not, so the label
+ // keeps its name and loses the 'by parity' data it carried;
+ expect(t.categories[0].dataType).toBe('none');
+ expect(TRUTH.formats.SingleFile.categories.find((c) => c.name === 'Review')?.dataType).toBe(
+ 'char',
+ );
+ const checked = t.files
+ .flatMap((f) => f.labels)
+ .filter((l) => l.name === 'Checked')
+ .map((l) => l.data);
+ expect(checked).toEqual(['']);
+ // - and the two working folders become ordinary members, because the file
+ // has a place to record a path and none to record what it is for.
+ const members = t.files.map((f) => f.path);
+ expect(members).toContain('cache');
+ expect(members).toContain('codegen');
+ expect(TRUTH.formats.SingleFile.files.map((f) => f.path)).not.toContain('cache');
+ // The one thing that does survive intact, and the reason the run-order claim
+ // above is about the project and not about XML: MATLAB still reports the same
+ // two startup files in the same order.
+ expect(t.startupFiles).toEqual(TRUTH.formats.SingleFile.startupFiles);
+ });
+ });
+});
diff --git a/test/projectParser.test.ts b/test/projectParser.test.ts
index 99226ea..06d99bb 100644
--- a/test/projectParser.test.ts
+++ b/test/projectParser.test.ts
@@ -554,14 +554,21 @@ describe('parseProject — the label catalog', () => {
// ReadOnly in the store; a label the project ADDED is not. That marking is the
// only thing separating the two, and it is what lets a page distinguish "this
// project defines its own vocabulary" from "this project uses the defaults".
- // Note the attribute spells itself 'READ_ONLY' on a label and '1' on a category,
- // so presence is what is read, not any one value.
+ //
+ // THE ATTRIBUTE HAS A VOCABULARY PER ELEMENT: 'READ_ONLY'/'WRITABLE' on a
+ // label, '1'/'0' on a category. `WRITABLE` is the case that matters and the one
+ // no hand-typed fixture here had ever contained — the rule used to be presence,
+ // which read a project's own label as one of MATLAB's and drew it on the page as
+ // a built-in. Measured on a MATLAB-written project: see
+ // test/parity/project.parity.test.ts, where the same claim is held to MATLAB's
+ // refusal to remove its own labels.
const parsed = parseProject(
store({
root: { cc: [''] },
cc: { cat: ['', ''] },
cat: {
builtin: ['', ''],
+ writable: ['', ''],
mine: ['', ''],
},
}),
@@ -569,6 +576,8 @@ describe('parseProject — the label catalog', () => {
);
const byId = new Map(parsed.labels.map((l) => [l.id, l]));
expect(byId.get('design')?.readOnly).toBe(true);
+ expect(byId.get('checked')?.readOnly).toBe(false);
+ // An older store writes no attribute at all on a label the project added.
expect(byId.get('mine')?.readOnly).toBe(false);
});
@@ -603,9 +612,11 @@ describe('parseProject — the label catalog', () => {
}),
'fallback',
);
+ // By category then name, not in store order: see the sort in parseProject —
+ // one project in two metadata layouts handed its catalog over in two orders.
expect(parsed.labels).toEqual([
- { id: 'lab1', category: 'Cat', name: 'Label One', readOnly: false },
{ id: 'lab2', category: 'Cat', name: 'lab2', readOnly: false },
+ { id: 'lab1', category: 'Cat', name: 'Label One', readOnly: false },
]);
});
});
@@ -751,10 +762,12 @@ describe('parseProject — working folders', () => {
// designate a purpose this version has no label for, and passing the raw key
// through lets a host show it rather than silently drop the row.
const parsed = parseProject(workingFolderStore(), 'fallback');
+ // By key, not in store order — these are keyed by purpose and the store's own
+ // order is its directory order, which differs between metadata layouts.
expect(parsed.workingFolders).toEqual([
- { key: 'SimulinkCacheFolder', ref: 'Cache' },
{ key: 'DependencyCacheFile', ref: 'Dep/cache.graphml' },
{ key: 'NewInSomeFutureRelease', ref: 'Somewhere' },
+ { key: 'SimulinkCacheFolder', ref: 'Cache' },
]);
});
@@ -813,6 +826,34 @@ describe('parseProject — entry points', () => {
expect(parsed.entryPoints.map((e) => e.name)).toEqual(['first', 'second']);
});
+ it('puts a hook in run order when the first file is unchained rather than HEAD', () => {
+ // The OTHER spelling of first, and the common one: a project that added two
+ // startup files and never reordered them writes no Extension on the first at
+ // all — only the second carries a link. Reading `HEAD` as the only head found
+ // no head here and fell back to document order, which is the order the store
+ // serializes UUIDs in: reversed, in the project MATLAB wrote for
+ // test/parity/project.parity.test.ts, against the order MATLAB runs them.
+ const parsed = parseProject(
+ store({
+ root: { ep: [''] },
+ ep: {
+ // Written second-first, as the monolithic document does.
+ two: [
+ '',
+ '' +
+ '',
+ ],
+ one: [
+ '',
+ '',
+ ],
+ },
+ }),
+ 'fallback',
+ );
+ expect(parsed.entryPoints.map((e) => e.name)).toEqual(['startup_one', 'startup_two']);
+ });
+
it('yields every entry exactly once when the chain is a cycle', () => {
// Nothing in the store prevents it, and a chain walk that trusts the links
// would never terminate. Order is then undefined, but completeness is not.