Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make schema2html an entry point and test it.
Port to Python 3. Note that this doesn't do much validation of whether the output makes any sense (in multkey defaults, it doesn't), just that it runs. I'll work on making sense in other PRs if I keep going down the direction of using this to produce a sphinx extension.
- Loading branch information
Showing
8 changed files
with
284 additions
and
139 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
############################################################################## | ||
# | ||
# Copyright (c) 2003 Zope Corporation and Contributors. | ||
# All Rights Reserved. | ||
# | ||
# This software is subject to the provisions of the Zope Public License, | ||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. | ||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED | ||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS | ||
# FOR A PARTICULAR PURPOSE. | ||
# | ||
############################################################################## | ||
from __future__ import print_function | ||
|
||
import argparse | ||
import sys | ||
import cgi | ||
|
||
import ZConfig.loader | ||
|
||
from ZConfig.info import SectionType | ||
from ZConfig.info import SectionInfo | ||
from ZConfig.info import ValueInfo | ||
|
||
def esc(x): | ||
return cgi.escape(str(x)) | ||
|
||
def dt(x): | ||
tn = type(x).__name__ | ||
|
||
if isinstance(x, type): | ||
return '%s %s' % (tn, x.__module__ + '.' + x.__name__) | ||
|
||
return '%s %s' % (tn, x.__name__) | ||
|
||
class explain(object): | ||
done = [] | ||
|
||
def __call__(self, st, file=None): | ||
if st.name in self.done: # pragma: no cover | ||
return | ||
|
||
self.done.append(st.name) | ||
|
||
out = file or sys.stdout | ||
|
||
if st.description: | ||
print(st.description, file=out) | ||
for sub in st.getsubtypenames(): | ||
print('<dl>', file=out) | ||
printContents(None, st.getsubtype(sub), file=file) | ||
print('</dl>', file=out) | ||
|
||
explain = explain() | ||
|
||
def printSchema(schema, out): | ||
print('<dl>', file=out) | ||
for child in schema: | ||
printContents(*child, file=out) | ||
print('</dl>', file=out) | ||
|
||
def printContents(name, info, file=None): | ||
out = file or sys.stdout | ||
|
||
if isinstance(info, SectionType): | ||
print('<dt><b><i>', info.name, '</i></b> (%s)</dt>' % dt(info.datatype), file=out) | ||
print('<dd>', file=out) | ||
if info.description: | ||
print(info.description, file=out) | ||
print('<dl>', file=out) | ||
for sub in info: | ||
printContents(*sub, file=out) # pragma: no cover | ||
print('</dl></dd>', file=out) | ||
elif isinstance(info, SectionInfo): | ||
st = info.sectiontype | ||
if st.isabstract(): | ||
print('<dt><b><i>', st.name, '</i>', info.name, '</b></dt>', file=out) | ||
print('<dd>', file=out) | ||
if info.description: | ||
print(info.description, file=out) | ||
explain(st, file=out) | ||
print('</dd>', file=out) | ||
else: | ||
print('<dt><b>', info.attribute, info.name, '</b>', file=out) | ||
print('(%s)</dt>' % dt(info.datatype), file=out) | ||
print('<dd><dl>', file=out) | ||
for sub in info.sectiontype: | ||
printContents(*sub, file=out) | ||
print('</dl></dd>', file=out) | ||
else: | ||
print('<dt><b>',info.name, '</b>', '(%s)' % dt(info.datatype), file=out) | ||
default = info.getdefault() | ||
if isinstance(default, ValueInfo): | ||
print('(default: %r)' % esc(default.value), file=out) | ||
elif default is not None: | ||
print('(default: %r)' % esc(default), file=out) | ||
if info.metadefault: | ||
print('(metadefault: %s)' % info.metadefault, file=out) | ||
print('</dt>', file=out) | ||
if info.description: | ||
print('<dd>',info.description,'</dd>', file=out) | ||
|
||
def main(argv=None): | ||
argv = argv or sys.argv[1:] | ||
|
||
argparser = argparse.ArgumentParser( | ||
description="Print an HTML version of a schema") | ||
argparser.add_argument( | ||
"schema", | ||
help="The schema to print", | ||
default="-", | ||
type=argparse.FileType('r')) | ||
argparser.add_argument( | ||
"--out", "-o", | ||
help="Write the schema to this file; if not given, write to stdout", | ||
type=argparse.FileType('w')) | ||
|
||
args = argparser.parse_args(argv) | ||
|
||
out = args.out or sys.stdout | ||
|
||
schema = ZConfig.loader.loadSchemaFile(args.schema) | ||
|
||
print('''<html><body> | ||
<style> | ||
dl {margin: 0 0 1em 0;} | ||
</style> | ||
''', file=out) | ||
printSchema(schema, out) | ||
print('</body></html>', file=out) | ||
|
||
return 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
############################################################################## | ||
# | ||
# Copyright (c) 2017 Zope Foundation and Contributors. | ||
# All Rights Reserved. | ||
# | ||
# This software is subject to the provisions of the Zope Public License, | ||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. | ||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED | ||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS | ||
# FOR A PARTICULAR PURPOSE. | ||
# | ||
############################################################################## | ||
from __future__ import absolute_import | ||
|
||
import contextlib | ||
import sys | ||
import unittest | ||
|
||
try: | ||
# Note that we're purposely using the old | ||
# StringIO object on Python 2 because it auto-converts | ||
# Unicode to str, which io.BytesIO and io.StringIO don't | ||
# but which normal printing to default sys.stdout *does* | ||
from cStringIO import StringIO | ||
except ImportError: | ||
from ZConfig._compat import NStringIO as StringIO | ||
|
||
|
||
from ZConfig import schema2html | ||
|
||
from .support import input_file | ||
from .support import with_stdin_from_input_file | ||
|
||
|
||
@contextlib.contextmanager | ||
def stdout_replaced(buf): | ||
old_stdout = sys.stdout | ||
sys.stdout = buf | ||
try: | ||
yield | ||
finally: | ||
sys.stdout = old_stdout | ||
|
||
|
||
def run_transform(*args): | ||
if '--out' not in args and '-o' not in args: | ||
buf = StringIO() | ||
with stdout_replaced(buf): | ||
schema2html.main(args) | ||
return buf | ||
return schema2html.main(args) | ||
|
||
|
||
|
||
class TestSchema2HTML(unittest.TestCase): | ||
|
||
def test_no_schema(self): | ||
self.assertRaises(SystemExit, | ||
run_transform) | ||
|
||
def test_schema_only(self): | ||
res = run_transform(input_file('simple.xml')) | ||
self.assertIn('</html>', res.getvalue()) | ||
|
||
@with_stdin_from_input_file('simple.xml') | ||
def test_schema_only_redirect(self): | ||
res = run_transform("-") | ||
self.assertIn('</html>', res.getvalue()) | ||
|
||
def test_cover_all_schemas(self): | ||
for name in ('base-datatype1.xml', | ||
'base-datatype2.xml', | ||
'base-keytype1.xml', | ||
'base-keytype2.xml', | ||
'base.xml', | ||
'library.xml', | ||
'simplesections.xml',): | ||
res = run_transform(input_file(name)) | ||
self.assertIn('</html>', res.getvalue()) | ||
|
||
|
||
def test_suite(): | ||
return unittest.makeSuite(TestSchema2HTML) | ||
|
||
if __name__ == "__main__": | ||
unittest.main(defaultTest="test_suite") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.