From 2451a9668fdf96b2fdb7a125d11e7754ab23b874 Mon Sep 17 00:00:00 2001
From: "mathias.chouet" <mathias.chouet@irstea.fr>
Date: Mon, 29 Jul 2019 14:08:23 +0200
Subject: [PATCH] Fix #121 - serialize enum keys rather than values

---
 .../remous_rect_euler_pentefaible.spec.ts     |  3 +-
 .../remous_rect_euler_penteforte.spec.ts      |  3 +-
 .../remous_rect_rk4_pentefaible.spec.ts       |  3 +-
 .../remous/remous_rect_rk4_penteforte.spec.ts |  5 ++-
 .../remous_rect_trapezes_pentefaible.spec.ts  |  3 +-
 .../remous_rect_trapezes_penteforte.spec.ts   |  3 +-
 spec/remous/remous_trapez.spec.ts             |  3 +-
 spec/remous/test-remous-fenetre.ts            |  2 +-
 spec/session/serialisation.spec.ts            |  5 ++-
 src/base.ts                                   | 10 +++--
 src/config.ts                                 |  2 +-
 src/index.ts                                  |  3 +-
 src/nub.ts                                    |  6 ++-
 src/pab/pab.ts                                |  4 +-
 src/remous/methode-resolution.ts              |  3 ++
 src/{ => remous}/remous.ts                    | 31 ++++++-------
 src/session.ts                                | 44 ++++++++++++++++---
 17 files changed, 92 insertions(+), 41 deletions(-)
 create mode 100644 src/remous/methode-resolution.ts
 rename src/{ => remous}/remous.ts (95%)

diff --git a/spec/remous/remous_rect_euler_pentefaible.spec.ts b/spec/remous/remous_rect_euler_pentefaible.spec.ts
index 5235f80a..6faefd3e 100644
--- a/spec/remous/remous_rect_euler_pentefaible.spec.ts
+++ b/spec/remous/remous_rect_euler_pentefaible.spec.ts
@@ -6,7 +6,8 @@
  */
 // import { describe, expect, it, xdescribe, xit } from "../mock_jasmine";
 
-import { CourbeRemous, CourbeRemousParams, MethodeResolution } from "../../src/remous";
+import { MethodeResolution } from "../../src/remous/methode-resolution";
+import { CourbeRemous, CourbeRemousParams } from "../../src/remous/remous";
 import { cSnRectang, ParamsSectionRectang } from "../../src/section/section_rectang";
 import { cLog } from "../../src/util/log";
 import { Message, MessageCode } from "../../src/util/message";
diff --git a/spec/remous/remous_rect_euler_penteforte.spec.ts b/spec/remous/remous_rect_euler_penteforte.spec.ts
index 4101afb6..c3ee3da1 100644
--- a/spec/remous/remous_rect_euler_penteforte.spec.ts
+++ b/spec/remous/remous_rect_euler_penteforte.spec.ts
@@ -1,4 +1,5 @@
-import { CourbeRemous, CourbeRemousParams, MethodeResolution } from "../../src/remous";
+import { MethodeResolution } from "../../src/remous/methode-resolution";
+import { CourbeRemous, CourbeRemousParams } from "../../src/remous/remous";
 import { cSnRectang, ParamsSectionRectang } from "../../src/section/section_rectang";
 import { cLog } from "../../src/util/log";
 import { Message, MessageCode } from "../../src/util/message";
diff --git a/spec/remous/remous_rect_rk4_pentefaible.spec.ts b/spec/remous/remous_rect_rk4_pentefaible.spec.ts
index 5c1afbee..09f07a65 100644
--- a/spec/remous/remous_rect_rk4_pentefaible.spec.ts
+++ b/spec/remous/remous_rect_rk4_pentefaible.spec.ts
@@ -1,4 +1,5 @@
-import { CourbeRemous, CourbeRemousParams, MethodeResolution } from "../../src/remous";
+import { MethodeResolution } from "../../src/remous/methode-resolution";
+import { CourbeRemous, CourbeRemousParams } from "../../src/remous/remous";
 import { cSnRectang, ParamsSectionRectang } from "../../src/section/section_rectang";
 import { cLog } from "../../src/util/log";
 import { Message, MessageCode } from "../../src/util/message";
