pappasam / jedi-language-server

A Python language server exclusively for Jedi. If Jedi supports it well, this language server should too.
MIT License
596 stars 45 forks source link

test_publish_diagnostics_on_change fails on Darwin #313

Open doronbehar opened 5 months ago

doronbehar commented 5 months ago

Hello, while updating the package to 0.41.4, on Nixpkgs we noticed this test failure:

============================= test session starts ==============================
platform darwin -- Python 3.12.2, pytest-8.0.2, pluggy-1.4.0
rootdir: /private/tmp/nix-build-python3.12-jedi-language-server-0.41.4.drv-0/source
plugins: typeguard-4.2.1
collected 53 items                                                             
tests/lsp_tests/test_completion.py ....                                  [  7%]
tests/lsp_tests/test_definition.py ..                                    [ 11%]
tests/lsp_tests/test_diagnostics.py .F.                                  [ 16%]
tests/lsp_tests/test_document_symbol.py ..                               [ 20%]
tests/lsp_tests/test_highlighting.py ..............                      [ 47%]
tests/lsp_tests/test_hover.py .....                                      [ 56%]
tests/lsp_tests/test_init_options.py .                                   [ 58%]
tests/lsp_tests/test_refactoring.py ........                             [ 73%]
tests/lsp_tests/test_references.py ........                              [ 88%]
tests/lsp_tests/test_signature.py ..                                     [ 92%]
tests/lsp_tests/test_workspace_symbol.py .                               [ 94%]
tests/test_cli.py ..                                                     [ 98%]
tests/test_initialization_options.py .                                   [100%]
=================================== FAILURES ===================================
______________________ test_publish_diagnostics_on_change ______________________
    def test_publish_diagnostics_on_change():
        """Tests publish diagnostics on change."""
        with open(
            DIAGNOSTICS_TEST_ROOT / "diagnostics_test1_contents.txt", "r"
        ) as text_file:
            contents = text_file.read()

        changes = get_changes(
            DIAGNOSTICS_TEST_ROOT / "diagnostics_test1_content_changes.json"
        )

        actual = []
        with PythonFile(contents, TEMP_DIR) as py_file:
            uri = as_uri(py_file.fullpath)

            initialize_params = copy.deepcopy(VSCODE_DEFAULT_INITIALIZE)
            initialize_params["workspaceFolders"] = [
                {"uri": as_uri(TEMP_DIR), "name": "jedi_lsp_test"}
            ]
            initialize_params["initializationOptions"]["diagnostics"] = {
                "enable": True,
                "didOpen": False,
                "didSave": False,
                "didChange": True,
            }

            with session.LspSession() as ls_session:
                ls_session.initialize(initialize_params)
                done = Event()

                def _handler(params):
                    actual.append(params)
                    done.set()

                ls_session.set_notification_callback(
                    session.PUBLISH_DIAGNOSTICS, _handler
                )

                ls_session.notify_did_open(
                    {
                        "textDocument": {
                            "uri": uri,
                            "languageId": "python",
                            "version": 1,
                            "text": contents,
                        }
                    }
                )

                # ensure the document is loaded
                symbols = ls_session.text_document_symbol(
                    {"textDocument": {"uri": uri}}
                )
                assert len(symbols) > 0

                # At this point there should be no published diagnostics
                assert_that(actual, is_([]))

                # Introduce a syntax error and save the file
                contents = contents.replace("1 == 1", "1 === 1")
                with open(py_file.fullpath, "w") as pyf:
                    pyf.write(contents)

                # Reset waiting event just in case a diagnostic was received
                done.clear()

                # Send changes to LS
                version = 2
                for change in changes:
                    change["textDocument"] = {"uri": uri, "version": version}
                    version = version + 1
                    ls_session.notify_did_change(change)

                # ensure the document is loaded
                symbols = ls_session.text_document_symbol(
                    {"textDocument": {"uri": uri}}
                )
                assert len(symbols) > 0

                # wait for a second to receive all notifications
                done.wait(1.1)

            # Diagnostics look a little different on Windows.
            filename = (
                as_uri(py_file.fullpath)
                if platform.system() == "Windows"
                else py_file.basename
            )

            expected = [
                {
                    "uri": uri,
                    "diagnostics": [
                        {
                            "range": {
                                "start": {"line": 5, "character": 15},
                                "end": {"line": 5, "character": 16},
                            },
                            "message": f"SyntaxError: invalid syntax ({filename}, line 6)",
                            "severity": 1,
                            "source": "compile",
                        }
                    ],
                }
            ]
>       assert_that(actual, is_(expected))
E       AssertionError: 
E       Expected: <[{'uri': 'file:///private/tmp/nix-build-python3.12-jedi-language-server-0.41.4.drv-0/aafmosyb.py', 'diagnostics': [{'range': {'start': {'line': 5, 'character': 15}, 'end': {'line': 5, 'character': 16}}, 'message': 'SyntaxError: invalid syntax (aafmosyb.py, line 6)', 'severity': 1, 'source': 'compile'}]}]>
E            but: was <[]>
tests/lsp_tests/test_diagnostics.py:207: AssertionError
=========================== short test summary info ============================
FAILED tests/lsp_tests/test_diagnostics.py::test_publish_diagnostics_on_change - AssertionError: 
======================== 1 failed, 52 passed in 58.66s =========================
pappasam commented 5 months ago

Interesting... was this failure only observed on Darwin? Looks like that target is not in our current test suite.

doronbehar commented 5 months ago

