From b743ae1749d93b179798d817e394632665db4ff5 Mon Sep 17 00:00:00 2001
From: "mathias.chouet" <mathias.chouet@irstea.fr>
Date: Fri, 31 Jul 2020 15:10:35 +0200
Subject: [PATCH] Fix #255 - results with family undefined are now linkable to
 parameters with family ANY

---
 spec/math/spp.spec.ts                         |  4 +--
 spec/math/trigo.spec.ts                       |  4 +--
 spec/math/yaxb.spec.ts                        |  8 +++---
 .../value_ref_Dever_Structures.spec.ts        | 28 +++++++++++++++++++
 src/nub.ts                                    |  8 ++++--
 src/param/param-definition.ts                 | 10 +++++--
 src/structure/structure.ts                    |  8 +++++-
 7 files changed, 56 insertions(+), 14 deletions(-)
 create mode 100644 spec/value_ref/value_ref_Dever_Structures.spec.ts

diff --git a/spec/math/spp.spec.ts b/spec/math/spp.spec.ts
index 21c75314..30264ce6 100644
--- a/spec/math/spp.spec.ts
+++ b/spec/math/spp.spec.ts
@@ -83,12 +83,12 @@ describe("Class SPP: ", () => {
 
             // SPP.Y should be linkable to all ParallelStructures params
             const lpY = Session.getInstance().getLinkableValues(spp.prms.Y);
-            expect(lpY.length).toBe(7);
+            expect(lpY.length).toBe(8);
 
             // all 3 YAXN.X should be linkable to all ParallelStructures params
             for (const c of spp.getChildren()) {
                 const lp = Session.getInstance().getLinkableValues((c as YAXN).prms.X);
-                expect(lp.length).toBe(13); // 7, plus siblings params
+                expect(lp.length).toBe(14); // 8, plus siblings params
             }
 
             // each ParallelStructures param should be linkable to SPP.Y and all 3 YAXN.X
diff --git a/spec/math/trigo.spec.ts b/spec/math/trigo.spec.ts
index a12b4b19..4d0afb31 100644
--- a/spec/math/trigo.spec.ts
+++ b/spec/math/trigo.spec.ts
@@ -157,8 +157,8 @@ describe("Class Trigo: ", () => {
             Session.getInstance().registerNubs([ trig, lo ]);
 
             // each Trigo param should be linkable to all ParallelStructures params
-            expect(Session.getInstance().getLinkableValues(trig.prms.Y).length).toBe(7);
-            expect(Session.getInstance().getLinkableValues(trig.prms.X).length).toBe(7);
+            expect(Session.getInstance().getLinkableValues(trig.prms.Y).length).toBe(8);
+            expect(Session.getInstance().getLinkableValues(trig.prms.X).length).toBe(8);
 
             // each ParallelStructures param should be linkable to all Trigo params
             for (const p of lo.parameterIterator) {
diff --git a/spec/math/yaxb.spec.ts b/spec/math/yaxb.spec.ts
index f9d96472..737b266d 100644
--- a/spec/math/yaxb.spec.ts
+++ b/spec/math/yaxb.spec.ts
@@ -70,10 +70,10 @@ describe("Class YAXB: ", () => {
             Session.getInstance().registerNubs([ yaxb, lo ]);
 
             // each YAXB param should be linkable to all ParallelStructures params
-            expect(Session.getInstance().getLinkableValues(yaxb.prms.Y).length).toBe(7);
-            expect(Session.getInstance().getLinkableValues(yaxb.prms.A).length).toBe(7);
-            expect(Session.getInstance().getLinkableValues(yaxb.prms.X).length).toBe(7);
-            expect(Session.getInstance().getLinkableValues(yaxb.prms.B).length).toBe(7);
+            expect(Session.getInstance().getLinkableValues(yaxb.prms.Y).length).toBe(8);
+            expect(Session.getInstance().getLinkableValues(yaxb.prms.A).length).toBe(8);
+            expect(Session.getInstance().getLinkableValues(yaxb.prms.X).length).toBe(8);
+            expect(Session.getInstance().getLinkableValues(yaxb.prms.B).length).toBe(8);
 
             // each ParallelStructures param should be linkable to all YAXB params
             for (const p of lo.parameterIterator) {
diff --git a/spec/value_ref/value_ref_Dever_Structures.spec.ts b/spec/value_ref/value_ref_Dever_Structures.spec.ts
new file mode 100644
index 00000000..020a6c1d
--- /dev/null
+++ b/spec/value_ref/value_ref_Dever_Structures.spec.ts
@@ -0,0 +1,28 @@
+import { Session } from "../../src/session";
+import { DeverParams } from "../../src/structure/dever_params";
+import { LoiDebit } from "../../src/structure/structure_props";
+import { Dever } from "../../src/structure/dever";
+import { CreateStructure } from "../../src/structure/factory_structure";
+import { YAXBParams } from "../../src/math/yaxb_params";
+import { YAXB } from "../../src/math/yaxb";
+
+describe("Dever and Structures", () => {
+
+    it("Dever results with family undefined, and Structure flow Q, should be linkable to param with family ANY", () => {
+        const dever = new Dever(new DeverParams(0.5, 102, 10, 99));
+        const s1 = CreateStructure(LoiDebit.RectangularOrificeFree, dever);
+        dever.addChild(s1);
+        const affine = new YAXB(new YAXBParams(0, 1, 2, 3));
+        Session.getInstance().clear();
+        Session.getInstance().registerNubs([ dever, affine ]);
+
+        const axlp = Session.getInstance().getLinkableValues(affine.prms.X);
+        expect(axlp.length).toBe(12); // Q, Z1, BR, ZR (params) + V, Ec, Cv (results) + ZDV, W, L CdGR (structure params) + Q (structure result)
+        expect(axlp.map((p) => p.symbol)).toEqual([ "Q", "Z1", "BR", "ZR", "V", "Ec", "Cv", "ZDV", "W", "L", "CdGR", "Q" ]);
+    });
+
+    xit("Structure flow Q in PreBarrage should (not ?) be linkable", () => {
+        // @TODO
+    });
+
+});
diff --git a/src/nub.ts b/src/nub.ts
index ee08e1b0..80ac04a6 100644
--- a/src/nub.ts
+++ b/src/nub.ts
@@ -716,9 +716,11 @@ export abstract class Nub extends ComputeNode implements IObservable {
                         const erFamily = this._resultsFamilies[erSymbol];
                         // if family is identical or ANY, and variability doesn't cause any problem
                         if (
-                            erFamily !== undefined
-                            && (
-                                erFamily === src.family
+                            (
+                                ( // both families cannot be undefined
+                                    erFamily === src.family
+                                    && erFamily !== undefined
+                                )
                                 || erFamily === ParamFamily.ANY
                                 || src.family === ParamFamily.ANY
                             )
diff --git a/src/param/param-definition.ts b/src/param/param-definition.ts
index b05038ca..62690805 100644
--- a/src/param/param-definition.ts
+++ b/src/param/param-definition.ts
@@ -766,8 +766,14 @@ export class ParamDefinition implements INamedIterableValues, IObservable {
             // 1. extra result ?
             // - start here to avoid extra results being presented as
             // parameters by the iterator internally used by nub.getParameter()
-            // - extra results with no family are not linkable
-            if (Object.keys(nub.resultsFamilies).includes(symbol) && nub.resultsFamilies[symbol] !== undefined) {
+            // - extra results with no family are linkable only if linking parameter family is ANY
+            if (
+                Object.keys(nub.resultsFamilies).includes(symbol)
+                && (
+                    nub.resultsFamilies[symbol] !== undefined
+                    || this._family === ParamFamily.ANY
+                )
+            ) {
                 this._referencedValue = new LinkedValue(nub, undefined, symbol);
             } else {
                 // 2. is it a parameter (possibly in CALC mode) ?
diff --git a/src/structure/structure.ts b/src/structure/structure.ts
index d1c9351b..ad090a6e 100644
--- a/src/structure/structure.ts
+++ b/src/structure/structure.ts
@@ -1,6 +1,6 @@
 import { ChildNub } from "../child_nub";
 import { CalculatorType } from "../compute-node";
-import { ParamCalculability, ParamDefinition } from "../param/param-definition";
+import { ParamCalculability, ParamDefinition, ParamFamily } from "../param/param-definition";
 import { Props } from "../props";
 import { Message, MessageCode } from "../util/message";
 import { Result } from "../util/result";
@@ -330,4 +330,10 @@ export abstract class Structure extends ChildNub {
         }
     }
 
+    protected exposeResults() {
+        this._resultsFamilies = {
+            Q: ParamFamily.FLOWS
+        };
+    }
+
 }
-- 
GitLab