Skip to content

Commit

Permalink
fix: complete toc disambiguation (#45)
Browse files Browse the repository at this point in the history
* fix: complete toc disambiguation

* fix: update to increment values

* chore: update names map to name_entries

* test: update to use unittest

* test: fix typo in ci.yaml

* test: update name and test file lengths
  • Loading branch information
dandhlee authored Jun 21, 2021
1 parent 9250ce0 commit 8928614
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 18 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@ jobs:
- name: Run tests
run: |
tox -e docs
- name: Run unittest
run: |
tox -e unittest
57 changes: 39 additions & 18 deletions docfx_yaml/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,45 @@ def insert_children_on_function(app, _type, datam):
insert_functions = app.env.docfx_yaml_functions[datam[FUNCTION]]
insert_functions.append(datam)

# Parses the package name and returns unique identifer and name.
def find_unique_name(package_name, entries):
for name in package_name:
# Only find unique identifiers beside "google" and "cloud"
# For example, if given
# "google.cloud.spanner.v1.params_v1.types"
# "google.cloud.spanner.v1.instance_v1.types"
# it will return "instace_v1" or "params_v1" and "types".
if name != "google" and name != "cloud" and entries[name] == 1:
return [name, package_name[-1]]

# Used to disambiguate names that have same entries.
def disambiguate_toc_name(toc_yaml):
name_entries = {}
for module in toc_yaml:
module_name = module['name']
if module_name not in name_entries:
name_entries[module_name] = {}

# Split the name and mark all duplicates.
# There will be at least 1 unique identifer for each name.
for part in module['uidname'].split("."):
if part not in name_entries[module_name]:
name_entries[module_name][part] = 1
else:
name_entries[module_name][part] += 1

# Some entries don't contain `name` in `uidname`, add these into the map as well.
if module_name not in name_entries[module_name]:
name_entries[module_name][module_name] = 1

if 'items' in module:
disambiguate_toc_name(module['items'])

for module in toc_yaml:
module_name = module['name']
# Check if there are multiple entires of module['name'], disambiguate if needed.
if name_entries[module_name][module_name] > 1:
module['name'] = ".".join(find_unique_name(module['uidname'].split("."), name_entries[module_name]))

def build_finished(app, exception):
"""
Expand All @@ -720,24 +759,6 @@ def sanitize_uidname_field(toc_yaml):
sanitize_uidname_field(module['items'])
module.pop('uidname')

# Parses the package name and returns package name and module name.
def find_package_name(package_name):
for name in package_name:
if name != "google" and name != "cloud":
return [name, package_name[-1]]

# Used to disambiguate names that have same entries.
def disambiguate_toc_name(toc_yaml):
names = {}
for module in toc_yaml:
names[module['name']] = 1 if module['name'] not in names else 2
if 'items' in module:
disambiguate_toc_name(module['items'])

for module in toc_yaml:
if names[module['name']] > 1:
module['name'] = ".".join(find_package_name(module['uidname'].split(".")))

def find_node_in_toc_tree(toc_yaml, to_add_node):
for module in toc_yaml:
if module['uidname'] == to_add_node:
Expand Down
48 changes: 48 additions & 0 deletions tests/test_unit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from docfx_yaml.extension import find_unique_name
from docfx_yaml.extension import disambiguate_toc_name

import unittest

from yaml import load, Loader

class TestGenerate(unittest.TestCase):
def test_find_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]:
for word in entry.split("."):
if word not in entries:
entries[word] = 1
else:
entries[word] += 1

got1 = find_unique_name(entry1.split("."), entries)
got2 = find_unique_name(entry2.split("."), entries)

self.assertEqual(want1, ".".join(got1))
self.assertEqual(want2, ".".join(got2))


def test_disambiguate_toc_name(self):

want_file = open('tests/yaml_post.yaml', 'r')
yaml_want = load(want_file, Loader=Loader)

test_file = open('tests/yaml_pre.yaml', 'r')
yaml_got = load(test_file, Loader=Loader)
disambiguate_toc_name(yaml_got)

want_file.close()
test_file.close()

self.assertEqual(yaml_want, yaml_got)

if __name__ == '__main__':
unittest.main()
50 changes: 50 additions & 0 deletions tests/yaml_post.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[
{
"name":"database_admin",
"uidname":"google.cloud.spanner_admin_database_v1.services.database_admin",
"items":[
{
"name":"DatabaseAdminAsyncClient",
"uidname":"google.cloud.spanner_admin_database_v1.services.database_admin.DatabaseAdminAsyncClient",
"uid":"google.cloud.spanner_admin_database_v1.services.database_admin.DatabaseAdminAsyncClient"
},
{
"name":"DatabaseAdminClient",
"uidname":"google.cloud.spanner_admin_database_v1.services.database_admin.DatabaseAdminClient",
"uid":"google.cloud.spanner_admin_database_v1.services.database_admin.DatabaseAdminClient"
}
]
},
{
"name":"spanner_admin_database_v1.types",
"uidname":"google.cloud.spanner_admin_database_v1.types",
},
{
"name":"instance_admin",
"uidname":"google.cloud.spanner_admin_instance_v1.services.instance_admin",
},
{
"name":"spanner_admin_instance_v1.types",
"uidname":"google.cloud.spanner_admin_instance_v1.types",
},
{
"name":"batch",
"uidname":"google.cloud.spanner_v1.batch",
"items":[
{
"name":"Overview",
"uidname":"google.cloud.spanner_v1.batch",
"uid":"google.cloud.spanner_v1.batch"
},
{
"name":"Batch",
"uidname":"google.cloud.spanner_v1.batch.Batch",
"uid":"google.cloud.spanner_v1.batch.Batch"
}
]
},
{
"name":"spanner_v1.types",
"uidname":"google.cloud.spanner_v1.types",
}
]
50 changes: 50 additions & 0 deletions tests/yaml_pre.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[
{
"name":"database_admin",
"uidname":"google.cloud.spanner_admin_database_v1.services.database_admin",
"items":[
{
"name":"DatabaseAdminAsyncClient",
"uidname":"google.cloud.spanner_admin_database_v1.services.database_admin.DatabaseAdminAsyncClient",
"uid":"google.cloud.spanner_admin_database_v1.services.database_admin.DatabaseAdminAsyncClient"
},
{
"name":"DatabaseAdminClient",
"uidname":"google.cloud.spanner_admin_database_v1.services.database_admin.DatabaseAdminClient",
"uid":"google.cloud.spanner_admin_database_v1.services.database_admin.DatabaseAdminClient"
}
]
},
{
"name":"types",
"uidname":"google.cloud.spanner_admin_database_v1.types",
},
{
"name":"instance_admin",
"uidname":"google.cloud.spanner_admin_instance_v1.services.instance_admin",
},
{
"name":"types",
"uidname":"google.cloud.spanner_admin_instance_v1.types",
},
{
"name":"batch",
"uidname":"google.cloud.spanner_v1.batch",
"items":[
{
"name":"Overview",
"uidname":"google.cloud.spanner_v1.batch",
"uid":"google.cloud.spanner_v1.batch"
},
{
"name":"Batch",
"uidname":"google.cloud.spanner_v1.batch.Batch",
"uid":"google.cloud.spanner_v1.batch.Batch"
}
]
},
{
"name":"types",
"uidname":"google.cloud.spanner_v1.types",
}
]
6 changes: 6 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ changedir = {toxinidir}/docs
commands =
sphinx-build -D extensions=sphinx.ext.autodoc,sphinx.ext.autosummary,docfx_yaml.extension,sphinx.ext.intersphinx,sphinx.ext.coverage,sphinx.ext.napoleon,sphinx.ext.todo,sphinx.ext.viewcode -b html -d {envtmpdir}/doctrees . {envtmpdir}/html

[testenv:unittest]
deps =
{[testenv]deps}
commands =
python3 -m unittest tests/test_unit.py

[testenv:lint]
deps =
{[testenv]deps}
Expand Down

0 comments on commit 8928614

Please sign in to comment.