diff --git a/spec/remous/remous_rect_rk4_penteforte.spec.ts b/spec/remous/remous_rect_rk4_penteforte.spec.ts
index 19475b8c..13b515cc 100644
--- a/spec/remous/remous_rect_rk4_penteforte.spec.ts
+++ b/spec/remous/remous_rect_rk4_penteforte.spec.ts
@@ -1,9 +1,10 @@
-import { CourbeRemous, CourbeRemousParams, MethodeResolution } from "../../src/remous";
+import { MethodeResolution } from "../../src/remous/methode-resolution";
+import { CourbeRemous, CourbeRemousParams } from "../../src/remous/remous";
 import { cSnRectang, ParamsSectionRectang } from "../../src/section/section_rectang";
 import { cLog } from "../../src/util/log";
 import { Message, MessageCode } from "../../src/util/message";
 import { precDist } from "../test_config";
-import { compareExtraResult, compareLog, equalEpsilon } from "../test_func";
+import { compareExtraResult, compareLog } from "../test_func";
 
 /*
    cas 1 :
diff --git a/spec/remous/remous_rect_trapezes_pentefaible.spec.ts b/spec/remous/remous_rect_trapezes_pentefaible.spec.ts
index 2f845221..720020a3 100644
--- a/spec/remous/remous_rect_trapezes_pentefaible.spec.ts
+++ b/spec/remous/remous_rect_trapezes_pentefaible.spec.ts
@@ -6,7 +6,8 @@
  */
 // import { describe, expect, it, xdescribe, xit } from "../mock_jasmine";
 
-import { CourbeRemous, CourbeRemousParams, MethodeResolution } from "../../src/remous";
+import { MethodeResolution } from "../../src/remous/methode-resolution";
+import { CourbeRemous, CourbeRemousParams } from "../../src/remous/remous";
 import { cSnRectang, ParamsSectionRectang } from "../../src/section/section_rectang";
 import { cLog } from "../../src/util/log";
 import { Message, MessageCode } from "../../src/util/message";
diff --git a/spec/remous/remous_rect_trapezes_penteforte.spec.ts b/spec/remous/remous_rect_trapezes_penteforte.spec.ts
index 08923433..9da0a480 100644
--- a/spec/remous/remous_rect_trapezes_penteforte.spec.ts
+++ b/spec/remous/remous_rect_trapezes_penteforte.spec.ts
@@ -1,4 +1,5 @@
-import { CourbeRemous, CourbeRemousParams, MethodeResolution } from "../../src/remous";
+import { MethodeResolution } from "../../src/remous/methode-resolution";
+import { CourbeRemous, CourbeRemousParams } from "../../src/remous/remous";
 import { cSnRectang, ParamsSectionRectang } from "../../src/section/section_rectang";
 import { cLog } from "../../src/util/log";
 import { Message, MessageCode } from "../../src/util/message";
diff --git a/spec/remous/remous_trapez.spec.ts b/spec/remous/remous_trapez.spec.ts
index 5bff6328..c2944082 100644
--- a/spec/remous/remous_trapez.spec.ts
+++ b/spec/remous/remous_trapez.spec.ts
@@ -6,7 +6,8 @@
  */
 // import { describe, expect, it, xdescribe, xit } from "../mock_jasmine";
 
-import { CourbeRemous, CourbeRemousParams, MethodeResolution } from "../../src/remous";
+import { MethodeResolution } from "../../src/remous/methode-resolution";
+import { CourbeRemous, CourbeRemousParams } from "../../src/remous/remous";
 import { cSnTrapez, ParamsSectionTrapez } from "../../src/section/section_trapez";
 import { precDist } from "../test_config";
 import { compareExtraResult } from "../test_func";
