Skip to content

Instantly share code, notes, and snippets.

@jawache
Created December 12, 2016 17:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jawache/a9e896de2e1584d4926ae3c8fa3b95e1 to your computer and use it in GitHub Desktop.
Save jawache/a9e896de2e1584d4926ae3c8fa3b95e1 to your computer and use it in GitHub Desktop.
Attempt at making a jasmine matcher that matches some HTML with some expected HTML (kinda works)
import {html2json} from 'html2json';
import * as _ from "lodash";
import {minify} from 'html-minifier';
----
toHaveHtml: () => {
let failures = [];
class Failure {
constructor(public depth: number,
public path: string[],
public actual: string,
public expected: string) {
}
getMessage(): string {
let pathString = this.path.join('.') || '<root>';
return `${pathString}:
actual: ${this.actual}
expected: ${this.expected}
`
}
}
function addFailure(path, actual, expected) {
return failures.push(new Failure(path.length, path, actual, expected));
}
function addToPath(path, value) {
return path.concat([value]);
}
function isSimilar(path, actual, expected) {
if (_.isArray(actual) && _.isArray(expected)) {
// Each element in the expected array should match an element in the actual array
for (let i = 0; i < expected.length; i++) {
let exEl = expected[i];
let found = false;
for (let actEl of actual) {
if (isSimilar(addToPath(path, i), actEl, exEl)) {
// We've found a match in the actual array, don't bother checking the
// other actual elements.
found = true;
break;
}
}
if (!found) {
// We've searched the whole actual array and can't find a match, this is
// a failure.
addFailure(path, JSON.stringify(actual, null, 2), JSON.stringify(expected, null, 2));
return false;
}
}
// If we are here then all items int he expected array have been found
// in the actual array.
return true;
} else if (_.isObject(actual) && _.isObject(expected)) {
// Every key in the expected object should exist in the actual object
// and every value should also match.
for (let key in expected) {
if ((key === "text") && expected[key] === " ") {
// Ignore this node, this is just a new line.
continue;
}
if (!_.has(actual, key)) {
// We can't find the same key in the actual object, this is a failure.
addFailure(path, JSON.stringify(actual, null, 2), JSON.stringify(expected, null, 2));
return false;
} else {
if (!isSimilar(addToPath(path, key), actual[key], expected[key])) {
// The value for the key is not the same in expected vs. actual, this is failure
addFailure(path, JSON.stringify(actual, null, 2), JSON.stringify(expected, null, 2));
return false;
}
}
}
// All keys and values match for actual vs expected, this is pass.
return true;
} else {
// If we are here then this is a scalar value comparison so we use lodash to perform this.
if (!_.isEqual(actual, expected)) {
addFailure(path, JSON.stringify(actual, null, 2), JSON.stringify(expected, null, 2));
return false;
} else {
return true;
}
}
}
return {
compare: (el: DebugElement, expected: string) => {
// debugger;
let actualHtml = el.nativeElement.innerHTML.trim();
actualHtml = actualHtml.replace(/\n/g, '');
actualHtml = actualHtml.replace(/\s+/g, ' ');
let expectedHtml = expected.trim();
expectedHtml = expectedHtml.replace(/\n/g, '');
expectedHtml = expectedHtml.replace(/\s+/g, ' ');
let actualJson = html2json(actualHtml);
console.log(JSON.stringify(actualJson, null, 2));
let expectedJson = html2json(expectedHtml);
console.log(JSON.stringify(expectedJson, null, 2));
return {
pass: isSimilar([], actualJson, expectedJson),
message: () => {
let failure = _.orderBy(failures, ['depth'], ['desc'])[0];
return failure.getMessage();
}
};
}
};
},
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment