1from nose.plugins.skip import SkipTest
2from webassets import Environment as AssetsEnvironment, Bundle
3from webassets.test import TempEnvironmentHelper
4
5
6try:
7    import jinja2
8except ImportError:
9    raise SkipTest('Jinja2 not installed')
10else:
11    from jinja2 import Template, Environment as JinjaEnvironment
12    from webassets.ext.jinja2 import AssetsExtension, Jinja2Loader
13
14
15class TestTemplateTag(object):
16
17    def setup(self):
18        # Setup the assets environment.
19        assets_env = AssetsEnvironment('', '')
20        self.foo_bundle = Bundle()
21        self.bar_bundle = Bundle()
22        assets_env.register('foo_bundle', self.foo_bundle)
23        assets_env.register('bar_bundle', self.bar_bundle)
24
25        # Inject a mock bundle class into the Jinja2 extension, so we
26        # can check on what exactly it does.
27        test_instance = self
28        class MockBundle(Bundle):
29            urls_to_fake = ['foo']
30            def __init__(self, *a, **kw):
31                Bundle.__init__(self, *a, **kw)
32                self.env = assets_env
33
34                self.dbg = kw.get('debug', None)
35
36                # Kind of hacky, but gives us access to the last Bundle
37                # instance used by the extension.
38                test_instance.the_bundle = self
39            def urls(self, *a, **kw):
40                return self.urls_to_fake
41        self._old_bundle_class = AssetsExtension.BundleClass
42        AssetsExtension.BundleClass = self.BundleClass = MockBundle
43
44        # Setup the Jinja2 environment.
45        self.jinja_env = JinjaEnvironment()
46        self.jinja_env.add_extension(AssetsExtension)
47        self.jinja_env.assets_environment = assets_env
48
49    def teardown(self):
50        AssetsExtension.BundleClass = self._old_bundle_class
51        del self._old_bundle_class
52
53    def render_template(self, args, ctx=None):
54        return self.jinja_env.from_string(
55            '{% assets '+args+' %}{{ ASSET_URL }};{% endassets %}')\
56                .render(ctx or {})
57
58    def render_template_sri(self, args, ctx=None):
59        return self.jinja_env.from_string(
60            '{% assets '+args+' %}{{ ASSET_URL }}[{{ ASSET_SRI|default(\'NOT_SET\', true) }}];{% endassets %}')\
61                .render(ctx or {})
62
63    def test_reference_bundles(self):
64        self.render_template('"foo_bundle", "bar_bundle"')
65        assert self.the_bundle.contents == (self.foo_bundle, self.bar_bundle)
66
67    def test_reference_files(self):
68        self.render_template('"file1", "file2", "file3"')
69        assert self.the_bundle.contents == ('file1', 'file2', 'file3',)
70
71    def test_reference_files_list(self):
72        self.render_template('["file1", "file2", "file3"]')
73        assert self.the_bundle.contents == ('file1', 'file2', 'file3',)
74
75    def test_reference_files_tuple(self):
76        self.render_template('("file1", "file2", "file3")')
77        assert self.the_bundle.contents == ('file1', 'file2', 'file3',)
78
79    def test_reference_files_mixed(self):
80        self.render_template('"file1", ("file2", "file3")')
81        assert self.the_bundle.contents == ('file1', 'file2', 'file3',)
82
83    def test_reference_mixed(self):
84        self.render_template('"foo_bundle", "file2", "file3"')
85        assert self.the_bundle.contents == (self.foo_bundle, 'file2', 'file3',)
86
87    def test_with_vars(self):
88        self.render_template('var1, var2', {'var1': self.foo_bundle, 'var2': 'a_file'})
89        assert self.the_bundle.contents == (self.foo_bundle, 'a_file',)
90
91    def test_output_urls(self):
92        """Ensure the tag correctly spits out the urls the bundle returns.
93        """
94        self.BundleClass.urls_to_fake = ['foo', 'bar']
95        assert self.render_template('"file1" "file2" "file3"') == 'foo;bar;'
96
97    def test_output_urls_integrity(self):
98        """Ensure the tag correctly spits out the urls the bundle returns when using SRI.
99        """
100        self.BundleClass.urls_to_fake = [{'uri': 'foo'}, {'uri': 'bar', 'sri': 'TEST_SRI'}]
101        assert self.render_template_sri('"file1" "file2" "file3"') == 'foo[NOT_SET];bar[TEST_SRI];'
102
103    def test_debug_on_tag(self):
104        content = self.jinja_env.from_string(
105            '{% assets debug="True", "debug1.txt" %}{{ ASSET_URL }};{% endassets %}').render({})
106        assert self.the_bundle.dbg == 'True'
107
108    def test_extra_values(self):
109        self.foo_bundle.extra = {'moo': 42}
110        output = self.jinja_env.from_string(
111            '{% assets "foo_bundle" %}{{ EXTRA.moo }}{% endassets %}').render()
112        assert output == '42'
113
114
115class TestLoader(TempEnvironmentHelper):
116
117    default_files = {
118        'template.html': """
119            <h1>Test</h1>
120            {% if foo %}
121                {% assets "A", "B", "C", output="output.html" %}
122                    {{ ASSET_URL }}
123                {% endassets %}
124            {% endif %}
125            """
126    }
127
128    def setup(self):
129        TempEnvironmentHelper.setup(self)
130        self.jinja_env = JinjaEnvironment()
131        self.jinja_env.add_extension(AssetsExtension)
132        self.jinja_env.assets_environment = self.env
133
134    def test(self):
135        loader = Jinja2Loader(self.env, [self.tempdir], [self.jinja_env])
136        bundles = loader.load_bundles()
137        assert len(bundles) == 1
138        assert bundles[0].output == "output.html"
139