Skip to content

Latest commit

 

History

History
63 lines (51 loc) · 4.34 KB

CONTRIBUTING.md

File metadata and controls

63 lines (51 loc) · 4.34 KB

Contributing to dtool-lookup-gui

Code style

Always follow PEP-8 with the exception of line breaks.

Development branches

New features should be developed always in its own branch. When creating your own branch, please prefix that branch by the date of creation. For example, if you begin working on implementing pagination on 6th April 2023, the branch could be called 2023-04-06-pagination.

Commits

Prepend you commits with a shortcut indicating the type of changes they contain:

  • BUG: Bug fix
  • CI: Changes to the CI configuration
  • DEP: Update in 3rd-party dependencies
  • DOC: Changes to documentation strings
  • ENH: Enhancement (e.g. a new feature)
  • MAINT: Maintenance (e.g. fixing a typo)
  • TST: Changes to the unit test environment
  • WIP: Work in progress

GTK-specific

The dtool-lookup-gui uses GTK 3 to provide a platform-independent graphical user interface (GUI). GTK originates at the GNOME project. At it's core sits GLib, and on top of that lives the GObject library. Again higher live the Gio and Gdk libraries and on top of them all the GTK toolkit. The dtool-lookup-gui interfaces all GLib, GObject, Gio, Gtk, and Gdk functionality with PyGObject. The Python GTK+ 3 Tutorial helps with learning how to build GTK applications with Python.

Signals and events, and the event loop

GTK applications run asynchronously in the GLib main event loop. gbulb provides an implementation of the PEP 3156 interface to this GLib event loop for Python-native use of asyncio. Within the dtool-lookup-gui's code, and importantly within test/conftest.py you will hence find gbulb bits that configure asyncio and GTK to share the same event loop.

Gio.Action

Next to signals and events, actions are an important concept. Actions implement functionality that is not necessarily bound to a specific element in the graphical representation. Wrapping as much behavior as possible into atomic actions helps to structure the code and let the application evolve in the spirit of a clean separation between model, view, and controlling logic (MVC software design pattern). Furthermore, actions can be evoked by other means than user interaction via the GUI, such as via the command line or a keyboard shortcut. They facilitate writing unit tests as well.

When implementing new features, think about how to break them down into atomic actions. In most cases, you will want to use the Gio.SimpleAction interface. You will find usage examples within the code, in the GTK Python developer handbook: Working with GIO Actions. Write actions as methods prefixed with do_*, e.g. do_search and attach them to the app itself or to the window they relate to. Write at least one unit test for each action, e.g. test_do_search for the action do_search.

Tests

For testing, we mock the dtool_lookup_api in conftest.py to return dummy data on all API calls used within dtool-lookup-gui. With for functionality packed in atomic actions, it is then straight forward to write unit tests. We aim at writing two test cases for each action. One test case directly calls the action, e.g. app.do_reset_config(...) and tests against its operation on the provided dummy data without mocking anything other than the dtool_lookup_api calls. The second test mocks many internal functions evoked by an action, activates the action via the intended GTK framework mechanism, e.g. app.activate_action('reset-config') and subsequently asserts the expected evocation of mocked methods.