changeset 370:cbf4febf0930

ObjectMeta, Tests, migrating to the new metadata model.
author sergey
date Tue, 10 Dec 2013 03:02:01 +0400
parents 7c784144d2f1
children d5c8b955bf8d
files Lib/IMPL/Web/View/Metadata/ObjectMeta.pm Lib/IMPL/Web/View/TTContext.pm _test/Test/Web/View.pm
diffstat 3 files changed, 81 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/Lib/IMPL/Web/View/Metadata/ObjectMeta.pm	Mon Dec 09 17:35:34 2013 +0400
+++ b/Lib/IMPL/Web/View/Metadata/ObjectMeta.pm	Tue Dec 10 03:02:01 2013 +0400
@@ -1,6 +1,7 @@
-package IMPL::Web::View::Metadata::FormMeta;
+package IMPL::Web::View::Metadata::ObjectMeta;
 use strict;
 
+use IMPL::lang;
 use IMPL::Const qw(:prop);
 use IMPL::declare {
 	require => {
@@ -11,7 +12,11 @@
 		AbstractObject => '-IMPL::Object::Abstract'
 	},
 	base => [
-		'IMPL::Web::View::Metadata::BaseMeta' => '@_'
+		'IMPL::Web::View::Metadata::BaseMeta' => sub {
+			my ($model,$type,$args) = @_;
+			$type ||= typeof($model);
+			return ($model,$type,$args);
+		}
 	],
 	props => [
 		isMultiple => PROP_RO,
@@ -26,8 +31,9 @@
 sub CTOR {
 	my ($this,$model,$type,$args) = @_;
 	
-	$type ||= typeof($model);
-	$args->{isMultiple} ||= $type eq 'ARRAY';
+	$type = $this->modelType;
+	
+	$args->{isMultiple} ||= $type && $type eq 'ARRAY';
 	
 	if ($args) {
 		$this->$_($args->{$_}) foreach grep $args->{$_}, qw(isMultiple holdingType);
@@ -58,7 +64,7 @@
 			
 			push @props, Meta->new($pv, $pt, \%args);
 		}
-	} elsif ( $modelType eq 'HASH' ) {
+	} elsif ( $modelType && $modelType eq 'HASH' ) {
 		while ( my ($k,$v) = each %{$this->model || {}} ) {
 			push @props, Meta->new($v,undef,{name => $k});
 		}
--- a/Lib/IMPL/Web/View/TTContext.pm	Mon Dec 09 17:35:34 2013 +0400
+++ b/Lib/IMPL/Web/View/TTContext.pm	Tue Dec 10 03:02:01 2013 +0400
@@ -25,7 +25,6 @@
 	no strict 'refs';
 	# modules is a global (for the whole document) templates cache
 	# tt_cache is a local (for the current context only) templtes cache
-	# view is a special variable, which will be cloned and passed to the nested context
 	foreach my $prop (qw(
 	   root
 	   base
@@ -37,8 +36,10 @@
 	   includes
 	   modules
 	   aliases
+	   
 	   id
-	   view
+	   metadata
+	   model
 	)) {
 		my $t = $prop;
 		
@@ -140,7 +141,7 @@
 
 sub display_for {
 	my $this = shift;
-	my $model = shift;
+	my $path = shift;
 	my ($template, $args);
 	
 	if (ref $_[0] eq 'HASH') {
@@ -153,15 +154,11 @@
 	my $prefix = $this->prefix;
 	
 	my $info;
+	my $meta = $this->resolve_model($path,$args);
 	
-    if (not(($args and delete $args->{_no_resolve}) or ref $model)) {
-		$info = $this->resolve_model($model,$args);
-	} else {
-		$info = {
-			model => $model,
-			prefix => ""
-		};
-	}
+	$info->{prefix} = $prefix ? $prefix . '.' . $path : $path;
+	$info->{model} = $meta->model;
+	$info->{metadata} = $meta;
 	
 	$template ||= $info->{template};
 	$template = $template ? $this->find_template($template) : $this->find_template_for($info->{model});
@@ -228,11 +225,6 @@
 		unshift @includes, $this->base;
 	}
 	
-	my $view = $this->view;
-	$view = ref $view eq 'HASH' ? { %{$view} } : {};
-	
-	hashApply($view, delete $env->{view});
-	
 	my $out = eval {
 		$ctx->localise(
             hashApply(
@@ -251,8 +243,7 @@
 		            display_model => sub {
 		            	$ctx->display_model(@_);
 		            },
-		            tt_cache => {},
-		            view => $view
+		            tt_cache => {}
 				},
                 $env
             )
@@ -328,29 +319,31 @@
 }
 
 sub resolve_model {
-	my ($this,$prefix,$args) = @_;
+	my ($this,$prefix) = @_;
 	
 	die ArgException->new(prefix => "the prefix must be specified")
 	   unless defined $prefix;
 	
-
-	
-	if (my $res = $this->stash->get(['resolve', [$this,$prefix,$args]] ) ) {
-		return $res;
+	my $meta = $this->metadata;
+	foreach my $part (grep length($_), split(/\.|\[(\d+)\]/, $prefix)) {
+		last unless $meta;
+		if ($part =~ /^\d+$/) {
+			$meta = $meta->GetItem($part);
+		} else {
+			$meta = $meta->GetProperty($part);
+		}
 	}
 	
-	my @comp = map { $_, 0 } grep length($_), split(/\.|\[(\d+)\]/, $prefix);
-	
-	return {
-		model => $this->stash->get(['model',0,@comp]),
-		prefix => $this->prefix ? $this->prefix . ".$prefix" : $prefix
-	};
+	return $meta;
 }
 
 sub find_template_for {
-	my ($this,$model, $nothrow) = @_;
+	my ($this,$meta, $nothrow) = @_;
 	
-	my $type = typeof($model);
+	return $this->find_template($meta->template)
+		if ($meta->template);
+	
+	my $type = $meta->modelType;
 	
 	return $this->find_template('templates/plain') unless $type;
 	
@@ -374,12 +367,13 @@
             	$this->cache->Set($sclass,$template);
             	return $template;
             } 
-                
+            
+            #todo $meta->GetISA
             push @isa, @{"${sclass}::ISA"};
         }
 		
 	}
-	$this->throw(Template::Constants::ERROR_FILE, "can't find a template for the model " . typeof($model))
+	$this->throw(Template::Constants::ERROR_FILE, "can't find a template for the model $type")
 		unless $nothrow;
 
 	return;
--- a/_test/Test/Web/View.pm	Mon Dec 09 17:35:34 2013 +0400
+++ b/_test/Test/Web/View.pm	Tue Dec 10 03:02:01 2013 +0400
@@ -15,10 +15,10 @@
 		FormMeta => 'IMPL::Web::View::Metadata::FormMeta',
 		ObjectMeta => 'IMPL::Web::View::Metadata::ObjectMeta',
 		Schema => 'IMPL::DOM::Schema',
-		Builder => 'IMPL::DOM::Navigator::Builder',
 		Document => 'IMPL::DOM::Document',
 		XMLReader => 'IMPL::DOM::XMLReader',
-		MProfiler => '-IMPL::Profiler::Memory'
+		MProfiler => '-IMPL::Profiler::Memory',
+		PersonModel => '-Test::Web::View::Model::Person'
 	},
 	base => [
 		'IMPL::Test::Unit' => '@_'
@@ -108,8 +108,49 @@
 test TestObjectMetadata => sub {
 	my ($this) = @_;
 	
+	my $meta = ObjectMeta->new(
+		PersonModel->new(
+			name => 'alex',
+			age => 29,
+			address => [
+				{ city => 'city 17', street => 'doomed' },
+				{ city => 'gropher', street => 'caveroad' }
+			]
+		)
+	);
 	
+	assert($meta->modelType eq PersonModel);
+	
+	my $prop = $meta->GetProperty('name');
+	assert($prop);
+	assert($prop->model eq 'alex');
+	
+	$prop = $meta->GetProperty('address');
+	
+	assert($prop->isMultiple);
+	assert($prop->name eq 'address');
+	assert($prop->modelType eq 'ARRAY');
+	
+	my $items = $prop->GetItems();
+	assert(@$items == 2);
+	assertarray(
+		[map $_->GetProperty('city')->model, @$items],
+		['city 17', 'gropher']
+	);
 };
 
+package Test::Web::View::Model::Person;
+use IMPL::Const qw(:prop);
+use IMPL::declare {
+	base => [
+		'IMPL::Object' => undef,
+		'IMPL::Object::Autofill' => '@_'
+	],
+	props => [
+		name => PROP_RW,
+		age => PROP_RW,
+		address => PROP_RW | PROP_LIST
+	]
+};
 
 1;
\ No newline at end of file