diff --git a/spec/remous/test-remous-fenetre.ts b/spec/remous/test-remous-fenetre.ts
index 80c556ae..f97afc47 100644
--- a/spec/remous/test-remous-fenetre.ts
+++ b/spec/remous/test-remous-fenetre.ts
@@ -1,5 +1,5 @@
 // // tslint:disable:no-console
-// import { CourbeRemous, CourbeRemousParams, MethodeResolution } from "../../src/remous";
+// import { CourbeRemous, CourbeRemousParams, MethodeResolution } from "../../src/remous/remous";
 // import { cSnRectang, ParamsSectionRectang } from "../../src/section/section_rectang";
 // import { equalEpsilon, compareArray } from "../test_func";
 // import { Result } from "../../src/util/result";
diff --git a/spec/session/serialisation.spec.ts b/spec/session/serialisation.spec.ts
index a5d2a0cc..075ac8f7 100644
--- a/spec/session/serialisation.spec.ts
+++ b/spec/session/serialisation.spec.ts
@@ -5,7 +5,8 @@ import { Cloisons } from "../../src/pab/cloisons";
 import { CloisonsParams } from "../../src/pab/cloisons_params";
 import { PabChute, PabChuteParams } from "../../src/pab/pab_chute";
 import { RegimeUniforme } from "../../src/regime_uniforme";
-import { CourbeRemous, CourbeRemousParams, MethodeResolution } from "../../src/remous";
+import { MethodeResolution } from "../../src/remous/methode-resolution";
+import { CourbeRemous, CourbeRemousParams } from "../../src/remous/remous";
 import { cSnCirc, ParamsSectionCirc } from "../../src/section/section_circulaire";
 import { cSnTrapez, ParamsSectionTrapez } from "../../src/section/section_trapez";
 import { Dever, DeverParams } from "../../src/structure/dever";
