Commit 38be11a3 authored by Grand Francois's avatar Grand Francois
Browse files

#45 implémentation de l'import de résultat (valeur unique)

- Nub implémente IReferencedObject
- ParamDefinition implémente IObjectReference à la place de ParamValues
- tests unitaires liant un paramètre à un autre dont la valeur est calculée
Showing with 291 additions and 104 deletions
+291 -104
......@@ -8,56 +8,189 @@
import { NubTest, NubTestParams } from "../nubtest";
import { precDigits } from "../test_config";
import { ParamValueMode } from "../../src";
let nub1: NubTest;
let nub2: NubTest;
let prm1: NubTestParams;
let prm2: NubTestParams;
/**
* crée l'environnement de test.
* répété dans à chaque test car il manque un mock de beforeEach
*/
function createEnv() {
// Nub maître (dont on référence la valeur du paramètre A)
nub1 = new NubTest(new NubTestParams());
prm1 = nub1.parameters as NubTestParams;
// Nub esclave (qui utilise la valeur de A du Nub maître)
nub2 = new NubTest(new NubTestParams());
prm2 = nub2.parameters as NubTestParams;
}
describe("tests ValueReference : ", () => {
beforeEach(() => {
// Nub maître (dont on référence la valeur du paramètre A)
nub1 = new NubTest(new NubTestParams());
prm1 = nub1.parameters as NubTestParams;
// Nub esclave (qui utilise la valeur de A du Nub maître)
nub2 = new NubTest(new NubTestParams());
prm2 = nub2.parameters as NubTestParams;
});
describe("classe ParamValues : ", () => {
it("test 1", () => {
// cas de figure :
// nub2.A est lié à nub1.A (valeur fixe)
// lecture des valeurs de tous les paramètres
it("test 1", () => {
prm1.A.v = 1; // valeur maître
prm2.A.v = 0; // valeur esclave (doit être masquée par la valeur maître)
prm2.A.paramValues.referencedObject = prm1.A.paramValues;
createEnv();
expect(prm1.A.v).toEqual(1);
expect(prm2.A.v).toEqual(1);
});
prm2.A.v = 0; // valeur esclave, doit être masquée par la valeur maître (cad prm1.A, normalement 1)
prm2.A.defineReference(nub1, "A");
it('test 2', () => {
prm1.A.v = 2; // valeur maître
prm2.A.v = 0; // valeur esclave (doit être masquée par la valeur maître)
prm2.A.paramValues.referencedObject = prm1.A.paramValues;
expect(prm1.A.v).toEqual(1);
expect(prm1.B.v).toEqual(2);
expect(prm1.C.v).toEqual(3);
expect(prm2.A.v).toEqual(1);
expect(prm2.B.v).toEqual(2);
expect(prm2.C.v).toEqual(3);
});
expect(nub1.Calc("C").vCalc).toBeCloseTo(4, precDigits);
expect(nub2.Calc("C").vCalc).toBeCloseTo(4, precDigits);
});
it("test 2", () => {
// cas de figure :
// nub2.B est lié à nub1.B (valeur fixe)
// lecture des valeurs de tous les paramètres
createEnv();
prm2.B.v = 0; // valeur esclave, doit être masquée par la valeur maître (cad prm1.B, normalement 2)
prm2.B.defineReference(nub1, "B");
expect(prm1.A.v).toEqual(1);
expect(prm1.B.v).toEqual(2);
expect(prm1.C.v).toEqual(3);
expect(prm2.A.v).toEqual(1);
expect(prm2.B.v).toEqual(2);
expect(prm2.C.v).toEqual(3);
});
it("test 3", () => {
// cas de figure :
// nub2.C est lié à nub1.C (valeur fixe)
// lecture des valeurs de tous les paramètres
createEnv();
prm2.C.v = 0; // valeur esclave, doit être masquée par la valeur maître (cad prm1.C, normalement 3)
prm2.C.defineReference(nub1, "C");
expect(prm1.A.v).toEqual(1);
expect(prm1.B.v).toEqual(2);
expect(prm1.C.v).toEqual(3);
expect(prm2.A.v).toEqual(1);
expect(prm2.B.v).toEqual(2);
expect(prm2.C.v).toEqual(3);
});
it('test 4', () => {
// cas de figure :
// nub2.A est lié à nub1.A (valeur fixe)
// calcul de tous les paramètres
createEnv();
prm2.A.v = 0; // valeur esclave, doit être masquée par la valeur maître (cad prm1.A, normalement 1)
prm2.A.defineReference(nub1, "A");
expect(nub1.Calc("A").vCalc).toBeCloseTo(1, precDigits);
expect(nub1.Calc("B").vCalc).toBeCloseTo(2, precDigits);
expect(nub1.Calc("C").vCalc).toBeCloseTo(3, precDigits);
expect(nub2.Calc("A").vCalc).toBeCloseTo(1, precDigits);
expect(nub2.Calc("B").vCalc).toBeCloseTo(2, precDigits);
expect(nub2.Calc("C").vCalc).toBeCloseTo(3, precDigits);
});
it('test 3', () => {
prm1.B.v = 3; // valeur maître
prm2.B.v = 0; // valeur esclave (doit être masquée par la valeur maître)
prm2.B.paramValues.referencedObject = prm1.B.paramValues;
it('test 5', () => {
// cas de figure :
// nub2.B est lié à nub1.B (valeur fixe)
// calcul de tous les paramètres
expect(nub1.Calc("A").vCalc).toBeCloseTo(0, precDigits);
expect(nub2.Calc("A").vCalc).toBeCloseTo(0, precDigits);
createEnv();
prm1.B.v = 3; // valeur maître
prm2.B.v = 0; // valeur esclave (doit être masquée par la valeur maître)
prm2.B.defineReference(nub1, "B");
expect(nub1.Calc("A").vCalc).toBeCloseTo(0, precDigits);
expect(nub1.Calc("B").vCalc).toBeCloseTo(3, precDigits);
expect(nub1.Calc("C").vCalc).toBeCloseTo(3, precDigits);
expect(nub2.Calc("A").vCalc).toBeCloseTo(0, precDigits);
expect(nub2.Calc("B").vCalc).toBeCloseTo(3, precDigits);
expect(nub2.Calc("C").vCalc).toBeCloseTo(3, precDigits);
});
it('test 6', () => {
// cas de figure :
// nub2.C est lié à nub1.C (valeur fixe)
// calcul de tous les paramètres
createEnv();
prm2.C.v = 0; // valeur esclave, doit être masquée par la valeur maître (cad prm1.C, normalement 3)
prm2.C.defineReference(nub1, "C");
expect(nub1.Calc("A").vCalc).toBeCloseTo(1, precDigits);
expect(nub1.Calc("B").vCalc).toBeCloseTo(2, precDigits);
expect(nub1.Calc("C").vCalc).toBeCloseTo(3, precDigits);
expect(nub2.Calc("A").vCalc).toBeCloseTo(1, precDigits);
expect(nub2.Calc("B").vCalc).toBeCloseTo(2, precDigits);
expect(nub2.Calc("C").vCalc).toBeCloseTo(3, precDigits);
});
});
it('test 4', () => {
prm1.C.v = 4; // valeur maître
prm2.C.v = 0; // valeur esclave (doit être masquée par la valeur maître)
prm2.C.paramValues.referencedObject = prm1.C.paramValues;
describe("classe Result : ", () => {
it('test 1', () => {
// cas de figure :
// nub2.A est lié à nub1.C (valeur calculée)
// lecture de nub2.A
createEnv();
// Nub maître
nub1 = new NubTest(new NubTestParams());
prm1 = nub1.parameters as NubTestParams;
// Nub esclave
nub2 = new NubTest(new NubTestParams());
prm2 = nub2.parameters as NubTestParams;
prm1.C.v = 10; // valeur maître bidon
prm1.C.paramValues.valueMode = ParamValueMode.CALCUL;
prm2.A.v = 0; // valeur esclave (doit être masquée par la valeur maître, cad prm1.C, normalement 3)
prm2.A.defineReference(nub1, "C");
expect(prm2.A.v).toBeCloseTo(3, precDigits);
});
it('test 2', () => {
// cas de figure :
// nub2.A est lié à nub1.C (valeur calculée)
// calcul de nub2.C
createEnv();
// Nub maître
nub1 = new NubTest(new NubTestParams());
prm1 = nub1.parameters as NubTestParams;
// Nub esclave
nub2 = new NubTest(new NubTestParams());
prm2 = nub2.parameters as NubTestParams;
prm1.C.v = 0; // valeur bidon, doit être 3 après calcul
prm1.C.paramValues.valueMode = ParamValueMode.CALCUL;
prm2.C.v = 0; // valeur bidon, doit être 5 après calcul
prm2.A.v = 0; // valeur esclave bidon, doit être masquée par la valeur maître (cad prm1.C, normalement 3)
prm2.A.defineReference(nub1, "C");
expect(nub1.Calc("B").vCalc).toBeCloseTo(3, precDigits);
expect(nub2.Calc("B").vCalc).toBeCloseTo(3, precDigits);
expect(nub2.Calc("C").vCalc).toBeCloseTo(5, precDigits);
});
});
});
......@@ -4,11 +4,12 @@ import { ComputeNode } from "./compute-node";
import { Result } from "./util/result";
import { ParamValues, ParamValueMode } from "./param/param-values";
import { ParamDefinition } from ".";
import { IReferencedObject } from "./value_ref/object_ref";
/**
* Classe abstraite de Noeud de calcul : classe de base pour tous les calculs
*/
export abstract class Nub extends ComputeNode {
export abstract class Nub extends ComputeNode implements IReferencedObject {
private _dichoStartIntervalMaxSteps: number = 100;
/**
......@@ -144,4 +145,36 @@ export abstract class Nub extends ComputeNode {
public get result(): Result {
return this._result;
}
// interface IReferencedObject
/**
* getter de la (des) valeurs référencées
*/
public getReferencedValues(desc: string): number[] {
const p: ParamDefinition = this.getParameter(desc);
if (p !== undefined) {
switch (p.valueMode) {
case ParamValueMode.CALCUL:
{
this.CalcSerie(0.001, 0.1, p.symbol);
const res: number[] = [];
for (const re of this._result.resultElements)
res.push(re.vCalc);
return res;
}
case ParamValueMode.LINK:
return p.referencedValues;
default:
const res: number[] = [];
for (const v of p.paramValues.getValuesIterator())
res.push(v);
return res;
}
}
throw new Error(`Nub : appel à IReferencedObject.getReferencedValues('${desc}') invalide`);
}
}
......@@ -2,6 +2,8 @@ import { Message, MessageCode } from "../util/message";
import { BaseParam } from "./param-base";
import { ParamDomain, ParamDomainValue } from "./param-domain";
import { ParamValueMode } from "./param-values";
import { IReferencedObject, IObjectReference, ObjectReference } from "../value_ref/object_ref";
/**
* calculabilité du paramètre
......@@ -32,19 +34,34 @@ export enum ParamCalculability {
* définition d'un paramètre d'un noeud de calcul
*/
// tslint:disable-next-line:max-classes-per-file
export class ParamDefinition extends BaseParam {
export class ParamDefinition extends BaseParam implements IObjectReference {
/**
* calculabilité
*/
private _calc: ParamCalculability;
/**
* implémentation par délégation de IObjectReference
*/
private _valueRef: ObjectReference;
constructor(s: string, d: ParamDomain | ParamDomainValue, val?: number) {
super(s, d, val);
this._valueRef = new ObjectReference();
this._calc = ParamCalculability.FREE;
}
get v(): number {
return super.getValue();
switch (this.valueMode) {
case ParamValueMode.SINGLE:
return super.getValue();
case ParamValueMode.LINK:
return this._valueRef.referencedValues[0];
default:
throw new Error(`mode de valeur ${ParamValueMode[this.valueMode]} invalide`);
}
}
set v(val: number) {
......@@ -87,4 +104,18 @@ export class ParamDefinition extends BaseParam {
res._calc = this._calc;
return res;
}
// interface IObjectReference
public defineReference(target: IReferencedObject, desc: string) {
this.paramValues.valueMode = ParamValueMode.LINK;
this._valueRef.defineReference(target, desc);
}
/**
* valeurs de l'objet IReferencedObject référencé
*/
public get referencedValues(): number[] {
return this._valueRef.referencedValues;
}
}
import { Pair } from "../util/pair"
import { DefinedNumber } from "../util/definedvalue";
import { IReferencedObject, IObjectReference, ObjectReference } from "../object_ref";
import { IReferencedObject, IObjectReference, ObjectReference } from "../value_ref/object_ref";
import { JalhydObject } from "../jalhyd_object";
/**
......@@ -180,7 +180,7 @@ export class ParamValueIterator implements IterableIterator<number> {
}
}
export class ParamValues extends JalhydObject implements IReferencedObject, IObjectReference {
export class ParamValues {
/**
* mode de génération des valeurs : min/max, liste, ...
*/
......@@ -216,15 +216,8 @@ export class ParamValues extends JalhydObject implements IReferencedObject, IObj
*/
private _iterator: ParamValueIterator;
/**
* implémentation par délégation de IObjectReference
*/
private _valueRef: ObjectReference;
constructor() {
super();
this._singleValue = new DefinedNumber();
this._valueRef = new ObjectReference();
}
public setValues(o: number | any, max?: number, step?: number) {
......@@ -283,12 +276,8 @@ export class ParamValues extends JalhydObject implements IReferencedObject, IObj
throw new Error(`ParamValues : liste de valeurs non définie`);
break;
case ParamValueMode.CALCUL:
break;
case ParamValueMode.LINK:
if (this.referencedObject instanceof ParamValues)
this.referencedObject.check();
case ParamValueMode.CALCUL:
break;
default:
......@@ -297,16 +286,7 @@ export class ParamValues extends JalhydObject implements IReferencedObject, IObj
}
public get singleValue() {
switch (this.valueMode) {
case ParamValueMode.SINGLE:
return this._singleValue.value;
case ParamValueMode.LINK:
return this._valueRef.referencedObject.values[0];
default:
throw new Error(`mode de valeur ${ParamValueMode[this.valueMode]} invalide`);
}
return this._singleValue.value;
}
public get uncheckedValue() {
......@@ -405,46 +385,4 @@ export class ParamValues extends JalhydObject implements IReferencedObject, IObj
this._singleValue.value = this._iterator.next().value;
return this._singleValue.value;
}
// interface IReferencedObject
/**
* getter de la (des) valeurs référencées
*/
public get values(): number[] {
const res: number[] = [];
for (const v of this.getValuesIterator())
res.push(v);
return res;
}
// interface IObjectReference
/**
* référence à l'objet pointé sous forme symbolique
* exemples : <uid calculette>.Q, <uid calculette>.<ouvrage>.Z1
*/
public get refDefinition(): string {
return this._valueRef.refDefinition;
}
public set refDefinition(def: string) {
this._valueRef.refDefinition = def;
}
/**
* valeurs de l'objet IReferencedObject référencé
*/
public get referencedValues(): number[] {
return this._valueRef.referencedValues;
}
/**
* MAJ de l'objet référencé
*/
public set referencedObject(rv: IReferencedObject) {
this.valueMode = ParamValueMode.LINK;
this._valueRef.referencedObject = rv;
}
}
import { IJalhydObject } from "./jalhyd_object";
import { ParamValues } from ".";
/**
* objet (paramètre ou résultat) dont les valeurs sont référençables pour réutilisation
* (d'une calculette sur une autre par ex)
*/
export interface IReferencedObject extends IJalhydObject {
export interface IReferencedObject {
/**
* getter de la (des) valeurs
*/
readonly values: number[];
getReferencedValues(desc?: string): number[];
}
/**
......@@ -17,10 +14,11 @@ export interface IReferencedObject extends IJalhydObject {
*/
export interface IObjectReference {
/**
* référence à l'objet pointé sous forme symbolique
* exemples : <uid calculette>.Q, <uid calculette>.<n° d'ouvrage>.Z1
* définition de l'objet référencé
* @param target objet contenant la valeur qu'on va référencer
* @param desc : description de la valeur pointée sous forme symbolique. Exemples : Q, <n° d'ouvrage>.Z1
*/
refDefinition: string;
defineReference(target: IReferencedObject, desc: string): void;
/**
* valeurs de l'objet IReferencedObject référencé
......@@ -37,18 +35,12 @@ export class ObjectReference implements IObjectReference {
private _refDefinition: string;
public get referencedValues(): number[] {
return this._referencedObject.values;
}
public get refDefinition(): string {
return this._refDefinition;
return this._referencedObject.getReferencedValues(this._refDefinition);
}
public set refDefinition(def: string) {
// RAZ de l'objet référencé
if (this._refDefinition !== def)
this._referencedObject = undefined;
this._refDefinition = def;
public defineReference(target: IReferencedObject, desc: string) {
this._referencedObject = target;
this._refDefinition = desc;
}
/**
......@@ -57,11 +49,4 @@ export class ObjectReference implements IObjectReference {
public get referencedObject(): IReferencedObject {
return this._referencedObject;
}
/**
* MAJ de l'objet référencé
*/
public set referencedObject(rv: IReferencedObject) {
this._referencedObject = rv;
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment