Skip to content

Commit

Permalink
Refactor initial document handling to separate command line from defa…
Browse files Browse the repository at this point in the history
…ult document handling.
  • Loading branch information
freakboy3742 committed Sep 23, 2024
1 parent d7f7823 commit d02f76a
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 33 deletions.
49 changes: 24 additions & 25 deletions core/src/toga/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -608,35 +608,34 @@ def _create_standard_commands(self):

def _create_initial_windows(self):
"""Internal utility method for creating initial windows based on command line
arguments. This method is used when the platform doesn't provide its own
command-line handling interface.
arguments.
If document types are defined, try to open every argument on the command line as
a document (unless the backend manages the command line arguments).
"""

if not (self._impl.HANDLES_COMMAND_LINE and self._impl.CLOSE_ON_LAST_WINDOW):
doc_count = len(self.windows)
If document types are defined, and the backend doesn't have native command line
handling, try to open every argument on the command line as a document (unless
the backend manages the command line arguments).
# Process command line arguments if the backend doesn't handle them
if not self._impl.HANDLES_COMMAND_LINE and self.documents.types:
If, after processing all command line arguments, the app doesn't have at least
one window, the app's default initial document handling will be triggered.
"""
# Process command line arguments if the backend doesn't handle them
if not self._impl.HANDLES_COMMAND_LINE:
if self.documents.types:
for filename in sys.argv[1:]:
if self._open_initial_document(filename):
doc_count += 1

# Ensure there is at least one document or window
if self.main_window is None and doc_count == 0:
if self.documents.types:
if self._impl.CLOSE_ON_LAST_WINDOW:
# Pass in the first document type as the default
self.documents.new(self.documents.types[0])
else:
self.loop.run_until_complete(self.documents.request_open())
self._open_initial_document(filename)

# Ensure there is at least one window
if self.main_window is None and len(self.windows) == 0:
if self.documents.types:
if self._impl.CLOSE_ON_LAST_WINDOW:
# Pass in the first document type as the default
self.documents.new(self.documents.types[0])
else:
# No document types defined.
raise RuntimeError(
"App didn't create any windows, or register any document types."
)
self.loop.run_until_complete(self.documents.request_open())
else:
# No document types defined.
raise RuntimeError(
"App didn't create any windows, or register any document types."
)

def _startup(self) -> None:
# Wrap the platform's event loop's task factory for task tracking
Expand Down
25 changes: 17 additions & 8 deletions core/tests/app/test_document_app.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import sys
from unittest.mock import AsyncMock, MagicMock, Mock
from unittest.mock import AsyncMock, Mock

import pytest

import toga
from toga.documents import DocumentSet
from toga_dummy.app import App as DummyApp
from toga_dummy.command import Command as DummyCommand
from toga_dummy.utils import (
Expand Down Expand Up @@ -170,9 +171,9 @@ def test_create_no_cmdline_default_handling_close_on_last_window(monkeypatch):

assert app.documents.types == [ExampleDocument]

# No documents or windows exist
assert len(app.documents) == 0
assert len(app.windows) == 0
# A default document has been created
assert len(app.documents) == 1
assert len(app.windows) == 1


def test_create_no_cmdline_default_handling_no_close_on_last_window(monkeypatch):
Expand All @@ -190,18 +191,26 @@ def test_create_no_cmdline_default_handling_no_close_on_last_window(monkeypatch)
# Mock request_open() because OpenFileDialog's response can't be set before the
# app creation. Since request_open() is called during app initialization, we can't
# set the dialog response in time, leading to an unexpected dialog response error.
monkeypatch.setattr(ExampleDocumentApp, "documents", MagicMock())
mock_request_open = AsyncMock()
monkeypatch.setattr(ExampleDocumentApp.documents, "request_open", mock_request_open)
monkeypatch.setattr(DocumentSet, "request_open", mock_request_open)

# Create the app instance
_ = ExampleDocumentApp(
app = ExampleDocumentApp(
"Test App",
"org.beeware.document-app",
document_types=[ExampleDocument],
)

# Check that request_open was called
assert app._impl.interface == app
assert_action_performed(app, "create App")

assert app.documents.types == [ExampleDocument]

# No documents have been created
assert len(app.documents) == 0
assert len(app.windows) == 0

# ...but request_open was called
mock_request_open.assert_called_once()


Expand Down

0 comments on commit d02f76a

Please sign in to comment.