Commits

Jan-Jaap Driessen committed 0865cd9

If a resource is a mode (debug, minified) of a resource, its dependencies should be the same or a subset of the dependencies that this mode replaces. Fixes #63

Comments (0)

Files changed (2)

fanstatic/core.py

     """A resource has an unrecognized extension.
     """
 
+class ModeResourceDependencyError(Exception):
+    """A Mode Resource does not have the same dependencies as the
+    resource it replaces.
+    """
+
 # BBB backwards compatibility
 UnknownResourceExtension = UnknownResourceExtensionError
 
         self.init_dependency_nr()
 
         self.modes = {}
-        if debug is not None:
-            debug = self.modes[DEBUG] = normalize_string(library, debug)
-            debug.dependency_nr = self.dependency_nr
-            debug.library_nr = self.library_nr
-        if minified is not None:
-            minified = self.modes[MINIFIED] = normalize_string(
-                library, minified)
-            minified.dependency_nr = self.dependency_nr
-            minified.library_nr = self.library_nr
+        for mode_name, argument in [(DEBUG, debug), (MINIFIED, minified)]:
+            if argument is None:
+                continue
+            elif isinstance(argument, basestring):
+                mode_resource = Resource(library, argument)
+            else:
+                # The dependencies of a mode resource should be the same 
+                # or a subset of the dependencies this mode replaces.
+                if len(argument.depends - self.depends) > 0:
+                    raise ModeResourceDependencyError
+                mode_resource = argument
 
+            mode_resource.dependency_nr = self.dependency_nr
+            mode_resource.library_nr = self.library_nr
+            self.modes[mode_name] = mode_resource
 
         assert not isinstance(supersedes, basestring)
         self.supersedes = supersedes or []
     return result
 
 
-def normalize_string(library, resource):
-    if isinstance(resource, basestring):
-        return Resource(library, resource)
-    return resource
-
-
 class NeededResources(object):
     """The current selection of needed resources..
 

fanstatic/test_core.py

                        UnknownResourceError,
                        set_resource_file_existence_checking)
 
-from fanstatic.core import inclusion_renderers, normalize_string
+from fanstatic.core import inclusion_renderers
 from fanstatic.core import thread_local_needed_data
+from fanstatic.core import ModeResourceDependencyError
 from fanstatic.codegen import sort_resources_topological
 
 def test_resource():
     z2.need()
     assert needed.resources() == [x1, z1, z2]
 
+
+def test_check_resource_dependencies():
+    foo = Library('foo', '')
+
+    r1 = Resource(foo, 'r1.css')
+    r2 = Resource(foo, 'r2.css')
+    r3 = Resource(foo, 'r3.css', depends=[r1, r2])
+    # https://bitbucket.org/fanstatic/fanstatic/issue/63
+    # If a resource is a mode (debug, minified) of a resource, its
+    # dependencies should be the same or a subset of the dependencies that
+    # this mode replaces.
+    with pytest.raises(ModeResourceDependencyError):
+        Resource(foo, 'r4.css', depends=[r1], minified=r3)
+
+
 def test_normalize_string():
     foo = Library('foo', '')
-    assert isinstance(normalize_string(foo, 'f.css'), Resource)
-    r1 = Resource(foo, 'f.js')
-    assert normalize_string(foo, r1) == r1
+    r1 = Resource(foo, 'r1.css', minified='r1.min.css')
+    assert isinstance(r1.modes['minified'], Resource)
 
-    r2 = Resource(foo, 'r2.css')
-    r3 = Resource(foo, 'r3.css', depends=[r2], minified='r3.min.css')
-    needed = NeededResources(minified=True, resources=[r3])
-    assert needed.resources() == [r2, r3.modes['minified']]
 
 def test_sort_group_per_renderer():
     foo = Library('foo', '')