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