Commits

Jan-Jaap Driessen committed 37b8f3e

Add implementation and tests for Compiler that does not compile; the Resource can still define a minifier, which will be used.

Comments (0)

Files changed (3)

fanstatic/compiler.py

         """
         directory, filename = os.path.split(path)
         base, _ = os.path.splitext(filename)
-        mode = {MINIFIED: '-min', DEBUG: '-debug'}.get(mode, '')
-        return os.path.join(directory, '%s%s.%s' % (base, mode, cls.target_extension))
+        suffix = ''
+        if mode == MINIFIED and cls.minified:
+            suffix = '-min'
+        elif mode == DEBUG and cls.debug:
+            suffix = '-debug'
+        return os.path.join(directory, '%s%s.%s' % (base, suffix, cls.target_extension))
 
 
 class SCSS(Compiler):
     source_extension = 'scss'
     target_extension = 'css'
 
+    minified = True
+    debug = True
+
     @staticmethod
     def available():
         try:
                 self.modes[DEBUG] = self.mode_clone(DEBUG)
 
         elif self._mode == MINIFIED:
-            if self.compiler is None and self.minifier is not None:
+            if self.minifier is not None:
+                # The result path changes because we are using a minifier.
                 self.relpath = self.minifier.target_path(self.relpath)
 
                 # In devmode, the minifier should be available.
         if self.compiler is not None:
             self.compiler.process(self.fullpath, mode=self._mode, force=force)
         if self.minifier is not None:
-            self.minifier.process(self.fullpath, mode=self._mode, force=force)
-
+            path = self.fullpath
+            if self.compiler and not self.compiler.minified:
+                # If the compiler does not minify, we use the result of the compilation
+                # step as input for the minification step.
+                path = self.compiler.target_path(self.fullpath, mode=self._mode)
+            self.minifier.process(path, mode=self._mode, force=force)
 
     def render(self, library_url):
         return self.renderer('%s/%s' % (library_url, self.relpath))

fanstatic/test_compiler.py

     assert tmpdir.join('r1-debug.js').read() == '''\
 #  compile  ddeebbuugg  :frop'''
 
+    class DebugCompiler(Compiler):
+        target_extension = 'js'
+
+        minified = False
+        debug = True
+
+        @classmethod
+        def __call__(cls, path, mode=None):
+            # Make mode a part of the compilation:
+            open(cls.target_path(path, mode=mode), 'wb').write('# compiler:' + open(path).read())
+
+    # A resource with a compiler that only supplies a debug mode:
+    tmpdir.join('r2.comp').write('frop2')
+    r2 = Resource(foo, 'r2.comp', compiler=DebugCompiler)
+
+    needed = NeededResources(resources=[r2])
+    assert needed.render() == '''\
+<script type="text/javascript" src="/fanstatic/foo/r2.js"></script>'''
+
+    needed_debug = NeededResources(resources=[r2], debug=True)
+    assert needed_debug.render() == '''\
+<script type="text/javascript" src="/fanstatic/foo/r2-debug.js"></script>'''
+
+    needed_minified = NeededResources(resources=[r2], minified=True)
+    assert needed_minified.render() == '''\
+<script type="text/javascript" src="/fanstatic/foo/r2.js"></script>'''
+
+    class Mini(Minifier):
+
+        @classmethod
+        def __call__(cls, path, mode=None):
+            input = open(path).read()
+            while '  ' in input:
+                input = input.replace('  ', ' ')
+            open(cls.target_path(path), 'w').write(input.strip())
+
+    tmpdir.join('r3.comp').write('    frop3      ')
+    r3 = Resource(foo, 'r3.comp', compiler=DebugCompiler, minifier=Mini)
+    needed_minified = NeededResources(resources=[r3], minified=True)
+    assert needed_minified.render() == '''\
+<script type="text/javascript" src="/fanstatic/foo/r3-min.js"></script>'''
+    # The minification step is applied by the minifier, not by the compiler.
+    assert tmpdir.join('r3-min.js').read() == '''\
+# compiler: frop3'''
+
 
 def test_compiler_bundle_interaction(tmpdir, monkeypatch):
     class Foo(Compiler):