Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/diagnostics/rust.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,7 @@ export function createCargoDiagnostic(
label: 'Cargo',
status: 'fail',
message: 'Cargo is unavailable or could not be executed.',
remediation:
'Install Cargo with the Rust toolchain and ensure `cargo` is available on PATH.',
remediation: 'Install Cargo and ensure `cargo` is available on PATH.',
};
}

Expand All @@ -98,7 +97,7 @@ export function createCargoDiagnostic(
status: 'fail',
message: 'Cargo returned an unrecognized version.',
remediation:
'Verify `cargo --version` works and reinstall Rust if necessary.',
'Verify `cargo --version` works and reinstall Cargo if necessary.',
};
}

Expand Down
74 changes: 66 additions & 8 deletions tests/rust-diagnostics.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ describe('Rust diagnostic', () => {
const diagnostic = createRustDiagnostic(execute).run();

expect(diagnostic.status).toBe('fail');
expect(diagnostic.remediation).toContain('>=1.84.0');
expect(diagnostic.remediation).toBe(
'Upgrade to Rust >=1.84.0 before building Stellar smart contracts.',
);
});

it('fails when rustc is unavailable without leaking process details', () => {
Expand All @@ -55,16 +57,24 @@ describe('Rust diagnostic', () => {
expect(diagnostic.message).toBe(
'Rust is unavailable or could not be executed.',
);
expect(diagnostic.remediation).toBe(
'Install Rust >=1.84.0 and ensure `rustc` is available on PATH.',
);
expect(JSON.stringify(diagnostic)).not.toContain('SECRET_TOKEN');
});

it('fails malformed rustc output', () => {
const execute: RunCommand = () => result(0, 'rustc unknown\n');
it('fails malformed rustc output without leaking stderr or process details', () => {
const execute: RunCommand = () =>
result(0, 'rustc unknown\n', 'SECRET_TOKEN=do-not-render');

const diagnostic = createRustDiagnostic(execute).run();

expect(diagnostic.status).toBe('fail');
expect(diagnostic.message).toBe('Rust returned an unrecognized version.');
expect(diagnostic.remediation).toBe(
'Verify `rustc --version` works and reinstall Rust if necessary.',
);
expect(JSON.stringify(diagnostic)).not.toContain('SECRET_TOKEN');
});
});

Expand All @@ -83,22 +93,70 @@ describe('Cargo diagnostic', () => {
expect(diagnostic.message).toContain('1.89.0');
});

it('fails when Cargo is unavailable without affecting Rust checks', () => {
it('fails when Cargo is unavailable without leaking process details', () => {
const execute: RunCommand = () =>
result(null, '', '', new Error('spawn cargo ENOENT'));
result(
null,
'',
'SECRET_TOKEN=do-not-render',
new Error('spawn cargo ENOENT SECRET_TOKEN=do-not-render'),
);

const diagnostic = createCargoDiagnostic(execute).run();

expect(diagnostic.status).toBe('fail');
expect(diagnostic.remediation).toContain('cargo');
expect(diagnostic.message).toBe(
'Cargo is unavailable or could not be executed.',
);
expect(diagnostic.remediation).toBe(
'Install Cargo and ensure `cargo` is available on PATH.',
);
expect(JSON.stringify(diagnostic)).not.toContain('SECRET_TOKEN');
});

it('fails malformed Cargo output', () => {
const execute: RunCommand = () => result(0, 'cargo unknown\n');
it('fails malformed Cargo output without leaking stderr or process details', () => {
const execute: RunCommand = () =>
result(0, 'cargo unknown\n', 'SECRET_TOKEN=do-not-render');

const diagnostic = createCargoDiagnostic(execute).run();

expect(diagnostic.status).toBe('fail');
expect(diagnostic.message).toBe('Cargo returned an unrecognized version.');
expect(diagnostic.remediation).toBe(
'Verify `cargo --version` works and reinstall Cargo if necessary.',
);
expect(JSON.stringify(diagnostic)).not.toContain('SECRET_TOKEN');
});

it('provides independently actionable guidance when rustc fails and cargo passes', () => {
const rustExecute: RunCommand = () =>
result(null, '', '', new Error('spawn rustc ENOENT'));
const cargoExecute: RunCommand = () =>
result(0, 'cargo 1.89.0 (c24e10642 2025-06-23)\n');

const rustDiag = createRustDiagnostic(rustExecute).run();
const cargoDiag = createCargoDiagnostic(cargoExecute).run();

expect(rustDiag.status).toBe('fail');
expect(rustDiag.remediation).toBe(
'Install Rust >=1.84.0 and ensure `rustc` is available on PATH.',
);
expect(cargoDiag.status).toBe('pass');
});

it('provides independently actionable guidance when cargo fails and rustc passes', () => {
const rustExecute: RunCommand = () =>
result(0, 'rustc 1.84.0 (9fc6b4312 2025-01-07)\n');
const cargoExecute: RunCommand = () =>
result(null, '', '', new Error('spawn cargo ENOENT'));

const rustDiag = createRustDiagnostic(rustExecute).run();
const cargoDiag = createCargoDiagnostic(cargoExecute).run();

expect(rustDiag.status).toBe('pass');
expect(cargoDiag.status).toBe('fail');
expect(cargoDiag.remediation).toBe(
'Install Cargo and ensure `cargo` is available on PATH.',
);
});
});