mirror of
https://github.com/gryf/fs-uae-wrapper.git
synced 2026-02-02 22:25:47 +01:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f1f64cf4d4 | |||
| a5606272cd | |||
| 463f6ed705 |
154
README.rst
154
README.rst
@@ -314,6 +314,155 @@ The steps would be as follows:
|
||||
- optionally create archive with save state (if save state directory place is
|
||||
*not* a global one)
|
||||
|
||||
whdload
|
||||
-------
|
||||
|
||||
Options used:
|
||||
|
||||
* ``wrapper`` (required) with ``whdload`` as an value
|
||||
* ``wrapper_whdload_base`` (required) path to the whdload base system. Usually
|
||||
it's minimal system containing at least whdload executables in C, and config
|
||||
in S. Read on below for further details.
|
||||
* ``wrapper_archive`` (optional) path to the whdload archive, defaults to same
|
||||
name as configuration file with some detected archive extension. Note, that
|
||||
name is case sensitive
|
||||
* ``wrapper_archiver`` (optional) archiver to use for storage save state -
|
||||
default ``7z``.
|
||||
|
||||
This module is solely used with whdload distributed games (not just whdload
|
||||
slave files, but whole games, which can be found on several places on the
|
||||
internet).
|
||||
|
||||
Base image
|
||||
~~~~~~~~~~
|
||||
|
||||
To make it work, first the minimal system archive need to be prepared. There
|
||||
are few dependences to be included in such small system:
|
||||
|
||||
- `WHDLoad`_ 18.9
|
||||
- `uaequit`_
|
||||
- `SetPatch`_ 43.6
|
||||
- ``Excecute``, ``Assign`` and whatever commands you'll be use in scripts from
|
||||
your copy of Workbench
|
||||
- `kgiconload`_ - tool for reading icon and executing *default tool* with
|
||||
optionally defined tool types as parameters (in this case: WHDLoad)
|
||||
- `SKick`_ optionally - for kickstart relocations. Also images of corresponding
|
||||
kickstart ROM images will be needed.
|
||||
|
||||
Now, the tree for the minimal image could look like that:
|
||||
|
||||
.. code::
|
||||
.
|
||||
├── C
|
||||
│  ├── Assign
|
||||
│  ├── DIC
|
||||
│  ├── Execute
|
||||
│  ├── kgiconload
|
||||
│  ├── Patcher
|
||||
│  ├── RawDIC
|
||||
│  ├── SetPatch
|
||||
│  ├── UAEquit
|
||||
│  ├── WHDLoad
|
||||
│  └── WHDLoadCD32
|
||||
└── S
|
||||
├── startup-sequence
|
||||
└── WHDLoad.prefs
|
||||
|
||||
to use relocation tables you'll need to place ``Kickstarts`` drawer into Devs
|
||||
drawer, so it'll looks like this:
|
||||
|
||||
.. code::
|
||||
.
|
||||
├── C
|
||||
│  ├── Assign
|
||||
│  ├── …
|
||||
│  └── WHDLoadCD32
|
||||
├── Devs
|
||||
│  └── Kickstarts
|
||||
│  ├── 39115_ROMKick.PAT
|
||||
│  ├── 39115_ROMKick.RTB
|
||||
│  ├── …
|
||||
│  ├── kick40068.A4000.PAT
|
||||
│  └── kick40068.A4000.RTB
|
||||
└── S
|
||||
├── startup-sequence
|
||||
└── WHDLoad.prefs
|
||||
|
||||
Important: You'll need to prepare archive with base OS without top directory,
|
||||
i.e. suppose you have prepared all the files in ``/tmp/baseos``:
|
||||
|
||||
.. code:: shell-session
|
||||
|
||||
$ pwd
|
||||
/tmp
|
||||
$ cd baseos
|
||||
$ pwd
|
||||
/tmp/basos
|
||||
$ ls
|
||||
C S
|
||||
$ zip -r /tmp/base.zip .
|
||||
adding: C/ (stored 0%)
|
||||
adding: C/Assign (deflated 31%)
|
||||
adding: C/WHDLoadCD32 (deflated 26%)
|
||||
adding: C/RawDIC (deflated 46%)
|
||||
adding: C/UAEquit (deflated 39%)
|
||||
adding: C/Execute (deflated 42%)
|
||||
adding: C/Patcher (deflated 56%)
|
||||
adding: C/DIC (deflated 33%)
|
||||
adding: C/kgiconload (deflated 49%)
|
||||
adding: C/SetPatch (deflated 39%)
|
||||
adding: C/WHDLoad (deflated 23%)
|
||||
adding: S/ (stored 0%)
|
||||
adding: S/startup-sequence (deflated 36%)
|
||||
adding: S/WHDLoad.prefs (deflated 51%)
|
||||
|
||||
You can do it with other archivers as well, like 7z: ``7z a /tmp/base.7z .`` or
|
||||
tar with different compressions: ``tar Jcf /tmp/base.tar.xz .``, ``tar zcf
|
||||
/tmp/base.tgz .``, ``tar jcf /tmp/base.tar.bz2 .``. It should work with all
|
||||
mentioned at the beginning of this document archivers.
|
||||
|
||||
Starting point is in ``S/startup-sequence`` file, where eventually
|
||||
``S/whdload-startup`` is executed, which will be created by fs-uae-warpper
|
||||
before execution by fs-uae.
|
||||
|
||||
|
||||
Configuration
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Now, to use whdload module with any of the WHDLoad game, you'll need to prepare
|
||||
configuration for the wrapper.
|
||||
|
||||
Example configuration:
|
||||
|
||||
.. code:: ini
|
||||
|
||||
[config]
|
||||
wrapper = whdload
|
||||
wrapper_whdload_base = $CONFIG/whdload_base.7z
|
||||
# ...
|
||||
|
||||
And execution is as usual:
|
||||
|
||||
.. code:: shell-session
|
||||
|
||||
$ fs-uae-wrapper ChaosEngine_v1.2_0106.fs-uae
|
||||
|
||||
Now, similar to the archive module, it will create temporary directory, unpack
|
||||
base image there, unpack WHDLoad game archive, search for slave file, and
|
||||
preapre ``s:whdload-startup``, and finally pass all the configuration to
|
||||
fs-uae.
|
||||
|
||||
|
||||
Limitations
|
||||
===========
|
||||
|
||||
There is one limitation when using save ``wrapper_save_state`` option. In case
|
||||
of floppies it should work without any issues, although save state for running
|
||||
Workbench or WHDLoad games may or may not work. In the past there was an issue
|
||||
with `fs-uae`_ where saving state was causing data corruption on the emulated
|
||||
system. Use it with caution!
|
||||
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
@@ -328,3 +477,8 @@ This work is licensed on 3-clause BSD license. See LICENSE file for details.
|
||||
.. _tar: https://www.gnu.org/software/tar/
|
||||
.. _zip: http://www.info-zip.org
|
||||
.. _CheeseShop: https://pypi.python.org/pypi/fs-/fs-uae-wrapperuae-wrapper
|
||||
.. _WHDLoad: https://www.whdload.de
|
||||
.. _uaequit: https://aminet.net/package/misc/emu/UAEquit
|
||||
.. _SKick: https://aminet.net/package/util/boot/skick346
|
||||
.. _SetPatch: https://aminet.net/package/util/boot/SetPatch_43.6b
|
||||
.. _kgiconload: https://eab.abime.net/showpost.php?p=733614&postcount=92
|
||||
|
||||
@@ -42,6 +42,7 @@ class Base(object):
|
||||
- run the emulation
|
||||
- archive save state
|
||||
"""
|
||||
logging.debug("run")
|
||||
if not self._validate_options():
|
||||
return False
|
||||
|
||||
@@ -176,13 +177,14 @@ class Base(object):
|
||||
Configuration file will be placed in new directory, therefore it is
|
||||
needed to calculate new paths so that emulator can find assets.
|
||||
"""
|
||||
options = ['wrapper_archive', 'accelerator_rom', 'base_dir',
|
||||
'cdrom_drive_0', 'cdroms_dir', 'controllers_dir',
|
||||
'cpuboard_flash_ext_file', 'cpuboard_flash_file',
|
||||
'floppies_dir', 'floppy_overlays_dir', 'fmv_rom',
|
||||
'graphics_card_rom', 'hard_drives_dir', 'kickstart_file',
|
||||
'kickstarts_dir', 'logs_dir', 'save_states_dir',
|
||||
'screenshots_output_dir']
|
||||
logging.debug("_normalize_options")
|
||||
options = ['wrapper_archive', 'wrapper_whdload_base',
|
||||
'accelerator_rom', 'base_dir', 'cdrom_drive_0',
|
||||
'cdroms_dir', 'controllers_dir', 'cpuboard_flash_ext_file',
|
||||
'cpuboard_flash_file', 'floppies_dir',
|
||||
'floppy_overlays_dir', 'fmv_rom', 'graphics_card_rom',
|
||||
'hard_drives_dir', 'kickstart_file', 'kickstarts_dir',
|
||||
'logs_dir', 'save_states_dir', 'screenshots_output_dir']
|
||||
|
||||
for num in range(20):
|
||||
options.append('cdrom_image_%d' % num)
|
||||
@@ -217,6 +219,7 @@ class Base(object):
|
||||
if val.startswith('$CONFIG'):
|
||||
abspath = utils.interpolate_variables(val, self.conf_file)
|
||||
changed_options[key] = abspath
|
||||
logging.info("%s: %s => %s", key, val, abspath)
|
||||
continue
|
||||
|
||||
_val = os.path.abspath(val)
|
||||
@@ -282,6 +285,7 @@ class ArchiveBase(Base):
|
||||
|
||||
def _extract(self):
|
||||
"""Extract archive to temp dir"""
|
||||
logging.debug("_extract")
|
||||
|
||||
title = self._get_title()
|
||||
curdir = os.path.abspath('.')
|
||||
@@ -291,8 +295,11 @@ class ArchiveBase(Base):
|
||||
return result
|
||||
|
||||
def _validate_options(self):
|
||||
logging.debug("_validate_options")
|
||||
|
||||
validation_result = super(ArchiveBase, self)._validate_options()
|
||||
if not validation_result:
|
||||
return False
|
||||
|
||||
if 'wrapper_archive' not in self.all_options:
|
||||
logging.warning("Configuration lacks of optional `wrapper_archive'"
|
||||
@@ -312,8 +319,8 @@ class ArchiveBase(Base):
|
||||
Return full path to the archive name using configuration file
|
||||
basename and appending one of the expected archive extensions.
|
||||
"""
|
||||
basename = os.path.splitext(self.conf_file)[0]
|
||||
file_list = os.listdir('.')
|
||||
basename = os.path.splitext(os.path.basename(self.conf_file))[0]
|
||||
file_list = os.listdir(os.path.dirname(self.conf_file))
|
||||
for fname in file_list:
|
||||
for ext in ('.7z', '.lha', '.lzx', '.zip', '.rar', '.tar', '.tgz',
|
||||
'.tar.gz', '.tar.bz2', '.tar.xz'):
|
||||
@@ -321,4 +328,3 @@ class ArchiveBase(Base):
|
||||
basename == os.path.splitext(fname)[0]):
|
||||
return fname
|
||||
return None
|
||||
|
||||
|
||||
@@ -3,19 +3,15 @@ Display message in separate process
|
||||
"""
|
||||
import multiprocessing as mp
|
||||
import sys
|
||||
try:
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
except ImportError:
|
||||
import Tkinter as tk
|
||||
import ttk
|
||||
import tkinter
|
||||
import tkinter.ttk
|
||||
|
||||
|
||||
class MessageGui(tk.Tk):
|
||||
class MessageGui(tkinter.Tk):
|
||||
"""Simple gui for displaying a message"""
|
||||
|
||||
def __init__(self, parent=None, msg=""):
|
||||
tk.Tk.__init__(self, parent)
|
||||
tkinter.Tk.__init__(self, parent)
|
||||
|
||||
self.grid()
|
||||
self.resizable(False, False)
|
||||
@@ -26,10 +22,11 @@ class MessageGui(tk.Tk):
|
||||
|
||||
self.frame = ttk.Frame(self, padding=5, borderwidth=0)
|
||||
self.frame.grid()
|
||||
ttk.Label(self.frame, text=msg, relief="ridge", padding=10).grid()
|
||||
tkinter.ttk.Label(self.frame, text=msg, relief="ridge",
|
||||
padding=10).grid()
|
||||
|
||||
if 'linux' in sys.platform:
|
||||
style = ttk.Style()
|
||||
style = tkinter.ttk.Style()
|
||||
style.theme_use('clam')
|
||||
|
||||
def __call__(self):
|
||||
|
||||
115
fs_uae_wrapper/whdload.py
Normal file
115
fs_uae_wrapper/whdload.py
Normal file
@@ -0,0 +1,115 @@
|
||||
"""
|
||||
Run fs-uae with WHDLoad games
|
||||
|
||||
It will use compressed base image and compressed directories.
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from fs_uae_wrapper import base
|
||||
from fs_uae_wrapper import utils
|
||||
|
||||
|
||||
class Wrapper(base.ArchiveBase):
|
||||
"""
|
||||
Class for performing extracting archive, copying emulator files, and
|
||||
cleaning it back again
|
||||
"""
|
||||
def __init__(self, conf_file, fsuae_options, configuration):
|
||||
super(Wrapper, self).__init__(conf_file, fsuae_options, configuration)
|
||||
self.archive_type = None
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
Main function which accepts configuration file for FS-UAE
|
||||
It will do as follows:
|
||||
- extract base image and archive file
|
||||
- copy configuration
|
||||
- run the emulation
|
||||
"""
|
||||
logging.debug("run")
|
||||
if not super().run():
|
||||
return False
|
||||
|
||||
if not self._extract():
|
||||
return False
|
||||
|
||||
if not self._copy_conf():
|
||||
return False
|
||||
|
||||
return self._run_emulator()
|
||||
|
||||
def _validate_options(self):
|
||||
"""
|
||||
Do the validation for the options, additionally check if there is
|
||||
mandatory WHDLoad base OS images set.
|
||||
"""
|
||||
if not super()._validate_options():
|
||||
return False
|
||||
|
||||
if not self.all_options.get('wrapper_whdload_base'):
|
||||
logging.error("wrapper_whdload_base is not set in configuration, "
|
||||
"exiting.")
|
||||
return False
|
||||
return True
|
||||
|
||||
def _extract(self):
|
||||
"""Extract base image and then WHDLoad archive"""
|
||||
base_image = self.fsuae_options['wrapper_whdload_base']
|
||||
if not os.path.exists(base_image):
|
||||
logging.error("Base image `%s` does't exists in provided "
|
||||
"location.", base_image)
|
||||
return False
|
||||
|
||||
title = self._get_title()
|
||||
curdir = os.path.abspath('.')
|
||||
os.chdir(self.dir)
|
||||
result = utils.extract_archive(base_image)
|
||||
os.chdir(curdir)
|
||||
if not result:
|
||||
return False
|
||||
|
||||
if not super()._extract():
|
||||
return False
|
||||
|
||||
return self._find_slave()
|
||||
|
||||
def _find_slave(self):
|
||||
"""Find Slave file and create apropriate entry in S:whdload-startup"""
|
||||
curdir = os.path.abspath('.')
|
||||
os.chdir(self.dir)
|
||||
|
||||
# find slave name
|
||||
slave_fname = None
|
||||
slave_path = None
|
||||
|
||||
for root, dirs, fnames in os.walk('.'):
|
||||
for fname in fnames:
|
||||
if fname.lower().endswith('.slave'):
|
||||
slave_path, slave_fname = os.path.normpath(root), fname
|
||||
break
|
||||
if slave_fname is None:
|
||||
logging.error("Cannot find .slave file in archive.")
|
||||
return False
|
||||
|
||||
# find corresponfing info (an icon) fname
|
||||
icon_fname = None
|
||||
for fname in os.listdir(slave_path):
|
||||
if (fname.lower().endswith('.info') and
|
||||
os.path.splitext(slave_fname)[0].lower() ==
|
||||
os.path.splitext(fname)[0].lower()):
|
||||
icon_fname = fname
|
||||
break
|
||||
if icon_fname is None:
|
||||
logging.error("Cannot find .info file corresponding to %s in "
|
||||
"archive.", slave_fname)
|
||||
return False
|
||||
|
||||
# Write startup file
|
||||
with open("S/whdload-startup", "w") as fobj:
|
||||
fobj.write(f"cd {slave_path}\n")
|
||||
fobj.write(f"C:kgiconload {icon_fname}\n")
|
||||
|
||||
os.chdir(curdir)
|
||||
return True
|
||||
@@ -27,7 +27,8 @@ def setup_logger(options):
|
||||
level = logging.DEBUG
|
||||
|
||||
logging.basicConfig(level=level,
|
||||
format="%(asctime)s %(levelname)s: %(message)s")
|
||||
format="%(asctime)s %(levelname)s\t%(filename)s:"
|
||||
"%(lineno)d:\t\t%(message)s")
|
||||
|
||||
|
||||
def parse_args():
|
||||
|
||||
@@ -10,7 +10,7 @@ description = "Automate archives support and state saves for fs-uae"
|
||||
readme = "README.rst"
|
||||
requires-python = ">=3.8"
|
||||
keywords = ["uae", "fs-uae", "amiga", "emulator", "wrapper"]
|
||||
version = "0.9.1"
|
||||
version = "0.10.0"
|
||||
classifiers = [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Environment :: Console",
|
||||
|
||||
@@ -2,11 +2,7 @@ import os
|
||||
import shutil
|
||||
from tempfile import mkdtemp
|
||||
from unittest import TestCase
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
from unittest import mock
|
||||
|
||||
from fs_uae_wrapper import archive
|
||||
from fs_uae_wrapper import utils
|
||||
@@ -26,23 +22,26 @@ class TestArchive(TestCase):
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._get_wrapper_archive_name')
|
||||
@mock.patch('fs_uae_wrapper.path.which')
|
||||
def test_validate_options(self, which):
|
||||
def test_validate_options(self, which, get_wrapper_arch_name):
|
||||
which.return_value = 'unrar'
|
||||
|
||||
arch = archive.Wrapper('Config.fs-uae', utils.CmdOption(), {})
|
||||
self.assertFalse(arch._validate_options())
|
||||
arch.all_options = {'wrapper': 'archive'}
|
||||
|
||||
arch.all_options['wrapper'] = 'archive'
|
||||
get_wrapper_arch_name.return_value = None
|
||||
arch.all_options = {'wrapper': 'archive'}
|
||||
self.assertFalse(arch._validate_options())
|
||||
|
||||
get_wrapper_arch_name.return_value = 'fake_arch_filename'
|
||||
arch.all_options['wrapper_archive'] = 'rar'
|
||||
self.assertTrue(arch._validate_options())
|
||||
|
||||
@mock.patch('tempfile.mkdtemp')
|
||||
@mock.patch('fs_uae_wrapper.path.which')
|
||||
@mock.patch('fs_uae_wrapper.archive.Wrapper._make_archive')
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._get_wrapper_archive_name')
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._save_save')
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._get_saves_dir')
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._run_emulator')
|
||||
@@ -50,7 +49,8 @@ class TestArchive(TestCase):
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._load_save')
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._extract')
|
||||
def test_run(self, extract, load_save, copy_conf, run_emulator,
|
||||
get_save_dir, save_state, make_arch, which, mkdtemp):
|
||||
get_save_dir, save_state, get_wrapper_arch_name, make_arch,
|
||||
which, mkdtemp):
|
||||
|
||||
extract.return_value = False
|
||||
load_save.return_value = False
|
||||
@@ -58,6 +58,7 @@ class TestArchive(TestCase):
|
||||
run_emulator.return_value = False
|
||||
get_save_dir.return_value = False
|
||||
save_state.return_value = False
|
||||
get_wrapper_arch_name.return_value = "fake_arch_filename"
|
||||
make_arch.return_value = False
|
||||
which.return_value = 'rar'
|
||||
|
||||
|
||||
@@ -3,11 +3,7 @@ import sys
|
||||
import shutil
|
||||
from tempfile import mkstemp, mkdtemp
|
||||
from unittest import TestCase
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
from unittest import mock
|
||||
|
||||
from fs_uae_wrapper import base
|
||||
from fs_uae_wrapper import utils
|
||||
@@ -94,6 +90,11 @@ class TestBase(TestCase):
|
||||
bobj._normalize_options()
|
||||
self.assertDictEqual(bobj.fsuae_options, {})
|
||||
|
||||
get_config.return_value = {'random_item': 10}
|
||||
bobj.fsuae_options = utils.CmdOption()
|
||||
bobj._normalize_options()
|
||||
self.assertDictEqual(bobj.fsuae_options, {})
|
||||
|
||||
@mock.patch('os.path.exists')
|
||||
@mock.patch('fs_uae_wrapper.utils.get_config')
|
||||
def test_normalize_options_path_not_exists(self, get_config, os_exists):
|
||||
@@ -390,16 +391,42 @@ class TestArchiveBase(TestCase):
|
||||
self.assertFalse(bobj._extract())
|
||||
utils_extract.assert_called_once_with(self.fname, '')
|
||||
|
||||
def test_validate_options(self):
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._get_wrapper_archive_name')
|
||||
def test_validate_options(self, get_wrapper_arch_name):
|
||||
|
||||
bobj = base.ArchiveBase('Config.fs-uae', utils.CmdOption(), {})
|
||||
bobj.all_options = {}
|
||||
|
||||
self.assertFalse(bobj._validate_options())
|
||||
|
||||
get_wrapper_arch_name.return_value = None
|
||||
bobj.all_options = {'wrapper': 'dummy'}
|
||||
self.assertFalse(bobj._validate_options())
|
||||
|
||||
bobj.all_options = {'wrapper': 'dummy',
|
||||
'wrapper_archive': 'myarchive.7z'}
|
||||
self.assertTrue(bobj._validate_options())
|
||||
|
||||
@mock.patch('os.listdir')
|
||||
def test_get_wrapper_archive_name(self, os_listdir):
|
||||
os_listdir.return_value = 'no archive among other files'.split()
|
||||
bobj = base.ArchiveBase('Config.fs-uae', utils.CmdOption(), {})
|
||||
bobj.all_options = {'wrapper': 'dummy'}
|
||||
self.assertIsNone(bobj._get_wrapper_archive_name())
|
||||
|
||||
os_listdir.return_value = 'no config.rar among other files'.split()
|
||||
bobj = base.ArchiveBase('Config.fs-uae', utils.CmdOption(), {})
|
||||
bobj.all_options = {'wrapper': 'dummy'}
|
||||
self.assertIsNone(bobj._get_wrapper_archive_name())
|
||||
|
||||
os_listdir.return_value = 'file Config.TAR among other files'.split()
|
||||
bobj = base.ArchiveBase('Config.fs-uae', utils.CmdOption(), {})
|
||||
bobj.all_options = {'wrapper': 'dummy'}
|
||||
self.assertEqual(bobj._get_wrapper_archive_name(), 'Config.TAR')
|
||||
|
||||
os_listdir.return_value = 'Config.lha FooBar_1.24b_20202.7z'.split()
|
||||
bobj = base.ArchiveBase('FooBar_1.24b_20202.fs-uae',
|
||||
utils.CmdOption(), {})
|
||||
bobj.all_options = {'wrapper': 'dummy'}
|
||||
self.assertEqual(bobj._get_wrapper_archive_name(),
|
||||
'FooBar_1.24b_20202.7z')
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
from unittest import TestCase
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
from unittest import mock
|
||||
|
||||
from fs_uae_wrapper import cd32
|
||||
from fs_uae_wrapper import utils
|
||||
@@ -13,6 +9,7 @@ class TestCD32(TestCase):
|
||||
|
||||
@mock.patch('tempfile.mkdtemp')
|
||||
@mock.patch('fs_uae_wrapper.path.which')
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._get_wrapper_archive_name')
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._save_save')
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._get_saves_dir')
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._run_emulator')
|
||||
@@ -20,7 +17,8 @@ class TestCD32(TestCase):
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._load_save')
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._extract')
|
||||
def test_run(self, extract, load_save, copy_conf, run_emulator,
|
||||
get_save_dir, save_state, which, mkdtemp):
|
||||
get_save_dir, save_state, get_wrapper_arch_name, which,
|
||||
mkdtemp):
|
||||
|
||||
extract.return_value = False
|
||||
copy_conf.return_value = False
|
||||
@@ -28,6 +26,7 @@ class TestCD32(TestCase):
|
||||
run_emulator.return_value = False
|
||||
get_save_dir.return_value = False
|
||||
save_state.return_value = False
|
||||
get_wrapper_arch_name.return_value = "fake_arch_filename"
|
||||
which.return_value = 'unrar'
|
||||
|
||||
acd32 = cd32.Wrapper('Config.fs-uae', utils.CmdOption(), {})
|
||||
|
||||
@@ -2,11 +2,7 @@ import os
|
||||
import shutil
|
||||
from tempfile import mkdtemp
|
||||
from unittest import TestCase
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
from unittest import mock
|
||||
|
||||
from fs_uae_wrapper import file_archive
|
||||
|
||||
|
||||
@@ -1,20 +1,12 @@
|
||||
from unittest import TestCase
|
||||
import os
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
from unittest import mock
|
||||
|
||||
from fs_uae_wrapper import message
|
||||
|
||||
if os.environ.get('DISPLAY'):
|
||||
try:
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
except ImportError:
|
||||
import Tkinter as tk
|
||||
import ttk
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
|
||||
|
||||
class TestMessage(TestCase):
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
from unittest import TestCase
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
from unittest import mock
|
||||
|
||||
from fs_uae_wrapper import plain
|
||||
from fs_uae_wrapper import utils
|
||||
|
||||
@@ -2,11 +2,7 @@ import os
|
||||
import shutil
|
||||
from tempfile import mkdtemp
|
||||
from unittest import TestCase
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
from unittest import mock
|
||||
|
||||
from fs_uae_wrapper import savestate
|
||||
from fs_uae_wrapper import utils
|
||||
|
||||
@@ -3,11 +3,7 @@ import sys
|
||||
from tempfile import mkstemp, mkdtemp
|
||||
from unittest import TestCase
|
||||
import shutil
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
from unittest import mock
|
||||
|
||||
from fs_uae_wrapper import utils
|
||||
|
||||
|
||||
192
tests/test_whdload.py
Normal file
192
tests/test_whdload.py
Normal file
@@ -0,0 +1,192 @@
|
||||
import os
|
||||
import shutil
|
||||
from tempfile import mkdtemp
|
||||
from unittest import TestCase
|
||||
from unittest import mock
|
||||
|
||||
from fs_uae_wrapper import whdload
|
||||
from fs_uae_wrapper import utils
|
||||
|
||||
|
||||
class TestWHDLoad(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.dirname = mkdtemp()
|
||||
self.curdir = os.path.abspath(os.curdir)
|
||||
os.chdir(self.dirname)
|
||||
|
||||
def tearDown(self):
|
||||
os.chdir(self.curdir)
|
||||
try:
|
||||
shutil.rmtree(self.dirname)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._validate_options')
|
||||
def test_validate_options_arch_validation_fail(self, base_valid):
|
||||
|
||||
base_valid.return_value = False
|
||||
wrapper = whdload.Wrapper('Config.fs-uae', utils.CmdOption(), {})
|
||||
self.assertFalse(wrapper._validate_options())
|
||||
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._validate_options')
|
||||
def test_validate_options_no_base_image(self, base_valid):
|
||||
|
||||
base_valid.return_value = True
|
||||
wrapper = whdload.Wrapper('Config.fs-uae', utils.CmdOption(), {})
|
||||
self.assertFalse(wrapper._validate_options())
|
||||
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._validate_options')
|
||||
def test_validate_options_with_base_image_set(self, base_valid):
|
||||
|
||||
base_valid.return_value = True
|
||||
wrapper = whdload.Wrapper('Config.fs-uae', utils.CmdOption(), {})
|
||||
wrapper.all_options['wrapper_whdload_base'] = 'fake_base_fname.7z'
|
||||
self.assertTrue(wrapper._validate_options())
|
||||
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase.run')
|
||||
def test_run_base_run_fail(self, run):
|
||||
|
||||
run.return_value = False
|
||||
wrapper = whdload.Wrapper('Config.fs-uae', utils.CmdOption(), {})
|
||||
self.assertFalse(wrapper.run())
|
||||
|
||||
@mock.patch('fs_uae_wrapper.whdload.Wrapper._extract')
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase.run')
|
||||
def test_run_extract_fail(self, run, extract):
|
||||
|
||||
run.return_value = True
|
||||
extract.return_value = False
|
||||
wrapper = whdload.Wrapper('Config.fs-uae', utils.CmdOption(), {})
|
||||
wrapper.all_options = {'wrapper': 'whdload',
|
||||
'wrapper_archive': 'fake.tgz',
|
||||
'wrapper_archiver': 'rar'}
|
||||
self.assertFalse(wrapper.run())
|
||||
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._copy_conf')
|
||||
@mock.patch('fs_uae_wrapper.whdload.Wrapper._extract')
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase.run')
|
||||
def test_run_copy_conf_fail(self, run, extract, copy_conf):
|
||||
|
||||
run.return_value = True
|
||||
extract.return_value = True
|
||||
copy_conf.return_value = False
|
||||
wrapper = whdload.Wrapper('Config.fs-uae', utils.CmdOption(), {})
|
||||
self.assertFalse(wrapper.run())
|
||||
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._run_emulator')
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._copy_conf')
|
||||
@mock.patch('fs_uae_wrapper.whdload.Wrapper._extract')
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase.run')
|
||||
def test_run_emulator_fail(self, run, extract, copy_conf, run_emulator):
|
||||
|
||||
run.return_value = True
|
||||
extract.return_value = True
|
||||
copy_conf.return_value = True
|
||||
run_emulator.return_value = False
|
||||
wrapper = whdload.Wrapper('Config.fs-uae', utils.CmdOption(), {})
|
||||
self.assertFalse(wrapper.run())
|
||||
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._run_emulator')
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._copy_conf')
|
||||
@mock.patch('fs_uae_wrapper.whdload.Wrapper._extract')
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase.run')
|
||||
def test_run_success(self, run, extract, copy_conf, run_emulator):
|
||||
|
||||
run.return_value = True
|
||||
extract.return_value = True
|
||||
copy_conf.return_value = True
|
||||
run_emulator.return_value = True
|
||||
wrapper = whdload.Wrapper('Config.fs-uae', utils.CmdOption(), {})
|
||||
self.assertTrue(wrapper.run())
|
||||
|
||||
@mock.patch('os.path.exists')
|
||||
def test_extract_nonexistent_image(self, exists):
|
||||
exists.return_value = False
|
||||
wrapper = whdload.Wrapper('Config.fs-uae', utils.CmdOption(), {})
|
||||
wrapper.fsuae_options['wrapper_whdload_base'] = 'fakefilename'
|
||||
self.assertFalse(wrapper._extract())
|
||||
|
||||
@mock.patch('os.chdir')
|
||||
@mock.patch('os.path.exists')
|
||||
def test_extract_extraction_failed(self, exists, chdir):
|
||||
exists.return_value = True
|
||||
wrapper = whdload.Wrapper('Config.fs-uae', utils.CmdOption(), {})
|
||||
wrapper.fsuae_options['wrapper_whdload_base'] = 'fakefilename.7z'
|
||||
self.assertFalse(wrapper._extract())
|
||||
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._extract')
|
||||
@mock.patch('fs_uae_wrapper.utils.extract_archive')
|
||||
@mock.patch('os.chdir')
|
||||
@mock.patch('os.path.exists')
|
||||
def test_extract_extraction_of_whdload_arch_failed(self, exists, chdir,
|
||||
image_extract,
|
||||
arch_extract):
|
||||
exists.return_value = True
|
||||
image_extract.return_value = True
|
||||
arch_extract.return_value = False
|
||||
wrapper = whdload.Wrapper('Config.fs-uae', utils.CmdOption(), {})
|
||||
wrapper.fsuae_options['wrapper_whdload_base'] = 'fakefilename'
|
||||
self.assertFalse(wrapper._extract())
|
||||
|
||||
@mock.patch('fs_uae_wrapper.whdload.Wrapper._find_slave')
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._extract')
|
||||
@mock.patch('fs_uae_wrapper.utils.extract_archive')
|
||||
@mock.patch('os.chdir')
|
||||
@mock.patch('os.path.exists')
|
||||
def test_extract_slave_not_found(self, exists, chdir, image_extract,
|
||||
arch_extract, find_slave):
|
||||
exists.return_value = True
|
||||
image_extract.return_value = True
|
||||
arch_extract.return_value = True
|
||||
find_slave.return_value = False
|
||||
wrapper = whdload.Wrapper('Config.fs-uae', utils.CmdOption(), {})
|
||||
wrapper.fsuae_options['wrapper_whdload_base'] = 'fakefilename'
|
||||
self.assertFalse(wrapper._extract())
|
||||
|
||||
@mock.patch('fs_uae_wrapper.whdload.Wrapper._find_slave')
|
||||
@mock.patch('fs_uae_wrapper.base.ArchiveBase._extract')
|
||||
@mock.patch('fs_uae_wrapper.utils.extract_archive')
|
||||
@mock.patch('os.chdir')
|
||||
@mock.patch('os.path.exists')
|
||||
def test_extract_success(self, exists, chdir, image_extract, arch_extract,
|
||||
find_slave):
|
||||
exists.return_value = True
|
||||
image_extract.return_value = True
|
||||
arch_extract.return_value = True
|
||||
find_slave.return_value = True
|
||||
wrapper = whdload.Wrapper('Config.fs-uae', utils.CmdOption(), {})
|
||||
wrapper.fsuae_options['wrapper_whdload_base'] = 'fakefilename'
|
||||
self.assertTrue(wrapper._extract())
|
||||
|
||||
@mock.patch('os.walk')
|
||||
@mock.patch('os.chdir')
|
||||
def test_find_slave_no_slave_file(self, chdir, walk):
|
||||
walk.return_value = [(".", ('game'), ()),
|
||||
('./game', (), ('foo', 'bar', 'baz'))]
|
||||
wrapper = whdload.Wrapper('Config.fs-uae', utils.CmdOption(), {})
|
||||
self.assertFalse(wrapper._find_slave())
|
||||
|
||||
@mock.patch('os.listdir')
|
||||
@mock.patch('os.walk')
|
||||
@mock.patch('os.chdir')
|
||||
def test_find_slave_no_corresponding_icon(self, chdir, walk, listdir):
|
||||
contents = ('foo', 'bar', 'baz.slave')
|
||||
walk.return_value = [(".", ('game'), ()),
|
||||
('./game', (), contents)]
|
||||
listdir.return_value = contents
|
||||
wrapper = whdload.Wrapper('Config.fs-uae', utils.CmdOption(), {})
|
||||
self.assertFalse(wrapper._find_slave())
|
||||
|
||||
@mock.patch('builtins.open')
|
||||
@mock.patch('os.listdir')
|
||||
@mock.patch('os.walk')
|
||||
@mock.patch('os.chdir')
|
||||
def test_find_slave_success(self, chdir, walk, listdir, bopen):
|
||||
contents = ('foo', 'bar', 'baz.slave', 'baz.info')
|
||||
walk.return_value = [(".", ('game'), ()),
|
||||
('./game', (), contents)]
|
||||
listdir.return_value = contents
|
||||
wrapper = whdload.Wrapper('Config.fs-uae', utils.CmdOption(), {})
|
||||
self.assertTrue(wrapper._find_slave())
|
||||
bopen.assert_called_once()
|
||||
@@ -3,11 +3,7 @@ import sys
|
||||
from tempfile import mkstemp, mkdtemp
|
||||
from unittest import TestCase
|
||||
import shutil
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
from unittest import mock
|
||||
|
||||
from fs_uae_wrapper import wrapper
|
||||
|
||||
|
||||
Reference in New Issue
Block a user