Added PHPUnit code coverage log output and chart in information tab.
Issue #148.
This commit is contained in:
parent
b67ee92f7e
commit
c5ce085371
108
public/assets/js/build-plugins/phpunit-coverage.js
Normal file
108
public/assets/js/build-plugins/phpunit-coverage.js
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
var coveragePlugin = ActiveBuild.UiPlugin.extend({
|
||||||
|
id: 'build-phpunit-coverage-chart',
|
||||||
|
css: 'col-xs-12',
|
||||||
|
title: Lang.get('coverage'),
|
||||||
|
lastData: null,
|
||||||
|
displayOnUpdate: false,
|
||||||
|
rendered: false,
|
||||||
|
chartData: null,
|
||||||
|
|
||||||
|
register: function () {
|
||||||
|
var self = this;
|
||||||
|
var query = ActiveBuild.registerQuery('phpunit-coverage', -1, {num_builds: 10, key: 'phpunit-coverage'})
|
||||||
|
|
||||||
|
$(window).on('phpunit-coverage', function (data) {
|
||||||
|
self.onUpdate(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(window).on('build-updated', function (data) {
|
||||||
|
if (data.queryData && data.queryData.status > 1 && !self.rendered) {
|
||||||
|
query();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
var self = this;
|
||||||
|
var container = $('<div id="phpunit-coverage" style="width: 100%; height: 300px"></div>');
|
||||||
|
|
||||||
|
container.append('<canvas id="phpunit-coverage-chart" style="width: 100%; height: 300px"></canvas>');
|
||||||
|
|
||||||
|
$(document).on('shown.bs.tab', function () {
|
||||||
|
$('#build-phpunit-coverage-chart').hide();
|
||||||
|
self.drawChart();
|
||||||
|
});
|
||||||
|
|
||||||
|
return container;
|
||||||
|
},
|
||||||
|
|
||||||
|
onUpdate: function (e) {
|
||||||
|
this.lastData = e.queryData;
|
||||||
|
this.displayChart();
|
||||||
|
},
|
||||||
|
|
||||||
|
displayChart: function () {
|
||||||
|
var self = this;
|
||||||
|
var builds = this.lastData;
|
||||||
|
self.rendered = true;
|
||||||
|
|
||||||
|
self.chartData = {
|
||||||
|
labels: [],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: Lang.get('classes'),
|
||||||
|
strokeColor: "#555299",
|
||||||
|
pointColor: "#555299",
|
||||||
|
data: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: Lang.get('methods'),
|
||||||
|
strokeColor: "#00A65A",
|
||||||
|
pointColor: "#00A65A",
|
||||||
|
data: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: Lang.get('lines'),
|
||||||
|
strokeColor: "#8AA4AF",
|
||||||
|
pointColor: "#8AA4AF",
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i in builds) {
|
||||||
|
self.chartData.labels.push(Lang.get('build') + ' ' + builds[i].build_id);
|
||||||
|
self.chartData.datasets[0].data.push(builds[i].meta_value.classes);
|
||||||
|
self.chartData.datasets[1].data.push(builds[i].meta_value.methods);
|
||||||
|
self.chartData.datasets[2].data.push(builds[i].meta_value.lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.drawChart();
|
||||||
|
},
|
||||||
|
|
||||||
|
drawChart: function () {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if ($('#information').hasClass('active') && self.chartData && self.lastData) {
|
||||||
|
$('#build-phpunit-coverage-chart').show();
|
||||||
|
|
||||||
|
var ctx = $("#phpunit-coverage-chart").get(0).getContext("2d");
|
||||||
|
var chart = new Chart(ctx, {
|
||||||
|
responsive: true
|
||||||
|
});
|
||||||
|
|
||||||
|
Chart.defaults.global.responsive = true;
|
||||||
|
|
||||||
|
chart.Line(self.chartData, {
|
||||||
|
scaleOverride : true,
|
||||||
|
scaleSteps : 10,
|
||||||
|
scaleStepWidth : 10,
|
||||||
|
scaleStartValue : 0,
|
||||||
|
datasetFill: false,
|
||||||
|
multiTooltipTemplate: "<%=datasetLabel%>: <%= value %>"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ActiveBuild.registerPlugin(new coveragePlugin());
|
|
@ -122,7 +122,11 @@ var Build = Class.extend({
|
||||||
if (renderOrder) {
|
if (renderOrder) {
|
||||||
renderOrder = JSON.parse(renderOrder);
|
renderOrder = JSON.parse(renderOrder);
|
||||||
} else {
|
} else {
|
||||||
renderOrder = ['build-lines-chart', 'build-warnings-chart'];
|
renderOrder = [
|
||||||
|
'build-lines-chart',
|
||||||
|
'build-warnings-chart',
|
||||||
|
'build-phpunit-coverage-chart'
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var idx in renderOrder) {
|
for (var idx in renderOrder) {
|
||||||
|
|
|
@ -199,12 +199,15 @@ PHP Censor',
|
||||||
|
|
||||||
'chart_display' => 'This chart will display once the build has completed.',
|
'chart_display' => 'This chart will display once the build has completed.',
|
||||||
|
|
||||||
'build' => 'Build',
|
'build' => 'Build',
|
||||||
'lines' => 'Lines',
|
'lines' => 'Lines',
|
||||||
|
'classes' => 'Classes',
|
||||||
|
'methods' => 'Methods',
|
||||||
'comment_lines' => 'Comment lines',
|
'comment_lines' => 'Comment lines',
|
||||||
'noncomment_lines' => 'Non-Comment lines',
|
'noncomment_lines' => 'Non-Comment lines',
|
||||||
'logical_lines' => 'Logical Lines',
|
'logical_lines' => 'Logical Lines',
|
||||||
'lines_of_code' => 'Lines of code',
|
'lines_of_code' => 'Lines of code',
|
||||||
|
'coverage' => 'PHPUnit code coverage',
|
||||||
'build_log' => 'Build log',
|
'build_log' => 'Build log',
|
||||||
'quality_trend' => 'Quality trend',
|
'quality_trend' => 'Quality trend',
|
||||||
'codeception_errors' => 'Codeception errors',
|
'codeception_errors' => 'Codeception errors',
|
||||||
|
|
|
@ -192,12 +192,15 @@ PHP Censor',
|
||||||
|
|
||||||
'chart_display' => 'Этот график будет показан после окончания сборки.',
|
'chart_display' => 'Этот график будет показан после окончания сборки.',
|
||||||
|
|
||||||
'build' => 'Сборка',
|
'build' => 'Сборка',
|
||||||
'lines' => 'Строк',
|
'lines' => 'Строк',
|
||||||
|
'classes' => 'Классов',
|
||||||
|
'methods' => 'Методов',
|
||||||
'comment_lines' => 'Строк комментариев',
|
'comment_lines' => 'Строк комментариев',
|
||||||
'noncomment_lines' => 'Строк некомментариев',
|
'noncomment_lines' => 'Строк некомментариев',
|
||||||
'logical_lines' => 'Строк логики',
|
'logical_lines' => 'Строк логики',
|
||||||
'lines_of_code' => 'Строк кода',
|
'lines_of_code' => 'Строк кода',
|
||||||
|
'coverage' => 'Покрытие кода тестами PHPUnit',
|
||||||
'build_log' => 'Лог сборки',
|
'build_log' => 'Лог сборки',
|
||||||
'quality_trend' => 'Тенденция качества',
|
'quality_trend' => 'Тенденция качества',
|
||||||
'codeception_errors' => 'Ошибки Codeception',
|
'codeception_errors' => 'Ошибки Codeception',
|
||||||
|
|
|
@ -121,6 +121,7 @@ class PhpUnitOptions
|
||||||
*/
|
*/
|
||||||
if (isset($this->options['coverage']) && $this->options['coverage']) {
|
if (isset($this->options['coverage']) && $this->options['coverage']) {
|
||||||
$this->addArgument('coverage-html', $this->location);
|
$this->addArgument('coverage-html', $this->location);
|
||||||
|
$this->addArgument('coverage-text');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -141,7 +142,7 @@ class PhpUnitOptions
|
||||||
* @param string $argumentName
|
* @param string $argumentName
|
||||||
* @param string $argumentValue
|
* @param string $argumentValue
|
||||||
*/
|
*/
|
||||||
public function addArgument($argumentName, $argumentValue)
|
public function addArgument($argumentName, $argumentValue = null)
|
||||||
{
|
{
|
||||||
if (isset($this->arguments[$argumentName])) {
|
if (isset($this->arguments[$argumentName])) {
|
||||||
if (!is_array($this->arguments[$argumentName])) {
|
if (!is_array($this->arguments[$argumentName])) {
|
||||||
|
|
|
@ -136,7 +136,7 @@ class PhpUnit extends Plugin implements ZeroConfigPluginInterface
|
||||||
|
|
||||||
// Save the results into a log file
|
// Save the results into a log file
|
||||||
$logFile = @tempnam($buildPath, 'jLog_');
|
$logFile = @tempnam($buildPath, 'jLog_');
|
||||||
$options->addArgument('log-'.$logFormat, $logFile);
|
$options->addArgument('log-' . $logFormat, $logFile);
|
||||||
|
|
||||||
// Removes any current configurations files
|
// Removes any current configurations files
|
||||||
$options->removeArgument('configuration');
|
$options->removeArgument('configuration');
|
||||||
|
@ -152,12 +152,25 @@ class PhpUnit extends Plugin implements ZeroConfigPluginInterface
|
||||||
$arguments = $this->builder->interpolate($options->buildArgumentString());
|
$arguments = $this->builder->interpolate($options->buildArgumentString());
|
||||||
$cmd = $this->findBinary('phpunit') . ' %s %s';
|
$cmd = $this->findBinary('phpunit') . ' %s %s';
|
||||||
$success = $this->builder->executeCommand($cmd, $arguments, $directory);
|
$success = $this->builder->executeCommand($cmd, $arguments, $directory);
|
||||||
|
$output = $this->builder->getLastOutput();
|
||||||
|
|
||||||
$this->processResults($logFile, $logFormat);
|
$this->processResults($logFile, $logFormat);
|
||||||
|
|
||||||
$config = $this->builder->getSystemConfig('php-censor');
|
$config = $this->builder->getSystemConfig('php-censor');
|
||||||
|
|
||||||
if ($options->getOption('coverage')) {
|
if ($options->getOption('coverage')) {
|
||||||
|
preg_match(
|
||||||
|
'#Classes:[\s]*(.*?)%[^M]*?Methods:[\s]*(.*?)%[^L]*?Lines:[\s]*(.*?)\%#s',
|
||||||
|
$output,
|
||||||
|
$matches
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->build->storeMeta('phpunit-coverage', [
|
||||||
|
'classes' => !empty($matches[1]) ? $matches[1] : '0.00',
|
||||||
|
'methods' => !empty($matches[2]) ? $matches[2] : '0.00',
|
||||||
|
'lines' => !empty($matches[3]) ? $matches[3] : '0.00',
|
||||||
|
]);
|
||||||
|
|
||||||
$this->builder->logSuccess(
|
$this->builder->logSuccess(
|
||||||
sprintf(
|
sprintf(
|
||||||
"\nPHPUnit successful.\nYou can use coverage report: %s",
|
"\nPHPUnit successful.\nYou can use coverage report: %s",
|
||||||
|
@ -190,7 +203,10 @@ class PhpUnit extends Plugin implements ZeroConfigPluginInterface
|
||||||
$this->build->storeMeta('phpunit-errors', $parser->getFailures());
|
$this->build->storeMeta('phpunit-errors', $parser->getFailures());
|
||||||
|
|
||||||
foreach ($parser->getErrors() as $error) {
|
foreach ($parser->getErrors() as $error) {
|
||||||
$severity = $error['severity'] == $parser::SEVERITY_ERROR ? BuildError::SEVERITY_CRITICAL : BuildError::SEVERITY_HIGH;
|
$severity = $error['severity'] ==
|
||||||
|
$parser::SEVERITY_ERROR ?
|
||||||
|
BuildError::SEVERITY_CRITICAL :
|
||||||
|
BuildError::SEVERITY_HIGH;
|
||||||
$this->build->reportError(
|
$this->build->reportError(
|
||||||
$this->builder, 'php_unit', $error['message'], $severity, $error['file'], $error['line']
|
$this->builder, 'php_unit', $error['message'], $severity, $error['file'], $error['line']
|
||||||
);
|
);
|
||||||
|
|
|
@ -140,8 +140,9 @@ class PhpUnitResultJson extends PhpUnitResult
|
||||||
/**
|
/**
|
||||||
* Saves additional info for a failing test
|
* Saves additional info for a failing test
|
||||||
*
|
*
|
||||||
* @param array $data
|
|
||||||
* @param array $event
|
* @param array $event
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function getFileAndLine($event)
|
protected function getFileAndLine($event)
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,6 +37,7 @@ class PhpUnitOptionsTest extends \PHPUnit\Framework\TestCase
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'coverage-html' => '/location',
|
'coverage-html' => '/location',
|
||||||
|
'coverage-text' => null,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
@ -49,6 +50,7 @@ class PhpUnitOptionsTest extends \PHPUnit\Framework\TestCase
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'coverage-html' => '/location',
|
'coverage-html' => '/location',
|
||||||
|
'coverage-text' => null,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
|
Loading…
Reference in a new issue