emmental3.py: Start Emmental 3.0

I'm going to put all of the main source code into a single subdirectory
under emmental/ and separate out tests into a separate tests/ directory.

Additionally, I have switched over to pytest for running tests to give
me better output (with color!)

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2022-05-26 14:42:09 -04:00
parent 08ea7342dc
commit 4072ea97d4
11 changed files with 181 additions and 9 deletions

1
.gitignore vendored
View File

@ -3,4 +3,5 @@
*.coverage
*.ui~
*.txt
*.patch
PKGBUILD

View File

@ -6,16 +6,17 @@ export EMMENTAL_LIB = ${PREFIX}/lib/emmental
export EMMENTAL_BIN = ${PREFIX}/bin
export EMMENTAL_SHARE = ${PREFIX}/share
export EMMENTAL_MAJOR = $(shell grep \^MAJOR lib/version.py | awk -F= '{ gsub(/ /,""); print $$2}')
export EMMENTAL_MINOR = $(shell grep \^MINOR lib/version.py | awk -F= '{ gsub(/ /,""); print $$2}')
export EMMENTAL_TARGZ = https://git.nowheycreamery.com/anna/emmental/archive/emmental-${EMMENTAL_MAJOR}.${EMMENTAL_MINOR}.tar.gz
export EMMENTAL_CSUM = $(shell curl -s ${EMMENTAL_TARGZ} | sha256sum | awk '{print $$1}')
all: flake8
clean:
find . -type d -name __pycache__ -exec rm -r {} \+
find data/ -type d -name "Test Album" -exec rm -r {} \+
find data/ -type d -name "Test Library" -exec rm -r {} \+
.PHONY:flake8
flake8:
flake8 emmental/ tests/
.PHONY: install
install:
exec tools/install.sh
@ -29,12 +30,18 @@ uninstall:
.PHONY: pkgbuild
pkgbuild:
$(eval MAJOR := $(shell grep \^MAJOR lib/version.py | awk -F= '{ gsub(/ /,""); print $$2}'))
$(eval MINOR := $(shell grep \^MINOR lib/version.py | awk -F= '{ gsub(/ /,""); print $$2}'))
$(eval TAG := $(shell git describe --tags --abbrev=0))
$(eval CSUM := $(shell git archive --format tar.gz $(TAG) | sha256sum | awk '{print $$1}'))
cp data/PKGBUILD aur/
sed -i 's|{MAJOR}.{MINOR}|${EMMENTAL_MAJOR}.${EMMENTAL_MINOR}|' aur/PKGBUILD
sed -i 's|{SHA256SUM}|${EMMENTAL_CSUM}|' aur/PKGBUILD
sed -i 's|{MAJOR}.{MINOR}|${MAJOR}.${MINOR}|' aur/PKGBUILD
sed -i 's|{SHA256SUM}|$(CSUM)|' aur/PKGBUILD
cd aur && makepkg --printsrcinfo > .SRCINFO
.PHONY: pytest
pytest:
pytest
.PHONY: tests
tests:
python tools/generate_tracks.py
python -m unittest discover -v
tests: pytest flake8

35
emmental/__init__.py Normal file
View File

@ -0,0 +1,35 @@
# Copyright 2022 (c) Anna Schumaker.
"""Set up our Application."""
from . import gsetup
from . import options
from gi.repository import GLib
from gi.repository import Adw
MAJOR_VERSION = 3
MINOR_VERSION = 0
VERSION_STRING = f"Emmental {MAJOR_VERSION}.{MINOR_VERSION}{gsetup.DEBUG_STR}"
class Application(Adw.Application):
"""Our custom Adw.Application."""
def __init__(self):
"""Initialize an Application."""
super().__init__(application_id=gsetup.APPLICATION_ID)
self.add_main_option_entries([options.Version])
def do_handle_local_options(self, opts: GLib.VariantDict) -> int:
"""Handle any command line options."""
if opts.contains("version"):
print(VERSION_STRING)
gsetup.print_versions()
return 0
return -1
def do_startup(self) -> None:
"""Handle the Adw.Application::startup signal."""
Adw.Application.do_startup(self)
def do_activate(self) -> None:
"""Handle the Adw.Application::activate signal."""
Adw.Application.do_activate(self)

26
emmental/gsetup.py Normal file
View File

