Chandra

 view release on metacpan or  search on metacpan

t/52_contextmenu_edge.t  view on Meta::CPAN

}

# ---- Deeply nested submenus ----
{
    my $deep = { label => 'L5', action => sub {} };
    for my $i (reverse 1..4) {
        $deep = { label => "L$i", submenu => [$deep] };
    }
    my $cm = Chandra::ContextMenu->new(items => [$deep]);
    $cm->attach('#x');
    my $js = $cm->js_code;
    like($js, qr/sub:/, 'nested submenus in JS');
    ok(length($js) > 100, 'JS code generated for deep nesting');
}

# ---- Very long label ----
{
    my $long = 'A' x 500;
    my $cm = Chandra::ContextMenu->new(
        items => [{ label => $long, action => sub {} }],
    );
    my $it = $cm->items->[0];
    is(length($it->{label}), 500, 'long label stored');
    $cm->attach('#x');
    my $js = $cm->js_code;
    like($js, qr/A{100}/, 'long label in JS');
}

# ---- Attach to nonexistent selector (no crash) ----
{
    my $cm = Chandra::ContextMenu->new;
    eval { $cm->attach('#does-not-exist') };
    ok(!$@, 'attach nonexistent selector no error');
    my @att = $cm->attachments;
    is(scalar @att, 1, 'selector stored even if nonexistent');
}

# ---- Duplicate labels ----
{
    my $cm = Chandra::ContextMenu->new(
        items => [
            { label => 'Dup', action => sub { 'first' } },
            { label => 'Dup', action => sub { 'second' } },
        ],
    );
    is(scalar @{$cm->items}, 2, 'duplicate labels allowed');
    # set_item only modifies first match
    $cm->set_item('Dup', disabled => 1);
    ok($cm->items->[0]{disabled}, 'first dup modified');
    ok(!$cm->items->[1]{disabled}, 'second dup not modified');
}

# ---- Unicode labels ----
{
    my $cm = Chandra::ContextMenu->new(
        items => [
            { label => "\x{2603} Snowman", action => sub {} },
            { label => "Caf\x{e9}", action => sub {} },
        ],
    );
    like($cm->items->[0]{label}, qr/Snowman/, 'unicode label stored');
    $cm->attach('#x');
    my $js = $cm->js_code;
    like($js, qr/Snowman/, 'unicode in JS output');
}

# ---- Many items ----
{
    my @items = map { { label => "Item $_", action => sub {} } } 1..100;
    my $cm = Chandra::ContextMenu->new(items => \@items);
    is(scalar @{$cm->items}, 100, '100 items stored');
    $cm->attach('#x');
    my $js = $cm->js_code;
    like($js, qr/Item 100/, 'all items in JS');
}

# ---- Remove nonexistent item (no crash) ----
{
    my $cm = Chandra::ContextMenu->new(
        items => [{ label => 'A', action => sub {} }],
    );
    eval { $cm->remove_item('NOPE') };
    ok(!$@, 'remove nonexistent no crash');
    is(scalar @{$cm->items}, 1, 'items unchanged');
}

# ---- set_item nonexistent (no crash) ----
{
    my $cm = Chandra::ContextMenu->new(
        items => [{ label => 'A', action => sub {} }],
    );
    eval { $cm->set_item('NOPE', disabled => 1) };
    ok(!$@, 'set_item nonexistent no crash');
}

# ---- Add then remove ----
{
    my $cm = Chandra::ContextMenu->new;
    $cm->add_item({ label => 'X', action => sub {} });
    $cm->add_item({ label => 'Y', action => sub {} });
    $cm->add_item({ label => 'Z', action => sub {} });
    is(scalar @{$cm->items}, 3, '3 items');

    $cm->remove_item('Y');
    is(scalar @{$cm->items}, 2, '2 items after remove middle');
    is($cm->items->[0]{label}, 'X', 'X remains');
    is($cm->items->[1]{label}, 'Z', 'Z remains');
}

# ---- Separator-only menu ----
{
    my $cm = Chandra::ContextMenu->new(
        items => [
            { separator => 1 },
            { separator => 1 },
        ],
    );
    $cm->attach('#x');
    my $js = $cm->js_code;
    like($js, qr/sep:1/, 'separator-only menu JS ok');
}

# ---- Dispatch malformed JSON ----
{



( run in 1.036 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )