Compare commits

...

9 Commits

19 changed files with 1650 additions and 6910 deletions

View File

@ -14,18 +14,18 @@ module.exports = function(config) {
frameworks: ["jasmine", "karma-typescript"],
// list of files / patterns to load in the browser
files: [ "src/*.ts", "tests/*.ts" , { pattern: 'tests/datas/*', watched: true, included: false, served: true } ],
files: [ "src/**/*.ts", "tests/**/*Spec.ts" , { pattern: 'tests/datas/*', watched: true, included: false, served: true } ],
proxies: { "/datas/": "http://localhost:9876/base/tests/datas/" },
// list of files / patterns to exclude
exclude: [ "src/example*" ],
exclude: [ "src/demo/*.ts" ],
// preprocess matching files before serving them to the browser
// available preprocessors: https://www.npmjs.com/search?q=keywords:karma-preprocessor
preprocessors: {
'src/*.ts': [ 'karma-typescript' ],
'tests/*.ts': [ 'karma-typescript' ]
'src/**/*.ts': [ 'karma-typescript' ],
'tests/**/*Spec.ts': [ 'karma-typescript' ]
},
// test results reporter to use

6917
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "freedatas2html",
"version": "1.0.0",
"version": "1.1.0",
"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": {
@ -12,7 +12,17 @@
"type": "git",
"url": "https://forge.chapril.org/Fab_Blab/freeDatas2HTML"
},
"keywords": ["CSV", "datas", "grid", "HTML", "JSON", "list", "parser", "TABLE", "view" ],
"keywords": [
"CSV",
"datas",
"grid",
"HTML",
"JSON",
"list",
"parser",
"TABLE",
"view"
],
"author": {
"name": "Fabrice PENHOËT",
"email": "fabrice@le-fab-lab.com",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -31,6 +31,7 @@
<li><a href="/withCSV.html">Parser et afficher un fichier CSV prédéfini</a>, avec ajout de filtres multi-critères, moteur de recherche, pagination, compteur de résultats.. Il s'agit de l'exemple le plus complet.</li>
<li><a href="/withJSON.html">Parser et afficher des données JSON</a>, avec ajout d'un filtre, d'un moteur de recherche, pagination et compteur de résultats.</li>
<li><a href="/withHTML.html">Parser et réafficher les données situées dans le code HTML</a> de la page, avec filtre, pagination et adaptation à la taille de l'écran.</li>
<li><a href="/withUL.html">Utilisation d'une extension créant des liens de classement</a>, dans le cas où les données ne sont pas listées dans un tableau.</li>
</ul>
<p>Un lien vers le code source TypeScript est fourni pour chaque exemple, de manière à ce que vous puissiez lire le code, tout en observant le résultat.</p>
</article>

53
public/withUL.html Normal file
View File

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Exemple dutilisation de FreeDatas2HTML pour classer des données, non listées sous forme de tableau.">
<meta name="robots" content="index, follow">
<link rel="stylesheet" href="CSS/paper.min.css">
<link rel="stylesheet" href="CSS/fd2html.css">
<script src="JS/exampleWithUL.app.js" defer></script>
<script src="JS/matomo.js" defer></script>
<title>Classer des données non listées sous forme de tableau HTML - FreeDatas2HTML</title>
</head>
<body class="paper container">
<header id="header" class="text-center">
<h1><a href="/">FreeDatas2HTML</a></h1>
<nav id="menu-principal">
<ul class="inline row flex-center">
<li><a href="./#intro" class="badge warning sm-12 col">Introduction</a></li>
<li><a href="./examples.html#content" class="badge success sm-12 col">Exemples</a></li>
<li><a href="https://forge.chapril.org/Fab_Blab/FreeDatas2HTML" target="_blank" title="accéder au dépôt GIT" rel="noopener" class="badge success sm-12 col">Git</a></li>
</ul>
</nav>
</header>
<h2>Classer des données non listées sous forme de tableau</h2>
<article id="content">
<p>Dans lexemple ci-dessous FreeDatas2HTML liste les données autrement que sous forme de tableau.<br>Dans ce cas, labsence dentêtes de colonne ne permet pas dutiliser le module rendant cliquables ces entêtes pour lancer le classement les données.</p>
<p>Aussi, <a href="https://forge.chapril.org/Fab_Blab/freeDatas2HTML/src/branch/master/src/extensions/exampleWithUL.ts" title="Script de lextension" target="_blank">une extension</a> est utilisée. Elle gère de manière autonome la création et le fonctionnement des liens de classements. Vous pouvez écrire votre propre extension, par exemple si vous préférez proposer une liste SELECT pour choisir le champ de classement. Limportant est que la demande de classement par lutilisateur appelle la fonction dactualisation de FreeDatas2HTML, en lui ayant transmis préalablement le champ sur lequel classer les données et lordre dans lequel les classer.</p>
</article>
<div id="classement">
</div>
<div id="datas">
<p>Si tout se passe bien, ce texte sera remplacé par un tableau de données extraites du fichier CSV.</p>
</div>
<aside>
<p>Les données listées viennent d<a href="./datas/elements-chimiques.csv">un fichier CSV</a> reprenant une partie des informations trouvées <a href="https://fr.wikipedia.org/wiki/%C3%89l%C3%A9ment_chimique#Caract%C3%A9ristiques_des_diff%C3%A9rents_%C3%A9l%C3%A9ments" target="_blank" rel="noopener" title="Wikipédia">sur Wikipédia</a>.</p>
</aside>
<aside>
<p><a href="https://forge.chapril.org/Fab_Blab/freeDatas2HTML/src/branch/master/src/demo/exampleWithUL.ts" target="_blank" title="accéder au code" rel="noopener" class="paper-btn btn-secondary">Code source utilisé par cette page.</a></p>
</aside>
<footer><p>Design : <a href="https://www.getpapercss.com" target="_blank">PaperCSS</a> | <a href="/mentions-legales.html">Contact et mentions légales</a>.</p></footer>
</body>
</html>

View File

@ -239,10 +239,10 @@ export class FreeDatas2HTML
// car l'élément HTML du compteur peut être dans le template du Render.
this.datasCounter2HTML();
// (ré)activation des éventuels champs de classement :
for(let field of this.datasSortingFields)
// (ré)activation des éventuels liens de classement, si ils sont affichés en même temps que le reste des données :
for(let field of this.datasSortingFields)
field.field2HTML();
// Tout réaffichage peut entraîner une modification du nombre de pages (évolution filtres, etc.)
if(this.pagination !== undefined)
this.pagination.pages2HTML();

View File

@ -1,4 +1,3 @@
const { compare }=require('natural-orderby');
const errors=require("./errors.js");
import { SortingFields } from "./interfaces";
import { FreeDatas2HTML } from "./FreeDatas2HTML";
@ -41,6 +40,11 @@ export class SortingField implements SortingFields
return this._fieldsDOMSelector;
}
set order(setting :"asc"|"desc"|undefined )
{
this._order=setting;
}
get order() : "asc"|"desc"|undefined
{
return this._order;

View File

@ -1,4 +1,3 @@
var compare = require('natural-orderby').compare;
var errors = require("./errors.js");
var SortingField = (function () {
function SortingField(converter, datasFieldNb, fieldsDOMSelector) {
@ -39,6 +38,9 @@ var SortingField = (function () {
get: function () {
return this._order;
},
set: function (setting) {
this._order = setting;
},
enumerable: true,
configurable: true
});

View File

@ -0,0 +1,83 @@
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
import { FreeDatas2HTML, Render, SortingField } from "../FreeDatas2HTML";
import { SortingFieldsStandAlone } from "../extensions/SortingFieldsStandAlone";
var initialise = function () { return __awaiter(void 0, void 0, void 0, function () {
var converter, myRender, sortingField1, sortingField2, sortingField3, allFields, e_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
converter = new FreeDatas2HTML("CSV");
converter.parser.setRemoteSource({ url: "http://localhost:8080/datas/elements-chimiques.csv" });
return [4, converter.run()];
case 1:
_a.sent();
converter.fields2Rend = [0, 1, 2, 3];
myRender = new Render();
myRender.settings =
{
allBegining: "<h4>Liste des éléments chimiques :</h4>",
allEnding: "",
linesBegining: "<ul>",
linesEnding: "</ul>",
lineBegining: "<li><ul>",
lineEnding: "</ul></li>",
dataDisplaying: "<li><b>#FIELDNAME :</b> #VALUE</li>",
};
converter.datasRender = myRender;
sortingField1 = new SortingField(converter, 0);
sortingField2 = new SortingField(converter, 1);
sortingField3 = new SortingField(converter, 2);
allFields = new SortingFieldsStandAlone(converter, { id: "classement" });
allFields.datasSortingFields = [sortingField1, sortingField2, sortingField3];
allFields.rendSettings.allBeginning = "<h4>#LABEL</h4><ul>";
allFields.rend2HTML("Champ sur lequel classer les données :");
converter.datasViewElt = { id: "datas" };
converter.refreshView();
return [3, 3];
case 2:
e_1 = _a.sent();
console.error(e_1);
document.getElementById("datas").innerHTML = "<div class=\"alert alert-warning\">D\u00E9sol\u00E9, mais un probl\u00E8me technique emp\u00EAche l'affichage des donn\u00E9es.</div>";
return [3, 3];
case 3: return [2];
}
});
}); };
console.log("Hello, ami développeur :-)\nLe code source TypeScript utilisé pour faire fonctionner cette page est lisible ici : :\nhttps://forge.chapril.org/Fab_Blab/freeDatas2HTML/src/branch/master/src/demo/exampleWithJSON.ts\nUn bug ? Une suggestion ? => fabrice@le-fab-lab.com");
initialise();

View File

@ -0,0 +1,67 @@
import { FreeDatas2HTML } from "../FreeDatas2HTML";
var errors = require("../errors.js");
errors.needSortingFields = "Vous devez fournir au moins un champ de classement valide.";
var SortingFieldsStandAlone = (function () {
function SortingFieldsStandAlone(converter, elt, settings) {
if (settings === void 0) { settings = SortingFieldsStandAlone.defaultSettings; }
this._datasViewElt = { id: "", eltDOM: undefined };
this.datasSortingFields = [];
if (converter.fields.length === 0)
throw new Error(errors.sortingFieldNeedDatas);
this._datasViewElt = FreeDatas2HTML.checkInDOMById(elt);
this._converter = converter;
this.rendSettings = settings;
}
Object.defineProperty(SortingFieldsStandAlone.prototype, "converter", {
get: function () {
return this._converter;
},
enumerable: true,
configurable: true
});
Object.defineProperty(SortingFieldsStandAlone.prototype, "datasViewElt", {
get: function () {
return this._datasViewElt;
},
enumerable: true,
configurable: true
});
SortingFieldsStandAlone.prototype.rend2HTML = function (label) {
if (label === void 0) { label = ""; }
if (this.datasSortingFields.length === 0)
throw new Error(errors.needSortingFields);
var htmlContent = this.rendSettings.allBeginning.replace("#LABEL", label);
for (var _i = 0, _a = this.datasSortingFields; _i < _a.length; _i++) {
var field = _a[_i];
htmlContent += this.rendSettings.fieldBeginning + "<a href='#freeDatas2HTMLSorting" + field.datasFieldNb + "' id='freeDatas2HTMLSorting" + field.datasFieldNb + "'>" + this._converter.fields[field.datasFieldNb] + "</a>" + this.rendSettings.fieldEnding;
}
htmlContent += this.rendSettings.allEnding;
this._datasViewElt.eltDOM.innerHTML = htmlContent;
var _loop_1 = function (field) {
var sortingLink = document.getElementById("freeDatas2HTMLSorting" + field.datasFieldNb);
sortingLink.addEventListener("click", function (e) {
e.preventDefault();
if (field.order === undefined || field.order === "desc")
field.order = "asc";
else
field.order = "desc";
field.converter.datasSortedField = field;
field.converter.refreshView();
});
};
for (var _b = 0, _c = this.datasSortingFields; _b < _c.length; _b++) {
var field = _c[_b];
_loop_1(field);
}
};
SortingFieldsStandAlone.defaultSettings = {
allBeginning: "<span>#LABEL</span><ul>",
allEnding: "</ul>",
fieldBeginning: "<li>",
fieldEnding: "</li>",
};
return SortingFieldsStandAlone;
}());
export { SortingFieldsStandAlone };
export { FreeDatas2HTML, SortingField } from "../FreeDatas2HTML";
export { errors };

51
src/demo/exampleWithUL.ts Normal file
View File

@ -0,0 +1,51 @@
import { FreeDatas2HTML, Pagination, Render, SearchEngine, Selector, SortingField } from "../FreeDatas2HTML";
import { SortingFieldsStandAlone } from "../extensions/SortingFieldsStandAlone";
const initialise=async () =>
{
try
{
// Création d'un convertisseur parsant les données d'un fichier CSV "distant"
const converter=new FreeDatas2HTML("CSV");
converter.parser.setRemoteSource({ url:"http://localhost:8080/datas/elements-chimiques.csv" });
// Parsage des données, qui ne sont pas encore affichées :
await converter.run();
// On affiche que certains champs :
converter.fields2Rend=[0,1,2,3];
// Les données sont listées en dehors d'un tableau :
const myRender=new Render();
myRender.settings=
{
allBegining:"<h4>Liste des éléments chimiques :</h4>",
allEnding:"",
linesBegining:"<ul>",
linesEnding:"</ul>",
lineBegining:"<li><ul>",
lineEnding:"</ul></li>",
dataDisplaying:"<li><b>#FIELDNAME :</b> #VALUE</li>",
};
converter.datasRender=myRender;
// Désignation des champs permettant de classer les données en dehors de l'affichage des données
let sortingField1=new SortingField(converter, 0);
let sortingField2=new SortingField(converter, 1);
let sortingField3=new SortingField(converter, 2);
const allFields=new SortingFieldsStandAlone(converter,{ id:"classement" });
allFields.datasSortingFields=[sortingField1,sortingField2, sortingField3];
allFields.rendSettings.allBeginning="<h4>#LABEL</h4><ul>";
allFields.rend2HTML("Champ sur lequel classer les données :") ;
// Affichage initial :
converter.datasViewElt={ id:"datas" };
converter.refreshView();
}
catch(e)
{
console.error(e);
document.getElementById("datas")!.innerHTML=`<div class="alert alert-warning">Désolé, mais un problème technique empêche l'affichage des données.</div>`;
}
}
console.log("Hello, ami développeur :-)\nLe code source TypeScript utilisé pour faire fonctionner cette page est lisible ici : :\nhttps://forge.chapril.org/Fab_Blab/freeDatas2HTML/src/branch/master/src/demo/exampleWithJSON.ts\nUn bug ? Une suggestion ? => fabrice@le-fab-lab.com");
initialise();

View File

@ -0,0 +1,87 @@
// Cette classe est une alternative à l'utilisation directe de SortingField.
// Ici, les liens de classement sont créés dans un élément du DOM externe à celui affichant les données
import { DOMElement } from "../interfaces";
import { FreeDatas2HTML, SortingField } from "../FreeDatas2HTML";
const errors=require("../errors.js");
errors.needSortingFields="Vous devez fournir au moins un champ de classement valide.";
interface SortingFieldsSettings
{
allBeginning: string;
allEnding: string;
fieldBeginning: string;
fieldEnding: string;
}
export class SortingFieldsStandAlone
{
private _converter: FreeDatas2HTML;
private _datasViewElt: DOMElement={ id: "", eltDOM: undefined };
public datasSortingFields: SortingField[]=[]; // SortingField refusera les champs non valides
public rendSettings: SortingFieldsSettings;
static readonly defaultSettings=
{
allBeginning: "<span>#LABEL</span><ul>",
allEnding: "</ul>",
fieldBeginning: "<li>",
fieldEnding: "</li>",
};
constructor(converter: FreeDatas2HTML, elt: DOMElement, settings: SortingFieldsSettings=SortingFieldsStandAlone.defaultSettings)
{
// Ne peut être appelé avant d'avoir récupéré la liste des champs :
if(converter.fields.length === 0)
throw new Error(errors.sortingFieldNeedDatas);
// Test l'existence dans le DOM de l'élément devant afficher les options de classement :
this._datasViewElt=FreeDatas2HTML.checkInDOMById(elt);
this._converter=converter;
this.rendSettings=settings;
}
get converter() : FreeDatas2HTML
{
return this._converter;
}
get datasViewElt() : DOMElement
{
return this._datasViewElt;
}
public rend2HTML(label:string="") : void
{
// Au moins un champ de classement valide doit avoir été fourni :
if(this.datasSortingFields.length === 0)
throw new Error(errors.needSortingFields);
// Arrivé ici, il y a au moins un lien de classement à injecter :
let htmlContent=this.rendSettings.allBeginning.replace("#LABEL", label);
for(let field of this.datasSortingFields)
{
htmlContent+=this.rendSettings.fieldBeginning+"<a href='#freeDatas2HTMLSorting"+field.datasFieldNb+"' id='freeDatas2HTMLSorting"+field.datasFieldNb+"'>"+this._converter.fields[field.datasFieldNb]+"</a>"+this.rendSettings.fieldEnding;
}
htmlContent+=this.rendSettings.allEnding;
this._datasViewElt.eltDOM!.innerHTML=htmlContent;// "!" car existence de l'élement dans le DOM a été testé dans le constructeur.
// Les liens venant d'êtres injectés dans le DOM, il reste à les rendre actifs :
for(let field of this.datasSortingFields)
{
let sortingLink=document.getElementById("freeDatas2HTMLSorting"+field.datasFieldNb);
sortingLink!.addEventListener("click", function(e) // "!" car je sais que sortingLink existe, venant de le créer.
{
e.preventDefault();
if(field.order === undefined || field.order === "desc")
field.order="asc";
else
field.order="desc";
field.converter.datasSortedField=field;
field.converter.refreshView();
});
}
}
}
// Utile au script de tests :
export { FreeDatas2HTML, SortingField } from "../FreeDatas2HTML";
export { errors };

View File

@ -0,0 +1,108 @@
import { errors, FreeDatas2HTML, SortingField, SortingFieldsStandAlone } from "../../src/extensions/SortingFieldsStandAlone";
const fixtures=require("../fixtures.js");
describe("Test des liens de classement (hors données).", () =>
{
let converter: FreeDatas2HTML;
let sortingFields: SortingFieldsStandAlone;
beforeEach( async () =>
{
document.body.insertAdjacentHTML("afterbegin", fixtures.datasViewEltHTML);
converter=new FreeDatas2HTML("CSV");
converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1.csv" });
converter.datasViewElt={ id:"datas" };
await converter.run(); // parsage + 1er affichage des données
});
afterEach( () =>
{
document.body.removeChild(document.getElementById("fixture"));
});
describe("Test des données reçues pour configurer les liens de classement.", () =>
{
it("Doit générer une erreur, si initialisé avant que les champs de données ne soient connus.", () =>
{
converter=new FreeDatas2HTML("CSV");
// Pas lancé converter.run(), donc les données n'ont pas été parsées :
expect(() => { return new SortingFieldsStandAlone(converter, { id:"selector1" }); }).toThrowError(errors.sortingFieldNeedDatas);
});
it("Doit générer une erreur, si initialisé avec l'id d'un élément n'existant pas dans le DOM", () =>
{
expect(() => { return new SortingFieldsStandAlone(converter, { id:"dontExist" }); }).toThrowError(errors.converterElementNotFound+"dontExist");
});
it("Si tous les paramètres sont ok, ils doivent être acceptés.", () =>
{
expect(() => { sortingFields=new SortingFieldsStandAlone(converter, { id:"selector1" }); }).not.toThrowError();
expect(sortingFields.converter).toEqual(converter);
expect(sortingFields.datasViewElt.id).toEqual("selector1");
});
});
describe("Création et action des liens de classement", () =>
{
let sortingField1: SortingField, sortingField2: SortingField;
beforeEach(() =>
{
sortingFields=new SortingFieldsStandAlone(converter, { id:"selector1" });
sortingField1=new SortingField(converter, 0);
sortingField2=new SortingField(converter, 2);
sortingFields.datasSortingFields=[sortingField1,sortingField2];
});
it("Doit générer une erreur, si lancé avant d'avoir fourni au moins un champ de classement.", () =>
{
sortingFields=new SortingFieldsStandAlone(converter, { id:"selector1" });
expect(() => { return sortingFields.rend2HTML() }).toThrowError(errors.needSortingFields);
});
it("Doit générer une liste de liens correspondant aux champs fournis .", () =>
{
sortingFields.rend2HTML();
let expectedHTML="<span></span><ul><li>"+fixtures.sortingColumn1HTML+"</li><li>"+fixtures.sortingColumn2HTML+"</li></ul>";
expect(document.getElementById("selector1").innerHTML).toEqual(expectedHTML);
// Idem avec des paramètres d'affichage :
sortingFields.rendSettings=
{
allBeginning: "<h4>#LABEL</h4><p>",
allEnding: "</p>",
fieldBeginning: "",
fieldEnding: " | ",
};
expectedHTML="<h4>Classer les données :</h4><p>"+fixtures.sortingColumn1HTML+" | "+fixtures.sortingColumn2HTML+" | </p>";
sortingFields.rend2HTML("Classer les données :");
expect(document.getElementById("selector1").innerHTML).toEqual(expectedHTML);
});
it("Lorsqu'ils sont cliqués, les liens de classement doivent transmettre l'information au convertisseur + lui demander d'actualiser l'affichage.", () =>
{
sortingFields.rend2HTML();
let getLinks=document.querySelectorAll("ul li a") as NodeListOf<HTMLElement>;
spyOn(converter, "refreshView");
getLinks[0].click();// tri ascendant 1er champ
expect(sortingField1.converter.datasSortedField).toEqual(sortingField1);
expect(sortingField1.converter.datasSortedField.order).toEqual("asc");
expect(converter.refreshView).toHaveBeenCalledTimes(1);
getLinks[1].click();// tri ascendant mais sur le second champ
expect(sortingField2.converter.datasSortedField).toEqual(sortingField2);
expect(sortingField2.converter.datasSortedField.order).toEqual("asc");
expect(converter.refreshView).toHaveBeenCalledTimes(2);
getLinks[0].click();// tri descendant sur le 1er champ
expect(sortingField1.converter.datasSortedField).toEqual(sortingField1);
expect(sortingField1.converter.datasSortedField.order).toEqual("desc");
expect(converter.refreshView).toHaveBeenCalledTimes(3);
getLinks[0].click();// de nouveau ascendant
expect(sortingField1.converter.datasSortedField).toEqual(sortingField1);
expect(sortingField1.converter.datasSortedField.order).toEqual("asc");
expect(converter.refreshView).toHaveBeenCalledTimes(4);
});
});
});

View File

@ -8,6 +8,7 @@ module.exports =
exampleWithCSV: "./src/demo/exampleWithCSV.ts",
exampleWithHTML: "./src/demo/exampleWithHTML.ts",
exampleWithJSON: "./src/demo/exampleWithJSON.ts",
exampleWithUL: "./src/demo/exampleWithUL.ts",
exampleWithUserFile: "./src/demo/exampleWithUserFile.ts"
},
output: