1
0
mirror of https://github.com/EDCD/EDMarketConnector.git synced 2025-06-12 13:22:54 +03:00

[2051] Add Tests and gitignore File

This commit is contained in:
David Sangrey 2023-10-19 20:06:52 -04:00
parent 239c5b6e24
commit 28e10b70ef
No known key found for this signature in database
GPG Key ID: 3AEADBB0186884BC
7 changed files with 64 additions and 46 deletions

37
.gitignore vendored
View File

@ -1,8 +1,18 @@
# Ignore version file
.gitversion .gitversion
# Ignore macOS DS_Store files
.DS_Store .DS_Store
# Ignore build artifacts
build build
ChangeLog.html dist.win32/
dist.* dist.*
# Ignore generated ChangeLog.html file
ChangeLog.html
# Ignore files
dump dump
*.bak *.bak
*.pyc *.pyc
@ -11,20 +21,37 @@ dump
*.pdb *.pdb
*.msi *.msi
*.wixobj *.wixobj
*.zip
# Ignore Update Things
EDMarketConnector_Installer_*.exe EDMarketConnector_Installer_*.exe
appcast_win_*.xml appcast_win_*.xml
appcast_mac_*.xml appcast_mac_*.xml
EDMarketConnector.VisualElementsManifest.xml
*.zip
EDMC_Installer_Config.iss EDMC_Installer_Config.iss
EDMarketConnector.wxs
wix/components.wxs
# Ignore Visual Elements Manifest file for Windows
EDMarketConnector.VisualElementsManifest.xml
# Ignore IDE and editor configuration files
.idea .idea
.vscode .vscode
# Ignore virtual environments
.venv/ .venv/
venv/ venv/
venv2
# Ignore workspace file for Visual Studio Code
*.code-workspace *.code-workspace
# Ignore coverage reports
htmlcov/ htmlcov/
.ignored .ignored
.coverage .coverage
EDMarketConnector.wxs pylintrc
wix/components.wxs pylint.txt
# Ignore Submodule data directory
coriolis-data/

View File

@ -37,7 +37,7 @@ def test_class_logger(caplog: 'LogCaptureFixture') -> None:
ClassVarLogger.set_logger(logger) ClassVarLogger.set_logger(logger)
ClassVarLogger.logger.debug('test') # type: ignore # its there ClassVarLogger.logger.debug('test') # type: ignore # its there
ClassVarLogger.logger.info('test2') # type: ignore # its there ClassVarLogger.logger.info('test2') # type: ignore # its there
log_stuff('test3') # type: ignore # its there log_stuff('test3')
# Dont move these, it relies on the line numbres. # Dont move these, it relies on the line numbres.
assert 'EDMarketConnector.EDMCLogging.py:test_logging_classvar.py:38 test' in caplog.text assert 'EDMarketConnector.EDMCLogging.py:test_logging_classvar.py:38 test' in caplog.text

View File

