blob: 6128b728758803c3f1fb55d81db05a4fc4e35da9 [file]
<!DOCTYPE html>
<!--
Copyright 2019 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>chromium-coverage.js test</title>
<script src="../bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="../bower_components/web-component-tester/browser.js"></script>
<script src="../src/main/resources/static/coverage.js"></script>
<test-fixture id="coverage-fixture">
<template>
<chromium-coverage></chromium-coverage>
</template>
</test-fixture>
<script>
suite('<code coverage>', () => {
// Sample change info used for testing.
const sampleChangeInfo = {
host: 'chromium-review.googlesource.com',
project: 'chromium/src',
changeNum: 12345,
patchNum: 2,
};
// Sample coverage data fetched from coverage serviced; used for testing.
const sampleCoverageData = {
data: {
files: [
{
path: 'base/test.cc',
lines: [
{
line: 10,
count: 10,
},
{
line: 11,
count: 0,
},
{
line: 12,
count: 0,
},
]
}
]
}
};
// Sample coverage ranges that match with the sample coverage data.
const sampleCoverageRanges = {
'base/test.cc': [
{
side: 'right',
type: 'COVERED',
code_range: {
start_line: 10,
end_line: 10,
}
},
{
side: 'right',
type: 'NOT_COVERED',
code_range: {
start_line: 11,
end_line: 12,
}
},
]
};
setup(() => {
coverageClient = new window.CoverageClient();
sinon.stub(window, 'fetch');
});
teardown(() => {
window.fetch.restore();
});
test('get normalized host', () => {
assert.equal('chromium-review.googlesource.com',
coverageClient.getNormalizedHost(
'chromium-review.googlesource.com'));
assert.equal('chromium-review.googlesource.com',
coverageClient.getNormalizedHost(
'canary-chromium-review.googlesource.com'));
});
test('parse project name from gerrit url', () => {
assert.equal('chromium/src',
coverageClient.parseProjectFromPathName(
'/c/chromium/src/+/1369646'));
assert.equal('chromium/src',
coverageClient.parseProjectFromPathName(
'/c/chromium/src/+/1369646'));
assert.equal('chromium/src',
coverageClient.parseProjectFromPathName(
'/c/chromium/src/+/1369646/3'));
assert.equal('chromium/src',
coverageClient.parseProjectFromPathName(
'/c/chromium/src/+/1369646/3/'));
assert.equal('chromium/src',
coverageClient.parseProjectFromPathName(
'/c/chromium/src/+/1369646/3/base/test.cc'));
assert.equal('chromium/src',
coverageClient.parseProjectFromPathName(
'/c/chromium/src/+/1369646/3/base/base/test.cc/'));
});
test('fetch coverage data for chromium', async () => {
const response = new window.Response(JSON.stringify(sampleCoverageData),
{ status: 200 });
window.fetch.returns(Promise.resolve(response));
const responseJson = await coverageClient.fetchCoverageJsonData(
sampleChangeInfo);
assert.equal('https://findit-for-me.appspot.com/coverage/api/' +
'coverage-data?host=chromium-review.googlesource.com&' +
'project=chromium%2Fsrc&change=12345&patchset=2&' +
'format=json&concise=1',
window.fetch.getCall(0).args[0]);
assert.deepEqual(sampleCoverageData, responseJson);
});
test('fetch coverage data for libassistant', async () => {
const response = new window.Response(JSON.stringify(sampleCoverageData),
{ status: 200 });
window.fetch.returns(Promise.resolve(response));
const responseJson = await coverageClient.fetchCoverageJsonData({
host: 'libassistant-internal-review.googlesource.com',
project: 'libassistant/internal',
changeNum: 12345,
patchNum: 2,
});
assert.equal('https://gob-coverage.googleplex.com/coverage/api/' +
'coverage-data?host=libassistant-internal-review.' +
'googlesource.com&project=libassistant%2Finternal&' +
'change=12345&patchset=2&format=json&concise=1',
window.fetch.getCall(0).args[0]);
assert.deepEqual(sampleCoverageData, responseJson);
});
test('fetch coverage data for unknown host', async () => {
const response = new window.Response(JSON.stringify(sampleCoverageData),
{ status: 200 });
window.fetch.returns(Promise.resolve(response));
const responseJson = await coverageClient.fetchCoverageJsonData({
host: 'unknown-review.googlesource.com',
project: 'unknown/src',
changeNum: 12345,
patchNum: 2,
});
assert.equal('https://findit-for-me.appspot.com/coverage/api/' +
'coverage-data?host=unknown-review.googlesource.com&' +
'project=unknown%2Fsrc&change=12345&patchset=2&' +
'format=json&concise=1',
window.fetch.getCall(0).args[0]);
assert.deepEqual(sampleCoverageData, responseJson);
});
test('parse coverage ranges', () => {
const coverageRanges =
coverageClient.convertResponseJsonToCoverageRanges(
sampleCoverageData);
assert.deepEqual(sampleCoverageRanges, coverageRanges);
});
test('coverage data is cached', async () => {
sinon.stub(coverageClient, 'getNormalizedHost');
sinon.stub(coverageClient, 'parseProjectFromPathName');
sinon.stub(coverageClient, 'fetchCoverageJsonData');
coverageClient.getNormalizedHost.returns(sampleChangeInfo.host);
coverageClient.parseProjectFromPathName.returns(sampleChangeInfo.project);
coverageClient.coverageData.changeInfo = sampleChangeInfo;
coverageClient.coverageData.rangesPromise = new Promise(
function(resolve, reject) {
resolve(sampleCoverageRanges);
});
const providedData = await coverageClient.provideCoverageData(
12345, 'base/test.cc', 'PARENT', 2);
assert.equal(false, coverageClient.fetchCoverageJsonData.called);
assert.deepEqual(sampleCoverageRanges['base/test.cc'], providedData);
coverageClient.getNormalizedHost.restore();
coverageClient.parseProjectFromPathName.restore();
coverageClient.fetchCoverageJsonData.restore();
});
test('coverage data is not cached', async () => {
sinon.stub(coverageClient, 'getNormalizedHost');
sinon.stub(coverageClient, 'parseProjectFromPathName');
sinon.stub(coverageClient, 'fetchCoverageJsonData');
coverageClient.getNormalizedHost.returns(sampleChangeInfo.host);
coverageClient.parseProjectFromPathName.returns(sampleChangeInfo.project);
coverageClient.fetchCoverageJsonData.returns(sampleCoverageData);
const providedData = await coverageClient.provideCoverageData(
12345, 'base/test.cc', 'PARENT', 2)
assert.deepEqual(sampleChangeInfo,
coverageClient.coverageData.changeInfo);
assert.deepEqual(sampleCoverageRanges['base/test.cc'], providedData);
coverageClient.getNormalizedHost.restore();
coverageClient.parseProjectFromPathName.restore();
coverageClient.fetchCoverageJsonData.restore();
});
test('prefetch coverage data', async () => {
sinon.stub(coverageClient, 'getNormalizedHost');
sinon.stub(coverageClient, 'fetchCoverageJsonData');
coverageClient.getNormalizedHost.returns(sampleChangeInfo.host);
coverageClient.fetchCoverageJsonData.returns(sampleCoverageData);
coverageClient.prefetchCoverageData(
{'project': 'chromium/src','_number': 12345}, {'_number': 2});
assert.deepEqual(sampleChangeInfo,
coverageClient.coverageData.changeInfo);
assert.deepEqual(sampleCoverageRanges,
await coverageClient.coverageData.rangesPromise);
coverageClient.getNormalizedHost.restore();
coverageClient.fetchCoverageJsonData.restore();
});
// This test tests the scenario that if two requests were issued to fetch
// coverage data for different change/patchset, the eventual coverage ranges
// won't be overwritten incorrectly.
test('racing condition between multiple fetches', async () => {
let changeInfo1 = JSON.parse(JSON.stringify(sampleChangeInfo));
changeInfo1.patchNum = 1;
let changeInfo2 = JSON.parse(JSON.stringify(sampleChangeInfo));
changeInfo2.patchNum = 2;
ranges1 = {
'base/test.cc': [
{
side: 'right',
type: 'NOT_COVERED',
code_range: {
start_line: 10,
end_line: 10,
}
}
]
};
const fetchPromise1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(ranges1);
}, 100);
});
ranges2 = {
'base/test.cc': [
{
side: 'right',
type: 'COVERED',
code_range: {
start_line: 20,
end_line: 20,
}
}
]
}
const fetchPromise2 = Promise.resolve(ranges2);
sinon.stub(coverageClient, 'getNormalizedHost');
sinon.stub(coverageClient, 'parseProjectFromPathName');
sinon.stub(coverageClient, 'fetchCoverageRanges');
coverageClient.getNormalizedHost.returns(sampleChangeInfo.host);
coverageClient.parseProjectFromPathName.returns(sampleChangeInfo.project);
coverageClient.fetchCoverageRanges.withArgs(changeInfo1).returns(
fetchPromise1)
coverageClient.fetchCoverageRanges.withArgs(changeInfo2).returns(
fetchPromise2)
coverageClient.prefetchCoverageData({
'project': changeInfo1.project,
'_number': changeInfo1.changeNum
}, {
'_number': changeInfo1.patchNum
});
coverageClient.provideCoverageData(changeInfo2.changeNum, 'base/test.cc',
'PARENT', changeInfo2.patchNum);
// Even though the first request finishes after the second request, it
// shouldn't overwrite the coverage ranges promise because the user has
// moved on to a different change/patchset.
await fetchPromise1, fetchPromise2;
assert.deepEqual(ranges2,
await coverageClient.coverageData.rangesPromise);
coverageClient.getNormalizedHost.restore();
coverageClient.parseProjectFromPathName.restore();
coverageClient.fetchCoverageRanges.restore();
})
});
</script>