Ajout possibilité de fournir une liste des champs à afficher pouvant être différente de celle récupérée par le parseur.

This commit is contained in:
Fabrice PENHOËT 2021-10-27 15:57:19 +02:00
parent 80b90f98a5
commit 3ea65db323
3 changed files with 106 additions and 7 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "freedatas2html", "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.", "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", "main": "index.js",
"scripts": { "scripts": {

View File

@ -21,6 +21,7 @@ export class FreeDatas2HTML
// Les options (classement, pagination, filtres...) : // Les options (classement, pagination, filtres...) :
private _datasCounterElt: DOMElement|undefined=undefined; private _datasCounterElt: DOMElement|undefined=undefined;
private _datasSortingFunctions: SortingFunctions[]=[]; private _datasSortingFunctions: SortingFunctions[]=[];
private _fields2Rend: number[]=[];
public datasFilters: Filters[]=[]; public datasFilters: Filters[]=[];
public datasSortingFields: SortingFields[]=[]; public datasSortingFields: SortingFields[]=[];
public datasSortedField: SortingFields|undefined; public datasSortedField: SortingFields|undefined;
@ -122,6 +123,29 @@ export class FreeDatas2HTML
} }
} }
// 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 // Retourne l'éventuelle fonction spécifique de classement associée à un champ
public getSortingFunctionForField(datasFieldNb: number): SortingFunctions|undefined public getSortingFunctionForField(datasFieldNb: number): SortingFunctions|undefined
{ {
@ -147,8 +171,20 @@ export class FreeDatas2HTML
{ {
this._fields=this.parser.parseResults.fields; this._fields=this.parser.parseResults.fields;
this._datas=this.parser.parseResults.datas; this._datas=this.parser.parseResults.datas;
// Les champs ne bougeront plus, donc on peut déjà les passer au moteur de rendu : // Les champs ne bougeront plus, donc on peut déjà les passer au moteur de rendu.
this.datasRender.fields=this._fields; // 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) if(this._datasViewElt !== undefined)
this.refreshView(); this.refreshView();
return true; return true;
@ -207,7 +243,7 @@ export class FreeDatas2HTML
let maxData=(this.pagination !== undefined && this.pagination.selectedValue !== undefined) ? this.pagination.selectedValue : this._datas.length; let maxData=(this.pagination !== undefined && this.pagination.selectedValue !== undefined) ? this.pagination.selectedValue : this._datas.length;
// Création du tableau des données à afficher : // Création du tableau des données à afficher :
const datas2Display=[]; let datas2Display=[];
let nbVisible=0, nbTotal=0; let nbVisible=0, nbTotal=0;
for (let row in this._datas) for (let row in this._datas)
{ {
@ -228,6 +264,26 @@ export class FreeDatas2HTML
nbTotal++; nbTotal++;
} }
this._nbDatasValid=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; return datas2Display;
} }
} }

View File

@ -111,11 +111,18 @@ describe("Tests du script central de FreeDatas2HTML", () =>
expect(converter.fields).toEqual(converter.parser.parseResults.fields); 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); 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 () => 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 () =>
{ {
spyOn(converter, "refreshView"); spyOn(converter, "refreshView");
@ -155,7 +162,7 @@ describe("Tests du script central de FreeDatas2HTML", () =>
converter=new FreeDatas2HTML("CSV"); converter=new FreeDatas2HTML("CSV");
const check=converter.checkFieldExist(0); const check=converter.checkFieldExist(0);
expect(converter.checkFieldExist(0)).toBeFalse(); 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.", () => it("Doit retourner false si le numéro de champ n'est pas trouvé dans les données.", () =>
@ -176,6 +183,23 @@ describe("Tests du script central de FreeDatas2HTML", () =>
expect(check).toBeTrue(); 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.", () => it("Doit générer une erreur si une fonction est associée à un champ n'existant pas dans les données.", () =>
{ {
expect(() => { return converter.datasSortingFunctions=[{ datasFieldNb:10, sort:simpleSort }]; }).toThrowError(errors.converterFieldNotFound); expect(() => { return converter.datasSortingFunctions=[{ datasFieldNb:10, sort:simpleSort }]; }).toThrowError(errors.converterFieldNotFound);
@ -272,6 +296,25 @@ describe("Tests du script central de FreeDatas2HTML", () =>
await converter.run(); 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.", () => 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 // Compliqué de tester avec spyOn que sort() a été appelée avec la bonne fonction de classement en paramètre