Skip to content

Commit

Permalink
#283 refactor PointBrowser tests
Browse files Browse the repository at this point in the history
  • Loading branch information
akorosov committed Mar 13, 2018
1 parent b44df51 commit b238e3c
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 62 deletions.
45 changes: 30 additions & 15 deletions nansat/pointbrowser.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
import numpy as np

try:
if 'DISPLAY' not in os.environ:
import matplotlib; matplotlib.use('Agg')
import matplotlib
if 'DISPLAY' not in os.environ:
matplotlib.use('Agg')
import matplotlib.pyplot as plt
except ImportError:
MATPLOTLIB_IS_INSTALLED = False
Expand All @@ -40,11 +40,13 @@ class PointBrowser():
transect : bool
if True, get transects / points
if False, get only points
force_interactive : bool
force PointBrowser to interactive mode? (True for regular use, False for tests)
**kwargs : dict
optional parameters for imshow
Creates
-------
Note
----
self.fig : pyplot Figure
self.data : ndarray with data
self.ax : axes
Expand All @@ -63,11 +65,11 @@ class PointBrowser():
lines = None
coordinates = None

def __init__(self, data, fmt='x-k', **kwargs):
def __init__(self, data, fmt='x-k', force_interactive=True, **kwargs):
"""Open figure with imshow and colorbar"""
if not MATPLOTLIB_IS_INSTALLED:
raise ImportError(' Matplotlib is not installed ')
if not matplotlib.is_interactive():
if force_interactive and not matplotlib.is_interactive():
raise SystemError('''
Python is started with -pylab option, transect will not work.
Please restart python without -pylab.''')
Expand All @@ -87,7 +89,17 @@ def __init__(self, data, fmt='x-k', **kwargs):
self.coordinates = [[]]

def onclick(self, event):
"""Append onclick event"""
""" Process mouse onclick event
Append coordinates of the click to self.coordinates, add point and 2D line to self.points
If click is outside, nothing is done
If click with 'z' pressed, nothing is done
If click with 'anykey', new line is started
Parameters
----------
event : matplotlib.mouse_event
"""
# ignore click outside image
if event.xdata is None or event.ydata is None:
return
Expand All @@ -108,16 +120,19 @@ def onclick(self, event):
self.ax.figure.canvas.draw()

