diff --git a/lib/Mason/Plugin/Cache/Component.pm b/lib/Mason/Plugin/Cache/Component.pm new file mode 100644 index 0000000..cf1ada1 --- /dev/null +++ b/lib/Mason/Plugin/Cache/Component.pm @@ -0,0 +1,32 @@ +package Mason::Plugin::Cache::Component; +use Mason::PluginRole; + +my %memoized; + +sub cache_memoized { + my $class = shift; + if (@_) { $memoized{$class} = $_[0] } + return $memoized{$class}; +} + +method cache_defaults () { $self->cmeta->interp->cache_defaults } +method cache_root_class () { $self->cmeta->interp->cache_root_class } +method cache_namespace () { $self->cmeta->path } + +method cache () { + if ( !@_ && $self->cache_memoized ) { + return $self->cache_memoized; + } + my $cache_root_class = $self->cache_root_class; + my %options = ( %{ $self->cache_defaults }, @_ ); + if ( !exists( $options{namespace} ) ) { + $options{namespace} = $self->cache_namespace; + } + my $cache = $cache_root_class->new(%options); + if ( !@_ ) { + $self->cache_memoized($cache); + } + return $cache; +} + +1; diff --git a/lib/Mason/Plugin/Cache/Filters.pm b/lib/Mason/Plugin/Cache/Filters.pm new file mode 100644 index 0000000..239bcd4 --- /dev/null +++ b/lib/Mason/Plugin/Cache/Filters.pm @@ -0,0 +1,12 @@ +package Mason::Plugin::Cache::Filters; +use Mason::PluginRole; + +method Cache ( $key, $set_options, %cache_options ) { + Mason::DynamicFilter->new( + filter => sub { + $self->cache(%cache_options)->compute( $key, $_[0], $set_options ); + } + ); +} + +1; diff --git a/lib/Mason/Plugin/Cache/Interp.pm b/lib/Mason/Plugin/Cache/Interp.pm new file mode 100644 index 0000000..992603c --- /dev/null +++ b/lib/Mason/Plugin/Cache/Interp.pm @@ -0,0 +1,18 @@ +package Mason::Plugin::Cache::Interp; +use CHI; +use Mason::Util qw(catdir); +use Mason::PluginRole; + +# Passed attributes +# +has 'cache_defaults' => ( isa => 'HashRef', lazy_build => 1 ); +has 'cache_root_class' => ( isa => 'Str', default => 'CHI' ); + +method _build_cache_defaults () { + return { + driver => 'File', + root_dir => catdir( $self->data_dir, 'cache' ) + }; +} + +1; diff --git a/lib/Mason/Plugin/Cache/t/Basic.pm b/lib/Mason/Plugin/Cache/t/Basic.pm new file mode 100644 index 0000000..5fe29b1 --- /dev/null +++ b/lib/Mason/Plugin/Cache/t/Basic.pm @@ -0,0 +1,91 @@ +package Mason::Plugin::Cache::t::Basic; +use Test::Class::Most parent => 'Mason::Test::Class'; + +__PACKAGE__->default_plugins( [ '@Default', 'Cache' ] ); + +sub test_cache_defaults : Test(2) { + my $self = shift; + $self->run_test_in_comp( + path => '/cache/defaults.m', + test => sub { + my $comp = shift; + is( $comp->cache->label, 'File', 'cache->label' ); + is( $comp->cache->namespace, $comp->cmeta->path, 'cache->namespace' ); + } + ); +} + +sub test_cache_method : Test(1) { + my $self = shift; + $self->test_comp( + path => '/cache.m', + src => ' +<%shared> +$.count => 0 + + +<%method getset ($key)> +<%perl>$.count($.count+1); +<% $.cache->compute($key, sub { $key . $.count }) %> + + +namespace: <% $.cache->namespace %> +<% $.getset("foo") %> +<% $.getset("bar") %> +<% $.getset("bar") %> +<% $.getset("foo") %> +', + expect => ' +namespace: /cache.m +foo1 + +bar2 + +bar2 + +foo1 +', + ); +} + +sub test_cache_filter : Test(2) { + my $self = shift; + + $self->test_comp( + src => ' +% my $i = 1; +% foreach my $key (qw(foo bar)) { +<% $.Repeat(3), $.Cache($key) { %> +i = <% $i++ %> + +% } +', + expect => ' +i = 1 +i = 1 +i = 1 +i = 2 +i = 2 +i = 2 +', + ); + + $self->test_comp( + src => ' +% my $i = 1; +% foreach my $key (qw(foo foo)) { +<% $.Cache($key), $.Repeat(3) { %> +i = <% $i++ %> + +% } +', + expect => ' +i = 1 +i = 2 +i = 3 +i = 1 +i = 2 +i = 3 +' + ); +} diff --git a/t/Basic.t b/t/Basic.t new file mode 100644 index 0000000..aba197e --- /dev/null +++ b/t/Basic.t @@ -0,0 +1,3 @@ +#!perl -w +use Mason::Plugin::Cache::t::Basic; +Mason::Plugin::Cache::t::Basic->runtests;