From 3ea65db32353433e8dd93f226d93a4b41b5b7a6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabrice=20PENHO=C3=8BT?= Date: Wed, 27 Oct 2021 15:57:19 +0200 Subject: [PATCH] =?UTF-8?q?Ajout=20possibilit=C3=A9=20de=20fournir=20une?= =?UTF-8?q?=20liste=20des=20champs=20=C3=A0=20afficher=20pouvant=20=C3=AAt?= =?UTF-8?q?re=20diff=C3=A9rente=20de=20celle=20r=C3=A9cup=C3=A9r=C3=A9e=20?= =?UTF-8?q?par=20le=20parseur.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/FreeDatas2HTML.ts | 62 +++++++++++++++++++++++++++++++++++-- tests/freeDatas2HTMLSpec.ts | 49 +++++++++++++++++++++++++++-- 3 files changed, 106 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index a31ac3e..65a4b4e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "freedatas2html", - "version": "0.9.5", + "version": "0.9.6", "description": "Conversion and display of data in different formats (CSV, JSON, HTML) with the possibility of filtering, classifying and paginating the results.", "main": "index.js", "scripts": { diff --git a/src/FreeDatas2HTML.ts b/src/FreeDatas2HTML.ts index 5c06d94..7e4dcbc 100644 --- a/src/FreeDatas2HTML.ts +++ b/src/FreeDatas2HTML.ts @@ -21,6 +21,7 @@ export class FreeDatas2HTML // Les options (classement, pagination, filtres...) : private _datasCounterElt: DOMElement|undefined=undefined; private _datasSortingFunctions: SortingFunctions[]=[]; + private _fields2Rend: number[]=[]; public datasFilters: Filters[]=[]; public datasSortingFields: SortingFields[]=[]; public datasSortedField: SortingFields|undefined; @@ -121,6 +122,29 @@ export class FreeDatas2HTML this._datasSortingFunctions.push(checkedFunction); } } + + // Vérifie que tous les numéros de champs à afficher sont valides + // Un tableau vide signifie que tous les champs parsés seront affichés. + set fields2Rend(fields: number[]) + { + if(fields.length === 0) + this._fields2Rend=fields; + else + { + for(let field of fields) + { + if(! this.checkFieldExist(field)) + throw new Error(errors.converterFieldNotFound); + else + this._fields2Rend.push(field); + } + } + } + + get fields2Rend() : number[] + { + return this._fields2Rend; + } // Retourne l'éventuelle fonction spécifique de classement associée à un champ public getSortingFunctionForField(datasFieldNb: number): SortingFunctions|undefined @@ -147,8 +171,20 @@ export class FreeDatas2HTML { this._fields=this.parser.parseResults.fields; this._datas=this.parser.parseResults.datas; - // Les champs ne bougeront plus, donc on peut déjà les passer au moteur de rendu : - this.datasRender.fields=this._fields; + // Les champs ne bougeront plus, donc on peut déjà les passer au moteur de rendu. + // Mais en prenant les comptes les éventuels champs à ne pas afficher + if(this._fields2Rend.length === 0) + this.datasRender.fields=this._fields; + else + { + const fields2Rend: string[]=[]; + for(let i=0; i< this._fields.length; i++) + { + if(this._fields2Rend.indexOf(i) !== -1) + fields2Rend.push(this._fields[i]); + } + this.datasRender.fields=fields2Rend; + } if(this._datasViewElt !== undefined) this.refreshView(); return true; @@ -207,7 +243,7 @@ export class FreeDatas2HTML let maxData=(this.pagination !== undefined && this.pagination.selectedValue !== undefined) ? this.pagination.selectedValue : this._datas.length; // Création du tableau des données à afficher : - const datas2Display=[]; + let datas2Display=[]; let nbVisible=0, nbTotal=0; for (let row in this._datas) { @@ -228,6 +264,26 @@ export class FreeDatas2HTML nbTotal++; } this._nbDatasValid=nbTotal; + + // Tous les champs doivent-ils être affichés ? + // Ne pas enlever les champs cachés plus tôt, car ils peuvent servir à filtrer les données + if(this._fields2Rend.length !== 0) + { + let newDatas2Display=[]; + for(let row in datas2Display) + { + let i=0, newData: {[index: string]: string} = {}; + for(let field in datas2Display[row]) + { + if(this._fields2Rend.indexOf(i) !== -1) + newData[field]=datas2Display[row][field]; + i++; + } + newDatas2Display.push(newData); + } + datas2Display=newDatas2Display; + } + return datas2Display; } } diff --git a/tests/freeDatas2HTMLSpec.ts b/tests/freeDatas2HTMLSpec.ts index 7ca4f90..a88dfc6 100644 --- a/tests/freeDatas2HTMLSpec.ts +++ b/tests/freeDatas2HTMLSpec.ts @@ -110,11 +110,18 @@ describe("Tests du script central de FreeDatas2HTML", () => expect(converter.datas).toEqual(converter.parser.parseResults.datas); expect(converter.fields).toEqual(converter.parser.parseResults.fields); }); - - it("Si le parsage s'est bien déroulé, la liste des champs trouvés doit être transmise au moteur de rendu sans altération.", () => + + it("Si le parsage s'est bien déroulé et que tous les champs doivent être affichés, leur liste doit être transmise au moteur de rendu sans altération.", () => { expect(converter.datasRender.fields).toEqual(converter.parser.parseResults.fields); }); + + it("Si le parsage s'est bien déroulé et qu'une liste de champs à afficher a été fournie, seuls ceux demandés doivent être transmis au moteur de rendu.", async () => + { + converter.fields2Rend=[1,2]; + await converter.run(); + expect(converter.datasRender.fields).toEqual([converter.parser.parseResults.fields[1],converter.parser.parseResults.fields[2]]); + }); it("Si le parsage s'est bien déroulé et qu'un élément HTML est renseigné pour recevoir les données, un premier affichage doit être demandé.", async () => { @@ -155,7 +162,7 @@ describe("Tests du script central de FreeDatas2HTML", () => converter=new FreeDatas2HTML("CSV"); const check=converter.checkFieldExist(0); expect(converter.checkFieldExist(0)).toBeFalse(); - // Dans le cas d'un parsage ne retournant rien, c'est le parseur qui va générer une erreur. + // Dans le cas d'un parsage ne retournant rien, c'est le parseur qui doit générer une erreur. }); it("Doit retourner false si le numéro de champ n'est pas trouvé dans les données.", () => @@ -175,6 +182,23 @@ describe("Tests du script central de FreeDatas2HTML", () => check=converter.checkFieldExist(2); expect(check).toBeTrue(); }); + + it("Doit générer une erreur si tous les champs devant être affichés ne sont pas présents dans les données reçues.", () => + { + expect(() => { return converter.fields2Rend=[0,2,8]; }).toThrowError(errors.converterFieldNotFound); + }); + + it("Doit accepter un tableau vide pour la liste de champs à afficher.", () => + { + expect(() => { return converter.fields2Rend=[]; }).not.toThrowError(); + expect(converter.fields2Rend.length).toEqual(0); + }); + + it("Si tous les champs à afficher sont trouvés dans les données, ils doivent être acceptés.", () => + { + expect(() => { return converter.fields2Rend=[0,1,2]; }).not.toThrowError(); + expect(converter.fields2Rend).toEqual([0,1,2]); + }); it("Doit générer une erreur si une fonction est associée à un champ n'existant pas dans les données.", () => { @@ -272,6 +296,25 @@ describe("Tests du script central de FreeDatas2HTML", () => await converter.run(); }); + it("Si une liste de champs à afficher a été renseignée, elle doit être prise en compte.", async () => + { + converter=new FreeDatas2HTML("CSV","id,firstname,name,birthday\n1,john,doe,2001/12/25\n2,donald,duck,1934/06/09"); + converter.datasViewElt={ id:"datas" }; + await converter.run(); + converter.fields2Rend=[1,2]; + converter.refreshView(); + expect(converter.datas2Rend).toEqual([{ firstname:"john", name:"doe" }, { firstname:"donald", name:"duck" }]); + }); + + it("Par défaut, tous les champs trouvés doivent être affichés.", async () => + { + converter=new FreeDatas2HTML("CSV","id,firstname,name,birthday\n1,john,doe,2001/12/25\n2,donald,duck,1934/06/09"); + converter.datasViewElt={ id:"datas" }; + await converter.run(); + converter.refreshView(); + expect(converter.datas2Rend).toEqual([{ id:"1", firstname:"john", name:"doe", birthday:"2001/12/25" }, { id:"2", firstname:"donald", name:"duck", birthday:"1934/06/09" }]); + }); + it("Si un champ de classement est activé par l'utilisateur, les données doivent être classées via ce champ.", () => { // Compliqué de tester avec spyOn que sort() a été appelée avec la bonne fonction de classement en paramètre