summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/AniDB/Manager.pm7
-rw-r--r--t/tests/manager.t172
2 files changed, 177 insertions, 2 deletions
diff --git a/lib/AniDB/Manager.pm b/lib/AniDB/Manager.pm
index 21d0d82..ee9d48e 100644
--- a/lib/AniDB/Manager.pm
+++ b/lib/AniDB/Manager.pm
@@ -66,10 +66,13 @@ sub maybe_new_name_for($self,$path) {
return $new_name;
}
-sub rename($self,$path,$new_path) {
+sub rename($self,$path,$new_path = undef) {
$path = path($path)->realpath;
$new_path ||= $self->new_name_for($path);
- if ($path->move($new_path)) {
+ if (
+ $new_path->parent->mkpath
+ && $path->move($new_path)
+ ) {
$self->datastore->rename($path,$new_path);
return 1;
}
diff --git a/t/tests/manager.t b/t/tests/manager.t
new file mode 100644
index 0000000..1ee509f
--- /dev/null
+++ b/t/tests/manager.t
@@ -0,0 +1,172 @@
+#!perl
+use 5.024;
+use strict;
+use warnings;
+use Test2::Bundle::Extended;
+use experimental 'signatures';
+use Path::Tiny;
+use AniDB::Manager;
+use Data::Dump 'pp';
+
+my $tempdir = Path::Tiny->tempdir;
+
+package AniDB::APIClient {
+ use Moo;
+ use experimental 'signatures';
+
+ has [qw(username password)] => (is=>'ro',required=>1);
+
+ sub episode_info_for($self,$path_info) {
+ return {
+ aid => 12,
+ eid => 73,
+ title => 'random episode',
+ };
+ }
+
+ sub anime_info_for($self,$episode_info) {
+ return {
+ aid => 12,
+ title => 'random series',
+ };
+ }
+};
+$INC{'AniDB/APIClient.pm'}=__FILE__;
+
+package Testing::Renamer {
+ use Moo;
+ use experimental 'signatures';
+
+ sub new_name_for($self,$path,$info) {
+ return $tempdir->child(
+ $info->{anime}{title},
+ $info->{episode}{title},
+ );
+ }
+};
+
+my $next_hash = 'abcd';
+sub fake_hash($fh) {
+ return $next_hash;
+}
+
+my $db_file = $tempdir->child('test.db');
+
+my $m;
+subtest 'construction' => sub {
+ try_ok {
+ $m = AniDB::Manager->new({
+ database => $db_file,
+ username => 'gino',
+ password => 'pino',
+ renamer => Testing::Renamer->new(),
+ hash_function => \&fake_hash,
+ });
+ } 'builds';
+
+ isa_ok(
+ $m->datastore,
+ ['AniDB::Datastore'],
+ 'datastore builds',
+ );
+
+ is(
+ $m->api_client,
+ object {
+ prop blessed => 'AniDB::APIClient';
+ call username => 'gino';
+ call password => 'pino';
+ },
+ 'api client builds',
+ );
+};
+
+my $test_file = $tempdir->child('some.video');
+$test_file->spew_raw('data');
+
+subtest 'update' => sub {
+ try_ok {
+ $m->update($test_file);
+ } 'lives';
+
+ is(
+ $m->datastore->full_info_for($test_file),
+ {
+ path => hash {
+ field name => $test_file->stringify;
+ field hash => $next_hash;
+ etc;
+ },
+ episode => {
+ aid => 12,
+ eid => 73,
+ title => 'random episode',
+ },
+ anime => {
+ aid => 12,
+ title => 'random series',
+ },
+ },
+ 'updates',
+ );
+
+ $next_hash = 'different';
+ try_ok {
+ $m->update($test_file);
+ } 'lives if not changed';
+
+ is(
+ $m->datastore->path_info_for($test_file),
+ hash {
+ field hash => 'abcd';
+ etc;
+ },
+ 'does not update if not changed',
+ );
+
+ $test_file->append_raw('more');
+
+ try_ok {
+ $m->update($test_file);
+ } 'lives if changed';
+
+ is(
+ $m->datastore->path_info_for($test_file),
+ hash {
+ field hash => $next_hash;
+ etc;
+ },
+ 'updates if changed',
+ );
+};
+
+subtest 'renaming' => sub {
+ is(
+ my $new_name = $m->new_name_for($test_file),
+ $tempdir->child(
+ 'random series',
+ 'random episode',
+ )->stringify,
+ 'new name',
+ );
+
+ try_ok {
+ $m->rename($test_file);
+ } 'renaming lives';
+
+ ok(not($test_file->exists),'old file not there');
+ ok(path($new_name)->exists,'new file is there');
+
+ is(
+ $m->datastore->path_info_for(path($new_name)),
+ hash {
+ field hash => $next_hash;
+ etc;
+ },
+ 'updates if renamed',
+ );
+
+ ok(not($m->maybe_new_name_for($new_name)),'double renaming is no-op');
+};
+
+done_testing;