@@ -269,7 +270,7 @@ describe("nodeType property - ", () => {
         Session.getInstance().clear();
         Session.getInstance().registerNub(rem);
         const serialized = Session.getInstance().serialise();
-        expect(serialized).toContain('"nodeType":1');
+        expect(serialized).toContain('"nodeType":"SectionTrapeze"');
     });
 
     it("serialized Nub with no Section should not have a nodeType property", () => {
diff --git a/src/base.ts b/src/base.ts
index 9b0c9494..27737d11 100644
--- a/src/base.ts
+++ b/src/base.ts
@@ -56,10 +56,14 @@ export function round(val: number, prec: number) {
     return Math.round(val * m) / m;
 }
 
-export function isNumeric(s: string): boolean {
+export function isNumeric(s: any): boolean {
     if (s !== undefined && s !== null) {
-        const trimmed = s.trim();
-        return trimmed !== "" && !isNaN(Number(trimmed));
+        if (typeof s === "string") {
+            const trimmed = s.trim();
+            return trimmed !== "" && !isNaN(Number(trimmed));
+        } else if (typeof s === "number") {
+            return true;
+        }
     }
     return false;
 }
diff --git a/src/config.ts b/src/config.ts
index da7adf29..6e025e84 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -3,6 +3,6 @@
  */
 export const config = {
     serialisation: {
-        fileFormatVersion: "1.0"
+        fileFormatVersion: "1.1"
     }
 };
diff --git a/src/index.ts b/src/index.ts
index 9847dc69..608aa955 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -10,7 +10,8 @@ export * from "./compute-node";
 export * from "./nub";
 export * from "./session";
 export * from "./props";
-export * from "./remous";
+export * from "./remous/methode-resolution";
+export * from "./remous/remous";
 export * from "./section/section_parametree";
 export * from "./section/section_type";
 export * from "./section/section_trapez";
diff --git a/src/nub.ts b/src/nub.ts
index 27fc43ce..0a1ddbdf 100644
--- a/src/nub.ts
+++ b/src/nub.ts
@@ -863,7 +863,7 @@ export abstract class Nub extends ComputeNode implements IObservable {
     public objectRepresentation(extra?: object) {
         let ret: any = {
             uid: this.uid,
-            props: this.properties.props,
+            props: Session.invertEnumKeysAndValuesInProperties(this.properties.props),
         };
 
         if (extra) {
@@ -928,8 +928,10 @@ export abstract class Nub extends ComputeNode implements IObservable {
         // iterate over children if any
         if (obj.children && Array.isArray(obj.children)) {
             for (const s of obj.children) {
+                // decode properties
+                const props = Session.invertEnumKeysAndValuesInProperties(s.props, true);
                 // create the Nub
-                const subNub = Session.getInstance().createNub(new Props(s.props), this);
+                const subNub = Session.getInstance().createNub(new Props(props), this);
                 // try to keep the original ID
                 if (! Session.getInstance().uidAlreadyUsed(s.uid)) {
                     subNub.setUid(s.uid);
diff --git a/src/pab/pab.ts b/src/pab/pab.ts
index 8ec75c0f..1280334d 100644
--- a/src/pab/pab.ts
+++ b/src/pab/pab.ts
@@ -231,8 +231,10 @@ export class Pab extends Nub {
         const ret: { p: ParamDefinition, hasErrors: boolean } = super.loadObjectRepresentation(obj);
         // load downwall if any
         if (obj.downWall) {
+            // decode properties
+            const props = Session.invertEnumKeysAndValuesInProperties(obj.downWall.props);
             // create the Nub
-            const dw = Session.getInstance().createNub(new Props(obj.downWall.props), this) as CloisonAval;
+            const dw = Session.getInstance().createNub(new Props(props), this) as CloisonAval;
             // try to keep the original ID
             if (! Session.getInstance().uidAlreadyUsed(obj.downWall.uid)) {
                 dw.setUid(obj.downWall.uid);
diff --git a/src/remous/methode-resolution.ts b/src/remous/methode-resolution.ts
new file mode 100644
index 00000000..af858408
--- /dev/null
+++ b/src/remous/methode-resolution.ts
@@ -0,0 +1,3 @@
+export enum MethodeResolution {
+    Trapezes, EulerExplicite, RungeKutta4
+}
diff --git a/src/remous.ts b/src/remous/remous.ts
similarity index 95%
rename from src/remous.ts
rename to src/remous/remous.ts
index 84b8d565..fcf2074e 100644
--- a/src/remous.ts
+++ b/src/remous/remous.ts
@@ -1,20 +1,17 @@
-import { round, XOR } from "./base";
-import { CalculatorType } from "./compute-node";
-import { Dichotomie } from "./dichotomie";
-import { ParamCalculability, ParamDefinition, ParamFamily } from "./param/param-definition";
-import { ParamDomainValue } from "./param/param-domain";
-import { ParamValueMode } from "./param/param-value-mode";
-import { ParamValues } from "./param/param-values";
-import { ParamsEquation } from "./param/params-equation";
-import { SectionNub } from "./section/section_nub";
-import { acSection } from "./section/section_type";
-import { Message, MessageCode } from "./util/message";
-import { Result } from "./util/result";
-import { ResultElement } from "./util/resultelement";
-
-export enum MethodeResolution {
-    Trapezes, EulerExplicite, RungeKutta4
-}
+import { round, XOR } from "../base";
+import { CalculatorType } from "../compute-node";
+import { Dichotomie } from "../dichotomie";
+import { ParamCalculability, ParamDefinition, ParamFamily } from "../param/param-definition";
+import { ParamDomainValue } from "../param/param-domain";
+import { ParamValueMode } from "../param/param-value-mode";
+import { ParamValues } from "../param/param-values";
+import { ParamsEquation } from "../param/params-equation";
+import { SectionNub } from "../section/section_nub";
+import { acSection } from "../section/section_type";
+import { Message, MessageCode } from "../util/message";
+import { Result } from "../util/result";
+import { ResultElement } from "../util/resultelement";
+import { MethodeResolution } from "./methode-resolution";
 
 /**
  * paramètres pour les courbes de remous
diff --git a/src/session.ts b/src/session.ts
index a3c9427f..8e45b7ed 100644
--- a/src/session.ts
+++ b/src/session.ts
@@ -14,7 +14,7 @@ import { PabDimension, PabDimensionParams } from "./pab/pab_dimension";
 import { PabNombre, PabNombreParams } from "./pab/pab_nombre";
 import { PabPuissance, PabPuissanceParams } from "./pab/pab_puissance";
 import { RegimeUniforme } from "./regime_uniforme";
-import { CourbeRemous, CourbeRemousParams, MethodeResolution } from "./remous";
+import { CourbeRemous, CourbeRemousParams } from "./remous/remous";
 import { SectionParametree } from "./section/section_parametree";
 
 // Classes relatives aux sections
@@ -25,15 +25,17 @@ import { cSnTrapez, ParamsSectionTrapez } from "./section/section_trapez";
 import { acSection } from "./section/section_type";
 
 // Classes relatives aux structures
+import { isNumeric } from "./base";
 import { CloisonAval } from "./pab/cloison_aval";
 import { Cloisons } from "./pab/cloisons";
 import { CloisonsParams } from "./pab/cloisons_params";
 import { Pab, PabParams } from "./pab/pab";
 import { ParamDefinition } from "./param/param-definition";
+import { MethodeResolution } from "./remous/methode-resolution";
 import { Dever, DeverParams } from "./structure/dever";
 import { CreateStructure } from "./structure/factory_structure";
 import { ParallelStructure, ParallelStructureParams } from "./structure/parallel_structure";
-import { LoiDebit } from "./structure/structure_props";
+import { LoiDebit, StructureType } from "./structure/structure_props";
 
 export class Session {
 
@@ -44,6 +46,37 @@ export class Session {
         return Session._instance;
     }
 
+    /**
+     * Returns a copy of given map, inverting enum keys and values
+     */
+    public static invertEnumKeysAndValuesInProperties(stringProps: any, forceNumbers: boolean = false) {
+        const res = JSON.parse(JSON.stringify(stringProps)); // clone
+        // tslint:disable-next-line:forin
+        for (const k in res) {
+            if (!forceNumbers || !isNumeric(res[k])) {
+                switch (k) {
+                    case "calcType":
+                        res[k] = CalculatorType[res[k]];
+                        break;
+                    case "nodeType":
+                        res[k] = ComputeNodeType[res[k]];
+                        break;
+                    case "structureType":
+                        res[k] = StructureType[res[k]];
+                        break;
+                    case "loiDebit":
+                        res[k] = LoiDebit[res[k]];
+                        break;
+                    case "methodeResolution":
+                        res[k] = MethodeResolution[res[k]];
+                        break;
+                    // "varCalc" is not an enum
+                }
+            }
+        }
+        return res;
+    }
+
     /** instance pour le pattern singleton */
     private static _instance: Session;
 
@@ -390,7 +423,6 @@ export class Session {
 
             default: {
                     throw new Error(
-                        // tslint:disable-next-line:max-line-length
                         `Session.createNub() : type de module '${CalculatorType[calcType]}' non pris en charge`
                     );
                 }
@@ -534,12 +566,14 @@ export class Session {
             meta: undefined,
             hasErrors: false
         };
+        // decode properties
+        const props = Session.invertEnumKeysAndValuesInProperties(obj.props, true);
         // create the Nub
         let newNub;
         if (register) {
-            newNub = this.createSessionNub(new Props(obj.props));
+            newNub = this.createSessionNub(new Props(props));
         } else {
-            newNub = this.createNub(new Props(obj.props));
+            newNub = this.createNub(new Props(props));
         }
         // try to keep the original ID
         if (!this.uidAlreadyUsed(obj.uid)) {
-- 
GitLab