-
Notifications
You must be signed in to change notification settings - Fork 600
Overhaul app launching, unit tests #4115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- classes.app will have a get_settings() function (which we should try to migrate to, from classes.settings.get_settings() - in addition, the OpenShotApp instance has a get_settings() METHOD which is most-preferable (`from classes.app import get_app; s = get_app().get_settings()`)
- Massively re-work the application setup, so that *far* less is done in the __init__() for OpenShotApp. In particular... * All GUI setup is deferred to a separate `.gui()` method, which is now optional (the application instance can be created without automatically creating the full GUI). * A new `StartupMessage` class is created, and any message to be displayed in a QMessageBox is now stored in an object instance and placed on a queue. OpenShotApp.gui() will automatically call the app's `.show_errors()` method to process the queue, but it can also be called before/without `.gui()`. * The app instance's references to `info` and `openshot` are non-global, so they're passed into several methods which need access to them (just something to look out for) - `launch.py` is also re-worked in accordance with the new design of classes.app.OpenShotApp - Multiple media files can now be passed as separate arguments on the command line, and they will be added to the initial project in order. The number of positional arguments is no longer capped at 1 (except in the case of an `.osp` file)
- Take advantage of the new, more compartmentalized OpenShotApp class, and run the unit tests without creating the application GUI at all. - Unit tests can even be run headless by selecting a platform plugin with no display requirements on the command line, e.g.: `python3 tests/query_tests.py --platform minimal` `python3 tests/query_tests.py --platform offscreen`
Settings should always be requested from the app instance, which holds the settings object: `get_app().get_settings()`
LGTM! Nice work! 😀 |
@ferdnyc Is this one ready to merge? |
@jonoomph AFAICT, yes, but maybe you want to test the Mac build first just in case? |
Sure, I can give it a quick look on Mac! |
As far as I can tell, works fine on the Mac! Merge away! |
@jonoomph Merged! So that should be the end of the spurious unit test failures. |
P.S> I'm about 2/3 of the way through this...
I just have about a solid afternoon's work left, fixing up all of the view classes. So, realistically, given the pace I've been managing lately... probably another week or two. (Especially now that a tenant moved out yesterday with zero notice, so the rest of this week is suddenly booked up with turning that apartment back around for the realtor.) |
(Replacing #4114)
This PR, tested on both Linux and Windows, completely revamps the initial creation of the
QApplication
instance and theMainWindow
class, as OpenShot is being started bylaunch.py
(also significantly rewritten), all in the service of one central goal: completely divorce the application setup (which is done inOpenShotApp's __init__
, same as always) from the interface startup, which now lives in a newOpenShotApp.gui()
method. Calling that is optional, and the unit tests simply... don't.When launching the unit tests (from
tests/query_tests.py
), the interface is never even started, and therefore (by implication) neither is the web backend. Which alleviates the problems caused byQtWebEngine
not shutting down properly because it hasn't even had a chance to start yet before the unit tests are completed.I've also moved all of that OpenGL setup stuff and other housekeeping out of the top of classes.app and put it in
launch.py
instead, so that it's truly done BEFORE creating theQApplication
(or,OpenShotApp
) instance. I've always been wary of the fact that we were effectively doing it "while" the instance was being created, not technically "before".And having it in
launch.py
means the unit tests can also skip that stuff. It's now possible, in fact, to run the unit tests in a headless environment without needingxvfb
, just by adding a-platform minimal
oron the command line for-platform offscreen
query_tests.py
.(The platform plugin has to be changed because Qt's default on Linux is xcb, which still expects an X display even if nothing makes use of it.) Edit: It seems from the Github Actions CI that
offscreen
still expects some sort of display output or server that isn't present.-platform minimal
works great even in the... well... minimal CI container environments, though. Whoda thunk?There were some other changes involved, like deferring any
QMessageBox
calls that previously occurred duringOpenShotApp.__init__()
. Now they're placed on a queue, and not shown until requested bylaunch.py
(or automatically, if there are any outstanding whenOpenShotApp.gui()
is called.Other changes
classes.settings.get_settings()
. Settings should now be requested from the app instance (because it holds the settings instance), using a path along the lines ofget_app().get_settings()
. There is also a convenience functionget_settings()
inclasses.app
, mirroring the old one inclasses.settings
, but you shouldn't useclasses.app.get_settings()
either. It just makes more sense to go through the application instance.Next steps
GUI-free Model Classes
The next obvious evolutionary step, here, would be to move the data models out of
MainWindow
, and have them be both initialized and held by theOpenShotApp
instance. There's no reason our data models should be dependent on a GUI being launched, and if they weren't then we could start writing unit tests for them, which would be a very good thing.For that to happen, though, all of the hidden GUI dependencies in them have to be shaken out. That means no calls to
get_app().window.anything
anywhere in the models. Right now they contain way too many sneaky dependency inversions like this (from the files proxy model):The way that should work — both for model integrity and to be far more efficient — is to have the main window class connect the
changed
signal from theQActionGroup
holding the selector buttons to a slot in the model class that stores the selected filter option as an instance variable, which defaults to no filtering.That way, the model doesn't need to consult the GUI just to do its job, and if there isn't a GUI then the filtering will never be activated. (Though it still could be, programmatically, in the unit tests. All they'd have to do is simply connect signals to that slot and
emit()
them.) Properly isolated, the existence of an actual GUI should be completely irrelevant to the group-filtering features of the files model. It certainly shouldn't be an assumption baked into the model that crashes its code when the GUI isn't available.