|
""" tests document generation |
""" |
|
import py |
from StringIO import StringIO |
|
from py.__.apigen.rest.genrest import ViewVC, RestGen, PipeWriter, \ |
DirWriter, FileWriter, \ |
DirectPaste, DirectFS, \ |
HTMLDirWriter, SourceView |
from py.__.apigen.tracer.tracer import Tracer |
from py.__.apigen.tracer.docstorage import DocStorage, DocStorageAccessor |
from py.__.apigen.tracer.permastore import PermaDocStorage |
import pickle |
|
from py.__.apigen.tracer.testing.runtest import cut_pyc |
from py.__.doc.conftest import genlinkchecks |
from py.__.rest.rst import Rest, Paragraph |
from py.__.rest.transform import HTMLHandler |
|
|
sorted = py.builtin.sorted |
|
def _nl(s): |
"""normalize newlines (converting to \n)""" |
s = s.replace('\r\n', '\n') |
s = s.replace('\r', '\n') |
return s |
|
def setup_module(mod): |
mod.temppath = py.test.ensuretemp('restgen') |
|
def fun_(): |
pass |
|
class SomeClass(object): |
"""Some class definition""" |
|
def __init__(self, a): |
self.a = a |
|
def method(self, a, b, c): |
"""method docstring""" |
return a + b + c |
|
class SomeSubClass(SomeClass): |
"""Some subclass definition""" |
|
def fun(a, b, c): |
"""Some docstring |
|
Let's make it span a couple of lines to be interesting... |
|
Note: |
|
* rest |
* should |
* be |
* supported |
* or |
* ignored... |
""" |
return "d" |
|
def test_direct_link(): |
fname = cut_pyc(__file__) |
title, link = DirectPaste().getlink(fname, 2, "") |
assert title == '%s:%s' % (fname, 2) |
assert link == '' |
|
def test_viewvc_link(): |
vcview = ViewVC("http://codespeak.net/viewvc/") |
fname = cut_pyc(__file__) |
title, link = vcview.getlink(fname, 0, "") |
assert title == '%s:%s' % (fname, 0) |
assert link == ('http://codespeak.net/viewvc/py/apigen/rest/' |
'testing/test_rest.py?view=markup') |
|
def test_fs_link(): |
title, link = DirectFS().getlink('/foo/bar/baz.py', 100, "func") |
assert title == '/foo/bar/baz.py:100' |
assert link == 'file:///foo/bar/baz.py' |
|
class WriterTest(object): |
def get_filled_writer(self, writerclass, *args, **kwargs): |
dw = writerclass(*args, **kwargs) |
dw.write_section('foo', Rest(Paragraph('foo data'))) |
dw.write_section('bar', Rest(Paragraph('bar data'))) |
return dw |
|
class TestDirWriter(WriterTest): |
def test_write_section(self): |
tempdir = temppath.ensure('dirwriter', dir=True) |
dw = self.get_filled_writer(DirWriter, tempdir) |
fpaths = tempdir.listdir('*.txt') |
assert len(fpaths) == 2 |
assert sorted([f.basename for f in fpaths]) == ['bar.txt', 'foo.txt'] |
assert _nl(tempdir.join('foo.txt').read()) == 'foo data\n' |
assert _nl(tempdir.join('bar.txt').read()) == 'bar data\n' |
|
def test_getlink(self): |
dw = DirWriter(temppath.join('dirwriter_getlink')) |
link = dw.getlink('function', 'Foo.bar', 'method_foo_bar') |
assert link == 'method_foo_bar.html' |
|
class TestFileWriter(WriterTest): |
def test_write_section(self): |
tempfile = temppath.ensure('filewriter', file=True) |
fw = self.get_filled_writer(FileWriter, tempfile) |
data = tempfile.read() |
assert len(data) |
|
def test_getlink(self): |
fw = FileWriter(temppath.join('filewriter_getlink')) |
link = fw.getlink('function', 'Foo.bar', 'method_foo_bar') |
assert link == '#function-foo-bar' |
|
link = fw.getlink('function', 'Foo.bar', 'method_foo_bar') |
assert link is None |
link = fw.getlink('function', 'Foo.__init__', 'method_foo___init__') |
assert link == '#function-foo-init' |
|
class TestPipeWriter(WriterTest): |
def test_write_section(self): |
s = StringIO() |
pw = self.get_filled_writer(PipeWriter, s) |
data = s.getvalue() |
assert len(data) |
|
def test_getlink(self): |
pw = PipeWriter(StringIO()) |
link = pw.getlink('function', 'Foo.bar', 'method_foo_bar') |
assert link == 'method_foo_bar.txt' |
|
class TestHTMLDirWriter(WriterTest): |
def test_write_section(self): |
tempdir = temppath.ensure('htmldirwriter', dir=1) |
hdw = self.get_filled_writer(HTMLDirWriter, HTMLHandler, HTMLHandler, |
tempdir) |
assert tempdir.join('foo.html').check(file=1) |
assert tempdir.join('bar.html').check(file=1) |
assert tempdir.join('foo.html').read().startswith('<html>') |
|
class TestRest(object): |
def get_filled_docstorage(self): |
descs = {'SomeClass': SomeClass, |
'SomeSubClass': SomeSubClass, |
'fun':fun} |
ds = DocStorage().from_dict(descs) |
t = Tracer(ds) |
t.start_tracing() |
s1 = SomeClass("a") |
fun(1, 2, s1) |
s2 = SomeSubClass("b") |
s2.method(1,2,3) |
fun(1, 3, s2) |
t.end_tracing() |
return DocStorageAccessor(ds) |
|
def get_filled_docstorage_modules(self): |
import somemodule |
import someothermodule |
descs = { |
'somemodule.SomeClass': somemodule.SomeClass, |
'someothermodule.SomeSubClass': someothermodule.SomeSubClass, |
'someothermodule.fun': someothermodule.fun, |
} |
ds = DocStorage().from_dict(descs) |
t = Tracer(ds) |
t.start_tracing() |
s1 = somemodule.SomeClass("a") |
someothermodule.fun(1, 2, s1) |
s2 = someothermodule.SomeSubClass("b") |
s2.method(1, 2, 3) |
someothermodule.fun(1, 3, s2) |
t.end_tracing() |
return DocStorageAccessor(ds) |
|
def check_rest(self, tempdir): |
from py.__.misc import rest |
for path in tempdir.listdir('*.txt'): |
try: |
rest.process(path) |
except ImportError: |
py.test.skip('skipping rest generation because docutils is ' |
'not installed (this is a partial skip, the rest ' |
'of the test was successful)') |
for path in tempdir.listdir('*.txt'): |
for item, arg1, arg2, arg3 in genlinkchecks(path): |
item(arg1, arg2, arg3) |
|
def test_generation_simple_api(self): |
ds = self.get_filled_docstorage() |
lg = DirectPaste() |
tempdir = temppath.ensure("simple_api", dir=True) |
r = RestGen(ds, lg, DirWriter(tempdir)) |
r.write() |
basenames = [p.basename for p in tempdir.listdir('*.txt')] |
expected = [ |
'class_SomeClass.txt', |
'class_SomeSubClass.txt', |
'function_fun.txt', |
'index.txt', |
'method_SomeClass.__init__.txt', |
'method_SomeClass.method.txt', |
'method_SomeSubClass.__init__.txt', |
'method_SomeSubClass.method.txt', |
'module_Unknown module.txt', |
'traceback_SomeClass.__init__.0.txt', |
'traceback_SomeSubClass.__init__.0.txt', |
'traceback_SomeSubClass.method.0.txt', |
'traceback_fun.0.txt', |
'traceback_fun.1.txt', |
] |
print sorted(basenames) |
assert sorted(basenames) == expected |
|
self.check_rest(tempdir) |
tempdir = temppath.ensure("simple_api_ps", dir=True) |
if 0: |
ps = PermaDocStorage(ds) |
r = RestGen(ps, lg, DirWriter(tempdir)) |
r.write() |
basenames = [p.basename for p in tempdir.listdir('*.txt')] |
assert sorted(basenames) == expected |
self.check_rest(tempdir) |
pickle.dumps(ps) |
|
def test_generation_modules(self): |
ds = self.get_filled_docstorage_modules() |
lg = DirectPaste() |
tempdir = temppath.ensure('module_api', dir=True) |
r = RestGen(ds, lg, DirWriter(tempdir)) |
r.write() |
basenames = [p.basename for p in tempdir.listdir('*.txt')] |
expected = [ |
'class_somemodule.SomeClass.txt', |
'class_someothermodule.SomeSubClass.txt', |
'function_someothermodule.fun.txt', |
'index.txt', |
'method_somemodule.SomeClass.__init__.txt', |
'method_somemodule.SomeClass.method.txt', |
'method_someothermodule.SomeSubClass.__init__.txt', |
'method_someothermodule.SomeSubClass.method.txt', |
'module_Unknown module.txt', |
'module_somemodule.txt', |
'module_someothermodule.txt', |
'traceback_somemodule.SomeClass.__init__.0.txt', |
'traceback_someothermodule.SomeSubClass.__init__.0.txt', |
'traceback_someothermodule.SomeSubClass.method.0.txt', |
'traceback_someothermodule.fun.0.txt', |
'traceback_someothermodule.fun.1.txt', |
] |
print sorted(basenames) |
assert sorted(basenames) == expected |
|
def test_check_internal_links(self): |
ds = self.get_filled_docstorage() |
lg = DirectFS() |
tempdir = temppath.ensure('internal_links', dir=True) |
r = RestGen(ds, lg, DirWriter(tempdir)) |
r.write() |
index = tempdir.join('module_Unknown module.txt') |
assert index.check(file=True) |
data = _nl(index.read()) |
assert data.find('.. _`fun`: function_fun.html\n') > -1 |
assert data.find('.. _`fun`: #function-fun\n') == -1 |
|
tempfile = temppath.ensure('internal_links.txt', |
file=True) |
r = RestGen(ds, lg, FileWriter(tempfile)) |
r.write() |
data = _nl(tempfile.read()) |
assert data.find('.. _`fun`: #function-fun\n') > -1 |
assert data.find('.. _`fun`: function_fun.html') == -1 |
tempfile = temppath.ensure("internal_links_ps.txt", file=True) |
if 0: |
ps = PermaDocStorage(ds) |
r = RestGen(ps, lg, FileWriter(tempfile)) |
r.write() |
data = _nl(tempfile.read()) |
assert data.find('.. _`fun`: #function-fun\n') > -1 |
assert data.find('.. _`fun`: function_fun.html') == -1 |
pickle.dumps(ps) |
|
def test_check_section_order(self): |
|
tempfile = temppath.join('internal_links.txt') |
if not tempfile.check(): |
py.test.skip('depends on previous test, which failed') |
data = _nl(tempfile.read()) |
|
assert data.find('classes\\:') > -1 |
assert data.find('classes\\:') < data.find('function\\: fun') |
assert data.find('classes\\:') < data.find( |
'class\\: SomeClass') |
|
assert data.find('function\\: fun') > data.find('class\\: SomeClass') |
|
assert data.find('class\\: SomeClass') < data.find( |
'method\\: SomeClass.method') |
|
assert data.find('method\\: SomeClass.\\_\\_init\\_\\_') > -1 |
assert data.find('method\\: SomeClass.\\_\\_init\\_\\_') < data.find( |
'method\\: SomeClass.method') |
|
assert py.std.re.search(r'class\\\: SomeSubClass.*' |
r'base classes\\\:\n\^+[\n ]+\* `SomeClass`_.*' |
r'`SomeSubClass.__init__', |
data, py.std.re.S) |
|
def test_som_fun(self): |
descs = {'fun_': fun_} |
ds = DocStorage().from_dict(descs) |
t = Tracer(ds) |
t.start_tracing() |
fun_() |
t.end_tracing() |
lg = DirectPaste() |
tempdir = temppath.ensure("some_fun", dir=True) |
r = RestGen(DocStorageAccessor(ds), lg, DirWriter(tempdir)) |
r.write() |
self.check_rest(tempdir) |
|
def test_function_source(self): |
def blah(): |
a = 3 |
b = 4 |
return a + b |
|
descs = {'blah': blah} |
ds = DocStorage().from_dict(descs) |
t = Tracer(ds) |
t.start_tracing() |
blah() |
t.end_tracing() |
lg = DirectPaste() |
tempdir = temppath.ensure("function_source", dir=True) |
r = RestGen(DocStorageAccessor(ds), lg, DirWriter(tempdir)) |
r.write() |
assert tempdir.join("function_blah.txt").read().find("a = 3") != -1 |
self.check_rest(tempdir) |
ps = DocStorageAccessor(ds) |
r = RestGen(ps, lg, DirWriter(tempdir)) |
r.write() |
assert tempdir.join("function_blah.txt").read().find("a = 3") != -1 |
|
def test_function_arguments(self): |
def blah(a, b, c): |
return "axx" |
|
class C: |
pass |
|
descs = {'blah':blah} |
ds = DocStorage().from_dict(descs) |
t = Tracer(ds) |
t.start_tracing() |
blah(3, "x", C()) |
t.end_tracing() |
lg = DirectPaste() |
tempdir = temppath.ensure("function_args", dir=True) |
r = RestGen(DocStorageAccessor(ds), lg, DirWriter(tempdir)) |
r.write() |
source = tempdir.join("function_blah.txt").read() |
call_point = source.find("call sites\:") |
assert call_point != -1 |
assert source.find("a \:\: <Int>") < call_point |
assert source.find("b \:\: <String>") < call_point |
assert source.find("c \:\: <Instance of Class C>") < call_point |
self.check_rest(tempdir) |
|
def test_class_typedefs(self): |
class A(object): |
def __init__(self, x): |
pass |
|
def a(self): |
pass |
|
class B(A): |
def __init__(self, y): |
pass |
|
def xxx(x): |
return x |
|
descs = {'A': A, 'B': B, 'xxx':xxx} |
ds = DocStorage().from_dict(descs) |
t = Tracer(ds) |
t.start_tracing() |
xxx(A(3)) |
xxx(B("f")) |
t.end_tracing() |
lg = DirectPaste() |
tempdir = temppath.ensure("classargs", dir=True) |
r = RestGen(DocStorageAccessor(ds), lg, DirWriter(tempdir)) |
r.write() |
source = tempdir.join("function_xxx.txt").read() |
call_point = source.find("call sites\:") |
assert call_point != -1 |
print source |
assert -1 < source.find("x \:\: <Instance of AnyOf( `Class B`_ , " |
"`Class A`_ )>") < call_point |
source = tempdir.join('method_B.a.txt').read() |
py.test.skip('XXX needs to be fixed, clueless atm though') |
assert source.find('**origin** \: `A`_') > -1 |
self.check_rest(tempdir) |
|
def test_exc_raising(self): |
def x(): |
try: |
1/0 |
except: |
pass |
|
descs = {'x':x} |
ds = DocStorage().from_dict(descs) |
t = Tracer(ds) |
t.start_tracing() |
x() |
t.end_tracing() |
lg = DirectPaste() |
tempdir = temppath.ensure("exc_raising", dir=True) |
r = RestGen(DocStorageAccessor(ds), lg, DirWriter(tempdir)) |
r.write() |
source = tempdir.join('function_x.txt').open().read() |
assert source.find('ZeroDivisionError') < source.find('call sites\:') |
|
|
def test_nonexist_origin(self): |
class A: |
def method(self): |
pass |
|
class B(A): |
pass |
|
descs = {'B':B} |
ds = DocStorage().from_dict(descs) |
t = Tracer(ds) |
t.start_tracing() |
B().method() |
t.end_tracing() |
lg = DirectPaste() |
tempdir = temppath.ensure("nonexit_origin", dir=True) |
r = RestGen(DocStorageAccessor(ds), lg, DirWriter(tempdir)) |
r.write() |
self.check_rest(tempdir) |
|
def test_sourceview(self): |
class A: |
def method(self): |
pass |
|
descs = {'A':A} |
ds = DocStorage().from_dict(descs) |
t = Tracer(ds) |
t.start_tracing() |
A().method() |
t.end_tracing() |
lg = SourceView('http://localhost:8000') |
tempdir = temppath.ensure("sourceview", dir=True) |
r = RestGen(DocStorageAccessor(ds), lg, DirWriter(tempdir)) |
r.write() |
self.check_rest(tempdir) |
assert tempdir.join('traceback_A.method.0.txt').open().read().find( |
'.. _`/py/apigen/rest/testing/test\_rest.py\:A.method`: http://localhost:8000/py/apigen/rest/testing/test_rest.py#A.method') != -1 |
|
def test_sourceview_fun(self): |
def f(): |
pass |
|
descs = {'f':f} |
ds = DocStorage().from_dict(descs) |
t = Tracer(ds) |
t.start_tracing() |
f() |
t.end_tracing() |
tempdir = temppath.ensure("sourceview_fun", dir=True) |
lg = SourceView('http://localhost:8000') |
r = RestGen(DocStorageAccessor(ds), lg, DirWriter(tempdir)) |
r.write() |
self.check_rest(tempdir) |
assert tempdir.join('function_f.txt').open().read().find( |
'.. _`/py/apigen/rest/testing/test\_rest.py\:f`: http://localhost:8000/py/apigen/rest/testing/test_rest.py#f') != -1 |
|