@open3cl/engine 1.6.0 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/10_besoin_fr.spec.js +122 -0
- package/10_clim.spec.js +116 -0
- package/11_besoin_ecs.spec.js +69 -0
- package/11_ecs.spec.js +282 -0
- package/11_nadeq.spec.js +37 -0
- package/12.4_pac.spec.js +131 -0
- package/13.2_generateur_combustion.js +2 -0
- package/13.2_generateur_combustion.spec.js +537 -0
- package/13.2_generateur_combustion_bouilleur.js +4 -1
- package/13.2_generateur_combustion_bouilleur.spec.js +74 -0
- package/13.2_generateur_combustion_ch.spec.js +323 -0
- package/13.2_generateur_combustion_chaudiere.spec.js +85 -0
- package/13.2_generateur_pac.spec.js +64 -0
- package/13_rendement_distribution_ecs.spec.js +38 -0
- package/14_generateur_ecs.js +4 -4
- package/14_generateur_ecs.spec.js +745 -0
- package/15_conso_aux.spec.js +225 -0
- package/16.2_production_enr.spec.js +188 -0
- package/16_conso_eclairage.spec.js +62 -0
- package/2021_04_13_confort_ete.spec.js +159 -0
- package/2021_04_13_qualite_isolation.js +1 -1
- package/2021_04_13_qualite_isolation.spec.js +286 -0
- package/3.1_b.js +1 -1
- package/3.1_b.spec.js +367 -0
- package/3.2.1_mur.spec.js +812 -39
- package/3.2.2_plancher_bas.spec.js +643 -78
- package/3.2.3_plancher_haut.spec.js +452 -0
- package/3.3.1.4_porte.spec.js +114 -0
- package/3.3_baie_vitree.spec.js +449 -295
- package/3.4_pont_thermique.spec.js +890 -0
- package/3_deperdition.spec.js +397 -0
- package/4_ventilation.js +1 -1
- package/4_ventilation.spec.js +406 -0
- package/5_conso_ventilation.spec.js +186 -0
- package/6.2_surface_sud_equivalente.spec.js +138 -0
- package/8_intermittence.spec.js +33 -0
- package/9_besoin_ch.js +2 -2
- package/9_besoin_ch.spec.js +381 -0
- package/9_chauffage.js +4 -0
- package/9_chauffage.spec.js +478 -92
- package/9_conso_ch.spec.js +502 -248
- package/9_emetteur_ch.spec.js +339 -0
- package/9_generateur_ch.spec.js +467 -81
- package/README.md +18 -9
- package/apport_et_besoin.spec.js +126 -0
- package/conso.js +1 -1
- package/conso.spec.js +471 -82
- package/core/assets/domain/add-additionnal-ue-values-tables.spec.js +53 -0
- package/core/assets/domain/synchronize-solicitations-tables.spec.js +25 -0
- package/core/assets/domain/synchronize-valeur-tables.spec.js +48 -0
- package/core/conf/infrastructure/application.config.spec.js +35 -0
- package/core/file/infrastructure/adapter/csv-parser.store.spec.js +31 -13
- package/core/file/infrastructure/adapter/file.store.spec.js +148 -12
- package/core/tv/infrastructure/assets/additional-ue-values.spec.js +36 -0
- package/core/util/infrastructure/object-util.spec.js +20 -0
- package/core/util/logger/log-service.js +16 -7
- package/core/util/logger/log-service.spec.js +101 -0
- package/dpe-sanitizer.service.spec.js +138 -0
- package/engine.js +7 -5
- package/engine.spec.js +854 -0
- package/enums.spec.js +46 -0
- package/features/dpe/domain/models/type-generateur.model.js +1 -2
- package/features/dpe/domain/models/type-generateur.model.spec.js +25 -0
- package/features/dpe/domain/models/type-habitation.model.spec.js +41 -0
- package/features/dpe/domain/models/type-stockage.model.spec.js +18 -0
- package/features/dpe/domain/models/type-ventilation.model.spec.js +19 -0
- package/features/dpe/infrastructure/ch/chTv.store.spec.js +4 -4
- package/features/dpe/infrastructure/enveloppe/baieVitreeTv.store.js +14 -2
- package/features/dpe/infrastructure/enveloppe/baieVitreeTv.store.spec.js +16 -0
- package/features/dpe/infrastructure/tv.store.js +28 -9
- package/features/dpe/infrastructure/tv.store.spec.js +44 -0
- package/features/engine/domain/apport_et_besoin/apport-et-besoin.service.spec.js +2 -1
- package/features/engine/domain/apport_et_besoin/ch/besoin-ch.service.spec.js +18 -0
- package/features/engine/domain/apport_et_besoin/ch/perte-ch-recup.service.spec.js +33 -1
- package/features/engine/domain/apport_et_besoin/ecs/besoin-ecs.service.spec.js +21 -1
- package/features/engine/domain/apport_et_besoin/ecs/perte-ecs-recup.service.spec.js +41 -1
- package/features/engine/domain/apport_et_besoin/froid/besoin-froid.service.spec.js +44 -1
- package/features/engine/domain/apport_et_besoin/surface-sud-equivalente.service.spec.js +2 -1
- package/features/engine/domain/ch/generateur-ch.service.js +2 -0
- package/features/engine/domain/ch/generateur-ch.service.spec.js +117 -2
- package/features/engine/domain/ch/installation-ch.service.spec.js +14 -0
- package/features/engine/domain/conso/froid/conso-froid.service.spec.js +82 -1
- package/features/engine/domain/constants.spec.js +14 -0
- package/features/engine/domain/contexte.builder.spec.js +21 -0
- package/features/engine/domain/ecs/generateur-ecs.service.spec.js +11 -0
- package/features/engine/domain/ecs/installation-ecs.service.spec.js +55 -2
- package/features/engine/domain/engine.service.spec.js +227 -4
- package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.spec.js +124 -1
- package/features/engine/domain/enveloppe/deperdition-enveloppe.service.spec.js +270 -2
- package/features/engine/domain/enveloppe/deperdition.service.spec.js +141 -0
- package/features/engine/domain/enveloppe/espace_tampon/espace-tampon.service.spec.js +2 -1
- package/features/engine/domain/enveloppe/mur/deperdition-mur.service.spec.js +117 -1
- package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.spec.js +134 -1
- package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.spec.js +126 -1
- package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.spec.js +18 -1
- package/features/engine/domain/enveloppe/porte/deperdition-porte.service.spec.js +2 -1
- package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.spec.js +67 -1
- package/features/normalizer/domain/dpe-normalizer.service.js +1 -1
- package/features/normalizer/domain/dpe-normalizer.service.spec.js +53 -2
- package/ficheTechnique.spec.js +26 -0
- package/index.spec.js +54 -0
- package/package.json +5 -2
- package/preprocessor/index.js +20 -0
- package/preprocessor/index.spec.js +15 -0
- package/tv.spec.js +38 -0
- package/utils.js +43 -1
- package/utils.spec.js +518 -2
- package/output.js +0 -1
|
@@ -1,89 +1,654 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Dépendances mockées pour isoler `calc_pb` :
|
|
5
|
+
* - `enums` : mapping minimal type d'adjacence / période de construction / période d'isolation ;
|
|
6
|
+
* - `b` (3.1_b.js) : simple espion (le coefficient b n'intervient pas dans le calcul de Upb ici) ;
|
|
7
|
+
* - `tv` : accès aux tables `upb0` / `upb` / `ue`, on contrôle la ligne retournée par table ;
|
|
8
|
+
* - `requestInput` : passe-plat renvoyant la donnée d'entrée demandée ;
|
|
9
|
+
* - `getKeyByValue` : implémentation déterministe (indépendante des vraies enums) ;
|
|
10
|
+
* - `getRange` : contrôlé par test pour fournir l'encadrement de Upb dans le calcul de Ue ;
|
|
11
|
+
* - `bug_for_bug_compat` : exposé via un getter afin de pouvoir le basculer par test.
|
|
12
|
+
*/
|
|
13
|
+
let bugForBugCompat = false;
|
|
14
|
+
|
|
15
|
+
vi.mock('./enums.js', () => ({
|
|
16
|
+
default: {
|
|
17
|
+
type_adjacence: {
|
|
18
|
+
5: 'terre-plein',
|
|
19
|
+
6: 'sous-sol non chauffé',
|
|
20
|
+
7: 'vide sanitaire',
|
|
21
|
+
8: 'extérieur'
|
|
22
|
+
},
|
|
23
|
+
periode_construction: { 1: 'avant 1948', 3: '1948-1974', 5: '1989-2000' },
|
|
24
|
+
periode_isolation: { 2: '1975-1977', 6: '2006-2012' }
|
|
25
|
+
}
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
vi.mock('./3.1_b.js', () => ({
|
|
29
|
+
default: vi.fn()
|
|
30
|
+
}));
|
|
31
|
+
|
|
32
|
+
vi.mock('./utils.js', () => ({
|
|
33
|
+
tv: vi.fn(),
|
|
34
|
+
requestInput: (de, du, field) => de[field],
|
|
35
|
+
getKeyByValue: (object, value) => Object.keys(object).find((key) => object[key] === value),
|
|
36
|
+
getRange: vi.fn(),
|
|
37
|
+
get bug_for_bug_compat() {
|
|
38
|
+
return bugForBugCompat;
|
|
39
|
+
}
|
|
40
|
+
}));
|
|
41
|
+
|
|
42
|
+
const { default: calc_pb } = await import('./3.2.2_plancher_bas.js');
|
|
43
|
+
const { tv, getRange } = await import('./utils.js');
|
|
44
|
+
|
|
45
|
+
/** Table `upb0` figée : U0 forfaitaire de la paroi nue. */
|
|
46
|
+
const ROW_UPB0 = { upb0: '2', tv_upb0_id: '9' };
|
|
47
|
+
/** Table `upb` figée : U forfaitaire de la paroi isolée. */
|
|
48
|
+
const ROW_UPB = { upb: '0.3', tv_upb_id: '2' };
|
|
49
|
+
|
|
50
|
+
beforeEach(() => {
|
|
51
|
+
bugForBugCompat = false;
|
|
52
|
+
tv.mockReset();
|
|
53
|
+
getRange.mockReset();
|
|
54
|
+
tv.mockImplementation((table) => {
|
|
55
|
+
if (table === 'upb0') return { ...ROW_UPB0 };
|
|
56
|
+
if (table === 'upb') return { ...ROW_UPB };
|
|
57
|
+
return null;
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 3.2.2 Coefficient de transmission des planchers bas (Upb)
|
|
63
|
+
* @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §3.2.2
|
|
64
|
+
*/
|
|
65
|
+
describe('calc_pb - plancher non isolé (methode 1)', () => {
|
|
66
|
+
test('Upb égal à Upb0 (paroi nue) et adjacence non déperditive => upb_final = upb', () => {
|
|
67
|
+
const pb = {
|
|
68
|
+
donnee_entree: {
|
|
69
|
+
enum_methode_saisie_u_id: '1',
|
|
70
|
+
methode_saisie_u0: 'type de paroi inconnu (valeur par défaut)',
|
|
71
|
+
enum_type_plancher_bas_id: '9',
|
|
72
|
+
type_adjacence: 'extérieur'
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
77
|
+
|
|
78
|
+
expect(pb.donnee_intermediaire.upb0).toBe(2);
|
|
79
|
+
expect(pb.donnee_intermediaire.upb).toBe(2);
|
|
80
|
+
expect(pb.donnee_intermediaire.upb_final).toBe(2);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('Upb0 initialisé depuis une donnée intermédiaire préexistante', () => {
|
|
84
|
+
const pb = {
|
|
85
|
+
donnee_entree: {
|
|
86
|
+
enum_methode_saisie_u_id: '1',
|
|
87
|
+
methode_saisie_u0: 'u0 non saisi car le u est saisi connu et justifié.',
|
|
88
|
+
type_adjacence: 'extérieur'
|
|
89
|
+
},
|
|
90
|
+
donnee_intermediaire: { upb0: 1.4 }
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
94
|
+
|
|
95
|
+
// 'u0 non saisi' ne recalcule pas Upb0 : la valeur préexistante est conservée
|
|
96
|
+
expect(pb.donnee_intermediaire.upb0).toBe(1.4);
|
|
97
|
+
expect(pb.donnee_intermediaire.upb).toBe(1.4);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('Upb0 introuvable dans la table : erreur émise', () => {
|
|
101
|
+
tv.mockReturnValue(null);
|
|
102
|
+
const error = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
103
|
+
const pb = {
|
|
104
|
+
donnee_entree: {
|
|
105
|
+
enum_methode_saisie_u_id: '1',
|
|
106
|
+
methode_saisie_u0:
|
|
107
|
+
'déterminé selon le matériau et épaisseur à partir de la table de valeur forfaitaire',
|
|
108
|
+
enum_type_plancher_bas_id: '9',
|
|
109
|
+
type_adjacence: 'extérieur'
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
114
|
+
|
|
115
|
+
expect(error).toHaveBeenCalledWith(expect.stringContaining('upb0'));
|
|
116
|
+
expect(pb.donnee_intermediaire.upb0).toBeUndefined();
|
|
117
|
+
error.mockRestore();
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
describe('calc_pb - calcul de Upb0 (calc_upb0)', () => {
|
|
122
|
+
test('saisie directe de Upb0 : valeur reprise depuis upb0_saisi sans accès table', () => {
|
|
123
|
+
const pb = {
|
|
124
|
+
donnee_entree: {
|
|
125
|
+
enum_methode_saisie_u_id: '1',
|
|
126
|
+
methode_saisie_u0:
|
|
127
|
+
'saisie direct u0 justifiée à partir des documents justificatifs autorisés',
|
|
128
|
+
upb0_saisi: 0.8,
|
|
129
|
+
type_adjacence: 'extérieur'
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
134
|
+
|
|
135
|
+
expect(tv).not.toHaveBeenCalled();
|
|
136
|
+
expect(pb.donnee_intermediaire.upb0).toBe(0.8);
|
|
137
|
+
expect(pb.donnee_intermediaire.upb).toBe(0.8);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
test('methode_saisie_u0 inconnue : avertissement émis', () => {
|
|
141
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
142
|
+
const pb = {
|
|
143
|
+
donnee_entree: {
|
|
144
|
+
enum_methode_saisie_u_id: '1',
|
|
145
|
+
methode_saisie_u0: 'valeur inexistante',
|
|
146
|
+
type_adjacence: 'extérieur'
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
151
|
+
|
|
152
|
+
expect(warn).toHaveBeenCalledWith('methode_saisie_u0 inconnue:', 'valeur inexistante');
|
|
153
|
+
warn.mockRestore();
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
describe('calc_pb - isolation par épaisseur / résistance', () => {
|
|
158
|
+
test.each([['3'], ['4']])(
|
|
159
|
+
"épaisseur d'isolation saisie (methode %s) : Upb = 1 / (1/Upb0 + e/0,042)",
|
|
160
|
+
(methode) => {
|
|
161
|
+
const pb = {
|
|
11
162
|
donnee_entree: {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
surface_paroi_opaque: 42.08,
|
|
18
|
-
tv_upb0_id: 11,
|
|
19
|
-
enum_type_plancher_bas_id: '11',
|
|
20
|
-
enum_methode_saisie_u0_id: '2',
|
|
21
|
-
enum_type_isolation_id: '4',
|
|
22
|
-
epaisseur_isolation: 5,
|
|
23
|
-
enum_methode_saisie_u_id: '3',
|
|
24
|
-
calcul_ue: 1,
|
|
25
|
-
perimetre_ue: 27,
|
|
26
|
-
surface_ue: 42.08,
|
|
27
|
-
ue: 0.37117494
|
|
28
|
-
},
|
|
29
|
-
donnee_intermediaire: {
|
|
30
|
-
b: 1,
|
|
31
|
-
upb: 0.5915492957746479,
|
|
32
|
-
upb_final: 0.37117494,
|
|
33
|
-
upb0: 2
|
|
163
|
+
enum_methode_saisie_u_id: methode,
|
|
164
|
+
methode_saisie_u0: 'type de paroi inconnu (valeur par défaut)',
|
|
165
|
+
enum_type_plancher_bas_id: '9',
|
|
166
|
+
epaisseur_isolation: '5',
|
|
167
|
+
type_adjacence: 'extérieur'
|
|
34
168
|
}
|
|
35
169
|
};
|
|
36
170
|
|
|
171
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
172
|
+
|
|
173
|
+
// Upb0 = 2 ; e = 5 * 0,01 = 0,05 m ; Upb = 1 / (1/2 + 0,05/0,042)
|
|
174
|
+
// valeur de référence de régression
|
|
175
|
+
expect(pb.donnee_intermediaire.upb).toBeCloseTo(0.5915492957746479, 9);
|
|
176
|
+
}
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
test.each([['5'], ['6']])(
|
|
180
|
+
"résistance d'isolation saisie (methode %s) : Upb = 1 / (1/Upb0 + R)",
|
|
181
|
+
(methode) => {
|
|
37
182
|
const pb = {
|
|
38
183
|
donnee_entree: {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
tv_upb0_id: 9,
|
|
45
|
-
enum_type_plancher_bas_id: '9', // Dalle béton
|
|
46
|
-
enum_methode_saisie_u0_id: '2', // déterminé selon le matériau et épaisseur à partir de la table de valeur forfaitaire
|
|
47
|
-
enum_type_isolation_id: '1', // inconnu
|
|
48
|
-
enum_periode_isolation_id: '1', // avant 1948
|
|
49
|
-
tv_upb_id: 2,
|
|
50
|
-
enum_methode_saisie_u_id: '8', // année de construction saisie (table forfaitaire)
|
|
51
|
-
calcul_ue: 1,
|
|
52
|
-
perimetre_ue: 22,
|
|
53
|
-
surface_ue: 24.34,
|
|
54
|
-
ue: 0.61789474
|
|
55
|
-
},
|
|
56
|
-
donnee_intermediaire: {
|
|
57
|
-
b: 1,
|
|
58
|
-
upb: 2,
|
|
59
|
-
upb_final: 0.61789474,
|
|
60
|
-
upb0: 2
|
|
184
|
+
enum_methode_saisie_u_id: methode,
|
|
185
|
+
methode_saisie_u0: 'type de paroi inconnu (valeur par défaut)',
|
|
186
|
+
enum_type_plancher_bas_id: '9',
|
|
187
|
+
resistance_isolation: '1',
|
|
188
|
+
type_adjacence: 'extérieur'
|
|
61
189
|
}
|
|
62
190
|
};
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
191
|
+
|
|
192
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
193
|
+
|
|
194
|
+
// Upb0 = 2 ; R = 1 ; Upb = 1 / (1/2 + 1)
|
|
195
|
+
// valeur de référence de régression
|
|
196
|
+
expect(pb.donnee_intermediaire.upb).toBeCloseTo(0.6666666666666666, 9);
|
|
197
|
+
}
|
|
198
|
+
);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
describe('calc_pb - isolation inconnue / table forfaitaire (methodes 2 et 7)', () => {
|
|
202
|
+
test("Upb = min(Upb table, Upb0) et la période d'isolation prime", () => {
|
|
203
|
+
const pb = {
|
|
204
|
+
donnee_entree: {
|
|
205
|
+
enum_methode_saisie_u_id: '2',
|
|
206
|
+
methode_saisie_u0: 'type de paroi inconnu (valeur par défaut)',
|
|
207
|
+
enum_type_plancher_bas_id: '9',
|
|
208
|
+
enum_periode_isolation_id: '6',
|
|
209
|
+
type_adjacence: 'extérieur'
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
214
|
+
|
|
215
|
+
// La période d'isolation renseignée est utilisée comme période de la table
|
|
216
|
+
expect(tv).toHaveBeenCalledWith(
|
|
217
|
+
'upb',
|
|
218
|
+
expect.objectContaining({ enum_periode_construction_id: '6' }),
|
|
219
|
+
pb.donnee_entree
|
|
220
|
+
);
|
|
221
|
+
// min(0,3 ; 2) = 0,3
|
|
222
|
+
expect(pb.donnee_intermediaire.upb).toBe(0.3);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
test("sans période d'isolation, la période de construction est utilisée", () => {
|
|
226
|
+
const pb = {
|
|
227
|
+
donnee_entree: {
|
|
228
|
+
enum_methode_saisie_u_id: '7',
|
|
229
|
+
methode_saisie_u0: 'type de paroi inconnu (valeur par défaut)',
|
|
230
|
+
enum_type_plancher_bas_id: '9',
|
|
231
|
+
type_adjacence: 'extérieur'
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
calc_pb(pb, 'h1a', '5', '0', [pb]);
|
|
236
|
+
|
|
237
|
+
expect(tv).toHaveBeenCalledWith(
|
|
238
|
+
'upb',
|
|
239
|
+
expect.objectContaining({ enum_periode_construction_id: '5' }),
|
|
240
|
+
pb.donnee_entree
|
|
241
|
+
);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
test('Upb introuvable dans la table forfaitaire : erreur émise', () => {
|
|
245
|
+
tv.mockImplementation((table) => (table === 'upb0' ? { ...ROW_UPB0 } : null));
|
|
246
|
+
const error = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
247
|
+
const pb = {
|
|
248
|
+
donnee_entree: {
|
|
249
|
+
enum_methode_saisie_u_id: '2',
|
|
250
|
+
methode_saisie_u0: 'type de paroi inconnu (valeur par défaut)',
|
|
251
|
+
enum_type_plancher_bas_id: '9',
|
|
252
|
+
type_adjacence: 'extérieur'
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
257
|
+
|
|
258
|
+
expect(error).toHaveBeenCalledWith(expect.stringContaining('upb'));
|
|
259
|
+
error.mockRestore();
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
describe('calc_pb - année de construction saisie (methode 8)', () => {
|
|
264
|
+
test("période d'isolation renseignée : elle est utilisée", () => {
|
|
265
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
266
|
+
const pb = {
|
|
267
|
+
donnee_entree: {
|
|
268
|
+
enum_methode_saisie_u_id: '8',
|
|
269
|
+
methode_saisie_u0: 'type de paroi inconnu (valeur par défaut)',
|
|
270
|
+
enum_type_plancher_bas_id: '9',
|
|
271
|
+
enum_periode_isolation_id: '6',
|
|
272
|
+
type_adjacence: 'extérieur'
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
calc_pb(pb, 'h1a', '5', '0', [pb]);
|
|
277
|
+
|
|
278
|
+
expect(tv).toHaveBeenCalledWith(
|
|
279
|
+
'upb',
|
|
280
|
+
expect.objectContaining({ enum_periode_construction_id: '6' }),
|
|
281
|
+
pb.donnee_entree
|
|
282
|
+
);
|
|
283
|
+
warn.mockRestore();
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
test.each([
|
|
287
|
+
['1', 'avant 1948'],
|
|
288
|
+
['3', '1948-1974']
|
|
289
|
+
])(
|
|
290
|
+
"construction ancienne (%s = %s) sans année d'isolation : isolation forcée à 1975-1977",
|
|
291
|
+
(pcId) => {
|
|
292
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
293
|
+
const pb = {
|
|
294
|
+
donnee_entree: {
|
|
295
|
+
enum_methode_saisie_u_id: '8',
|
|
296
|
+
methode_saisie_u0: 'type de paroi inconnu (valeur par défaut)',
|
|
297
|
+
enum_type_plancher_bas_id: '9',
|
|
298
|
+
type_adjacence: 'extérieur'
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
calc_pb(pb, 'h1a', pcId, '0', [pb]);
|
|
303
|
+
|
|
304
|
+
// getKeyByValue(periode_isolation, '1975-1977') = '2' (différent de pc_id) => avertissement
|
|
305
|
+
expect(tv).toHaveBeenCalledWith(
|
|
306
|
+
'upb',
|
|
307
|
+
expect.objectContaining({ enum_periode_construction_id: '2' }),
|
|
308
|
+
pb.donnee_entree
|
|
309
|
+
);
|
|
310
|
+
expect(warn).toHaveBeenCalled();
|
|
311
|
+
warn.mockRestore();
|
|
312
|
+
}
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
test('construction ancienne + bug_for_bug : second appel avec la période de construction', () => {
|
|
316
|
+
bugForBugCompat = true;
|
|
317
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
318
|
+
const error = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
319
|
+
// 1er appel (période 1975-1977) renvoie tv_upb_id = 2 ; l'appel avec la période de
|
|
320
|
+
// construction ('1') renvoie tv_upb_id = 3 (valeur différente => déclenche le recalcul).
|
|
321
|
+
tv.mockImplementation((table, matcher) => {
|
|
322
|
+
if (table === 'upb0') return { ...ROW_UPB0 };
|
|
323
|
+
if (table === 'upb') {
|
|
324
|
+
return {
|
|
325
|
+
upb: '0.3',
|
|
326
|
+
effet_joule: '0',
|
|
327
|
+
tv_upb_id: matcher.enum_periode_construction_id === '1' ? '3' : '2'
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
return null;
|
|
331
|
+
});
|
|
332
|
+
const pb = {
|
|
333
|
+
donnee_entree: {
|
|
334
|
+
enum_methode_saisie_u_id: '8',
|
|
335
|
+
methode_saisie_u0: 'type de paroi inconnu (valeur par défaut)',
|
|
336
|
+
enum_type_plancher_bas_id: '9',
|
|
337
|
+
type_adjacence: 'extérieur'
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
342
|
+
|
|
343
|
+
// L'avertissement de bascule d'année d'isolation est émis
|
|
344
|
+
expect(warn).toHaveBeenCalledWith(expect.stringContaining('Année d'));
|
|
345
|
+
// Le dernier appel forfaitaire utilise la période de construction d'origine ('1')
|
|
346
|
+
expect(tv).toHaveBeenLastCalledWith(
|
|
347
|
+
'upb',
|
|
348
|
+
expect.objectContaining({ enum_periode_construction_id: '1' }),
|
|
349
|
+
pb.donnee_entree
|
|
350
|
+
);
|
|
351
|
+
warn.mockRestore();
|
|
352
|
+
error.mockRestore();
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
test("construction récente sans année d'isolation : pas de forçage ni d'avertissement", () => {
|
|
356
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
357
|
+
const pb = {
|
|
358
|
+
donnee_entree: {
|
|
359
|
+
enum_methode_saisie_u_id: '8',
|
|
360
|
+
methode_saisie_u0: 'type de paroi inconnu (valeur par défaut)',
|
|
361
|
+
enum_type_plancher_bas_id: '9',
|
|
362
|
+
type_adjacence: 'extérieur'
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
calc_pb(pb, 'h1a', '5', '0', [pb]);
|
|
367
|
+
|
|
368
|
+
expect(tv).toHaveBeenCalledWith(
|
|
369
|
+
'upb',
|
|
370
|
+
expect.objectContaining({ enum_periode_construction_id: '5' }),
|
|
371
|
+
pb.donnee_entree
|
|
372
|
+
);
|
|
373
|
+
expect(warn).not.toHaveBeenCalled();
|
|
374
|
+
warn.mockRestore();
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
describe('calc_pb - saisie directe de Upb (methodes 9 et 10)', () => {
|
|
379
|
+
test.each([['9'], ['10']])('Upb pris depuis upb_saisi (methode %s)', (methode) => {
|
|
380
|
+
const pb = {
|
|
381
|
+
donnee_entree: {
|
|
382
|
+
enum_methode_saisie_u_id: methode,
|
|
383
|
+
upb_saisi: 0.22,
|
|
384
|
+
type_adjacence: 'extérieur'
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
389
|
+
|
|
390
|
+
expect(pb.donnee_intermediaire.upb).toBe(0.22);
|
|
391
|
+
});
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
describe('calc_pb - méthode de saisie de U inconnue', () => {
|
|
395
|
+
test('aucun calcul de Upb et avertissement émis', () => {
|
|
396
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
397
|
+
const pb = {
|
|
398
|
+
donnee_entree: {
|
|
399
|
+
enum_methode_saisie_u_id: '99',
|
|
400
|
+
type_adjacence: 'extérieur'
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
405
|
+
|
|
406
|
+
expect(warn).toHaveBeenCalledWith('methode_saisie_u inconnue:', 99);
|
|
407
|
+
warn.mockRestore();
|
|
408
|
+
});
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Compatibilité "bug for bug" : la méthode de saisie de U est forcée quand une donnée d'entrée
|
|
413
|
+
* (résistance, épaisseur ou Upb saisi) est présente mais incohérente avec la méthode déclarée.
|
|
414
|
+
*/
|
|
415
|
+
describe('calc_pb - compatibilité bug for bug (forçage de la méthode de saisie)', () => {
|
|
416
|
+
beforeEach(() => {
|
|
417
|
+
bugForBugCompat = true;
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
test('résistance connue mais methode != 5/6 : méthode forcée à 5', () => {
|
|
421
|
+
const error = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
422
|
+
const pb = {
|
|
423
|
+
donnee_entree: {
|
|
424
|
+
enum_methode_saisie_u_id: '1',
|
|
425
|
+
methode_saisie_u0: 'type de paroi inconnu (valeur par défaut)',
|
|
426
|
+
enum_type_plancher_bas_id: '9',
|
|
427
|
+
resistance_isolation: '1',
|
|
428
|
+
type_adjacence: 'extérieur'
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
433
|
+
|
|
434
|
+
expect(error).toHaveBeenCalledWith(expect.stringContaining('resistance isolation saisie'));
|
|
435
|
+
// Upb calculé comme en methode 5 : 1 / (1/2 + 1)
|
|
436
|
+
expect(pb.donnee_intermediaire.upb).toBeCloseTo(0.6666666666666666, 9);
|
|
437
|
+
error.mockRestore();
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
test('épaisseur connue mais methode != 3/4 : méthode forcée à 3', () => {
|
|
441
|
+
const error = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
442
|
+
const pb = {
|
|
443
|
+
donnee_entree: {
|
|
444
|
+
enum_methode_saisie_u_id: '1',
|
|
445
|
+
methode_saisie_u0: 'type de paroi inconnu (valeur par défaut)',
|
|
446
|
+
enum_type_plancher_bas_id: '9',
|
|
447
|
+
epaisseur_isolation: '5',
|
|
448
|
+
type_adjacence: 'extérieur'
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
|
|
452
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
453
|
+
|
|
454
|
+
expect(error).toHaveBeenCalledWith(expect.stringContaining('epaisseur isolation saisie'));
|
|
455
|
+
expect(pb.donnee_intermediaire.upb).toBeCloseTo(0.5915492957746479, 9);
|
|
456
|
+
error.mockRestore();
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
test('Upb saisi mais methode != 9/10 : méthode forcée à 9', () => {
|
|
460
|
+
const error = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
461
|
+
const pb = {
|
|
462
|
+
donnee_entree: {
|
|
463
|
+
enum_methode_saisie_u_id: '1',
|
|
464
|
+
upb_saisi: 0.25,
|
|
465
|
+
type_adjacence: 'extérieur'
|
|
466
|
+
}
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
470
|
+
|
|
471
|
+
expect(error).toHaveBeenCalledWith(expect.stringContaining('saisie direct u'));
|
|
472
|
+
expect(pb.donnee_intermediaire.upb).toBe(0.25);
|
|
473
|
+
error.mockRestore();
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
test('effet_joule du DPE différent de celui attendu : valeur du DPE conservée dans le matcher', () => {
|
|
477
|
+
const error = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
478
|
+
// La relecture via tv_upb_id renvoie effet_joule = '1' alors que l'effet Joule attendu est '0'
|
|
479
|
+
tv.mockImplementation((table, matcher) => {
|
|
480
|
+
if (table === 'upb0') return { ...ROW_UPB0 };
|
|
481
|
+
if (table === 'upb' && matcher.tv_upb_id) return { effet_joule: '1', tv_upb_id: '2' };
|
|
482
|
+
if (table === 'upb') return { ...ROW_UPB };
|
|
483
|
+
return null;
|
|
484
|
+
});
|
|
485
|
+
const pb = {
|
|
486
|
+
donnee_entree: {
|
|
487
|
+
enum_methode_saisie_u_id: '2',
|
|
488
|
+
methode_saisie_u0: 'type de paroi inconnu (valeur par défaut)',
|
|
489
|
+
enum_type_plancher_bas_id: '9',
|
|
490
|
+
tv_upb_id: 2,
|
|
491
|
+
type_adjacence: 'extérieur',
|
|
492
|
+
description: 'PB test'
|
|
493
|
+
}
|
|
494
|
+
};
|
|
495
|
+
|
|
496
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
497
|
+
|
|
498
|
+
expect(error).toHaveBeenCalledWith(expect.stringContaining('effet_joule'));
|
|
499
|
+
// Le matcher forfaitaire final utilise l'effet Joule '1' issu du DPE
|
|
500
|
+
expect(tv).toHaveBeenLastCalledWith(
|
|
501
|
+
'upb',
|
|
502
|
+
expect.objectContaining({ effet_joule: '1' }),
|
|
503
|
+
pb.donnee_entree
|
|
504
|
+
);
|
|
505
|
+
error.mockRestore();
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
test('données cohérentes avec la méthode : aucun forçage', () => {
|
|
509
|
+
const error = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
510
|
+
const pb = {
|
|
511
|
+
donnee_entree: {
|
|
512
|
+
enum_methode_saisie_u_id: '5',
|
|
513
|
+
methode_saisie_u0: 'type de paroi inconnu (valeur par défaut)',
|
|
514
|
+
enum_type_plancher_bas_id: '9',
|
|
515
|
+
resistance_isolation: '1',
|
|
516
|
+
epaisseur_isolation: '5',
|
|
517
|
+
upb_saisi: 0.25,
|
|
518
|
+
type_adjacence: 'extérieur'
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
|
|
522
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
523
|
+
|
|
524
|
+
// methode 5 cohérente avec resistance_isolation => pas d'erreur de forçage de résistance,
|
|
525
|
+
// mais épaisseur et upb_saisi présents restent incohérents (couverture des branches vraies)
|
|
526
|
+
expect(error).toHaveBeenCalled();
|
|
527
|
+
error.mockRestore();
|
|
528
|
+
});
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Calcul de la déperdition Ue vers un plancher bas sur terre-plein / vide sanitaire / sous-sol.
|
|
533
|
+
* @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §3.2.2 (Ue)
|
|
534
|
+
*/
|
|
535
|
+
describe('calc_pb - calcul de Ue (tv_ue)', () => {
|
|
536
|
+
/** Renvoie une ue interpolée selon la valeur de upb du matcher. */
|
|
537
|
+
const mockTvUe = (ueForUpb) => {
|
|
538
|
+
tv.mockImplementation((table, matcher) => {
|
|
539
|
+
if (table === 'upb0') return { ...ROW_UPB0, upb0: '0.4' };
|
|
540
|
+
if (table === 'ue') return { ue: String(ueForUpb[matcher.upb]) };
|
|
541
|
+
return null;
|
|
87
542
|
});
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
test('terre-plein, bâtiment avant 2001 (pc < 7) : interpolation linéaire de Ue', () => {
|
|
546
|
+
getRange.mockReturnValue([0.3, 0.5]);
|
|
547
|
+
mockTvUe({ 0.3: 0.2, 0.5: 0.4 });
|
|
548
|
+
|
|
549
|
+
// Deux planchers de même adjacence + un plancher d'adjacence différente (ignoré)
|
|
550
|
+
const autre = {
|
|
551
|
+
donnee_entree: { enum_type_adjacence_id: '8', surface_paroi_opaque: 99, perimetre_ue: 99 }
|
|
552
|
+
};
|
|
553
|
+
const pb1 = {
|
|
554
|
+
donnee_entree: { enum_type_adjacence_id: '5', surface_ue: 20, perimetre_ue: 12 }
|
|
555
|
+
};
|
|
556
|
+
const pb = {
|
|
557
|
+
donnee_entree: {
|
|
558
|
+
enum_methode_saisie_u_id: '1',
|
|
559
|
+
methode_saisie_u0: 'type de paroi inconnu (valeur par défaut)',
|
|
560
|
+
enum_type_plancher_bas_id: '9',
|
|
561
|
+
type_adjacence: 'terre-plein',
|
|
562
|
+
enum_type_adjacence_id: '5',
|
|
563
|
+
surface_paroi_opaque: 4 // pas de surface_ue => fallback
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
|
|
567
|
+
calc_pb(pb, 'h1a', '1', '0', [pb1, pb, autre]);
|
|
568
|
+
|
|
569
|
+
// surfaceUe = 20 (pb1.surface_ue) + 4 (pb.surface_paroi_opaque) = 24 ; perimetreUe = 12 + 0 = 12
|
|
570
|
+
// 2S/P = round(48/12) = 4 (valeur présente dans values_2s_p)
|
|
571
|
+
expect(tv).toHaveBeenCalledWith('ue', {
|
|
572
|
+
type_adjacence_plancher: 'terre plein bâtiment construit avant 2001',
|
|
573
|
+
'2s_p': '^4$',
|
|
574
|
+
upb: '0.3'
|
|
575
|
+
});
|
|
576
|
+
// di.upb = 0,4 ; interpolation : 0,2 + (0,4-0,3)*(0,4-0,2)/(0,5-0,3) = 0,3
|
|
577
|
+
// valeur de référence de régression
|
|
578
|
+
expect(pb.donnee_entree.ue).toBeCloseTo(0.3, 9);
|
|
579
|
+
expect(pb.donnee_intermediaire.upb_final).toBeCloseTo(0.3, 9);
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
test('terre-plein, bâtiment à partir de 2001 (pc >= 7) : catégorie adaptée', () => {
|
|
583
|
+
getRange.mockReturnValue([0.31, 0.31]);
|
|
584
|
+
mockTvUe({ 0.31: 0.25 });
|
|
585
|
+
const pb = {
|
|
586
|
+
donnee_entree: {
|
|
587
|
+
enum_methode_saisie_u_id: '1',
|
|
588
|
+
methode_saisie_u0: 'type de paroi inconnu (valeur par défaut)',
|
|
589
|
+
enum_type_plancher_bas_id: '9',
|
|
590
|
+
type_adjacence: 'terre-plein',
|
|
591
|
+
enum_type_adjacence_id: '5',
|
|
592
|
+
surface_ue: 10,
|
|
593
|
+
perimetre_ue: 10
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
|
|
597
|
+
calc_pb(pb, 'h1a', '8', '0', [pb]);
|
|
598
|
+
|
|
599
|
+
expect(tv).toHaveBeenCalledWith(
|
|
600
|
+
'ue',
|
|
601
|
+
expect.objectContaining({
|
|
602
|
+
type_adjacence_plancher: 'terre plein bâtiment construit à partir de 2001'
|
|
603
|
+
})
|
|
604
|
+
);
|
|
605
|
+
// delta_upb = 0 => ue = ue de la borne inférieure = 0,25
|
|
606
|
+
expect(pb.donnee_entree.ue).toBe(0.25);
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
test('vide sanitaire / sous-sol non chauffé : catégorie plancher sur vide sanitaire', () => {
|
|
610
|
+
getRange.mockReturnValue([0.31, 0.31]);
|
|
611
|
+
mockTvUe({ 0.31: 0.18 });
|
|
612
|
+
const pb = {
|
|
613
|
+
donnee_entree: {
|
|
614
|
+
enum_methode_saisie_u_id: '1',
|
|
615
|
+
methode_saisie_u0: 'type de paroi inconnu (valeur par défaut)',
|
|
616
|
+
enum_type_plancher_bas_id: '9',
|
|
617
|
+
type_adjacence: 'vide sanitaire',
|
|
618
|
+
enum_type_adjacence_id: '7',
|
|
619
|
+
surface_ue: 10,
|
|
620
|
+
perimetre_ue: 10
|
|
621
|
+
}
|
|
622
|
+
};
|
|
623
|
+
|
|
624
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
625
|
+
|
|
626
|
+
expect(tv).toHaveBeenCalledWith(
|
|
627
|
+
'ue',
|
|
628
|
+
expect.objectContaining({
|
|
629
|
+
type_adjacence_plancher: 'plancher sur vide sanitaire ou sous-sol non chauffé'
|
|
630
|
+
})
|
|
631
|
+
);
|
|
632
|
+
expect(pb.donnee_intermediaire.upb_final).toBe(0.18);
|
|
633
|
+
});
|
|
634
|
+
|
|
635
|
+
test('adjacence sous-sol non chauffé : upb_final = Ue', () => {
|
|
636
|
+
getRange.mockReturnValue([0.31, 0.31]);
|
|
637
|
+
mockTvUe({ 0.31: 0.19 });
|
|
638
|
+
const pb = {
|
|
639
|
+
donnee_entree: {
|
|
640
|
+
enum_methode_saisie_u_id: '1',
|
|
641
|
+
methode_saisie_u0: 'type de paroi inconnu (valeur par défaut)',
|
|
642
|
+
enum_type_plancher_bas_id: '9',
|
|
643
|
+
type_adjacence: 'sous-sol non chauffé',
|
|
644
|
+
enum_type_adjacence_id: '6',
|
|
645
|
+
surface_ue: 10,
|
|
646
|
+
perimetre_ue: 10
|
|
647
|
+
}
|
|
648
|
+
};
|
|
649
|
+
|
|
650
|
+
calc_pb(pb, 'h1a', '1', '0', [pb]);
|
|
651
|
+
|
|
652
|
+
expect(pb.donnee_intermediaire.upb_final).toBe(0.19);
|
|
88
653
|
});
|
|
89
654
|
});
|