3 # Author: Felix Wiemann
4 # Contact: Felix_Wiemann@ososo.de
7 # Copyright: This module has been placed in the public domain.
10 Perform tests with the data in the functional/ directory.
12 Read README.txt for details on how this is done.
21 import DocutilsTestSupport
# must be imported before docutils
26 datadir
= 'functional'
27 """The directory to store the data needed for the functional tests."""
31 return '/'.join(args
) or '.'
34 class FunctionalTestSuite(DocutilsTestSupport
.CustomTestSuite
):
36 """Test suite containing test cases for all config files."""
39 """Process all config files in functional/tests/."""
40 DocutilsTestSupport
.CustomTestSuite
.__init
__(self
)
41 os
.chdir(DocutilsTestSupport
.testroot
)
42 self
.clear_output_directory()
44 os
.path
.walk(join_path(datadir
, 'tests'), self
.walker
, None)
45 assert self
.added
, 'No functional tests found.'
47 def clear_output_directory(self
):
48 files
= os
.listdir(os
.path
.join('functional', 'output'))
50 if f
in ('README.txt', '.svn', 'CVS'):
51 continue # don't touch the infrastructure
52 path
= os
.path
.join('functional', 'output', f
)
53 if os
.path
.isdir(path
):
58 def walker(self
, dummy
, dirname
, names
):
60 Process all config files among `names` in `dirname`.
62 This is a helper function for os.path.walk. A config file is
63 a Python file (*.py) which sets several variables.
66 if name
.endswith('.py') and not name
.startswith('_'):
67 config_file_full_path
= join_path(dirname
, name
)
68 self
.addTestCase(FunctionalTestCase
, 'test', None, None,
69 id=config_file_full_path
,
70 configfile
=config_file_full_path
)
74 class FunctionalTestCase(DocutilsTestSupport
.CustomTestCase
):
76 """Test case for one config file."""
78 def __init__(self
, *args
, **kwargs
):
79 """Set self.configfile, pass arguments to parent __init__."""
80 self
.configfile
= kwargs
['configfile']
81 del kwargs
['configfile']
82 DocutilsTestSupport
.CustomTestCase
.__init
__(self
, *args
, **kwargs
)
84 def shortDescription(self
):
85 return 'test_functional.py: ' + self
.configfile
88 """Process self.configfile."""
89 os
.chdir(DocutilsTestSupport
.testroot
)
90 # Keyword parameters for publish_file:
92 # Initialize 'settings_overrides' for test settings scripts,
93 # and disable configuration files:
94 namespace
['settings_overrides'] = {'_disable_config': 1}
95 # Read the variables set in the default config file and in
96 # the current config file into namespace:
97 execfile(join_path(datadir
, 'tests', '_default.py'), namespace
)
98 execfile(self
.configfile
, namespace
)
99 # Check for required settings:
100 assert namespace
.has_key('test_source'),\
101 "No 'test_source' supplied in " + self
.configfile
102 assert namespace
.has_key('test_destination'),\
103 "No 'test_destination' supplied in " + self
.configfile
104 # Set source_path and destination_path if not given:
105 namespace
.setdefault('source_path',
106 join_path(datadir
, 'input',
107 namespace
['test_source']))
108 # Path for actual output:
109 namespace
.setdefault('destination_path',
110 join_path(datadir
, 'output',
111 namespace
['test_destination']))
112 # Path for expected output:
113 expected_path
= join_path(datadir
, 'expected',
114 namespace
['test_destination'])
115 # shallow copy of namespace to minimize:
116 params
= namespace
.copy()
117 # remove unneeded parameters:
118 del params
['test_source']
119 del params
['test_destination']
120 # Delete private stuff like params['__builtins__']:
121 for key
in params
.keys():
122 if key
.startswith('_'):
124 # Get output (automatically written to the output/ directory
126 output
= docutils
.core
.publish_file(**params
)
127 # Get the expected output *after* writing the actual output.
128 self
.assert_(os
.access(expected_path
, os
.R_OK
),\
129 'Cannot find expected output at\n' + expected_path
)
130 f
= open(expected_path
, 'rU')
133 diff
= ('The expected and actual output differs.\n'
134 'Please compare the expected and actual output files:\n'
136 'If the actual output is correct, please replace the\n'
137 'expected output and check it in to Subversion:\n'
139 ' svn commit -m "<comment>" %s'
140 % (expected_path
, params
['destination_path'],
141 params
['destination_path'], expected_path
, expected_path
))
143 self
.assertEquals(output
, expected
, diff
)
144 except AssertionError:
145 if hasattr(difflib
, 'unified_diff'):
146 # Generate diff if unified_diff available:
148 difflib
.unified_diff(expected
.splitlines(1),
149 output
.splitlines(1),
151 params
['destination_path']))
152 print >>sys
.stderr
, '\n%s:' % (self
,)
153 print >>sys
.stderr
, diff
155 # Execute optional function containing extra tests:
156 if namespace
.has_key('_test_more'):
157 namespace
['_test_more'](join_path(datadir
, 'expected'),
158 join_path(datadir
, 'output'),
163 return FunctionalTestSuite()
166 if __name__
== '__main__':
167 unittest
.main(defaultTest
='suite')