blob: 4148f40fa884540c049b1d3cbc7fc6bf683d0a94 [file] [log] [blame]
import './index';
import { $, $$ } from 'common-sk/modules/dom';
import { deepCopy } from 'common-sk/modules/object';
import sinon from 'sinon';
import { expect } from 'chai';
import { setUpElementUnderTest } from '../../../infra-sk/modules/test_util';
import { entry } from './test_data';
import { testOnlySetSettings } from '../settings';
import { ByBlameEntrySk } from './byblameentry-sk';
import { ByBlameEntry } from '../rpc_types';
describe('byblameentry-sk', () => {
const newInstance = setUpElementUnderTest<ByBlameEntrySk>('byblameentry-sk');
const newByBlameEntrySk = (byBlameEntry: ByBlameEntry, opts: {baseRepoUrl?: string, corpus?: string} = {}) => {
testOnlySetSettings({
baseRepoURL: opts.baseRepoUrl || 'https://skia.googlesource.com/skia.git',
});
return newInstance((el) => {
el.byBlameEntry = byBlameEntry;
el.corpus = opts.corpus || 'gm';
});
};
let clock: sinon.SinonFakeTimers;
beforeEach(() => {
// This is necessary to make commit ages deterministic, and is set to 50
// seconds after Elisa's commit in the 'full example' test case below.
clock = sinon.useFakeTimers(1573149864000); // Nov 7, 2019 6:04:24 PM GMT
});
afterEach(() => {
clock.restore();
});
describe('full example', () => {
it('renders correctly', async () => {
// This is a comprehensive example of a blame group with multiple
// untriaged digests that could have originated from two different
// commits, and includes a list of affected tests along with links to an
// example untriaged digest for each affected test.
const byBlameEntrySk = newByBlameEntrySk(entry);
expectTriageLinkEquals(
byBlameEntrySk,
'112 untriaged digests',
// This server-generated blame ID is a colon-separated list of the
// commit hashes blamed for these untriaged digests.
'/search?blame=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb&corpus=gm',
);
expectBlamesListEquals(
byBlameEntrySk,
[{
linkText: 'bbbbbbb',
linkHref: 'https://skia.googlesource.com/skia.git/+show/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
commitMessage: 'One glyph() to rule them all!!!',
author: 'Elisa (elisa@example.com)',
age: '6h',
}, {
linkText: 'aaaaaaa',
linkHref: 'https://skia.googlesource.com/skia.git/+show/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
commitMessage: 'flesh out blendmodes through Screen',
author: 'Joe (joe@example.com)',
age: '5m',
}],
);
expectNumTestsAffectedEquals(byBlameEntrySk, '7 tests affected.');
expectAffectedTestsTableEquals(
byBlameEntrySk,
[{
test: 'aarectmodes',
numDigests: 50,
exampleLinkText: 'c6476baec94eb6a5071606575318e4df',
exampleLinkHref: '/detail?test=aarectmodes&digest=c6476baec94eb6a5071606575318e4df',
}, {
test: 'aaxfermodes',
numDigests: 32,
exampleLinkText: '4acfd6b3a3943cc5d75cd22e966ae6f1',
exampleLinkHref: '/detail?test=aaxfermodes&digest=4acfd6b3a3943cc5d75cd22e966ae6f1',
}, {
test: 'hairmodes',
numDigests: 21,
exampleLinkText: 'f9e20c63b5ce3b58d9b6a90fa3e7224c',
exampleLinkHref: '/detail?test=hairmodes&digest=f9e20c63b5ce3b58d9b6a90fa3e7224c',
}, {
test: 'imagefilters_xfermodes',
numDigests: 5,
exampleLinkText: '47644613317040264fea6fa815af32e8',
exampleLinkHref: '/detail?test=imagefilters_xfermodes&digest=47644613317040264fea6fa815af32e8',
}, {
test: 'lattice2',
numDigests: 2,
exampleLinkText: '16e41798ecd59b1523322a57b49cc17f',
exampleLinkHref: '/detail?test=lattice2&digest=16e41798ecd59b1523322a57b49cc17f',
}, {
test: 'xfermodes',
numDigests: 1,
exampleLinkText: '8fbee03f794c455c4e4842ec2736b744',
exampleLinkHref: '/detail?test=xfermodes&digest=8fbee03f794c455c4e4842ec2736b744',
}, {
test: 'xfermodes3',
numDigests: 1,
exampleLinkText: 'fed2ff29abe371fc0ec1b2c65dfb3949',
exampleLinkHref: '/detail?test=xfermodes3&digest=fed2ff29abe371fc0ec1b2c65dfb3949',
}],
);
});
});
describe('triage link', () => {
it('renders link text in singular if there is just 1 digest', async () => {
const testByBlameEntry = deepCopy(entry);
testByBlameEntry.nDigests = 1;
const byBlameEntrySk = newByBlameEntrySk(testByBlameEntry);
expectTriageLinkEquals(
byBlameEntrySk,
'1 untriaged digest',
'/search?blame=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb&corpus=gm',
);
});
it('includes the right corpus in the link href', async () => {
const byBlameEntrySk = newByBlameEntrySk(entry, { corpus: 'svg' });
expectTriageLinkEquals(
byBlameEntrySk,
'112 untriaged digests',
'/search?blame=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb&corpus=svg',
);
});
});
describe('blamelist', () => {
it('shows "No blamelist" message if there are 0 blames', async () => {
const testByBlameEntry = deepCopy(entry);
testByBlameEntry.commits = [];
const byBlameEntrySk = newByBlameEntrySk(testByBlameEntry);
expectBlamesListEquals(byBlameEntrySk, []);
});
it('points commit links to GitHub if repo is hosted there', async () => {
const byBlameEntrySk = newByBlameEntrySk(
entry,
{ baseRepoUrl: 'https://github.com/google/skia' },
);
expectBlamesListEquals(
byBlameEntrySk,
[{
linkText: 'bbbbbbb',
linkHref: 'https://github.com/google/skia/commit/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
commitMessage: 'One glyph() to rule them all!!!',
author: 'Elisa (elisa@example.com)',
age: '6h',
}, {
linkText: 'aaaaaaa',
linkHref: 'https://github.com/google/skia/commit/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
commitMessage: 'flesh out blendmodes through Screen',
author: 'Joe (joe@example.com)',
age: '5m',
}],
);
});
it('shows empty commit messages if Git log is empty/missing', async () => {
const byBlameEntrySk = newByBlameEntrySk(entry);
expectBlamesListEquals(
byBlameEntrySk,
[{
linkText: 'bbbbbbb',
linkHref: 'https://skia.googlesource.com/skia.git/+show/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
commitMessage: '',
author: 'Elisa (elisa@example.com)',
age: '6h',
}, {
linkText: 'aaaaaaa',
linkHref: 'https://skia.googlesource.com/skia.git/+show/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
commitMessage: '',
author: 'Joe (joe@example.com)',
age: '5m',
}],
);
});
});
describe('affected tests', () => {
it('renders correctly with nTests = 0', async () => {
const testByBlameEntry = deepCopy(entry);
testByBlameEntry.nTests = 0;
testByBlameEntry.affectedTests = [];
const byBlameEntrySk = newByBlameEntrySk(testByBlameEntry);
expectNumTestsAffectedEquals(byBlameEntrySk, '0 tests affected.');
expectAffectedTestsTableEquals(byBlameEntrySk, []);
});
it('renders correctly with nTests = 1 and 0 affected tests', async () => {
const testByBlameEntry = deepCopy(entry);
testByBlameEntry.nTests = 1;
testByBlameEntry.affectedTests = [];
const byBlameEntrySk = newByBlameEntrySk(testByBlameEntry);
expectNumTestsAffectedEquals(byBlameEntrySk, '1 test affected.');
expectAffectedTestsTableEquals(byBlameEntrySk, []);
});
it('renders correctly with nTests = 2 and 0 affected tests', async () => {
const testByBlameEntry = deepCopy(entry);
testByBlameEntry.nTests = 2;
testByBlameEntry.affectedTests = [];
const byBlameEntrySk = newByBlameEntrySk(testByBlameEntry);
expectNumTestsAffectedEquals(byBlameEntrySk, '2 tests affected.');
expectAffectedTestsTableEquals(byBlameEntrySk, []);
});
it('renders correctly with nTests = 2 and one affected test', async () => {
const testByBlameEntry = deepCopy(entry);
testByBlameEntry.nTests = 2;
testByBlameEntry.affectedTests = [{
test: 'aarectmodes',
num: 5,
sample_digest: 'c6476baec94eb6a5071606575318e4df',
}];
const byBlameEntrySk = newByBlameEntrySk(testByBlameEntry);
expectNumTestsAffectedEquals(byBlameEntrySk, '2 tests affected.');
expectAffectedTestsTableEquals(
byBlameEntrySk,
[{
test: 'aarectmodes',
numDigests: 5,
exampleLinkText: 'c6476baec94eb6a5071606575318e4df',
exampleLinkHref:
'/detail?test=aarectmodes&digest=c6476baec94eb6a5071606575318e4df',
}],
);
});
});
});
const expectTriageLinkEquals = (byBlameEntrySk: ByBlameEntrySk, text: string, href: string) => {
const triageLink = $$<HTMLAnchorElement>('a.triage', byBlameEntrySk)!;
expect(triageLink.innerText).to.contain(text);
expect(triageLink.href).to.have.string(href);
};
interface ExpectedBlame {
linkText: string;
linkHref: string;
commitMessage: string;
author: string;
age: string;
}
const expectBlamesListEquals = (byBlameEntrySk: ByBlameEntrySk, expectedBlames: ExpectedBlame[]) => {
const noBlameList = $$<HTMLParagraphElement>('p.no-blamelist', byBlameEntrySk)!;
const blames = $<HTMLLIElement>('ul.blames li', byBlameEntrySk);
if (!expectedBlames.length) {
expect(noBlameList.innerText).to.contain('No blamelist.');
expect(blames).to.be.empty;
} else {
expect(noBlameList).to.be.null;
expect(blames).to.have.length(expectedBlames.length);
for (let i = 0; i < expectedBlames.length; i++) {
const linkText = $$<HTMLAnchorElement>('a', blames[i])!.innerText;
const linkHref = $$<HTMLAnchorElement>('a', blames[i])!.href;
const commitMessage = $$<HTMLElement>('.commit-message', blames[i])!.innerText;
const author = $$<HTMLElement>('.author', blames[i])!.innerText;
const age = $$<HTMLElement>('.age', blames[i])!.innerText;
expect(linkText).to.contain(expectedBlames[i].linkText);
expect(linkHref).to.equal(expectedBlames[i].linkHref);
expect(commitMessage).to.contain(expectedBlames[i].commitMessage);
expect(author).to.contain(expectedBlames[i].author);
expect(age).to.contain(expectedBlames[i].age);
}
}
};
const expectNumTestsAffectedEquals = (byBlameEntrySk: ByBlameEntrySk, numTestsAffected: string) => expect($$<HTMLElement>('.num-tests-affected', byBlameEntrySk)!.innerText)
.to.contain(numTestsAffected);
interface ExpectedRow {
test: string;
numDigests: number;
exampleLinkText: string;
exampleLinkHref: string;
}
const expectAffectedTestsTableEquals = (byBlameEntrySk: ByBlameEntrySk, expectedRows: ExpectedRow[]) => {
const actualRows = $('.affected-tests tbody tr');
expect(actualRows.length).to.equal(expectedRows.length);
for (let i = 0; i < expectedRows.length; i++) {
const test = $$<HTMLElement>('.test', actualRows[i])!.innerText;
const numDigests = +$$<HTMLElement>('.num-digests', actualRows[i])!.innerText;
const exampleLinkText = $$<HTMLAnchorElement>('a.example-link', actualRows[i])!.innerText;
const exampleLinkHref = $$<HTMLAnchorElement>('a.example-link', actualRows[i])!.href;
expect(test).to.contain(expectedRows[i].test);
expect(numDigests).to.equal(expectedRows[i].numDigests);
expect(exampleLinkText).to.contain(expectedRows[i].exampleLinkText);
expect(exampleLinkHref).to.contain(expectedRows[i].exampleLinkHref);
}
};