Data-SortedSet-Shared

 view release on metacpan or  search on metacpan

t/09-frozen.t  view on Meta::CPAN

    my @seen;
    $ro->each(sub { push @seen, $_[0] });
    is_deeply \@seen, \@members, 'each() full iteration on PROT_READ handle';

    ok $ro->_validate, 'read-only tree validates lock-free';

    my $st = $ro->stats;
    is $st->{frozen},   1,  'stats.frozen == 1';
    is $st->{readonly}, 1,  'stats.readonly == 1';
    is $st->{count},    $N, 'stats.count via read-only view';

    # every mutator croaks on the read-only view
    like exception(sub { $ro->add(1, 2) }),         qr/read-only|frozen/, 'add croaks on read-only view';
    like exception(sub { $ro->incr(1, 1) }),        qr/read-only|frozen/, 'incr croaks on read-only view';
    like exception(sub { $ro->remove(1) }),         qr/read-only|frozen/, 'remove croaks on read-only view';
    like exception(sub { $ro->clear }),             qr/read-only|frozen/, 'clear croaks on read-only view';
    like exception(sub { $ro->pop_min }),           qr/read-only|frozen/, 'pop_min croaks on read-only view';
    like exception(sub { $ro->pop_max }),           qr/read-only|frozen/, 'pop_max croaks on read-only view';
    like exception(sub { $ro->add_many([[1,2]]) }), qr/read-only|frozen/, 'add_many croaks on read-only view';
    like exception(sub { $ro->freeze }),            qr/read-only/,        'freeze croaks on read-only view';

    is $ro->sync, undef, 'sync is a harmless no-op on a read-only view';
}

# ---- two independent read-only views of the same file, concurrently ----
{
    my $a = Data::SortedSet::Shared->new_readonly($path);
    my $b = Data::SortedSet::Shared->new_readonly($path);
    ok $a->score(1) == 1.5 && $b->score($N) == $N + 0.5,
        'two read-only views query the same file';
}

# ---- refuse a read-write reopen of a sealed file ----
like exception(sub { Data::SortedSet::Shared->new($path, 2 * $N) }),
     qr/frozen|read-only/, 'read-write reopen of a sealed file is refused';

# ---- refuse a read-write new_from_fd of a sealed file ----
{
    open my $fh, '+<', $path or die "open $path: $!";
    like exception(sub { Data::SortedSet::Shared->new_from_fd(fileno $fh) }),
         qr/frozen|read-only/, 'new_from_fd on a sealed file is refused';
    close $fh;
}

# ---- new_readonly rejects a non-frozen file ----
{
    my $u = "$dir/unsealed.sset";
    { my $z = Data::SortedSet::Shared->new($u, 100); $z->add(1, 1); }
    like exception(sub { Data::SortedSet::Shared->new_readonly($u) }),
         qr/not frozen/, 'new_readonly on an unsealed file croaks';
}

# ---- new_readonly error paths ----
like exception(sub { Data::SortedSet::Shared->new_readonly("$dir/does-not-exist.sset") }),
     qr/open|No such/, 'new_readonly on a missing path croaks';
like exception(sub { Data::SortedSet::Shared->new_readonly(undef) }),
     qr/required/, 'new_readonly requires a path';

done_testing;

# minimal exception helper (avoid a Test::Fatal dependency)
sub exception {
    my $code = shift;
    my $err;
    { local $@; eval { $code->(); 1 } or $err = $@; }
    return $err;
}



( run in 0.820 second using v1.01-cache-2.11-cpan-54e63673c56 )