@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
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Dépendances mockées pour isoler le module :
|
|
5
|
+
* - tables de valeurs (`tvs`) : profils mensuels nref / e_fr / textmoy_clim ;
|
|
6
|
+
* - calcul des apports internes/solaires (`calc_ai_j`, `calc_as_j`) et surface sud équivalente
|
|
7
|
+
* (`calc_sse_j`) : simples fonctions dont on contrôle le retour ;
|
|
8
|
+
* - `mois_liste` : réduite à un seul mois pour rendre la somme vérifiable.
|
|
9
|
+
*/
|
|
10
|
+
vi.mock('./tv.js', () => ({
|
|
11
|
+
tvs: {
|
|
12
|
+
nref26: { ca1: { Janvier: { h1a: 10 } } },
|
|
13
|
+
nref28: { ca1: { Janvier: { h1a: 10 } } },
|
|
14
|
+
e_fr_26: { ca1: { Janvier: { h1a: 100 } } },
|
|
15
|
+
e_fr_28: { ca1: { Janvier: { h1a: 100 } } },
|
|
16
|
+
textmoy_clim_26: { ca1: { Janvier: { h1a: 30 } } },
|
|
17
|
+
textmoy_clim_28: { ca1: { Janvier: { h1a: 30 } } }
|
|
18
|
+
}
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
vi.mock('./utils.js', () => ({
|
|
22
|
+
mois_liste: ['Janvier']
|
|
23
|
+
}));
|
|
24
|
+
|
|
25
|
+
vi.mock('./6.1_apport_gratuit.js', () => ({
|
|
26
|
+
calc_ai_j: vi.fn(),
|
|
27
|
+
calc_as_j: vi.fn()
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
vi.mock('./6.2_surface_sud_equivalente.js', () => ({
|
|
31
|
+
calc_sse_j: vi.fn()
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
const { default: calc_besoin_fr, calc_besoin_fr_j } = await import('./10_besoin_fr.js');
|
|
35
|
+
const { calc_ai_j, calc_as_j } = await import('./6.1_apport_gratuit.js');
|
|
36
|
+
const { calc_sse_j } = await import('./6.2_surface_sud_equivalente.js');
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 10. Calcul des besoins de froid (Bfr)
|
|
40
|
+
* @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §10
|
|
41
|
+
*/
|
|
42
|
+
describe('calc_besoin_fr_j - besoin de froid journalier', () => {
|
|
43
|
+
test('retourne 0 lorsque le nombre de jours de référence est nul', () => {
|
|
44
|
+
expect(calc_besoin_fr_j(100, 300, 'moyenne', 5000, 2000, 0, 30, 28)).toBe(0);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('retourne 0 lorsque le taux Rbth est inférieur à 1/2 (apports insuffisants)', () => {
|
|
48
|
+
// aij + asj = 0 => Rbth = 0 < 0.5
|
|
49
|
+
expect(calc_besoin_fr_j(100, 300, 'moyenne', 0, 0, 10, 30, 28)).toBe(0);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('valeur de référence (Tint=28°C, inertie moyenne)', () => {
|
|
53
|
+
expect(calc_besoin_fr_j(100, 300, 'moyenne', 5000, 2000, 10, 30, 28)).toBeCloseTo(
|
|
54
|
+
11.312243423584366,
|
|
55
|
+
9
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('valeur de référence en mode dépensier (Tint=26°C)', () => {
|
|
60
|
+
expect(calc_besoin_fr_j(100, 300, 'moyenne', 5000, 2000, 10, 30, 26)).toBeCloseTo(
|
|
61
|
+
12.777039072730146,
|
|
62
|
+
9
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('taux Rbth exactement égal à 1 : facteur d’utilisation futj = a / (a + 1)', () => {
|
|
67
|
+
// Rbth = (aij + asj) / (GV * (textmoy - Tint) * nrefj) = 2000 / (100 * 2 * 10) = 1
|
|
68
|
+
// valeur de référence de régression
|
|
69
|
+
expect(calc_besoin_fr_j(100, 100, 'moyenne', 1000, 1000, 10, 30, 28)).toBeCloseTo(
|
|
70
|
+
3.604395604395604,
|
|
71
|
+
9
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test('le besoin de froid dépensier (26°C) est supérieur au besoin conventionnel (28°C)', () => {
|
|
76
|
+
const conventionnel = calc_besoin_fr_j(100, 300, 'moyenne', 5000, 2000, 10, 30, 28);
|
|
77
|
+
const depensier = calc_besoin_fr_j(100, 300, 'moyenne', 5000, 2000, 10, 30, 26);
|
|
78
|
+
expect(depensier).toBeGreaterThan(conventionnel);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe('calc_besoin_fr - agrégation mensuelle', () => {
|
|
83
|
+
beforeEach(() => {
|
|
84
|
+
vi.mocked(calc_ai_j).mockReset();
|
|
85
|
+
vi.mocked(calc_as_j).mockReset();
|
|
86
|
+
vi.mocked(calc_sse_j).mockReset();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('agrège le besoin conventionnel et dépensier sur les mois', () => {
|
|
90
|
+
vi.mocked(calc_ai_j).mockReturnValue(5000);
|
|
91
|
+
vi.mocked(calc_as_j).mockReturnValue(2000);
|
|
92
|
+
vi.mocked(calc_sse_j).mockReturnValue(10);
|
|
93
|
+
|
|
94
|
+
const ret = calc_besoin_fr('ca1', 'h1a', 100, 3, 300, 'moyenne', [], null);
|
|
95
|
+
|
|
96
|
+
expect(ret.besoin_fr).toBeCloseTo(11.312243423584366, 9);
|
|
97
|
+
expect(ret.besoin_fr_depensier).toBeCloseTo(12.777039072730146, 9);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('délègue le calcul de la surface sud équivalente mois par mois', () => {
|
|
101
|
+
vi.mocked(calc_ai_j).mockReturnValue(0);
|
|
102
|
+
vi.mocked(calc_as_j).mockReturnValue(0);
|
|
103
|
+
vi.mocked(calc_sse_j).mockReturnValue(0);
|
|
104
|
+
|
|
105
|
+
calc_besoin_fr('ca1', 'h1a', 100, 3, 300, 'moyenne', ['bv'], 'ets');
|
|
106
|
+
|
|
107
|
+
expect(calc_sse_j).toHaveBeenCalledWith(['bv'], 'ets', 'ca1', 'h1a', 'Janvier');
|
|
108
|
+
// apports internes calculés à partir de la surface et du nombre d'adultes équivalents
|
|
109
|
+
expect(calc_ai_j).toHaveBeenCalledWith(100, 3, 10);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test('un besoin nul sur tous les mois donne un besoin annuel nul', () => {
|
|
113
|
+
vi.mocked(calc_ai_j).mockReturnValue(0);
|
|
114
|
+
vi.mocked(calc_as_j).mockReturnValue(0);
|
|
115
|
+
vi.mocked(calc_sse_j).mockReturnValue(0);
|
|
116
|
+
|
|
117
|
+
const ret = calc_besoin_fr('ca1', 'h1a', 100, 3, 300, 'moyenne', [], null);
|
|
118
|
+
|
|
119
|
+
expect(ret.besoin_fr).toBe(0);
|
|
120
|
+
expect(ret.besoin_fr_depensier).toBe(0);
|
|
121
|
+
});
|
|
122
|
+
});
|
package/10_clim.spec.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Dépendances mockées pour isoler `calc_clim` :
|
|
5
|
+
* - `tv` : accès à la table de valeurs `seer` (on contrôle la ligne retournée
|
|
6
|
+
* et donc l'EER forfaitaire) ;
|
|
7
|
+
* - `requestInputID` : passe-plat vers les données d'entrée pour la période
|
|
8
|
+
* d'installation.
|
|
9
|
+
*/
|
|
10
|
+
vi.mock('./utils.js', () => ({
|
|
11
|
+
tv: vi.fn(),
|
|
12
|
+
requestInputID: (de, du, field) => {
|
|
13
|
+
const enumName = `enum_${field}_id`;
|
|
14
|
+
du[enumName] = de[enumName];
|
|
15
|
+
return de[enumName];
|
|
16
|
+
}
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
const { default: calc_clim } = await import('./10_clim.js');
|
|
20
|
+
const { tv } = await import('./utils.js');
|
|
21
|
+
|
|
22
|
+
/** Fabrique un objet climatisation minimal. */
|
|
23
|
+
function clim(de) {
|
|
24
|
+
return { donnee_entree: de };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
vi.mocked(tv).mockReset();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* 10. Calcul de la consommation de climatisation (froid)
|
|
33
|
+
* @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §10
|
|
34
|
+
*/
|
|
35
|
+
describe('calc_clim - consommation de climatisation', () => {
|
|
36
|
+
test('prorate le besoin de froid au ratio surface_clim / Sh', () => {
|
|
37
|
+
tv.mockReturnValue({ tv_seer_id: '5', eer: 3 });
|
|
38
|
+
const c = clim({ surface_clim: 50, enum_methode_saisie_carac_sys_id: '1' });
|
|
39
|
+
|
|
40
|
+
calc_clim(c, 1000, 1500, '1', 100);
|
|
41
|
+
|
|
42
|
+
// rs = 50 / 100 = 0.5
|
|
43
|
+
expect(c.donnee_intermediaire.besoin_fr).toBeCloseTo(500, 9);
|
|
44
|
+
expect(c.donnee_intermediaire.besoin_fr_depensier).toBeCloseTo(750, 9);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('EER forfaitaire issu de la table : conso = 0.9 * besoin_fr / eer', () => {
|
|
48
|
+
tv.mockReturnValue({ tv_seer_id: '5', eer: 3 });
|
|
49
|
+
const c = clim({ surface_clim: 50, enum_methode_saisie_carac_sys_id: '1' });
|
|
50
|
+
|
|
51
|
+
calc_clim(c, 1000, 1500, '1', 100);
|
|
52
|
+
|
|
53
|
+
// valeur de référence de régression : 0.9 * 500 / 3
|
|
54
|
+
expect(c.donnee_intermediaire.conso_fr).toBeCloseTo(150, 9);
|
|
55
|
+
// 0.9 * 750 / 3
|
|
56
|
+
expect(c.donnee_intermediaire.conso_fr_depensier).toBeCloseTo(225, 9);
|
|
57
|
+
expect(c.donnee_entree.tv_seer_id).toBe(5);
|
|
58
|
+
expect(c.donnee_intermediaire.eer).toBe(3);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("matcher de la table seer : zone climatique + période d'installation", () => {
|
|
62
|
+
tv.mockReturnValue({ tv_seer_id: '5', eer: 3 });
|
|
63
|
+
const c = clim({
|
|
64
|
+
surface_clim: 50,
|
|
65
|
+
enum_methode_saisie_carac_sys_id: '1',
|
|
66
|
+
enum_periode_installation_fr_id: '4'
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
calc_clim(c, 1000, 1500, '2', 100);
|
|
70
|
+
|
|
71
|
+
expect(tv).toHaveBeenCalledWith(
|
|
72
|
+
'seer',
|
|
73
|
+
{
|
|
74
|
+
enum_zone_climatique_id: '2',
|
|
75
|
+
enum_periode_installation_fr_id: '4'
|
|
76
|
+
},
|
|
77
|
+
c.donnee_entree
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test.each([['6'], ['7'], ['8']])(
|
|
82
|
+
"méthode de saisie %s avec EER déjà connu : pas d'accès à la table forfaitaire",
|
|
83
|
+
(methode) => {
|
|
84
|
+
const c = {
|
|
85
|
+
donnee_entree: { surface_clim: 50, enum_methode_saisie_carac_sys_id: methode },
|
|
86
|
+
donnee_intermediaire: { eer: 4 }
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
calc_clim(c, 1000, 1500, '1', 100);
|
|
90
|
+
|
|
91
|
+
expect(tv).not.toHaveBeenCalled();
|
|
92
|
+
// conso calculée avec l'EER saisi : 0.9 * 500 / 4
|
|
93
|
+
expect(c.donnee_intermediaire.conso_fr).toBeCloseTo(112.5, 9);
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
test('méthode de saisie caractéristiques (6) mais EER absent : recours à la table', () => {
|
|
98
|
+
tv.mockReturnValue({ tv_seer_id: '5', eer: 3 });
|
|
99
|
+
const c = clim({ surface_clim: 50, enum_methode_saisie_carac_sys_id: '6' });
|
|
100
|
+
|
|
101
|
+
calc_clim(c, 1000, 1500, '1', 100);
|
|
102
|
+
|
|
103
|
+
expect(tv).toHaveBeenCalled();
|
|
104
|
+
expect(c.donnee_intermediaire.eer).toBe(3);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test('aucune ligne forfaitaire trouvée : EER indéfini, conso non finie', () => {
|
|
108
|
+
tv.mockReturnValue(null);
|
|
109
|
+
const c = clim({ surface_clim: 50, enum_methode_saisie_carac_sys_id: '1' });
|
|
110
|
+
|
|
111
|
+
calc_clim(c, 1000, 1500, '1', 100);
|
|
112
|
+
|
|
113
|
+
expect(c.donnee_intermediaire.eer).toBeUndefined();
|
|
114
|
+
expect(Number.isFinite(c.donnee_intermediaire.conso_fr)).toBe(false);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { describe, expect, test, vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Dépendances mockées pour isoler le module :
|
|
5
|
+
* - `tvs.tefs` : température d'eau froide sanitaire mensuelle par classe d'altitude / zone ;
|
|
6
|
+
* - `Njj` : nombre de jours du mois ;
|
|
7
|
+
* - `mois_liste` : réduite à un seul mois pour rendre la somme annuelle vérifiable.
|
|
8
|
+
* Le calcul du besoin ECS ne dépend ainsi que de valeurs contrôlées.
|
|
9
|
+
*/
|
|
10
|
+
vi.mock('./tv.js', () => ({
|
|
11
|
+
tvs: {
|
|
12
|
+
tefs: { ca1: { Janvier: { h1a: 10 } } }
|
|
13
|
+
}
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
vi.mock('./utils.js', () => ({
|
|
17
|
+
mois_liste: ['Janvier'],
|
|
18
|
+
Njj: { Janvier: 30 }
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
const { default: calc_besoin_ecs, calc_besoin_ecs_j } = await import('./11_besoin_ecs.js');
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 11. Calcul du besoin d'eau chaude sanitaire (Becs)
|
|
25
|
+
* @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §11
|
|
26
|
+
*/
|
|
27
|
+
describe('calc_besoin_ecs_j - besoin ECS journalier', () => {
|
|
28
|
+
test('valeur de référence en mode conventionnel (56 L/j/personne)', () => {
|
|
29
|
+
// valeur de référence de régression : (1.163 * 2 * 56 * (40 - 10) * 30) / 1000
|
|
30
|
+
expect(calc_besoin_ecs_j('ca1', 'Janvier', 'h1a', 2, false)).toBeCloseTo(117.2304, 9);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('valeur de référence en mode dépensier (79 L/j/personne)', () => {
|
|
34
|
+
// valeur de référence de régression : (1.163 * 2 * 79 * (40 - 10) * 30) / 1000
|
|
35
|
+
expect(calc_besoin_ecs_j('ca1', 'Janvier', 'h1a', 2, true)).toBeCloseTo(165.3786, 9);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('le besoin dépensier est supérieur au besoin conventionnel (ratio 79/56)', () => {
|
|
39
|
+
const conventionnel = calc_besoin_ecs_j('ca1', 'Janvier', 'h1a', 2, false);
|
|
40
|
+
const depensier = calc_besoin_ecs_j('ca1', 'Janvier', 'h1a', 2, true);
|
|
41
|
+
expect(depensier / conventionnel).toBeCloseTo(79 / 56, 9);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('un nombre équivalent d’adultes nul donne un besoin nul', () => {
|
|
45
|
+
expect(calc_besoin_ecs_j('ca1', 'Janvier', 'h1a', 0, false)).toBe(0);
|
|
46
|
+
expect(calc_besoin_ecs_j('ca1', 'Janvier', 'h1a', 0, true)).toBe(0);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('le besoin est proportionnel au nombre équivalent d’adultes', () => {
|
|
50
|
+
const un = calc_besoin_ecs_j('ca1', 'Janvier', 'h1a', 1, false);
|
|
51
|
+
const trois = calc_besoin_ecs_j('ca1', 'Janvier', 'h1a', 3, false);
|
|
52
|
+
expect(trois).toBeCloseTo(3 * un, 9);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
describe('calc_besoin_ecs - agrégation annuelle', () => {
|
|
57
|
+
test('agrège les besoins conventionnel et dépensier sur les mois', () => {
|
|
58
|
+
const ret = calc_besoin_ecs('ca1', 'h1a', 2);
|
|
59
|
+
// un seul mois mocké => identique au calcul journalier
|
|
60
|
+
expect(ret.besoin_ecs).toBeCloseTo(117.2304, 9);
|
|
61
|
+
expect(ret.besoin_ecs_depensier).toBeCloseTo(165.3786, 9);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('un nombre équivalent d’adultes nul donne un besoin annuel nul', () => {
|
|
65
|
+
const ret = calc_besoin_ecs('ca1', 'h1a', 0);
|
|
66
|
+
expect(ret.besoin_ecs).toBe(0);
|
|
67
|
+
expect(ret.besoin_ecs_depensier).toBe(0);
|
|
68
|
+
});
|
|
69
|
+
});
|
package/11_ecs.spec.js
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Dépendances mockées pour isoler `calc_ecs` :
|
|
5
|
+
* - `enums.type_installation` : libellé du type d'installation (individuelle / collective) ;
|
|
6
|
+
* - `tv` : accès à la table rendement_distribution_ecs (ligne contrôlée) ;
|
|
7
|
+
* - `requestInput` : passe-plat vers les données d'entrée pour le réseau collectif ;
|
|
8
|
+
* - `calc_gen_ecs` : calcul par générateur, neutralisé (les consommations sont pré-remplies).
|
|
9
|
+
* Aucune vraie table de valeurs n'est sollicitée : les tests restent stables si les données changent.
|
|
10
|
+
*/
|
|
11
|
+
vi.mock('./enums.js', () => ({
|
|
12
|
+
default: {
|
|
13
|
+
type_installation: {
|
|
14
|
+
1: 'installation individuelle',
|
|
15
|
+
2: 'installation collective',
|
|
16
|
+
3: 'installation collective multi-bâtiment'
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
vi.mock('./utils.js', () => ({
|
|
22
|
+
tv: vi.fn(),
|
|
23
|
+
requestInput: vi.fn()
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
vi.mock('./14_generateur_ecs.js', () => ({
|
|
27
|
+
default: vi.fn()
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
const { default: calc_ecs } = await import('./11_ecs.js');
|
|
31
|
+
const { tv, requestInput } = await import('./utils.js');
|
|
32
|
+
const { default: calc_gen_ecs } = await import('./14_generateur_ecs.js');
|
|
33
|
+
|
|
34
|
+
/** Fabrique une installation ECS avec un générateur dont la consommation est pré-remplie. */
|
|
35
|
+
function makeEcs(de, gens) {
|
|
36
|
+
return {
|
|
37
|
+
donnee_entree: de,
|
|
38
|
+
generateur_ecs_collection: {
|
|
39
|
+
generateur_ecs: gens ?? [
|
|
40
|
+
{
|
|
41
|
+
donnee_entree: { position_volume_chauffe: 1 },
|
|
42
|
+
donnee_intermediaire: { conso_ecs: 10, conso_ecs_depensier: 20 }
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
beforeEach(() => {
|
|
50
|
+
vi.mocked(tv).mockReset();
|
|
51
|
+
vi.mocked(requestInput).mockReset();
|
|
52
|
+
vi.mocked(calc_gen_ecs).mockReset();
|
|
53
|
+
// ligne forfaitaire de rendement de distribution par défaut
|
|
54
|
+
vi.mocked(tv).mockReturnValue({ rd: '0.9', tv_rendement_distribution_ecs_id: '5' });
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 11. Prise en compte de l'ECS (ratio de besoin + rendement de distribution)
|
|
59
|
+
* @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §11 / §17.2.1
|
|
60
|
+
*/
|
|
61
|
+
describe('calc_ecs - ratio de besoin ECS', () => {
|
|
62
|
+
test('virtualisation : le ratio est la clé de répartition ECS', () => {
|
|
63
|
+
const de = { tv_rendement_distribution_ecs_id: '5', cle_repartition_ecs: 0.5 };
|
|
64
|
+
const ecs = makeEcs(de);
|
|
65
|
+
calc_ecs({}, ecs, 100, 200, 1, 'ca1', 'h1a', 'maison', true, null, null, false);
|
|
66
|
+
|
|
67
|
+
expect(ecs.donnee_intermediaire.ratio_besoin_ecs).toBe(0.5);
|
|
68
|
+
expect(ecs.donnee_intermediaire.besoin_ecs).toBeCloseTo(50, 9);
|
|
69
|
+
expect(ecs.donnee_intermediaire.besoin_ecs_depensier).toBeCloseTo(100, 9);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('immeuble à systèmes ECS individuels : ratio = 1 / nombre d’appartements', () => {
|
|
73
|
+
const de = { tv_rendement_distribution_ecs_id: '5' };
|
|
74
|
+
const ecs = makeEcs(de);
|
|
75
|
+
calc_ecs({}, ecs, 100, 200, 1, 'ca1', 'h1a', 'immeuble', false, null, 4, true);
|
|
76
|
+
|
|
77
|
+
expect(ecs.donnee_intermediaire.ratio_besoin_ecs).toBe(0.25);
|
|
78
|
+
expect(ecs.donnee_intermediaire.besoin_ecs).toBeCloseTo(25, 9);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test('présence de rdim : ratio = 1 / rdim', () => {
|
|
82
|
+
const de = { tv_rendement_distribution_ecs_id: '5', rdim: 2 };
|
|
83
|
+
const ecs = makeEcs(de);
|
|
84
|
+
calc_ecs({}, ecs, 100, 200, 1, 'ca1', 'h1a', 'maison', false, null, null, false);
|
|
85
|
+
|
|
86
|
+
expect(ecs.donnee_intermediaire.ratio_besoin_ecs).toBe(0.5);
|
|
87
|
+
expect(ecs.donnee_intermediaire.besoin_ecs).toBeCloseTo(50, 9);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test('virtualisation sans clé de répartition : ratio = 1 (valeur de repli)', () => {
|
|
91
|
+
const de = { tv_rendement_distribution_ecs_id: '5' };
|
|
92
|
+
const ecs = makeEcs(de);
|
|
93
|
+
calc_ecs({}, ecs, 100, 200, 1, 'ca1', 'h1a', 'maison', true, null, null, false);
|
|
94
|
+
|
|
95
|
+
expect(ecs.donnee_intermediaire.ratio_besoin_ecs).toBe(1);
|
|
96
|
+
expect(ecs.donnee_intermediaire.besoin_ecs).toBe(100);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test('immeuble à systèmes ECS individuels sans nombre d’appartements : ratio calculé au prorata', () => {
|
|
100
|
+
const de = {
|
|
101
|
+
tv_rendement_distribution_ecs_id: '5',
|
|
102
|
+
surface_habitable: 50,
|
|
103
|
+
rdim: 1,
|
|
104
|
+
nombre_logement: 10
|
|
105
|
+
};
|
|
106
|
+
const ecs = makeEcs(de);
|
|
107
|
+
calc_ecs({}, ecs, 100, 200, 1, 'ca1', 'h1a', 'immeuble', false, 200, null, true);
|
|
108
|
+
|
|
109
|
+
// ratio = ((surface_habitable / surfaceImmeuble) * rdim) / (nombre_logement * nombreAppartements)
|
|
110
|
+
// nombreAppartements est nul -> division par 0 => ratio infini, on vérifie seulement la branche prise
|
|
111
|
+
expect(ecs.donnee_intermediaire.ratio_besoin_ecs).toBe(Infinity);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('immeuble à systèmes ECS individuels : surface immeuble et rdim absents utilisent le repli 1', () => {
|
|
115
|
+
const de = {
|
|
116
|
+
tv_rendement_distribution_ecs_id: '5',
|
|
117
|
+
surface_habitable: 50,
|
|
118
|
+
nombre_logement: 10
|
|
119
|
+
};
|
|
120
|
+
const ecs = makeEcs(de);
|
|
121
|
+
// surfaceImmeuble null et de.rdim absent -> les deux `|| 1` s'appliquent
|
|
122
|
+
calc_ecs({}, ecs, 100, 200, 1, 'ca1', 'h1a', 'immeuble', false, null, null, true);
|
|
123
|
+
|
|
124
|
+
expect(ecs.donnee_intermediaire.ratio_besoin_ecs).toBe(Infinity);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test('rdim infini : la valeur de repli 1 s’applique (1 / Infinity vaut 0)', () => {
|
|
128
|
+
const de = { tv_rendement_distribution_ecs_id: '5', rdim: Infinity };
|
|
129
|
+
const ecs = makeEcs(de);
|
|
130
|
+
calc_ecs({}, ecs, 100, 200, 1, 'ca1', 'h1a', 'maison', false, null, null, false);
|
|
131
|
+
|
|
132
|
+
// 1 / Infinity = 0 -> `|| 1` prend le repli
|
|
133
|
+
expect(ecs.donnee_intermediaire.ratio_besoin_ecs).toBe(1);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test('cas par défaut : ratio = 1 (aucune proratisation)', () => {
|
|
137
|
+
const de = { tv_rendement_distribution_ecs_id: '5' };
|
|
138
|
+
const ecs = makeEcs(de);
|
|
139
|
+
calc_ecs({}, ecs, 100, 200, 1, 'ca1', 'h1a', 'maison', false, null, null, false);
|
|
140
|
+
|
|
141
|
+
expect(ecs.donnee_intermediaire.ratio_besoin_ecs).toBe(1);
|
|
142
|
+
expect(ecs.donnee_intermediaire.besoin_ecs).toBe(100);
|
|
143
|
+
expect(ecs.donnee_intermediaire.besoin_ecs_depensier).toBe(200);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
describe('calc_ecs - rendement de distribution', () => {
|
|
148
|
+
test('la ligne forfaitaire alimente rendement_distribution et l’identifiant de table', () => {
|
|
149
|
+
const de = { tv_rendement_distribution_ecs_id: '5' };
|
|
150
|
+
const ecs = makeEcs(de);
|
|
151
|
+
calc_ecs({}, ecs, 100, 200, 1, 'ca1', 'h1a', 'maison', false, null, null, false);
|
|
152
|
+
|
|
153
|
+
expect(ecs.donnee_intermediaire.rendement_distribution).toBe(0.9);
|
|
154
|
+
expect(de.tv_rendement_distribution_ecs_id).toBe(5);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
test('installation individuelle, production dans le volume chauffé : matcher de configuration', () => {
|
|
158
|
+
const de = { enum_type_installation_id: '1' };
|
|
159
|
+
const ecs = makeEcs(de, [
|
|
160
|
+
{
|
|
161
|
+
donnee_entree: { position_volume_chauffe: 1 },
|
|
162
|
+
donnee_intermediaire: { conso_ecs: 0, conso_ecs_depensier: 0 }
|
|
163
|
+
}
|
|
164
|
+
]);
|
|
165
|
+
calc_ecs({}, ecs, 100, 200, 1, 'ca1', 'h1a', 'maison', false, null, null, false);
|
|
166
|
+
|
|
167
|
+
expect(tv).toHaveBeenCalledWith('rendement_distribution_ecs', {
|
|
168
|
+
configuration_logement: 'production volume habitable [+] pièces alimentées contiguës'
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
test('installation individuelle, production hors volume chauffé : configuration adaptée', () => {
|
|
173
|
+
const de = { enum_type_installation_id: '1' };
|
|
174
|
+
const ecs = makeEcs(de, [
|
|
175
|
+
{
|
|
176
|
+
donnee_entree: { position_volume_chauffe: 0 },
|
|
177
|
+
donnee_intermediaire: { conso_ecs: 0, conso_ecs_depensier: 0 }
|
|
178
|
+
}
|
|
179
|
+
]);
|
|
180
|
+
calc_ecs({}, ecs, 100, 200, 1, 'ca1', 'h1a', 'maison', false, null, null, false);
|
|
181
|
+
|
|
182
|
+
expect(tv).toHaveBeenCalledWith('rendement_distribution_ecs', {
|
|
183
|
+
configuration_logement: 'production hors volume habitable'
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
test('installation collective non isolée : matcher type de réseau + configuration', () => {
|
|
188
|
+
vi.mocked(requestInput).mockImplementation((de, du, field) =>
|
|
189
|
+
field === 'reseau_distribution_isole' ? 0 : undefined
|
|
190
|
+
);
|
|
191
|
+
const de = { enum_type_installation_id: '2' };
|
|
192
|
+
const ecs = makeEcs(de, [
|
|
193
|
+
{
|
|
194
|
+
donnee_entree: { position_volume_chauffe: 1 },
|
|
195
|
+
donnee_intermediaire: { conso_ecs: 0, conso_ecs_depensier: 0 }
|
|
196
|
+
}
|
|
197
|
+
]);
|
|
198
|
+
calc_ecs({}, ecs, 100, 200, 1, 'ca1', 'h1a', 'immeuble', false, null, null, false);
|
|
199
|
+
|
|
200
|
+
expect(tv).toHaveBeenCalledWith('rendement_distribution_ecs', {
|
|
201
|
+
type_reseau_collectif: 'Réseau collectif non isolé',
|
|
202
|
+
configuration_logement: 'majorité des logements avec pièces alimentées contiguës'
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
test('installation collective multi-bâtiment isolée bouclée : configuration non contiguë', () => {
|
|
207
|
+
vi.mocked(requestInput).mockImplementation((de, du, field) => {
|
|
208
|
+
if (field === 'reseau_distribution_isole') return 1;
|
|
209
|
+
if (field === 'bouclage_reseau_ecs') return "réseau d'ecs bouclé";
|
|
210
|
+
return undefined;
|
|
211
|
+
});
|
|
212
|
+
const de = { enum_type_installation_id: '3' };
|
|
213
|
+
const ecs = makeEcs(de, [
|
|
214
|
+
{
|
|
215
|
+
donnee_entree: { position_volume_chauffe: 1 },
|
|
216
|
+
donnee_intermediaire: { conso_ecs: 0, conso_ecs_depensier: 0 }
|
|
217
|
+
}
|
|
218
|
+
]);
|
|
219
|
+
calc_ecs({}, ecs, 100, 200, 1, 'ca1', 'h1a', 'immeuble', false, null, null, false);
|
|
220
|
+
|
|
221
|
+
expect(tv).toHaveBeenCalledWith('rendement_distribution_ecs', {
|
|
222
|
+
type_reseau_collectif: 'Réseau collectif isolé bouclé',
|
|
223
|
+
configuration_logement: 'majorité des logements avec pièces alimentées non contiguës'
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
test('installation collective isolée sans bouclage (traçage) : configuration ignorée', () => {
|
|
228
|
+
vi.mocked(requestInput).mockImplementation((de, du, field) => {
|
|
229
|
+
if (field === 'reseau_distribution_isole') return 1;
|
|
230
|
+
if (field === 'bouclage_reseau_ecs') return "réseau d'ecs non bouclé";
|
|
231
|
+
return undefined;
|
|
232
|
+
});
|
|
233
|
+
const de = { enum_type_installation_id: '2' };
|
|
234
|
+
const ecs = makeEcs(de, [
|
|
235
|
+
{
|
|
236
|
+
donnee_entree: { position_volume_chauffe: 1 },
|
|
237
|
+
donnee_intermediaire: { conso_ecs: 0, conso_ecs_depensier: 0 }
|
|
238
|
+
}
|
|
239
|
+
]);
|
|
240
|
+
calc_ecs({}, ecs, 100, 200, 1, 'ca1', 'h1a', 'immeuble', false, null, null, false);
|
|
241
|
+
|
|
242
|
+
// configuration_logement mise à null -> absente du matcher, seul le type de réseau subsiste
|
|
243
|
+
expect(tv).toHaveBeenCalledWith('rendement_distribution_ecs', {
|
|
244
|
+
type_reseau_collectif:
|
|
245
|
+
'Réseau collectif isolé avec traçage ou Réseau collectif isolé sans traçage ni bouclage'
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
test('aucune ligne forfaitaire trouvée : rendement de distribution non renseigné', () => {
|
|
250
|
+
const errSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
251
|
+
vi.mocked(tv).mockReturnValue(undefined);
|
|
252
|
+
const de = { tv_rendement_distribution_ecs_id: '5' };
|
|
253
|
+
const ecs = makeEcs(de);
|
|
254
|
+
calc_ecs({}, ecs, 100, 200, 1, 'ca1', 'h1a', 'maison', false, null, null, false);
|
|
255
|
+
|
|
256
|
+
expect(ecs.donnee_intermediaire.rendement_distribution).toBeUndefined();
|
|
257
|
+
expect(errSpy).toHaveBeenCalled();
|
|
258
|
+
errSpy.mockRestore();
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
describe('calc_ecs - agrégation des consommations', () => {
|
|
263
|
+
test('somme les consommations des générateurs et invoque calc_gen_ecs par générateur', () => {
|
|
264
|
+
const de = { tv_rendement_distribution_ecs_id: '5' };
|
|
265
|
+
const gens = [
|
|
266
|
+
{
|
|
267
|
+
donnee_entree: { position_volume_chauffe: 1 },
|
|
268
|
+
donnee_intermediaire: { conso_ecs: 10, conso_ecs_depensier: 20 }
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
donnee_entree: { position_volume_chauffe: 1 },
|
|
272
|
+
donnee_intermediaire: { conso_ecs: 5, conso_ecs_depensier: 8 }
|
|
273
|
+
}
|
|
274
|
+
];
|
|
275
|
+
const ecs = makeEcs(de, gens);
|
|
276
|
+
calc_ecs({}, ecs, 100, 200, 1, 'ca1', 'h1a', 'maison', false, null, null, false);
|
|
277
|
+
|
|
278
|
+
expect(calc_gen_ecs).toHaveBeenCalledTimes(2);
|
|
279
|
+
expect(ecs.donnee_intermediaire.conso_ecs).toBe(15);
|
|
280
|
+
expect(ecs.donnee_intermediaire.conso_ecs_depensier).toBe(28);
|
|
281
|
+
});
|
|
282
|
+
});
|
package/11_nadeq.spec.js
CHANGED
|
@@ -53,4 +53,41 @@ describe('Nadeq unit tests', () => {
|
|
|
53
53
|
expect(nadeq.calculateNadeq(logement)).toBeCloseTo(expectedNadeq, 2);
|
|
54
54
|
}
|
|
55
55
|
);
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Pour un appartement individuel, la méthode collective est appelée avec la surface habitable du
|
|
59
|
+
* logement et un unique appartement (Nappart = 1).
|
|
60
|
+
* enum_methode_application_dpe_log_id ∈ {2,3,4,5,31,32,35,36,37}
|
|
61
|
+
*/
|
|
62
|
+
test.each([
|
|
63
|
+
// Shmoy < 10 => Nmax = 1
|
|
64
|
+
[2, 1, 8],
|
|
65
|
+
[3, 1, 8],
|
|
66
|
+
// 10 <= Shmoy < 50 => Nmax = 1.75 - 0.01875 * (50 - Shmoy) ; Shmoy = 45 => 1.65625
|
|
67
|
+
[4, 1.65625, 45],
|
|
68
|
+
// Shmoy >= 50 => Nmax = 0.035 * Shmoy = 2.625 (> 1.75) => 1.75 + 0.3 * (2.625 - 1.75) = 2.0125
|
|
69
|
+
[37, 2.0125, 75]
|
|
70
|
+
])(
|
|
71
|
+
'should get appartement nadeq (méthode %s) = %s pour surface_habitable_logement %s',
|
|
72
|
+
(enum_methode_application_dpe_log_id, expectedNadeq, surface_habitable_logement) => {
|
|
73
|
+
const logement = {
|
|
74
|
+
caracteristique_generale: {
|
|
75
|
+
enum_methode_application_dpe_log_id,
|
|
76
|
+
surface_habitable_logement
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
expect(nadeq.calculateNadeq(logement)).toBeCloseTo(expectedNadeq, 4);
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
test('les identifiants de méthode sont comparés numériquement (chaîne "1" acceptée)', () => {
|
|
84
|
+
const logement = {
|
|
85
|
+
caracteristique_generale: {
|
|
86
|
+
enum_methode_application_dpe_log_id: '1',
|
|
87
|
+
surface_habitable_logement: 8
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
// méthode individuelle : surface < 30 => Nmax = 1
|
|
91
|
+
expect(nadeq.calculateNadeq(logement)).toBe(1);
|
|
92
|
+
});
|
|
56
93
|
});
|