fix inherit from
This commit is contained in:
@@ -239,6 +239,88 @@ test("Ctrl+click on simple-content text jumps to the definition", async () => {
|
||||
);
|
||||
});
|
||||
|
||||
test("hover on simpleContent complex content shows the referenced definition", async () => {
|
||||
const text =
|
||||
`<AssetDeclaration>\n` +
|
||||
` <AudioEvent id="A">\n` +
|
||||
` <Sound>VoiceFile</Sound>\n` +
|
||||
` </AudioEvent>\n` +
|
||||
`</AssetDeclaration>`;
|
||||
const def = {
|
||||
type: "AudioFile",
|
||||
id: "VoiceFile",
|
||||
file: URI,
|
||||
line: 2,
|
||||
origin: "project",
|
||||
};
|
||||
const scope = await makeScope(text, makeIdx([def]));
|
||||
const provider = new Ra3HoverProvider({
|
||||
isRa3Workspace: () => true,
|
||||
getScope: async () => scope,
|
||||
searchPaths: () => null,
|
||||
});
|
||||
const line = text.split("\n")[2];
|
||||
const pos = new Position(2, line.indexOf("VoiceFile") + 3);
|
||||
const hover = await provider.provideHover(makeDocument(text), pos, {});
|
||||
assert.ok(hover, "hover is returned for AudioFileRefWithWeight content");
|
||||
assert.match(hover.contents.value, /1 definition/);
|
||||
assert.match(hover.contents.value, /AudioFile/);
|
||||
});
|
||||
|
||||
test("Ctrl+click on simpleContent complex content jumps to the definition", async () => {
|
||||
const text =
|
||||
`<AssetDeclaration>\n` +
|
||||
` <AudioEvent id="A">\n` +
|
||||
` <Sound>VoiceFile</Sound>\n` +
|
||||
` </AudioEvent>\n` +
|
||||
`</AssetDeclaration>`;
|
||||
const def = {
|
||||
type: "AudioFile",
|
||||
id: "VoiceFile",
|
||||
file: URI,
|
||||
line: 2,
|
||||
origin: "project",
|
||||
};
|
||||
const scope = await makeScope(text, makeIdx([def]));
|
||||
const provider = new Ra3DefinitionProvider({
|
||||
isRa3Workspace: () => true,
|
||||
getScope: async () => scope,
|
||||
settings: { definitionMode: "all" },
|
||||
indexer: null,
|
||||
});
|
||||
const line = text.split("\n")[2];
|
||||
const pos = new Position(2, line.indexOf("VoiceFile") + 3);
|
||||
const locations = await provider.provideDefinition(makeDocument(text), pos, {});
|
||||
assert.ok(locations && locations.length === 1);
|
||||
assert.equal(locations[0].uri.fsPath, URI);
|
||||
});
|
||||
|
||||
test("diagnostics report unresolved simpleContent complex content references", async () => {
|
||||
const text =
|
||||
`<AssetDeclaration>\n` +
|
||||
` <Multisound id="M">\n` +
|
||||
` <Subsound>MissingEvent</Subsound>\n` +
|
||||
` </Multisound>\n` +
|
||||
`</AssetDeclaration>`;
|
||||
const scope = await makeScope(text, makeIdx([]));
|
||||
const collection = new FakeDiagnosticCollection();
|
||||
const provider = new Ra3Diagnostics({
|
||||
isRa3Workspace: () => true,
|
||||
getScope: async () => scope,
|
||||
settings: {
|
||||
diagnoseUnknownElements: false,
|
||||
reportUnresolvedReferences: "warning",
|
||||
},
|
||||
});
|
||||
provider["collection"] = collection;
|
||||
await provider.update(makeDocument(text));
|
||||
const messages = collection.last.diags.map((d) => d.message);
|
||||
assert.ok(
|
||||
messages.some((m) => m.includes('Unresolved reference "MissingEvent"')),
|
||||
"MultisoundSubsoundRef text is diagnosed as a typed content reference",
|
||||
);
|
||||
});
|
||||
|
||||
test("Ctrl+click on a manifest definition maps to SageXml even when the mod shadows the DATA path", async () => {
|
||||
const tmp = mkdtempSync(join(tmpdir(), "ra3-nav-manifest-"));
|
||||
try {
|
||||
@@ -518,6 +600,103 @@ test("fragment diagnostics ignore unknown wrapper roots and still report missing
|
||||
);
|
||||
});
|
||||
|
||||
test("diagnostics accept universal inheritFrom on asset types", async () => {
|
||||
const text =
|
||||
`<AssetDeclaration>\n` +
|
||||
` <FXList id="FX_A" inheritFrom="FX_Base">\n` +
|
||||
` <NuggetList/>\n` +
|
||||
` </FXList>\n` +
|
||||
`</AssetDeclaration>`;
|
||||
const scope = await makeScope(text, makeIdx([]));
|
||||
const collection = new FakeDiagnosticCollection();
|
||||
const provider = new Ra3Diagnostics({
|
||||
isRa3Workspace: () => true,
|
||||
getScope: async () => scope,
|
||||
settings: {
|
||||
diagnoseUnknownElements: true,
|
||||
reportUnresolvedReferences: "none",
|
||||
},
|
||||
});
|
||||
provider["collection"] = collection;
|
||||
await provider.update(makeDocument(text));
|
||||
const codes = collection.last.diags.map((d) => d.code);
|
||||
assert.ok(
|
||||
!codes.includes("unknown-attribute"),
|
||||
"FXList inheritFrom must not be flagged as unknown",
|
||||
);
|
||||
|
||||
const badText =
|
||||
`<AssetDeclaration>\n` +
|
||||
` <FXList id="FX_B" Bogus="x">\n` +
|
||||
` <NuggetList/>\n` +
|
||||
` </FXList>\n` +
|
||||
`</AssetDeclaration>`;
|
||||
const badScope = await makeScope(badText, makeIdx([]));
|
||||
const badCollection = new FakeDiagnosticCollection();
|
||||
const badProvider = new Ra3Diagnostics({
|
||||
isRa3Workspace: () => true,
|
||||
getScope: async () => badScope,
|
||||
settings: {
|
||||
diagnoseUnknownElements: true,
|
||||
reportUnresolvedReferences: "none",
|
||||
},
|
||||
});
|
||||
badProvider["collection"] = badCollection;
|
||||
await badProvider.update(makeDocument(badText));
|
||||
assert.ok(
|
||||
badCollection.last.diags.map((d) => d.code).includes("unknown-attribute"),
|
||||
"a real unknown attribute is still reported",
|
||||
);
|
||||
});
|
||||
|
||||
test("diagnostics keep simpleContent extension attributes known", async () => {
|
||||
const text =
|
||||
`<AssetDeclaration>\n` +
|
||||
` <AudioEvent id="A">\n` +
|
||||
` <Sound Weight="100">AudioFile</Sound>\n` +
|
||||
` </AudioEvent>\n` +
|
||||
`</AssetDeclaration>`;
|
||||
const scope = await makeScope(text, makeIdx([]));
|
||||
const collection = new FakeDiagnosticCollection();
|
||||
const provider = new Ra3Diagnostics({
|
||||
isRa3Workspace: () => true,
|
||||
getScope: async () => scope,
|
||||
settings: {
|
||||
diagnoseUnknownElements: true,
|
||||
reportUnresolvedReferences: "none",
|
||||
},
|
||||
});
|
||||
provider["collection"] = collection;
|
||||
await provider.update(makeDocument(text));
|
||||
const codes = collection.last.diags.map((d) => d.code);
|
||||
assert.ok(
|
||||
!codes.includes("unknown-attribute"),
|
||||
"Weight on AudioFileRefWithWeight must be known",
|
||||
);
|
||||
});
|
||||
|
||||
test("diagnostics use the top-level asset type for colliding fragment roots", async () => {
|
||||
const text =
|
||||
`<EvaEvent id="IncomingTransmission" Priority="100" TimeBetweenEvents="0ms" ExpirationTime="10000ms"/>`;
|
||||
const scope = await makeScope(text, makeIdx([]));
|
||||
const collection = new FakeDiagnosticCollection();
|
||||
const provider = new Ra3Diagnostics({
|
||||
isRa3Workspace: () => true,
|
||||
getScope: async () => scope,
|
||||
settings: {
|
||||
diagnoseUnknownElements: true,
|
||||
reportUnresolvedReferences: "none",
|
||||
},
|
||||
});
|
||||
provider["collection"] = collection;
|
||||
await provider.update(makeDocument(text));
|
||||
const codes = collection.last.diags.map((d) => d.code);
|
||||
assert.ok(
|
||||
!codes.includes("unknown-attribute"),
|
||||
"EvaEvent fragment root attributes must resolve against the top-level asset type",
|
||||
);
|
||||
});
|
||||
|
||||
test("full documents still require ids on top-level assets", async () => {
|
||||
const text = `<AssetDeclaration>\n <GameObject/>\n</AssetDeclaration>`;
|
||||
const scope = await makeScope(text, makeIdx([]));
|
||||
|
||||
Reference in New Issue
Block a user