Project docs, scaffolding, utilities and other useful stuff. See README for details.
This commit is contained in:
parent
f370f94221
commit
59c8d8a495
13 changed files with 603 additions and 1 deletions
107
.gitignore
vendored
Normal file
107
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# celery beat schedule file
|
||||
celerybeat-schedule
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
|
||||
# vim
|
||||
*.swp
|
||||
9
CHANGES.rst
Normal file
9
CHANGES.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
Release History
|
||||
===============
|
||||
|
||||
0.0.1
|
||||
-----
|
||||
|
||||
Initial release.
|
||||
|
||||
* TO BE DONE.
|
||||
20
CONTRIBUTING.rst
Normal file
20
CONTRIBUTING.rst
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
Contributing
|
||||
============
|
||||
|
||||
Please note that this project is released with a Contributor Code of Conduct.
|
||||
By participating in this project you agree to abide by its terms. Participation
|
||||
covers any forum used to converse about CircuitPython including unofficial and
|
||||
official spaces. Failure to do so will result in corrective actions such as
|
||||
time out or ban from the project.
|
||||
|
||||
Licensing
|
||||
---------
|
||||
|
||||
By contributing to this repository you are certifying that you have all
|
||||
necessary permissions to license the code under an MIT License. You still
|
||||
retain the copyright but are granting many permissions under the MIT License.
|
||||
|
||||
If you have an employment contract with your employer please make sure that
|
||||
they don't automatically own your work product. Make sure to get any necessary
|
||||
approvals before contributing. Another term for this contribution off-hours is
|
||||
moonlighting.
|
||||
67
Makefile
Normal file
67
Makefile
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
XARGS := xargs -0 $(shell test $$(uname) = Linux && echo -r)
|
||||
GREP_T_FLAG := $(shell test $$(uname) = Linux && echo -T)
|
||||
|
||||
all:
|
||||
@echo "\nThere is no default Makefile target right now. Try:\n"
|
||||
@echo "make clean - reset the project and remove auto-generated assets."
|
||||
@echo "make pyflakes - run the PyFlakes code checker."
|
||||
@echo "make pycodestyle - run the PEP8 style checker."
|
||||
@echo "make test - run the test suite."
|
||||
@echo "make coverage - view a report on test coverage."
|
||||
@echo "make tidy - tidy code with the 'black' formatter."
|
||||
@echo "make check - run all the checkers and tests."
|
||||
@echo "make dist - make a dist/wheel for the project."
|
||||
@echo "make publish-test - publish the project to PyPI test instance."
|
||||
@echo "make publish-live - publish the project to PyPI production."
|
||||
@echo "make docs - run sphinx to create project documentation.\n"
|
||||
|
||||
clean:
|
||||
rm -rf build
|
||||
rm -rf dist
|
||||
rm -rf circup.egg-info
|
||||
rm -rf .coverage
|
||||
rm -rf .eggs
|
||||
rm -rf .pytest_cache
|
||||
rm -rf .tox
|
||||
rm -rf docs/_build
|
||||
find . \( -name '*.py[co]' -o -name dropin.cache \) -delete
|
||||
find . \( -name '*.bak' -o -name dropin.cache \) -delete
|
||||
find . \( -name '*.tgz' -o -name dropin.cache \) -delete
|
||||
find . | grep -E "(__pycache__)" | xargs rm -rf
|
||||
|
||||
pyflakes:
|
||||
find . \( -name _build -o -name var -o -path ./docs \) -type d -prune -o -name '*.py' -print0 | $(XARGS) pyflakes
|
||||
|
||||
pycodestyle:
|
||||
find . \( -name _build -o -name var \) -type d -prune -o -name '*.py' -print0 | $(XARGS) -n 1 pycodestyle --repeat --exclude=docs/*,.vscode/* --ignore=E731,E402,W504,W503
|
||||
|
||||
test: clean
|
||||
pytest --random-order
|
||||
|
||||
coverage: clean
|
||||
pytest --random-order --cov-config .coveragerc --cov-report term-missing --cov=circup tests/
|
||||
|
||||
tidy: clean
|
||||
@echo "\nTidying code with black..."
|
||||
black -l 79 circup.py
|
||||
black -l 79 tests
|
||||
|
||||
check: clean tidy pycodestyle pyflakes coverage
|
||||
|
||||
dist: check
|
||||
@echo "\nChecks pass, good to package..."
|
||||
python setup.py sdist bdist_wheel
|
||||
|
||||
publish-test: dist
|
||||
@echo "\nPackaging complete... Uploading to PyPi..."
|
||||
twine upload -r test --sign dist/*
|
||||
|
||||
publish-live: dist
|
||||
@echo "\nPackaging complete... Uploading to PyPi..."
|
||||
twine upload --sign dist/*
|
||||
|
||||
docs: clean
|
||||
$(MAKE) -C docs html
|
||||
@echo "\nDocumentation can be found here:"
|
||||
@echo file://`pwd`/docs/_build/html/index.html
|
||||
@echo "\n"
|
||||
61
README.rst
61
README.rst
|
|
@ -1,4 +1,63 @@
|
|||
CircUp
|
||||
======
|
||||
|
||||
A tool to update CircuitPython libraries. More soon...
|
||||
A tool to manage and update libraries on a CircuitPython device.
|
||||
|
||||
How
|
||||
---
|
||||
|
||||
Each CircuitPython library on the device (``.py``, *NOT* ``.mpy`` at this time)
|
||||
has a version number and a github repo URL.
|
||||
|
||||
This utility looks at all the libraries on the device and checks if they are
|
||||
the most recet (compared to what is in the referenced GitHub repository). If
|
||||
the libraries are out of date, the utility downloads them to the local device
|
||||
and/or local system in a zip file.
|
||||
|
||||
Example libraries:
|
||||
|
||||
https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases/download/20190830/adafruit-circuitpython-bundle-py-20190830.zip
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Example usage::
|
||||
|
||||
circup list --outdated
|
||||
|
||||
Package Version Latest
|
||||
----------- ------- ------
|
||||
foo 1.0.1 1.1.0
|
||||
bar 19.3 19.4
|
||||
baz 0.3.1 0.9
|
||||
|
||||
Developer Setup
|
||||
---------------
|
||||
|
||||
Clone the repository then make a virtualenv. From the root of the project,
|
||||
install the requirements::
|
||||
|
||||
pip install -r ".[dev]"
|
||||
|
||||
Run the test suite::
|
||||
|
||||
make check
|
||||
|
||||
There is a Makefile that helps with most of the common workflows associated
|
||||
with development. Typing "make" on its own will list the options thus::
|
||||
|
||||
$ make
|
||||
|
||||
There is no default Makefile target right now. Try:
|
||||
|
||||
make clean - reset the project and remove auto-generated assets.
|
||||
make pyflakes - run the PyFlakes code checker.
|
||||
make pycodestyle - run the PEP8 style checker.
|
||||
make test - run the test suite.
|
||||
make coverage - view a report on test coverage.
|
||||
make tidy - tidy code with the 'black' formatter.
|
||||
make check - run all the checkers and tests.
|
||||
make dist - make a dist/wheel for the project.
|
||||
make publish-test - publish the project to PyPI test instance.
|
||||
make publish-live - publish the project to PyPI production.
|
||||
make docs - run sphinx to create project documentation.
|
||||
|
|
|
|||
60
circup.py
Normal file
60
circup.py
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
"""
|
||||
CircUp -- a utility to manage and update libraries on a CircuitPython device.
|
||||
|
||||
Copyright (c) 2019 Adafruit Industries
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
"""
|
||||
from serial.tools.list_ports import comports as list_serial_ports
|
||||
|
||||
|
||||
# IMPORTANT
|
||||
# ---------
|
||||
# Keep these metadata assignments simple and single-line. They are parsed
|
||||
# somewhat naively by setup.py.
|
||||
__title__ = "circup"
|
||||
__description__ = "A tool to manage/update libraries on CircuitPython devices."
|
||||
__version__ = "0.0.1"
|
||||
__license__ = "MIT"
|
||||
__url__ = "https://github.com/adafruit/circup"
|
||||
__author__ = "Adafruit Industries"
|
||||
__email__ = "ntoll@ntoll.org"
|
||||
|
||||
|
||||
VENDOR_ID = 9114 #: The unique USB vendor ID for Adafruit boards.
|
||||
|
||||
|
||||
def find_device():
|
||||
"""
|
||||
Returns a tuple containing the port's device and description for a
|
||||
connected Adafruit device. If no device is connected, the tuple will be
|
||||
(None, None).
|
||||
"""
|
||||
ports = list_serial_ports()
|
||||
for port in ports:
|
||||
if port.vid == VENDOR_ID:
|
||||
return (port.device, port.description)
|
||||
return (None, None)
|
||||
|
||||
|
||||
def main(): # pragma: no cover
|
||||
"""
|
||||
TODO: Finish this. Just checking things work.
|
||||
"""
|
||||
print(find_device())
|
||||
20
docs/Makefile
Normal file
20
docs/Makefile
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# Minimal makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line, and also
|
||||
# from the environment for the first two.
|
||||
SPHINXOPTS ?=
|
||||
SPHINXBUILD ?= sphinx-build
|
||||
SOURCEDIR = .
|
||||
BUILDDIR = _build
|
||||
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
61
docs/conf.py
Normal file
61
docs/conf.py
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file only contains a selection of the most common options. For a full
|
||||
# list see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
# -- Path setup --------------------------------------------------------------
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.abspath('..'))
|
||||
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'CircUp'
|
||||
copyright = '2019, Adafruit Industries'
|
||||
author = 'Adafruit Industries'
|
||||
|
||||
# The full version, including alpha/beta/rc tags
|
||||
import circup
|
||||
release = circup.__version__
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.viewcode',
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This pattern also affects html_static_path and html_extra_path.
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = 'alabaster'
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
21
docs/index.rst
Normal file
21
docs/index.rst
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
.. CircUp documentation master file, created by
|
||||
sphinx-quickstart on Mon Sep 2 10:58:36 2019.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
.. include:: ../README.rst
|
||||
|
||||
.. include:: ../CONTRIBUTING.rst
|
||||
|
||||
API
|
||||
===
|
||||
|
||||
.. automodule:: circup
|
||||
:members:
|
||||
|
||||
.. include:: ../CHANGES.rst
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
.. include:: ../LICENSE
|
||||
35
docs/make.bat
Normal file
35
docs/make.bat
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
@ECHO OFF
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set SOURCEDIR=.
|
||||
set BUILDDIR=_build
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
%SPHINXBUILD% >NUL 2>NUL
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.http://sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
goto end
|
||||
|
||||
:help
|
||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
|
||||
:end
|
||||
popd
|
||||
83
setup.py
Normal file
83
setup.py
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
#!/usr/bin/env python3
|
||||
import os
|
||||
import re
|
||||
from setuptools import setup
|
||||
|
||||
|
||||
base_dir = os.path.dirname(__file__)
|
||||
|
||||
|
||||
DUNDER_ASSIGN_RE = re.compile(r"""^__\w+__\s*=\s*['"].+['"]$""")
|
||||
about = {}
|
||||
with open(os.path.join(base_dir, "circup.py"), encoding="utf8") as f:
|
||||
for line in f:
|
||||
if DUNDER_ASSIGN_RE.search(line):
|
||||
exec(line, about)
|
||||
|
||||
|
||||
with open(os.path.join(base_dir, "README.rst"), encoding="utf8") as f:
|
||||
readme = f.read()
|
||||
|
||||
with open(os.path.join(base_dir, "CHANGES.rst"), encoding="utf8") as f:
|
||||
changes = f.read()
|
||||
|
||||
|
||||
install_requires = ["pyserial>=3.0,<4.0", "PyGithub>=1.43.8"]
|
||||
|
||||
extras_require = {
|
||||
"tests": [
|
||||
"pytest",
|
||||
"pytest-cov",
|
||||
"pytest-random-order>=1.0.0",
|
||||
"pytest-faulthandler",
|
||||
"coverage",
|
||||
"pycodestyle",
|
||||
"pyflakes",
|
||||
"black",
|
||||
],
|
||||
"docs": ["sphinx"],
|
||||
"package": [
|
||||
# Wheel building and PyPI uploading
|
||||
"wheel",
|
||||
"twine",
|
||||
],
|
||||
}
|
||||
|
||||
extras_require["dev"] = (
|
||||
extras_require["tests"]
|
||||
+ extras_require["docs"]
|
||||
+ extras_require["package"]
|
||||
)
|
||||
|
||||
extras_require["all"] = list(
|
||||
{req for extra, reqs in extras_require.items() for req in reqs}
|
||||
)
|
||||
|
||||
setup(
|
||||
name=about["__title__"],
|
||||
version=about["__version__"],
|
||||
description=about["__description__"],
|
||||
long_description="{}\n\n{}".format(readme, changes),
|
||||
author=about["__author__"],
|
||||
author_email=about["__email__"],
|
||||
url=about["__url__"],
|
||||
license=about["__license__"],
|
||||
py_modules=["circup"],
|
||||
install_requires=install_requires,
|
||||
extras_require=extras_require,
|
||||
classifiers=[
|
||||
"Development Status :: 3 - Alpha",
|
||||
"Environment :: Console",
|
||||
"Intended Audience :: Developers",
|
||||
"Intended Audience :: Education",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Operating System :: POSIX",
|
||||
"Operating System :: Microsoft :: Windows",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Topic :: Education",
|
||||
"Topic :: Software Development :: Embedded Systems",
|
||||
"Topic :: System :: Software Distribution",
|
||||
],
|
||||
entry_points={"console_scripts": ["circup=circup:main"]},
|
||||
)
|
||||
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
60
tests/test_circup.py
Normal file
60
tests/test_circup.py
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
"""
|
||||
Unit tests for the circup module.
|
||||
|
||||
Copyright (c) 2019 Adafruit Industries
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
"""
|
||||
import circup
|
||||
from unittest import mock
|
||||
|
||||
|
||||
def test_find_device():
|
||||
"""
|
||||
Ensure the find_device function returns the expected information about
|
||||
any Adafruit devices connected to the user's computer.
|
||||
"""
|
||||
|
||||
class FakePort:
|
||||
"""
|
||||
Pretends to be a representation of a port in PySerial.
|
||||
"""
|
||||
|
||||
def __init__(self, vid, device, description):
|
||||
self.vid = vid
|
||||
self.device = device
|
||||
self.description = description
|
||||
|
||||
device = "/dev/ttyACM3"
|
||||
description = "CircuitPlayground Express - CircuitPython CDC control"
|
||||
port = FakePort(circup.VENDOR_ID, device, description)
|
||||
ports = [port]
|
||||
with mock.patch("circup.list_serial_ports", return_value=ports):
|
||||
result = circup.find_device()
|
||||
assert result == (device, description)
|
||||
|
||||
|
||||
def test_find_device_not_connected():
|
||||
"""
|
||||
If no Adafruit device is connected to the user's computer, ensure the
|
||||
result is (None, None)
|
||||
"""
|
||||
with mock.patch("circup.list_serial_ports", return_value=[]):
|
||||
result = circup.find_device()
|
||||
assert result == (None, None)
|
||||
Loading…
Reference in a new issue