Skip to content

Commit

Permalink
refactor xml helper
Browse files Browse the repository at this point in the history
- xml helper now uses named arguments
- added tests for xml helper
  • Loading branch information
wickedOne committed Feb 12, 2024
1 parent 5eebf30 commit 8650921
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 47 deletions.
38 changes: 19 additions & 19 deletions lib/GPH/PHPMD.pm
Original file line number Diff line number Diff line change
Expand Up @@ -45,33 +45,33 @@ sub new {
#
# Returns: ruleset.xml config file string
sub getConfig {
my $self = shift;
my $self = shift;

my $ruleset = $self->{generator}->buildElement('ruleset', undef, undef, (
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
'xsi:schemaLocation' => 'http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd',
'xsi:noNamespaceSchemaLocation' => 'http://pmd.sf.net/ruleset_xml_schema.xsd',
'name' => "$self->{owner} PHPMD rule set",
));
my $ruleset = $self->{generator}->buildElement((name => 'ruleset', attributes => {
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
'xsi:schemaLocation' => 'http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd',
'xsi:noNamespaceSchemaLocation' => 'http://pmd.sf.net/ruleset_xml_schema.xsd',
'name' => "$self->{owner} PHPMD rule set",
}));

$ruleset->setNamespace('http://pmd.sf.net/ruleset/1.0.0');
$ruleset->setNamespace('http://pmd.sf.net/ruleset/1.0.0');

my $rule = $self->{generator}->buildElement('rule', undef, $ruleset, (
'ref' => 'rulesets/codesize.xml/CyclomaticComplexity'
));
my $rule = $self->{generator}->buildElement((name => 'rule', parent => $ruleset, attributes => {
'ref' => 'rulesets/codesize.xml/CyclomaticComplexity'
}));

my $properties = $self->{generator}->buildElement('properties', undef, $rule);
my $properties = $self->{generator}->buildElement((name => 'properties', parent => $rule));

$self->{generator}->buildElement('property', undef, $properties, (
'name' => 'reportLevel',
'value' => $self->{cycloLevel}
));
$self->{generator}->buildElement((name => 'property', parent => $properties, attributes => {
'name' => 'reportLevel',
'value' => $self->{cycloLevel}
}));

my $dom = $self->{generator}->getDom();
my $dom = $self->{generator}->getDom();

$dom->setDocumentElement($ruleset);
$dom->setDocumentElement($ruleset);

return ($dom->toString(1));
return ($dom->toString(1));
}

1;
22 changes: 11 additions & 11 deletions lib/GPH/Psalm.pm
Original file line number Diff line number Diff line change
Expand Up @@ -61,43 +61,43 @@ sub new {
sub getConfig {
my $self = shift;

my $psalm = $self->{generator}->buildElement('psalm', undef, undef, (
my $psalm = $self->{generator}->buildElement((name => 'psalm', attributes => {
'resolveFromConfigFile' => 'true',
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
'xsi:schemaLocation' => 'https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd',
'errorLevel' => $self->{level},
'cacheDirectory' => $self->{cacheDir},
'errorBaseline' => $self->{baseline},
'findUnusedBaselineEntry' => $self->{baselineCheck},
));
}));

$psalm->setNamespace('https://getpsalm.org/schema/config');

my $projectFiles = $self->{generator}->buildElement('projectFiles', undef, $psalm);
my $projectFiles = $self->{generator}->buildElement((name => 'projectFiles', parent => $psalm));

foreach my $path (@{$self->{paths}}) {
$self->{generator}->buildElement('directory', undef, $projectFiles, (
$self->{generator}->buildElement((name => 'directory', parent => $projectFiles, attributes => {
'name' => $path,
));
}));
}

if (defined $self->{ignoredDirectories}) {
my $ignoreFiles = $self->{generator}->buildElement('ignoreFiles', undef, $projectFiles);
my $ignoreFiles = $self->{generator}->buildElement((name => 'ignoreFiles', parent => $projectFiles));

foreach my $path (@{$self->{ignoredDirectories}}) {
$self->{generator}->buildElement('directory', undef, $ignoreFiles, (
$self->{generator}->buildElement((name => 'directory', parent => $ignoreFiles, attributes => {
'name' => $path,
));
}));
}
}

if (defined $self->{plugins}) {
my $plugins = $self->{generator}->buildElement('plugins', undef, $psalm);
my $plugins = $self->{generator}->buildElement((name => 'plugins', parent => $psalm));

foreach my $plugin (@{$self->{plugins}}) {
$self->{generator}->buildElement('pluginClass', undef, $plugins, (
$self->{generator}->buildElement((name => 'pluginClass', parent => $plugins, attributes => {
'class' => $plugin,
));
}));
}
}

Expand Down
39 changes: 22 additions & 17 deletions lib/GPH/XMLHelper.pm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#
# Revisions: 2023-09-03 - created
# 2024-02-10 - namespaced module, bugfixes and unit tests
# 2024-02-12 - constructor now requires named arguments
#------------------------------------------------------------------------------

package GPH::XMLHelper;
Expand Down Expand Up @@ -33,32 +34,36 @@ sub new {
#------------------------------------------------------------------------------
# Build element
#
# Inputs: 0) string: name of the element
# 1) mixed: value of the element
# 2) LibXML::Element object: parent element
# 3) list: element attributes
# Inputs: name => (string) name of the element
# value => (string) value of the element
# parent => (LibXML::Element object) parent element
# attributes => (hash) element attributes
#
# Returns: LibXML::Element object
sub buildElement {
my ($self, $name, $value, $parent, %attributes) = @_;
my ($self, %args) = @_;

my $element = $self->{dom}->createElement($name);
(exists($args{name})) or die "$!";

foreach my $key (sort keys %attributes) {
if (defined $attributes{$key}) {
$element->{$key} = $attributes{$key};
my $element = $self->{dom}->createElement($args{name});

if (exists($args{attributes})) {
foreach my $key (sort keys %{$args{attributes}}) {
if (defined $args{attributes}{$key}) {
$element->{$key} = $args{attributes}{$key};
}
}
}
}

if (defined $value) {
$element->appendText($value);
}
if (defined $args{value}) {
$element->appendText($args{value});
}

if (defined $parent) {
$parent->appendChild($element);
}
if (defined $args{parent}) {
$args{parent}->appendChild($element);
}

return $element;
return $element;
}

#------------------------------------------------------------------------------
Expand Down
137 changes: 137 additions & 0 deletions t/unit/GPH/XMLHelper.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#!/usr/bin/perl
package t::unit::GPH::XMLHelper;

use strict;
use warnings;

use Test2::V0 -target => 'GPH::XMLHelper';
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 "mandatory element options" => sub {
my $object = $CLASS->new();

ok(dies {$object->buildElement((attributes => {}))}, 'died with missing name') or note($@);
ok(lives {$object->buildElement((name => 'foo'))}, 'lives with mandatory options') or note($@);
};

tests 'object validation' => sub {
my ($object, $exception, $warnings);
$exception = dies {
$warnings = warns {
$object = $CLASS->new();
};
};

is($exception, undef, 'no exception thrown');
is($warnings, 0, 'no warnings generated');
is(
$object,
object {
field dom => object {
prop blessed => 'XML::LibXML::Document';
};
},
'object as expected',
Dumper($object)
);

};
};

describe 'test element' => sub {
my (%args, $element, $expected_xml);

case 'name value attributes' => sub {
%args = (
name => 'foo',
value => 'bar',
attributes => {
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
}
);
$expected_xml = '<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">bar</foo>';
};

case 'name' => sub {
%args = (
name => 'foo',
);
$expected_xml = '<foo/>';
};

case 'name value' => sub {
%args = (
name => 'foo',
value => 'bar',
);
$expected_xml = '<foo>bar</foo>';
};

tests 'element generation' => sub {
my ($object, $exception, $warnings);
$exception = dies {
$warnings = warns {
$object = $CLASS->new();
$element = $object->buildElement(%args);
};
};

is($exception, undef, 'no exception thrown');
is($warnings, 0, 'no warnings generated');

is(
$element->toString(),
$expected_xml,
'element as expected',
Dumper($element)
);
};
};

describe 'test paren element' => sub {
my ($object, $dom, $element, $exception, $warnings);

$exception = dies {
$warnings = warns {
$object = $CLASS->new();
$element = $object->buildElement((
name => 'foo',
attributes => {
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
}
));

$object->buildElement((
name => 'bar',
parent => $element,
value => 'baz',
));

$dom = $object->getDom();
$dom->setDocumentElement($element);
};
};

is($exception, undef, 'no exception thrown');
is($warnings, 0, 'no warnings generated');

is(
$dom->toString(),
'<?xml version="1.0" encoding="UTF-8"?>
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><bar>baz</bar></foo>
',
'parent child element as expected',
Dumper($dom->toString())
)
};

done_testing();

0 comments on commit 8650921

Please sign in to comment.