def _convert_coordinates(self):
''' Converts the coordinates array to points array for return in
""" Converts the coordinates array to points array for return in
get_points, so that the internal structure can be tested
The format of the returned array:
[array([[x1,...,xn],[y1,...,yn]]),array([[xn+1,...],[yn+1,...]]),...]
Each 'array' element is a numpy.ndarray and represents one transect,
where x1,y1 is the first point in the first transect,
and xn,yn the last point in the first transect.
The inner x/y-arrays are also numpy.ndarrays
'''
Returns
-------
list of arrays
The format of the returned array:
[array([[x1,...,xn],[y1,...,yn]]),array([[xn+1,...],[yn+1,...]]),...]
Each 'array' element is a numpy.ndarray and represents one transect,
where x1,y1 is the first point in the first transect,
and xn,yn the last point in the first transect.
The inner x/y-arrays are also numpy.ndarrays
"""
return [np.array(p).T for p in self.coordinates if len(p) > 0]

def get_points(self):
Expand Down
7 changes: 2 additions & 5 deletions nansat/tests/test_domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# http://www.gnu.org/licenses/gpl-3.0.html
#------------------------------------------------------------------------------
import unittest
import os
import os, sys
import numpy as np

try:
Expand All @@ -31,10 +31,7 @@
from nansat.figure import Image
import sys
from nansat.tests import nansat_test_data as ntd
try:
from mock import patch, Mock, MagicMock, PropertyMock, DEFAULT
except:
from unittest.mock import patch, Mock, MagicMock, PropertyMock, DEFAULT
from mock import patch, PropertyMock, Mock, MagicMock, DEFAULT

from nansat.exceptions import NansatProjectionError

Expand Down
2 changes: 1 addition & 1 deletion nansat/tests/test_nansat.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import json
import sys
from xml.sax.saxutils import unescape
from mock import patch, PropertyMock, MagicMock, Mock, DEFAULT
from mock import patch, PropertyMock, Mock, MagicMock, DEFAULT

import numpy as np

Expand Down
113 changes: 76 additions & 37 deletions nansat/tests/test_pointbrowser.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,59 +12,98 @@
# ------------------------------------------------------------------------------
import os
import unittest
from mock import patch, PropertyMock, Mock, MagicMock, DEFAULT

import numpy as np
from nansat.pointbrowser import PointBrowser

try:
if 'DISPLAY' not in os.environ:
import matplotlib; matplotlib.use('Agg')
import matplotlib
import matplotlib.pyplot as plt
plt.switch_backend('qt5agg')
plt.switch_backend('Agg')
except ImportError:
MATPLOTLIB_IS_INSTALLED = False
else:
MATPLOTLIB_IS_INSTALLED = True


class PointBrowserTest(unittest.TestCase):
@unittest.skipUnless(MATPLOTLIB_IS_INSTALLED and 'DISPLAY' in os.environ, 'Matplotlib is required')
@unittest.skipUnless(MATPLOTLIB_IS_INSTALLED, 'Matplotlib is required')
def setUp(self):
plt.switch_backend('qt5agg')
plt.ion()
data = np.ndarray(shape=(4, 4), dtype=float, order='F')
self.point = PointBrowser(data)
self.data = np.zeros((4, 4))
self.event = MagicMock()

def test_init(self):
""" Create Pointbrowser """
pb = PointBrowser(self.data, force_interactive=False)
self.assertIsInstance(pb.fig, plt.Figure)
self.assertTrue(np.alltrue(pb.data == self.data))
self.assertTrue(np.alltrue(pb.ax.get_images()[0].get_array() == self.data))
self.assertEqual(pb.fmt, 'x-k')
self.assertEqual(pb.points, [])
self.assertEqual(pb.coordinates, [[]])

def test_onclick(self):
event = Event(xdata=0, ydata=0, key=None)
self.point.onclick(event)
t = self.point._convert_coordinates()[0]
self.assertIsInstance(t, np.ndarray)
xPoints = t[0]
self.assertIsInstance(xPoints, np.ndarray)
yPoints = t[1]
self.assertIsInstance(yPoints, np.ndarray)
self.assertEqual(xPoints[0], event.xdata, "x coordinates is set wrong")
self.assertEqual(yPoints[0], event.ydata, "y coordinates is set wrong")

def test_onclick_multilines(self):
events = []
events.append(Event(xdata=0, ydata=0, key=None))
events.append(Event(xdata=1, ydata=0, key=None))
events.append(Event(xdata=2, ydata=2, key='AnyKeyButZorAltZ'))
events.append(Event(xdata=2, ydata=3, key=None))
for event in events:
self.point.onclick(event)
points = self.point._convert_coordinates()
self.assertEqual(len(points), 2, 'There should be two transects')
self.assertTrue(np.alltrue(points[0] == np.array([[0, 1], [0, 0]])),
't1 is not correct')
self.assertTrue(np.alltrue(points[1] == np.array([[2, 2], [2, 3]])),
't2 is not correct')

class Event:
def __init__(self, **kwds):
self.__dict__.update(kwds)
""" Mimic click """
self.event = MagicMock()
self.event.xdata = 10
self.event.ydata = 10
self.event.key = None
pb = PointBrowser(self.data, force_interactive=False)

pb.onclick(self.event)
self.assertIsInstance(pb.points[0][0], matplotlib.lines.Line2D)
self.assertEqual(pb.coordinates, [[(self.event.xdata, self.event.ydata)]])

def test_onclick_none(self):
""" Mimic click outside figure """
self.event.xdata = None
self.event.ydata = None
self.event.key = None
pb = PointBrowser(self.data, force_interactive=False)

pb.onclick(self.event)
self.assertEqual(pb.points, [])
self.assertEqual(pb.coordinates, [[]])

def test_onclick_key_z(self):
""" Mimic click with 'z' pressed """
self.event.xdata = 10
self.event.ydata = 10
self.event.key = 'z'
pb = PointBrowser(self.data, force_interactive=False)

pb.onclick(self.event)
self.assertEqual(pb.points, [])
self.assertEqual(pb.coordinates, [[]])

def test_onclick_key(self):
""" Mimic click with 'anykey' pressed """
self.event = MagicMock()
self.event.xdata = 10
self.event.ydata = 10
self.event.key = 'newkey'
pb = PointBrowser(self.data, force_interactive=False)

pb.onclick(self.event)
self.assertIsInstance(pb.points[0][0], matplotlib.lines.Line2D)
self.assertEqual(pb.coordinates, [[],[(self.event.xdata, self.event.ydata)]])

def test_convert_coordinates(self):
""" Mimic click with 'anykey' pressed """
pb = PointBrowser(self.data, force_interactive=False)
pb.coordinates = [[[1,2,3],[4,5,6]]]
new_coordinates = pb._convert_coordinates()
self.assertTrue(np.all(new_coordinates[0] == np.array([[1,2,3], [4,5,6]]).T))

@patch('nansat.pointbrowser.plt')
def test_get_points(self, plt_mock):
plt_mock.show.return_value = None
pb = PointBrowser(self.data, force_interactive=False)
points = pb.get_points()
self.assertTrue(pb.fig.canvas.mpl_connect.called)
self.assertTrue(plt_mock.show.called)
self.assertEqual(points, [])


if __name__ == "__main__":
Expand Down
5 changes: 1 addition & 4 deletions nansat/tests/test_vrt.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@
import logging
import os
import sys
if sys.version_info.major == 2:
from mock import patch, PropertyMock, Mock, MagicMock, DEFAULT
else:
from unittest.mock import patch, PropertyMock, Mock, MagicMock, DEFAULT
from mock import patch, PropertyMock, Mock, MagicMock, DEFAULT

import xml.etree.ElementTree as ET
import warnings
Expand Down

0 comments on commit b238e3c

Please sign in to comment.