From 39d87830558540fefad1d4dd24a14f273bd4d5a7 Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Wed, 13 Jan 2021 21:51:17 +0000 Subject: [PATCH] simulator: test_qa: Add some basic docstring tests This one picked up a lot of inconsistancy so the changes here are pretty big. Signed-off-by: Daniel Thompson --- docs/apps.rst | 3 +-- wasp/apps/calc.py | 6 ++++- wasp/apps/clock.py | 11 ++++----- wasp/apps/flashlight.py | 11 ++++----- wasp/apps/haiku.py | 3 +++ wasp/apps/heart.py | 17 ++++++++------ wasp/apps/launcher.py | 11 ++++----- wasp/apps/settings.py | 28 +++++++++++++++------- wasp/apps/snake.py | 6 ++--- wasp/apps/software.py | 14 ++++++++++- wasp/apps/steps.py | 19 +++++++++------ wasp/apps/stopwatch.py | 17 ++++++++------ wasp/apps/testapp.py | 14 +++++------ wasp/boards/simulator/test_qa.py | 40 +++++++++++++++++++++++++------- 14 files changed, 126 insertions(+), 74 deletions(-) diff --git a/docs/apps.rst b/docs/apps.rst index 37bc795..0cb75ce 100644 --- a/docs/apps.rst +++ b/docs/apps.rst @@ -21,8 +21,7 @@ treated as examples they are described in detail as part of the * :py:class:`.SoftwareApp` * :py:class:`.StepCounterApp` * :py:class:`.StopwatchApp` - * :py:class:`.TestApp` - * :py:class:`.TemplateApp`` + * :py:class:`.TemplateApp` Watch faces ----------- diff --git a/wasp/apps/calc.py b/wasp/apps/calc.py index 1268a26..e283290 100644 --- a/wasp/apps/calc.py +++ b/wasp/apps/calc.py @@ -1,9 +1,13 @@ # SPDX-License-Identifier: LGPL-3.0-or-later # Copyright (C) 2020 Johannes Wache -"""Calculator application +"""Calculator +~~~~~~~~~~~~~ This is a simple calculator app that uses the build-in eval() function to compute the solution. + +.. figure:: res/CalcApp.png + :width: 179 """ import wasp, fonts diff --git a/wasp/apps/clock.py b/wasp/apps/clock.py index 9e6ba05..5c7854d 100644 --- a/wasp/apps/clock.py +++ b/wasp/apps/clock.py @@ -5,6 +5,9 @@ ~~~~~~~~~~~~~~~~ Shows a time (as HH:MM) together with a battery meter and the date. + +.. figure:: res/ClockApp.png + :width: 179 """ import wasp @@ -21,13 +24,7 @@ DIGITS = ( MONTH = 'JanFebMarAprMayJunJulAugSepOctNovDec' class ClockApp(): - """Simple digital clock application. - - .. figure:: res/ClockApp.png - :width: 179 - - Screenshot of the clock application - """ + """Simple digital clock application.""" NAME = 'Clock' ICON = icons.clock diff --git a/wasp/apps/flashlight.py b/wasp/apps/flashlight.py index f5b8684..fa734c7 100644 --- a/wasp/apps/flashlight.py +++ b/wasp/apps/flashlight.py @@ -5,6 +5,9 @@ ~~~~~~~~~~~~~ Shows a pure white screen with the backlight set to maximum. + +.. figure:: res/TorchApp.png + :width: 179 """ import wasp @@ -12,13 +15,7 @@ import wasp import icons class TorchApp(object): - """Trivial flashlight application. - - .. figure:: res/TorchApp.png - :width: 179 - - Screenshot of the flashlight application - """ + """Trivial flashlight application.""" NAME = 'Torch' ICON = icons.torch diff --git a/wasp/apps/haiku.py b/wasp/apps/haiku.py index ca5c3f4..2e8c8a6 100644 --- a/wasp/apps/haiku.py +++ b/wasp/apps/haiku.py @@ -6,6 +6,9 @@ These three lines poems are fun to write and fit nicely on a tiny screen. +.. figure:: res/HaikuApp.png + :width: 179 + If there is a file called haiku.txt in the flash filesystem then this app allows it to be displayed three lines at a time using the pager. diff --git a/wasp/apps/heart.py b/wasp/apps/heart.py index 45b3a69..541e57d 100644 --- a/wasp/apps/heart.py +++ b/wasp/apps/heart.py @@ -1,18 +1,21 @@ # SPDX-License-Identifier: LGPL-3.0-or-later # Copyright (C) 2020 Daniel Thompson +"""Heart rate monitor +~~~~~~~~~~~~~~~~~~~~~ + +A graphing heart rate monitor using a PPG sensor. + +.. figure:: res/HeartApp.png + :width: 179 +""" + import wasp import machine import ppg class HeartApp(): - """Heart Rate Sensing application. - - .. figure:: res/HeartApp.png - :width: 179 - - Screenshot of the heart rate application - """ + """Heart rate monitor application.""" NAME = 'Heart' def foreground(self): diff --git a/wasp/apps/launcher.py b/wasp/apps/launcher.py index b529017..735ac70 100644 --- a/wasp/apps/launcher.py +++ b/wasp/apps/launcher.py @@ -3,19 +3,16 @@ """Application launcher ~~~~~~~~~~~~~~~~~~~~~~~ + +.. figure:: res/LauncherApp.png + :width: 179 """ import wasp import icons class LauncherApp(): - """An application launcher application. - - .. figure:: res/LauncherApp.png - :width: 179 - - Screenshot of the application launcher - """ + """An application launcher application.""" NAME = 'Launcher' ICON = icons.app diff --git a/wasp/apps/settings.py b/wasp/apps/settings.py index c11c971..c4708e2 100644 --- a/wasp/apps/settings.py +++ b/wasp/apps/settings.py @@ -1,20 +1,30 @@ # SPDX-License-Identifier: LGPL-3.0-or-later # Copyright (C) 2020-21 Daniel Thompson +"""Settings application +~~~~~~~~~~~~~~~~~~~~~~~ + +Allows a very small set of user preferences (including the date and +time) to be set on the device itself. + +.. figure:: res/SettingsApp.png + :width: 179 + +.. note:: + + The settings tool is not expected to comprehensively present every + user configurable preference. Some are better presented via a + companion app and some particular exotic ones are perhaps best + managed with a user-provided ``main.py``. +""" + + import wasp import fonts import icons class SettingsApp(): - """Ultra-simple settings application. - - Currently the settings application contains only one setting: brightness - - .. figure:: res/SettingsApp.png - :width: 179 - - Screenshot of the settings application - """ + """Settings application.""" NAME = 'Settings' ICON = icons.settings diff --git a/wasp/apps/snake.py b/wasp/apps/snake.py index e1a853a..fc00138 100644 --- a/wasp/apps/snake.py +++ b/wasp/apps/snake.py @@ -1,9 +1,8 @@ # SPDX-License-Identifier: LGPL-3.0-or-later # Copyright (C) 2020 Johannes Wache -""" -Snake Game -~~~~~~~~~~ +"""Snake Game +~~~~~~~~~~~~~ This is a classic arcade game called snake. @@ -174,4 +173,3 @@ class Snake(): draw = wasp.watch.drawable draw.fill(x=self.oldtail[0],y=self.oldtail[1],w=15,h=15,bg=0x0000) draw.fill(x=self.body[-1][0]+1,y=self.body[-1][1]+1,w=13,h=13,bg=0xffff) - diff --git a/wasp/apps/software.py b/wasp/apps/software.py index a7c07eb..b45cc0e 100644 --- a/wasp/apps/software.py +++ b/wasp/apps/software.py @@ -1,6 +1,18 @@ # SPDX-License-Identifier: LGPL-3.0-or-later # Copyright (C) 2020 Daniel Thompson -"""Wizard to generate main.py.""" +"""Software +~~~~~~~~~~~ + +A tool to enable/disable applications. + +.. figure:: res/SoftwareApp.png + :width: 179 + +Most applications are disabled by default at boot in order to conserve +RAM (which is in short supply and very useful to anyone wanting to +write an application). This tools allows us to boot and conserve RAM +whilst still allowing users to activate so many awesome applications! +""" import wasp import icons diff --git a/wasp/apps/steps.py b/wasp/apps/steps.py index c7899a6..8945d5f 100644 --- a/wasp/apps/steps.py +++ b/wasp/apps/steps.py @@ -1,6 +1,17 @@ # SPDX-License-Identifier: LGPL-3.0-or-later # Copyright (C) 2020 Daniel Thompson +"""Step counter +~~~~~~~~~~~~~~~ + +Provide a daily step count. + + .. figure:: res/StepsApp.png + :width: 179 + +The step counts automatically reset at midnight. +""" + import wasp import fonts @@ -30,13 +41,7 @@ feet = ( ) class StepCounterApp(): - """Step counter application. - - .. figure:: res/StepsApp.png - :width: 179 - - Screenshot of the step counter application - """ + """Step counter application.""" NAME = 'Steps' ICON = icons.app diff --git a/wasp/apps/stopwatch.py b/wasp/apps/stopwatch.py index f46baa0..c46226e 100644 --- a/wasp/apps/stopwatch.py +++ b/wasp/apps/stopwatch.py @@ -1,19 +1,22 @@ # SPDX-License-Identifier: LGPL-3.0-or-later # Copyright (C) 2020 Daniel Thompson +"""Stopwatch +~~~~~~~~~~~~ + +Simple stop/start watch with support for split times. + +.. figure:: res/StopclockApp.png + :width: 179 +""" import wasp import icons import fonts class StopwatchApp(): - """Stopwatch application. - - .. figure:: res/StopclockApp.png - :width: 179 - - Screenshot of the stopwatch application - """ + """Stopwatch application.""" # Stopwatch requires too many pixels to fit into the launcher + NAME = 'Stopclock' ICON = icons.app diff --git a/wasp/apps/testapp.py b/wasp/apps/testapp.py index acd1735..5e4832f 100644 --- a/wasp/apps/testapp.py +++ b/wasp/apps/testapp.py @@ -3,6 +3,12 @@ """Self Tests ~~~~~~~~~~~~~ + +A collection of tests used to develop features or provide useful metrics such +as performance indicators or memory usage. + +.. figure:: res/SelfTestApp.png + :width: 179 """ import wasp @@ -15,13 +21,7 @@ import machine from apps.pager import PagerApp class TestApp(): - """Simple test application. - - .. figure:: res/SelfTestApp.png - :width: 179 - - Screenshot of the self test application - """ + """Self test application.""" NAME = 'Self Test' ICON = icons.app diff --git a/wasp/boards/simulator/test_qa.py b/wasp/boards/simulator/test_qa.py index 0bde20b..195196b 100644 --- a/wasp/boards/simulator/test_qa.py +++ b/wasp/boards/simulator/test_qa.py @@ -1,25 +1,25 @@ import pytest import wasp +import importlib import os EXCLUDE = ('Notifications', 'Template', 'Demo') -def test_screenshot(constructor): - if constructor.NAME in EXCLUDE: - return - fname = f'res/{constructor.NAME}App.png'.replace(' ', '') - assert os.path.exists(fname) - def test_screenshot_README(constructor): if constructor.NAME in EXCLUDE: return fname = f'res/{constructor.NAME}App.png'.replace(' ', '') - + + # A screenshot must exist for every application (press 's' in the + # simulator) + assert os.path.exists(fname) + + # Every screenshot must be included in the README image gallery with open('README.rst') as f: readme = f.read() assert fname in readme -def test_apps_documented(constructor): +def test_app_library(constructor): if constructor.NAME in EXCLUDE: return @@ -28,8 +28,32 @@ def test_apps_documented(constructor): with open('docs/wasp.rst') as f: waspdoc = f.read() + # Every application must be listed in either the + # Application Library or the Reference manual needle = f'.. automodule:: {constructor.__module__}' assert needle in appdoc or needle in waspdoc + # If an application is listed in the Reference manual + # then we need to make sure there is long to it from the + # Application Library if needle in waspdoc: assert constructor.__name__ in appdoc + +def test_docstrings(constructor): + if constructor.NAME in EXCLUDE: + return + fname = f'res/{constructor.NAME}App.png'.replace(' ', '') + + class_doc = constructor.__doc__ + module_doc = importlib.import_module(constructor.__module__).__doc__ + + # Screenshots should *not* appear in the constructor. + if constructor.__doc__: + assert fname not in constructor.__doc__ + + # Screenshots should appear in the full module documentation + assert f'.. figure:: {fname }' in module_doc + + # The second line of the module documentation should be an + # underline (e.g. the first line must be a section header) + assert(module_doc.split('\n')[1].startswith('~~~~'))