@ -1,4 +1,4 @@
# type: ignore """Old Configuration Test File."""
import numbers import numbers
import sys import sys
import warnings import warnings
@ -6,7 +6,6 @@ from configparser import NoOptionError
from os import getenv, makedirs, mkdir, pardir from os import getenv, makedirs, mkdir, pardir
from os.path import dirname, expanduser, isdir, join, normpath from os.path import dirname, expanduser, isdir, join, normpath
from typing import TYPE_CHECKING, Optional, Union from typing import TYPE_CHECKING, Optional, Union
from config import applongname, appname, update_interval from config import applongname, appname, update_interval
from EDMCLogging import get_main_logger from EDMCLogging import get_main_logger
@ -95,7 +94,7 @@ elif sys.platform == 'linux':
from configparser import RawConfigParser from configparser import RawConfigParser
class OldConfig(): class OldConfig:
"""Object that holds all configuration data.""" """Object that holds all configuration data."""
OUT_EDDN_SEND_STATION_DATA = 1 OUT_EDDN_SEND_STATION_DATA = 1
@ -139,7 +138,7 @@ class OldConfig():
self.identifier = f'uk.org.marginal.{appname.lower()}' self.identifier = f'uk.org.marginal.{appname.lower()}'
NSBundle.mainBundle().infoDictionary()['CFBundleIdentifier'] = self.identifier NSBundle.mainBundle().infoDictionary()['CFBundleIdentifier'] = self.identifier
self.default_journal_dir: str | None = join( self.default_journal_dir: Optional[str] = join(
NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, True)[0], NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, True)[0],
'Frontier Developments', 'Frontier Developments',
'Elite Dangerous' 'Elite Dangerous'
@ -159,14 +158,13 @@ class OldConfig():
if val is None: if val is None:
return default return default
elif isinstance(val, str): if isinstance(val, str):
return str(val) return str(val)
elif isinstance(val, list): if isinstance(val, list):
return list(val) # make writeable return list(val) # make writeable
else: return default
return default
def getint(self, key: str, default: int = 0) -> int: def getint(self, key: str, default: int = 0) -> int:
"""Look up an integer configuration value.""" """Look up an integer configuration value."""
@ -202,7 +200,7 @@ class OldConfig():
elif sys.platform == 'win32': elif sys.platform == 'win32':
def __init__(self): def __init__(self):
self.app_dir = join(known_folder_path(FOLDERID_LocalAppData), appname) # type: ignore # Not going to change self.app_dir = join(known_folder_path(FOLDERID_LocalAppData), appname) # type: ignore
if not isdir(self.app_dir): if not isdir(self.app_dir):
mkdir(self.app_dir) mkdir(self.app_dir)
@ -223,13 +221,13 @@ class OldConfig():
journaldir = known_folder_path(FOLDERID_SavedGames) journaldir = known_folder_path(FOLDERID_SavedGames)
if journaldir: if journaldir:
self.default_journal_dir: str | None = join(journaldir, 'Frontier Developments', 'Elite Dangerous') self.default_journal_dir: Optional[str] = join(journaldir, 'Frontier Developments', 'Elite Dangerous')
else: else:
self.default_journal_dir = None self.default_journal_dir = None
self.identifier = applongname self.identifier = applongname
self.hkey: ctypes.c_void_p | None = HKEY() self.hkey: Optional[ctypes.c_void_p] = HKEY()
disposition = DWORD() disposition = DWORD()
if RegCreateKeyEx( if RegCreateKeyEx(
HKEY_CURRENT_USER, HKEY_CURRENT_USER,
@ -279,7 +277,7 @@ class OldConfig():
RegSetValueEx(sparklekey, 'UpdateInterval', 0, 1, buf, len(buf) * 2) RegSetValueEx(sparklekey, 'UpdateInterval', 0, 1, buf, len(buf) * 2)
RegCloseKey(sparklekey) RegCloseKey(sparklekey)
if not self.get('outdir') or not isdir(self.get('outdir')): # type: ignore # Not going to change if not self.get('outdir') or not isdir(self.get('outdir')): # type: ignore
self.set('outdir', known_folder_path(FOLDERID_Documents) or self.home) self.set('outdir', known_folder_path(FOLDERID_Documents) or self.home)
def get(self, key: str, default: Union[None, list, str] = None) -> Union[None, list, str]: def get(self, key: str, default: Union[None, list, str] = None) -> Union[None, list, str]:
@ -304,11 +302,10 @@ class OldConfig():
if RegQueryValueEx(self.hkey, key, 0, ctypes.byref(key_type), buf, ctypes.byref(key_size)): if RegQueryValueEx(self.hkey, key, 0, ctypes.byref(key_type), buf, ctypes.byref(key_size)):
return default return default
elif key_type.value == REG_MULTI_SZ: if key_type.value == REG_MULTI_SZ:
return list(ctypes.wstring_at(buf, len(buf)-2).split('\x00')) return list(ctypes.wstring_at(buf, len(buf)-2).split('\x00'))
else: return str(buf.value)
return str(buf.value)
def getint(self, key: str, default: int = 0) -> int: def getint(self, key: str, default: int = 0) -> int:
"""Look up an integer configuration value.""" """Look up an integer configuration value."""
@ -328,8 +325,7 @@ class OldConfig():
): ):
return default return default
else: return key_val.value
return key_val.value
def set(self, key: str, val: Union[int, str, list]) -> None: def set(self, key: str, val: Union[int, str, list]) -> None:
"""Set value on the specified configuration key.""" """Set value on the specified configuration key."""
@ -377,7 +373,7 @@ class OldConfig():
mkdir(self.plugin_dir) mkdir(self.plugin_dir)
self.internal_plugin_dir = join(dirname(__file__), 'plugins') self.internal_plugin_dir = join(dirname(__file__), 'plugins')
self.default_journal_dir: str | None = None self.default_journal_dir: Optional[str] = None
self.home = expanduser('~') self.home = expanduser('~')
self.respath = dirname(__file__) self.respath = dirname(__file__)
self.identifier = f'uk.org.marginal.{appname.lower()}' self.identifier = f'uk.org.marginal.{appname.lower()}'
@ -388,7 +384,7 @@ class OldConfig():
self.config = RawConfigParser(comment_prefixes=('#',)) self.config = RawConfigParser(comment_prefixes=('#',))
try: try:
with codecs.open(self.filename, 'r') as h: with codecs.open(self.filename) as h:
self.config.read_file(h) self.config.read_file(h)
except Exception as e: except Exception as e:
@ -407,8 +403,7 @@ class OldConfig():
# so we add a spurious ';' entry in set() and remove it here # so we add a spurious ';' entry in set() and remove it here
assert val.split('\n')[-1] == ';', val.split('\n') assert val.split('\n')[-1] == ';', val.split('\n')
return [self._unescape(x) for x in val.split('\n')[:-1]] return [self._unescape(x) for x in val.split('\n')[:-1]]
else: return self._unescape(val)
return self._unescape(val)
except NoOptionError: except NoOptionError:
logger.debug(f'attempted to get key {key} that does not exist') logger.debug(f'attempted to get key {key} that does not exist')
@ -437,10 +432,10 @@ class OldConfig():
def set(self, key: str, val: Union[int, str, list]) -> None: def set(self, key: str, val: Union[int, str, list]) -> None:
"""Set value on the specified configuration key.""" """Set value on the specified configuration key."""
if isinstance(val, bool): if isinstance(val, bool):
self.config.set(self.SECTION, key, val and '1' or '0') # type: ignore # Not going to change self.config.set(self.SECTION, key, val and '1' or '0')
elif isinstance(val, str) or isinstance(val, numbers.Integral): elif isinstance(val, (numbers.Integral, str)):
self.config.set(self.SECTION, key, self._escape(val)) # type: ignore # Not going to change self.config.set(self.SECTION, key, self._escape(val))
elif isinstance(val, list): elif isinstance(val, list):
self.config.set(self.SECTION, key, '\n'.join([self._escape(x) for x in val] + [';'])) self.config.set(self.SECTION, key, '\n'.join([self._escape(x) for x in val] + [';']))
@ -460,7 +455,7 @@ class OldConfig():
def close(self) -> None: def close(self) -> None:
"""Close the configuration.""" """Close the configuration."""
self.save() self.save()
self.config = None self.config = None # type: ignore
def _escape(self, val: str) -> str: def _escape(self, val: str) -> str:
"""Escape a string for storage.""" """Escape a string for storage."""

