def test_format_docstring_with_summary_that_ends_in_quote(self): self.assertEqual('''""""Hello"."""''', docformatter.format_docstring(' ', ''' """ "Hello" """ '''.strip()))
def test_format_docstring(self): self.assertEqual('"""Hello."""', docformatter.format_docstring(' ', ''' """ Hello. """ '''.strip()))
def test_format_docstring_with_single_quotes(self): self.assertEqual('"""Hello."""', docformatter.format_docstring(' ', """ ''' Hello. ''' """.strip()))
def set_summary_desc(self): doc = self.service_class.__doc__ if not doc: return split = doc.strip().splitlines() if not split: return summary = split[0] # format_docstring expects an empty line between summary and description if len(split) > 1: _doc = [] _doc.append(split[0]) _doc.append('') _doc.extend(split[1:]) doc = '\n'.join(_doc) # This gives us the full docstring out of which we need to extract description alone. full_docstring = format_docstring('', '"{}"'.format(doc), post_description_blank=False) full_docstring = full_docstring.lstrip('"""').rstrip('"""') description = full_docstring.splitlines() # If there are multiple lines and the second one is empty this means it is an indicator of a summary to follow. if len(description) > 1 and not description[1]: description = '\n'.join(description[2:]) else: description = '' # docformatter.normalize_summary adds superfluous period at end docstring. if full_docstring: if description and full_docstring[ -1] == '.' and full_docstring[-1] != description[-1]: full_docstring = full_docstring[:-1] if summary and full_docstring[ -1] == '.' and full_docstring[-1] != summary[-1]: full_docstring = full_docstring[:-1] summary = summary.strip() full_docstring = full_docstring.strip() # If we don't have any summary but there is a docstring at all then it must be a single-line one # and it becomes our summary. if full_docstring and not summary: summary = full_docstring # If we don't have description but we have summary then summary becomes description if summary and not description: description = summary self.docstring.summary = summary self.docstring.description = description self.docstring.full = full_docstring
def test_format_docstring_make_summary_multi_line(self): self.assertEqual(('''\ """ This one-line docstring will be multi-line. """\ '''), docformatter.format_docstring(' ', '''\ """This one-line docstring will be multi-line"""\ ''', make_summary_multi_line=True))
def test_format_docstring_should_underlined_summaries_alone(self): docstring = '''""" Foo bar ------- This is more. """''' self.assertEqual(docstring, docformatter.format_docstring(' ', docstring))
def test_format_docstring_for_one_line_summary_alone_but_too_long(self): self.assertEqual(('''\ """This one-line docstring will not be multi-line but quotes will be below. """\ '''), docformatter.format_docstring(' ', '''\ """This one-line docstring will not be multi-line but quotes will be below."""\ ''', summary_wrap_length=80))
def test_format_docstring_should_ignore__colon_parameter_lists(self): docstring = '''"""Hello. foo: This is a foo. This is a foo. This is a foo. This is a foo. This is. bar: This is a bar. This is a bar. This is a bar. This is a bar. This is. """''' self.assertEqual( docstring, docformatter.format_docstring(' ', docstring, description_wrap_length=72))
def test_force_wrap(self): self.assertEqual(('''\ """num_iterations is the number of updates - instead of a better definition of convergence."""\ '''), docformatter.format_docstring(' ', '''\ """ num_iterations is the number of updates - instead of a better definition of convergence. """\ ''', description_wrap_length=50, summary_wrap_length=50, force_wrap=True))
def test_format_docstring_should_ignore_doctests_in_summary(self): docstring = '''""" >>> 4 4 """''' self.assertEqual( docstring, docformatter.format_docstring(' ', docstring, description_wrap_length=72))
def test_format_docstring_for_multi_line_summary_alone(self): self.assertEqual(('''\ """This one-line docstring will be multi-line because it's quite long. """\ '''), docformatter.format_docstring(' ', '''\ """This one-line docstring will be multi-line because it's quite long."""\ ''', summary_wrap_length=69))
def test_format_docstring_should_underlined_summaries_alone(self): docstring = '''""" Foo bar ------- This is more. """''' self.assertEqual( docstring, docformatter.format_docstring(' ', docstring))
def test_format_docstring_should_ignore_numbered_lists(self): docstring = '''"""Hello. 1. This should be indented but it is not. The next line should be indented too. But this is okay. """''' self.assertEqual( docstring, docformatter.format_docstring(' ', docstring, description_wrap_length=72))
def test_format_docstring_with_single_quotes_multi_line(self): self.assertEqual(''' """Return x factorial. This uses math.factorial. """ '''.strip(), docformatter.format_docstring(' ', """ ''' Return x factorial. This uses math.factorial. ''' """.strip()))
def test_format_docstring_with_trailing_whitespace(self): self.assertEqual('''"""Hello. This should be not have trailing whitespace. The next line should not have trailing whitespace either. """''', docformatter.format_docstring(' ', ''' """Hello.\t \t This should be not have trailing whitespace. The\t\t\t next line should not have trailing whitespace either.\t \t """ '''.strip()))
def test_format_docstring_with_no_post_description_blank(self): self.assertEqual('''"""Hello. Description. """''', docformatter.format_docstring(' ', ''' """ Hello. Description. """ '''.strip(), post_description_blank=False))
def test_format_docstring_with_bad_indentation(self): self.assertEqual('''"""Hello. This should be indented but it is not. The next line should be indented too. And this too. """''', docformatter.format_docstring(' ', ''' """Hello. This should be indented but it is not. The next line should be indented too. And this too. """ '''.strip()))
def test_format_docstring_with_description_wrapping(self): self.assertEqual('''"""Hello. This should be indented but it is not. The next line should be indented too. But this is okay. """''', docformatter.format_docstring(' ', ''' """Hello. This should be indented but it is not. The next line should be indented too. But this is okay. """ '''.strip(), description_wrap_length=72))
def test_format_docstring_with_pre_summary_newline(self): self.assertEqual('''""" Hello. Description. """''', docformatter.format_docstring(' ', ''' """ Hello. Description. """ '''.strip(), pre_summary_newline=True))
def test_format_docstring_with_wrap(self): min_line_length = 30 for max_length in range(min_line_length, 100): for num_indents in range(0, 20): indentation = ' ' * num_indents formatted_text = indentation + docformatter.format_docstring( indentation=indentation, docstring=generate_random_docstring( max_word_length=min_line_length // 2), summary_wrap_length=max_length) for line in formatted_text.split('\n'): # It is not the formatter's fault if a word is too long to # wrap. if len(line.split()) > 1: self.assertLessEqual(len(line), max_length)
def test_format_docstring_should_leave_list_alone(self): docstring = '''""" one two three four five six seven eight nine ten eleven """''' self.assertEqual(docstring, docformatter.format_docstring(' ', docstring))
def test_format_docstring_should_maintain_indentation_of_doctest(self): self.assertEqual( '''"""Foo bar bing bang. >>> tests = DocTestFinder().find(_TestClass) >>> runner = DocTestRunner(verbose=False) >>> tests.sort(key = lambda test: test.name) """''', docformatter.format_docstring(' ', docstring='''"""Foo bar bing bang. >>> tests = DocTestFinder().find(_TestClass) >>> runner = DocTestRunner(verbose=False) >>> tests.sort(key = lambda test: test.name) """''', description_wrap_length=72))
def test_format_docstring_should_leave_list_alone(self): docstring = '''""" one two three four five six seven eight nine ten eleven """''' self.assertEqual( docstring, docformatter.format_docstring(' ', docstring))
def test_format_docstring_with_weird_indentation_and_punctuation(self): self.assertEqual(''' """Creates and returns four was awakens to was created tracked ammonites was the fifty, arithmetical four was pyrotechnic to pyrotechnic physicists. `four' falsified x falsified ammonites to awakens to. `created' to ancestor was four to x dynamo to was four ancestor to physicists(). """ '''.strip(), docformatter.format_docstring(' ', ''' """Creates and returns four was awakens to was created tracked ammonites was the fifty, arithmetical four was pyrotechnic to pyrotechnic physicists. `four' falsified x falsified ammonites to awakens to. `created' to ancestor was four to x dynamo to was four ancestor to physicists(). """ '''.strip(), summary_wrap_length=79))
def test_format_docstring_should_maintain_indentation_of_doctest(self): self.assertEqual( '''"""Foo bar bing bang. >>> tests = DocTestFinder().find(_TestClass) >>> runner = DocTestRunner(verbose=False) >>> tests.sort(key = lambda test: test.name) """''', docformatter.format_docstring( ' ', docstring='''"""Foo bar bing bang. >>> tests = DocTestFinder().find(_TestClass) >>> runner = DocTestRunner(verbose=False) >>> tests.sort(key = lambda test: test.name) """''', description_wrap_length=72))
def test_format_docstring_with_too_much_indentation(self): self.assertEqual('''"""Hello. This should be dedented. 1. This too. 2. And this. 3. And this. """''', docformatter.format_docstring(' ', ''' """Hello. This should be dedented. 1. This too. 2. And this. 3. And this. """ '''.strip()))
def test_format_docstring_with_wrap(self): # This function uses `random` so make sure each run of this test is # repeatable. random.seed(0) min_line_length = 50 for max_length in range(min_line_length, 100): for num_indents in range(0, 20): indentation = ' ' * num_indents formatted_text = indentation + docformatter.format_docstring( indentation=indentation, docstring=generate_random_docstring( max_word_length=min_line_length // 2), summary_wrap_length=max_length) for line in formatted_text.split('\n'): # It is not the formatter's fault if a word is too long to # wrap. if len(line.split()) > 1: self.assertLessEqual(len(line), max_length)
def set_summary_desc(self): if not self.service_class.__doc__: return summary, _ = split_docstring(self.service_class.__doc__) # This gives us the full docstring out of which we need to extract description alone. full_docstring = format_docstring('', '"{}"'.format(self.service_class.__doc__), post_description_blank=False) description = full_docstring.lstrip('"""').rstrip('"""').splitlines() # If there are multiple lines and the second one is empty this means it is an indicator of a summary to follow. if len(description) > 1 and not description[1]: description = '\n'.join(description[2:]) else: description = '' self.docstring.summary = summary.strip() self.docstring.description = description self.docstring.full = full_docstring
def _parse_split_segment(self, tag, split, is_tag_internal, prefix_with_tag): # type: (str, list, bool, bool) -> _DocstringSegment if is_tag_internal: split.insert(0, not_public) # For implicit tags (e.g. public), the summary will be under index 0, # but for tags named explicitly, index 0 may be an empty element # and the summary will be under index 1. summary = split[0] or split[1] # format_docstring expects an empty line between summary and description if len(split) > 1: _doc = [] _doc.append(split[0]) _doc.append('') _doc.extend(split[1:]) doc = '\n'.join(_doc) else: doc = '' # This gives us the full docstring out of which we need to extract description alone. full_docstring = format_docstring('', '"{}"'.format(doc), post_description_blank=False) full_docstring = full_docstring.lstrip('"""').rstrip('"""') description = full_docstring.splitlines() # If there are multiple lines and the second one is empty this means it is an indicator of a summary to follow. if len(description) > 1 and not description[1]: description = '\n'.join(description[2:]) else: description = '' # Function docformatter.normalize_summary adds a superfluous period at the end of docstring. if full_docstring: if description and full_docstring[-1] == '.' and full_docstring[-1] != description[-1]: full_docstring = full_docstring[:-1] if summary and full_docstring[-1] == '.' and full_docstring[-1] != summary[-1]: full_docstring = full_docstring[:-1] # If we don't have any summary but there is a docstring at all then it must be a single-line one # and it becomes our summary. if full_docstring and not summary: summary = full_docstring # If we don't have description but we have summary then summary becomes description and full docstring as well if summary and not description: description = summary full_docstring = summary summary = summary.lstrip() # This is needed in case we have one of the tags # that need a highlight because they contain information # that is internal to users generating the specification. tag_html = tag if is_tag_internal: tag_html = tag_html_internal.format(tag) else: tag_html = tag if prefix_with_tag: description = '\n\n{}\n{}'.format(tag_html, description) full_docstring = '\n{}\n\n{}'.format(tag_html, full_docstring) out = _DocstringSegment() out.tag = tag.replace('@', '', 1) out.summary = summary out.description = description out.full = full_docstring return out
def test_format_docstring_with_empty_docstring(self): self.assertEqual('""""""', docformatter.format_docstring(' ', '""""""'))