1#!/usr/bin/env python 2# 3# Copyright 2009 The Closure Library Authors. All Rights Reserved. 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS-IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17 18"""Unit test for depstree.""" 19 20__author__ = 'nnaze@google.com (Nathan Naze)' 21 22 23import unittest 24 25import depstree 26 27 28def _GetProvides(sources): 29 """Get all namespaces provided by a collection of sources.""" 30 31 provides = set() 32 for source in sources: 33 provides.update(source.provides) 34 return provides 35 36 37class MockSource(object): 38 """Mock Source file.""" 39 40 def __init__(self, provides, requires): 41 self.provides = set(provides) 42 self.requires = set(requires) 43 44 def __repr__(self): 45 return 'MockSource %s' % self.provides 46 47 48class DepsTreeTestCase(unittest.TestCase): 49 """Unit test for DepsTree. Tests several common situations and errors.""" 50 51 def AssertValidDependencies(self, deps_list): 52 """Validates a dependency list. 53 54 Asserts that a dependency list is valid: For every source in the list, 55 ensure that every require is provided by a source earlier in the list. 56 57 Args: 58 deps_list: A list of sources that should be in dependency order. 59 """ 60 61 for i in range(len(deps_list)): 62 source = deps_list[i] 63 previous_provides = _GetProvides(deps_list[:i]) 64 for require in source.requires: 65 self.assertTrue( 66 require in previous_provides, 67 'Namespace "%s" not provided before required by %s' % ( 68 require, source)) 69 70 def testSimpleDepsTree(self): 71 a = MockSource(['A'], ['B', 'C']) 72 b = MockSource(['B'], []) 73 c = MockSource(['C'], ['D']) 74 d = MockSource(['D'], ['E']) 75 e = MockSource(['E'], []) 76 77 tree = depstree.DepsTree([a, b, c, d, e]) 78 79 self.AssertValidDependencies(tree.GetDependencies('A')) 80 self.AssertValidDependencies(tree.GetDependencies('B')) 81 self.AssertValidDependencies(tree.GetDependencies('C')) 82 self.AssertValidDependencies(tree.GetDependencies('D')) 83 self.AssertValidDependencies(tree.GetDependencies('E')) 84 85 def testCircularDependency(self): 86 # Circular deps 87 a = MockSource(['A'], ['B']) 88 b = MockSource(['B'], ['C']) 89 c = MockSource(['C'], ['A']) 90 91 tree = depstree.DepsTree([a, b, c]) 92 93 self.assertRaises(depstree.CircularDependencyError, 94 tree.GetDependencies, 'A') 95 96 def testRequiresUndefinedNamespace(self): 97 a = MockSource(['A'], ['B']) 98 b = MockSource(['B'], ['C']) 99 c = MockSource(['C'], ['D']) # But there is no D. 100 101 def MakeDepsTree(): 102 return depstree.DepsTree([a, b, c]) 103 104 self.assertRaises(depstree.NamespaceNotFoundError, MakeDepsTree) 105 106 def testDepsForMissingNamespace(self): 107 a = MockSource(['A'], ['B']) 108 b = MockSource(['B'], []) 109 110 tree = depstree.DepsTree([a, b]) 111 112 # There is no C. 113 self.assertRaises(depstree.NamespaceNotFoundError, 114 tree.GetDependencies, 'C') 115 116 def testMultipleRequires(self): 117 a = MockSource(['A'], ['B']) 118 b = MockSource(['B'], ['C']) 119 c = MockSource(['C'], []) 120 d = MockSource(['D'], ['B']) 121 122 tree = depstree.DepsTree([a, b, c, d]) 123 self.AssertValidDependencies(tree.GetDependencies(['D', 'A'])) 124 125 126if __name__ == '__main__': 127 unittest.main() 128