1 #!/usr/bin/env python 2 3 """ 4 Test document parsing and serialisation. 5 6 Copyright (C) 2017, 2018, 2019, 2023 Paul Boddie <paul@boddie.org.uk> 7 8 This program is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free Software 10 Foundation; either version 3 of the License, or (at your option) any later 11 version. 12 13 This program is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 details. 17 18 You should have received a copy of the GNU General Public License along with 19 this program. If not, see <http://www.gnu.org/licenses/>. 20 """ 21 22 from os import listdir 23 from os.path import abspath, split 24 import sys 25 26 # Locate and import the moinformat package. 27 28 dirname = split(abspath(sys.argv[0]))[0] 29 parent = split(dirname)[0] 30 31 try: 32 import moinformat 33 except ImportError: 34 if "moinformat" in listdir(parent): 35 sys.path.append(parent) 36 37 # Import specific objects. 38 39 from moinformat import get_parser, Metadata, make_input, make_output, \ 40 make_parser, make_serialiser, parse, serialise 41 from moinformat.tree.moin import Container 42 43 44 45 def test_input(d, s): 46 47 "Compare serialised output from 'd' with its original form 's'." 48 49 metadata = Metadata({ 50 "pagename" : "TestPage", 51 }) 52 53 # Encode the input. 54 55 output = make_output(metadata) 56 expected = output.encode(s) 57 58 # Obtain and encode the output. 59 60 result = serialise(d, make_serialiser(metadata)) 61 result = output.encode(result) 62 63 # Test encoded input and output. 64 65 identical = result == expected 66 67 if quiet: 68 return identical 69 70 # Show output versus input comparison result. 71 72 print identical 73 print "-" * 60 74 print result 75 if not identical: 76 print "-" * 60 77 print expected 78 print "-" * 60 79 80 # Show HTML serialisation. 81 82 metadata.set("output_format", "html") 83 metadata.set("mapping", {"MoinMoin" : "https://moinmo.in/"}) 84 85 result = serialise(d, make_serialiser(metadata)) 86 print output.encode(result) 87 print "-" * 60 88 print 89 90 return identical 91 92 def test_tree(d, t, ts): 93 94 """ 95 Compare tree structure 'd' with simplified, expected form 't' from 'ts'. 96 """ 97 98 failing = t.test(d) 99 100 if quiet: 101 return not failing 102 103 # Show tree versus expected forms. 104 105 moin_prettyprinter = make_serialiser(Metadata({"input_format" : "moin"}), "pretty") 106 tree_prettyprinter = make_serialiser(Metadata({"input_format" : "pretty"}), "pretty") 107 108 print not failing 109 print "-" * 60 110 print serialise(d, moin_prettyprinter) 111 if failing: 112 print "-" * 60 113 print ts 114 simple, tree, error = failing 115 print "-" * 60 116 print error 117 print repr(simple) 118 print repr(tree) 119 print "-" * 60 120 print serialise(tree, tree_prettyprinter) 121 print "-" * 60 122 print serialise(simple, tree_prettyprinter) 123 print "-" * 60 124 print 125 126 return not failing 127 128 def get_filename(filename): 129 130 "Using 'filename', return the core text filename and any encoding." 131 132 t = filename.split(".") 133 if len(t) > 2: 134 text_filename = ".".join(t[:2]) 135 encoding = t[2] 136 else: 137 text_filename = filename 138 encoding = None 139 140 return text_filename, encoding 141 142 def get_tree(input, tree_filename): 143 144 "Using 'input', return (text, tree) for 'tree_filename'." 145 146 if input.dir.exists(tree_filename): 147 ts = input.readfile(tree_filename) 148 return ts, parse(ts, make_parser(Metadata(), "pretty")) 149 else: 150 return None, None 151 152 153 154 # Main program. 155 156 if __name__ == "__main__": 157 args = sys.argv[1:] 158 159 if "--help" in args: 160 print >>sys.stderr, """\ 161 Usage: %s [ -q ] [ <filename>... ] 162 163 Run the test suite or, if filenames are indicated, specific test files. 164 The following options are supported: 165 166 -q Suppress test output, reporting only success or failure 167 --quiet Equivalent to -q 168 """ 169 sys.exit(1) 170 171 for arg in ["-q", "--quiet"]: 172 if arg in args: 173 del args[args.index(arg)] 174 quiet = True 175 break 176 else: 177 quiet = False 178 179 metadata = Metadata({ 180 "input_context" : "directory", 181 "input_filename" : dirname, 182 }) 183 184 # Make an input context. 185 186 input = make_input(metadata) 187 188 # Obtain input filenames. 189 190 filenames = args or input.dir.select_files("test*.txt*") 191 filenames.sort() 192 193 # Process each filename, obtaining a corresponding tree definition. 194 195 for filename in filenames: 196 text_filename, encoding = get_filename(filename) 197 198 # Identify any tree-related filenames. 199 200 basename = text_filename.rsplit(".", 1)[0] 201 tree_filename = "%s.tree" % basename 202 tree_exp_filename = "%s.tree-exp" % basename 203 204 # Read and parse the input. 205 206 s = input.readfile(filename, encoding) 207 p = make_parser(metadata) 208 d = parse(s, p) 209 210 # Read and parse any tree definitions. 211 212 ts, t = get_tree(input, tree_filename) 213 tsexp, texp = get_tree(input, tree_exp_filename) 214 215 # Report the test results. 216 217 if not quiet: 218 print filename 219 220 identical = test_input(d, s) 221 tree_identical = ts and test_tree(d, t, ts) 222 223 if tsexp: 224 p.evaluate_macros() 225 tree_exp_identical = test_tree(d, texp, tsexp) 226 else: 227 tree_exp_identical = None 228 229 if quiet: 230 print "%s %s %s: %s" % (identical, tree_identical, tree_exp_identical, filename) 231 232 # vim: tabstop=4 expandtab shiftwidth=4