Example #1
0
 def test_reorder_automatic_with_start(self):
     """Verify items can be reordered with a given start."""
     mock_item = Mock(level=Level('2.3'))
     mock_items = [Mock(level=Level('2.2')),
                   mock_item,
                   Mock(level=Level('2.3')),
                   Mock(level=Level('2.7')),
                   Mock(level=Level('3.2.2')),
                   Mock(level=Level('3.4.2')),
                   Mock(level=Level('3.5.0')),
                   Mock(level=Level('3.5.0')),
                   Mock(level=Level('3.6')),
                   Mock(level=Level('5.0')),
                   Mock(level=Level('5.9'))]
     expected = [Level('1.2'),
                 Level('1.3'),
                 Level('1.4'),
                 Level('1.5'),
                 Level('2.1.1'),
                 Level('2.2.1'),
                 Level('2.3.0'),
                 Level('2.4.0'),
                 Level('2.5'),
                 Level('3.0'),
                 Level('3.1')]
     Document._reorder_automatic(mock_items, start=(1, 2), keep=mock_item)
     actual = [item.level for item in mock_items]
     self.assertListEqual(expected, actual)
Example #2
0
 def test_reorder_automatic(self):
     """Verify items can be reordered automatically."""
     mock_items = [Mock(level=Level('2.3')),
                   Mock(level=Level('2.3')),
                   Mock(level=Level('2.7')),
                   Mock(level=Level('3.2.2')),
                   Mock(level=Level('3.4.2')),
                   Mock(level=Level('3.5.0')),
                   Mock(level=Level('3.5.0')),
                   Mock(level=Level('3.6')),
                   Mock(level=Level('5.0')),
                   Mock(level=Level('5.9'))]
     expected = [Level('2.3'),
                 Level('2.4'),
                 Level('2.5'),
                 Level('3.1.1'),
                 Level('3.2.1'),
                 Level('3.3.0'),
                 Level('3.4.0'),
                 Level('3.5'),
                 Level('4.0'),
                 Level('4.1')]
     Document._reorder_automatic(mock_items)
     actual = [item.level for item in mock_items]
     self.assertListEqual(expected, actual)
Example #3
0
 def test_reorder_automatic(self):
     """Verify items can be reordered automatically."""
     mock_items = [
         Mock(level=Level('2.3')),
         Mock(level=Level('2.3')),
         Mock(level=Level('2.7')),
         Mock(level=Level('3.2.2')),
         Mock(level=Level('3.4.2')),
         Mock(level=Level('3.5.0')),
         Mock(level=Level('3.5.0')),
         Mock(level=Level('3.6')),
         Mock(level=Level('5.0')),
         Mock(level=Level('5.9'))
     ]
     expected = [
         Level('2.3'),
         Level('2.4'),
         Level('2.5'),
         Level('3.1.1'),
         Level('3.2.1'),
         Level('3.3.0'),
         Level('3.4.0'),
         Level('3.5'),
         Level('4.0'),
         Level('4.1')
     ]
     Document._reorder_automatic(mock_items)
     actual = [item.level for item in mock_items]
     self.assertListEqual(expected, actual)
Example #4
0
    def test_reorder_from_index_add(self):
        """Verify items can be added when reordering from an index."""
        data = {
            'initial': 2.0,
            'outline': [
                {'a': None},
                {
                    'b': [
                        {'ba': [{'baa': None}, {'new': None}, {'bac': None}]},
                        {'bb': [{'new': [{'text': 'item_text'}]}]},
                    ]
                },
                {'c': None},
            ],
        }
        expected = [
            Level('2'),
            Level('3.0'),
            Level('3.1.0'),
            Level('3.1.1'),
            Level('3.1.2'),
            Level('3.1.3'),
            Level('3.2.0'),
            Level('3.2.1'),
            Level('4'),
        ]
        # Act
        self.document._read_index = MagicMock(return_value=data)
        Document._reorder_from_index(self.document, 'mock_path')

        # Assert
        self.document._read_index.assert_called_once_with('mock_path')
        actual = [item.level for item in self.document.items]
        self.assertListEqual(expected, actual)
        self.assertEqual(self.document.items[-2].text, 'item_text')
