diff --git a/src/errors.js b/src/errors.js index a7bb1be..8fa707e 100644 --- a/src/errors.js +++ b/src/errors.js @@ -10,6 +10,7 @@ module.exports = needUrl: "Merci de fournir une url valide pour le fichier CSV à parser.", parserFail: "La lecture des données du fichier a échoué.", selector2HTMLFail: "Le création d'un filtre dans le DOM nécessite l'initialisation de l'élément HTML et du numéro du champs à filter.", + selectorCheckIsOkFail: "Le test est lancé sur un filtre incorrectement initialisé ou sur un attribut absent de la donnée à tester.", sortingColumnsFieldNotFound: "Au moins une des colonnes devant servir à classer les données n'existe pas dans le fichier.", selectorFieldNotFound: "Au moins une des colonnes devant servir à filtrer les données n'existe pas dans le fichier.", selectorNeedDatas: "Le création d'un filtre nécessite la transmission des données à filtrer.", diff --git a/src/freeDatas2HTMLSelector.ts b/src/freeDatas2HTMLSelector.ts index 8889e6c..71e24d7 100644 --- a/src/freeDatas2HTMLSelector.ts +++ b/src/freeDatas2HTMLSelector.ts @@ -11,7 +11,8 @@ export class Selector implements Selectors _separator: string|undefined; // séparateur éventuel pour les données du champ name: string = ""; // nom à afficher dans le DOM comme "label" du "select" values: string[]=[]; // données proposées par le filtre, après traitement des données reçues - + + // Injection de la classe principale, mais uniquement si les données ont été importées constructor(converter: FreeDatas2HTML) { if(converter.parseMetas === undefined || converter.parseMetas.fields === undefined || converter.parseDatas.length === 0) @@ -69,18 +70,18 @@ export class Selector implements Selectors throw new Error(errors.selector2HTMLFail); else { - this.name=this._converter.parseMetas!.fields![this._datasFieldNb]; // this.converter.parse... ne peut être indéfinis si this.converter existe (cf constructeur) + this.name=this._converter.parseMetas!.fields![this._datasFieldNb]; // this._converter.parse... ne peuvent être indéfinis si this._converter existe (cf constructeur) for (let row in this._converter.parseDatas) { if(this._separator === undefined) { - let checkedValue=this._converter.parseDatas[row][this.name].trim(); + let checkedValue=String(this._converter.parseDatas[row][this.name]).trim(); // trim() nécessaire pour éviter problème de classement du tableau (sort) if(checkedValue !== "" && this.values.indexOf(checkedValue) === -1) this.values.push(checkedValue); } else { - let checkedValues=String(this._converter.parseDatas[row][this.name]).split(this._separator); // les données peuvent être des chiffres, etc. + let checkedValues=String(this._converter.parseDatas[row][this.name]).split(this._separator); // String() car les données peuvent être des chiffres, etc. for(let i in checkedValues) { let checkedValue=checkedValues[i].trim(); @@ -110,7 +111,7 @@ export class Selector implements Selectors } } - // Vérifie sur une valeur est sélectionnée dans la liste et la retourne + // Vérifie si une valeur est sélectionnée dans la liste et, si oui, la retourne public getSelectionnedId() : number { const selectElement=document.getElementById("freeDatas2HTML_"+this._datasViewElt.id) as HTMLInputElement; @@ -120,12 +121,12 @@ export class Selector implements Selectors return parseInt(selectElement.value,10); } - // Vérifie sur l'enregistrement est valide pour la valeur sélectionnée dans le filtre + // Vérifie sur l'enregistrement passé correspond à la valeur sélectionnée par l'utilisateur dans le filtre public dataIsOk(data: any) : boolean - { - if(this.name === undefined || data[this.name] === undefined) // attribut absent pour cet enregistrement - return false; - + { + if(this.name === undefined || this.name === "") + throw new Error(errors.selectorCheckIsOkFail); + let selectedValue = this.getSelectionnedId(); if(selectedValue === 0) // = pas de valeur sélectionnée = pas de filtre sur ce champ return true; @@ -134,11 +135,14 @@ export class Selector implements Selectors if(this.values[selectedValue] === undefined) throw new Error(errors.selectorSelectedIndexNotFound); + + if(data[this.name] === undefined) // attribut absent pour cet enregistrement, qui est donc refusé + return false; const selectedValueTxt=this.values[selectedValue] ; if(this._separator === undefined) { - if(data[this.name].trim() !== selectedValueTxt) + if(data[this.name].trim() !== selectedValueTxt) // retour du trim() utilisé pour créer la liste return false; else return true; diff --git a/tests/selectorsSpec.ts b/tests/selectorsSpec.ts index b866166..18f08f9 100644 --- a/tests/selectorsSpec.ts +++ b/tests/selectorsSpec.ts @@ -48,7 +48,7 @@ describe("Test des filtres de données", () => expect(selector.datasViewElt).toEqual({ id:"selector1", "eltDOM": myContainer }); }); - it("Doit générer une erreur, si le numéro de champ fourni n'existe pas dans les données fournies.", () => + it("Doit générer une erreur, si le numéro de champ fourni n'existe pas dans les données.", () => { expect(() => { return selector.datasFieldNb=9; }).toThrowError(errors.selectorFieldNotFound); expect(() => { return selector.datasFieldNb=-1; }).toThrowError(errors.selectorFieldNotFound); @@ -58,6 +58,8 @@ describe("Test des filtres de données", () => it("Si le numéro de champ fourni est valide, il doit être accepté.", () => { expect(() => { return selector.datasFieldNb=1; }).not.toThrowError(); + selector.datasFieldNb=1; + expect(selector.datasFieldNb).toEqual(1); }); it("Si un séparateur vide est fourni pour un filtre, il doit être ignoré.", () => @@ -135,7 +137,35 @@ describe("Test des filtres de données", () => expect(document.getElementById("selector1").innerHTML).toEqual(fixtures.selector1HTMLWithFunction); }); - it("Doit retourner false, si une donnée testée ne correspond pas à la valeur sélectionnée dans la liste.", () => + it("Doit générer une erreur si une donnée est testée pour un sélecteur non correctement initialisé.", () => + { + let data2Test= { + "Z (numéro atomique)" : "53", + "Élément": "Iode", + "Symbole": "I", + "Famille": "Halogène", + "Abondance des éléments dans la croûte terrestre (μg/k)": "> 1 et < 100 000", + }; + expect(() => { selector.dataIsOk(data2Test); }).toThrowError(errors.selectorCheckIsOkFail); + }); + + it("Doit retourner false, si la donnée testée ne possède pas le champ sur lequel les données sont filtrées.", () => + { + selector.datasViewElt={ id:"selector1"}; + selector.datasFieldNb=3; + selector.selector2HTML(); + let selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLInputElement; + selectElement.value="4"; + let data2Test= { // le champ à filtrer ("Famill") est manquant + "Z (numéro atomique)" : "53", + "Élément": "Iode", + "Symbole": "I", + "Abondance des éléments dans la croûte terrestre (μg/k)": "> 1 et < 100 000", + }; + expect(selector.dataIsOk(data2Test)).toBeFalse(); + }); + + it("Doit retourner false, si une donnée testée ne correspond pas à la valeur sélectionnée pour le filtre.", () => { selector.datasViewElt={ id:"selector1"}; selector.datasFieldNb=3; @@ -150,16 +180,9 @@ describe("Test des filtres de données", () => "Abondance des éléments dans la croûte terrestre (μg/k)": "> 1 et < 100 000", }; expect(selector.dataIsOk(data2Test)).toBeFalse(); - let data2Test2= { // le champ à filtrer est manquant - "Z (numéro atomique)" : "53", - "Élément": "Iode", - "Symbole": "I", - "Abondance des éléments dans la croûte terrestre (μg/k)": "> 1 et < 100 000", - }; - expect(selector.dataIsOk(data2Test2)).toBeFalse(); }); - it("Doit retourner true, si une donnée testée correspond pas à la valeur sélectionnée dans la liste.", () => + it("Doit retourner true, si une donnée testée correspond pas à la valeur sélectionnée pour ce filtre.", () => { selector.datasViewElt={ id:"selector1"}; selector.datasFieldNb=3; @@ -288,6 +311,4 @@ describe("Test des filtres de données", () => expect(txtDatasViewsElt).toEqual("
Z (numéro atomique)ÉlémentSymboleFamilleAbondance des éléments dans la croûte terrestre (μg/k)Étiquettes
"); }); }); - - }); \ No newline at end of file