Commit f2225815 authored by cduvall@chromium.org's avatar cduvall@chromium.org

Extensions Docs Server: Proper $ref handling

If an API has a $ref type to another file, it is now displayed with the prefix
of the API it is a ref to. For example if Tabs references Windows, the ref will
be windows.Window, but if Tabs references Tab, the ref will be just Tab.

Also, $refs are handled in descriptions.

BUG=131095

Review URL: https://chromiumcodereview.appspot.com/10826024

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149001 0039d316-1c4b-4281-b951-d872f2087c98
parent b1b4faa5
......@@ -22,17 +22,13 @@ def _RemoveNoDocs(item):
return False
def _GetLinkToRefType(namespace_name, ref_type):
terms = ref_type.split('.')
if len(terms) > 1:
text = '.'.join(terms[1:])
href = terms[0] + '.html' + '#type-' + text
else:
href = namespace_name + '.html' + '#type-' +ref_type
text = ref_type
return ({
"href": href,
"text": text
})
if ref_type.startswith(namespace_name + '.'):
type_name = ref_type[len(namespace_name + '.'):]
return { 'href': '#type-' + type_name, 'text': type_name }
elif '.' not in ref_type:
return { 'href': '#type-' + ref_type, 'text': ref_type }
api, type_name = ref_type.rsplit('.', 1)
return { 'href': api + '.html#type-' + type_name, 'text': ref_type }
def _FormatValue(value):
"""Inserts commas every three digits for integer values. It is magic.
......@@ -52,6 +48,32 @@ class HandlebarDictGenerator(object):
except Exception as e:
logging.info(e)
def _StripPrefix(self, name):
if name.startswith(self._namespace.name + '.'):
return name[len(self._namespace.name + '.'):]
return name
def _FormatDescription(self, description):
if description is None or '$ref:' not in description:
return description
refs = description.split('$ref:')
formatted_description = [refs[0]]
for ref in refs[1:]:
parts = ref.split(' ', 1)
if len(parts) == 1:
ref = parts[0]
rest = ''
else:
ref, rest = parts
rest = ' ' + rest
if not ref[-1].isalnum():
rest = ref[-1] + rest
ref = ref[:-1]
ref_dict = _GetLinkToRefType(self._namespace.name, ref)
formatted_description.append('<a href="%(href)s">%(text)s</a>%(rest)s' %
{ 'href': ref_dict['href'], 'text': ref_dict['text'], 'rest': rest })
return ''.join(formatted_description)
def Generate(self):
try:
return {
......@@ -66,8 +88,8 @@ class HandlebarDictGenerator(object):
def _GenerateType(self, type_):
type_dict = {
'name': type_.name,
'description': type_.description,
'name': self._StripPrefix(type_.name),
'description': self._FormatDescription(type_.description),
'properties': self._GenerateProperties(type_.properties),
'functions': self._GenerateFunctions(type_.functions),
'events': map(self._GenerateEvent, type_.events.values())
......@@ -81,7 +103,7 @@ class HandlebarDictGenerator(object):
def _GenerateFunction(self, function):
function_dict = {
'name': function.name,
'description': function.description,
'description': self._FormatDescription(function.description),
'callback': self._GenerateCallback(function.callback),
'parameters': [],
'returns': None
......@@ -98,8 +120,8 @@ class HandlebarDictGenerator(object):
def _GenerateEvent(self, event):
event_dict = {
'name': event.name,
'description': event.description,
'name': self._StripPrefix(event.name),
'description': self._FormatDescription(event.description),
'parameters': map(self._GenerateProperty, event.params)
}
if len(event_dict['parameters']) > 0:
......@@ -111,7 +133,7 @@ class HandlebarDictGenerator(object):
return None
callback_dict = {
'name': 'callback',
'description': callback.description,
'description': self._FormatDescription(callback.description),
'simple_type': {'simple_type': 'function'},
'optional': callback.optional,
'parameters': []
......@@ -127,9 +149,9 @@ class HandlebarDictGenerator(object):
def _GenerateProperty(self, property_):
property_dict = {
'name': property_.name,
'name': self._StripPrefix(property_.name),
'optional': property_.optional,
'description': property_.description,
'description': self._FormatDescription(property_.description),
'properties': self._GenerateProperties(property_.properties),
'functions': self._GenerateFunctions(property_.functions)
}
......
......@@ -13,6 +13,14 @@ from handlebar_dict_generator import _FormatValue
import third_party.json_schema_compiler.json_comment_eater as comment_eater
import third_party.json_schema_compiler.model as model
def _MakeLink(href, text):
return '<a href="%s">%s</a>' % (href, text)
def _GetType(dict_, name):
for type_ in dict_['types']:
if type_['name'] == name:
return type_
class DictGeneratorTest(unittest.TestCase):
def setUp(self):
self._base_path = os.path.join('test_data', 'test_json')
......@@ -21,10 +29,12 @@ class DictGeneratorTest(unittest.TestCase):
with open(os.path.join(self._base_path, filename), 'r') as f:
return f.read()
def _LoadJSON(self, filename):
return json.loads(comment_eater.Nom(self._ReadLocalFile(filename)))[0]
def _GenerateTest(self, filename):
expected_json = json.loads(self._ReadLocalFile('expected_' + filename))
gen = HandlebarDictGenerator(
json.loads(comment_eater.Nom(self._ReadLocalFile(filename)))[0])
gen = HandlebarDictGenerator(self._LoadJSON(filename))
self.assertEquals(expected_json, gen.Generate())
def testGenerate(self):
......@@ -32,19 +42,32 @@ class DictGeneratorTest(unittest.TestCase):
def testGetLinkToRefType(self):
link = _GetLinkToRefType('truthTeller', 'liar.Tab')
self.assertEquals(link['href'], 'liar.html#type-Tab')
self.assertEquals(link['text'], 'Tab')
self.assertEquals('liar.html#type-Tab', link['href'])
self.assertEquals('liar.Tab', link['text'])
link = _GetLinkToRefType('truthTeller', 'Tab')
self.assertEquals(link['href'], 'truthTeller.html#type-Tab')
self.assertEquals(link['text'], 'Tab')
self.assertEquals('#type-Tab', link['href'])
self.assertEquals('Tab', link['text'])
link = _GetLinkToRefType('nay', 'lies.chrome.bookmarks.Tab')
self.assertEquals(link['href'], 'lies.html#type-chrome.bookmarks.Tab')
self.assertEquals(link['text'], 'chrome.bookmarks.Tab')
self.assertEquals('lies.chrome.bookmarks.html#type-Tab', link['href'])
self.assertEquals('lies.chrome.bookmarks.Tab', link['text'])
def testFormatValue(self):
self.assertEquals('1,234,567', _FormatValue(1234567))
self.assertEquals('67', _FormatValue(67))
self.assertEquals('234,567', _FormatValue(234567))
def testFormatDescription(self):
dict_ = HandlebarDictGenerator(self._LoadJSON('ref_test.json')).Generate()
self.assertEquals(_MakeLink('#type-type2', 'type2'),
_GetType(dict_, 'type1')['description'])
self.assertEquals(
'A %s, or %s' % (_MakeLink('#type-type3', 'type3'),
_MakeLink('#type-type2', 'type2')),
_GetType(dict_, 'type2')['description'])
self.assertEquals(
'%s != %s' % (_MakeLink('other.html#type-type2', 'other.type2'),
_MakeLink('#type-type2', 'type2')),
_GetType(dict_, 'type3')['description'])
if __name__ == '__main__':
unittest.main()
......@@ -4,159 +4,159 @@
"callback": {
"simple_type": {
"simple_type": "function"
},
"last": true,
"name": "callback",
},
"last": true,
"name": "callback",
"parameters": [
{
"functions": [],
"last": true,
"name": "results",
"functions": [],
"last": true,
"name": "results",
"array": {
"functions": [],
"name": "resultsElement",
"functions": [],
"name": "resultsElement",
"link": {
"text": "TypeA",
"href": "tester.html#type-TypeA"
},
"optional": false,
"properties": [],
"text": "TypeA",
"href": "#type-TypeA"
},
"optional": false,
"properties": [],
"description": null
},
"optional": false,
"properties": [],
},
"optional": false,
"properties": [],
"description": null
}
],
"optional": false,
],
"optional": false,
"description": null
},
"returns": null,
"name": "get",
},
"returns": null,
"name": "get",
"parameters": [
{
"functions": [],
"name": "a",
"functions": [],
"name": "a",
"choices": [
{
"functions": [],
"name": "a",
"simple_type": "string",
"optional": true,
"properties": [],
"functions": [],
"name": "a",
"simple_type": "string",
"optional": true,
"properties": [],
"description": null
},
},
{
"functions": [],
"last": true,
"name": "a",
"functions": [],
"last": true,
"name": "a",
"array": {
"functions": [],
"name": "aElement",
"simple_type": "string",
"optional": false,
"properties": [],
"functions": [],
"name": "aElement",
"simple_type": "string",
"optional": false,
"properties": [],
"description": null
},
"optional": true,
"properties": [],
},
"optional": true,
"properties": [],
"description": null
}
],
"optional": false,
"properties": [],
],
"optional": false,
"properties": [],
"description": "a param"
},
},
{
"simple_type": {
"simple_type": "function"
},
"last": true,
"name": "callback",
},
"last": true,
"name": "callback",
"parameters": [
{
"functions": [],
"last": true,
"name": "results",
"functions": [],
"last": true,
"name": "results",
"array": {
"functions": [],
"name": "resultsElement",
"functions": [],
"name": "resultsElement",
"link": {
"text": "TypeA",
"href": "tester.html#type-TypeA"
},
"optional": false,
"properties": [],
"text": "TypeA",
"href": "#type-TypeA"
},
"optional": false,
"properties": [],
"description": null
},
"optional": false,
"properties": [],
},
"optional": false,
"properties": [],
"description": null
}
],
"optional": false,
],
"optional": false,
"description": null
}
],
],
"description": "Gets stuff."
}
],
"properties": [],
"name": "tester",
],
"properties": [],
"name": "tester",
"types": [
{
"functions": [],
"name": "TypeA",
"simple_type": "object",
"properties": [
{
"functions": [],
"name": "b",
"functions": [],
"name": "b",
"array": {
"functions": [],
"name": "bElement",
"functions": [],
"name": "bElement",
"link": {
"text": "TypeA",
"href": "tester.html#type-TypeA"
},
"optional": false,
"properties": [],
"text": "TypeA",
"href": "#type-TypeA"
},
"optional": false,
"properties": [],
"description": null
},
"optional": true,
"properties": [],
},
"optional": true,
"properties": [],
"description": "List of TypeA."
}
],
],
"events": [],
"functions": [],
"name": "TypeA",
"simple_type": "object",
"description": "A cool thing."
}
],
],
"events": [
{
"name": "EventA",
"name": "EventA",
"parameters": [
{
"functions": [],
"name": "id",
"simple_type": "string",
"optional": false,
"properties": [],
"functions": [],
"name": "id",
"simple_type": "string",
"optional": false,
"properties": [],
"description": null
},
},
{
"functions": [],
"last": true,
"name": "bookmark",
"functions": [],
"last": true,
"name": "bookmark",
"link": {
"text": "TypeA",
"href": "tester.html#type-TypeA"
},
"optional": false,
"properties": [],
"text": "TypeA",
"href": "#type-TypeA"
},
"optional": false,
"properties": [],
"description": null
}
],
],
"description": "A cool event."
}
]
......
[
{
"namespace": "ref_test",
"types": [
{
"id": "type1",
"type": "string",
"description": "$ref:type2"
},
{
"id": "type2",
"type": "string",
"description": "A $ref:type3, or $ref:type2"
},
{
"id": "type3",
"type": "string",
"description": "$ref:other.type2 != $ref:ref_test.type2"
}
]
}
]
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment