12cb6d6f1SJim Jagielski################################################################ 22cb6d6f1SJim Jagielski# 32cb6d6f1SJim Jagielski# Licensed to the Apache Software Foundation (ASF) under one 42cb6d6f1SJim Jagielski# or more contributor license agreements. See the NOTICE file 52cb6d6f1SJim Jagielski# distributed with this work for additional information 62cb6d6f1SJim Jagielski# regarding copyright ownership. The ASF licenses this file 72cb6d6f1SJim Jagielski# to you under the Apache License, Version 2.0 (the 82cb6d6f1SJim Jagielski# "License"); you may not use this file except in compliance 92cb6d6f1SJim Jagielski# with the License. You may obtain a copy of the License at 102cb6d6f1SJim Jagielski# 112cb6d6f1SJim Jagielski# http://www.apache.org/licenses/LICENSE-2.0 122cb6d6f1SJim Jagielski# 132cb6d6f1SJim Jagielski# Unless required by applicable law or agreed to in writing, 142cb6d6f1SJim Jagielski# software distributed under the License is distributed on an 152cb6d6f1SJim Jagielski# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 162cb6d6f1SJim Jagielski# KIND, either express or implied. See the License for the 172cb6d6f1SJim Jagielski# specific language governing permissions and limitations 182cb6d6f1SJim Jagielski# under the License. 192cb6d6f1SJim Jagielski 202cb6d6f1SJim Jagielski"""aootest.stability: two saves that differ only in the cached value of a date or time field compare equal, and any other 212cb6d6f1SJim Jagielskidifference does not.""" 222cb6d6f1SJim Jagielskiimport zipfile 232cb6d6f1SJim Jagielski 242cb6d6f1SJim Jagielskiimport pytest 252cb6d6f1SJim Jagielski 262cb6d6f1SJim Jagielskifrom aootest import stability 272cb6d6f1SJim Jagielski 282cb6d6f1SJim Jagielskipytestmark = pytest.mark.selftest 292cb6d6f1SJim Jagielski 302cb6d6f1SJim JagielskiBODY = '<office:text><text:p>Hello <text:time text:time-value="2026-11-02T07:47:54" text:fixed="false">07:47:54</text:time></text:p></office:text>' 312cb6d6f1SJim Jagielski 322cb6d6f1SJim Jagielski 332cb6d6f1SJim Jagielskidef package(path, content, styles="<office:document-styles/>"): 342cb6d6f1SJim Jagielski with zipfile.ZipFile(path, "w") as z: 352cb6d6f1SJim Jagielski z.writestr("content.xml", content) 36*85d6e4e5SJim Jagielski if styles is not None: 372cb6d6f1SJim Jagielski z.writestr("styles.xml", styles) 382cb6d6f1SJim Jagielski return str(path) 392cb6d6f1SJim Jagielski 402cb6d6f1SJim Jagielski 412cb6d6f1SJim Jagielskidef test_normalize_drops_the_cached_time_and_the_value_attribute(): 422cb6d6f1SJim Jagielski other = BODY.replace("07:47:54", "07:48:00") 432cb6d6f1SJim Jagielski assert stability.normalize(BODY) == stability.normalize(other) 442cb6d6f1SJim Jagielski assert "07:47:54" not in stability.normalize(BODY) 452cb6d6f1SJim Jagielski 462cb6d6f1SJim Jagielski 472cb6d6f1SJim Jagielskidef test_two_packages_differing_only_in_a_time_field_compare_equal(tmp_path): 482cb6d6f1SJim Jagielski a = package(tmp_path / "a.zip", BODY) 492cb6d6f1SJim Jagielski b = package(tmp_path / "b.zip", BODY.replace("07:47:54", "09:00:00")) 502cb6d6f1SJim Jagielski assert stability.differing_parts(a, b) == [] 512cb6d6f1SJim Jagielski 522cb6d6f1SJim Jagielski 532cb6d6f1SJim Jagielski@pytest.mark.parametrize("change", [lambda t: t.replace("Hello", "Hullo"), lambda t: t.replace('text:fixed="false"', 'text:fixed="true"'), 542cb6d6f1SJim Jagielski lambda t: t.replace("<text:p>", "<text:p text:style-name=\"P1\">")]) 552cb6d6f1SJim Jagielskidef test_any_other_difference_is_reported(tmp_path, change): 562cb6d6f1SJim Jagielski a = package(tmp_path / "a.zip", BODY) 572cb6d6f1SJim Jagielski b = package(tmp_path / "b.zip", change(BODY)) 582cb6d6f1SJim Jagielski assert stability.differing_parts(a, b) == ["content.xml"] 592cb6d6f1SJim Jagielski 602cb6d6f1SJim Jagielski 612cb6d6f1SJim Jagielskidef test_a_difference_in_styles_xml_is_reported(tmp_path): 622cb6d6f1SJim Jagielski a = package(tmp_path / "a.zip", BODY) 632cb6d6f1SJim Jagielski b = package(tmp_path / "b.zip", BODY, "<office:document-styles>x</office:document-styles>") 642cb6d6f1SJim Jagielski assert stability.differing_parts(a, b) == ["styles.xml"] 65*85d6e4e5SJim Jagielski 66*85d6e4e5SJim Jagielski 67*85d6e4e5SJim Jagielskidef test_a_part_neither_package_has_is_not_compared(tmp_path): 68*85d6e4e5SJim Jagielski a = package(tmp_path / "a.zip", BODY, None) 69*85d6e4e5SJim Jagielski b = package(tmp_path / "b.zip", BODY, None) 70*85d6e4e5SJim Jagielski assert stability.differing_parts(a, b) == [] 71*85d6e4e5SJim Jagielski assert stability.differing_parts(a, package(tmp_path / "c.zip", BODY.replace("Hello", "Hullo"), None)) == ["content.xml"] 72*85d6e4e5SJim Jagielski 73*85d6e4e5SJim Jagielski 74*85d6e4e5SJim Jagielskidef test_a_part_only_one_package_has_is_reported(tmp_path): 75*85d6e4e5SJim Jagielski a = package(tmp_path / "a.zip", BODY, None) 76*85d6e4e5SJim Jagielski b = package(tmp_path / "b.zip", BODY) 77*85d6e4e5SJim Jagielski assert stability.differing_parts(a, b) == ["styles.xml"] 78*85d6e4e5SJim Jagielski assert stability.differing_parts(b, a) == ["styles.xml"] 79