basic comment store code
Matt S Trout [Wed, 12 Jan 2011 11:42:59 +0000 (11:42 +0000)]
lib/App/Commentry/Comment.pm [new file with mode: 0644]
lib/App/Commentry/CommentSet.pm [new file with mode: 0644]
lib/App/Commentry/CommentStore.pm [new file with mode: 0644]
t/comment_store.t [new file with mode: 0644]

diff --git a/lib/App/Commentry/Comment.pm b/lib/App/Commentry/Comment.pm
new file mode 100644 (file)
index 0000000..3670da8
--- /dev/null
@@ -0,0 +1,8 @@
+package App::Commentry::Comment;
+
+use Moo;
+
+has title => (is => 'ro', required => 1);
+has body => (is => 'ro', required => 1);
+
+1;
diff --git a/lib/App/Commentry/CommentSet.pm b/lib/App/Commentry/CommentSet.pm
new file mode 100644 (file)
index 0000000..2419cf2
--- /dev/null
@@ -0,0 +1,33 @@
+package App::Commentry::CommentSet;
+
+use aliased 'App::Commentry::Comment';
+use JSON;
+use Moo;
+
+has base_dir => (is => 'ro', required => 1);
+has path => (is => 'ro', required => 1);
+
+has _json => (is => 'lazy');
+
+sub _build__json { JSON->new->utf8->pretty }
+
+has _members => (is => 'lazy');
+
+sub _build__members {
+  my ($self) = @_;
+  my $file = join('/', $self->base_dir, $self->path).'.json';
+  return [] unless -e $file;
+  my $text = do {
+    open my $in, '<', $file
+      or die "Couldn't open ${file}: $!";
+    local $/; <$in>;
+  };
+  [ map Comment->new($_), @{$self->_json->decode($text)} ];
+}
+
+sub flatten {
+  my ($self) = @_;
+  @{$self->_members};
+}
+
+1;
diff --git a/lib/App/Commentry/CommentStore.pm b/lib/App/Commentry/CommentStore.pm
new file mode 100644 (file)
index 0000000..6676cc4
--- /dev/null
@@ -0,0 +1,18 @@
+package App::Commentry::CommentStore;
+
+use aliased 'App::Commentry::CommentSet';
+use Moo;
+
+has base_dir => (is => 'ro', required => 1);
+
+has _cache => (is => 'ro', default => sub { {} });
+
+sub get {
+  my ($self, $proto) = @_;
+  my $path = $proto->{path} or die "->get requires a path key";
+  $self->_cache->{$path} ||= do {
+    CommentSet->new(base_dir => $self->base_dir, path => $path)
+  };
+}
+
+1;
diff --git a/t/comment_store.t b/t/comment_store.t
new file mode 100644 (file)
index 0000000..2dcb5ba
--- /dev/null
@@ -0,0 +1,19 @@
+use strictures 1;
+use Test::More;
+use aliased 'App::Commentry::CommentStore';
+use aliased 'App::Commentry::Comment';
+
+my $store = CommentStore->new(base_dir => 't/var/exstore');
+
+is_deeply(
+  [ $store->get({ path => 'not/there' })->flatten ],
+  [], 'Nonexistent set is empty'
+);
+
+is_deeply(
+  [ $store->get({ path => 'one/two/three' })->flatten ],
+  [ map Comment->new({ title => "Title $_", body => "Body $_" }), 1, 2 ],
+  'Existing set loads ok'
+);
+
+done_testing;