fix(ci): rustfmt, ESLint this-binding test, Sonar test execution path
CI / Rust Format (pull_request) Successful in 19s
CI / TypeScript Lint + Typecheck (pull_request) Successful in 17s
CI / TypeScript Tests + Coverage (pull_request) Successful in 43s
CI / Rust Tests + Coverage (pull_request) Successful in 1m12s
CI / Dependency-Track (BOM) (pull_request) Successful in 22s
CI / Clippy (SARIF) (pull_request) Successful in 1m21s
CI / E2E Tests (Playwright + Electron) (pull_request) Successful in 1m40s
CI / SonarQube (pull_request) Failing after 36s
CI / Electron Release Build (pull_request) Successful in 2m48s

- Apply nightly rustfmt to format.rs and cli.rs (Rust Format job).
- Use Vitest mock.contexts instead of assigning this in api.test.ts.
- Point sonar.testExecutionReportPaths at Vitest only; SonarQube 26.4
  rejects the nextest report whose file paths are library sources with
  inline tests. Rust coverage still uses sonar.coverageReportPaths.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-09 01:05:33 -04:00
parent 1a3bc1b75c
commit 11dba0d5b7
4 changed files with 46 additions and 17 deletions
+17 -4
View File
@@ -484,7 +484,11 @@ mod tests {
#[test]
fn strip_jsonc_comments_ignores_url_in_string() {
let input = r#"{"url": "https://example.com"}"#;
assert_eq!(strip(input), input, "// inside a string value must not be stripped");
assert_eq!(
strip(input),
input,
"// inside a string value must not be stripped"
);
}
#[test]
@@ -588,7 +592,10 @@ mod tests {
let mut p = JsoncParser::new(b"\"hello\"");
let mut out = String::new();
let consumed = p.advance_normal(0, &mut out);
assert!(p.in_string, "parser must be in string mode after opening quote");
assert!(
p.in_string,
"parser must be in string mode after opening quote"
);
assert_eq!(consumed, 1);
}
@@ -603,7 +610,10 @@ mod tests {
p.advance_in_string(i, &mut out);
}
p.advance_in_string(5, &mut out); // closing "
assert!(!p.in_string, "parser must exit string mode on closing quote");
assert!(
!p.in_string,
"parser must exit string mode on closing quote"
);
}
#[test]
@@ -672,7 +682,10 @@ mod tests {
fn format_document_xml_indents_nested_elements() {
let input = "<root><child>text</child></root>";
let result = format_document(LanguageId::Xml, input).unwrap();
assert!(result.contains('\n'), "XML should be formatted with newlines");
assert!(
result.contains('\n'),
"XML should be formatted with newlines"
);
assert!(result.contains("child"), "child element must be present");
}
+22 -6
View File
@@ -917,10 +917,15 @@ mod tests {
&req("s1", "save_session", json!({ "session": session_json })),
&fresh_state(),
);
assert!(ok_val(&save_r).is_null(), "save_session must return ok:null");
assert!(
ok_val(&save_r).is_null(),
"save_session must return ok:null"
);
let load_r = dispatch(&req("s2", "load_session", json!({})), &fresh_state());
let raw = ok_val(&load_r).as_str().expect("load_session must return the raw JSON string");
let raw = ok_val(&load_r)
.as_str()
.expect("load_session must return the raw JSON string");
assert!(raw.contains("tabs"), "loaded session must contain 'tabs'");
// Restore HOME
@@ -941,7 +946,10 @@ mod tests {
}
let r = dispatch(&req("s3", "load_session", json!({})), &fresh_state());
assert!(ok_val(&r).is_null(), "load_session must return ok:null when no session file exists");
assert!(
ok_val(&r).is_null(),
"load_session must return ok:null when no session file exists"
);
if let Some(home) = orig_home {
unsafe { std::env::set_var("HOME", home) };
@@ -966,10 +974,15 @@ mod tests {
&req("p1", "save_ui_prefs", json!({ "prefs": prefs_json })),
&fresh_state(),
);
assert!(ok_val(&save_r).is_null(), "save_ui_prefs must return ok:null");
assert!(
ok_val(&save_r).is_null(),
"save_ui_prefs must return ok:null"
);
let load_r = dispatch(&req("p2", "load_ui_prefs", json!({})), &fresh_state());
let raw = ok_val(&load_r).as_str().expect("load_ui_prefs must return the raw JSON string");
let raw = ok_val(&load_r)
.as_str()
.expect("load_ui_prefs must return the raw JSON string");
assert!(raw.contains("theme"), "loaded prefs must contain 'theme'");
if let Some(home) = orig_home {
@@ -989,7 +1002,10 @@ mod tests {
}
let r = dispatch(&req("p3", "load_ui_prefs", json!({})), &fresh_state());
assert!(ok_val(&r).is_null(), "load_ui_prefs must return ok:null when no prefs file exists");
assert!(
ok_val(&r).is_null(),
"load_ui_prefs must return ok:null when no prefs file exists"
);
if let Some(home) = orig_home {
unsafe { std::env::set_var("HOME", home) };
+4 -3
View File
@@ -14,9 +14,10 @@ sonar.sarifReportPaths=target/clippy-report.sarif
# Rust: CI converts target/lcov.info → target/sonar-rust-coverage.xml (Generic Coverage).
# TypeScript still uses sonar.javascript.lcov.reportPaths below.
sonar.coverageReportPaths=target/sonar-rust-coverage.xml
# Generic Test Execution: nextest + Vitest JUnit converted in CI (see scripts/junit_to_sonar_test_execution.py).
# Paths match artifact download layout in the sonarqube job (Rust under target/, TS under ui-reports/test-results/).
sonar.testExecutionReportPaths=target/nextest/ci/sonar-test-execution.xml,ui-reports/test-results/sonar-test-execution.xml
# Generic Test Execution: Vitest JUnit converted in CI (see scripts/junit_to_sonar_test_execution.py).
# SonarQube 26.4+ rejects our Rust report: paths map to library sources (inline #[cfg(test)]), not dedicated test files.
# Rust coverage still comes from sonar.coverageReportPaths; nextest conversion remains in CI for debugging/ future use.
sonar.testExecutionReportPaths=ui-reports/test-results/sonar-test-execution.xml
sonar.scm.provider=git
+3 -4
View File
@@ -137,9 +137,7 @@ describe('api.ts bridge', () => {
});
it('binds injected functions to the merged API object', async () => {
let capturedThis: unknown;
const customSaveFile = vi.fn(function (this: unknown) {
capturedThis = this;
return Promise.resolve();
});
@@ -148,8 +146,9 @@ describe('api.ts bridge', () => {
await api.saveFile('/test.txt', 'content', 'UTF-8');
expect(customSaveFile).toHaveBeenCalled();
expect(capturedThis).toBeDefined();
expect(capturedThis).not.toBe(api); // bound to merged object, not proxy
const callThis = customSaveFile.mock.contexts[0];
expect(callThis).toBeDefined();
expect(callThis).not.toBe(api); // bound to merged object, not proxy
});
});