diff options
author | Eevee (Alex Munroe) <eevee.git@veekun.com> | 2014-08-26 13:03:48 -0700 |
---|---|---|
committer | Eevee (Alex Munroe) <eevee.git@veekun.com> | 2014-08-26 14:32:01 -0700 |
commit | e045cd72c467eacd16aaee2613ef0850e559a3ce (patch) | |
tree | fd6dec2df10907e5f2c912a8ab83f070223e4278 /conftest.py | |
parent | 77f24e0a2e8fb394004023191c8662febd8ceda0 (diff) | |
download | pyscss-e045cd72c467eacd16aaee2613ef0850e559a3ce.tar.gz |
Revamp py.test's handling of test files.
Each .scss file is now its own test -- you can run them directly, with
`py.test scss/tests/files/foo/bar.scss`, or use wildcards, or specify a
partial directory, or whatever.
Accordingly, `test_files.py` is gone, as is the `--test-file-filter`
option that was so cumbersome I never actually used it.
Regressions:
- xfail is no longer supported.
- Ruby tests are now not collected at all, rather than marked as
skipped.
Diffstat (limited to 'conftest.py')
-rw-r--r-- | conftest.py | 110 |
1 files changed, 102 insertions, 8 deletions
diff --git a/conftest.py b/conftest.py index 445657d..8019aa8 100644 --- a/conftest.py +++ b/conftest.py @@ -1,4 +1,27 @@ """py.test plugin configuration.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import logging + +import pytest + +import scss +import scss.config + +try: + import fontforge +except ImportError: + fontforge = None + + +# Turn on pyscss's logging +console = logging.StreamHandler() +logger = logging.getLogger('scss') +logger.setLevel(logging.ERROR) +logger.addHandler(console) + def pytest_addoption(parser): """Add options for filtering which file tests run. @@ -7,16 +30,87 @@ def pytest_addoption(parser): recursively look for conftest.py files until after it's parsed the command line. """ - parser.addoption('--include-ruby', + parser.addoption( + '--include-ruby', help='run tests imported from Ruby and sassc, most of which fail', action='store_true', dest='include_ruby', ) - parser.addoption('--test-file-filter', - help='comma-separated regexes to select test files', - action='store', - type='string', - dest='test_file_filter', - default=None, - ) + +def pytest_ignore_collect(path, config): + # Ruby/sassc tests don't even exist without this option + if path.basename in ('from_ruby', 'from-sassc'): + if not config.getoption('include_ruby'): + return True + + +def pytest_collect_file(path, parent): + if path.ext == '.scss': + parts = str(path).split(path.sep) + # -4 tests / -3 files / -2 directory / -1 file.scss + if parts[-4:-2] == ['tests', 'files']: + return SassFile(path, parent) + + +class SassFile(pytest.File): + def collect(self): + parent_name = self.fspath.dirpath().basename + if not fontforge and parent_name == 'fonts': + pytest.skip("font tests require fontforge") + + yield SassItem(str(self.fspath), self) + + +class SassItem(pytest.Item): + """A Sass test input file, collected as its own test item. + + A file of the same name but with a .css extension is assumed to contain the + expected output. + """ + _nodeid = None + + @property + def nodeid(self): + # Rig the nodeid to be "directory::filename", so all the files in the + # same directory are treated as grouped together + if not self._nodeid: + self._nodeid = "{0}::{1}".format( + self.fspath.dirpath().relto(self.session.fspath), + self.fspath.basename, + ) + return self._nodeid + + def reportinfo(self): + return ( + self.fspath.dirpath(), + None, + self.fspath.relto(self.session.fspath), + ) + + def runtest(self): + 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=[ + str(scss_file.dirpath('include')), + str(scss_file.dirname), + ], + ) + actual = compiler.compile(source) + + # Normalize leading and trailing newlines + actual = actual.strip('\n') + expected = expected.strip('\n') + + assert expected == actual |