diff options
-rw-r--r-- | conftest.py | 21 | ||||
-rw-r--r-- | scss/compiler.py | 44 | ||||
-rw-r--r-- | scss/tests/files/xfail/missing-import.css | 0 | ||||
-rw-r--r-- | scss/tests/files/xfail/missing-import.scss | 1 | ||||
-rw-r--r-- | scss/tests/test_misc.py | 9 |
5 files changed, 64 insertions, 11 deletions
diff --git a/conftest.py b/conftest.py index 014b4d8..0a81986 100644 --- a/conftest.py +++ b/conftest.py @@ -8,7 +8,12 @@ import logging import pytest import scss +from scss.compiler import compile_file import scss.config +from scss.extension.core import CoreExtension +from scss.extension.extra import ExtraExtension +from scss.extension.fonts import FontsExtension +from scss.extension.compass import CompassExtension try: import fontforge @@ -97,22 +102,26 @@ class SassItem(pytest.Item): scss_file = self.fspath css_file = scss_file.new(ext='css') - with scss_file.open('rb') as fh: - source = fh.read() with css_file.open('rb') as fh: # Output is Unicode, so decode this here expected = fh.read().decode('utf8') scss.config.STATIC_ROOT = str(scss_file.dirpath('static')) - compiler = scss.Scss( - scss_opts=dict(style='expanded'), - search_paths=[ + actual = compile_file( + str(scss_file), + output_style='expanded', + search_path=[ str(scss_file.dirpath('include')), str(scss_file.dirname), ], + extensions=[ + CoreExtension, + ExtraExtension, + FontsExtension, + CompassExtension, + ], ) - actual = compiler.compile(source) # Normalize leading and trailing newlines actual = actual.strip('\n') diff --git a/scss/compiler.py b/scss/compiler.py index ac9dea7..dceacef 100644 --- a/scss/compiler.py +++ b/scss/compiler.py @@ -85,15 +85,12 @@ def warn_deprecated(rule, message): ) -# TODO it's probably still kind of weird to go Compiler().compile('a/b/c') and -# not have stuff in a/b/ importable. maybe need a top-level compile_sass() -# function that takes a single file? (compile_file? compile_string?) class Compiler(object): """A Sass compiler. Stores settings and knows how to fire off a compilation. Main entry point into compiling Sass. """ def __init__( - self, root='', search_path=('',), + self, root='', search_path=(), namespace=None, extensions=(CoreExtension,), output_style='nested', generate_source_map=False, live_errors=False, warn_unused_imports=False, @@ -180,10 +177,49 @@ class Compiler(object): def compile(self, *filenames): compilation = self.make_compilation() for filename in filenames: + # TODO maybe SourceFile should not be exposed to the end user, and + # instead Compilation should have methods for add_string etc. that + # can call normalize_path. + # TODO it's not possible to inject custom files into the + # /compiler/ as persistent across compiles, nor to provide "fake" + # imports. do we want the former? is the latter better suited to + # an extension? source = SourceFile.from_filename(self.normalize_path(filename)) compilation.add_source(source) return self.call_and_catch_errors(compilation.run) + def compile_string(self, string): + source = SourceFile.from_string(string) + compilation = self.make_compilation() + compilation.add_source(source) + return self.call_and_catch_errors(compilation.run) + + +def compile_file(filename, compiler_class=Compiler, **kwargs): + """Compile a single file, and return a string of CSS. + + Keyword arguments are passed along to the underlying `Compiler`. + + Note that the search path is set to the file's containing directory by + default, unless you explicitly pass a ``search_path`` kwarg. + """ + if 'search_path' not in kwargs: + kwargs['search_path'] = [ + os.path.abspath(os.path.dirname(filename)), + ] + + compiler = compiler_class(**kwargs) + return compiler.compile(filename) + + +def compile_string(string, compiler_class=Compiler, **kwargs): + """Compile a single string, and return a string of CSS. + + Keyword arguments are passed along to the underlying `Compiler`. + """ + compiler = compiler_class(**kwargs) + return compiler.compile_string(string) + class Compilation(object): """A single run of a compiler.""" diff --git a/scss/tests/files/xfail/missing-import.css b/scss/tests/files/xfail/missing-import.css deleted file mode 100644 index e69de29..0000000 --- a/scss/tests/files/xfail/missing-import.css +++ /dev/null diff --git a/scss/tests/files/xfail/missing-import.scss b/scss/tests/files/xfail/missing-import.scss deleted file mode 100644 index c10a6bb..0000000 --- a/scss/tests/files/xfail/missing-import.scss +++ /dev/null @@ -1 +0,0 @@ -@import "missing-file"; diff --git a/scss/tests/test_misc.py b/scss/tests/test_misc.py index adcb893..767a319 100644 --- a/scss/tests/test_misc.py +++ b/scss/tests/test_misc.py @@ -4,6 +4,8 @@ own files, maybe. """ from scss import Scss +from scss.compiler import compile_string +from scss.errors import SassImportError def test_super_selector(): @@ -107,3 +109,10 @@ def test_unicode_files(): output = compiler.compile(unicode_input) assert output == unicode_input + + +def test_missing_import(): + with pytest.raises(SassImportError): + compile_string(""" + @import "bogus-file"; + """) |