Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dist/js/application.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ import { type ApplicationMixin, type ApplicationStaticMixin } from "./applicatio
type Base = typeof NamedDefaultableInMemoryEntity & Constructor<ApplicationMixin> & ApplicationStaticMixin;
declare const Application_base: Base;
export default class Application extends Application_base {
calculateHash(): string;
}
export {};
4 changes: 4 additions & 0 deletions dist/js/application.js
Original file line number Diff line number Diff line change
@@ -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);
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ tests = [
"pytest",
"pytest-cov",
"mat3ra-esse",
"mat3ra-utils"
"mat3ra-utils>=2026.2.3",
"mat3ra-standata"
]
all = [
"mat3ra-ade[tests]",
Expand Down Expand Up @@ -94,4 +95,3 @@ pythonpath = [
testpaths = [
"tests/py"
]

9 changes: 8 additions & 1 deletion src/js/application.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -12,7 +13,13 @@ type Base = typeof NamedDefaultableInMemoryEntity &
Constructor<ApplicationMixin> &
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);
3 changes: 3 additions & 0 deletions src/py/mat3ra/ade/application.py
Original file line number Diff line number Diff line change
@@ -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):
Expand All @@ -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()))
8 changes: 8 additions & 0 deletions tests/fixtures/application_hash.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"standata": {
"name": "espresso",
"version": "6.3",
"build": "GNU"
},
"hash": "e4f4762afefb659c36b6ac2d08d860cc"
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, but should we get this from standata?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, that's what I did for WF. But at least hash must be here in the common folder to compare Py/JS.

15 changes: 15 additions & 0 deletions tests/js/application.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
/* eslint-disable no-unused-expressions */
import { ApplicationStandata } from "@mat3ra/standata";
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";
Expand Down Expand Up @@ -134,4 +137,16 @@ 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 { 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);
});
});
18 changes: 18 additions & 0 deletions tests/py/test_application.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import json
from pathlib import Path

from mat3ra.ade import Application
from mat3ra.standata.applications import ApplicationStandata
from mat3ra.utils import assertion

APPLICATION_DEFAULT_FIELDS = {
Expand Down Expand Up @@ -86,3 +90,17 @@ 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())

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"]
Loading