Repository: astral-sh/ruff
File: crates/ty_server/tests/e2e/publish_diagnostics.rs (Rust)

Code before:

    let mut server = TestServerBuilder::new()?
        .with_workspace(SystemPath::new("src"), None)?
        .with_file(foo, foo_content)?
        .enable_pull_diagnostics(false)
        .build()
        .wait_until_workspaces_are_initialized();

    server.open_text_document(foo, foo_content, 1);
    let diagnostics = server.await_notification::<PublishDiagnostics>();

    insta::assert_debug_snapshot!(diagnostics);

    server.close_text_document(foo);

    let params = DidOpenTextDocumentParams {
        text_document: TextDocumentItem {
            uri: server.file_uri(foo),
            language_id: "text".to_string(),
            version: 1,
            text: foo_content.to_string(),
        },
    };
    server.send_notification::<DidOpenTextDocument>(params);
    let _close_diagnostics = server.await_notification::<PublishDiagnostics>();

    let diagnostics = server.await_notification::<PublishDiagnostics>();

    insta::assert_debug_snapshot!(diagnostics);

    Ok(())
}

#[test]
fn invalid_syntax_with_syntax_errors_disabled() -> Result<()> {
    let workspace_root = SystemPath::new("src");
    let foo = SystemPath::new("src/foo.py");
    let foo_content = "\
def foo(
";

    let mut server = TestServerBuilder::new()?
        .with_workspace(
            workspace_root,
            Some(ClientOptions::default().with_show_syntax_errors(false)),
        )?
        .with_file(foo, foo_content)?
        .enable_pull_diagnostics(false)
        .build()
        .wait_until_workspaces_are_initialized();


Review comment (bug):
I'm not sure if it was intentional to have the diagnostics send back twice, but this is no longer the case. It was happening previously because:

1. Closing the document (above) would result in _clearing_ diagnostics only when `DocumentHandle::close` returns `true`. And that would return true _because_ `session.global_settings().diagnostic_mode().is_open_files_only()` returned `true`. Because the session global settings used `OpenFilesOnly` by default.
2. Re-opening the document (with the language ID changed) caused `publish_diagnostics_if_needed` inside of the `DidOpenTextDocumentHandler` handler to run. This would eventually do `Project::check_file` and that would call `should_check_file`. And _that_ would return `false` because the projects have been defaulting to `AllFiles` as a check mode by default, and the file in question is only in the "open file" set. (Which is perhaps a bug on its own, but I digress.)

The end result is that the test got no diagnostics which was what was expected, but it got for a reason other than respecting the change in language ID. Once I fixed the `AllFiles`/`OpenFilesOnly` problem, this test started failing because we would still send back diagnostics for the plain text file.

I ended up fixing this by checking the language ID of the file in the `DidOpenTextDocumentHandler` handler. If it's `Other`, then we ignore it, _hopefully_ mirroring what we do in `ty_project/src/walk.rs`.

Code after:

    let mut server = TestServerBuilder::new()?
        .with_workspace(SystemPath::new("src"), None)?
        .with_file(foo, foo_content)?
        .enable_pull_diagnostics(false)
        .build()
        .wait_until_workspaces_are_initialized();

    server.open_text_document(foo, foo_content, 1);
    let diagnostics = server.await_notification::<PublishDiagnostics>();

    insta::assert_debug_snapshot!(diagnostics);

    server.close_text_document(foo);

    let params = DidOpenTextDocumentParams {
        text_document: TextDocumentItem {
            uri: server.file_uri(foo),
            language_id: "text".to_string(),
            version: 1,
            text: foo_content.to_string(),
        },
    };
    server.send_notification::<DidOpenTextDocument>(params);
    let diagnostics = server.await_notification::<PublishDiagnostics>();

    insta::assert_debug_snapshot!(diagnostics);

    Ok(())
}

#[test]
fn invalid_syntax_with_syntax_errors_disabled() -> Result<()> {
    let workspace_root = SystemPath::new("src");
    let foo = SystemPath::new("src/foo.py");
    let foo_content = "\
def foo(
";

    let mut server = TestServerBuilder::new()?
        .with_workspace(
            workspace_root,
            Some(ClientOptions::default().with_show_syntax_errors(false)),
        )?
        .with_file(foo, foo_content)?
        .enable_pull_diagnostics(false)
        .build()
        .wait_until_workspaces_are_initialized();

    server.open_text_document(foo, foo_content, 1);