def test_mode_fully_specified(): foo = Library('foo', '') k_debug = Resource(foo, 'k-debug.js') k = Resource(foo, 'k.js', debug=k_debug) x = Resource(foo, 'x.js', minified='x-min.js') needed = init_needed() needed.need(k) incl = Inclusion(needed) assert incl.resources == [k] incl = Inclusion(needed, mode='debug') assert incl.resources == [k_debug] # If no minified can be found, the 'raw' resource is taken. incl = Inclusion(needed, mode='minified') assert incl.resources == [k] # If only a minified resource is defined, debug returns the raw version. needed = init_needed() needed.need(x) incl = Inclusion(needed, mode='debug') assert incl.resources == [x] incl = Inclusion(needed, mode='minified') assert incl.resources == [x.modes['minified']]
def test_rendering_base_url(): foo = Library('foo', '') x1 = Resource(foo, 'a.js') x2 = Resource(foo, 'b.css') y1 = Resource(foo, 'c.js', depends=[x1, x2]) needed = init_needed(resources=[y1]) incl = Inclusion(needed) assert incl.render() == '''\ <link rel="stylesheet" type="text/css" href="/fanstatic/foo/b.css" /> <script type="text/javascript" src="/fanstatic/foo/a.js"></script> <script type="text/javascript" src="/fanstatic/foo/c.js"></script>''' needed = init_needed(base_url='http://localhost/static', resources=[y1]) incl = Inclusion(needed) assert incl.render() == '''\ <link rel="stylesheet" type="text/css" href="http://localhost/static/fanstatic/foo/b.css" /> <script type="text/javascript" src="http://localhost/static/fanstatic/foo/a.js"></script> <script type="text/javascript" src="http://localhost/static/fanstatic/foo/c.js"></script>''' # The base_url has been set. assert needed.has_base_url() needed.set_base_url('foo') # The base_url can only be set once. assert needed._base_url == 'http://localhost/static'
def test_inclusion_rollup_and_debug(): foo = Library('foo', '') f1 = Resource(foo, 'f1.js', debug='f1-debug.js') f2 = Resource(foo, 'f2.js', debug='f2-debug.js') giantf = Resource(foo, 'giantf.js', supersedes=[f1, f2], debug='giantf-debug.js') needed = init_needed(resources=[f1, f2]) incl = Inclusion(needed, rollup=True) assert incl.resources == [giantf] incl = Inclusion(needed, rollup=True, mode='debug') assert incl.resources == [giantf.modes['debug']]
def test_redundant_more_complicated(): foo = Library('foo', '') a1 = Resource(foo, 'a1.js') a2 = Resource(foo, 'a2.js', depends=[a1]) a3 = Resource(foo, 'a3.js', depends=[a2]) a4 = Resource(foo, 'a4.js', depends=[a1]) needed = init_needed() needed.need(a3) incl = Inclusion(needed) assert incl.resources == [a1, a2, a3] needed.need(a4) # a4 is sorted before a3, because it is less deep # in the dependency tree incl = Inclusion(needed) assert incl.resources == [a1, a2, a4, a3]
def test_compile_only_for_libraries_under_development(compilers): compilers.add_compiler(MockCompiler()) lib = Library('lib', '') a = Resource(lib, 'a.js', compiler='mock') needed = init_needed(resources=[a]) incl = Inclusion(needed, compile=True) assert len(compilers.compiler('mock').calls) == 1 # Gathering all resources again will add a call. incl = Inclusion(needed, compile=True) assert len(compilers.compiler('mock').calls) == 2 lib.version = 1 incl = Inclusion(needed, compile=True) assert len(compilers.compiler('mock').calls) == 2
def test_empty_base_url_and_publisher_signature(): ''' When the base_url is not set and the publisher_signature is an empty string, render a URL without them. ''' foo = Library('foo', '') x1 = Resource(foo, 'a.js') needed = init_needed(publisher_signature='', resources=[x1]) incl = Inclusion(needed) assert incl.render() == '''\
def test_custom_renderer_for_resource(): foo = Library('foo', '') from fanstatic.core import render_print_css def render_unknown(url): return '<unknown href="%s"/>' % url a = Resource(foo, 'printstylesheet.css', renderer=render_print_css) b = Resource(foo, 'nothing.unknown', renderer=render_unknown) needed = init_needed() needed.need(a) incl = Inclusion(needed) assert incl.render() == """\ <link rel="stylesheet" type="text/css" href="/fanstatic/foo/printstylesheet.css" media="print" />""" needed.need(b) incl = Inclusion(needed) assert incl.render() == """\
def test_inclusion_rollup_and_debug_missing(): foo = Library('foo', '') h1 = Resource(foo, 'h1.js', debug='h1-debug.js') h2 = Resource(foo, 'h2.js', debug='h2-debug.js') gianth = Resource(foo, 'gianth.js', supersedes=[h1, h2]) needed = init_needed(resources=[h1, h2]) incl = Inclusion(needed, rollup=True, mode='debug') # No mode debug version of the rollup use it instead assert incl.resources == [gianth]
def test_rendering(): foo = Library('foo', '') x1 = Resource(foo, 'a.js') x2 = Resource(foo, 'b.css') y1 = Resource(foo, 'c.js', depends=[x1, x2]) needed = init_needed(resources=[y1]) incl = Inclusion(needed) assert incl.render() == '''\
def test_rendering_base_url_assign(): foo = Library('foo', '') x1 = Resource(foo, 'a.js') x2 = Resource(foo, 'b.css') y1 = Resource(foo, 'c.js', depends=[x1, x2]) needed = init_needed(resources=[y1]) needed.set_base_url('http://localhost/static') incl = Inclusion(needed) assert incl.render() == '''\
def test_redundant_resource(): foo = Library('foo', '') x1 = Resource(foo, 'a.js') x2 = Resource(foo, 'b.css') y1 = Resource(foo, 'c.js', depends=[x1, x2]) needed = init_needed() needed.need(y1) needed.need(y1) incl = Inclusion(needed) assert incl.resources == [x2, x1, y1] needed.need(x1) incl = Inclusion(needed) assert incl.resources == [x2, x1, y1] needed.need(x2) incl = Inclusion(needed) assert incl.resources == [x2, x1, y1]
def test_minified_mode_relpath_respect_subdir(compilers): compilers.add_compiler(MockCompiler()) compilers.add_minifier(MockMinifier()) lib = Library('lib', '') a = Resource(lib, 'foo/bar/a.js', compiler='mock', minifier='mock') needed = init_needed(resources=[a]) incl = Inclusion(needed, compile=True, mode=MINIFIED) assert len(incl.resources) == 1 assert incl.resources[0].relpath == 'foo/bar/a.min.js' assert incl.resources[0] != a
def test_setting_compile_False_should_not_call_compiler_and_minifier( compilers): compilers.add_compiler(MockCompiler()) compilers.add_minifier(MockMinifier()) lib = Library('lib', '') a = Resource(lib, 'a.js', compiler='mock', minifier='mock') needed = init_needed(resources=[a]) incl = Inclusion(needed) incl.render() assert not compilers.compiler('mock').calls assert not compilers.minifier('mock').calls
def test_slot_minified(): lib = Library('lib', '') slot = Slot(lib, '.js') a = Resource(lib, 'a.js', depends=[slot]) b = Resource(lib, 'b.js', minified='b-min.js') needed = init_needed() needed.need(a, {slot: b}) incl = Inclusion(needed, mode=MINIFIED) assert [r.relpath for r in incl.resources] == ['b-min.js', 'a.js']
def test_redundant_more_complicated_depends_on_all(): foo = Library('foo', '') a1 = Resource(foo, 'a1.js') a2 = Resource(foo, 'a2.js', depends=[a1]) a3 = Resource(foo, 'a3.js', depends=[a2]) a4 = Resource(foo, 'a4.js', depends=[a1]) a5 = Resource(foo, 'a5.js', depends=[a4, a3]) needed = init_needed() needed.need(a5) incl = Inclusion(needed) assert incl.resources == [a1, a2, a4, a3, a5]
def test_resource_subclass_render(): foo = Library('foo', '') class MyResource(Resource): def render(self, library_url): return '<myresource reference="%s/%s"/>' % (library_url, self.relpath) a = MyResource(foo, 'printstylesheet.css') needed = init_needed(resources=[a]) incl = Inclusion(needed) assert incl.render() == """\
def test_compile_with_slots(compilers): compilers.add_compiler(MockCompiler()) lib = Library('lib', '') slot = Slot(lib, '.js') a = Resource(lib, 'a.js', compiler='mock') b = Resource(lib, 'b.js', depends=[slot]) needed = init_needed() needed.need(b, {slot: a}) incl = Inclusion(needed, compile=True) assert len(compilers.compiler('mock').calls) == 1
def test_redundant_more_complicated_reversed(): foo = Library('foo', '') a1 = Resource(foo, 'a1.js') a2 = Resource(foo, 'a2.js', depends=[a1]) a3 = Resource(foo, 'a3.js', depends=[a2]) a4 = Resource(foo, 'a4.js', depends=[a1]) needed = init_needed() needed.need(a4) needed.need(a3) # this will always be consistent, no matter # in what order we need the resources incl = Inclusion(needed) assert incl.resources == [a1, a2, a4, a3]
def test_render_bundle(): foo = Library('foo', '') x1 = Resource(foo, 'a.css') x2 = Resource(foo, 'b.css') x3 = Resource(foo, 'c.css', dont_bundle=True) x4 = Resource(foo, 'subdir/subdir/x4.css') x5 = Resource(foo, 'subdir/subdir/x5.css') needed = init_needed(resources=[x1, x2, x3]) incl = Inclusion(needed) assert incl.render( ) == '''<link rel="stylesheet" type="text/css" href="/fanstatic/foo/a.css" /> <link rel="stylesheet" type="text/css" href="/fanstatic/foo/b.css" /> <link rel="stylesheet" type="text/css" href="/fanstatic/foo/c.css" />''' needed = init_needed(resources=[x1, x2, x3]) incl = Inclusion(needed, bundle=True) assert incl.render( ) == '''<link rel="stylesheet" type="text/css" href="/fanstatic/foo/:bundle:a.css;b.css" /> <link rel="stylesheet" type="text/css" href="/fanstatic/foo/c.css" />''' needed = init_needed(resources=[x1, x2, x4, x5]) incl = Inclusion(needed, bundle=True) assert incl.render( ) == '''<link rel="stylesheet" type="text/css" href="/fanstatic/foo/:bundle:a.css;b.css" />
def test_setting_compile_True_should_call_compiler_and_minifier(compilers): compilers.add_compiler(MockCompiler()) compilers.add_minifier(MockMinifier()) lib = Library('lib', '') a = Resource(lib, 'a.js', compiler='mock', minifier='mock') needed = init_needed(resources=[a]) incl = Inclusion(needed, compile=True) incl.render() mock_compiler = compilers.compiler('mock') mock_minifier = compilers.minifier('mock') assert len(mock_compiler.calls) == 1 assert mock_compiler.calls[0] == a assert len(mock_minifier.calls) == 1 assert mock_minifier.calls[0] == a
def test_rollup_with_slot(): from fanstatic import Slot lib = Library('lib', '') c = Resource(lib, 'c.js') slot = Slot(lib, '.js', depends=[c]) a = Resource(lib, 'a.js', depends=[slot]) b = Resource(lib, 'b.js', depends=[c]) needed = init_needed() needed.need(a, {slot: b}) incl = Inclusion(needed, rollup=True) assert len(incl.resources) == 3 assert a in incl.resources assert c in incl.resources
def test_register_inclusion_renderer(): foo = Library('foo', '') with pytest.raises(UnknownResourceExtensionError): # The renderer for '.unknown' is not yet defined. Resource(foo, 'nothing.unknown') def render_unknown(url): return '<link rel="unknown" href="%s" />' % url register_inclusion_renderer('.unknown', render_unknown) a = Resource(foo, 'stuff.unknown') needed = init_needed(resources=[a]) incl = Inclusion(needed) assert incl.render() == \ '<link rel="unknown" href="/fanstatic/foo/stuff.unknown" />'
def test_custom_renderer_keep_together(): foo = Library('foo', '') def render_print_css(url): return ( '<link rel="stylesheet" type="text/css" href="%s" media="print"/>' % url) a = Resource(foo, 'printstylesheet.css', renderer=render_print_css) b = Resource(foo, 'regular.css') c = Resource(foo, 'something.js') needed = init_needed() needed.need(a) needed.need(b) needed.need(c) incl = Inclusion(needed) assert incl.resources == [a, b, c]
def test_minified_mode_should_call_compiler_and_minifier_of_parent_resource( compilers): compilers.add_compiler(MockCompiler()) compilers.add_minifier(MockMinifier()) lib = Library('lib', '') a = Resource(lib, 'a.js', compiler='mock', minifier='mock') needed = init_needed(resources=[a]) incl = Inclusion(needed, compile=True, mode=MINIFIED) assert len(incl.resources) == 1 assert incl.resources[0].relpath == 'a.min.js' assert incl.resources[0] != a mock_compiler = compilers.compiler('mock') mock_minifier = compilers.minifier('mock') assert len(mock_compiler.calls) == 1 assert mock_compiler.calls[0] == a assert len(mock_minifier.calls) == 1 assert mock_minifier.calls[0] == a
def test_sass_resource(tmpdir): compiler = fanstatic.CompilerRegistry.instance()['sass'] if not compiler.available: pytest.skip('`%s` not found on PATH' % compiler.command) lib = Library('lib', str(tmpdir), compilers={'.css': 'sass'}) a = Resource(lib, 'a.css') tmpdir.join('a.scss').write('''\ #navbar { li { a { font-weight: bold; } } }''') # Before compilation, the resource is not present. assert not tmpdir.join('a.css').check() needed = init_needed(resources=[a]) incl = Inclusion(needed, compile=True) incl.render() # After compilation, the resource is present, and compiled using the sass # compiler. assert '#navbar li a' in tmpdir.join('a.css').read()