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 da74e5c43bb300b65d32754f3c264948f8ddd0ad
Author: Jim Jagielski <[email protected]>
AuthorDate: Tue Nov 3 07:06:14 2026 -0500

    test/odf-validate: check that ODF 1.4 error cells load with their error 
code and save as strings
---
 test/odf-validate/fixtures/t14/error_cells.py | 112 ++++++++++++++++++++++++++
 1 file changed, 112 insertions(+)

diff --git a/test/odf-validate/fixtures/t14/error_cells.py 
b/test/odf-validate/fixtures/t14/error_cells.py
new file mode 100644
index 0000000000..8307fd4c33
--- /dev/null
+++ b/test/odf-validate/fixtures/t14/error_cells.py
@@ -0,0 +1,112 @@
+#**************************************************************
+#
+#  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/error_cells.py <port> <outdir>
+# Builds an ODS with office:value-type="error" cells (with and without 
office:string-value, error code only in the text:p, a
+# repeated cell, a string cell as control), loads it, compares each cell's 
error code with the expected one, saves it again and
+# compares the reloaded file. Exit status 1 when a row fails.
+import os, sys, zipfile
+import uno
+from unohelp import FILTERS, connect, desktop, pv
+
+port, out = int(sys.argv[1]), os.path.abspath(sys.argv[2])
+os.makedirs(out, exist_ok=True)
+
+# text, expected error code (519 = #VALUE!, the fallback)
+CASES = [("#NULL!", 521), ("#DIV/0!", 532), ("#VALUE!", 519), ("#REF!", 524), 
("#NAME?", 525), ("#NUM!", 503),
+         ("#N/A", 32767), ("Err:504", 504), ("Err:99999", 519), ("Err:12x", 
519), ("#BOGUS", 519), ("", 519)]
+
+NS = ('xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" '
+      'xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"')
+rows = []
+for t, _ in CASES:
+    p = "<text:p>%s</text:p>" % t if t else ""
+    rows.append('<table:table-row><table:table-cell office:value-type="error" 
office:string-value="%s">%s</table:table-cell>'
+                '<table:table-cell 
office:value-type="error">%s</table:table-cell></table:table-row>' % (t, p, p))
+rows.append('<table:table-row><table:table-cell office:value-type="error" 
office:string-value="#DIV/0!" 
table:number-columns-repeated="3"/></table:table-row>')
+rows.append('<table:table-row><table:table-cell office:value-type="string" 
office:string-value="#DIV/0!"><text:p>#DIV/0!</text:p></table:table-cell></table:table-row>')
+rows.append('<table:table-row><table:table-cell 
office:value-type="error"><text:p><text:span>#DIV/</text:span><text:span>0!</text:span></text:p></table:table-cell></table:table-row>')
+content = ('<?xml version="1.0" encoding="UTF-8"?><office:document-content %s 
office:version="1.4"><office:body><office:spreadsheet>'
+           '<table:table table:name="Sheet1"><table:table-column 
table:number-columns-repeated="3"/>%s</table:table></office:spreadsheet>'
+           '</office:body></office:document-content>') % (NS, "".join(rows))
+manifest = ('<?xml version="1.0" encoding="UTF-8"?><manifest:manifest 
xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" '
+            'manifest:version="1.4"><manifest:file-entry 
manifest:full-path="/" manifest:version="1.4" '
+            
'manifest:media-type="application/vnd.oasis.opendocument.spreadsheet"/>'
+            '<manifest:file-entry manifest:full-path="content.xml" 
manifest:media-type="text/xml"/></manifest:manifest>')
+src = os.path.join(out, "error-cells.ods")
+with zipfile.ZipFile(src, "w") as z:
+    z.writestr(zipfile.ZipInfo("mimetype"), 
"application/vnd.oasis.opendocument.spreadsheet")
+    z.writestr("META-INF/manifest.xml", manifest, zipfile.ZIP_DEFLATED)
+    z.writestr("content.xml", content, zipfile.ZIP_DEFLATED)
+
+fails = 0
+
+
+TEXT = {521: "#NULL!", 532: "#DIV/0!", 519: "#VALUE!", 524: "#REF!", 525: 
"#NAME?", 503: "#NUM!", 32767: "#N/A", 504: "Err:504"}
+
+
+def check(label, doc, asstring):
+    # asstring: the saved file holds error cells as value-type="string" (no 
formula), so the reload is a text cell
+    global fails
+    sh = doc.Sheets.getByIndex(0)
+
+    def row(what, c, code):
+        global fails
+        if asstring:
+            ok = c.getError() == 0 and c.getString() == TEXT[code] and 
c.getFormula() == TEXT[code]
+            got = "error %d string %r formula %r" % (c.getError(), 
c.getString(), c.getFormula())
+        else:
+            ok = c.getError() == code
+            got = "error %d" % c.getError()
+        fails += not ok
+        print("%-7s %-26s expect %-7s got %s  %s" % (label, what, TEXT[code] 
if asstring else code, got, "ok" if ok else "FAIL"))
+
+    for i, (t, code) in enumerate(CASES):
+        for col, kind in ((0, "string-value"), (1, "text only")):
+            row("%r %s" % (t, kind), sh.getCellByPosition(col, i), code)
+    for col in range(3):
+        row("repeated col %d" % col, sh.getCellByPosition(col, len(CASES)), 
532)
+    c = sh.getCellByPosition(0, len(CASES) + 1)
+    ok = c.getError() == 0 and c.getString() == "#DIV/0!"
+    fails += not ok
+    print("%-7s string control: error %d string %r  %s" % (label, 
c.getError(), c.getString(), "ok" if ok else "FAIL"))
+    row("text in text:span", sh.getCellByPosition(0, len(CASES) + 2), 532)
+
+
+ctx = connect(port)
+desk = desktop(ctx)
+load = lambda p: desk.loadComponentFromURL(uno.systemPathToFileUrl(p), 
"_blank", 0, (pv("Hidden", True),))
+doc = load(src)
+if doc is None:
+    sys.exit("could not load " + src)
+check("load", doc, False)
+# an unchanged sheet is copied verbatim in some modes, so touch it to force 
the real export
+doc.Sheets.getByIndex(0).getCellByPosition(5, 0).setValue(1)
+dst = os.path.join(out, "error-cells-resaved.ods")
+if os.path.exists(dst):
+    os.remove(dst)
+doc.storeToURL(uno.systemPathToFileUrl(dst), (pv("FilterName", 
FILTERS["ods"]), pv("Overwrite", True)))
+doc.close(True)
+doc = load(dst)
+check("reload", doc, True)
+doc.close(True)
+print("FAILS", fails)
+sys.exit(1 if fails else 0)

Reply via email to