def test_sort_decorated_projects_cycles(self):
        def create_mock(path, depend):
            m = Mock()
            m.path = path
            m.depends_for_topological_order = set([depend])
            m.message_generator = False
            return m

        # creating a cycle for cycle detection
        mock1 = create_mock('mock1', 'mock2')
        mock2 = create_mock('mock2', 'mock3')
        mock3 = create_mock('mock3', 'mock4')
        mock4 = create_mock('mock4', 'mock2')

        projects = {'mock3': mock3, 'mock2': mock2, 'mock1': mock1, 'mock4': mock4}
        sprojects = _sort_decorated_projects(projects)
        self.assertEqual([[None, 'mock2, mock3, mock4']], sprojects)

        # remove cycle
        mock4.depends_for_topological_order = set()
        sprojects = _sort_decorated_projects(projects)

        # mock4 first since it has no dependencies
        # than mock3 since it only had mock4 as a dependency
        # than mock2 since it only had mock3 as a dependency
        # than mock1 since it only had mock2 as a dependency
        self.assertEqual(['mock4', 'mock3', 'mock2', 'mock1'], [path for path, _ in sprojects])
    def test_sort_decorated_projects(self):
        projects = {}
        sprojects = _sort_decorated_projects(projects)
        self.assertEqual([], sprojects)

        def create_mock(path):
            m = Mock()
            m.path = path
            m.depends_for_topological_order = set()
            m.message_generator = False
            return m

        mock1 = create_mock('mock1')
        mock2 = create_mock('mock2')
        mock3 = create_mock('mock3')
        mock3.message_generator = True

        projects = {'mock3': mock3, 'mock2': mock2, 'mock1': mock1}
        sprojects = _sort_decorated_projects(projects)

        # mock3 first since it is a message generator
        # mock1 before mock2 due to alphabetic order 
        self.assertEqual(['mock3', 'mock1', 'mock2'], [path for path, _ in sprojects])
    def test_sort_decorated_projects_favoring_message_generators(self):
        def create_mock(path):
            m = Mock()
            m.path = path
            m.depends_for_topological_order = set()
            m.message_generator = False
            return m

        mock1 = create_mock('mock1')
        mock2 = create_mock('mock2')
        mock3 = create_mock('mock3')
        mock3.depends_for_topological_order = set(['mock2'])
        mock3.message_generator = True

        projects = {'mock3': mock3, 'mock2': mock2, 'mock1': mock1}
        sprojects = _sort_decorated_projects(projects)

        # mock2 first since it is the dependency of a message generator
        # mock3 since it is a message generator
        # mock1 last, although having no dependencies and being first in alphabetic order 
        self.assertEqual(['mock2', 'mock3', 'mock1'], [path for path, _ in sprojects])