Example #5
0
 def test_reorder_automatic_with_start(self):
     """Verify items can be reordered with a given start."""
     mock_item = Mock(level=Level('2.3'))
     mock_items = [
         Mock(level=Level('2.2')), mock_item,
         Mock(level=Level('2.3')),
         Mock(level=Level('2.7')),
         Mock(level=Level('3.2.2')),
         Mock(level=Level('3.4.2')),
         Mock(level=Level('3.5.0')),
         Mock(level=Level('3.5.0')),
         Mock(level=Level('3.6')),
         Mock(level=Level('5.0')),
         Mock(level=Level('5.9'))
     ]
     expected = [
         Level('1.2'),
         Level('1.3'),
         Level('1.4'),
         Level('1.5'),
         Level('2.1.1'),
         Level('2.2.1'),
         Level('2.3.0'),
         Level('2.4.0'),
         Level('2.5'),
         Level('3.0'),
         Level('3.1')
     ]
     Document._reorder_automatic(mock_items, start=(1, 2), keep=mock_item)
     actual = [item.level for item in mock_items]
     self.assertListEqual(expected, actual)
Example #6
0
    def test_reorder_from_index_add(self):
        """Verify items can be added when reordering from an index."""
        data = {'initial': 2.0,
                'outline': [
                    {'a': None},
                    {'b': [
                        {'ba': [
                            {'baa': None},
                            {'new': None},
                            {'bac': None}]},
                        {'bb': [
                            {'new': [{'text': 'item_text'}]}]}]},
                    {'c': None}]}
        expected = [Level('2'),
                    Level('3.0'),
                    Level('3.1.0'),
                    Level('3.1.1'),
                    Level('3.1.2'),
                    Level('3.1.3'),
                    Level('3.2.0'),
                    Level('3.2.1'),
                    Level('4')]
        # Act
        self.document._read_index = MagicMock(return_value=data)
        Document._reorder_from_index(self.document, 'mock_path')

        # Assert
        self.document._read_index.assert_called_once_with('mock_path')
        actual = [item.level for item in self.document.items]
        self.assertListEqual(expected, actual)
        self.assertEqual(self.document.items[-2].text, 'item_text')
Example #7
0
    def test_reorder_from_index(self):
        """Verify items can be reordered from an index."""
        mock_items = []

        def mock_find_item(uid):
            """Return a mock item and store it."""
            mock_item = MagicMock()
            if uid == 'bb':
                mock_item.level = Level('3.2')
            elif uid == 'bab':
                raise DoorstopError("unknown UID: bab")
            mock_item.uid = uid
            mock_items.append(mock_item)
            return mock_item

        mock_document = Mock()
        mock_document.find_item = mock_find_item

        data = {
            'initial':
            2.0,
            'outline': [{
                'a': None
            }, {
                'b': [{
                    'ba': [{
                        'baa': None
                    }, {
                        'bab': None
                    }, {
                        'bac': None
                    }]
                }, {
                    'bb': None
                }]
            }, {
                'c': None
            }]
        }
        expected = [
            Level('2'),
            Level('3.0'),
            Level('3.1.0'),
            Level('3.1.1'),
            Level('3.1.3'),
            Level('3.2'),
            Level('4')
        ]

        # Act
        with patch('doorstop.common.read_text') as mock_read_text:
            with patch('doorstop.common.load_yaml', Mock(return_value=data)):
                Document._reorder_from_index(mock_document, 'mock_path')

        # Assert
        mock_read_text.assert_called_once_with('mock_path')
        actual = [item.level for item in mock_items]
        self.assertListEqual(expected, actual)
Example #8
0
    def test_reorder_from_index_delete(self):
        """Verify items can be deleted when reordering from an index."""
        data = {
            'initial':
            2.0,
            'outline': [{
                'a': None
            }, {
                'b': [{
                    'ba': [{
                        'baa': None
                    }, {
                        'bab': None
                    }, {
                        'bac': None
                    }]
                }, {
                    'bb': [{
                        'bba': None
                    }]
                }]
            }, {
                'c': None
            }]
        }
        expected = [
            Level('2'),
            Level('3.0'),
            Level('3.1.0'),
            Level('3.1.1'),
            Level('3.1.2'),
            Level('3.1.3'),
            Level('3.2.0'),
            Level('3.2.1'),
            Level('4')
        ]

        mock_item = self.document.add_item()
        # Act
        self.document._read_index = MagicMock(return_value=data)
        Document._reorder_from_index(self.document, 'mock_path')

        # Assert
        self.document._read_index.assert_called_once_with('mock_path')
        items = []
        for item in self.document.items:
            if item is not mock_item:
                items.append(item)
        actual = [item.level for item in items]
        self.assertListEqual(expected, actual)
        self.assertEqual(mock_item.method_calls, [call.delete()])
