Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/GPH/Gitlab.pm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
# 2023-12-23 - added blacklist for more specific path definition
# 2024-02-10 - namespaced module, bugfixes and unit tests
# 2024-02-11 - constructor now requires named arguments
# 2024-02-18 - added support for default codeowners
#------------------------------------------------------------------------------
package GPH::Gitlab;

Expand Down
2 changes: 1 addition & 1 deletion lib/GPH/PHPUnit.pm
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ sub new {
bless $self, $class;

if (exists($args{baseline}) and defined $args{baseline}) {
open(my $fh, '<', $args{baseline}) or die "unable to open phpunit baseline file $args{baseline} $!";
open my $fh, '<', $args{baseline} or die $!;
my @lines = ();

while (<$fh>) {
Expand Down
10 changes: 6 additions & 4 deletions lib/GPH/PHPUnit/Stats.pm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#
# Revisions: 2024-02-10 - created
# 2024-02-11 - constructor now requires named arguments
# 2024-02-19 - fixed rounding bug
#------------------------------------------------------------------------------
package GPH::PHPUnit::Stats;

Expand Down Expand Up @@ -95,21 +96,22 @@ sub summary {
# Returns: string
sub footer {
my $self = shift;
my $percentage = sprintf("%.2f", $self->{lines}->percentage());

if ($self->{lines}->percentage() > $self->{threshold}) {
if ($percentage > $self->{threshold}) {
return(sprintf(
"\n ! [NOTE] Your coverage is %.2f%% percentage points over the required coverage.\n !%sConsider increasing the required coverage percentage.\n",
($self->{lines}->percentage() - $self->{threshold}),
' ' x 8
))
));
}

if ($self->{lines}->percentage() < $self->{threshold}) {
if ($percentage < $self->{threshold}) {
return(sprintf(
"\n ! [FAILED] Your coverage is %.2f%% percentage points under the required coverage.\n !%sPlease increase coverage by improving your tests.\n",
($self->{threshold} - $self->{lines}->percentage()),
' ' x 10
))
));
}
};

Expand Down
2 changes: 1 addition & 1 deletion lib/GPH/Psalm.pm
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ sub getConfigWithIssueHandlers {
my ($handlers) = $dom->findnodes('//*[local-name()="issueHandlers"]');

foreach my $exclude ($blacklist) {
next if not defined $exclude;
next unless defined $exclude;

my ($remove) = $handlers->findnodes("//*[local-name()=\"${exclude}\"]");

Expand Down
5 changes: 4 additions & 1 deletion t/share/Gitlab/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@
.gitlab-ci.yml

^[gamma][3] @teams/gamma
/tests/Unit/Service/
/tests/Unit/Service/

[delta]
/tests/Unit/Command
11 changes: 11 additions & 0 deletions t/share/PHPStan/phpstan-includes.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
includes:
- /includes/

parameters:
level: 4
tmpDir: var
parallel:
maximumNumberOfProcesses: 4
paths:
- src/Service/PhraseTagService.php
- src/Command/AbstractPhraseKeyCommand.php
10 changes: 4 additions & 6 deletions t/unit/GPH/Composer.t
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ use Test2::Tools::Spec;

use Data::Dumper;

local $SIG{__WARN__} = sub {};

use constant CLASSMAP_FILE => './t/share/Composer/autoload_classmap.php';

describe "class `$CLASS`" => sub {
Expand All @@ -35,12 +33,12 @@ describe "class `$CLASS`" => sub {
};

tests "classmap not found" => sub {
ok(dies{$CLASS->new((classmap => 'foo.php'))}, 'died with classmap not found') or note ($@);
ok(dies {$CLASS->new((classmap => 'foo.php'))}, 'died with classmap not found') or note($@);
};

tests "mandatory config options" => sub {
ok(dies{$CLASS->new(())}, 'died with missing classmap option') or note ($@);
ok(lives{$CLASS->new((classmap => CLASSMAP_FILE))}, 'lived with mandatory options') or note ($@);
ok(dies {$CLASS->new(())}, 'died with missing classmap option') or note($@);
ok(lives {$CLASS->new((classmap => CLASSMAP_FILE))}, 'lived with mandatory options') or note($@);
};
};

Expand Down Expand Up @@ -69,7 +67,7 @@ describe 'test matching' => sub {
};

tests 'match' => sub {
my ( $object, $exception, $warnings, $result );
my ($object, $exception, $warnings, $result);

$exception = dies {
$warnings = warns {
Expand Down
20 changes: 14 additions & 6 deletions t/unit/GPH/Gitlab.t
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ use Data::Dumper;

use constant CODEOWNERS_FILE => './t/share/Gitlab/CODEOWNERS';

local $SIG{__WARN__} = sub {};

describe "class `$CLASS`" => sub {
my %config = (
codeowners => CODEOWNERS_FILE,
Expand Down Expand Up @@ -68,15 +66,15 @@ describe "class `$CLASS`" => sub {
item '/src/Service/';
end;
},
'GetPaths call correct'
'GetPaths call correct'
);

is($object->getBlacklistPaths(),
array {
item '/src/Command/Config/ConfigPhraseKeyCommand.php';
end;
},
'GetBlacklistPaths call correct'
'GetBlacklistPaths call correct'
);

is($object->getCommaSeparatedPathList(), '/src/Command/,/src/Service/', 'GetCommaSeparatedPathList call correct');
Expand All @@ -90,7 +88,7 @@ describe "class `$CLASS`" => sub {
item '/src/Command/';
end;
},
'Intersect call correct'
'Intersect call correct'
);

is($object->match('/src/Service/'), 1, 'Match call match correct');
Expand All @@ -102,21 +100,30 @@ describe "class `$CLASS`" => sub {
};

describe 'test codeowners syntax' => sub {
my ($object, %config, $owner, $expected_paths, $exception, $warnings);
my ($object, %config, $owner, $expected_paths, $expected_blacklist, $exception, $warnings);

case 'section with default owner' => sub {
$owner = '@teams/beta';
$expected_paths = [ '/src/Command/Config/ConfigPhraseKeyCommand.php', '/src/DependencyInjection/' ];
$expected_blacklist = [];
};

case 'optional section with default owner and required approvals' => sub {
$owner = '@teams/gamma';
$expected_paths = [ '/tests/Unit/Service/' ];
$expected_blacklist = [];
};

case 'owner with email' => sub {
$owner = 'john@doe.com';
$expected_paths = [ '/src/Service/' ];
$expected_blacklist = [];
};

case 'non defined owner' => sub {
$owner = 'jane@doe.com';
$expected_paths = [ ];
$expected_blacklist = [];
};

tests 'module get paths' => sub {
Expand All @@ -135,6 +142,7 @@ describe 'test codeowners syntax' => sub {
is($exception, undef, 'no exception thrown');
is($warnings, 0, 'no warnings generated');
is($object->getPaths(), $expected_paths, 'paths correct') or diag Dumper($object);
is($object->getBlacklistPaths(), $expected_blacklist, 'blacklist correct') or diag Dumper($object);
};
};

Expand Down
8 changes: 3 additions & 5 deletions t/unit/GPH/Infection.t
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,15 @@ use warnings;
use Test2::V0 -target => 'GPH::Infection';
use Test2::Tools::Spec;

local $SIG{__WARN__} = sub {};

describe "class `$CLASS`" => sub {
tests 'it can be instantiated' => sub {
can_ok($CLASS, 'new');
};

tests "mandatory config options" => sub {
ok(dies{$CLASS->new((msi => '9.0'))}, 'died with missing covered') or note ($@);
ok(dies{$CLASS->new((covered => '9.0'))}, 'died with missing msi') or note ($@);
ok(lives{$CLASS->new((msi => '9.0', covered => '9.0'))}, 'lives with mandatory options') or note ($@);
ok(dies {$CLASS->new((msi => '9.0'))}, 'died with missing covered') or note($@);
ok(dies {$CLASS->new((covered => '9.0'))}, 'died with missing msi') or note($@);
ok(lives {$CLASS->new((msi => '9.0', covered => '9.0'))}, 'lives with mandatory options') or note($@);
};
};

Expand Down
14 changes: 6 additions & 8 deletions t/unit/GPH/PHPMD.t
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,23 @@ use warnings;
use Test2::V0 -target => 'GPH::PHPMD';
use Test2::Tools::Spec;

local $SIG{__WARN__} = sub {};

describe "class `$CLASS`" => sub {
tests 'it can be instantiated' => sub {
can_ok($CLASS, 'new');
};

tests "mandatory config options" => sub {
ok(dies{$CLASS->new((owner =>'@teams/alpha'))}, 'died with missing cyclo level option') or note ($@);
ok(dies{$CLASS->new((cyclo_level => 8))}, 'died with missing owner option') or note ($@);
ok(lives{$CLASS->new((owner =>'@teams/alpha', cyclo_level => 8))}, 'lived with mandatory options') or note ($@);
ok(dies {$CLASS->new((owner => '@teams/alpha'))}, 'died with missing cyclo level option') or note($@);
ok(dies {$CLASS->new((cyclo_level => 8))}, 'died with missing owner option') or note($@);
ok(lives {$CLASS->new((owner => '@teams/alpha', cyclo_level => 8))}, 'lived with mandatory options') or note($@);
};

tests 'instantation' => sub {
my ($object, $exception, $warnings);

$exception = dies {
$warnings = warns {
$object = $CLASS->new((owner =>'@teams/alpha', cyclo_level => 3));
$object = $CLASS->new((owner => '@teams/alpha', cyclo_level => 3));
};
};

Expand All @@ -49,11 +47,11 @@ describe "class `$CLASS`" => sub {

describe "class `$CLASS` config generation" => sub {
tests 'compare config contents' => sub {
my $object = $CLASS->new((owner =>'@teams/alpha', cyclo_level => 3));
my $object = $CLASS->new((owner => '@teams/alpha', cyclo_level => 3));
my $config = $object->getConfig();
my $mock;

open (my $fh, '<', './t/share/PHPMD/phpmd-ruleset.xml');
open(my $fh, '<', './t/share/PHPMD/phpmd-ruleset.xml');
{
local $/;
$mock = <$fh>;
Expand Down
26 changes: 20 additions & 6 deletions t/unit/GPH/PHPStan.t
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,15 @@ use Test2::V0 -target => 'GPH::PHPStan';
use Test2::Tools::Spec;
use Data::Dumper;

local $SIG{__WARN__} = sub {};

describe "class `$CLASS`" => sub {
tests 'it can be instantiated' => sub {
can_ok($CLASS, 'new');
};

tests 'dies without correct config' => sub {
ok(dies{$CLASS->new(('level' => 4))}, 'died with paths missing') or note ($@);
ok(dies{$CLASS->new(('paths' => []))}, 'died with level missing') or note ($@);
ok(lives{$CLASS->new(('level' => 4, 'paths' => []))}, 'lives with mandatory config settings') or note ($@);
ok(dies {$CLASS->new(('level' => 4))}, 'died with paths missing') or note($@);
ok(dies {$CLASS->new(('paths' => []))}, 'died with level missing') or note($@);
ok(lives {$CLASS->new(('level' => 4, 'paths' => []))}, 'lives with mandatory config settings') or note($@);
};
};

Expand All @@ -43,6 +41,22 @@ describe "class `$CLASS` instantiation values" => sub {
$config_path = './t/share/PHPStan/phpstan-min.neon';
};

case 'includes, no baseline' => sub {
%config = (
level => 4,
paths => \@paths,
includes => [ '/includes/' ],
);

$expected_level = 4;
$expected_baseline = undef;
$expected_ignoredDirectories = undef;
$expected_cacheDir = 'var';
$expected_includes = [ '/includes/' ];
$expected_threads = 4;
$config_path = './t/share/PHPStan/phpstan-includes.neon';
};

case 'config with empty array for ignores' => sub {
%config = (
level => 4,
Expand Down Expand Up @@ -126,7 +140,7 @@ describe "class `$CLASS` instantiation values" => sub {
is($exception, undef, 'no exception thrown', Dumper($object));
is($warnings, 0, 'no warnings generated', Dumper($object));

open (my $fh, '<', $config_path);
open(my $fh, '<', $config_path);
{
local $/;
$mock = <$fh>;
Expand Down
11 changes: 5 additions & 6 deletions t/unit/GPH/PHPUnit.t
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ use constant CLASSMAP_FILE => './t/share/Composer/autoload_classmap.php';
use constant PHPUNIT_OUTPUT_FILE => './t/share/PHPUnit/phpunit-output.txt';
use constant PHPUNIT_BASELINE_FILE => './t/share/PHPUnit/phpunit-baseline.txt';

local $SIG{__WARN__} = sub {};

describe "class `$CLASS`" => sub {
tests 'it can be instantiated' => sub {
can_ok($CLASS, 'new');
Expand All @@ -29,8 +27,8 @@ describe "class `$CLASS`" => sub {
};

tests "baseline file not found" => sub {
ok(dies{$CLASS->new((codeowners => CODEOWNERS_FILE, owner =>'@teams/alpha', baseline => 'foo.txt'))}, 'died with baseline not found') or note ($@);
ok(lives{$CLASS->new((codeowners => CODEOWNERS_FILE, owner =>'@teams/alpha', classmap => CLASSMAP_FILE, baseline => PHPUNIT_BASELINE_FILE))}, 'lives with correct baseline') or note ($@);
ok(dies {$CLASS->new((codeowners => CODEOWNERS_FILE, owner => '@teams/alpha', baseline => 'foo.txt'))}, 'died with baseline not found') or note($@);
ok(lives {$CLASS->new((codeowners => CODEOWNERS_FILE, owner => '@teams/alpha', classmap => CLASSMAP_FILE, baseline => PHPUNIT_BASELINE_FILE))}, 'lives with correct baseline') or note($@);
};
};

Expand All @@ -43,6 +41,7 @@ describe 'configuration options' => sub {
owner => $owner,
classmap => CLASSMAP_FILE,
codeowners => CODEOWNERS_FILE,
baseline => undef,
);

$expected_threshold = 0.0;
Expand All @@ -55,7 +54,7 @@ describe 'configuration options' => sub {
classmap => CLASSMAP_FILE,
codeowners => CODEOWNERS_FILE,
threshold => 95.5,
excludes => ['.gitlab-ci.yml'],
excludes => [ '.gitlab-ci.yml' ],
baseline => PHPUNIT_BASELINE_FILE
);

Expand Down Expand Up @@ -106,7 +105,7 @@ describe "parsing phpunit report output" => sub {
owner => '@teams/alpha',
classmap => CLASSMAP_FILE,
codeowners => CODEOWNERS_FILE,
excludes => ['.gitlab-ci.yml'],
excludes => [ '.gitlab-ci.yml' ],
baseline => PHPUNIT_BASELINE_FILE
);

Expand Down
2 changes: 0 additions & 2 deletions t/unit/GPH/PHPUnit/Stat.t
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ use Test2::Tools::Spec;

use Data::Dumper;

local $SIG{__WARN__} = sub {};

describe "class `$CLASS`" => sub {
tests 'it can be instantiated' => sub {
can_ok($CLASS, 'new');
Expand Down
Loading