@ -0,0 +1,26 @@
# Copyright 2022 (c) Anna Schumaker.
"""Set up GObject Introspection."""
import sys
import gi
gi.require_version("Gtk", "4.0")
gi.require_version("Adw", "1")
DEBUG_STR = "-debug" if __debug__ else ""
APPLICATION_ID = f"com.nowheycreamery.emmental{DEBUG_STR}"
def __print_version(subsystem, major, minor, micro):
print(f"{subsystem} {major}.{minor}.{micro}")
def print_versions():
"""Print version information for libraries we use."""
__print_version("Python", sys.version_info.major, sys.version_info.minor,
sys.version_info.micro)
__print_version("Gtk", gi.repository.Gtk.MAJOR_VERSION,
gi.repository.Gtk.MINOR_VERSION,
gi.repository.Gtk.MICRO_VERSION)
__print_version("Libadwaita", gi.repository.Adw.MAJOR_VERSION,
gi.repository.Adw.MINOR_VERSION,
gi.repository.Adw.MICRO_VERSION)

12
emmental/options.py Normal file
View File

@ -0,0 +1,12 @@
# Copyright 2022 (c) Anna Schumaker.
"""Configure command line options passed to Emmental."""
from gi.repository import GLib
Version = GLib.OptionEntry()
Version.long_name = "version"
Version.short_name = ord("v")
Version.flags = GLib.OptionFlags.NONE
Version.arg = GLib.OptionArg.NONE
Version.arg_data = None
Version.description = "Print version information and exit"
Version.arg_description = None

8
emmental3.py Executable file
View File

@ -0,0 +1,8 @@
#!/usr/bin/python
# Copyright 2022 (c) Anna Schumaker.
"""The main Emmental application, version 3.0"""
import sys
import emmental
if __name__ == "__main__":
emmental.Application().run(sys.argv)

7
pytest.ini Normal file
View File

@ -0,0 +1,7 @@
[pytest]
required_plugins = pytest-timeout pytest-subtests
testpaths = emmental/ tests/
addopts = -rP
timeout = 5
timeout_method = thread
timeout_func_only = true

2
tests/__init__.py Normal file
View File

@ -0,0 +1,2 @@
# Copyright 2022 (c) Anna Schumaker
"""Needed to initialize tests correctly."""

25
tests/test_emmental.py Normal file
View File

@ -0,0 +1,25 @@
# Copyright 2022 (c) Anna Schumaker.
"""Test as much as we can of the Emmental Application."""
import unittest
import gi
import emmental
class TestEmmental(unittest.TestCase):
"""Emmental Application test case."""
def setUp(self):
"""Set up common variables."""
self.application = emmental.Application()
def test_version(self):
"""Check that version constants have been set properly."""
self.assertEqual(emmental.MAJOR_VERSION, 3)
self.assertEqual(emmental.MINOR_VERSION, 0)
self.assertEqual(emmental.VERSION_STRING, "Emmental 3.0-debug")
def test_application(self):
"""Check that the application instance is initialized properly."""
self.assertIsInstance(self.application, gi.repository.Adw.Application)
self.assertEqual(self.application.get_application_id(),
"com.nowheycreamery.emmental-debug")

30
tests/test_gsetup.py Normal file
View File

@ -0,0 +1,30 @@
# Copyright 2022 (c) Anna Schumaker.
"""Test that the gi.repository has been configured correctly."""
import unittest
import emmental
import gi
class TestGSetup(unittest.TestCase):
"""GObject Introspection configuration test case."""
def test_require_version(self):
"""Check that gi.require_version() has been called."""
self.assertEqual(gi.get_required_version("Gtk"), "4.0")
self.assertEqual(gi.get_required_version("Adw"), "1")
def test_adw(self):
"""Check that libadwaita style has been set."""
style = gi.repository.Adw.StyleManager.get_default()
self.assertEqual(style.get_color_scheme(),
gi.repository.Adw.ColorScheme.DEFAULT)
def test_import(self):
"""Check that modules have been imported."""
self.assertIsNotNone(emmental.gsetup.gi)
def test_application_id(self):
"""Check that the application id is generated properly."""
self.assertEqual(emmental.gsetup.DEBUG_STR, "-debug")
self.assertEqual(emmental.gsetup.APPLICATION_ID,
"com.nowheycreamery.emmental-debug")

19
tests/test_options.py Normal file
View File

@ -0,0 +1,19 @@
# Copyright 2022 (c) Anna Schumaker.
"""Test setup of the Emmental command line options."""
import unittest
import gi
import emmental.options
class TestOptions(unittest.TestCase):
"""Test case for our various command line options."""
def test_version(self):
"""Check that the version option is set up properly."""
opt = emmental.options.Version
self.assertIsInstance(opt, gi.repository.GLib.OptionEntry)
self.assertEqual(opt.long_name, "version")
self.assertEqual(opt.short_name, ord("v"))
self.assertEqual(opt.flags, gi.repository.GLib.OptionFlags.NONE)
self.assertEqual(opt.arg, gi.repository.GLib.OptionArg.NONE)
self.assertEqual(opt.arg_data, 0)