Example #9
0
 def test_reorder_automatic_no_change(self):
     """Verify already ordered items can be reordered."""
     mock_items = [Mock(level=Level('1.1')),
                   Mock(level=Level('1.1.1.1')),
                   Mock(level=Level('2')),
                   Mock(level=Level('3')),
                   Mock(level=Level('4.1.1'))]
     expected = [Level('1.1'),
                 Level('1.1.1.1'),
                 Level('2'),
                 Level('3'),
                 Level('4.1.1')]
     Document._reorder_automatic(mock_items)
     actual = [item.level for item in mock_items]
     self.assertListEqual(expected, actual)
Example #10
0
 def test_reorder_automatic_no_change(self):
     """Verify already ordered items can be reordered."""
     mock_items = [Mock(level=Level('1.1')),
                   Mock(level=Level('1.1.1.1')),
                   Mock(level=Level('2')),
                   Mock(level=Level('3')),
                   Mock(level=Level('4.1.1'))]
     expected = [Level('1.1'),
                 Level('1.1.1.1'),
                 Level('2'),
                 Level('3'),
                 Level('4.1.1')]
     Document._reorder_automatic(mock_items)
     actual = [item.level for item in mock_items]
     self.assertListEqual(expected, actual)
Example #11
0
    def create_document(self, path, value, sep=None, digits=None, parent=None):  # pylint: disable=R0913
        """Create a new document and add it to the tree.

        :param path: directory path for the new document
        :param value: document or prefix
        :param sep: separator between prefix and numbers
        :param digits: number of digits for the document's numbers
        :param parent: parent document's prefix

        :raises: :class:`~doorstop.common.DoorstopError` if the
            document cannot be created

        :return: newly created and placed document
            :class:`~doorstop.core.document.Document`

        """
        prefix = Prefix(value)
        document = Document.new(self,
                                path,
                                self.root,
                                prefix,
                                sep=sep,
                                digits=digits,
                                parent=parent)
        try:
            self._place(document)
        except DoorstopError:
            msg = "deleting unplaced directory {}...".format(document.path)
            log.debug(msg)
            document.delete()
            raise
        else:
            log.info("added to tree: {}".format(document))
        return document
Example #12
0
def create_document(prefix, path, parent=None, tree=None):
    """Create a Doorstop document from existing document information.

    :param prefix: existing document's prefix (for new items)
    :param path: new directory path to store this document's items
    :param parent: parent document's prefix (if one will exist)
    :param tree: explicit tree to add the document

    :return: imported Document

    """
    if not tree:
        tree = _get_tree()

    # Attempt to create a document with the given parent
    log.info("importing document '{}'...".format(prefix))
    try:
        document = tree.create_document(path, prefix, parent=parent)
    except DoorstopError as exc:
        if not parent:
            raise exc from None

        # Create the document despite an unavailable parent
        document = Document.new(tree,
                                path, tree.root, prefix,
                                parent=parent)
        log.warning(exc)
        _documents.append(document)

    # TODO: attempt to place unplaced documents?

    log.info("imported: {}".format(document))
    return document
Example #13
0
    def create_document(self, path, value, sep=None, digits=None, parent=None):  # pylint: disable=R0913
        """Create a new document and add it to the tree.

        :param path: directory path for the new document
        :param value: document or prefix
        :param sep: separator between prefix and numbers
        :param digits: number of digits for the document's numbers
        :param parent: parent document's prefix

        :raises: :class:`~doorstop.common.DoorstopError` if the
            document cannot be created

        :return: newly created and placed document
            :class:`~doorstop.core.document.Document`

        """
        prefix = Prefix(value)
        document = Document.new(self,
                                path, self.root, prefix, sep=sep,
                                digits=digits, parent=parent)
        try:
            self._place(document)
        except DoorstopError:
            msg = "deleting unplaced directory {}...".format(document.path)
            log.debug(msg)
            document.delete()
            raise
        else:
            log.info("added to tree: {}".format(document))
        return document
