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