Setup a python test framework
This commit is contained in:
		
							
								
								
									
										8
									
								
								bin/qmk
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								bin/qmk
									
									
									
									
									
								
							| @@ -94,4 +94,10 @@ else: | |||||||
|         exit(1) |         exit(1) | ||||||
|  |  | ||||||
| if __name__ == '__main__': | if __name__ == '__main__': | ||||||
|     milc.cli() |     return_code = milc.cli() | ||||||
|  |     if return_code is False: | ||||||
|  |         exit(1) | ||||||
|  |     elif return_code is not True and isinstance(return_code, int) and return_code < 256: | ||||||
|  |         exit(return_code) | ||||||
|  |     else: | ||||||
|  |         exit(0) | ||||||
|   | |||||||
							
								
								
									
										23
									
								
								keyboards/handwired/onekey/pytest/config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								keyboards/handwired/onekey/pytest/config.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  | /* Copyright 2019 | ||||||
|  |  * | ||||||
|  |  * This program is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 2 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "config_common.h" | ||||||
|  |  | ||||||
|  | #define MATRIX_COL_PINS { A3 } | ||||||
|  | #define MATRIX_ROW_PINS { A2 } | ||||||
|  | #define UNUSED_PINS | ||||||
							
								
								
									
										3
									
								
								keyboards/handwired/onekey/pytest/readme.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								keyboards/handwired/onekey/pytest/readme.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | # PyTest onekey | ||||||
|  |  | ||||||
|  | This is used by the python test framework. It's probably not useful otherwise. | ||||||
							
								
								
									
										2
									
								
								keyboards/handwired/onekey/pytest/rules.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								keyboards/handwired/onekey/pytest/rules.mk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | # MCU name | ||||||
|  | MCU = STM32F303 | ||||||
							
								
								
									
										1
									
								
								keyboards/handwired/onekey/pytest/templates/keymap.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								keyboards/handwired/onekey/pytest/templates/keymap.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {__KEYMAP_GOES_HERE__}; | ||||||
| @@ -534,8 +534,7 @@ class MILC(object): | |||||||
|         if not self._inside_context_manager: |         if not self._inside_context_manager: | ||||||
|             # If they didn't use the context manager use it ourselves |             # If they didn't use the context manager use it ourselves | ||||||
|             with self: |             with self: | ||||||
|                 self.__call__() |                 return self.__call__() | ||||||
|                 return |  | ||||||
|  |  | ||||||
|         if not self._entrypoint: |         if not self._entrypoint: | ||||||
|             raise RuntimeError('No entrypoint provided!') |             raise RuntimeError('No entrypoint provided!') | ||||||
|   | |||||||
| @@ -2,9 +2,11 @@ | |||||||
|  |  | ||||||
| Check up for QMK environment. | Check up for QMK environment. | ||||||
| """ | """ | ||||||
| import shutil |  | ||||||
| import platform |  | ||||||
| import os | import os | ||||||
|  | import platform | ||||||
|  | import shutil | ||||||
|  | import subprocess | ||||||
|  | from glob import glob | ||||||
|  |  | ||||||
| from milc import cli | from milc import cli | ||||||
|  |  | ||||||
| @@ -16,20 +18,26 @@ def main(cli): | |||||||
|     This is currently very simple, it just checks that all the expected binaries are on your system. |     This is currently very simple, it just checks that all the expected binaries are on your system. | ||||||
|  |  | ||||||
|     TODO(unclaimed): |     TODO(unclaimed): | ||||||
|         * [ ] Run the binaries to make sure they work |  | ||||||
|         * [ ] Compile a trivial program with each compiler |         * [ ] Compile a trivial program with each compiler | ||||||
|         * [ ] Check for udev entries on linux |         * [ ] Check for udev entries on linux | ||||||
|     """ |     """ | ||||||
|  |  | ||||||
|     binaries = ['dfu-programmer', 'avrdude', 'dfu-util', 'avr-gcc', 'arm-none-eabi-gcc'] |     binaries = ['dfu-programmer', 'avrdude', 'dfu-util', 'avr-gcc', 'arm-none-eabi-gcc'] | ||||||
|  |     binaries += glob('bin/qmk-*') | ||||||
|  |  | ||||||
|     cli.log.info('QMK Doctor is Checking your environment') |     cli.log.info('QMK Doctor is checking your environment') | ||||||
|  |  | ||||||
|     ok = True |     ok = True | ||||||
|     for binary in binaries: |     for binary in binaries: | ||||||
|         res = shutil.which(binary) |         res = shutil.which(binary) | ||||||
|         if res is None: |         if res is None: | ||||||
|             cli.log.error('{fg_red}QMK can\'t find ' + binary + ' in your path') |             cli.log.error("{fg_red}QMK can't find %s in your path", binary) | ||||||
|  |             ok = False | ||||||
|  |         else: | ||||||
|  |             try: | ||||||
|  |                 subprocess.run([binary, '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=5, check=True) | ||||||
|  |             except subprocess.CalledProcessError: | ||||||
|  |                 cli.log.error("{fg_red}Can't run `%s --version`", binary) | ||||||
|                 ok = False |                 ok = False | ||||||
|  |  | ||||||
|     OS = platform.system() |     OS = platform.system() | ||||||
| @@ -37,11 +45,17 @@ def main(cli): | |||||||
|         cli.log.info("Detected {fg_cyan}macOS") |         cli.log.info("Detected {fg_cyan}macOS") | ||||||
|     elif OS == "Linux": |     elif OS == "Linux": | ||||||
|         cli.log.info("Detected {fg_cyan}linux") |         cli.log.info("Detected {fg_cyan}linux") | ||||||
|  |         if shutil.which('systemctl'): | ||||||
|             test = 'systemctl list-unit-files | grep enabled | grep -i ModemManager' |             test = 'systemctl list-unit-files | grep enabled | grep -i ModemManager' | ||||||
|             if os.system(test) == 0: |             if os.system(test) == 0: | ||||||
|                 cli.log.warn("{bg_yellow}Detected modem manager. Please disable it if you are using Pro Micros") |                 cli.log.warn("{bg_yellow}Detected modem manager. Please disable it if you are using Pro Micros") | ||||||
|  |         else: | ||||||
|  |             cli.log.warn("Can't find systemctl to check for ModemManager.") | ||||||
|     else: |     else: | ||||||
|         cli.log.info("Assuming {fg_cyan}Windows") |         cli.log.info("Assuming {fg_cyan}Windows") | ||||||
|  |  | ||||||
|     if ok: |     if ok: | ||||||
|         cli.log.info('{fg_green}QMK is ready to go') |         cli.log.info('{fg_green}QMK is ready to go') | ||||||
|  |     else: | ||||||
|  |         cli.log.info('{fg_yellow}Problems detected, please fix these problems before proceeding.') | ||||||
|  |         # FIXME(skullydazed): Link to a document about troubleshooting, or discord or something | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								lib/python/qmk/cli/nose2.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								lib/python/qmk/cli/nose2.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | """QMK Python Unit Tests | ||||||
|  |  | ||||||
|  | QMK script to run unit and integration tests against our python code. | ||||||
|  | """ | ||||||
|  | from milc import cli | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @cli.entrypoint('QMK Python Unit Tests') | ||||||
|  | def main(cli): | ||||||
|  |     """Use nose2 to run unittests | ||||||
|  |     """ | ||||||
|  |     try: | ||||||
|  |         import nose2 | ||||||
|  |     except ImportError: | ||||||
|  |         cli.log.error('Could not import nose2! Please install it with {fg_cyan}pip3 install nose2') | ||||||
|  |         return False | ||||||
|  |  | ||||||
|  |     nose2.discover() | ||||||
							
								
								
									
										0
									
								
								lib/python/qmk/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								lib/python/qmk/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										8
									
								
								lib/python/qmk/tests/attrdict.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								lib/python/qmk/tests/attrdict.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | class AttrDict(dict): | ||||||
|  |     """A dictionary that can be accessed by attributes. | ||||||
|  |  | ||||||
|  |     This should only be used to mock objects for unit testing. Please do not use this outside of qmk.tests. | ||||||
|  |     """ | ||||||
|  |     def __init__(self, *args, **kwargs): | ||||||
|  |         super(AttrDict, self).__init__(*args, **kwargs) | ||||||
|  |         self.__dict__ = self | ||||||
							
								
								
									
										6
									
								
								lib/python/qmk/tests/onekey_export.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								lib/python/qmk/tests/onekey_export.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | { | ||||||
|  |     "keyboard":"handwired/onekey/pytest", | ||||||
|  |     "keymap":"pytest_unittest", | ||||||
|  |     "layout":"LAYOUT", | ||||||
|  |     "layers":[["KC_A"]] | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								lib/python/qmk/tests/test_qmk_errors.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								lib/python/qmk/tests/test_qmk_errors.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | from qmk.errors import NoSuchKeyboardError | ||||||
|  |  | ||||||
|  | def test_NoSuchKeyboardError(): | ||||||
|  |     try: | ||||||
|  |         raise(NoSuchKeyboardError("test message")) | ||||||
|  |     except NoSuchKeyboardError as e: | ||||||
|  |         assert e.message == 'test message' | ||||||
							
								
								
									
										18
									
								
								lib/python/qmk/tests/test_qmk_keymap.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								lib/python/qmk/tests/test_qmk_keymap.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | import qmk.keymap | ||||||
|  |  | ||||||
|  | def test_template_onekey_proton_c(): | ||||||
|  |     templ = qmk.keymap.template('handwired/onekey/proton_c') | ||||||
|  |     assert templ == qmk.keymap.DEFAULT_KEYMAP_C | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def test_template_onekey_pytest(): | ||||||
|  |     templ = qmk.keymap.template('handwired/onekey/pytest') | ||||||
|  |     assert templ == 'const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {__KEYMAP_GOES_HERE__};\n' | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def test_generate_onekey_pytest(): | ||||||
|  |     templ = qmk.keymap.generate('handwired/onekey/pytest', 'LAYOUT', [['KC_A']]) | ||||||
|  |     assert templ == 'const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {	[0] = LAYOUT(KC_A)};\n' | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # FIXME(skullydazed): Add a test for qmk.keymap.write that mocks up an FD. | ||||||
							
								
								
									
										12
									
								
								lib/python/qmk/tests/test_qmk_path.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								lib/python/qmk/tests/test_qmk_path.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | import os | ||||||
|  |  | ||||||
|  | import qmk.path | ||||||
|  |  | ||||||
|  | def test_keymap_onekey_pytest(): | ||||||
|  |     path = qmk.path.keymap('handwired/onekey/pytest') | ||||||
|  |     assert path == 'keyboards/handwired/onekey/keymaps' | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def test_normpath(): | ||||||
|  |     path = qmk.path.normpath('lib/python') | ||||||
|  |     assert path == os.environ['ORIG_CWD'] + '/lib/python' | ||||||
		Reference in New Issue
	
	Block a user