Simplification instanciation des filtres (selector) + adaptation tests et script démo.

This commit is contained in:
Fabrice PENHOËT 2021-09-22 17:12:00 +02:00
parent 7b313ae150
commit ea4174cf73
5 changed files with 60 additions and 98 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "freedatas2html", "name": "freedatas2html",
"version": "0.4.3", "version": "0.4.4",
"description": "Visualization of data from various sources (CSV, API, HTML...) with filters, classification, pagination, etc.", "description": "Visualization of data from various sources (CSV, API, HTML...) with filters, classification, pagination, etc.",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

View File

@ -23,7 +23,7 @@ const initialise = async () =>
converter.datasViewElt={ id:"datas" }; converter.datasViewElt={ id:"datas" };
converter.datasSourceUrl="http://localhost:8080/datas/elements-chimiques.csv"; converter.datasSourceUrl="http://localhost:8080/datas/elements-chimiques.csv";
await converter.parse(); await converter.parse();
converter.datasSortingFunctions=[{ datasFieldNb: 4, sort:mySort }]; converter.datasSortingFunctions=[{ datasFieldNb:4, sort:mySort }];
// Configuration de la pagination // Configuration de la pagination
const pagination=new Pagination(converter, { id:"pages" }, "Page à afficher :"); const pagination=new Pagination(converter, { id:"pages" }, "Page à afficher :");
@ -36,20 +36,14 @@ const initialise = async () =>
await converter.run(); await converter.run();
// Création d'outils permettant de filtrer les données des champs de données // Création d'outils permettant de filtrer les données des champs de données
let filtre1=new Selector(converter); let filtre1=new Selector(converter, 3, { id:"filtre1"} );
filtre1.datasViewElt={ id:"filtre1"};
filtre1.datasFieldNb=3;
filtre1.selector2HTML(); filtre1.selector2HTML();
let filtre2=new Selector(converter); let filtre2=new Selector(converter, 4, { id:"filtre2"} );
filtre2.datasViewElt={ id:"filtre2"};
filtre2.datasFieldNb=4;
filtre2.selector2HTML(); filtre2.selector2HTML();
let filtre3=new Selector(converter); let filtre3=new Selector(converter, 5, { id:"filtre3"} );
filtre3.datasViewElt={ id:"filtre3"};
filtre3.datasFieldNb=5;
filtre3.separator=","; filtre3.separator=",";
filtre3.selector2HTML(); filtre3.selector2HTML();
// Injection des filtres dans le convertisseur // + Injection des filtres dans le convertisseur
converter.datasSelectors=[filtre1,filtre2,filtre3]; converter.datasSelectors=[filtre1,filtre2,filtre3];
// Ajout de champs permettant de classer les données // Ajout de champs permettant de classer les données

View File

