6BPELYYTVDAMKH63BY722LHJEQ426V5JJ3ZSU5HRLZRDK745MFSQC package Hydra::Helper::AttributeSet;use strict;use warnings;sub new {my ($self) = @_;return bless { "paths" => [] }, $self;}sub registerValue {my ($self, $attributePath) = @_;my @pathParts = splitPath($attributePath);pop(@pathParts);if (scalar(@pathParts) == 0) {return;}my $lineage = "";for my $pathPart (@pathParts) {$lineage = $self->registerChild($lineage, $pathPart);}}sub registerChild {my ($self, $parent, $attributePath) = @_;if ($parent ne "") {$parent .= "."}my $name = $parent . $attributePath;if (!grep { $_ eq $name} @{$self->{"paths"}}) {push(@{$self->{"paths"}}, $name);}return $name;}sub splitPath {my ($s) = @_;if ($s eq "") {return ('')}return split(/\./, $s, -1);}sub enumerate {my ($self) = @_;my @paths = sort { length($a) <=> length($b) } @{$self->{"paths"}};return wantarray ? @paths : \@paths;}1;
sub escapeAttributePath {my ($s) = @_;return join(".", map( { escapeString($_) } Hydra::Helper::AttributeSet::splitPath($s)));}
use strict;use warnings;use Setup;use Data::Dumper;use Test2::V0;use Hydra::Helper::AttributeSet;subtest "splitting an attribute path in to its component parts" => sub {my %values = ("" => [''],"." => ['', ''],"...." => ['', '', '', '', ''],"foobar" => ['foobar'],"foo.bar" => ['foo', 'bar'],"🌮" => ['🌮'],# not supported: 'foo."bar.baz".tux' => [ 'foo', 'bar.baz', 'tux' ]# the edge cases are fairly significant around escaping and unescaping.);for my $input (keys %values) {my @value = @{$values{$input}};my @components = Hydra::Helper::AttributeSet::splitPath($input);is(\@components, \@value, "Splitting the attribute path: " . $input);}};my $attrs = Hydra::Helper::AttributeSet->new();$attrs->registerValue("foo");$attrs->registerValue("bar.baz.tux");$attrs->registerValue("bar.baz.bux.foo.bar.baz");is($attrs->enumerate(),[# "foo": skipped since we're registering values, and we# only want to track nested attribute sets.# "bar.baz.tux": expand the path"bar","bar.baz",#"bar.baz.bux.foo.bar.baz": expand the path, but only register new# attribute set names."bar.baz.bux","bar.baz.bux.foo","bar.baz.bux.foo.bar",],"Attribute set paths are registered.");done_testing;
subtest "escaping path components of a nested attribute" => sub {my %values = ("" => '""',"." => '"".""',"...." => '""."".""."".""',"foobar" => '"foobar"',"foo.bar" => '"foo"."bar"',"🌮" => '"🌮"','foo"bar' => '"foo\"bar"','foo\\bar' => '"foo\\\\bar"','$bar' => '"\\$bar"',);for my $input (keys %values) {my $value = $values{$input};is(escapeAttributePath($input), $value, "Escaping the attribute path: " . $input);}};