Path: blob/develop/tests/unit/bcdoc/test_docstringparser.py
1567 views
# Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.1#2# Permission is hereby granted, free of charge, to any person obtaining a3# copy of this software and associated documentation files (the4# "Software"), to deal in the Software without restriction, including5# without limitation the rights to use, copy, modify, merge, publish, dis-6# tribute, sublicense, and/or sell copies of the Software, and to permit7# persons to whom the Software is furnished to do so, subject to the fol-8# lowing conditions:9#10# The above copyright notice and this permission notice shall be included11# in all copies or substantial portions of the Software.12#13# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS14# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-15# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT16# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,17# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,18# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS19# IN THE SOFTWARE.20from awscli.testutils import mock, unittest2122import awscli.bcdoc.docstringparser as parser23from awscli.bcdoc.restdoc import ReSTDocument242526class TestDocStringParser(unittest.TestCase):27def parse(self, html):28docstring_parser = parser.DocStringParser(ReSTDocument())29docstring_parser.feed(html)30docstring_parser.close()31return docstring_parser.doc.getvalue()3233def assert_contains_exact_lines_in_order(self, actual, expected):34# Get each line and filter out empty lines35contents = actual.split(b'\n')36contents = [line for line in contents if line and not line.isspace()]3738for line in expected:39self.assertIn(line, contents)40beginning = contents.index(line)41contents = contents[beginning:]4243def test_nested_lists(self):44html = "<ul><li>Wello</li><ul><li>Horld</li></ul></ul>"45result = self.parse(html)46self.assert_contains_exact_lines_in_order(result, [47b'* Wello',48b' * Horld'49])5051def test_nested_lists_with_extra_white_space(self):52html = "<ul> <li> Wello</li><ul> <li> Horld</li></ul></ul>"53result = self.parse(html)54self.assert_contains_exact_lines_in_order(result, [55b'* Wello',56b' * Horld'57])585960class TestHTMLTree(unittest.TestCase):61def setUp(self):62self.style = mock.Mock()63self.doc = mock.Mock()64self.doc.style = self.style65self.tree = parser.HTMLTree(self.doc)6667def test_add_tag(self):68self.tree.add_tag('foo')69self.assertIsInstance(self.tree.current_node, parser.TagNode)70self.assertEqual(self.tree.current_node.tag, 'foo')7172def test_add_unsupported_tag(self):73del self.style.start_foo74del self.style.end_foo75self.tree.add_tag('foo')76self.assertIn('foo', self.tree.unhandled_tags)7778def test_add_data(self):79self.tree.add_data('foo')80self.assertNotIsInstance(self.tree.current_node, parser.DataNode)81node = self.tree.head.children[0]82self.assertIsInstance(node, parser.DataNode)83self.assertEqual(node.data, 'foo')848586class TestStemNode(unittest.TestCase):87def setUp(self):88self.style = mock.Mock()89self.doc = mock.Mock()90self.doc.style = self.style91self.node = parser.StemNode()9293def test_add_child(self):94child = parser.StemNode()95self.node.add_child(child)96self.assertIn(child, self.node.children)97self.assertEqual(child.parent, self.node)9899def test_write(self):100self.node.add_child(mock.Mock())101self.node.add_child(mock.Mock())102103self.node.write(mock.Mock())104for child in self.node.children:105self.assertTrue(child.write.called)106107108class TestTagNode(unittest.TestCase):109def setUp(self):110self.style = mock.Mock()111self.doc = mock.Mock()112self.doc.style = self.style113self.tag = 'foo'114self.node = parser.TagNode(self.tag)115116def test_write_calls_style(self):117self.node.write(self.doc)118self.assertTrue(self.style.start_foo.called)119self.assertTrue(self.style.end_foo.called)120121def test_write_unsupported_tag(self):122del self.style.start_foo123del self.style.end_foo124125try:126self.node.write(self.doc)127except AttributeError as e:128self.fail(str(e))129130131class TestDataNode(unittest.TestCase):132def setUp(self):133self.style = mock.Mock()134self.doc = mock.Mock()135self.doc.style = self.style136137def test_string_data(self):138node = parser.DataNode('foo')139self.assertEqual(node.data, 'foo')140141def test_non_string_data_raises_error(self):142with self.assertRaises(ValueError):143parser.DataNode(5)144145def test_lstrip(self):146node = parser.DataNode(' foo')147node.lstrip()148self.assertEqual(node.data, 'foo')149150def test_write(self):151node = parser.DataNode('foo bar baz')152self.doc.translate_words.return_value = ['foo', 'bar', 'baz']153node.write(self.doc)154self.doc.handle_data.assert_called_once_with('foo bar baz')155156def test_write_space(self):157node = parser.DataNode(' ')158node.write(self.doc)159self.doc.handle_data.assert_called_once_with(' ')160self.doc.handle_data.reset_mock()161162node = parser.DataNode(' ')163node.write(self.doc)164self.doc.handle_data.assert_called_once_with(' ')165166def test_write_empty_string(self):167node = parser.DataNode('')168node.write(self.doc)169self.assertFalse(self.doc.handle_data.called)170171172class TestLineItemNode(unittest.TestCase):173def setUp(self):174self.style = mock.Mock()175self.doc = mock.Mock()176self.doc.style = self.style177self.doc.translate_words.return_value = ['foo']178self.node = parser.LineItemNode()179180def test_write_strips_white_space(self):181self.node.add_child(parser.DataNode(' foo'))182self.node.write(self.doc)183self.doc.handle_data.assert_called_once_with('foo')184185def test_write_strips_nested_white_space(self):186self.node.add_child(parser.DataNode(' '))187tag_child = parser.TagNode('foo')188tag_child.add_child(parser.DataNode(' '))189tag_child_2 = parser.TagNode('foo')190tag_child_2.add_child(parser.DataNode(' foo'))191tag_child.add_child(tag_child_2)192self.node.add_child(tag_child)193194self.node.write(self.doc)195self.doc.handle_data.assert_called_once_with('foo')196197def test_write_only_strips_until_text_is_found(self):198self.node.add_child(parser.DataNode(' '))199tag_child = parser.TagNode('foo')200tag_child.add_child(parser.DataNode(' '))201tag_child_2 = parser.TagNode('foo')202tag_child_2.add_child(parser.DataNode(' foo'))203tag_child_2.add_child(parser.DataNode(' '))204tag_child.add_child(tag_child_2)205self.node.add_child(tag_child)206207self.node.write(self.doc)208209calls = [mock.call('foo'), mock.call(' ')]210self.doc.handle_data.assert_has_calls(calls)211212213