@ -27,7 +27,7 @@ export interface PaginationsPages
export interface Selectors export interface Selectors
{ {
datasViewElt: DOMElement; datasViewElt: DOMElement;
datasFieldNb: number|undefined; datasFieldNb: number;
separator?: string|undefined; separator?: string|undefined;
name?: string; name?: string;
values?: string[]; values?: string[];

View File

@ -7,43 +7,24 @@ export class Selector implements Selectors
{ {
_converter: FreeDatas2HTML; _converter: FreeDatas2HTML;
_datasViewElt: DOMElement= { id:"", eltDOM:undefined }; // élément du DOM dans lequel afficher le "select" _datasViewElt: DOMElement= { id:"", eltDOM:undefined }; // élément du DOM dans lequel afficher le "select"
_datasFieldNb: number|undefined; // numéro du champ dont les données serviront au filtre _datasFieldNb: number; // numéro du champ dont les données serviront au filtre
_separator: string|undefined; // séparateur éventuel pour les données du champ _separator: string|undefined; // séparateur éventuel pour les données du champ
name: string = ""; // nom à afficher dans le DOM comme "label" du "select" 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 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 // Injection de la classe principale, mais uniquement si les données ont été importées
constructor(converter: FreeDatas2HTML) constructor(converter: FreeDatas2HTML, datasFieldNb: number, elt: DOMElement)
{ {
if(converter.parseMetas === undefined || converter.parseMetas.fields === undefined || converter.parseDatas.length === 0) if(converter.parseMetas === undefined || converter.parseMetas.fields === undefined || converter.parseDatas.length === 0)
throw new Error(errors.selectorNeedDatas); throw new Error(errors.selectorNeedDatas);
else else if(! converter.checkFieldExist(Number(datasFieldNb)))
this._converter=converter;
}
// Vérifie que l'élément devant recevoir le filtre existe dans la page
set datasViewElt(elt: DOMElement)
{
this._datasViewElt=FreeDatas2HTML.checkInDOMById(elt);
}
get datasViewElt() : DOMElement
{
return this._datasViewElt;
}
// Vérifie que le numéro de champ existe dans les données reçues
set datasFieldNb(datasFieldNb: number|undefined)
{
if(datasFieldNb === undefined || ! this._converter.checkFieldExist(Number(datasFieldNb)))
throw new Error(errors.selectorFieldNotFound); throw new Error(errors.selectorFieldNotFound);
else else
{
this._datasViewElt=FreeDatas2HTML.checkInDOMById(elt); // provoque une erreur, si élement non trouvé dans DOM
this._converter=converter;
this._datasFieldNb=datasFieldNb; this._datasFieldNb=datasFieldNb;
} }
get datasFieldNb() : number|undefined
{
return this._datasFieldNb;
} }
// Ignore un séparateur de données vide // Ignore un séparateur de données vide
@ -56,6 +37,21 @@ export class Selector implements Selectors
this._separator=separator; this._separator=separator;
} }
get datasViewElt() : DOMElement
{
return this._datasViewElt;
}
get datasFieldNb() : number
{
return this._datasFieldNb;
}
get separator() : string|undefined
{
return this._separator;
}
// Création du <select> dans le HTML correspondant au filtre // Création du <select> dans le HTML correspondant au filtre
public selector2HTML() : void public selector2HTML() : void
{ {

View File

@ -15,7 +15,6 @@ describe("Test des filtres de données", () =>
converter.datasViewElt={ id:"datas" }; converter.datasViewElt={ id:"datas" };
converter.datasSourceUrl="http://localhost:9876/datas/datas1.csv"; converter.datasSourceUrl="http://localhost:9876/datas/datas1.csv";
await converter.parse(); await converter.parse();
selector=new Selector(converter);
}); });
afterEach( () => afterEach( () =>
@ -28,33 +27,33 @@ describe("Test des filtres de données", () =>
it("Doit générer une erreur, si initialisé sans fournir la liste des champs servant à classer les données.", () => it("Doit générer une erreur, si initialisé sans fournir la liste des champs servant à classer les données.", () =>
{ {
converter=new FreeDatas2HTML(); converter=new FreeDatas2HTML();
expect(() => { return new Selector(converter); }).toThrowError(errors.selectorNeedDatas); expect(() => { return new Selector(converter, 0, { id:"selector1" }); }).toThrowError(errors.selectorNeedDatas);
}); });
it("Ne doit pas générer d'erreur, si initialisé avec des données correctes.", () =>
{
expect(() => { return new Selector(converter); }).not.toThrowError();
});
it("Doit générer une erreur, si le numéro de champ fourni n'existe pas dans les données.", () => 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 new Selector(converter, 9, { id:"selector1" }); }).toThrowError(errors.selectorFieldNotFound);
expect(() => { return selector.datasFieldNb=-1; }).toThrowError(errors.selectorFieldNotFound); expect(() => { return new Selector(converter, -1, { id:"selector1" }); }).toThrowError(errors.selectorFieldNotFound);
expect(() => { return selector.datasFieldNb=1.1; }).toThrowError(errors.selectorFieldNotFound); expect(() => { return new Selector(converter, 1.1, { id:"selector1" }); }).toThrowError(errors.selectorFieldNotFound);
}); });
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é.", () => it("Si un séparateur vide est fourni pour un filtre, il doit être ignoré.", () =>
{ {
selector=new Selector(converter, 0, { id:"selector1" });
selector.separator=""; selector.separator="";
expect(selector.separator).toBeUndefined(); expect(selector.separator).toBeUndefined();
}); });
it("Si toutes les paramètres sont correctes, ils doivent être acceptés.", () =>
{
const elt=document.getElementById("selector1");
const selector=new Selector(converter, 2, { id:"selector1" });
selector.separator=",";
expect(selector.datasFieldNb).toEqual(2);
expect(selector.datasViewElt).toEqual({ id:"selector1", eltDOM:elt });
expect(selector.separator).toEqual(",");
});
}); });
describe("Création et action des sélecteurs permettant de filter les données affichées.", () => describe("Création et action des sélecteurs permettant de filter les données affichées.", () =>
@ -66,18 +65,14 @@ describe("Test des filtres de données", () =>
converter.datasViewElt={ id:"datas" }; converter.datasViewElt={ id:"datas" };
converter.datasSourceUrl="http://localhost:9876/datas/datas1.csv"; converter.datasSourceUrl="http://localhost:9876/datas/datas1.csv";
await converter.parse(); await converter.parse();
selector=new Selector(converter); selector=new Selector(converter, 3, { id:"selector1" });
}); });
it("Doit générer un élement <select> listant les valeurs distinctes du champ spécifié, classées dans le bon ordre.", () => it("Doit générer un élement <select> listant les valeurs distinctes du champ spécifié, classées dans le bon ordre.", () =>
{ {
selector.datasViewElt={ id:"selector1"};
selector.datasFieldNb=3;
selector.selector2HTML(); selector.selector2HTML();
expect(document.getElementById("selector1").innerHTML).toEqual(fixtures.selector1HTML); expect(document.getElementById("selector1").innerHTML).toEqual(fixtures.selector1HTML);
selector=new Selector(converter); selector=new Selector(converter, 4, { id:"selector2" });
selector.datasViewElt={ id:"selector2"};
selector.datasFieldNb=4;
selector.selector2HTML(); selector.selector2HTML();
expect(document.getElementById("selector2").innerHTML).toEqual(fixtures.selector2HTML); expect(document.getElementById("selector2").innerHTML).toEqual(fixtures.selector2HTML);
}); });
@ -86,8 +81,6 @@ describe("Test des filtres de données", () =>
{ {
converter.datasSourceUrl="http://localhost:9876/datas/datas1-emtyinfield.csv"; converter.datasSourceUrl="http://localhost:9876/datas/datas1-emtyinfield.csv";
await converter.parse(); await converter.parse();
selector.datasViewElt={ id:"selector1"};
selector.datasFieldNb=3;
selector.selector2HTML(); selector.selector2HTML();
expect(document.getElementById("selector1").innerHTML).toEqual(fixtures.selector1HTML); expect(document.getElementById("selector1").innerHTML).toEqual(fixtures.selector1HTML);
}); });
@ -96,8 +89,7 @@ describe("Test des filtres de données", () =>
{ {
converter.datasSourceUrl="http://localhost:9876/datas/datas1+tagsfield.csv"; converter.datasSourceUrl="http://localhost:9876/datas/datas1+tagsfield.csv";
await converter.parse(); await converter.parse();
selector.datasViewElt={ id:"selector1"}; selector=new Selector(converter, 5, { id:"selector1" });
selector.datasFieldNb=5;
selector.separator="|"; selector.separator="|";
selector.selector2HTML(); selector.selector2HTML();
expect(document.getElementById("selector1").innerHTML).toEqual(fixtures.selector1HTMLWithSeparator); expect(document.getElementById("selector1").innerHTML).toEqual(fixtures.selector1HTMLWithSeparator);
@ -118,8 +110,7 @@ describe("Test des filtres de données", () =>
return 0; return 0;
}; };
converter.datasSortingFunctions=[{ datasFieldNb: 4, sort:mySort }]; converter.datasSortingFunctions=[{ datasFieldNb: 4, sort:mySort }];
selector.datasViewElt={ id:"selector1"}; selector=new Selector(converter, 4, { id:"selector1" });
selector.datasFieldNb=4;
selector.separator="|"; selector.separator="|";
selector.selector2HTML(); selector.selector2HTML();
expect(document.getElementById("selector1").innerHTML).toEqual(fixtures.selector1HTMLWithFunction); expect(document.getElementById("selector1").innerHTML).toEqual(fixtures.selector1HTMLWithFunction);
@ -139,12 +130,10 @@ describe("Test des filtres de données", () =>
it("Doit retourner false, si la donnée testée ne possède pas le champ sur lequel les données sont filtrées.", () => 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(); selector.selector2HTML();
let selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLInputElement; let selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLInputElement;
selectElement.value="4"; selectElement.value="4";
let data2Test= { // le champ à filtrer ("Famill") est manquant let data2Test= { // le champ à filtrer ("Famille") est manquant
"Z (numéro atomique)" : "53", "Z (numéro atomique)" : "53",
"Élément": "Iode", "Élément": "Iode",
"Symbole": "I", "Symbole": "I",
@ -155,8 +144,6 @@ describe("Test des filtres de données", () =>
it("Doit retourner false, si une donnée testée ne correspond pas à la valeur sélectionnée pour le filtre.", () => 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;
selector.selector2HTML(); selector.selector2HTML();
let selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLInputElement; let selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLInputElement;
selectElement.value="4"; selectElement.value="4";
@ -172,8 +159,6 @@ describe("Test des filtres de données", () =>
it("Doit retourner true, si une donnée testée correspond pas à la valeur sélectionnée pour ce filtre.", () => 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;
selector.selector2HTML(); selector.selector2HTML();
let selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLInputElement; let selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLInputElement;
selectElement.value="4"; selectElement.value="4";
@ -189,8 +174,6 @@ describe("Test des filtres de données", () =>
it("Doit toujours retourner true, si aucune valeur sélectionnée dans la liste.", () => it("Doit toujours retourner true, si aucune valeur sélectionnée dans la liste.", () =>
{ {
selector.datasViewElt={ id:"selector1"};
selector.datasFieldNb=3;
selector.selector2HTML(); selector.selector2HTML();
let data2Test= { let data2Test= {
"Z (numéro atomique)" : "530", "Z (numéro atomique)" : "530",
@ -212,14 +195,12 @@ describe("Test des filtres de données", () =>
converter.datasViewElt={ id:"datas" }; converter.datasViewElt={ id:"datas" };
converter.datasSourceUrl="http://localhost:9876/datas/datas1.csv"; converter.datasSourceUrl="http://localhost:9876/datas/datas1.csv";
await converter.parse(); await converter.parse();
selector=new Selector(converter); selector=new Selector(converter, 3, { id:"selector1" });
selector.selector2HTML();
}); });
it("Le choix d'une option dans un des sélecteurs doit modifier le contenu du tableau pour ne garder que les données correspondantes et les afficher toutes si sélection 0.", () => it("Le choix d'une option dans un des sélecteurs doit modifier le contenu du tableau pour ne garder que les données correspondantes et les afficher toutes si sélection 0.", () =>
{ {
selector.datasViewElt={ id:"selector1"};
selector.datasFieldNb=3;
selector.selector2HTML();
converter.datasSelectors=[selector]; converter.datasSelectors=[selector];
let selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLInputElement; let selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLInputElement;
selectElement.value="4"; selectElement.value="4";
@ -234,12 +215,7 @@ describe("Test des filtres de données", () =>
it("Si plusieurs sélecteurs sont utilisés, seules les données correspondant à tous ces choix doivent être affichées. Il peut n'y avoir aucun résultat.", () => it("Si plusieurs sélecteurs sont utilisés, seules les données correspondant à tous ces choix doivent être affichées. Il peut n'y avoir aucun résultat.", () =>
{ {
selector.datasViewElt={ id:"selector1"}; let selector2=new Selector(converter, 4, { id:"selector2" });
selector.datasFieldNb=3;
selector.selector2HTML();
let selector2=new Selector(converter);
selector2.datasViewElt={ id:"selector2"};
selector2.datasFieldNb=4;
selector2.selector2HTML(); selector2.selector2HTML();
converter.datasSelectors=[selector, selector2]; converter.datasSelectors=[selector, selector2];
let selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLInputElement; let selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLInputElement;
@ -259,8 +235,7 @@ describe("Test des filtres de données", () =>
{ {
converter.datasSourceUrl="http://localhost:9876/datas/datas1+tagsfield.csv"; converter.datasSourceUrl="http://localhost:9876/datas/datas1+tagsfield.csv";
await converter.parse(); await converter.parse();
selector.datasViewElt={ id:"selector1"}; selector=new Selector(converter, 5, { id:"selector1" });
selector.datasFieldNb=5;
selector.separator="|"; selector.separator="|";
selector.selector2HTML(); selector.selector2HTML();
converter.datasSelectors=[selector]; converter.datasSelectors=[selector];
@ -271,19 +246,16 @@ describe("Test des filtres de données", () =>
expect(txtDatasViewsElt).toEqual(fixtures.datasHTMLForSelectTagsField); expect(txtDatasViewsElt).toEqual(fixtures.datasHTMLForSelectTagsField);
}); });
it("Les sélecteurs basés sur un séparateur peuvent fonctionner avec un autre filtre.", async () => it("Les filtres basés sur un séparateur peuvent fonctionner avec un autre filtre.", async () =>
{ {
converter.datasSourceUrl="http://localhost:9876/datas/datas1+tagsfield.csv"; converter.datasSourceUrl="http://localhost:9876/datas/datas1+tagsfield.csv";
await converter.parse(); await converter.parse();
selector.datasViewElt={ id:"selector1"}; selector=new Selector(converter, 4, { id:"selector1" });
selector.datasFieldNb=4;
selector.selector2HTML(); selector.selector2HTML();
let selector2=new Selector(converter); let selector2=new Selector(converter, 5, { id:"selector2" });
selector2.datasViewElt={ id:"selector2"};
selector2.datasFieldNb=5;
selector2.separator="|"; selector2.separator="|";
selector2.selector2HTML(); selector2.selector2HTML();
converter.datasSelectors=[selector, selector2]; converter.datasSelectors=[selector, selector2];
let selectElement=document.getElementById("freeDatas2HTML_selector2") as HTMLInputElement; let selectElement=document.getElementById("freeDatas2HTML_selector2") as HTMLInputElement;
selectElement.value="11"; //="Exemple10" retournant une seule ligne selectElement.value="11"; //="Exemple10" retournant une seule ligne
selectElement.dispatchEvent(new Event('change')); selectElement.dispatchEvent(new Event('change'));