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 make_input, make_output, make_serialiser, parse, serialise 21 from moinformat.tree.moin import Container 22 23 def test_input(d, s): 24 25 "Compare serialised output from 'd' with its original form 's'." 26 27 output = make_output("standalone") 28 expected = output.encode(s) 29 30 result = serialise(d, make_serialiser("moin", output)) 31 identical = result == expected 32 33 if quiet: 34 return identical 35 36 # Show output versus input comparison result. 37 38 print identical 39 print "-" * 60 40 print result 41 if not identical: 42 print "-" * 60 43 print expected 44 print "-" * 60 45 46 # Show HTML serialisation. 47 48 output = make_output("standalone") 49 print serialise(d, make_serialiser("html", output)) 50 print "-" * 60 51 print 52 53 return identical 54 55 def test_tree(d, t, ts): 56 57 "Compare tree structure 'd' with simplified, expected form 't' from 'ts'." 58 59 failing = t.test(d) 60 61 if quiet: 62 return not failing 63 64 # Show tree versus expected forms. 65 66 print not failing 67 print "-" * 60 68 print d.prettyprint() 69 if failing: 70 print "-" * 60 71 print ts 72 simple, tree, error = failing 73 print "-" * 60 74 print error 75 print repr(simple) 76 print repr(tree) 77 print "-" * 60 78 print tree.prettyprint() 79 print "-" * 60 80 print simple.prettyprint() 81 print "-" * 60 82 print 83 84 return not failing 85 86 class Node: 87 88 "A simplified tree node representation." 89 90 def __init__(self, name): 91 self.name = name 92 self.nodes = [] 93 94 def __repr__(self): 95 return "Node(%r, %r)" % (self.name, self.nodes) 96 97 def prettyprint(self, indent=""): 98 l = [] 99 l.append("%s%s%s" % (indent, self.name, len(self.nodes) and " nodes=%d" % len(self.nodes) or "")) 100 for node in self.nodes: 101 l.append(node.prettyprint(indent + " ")) 102 return "\n".join(l) 103 104 def append(self, node): 105 self.nodes.append(node) 106 107 def test(self, other): 108 109 """ 110 Test whether this node is considered equivalent to 'other', where 111 'other' is a moinparser.tree node. 112 113 Return any failing tree nodes or None. 114 """ 115 116 if other.__class__.__name__ != self.name: 117 return self, other, "name" 118 119 if isinstance(other, Container): 120 for node, other_node in map(None, self.nodes, other.nodes): 121 if node is None or other_node is None: 122 return self, other, node is None and "simple" or "document" 123 t = node.test(other_node) 124 if t: 125 return t 126 elif self.nodes: 127 return self, other, "empty" 128 129 return None 130 131 def parse_tree(s): 132 133 "Parse the tree structure representation in 's'." 134 135 indent = 0 136 branches = [] 137 138 for line in s.split("\n"): 139 line = line.rstrip() 140 if not line: 141 continue 142 143 new_indent = line.rfind(" ") + 1 144 node = Node(line[new_indent:]) 145 146 # Establish a branch to add nodes to. 147 148 if not branches: 149 branches.append(node) 150 else: 151 # Note the current node as outermost branch. 152 153 if new_indent > indent: 154 branches.append(node) 155 else: 156 # Reduced indent involves obtaining an inner branch again. 157 158 while indent > new_indent: 159 del branches[-1] 160 indent -= 2 161 162 # Note the current node as outermost branch. 163 164 branches[-1] = node 165 166 # Append the current node to the parent branch. 167 168 branches[-2].append(node) 169 170 indent = new_indent 171 172 return branches[0] 173 174 if __name__ == "__main__": 175 args = sys.argv[1:] 176 177 quiet = "-q" in args 178 if quiet: 179 del args[args.index("-q")] 180 181 # Make an input context. 182 183 input = make_input("directory", {"filename" : dirname}) 184 185 # Obtain input filenames. 186 187 filenames = args or input.dir.select_files("test*.txt*") 188 filenames.sort() 189 190 # Process each filename, obtaining a corresponding tree definition. 191 192 for filename in filenames: 193 194 # Test for an explicit encoding suffix. 195 196 t = filename.split(".") 197 if len(t) > 2: 198 text_filename = ".".join(t[:2]) 199 encoding = t[2] 200 else: 201 text_filename = filename 202 encoding = None 203 204 tree_filename = "%s.tree" % text_filename.rsplit(".", 1)[0] 205 206 # Read and parse the input. 207 208 s = input.readfile(text_filename, encoding) 209 d = parse(s) 210 211 # Read and parse any tree definition. 212 213 if input.dir.exists(tree_filename): 214 ts = input.readfile(tree_filename) 215 t = parse_tree(ts) 216 else: 217 ts = None 218 219 # Report the test results. 220 221 if not quiet: 222 print filename 223 224 identical = test_input(d, s) 225 tree_identical = ts and test_tree(d, t, ts) 226 227 if quiet: 228 print "%s %s: %s" % (identical, tree_identical, filename) 229 230 # vim: tabstop=4 expandtab shiftwidth=4