view _test/Test/Web/View.pm @ 250:129e48bb5afb

DOM refactoring ObjectToDOM methods are virtual QueryToDOM uses inflators Fixed transform for the complex values in the ObjectToDOM QueryToDOM doesn't allow to use complex values (HASHes) as values for nodes (overpost problem)
author sergey
date Wed, 07 Nov 2012 04:17:53 +0400
parents b8c724f6de36
children 0f59b2de72af
line wrap: on
line source

package Test::Web::View;
use IMPL::Profiler::Memory;
use strict;
use warnings;
use utf8;

use parent qw(IMPL::Test::Unit);
__PACKAGE__->PassThroughArgs;

use File::Slurp;
use Scalar::Util qw(weaken);

use IMPL::Test qw(assert test GetCallerSourceLine);
use IMPL::Web::View::TTLoader();

use constant {
    TTLoader => typeof IMPL::Web::View::TTLoader,
    MProfiler => 'IMPL::Profiler::Memory'
};

sub AssertMemoryLeak {
    my $code = shift;
    my $dump = shift;
    
    my $data = MProfiler->Monitor($code);
    
    if ($data->isLeak and $dump) {
        write_file("dump.out", { binmode => ':utf8' }, $data->Dump() );
    }
    
    assert( not($data->isLeak), "Memory leak detected", GetCallerSourceLine()  , @{$data->{objects}} );    
}

sub templatesDir {
    $_[0]->GetResourceDir('Resources','TTView');
}

sub CreateLoader {
    my ($this) = @_;
    
    my $loader = TTLoader->new(
        {
            INCLUDE_PATH => [
                $this->templatesDir
            ],
            INTERPOLATE => 1,
            POST_CHOMP => 1,
            ENCODING => 'utf-8'
        },
        ext => '.tt',
        initializer => 'global.tt',
        globals => {
            site => {
                name => 'Test Site'
            },
            date => {
                now => sub { localtime(time); }
            },
            dynamic => sub { 'this is a dynamic value' },
            view => {
            }
        },
        layoutBase => 'Layout'
    );
}

test TTLoaderTests => sub {
    my ($this) = @_;
    
    my $loader = $this->CreateLoader();
    
    # test the loader to be able to find a desired resource
    assert( defined($loader->template('simple') ) );
    
    # loader should be initialized on demand
    assert( not $loader->isInitialized );
    
    # loader should be able to load a document
    my $doc = $loader->document('simple');
    assert(defined $doc);
    
    assert( $loader->isInitialized );
    assert( $loader->context->stash->get('user') eq 'test_user');
    
    # document should inherit loader's context 
    assert( $doc->context->stash->get('user') eq 'test_user');
    
    # document should not have 'this' template variable
    assert( not $doc->templateVars('this') );
    
    assert( $doc->context != $loader->context); # document should have an own context
};

test TTDocumentTests => sub {
    my ($this) = @_;
    my $loader = $this->CreateLoader();
    
    my $doc = $loader->document('simple');
    
    assert(defined $doc);
    $doc->title('test document');
    
    assert($doc->name eq 'document');
    assert($doc->title eq 'test document');
    
    assert(not $doc->can('notexists')); # autoloaded property should be ignored
    assert(not defined $doc->notexists); # nonexisting property 
    assert($doc->template->version == 10); # static metadata
    assert($doc->templateVars('notexists') eq ''); #nonexisting template variable
    assert($doc->templateVars('user') eq 'test_user'); # global data
    assert($doc->templateVars('templateVar') eq ''); # defined in CTOR block, should be local
    assert($doc->templateVars('dynamic') eq 'this is a dynamic value');
    
    my $text = $doc->Render();
    my $expected = read_file($this->GetResourceFile('Resources','TTView.Output','simple.txt'), binmode => ':utf8');
    
    assert($text eq $expected, "Bad Render() output","Got: $text", "Expected: $expected");
    
};

test TTControlTests => sub {
    my ($this) = @_;
    
    my $loader = $this->CreateLoader();
    
    my $doc = $loader->document('simple');
    
    assert(defined $doc);
    
    my $factory = $doc->RequireControl('My/Org/Panel');
    
    assert(defined $factory);
    
    
    assert($factory->context->stash != $doc->context->stash);
    
    assert($factory == $doc->RequireControl('My/Org/Panel'), "Control should be loaded only once");
    
    my $ctl = $factory->new('information', { visualClass => 'simple', data => ['one','two','hello world'] } );
    
    assert(defined $ctl);    
    
    assert($ctl->name eq 'information', "Created control should have a name", "Got: ".$ctl->name, "Expected: information");
    
    assert($ctl->GetAttribute('visualClass') eq 'simple');
    
    assert($factory->instances == 1);
    
    $doc->childNodes([$ctl]);
    
    assert($doc->templateVars('dojo.require'));
    assert(ref $doc->templateVars('dojo.require') eq 'ARRAY');
    assert($doc->templateVars('dojo.require')->[0] eq 'dijit.form.Input' );
    
    my $text = $ctl->Render();
    
    my $expected = read_file($this->GetResourceFile('Resources', 'TTView.Output', 'Panel.txt'), binmode => ':utf8');    
    assert($text eq $expected, '$ctl->Render(): Bad output', "Got:      $text", "Expected: $expected");
    
    
    
};

test TestDocumentLayout => sub {
    my ($this) = @_;
    
    my $loader = $this->CreateLoader();
    
    my $doc = $loader->document(
        'complex',
        {
            data => [qw(one two three)],
            site => {
                name => 'Test Site'
            }
        }
    );
    
    assert($doc->layout eq 'default');
    
    assert($doc->templateVars('dojo.require')->[0]);
    
    my $text = $doc->Render();
    my $expected = read_file($this->GetResourceFile('Resources', 'TTView.Output', 'complex.default.txt'), binmode => ':utf8' );
    #assert($text eq $expected, '$doc->Render(): Bad output', "Got:      $text", "Expected: $expected"); 
};

test TestMemoryLeaks => sub {
    my ($this) = @_;
    
    my $loader = $this->CreateLoader();
    $loader->document('simple'); # force loader initialization
    
    AssertMemoryLeak(sub {        
        my $doc = $loader->document('simple');
    });
        
    AssertMemoryLeak(sub {
        my $doc = $loader->document('simple');
        $doc->Render( { self => $doc } );
    });
    
    $loader->template('Layout/default');
    $loader->template('My/Org/Panel');
    $loader->template('My/Org/TextPreview');
    AssertMemoryLeak(sub {
        my $doc = $loader->document('simple');
        my $factory = $doc->RequireControl('My/Org/Panel');
        my $ctl = $doc->childNodes($factory->new('information', { visualClass => 'complex' }) );        
    });
    
    $loader->template('complex');
    AssertMemoryLeak(sub {
        my $doc = $loader->document('complex');
        $doc->Render();
    },'dump');
    
};

1;