Create a helper for dealing with nested attribute sets

[?]
Mar 17, 2021, 3:53 PM
6BPELYYTVDAMKH63BY722LHJEQ426V5JJ3ZSU5HRLZRDK745MFSQC

Dependencies

  • [2] S2KNQCPB NixExprs: extract the `escape` function and test it
  • [*] D5QIOJGP * Move everything up one directory.

Change contents

  • file addition: AttributeSet.pm (----------)
    [4.339]
    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;
  • edit in src/lib/Hydra/Helper/Escape.pm at line 5
    [2.69]
    [2.69]
    use Hydra::Helper::AttributeSet;
  • replacement in src/lib/Hydra/Helper/Escape.pm at line 7
    [2.70][2.70:102]()
    our @EXPORT = qw(escapeString);
    [2.70]
    [2.102]
    our @EXPORT = qw(escapeString escapeAttributePath);
  • edit in src/lib/Hydra/Helper/Escape.pm at line 16
    [2.240]
    sub escapeAttributePath {
    my ($s) = @_;
    return join(".", map( { escapeString($_) } Hydra::Helper::AttributeSet::splitPath($s)));
    }
  • file addition: attributeset.t (----------)
    [2.981]
    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;
  • edit in t/Helper/escape.t at line 25
    [2.1571]
    [2.1571]
    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);
    }
    };