1 #!/usr/bin/env python 2 3 from os import listdir 4 from os.path import abspath, split 5 import sys 6 7 # Locate and import the moinformat package. 8 9 dirname = split(abspath(sys.argv[0]))[0] 10 parent = split(dirname)[0] 11 12 try: 13 import moinformat 14 except ImportError: 15 if "moinformat" in listdir(parent): 16 sys.path.append(parent) 17 18 # Import specific objects. 19 20 from moinformat import Metadata, make_input, make_output, make_parser, \ 21 make_serialiser, parse, serialise 22 from moinformat.tree.moin import Container 23 24 def test_input(d, s): 25 26 "Compare serialised output from 'd' with its original form 's'." 27 28 metadata = Metadata({ 29 "pagename" : "TestPage", 30 }) 31 32 # Encode the input. 33 34 output = make_output(metadata) 35 expected = output.encode(s) 36 37 # Obtain and encode the output. 38 39 result = serialise(d, make_serialiser(metadata)) 40 result = output.encode(result) 41 42 # Test encoded input and output. 43 44 identical = result == expected 45 46 if quiet: 47 return identical 48 49 # Show output versus input comparison result. 50 51 print identical 52 print "-" * 60 53 print result 54 if not identical: 55 print "-" * 60 56 print expected 57 print "-" * 60 58 59 # Show HTML serialisation. 60 61 metadata.set("output_format", "html") 62 metadata.set("mapping", {"MoinMoin" : "https://moinmo.in/"}) 63 64 print serialise(d, make_serialiser(metadata)) 65 print "-" * 60 66 print 67 68 return identical 69 70 def test_tree(d, t, ts): 71 72 "Compare tree structure 'd' with simplified, expected form 't' from 'ts'." 73 74 failing = t.test(d) 75 76 if quiet: 77 return not failing 78 79 # Show tree versus expected forms. 80 81 print not failing 82 print "-" * 60 83 print d.prettyprint() 84 if failing: 85 print "-" * 60 86 print ts 87 simple, tree, error = failing 88 print "-" * 60 89 print error 90 print repr(simple) 91 print repr(tree) 92 print "-" * 60 93 print tree.prettyprint() 94 print "-" * 60 95 print simple.prettyprint() 96 print "-" * 60 97 print 98 99 return not failing 100 101 class Node: 102 103 "A simplified tree node representation." 104 105 def __init__(self, name): 106 self.name = name 107 self.nodes = [] 108 109 def __repr__(self): 110 return "Node(%r, %r)" % (self.name, self.nodes) 111 112 def prettyprint(self, indent=""): 113 l = [] 114 l.append("%s%s%s" % (indent, self.name, len(self.nodes) and " nodes=%d" % len(self.nodes) or "")) 115 for node in self.nodes: 116 l.append(node.prettyprint(indent + " ")) 117 return "\n".join(l) 118 119 def append(self, node): 120 self.nodes.append(node) 121 122 def test(self, other): 123 124 """ 125 Test whether this node is considered equivalent to 'other', where 126 'other' is a moinparser.tree node. 127 128 Return any failing tree nodes or None. 129 """ 130 131 if other.__class__.__name__ != self.name: 132 return self, other, "name" 133 134 if isinstance(other, Container): 135 for node, other_node in map(None, self.nodes, other.nodes): 136 if node is None or other_node is None: 137 return self, other, node is None and "simple" or "document" 138 t = node.test(other_node) 139 if t: 140 return t 141 elif self.nodes: 142 return self, other, "empty" 143 144 return None 145 146 def parse_tree(s): 147 148 "Parse the tree structure representation in 's'." 149 150 indent = 0 151 branches = [] 152 153 for line in s.split("\n"): 154 line = line.rstrip() 155 if not line: 156 continue 157 158 new_indent = line.rfind(" ") + 1 159 node = Node(line[new_indent:]) 160 161 # Establish a branch to add nodes to. 162 163 if not branches: 164 branches.append(node) 165 else: 166 # Note the current node as outermost branch. 167 168 if new_indent > indent: 169 branches.append(node) 170 else: 171 # Reduced indent involves obtaining an inner branch again. 172 173 while indent > new_indent: 174 del branches[-1] 175 indent -= 2 176 177 # Note the current node as outermost branch. 178 179 branches[-1] = node 180 181 # Append the current node to the parent branch. 182 183 branches[-2].append(node) 184 185 indent = new_indent 186 187 return branches[0] 188 189 def get_filename(filename): 190 191 "Using 'filename', return the core text filename and any encoding." 192 193 t = filename.split(".") 194 if len(t) > 2: 195 text_filename = ".".join(t[:2]) 196 encoding = t[2] 197 else: 198 text_filename = filename 199 encoding = None 200 201 return text_filename, encoding 202 203 def get_tree(input, tree_filename): 204 205 "Using 'input', return (text, tree) for 'tree_filename'." 206 207 if input.dir.exists(tree_filename): 208 ts = input.readfile(tree_filename) 209 return ts, parse_tree(ts) 210 else: 211 return None, None 212 213 if __name__ == "__main__": 214 args = sys.argv[1:] 215 216 if "--help" in args: 217 print >>sys.stderr, """\ 218 Usage: %s [ -q ] [ <filename>... ] 219 220 Run the test suite or, if filenames are indicated, specific test files. 221 The following options are supported: 222 223 -q Suppress test output, reporting only success or failure 224 --quiet Equivalent to -q 225 """ 226 sys.exit(1) 227 228 for arg in ["-q", "--quiet"]: 229 if arg in args: 230 del args[args.index(arg)] 231 quiet = True 232 break 233 else: 234 quiet = False 235 236 metadata = Metadata({ 237 "input_context" : "directory", 238 "input_filename" : dirname, 239 }) 240 241 # Make an input context. 242 243 input = make_input(metadata) 244 245 # Obtain input filenames. 246 247 filenames = args or input.dir.select_files("test*.txt*") 248 filenames.sort() 249 250 # Process each filename, obtaining a corresponding tree definition. 251 252 for filename in filenames: 253 text_filename, encoding = get_filename(filename) 254 255 # Identify any tree-related filenames. 256 257 basename = text_filename.rsplit(".", 1)[0] 258 tree_filename = "%s.tree" % basename 259 tree_exp_filename = "%s.tree-exp" % basename 260 261 # Read and parse the input. 262 263 s = input.readfile(filename, encoding) 264 p = make_parser(metadata) 265 d = parse(s, p) 266 267 # Read and parse any tree definitions. 268 269 ts, t = get_tree(input, tree_filename) 270 tsexp, texp = get_tree(input, tree_exp_filename) 271 272 # Report the test results. 273 274 if not quiet: 275 print filename 276 277 identical = test_input(d, s) 278 tree_identical = ts and test_tree(d, t, ts) 279 280 if tsexp: 281 p.evaluate_macros() 282 tree_exp_identical = test_tree(d, texp, tsexp) 283 else: 284 tree_exp_identical = None 285 286 if quiet: 287 print "%s %s %s: %s" % (identical, tree_identical, tree_exp_identical, filename) 288 289 # vim: tabstop=4 expandtab shiftwidth=4