Index: third_party/twisted_8_1/twisted/python/test/test_release.py |
diff --git a/third_party/twisted_8_1/twisted/python/test/test_release.py b/third_party/twisted_8_1/twisted/python/test/test_release.py |
deleted file mode 100644 |
index a12eeae7332176932ec9c13836d9dffb767cef75..0000000000000000000000000000000000000000 |
--- a/third_party/twisted_8_1/twisted/python/test/test_release.py |
+++ /dev/null |
@@ -1,1516 +0,0 @@ |
-# Copyright (c) 2007-2008 Twisted Matrix Laboratories. |
-# See LICENSE for details. |
- |
-""" |
-Tests for L{twisted.python.release} and L{twisted.python._release}. |
-""" |
- |
-import warnings |
-import operator |
-import os, sys, signal |
-from StringIO import StringIO |
-import tarfile |
- |
-from datetime import date |
- |
-try: |
- import pydoctor.driver |
- # it might not be installed, or it might use syntax not available in |
- # this version of Python. |
-except (ImportError, SyntaxError): |
- pydoctor = None |
- |
-from twisted.trial.unittest import TestCase |
- |
-from twisted.python.compat import set |
-from twisted.python.procutils import which |
-from twisted.python import release |
-from twisted.python.filepath import FilePath |
-from twisted.python.util import dsu |
-from twisted.python.versions import Version |
-from twisted.python._release import _changeVersionInFile, getNextVersion |
-from twisted.python._release import findTwistedProjects, replaceInFile |
-from twisted.python._release import replaceProjectVersion |
-from twisted.python._release import updateTwistedVersionInformation, Project |
-from twisted.python._release import VERSION_OFFSET, DocBuilder, ManBuilder |
-from twisted.python._release import NoDocumentsFound, filePathDelta |
-from twisted.python._release import CommandFailed, BookBuilder |
-from twisted.python._release import DistributionBuilder, APIBuilder |
- |
-try: |
- from twisted.lore.scripts import lore |
-except ImportError: |
- lore = None |
- |
- |
- |
-class ChangeVersionTest(TestCase): |
- """ |
- Twisted has the ability to change versions. |
- """ |
- |
- def makeFile(self, relativePath, content): |
- """ |
- Create a file with the given content relative to a temporary directory. |
- |
- @param relativePath: The basename of the file to create. |
- @param content: The content that the file will have. |
- @return: The filename. |
- """ |
- baseDirectory = FilePath(self.mktemp()) |
- directory, filename = os.path.split(relativePath) |
- directory = baseDirectory.preauthChild(directory) |
- directory.makedirs() |
- file = directory.child(filename) |
- directory.child(filename).setContent(content) |
- return file |
- |
- |
- def test_getNextVersion(self): |
- """ |
- When calculating the next version to release when a release is |
- happening in the same year as the last release, the minor version |
- number is incremented. |
- """ |
- now = date.today() |
- major = now.year - VERSION_OFFSET |
- version = Version("twisted", major, 9, 0) |
- self.assertEquals(getNextVersion(version, now=now), |
- Version("twisted", major, 10, 0)) |
- |
- |
- def test_getNextVersionAfterYearChange(self): |
- """ |
- When calculating the next version to release when a release is |
- happening in a later year, the minor version number is reset to 0. |
- """ |
- now = date.today() |
- major = now.year - VERSION_OFFSET |
- version = Version("twisted", major - 1, 9, 0) |
- self.assertEquals(getNextVersion(version, now=now), |
- Version("twisted", major, 0, 0)) |
- |
- |
- def test_changeVersionInFile(self): |
- """ |
- _changeVersionInFile replaces the old version information in a file |
- with the given new version information. |
- """ |
- # The version numbers are arbitrary, the name is only kind of |
- # arbitrary. |
- packageName = 'foo' |
- oldVersion = Version(packageName, 2, 5, 0) |
- file = self.makeFile('README', |
- "Hello and welcome to %s." % oldVersion.base()) |
- |
- newVersion = Version(packageName, 7, 6, 0) |
- _changeVersionInFile(oldVersion, newVersion, file.path) |
- |
- self.assertEqual(file.getContent(), |
- "Hello and welcome to %s." % newVersion.base()) |
- |
- |
- |
-class ProjectTest(TestCase): |
- """ |
- There is a first-class representation of a project. |
- """ |
- |
- def assertProjectsEqual(self, observedProjects, expectedProjects): |
- """ |
- Assert that two lists of L{Project}s are equal. |
- """ |
- self.assertEqual(len(observedProjects), len(expectedProjects)) |
- observedProjects = dsu(observedProjects, |
- key=operator.attrgetter('directory')) |
- expectedProjects = dsu(expectedProjects, |
- key=operator.attrgetter('directory')) |
- for observed, expected in zip(observedProjects, expectedProjects): |
- self.assertEqual(observed.directory, expected.directory) |
- |
- |
- def makeProject(self, version, baseDirectory=None): |
- """ |
- Make a Twisted-style project in the given base directory. |
- |
- @param baseDirectory: The directory to create files in |
- (as a L{FilePath). |
- @param version: The version information for the project. |
- @return: L{Project} pointing to the created project. |
- """ |
- if baseDirectory is None: |
- baseDirectory = FilePath(self.mktemp()) |
- baseDirectory.createDirectory() |
- segments = version.package.split('.') |
- directory = baseDirectory |
- for segment in segments: |
- directory = directory.child(segment) |
- if not directory.exists(): |
- directory.createDirectory() |
- directory.child('__init__.py').setContent('') |
- directory.child('topfiles').createDirectory() |
- directory.child('topfiles').child('README').setContent(version.base()) |
- replaceProjectVersion( |
- version.package, directory.child('_version.py').path, |
- version) |
- return Project(directory) |
- |
- |
- def makeProjects(self, *versions): |
- """ |
- Create a series of projects underneath a temporary base directory. |
- |
- @return: A L{FilePath} for the base directory. |
- """ |
- baseDirectory = FilePath(self.mktemp()) |
- baseDirectory.createDirectory() |
- for version in versions: |
- self.makeProject(version, baseDirectory) |
- return baseDirectory |
- |
- |
- def test_getVersion(self): |
- """ |
- Project objects know their version. |
- """ |
- version = Version('foo', 2, 1, 0) |
- project = self.makeProject(version) |
- self.assertEquals(project.getVersion(), version) |
- |
- |
- def test_updateVersion(self): |
- """ |
- Project objects know how to update the version numbers in those |
- projects. |
- """ |
- project = self.makeProject(Version("bar", 2, 1, 0)) |
- newVersion = Version("bar", 3, 2, 9) |
- project.updateVersion(newVersion) |
- self.assertEquals(project.getVersion(), newVersion) |
- self.assertEquals( |
- project.directory.child("topfiles").child("README").getContent(), |
- "3.2.9") |
- |
- |
- def test_repr(self): |
- """ |
- The representation of a Project is Project(directory). |
- """ |
- foo = Project(FilePath('bar')) |
- self.assertEqual( |
- repr(foo), 'Project(%r)' % (foo.directory)) |
- |
- |
- def test_findTwistedStyleProjects(self): |
- """ |
- findTwistedStyleProjects finds all projects underneath a particular |
- directory. A 'project' is defined by the existence of a 'topfiles' |
- directory and is returned as a Project object. |
- """ |
- baseDirectory = self.makeProjects( |
- Version('foo', 2, 3, 0), Version('foo.bar', 0, 7, 4)) |
- projects = findTwistedProjects(baseDirectory) |
- self.assertProjectsEqual( |
- projects, |
- [Project(baseDirectory.child('foo')), |
- Project(baseDirectory.child('foo').child('bar'))]) |
- |
- |
- def test_updateTwistedVersionInformation(self): |
- """ |
- Update Twisted version information in the top-level project and all of |
- the subprojects. |
- """ |
- baseDirectory = FilePath(self.mktemp()) |
- baseDirectory.createDirectory() |
- now = date.today() |
- |
- projectName = 'foo' |
- oldVersion = Version(projectName, 2, 5, 0) |
- newVersion = getNextVersion(oldVersion, now=now) |
- |
- project = self.makeProject(oldVersion, baseDirectory) |
- |
- updateTwistedVersionInformation(baseDirectory, now=now) |
- |
- self.assertEqual(project.getVersion(), newVersion) |
- self.assertEqual( |
- project.directory.child('topfiles').child('README').getContent(), |
- newVersion.base()) |
- |
- |
- |
-class UtilityTest(TestCase): |
- """ |
- Tests for various utility functions for releasing. |
- """ |
- |
- def test_chdir(self): |
- """ |
- Test that the runChdirSafe is actually safe, i.e., it still |
- changes back to the original directory even if an error is |
- raised. |
- """ |
- cwd = os.getcwd() |
- def chAndBreak(): |
- os.mkdir('releaseCh') |
- os.chdir('releaseCh') |
- 1/0 |
- self.assertRaises(ZeroDivisionError, |
- release.runChdirSafe, chAndBreak) |
- self.assertEquals(cwd, os.getcwd()) |
- |
- |
- |
- def test_replaceInFile(self): |
- """ |
- L{replaceInFile} replaces data in a file based on a dict. A key from |
- the dict that is found in the file is replaced with the corresponding |
- value. |
- """ |
- in_ = 'foo\nhey hey $VER\nbar\n' |
- outf = open('release.replace', 'w') |
- outf.write(in_) |
- outf.close() |
- |
- expected = in_.replace('$VER', '2.0.0') |
- replaceInFile('release.replace', {'$VER': '2.0.0'}) |
- self.assertEquals(open('release.replace').read(), expected) |
- |
- |
- expected = expected.replace('2.0.0', '3.0.0') |
- replaceInFile('release.replace', {'2.0.0': '3.0.0'}) |
- self.assertEquals(open('release.replace').read(), expected) |
- |
- |
- |
-class VersionWritingTest(TestCase): |
- """ |
- Tests for L{replaceProjectVersion}. |
- """ |
- |
- def test_replaceProjectVersion(self): |
- """ |
- L{replaceProjectVersion} writes a Python file that defines a |
- C{version} variable that corresponds to the given name and version |
- number. |
- """ |
- replaceProjectVersion("twisted.test_project", |
- "test_project", Version("whatever", 0, 82, 7)) |
- ns = {'__name___': 'twisted.test_project'} |
- execfile("test_project", ns) |
- self.assertEquals(ns["version"].base(), "0.82.7") |
- |
- |
- def test_replaceProjectVersionWithPrerelease(self): |
- """ |
- L{replaceProjectVersion} will write a Version instantiation that |
- includes a prerelease parameter if necessary. |
- """ |
- replaceProjectVersion("twisted.test_project", |
- "test_project", Version("whatever", 0, 82, 7, |
- prerelease=8)) |
- ns = {'__name___': 'twisted.test_project'} |
- execfile("test_project", ns) |
- self.assertEquals(ns["version"].base(), "0.82.7pre8") |
- |
- |
- |
-class BuilderTestsMixin(object): |
- """ |
- A mixin class which provides various methods for creating sample Lore input |
- and output. |
- |
- @cvar template: The lore template that will be used to prepare sample |
- output. |
- @type template: C{str} |
- |
- @ivar docCounter: A counter which is incremented every time input is |
- generated and which is included in the documents. |
- @type docCounter: C{int} |
- """ |
- template = ''' |
- <html> |
- <head><title>Yo:</title></head> |
- <body> |
- <div class="body" /> |
- <a href="index.html">Index</a> |
- <span class="version">Version: </span> |
- </body> |
- </html> |
- ''' |
- |
- def setUp(self): |
- """ |
- Initialize the doc counter which ensures documents are unique. |
- """ |
- self.docCounter = 0 |
- |
- |
- def getArbitraryOutput(self, version, counter, prefix=""): |
- """ |
- Get the correct HTML output for the arbitrary input returned by |
- L{getArbitraryLoreInput} for the given parameters. |
- |
- @param version: The version string to include in the output. |
- @type version: C{str} |
- @param counter: A counter to include in the output. |
- @type counter: C{int} |
- """ |
- document = ('<?xml version="1.0"?><html><head>' |
- '<title>Yo:Hi! Title: %(count)s</title></head>' |
- '<body><div class="content">Hi! %(count)s' |
- '<div class="API"><a href="foobar" title="foobar">' |
- 'foobar</a></div></div><a href="%(prefix)sindex.html">' |
- 'Index</a><span class="version">Version: %(version)s' |
- '</span></body></html>') |
- return document % {"count": counter, "prefix": prefix, |
- "version": version} |
- |
- |
- def getArbitraryLoreInput(self, counter): |
- """ |
- Get an arbitrary, unique (for this test case) string of lore input. |
- |
- @param counter: A counter to include in the input. |
- @type counter: C{int} |
- """ |
- template = ( |
- '<html>' |
- '<head><title>Hi! Title: %(count)s</title></head>' |
- '<body>' |
- 'Hi! %(count)s' |
- '<div class="API">foobar</div>' |
- '</body>' |
- '</html>') |
- return template % {"count": counter} |
- |
- |
- def getArbitraryLoreInputAndOutput(self, version, prefix=""): |
- """ |
- Get an input document along with expected output for lore run on that |
- output document, assuming an appropriately-specified C{self.template}. |
- |
- @param version: A version string to include in the input and output. |
- @type version: C{str} |
- @param prefix: The prefix to include in the link to the index. |
- @type prefix: C{str} |
- |
- @return: A two-tuple of input and expected output. |
- @rtype: C{(str, str)}. |
- """ |
- self.docCounter += 1 |
- return (self.getArbitraryLoreInput(self.docCounter), |
- self.getArbitraryOutput(version, self.docCounter, |
- prefix=prefix)) |
- |
- |
- def getArbitraryManInput(self): |
- """ |
- Get an arbitrary man page content. |
- """ |
- return """.TH MANHOLE "1" "August 2001" "" "" |
-.SH NAME |
-manhole \- Connect to a Twisted Manhole service |
-.SH SYNOPSIS |
-.B manhole |
-.SH DESCRIPTION |
-manhole is a GTK interface to Twisted Manhole services. You can execute python |
-code as if at an interactive Python console inside a running Twisted process |
-with this.""" |
- |
- |
- def getArbitraryManLoreOutput(self): |
- """ |
- Get an arbitrary lore input document which represents man-to-lore |
- output based on the man page returned from L{getArbitraryManInput} |
- """ |
- return ("<html><head>\n<title>MANHOLE.1</title>" |
- "</head>\n<body>\n\n<h1>MANHOLE.1</h1>\n\n<h2>NAME</h2>\n\n" |
- "<p>manhole - Connect to a Twisted Manhole service\n</p>\n\n" |
- "<h2>SYNOPSIS</h2>\n\n<p><strong>manhole</strong> </p>\n\n" |
- "<h2>DESCRIPTION</h2>\n\n<p>manhole is a GTK interface to Twisted " |
- "Manhole services. You can execute python\ncode as if at an " |
- "interactive Python console inside a running Twisted process\nwith" |
- " this.</p>\n\n</body>\n</html>\n") |
- |
- |
- def getArbitraryManHTMLOutput(self, version, prefix=""): |
- """ |
- Get an arbitrary lore output document which represents the lore HTML |
- output based on the input document returned from |
- L{getArbitraryManLoreOutput}. |
- |
- @param version: A version string to include in the document. |
- @type version: C{str} |
- @param prefix: The prefix to include in the link to the index. |
- @type prefix: C{str} |
- """ |
- return ('<?xml version="1.0"?><html><head>' |
- '<title>Yo:MANHOLE.1</title></head><body><div class="content">' |
- '<span></span><h2>NAME<a name="auto0"></a></h2><p>manhole - ' |
- 'Connect to a Twisted Manhole service\n</p><h2>SYNOPSIS<a ' |
- 'name="auto1"></a></h2><p><strong>manhole</strong></p><h2>' |
- 'DESCRIPTION<a name="auto2"></a></h2><p>manhole is a GTK ' |
- 'interface to Twisted Manhole services. You can execute ' |
- 'python\ncode as if at an interactive Python console inside a ' |
- 'running Twisted process\nwith this.</p></div><a ' |
- 'href="%sindex.html">Index</a><span class="version">Version: ' |
- '%s</span></body></html>' % (prefix, version)) |
- |
- |
- |
- |
-class DocBuilderTestCase(TestCase, BuilderTestsMixin): |
- """ |
- Tests for L{DocBuilder}. |
- |
- Note for future maintainers: The exact byte equality assertions throughout |
- this suite may need to be updated due to minor differences in lore. They |
- should not be taken to mean that Lore must maintain the same byte format |
- forever. Feel free to update the tests when Lore changes, but please be |
- careful. |
- """ |
- |
- def setUp(self): |
- """ |
- Set up a few instance variables that will be useful. |
- |
- @ivar builder: A plain L{DocBuilder}. |
- @ivar docCounter: An integer to be used as a counter by the |
- C{getArbitrary...} methods. |
- @ivar howtoDir: A L{FilePath} representing a directory to be used for |
- containing Lore documents. |
- @ivar templateFile: A L{FilePath} representing a file with |
- C{self.template} as its content. |
- """ |
- BuilderTestsMixin.setUp(self) |
- self.builder = DocBuilder() |
- self.howtoDir = FilePath(self.mktemp()) |
- self.howtoDir.createDirectory() |
- self.templateFile = self.howtoDir.child("template.tpl") |
- self.templateFile.setContent(self.template) |
- |
- |
- def test_build(self): |
- """ |
- The L{DocBuilder} runs lore on all .xhtml files within a directory. |
- """ |
- version = "1.2.3" |
- input1, output1 = self.getArbitraryLoreInputAndOutput(version) |
- input2, output2 = self.getArbitraryLoreInputAndOutput(version) |
- |
- self.howtoDir.child("one.xhtml").setContent(input1) |
- self.howtoDir.child("two.xhtml").setContent(input2) |
- |
- self.builder.build(version, self.howtoDir, self.howtoDir, |
- self.templateFile) |
- out1 = self.howtoDir.child('one.html') |
- out2 = self.howtoDir.child('two.html') |
- self.assertEquals(out1.getContent(), output1) |
- self.assertEquals(out2.getContent(), output2) |
- |
- |
- def test_noDocumentsFound(self): |
- """ |
- The C{build} method raises L{NoDocumentsFound} if there are no |
- .xhtml files in the given directory. |
- """ |
- self.assertRaises( |
- NoDocumentsFound, |
- self.builder.build, "1.2.3", self.howtoDir, self.howtoDir, |
- self.templateFile) |
- |
- |
- def test_parentDocumentLinking(self): |
- """ |
- The L{DocBuilder} generates correct links from documents to |
- template-generated links like stylesheets and index backreferences. |
- """ |
- input = self.getArbitraryLoreInput(0) |
- tutoDir = self.howtoDir.child("tutorial") |
- tutoDir.createDirectory() |
- tutoDir.child("child.xhtml").setContent(input) |
- self.builder.build("1.2.3", self.howtoDir, tutoDir, self.templateFile) |
- outFile = tutoDir.child('child.html') |
- self.assertIn('<a href="../index.html">Index</a>', |
- outFile.getContent()) |
- |
- |
- def test_siblingDirectoryDocumentLinking(self): |
- """ |
- It is necessary to generate documentation in a directory foo/bar where |
- stylesheet and indexes are located in foo/baz. Such resources should be |
- appropriately linked to. |
- """ |
- input = self.getArbitraryLoreInput(0) |
- resourceDir = self.howtoDir.child("resources") |
- docDir = self.howtoDir.child("docs") |
- docDir.createDirectory() |
- docDir.child("child.xhtml").setContent(input) |
- self.builder.build("1.2.3", resourceDir, docDir, self.templateFile) |
- outFile = docDir.child('child.html') |
- self.assertIn('<a href="../resources/index.html">Index</a>', |
- outFile.getContent()) |
- |
- |
- def test_apiLinking(self): |
- """ |
- The L{DocBuilder} generates correct links from documents to API |
- documentation. |
- """ |
- version = "1.2.3" |
- input, output = self.getArbitraryLoreInputAndOutput(version) |
- self.howtoDir.child("one.xhtml").setContent(input) |
- |
- self.builder.build(version, self.howtoDir, self.howtoDir, |
- self.templateFile, "scheme:apilinks/%s.ext") |
- out = self.howtoDir.child('one.html') |
- self.assertIn( |
- '<a href="scheme:apilinks/foobar.ext" title="foobar">foobar</a>', |
- out.getContent()) |
- |
- |
- def test_deleteInput(self): |
- """ |
- L{DocBuilder.build} can be instructed to delete the input files after |
- generating the output based on them. |
- """ |
- input1 = self.getArbitraryLoreInput(0) |
- self.howtoDir.child("one.xhtml").setContent(input1) |
- self.builder.build("whatever", self.howtoDir, self.howtoDir, |
- self.templateFile, deleteInput=True) |
- self.assertTrue(self.howtoDir.child('one.html').exists()) |
- self.assertFalse(self.howtoDir.child('one.xhtml').exists()) |
- |
- |
- def test_doNotDeleteInput(self): |
- """ |
- Input will not be deleted by default. |
- """ |
- input1 = self.getArbitraryLoreInput(0) |
- self.howtoDir.child("one.xhtml").setContent(input1) |
- self.builder.build("whatever", self.howtoDir, self.howtoDir, |
- self.templateFile) |
- self.assertTrue(self.howtoDir.child('one.html').exists()) |
- self.assertTrue(self.howtoDir.child('one.xhtml').exists()) |
- |
- |
- def test_getLinkrelToSameDirectory(self): |
- """ |
- If the doc and resource directories are the same, the linkrel should be |
- an empty string. |
- """ |
- linkrel = self.builder.getLinkrel(FilePath("/foo/bar"), |
- FilePath("/foo/bar")) |
- self.assertEquals(linkrel, "") |
- |
- |
- def test_getLinkrelToParentDirectory(self): |
- """ |
- If the doc directory is a child of the resource directory, the linkrel |
- should make use of '..'. |
- """ |
- linkrel = self.builder.getLinkrel(FilePath("/foo"), |
- FilePath("/foo/bar")) |
- self.assertEquals(linkrel, "../") |
- |
- |
- def test_getLinkrelToSibling(self): |
- """ |
- If the doc directory is a sibling of the resource directory, the |
- linkrel should make use of '..' and a named segment. |
- """ |
- linkrel = self.builder.getLinkrel(FilePath("/foo/howto"), |
- FilePath("/foo/examples")) |
- self.assertEquals(linkrel, "../howto/") |
- |
- |
- def test_getLinkrelToUncle(self): |
- """ |
- If the doc directory is a sibling of the parent of the resource |
- directory, the linkrel should make use of multiple '..'s and a named |
- segment. |
- """ |
- linkrel = self.builder.getLinkrel(FilePath("/foo/howto"), |
- FilePath("/foo/examples/quotes")) |
- self.assertEquals(linkrel, "../../howto/") |
- |
- |
- |
-class APIBuilderTestCase(TestCase): |
- """ |
- Tests for L{APIBuilder}. |
- """ |
- if pydoctor is None or getattr(pydoctor, "version_info", (0,)) < (0, 1): |
- skip = "APIBuilder requires Pydoctor 0.1 or newer" |
- |
- def test_build(self): |
- """ |
- L{APIBuilder.build} writes an index file which includes the name of the |
- project specified. |
- """ |
- stdout = StringIO() |
- self.patch(sys, 'stdout', stdout) |
- |
- projectName = "Foobar" |
- packageName = "quux" |
- projectURL = "scheme:project" |
- sourceURL = "scheme:source" |
- docstring = "text in docstring" |
- badDocstring = "should not appear in output" |
- |
- inputPath = FilePath(self.mktemp()).child(packageName) |
- inputPath.makedirs() |
- inputPath.child("__init__.py").setContent( |
- "def foo():\n" |
- " '%s'\n" |
- "def _bar():\n" |
- " '%s'" % (docstring, badDocstring)) |
- |
- outputPath = FilePath(self.mktemp()) |
- outputPath.makedirs() |
- |
- builder = APIBuilder() |
- builder.build(projectName, projectURL, sourceURL, inputPath, outputPath) |
- |
- indexPath = outputPath.child("index.html") |
- self.assertTrue( |
- indexPath.exists(), |
- "API index %r did not exist." % (outputPath.path,)) |
- self.assertIn( |
- '<a href="%s">%s</a>' % (projectURL, projectName), |
- indexPath.getContent(), |
- "Project name/location not in file contents.") |
- |
- quuxPath = outputPath.child("quux.html") |
- self.assertTrue( |
- quuxPath.exists(), |
- "Package documentation file %r did not exist." % (quuxPath.path,)) |
- self.assertIn( |
- docstring, quuxPath.getContent(), |
- "Docstring not in package documentation file.") |
- self.assertIn( |
- '<a href="%s/%s">View Source</a>' % (sourceURL, packageName), |
- quuxPath.getContent()) |
- self.assertIn( |
- '<a href="%s/%s">View Source</a>' % (sourceURL, packageName), |
- quuxPath.getContent()) |
- self.assertIn( |
- '<a href="%s/%s/__init__.py#L1" class="functionSourceLink">' % ( |
- sourceURL, packageName), |
- quuxPath.getContent()) |
- self.assertNotIn(badDocstring, quuxPath.getContent()) |
- |
- self.assertEqual(stdout.getvalue(), '') |
- |
- |
- |
-class ManBuilderTestCase(TestCase, BuilderTestsMixin): |
- """ |
- Tests for L{ManBuilder}. |
- """ |
- |
- def setUp(self): |
- """ |
- Set up a few instance variables that will be useful. |
- |
- @ivar builder: A plain L{ManBuilder}. |
- @ivar manDir: A L{FilePath} representing a directory to be used for |
- containing man pages. |
- """ |
- BuilderTestsMixin.setUp(self) |
- self.builder = ManBuilder() |
- self.manDir = FilePath(self.mktemp()) |
- self.manDir.createDirectory() |
- |
- |
- def test_noDocumentsFound(self): |
- """ |
- L{ManBuilder.build} raises L{NoDocumentsFound} if there are no |
- .1 files in the given directory. |
- """ |
- self.assertRaises(NoDocumentsFound, self.builder.build, self.manDir) |
- |
- |
- def test_build(self): |
- """ |
- Check that L{ManBuilder.build} find the man page in the directory, and |
- successfully produce a Lore content. |
- """ |
- manContent = self.getArbitraryManInput() |
- self.manDir.child('test1.1').setContent(manContent) |
- self.builder.build(self.manDir) |
- output = self.manDir.child('test1-man.xhtml').getContent() |
- expected = self.getArbitraryManLoreOutput() |
- # No-op on *nix, fix for windows |
- expected = expected.replace('\n', os.linesep) |
- self.assertEquals(output, expected) |
- |
- |
- def test_toHTML(self): |
- """ |
- Check that the content output by C{build} is compatible as input of |
- L{DocBuilder.build}. |
- """ |
- manContent = self.getArbitraryManInput() |
- self.manDir.child('test1.1').setContent(manContent) |
- self.builder.build(self.manDir) |
- |
- templateFile = self.manDir.child("template.tpl") |
- templateFile.setContent(DocBuilderTestCase.template) |
- docBuilder = DocBuilder() |
- docBuilder.build("1.2.3", self.manDir, self.manDir, |
- templateFile) |
- output = self.manDir.child('test1-man.html').getContent() |
- self.assertEquals(output, '<?xml version="1.0"?><html><head>' |
- '<title>Yo:MANHOLE.1</title></head><body><div class="content">' |
- '<span></span><h2>NAME<a name="auto0"></a></h2><p>manhole - ' |
- 'Connect to a Twisted Manhole service\n</p><h2>SYNOPSIS<a ' |
- 'name="auto1"></a></h2><p><strong>manhole</strong></p><h2>' |
- 'DESCRIPTION<a name="auto2"></a></h2><p>manhole is a GTK ' |
- 'interface to Twisted Manhole services. You can execute ' |
- 'python\ncode as if at an interactive Python console inside a ' |
- 'running Twisted process\nwith this.</p></div><a ' |
- 'href="index.html">Index</a><span class="version">Version: ' |
- '1.2.3</span></body></html>') |
- |
- |
- |
-class BookBuilderTests(TestCase, BuilderTestsMixin): |
- """ |
- Tests for L{BookBuilder}. |
- """ |
- if not (which("latex") and which("dvips") and which("ps2pdf13")): |
- skip = "Book Builder tests require latex." |
- try: |
- from popen2 import Popen4 |
- except ImportError: |
- skip = "Book Builder requires popen2.Popen4." |
- else: |
- del Popen4 |
- |
- def setUp(self): |
- """ |
- Make a directory into which to place temporary files. |
- """ |
- self.docCounter = 0 |
- self.howtoDir = FilePath(self.mktemp()) |
- self.howtoDir.makedirs() |
- |
- |
- def getArbitraryOutput(self, version, counter, prefix=""): |
- """ |
- Create and return a C{str} containing the LaTeX document which is |
- expected as the output for processing the result of the document |
- returned by C{self.getArbitraryLoreInput(counter)}. |
- """ |
- path = self.howtoDir.child("%d.xhtml" % (counter,)).path |
- path = path[len(os.getcwd()) + 1:] |
- return ( |
- r'\section{Hi! Title: %(count)s\label{%(path)s}}' |
- '\n' |
- r'Hi! %(count)sfoobar') % {'count': counter, 'path': path} |
- |
- |
- def test_runSuccess(self): |
- """ |
- L{BookBuilder.run} executes the command it is passed and returns a |
- string giving the stdout and stderr of the command if it completes |
- successfully. |
- """ |
- builder = BookBuilder() |
- self.assertEqual(builder.run("echo hi; echo bye 1>&2"), "hi\nbye\n") |
- |
- |
- def test_runFailed(self): |
- """ |
- L{BookBuilder.run} executes the command it is passed and raises |
- L{CommandFailed} if it completes unsuccessfully. |
- """ |
- builder = BookBuilder() |
- exc = self.assertRaises(CommandFailed, builder.run, "echo hi; false") |
- self.assertNotEqual(os.WEXITSTATUS(exc.exitCode), 0) |
- self.assertEqual(exc.output, "hi\n") |
- |
- |
- def test_runSignaled(self): |
- """ |
- L{BookBuilder.run} executes the command it is passed and raises |
- L{CommandFailed} if it exits due to a signal. |
- """ |
- builder = BookBuilder() |
- exc = self.assertRaises( |
- # This is only a little bit too tricky. |
- CommandFailed, builder.run, "echo hi; exec kill -9 $$") |
- self.assertTrue(os.WIFSIGNALED(exc.exitCode)) |
- self.assertEqual(os.WTERMSIG(exc.exitCode), signal.SIGKILL) |
- self.assertEqual(exc.output, "hi\n") |
- |
- |
- def test_buildTeX(self): |
- """ |
- L{BookBuilder.buildTeX} writes intermediate TeX files for all lore |
- input files in a directory. |
- """ |
- version = "3.2.1" |
- input1, output1 = self.getArbitraryLoreInputAndOutput(version) |
- input2, output2 = self.getArbitraryLoreInputAndOutput(version) |
- |
- # Filenames are chosen by getArbitraryOutput to match the counter used |
- # by getArbitraryLoreInputAndOutput. |
- self.howtoDir.child("1.xhtml").setContent(input1) |
- self.howtoDir.child("2.xhtml").setContent(input2) |
- |
- builder = BookBuilder() |
- builder.buildTeX(self.howtoDir) |
- self.assertEqual(self.howtoDir.child("1.tex").getContent(), output1) |
- self.assertEqual(self.howtoDir.child("2.tex").getContent(), output2) |
- |
- |
- def test_buildTeXRejectsInvalidDirectory(self): |
- """ |
- L{BookBuilder.buildTeX} raises L{ValueError} if passed a directory |
- which does not exist. |
- """ |
- builder = BookBuilder() |
- self.assertRaises( |
- ValueError, builder.buildTeX, self.howtoDir.temporarySibling()) |
- |
- |
- def test_buildTeXOnlyBuildsXHTML(self): |
- """ |
- L{BookBuilder.buildTeX} ignores files which which don't end with |
- ".xhtml". |
- """ |
- # Hopefully ">" is always a parse error from microdom! |
- self.howtoDir.child("not-input.dat").setContent(">") |
- self.test_buildTeX() |
- |
- |
- def test_stdout(self): |
- """ |
- L{BookBuilder.buildTeX} does not write to stdout. |
- """ |
- stdout = StringIO() |
- self.patch(sys, 'stdout', stdout) |
- |
- # Suppress warnings so that if there are any old-style plugins that |
- # lore queries for don't confuse the assertion below. See #3070. |
- self.patch(warnings, 'warn', lambda *a, **kw: None) |
- self.test_buildTeX() |
- self.assertEqual(stdout.getvalue(), '') |
- |
- |
- def test_buildPDFRejectsInvalidBookFilename(self): |
- """ |
- L{BookBuilder.buildPDF} raises L{ValueError} if the book filename does |
- not end with ".tex". |
- """ |
- builder = BookBuilder() |
- self.assertRaises( |
- ValueError, |
- builder.buildPDF, |
- FilePath(self.mktemp()).child("foo"), |
- None, |
- None) |
- |
- |
- def _setupTeXFiles(self): |
- sections = range(3) |
- self._setupTeXSections(sections) |
- return self._setupTeXBook(sections) |
- |
- |
- def _setupTeXSections(self, sections): |
- for texSectionNumber in sections: |
- texPath = self.howtoDir.child("%d.tex" % (texSectionNumber,)) |
- texPath.setContent(self.getArbitraryOutput( |
- "1.2.3", texSectionNumber)) |
- |
- |
- def _setupTeXBook(self, sections): |
- bookTeX = self.howtoDir.child("book.tex") |
- bookTeX.setContent( |
- r"\documentclass{book}" "\n" |
- r"\begin{document}" "\n" + |
- "\n".join([r"\input{%d.tex}" % (n,) for n in sections]) + |
- r"\end{document}" "\n") |
- return bookTeX |
- |
- |
- def test_buildPDF(self): |
- """ |
- L{BookBuilder.buildPDF} creates a PDF given an index tex file and a |
- directory containing .tex files. |
- """ |
- bookPath = self._setupTeXFiles() |
- outputPath = FilePath(self.mktemp()) |
- |
- builder = BookBuilder() |
- builder.buildPDF(bookPath, self.howtoDir, outputPath) |
- |
- self.assertTrue(outputPath.exists()) |
- |
- |
- def test_buildPDFLongPath(self): |
- """ |
- L{BookBuilder.buildPDF} succeeds even if the paths it is operating on |
- are very long. |
- |
- C{ps2pdf13} seems to have problems when path names are long. This test |
- verifies that even if inputs have long paths, generation still |
- succeeds. |
- """ |
- # Make it long. |
- self.howtoDir = self.howtoDir.child("x" * 128).child("x" * 128).child("x" * 128) |
- self.howtoDir.makedirs() |
- |
- # This will use the above long path. |
- bookPath = self._setupTeXFiles() |
- outputPath = FilePath(self.mktemp()) |
- |
- builder = BookBuilder() |
- builder.buildPDF(bookPath, self.howtoDir, outputPath) |
- |
- self.assertTrue(outputPath.exists()) |
- |
- |
- def test_buildPDFRunsLaTeXThreeTimes(self): |
- """ |
- L{BookBuilder.buildPDF} runs C{latex} three times. |
- """ |
- class InspectableBookBuilder(BookBuilder): |
- def __init__(self): |
- BookBuilder.__init__(self) |
- self.commands = [] |
- |
- def run(self, command): |
- """ |
- Record the command and then execute it. |
- """ |
- self.commands.append(command) |
- return BookBuilder.run(self, command) |
- |
- bookPath = self._setupTeXFiles() |
- outputPath = FilePath(self.mktemp()) |
- |
- builder = InspectableBookBuilder() |
- builder.buildPDF(bookPath, self.howtoDir, outputPath) |
- |
- # These string comparisons are very fragile. It would be better to |
- # have a test which asserted the correctness of the contents of the |
- # output files. I don't know how one could do that, though. -exarkun |
- latex1, latex2, latex3, dvips, ps2pdf13 = builder.commands |
- self.assertEqual(latex1, latex2) |
- self.assertEqual(latex2, latex3) |
- self.assertTrue( |
- latex1.startswith("latex "), |
- "LaTeX command %r does not start with 'latex '" % (latex1,)) |
- self.assertTrue( |
- latex1.endswith(" " + bookPath.path), |
- "LaTeX command %r does not end with the book path (%r)." % ( |
- latex1, bookPath.path)) |
- |
- self.assertTrue( |
- dvips.startswith("dvips "), |
- "dvips command %r does not start with 'dvips '" % (dvips,)) |
- self.assertTrue( |
- ps2pdf13.startswith("ps2pdf13 "), |
- "ps2pdf13 command %r does not start with 'ps2pdf13 '" % ( |
- ps2pdf13,)) |
- |
- |
- def test_noSideEffects(self): |
- """ |
- The working directory is the same before and after a call to |
- L{BookBuilder.buildPDF}. Also the contents of the directory containing |
- the input book are the same before and after the call. |
- """ |
- startDir = os.getcwd() |
- bookTeX = self._setupTeXFiles() |
- startTeXSiblings = bookTeX.parent().children() |
- startHowtoChildren = self.howtoDir.children() |
- |
- builder = BookBuilder() |
- builder.buildPDF(bookTeX, self.howtoDir, FilePath(self.mktemp())) |
- |
- self.assertEqual(startDir, os.getcwd()) |
- self.assertEqual(startTeXSiblings, bookTeX.parent().children()) |
- self.assertEqual(startHowtoChildren, self.howtoDir.children()) |
- |
- |
- def test_failedCommandProvidesOutput(self): |
- """ |
- If a subprocess fails, L{BookBuilder.buildPDF} raises L{CommandFailed} |
- with the subprocess's output and leaves the temporary directory as a |
- sibling of the book path. |
- """ |
- bookTeX = FilePath(self.mktemp() + ".tex") |
- builder = BookBuilder() |
- inputState = bookTeX.parent().children() |
- exc = self.assertRaises( |
- CommandFailed, |
- builder.buildPDF, |
- bookTeX, self.howtoDir, FilePath(self.mktemp())) |
- self.assertTrue(exc.output) |
- newOutputState = set(bookTeX.parent().children()) - set(inputState) |
- self.assertEqual(len(newOutputState), 1) |
- workPath = newOutputState.pop() |
- self.assertTrue( |
- workPath.isdir(), |
- "Expected work path %r was not a directory." % (workPath.path,)) |
- |
- |
- def test_build(self): |
- """ |
- L{BookBuilder.build} generates a pdf book file from some lore input |
- files. |
- """ |
- sections = range(1, 4) |
- for sectionNumber in sections: |
- self.howtoDir.child("%d.xhtml" % (sectionNumber,)).setContent( |
- self.getArbitraryLoreInput(sectionNumber)) |
- bookTeX = self._setupTeXBook(sections) |
- bookPDF = FilePath(self.mktemp()) |
- |
- builder = BookBuilder() |
- builder.build(self.howtoDir, [self.howtoDir], bookTeX, bookPDF) |
- |
- self.assertTrue(bookPDF.exists()) |
- |
- |
- def test_buildRemovesTemporaryLaTeXFiles(self): |
- """ |
- L{BookBuilder.build} removes the intermediate LaTeX files it creates. |
- """ |
- sections = range(1, 4) |
- for sectionNumber in sections: |
- self.howtoDir.child("%d.xhtml" % (sectionNumber,)).setContent( |
- self.getArbitraryLoreInput(sectionNumber)) |
- bookTeX = self._setupTeXBook(sections) |
- bookPDF = FilePath(self.mktemp()) |
- |
- builder = BookBuilder() |
- builder.build(self.howtoDir, [self.howtoDir], bookTeX, bookPDF) |
- |
- self.assertEqual( |
- set(self.howtoDir.listdir()), |
- set([bookTeX.basename()] + ["%d.xhtml" % (n,) for n in sections])) |
- |
- |
- |
-class FilePathDeltaTest(TestCase): |
- """ |
- Tests for L{filePathDelta}. |
- """ |
- |
- def test_filePathDeltaSubdir(self): |
- """ |
- L{filePathDelta} can create a simple relative path to a child path. |
- """ |
- self.assertEquals(filePathDelta(FilePath("/foo/bar"), |
- FilePath("/foo/bar/baz")), |
- ["baz"]) |
- |
- |
- def test_filePathDeltaSiblingDir(self): |
- """ |
- L{filePathDelta} can traverse upwards to create relative paths to |
- siblings. |
- """ |
- self.assertEquals(filePathDelta(FilePath("/foo/bar"), |
- FilePath("/foo/baz")), |
- ["..", "baz"]) |
- |
- |
- def test_filePathNoCommonElements(self): |
- """ |
- L{filePathDelta} can create relative paths to totally unrelated paths |
- for maximum portability. |
- """ |
- self.assertEquals(filePathDelta(FilePath("/foo/bar"), |
- FilePath("/baz/quux")), |
- ["..", "..", "baz", "quux"]) |
- |
- |
- |
-class DistributionBuilderTests(BuilderTestsMixin, TestCase): |
- """ |
- Tests for L{DistributionBuilder}. |
- """ |
- |
- def setUp(self): |
- BuilderTestsMixin.setUp(self) |
- |
- self.rootDir = FilePath(self.mktemp()) |
- self.rootDir.createDirectory() |
- |
- outputDir = FilePath(self.mktemp()) |
- outputDir.createDirectory() |
- self.builder = DistributionBuilder(self.rootDir, outputDir) |
- |
- |
- def createStructure(self, root, dirDict): |
- """ |
- Create a set of directories and files given a dict defining their |
- structure. |
- |
- @param root: The directory in which to create the structure. |
- @type root: L{FilePath} |
- |
- @param dirDict: The dict defining the structure. Keys should be strings |
- naming files, values should be strings describing file contents OR |
- dicts describing subdirectories. For example: C{{"foofile": |
- "foocontents", "bardir": {"barfile": "barcontents"}}} |
- @type dirDict: C{dict} |
- """ |
- for x in dirDict: |
- child = root.child(x) |
- if isinstance(dirDict[x], dict): |
- child.createDirectory() |
- self.createStructure(child, dirDict[x]) |
- else: |
- child.setContent(dirDict[x]) |
- |
- |
- def assertExtractedStructure(self, outputFile, dirDict): |
- """ |
- Assert that a tarfile content is equivalent to one described by a dict. |
- |
- @param outputFile: The tar file built by L{DistributionBuilder}. |
- @type outputFile: L{FilePath}. |
- @param dirDict: The dict that should describe the contents of the |
- directory. It should be the same structure as the C{dirDict} |
- parameter to L{createStructure}. |
- @type dirDict: C{dict} |
- """ |
- tarFile = tarfile.TarFile.open(outputFile.path, "r:bz2") |
- extracted = FilePath(self.mktemp()) |
- extracted.createDirectory() |
- for info in tarFile: |
- tarFile.extract(info, path=extracted.path) |
- self.assertStructure(extracted.children()[0], dirDict) |
- |
- |
- def assertStructure(self, root, dirDict): |
- """ |
- Assert that a directory is equivalent to one described by a dict. |
- |
- @param root: The filesystem directory to compare. |
- @type root: L{FilePath} |
- @param dirDict: The dict that should describe the contents of the |
- directory. It should be the same structure as the C{dirDict} |
- parameter to L{createStructure}. |
- @type dirDict: C{dict} |
- """ |
- children = [x.basename() for x in root.children()] |
- for x in dirDict: |
- child = root.child(x) |
- if isinstance(dirDict[x], dict): |
- self.assertTrue(child.isdir(), "%s is not a dir!" |
- % (child.path,)) |
- self.assertStructure(child, dirDict[x]) |
- else: |
- a = child.getContent() |
- self.assertEquals(a, dirDict[x], child.path) |
- children.remove(x) |
- if children: |
- self.fail("There were extra children in %s: %s" |
- % (root.path, children)) |
- |
- |
- def test_twistedDistribution(self): |
- """ |
- The Twisted tarball contains everything in the source checkout, with |
- built documentation. |
- """ |
- loreInput, loreOutput = self.getArbitraryLoreInputAndOutput("10.0.0") |
- manInput1 = self.getArbitraryManInput() |
- manOutput1 = self.getArbitraryManHTMLOutput("10.0.0", "../howto/") |
- manInput2 = self.getArbitraryManInput() |
- manOutput2 = self.getArbitraryManHTMLOutput("10.0.0", "../howto/") |
- coreIndexInput, coreIndexOutput = self.getArbitraryLoreInputAndOutput( |
- "10.0.0", prefix="howto/") |
- |
- structure = { |
- "README": "Twisted", |
- "unrelated": "x", |
- "LICENSE": "copyright!", |
- "setup.py": "import toplevel", |
- "bin": {"web": {"websetroot": "SET ROOT"}, |
- "twistd": "TWISTD"}, |
- "twisted": |
- {"web": |
- {"__init__.py": "import WEB", |
- "topfiles": {"setup.py": "import WEBINSTALL", |
- "README": "WEB!"}}, |
- "words": {"__init__.py": "import WORDS"}, |
- "plugins": {"twisted_web.py": "import WEBPLUG", |
- "twisted_words.py": "import WORDPLUG"}}, |
- "doc": {"web": {"howto": {"index.xhtml": loreInput}, |
- "man": {"websetroot.1": manInput2}}, |
- "core": {"howto": {"template.tpl": self.template}, |
- "man": {"twistd.1": manInput1}, |
- "index.xhtml": coreIndexInput}}} |
- |
- outStructure = { |
- "README": "Twisted", |
- "unrelated": "x", |
- "LICENSE": "copyright!", |
- "setup.py": "import toplevel", |
- "bin": {"web": {"websetroot": "SET ROOT"}, |
- "twistd": "TWISTD"}, |
- "twisted": |
- {"web": {"__init__.py": "import WEB", |
- "topfiles": {"setup.py": "import WEBINSTALL", |
- "README": "WEB!"}}, |
- "words": {"__init__.py": "import WORDS"}, |
- "plugins": {"twisted_web.py": "import WEBPLUG", |
- "twisted_words.py": "import WORDPLUG"}}, |
- "doc": {"web": {"howto": {"index.html": loreOutput}, |
- "man": {"websetroot.1": manInput2, |
- "websetroot-man.html": manOutput2}}, |
- "core": {"howto": {"template.tpl": self.template}, |
- "man": {"twistd.1": manInput1, |
- "twistd-man.html": manOutput1}, |
- "index.html": coreIndexOutput}}} |
- |
- self.createStructure(self.rootDir, structure) |
- |
- outputFile = self.builder.buildTwisted("10.0.0") |
- |
- self.assertExtractedStructure(outputFile, outStructure) |
- |
- def test_twistedDistributionExcludesWeb2AndVFS(self): |
- """ |
- The main Twisted distribution does not include web2 or vfs. |
- """ |
- loreInput, loreOutput = self.getArbitraryLoreInputAndOutput("10.0.0") |
- coreIndexInput, coreIndexOutput = self.getArbitraryLoreInputAndOutput( |
- "10.0.0", prefix="howto/") |
- |
- structure = { |
- "README": "Twisted", |
- "unrelated": "x", |
- "LICENSE": "copyright!", |
- "setup.py": "import toplevel", |
- "bin": {"web2": {"websetroot": "SET ROOT"}, |
- "vfs": {"vfsitup": "hee hee"}, |
- "twistd": "TWISTD"}, |
- "twisted": |
- {"web2": |
- {"__init__.py": "import WEB", |
- "topfiles": {"setup.py": "import WEBINSTALL", |
- "README": "WEB!"}}, |
- "vfs": |
- {"__init__.py": "import VFS", |
- "blah blah": "blah blah"}, |
- "words": {"__init__.py": "import WORDS"}, |
- "plugins": {"twisted_web.py": "import WEBPLUG", |
- "twisted_words.py": "import WORDPLUG", |
- "twisted_web2.py": "import WEB2", |
- "twisted_vfs.py": "import VFS"}}, |
- "doc": {"web2": {"excluded!": "yay"}, |
- "vfs": {"unrelated": "whatever"}, |
- "core": {"howto": {"template.tpl": self.template}, |
- "index.xhtml": coreIndexInput}}} |
- |
- outStructure = { |
- "README": "Twisted", |
- "unrelated": "x", |
- "LICENSE": "copyright!", |
- "setup.py": "import toplevel", |
- "bin": {"twistd": "TWISTD"}, |
- "twisted": |
- {"words": {"__init__.py": "import WORDS"}, |
- "plugins": {"twisted_web.py": "import WEBPLUG", |
- "twisted_words.py": "import WORDPLUG"}}, |
- "doc": {"core": {"howto": {"template.tpl": self.template}, |
- "index.html": coreIndexOutput}}} |
- self.createStructure(self.rootDir, structure) |
- |
- outputFile = self.builder.buildTwisted("10.0.0") |
- |
- self.assertExtractedStructure(outputFile, outStructure) |
- |
- |
- def test_subProjectLayout(self): |
- """ |
- The subproject tarball includes files like so: |
- |
- 1. twisted/<subproject>/topfiles defines the files that will be in the |
- top level in the tarball, except LICENSE, which comes from the real |
- top-level directory. |
- 2. twisted/<subproject> is included, but without the topfiles entry |
- in that directory. No other twisted subpackages are included. |
- 3. twisted/plugins/twisted_<subproject>.py is included, but nothing |
- else in plugins is. |
- """ |
- structure = { |
- "README": "HI!@", |
- "unrelated": "x", |
- "LICENSE": "copyright!", |
- "setup.py": "import toplevel", |
- "bin": {"web": {"websetroot": "SET ROOT"}, |
- "words": {"im": "#!im"}}, |
- "twisted": |
- {"web": |
- {"__init__.py": "import WEB", |
- "topfiles": {"setup.py": "import WEBINSTALL", |
- "README": "WEB!"}}, |
- "words": {"__init__.py": "import WORDS"}, |
- "plugins": {"twisted_web.py": "import WEBPLUG", |
- "twisted_words.py": "import WORDPLUG"}}} |
- |
- outStructure = { |
- "README": "WEB!", |
- "LICENSE": "copyright!", |
- "setup.py": "import WEBINSTALL", |
- "bin": {"websetroot": "SET ROOT"}, |
- "twisted": {"web": {"__init__.py": "import WEB"}, |
- "plugins": {"twisted_web.py": "import WEBPLUG"}}} |
- |
- self.createStructure(self.rootDir, structure) |
- |
- outputFile = self.builder.buildSubProject("web", "0.3.0") |
- |
- self.assertExtractedStructure(outputFile, outStructure) |
- |
- |
- def test_minimalSubProjectLayout(self): |
- """ |
- buildSubProject should work with minimal subprojects. |
- """ |
- structure = { |
- "LICENSE": "copyright!", |
- "bin": {}, |
- "twisted": |
- {"web": {"__init__.py": "import WEB", |
- "topfiles": {"setup.py": "import WEBINSTALL"}}, |
- "plugins": {}}} |
- |
- outStructure = { |
- "setup.py": "import WEBINSTALL", |
- "LICENSE": "copyright!", |
- "twisted": {"web": {"__init__.py": "import WEB"}}} |
- |
- self.createStructure(self.rootDir, structure) |
- |
- outputFile = self.builder.buildSubProject("web", "0.3.0") |
- |
- self.assertExtractedStructure(outputFile, outStructure) |
- |
- |
- def test_subProjectDocBuilding(self): |
- """ |
- When building a subproject release, documentation should be built with |
- lore. |
- """ |
- loreInput, loreOutput = self.getArbitraryLoreInputAndOutput("0.3.0") |
- manInput = self.getArbitraryManInput() |
- manOutput = self.getArbitraryManHTMLOutput("0.3.0", "../howto/") |
- structure = { |
- "LICENSE": "copyright!", |
- "twisted": {"web": {"__init__.py": "import WEB", |
- "topfiles": {"setup.py": "import WEBINST"}}}, |
- "doc": {"web": {"howto": {"index.xhtml": loreInput}, |
- "man": {"twistd.1": manInput}}, |
- "core": {"howto": {"template.tpl": self.template}} |
- } |
- } |
- |
- outStructure = { |
- "LICENSE": "copyright!", |
- "setup.py": "import WEBINST", |
- "twisted": {"web": {"__init__.py": "import WEB"}}, |
- "doc": {"howto": {"index.html": loreOutput}, |
- "man": {"twistd.1": manInput, |
- "twistd-man.html": manOutput}}} |
- |
- self.createStructure(self.rootDir, structure) |
- |
- outputFile = self.builder.buildSubProject("web", "0.3.0") |
- |
- self.assertExtractedStructure(outputFile, outStructure) |
- |
- |
- def test_coreProjectLayout(self): |
- """ |
- The core tarball looks a lot like a subproject tarball, except it |
- doesn't include: |
- |
- - Python packages from other subprojects |
- - plugins from other subprojects |
- - scripts from other subprojects |
- """ |
- indexInput, indexOutput = self.getArbitraryLoreInputAndOutput( |
- "8.0.0", prefix="howto/") |
- howtoInput, howtoOutput = self.getArbitraryLoreInputAndOutput("8.0.0") |
- specInput, specOutput = self.getArbitraryLoreInputAndOutput( |
- "8.0.0", prefix="../howto/") |
- upgradeInput, upgradeOutput = self.getArbitraryLoreInputAndOutput( |
- "8.0.0", prefix="../howto/") |
- tutorialInput, tutorialOutput = self.getArbitraryLoreInputAndOutput( |
- "8.0.0", prefix="../") |
- |
- structure = { |
- "LICENSE": "copyright!", |
- "twisted": {"__init__.py": "twisted", |
- "python": {"__init__.py": "python", |
- "roots.py": "roots!"}, |
- "conch": {"__init__.py": "conch", |
- "unrelated.py": "import conch"}, |
- "plugin.py": "plugin", |
- "plugins": {"twisted_web.py": "webplug", |
- "twisted_whatever.py": "include!", |
- "cred.py": "include!"}, |
- "topfiles": {"setup.py": "import CORE", |
- "README": "core readme"}}, |
- "doc": {"core": {"howto": {"template.tpl": self.template, |
- "index.xhtml": howtoInput, |
- "tutorial": |
- {"index.xhtml": tutorialInput}}, |
- "specifications": {"index.xhtml": specInput}, |
- "upgrades": {"index.xhtml": upgradeInput}, |
- "examples": {"foo.py": "foo.py"}, |
- "index.xhtml": indexInput}, |
- "web": {"howto": {"index.xhtml": "webindex"}}}, |
- "bin": {"twistd": "TWISTD", |
- "web": {"websetroot": "websetroot"}} |
- } |
- |
- outStructure = { |
- "LICENSE": "copyright!", |
- "setup.py": "import CORE", |
- "README": "core readme", |
- "twisted": {"__init__.py": "twisted", |
- "python": {"__init__.py": "python", |
- "roots.py": "roots!"}, |
- "plugin.py": "plugin", |
- "plugins": {"twisted_whatever.py": "include!", |
- "cred.py": "include!"}}, |
- "doc": {"howto": {"template.tpl": self.template, |
- "index.html": howtoOutput, |
- "tutorial": {"index.html": tutorialOutput}}, |
- "specifications": {"index.html": specOutput}, |
- "upgrades": {"index.html": upgradeOutput}, |
- "examples": {"foo.py": "foo.py"}, |
- "index.html": indexOutput}, |
- "bin": {"twistd": "TWISTD"}, |
- } |
- |
- self.createStructure(self.rootDir, structure) |
- |
- outputFile = self.builder.buildCore("8.0.0") |
- |
- self.assertExtractedStructure(outputFile, outStructure) |
- |
- |
- |
-if lore is None: |
- skipMessage = "Lore is not present." |
- BookBuilderTests.skip = skipMessage |
- DocBuilderTestCase.skip = skipMessage |
- ManBuilderTestCase.skip = skipMessage |
- DistributionBuilderTests.skip = skipMessage |