From b8fa93ec17949b92bc0d7286767fa8213cfbaf3d Mon Sep 17 00:00:00 2001
From: Dan Lee <71398022+dandhlee@users.noreply.github.com>
Date: Fri, 3 May 2024 20:23:57 -0400
Subject: [PATCH] test: refactor unit_test.py (#377)
* test: refactor upto references
* tests: refactor docstring extractor
* tests: refactor upto packages
* test: refactors for parsing docstring summary
* tests: finished refactoring test_unit.py
* test: update typos
* test: move the explanation comment up
* test: refactor to use test paramters
* test: refactor rest of tests into similar format
---
tests/test_unit.py | 1342 ++++++++++++++++++++++++++------------------
1 file changed, 799 insertions(+), 543 deletions(-)
diff --git a/tests/test_unit.py b/tests/test_unit.py
index ce5870bb..4ab3b3a0 100644
--- a/tests/test_unit.py
+++ b/tests/test_unit.py
@@ -6,68 +6,77 @@
from yaml import load, Loader
class TestGenerate(unittest.TestCase):
- def test_find_unique_name(self):
+ def test_finds_unique_name(self):
entries = {}
# Disambiguate with unique entries.
- entry1 = "google.cloud.aiplatform.v1.schema.predict.instance_v1.types"
- entry2 = "google.cloud.aiplatform.v1beta2.schema.predict.instance_v1.types"
- want1 = "v1.types"
- want2 = "v1beta2.types"
-
- for entry in [entry1, entry2]:
+ schema_v1_entry = (
+ "google.cloud.aiplatform.v1.schema.predict.instance_v1.types"
+ )
+ schema_v1beta2_entry = (
+ "google.cloud.aiplatform.v1beta2.schema.predict.instance_v1.types"
+ )
+ for entry in [schema_v1_entry, schema_v1beta2_entry]:
for word in entry.split("."):
if word not in entries:
entries[word] = 1
else:
entries[word] += 1
- got1 = extension.find_unique_name(entry1.split("."), entries)
- got2 = extension.find_unique_name(entry2.split("."), entries)
-
- self.assertEqual(want1, ".".join(got1))
- self.assertEqual(want2, ".".join(got2))
-
-
- def test_disambiguate_toc_name(self):
-
- with open('tests/yaml_post.yaml', 'r') as want_file:
- yaml_want = load(want_file, Loader=Loader)
- disambiguated_names_want = {
- 'google.cloud.spanner_admin_database_v1.types': 'spanner_admin_database_v1.types',
- 'google.cloud.spanner_admin_instance_v1.types': 'spanner_admin_instance_v1.types',
- 'google.cloud.spanner_v1.types': 'spanner_v1.types'
- }
-
- with open('tests/yaml_pre.yaml', 'r') as test_file:
- yaml_got = load(test_file, Loader=Loader)
- disambiguated_names_got = extension.disambiguate_toc_name(yaml_got)
-
- self.assertEqual(yaml_want, yaml_got)
- self.assertEqual(disambiguated_names_want, disambiguated_names_got)
-
-
- def test_disambiguate_toc_name_duplicate(self):
-
- with open('tests/yaml_post_duplicate.yaml', 'r') as want_file:
- yaml_want = load(want_file, Loader=Loader)
- disambiguated_names_want = {
- 'google.api_core.client_info': 'client_info',
- 'google.api_core.gapic_v1.client_info': 'gapic_v1.client_info'
- }
+ unique_v1_name = extension.find_unique_name(
+ schema_v1_entry.split("."), entries
+ )
+ unique_v1beta2_name = extension.find_unique_name(
+ schema_v1beta2_entry.split("."), entries
+ )
- with open('tests/yaml_pre_duplicate.yaml', 'r') as test_file:
- yaml_got = load(test_file, Loader=Loader)
- disambiguated_names_got = extension.disambiguate_toc_name(yaml_got)
+ self.assertEqual("v1.types", ".".join(unique_v1_name))
+ self.assertEqual("v1beta2.types", ".".join(unique_v1beta2_name))
- self.assertEqual(yaml_want, yaml_got)
- self.assertEqual(disambiguated_names_want, disambiguated_names_got)
+ test_entries = [
+ [
+ "tests/yaml_pre.yaml",
+ "tests/yaml_post.yaml",
+ {
+ "google.cloud.spanner_admin_database_v1.types": "spanner_admin_database_v1.types",
+ "google.cloud.spanner_admin_instance_v1.types": "spanner_admin_instance_v1.types",
+ "google.cloud.spanner_v1.types": "spanner_v1.types",
+ },
+ ],
+ [
+ # Tests duplicate names
+ "tests/yaml_pre_duplicate.yaml",
+ "tests/yaml_post_duplicate.yaml",
+ {
+ "google.api_core.client_info": "client_info",
+ "google.api_core.gapic_v1.client_info": "gapic_v1.client_info",
+ },
+ ]
+ ]
+ @parameterized.expand(test_entries)
+ def test_disambiguates_toc_name(
+ self,
+ test_filename,
+ expected_filename,
+ expected_disambiguated_names,
+ ):
+ with open(test_filename, "r") as test_file:
+ test_yaml = load(test_file, Loader=Loader)
+ with open(expected_filename, "r") as expected_yaml_file:
+ expected_yaml = load(expected_yaml_file, Loader=Loader)
+
+ disambiguated_names = extension.disambiguate_toc_name(
+ test_yaml
+ )
+ self.assertEqual(expected_yaml, test_yaml)
+ self.assertEqual(expected_disambiguated_names, disambiguated_names)
- def test_reference_in_summary(self):
- lines_got = """
+ test_entries = [
+ [
+ """
If a ``stream`` is attached to this download, then the downloaded
resource will be written to the stream.
@@ -87,22 +96,12 @@ def test_reference_in_summary(self):
~google.cloud.requests.Response: The HTTP response returned by ``transport``.
Raises:
- ~google.cloud.resumable_media.common.DataCorruption: If the download's
+ ~google.cloud.resumable_media.common.DataCorruption: If the download"s
checksum doesn't agree with server-computed checksum.
ValueError: If the current :class:`Download` has already
finished.
-"""
- lines_got = lines_got.split("\n")
- xrefs_got = []
- # Resolve over different regular expressions for different types of reference patterns.
- lines_got, xrefs = extension._resolve_reference_in_module_summary(extension.REF_PATTERN, lines_got)
- for xref in xrefs:
- xrefs_got.append(xref)
- lines_got, xrefs = extension._resolve_reference_in_module_summary(extension.REF_PATTERN_LAST, lines_got)
- for xref in xrefs:
- xrefs_got.append(xref)
-
- lines_want = """
+ """,
+ """
If a ``stream`` is attached to this download, then the downloaded
resource will be written to the stream.
@@ -122,28 +121,20 @@ def test_reference_in_summary(self):
Response: The HTTP response returned by ``transport``.
Raises:
- DataCorruption: If the download's
+ DataCorruption: If the download"s
checksum doesn't agree with server-computed checksum.
ValueError: If the current `Download` has already
finished.
-"""
- lines_want = lines_want.split("\n")
- xrefs_want = [
- "google.cloud.requests.Session",
- "google.cloud.requests.Session.request",
- "google.cloud.requests.Response",
- "google.cloud.resumable_media.common.DataCorruption"
- ]
-
- self.assertEqual(lines_got, lines_want)
- self.assertCountEqual(xrefs_got, xrefs_want)
- # assertCountEqual is a misleading name but checks that two lists contain
- # same items regardless of order, as long as items in list are sortable.
-
-
- # Test for added xref coverage and third party xrefs staying as-is
- def test_reference_in_summary_more_xrefs(self):
- lines_got = """
+ """,
+ [
+ "google.cloud.requests.Session",
+ "google.cloud.requests.Session.request",
+ "google.cloud.requests.Response",
+ "google.cloud.resumable_media.common.DataCorruption",
+ ],
+ ],
+ [
+ """
If a ~dateutil.time.stream() is attached to this download, then the downloaded
resource will be written to the stream.
@@ -158,18 +149,8 @@ def test_reference_in_summary_more_xrefs(self):
Can also be passed as a :func:`~google.cloud.requests.tuple()` (connect_timeout, read_timeout).
See :meth:`google.cloud.requests.Session.request()` documentation for details.
-"""
- lines_got = lines_got.split("\n")
- xrefs_got = []
- # Resolve over different regular expressions for different types of reference patterns.
- lines_got, xrefs = extension._resolve_reference_in_module_summary(extension.REF_PATTERN, lines_got)
- for xref in xrefs:
- xrefs_got.append(xref)
- lines_got, xrefs = extension._resolve_reference_in_module_summary(extension.REF_PATTERN_LAST, lines_got)
- for xref in xrefs:
- xrefs_got.append(xref)
-
- lines_want = """
+ """,
+ """
If a `dateutil.time.stream()` is attached to this download, then the downloaded
resource will be written to the stream.
@@ -184,92 +165,91 @@ def test_reference_in_summary_more_xrefs(self):
Can also be passed as a tuple() (connect_timeout, read_timeout).
See request() documentation for details.
-"""
- lines_want = lines_want.split("\n")
- xrefs_want = [
- "google.cloud.requests.Session",
- "google.cloud.requests.tuple",
- "google.cloud.requests.Session.request"
- ]
-
- self.assertEqual(lines_got, lines_want)
- self.assertCountEqual(xrefs_got, xrefs_want)
- # assertCountEqual is a misleading name but checks that two lists contain
- # same items regardless of order, as long as items in list are sortable.
-
-
- # Variables used for testing _extract_docstring_info
- top_summary1_want = "\nSimple test for docstring.\n\n"
- summary_info1_want = {
- 'variables': {
- 'arg1': {
- 'var_type': 'int',
- 'description': 'simple description.'
- },
- 'arg2': {
- 'var_type': 'str',
- 'description': 'simple description for `arg2`.'
- }
- },
- 'returns': [
- {
- 'var_type': 'str',
- 'description': 'simple description for return value.'
- }
+ """,
+ [
+ "google.cloud.requests.Session",
+ "google.cloud.requests.tuple",
+ "google.cloud.requests.Session.request",
+ ],
],
- 'exceptions': [
- {
- 'var_type': 'AttributeError',
- 'description': 'if `condition x`.'
- }
- ]
- }
-
+ ]
+ @parameterized.expand(test_entries)
+ def test_resolves_references_in_summary(
+ self,
+ test_docstring,
+ expected_content,
+ expected_xrefs,
+ ):
+ xrefs_to_check = []
+ # Resolve over different regular expressions for different types of reference patterns.
+ content_to_resolve, xrefs = (
+ extension._resolve_reference_in_module_summary(
+ extension.REF_PATTERN,
+ test_docstring.split("\n"),
+ )
+ )
+ xrefs_to_check.extend(xrefs)
- # Test for resolving square bracketed references.
- def test_reference_square_brackets(self):
- xrefs_want = [
- 'google.cloud.kms.v1.KeyRing.name',
- 'google.cloud.kms.v1.KeyRing',
- 'google.cloud.kms.v1.ImportJob',
- ]
- summary_want = """Required.
+ resolved_content, xrefs = (
+ extension._resolve_reference_in_module_summary(
+ extension.REF_PATTERN_LAST,
+ content_to_resolve,
+ )
+ )
+ xrefs_to_check.extend(xrefs)
-The name of the KeyRing associated with the ImportJobs.
-"""
- summary_want = summary_want.split("\n")
+ self.assertEqual(resolved_content, expected_content.split("\n"))
+ self.assertCountEqual(xrefs_to_check, expected_xrefs)
- summary = """Required.
+ test_entries = [
+ [
+ """Required.
The [name][google.cloud.kms.v1.KeyRing.name] of the [KeyRing][google.cloud.kms.v1.KeyRing] associated with the [ImportJobs][google.cloud.kms.v1.ImportJob].
-"""
- summary = summary.split("\n")
+ """,
+ """Required.
- summary_got, xrefs_got = extension._resolve_reference_in_module_summary(extension.REF_PATTERN_BRACKETS, summary)
+The name of the KeyRing associated with the ImportJobs.
+ """,
+ [
+ "google.cloud.kms.v1.KeyRing.name",
+ "google.cloud.kms.v1.KeyRing",
+ "google.cloud.kms.v1.ImportJob",
+ ],
+ ],
+ ]
+ @parameterized.expand(test_entries)
+ def test_resolves_square_bracket_references(
+ self,
+ summary,
+ expected_summary,
+ expected_xrefs,
+ ):
+ resolved_summary, xrefs = (
+ extension._resolve_reference_in_module_summary(
+ extension.REF_PATTERN_BRACKETS,
+ summary.split("\n"),
+ )
+ )
- self.assertEqual(summary_got, summary_want)
- self.assertCountEqual(xrefs_got, xrefs_want)
+ self.assertEqual(resolved_summary, expected_summary.split("\n"))
+ self.assertCountEqual(xrefs, expected_xrefs)
- # Check that other patterns throws an exception.
- def test_reference_check_error(self):
+ def test_raises_error_for_invalid_references(self):
with self.assertRaises(ValueError):
- extension._resolve_reference_in_module_summary('.*', 'not a valid ref line'.split('\n'))
-
-
- def test_extract_docstring_info_normal_input(self):
+ extension._resolve_reference_in_module_summary(
+ ".*",
+ "not a valid ref line".split("\n"),
+ )
- ## Test for normal input
- summary_info1_got = {
- 'variables': {},
- 'returns': [],
- 'exceptions': []
- }
- summary1 = """
+ test_entries = [
+ [
+ """
Simple test for docstring.
-Args:
+Args:
arg1(int): simple description.
arg2(str): simple description for `arg2`.
@@ -278,17 +258,32 @@ def test_extract_docstring_info_normal_input(self):
Raises:
AttributeError: if `condition x`.
-"""
-
- top_summary1_got = extension._extract_docstring_info(summary_info1_got, summary1, "")
-
- self.assertEqual(top_summary1_got, self.top_summary1_want)
- self.assertEqual(summary_info1_got, self.summary_info1_want)
-
-
- def test_extract_docstring_info_mixed_format(self):
- ## Test for input coming in mixed format.
- summary2 = """
+ """,
+ "\nSimple test for docstring.\n\n",
+ {
+ "variables": {
+ "arg1": {
+ "var_type": "int",
+ "description": "simple description.",
+ },
+ "arg2": {
+ "var_type": "str",
+ "description": "simple description for `arg2`.",
+ },
+ },
+ "returns": [{
+ "var_type": "str",
+ "description": "simple description for return value.",
+ }],
+ "exceptions": [{
+ "var_type": "AttributeError",
+ "description": "if `condition x`.",
+ }],
+ },
+ ],
+ [
+ # Tests summary in mixed format
+ """
Simple test for docstring.
:type arg1: int
@@ -299,102 +294,58 @@ def test_extract_docstring_info_mixed_format(self):
:rtype: str
:returns: simple description for return value.
-:raises AttributeError: if `condition x`.
-"""
-
- summary_info2_got = {
- 'variables': {},
- 'returns': [],
- 'exceptions': []
- }
-
- top_summary2_got = extension._extract_docstring_info(summary_info2_got, summary2, "")
-
- # Output should be same as test 1 with normal input.
- self.assertEqual(top_summary2_got, self.top_summary1_want)
- self.assertEqual(summary_info2_got, self.summary_info1_want)
-
-
- def test_extract_docstring_info_check_parser(self):
- ## Test for parser to correctly scan docstring tokens and not custom fields
- summary_info3_want = {
- 'variables': {},
- 'returns': [],
- 'exceptions': []
- }
+:raises AttributeError: if `condition x`.
+ """,
+ "\nSimple test for docstring.\n\n",
+ {
+ "variables": {
+ "arg1": {
+ "var_type": "int",
+ "description": "simple description.",
+ },
+ "arg2": {
+ "var_type": "str",
+ "description": "simple description for `arg2`.",
+ },
+ },
+ "returns": [{
+ "var_type": "str",
+ "description": "simple description for return value.",
+ }],
+ "exceptions": [{
+ "var_type": "AttributeError",
+ "description": "if `condition x`.",
+ }],
+ },
- summary3 = """
+ ],
+ [
+ # Tests summary for docstring tokens and not custom fields
+ """
Union[int, None]: Expiration time in milliseconds for a partition.
If :attr:`partition_expiration` is set and is
not set, :attr:`type_` will default to
:attr:`~google.cloud.bigquery.table.TimePartitioningType.DAY`.
It could return :param: with :returns as well.
-"""
-
- summary_info3_got = {
- 'variables': {},
- 'returns': [],
- 'exceptions': []
- }
-
- # Nothing should change
- top_summary3_want = summary3
-
- top_summary3_got = extension._extract_docstring_info(summary_info3_got, summary3, "")
-
- self.assertEqual(top_summary3_got, top_summary3_want)
- self.assertEqual(summary_info3_got, summary_info3_want)
-
-
- def test_extract_docstring_info_check_error(self):
- ## Test for incorrectly formmatted docstring raising error
- summary4 = """
-Description of docstring which should fail.
-
-:returns:param:
-"""
- with self.assertRaises(ValueError):
- extension._extract_docstring_info({}, summary4, "error string")
-
- summary5 = """
-Description of malformed docstring.
-
-Raises:
- Error that should fail: if condition `x`.
-"""
- with self.assertRaises(KeyError):
- extension._extract_docstring_info({}, summary5, "malformed docstring")
-
-
- def test_extract_docstring_info_with_xref(self):
- ## Test with xref included in the summary, ensure they're processed as-is
- summary_info_want = {
- 'variables': {
- 'arg1': {
- 'var_type': 'Type',
- 'description': 'simple description.'
- },
- 'arg2': {
- 'var_type': '~google.spanner_v1.type.dict',
- 'description': 'simple description for `arg2`.'
- }
- },
- 'returns': [
- {
- 'var_type': 'Pair',
- 'description': 'simple description for return value.'
- }
- ],
- 'exceptions': [
- {
- 'var_type': 'SpannerException',
- 'description': 'if `condition x`.'
- }
- ]
- }
+ """,
+ """
+Union[int, None]: Expiration time in milliseconds for a partition.
- summary = """
+If :attr:`partition_expiration` is set and is
+not set, :attr:`type_` will default to
+:attr:`~google.cloud.bigquery.table.TimePartitioningType.DAY`.
+It could return :param: with :returns as well.
+ """,
+ {
+ "variables": {},
+ "returns": [],
+ "exceptions": [],
+ }
+ ],
+ [
+ # Tests summary with xrefs
+ """
Simple test for docstring.
:type arg1: Type
@@ -405,25 +356,34 @@ def test_extract_docstring_info_with_xref(self):
:rtype: Pair
:returns: simple description for return value.
-:raises SpannerException: if `condition x`.
-"""
-
- summary_info_got = {
- 'variables': {},
- 'returns': [],
- 'exceptions': []
- }
-
- top_summary_got = extension._extract_docstring_info(summary_info_got, summary, "")
- # Same as the top summary from previous example, compare with that
- self.assertEqual(top_summary_got, self.top_summary1_want)
- self.assertDictEqual(summary_info_got, summary_info_want)
-
-
- def test_extract_docstring_info_no_summary(self):
- ## Test parsing docstring with no summary.
- summary =(
-"""Args:
+:raises SpannerException: if `condition x`.
+ """,
+ "\nSimple test for docstring.\n\n",
+ {
+ "variables": {
+ "arg1": {
+ "var_type": "Type",
+ "description": "simple description.",
+ },
+ "arg2": {
+ "var_type": "~google.spanner_v1.type.dict",
+ "description": "simple description for `arg2`.",
+ },
+ },
+ "returns": [{
+ "var_type": "Pair",
+ "description": "simple description for return value.",
+ }],
+ "exceptions": [{
+ "var_type": "SpannerException",
+ "description": "if `condition x`.",
+ }],
+ },
+ ],
+ [
+ # Tests docstring without a summary
+ """
+Args:
arg1(int): simple description.
arg2(str): simple description for `arg2`.
@@ -432,101 +392,124 @@ def test_extract_docstring_info_no_summary(self):
Raises:
AttributeError: if `condition x`.
-"""
- )
- summary_info_got = {
- 'variables': {},
- 'returns': [],
- 'exceptions': []
- }
-
- top_summary_got = extension._extract_docstring_info(summary_info_got, summary, "")
- self.assertEqual(top_summary_got, "")
- self.assertDictEqual(summary_info_got, self.summary_info1_want)
-
-
- def test_find_package_group(self):
- package_group_want = "google.cloud.spanner_v1beta2"
- uid = "google.cloud.spanner_v1beta2.services.admin_database_v1.types"
+ """,
+ "\n",
+ {
+ "variables": {
+ "arg1": {
+ "var_type": "int",
+ "description": "simple description.",
+ },
+ "arg2": {
+ "var_type": "str",
+ "description": "simple description for `arg2`.",
+ },
+ },
+ "returns": [{
+ "var_type": "str",
+ "description": "simple description for return value.",
+ }],
+ "exceptions": [{
+ "var_type": "AttributeError",
+ "description": "if `condition x`.",
+ }],
+ },
- package_group_got = extension.find_package_group(uid)
- self.assertEqual(package_group_got, package_group_want)
+ ],
+ ]
+ @parameterized.expand(test_entries)
+ def test_extracts_docstring_info(
+ self,
+ summary,
+ expected_top_summary,
+ expected_summary_info
+ ):
+ summary_info = {
+ "variables": {},
+ "returns": [],
+ "exceptions": []
+ }
+ top_summary = extension._extract_docstring_info(
+ summary_info,
+ summary,
+ "",
+ )
- def test_pretty_package_name(self):
- package_name_want = "Spanner V1beta2"
- package_group = "google.cloud.spanner_v1beta2"
+ self.assertEqual(top_summary, expected_top_summary)
+ self.assertDictEqual(summary_info, expected_summary_info)
- package_name_got = extension.pretty_package_name(package_group)
- self.assertEqual(package_name_got, package_name_want)
+ test_entries = [
+ [
+ """
+Description of docstring which should fail.
- def test_group_by_package(self):
- toc_yaml_want = [
- {
- "name": "Spanner Admin Database V1",
- "uidname":"google.cloud.spanner_admin_database_v1",
- "items": [
- {
- "name":"database_admin",
- "uidname":"google.cloud.spanner_admin_database_v1.services.database_admin",
- "items":[
- {
- "name":"Overview",
- "uidname":"google.cloud.spanner_admin_database_v1.services.database_admin",
- "uid":"google.cloud.spanner_admin_database_v1.services.database_admin"
- },
- {
- "name":"ListBackupOperationsAsyncPager",
- "uidname":"google.cloud.spanner_admin_database_v1.services.database_admin.pagers.ListBackupOperationsAsyncPager",
- "uid":"google.cloud.spanner_admin_database_v1.services.database_admin.pagers.ListBackupOperationsAsyncPager"
- }
- ]
- },
- {
- "name":"spanner_admin_database_v1.types",
- "uidname":"google.cloud.spanner_admin_database_v1.types",
- "items":[
- {
- "name":"Overview",
- "uidname":"google.cloud.spanner_admin_database_v1.types",
- "uid":"google.cloud.spanner_admin_database_v1.types"
- },
- {
- "name":"BackupInfo",
- "uidname":"google.cloud.spanner_admin_database_v1.types.BackupInfo",
- "uid":"google.cloud.spanner_admin_database_v1.types.BackupInfo"
- }
- ]
- },
- ]
- },
- {
- "name": "Spanner V1",
- "uidname":"google.cloud.spanner_v1",
- "items": [
- {
- "name":"pool",
- "uidname":"google.cloud.spanner_v1.pool",
- "items":[
- {
- "name":"Overview",
- "uidname":"google.cloud.spanner_v1.pool",
- "uid":"google.cloud.spanner_v1.pool"
- },
- {
- "name":"AbstractSessionPool",
- "uidname":"google.cloud.spanner_v1.pool.AbstractSessionPool",
- "uid":"google.cloud.spanner_v1.pool.AbstractSessionPool"
- }
- ]
- }
- ]
- }
- ]
+:returns:param:
+ """,
+ ValueError,
+ "Error string",
+ ],
+ [
+ """
+Description of malformed docstring.
- toc_yaml = [
- {
+Raises:
+ Error that should fail: if condition `x`.
+ """,
+ KeyError,
+ "Malformed docstring",
+ ],
+ ]
+ @parameterized.expand(test_entries)
+ def test_raises_error_extracting_malformed_docstring(
+ self,
+ summary,
+ error_type,
+ error_string,
+ ):
+ with self.assertRaises(error_type):
+ extension._extract_docstring_info({}, summary, error_string)
+
+
+ test_entries = [
+ [
+ "google.cloud.spanner_v1beta2.services.admin_database_v1.types",
+ "google.cloud.spanner_v1beta2",
+ ],
+ ]
+ @parameterized.expand(test_entries)
+ def test_finds_package_group(
+ self,
+ uid,
+ expected_package_group,
+ ):
+ package_group = extension.find_package_group(uid)
+
+ self.assertEqual(package_group, expected_package_group)
+
+
+ test_entries = [
+ [
+ "google.cloud.spanner_v1beta2",
+ "Spanner V1beta2",
+ ],
+ ]
+ @parameterized.expand(test_entries)
+ def test_finds_pretty_package_name(
+ self,
+ package_group,
+ expected_package_name,
+ ):
+ package_name = extension.pretty_package_name(package_group)
+
+ self.assertEqual(package_name, expected_package_name)
+
+
+ test_entries = [
+ [
+ # toc_yaml entry
+ [{
"name":"database_admin",
"uidname":"google.cloud.spanner_admin_database_v1.services.database_admin",
"items":[
@@ -573,18 +556,105 @@ def test_group_by_package(self):
"uid":"google.cloud.spanner_v1.pool.AbstractSessionPool"
}
]
- }
- ]
+ }],
+ # expected_toc_yaml entry
+ [
+ {
+ "name": "Spanner Admin Database V1",
+ "uidname":"google.cloud.spanner_admin_database_v1",
+ "items": [{
+ "name":"database_admin",
+ "uidname":"google.cloud.spanner_admin_database_v1.services.database_admin",
+ "items": [{
+ "name":"Overview",
+ "uidname":"google.cloud.spanner_admin_database_v1.services.database_admin",
+ "uid":"google.cloud.spanner_admin_database_v1.services.database_admin"
+ },
+ {
+ "name":"ListBackupOperationsAsyncPager",
+ "uidname":"google.cloud.spanner_admin_database_v1.services.database_admin.pagers.ListBackupOperationsAsyncPager",
+ "uid":"google.cloud.spanner_admin_database_v1.services.database_admin.pagers.ListBackupOperationsAsyncPager",
+ }],
+ },
+ {
+ "name":"spanner_admin_database_v1.types",
+ "uidname":"google.cloud.spanner_admin_database_v1.types",
+ "items": [{
+ "name":"Overview",
+ "uidname":"google.cloud.spanner_admin_database_v1.types",
+ "uid":"google.cloud.spanner_admin_database_v1.types",
+ },
+ {
+ "name":"BackupInfo",
+ "uidname":"google.cloud.spanner_admin_database_v1.types.BackupInfo",
+ "uid":"google.cloud.spanner_admin_database_v1.types.BackupInfo",
+ }],
+ }],
+ },
+ {
+ "name": "Spanner V1",
+ "uidname":"google.cloud.spanner_v1",
+ "items": [{
+ "name":"pool",
+ "uidname":"google.cloud.spanner_v1.pool",
+ "items": [{
+ "name":"Overview",
+ "uidname":"google.cloud.spanner_v1.pool",
+ "uid":"google.cloud.spanner_v1.pool"
+ },
+ {
+ "name":"AbstractSessionPool",
+ "uidname":"google.cloud.spanner_v1.pool.AbstractSessionPool",
+ "uid":"google.cloud.spanner_v1.pool.AbstractSessionPool",
+ }],
+ }],
+ },
+ ],
+ ],
+ ]
+ @parameterized.expand(test_entries)
+ def test_groups_by_package(
+ self,
+ toc_yaml,
+ expected_toc_yaml,
+ ):
+ toc_yaml = extension.group_by_package(toc_yaml)
+
+ self.assertCountEqual(toc_yaml, expected_toc_yaml)
- toc_yaml_got = extension.group_by_package(toc_yaml)
- self.assertCountEqual(toc_yaml_got, toc_yaml_want)
+ test_entries = [
+ [
+ (\
+"""
+
+.. code-block:: python
- def test_parse_docstring_summary(self):
- # Check that the summary gets parsed correctly.
- attributes_want = []
- summary_want = \
+\n from google.api_core.client_options import ClientOptions
+\n from google.cloud.vision_v1 import ImageAnnotatorClient
+\n def get_client_cert():
+\n # code to load client certificate and private key.
+\n return client_cert_bytes, client_private_key_bytes
+\n options = ClientOptions(api_endpoint=\"foo.googleapis.com\",
+\n client_cert_source=get_client_cert)
+\n client = ImageAnnotatorClient(client_options=options)
+
+
+You can also pass a mapping object.
+
+
+\n.. code-block:: ruby
+
+\n from google.cloud.vision_v1 import ImageAnnotatorClient
+\n client = ImageAnnotatorClient(
+\n client_options={
+\n \"api_endpoint\": \"foo.googleapis.com\",
+\n \"client_cert_source\" : get_client_cert
+\n })
+"""
+ ),
+ (\
"""```python
from google.api_core.client_options import ClientOptions
@@ -620,68 +690,45 @@ def get_client_cert():
```
"""
- summary = \
+ ),
+ ],
+ [
+ # Check that nothing changes for literalincludes.
+ (\
"""
+.. literalinclude::
+ note that these are not supported yet, so they will be ignored for now.
-
-.. code-block:: python
-
-\n from google.api_core.client_options import ClientOptions
-\n from google.cloud.vision_v1 import ImageAnnotatorClient
-\n def get_client_cert():
-\n # code to load client certificate and private key.
-\n return client_cert_bytes, client_private_key_bytes
-\n options = ClientOptions(api_endpoint=\"foo.googleapis.com\",
-\n client_cert_source=get_client_cert)
-\n client = ImageAnnotatorClient(client_options=options)
-
-
-You can also pass a mapping object.
-
-
-\n.. code-block:: ruby
-
-\n from google.cloud.vision_v1 import ImageAnnotatorClient
-\n client = ImageAnnotatorClient(
-\n client_options={
-\n \"api_endpoint\": \"foo.googleapis.com\",
-\n \"client_cert_source\" : get_client_cert
-\n })
+And any other documentation that the source code would have could go here.
"""
- summary_got, attributes_got = extension._parse_docstring_summary(summary)
- self.assertEqual(summary_got, summary_want)
- self.assertEqual(attributes_got, attributes_want)
-
- # Check that nothing much changes otherwise.
- summary = \
+ ),
+ (\
"""
.. literalinclude::
note that these are not supported yet, so they will be ignored for now.
And any other documentation that the source code would have could go here.
-"""
- summary_want = summary + "\n"
-
- summary_got, attributes_got = extension._parse_docstring_summary(summary)
- self.assertEqual(summary_got, summary_want)
- self.assertEqual(attributes_got, attributes_want)
- # Check that exception is raised if code block is not indented.
- summary = \
"""
+ ),
+ ],
+ [
+ # Tests notices are processed properly.
+ (\
+"""
+.. note::
+\n this is a note.
-.. code:: python
+.. caution::
+\n another type of notice.
-\nprint("This should throw an exception.")
-\nfor i in range(10):
-\n print(i)
-"""
- with self.assertRaises(ValueError):
- extension._parse_docstring_summary(summary)
- # Check that notices are processed properly.
- summary_want = \
+.. key-term::
+\n hyphenated term notice.
+"""
+ ),
+ (\
""""""
-
- summary = \
+ ),
+ ],
+ ]
+ @parameterized.expand(test_entries)
+ def test_parses_docstring_summary(
+ self,
+ summary,
+ expected_summary,
+ ):
+ parsed_summary, attributes = extension._parse_docstring_summary(summary)
+ self.assertEqual(parsed_summary, expected_summary)
+ self.assertEqual(attributes, [])
+
+
+ test_entries = [
+ [
+ (\
"""
-.. note::
-\n this is a note.
-.. caution::
-\n another type of notice.
-
+.. code:: python
-.. key-term::
-\n hyphenated term notice.
+\nprint("This should throw an exception.")
+\nfor i in range(10):
+\n print(i)
"""
-
- summary_got, attributes_got = extension._parse_docstring_summary(summary)
- self.assertEqual(summary_got, summary_want)
- self.assertEqual(attributes_got, attributes_want)
-
- # Check that exception is raised if block is not formatted properly.
-
- summary = \
+ ),
+ ValueError,
+ ],
+ [
+ (\
"""
.. warning::
this is not a properly formatted warning.
"""
- with self.assertRaises(ValueError):
+ ),
+ ValueError,
+ ],
+ ]
+ @parameterized.expand(test_entries)
+ def test_raises_error_parsing_malformed_docstring(
+ self,
+ summary,
+ error_type
+ ):
+ with self.assertRaises(error_type):
extension._parse_docstring_summary(summary)
- def test_parse_docstring_summary_attributes(self):
- # Test parsing docstring with attributes.
- attributes_want = [
- {
- "id": "simple name",
- "description": "simple description",
- "var_type": 'str'
- }
- ]
- summary = \
+
+ test_entries = [
+ [
+ (\
"""
@@ -742,25 +802,16 @@ def test_parse_docstring_summary_attributes(self):
\n:type: str
"""
-
- summary_got, attributes_got = extension._parse_docstring_summary(summary)
- self.assertCountEqual(attributes_got, attributes_want)
-
- # Check multiple attributes are parsed.
- attributes_want = [
- {
+ ),
+ [{
"id": "simple name",
"description": "simple description",
- "var_type": "str"
- },
- {
- "id": "table_insert_request",
- "description": "Table insert request.",
- "var_type": "google.cloud.bigquery_logging_v1.types.TableInsertRequest"
- }
- ]
-
- summary = \
+ "var_type": "str",
+ }],
+ ],
+ [
+ # Tests for multiple attributes.
+ (\
"""
@@ -777,21 +828,21 @@ def test_parse_docstring_summary_attributes(self):
\n:type: google.cloud.bigquery_logging_v1.types.TableInsertRequest
"""
- summary_got, attributes_got = extension._parse_docstring_summary(summary)
-
- self.assertCountEqual(attributes_got, attributes_want)
- for attribute_got, attribute_want in zip(attributes_got, attributes_want):
- self.assertDictEqual(attribute_got, attribute_want)
-
- # Check only attributes in valid format gets parsed.
- attributes_want = [
+ ),
+ [{
+ "id": "simple name",
+ "description": "simple description",
+ "var_type": "str",
+ },
{
- "id": "proper name",
- "description": "proper description.",
- "var_type": "str"
- }
- ]
- summary = \
+ "id": "table_insert_request",
+ "description": "Table insert request.",
+ "var_type": "google.cloud.bigquery_logging_v1.types.TableInsertRequest",
+ }],
+ ],
+ [
+ # Tests only attributes in valid format are parsed.
+ (\
"""
@@ -808,82 +859,287 @@ def test_parse_docstring_summary_attributes(self):
\n:type: str
"""
- summary_got, attributes_got = extension._parse_docstring_summary(summary)
-
- # Check that we are returned only one item.
- self.assertCountEqual(attributes_got, attributes_want)
- for attribute_got, attribute_want in zip(attributes_got, attributes_want):
- self.assertDictEqual(attribute_got, attribute_want)
-
-
- def test_merge_markdown_and_package_toc(self):
- known_uids = {'acl','batch','blob','client','constants','fileio','hmac_key','notification','retry'}
+ ),
+ [{
+ "id": "proper name",
+ "description": "proper description.",
+ "var_type": "str",
+ }],
+ ],
+ ]
+ @parameterized.expand(test_entries)
+ def test_parses_docstring_summary_for_attributes(
+ self,
+ summary,
+ expected_attributes,
+ ):
+ _, attributes = extension._parse_docstring_summary(summary)
+ self.assertCountEqual(attributes, expected_attributes)
+ for attributes, expected_attributes in zip(
+ attributes, expected_attributes
+ ):
+ self.assertDictEqual(attributes, expected_attributes)
+
+
+ def test_merges_markdown_and_package_toc(self):
+ known_uids = {
+ "acl",
+ "batch",
+ "blob",
+ "client",
+ "constants",
+ "fileio",
+ "hmac_key",
+ "notification",
+ "retry",
+ }
markdown_pages = {
- 'storage': [
- {'name': 'FileIO', 'href': 'fileio.md'},
- {'name': 'Retry', 'href': 'retry.md'},
- {'name': 'Notification', 'href': 'notification.md'},
- {'name': 'HMAC Key Metadata', 'href': 'hmac_key.md'},
- {'name': 'Batches', 'href': 'batch.md'},
- {'name': 'Constants', 'href': 'constants.md'},
- {'name': 'Storage Client', 'href': 'client.md'},
- {'name': 'Blobs / Objects', 'href': 'blobs.md'}
+ "storage": [
+ {"name": "FileIO", "href": "fileio.md"},
+ {"name": "Retry", "href": "retry.md"},
+ {"name": "Notification", "href": "notification.md"},
+ {"name": "HMAC Key Metadata", "href": "hmac_key.md"},
+ {"name": "Batches", "href": "batch.md"},
+ {"name": "Constants", "href": "constants.md"},
+ {"name": "Storage Client", "href": "client.md"},
+ {"name": "Blobs / Objects", "href": "blobs.md"}
],
- 'acl': [
- {'name': 'ACL', 'href': 'acl.md'},
- {'name': 'ACL guide', 'href': 'acl_guide.md'}
+ "acl": [
+ {"name": "ACL", "href": "acl.md"},
+ {"name": "ACL guide", "href": "acl_guide.md"}
],
- '/': [
- {'name': 'Overview', 'href': 'index.md'},
- {'name': 'Changelog', 'href': 'changelog.md'}
+ "/": [
+ {"name": "Overview", "href": "index.md"},
+ {"name": "Changelog", "href": "changelog.md"}
],
}
pkg_toc_yaml = [
- {'name': 'Storage',
- 'items': [
- {'name': 'acl', 'uid': 'google.cloud.storage.acl', 'items': [{'name': 'Overview', 'uid': 'google.cloud.storage.acl'}]},
- {'name': 'batch', 'uid': 'google.cloud.storage.batch', 'items': [{'name': 'Overview', 'uid': 'google.cloud.storage.batch'}]},
- {'name': 'blob', 'uid': 'google.cloud.storage.blob', 'items': [{'name': 'Overview', 'uid': 'google.cloud.storage.blob'}]},
- {'name': 'bucket', 'uid': 'google.cloud.storage.bucket', 'items': [{'name': 'Overview', 'uid': 'google.cloud.storage.bucket'}]},
- {'name': 'client', 'uid': 'google.cloud.storage.client', 'items': [{'name': 'Overview', 'uid': 'google.cloud.storage.client'}]},
- {'name': 'constants', 'uid': 'google.cloud.storage.constants'},
- {'name': 'fileio', 'uid': 'google.cloud.storage.fileio', 'items': [{'name': 'Overview', 'uid': 'google.cloud.storage.fileio'}]},
- {'name': 'hmac_key', 'uid': 'google.cloud.storage.hmac_key', 'items': [{'name': 'Overview', 'uid': 'google.cloud.storage.hmac_key'}]},
- {'name': 'notification', 'uid': 'google.cloud.storage.notification', 'items': [{'name': 'Overview', 'uid': 'google.cloud.storage.notification'}]},
- {'name': 'retry', 'uid': 'google.cloud.storage.retry', 'items': [{'name': 'Overview', 'uid': 'google.cloud.storage.retry'}]},
- ]
+ {"name": "Storage",
+ "items": [
+ {
+ "name": "acl",
+ "uid": "google.cloud.storage.acl",
+ "items": [
+ {
+ "name": "Overview",
+ "uid": "google.cloud.storage.acl",
+ },
+ ],
+ },
+ {
+ "name": "batch",
+ "uid": "google.cloud.storage.batch",
+ "items": [
+ {
+ "name": "Overview",
+ "uid": "google.cloud.storage.batch",
+ },
+ ],
+ },
+ {
+ "name": "blob",
+ "uid": "google.cloud.storage.blob",
+ "items": [
+ {
+ "name": "Overview",
+ "uid": "google.cloud.storage.blob",
+ },
+ ],
+ },
+ {
+ "name": "bucket",
+ "uid": "google.cloud.storage.bucket",
+ "items": [
+ {
+ "name": "Overview",
+ "uid": "google.cloud.storage.bucket",
+ },
+ ],
+ },
+ {
+ "name": "client",
+ "uid": "google.cloud.storage.client",
+ "items": [
+ {
+ "name": "Overview",
+ "uid": "google.cloud.storage.client",
+ },
+ ],
+ },
+ {
+ "name": "constants",
+ "uid": "google.cloud.storage.constants",
+ },
+ {
+ "name": "fileio",
+ "uid": "google.cloud.storage.fileio",
+ "items": [
+ {
+ "name": "Overview",
+ "uid": "google.cloud.storage.fileio",
+ },
+ ],
+ },
+ {
+ "name": "hmac_key",
+ "uid": "google.cloud.storage.hmac_key",
+ "items": [
+ {
+ "name": "Overview",
+ "uid": "google.cloud.storage.hmac_key",
+ },
+ ],
+ },
+ {
+ "name": "notification",
+ "uid": "google.cloud.storage.notification",
+ "items": [
+ {
+ "name": "Overview",
+ "uid": "google.cloud.storage.notification"},
+ ],
+ },
+ {
+ "name": "retry",
+ "uid": "google.cloud.storage.retry",
+ "items": [
+ {
+ "name": "Overview",
+ "uid": "google.cloud.storage.retry",
+ },
+ ],
+ },
+ ],
},
]
added_pages, merged_pkg_toc_yaml = extension.merge_markdown_and_package_toc(
- pkg_toc_yaml, markdown_pages, known_uids)
+ pkg_toc_yaml, markdown_pages, known_uids
+ )
- expected_added_pages = {'index.md', 'changelog.md', 'blobs.md', 'acl_guide.md'}
expected_merged_pkg_toc_yaml = [
- {'name': 'Overview', 'href': 'index.md'},
- {'name': 'Changelog', 'href': 'changelog.md'},
- {'name': 'Storage',
- 'items': [
- {'name': 'Blobs / Objects', 'href': 'blobs.md'},
- {'name': 'acl', 'uid': 'google.cloud.storage.acl', 'items': [
- {'name': 'ACL guide', 'href': 'acl_guide.md'},
- {'name': 'Overview', 'uid': 'google.cloud.storage.acl'},
+ {"name": "Overview", "href": "index.md"},
+ {"name": "Changelog", "href": "changelog.md"},
+ {"name": "Storage",
+ "items": [
+ {"name": "Blobs / Objects", "href": "blobs.md"},
+ {"name": "acl", "uid": "google.cloud.storage.acl", "items": [
+ {"name": "ACL guide", "href": "acl_guide.md"},
+ {"name": "Overview", "uid": "google.cloud.storage.acl"},
]},
- {'name': 'batch', 'uid': 'google.cloud.storage.batch', 'items': [{'name': 'Overview', 'uid': 'google.cloud.storage.batch'}]},
- {'name': 'blob', 'uid': 'google.cloud.storage.blob', 'items': [{'name': 'Overview', 'uid': 'google.cloud.storage.blob'}]},
- {'name': 'bucket', 'uid': 'google.cloud.storage.bucket', 'items': [{'name': 'Overview', 'uid': 'google.cloud.storage.bucket'}]},
- {'name': 'client', 'uid': 'google.cloud.storage.client', 'items': [{'name': 'Overview', 'uid': 'google.cloud.storage.client'}]},
- {'name': 'constants', 'uid': 'google.cloud.storage.constants'},
- {'name': 'fileio', 'uid': 'google.cloud.storage.fileio', 'items': [{'name': 'Overview', 'uid': 'google.cloud.storage.fileio'}]},
- {'name': 'hmac_key', 'uid': 'google.cloud.storage.hmac_key', 'items': [{'name': 'Overview', 'uid': 'google.cloud.storage.hmac_key'}]},
- {'name': 'notification', 'uid': 'google.cloud.storage.notification', 'items': [{'name': 'Overview', 'uid': 'google.cloud.storage.notification'}]},
- {'name': 'retry', 'uid': 'google.cloud.storage.retry', 'items': [{'name': 'Overview', 'uid': 'google.cloud.storage.retry'}]},
+ {"name": "batch", "uid": "google.cloud.storage.batch", "items": [{"name": "Overview", "uid": "google.cloud.storage.batch"}]},
+ {"name": "blob", "uid": "google.cloud.storage.blob", "items": [{"name": "Overview", "uid": "google.cloud.storage.blob"}]},
+ {"name": "bucket", "uid": "google.cloud.storage.bucket", "items": [{"name": "Overview", "uid": "google.cloud.storage.bucket"}]},
+ {"name": "client", "uid": "google.cloud.storage.client", "items": [{"name": "Overview", "uid": "google.cloud.storage.client"}]},
+ {"name": "constants", "uid": "google.cloud.storage.constants"},
+ {"name": "fileio", "uid": "google.cloud.storage.fileio", "items": [{"name": "Overview", "uid": "google.cloud.storage.fileio"}]},
+ {"name": "hmac_key", "uid": "google.cloud.storage.hmac_key", "items": [{"name": "Overview", "uid": "google.cloud.storage.hmac_key"}]},
+ {"name": "notification", "uid": "google.cloud.storage.notification", "items": [{"name": "Overview", "uid": "google.cloud.storage.notification"}]},
+ {"name": "retry", "uid": "google.cloud.storage.retry", "items": [{"name": "Overview", "uid": "google.cloud.storage.retry"}]},
]
},
]
- self.assertSetEqual(added_pages, expected_added_pages)
- self.assertListEqual(merged_pkg_toc_yaml, expected_merged_pkg_toc_yaml)
+ self.assertSetEqual(
+ added_pages,
+ {
+ "index.md",
+ "changelog.md",
+ "blobs.md",
+ "acl_guide.md",
+ }
+ )
+ self.assertListEqual(
+ merged_pkg_toc_yaml,
+ [
+ {"name": "Overview", "href": "index.md"},
+ {"name": "Changelog", "href": "changelog.md"},
+ {"name": "Storage",
+ "items": [
+ {"name": "Blobs / Objects", "href": "blobs.md"},
+ {
+ "name": "acl",
+ "uid": "google.cloud.storage.acl",
+ "items": [
+ {"name": "ACL guide", "href": "acl_guide.md"},
+ {
+ "name": "Overview",
+ "uid": "google.cloud.storage.acl",
+ },
+ ],
+ },
+ {
+ "name": "batch",
+ "uid": "google.cloud.storage.batch",
+ "items": [{
+ "name": "Overview",
+ "uid": "google.cloud.storage.batch",
+ }],
+ },
+ {
+ "name": "blob",
+ "uid": "google.cloud.storage.blob",
+ "items": [{
+ "name": "Overview",
+ "uid": "google.cloud.storage.blob",
+ }],
+ },
+ {
+ "name": "bucket",
+ "uid": "google.cloud.storage.bucket",
+ "items": [{
+ "name": "Overview",
+ "uid": "google.cloud.storage.bucket",
+ }],
+ },
+ {
+ "name": "client",
+ "uid": "google.cloud.storage.client",
+ "items": [{
+ "name": "Overview",
+ "uid": "google.cloud.storage.client",
+ }],
+ },
+ {
+ "name": "constants",
+ "uid": "google.cloud.storage.constants",
+ },
+ {
+ "name": "fileio",
+ "uid": "google.cloud.storage.fileio",
+ "items": [{
+ "name": "Overview",
+ "uid": "google.cloud.storage.fileio",
+ }],
+ },
+ {
+ "name": "hmac_key",
+ "uid": "google.cloud.storage.hmac_key",
+ "items": [{
+ "name": "Overview",
+ "uid": "google.cloud.storage.hmac_key",
+ }],
+ },
+ {
+ "name": "notification",
+ "uid": "google.cloud.storage.notification",
+ "items": [{
+ "name": "Overview",
+ "uid": "google.cloud.storage.notification",
+ }],
+ },
+ {
+ "name": "retry",
+ "uid": "google.cloud.storage.retry",
+ "items": [{
+ "name": "Overview",
+ "uid": "google.cloud.storage.retry",
+ }],
+ },
+ ],
+ },
+ ],
+ ),
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()