"""Tests for the Compass helper functions. Not all of Compass is implemented, and the arrangement of Compass functions doesn't exactly match the arrangement in the original documentation. Regardless, this is a good starting place: http://compass-style.org/reference/compass/helpers/ Some functions appear to be undocumented, but nonetheless are part of Compass's Ruby code. """ from __future__ import absolute_import from __future__ import unicode_literals import os from scss import config from scss.calculator import Calculator from scss.extension.compass import CompassExtension import pytest # TODO many of these tests could also stand to test for failure cases @pytest.fixture def calc(): return Calculator(CompassExtension.namespace).evaluate_expression # ------------------------------------------------------------------------------ # Listish functions # See: http://ruby-doc.org/gems/docs/c/compass-0.12.2/Compass/SassExtensions/Functions/Lists.html def test_blank(calc): assert calc('blank(false)') assert calc('blank("")') assert calc('blank(" ")') # TODO this is a syntax error; see #166 #assert calc('blank(())') assert not calc('blank(null)') # yes, really assert not calc('blank(1)') assert not calc('blank((1, 2))') assert not calc('blank(0)') def test_compact(calc): assert calc('compact(1 2 3 false 4 5 null 6 7)') == calc('1 2 3 4 5 6 7') def test_reject(calc): assert calc('reject(a b c d, a, c)') == calc('b d') assert calc('reject(a b c d, e)') == calc('a b c d') def test_first_value_of(calc): assert calc('first-value-of(a b c d)') == calc('a') assert calc('first-value-of("a b c d")') == calc('"a"') # -compass-list # -compass-space-list # -compass-slice ## Property prefixing # prefixed # prefix # -moz... ## Selector generation # append-selector # elements-of-type def test_enumerate(calc): assert calc('enumerate(foo, 4, 7)') == calc('foo-4, foo-5, foo-6, foo-7') assert calc('enumerate("bar", 8, 10)') == calc('bar-8, bar-9, bar-10') def test_headings(calc): assert calc('headings()') == calc('h1, h2, h3, h4, h5, h6') assert calc('headings(all)') == calc('h1, h2, h3, h4, h5, h6') assert calc('headings(2)') == calc('h1, h2') assert calc('headings(2, 5)') == calc('h2, h3, h4, h5') def test_nest(calc): # Using .render() here because the structure is complicated and only the # output matters assert calc('nest(selector1, selector2, selector3)').render() == 'selector1 selector2 selector3' assert calc('nest("a b", "c d")').render() == 'a b c d' assert calc('nest((a, b), (c, d))').render() == 'a c, a d, b c, b d' # range ## Working with CSS constants # position def test_opposite_position(calc): assert calc('opposite-position(left)') == calc('right') assert calc('opposite-position(top)') == calc('bottom') assert calc('opposite-position(center)') == calc('center') assert calc('opposite-position(top left)') == calc('bottom right') assert calc('opposite-position(center right)') == calc('center left') ## Math def test_pi(calc): assert calc('pi()') == calc('3.141592653589793') def test_e(calc): assert calc('e()') == calc('2.718281828459045') def test_sqrt(calc): assert calc('sqrt(9)') == calc('3') def test_log(calc): assert calc('log(9, 3)') == calc('2') def test_pow(calc): assert calc('pow(3, 2)') == calc('9') assert calc('pow(10px, 2) / 1px') == calc('100px') # sin # cos # tan ## Fonts # font-url def test_font_url(calc): # nb: config.FONTS_URL is None and defaults to this fonts_url = config.STATIC_URL assert calc('font-url("/some_path.woff")').render() == 'url({0}some_path.woff)'.format(fonts_url) assert calc('font-url("/some_path.woff") format("woff")').render() == 'url({0}some_path.woff) format("woff")'.format(fonts_url) # font-files def test_font_files(calc): """ @author: funvit @note: adapted from compass / test / units / sass_extensions_test.rb """ # nb: config.FONTS_URL is None and defaults to this fonts_url = config.STATIC_URL assert '' == calc('font-files()').render() assert 'url({0}font/name.woff) format("woff"), url({0}fonts/name.ttf) format("truetype"), url({0}fonts/name.svg#fontpath) format("svg")'.format(fonts_url) == calc('font-files("/font/name.woff", woff, "/fonts/name.ttf", truetype, "/fonts/name.svg#fontpath", svg)').render() assert 'url({0}font/with/right_ext.woff) format("woff")'.format(fonts_url) == calc('font_files("/font/with/right_ext.woff")').render() assert 'url({0}font/with/wrong_ext.woff) format("svg")'.format(fonts_url) == calc('font_files("/font/with/wrong_ext.woff", "svg")').render() assert 'url({0}font/with/no_ext) format("opentype")'.format(fonts_url) == calc('font_files("/font/with/no_ext", "otf")').render() assert 'url({0}font/with/weird.ext) format("truetype")'.format(fonts_url) == calc('font_files("/font/with/weird.ext", "truetype")').render() assert 'url({0}font/with/right_ext.woff) format("woff"), url({0}font/with/right_ext_also.otf) format("opentype")'.format(fonts_url) == calc('font_files("/font/with/right_ext.woff", "/font/with/right_ext_also.otf")').render() assert 'url({0}font/with/wrong_ext.woff) format("truetype"), url({0}font/with/right_ext.otf) format("opentype")'.format(fonts_url) == calc('font_files("/font/with/wrong_ext.woff", "ttf", "/font/with/right_ext.otf")').render() # inline-font-files def test_inline_font_files(calc, monkeypatch): """ @author: funvit @note: adapted from compass / test / units / sass_extensions_test.rb """ monkeypatch.setattr(config, 'FONTS_ROOT', os.path.join(config.PROJECT_ROOT, 'tests/files/fonts')) with open(os.path.join(config.PROJECT_ROOT, 'tests/files/fonts/bgrove.base64.txt'), 'r') as f: font_base64 = ''.join((f.readlines())) assert 'url(data:font/truetype;base64,%s) format("truetype")' % font_base64 == calc('inline_font_files("/bgrove.ttf", truetype)').render() ## External stylesheets # stylesheet-url