View File

@ -7,8 +7,6 @@ key deletions. Said modifications are to keys that are generated internally.
Most of these tests are parity tests with the "old" config, and likely one day can be Most of these tests are parity tests with the "old" config, and likely one day can be
entirely removed. entirely removed.
""" """
from __future__ import annotations
import contextlib import contextlib
import itertools import itertools
import pathlib import pathlib
@ -81,7 +79,7 @@ def _build_test_list(static_data, random_data, random_id_name='random_test_{i}')
class TestNewConfig: class TestNewConfig:
"""Test the new config with an array of hand picked and random data.""" """Test the new config with an array of hand-picked and random data."""
def __update_linuxconfig(self) -> None: def __update_linuxconfig(self) -> None:
"""On linux config uses ConfigParser, which doesn't update from disk changes. Force the update here.""" """On linux config uses ConfigParser, which doesn't update from disk changes. Force the update here."""

View File

@ -3,11 +3,9 @@ import multiprocessing as mp
import os import os
import pathlib import pathlib
import sys import sys
from typing import Generator from typing import Generator, Optional
import pytest import pytest
from pytest import MonkeyPatch, TempdirFactory, TempPathFactory from pytest import MonkeyPatch, TempdirFactory, TempPathFactory
from config import config from config import config
from journal_lock import JournalLock, JournalLockResult from journal_lock import JournalLock, JournalLockResult
@ -120,7 +118,7 @@ class TestJournalLock:
tmp_path_factory: TempdirFactory tmp_path_factory: TempdirFactory
) -> Generator: ) -> Generator:
"""Fixture for mocking config.get_str('journaldir').""" """Fixture for mocking config.get_str('journaldir')."""
def get_str(key: str, *, default: str | None = None) -> str: def get_str(key: str, *, default: Optional[str] = None) -> str:
"""Mock config.*Config get_str to provide fake journaldir.""" """Mock config.*Config get_str to provide fake journaldir."""
if key == 'journaldir': if key == 'journaldir':
return str(tmp_path_factory.getbasetemp()) return str(tmp_path_factory.getbasetemp())
@ -139,10 +137,10 @@ class TestJournalLock:
tmp_path_factory: TempdirFactory tmp_path_factory: TempdirFactory
) -> Generator: ) -> Generator:
"""Fixture for mocking config.get_str('journaldir').""" """Fixture for mocking config.get_str('journaldir')."""
def get_str(key: str, *, default: str | None = None) -> str: def get_str(key: str, *, default: Optional[str] = None) -> str:
"""Mock config.*Config get_str to provide fake journaldir.""" """Mock config.*Config get_str to provide fake journaldir."""
if key == 'journaldir': if key == 'journaldir':
return tmp_path_factory.mktemp("changing") return tmp_path_factory.mktemp("changing") # type: ignore
print('Other key, calling up ...') print('Other key, calling up ...')
return config.get_str(key) # Call the non-mocked return config.get_str(key) # Call the non-mocked
@ -301,7 +299,7 @@ class TestJournalLock:
# Need to release any handles on the lockfile else the sub-process # Need to release any handles on the lockfile else the sub-process
# might not be able to clean up properly, and that will impact # might not be able to clean up properly, and that will impact
# on later tests. # on later tests.
jlock.journal_dir_lockfile.close() jlock.journal_dir_lockfile.close() # type: ignore
print('Telling sub-process to quit...') print('Telling sub-process to quit...')
exit_q.put('quit') exit_q.put('quit')

