Permalink
Browse files

Add tests

1 parent b72823e commit 9681548d9c375f8c71a39e1ef48551a153ab19af @bgilbert bgilbert committed May 25, 2016
View
@@ -2,4 +2,5 @@
/dist
/MANIFEST
/*.egg-info
+/openslide/_convert*.so
*.pyc
View
@@ -1,3 +1,4 @@
include *.txt
recursive-include doc *.py *.rst
recursive-include examples *.html *.js *.png *.py
+recursive-include tests *.png *.py *.tiff
View
@@ -21,6 +21,7 @@
],
),
},
+ test_suite='tests',
maintainer='OpenSlide project',
maintainer_email='openslide-users@lists.andrew.cmu.edu',
description='Python interface to OpenSlide',
View
@@ -0,0 +1,23 @@
+#
+# openslide-python - Python bindings for the OpenSlide library
+#
+# Copyright (c) 2016 Benjamin Gilbert
+#
+# This library is free software; you can redistribute it and/or modify it
+# under the terms of version 2.1 of the GNU Lesser General Public License
+# as published by the Free Software Foundation.
+#
+# This library 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 Lesser General Public
+# License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+import os
+
+def file_path(name):
+ return os.path.join(os.path.dirname(__file__), name)
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
Binary file not shown.
View
@@ -0,0 +1,39 @@
+#
+# openslide-python - Python bindings for the OpenSlide library
+#
+# Copyright (c) 2016 Benjamin Gilbert
+#
+# This library is free software; you can redistribute it and/or modify it
+# under the terms of version 2.1 of the GNU Lesser General Public License
+# as published by the Free Software Foundation.
+#
+# This library 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 Lesser General Public
+# License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+import openslide
+from openslide import open_slide, OpenSlide, ImageSlide
+import sys
+import unittest
+
+from . import file_path
+
+# Tests should be written to be compatible with Python 2.6 unittest.
+
+class TestLibrary(unittest.TestCase):
+ def test_version(self):
+ string = unicode if sys.version[0] == '2' else str
+ self.assertTrue(isinstance(openslide.__version__, string))
+ self.assertTrue(isinstance(openslide.__library_version__, string))
+
+ def test_open_slide(self):
+ self.assertTrue(isinstance(open_slide(file_path('boxes.tiff')),
+ OpenSlide))
+ self.assertTrue(isinstance(open_slide(file_path('boxes.png')),
+ ImageSlide))
View
@@ -0,0 +1,76 @@
+#
+# openslide-python - Python bindings for the OpenSlide library
+#
+# Copyright (c) 2016 Benjamin Gilbert
+#
+# This library is free software; you can redistribute it and/or modify it
+# under the terms of version 2.1 of the GNU Lesser General Public License
+# as published by the Free Software Foundation.
+#
+# This library 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 Lesser General Public
+# License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+from openslide import OpenSlide, ImageSlide
+from openslide.deepzoom import DeepZoomGenerator
+import unittest
+
+from . import file_path
+
+# Tests should be written to be compatible with Python 2.6 unittest.
+
+class _BoxesDeepZoomTest(object):
+ def setUp(self):
+ self.osr = self.CLASS(file_path(self.FILENAME))
+ self.dz = DeepZoomGenerator(self.osr, 254, 1)
+
+ def tearDown(self):
+ self.osr.close()
+
+ def test_metadata(self):
+ self.assertEqual(self.dz.level_count, 10)
+ self.assertEqual(self.dz.tile_count, 11)
+ self.assertEqual(self.dz.level_tiles,
+ ((1, 1), (1, 1), (1, 1), (1, 1), (1, 1),
+ (1, 1), (1, 1), (1, 1), (1, 1), (2, 1)))
+ self.assertEqual(self.dz.level_dimensions,
+ ((1, 1), (2, 1), (3, 2), (5, 4), (10, 8),
+ (19, 16), (38, 32), (75, 63), (150, 125), (300, 250)))
+
+ def test_get_tile(self):
+ self.assertEqual(self.dz.get_tile(9, (1, 0)).size, (47, 250))
+
+ def test_get_tile_bad_level(self):
+ self.assertRaises(ValueError, lambda: self.dz.get_tile(-1, (0, 0)))
+ self.assertRaises(ValueError, lambda: self.dz.get_tile(10, (0, 0)))
+
+ def test_get_tile_bad_address(self):
+ self.assertRaises(ValueError, lambda: self.dz.get_tile(0, (-1, 0)))
+ self.assertRaises(ValueError, lambda: self.dz.get_tile(0, (1, 0)))
+
+ def test_get_tile_coordinates(self):
+ self.assertEqual(self.dz.get_tile_coordinates(9, (1, 0)),
+ ((253, 0), 0, (47, 250)))
+
+ def test_get_tile_dimensions(self):
+ self.assertEqual(self.dz.get_tile_dimensions(9, (1, 0)), (47, 250))
+
+ def test_get_dzi(self):
+ self.assertTrue('http://schemas.microsoft.com/deepzoom/2008' in
+ self.dz.get_dzi('jpeg'))
+
+
+class TestSlideDeepZoom(_BoxesDeepZoomTest, unittest.TestCase):
+ CLASS = OpenSlide
+ FILENAME = 'boxes.tiff'
+
+
+class TestImageDeepZoom(_BoxesDeepZoomTest, unittest.TestCase):
+ CLASS = ImageSlide
+ FILENAME = 'boxes.png'
View
@@ -0,0 +1,102 @@
+#
+# openslide-python - Python bindings for the OpenSlide library
+#
+# Copyright (c) 2016 Benjamin Gilbert
+#
+# This library is free software; you can redistribute it and/or modify it
+# under the terms of version 2.1 of the GNU Lesser General Public License
+# as published by the Free Software Foundation.
+#
+# This library 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 Lesser General Public
+# License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+from openslide import ImageSlide, OpenSlideError
+from PIL import Image
+import unittest
+
+from . import file_path
+
+# Tests should be written to be compatible with Python 2.6 unittest.
+
+class TestImageWithoutOpening(unittest.TestCase):
+ def test_detect_format(self):
+ self.assertTrue(
+ ImageSlide.detect_format(file_path('__missing_file')) is None)
+ self.assertTrue(
+ ImageSlide.detect_format(file_path('../setup.py')) is None)
+ self.assertEqual(
+ ImageSlide.detect_format(file_path('boxes.png')), 'PNG')
+
+ def test_open(self):
+ self.assertRaises(IOError,
+ lambda: ImageSlide(file_path('__does_not_exist')))
+ self.assertRaises(IOError,
+ lambda: ImageSlide(file_path('../setup.py')))
+
+ # passing PIL.Image to ImageSlide
+ self.assertEqual(
+ ImageSlide(Image.open(file_path('boxes.png'))).dimensions,
+ (300, 250))
+
+ def test_operations_on_closed_handle(self):
+ img = Image.open(file_path('boxes.png'))
+ osr = ImageSlide(img)
+ osr.close()
+ self.assertRaises(AttributeError,
+ lambda: osr.read_region((0, 0), 0, (100, 100)))
+ # If an Image is passed to the constructor, ImageSlide.close()
+ # shouldn't close it
+ self.assertEqual(img.getpixel((0, 0)), 3)
+
+ def test_context_manager(self):
+ osr = ImageSlide(file_path('boxes.png'))
+ with osr:
+ pass
+ self.assertRaises(AttributeError,
+ lambda: osr.read_region((0, 0), 0, (100, 100)))
+
+
+class TestImage(unittest.TestCase):
+ def setUp(self):
+ self.osr = ImageSlide(file_path('boxes.png'))
+
+ def tearDown(self):
+ self.osr.close()
+
+ def test_metadata(self):
+ self.assertEqual(self.osr.level_count, 1)
+ self.assertEqual(self.osr.level_dimensions, ((300, 250),))
+ self.assertEqual(self.osr.dimensions, (300, 250))
+ self.assertEqual(self.osr.level_downsamples, (1.0,))
+
+ self.assertEqual(self.osr.get_best_level_for_downsample(0.5), 0)
+ self.assertEqual(self.osr.get_best_level_for_downsample(3), 0)
+
+ self.assertEqual(self.osr.properties, {})
+ self.assertEqual(self.osr.associated_images, {})
+
+ def test_read_region(self):
+ self.assertEqual(self.osr.read_region((-10, -10), 0, (400, 400)).size,
+ (400, 400))
+
+ def test_read_region_size_dimension_zero(self):
+ self.assertEqual(self.osr.read_region((0, 0), 0, (400, 0)).size,
+ (400, 0))
+
+ def test_read_region_bad_level(self):
+ self.assertRaises(OpenSlideError,
+ lambda: self.osr.read_region((0, 0), 1, (100, 100)))
+
+ def test_read_region_bad_size(self):
+ self.assertRaises(OpenSlideError,
+ lambda: self.osr.read_region((0, 0), 0, (400, -5)))
+
+ def test_thumbnail(self):
+ self.assertEqual(self.osr.get_thumbnail((100, 100)).size, (100, 83))
View
@@ -0,0 +1,121 @@
+#
+# openslide-python - Python bindings for the OpenSlide library
+#
+# Copyright (c) 2016 Benjamin Gilbert
+#
+# This library is free software; you can redistribute it and/or modify it
+# under the terms of version 2.1 of the GNU Lesser General Public License
+# as published by the Free Software Foundation.
+#
+# This library 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 Lesser General Public
+# License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+from ctypes import ArgumentError
+from openslide import (OpenSlide, OpenSlideError,
+ OpenSlideUnsupportedFormatError)
+import unittest
+
+from . import file_path
+
+# Tests should be written to be compatible with Python 2.6 unittest.
+
+class TestSlideWithoutOpening(unittest.TestCase):
+ def test_detect_format(self):
+ self.assertTrue(
+ OpenSlide.detect_format(file_path('__missing_file')) is None)
+ self.assertTrue(
+ OpenSlide.detect_format(file_path('../setup.py')) is None)
+ self.assertEqual(
+ OpenSlide.detect_format(file_path('boxes.tiff')),
+ 'generic-tiff')
+
+ def test_open(self):
+ self.assertRaises(OpenSlideUnsupportedFormatError,
+ lambda: OpenSlide('__does_not_exist'))
+ self.assertRaises(OpenSlideUnsupportedFormatError,
+ lambda: OpenSlide('setup.py'))
+ self.assertRaises(OpenSlideError,
+ lambda: OpenSlide('unopenable.tiff'))
+
+ def test_operations_on_closed_handle(self):
+ osr = OpenSlide(file_path('boxes.tiff'))
+ props = osr.properties
+ associated = osr.associated_images
+ osr.close()
+ self.assertRaises(ArgumentError,
+ lambda: osr.read_region((0, 0), 0, (100, 100)))
+ self.assertRaises(ArgumentError, lambda: osr.close())
+ self.assertRaises(ArgumentError, lambda: props['openslide.vendor'])
+ self.assertRaises(ArgumentError, lambda: associated['label'])
+
+ def test_context_manager(self):
+ osr = OpenSlide(file_path('boxes.tiff'))
+ with osr:
+ self.assertEqual(osr.level_count, 4)
+ self.assertRaises(ArgumentError, lambda: osr.level_count)
+
+
+class TestSlide(unittest.TestCase):
+ def setUp(self):
+ self.osr = OpenSlide(file_path('boxes.tiff'))
+
+ def tearDown(self):
+ self.osr.close()
+
+ def test_basic_metadata(self):
+ self.assertEqual(self.osr.level_count, 4)
+ self.assertEqual(self.osr.level_dimensions,
+ ((300, 250), (150, 125), (75, 62), (37, 31)))
+ self.assertEqual(self.osr.dimensions, (300, 250))
+
+ self.assertEqual(len(self.osr.level_downsamples), self.osr.level_count)
+ self.assertEqual(self.osr.level_downsamples[0:2], (1, 2))
+ self.assertAlmostEqual(self.osr.level_downsamples[2], 4, places=0)
+ self.assertAlmostEqual(self.osr.level_downsamples[3], 8, places=0)
+
+ self.assertEqual(self.osr.get_best_level_for_downsample(0.5), 0)
+ self.assertEqual(self.osr.get_best_level_for_downsample(3), 1)
+ self.assertEqual(self.osr.get_best_level_for_downsample(37), 3)
+
+ def test_properties(self):
+ self.assertEqual(self.osr.properties['openslide.vendor'],
+ 'generic-tiff')
+ self.assertRaises(KeyError,
+ lambda: self.osr.properties['__does_not_exist'])
+ # test __len__ and __iter__
+ self.assertEqual(len([v for v in self.osr.properties]),
+ len(self.osr.properties))
+
+ def test_associated_images(self):
+ # XXX test an associated image
+ self.assertRaises(KeyError,
+ lambda: self.osr.associated_images['__missing'])
+ # test __len__ and __iter__
+ self.assertEqual(len([v for v in self.osr.associated_images]),
+ len(self.osr.associated_images))
+
+ def test_read_region(self):
+ self.assertEqual(self.osr.read_region((-10, -10), 1, (400, 400)).size,
+ (400, 400))
+
+ def test_read_region_size_dimension_zero(self):
+ self.assertEqual(self.osr.read_region((0, 0), 1, (400, 0)).size,
+ (400, 0))
+
+ def test_read_region_bad_level(self):
+ self.assertEqual(self.osr.read_region((0, 0), 4, (100, 100)).size,
+ (100, 100))
+
+ def test_read_region_bad_size(self):
+ self.assertRaises(OpenSlideError,
+ lambda: self.osr.read_region((0, 0), 1, (400, -5)))
+
+ def test_thumbnail(self):
+ self.assertEqual(self.osr.get_thumbnail((100, 100)).size, (100, 83))
View
Binary file not shown.

0 comments on commit 9681548

Please sign in to comment.