xref: /trunk/test/odf-validate/make-doctype-controls.py (revision 0e16a31d78a652c56c5c0fc79c752f48b9048df9)
1#**************************************************************
2#
3#  Licensed to the Apache Software Foundation (ASF) under one
4#  or more contributor license agreements.  See the NOTICE file
5#  distributed with this work for additional information
6#  regarding copyright ownership.  The ASF licenses this file
7#  to you under the Apache License, Version 2.0 (the
8#  "License"); you may not use this file except in compliance
9#  with the License.  You may obtain a copy of the License at
10#
11#    http://www.apache.org/licenses/LICENSE-2.0
12#
13#  Unless required by applicable law or agreed to in writing,
14#  software distributed under the License is distributed on an
15#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16#  KIND, either express or implied.  See the License for the
17#  specific language governing permissions and limitations
18#  under the License.
19#
20#**************************************************************
21
22# usage: make-doctype-controls.py -- (re)generate doctypecheck.py's negative-control documents in fixtures/control-doctype/
23# .expected.json maps each document to the (level, rule) pairs doctypecheck.py must report, exactly.
24import json, os, shutil, zipfile
25
26C = os.path.join(os.path.dirname(os.path.abspath(__file__)), "fixtures", "control-doctype")
27P = "application/vnd.oasis.opendocument."
28NS = ('xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML"')
29S, Z = zipfile.ZIP_STORED, zipfile.ZIP_DEFLATED
30EXPECTED = {}
31
32
33def content(child="text", root="office:document-content", extra=""):
34    body = "<office:body>%s</office:body>" % ("<office:%s/>" % child if child else "")
35    return '<?xml version="1.0" encoding="UTF-8"?>\n<%s %s office:version="1.2"%s>%s</%s>\n' % (root, NS, extra, body, root)
36
37
38MATHDOC = '<?xml version="1.0" encoding="UTF-8"?>\n<math:math %s><math:mi>x</math:mi></math:math>\n' % NS
39
40
41def pkg(name, mime, body, expect=(), files=None, manifest=""):
42    """files: replaces the default content.xml; manifest: extra file-entry elements."""
43    with zipfile.ZipFile(os.path.join(C, name + ".odt"), "w") as z:
44        if mime is not None:
45            z.writestr(zipfile.ZipInfo("mimetype"), mime, compress_type=S)
46        for n, d in (files if files is not None else {"content.xml": body}).items():
47            z.writestr(n, d, compress_type=Z)
48        z.writestr("META-INF/manifest.xml", '<?xml version="1.0" encoding="UTF-8"?>\n<manifest:manifest xmlns:manifest='
49                   '"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" manifest:version="1.2">%s</manifest:manifest>\n' % manifest, compress_type=Z)
50    EXPECTED[name + ".odt"] = sorted(expect)
51
52
53def flat(name, mime, child="text", expect=()):
54    attr = "" if mime is None else ' office:mimetype="%s"' % mime
55    open(os.path.join(C, name + ".fodt"), "w").write(content(child, "office:document", attr))
56    EXPECTED[name + ".fodt"] = sorted(expect)
57
58
59shutil.rmtree(C, ignore_errors=True)
60os.makedirs(C)
61for t, ms, child in (("text", ["text", "text-template", "text-master"], "text"), ("spreadsheet", ["spreadsheet", "spreadsheet-template"], "spreadsheet"),
62                     ("drawing", ["graphics", "graphics-template"], "drawing"), ("presentation", ["presentation", "presentation-template"], "presentation"),
63                     ("chart", ["chart", "chart-template"], "chart"), ("image", ["image", "image-template"], "image"), ("database", ["base"], "database")):
64    for m in ms:
65        pkg("good-" + m, P + m, content(child))
66pkg("good-formula", P + "formula", MATHDOC)
67sub = lambda mt, c: {"content.xml": content(), "Object 1/content.xml": c}
68ent = lambda mt: '<manifest:file-entry manifest:full-path="Object 1/" manifest:media-type="%s"/>' % mt
69pkg("good-embedded", P + "text", None, files=sub(P + "chart", content("chart")), manifest=ent(P + "chart"))
70pkg("good-embedded-math", P + "text", None, files=sub("", MATHDOC), manifest=ent(P + "formula"))
71flat("good-flat", P + "text")
72for m, ru in (("application/x-bogus", "doctype-unknown-mimetype"), (P + "text\n", "doctype-unknown-mimetype"),
73              ("application.vnd.oasis.opendocument.graphics", "doctype-unknown-mimetype"),
74              (P + "text-web", "doctype-unlisted-mimetype"), (P + "formula-template", "doctype-unlisted-mimetype")):
75    pkg("bad-mime-" + str(len(EXPECTED)), m, content(), [("shall", ru)])
76pkg("no-mimetype", None, content(), [("shall", "doctype-no-mimetype")])
77pkg("body-mismatch", P + "text", content("spreadsheet"), [("shall", "doctype-body")])
78pkg("body-empty", P + "text", content(None), [("shall", "doctype-body")])
79pkg("root-styles", P + "text", content(root="office:document-styles"), [("shall", "doctype-root")])
80pkg("formula-wrong-root", P + "formula", content(), [("shall", "doctype-root")])
81pkg("math-in-text", P + "text", MATHDOC, [("shall", "doctype-root")])
82pkg("only-styles", P + "text", None, [("shall", "doctype-no-body")], files={"styles.xml": content(None, "office:document-styles")})
83pkg("only-meta", P + "text", None, [("shall", "doctype-no-content"), ("shall", "doctype-no-body")], files={"meta.xml": "<a/>"})
84pkg("malformed", P + "text", "<office:document-content", [("shall", "doctype-malformed")])
85pkg("sub-body", P + "text", None, [("should", "sub-doctype-body")], files=sub(P + "chart", content("spreadsheet")), manifest=ent(P + "chart"))
86pkg("sub-root", P + "text", None, [("should", "sub-doctype-root")], files=sub(P + "formula", content()), manifest=ent(P + "formula"))
87flat("flat-no-mimetype", None, expect=[("shall", "doctype-no-mimetype")])
88flat("flat-unknown", "application/x-bogus", expect=[("shall", "doctype-unknown-mimetype")])
89flat("flat-formula-mime", P + "formula", expect=[("shall", "doctype-unknown-mimetype")])
90flat("flat-body", P + "text", "presentation", [("shall", "doctype-body")])
91json.dump(EXPECTED, open(os.path.join(C, ".expected.json"), "w"), indent=1)
92