Example #14
0
def create_document(prefix, path, parent=None, tree=None):
    """Create a Doorstop document from existing document information.

    :param prefix: existing document's prefix (for new items)
    :param path: new directory path to store this document's items
    :param parent: parent document's prefix (if one will exist)
    :param tree: explicit tree to add the document

    :return: imported Document

    """
    if not tree:
        tree = _get_tree()

    # Attempt to create a document with the given parent
    log.info("importing document '{}'...".format(prefix))
    try:
        document = tree.create_document(path, prefix, parent=parent)
    except DoorstopError as exc:
        if not parent:
            raise exc from None

        # Create the document despite an unavailable parent
        document = Document.new(tree, path, tree.root, prefix, parent=parent)
        log.warning(exc)
        _documents.append(document)

    # TODO: attempt to place unplaced documents?

    log.info("imported: {}".format(document))
    return document
Example #15
0
    def test_reorder_from_index(self):
        """Verify items can be reordered from an index."""
        mock_items = []

        def mock_find_item(uid):
            """Return a mock item and store it."""
            mock_item = MagicMock()
            if uid == 'bb':
                mock_item.level = Level('3.2')
            elif uid == 'bab':
                raise DoorstopError("unknown UID: bab")
            mock_item.uid = uid
            mock_items.append(mock_item)
            return mock_item

        mock_document = Mock()
        mock_document.find_item = mock_find_item

        data = {'initial': 2.0,
                'outline': [
                    {'a': None},
                    {'b': [
                        {'ba': [
                            {'baa': None},
                            {'bab': None},
                            {'bac': None}]},
                        {'bb': None}]},
                    {'c': None}]}
        expected = [Level('2'),
                    Level('3.0'),
                    Level('3.1.0'),
                    Level('3.1.1'),
                    Level('3.1.3'),
                    Level('3.2'),
                    Level('4')]

        # Act
        with patch('doorstop.common.read_text') as mock_read_text:
            with patch('doorstop.common.load_yaml', Mock(return_value=data)):
                Document._reorder_from_index(mock_document, 'mock_path')

        # Assert
        mock_read_text.assert_called_once_with('mock_path')
        actual = [item.level for item in mock_items]
        self.assertListEqual(expected, actual)
Example #16
0
 def test_publish_document_template(self, mock_publish):
     """Verify 'doorstop publish' is called with template."""
     path = os.path.join(self.temp, 'req.html')
     self.assertIs(
         None, main(['publish', '--template', 'my_template.html', 'req', path])
     )
     mock_publish.assert_called_once_with(
         Document(os.path.abspath(REQS)), path, '.html', template='my_template.html'
     )
Example #17
0
 def setUp(self):
     document = Document(SYS)
     self.tree = Tree(document)
     document.tree = self.tree
     document = Document(FILES)
     self.tree._place(document)  # pylint: disable=W0212
     document.tree = self.tree
Example #18
0
    def test_reorder_from_index_delete(self):
        """Verify items can be deleted when reordering from an index."""
        data = {'initial': 2.0,
                'outline': [
                    {'a': None},
                    {'b': [
                        {'ba': [
                            {'baa': None},
                            {'bab': None},
                            {'bac': None}]},
                        {'bb': [
                            {'bba': None}]}]},
                    {'c': None}]}
        expected = [Level('2'),
                    Level('3.0'),
                    Level('3.1.0'),
                    Level('3.1.1'),
                    Level('3.1.2'),
                    Level('3.1.3'),
                    Level('3.2.0'),
                    Level('3.2.1'),
                    Level('4')]

        mock_item = self.document.add_item()
        # Act
        self.document._read_index = MagicMock(return_value=data)
        Document._reorder_from_index(self.document, 'mock_path')

        # Assert
        self.document._read_index.assert_called_once_with('mock_path')
        items = []
        for item in self.document.items:
            if item is not mock_item:
                items.append(item)
        actual = [item.level for item in items]
        self.assertListEqual(expected, actual)
        self.assertEqual(mock_item.method_calls, [call.delete()])
Example #19
0
def _document_from_path(path, root, documents):
    """Attempt to create and append a document from the specified path.

    :param path: path to a potential document
    :param root: path to root of working copy
    :param documents: list of :class:`~doorstop.core.document.Document`
        to append results

    """
    try:
        document = Document(path, root, tree=None)  # tree attached later
    except DoorstopError:
        pass  # no document in directory
    else:
        if document.skip:
            log.debug("skipped document: {}".format(document))
        else:
            log.info("found document: {}".format(document))
            documents.append(document)
Example #20
0
 def test_publish_document_to_stdout(self, mock_publish_lines):
     """Verify 'doorstop publish_lines' is called when no output path specified"""
     self.assertIs(None, main(['publish', 'req']))
     mock_publish_lines.assert_called_once_with(
         Document(os.path.abspath(REQS)), '.txt')