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