This is an automated email from the ASF dual-hosted git repository. jimjag pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/openoffice.git
commit 9a8341fd38268a6e9d098ebdffda74a60de5b04e Author: Jim Jagielski <[email protected]> AuthorDate: Tue Nov 3 04:13:38 2026 -0500 test/odf-validate: check the ODF 1.4 save formats, the load prompt and the volatile footnote document --- test/odf-validate/fixtures/t13/prompt_check.py | 8 +-- test/odf-validate/fixtures/t14/config_roundtrip.py | 72 ++++++++++++++++++++++ test/odf-validate/fixtures/t14/config_roundtrip.sh | 40 ++++++++++++ test/odf-validate/gate-volatile.tsv | 1 + test/odf-validate/selftest.py | 2 +- 5 files changed, 118 insertions(+), 5 deletions(-) diff --git a/test/odf-validate/fixtures/t13/prompt_check.py b/test/odf-validate/fixtures/t13/prompt_check.py index b871122ad2..d4d68d1661 100644 --- a/test/odf-validate/fixtures/t13/prompt_check.py +++ b/test/odf-validate/fixtures/t13/prompt_check.py @@ -20,10 +20,10 @@ #************************************************************** # usage: runpy.sh fixtures/t13/prompt_check.py <port> <package.odt|ods|odp|odg> <outdir> -# Loads copies of one ODF 1.2 package whose office:version and manifest:version are rewritten to 1.2, 1.3 and 1.4, with an +# Loads copies of one ODF 1.2 package whose office:version and manifest:version are rewritten to 1.2, 1.3, 1.4 and 1.5, with an # interaction handler, and reports whether the "created with a newer version" request (FutureDocumentVersionProductUpdateRequest) -# was raised, counted as a call of the handler (the documents used raise no other request). Expected: none for 1.2 and 1.3, one for -# 1.4 (the negative control). Needs Load/ShowOfficeUpdateDialog = true. +# was raised, counted as a call of the handler (the documents used raise no other request). Expected: none for 1.2, 1.3 and 1.4, one for +# 1.5 (the negative control). Needs Load/ShowOfficeUpdateDialog = true. import os, re, sys, zipfile import uno, unohelper from com.sun.star.task import XInteractionHandler @@ -63,7 +63,7 @@ ctx = connect(port) desk = desktop(ctx) ext = os.path.splitext(src)[1] results = {} -for version, want in (("1.2", False), ("1.3", False), ("1.4", True)): +for version, want in (("1.2", False), ("1.3", False), ("1.4", False), ("1.5", True)): dst = os.path.join(out, "v" + version.replace(".", "") + ext) rewrite(version, dst) h = Handler() diff --git a/test/odf-validate/fixtures/t14/config_roundtrip.py b/test/odf-validate/fixtures/t14/config_roundtrip.py new file mode 100644 index 0000000000..36683d5579 --- /dev/null +++ b/test/odf-validate/fixtures/t14/config_roundtrip.py @@ -0,0 +1,72 @@ +#************************************************************** +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# usage: runpy.sh fixtures/t14/config_roundtrip.py <port> <outdir> <value> (run for the values 0..8 by config_roundtrip.sh) +# Saves a Writer, a Calc, an Impress and a Draw document (writer8, calc8, impress8, draw8) with the office's Save/ODF/DefaultVersion +# set in its profile to <value> and reads office:version of every XML stream and manifest:version back from the package. +# Expected: 1 = no version, 2 = 1.1, 3 and 4 = 1.2, 5 and 6 = 1.3, 7 and 8 = 1.4; 0 (unknown) is only reported. +import os, re, sys, zipfile +import uno +from unohelp import FILTERS, connect, desktop, pv + +port, out, n = int(sys.argv[1]), os.path.abspath(sys.argv[2]), int(sys.argv[3]) +os.makedirs(out, exist_ok=True) +EXPECT = {1: None, 2: "1.1", 3: "1.2", 4: "1.2", 5: "1.3", 6: "1.3", 7: "1.4", 8: "1.4"} +ctx = connect(port) +sm = ctx.ServiceManager +desk = desktop(ctx) +def build(doc, ext): + if ext == "odt": + doc.Text.insertString(doc.Text.createTextCursor(), "text", False) + elif ext == "ods": + doc.Sheets.getByIndex(0).getCellByPosition(0, 0).Value = 1 + else: + sh = doc.createInstance("com.sun.star.drawing.TextShape") + doc.DrawPages.getByIndex(0).add(sh) + sh.String = "shape" + + +URL = {"odt": "private:factory/swriter", "ods": "private:factory/scalc", "odp": "private:factory/simpress", "odg": "private:factory/sdraw"} +bad = 0 +for ext in ("odt", "ods", "odp", "odg"): + doc = desk.loadComponentFromURL(URL[ext], "_blank", 0, (pv("Hidden", True),)) + build(doc, ext) + path = os.path.join(out, "c%d.%s" % (n, ext)) + if os.path.exists(path): + os.remove(path) + doc.storeToURL(uno.systemPathToFileUrl(path), (pv("FilterName", FILTERS[ext]), pv("Overwrite", True))) + doc.close(True) + z = zipfile.ZipFile(path) + vers = {} + for name in ("content.xml", "styles.xml", "meta.xml", "settings.xml"): + if name in z.namelist(): + m = re.search(r'<office:document-[a-z]+ [^>]*office:version="([0-9.]+)"', z.read(name).decode("utf-8")) + vers[name] = m.group(1) if m else None + mm = re.search(r'<manifest:manifest [^>]*manifest:version="([0-9.]+)"', z.read("META-INF/manifest.xml").decode("utf-8")) + vers["manifest"] = mm.group(1) if mm else None + want = EXPECT.get(n, "skip") + if n == 0: + ok = True + else: + ok = all(v == want for k, v in vers.items() if k != "manifest") and (vers["manifest"] == want if want and want >= "1.2" else True) + bad += 0 if ok else 1 + print("%s config %d %s: want %s got %s" % ("PASS" if ok else "FAIL", n, ext, want, vers)) +print("config_roundtrip %d: %d failures" % (n, bad)) +sys.exit(1 if bad else 0) diff --git a/test/odf-validate/fixtures/t14/config_roundtrip.sh b/test/odf-validate/fixtures/t14/config_roundtrip.sh new file mode 100755 index 0000000000..e0e7fb5909 --- /dev/null +++ b/test/odf-validate/fixtures/t14/config_roundtrip.sh @@ -0,0 +1,40 @@ +#!/bin/zsh +#************************************************************** +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +#************************************************************** +# usage: config_roundtrip.sh <outdir> +# Starts an office per Save/ODF/DefaultVersion value 0..8 (profile runs/profile_cfgN, port 2310+N) and runs config_roundtrip.py in it. +source ${0:A:h}/../../env.sh +out=${1:?outdir} +rc=0 +for n in {0..8}; do + prof=cfg$n + mkdir -p $D/runs/profile_$prof/user + cat > $D/runs/profile_$prof/user/registrymodifications.xcu <<XCU +<?xml version="1.0" encoding="UTF-8"?> +<oor:items xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> +<item oor:path="/org.openoffice.Office.Common/Save/ODF"><prop oor:name="DefaultVersion" oor:op="fuse"><value>$n</value></prop></item> +</oor:items> +XCU + $D/start.sh $prof $((2310 + n)) || { rc=1; continue; } + (cd $D && gtimeout 120 $D/runpy.sh fixtures/t14/config_roundtrip.py $((2310 + n)) $out $n) || rc=1 + pkill -f "profile_$prof"; sleep 2 +done +exit $rc diff --git a/test/odf-validate/gate-volatile.tsv b/test/odf-validate/gate-volatile.tsv index ea980d51df..cefc173c30 100644 --- a/test/odf-validate/gate-volatile.tsv +++ b/test/odf-validate/gate-volatile.tsv @@ -13,3 +13,4 @@ 0266_RedlineTest.odt redline import stamps Unknown Author changes with the load time 0238_parentinvguid.odt the loader gives different shape and frame order in fresh sessions (the export is identical) 0083_StarOffice_Delphi.odt reload: the height of one frame comes out as 2540 or 3067 between runs in every mode, cause not found (seen in p2c1 strict and p5a ext, not in the other gates) +0264_Paragraph with footnote.odt docx footnote and endnote styles and the order of automatic styles vary between runs of an unchanged build (ext output of two runs differ) diff --git a/test/odf-validate/selftest.py b/test/odf-validate/selftest.py index 511035ae7e..6f96fa34e4 100644 --- a/test/odf-validate/selftest.py +++ b/test/odf-validate/selftest.py @@ -165,7 +165,7 @@ gspec = importlib.util.spec_from_file_location("gate", os.path.join(D, "gate.py" gt = importlib.util.module_from_spec(gspec) gspec.loader.exec_module(gt) vol = gt.read_volatile() -checks["gate: gate-volatile.tsv lists the 13 documents with a reason"] = len(vol) == 13 and all(len(r) > 10 for r in vol.values()) +checks["gate: gate-volatile.tsv lists the 14 documents with a reason"] = len(vol) == 14 and all(len(r) > 10 for r in vol.values()) checks["gate: rewrite_jobs keeps sources and moves outputs"] = gt.rewrite_jobs([("/a/b.odt", "/x/0001_b.odt")], "/new") == [("/a/b.odt", "/new/0001_b.odt")] fake = {"0067_AddInChart.ods": {"ndiff": 1}, "0001_x.odt": {"ndiff": 0}, "0002_y.odt": {"ndiff": 3}} checks["gate: classify separates volatile from unexplained differences"] = gt.classify(fake, vol) == (1, ["0067_AddInChart.ods"], ["0002_y.odt"])
