fix: add support for Apple icon assets for manifest suggestions and diagnostics (#289)

* test: add tests for `expo.icon` asset diagnostics

* fix: avoid marking `.cion` assets as "directory" when diagnosing manifests

* fix: auto-complete Apple `.icon` references as files
This commit is contained in:
Cedric van Putten authored and GitHub committed 2026-05-21 12:13:21 +02:00
1 parent a3fc22079a
commit 075f8daa60
8 files changed
+78 -7

No files matched your search

@@ -1,3 +1,4 @@
import 'sinon-chai';
import { expect } from 'chai';
import vscode from 'vscode';
@@ -41,12 +42,13 @@ describe('ManifestAssetCompletionsProvider', () => {
);
// Make sure only these files are suggested, it might trigger false positives
expect(suggestions.items).to.have.length(4);
expect(suggestions.items).to.have.length(5);
expect(suggestions.items).to.containSubset([
{ label: 'adaptive-icon.png' },
{ label: 'favicon.png' },
{ label: 'icon.png' },
{ label: 'splash.png' },
{ label: 'expo.icon' },
]);
});
+25 -5
View File
@@ -62,6 +62,31 @@ describe('ManifestDiagnosticsProvider', () => {
});
});
it('diagnoses non-existing asset directory reference for Apple .icon folders', async () => {
const range = findContentRange(app, './assets/adaptive-icon.png');
await app.edit((builder) => builder.replace(range, './assets/expo-non-existing.icon'));
await waitFor(1000);
const diagnostics = await vscode.languages.getDiagnostics(app.document.uri);
expect(diagnostics).to.have.length(1);
expect(diagnostics[0]).contain({
code: 'FILE_NOT_FOUND',
message: 'File not found: ./assets/expo-non-existing.icon',
severity: vscode.DiagnosticSeverity.Warning,
});
});
it('does not diagnose asset directory reference for Apple .icon folders', async () => {
const range = findContentRange(app, './assets/adaptive-icon.png');
await app.edit((builder) => builder.replace(range, './assets/expo.icon'));
await waitFor(1000);
const diagnostics = await vscode.languages.getDiagnostics(app.document.uri);
expect(diagnostics).to.have.length(0);
});
it('diagnoses non-existing plugin definition', async () => {
const range = findContentRange(app, '"expo-system-ui",');
await app.edit((builder) => builder.replace(range, '"doesnt-exists",'));
@@ -70,11 +95,6 @@ describe('ManifestDiagnosticsProvider', () => {
const diagnostics = await vscode.languages.getDiagnostics(app.document.uri);
expect(diagnostics).to.have.length(1);
expect(diagnostics[0]).contain({
code: 'PLUGIN_NOT_FOUND',
message: 'Plugin not found: doesnt-exists',
severity: vscode.DiagnosticSeverity.Warning,
});
});
it('diagnoses empty string plugin definition', async () => {
+1
View File
@@ -1,4 +1,5 @@
import { expect } from 'chai';
import 'sinon-chai';
import { mockDevice } from '../../__tests__/utils/debugging';
import { stubFetch } from '../../__tests__/utils/fetch';
+5
View File
@@ -91,6 +91,11 @@ export class ManifestAssetCompletionsProvider extends ExpoCompletionsProvider {
return null;
}
// Apple icons are always folders, but we auto-complete it as file
if (entityType === vscode.FileType.Directory && entityName.endsWith('.icon')) {
return createFile(entityName);
}
if (entityType === vscode.FileType.Directory) {
return createFolder(entityName);
}
+1 -1
View File
@@ -122,7 +122,7 @@ async function diagnoseAsset(
const uri = vscode.Uri.joinPath(project.root, reference.filePath);
const asset = await vscode.workspace.fs.stat(uri);
if (asset.type === vscode.FileType.Directory) {
if (!reference.filePath.endsWith('.icon') && asset.type === vscode.FileType.Directory) {
const issue = new vscode.Diagnostic(
getDocumentRange(document, reference.fileRange),
`File is a directory: ${reference.filePath}`,
@@ -0,0 +1,3 @@
<svg width="652" height="606" viewBox="0 0 652 606" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M353.554 0H298.446C273.006 0 249.684 14.6347 237.962 37.9539L4.37994 502.646C-1.04325 513.435 -1.45067 526.178 3.2716 537.313L22.6123 582.918C34.6475 611.297 72.5404 614.156 88.4414 587.885L309.863 222.063C313.34 216.317 319.439 212.826 326 212.826C332.561 212.826 338.659 216.317 342.137 222.063L563.559 587.885C579.46 614.156 617.352 611.297 629.388 582.918L648.728 537.313C653.451 526.178 653.043 513.435 647.62 502.646L414.038 37.9539C402.316 14.6347 378.994 0 353.554 0Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 608 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

@@ -0,0 +1,40 @@
{
"fill" : {
"automatic-gradient" : "extended-srgb:0.00000,0.47843,1.00000,1.00000"
},
"groups" : [
{
"layers" : [
{
"image-name" : "expo-symbol 2.svg",
"name" : "expo-symbol 2",
"position" : {
"scale" : 1,
"translation-in-points" : [
1.1008400065293245e-05,
-16.046875
]
}
},
{
"image-name" : "grid.png",
"name" : "grid"
}
],
"shadow" : {
"kind" : "neutral",
"opacity" : 0.5
},
"translucency" : {
"enabled" : true,
"value" : 0.5
}
}
],
"supported-platforms" : {
"circles" : [
"watchOS"
],
"squares" : "shared"
}
}