diff options
author | Eevee (Alex Munroe) <eevee.git@veekun.com> | 2014-10-17 14:36:04 -0700 |
---|---|---|
committer | Eevee (Alex Munroe) <eevee.git@veekun.com> | 2014-10-17 14:36:04 -0700 |
commit | cf388579d73f12993eb4a50a7bf11c373eff6c87 (patch) | |
tree | dbeac0b98c160d97cdc60926e0de8a608dd16573 | |
parent | 9f17aef50155ac0d7191cf9596d9664d2b6b53e4 (diff) | |
download | pyscss-cf388579d73f12993eb4a50a7bf11c373eff6c87.tar.gz |
Better handle running the tests without PIL installed.
-rw-r--r-- | conftest.py | 34 | ||||
-rw-r--r-- | scss/errors.py | 16 | ||||
-rw-r--r-- | scss/extension/compass/images.py | 7 | ||||
-rw-r--r-- | scss/extension/compass/sprites.py | 3 | ||||
-rw-r--r-- | scss/extension/extra.py | 9 | ||||
-rw-r--r-- | scss/extension/fonts.py | 3 | ||||
-rw-r--r-- | scss/tests/functions/compass/test_images.py | 3 | ||||
-rw-r--r-- | scss/tests/functions/test_extra.py | 5 | ||||
-rw-r--r-- | scss/tests/util.py | 15 |
9 files changed, 75 insertions, 20 deletions
diff --git a/conftest.py b/conftest.py index e4371a3..535bb68 100644 --- a/conftest.py +++ b/conftest.py @@ -11,6 +11,8 @@ import pytest import scss from scss.compiler import compile_file import scss.config +from scss.errors import SassEvaluationError +from scss.errors import SassMissingDependency from scss.extension.core import CoreExtension from scss.extension.extra import ExtraExtension from scss.extension.fonts import FontsExtension @@ -115,17 +117,27 @@ class SassItem(pytest.Item): search_path.append(include) search_path.append(scss_file.parent) - actual = compile_file( - scss_file, - output_style='expanded', - search_path=search_path, - extensions=[ - CoreExtension, - ExtraExtension, - FontsExtension, - CompassExtension, - ], - ) + try: + actual = compile_file( + scss_file, + output_style='expanded', + search_path=search_path, + extensions=[ + CoreExtension, + ExtraExtension, + FontsExtension, + CompassExtension, + ], + ) + except SassEvaluationError as e: + # Treat any missing dependencies (PIL not installed, fontforge not + # installed) as skips + # TODO this is slightly cumbersome and sorta defeats the purpose of + # having separate exceptions + if isinstance(e.exc, SassMissingDependency): + pytest.skip(e.format_message()) + else: + raise # Normalize leading and trailing newlines actual = actual.strip('\n') diff --git a/scss/errors.py b/scss/errors.py index 75d98b6..b06793c 100644 --- a/scss/errors.py +++ b/scss/errors.py @@ -168,6 +168,22 @@ class SassImportError(SassBaseError): ) +class SassMissingDependency(SassBaseError): + """Error raised when an optional library (e.g., PIL or fontforge) is + missing. + """ + + def __init__(self, library, activity, **kwargs): + super(SassMissingDependency, self).__init__(**kwargs) + + self.library = library + self.activity = activity + + def format_message(self): + return "{0} requires {1}, which is not installed".format( + self.activity, self.library) + + class SassError(SassBaseError): """Error class that wraps another exception and attempts to bolt on some useful context. diff --git a/scss/extension/compass/images.py b/scss/extension/compass/images.py index 465246c..b2f33f1 100644 --- a/scss/extension/compass/images.py +++ b/scss/extension/compass/images.py @@ -13,6 +13,7 @@ from six.moves import xrange from . import CompassExtension from .helpers import add_cache_buster from scss import config +from scss.errors import SassMissingDependency from scss.types import Color, List, Number, String, Url from scss.util import getmtime, make_data_url, make_filename_hash from scss.extension import Cache @@ -49,7 +50,7 @@ def _image_url(path, only_path=False, cache_buster=True, dst_color=None, src_col """ if inline or dst_color or spacing: if not Image: - raise Exception("Images manipulation require PIL") + raise SassMissingDependency('PIL', 'image manipulation') filepath = String.unquoted(path).value fileext = os.path.splitext(filepath)[1].lstrip('.').lower() @@ -223,7 +224,7 @@ def image_width(image): relative to your project's images directory. """ if not Image: - raise Exception("Images manipulation require PIL") + raise SassMissingDependency('PIL', 'image manipulation') image_size_cache = _get_cache('image_size_cache') @@ -261,7 +262,7 @@ def image_height(image): """ image_size_cache = _get_cache('image_size_cache') if not Image: - raise Exception("Images manipulation require PIL") + raise SassMissingDependency('PIL', 'image manipulation') filepath = String.unquoted(image).value path = None try: diff --git a/scss/extension/compass/sprites.py b/scss/extension/compass/sprites.py index e8208d6..28ba4fb 100644 --- a/scss/extension/compass/sprites.py +++ b/scss/extension/compass/sprites.py @@ -33,6 +33,7 @@ from six.moves import xrange from . import CompassExtension from .layouts import PackedSpritesLayout, HorizontalSpritesLayout, VerticalSpritesLayout, DiagonalSpritesLayout from scss import config +from scss.errors import SassMissingDependency from scss.types import Color, List, Number, String, Boolean from scss.util import escape, getmtime, make_data_url, make_filename_hash from scss.extension import Cache @@ -121,7 +122,7 @@ def sprite_map(g, **kwargs): $collapse-y - Collapses a size for `y`. """ if not Image: - raise Exception("Images manipulation require PIL") + raise SassMissingDependency('PIL', 'image manipulation') sprite_maps = _get_cache('sprite_maps') diff --git a/scss/extension/extra.py b/scss/extension/extra.py index 30cbe5f..3edc9f3 100644 --- a/scss/extension/extra.py +++ b/scss/extension/extra.py @@ -12,6 +12,7 @@ import six from six.moves import xrange from scss import config +from scss.errors import SassMissingDependency from scss.extension import Extension from scss.namespace import Namespace from scss.types import Color, Number, String, List @@ -275,7 +276,7 @@ def _image_brushed(pixdata, size, density=None, intensity=None, color=None, opac @ns.declare def background_noise(density=None, opacity=None, size=None, monochrome=False, intensity=(), color=None, background=None, inline=False): if not Image: - raise Exception("Images manipulation require PIL") + raise SassMissingDependency('PIL', 'image manipulation') density = [Number(v).value for v in List.from_maybe(density)] intensity = [Number(v).value for v in List.from_maybe(intensity)] @@ -325,7 +326,7 @@ def background_noise(density=None, opacity=None, size=None, monochrome=False, in @ns.declare def background_brushed(density=None, intensity=None, color=None, opacity=None, size=None, monochrome=False, direction=(), spread=(), background=None, inline=False): if not Image: - raise Exception("Images manipulation require PIL") + raise SassMissingDependency('PIL', 'image manipulation') density = [Number(v).value for v in List.from_maybe(density)] intensity = [Number(v).value for v in List.from_maybe(intensity)] @@ -378,7 +379,7 @@ def background_brushed(density=None, intensity=None, color=None, opacity=None, s @ns.declare def grid_image(left_gutter, width, right_gutter, height, columns=1, grid_color=None, baseline_color=None, background_color=None, inline=False): if not Image: - raise Exception("Images manipulation require PIL") + raise SassMissingDependency('PIL', 'image manipulation') if grid_color is None: grid_color = (120, 170, 250, 15) else: @@ -443,7 +444,7 @@ def grid_image(left_gutter, width, right_gutter, height, columns=1, grid_color=N @ns.declare def image_color(color, width=1, height=1): if not Image: - raise Exception("Images manipulation require PIL") + raise SassMissingDependency('PIL', 'image manipulation') w = int(Number(width).value) h = int(Number(height).value) if w <= 0 or h <= 0: diff --git a/scss/extension/fonts.py b/scss/extension/fonts.py index 67a3b2d..b772ceb 100644 --- a/scss/extension/fonts.py +++ b/scss/extension/fonts.py @@ -26,6 +26,7 @@ except: fontforge = None from scss import config +from scss.errors import SassMissingDependency from scss.extension import Extension from scss.namespace import Namespace from scss.types import Boolean, List, String, Url @@ -129,7 +130,7 @@ def ttf2eot(ttf): @ns.declare def font_sheet(g, **kwargs): if not fontforge: - raise Exception("Fonts manipulation require fontforge") + raise SassMissingDependency('fontforge', 'font manipulation') font_sheets = _get_cache('font_sheets') diff --git a/scss/tests/functions/compass/test_images.py b/scss/tests/functions/compass/test_images.py index a5d0312..025a32e 100644 --- a/scss/tests/functions/compass/test_images.py +++ b/scss/tests/functions/compass/test_images.py @@ -20,6 +20,7 @@ import pytest from scss import config from scss.calculator import Calculator from scss.extension.compass import CompassExtension +from scss.tests.util import needs_PIL # TODO many of these tests could also stand to test for failure cases @@ -36,6 +37,7 @@ def test_image_url(calc): # inline-image +@needs_PIL def test_inline_image(calc, monkeypatch): monkeypatch.setattr(config, 'IMAGES_ROOT', os.path.join(config.PROJECT_ROOT, 'tests/files/images')) @@ -45,6 +47,7 @@ def test_inline_image(calc, monkeypatch): @pytest.mark.skipif(sys.platform == 'win32', reason='cur mimetype is defined on windows') +@needs_PIL def test_inline_cursor(calc, monkeypatch): monkeypatch.setattr(config, 'IMAGES_ROOT', os.path.join(config.PROJECT_ROOT, 'tests/files/cursors')) diff --git a/scss/tests/functions/test_extra.py b/scss/tests/functions/test_extra.py index 8940e94..d9f97cb 100644 --- a/scss/tests/functions/test_extra.py +++ b/scss/tests/functions/test_extra.py @@ -8,25 +8,30 @@ from __future__ import absolute_import from __future__ import unicode_literals import scss.extension.extra as libextra +from scss.tests.util import needs_PIL from scss.types import Boolean, Color, Number # TODO: currently these all just call the functions and make sure they pass. # would be nice to check the output, though that's a little tedious. +@needs_PIL def test_background_noise(): libextra.background_noise(Number(0.5), Number(0.5), Number(100), Boolean(True), color=Color.from_name('green')) +@needs_PIL def test_background_brushed(): libextra.background_brushed(Number(0.5), Number(0.5), Color.from_name('red'), Number(0.5)) +@needs_PIL def test_grid_image(): # TODO this should accept sass values only :| libextra.grid_image(5, 100, 5, 100) +@needs_PIL def test_image_color(): libextra.image_color(Color.from_rgb(1, 1, 0)) assert True diff --git a/scss/tests/util.py b/scss/tests/util.py new file mode 100644 index 0000000..8b36d7d --- /dev/null +++ b/scss/tests/util.py @@ -0,0 +1,15 @@ +"""Test utilities.""" +from __future__ import absolute_import + +import pytest + +try: + import PIL +except ImportError: + try: + import Image as PIL + except ImportError: + PIL = None + + +needs_PIL = pytest.mark.skipif(PIL is None, reason='image tests require PIL') |