Skip to content
Snippets Groups Projects
Commit b5762ebf authored by Mayr, Hannes's avatar Mayr, Hannes
Browse files

Merge branch 'dev' of git.rwth-aachen.de:plotid/plotid_python into dev

parents 3df7087c ed0e2fea
No related branches found
No related tags found
1 merge request!16Dev
Pipeline #768799 passed
...@@ -43,7 +43,7 @@ plotID has two main functionalities: ...@@ -43,7 +43,7 @@ plotID has two main functionalities:
2. Export the resulting file to a specified directory along the corresponding research data, the plot is based on. Additionally, the script that created the plot will also be copied to the directory. 2. Export the resulting file to a specified directory along the corresponding research data, the plot is based on. Additionally, the script that created the plot will also be copied to the directory.
### tagplot() ### tagplot()
Tag your figure/plot with an ID. Tag your figure/plot with an ID. It is possible to tag multiple figures at once.
`tagplot(figures, plot_engine)` `tagplot(figures, plot_engine)`
The variable "figures" can be a single figure or a list of multiple figures. The variable "figures" can be a single figure or a list of multiple figures.
The argument "plot_engine" defines which plot engine was used to create the figures. It also determines which plot engine plotID uses to place the ID on the plot. Currently supported plot engines are: The argument "plot_engine" defines which plot engine was used to create the figures. It also determines which plot engine plotID uses to place the ID on the plot. Currently supported plot engines are:
...@@ -69,13 +69,13 @@ FIGS_AS_LIST = [FIG1, FIG2] ...@@ -69,13 +69,13 @@ FIGS_AS_LIST = [FIG1, FIG2]
### publish() ### publish()
Save plot, data and measuring script. Save plot, data and measuring script. It is possible to export multiple figures at once.
`publish(src_datapath, dst_path, figure, plot_name)` `publish(src_datapath, dst_path, figure, plot_name)`
- "src_datapath" specifies the path to (raw) data that should be published. - "src_datapath" specifies the path to (raw) data that should be published. It can be a string or a list of strings that specifies all files and directories which will be published.
- "dst_path" is the path to the destination directory, where all the data should be copied/exported to. - "dst_path" is the path to the destination directory, where all the data should be copied/exported to.
- "figure" expects the figure that was tagged and now should be saved as picture. - "figure" expects the figure or a list of figures that were tagged and now should be saved as pictures.
- "plot_name" will be the file name for the exported plot. - "plot_names" will be the file names for the exported plots. If you give only one plot name but several figures, plotID will name the exported plots with an appended number, e.g. example_fig1.png, example_fig2.png, ...
Optional parameters can be used to customize the publish process. Optional parameters can be used to customize the publish process.
- data_storage: str, optional - data_storage: str, optional
...@@ -96,6 +96,7 @@ If you want to build plotID yourself, follow these steps: ...@@ -96,6 +96,7 @@ If you want to build plotID yourself, follow these steps:
4. Build the package 4. Build the package
`python3 -m build` `python3 -m build`
## Documentation ## Documentation
If you have more questions about plotID, please have a look at the [documentation](link-to-docs). If you have more questions about plotID, please have a look at the [documentation](link-to-docs).
Also have a look at the example.py that is shipped with plotID. Also have a look at the example.py that is shipped with plotID.
...@@ -47,12 +47,14 @@ FIGS_AS_LIST = [FIG1, FIG2] ...@@ -47,12 +47,14 @@ FIGS_AS_LIST = [FIG1, FIG2]
# %% Save figure as tiff-file, but publish also exports the plot to a picture # %% Save figure as tiff-file, but publish also exports the plot to a picture
# file in the destination folder. # file in the destination folder.
for i, figure in enumerate(TAGGED_FIGS): # for i, figure in enumerate(TAGGED_FIGS):
NAME = "Test"+str(i)+".tiff" # NAME = "Test"+str(i)+".tiff"
figure.savefig(NAME) # figure.savefig(NAME)
# %% Publish # %% Publish
# Arguments: Source directory, destination directory, figure, plot name, # Arguments: Source directory, destination directory, figure, plot name,
# publish-mode). # publish-mode).
publish('../../tests', '/home/chief/Dokumente/fst/plotid_python/data',
FIG1, 'Bild', 'individual') publish(['../README.md', '../tests', '../LICENSE'],
'/home/chief/Dokumente/fst/plotid_python/data',
FIGS_AS_LIST, 'Bild', 'individual')
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Contains the PlotOption class.""" """Contains the PlotOptions and PublishOptions class."""
class PlotOptions: class PlotOptions:
...@@ -18,7 +18,7 @@ class PlotOptions: ...@@ -18,7 +18,7 @@ class PlotOptions:
Figure that will be tagged. Figure that will be tagged.
prefix : str prefix : str
Prefix that is placed before the ID. Prefix that is placed before the ID.
id_method : int id_method : str
Method that decides which method is used to generate the ID. Method that decides which method is used to generate the ID.
rotation : int rotation : int
Rotation angle for the ID. Rotation angle for the ID.
...@@ -49,7 +49,6 @@ class PlotOptions: ...@@ -49,7 +49,6 @@ class PlotOptions:
0, if all checks succeed. 0, if all checks succeed.
""" """
# %% Validate inputs
# Input validation for figs is done in submodules tagplot_$engine.py # Input validation for figs is done in submodules tagplot_$engine.py
if isinstance(self.prefix, str): if isinstance(self.prefix, str):
pass pass
......
...@@ -8,7 +8,7 @@ the plot is based on. Additionally, the script that produced the plot will be ...@@ -8,7 +8,7 @@ the plot is based on. Additionally, the script that produced the plot will be
copied to the destination directory. copied to the destination directory.
Functions: Functions:
publish(path-like, path-like, figure, string, string) -> None publish(str, str, figure, str, str) -> None
""" """
import os import os
...@@ -18,92 +18,229 @@ import warnings ...@@ -18,92 +18,229 @@ import warnings
from plotid.save_plot import save_plot from plotid.save_plot import save_plot
def publish(src_datapath, dst_path, figure, plot_name, class PublishOptions:
data_storage='individual'):
""" """
Save plot, data and measuring script. Container objects which include all publish options provided by plotid.
Parameters Methods
-------
__init__
validate_input: Check if input is correct type.
Attributes
---------- ----------
src_datapath : string src_datapaths : str or list of str
Path to data that should be published. Path(s) to data that should be published.
dst_path : string dst_path : str
Path to the destination directory. Path to the destination directory.
figure : figure object figure : figure object
Figure that was tagged and now should be saved as picture. Figure that was tagged and now should be saved as picture.
plot_name: string plot_name : str
Name for the exported plot. Name for the exported plot.
data_storage: string data_storage : str
Method how the data should be stored. Available options: Method how the data should be stored. Available options:
centralized: The raw data will copied only once. All other plots centralized : The data files will copied only once. All other plots
will reference this data via sym link. will reference this data via sym link.
individual: The complete raw data will be copied to a folder for individual [default]: The complete data files will be copied to a
every plot, respectively. This is the default value. separate folder for every plot.
"""
def __init__(self, src_datapaths, dst_path, figure, plot_names,
data_storage):
self.src_datapaths = src_datapaths
self.dst_path = dst_path
self.figure = figure
self.plot_names = plot_names
self.data_storage = data_storage
self.dst_path_head, self.dst_dirname = os.path.split(self.dst_path)
def validate_input(self):
"""
Validate if input for PublishOptions is correct type.
Raises
------
FileNotFoundError
If the path to the source or the destination directory does not
exist.
TypeError
If input data is of wrong type.
Returns Returns
------- -------
None. None.
""" """
# Check if source directory exists if isinstance(self.src_datapaths, str):
if not os.path.exists(src_datapath): self.src_datapaths = [self.src_datapaths]
if isinstance(self.src_datapaths, list):
for path in self.src_datapaths:
if not isinstance(path, str):
raise TypeError(f'{path} is not a string.')
# Check if source directory and files exist
if not os.path.exists(path):
raise FileNotFoundError('The specified source directory' raise FileNotFoundError('The specified source directory'
'does not exist.') f'/file {path} does not exist.')
else:
raise TypeError('The source directory/files are neither '
'a string nor a list.')
# Check if destination directory is allowed path # Check if destination directory is allowed path
dst_path_head, dst_dirname = os.path.split(dst_path) if not os.path.exists(self.dst_path_head):
if not os.path.exists(dst_path_head):
raise FileNotFoundError('The specified destination directory ' raise FileNotFoundError('The specified destination directory '
'does not exist.') 'does not exist.')
# If dst dir already exists ask user if it should be overwritten or not. # Check if plot_name is a string or a list of strings
if os.path.isdir(dst_path): if isinstance(self.plot_names, str):
warnings.warn(f'Folder "{dst_dirname}" already exists – ' self.plot_names = [self.plot_names]
if isinstance(self.plot_names, list):
for name in self.plot_names:
if not isinstance(name, str):
raise TypeError('The list of plot_names contains an object'
' which is not a string.')
else:
raise TypeError('The specified plot_names is neither a string nor'
' a list of strings.')
# Check if data_storage is a string
if not isinstance(self.data_storage, str):
raise TypeError('The specified data_storage method is not a '
'string.')
def export(self):
"""
Export the plot and copy specified files to the destiantion folder.
Raises
------
RuntimeError
If user does not want to overwrite existing folder.
ValueError
If non-supported data_storage method is given.
Returns
-------
None.
"""
# Export plot figure to picture.
plot_paths = save_plot(self.figure, self.plot_names)
# If dst dir already exists ask user if it should be overwritten.
if os.path.isdir(self.dst_path):
warnings.warn(f'Folder "{self.dst_dirname}" already exists – '
'plot has already been published.') 'plot has already been published.')
overwrite_dir = input('Do you want to overwrite the existing folder?' overwrite_dir = input('Do you want to overwrite the existing'
' (yes/no[default])\n') ' folder? (yes/no[default])\n')
if overwrite_dir in ('yes', 'y'): if overwrite_dir in ('yes', 'y'):
shutil.rmtree(dst_path) shutil.rmtree(self.dst_path)
else: else:
raise RuntimeError('PlotID has finished without an export.\n' raise RuntimeError('PlotID has finished without an export.\n'
'Rerun TagPlot if you need a new ID or ' 'Rerun TagPlot if you need a new ID or '
'consider overwriting.') 'consider overwriting.')
# Export plot figure to picture.
plot_path = save_plot(figure, plot_name)
# Create invisible folder # Create invisible folder
dst_path_invisible = os.path.join(dst_path_head, '.' + dst_dirname) dst_path_invisible = os.path.join(self.dst_path_head,
# If invisible Folder exists, delete it (publish was not successful before) '.' + self.dst_dirname)
# If invisible Folder exists, delete it
# (publish was not successful before)
if os.path.isdir(dst_path_invisible): if os.path.isdir(dst_path_invisible):
shutil.rmtree(dst_path_invisible) shutil.rmtree(dst_path_invisible)
match data_storage: match self.data_storage:
case 'centralized': case 'centralized':
self.centralized_data_storage()
case 'individual':
self.individual_data_storage(dst_path_invisible, plot_paths)
case _:
raise ValueError('The data storage method {data_storage} '
'is not available.')
# If export was successful, make the directory visible
os.rename(dst_path_invisible, self.dst_path)
print(f'Publish was successful.\nYour plot(s) {plot_paths},\nyour'
f' data {self.src_datapaths}\nand your script {sys.argv[0]}\n'
f'were copied to {self.dst_path}\nin {self.data_storage} mode.')
def centralized_data_storage(self):
"""
Store the data only in one directory and link all others to it.
Returns
-------
None.
"""
# Does nothing, not implemented yet # Does nothing, not implemented yet
pass pass
case 'individual':
def individual_data_storage(self, destination, pic_paths):
"""
Store all the data in an individual directory.
Parameters
----------
destination : path-like
Directory where the data should be stored.
pic_path : path-like
Path to the picture file that will be stored in destination.
Returns
-------
None.
"""
# Copy all files to destination directory # Copy all files to destination directory
print('Copying data has been started. Depending on the size of' print('Copying data has been started. Depending on the size of'
' your data this may take a while...') ' your data this may take a while...')
# Copy data to invisible folder os.makedirs(destination)
shutil.copytree(src_datapath, dst_path_invisible) # Copy data to destination folder
for path in self.src_datapaths:
try:
shutil.copytree(path, destination, dirs_exist_ok=True)
except NotADirectoryError:
shutil.copy2(path, destination)
# Copy script that calls this function to folder # Copy script that calls this function to folder
shutil.copy2(sys.argv[0], dst_path_invisible) shutil.copy2(sys.argv[0], destination)
# Copy plot file to folder # Copy plot files to folder
if os.path.isfile(plot_path): for path in pic_paths:
shutil.copy2(plot_path, dst_path_invisible) if os.path.isfile(path):
os.remove(plot_path) shutil.copy2(path, destination)
case _: os.remove(path)
raise ValueError('The data storage method {data_storage} '
'is not available.')
print('Copying data finished. Starting to clean up.')
# If export was successful, make the directory visible def publish(src_datapath, dst_path, figure, plot_name,
os.rename(dst_path_invisible, dst_path) data_storage='individual'):
print(f'Publish was successful.\nYour plot "{plot_path}",\n' """
f'your data "{src_datapath}"\nand your script "{sys.argv[0]}"\n' Save plot, data and measuring script.
f'were copied to {dst_path}\nin {data_storage} mode.')
Parameters
----------
src_datapath : str
Path to data that should be published.
dst_path : str
Path to the destination directory.
figure : figure object
Figure that was tagged and now should be saved as picture.
plot_name : str
Name for the exported plot.
data_storage : str
Method how the data should be stored. Available options:
centralized : The raw data will copied only once. All other plots
will reference this data via sym link.
individual [default]: The complete raw data will be copied to a
folder for every plot, respectively.
Returns
-------
None.
"""
publish_container = PublishOptions(src_datapath, dst_path, figure,
plot_name, data_storage)
publish_container.validate_input()
publish_container.export()
...@@ -7,33 +7,59 @@ Functions: ...@@ -7,33 +7,59 @@ Functions:
save_plot(figure, string) -> path-like save_plot(figure, string) -> path-like
""" """
import warnings
import matplotlib import matplotlib
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
def save_plot(figure, plot_name, extension='png'): def save_plot(figures, plot_names, extension='png'):
""" """
Export plot. Export plot(s).
Parameters Parameters
---------- ----------
figure : figure object figure : list of/single figure object
Figure that was tagged and now should be saved as picture. Figure that was tagged and now should be saved as picture.
plot_name: Name of the file where the plot will be saved to. plot_name : list of strings
extension: string Names of the files where the plots will be saved to.
extension : str
File extension for the plot export. File extension for the plot export.
Returns Returns
------- -------
plot_path: Name of the created picture. plot_path : list
Names of the created pictures.
""" """
match type(figure): # Check if figs is a valid figure or a list of valid figures
case matplotlib.figure.Figure: if isinstance(figures, matplotlib.figure.Figure):
plt.figure(figure) figures = [figures]
plot_path = plot_name + '.' + extension if isinstance(figures, list):
plt.savefig(plot_path) for fig in figures:
case _: if isinstance(fig, matplotlib.figure.Figure):
raise TypeError('The given figure is not a valid figure object.') pass
else:
raise TypeError('Figures is neither a valid matplotlib-figure nor'
' a list of matplotlib-figures.')
if len(plot_names) < len(figures):
warnings.warn('There are more figures than plot names. The first name'
' will be taken for all plots with an appended number.')
first_name = plot_names[0]
plot_names = [None] * len(figures)
for i, _ in enumerate(plot_names):
plot_names[i] = first_name + f'{i+1}'
elif len(plot_names) > len(figures):
raise IndexError('There are more plot names than figures.')
plot_path = []
# match type(figures):
# case matplotlib.figure.Figure:
for i, fig in enumerate(figures):
plt.figure(fig)
plot_path.append(plot_names[i] + '.' + extension)
plt.savefig(plot_path[i])
# case _:
# raise TypeError('The given figure is not a valid figure object.')
return plot_path return plot_path
...@@ -27,12 +27,13 @@ def tagplot_matplotlib(plotid_object): ...@@ -27,12 +27,13 @@ def tagplot_matplotlib(plotid_object):
# Check if figs is a valid figure or a list of valid figures # Check if figs is a valid figure or a list of valid figures
if isinstance(plotid_object.figs, matplotlib.figure.Figure): if isinstance(plotid_object.figs, matplotlib.figure.Figure):
plotid_object.figs = [plotid_object.figs] plotid_object.figs = [plotid_object.figs]
elif isinstance(plotid_object.figs, list): if isinstance(plotid_object.figs, list):
for figure in plotid_object.figs: for figure in plotid_object.figs:
if isinstance(figure, matplotlib.figure.Figure): if isinstance(figure, matplotlib.figure.Figure):
pass pass
else: else:
raise TypeError('Figure is not a valid matplotlib-figure.') raise TypeError('Figures is neither a valid matplotlib-figure nor'
' a list of matplotlib-figures.')
fontsize = 'small' fontsize = 'small'
color = 'grey' color = 'grey'
......
...@@ -26,7 +26,7 @@ cov.save() ...@@ -26,7 +26,7 @@ cov.save()
if result.wasSuccessful(): if result.wasSuccessful():
covered = cov.report(show_missing=True, precision=2) covered = cov.report(show_missing=True, precision=2)
assert covered > 90, "Not enough coverage." assert covered > 95, "Not enough coverage."
sys.exit(0) sys.exit(0)
else: else:
sys.exit(1) sys.exit(1)
...@@ -14,12 +14,16 @@ from plotid.publish import publish ...@@ -14,12 +14,16 @@ from plotid.publish import publish
SRC_DIR = 'test_src_folder' SRC_DIR = 'test_src_folder'
SRC_FILES = ['test_file1.txt', 'test_file2.jpg', 'test_file3.exe']
PIC_NAME = 'test_picture' PIC_NAME = 'test_picture'
DST_DIR = 'test_dst_folder' DST_DIR = 'test_dst_folder'
DST_PARENT_DIR = 'test_parent' DST_PARENT_DIR = 'test_parent'
DST_PATH = os.path.join(DST_PARENT_DIR, DST_DIR) DST_PATH = os.path.join(DST_PARENT_DIR, DST_DIR)
INVISIBLE_PATH = os.path.join(DST_PARENT_DIR, '.' + DST_DIR) INVISIBLE_PATH = os.path.join(DST_PARENT_DIR, '.' + DST_DIR)
fig = plt.figure() FIG = plt.figure()
FIG2 = plt.figure()
FIGS_AS_LIST = [FIG, FIG2]
PIC_NAME_LIST = [PIC_NAME, 'second_picture']
class TestPublish(unittest.TestCase): class TestPublish(unittest.TestCase):
...@@ -28,9 +32,11 @@ class TestPublish(unittest.TestCase): ...@@ -28,9 +32,11 @@ class TestPublish(unittest.TestCase):
""" """
def setUp(self): def setUp(self):
""" Generate source and destination directory and test image. """ """ Generate source and destination directory and source files. """
os.makedirs(SRC_DIR, exist_ok=True) os.makedirs(SRC_DIR, exist_ok=True)
os.makedirs(DST_PARENT_DIR, exist_ok=True) os.makedirs(DST_PARENT_DIR, exist_ok=True)
for file in SRC_FILES:
open(file, 'w', encoding='utf-8').close()
# Skip test if tests are run from command line. # Skip test if tests are run from command line.
@unittest.skipIf(not os.path.isfile(sys.argv[0]), 'Publish is not called ' @unittest.skipIf(not os.path.isfile(sys.argv[0]), 'Publish is not called '
...@@ -38,20 +44,53 @@ class TestPublish(unittest.TestCase): ...@@ -38,20 +44,53 @@ class TestPublish(unittest.TestCase):
'copied.') 'copied.')
def test_publish(self): def test_publish(self):
""" Test publish and check if an exported picture file exists. """ """ Test publish and check if an exported picture file exists. """
publish(SRC_DIR, DST_PATH, fig, PIC_NAME, 'individual') publish(SRC_DIR, DST_PATH, FIG, PIC_NAME, 'individual')
assert os.path.isfile(os.path.join(DST_PATH, PIC_NAME + '.png')) assert os.path.isfile(os.path.join(DST_PATH, PIC_NAME + '.png'))
# Skip test if tests are run from command line.
@unittest.skipIf(not os.path.isfile(sys.argv[0]), 'Publish is not called '
'from a Python script. Therefore, the script cannot be '
'copied.')
def test_publish_multiple_figs(self):
"""
Test publish with multiple figures and check if all exported picture
files exist.
"""
publish(SRC_DIR, DST_PATH, FIGS_AS_LIST, PIC_NAME_LIST, 'individual')
for name in PIC_NAME_LIST:
assert os.path.isfile(os.path.join(DST_PATH, name + '.png'))
def test_publish_multiple_src_files(self):
"""
Test publish with multiple source files and check
if the exported data files exist.
"""
files_and_dir = list(SRC_FILES)
files_and_dir.append(SRC_DIR)
publish(files_and_dir, DST_PATH, FIGS_AS_LIST, PIC_NAME_LIST,
'individual')
assert os.path.isdir(DST_PATH)
for file in SRC_FILES:
assert os.path.isfile(os.path.join(DST_PATH, file))
def test_src_directory(self): def test_src_directory(self):
""" Test if Error is raised when source directory does not exist.""" """ Test if Error is raised when source directory does not exist."""
with self.assertRaises(FileNotFoundError): with self.assertRaises(FileNotFoundError):
publish('not_existing_folder', DST_PATH, fig, publish('not_existing_folder', DST_PATH, FIG,
PIC_NAME, 'individual') PIC_NAME, 'individual')
def test_src_directory_type(self):
""" Test if Error is raised when source directory is not a string."""
with self.assertRaises(TypeError):
publish([SRC_DIR, 4], DST_PATH, FIG, PIC_NAME, 'individual')
with self.assertRaises(TypeError):
publish(4, DST_PATH, FIG, PIC_NAME, 'individual')
def test_dst_directory(self): def test_dst_directory(self):
""" Test if Error is raised when destination dir does not exist.""" """ Test if Error is raised when destination dir does not exist."""
with self.assertRaises(FileNotFoundError): with self.assertRaises(FileNotFoundError):
publish(SRC_DIR, 'not_existing_folder', publish(SRC_DIR, 'not_existing_folder',
fig, PIC_NAME, 'individual') FIG, PIC_NAME, 'individual')
# Skip test if tests are run from command line. # Skip test if tests are run from command line.
@unittest.skipIf(not os.path.isfile(sys.argv[0]), 'Publish is not called ' @unittest.skipIf(not os.path.isfile(sys.argv[0]), 'Publish is not called '
...@@ -65,7 +104,7 @@ class TestPublish(unittest.TestCase): ...@@ -65,7 +104,7 @@ class TestPublish(unittest.TestCase):
os.mkdir(DST_PATH) os.mkdir(DST_PATH)
# Mock user input as 'yes' # Mock user input as 'yes'
with patch('builtins.input', return_value='yes'): with patch('builtins.input', return_value='yes'):
publish(SRC_DIR, DST_PATH, fig, PIC_NAME, 'individual') publish(SRC_DIR, DST_PATH, FIG, PIC_NAME, 'individual')
# Skip test if tests are run from command line. # Skip test if tests are run from command line.
@unittest.skipIf(not os.path.isfile(sys.argv[0]), 'Publish is not called ' @unittest.skipIf(not os.path.isfile(sys.argv[0]), 'Publish is not called '
...@@ -80,7 +119,7 @@ class TestPublish(unittest.TestCase): ...@@ -80,7 +119,7 @@ class TestPublish(unittest.TestCase):
# Mock user input as 'no' # Mock user input as 'no'
with patch('builtins.input', return_value='no'): with patch('builtins.input', return_value='no'):
with self.assertRaises(RuntimeError): with self.assertRaises(RuntimeError):
publish(SRC_DIR, DST_PATH, fig, PIC_NAME, 'individual') publish(SRC_DIR, DST_PATH, FIG, PIC_NAME, 'individual')
# Skip test if tests are run from command line. # Skip test if tests are run from command line.
@unittest.skipIf(not os.path.isfile(sys.argv[0]), 'Publish is not called ' @unittest.skipIf(not os.path.isfile(sys.argv[0]), 'Publish is not called '
...@@ -95,7 +134,7 @@ class TestPublish(unittest.TestCase): ...@@ -95,7 +134,7 @@ class TestPublish(unittest.TestCase):
# Mock user input as empty (no should be default). # Mock user input as empty (no should be default).
with patch('builtins.input', return_value=''): with patch('builtins.input', return_value=''):
with self.assertRaises(RuntimeError): with self.assertRaises(RuntimeError):
publish(SRC_DIR, DST_PATH, fig, PIC_NAME, 'individual') publish(SRC_DIR, DST_PATH, FIG, PIC_NAME, 'individual')
# Skip test if tests are run from command line. # Skip test if tests are run from command line.
@unittest.skipIf(not os.path.isfile(sys.argv[0]), 'Publish is not called ' @unittest.skipIf(not os.path.isfile(sys.argv[0]), 'Publish is not called '
...@@ -107,19 +146,34 @@ class TestPublish(unittest.TestCase): ...@@ -107,19 +146,34 @@ class TestPublish(unittest.TestCase):
directory from a previous run (delete the folder and proceed). directory from a previous run (delete the folder and proceed).
""" """
os.mkdir(INVISIBLE_PATH) os.mkdir(INVISIBLE_PATH)
publish(SRC_DIR, DST_PATH, fig, PIC_NAME, 'individual') publish(SRC_DIR, DST_PATH, FIG, PIC_NAME, 'individual')
def test_plot_names(self):
""" Test if Error is raised if plot_name is not a string. """
with self.assertRaises(TypeError):
publish(SRC_DIR, DST_PATH, FIG, 7.6, 'individual')
with self.assertRaises(TypeError):
publish(SRC_DIR, DST_PATH, FIG, (), 'individual')
with self.assertRaises(TypeError):
publish(SRC_DIR, DST_PATH, FIG, ['test', 3], 'individual')
def test_data_storage(self): def test_data_storage(self):
""" """
Test if Error is raised when unsupported storage method was chosen. Test if Error is raised when unsupported storage method was chosen.
""" """
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
publish(SRC_DIR, DST_PATH, fig, PIC_NAME, 'none_existing_method') publish(SRC_DIR, DST_PATH, FIG, PIC_NAME, 'none_existing_method')
with self.assertRaises(TypeError):
publish(SRC_DIR, DST_PATH, FIG, PIC_NAME, 3)
with self.assertRaises(TypeError):
publish(SRC_DIR, DST_PATH, FIG, PIC_NAME, [])
def tearDown(self): def tearDown(self):
""" Delete all files created in setUp. """ """ Delete all files created in setUp. """
shutil.rmtree(SRC_DIR) shutil.rmtree(SRC_DIR)
shutil.rmtree(DST_PARENT_DIR) shutil.rmtree(DST_PARENT_DIR)
for file in SRC_FILES:
os.remove(file)
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -20,9 +20,26 @@ class TestSavePlot(unittest.TestCase): ...@@ -20,9 +20,26 @@ class TestSavePlot(unittest.TestCase):
def test_save_plot(self): def test_save_plot(self):
""" Test if save_plot succeeds with valid arguments. """ """ Test if save_plot succeeds with valid arguments. """
save_plot(FIGURE, PLOT_NAME, extension='jpg') plot_paths = save_plot(FIGURE, [PLOT_NAME], extension='jpg')
self.assertIsInstance(plot_paths, list)
os.remove(PLOT_NAME + '.jpg') os.remove(PLOT_NAME + '.jpg')
def test_more_figs_than_names(self):
"""
Test if a warning is raised if more figures than plot names are given.
Additionally, check if files are named correctly.
"""
with self.assertWarns(Warning):
save_plot([FIGURE, FIGURE, FIGURE], [PLOT_NAME])
for i in (1, 2, 3):
assert os.path.isfile(PLOT_NAME + f'{i}.png')
os.remove(PLOT_NAME + f'{i}.png')
def test_more_names_than_figs(self):
""" Test if Error is raised if more names than figures are given. """
with self.assertRaises(IndexError):
save_plot([FIGURE, FIGURE], [PLOT_NAME, PLOT_NAME, PLOT_NAME])
def test_wrong_fig_type(self): def test_wrong_fig_type(self):
""" Test if Error is raised when not a figure object is given. """ """ Test if Error is raised when not a figure object is given. """
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment