From 498245c175fb44a19e248ee23e4aae41360578c0 Mon Sep 17 00:00:00 2001 From: VsevolodX Date: Mon, 2 Mar 2026 12:16:35 -0800 Subject: [PATCH 1/6] update: calculate hash --- dist/js/application.d.ts | 1 + dist/js/application.js | 4 ++++ src/js/application.ts | 9 ++++++++- src/py/mat3ra/ade/application.py | 3 +++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/dist/js/application.d.ts b/dist/js/application.d.ts index fd78625..884211d 100644 --- a/dist/js/application.d.ts +++ b/dist/js/application.d.ts @@ -4,5 +4,6 @@ import { type ApplicationMixin, type ApplicationStaticMixin } from "./applicatio type Base = typeof NamedDefaultableInMemoryEntity & Constructor & ApplicationStaticMixin; declare const Application_base: Base; export default class Application extends Application_base { + calculateHash(): string; } export {}; diff --git a/dist/js/application.js b/dist/js/application.js index 129810e..6570046 100644 --- a/dist/js/application.js +++ b/dist/js/application.js @@ -1,8 +1,12 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const entity_1 = require("@mat3ra/code/dist/js/entity"); +const utils_1 = require("@mat3ra/utils"); const applicationMixin_1 = require("./applicationMixin"); class Application extends entity_1.NamedDefaultableInMemoryEntity { + calculateHash() { + return utils_1.Utils.hash.calculateHashFromObject(utils_1.Utils.specific.removeTimestampableKeysFromConfig(this.toJSON())); + } } exports.default = Application; (0, applicationMixin_1.applicationMixin)(Application.prototype); diff --git a/src/js/application.ts b/src/js/application.ts index 7a980d0..f18d5ae 100644 --- a/src/js/application.ts +++ b/src/js/application.ts @@ -1,5 +1,6 @@ import { NamedDefaultableInMemoryEntity } from "@mat3ra/code/dist/js/entity"; import type { Constructor } from "@mat3ra/code/dist/js/utils/types"; +import { Utils } from "@mat3ra/utils"; import { type ApplicationMixin, @@ -12,7 +13,13 @@ type Base = typeof NamedDefaultableInMemoryEntity & Constructor & ApplicationStaticMixin; -export default class Application extends (NamedDefaultableInMemoryEntity as Base) {} +export default class Application extends (NamedDefaultableInMemoryEntity as Base) { + calculateHash() { + return Utils.hash.calculateHashFromObject( + Utils.specific.removeTimestampableKeysFromConfig(this.toJSON()), + ); + } +} applicationMixin(Application.prototype); applicationStaticMixin(Application); diff --git a/src/py/mat3ra/ade/application.py b/src/py/mat3ra/ade/application.py index ed2c8c2..fbce130 100644 --- a/src/py/mat3ra/ade/application.py +++ b/src/py/mat3ra/ade/application.py @@ -1,5 +1,6 @@ from mat3ra.code.entity import InMemoryEntitySnakeCase from mat3ra.esse.models.software.application import ApplicationSchemaBase +from mat3ra.utils.object import calculate_hash_from_object, remove_timestampable_keys class Application(ApplicationSchemaBase, InMemoryEntitySnakeCase): @@ -26,3 +27,5 @@ def is_using_material(self) -> bool: def get_short_name(self) -> str: return self.short_name if self.short_name else self.name + def calculate_hash(self) -> str: + return calculate_hash_from_object(remove_timestampable_keys(self.to_dict())) From 8d63598ed4aac5ea9624383c8f70fef06bbd166b Mon Sep 17 00:00:00 2001 From: VsevolodX Date: Mon, 2 Mar 2026 12:19:09 -0800 Subject: [PATCH 2/6] update: test hashing --- tests/fixtures/application_hash.json | 14 ++++++++++++++ tests/js/application.test.ts | 10 ++++++++++ tests/py/test_application.py | 9 +++++++++ 3 files changed, 33 insertions(+) create mode 100644 tests/fixtures/application_hash.json diff --git a/tests/fixtures/application_hash.json b/tests/fixtures/application_hash.json new file mode 100644 index 0000000..372ddc2 --- /dev/null +++ b/tests/fixtures/application_hash.json @@ -0,0 +1,14 @@ +{ + "config": { + "name": "espresso", + "version": "6.8", + "build": "", + "shortName": "espresso", + "summary": "", + "hasAdvancedComputeOptions": false, + "isLicensed": false, + "isDefault": false, + "schemaVersion": "2022.8.16" + }, + "hash": "b7353f1be53119573f184497442e3202" +} diff --git a/tests/js/application.test.ts b/tests/js/application.test.ts index e473fe9..4938f96 100644 --- a/tests/js/application.test.ts +++ b/tests/js/application.test.ts @@ -1,5 +1,7 @@ /* eslint-disable no-unused-expressions */ import { expect } from "chai"; +import { readFileSync } from "fs"; +import { resolve } from "path"; import Application from "../../src/js/application"; import type { CreateApplicationConfig } from "../../src/js/ApplicationRegistry"; @@ -134,4 +136,12 @@ describe("Application", () => { expect(schema).to.have.property("$id"); }); }); + + it("calculateHash matches fixture", () => { + const fixture = JSON.parse( + readFileSync(resolve(__dirname, "../fixtures/application_hash.json"), "utf-8"), + ); + const app = new Application(fixture.config); + expect(app.calculateHash()).to.equal(fixture.hash); + }); }); diff --git a/tests/py/test_application.py b/tests/py/test_application.py index 00ab98c..0c912f5 100644 --- a/tests/py/test_application.py +++ b/tests/py/test_application.py @@ -1,5 +1,7 @@ from mat3ra.ade import Application from mat3ra.utils import assertion +from pathlib import Path +import json APPLICATION_DEFAULT_FIELDS = { "schemaVersion": "2022.8.16", @@ -86,3 +88,10 @@ def test_application_from_dict(): app = Application(**config) expected = {**config} assertion.assert_deep_almost_equal(expected, app.model_dump(exclude_unset=True)) + + +def test_calculate_hash_matches_fixture(): + fixture_path = Path(__file__).parent.parent / "fixtures" / "application_hash.json" + fixture = json.loads(fixture_path.read_text()) + app = Application(**fixture["config"]) + assert app.calculate_hash() == fixture["hash"] From ee7097e6a8bfc87684d34aba85a9fbee593658ba Mon Sep 17 00:00:00 2001 From: VsevolodX Date: Tue, 3 Mar 2026 13:39:40 -0800 Subject: [PATCH 3/6] update: test use standata --- tests/fixtures/application_hash.json | 14 ++++---------- tests/js/application.test.ts | 7 ++++++- tests/py/test_application.py | 10 +++++++++- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/tests/fixtures/application_hash.json b/tests/fixtures/application_hash.json index 372ddc2..b9273da 100644 --- a/tests/fixtures/application_hash.json +++ b/tests/fixtures/application_hash.json @@ -1,14 +1,8 @@ { - "config": { + "standata": { "name": "espresso", - "version": "6.8", - "build": "", - "shortName": "espresso", - "summary": "", - "hasAdvancedComputeOptions": false, - "isLicensed": false, - "isDefault": false, - "schemaVersion": "2022.8.16" + "version": "6.3", + "build": "GNU" }, - "hash": "b7353f1be53119573f184497442e3202" + "hash": "e4f4762afefb659c36b6ac2d08d860cc" } diff --git a/tests/js/application.test.ts b/tests/js/application.test.ts index 4938f96..a9b3f71 100644 --- a/tests/js/application.test.ts +++ b/tests/js/application.test.ts @@ -1,4 +1,5 @@ /* eslint-disable no-unused-expressions */ +import { ApplicationStandata } from "@mat3ra/standata"; import { expect } from "chai"; import { readFileSync } from "fs"; import { resolve } from "path"; @@ -141,7 +142,11 @@ describe("Application", () => { const fixture = JSON.parse( readFileSync(resolve(__dirname, "../fixtures/application_hash.json"), "utf-8"), ); - const app = new Application(fixture.config); + const { name, version, build } = fixture.standata; + const standata = new ApplicationStandata(); + const configs = standata.getByApplicationName(name) as any[]; + const config = configs.find((a) => a.version === version && a.build === build); + const app = new Application(config); expect(app.calculateHash()).to.equal(fixture.hash); }); }); diff --git a/tests/py/test_application.py b/tests/py/test_application.py index 0c912f5..a8bb3f8 100644 --- a/tests/py/test_application.py +++ b/tests/py/test_application.py @@ -93,5 +93,13 @@ def test_application_from_dict(): def test_calculate_hash_matches_fixture(): fixture_path = Path(__file__).parent.parent / "fixtures" / "application_hash.json" fixture = json.loads(fixture_path.read_text()) - app = Application(**fixture["config"]) + from mat3ra.standata.applications import ApplicationStandata + + st = fixture["standata"] + [config] = [ + a + for a in ApplicationStandata.get_by_name(st["name"]) + if a.get("version") == st["version"] and a.get("build") == st["build"] + ] + app = Application(**config) assert app.calculate_hash() == fixture["hash"] From 6a6f3832251347a5846303927f22687085796663 Mon Sep 17 00:00:00 2001 From: VsevolodX Date: Tue, 3 Mar 2026 13:42:27 -0800 Subject: [PATCH 4/6] update: import standata --- pyproject.toml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a5c6692..b4e83c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,8 @@ dependencies = [ "pydantic>=2.0", "mat3ra-esse", "mat3ra-code", - "mat3ra-utils[extra]" + "mat3ra-utils[extra]", + "mat3ra-standata" ] [project.optional-dependencies] @@ -40,7 +41,8 @@ tests = [ "pytest", "pytest-cov", "mat3ra-esse", - "mat3ra-utils" + "mat3ra-utils>=2026.2.3", + "mat3ra-standata" ] all = [ "mat3ra-ade[tests]", @@ -94,4 +96,3 @@ pythonpath = [ testpaths = [ "tests/py" ] - From cc8c9cf34c8c6e2f78d1d14a6fa21d0108145ecc Mon Sep 17 00:00:00 2001 From: VsevolodX Date: Tue, 3 Mar 2026 13:48:12 -0800 Subject: [PATCH 5/6] chore: lint --- tests/py/test_application.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/py/test_application.py b/tests/py/test_application.py index a8bb3f8..f6b5d14 100644 --- a/tests/py/test_application.py +++ b/tests/py/test_application.py @@ -1,7 +1,9 @@ +import json +from pathlib import Path + from mat3ra.ade import Application +from mat3ra.standata.applications import ApplicationStandata from mat3ra.utils import assertion -from pathlib import Path -import json APPLICATION_DEFAULT_FIELDS = { "schemaVersion": "2022.8.16", @@ -93,7 +95,6 @@ def test_application_from_dict(): def test_calculate_hash_matches_fixture(): fixture_path = Path(__file__).parent.parent / "fixtures" / "application_hash.json" fixture = json.loads(fixture_path.read_text()) - from mat3ra.standata.applications import ApplicationStandata st = fixture["standata"] [config] = [ From 1f85b51ed09b99a48b438daf11beb9a2a66f08c6 Mon Sep 17 00:00:00 2001 From: VsevolodX Date: Tue, 3 Mar 2026 13:52:04 -0800 Subject: [PATCH 6/6] chore: pyproject --- pyproject.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b4e83c2..a38a4a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,8 +23,7 @@ dependencies = [ "pydantic>=2.0", "mat3ra-esse", "mat3ra-code", - "mat3ra-utils[extra]", - "mat3ra-standata" + "mat3ra-utils[extra]" ] [project.optional-dependencies]