was this failure only observed on Darwin?

Correct. Our CI reports this issue only on Darwin.

doronbehar commented 5 months ago

It also reports test_publish_diagnostics_on_save to fail on python3.12 and Darwin.

============================= test session starts ==============================
platform darwin -- Python 3.12.2, pytest-8.0.2, pluggy-1.4.0
rootdir: /private/tmp/nix-build-python3.12-jedi-language-server-0.41.4.drv-0/source
plugins: typeguard-4.2.1
collected 53 items / 1 deselected / 52 selected                                
tests/lsp_tests/test_completion.py ....                                  [  7%]
tests/lsp_tests/test_definition.py ..                                    [ 11%]
tests/lsp_tests/test_diagnostics.py .F                                   [ 15%]
tests/lsp_tests/test_document_symbol.py ..                               [ 19%]
tests/lsp_tests/test_highlighting.py ..............                      [ 46%]
tests/lsp_tests/test_hover.py .....                                      [ 55%]
tests/lsp_tests/test_init_options.py .                                   [ 57%]
tests/lsp_tests/test_refactoring.py ........                             [ 73%]
tests/lsp_tests/test_references.py ........                              [ 88%]
tests/lsp_tests/test_signature.py ..                                     [ 92%]
tests/lsp_tests/test_workspace_symbol.py .                               [ 94%]
tests/test_cli.py ..                                                     [ 98%]
tests/test_initialization_options.py .                                   [100%]
=================================== FAILURES ===================================
_______________________ test_publish_diagnostics_on_save _______________________
    def test_publish_diagnostics_on_save():
        """Tests publish diagnostics on save."""
        with open(
            DIAGNOSTICS_TEST_ROOT / "diagnostics_test1_contents.txt", "r"
        ) as text_file:
            contents = text_file.read()

        changes = get_changes(
            DIAGNOSTICS_TEST_ROOT / "diagnostics_test1_content_changes.json"
        )

        actual = []
        with PythonFile(contents, TEMP_DIR) as py_file:
            uri = as_uri(py_file.fullpath)

            initialize_params = copy.deepcopy(VSCODE_DEFAULT_INITIALIZE)
            initialize_params["workspaceFolders"] = [
                {"uri": as_uri(TEMP_DIR), "name": "jedi_lsp_test"}
            ]
            initialize_params["initializationOptions"]["diagnostics"] = {
                "enable": True,
                "didOpen": False,
                "didSave": True,
                "didChange": False,
            }

            with session.LspSession() as ls_session:
                ls_session.initialize(initialize_params)
                done = Event()

                def _handler(params):
                    actual.append(params)
                    done.set()

                ls_session.set_notification_callback(
                    session.PUBLISH_DIAGNOSTICS, _handler
                )

                ls_session.notify_did_open(
                    {
                        "textDocument": {
                            "uri": uri,
                            "languageId": "python",
                            "version": 1,
                            "text": contents,
                        }
                    }
                )

                # ensure the document is loaded
                symbols = ls_session.text_document_symbol(
                    {"textDocument": {"uri": uri}}
                )
                assert len(symbols) > 0

                # At this point there should be no published diagnostics
                assert_that(actual, is_([]))

                # Introduce a syntax error and save the file
                contents = contents.replace("1 == 1", "1 === 1")
                with open(py_file.fullpath, "w") as pyf:
                    pyf.write(contents)

                # Reset waiting event just in case a diagnostic was received
                done.clear()

                # Send changes to LS
                version = 2
                for change in changes:
                    change["textDocument"] = {"uri": uri, "version": version}
                    version = version + 1
                    ls_session.notify_did_change(change)

                # ensure the document is loaded
                symbols = ls_session.text_document_symbol(
                    {"textDocument": {"uri": uri}}
                )
                assert len(symbols) > 0

                # At this point there should be no published diagnostics
                assert_that(actual, is_([]))

                # Reset waiting event just in case a diagnostic was received
                done.clear()

                ls_session.notify_did_save(
                    {
                        "textDocument": {
                            "uri": uri,
                            "version": version,
                        }
                    }
                )

                # wait for a second to receive all notifications
                done.wait(1.1)

            # Diagnostics look a little different on Windows.
            filename = (
                as_uri(py_file.fullpath)
                if platform.system() == "Windows"
                else py_file.basename
            )

            expected = [
                {
                    "uri": uri,
                    "diagnostics": [
                        {
                            "range": {
                                "start": {"line": 5, "character": 15},
                                "end": {"line": 5, "character": 16},
                            },
                            "message": f"SyntaxError: invalid syntax ({filename}, line 6)",
                            "severity": 1,
                            "source": "compile",
                        }
                    ],
                }
            ]
>       assert_that(actual, is_(expected))
E       AssertionError: 
E       Expected: <[{'uri': 'file:///private/tmp/nix-build-python3.12-jedi-language-server-0.41.4.drv-0/bcctuqtj.py', 'diagnostics': [{'range': {'start': {'line': 5, 'character': 15}, 'end': {'line': 5, 'character': 16}}, 'message': 'SyntaxError: invalid syntax (bcctuqtj.py, line 6)', 'severity': 1, 'source': 'compile'}]}]>
E            but: was <[]>
tests/lsp_tests/test_diagnostics.py:330: AssertionError
=========================== short test summary info ============================
FAILED tests/lsp_tests/test_diagnostics.py::test_publish_diagnostics_on_save - AssertionError: 
================= 1 failed, 51 passed, 1 deselected in 49.62s ==================