import { ParserForHTML as Parser } from "../src/ParserForHTML"; const errors=require("../src/errors.js"); const fixtures=require("./fixtures.js"); describe("Tests du parseur HTML", () => { let parser: Parser, datasElt: HTMLElement; beforeEach( () => { parser=new Parser(); document.body.insertAdjacentHTML('afterbegin', "
"); datasElt=document.getElementById("datas"); }); afterEach( () => { document.body.removeChild(document.getElementById("datas")); }); it("Doit avoir créé une instance du parseur.", () => { expect(parser).toBeInstanceOf(Parser); expect(parser.datasRemoteSource.url).toEqual(""); }); it("Ne doit pas accepter de valeurs vides pour les sélecteurs CSS.", () => { expect(() => { return parser.fieldsSelector=""; }).toThrowError(errors.parserSelectorsIsEmpty); expect(() => { return parser.rowsSelector=" "; }).toThrowError(errors.parserSelectorsIsEmpty); expect(() => { return parser.datasSelector=" "; }).toThrowError(errors.parserSelectorsIsEmpty); }); describe("Accès à des données distantes.", () => { it("Doit générer une erreur, si l'accès aux données distantes ne fonctionne pas.", async () => { parser.setRemoteSource({ url:"http://localhost:9876/datas/datas.htm" }); // une seule lettre vous manque... await expectAsync(parser.parse()).toBeRejectedWith(new Error(errors.parserRemoteFail)); }); it("Si le parseur est appelé avec une url correcte, le DOM du document distant doit être enregistré.", async () => { parser.setRemoteSource({ url:"http://localhost:9876/datas/datas.html" }); await parser.parse(); const parserDOM=new DOMParser(); const htmlString="
Champ 1Champ 2
"; const doc=parserDOM.parseFromString(htmlString, "text/html"); expect(parser.document2Parse).toEqual(doc); }); it("Si des options de connexion distante sont fournies, elles doivent être utilisées.", async () => { spyOn(window, "fetch").and.callThrough(); parser.setRemoteSource({ url:"http://localhost:9876/datas/datas.html", headers: [{ key:"token", value:"1234" }, { key:"userName", value:"Toto" }], withCredentials:true }); await parser.parse(); const headers=new Headers(); headers.append("token", "1234"); headers.append("userName", "Toto"); expect(window.fetch).toHaveBeenCalledWith("http://localhost:9876/datas/datas.html", { method: "GET", headers: headers, credentials: "include" }); }); }); describe("Extraction des données du document.", () => { it("Doit générer une erreur si aucun élément n'est trouvé dans le document pour les sélecteurs CSS fournis pour les noms de champs.", async () => { await expectAsync(parser.parse()).toBeRejectedWith(new Error(errors.parserElementsNotFound+"table > thead > tr > th")); // = valeurs par défaut, mais rien dans le DOM datasElt.innerHTML=fixtures.htmlParserDatas; await expectAsync(parser.parse()).not.toBeRejectedWith(new Error(errors.parserElementsNotFound+"table > thead > tr > th")); parser.fieldsSelector="ul#dontExist > li"; // n'existe pas dans ce qui a été injecté await expectAsync(parser.parse()).toBeRejectedWith(new Error(errors.parserElementsNotFound+"ul#dontExist > li")); }); it("Les noms de champ vides ou en doublon doivent être ignorés et les erreurs reportées.", async () => { datasElt.innerHTML=""; parser.fieldsSelector="ul > li"; await parser.parse(); expect(parser.parseResults.fields).toEqual(["Champ1","Champ2"]); expect(parser.parseResults.errors).toEqual([{ row:-1, message: errors.parserFieldNameFail}, { row:-1, message: errors.parserFieldNameFail}]); }); it("Doit générer une erreur, si aucun nom de champ valide n'est trouvé dans le document.", async () => { datasElt.innerHTML=""; parser.fieldsSelector="ul > li"; await expectAsync(parser.parse()).toBeRejectedWith(new Error(errors.parserFieldsNotFound)); }); it("Les espaces entourant les noms de champs doivent être supprimés.", async () => { datasElt.innerHTML=fixtures.htmlParserDatas; await parser.parse(); expect(parser.parseResults.fields).toEqual(["Z (numéro atomique)","Élément", "Symbole", "Famille", "Mots-clés"]); }); it("Si des champs en trop sont trouvés dans une ligne de données, ils doivent être ignorés. Idem pour les champs absents. Ces anomalies doivent être reportées.", async () => { datasElt.innerHTML=fixtures.htmlParserDatasBadFields; // un "td" manquant en ligne 0 et un en trop en ligne 1 await parser.parse(); expect(parser.parseResults.datas).toEqual([{"Z (numéro atomique)":"1","Élément":"Hydrogène", Symbole:"H", Famille:"Non-métal" }, {"Z (numéro atomique)":"2","Élément":"Hélium", Symbole:"He", Famille:"Gaz noble", "Mots-clés":"Mot-clé2" }, {"Z (numéro atomique)":"3","Élément":"Lithium", Symbole:"Li", Famille:"Métal alcalin", "Mots-clés":"Mot-clé2,Mot-clé1" }, {"Z (numéro atomique)":"4","Élément":"Béryllium", Symbole:"Be", Famille:"Métal alcalino-terreux", "Mots-clés":"Mot-clé3" }]); expect(parser.parseResults.errors[0]).toEqual({row:0,message:errors.parserNumberOfFieldsFail}); expect(parser.parseResults.errors[1]).toEqual({row:1,message:errors.parserNumberOfFieldsFail}); }); it("Le fait qu'aucune donnée ne soit trouvée ne doit pas générer une erreur.", async () => { datasElt.innerHTML="
Champ1Champ2
"; await expectAsync(parser.parse()).toBeResolved(); }); it("Une ligne n'ayant aucune donnée sera ignorée et l'erreur reportée. Les valeurs vides sont par contre acceptées.", async () => { datasElt.innerHTML=fixtures.htmlParserDatasEmptyLine; // avant dernière ligne sans "td", "Mots-clé" vide pour la 1ière ligne. await parser.parse(); expect(parser.parseResults.datas).toEqual([{"Z (numéro atomique)":"1","Élément":"Hydrogène", Symbole:"H", Famille:"Non-métal", "Mots-clés":"" }, {"Z (numéro atomique)":"2","Élément":"Hélium", Symbole:"He", Famille:"Gaz noble", "Mots-clés":"Mot-clé2" }, {"Z (numéro atomique)":"3","Élément":"Lithium", Symbole:"Li", Famille:"Métal alcalin", "Mots-clés":"Mot-clé2,Mot-clé1" }, {"Z (numéro atomique)":"4","Élément":"Béryllium", Symbole:"Be", Famille:"Métal alcalino-terreux", "Mots-clés":"Mot-clé3" }]); expect(parser.parseResults.errors[1]).toEqual({row:3,message:errors.parserLineWithoutDatas});// errors[0] = erreur nombre de champs 1ère ligne }); it("Si le code HTML fourni est ok, aucune erreur de lecture ne doit être reportée.", async () => { datasElt.innerHTML=fixtures.htmlParserDatas; await parser.parse(); expect(parser.parseResults.datas).toEqual([{"Z (numéro atomique)":"1","Élément":"Hydrogène", Symbole:"H", Famille:"Non-métal", "Mots-clés":"" }, {"Z (numéro atomique)":"2","Élément":"Hélium", Symbole:"He", Famille:"Gaz noble", "Mots-clés":"Mot-clé2" }, {"Z (numéro atomique)":"3","Élément":"Lithium", Symbole:"Li", Famille:"Métal alcalin", "Mots-clés":"Mot-clé2,Mot-clé1" }, {"Z (numéro atomique)":"4","Élément":"Béryllium", Symbole:"Be", Famille:"Métal alcalino-terreux", "Mots-clés":"Mot-clé3" }]); expect(parser.parseResults.errors.length).toEqual(0); }); }); });