Skip to content

Commit

Permalink
Merge pull request #2047 from mattip/startup-refactor
Browse files Browse the repository at this point in the history
test, fix invalid user-provided startup() method
  • Loading branch information
freakboy3742 authored Jul 23, 2023
2 parents 930f4e3 + 42efae4 commit 5874d2e
Show file tree
Hide file tree
Showing 10 changed files with 53 additions and 6 deletions.
2 changes: 1 addition & 1 deletion android/src/toga_android/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ def create(self):
# the app's `.native` is the listener's native Java class.
self._listener = TogaApp(self)
# Call user code to populate the main window
self.interface.startup()
self.interface._startup()

def open_document(self, fileURL):
print("Can't open document %s (yet)" % fileURL)
Expand Down
1 change: 1 addition & 0 deletions changes/2047.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Applications now verify that a main window has been created as part of the ``startup()`` method.
2 changes: 1 addition & 1 deletion cocoa/src/toga_cocoa/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ def create(self):
self._create_app_commands()

# Call user code to populate the main window
self.interface.startup()
self.interface._startup()

# Create the lookup table of menu items,
# then force the creation of the menus.
Expand Down
17 changes: 17 additions & 0 deletions core/src/toga/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,19 @@ def startup(self):

self.main_window.show()

def _startup(self):
# This is a wrapper around the user's startup method that performs any
# post-setup validation.
self.startup()
self._verify_startup()

def _verify_startup(self):
if not isinstance(self.main_window, MainWindow):
raise ValueError(
"Application does not have a main window. "
"Does your startup() method assign a value to self.main_window?"
)

def about(self):
"""Display the About dialog for the app.
Expand Down Expand Up @@ -683,6 +696,10 @@ def __init__(
def _create_impl(self):
return self.factory.DocumentApp(interface=self)

def _verify_startup(self):
# No post-startup validation required for DocumentApps
pass

@property
def documents(self):
"""Return the list of documents associated with this app.
Expand Down
27 changes: 27 additions & 0 deletions core/tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,21 @@ async def test_handler(sender):
args=(None,),
)

def test_override_startup(self):
class BadApp(toga.App):
"A startup method that doesn't assign main window raises an error (#760)"

def startup(self):
# Override startup but don't create a main window
pass

app = BadApp(app_name="bad_app", formal_name="Bad Aoo", app_id="org.beeware")
with self.assertRaisesRegex(
ValueError,
r"Application does not have a main window.",
):
app.main_loop()


class DocumentAppTests(TestCase):
def setUp(self):
Expand All @@ -191,3 +206,15 @@ def test_app_documents(self):
doc = MagicMock()
self.app._documents.append(doc)
self.assertEqual(self.app.documents, [doc])

def test_override_startup(self):
mock = MagicMock()

class DocApp(toga.DocumentApp):
def startup(self):
# A document app doesn't have to provide a Main Window.
mock()

app = DocApp(app_name="docapp", formal_name="Doc App", app_id="org.beeware")
app.main_loop()
mock.assert_called_once()
2 changes: 2 additions & 0 deletions dummy/src/toga_dummy/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ def __init__(self, interface):

def create(self):
self._action("create")
self.interface._startup()

@not_required_on("mobile")
def create_menus(self):
self._action("create menus")

def main_loop(self):
self._action("main loop")
self.create()

def set_main_window(self, window):
self._set_value("main_window", window)
Expand Down
2 changes: 1 addition & 1 deletion gtk/src/toga_gtk/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def gtk_startup(self, data=None):
)
self._create_app_commands()

self.interface.startup()
self.interface._startup()

# Create the lookup table of menu items,
# then force the creation of the menus.
Expand Down
2 changes: 1 addition & 1 deletion iOS/src/toga_iOS/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def __init__(self, interface):

def create(self):
"""Calls the startup method on the interface."""
self.interface.startup()
self.interface._startup()

def open_document(self, fileURL):
"""Add a new document to this app."""
Expand Down
2 changes: 1 addition & 1 deletion web/src/toga_web/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def create(self):
self.create_menus()

# Call user code to populate the main window
self.interface.startup()
self.interface._startup()

def _create_submenu(self, group, items):
submenu = create_element(
Expand Down
2 changes: 1 addition & 1 deletion winforms/src/toga_winforms/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def create(self):
self._create_app_commands()

# Call user code to populate the main window
self.interface.startup()
self.interface._startup()
self.create_menus()
self.interface.main_window._impl.set_app(self)

Expand Down

0 comments on commit 5874d2e

Please sign in to comment.