Chandra

 view release on metacpan or  search on metacpan

t/99_branches.t  view on Meta::CPAN

#!/usr/bin/env perl
use strict;
use warnings;
use Test::More;

# The arms of the Perl conditions and the mock-side XS branches that the
# other tests leave untaken.

use Chandra::App;
use Chandra::Breadcrumb;
use Chandra::Component;
use Chandra::Form;
use Chandra::Form::Validator;
use Chandra::Nav;
use Chandra::Notify;
use Chandra::Table;
use Chandra::Tabs;
use Chandra::Window;

package MockWV;
sub new { my ($class, %o) = @_; bless { eval_js => [], dispatch_eval_js => [], bound => {}, loops => $o{loops} || 0 }, $class }
sub eval_js          { push @{ $_[0]{eval_js} }, $_[1] }
sub dispatch_eval_js { push @{ $_[0]{dispatch_eval_js} }, $_[1] }
sub init             { $_[0]{inits}++ }
sub loop             { my $self = shift; return $self->{loops}-- > 0 ? 0 : 1 }
sub exit             { $_[0]{exits}++ }
sub terminate        { $_[0]{terminated}++ }
sub bind             { $_[0]{bound}{ $_[1] } = $_[2] }
sub set_title        { push @{ $_[0]{titles} }, $_[1] }
sub title            { 'Mock' }

package MockCompApp;
our @updates;
sub new { bless {}, shift }
sub bind { $_[0] }
sub update { my ($self, $sel, $html) = @_; push @updates, [$sel, $html]; return $self }
sub eval { 1 }

package main;

my @warned;
local $SIG{__WARN__} = sub { push @warned, $_[0] };

sub mock_app {
    my %o = @_;
    my $app = Chandra::App->new(title => 'Branches');
    $app->{_webview} = MockWV->new(%o);
    return $app;
}

# --- a component whose app is set but which is not mounted ---
{
    my $c = Chandra::Component->new;
    Chandra::Component::comp__app($c, MockCompApp->new);
    Chandra::Component::comp__mounted($c, 0);
    @MockCompApp::updates = ();
    is($c->update, $c, 'update with an app but unmounted returns the component');
    is($c->update_part('part', '<i>x</i>'), $c, 'and so does update_part');
    is(scalar @MockCompApp::updates, 0, 'neither reached the app');
}

# --- breadcrumb items without a label or a route ---
{
    my $bc = Chandra::Breadcrumb->new(items => [ {}, { route => '/x' }, { label => 'B' }, { route => '/last' } ]);
    my $html = $bc->render;
    like($html, qr/chandra-breadcrumb-current"><\/span>/, 'an item without a route or label renders an empty current span');
    like($html, qr/navigate:\/x/, 'an item with a route links');
    ok(scalar(() = $html =~ /chandra-breadcrumb-current/g) >= 2, 'the last item is current even with a route');
}

# --- tabs with a negative active index ---
{
    my $t = Chandra::Tabs->new(tabs => [ { label => 'only', content => 'c' } ]);
    Chandra::Tabs::tabs__active_index($t, -1);
    unlike($t->render, qr/chandra-tabs-body"><div/, 'a negative active index renders an empty body');
}

# --- a nav navigating while unmounted ---
{
    my $nav = Chandra::Nav->new(items => [ { label => 'x', route => '/x' } ]);
    $nav->on_navigate('/x');
    is(Chandra::Nav::nav__active($nav), '/x', 'navigating without an app still records the route');
}

# --- validator fields of every shape ---
{
    my $f = Chandra::Form->new(id => 'q');
    $f->{_fields} = undef;
    is(Chandra::Form::Validator->validation_js($f), '', 'no field list, no script');
    $f->{_fields} = { not => 'a list' };
    is(Chandra::Form::Validator->validation_js($f), '', 'a field hash, no script');
    $f->{_fields} = [
        { name => 's', type => 'submit' },
        { name => 'g', type => 'group' },
        { name => 'p', opts => { pattern => '\d+' } },
        { name => 'o', opts => 'not a hash' },



( run in 1.331 second using v1.01-cache-2.11-cpan-145b269f2f3 )