View File

@ -33,11 +33,11 @@ def test_apply(source: UPDATABLE_DATA, key: str, action: str, to_set: Any, resul
def test_apply_errors() -> None: def test_apply_errors() -> None:
"""_apply should fail when passed something that isn't a Sequence or MutableMapping.""" """_apply should fail when passed something that isn't a Sequence or MutableMapping."""
with pytest.raises(ValueError, match=r'Dont know how to'): with pytest.raises(ValueError, match=r'Dont know how to'):
killswitch._apply(set(), '0', None, False) # type: ignore # Its intentional that its broken killswitch._apply(set(), '0') # type: ignore # Its intentional that its broken
killswitch._apply(None, '', None) # type: ignore # Its intentional that its broken killswitch._apply(None, '') # type: ignore # Its intentional that its broken
with pytest.raises(ValueError, match=r'Cannot use string'): with pytest.raises(ValueError, match=r'Cannot use string'):
killswitch._apply([], 'test', None, False) killswitch._apply([], 'test')
def test_apply_no_error() -> None: def test_apply_no_error() -> None:

View File

@ -1,6 +1,6 @@
"""Tests of killswitch behaviour.""" """Tests of killswitch behaviour."""
import copy import copy
from typing import Optional from typing import Optional, List
import pytest import pytest
import semantic_version import semantic_version
@ -85,7 +85,7 @@ def test_operator_precedence(
] ]
) )
def test_check_multiple( def test_check_multiple(
names: list[str], input: killswitch.UPDATABLE_DATA, result: killswitch.UPDATABLE_DATA, expected_return: bool names: List[str], input: killswitch.UPDATABLE_DATA, result: killswitch.UPDATABLE_DATA, expected_return: bool
) -> None: ) -> None:
"""Check that order is correct when checking multiple killswitches.""" """Check that order is correct when checking multiple killswitches."""
should_return, data = TEST_SET.check_multiple_killswitches(input, *names, version='1.0.0') should_return, data = TEST_SET.check_multiple_killswitches(input, *names, version='1.0.0')