def test_root_nodes_are_reversed_ordered(self): items = ['policy', 'xy', 'foo'] self.assertEqual(['xy', 'policy', 'foo'], topological_sort(items, (('policy', 'foo'), ))) self.assertEqual(['xy', 'policy', 'foo'], topological_sort(reversed(items), (('policy', 'foo'), )), 'items input order should not change result order')
def test_root_nodes_are_reversed_ordered(self): items = ['policy', 'xy', 'foo'] self.assertEqual( ['xy', 'policy', 'foo'], topological_sort(items, (('policy', 'foo'),))) self.assertEqual( ['xy', 'policy', 'foo'], topological_sort(reversed(items), (('policy', 'foo'),)), 'items input order should not change result order')
def test_cyclic(self): items = ['a', 'b'] dependencies = ( ('a', 'b'), ('b', 'a')) self.assertEqual(None, topological_sort(items, dependencies))
def test_duplicated(self): items = ['a', 'b', 'a'] dependencies = ( ('b', 'a'), ) self.assertEqual(['b', 'a'], topological_sort(items, dependencies))
def test_simple(self): items = ['b', 'a', 'c'] dependencies = ( ('a', 'b'), ('b', 'c')) self.assertEqual(['a', 'b', 'c'], topological_sort(items, dependencies))
def test_advanced(self): items = ['a', 'c', 'b', 'd'] dependencies = ( ('a', 'b'), ('a', 'c'), ('b', 'd'), ('b', 'c')) self.assertEqual(['a', 'b', 'c', 'd'], topological_sort(items, dependencies))
def get_sorted_profile_ids(portal_setup, mixin_dependencies): """Returns a sorted list of profile ids (without profile- prefix). The sorting is done by resolving the dependencies and performing a topological graph sort. If there are circular dependencies a CyclicDependencies exception is thrown. """ profile_ids = [] dependencies = [] for profile in portal_setup.listProfileInfo(): profile_ids.append(profile['id']) for profile in portal_setup.listProfileInfo(): if not profile.get('dependencies'): continue profile_dependencies = list(profile.get('dependencies') or []) if profile.get('id') in mixin_dependencies: profile_dependencies.extend(mixin_dependencies[profile['id']]) for dependency in profile_dependencies: if dependency.startswith('profile-'): dependency = dependency.split('profile-', 1)[1] else: continue if dependency not in profile_ids: continue dependencies.append((profile['id'], dependency)) order = topological_sort(profile_ids, dependencies) if order is None: raise CyclicDependencies(dependencies) else: return list(reversed(order))