Dependencies - #410
- Completed support for 'task 1 depends:2,-3' to manipulate the dependencies. - Now supports rc.dependency.reminder to indicate when to nag about dependency chain violations, defaulting to on. - Now supports rc.dependency.confirm to require confirmation before fixing dependency chains, defaulting to on. - New source file dependency.cpp which implements a low-level API for determining dependency status, and assorted handlers for task state changes. - Adds blocking tasks to the 'next' report. - Added more dependency unit tests, changed the wording in a couple of them and numbered them for easy reference.
This commit is contained in:
@@ -28,59 +28,71 @@
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More tests => 39;
|
||||
use Test::More tests => 41;
|
||||
|
||||
# Create the rc file.
|
||||
if (open my $fh, '>', 'dep.rc')
|
||||
{
|
||||
print $fh "data.location=.\n";
|
||||
print $fh "dependency.confirm=yes\n";
|
||||
print $fh "dependency.confirmation=yes\n";
|
||||
print $fh "report.depreport.columns=id,depends,description\n";
|
||||
print $fh "report.depreport.labels=ID,Depends,Description\n";
|
||||
print $fh "report.depreport.filter=status:pending\n";
|
||||
print $fh "report.depreport.sort=depends+\n";
|
||||
print $fh "nag=NAG";
|
||||
close $fh;
|
||||
|
||||
# [1]
|
||||
ok (-r 'dep.rc', 'Created dep.rc');
|
||||
}
|
||||
|
||||
qx{../task rc:dep.rc add One};
|
||||
qx{../task rc:dep.rc add Two};
|
||||
|
||||
# [2]
|
||||
my $output = qx{../task rc:dep.rc 1 dep:-2};
|
||||
like ($output, qr/Modified 0 tasks\./, 'dependencies - remove nonexistent dependency');
|
||||
|
||||
# [3]
|
||||
$output = qx{../task rc:dep.rc 1 dep:99};
|
||||
like ($output, qr/Could not create a dependency on task 99 - not found\./, 'dependencies - add dependency for nonexistent task');
|
||||
|
||||
# [4]
|
||||
$output = qx{../task rc:dep.rc 99 dep:1};
|
||||
like ($output, qr/Task 99 not found\./, 'dependencies - add dependency to nonexistent task');
|
||||
|
||||
# t 1 dep:2; t info 1 => blocked by 2
|
||||
# [5,6] t 1 dep:2; t info 1 => blocked by 2
|
||||
$output = qx{../task rc:dep.rc 1 dep:2; ../task rc:dep.rc info 1};
|
||||
like ($output, qr/This task blocked by\s+2 Two\nUUID/, 'dependencies - trivial blocked');
|
||||
unlike ($output, qr/This task is blocking\n/, 'dependencies - trivial blocked');
|
||||
|
||||
# t info 2 => blocking 1
|
||||
# [7,8] t info 2 => blocking 1
|
||||
$output = qx{../task rc:dep.rc info 2};
|
||||
unlike ($output, qr/This task blocked by/, 'dependencies - trivial blocking');
|
||||
like ($output, qr/This task is blocking\s+1 One\nUUID/, 'dependencies - trivial blocking');
|
||||
|
||||
# t 1 dep:2 (again)
|
||||
# [9] t 1 dep:2 (again)
|
||||
$output = qx{../task rc:dep.rc 1 dep:2};
|
||||
like ($output, qr/Task 1 already depends on task 2\./, 'dependencies - add already existing dependency');
|
||||
|
||||
# t 1 dep:1 => error
|
||||
# [10,11] t 1 dep:1 => error
|
||||
$output = qx{../task rc:dep.rc 1 dep:1};
|
||||
like ($output, qr/A task cannot be dependent on itself\./, 'dependencies - cannot depend on self');
|
||||
unlike ($output, qr/Modified 1 task\./, 'dependencies - cannot depend on self');
|
||||
|
||||
# t 1 dep:2; t 2 dep:1 => error
|
||||
# [12,13] t 1 dep:2; t 2 dep:1 => error
|
||||
$output = qx{../task rc:dep.rc 2 dep:1};
|
||||
like ($output, qr/Circular dependency detected and disallowed\./, 'dependencies - trivial circular');
|
||||
unlike ($output, qr/Modified 1 task\./, 'dependencies - trivial circular');
|
||||
|
||||
# [14,15] t 1 dep:2; t 2 dep:3; t 1 dep:3 => not circular
|
||||
qx{../task rc:dep.rc 1 dep:2};
|
||||
qx{../task rc:dep.rc add Three};
|
||||
qx{../task rc:dep.rc 2 dep:3};
|
||||
$output = qx{../task rc:dep.rc 1 dep:3};
|
||||
unlike ($output, qr/Circular dependency detected and disallowed\./, 'dependencies - diamond, non-circular');
|
||||
like ($output, qr/Modified 1 task\./, 'dependencies - diamond, non-circular');
|
||||
|
||||
# [16]
|
||||
unlink 'pending.data';
|
||||
ok (!-r 'pending.data', 'Removed pending.data for a fresh start');
|
||||
|
||||
@@ -92,11 +104,12 @@ qx{../task rc:dep.rc add Five};
|
||||
|
||||
qx{../task rc:dep.rc 5 dep:4; ../task rc:dep.rc 4 dep:3; ../task rc:dep.rc 3 dep:2; ../task rc:dep.rc 2 dep:1};
|
||||
|
||||
# 5 dep 4 dep 3 dep 2 dep 1 dep 5 => error
|
||||
# [17,18] 5 dep 4 dep 3 dep 2 dep 1 dep 5 => error
|
||||
$output = qx{../task rc:dep.rc 1 dep:5};
|
||||
like ($output, qr/Circular dependency detected and disallowed\./, 'dependencies - nontrivial circular');
|
||||
unlike ($output, qr/Modified 1 task\./, 'dependencies - nontrivial circular');
|
||||
|
||||
# [19]
|
||||
unlink 'pending.data';
|
||||
ok (!-r 'pending.data', 'Removed pending.data for a fresh start');
|
||||
|
||||
@@ -107,23 +120,28 @@ qx{../task rc:dep.rc add Four};
|
||||
qx{../task rc:dep.rc add Five};
|
||||
qx{../task rc:dep.rc add Six recurring due:tomorrow recur:daily};
|
||||
|
||||
# [20]
|
||||
$output = qx{../task rc:dep.rc 6 dep:5};
|
||||
unlike ($output,qr/Modified \d+ task/, 'dependencies - recurring task depending on another task');
|
||||
like ($output, qr/Modified \d+ task/, 'dependencies - recurring task depending on another task');
|
||||
|
||||
# [21]
|
||||
$output = qx{../task rc:dep.rc 5 dep:6};
|
||||
like ($output,qr/Modified \d+ task/, 'dependencies - task depending on recurring task');
|
||||
like ($output, qr/Modified \d+ task/, 'dependencies - task depending on recurring task');
|
||||
|
||||
# t 1 dep:2,3,4; t 1 dep:-2,-4,5; t info 1 => blocked by 3,5
|
||||
# [22] t 1 dep:2,3,4; t 1 dep:-2,-4,5; t info 1 => blocked by 3,5
|
||||
$output = qx{../task rc:dep.rc 1 dep:2,3,4; ../task rc:dep.rc 1 dep:-2,-4,5; ../task rc:dep.rc info 1};
|
||||
like ($output, qr/This task blocked by\s+3 Three\n\s+5 Five\nThis task is blocking/, 'dependencies - multiple dependencies modified');
|
||||
like ($output, qr/This task blocked by\s+3 Three\n\s+5 Five\nUUID/, 'dependencies - multiple dependencies modified');
|
||||
|
||||
# [23,24]
|
||||
$output = qx{../task rc:dep.rc do 3,5; ../task rc:dep.rc info 1};
|
||||
unlike ($output, qr/This task blocked by/, 'dependencies - task info reflects completed dependencies');
|
||||
unlike ($output, qr/This task is blocking/, 'dependencies - task info reflects completed dependencies');
|
||||
|
||||
# [25]
|
||||
$output = qx{../task rc:dep.rc depreport};
|
||||
like ($output, qr/\s1\s+One\s+/, 'dependencies - depends report column reflects completed dependencies');
|
||||
|
||||
# [26]
|
||||
unlink 'pending.data';
|
||||
ok (!-r 'pending.data', 'Removed pending.data for a fresh start');
|
||||
|
||||
@@ -135,12 +153,16 @@ qx{../task rc:dep.rc add Four};
|
||||
qx{../task rc:dep.rc 1 dep:3,4};
|
||||
qx{../task rc:dep.rc do 2};
|
||||
|
||||
# [27]
|
||||
$output = qx{../task rc:dep.rc depreport};
|
||||
like ($output, qr/\s1\s+2, 3\s+One\s+/, 'dependencies - depends report column reflects changed IDs');
|
||||
like ($output, qr/\s1\s+2,3\s+One\s+/, 'dependencies - depends report column reflects changed IDs');
|
||||
|
||||
# [28]
|
||||
qx{../task rc:dep.rc do 3};
|
||||
$output = qx{../task rc:dep.rc depreport};
|
||||
like ($output, qr/\s1\s+One\s+/, 'dependencies - depends report column reflects completed dependencies');
|
||||
like ($output, qr/\s1\s+2\s+One\s+/, 'dependencies - depends report column reflects completed dependencies');
|
||||
|
||||
# [29]
|
||||
unlink 'pending.data';
|
||||
ok (!-r 'pending.data', 'Removed pending.data for a fresh start');
|
||||
|
||||
@@ -151,17 +173,20 @@ qx{../task rc:dep.rc add Four};
|
||||
|
||||
qx{../task rc:dep.rc 2 dep:1; ../task rc:dep.rc 3 dep:2; ../task rc:dep.rc 4 dep:3};
|
||||
|
||||
# [30,31]
|
||||
$output = qx{echo y | ../task rc:dep.rc do 2};
|
||||
like ($output, qr/fixed/, 'dependencies - user prompted to fix broken chain after completing a blocked task');
|
||||
like ($output, qr/is blocked by/, 'dependencies - user nagged for completing a blocked task');
|
||||
|
||||
like ($output, qr/NAG/, 'dependencies - user nagged for completing a blocked task');
|
||||
|
||||
# [32]
|
||||
$output = qx{echo y | ../task rc:dep.rc do 1};
|
||||
unlike ($output, qr/fixed/, 'dependencies - user not prompted to fix broken chain when the head of the chain is marked as complete');
|
||||
|
||||
# [33]
|
||||
$output = qx{echo y | ../task rc:dep.rc del 4};
|
||||
unlike ($output, qr/fixed/, 'dependencies - user not prompted to fix broken chain when the tail of the chain is deleted');
|
||||
|
||||
# [34]
|
||||
unlink 'pending.data';
|
||||
ok (!-r 'pending.data', 'Removed pending.data for a fresh start');
|
||||
|
||||
@@ -176,20 +201,22 @@ qx{../task rc:dep.rc 3 dep:2};
|
||||
qx{../task rc:dep.rc 4 dep:3};
|
||||
qx{../task rc:dep.rc 5 dep:4};
|
||||
|
||||
# [35]
|
||||
qx{echo y | ../task rc:dep.rc do 2};
|
||||
$output = qx{../task rc:dep.rc depreport};
|
||||
|
||||
like ($output, qr/\s1\s+One\s*\n\s2\s+1\s+Three\s*\n\s3\s+2\s+Four\s*\n\s4\s+3\s+Five/, 'dependencies - fixed chain after completing a blocked task');
|
||||
|
||||
# [36]
|
||||
qx{printf "Y\nY\n" | ../task rc:dep.rc del 2};
|
||||
$output = qx{../task rc:dep.rc depreport};
|
||||
like ($output, qr/\s1\s+One\s*\n\s2\s+1\s+Four\s*\n\s3\s+2\s+Five/, 'dependencies - fixed chain after deleting a blocked task');
|
||||
|
||||
# [37]
|
||||
qx{../task rc:dep.rc 2 dep:-1};
|
||||
$output = qx{../task rc:dep.rc depreport};
|
||||
like ($output, qr/\s1\s+One\s*\n\s2\s+Four\s*\n\s3\s+2\s+Five/, 'dependencies - chain should not be automatically repaired after manually removing a dependency');
|
||||
|
||||
# TODO - test dependency.confirm config variable
|
||||
# TODO - test dependency.confirmation config variable
|
||||
# TODO - test undo on backing out chain gap repair
|
||||
# TODO - test undo on backing out choice to not perform chain gap repair
|
||||
# TODO - test blocked task completion nag
|
||||
|
||||
Reference in New Issue
Block a user