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