- Fixed bug #251 that caused the .hasnt attribute modifier to fail
  when annotations were present.  Thanks to John Florian.
This commit is contained in:
Paul Beckingham 2009-08-16 22:38:33 -04:00
parent ec7f7cc939
commit 07da2396fc
4 changed files with 184 additions and 62 deletions

View file

@ -27,6 +27,8 @@
+ Fixed bug #260 whereby the start, stop and delete commands did not complain + Fixed bug #260 whereby the start, stop and delete commands did not complain
when filter arguments were specified, even though they were ignored when filter arguments were specified, even though they were ignored
(thanks to Charles T. Yun). (thanks to Charles T. Yun).
+ Fixed bug #251 whereby the presence of annotations cause the .hasnt attribute
modifier to not work (thanks to John Florian).
------ old releases ------------------------------ ------ old releases ------------------------------

View file

@ -25,7 +25,6 @@
// //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include <iostream> // TODO Remove
#include <sstream> #include <sstream>
#include "Filter.h" #include "Filter.h"
#include "util.h" #include "util.h"
@ -48,7 +47,8 @@ bool Filter::pass (const Record& record) const
if (att->name () == "description") if (att->name () == "description")
{ {
bool description_result = true; bool description_result = true;
bool annotation_result = true; int annotation_pass_count = 0;
int annotation_fail_count = 0;
if ((r = record.find (att->name ())) != record.end ()) if ((r = record.find (att->name ())) != record.end ())
{ {
@ -58,16 +58,30 @@ bool Filter::pass (const Record& record) const
{ {
if (ra->first.length () > 11 && if (ra->first.length () > 11 &&
ra->first.substr (0, 11) == "annotation_") ra->first.substr (0, 11) == "annotation_")
annotation_result = annotation_result && att->match (ra->second); {
if (att->match (ra->second))
++annotation_pass_count;
else
++annotation_fail_count;
}
} }
} }
else if (! att->match (Att ())) else if (! att->match (Att ()))
return false; return false;
// This innocuous little if-else took significantly more thinking and
// debugging than anything else in task. Only change this code if you
// are willing to invest a week understanding and testing it.
if (att->modType (att->mod ()) == "positive") if (att->modType (att->mod ()) == "positive")
return description_result && annotation_result; {
if (! (description_result || annotation_pass_count > 0))
return description_result || annotation_result; return false;
}
else
{
if (!description_result || annotation_fail_count > 0)
return false;
}
} }
// Annotations are skipped, because they are handled above. // Annotations are skipped, because they are handled above.

106
src/tests/bug.hasnt.t Executable file
View file

@ -0,0 +1,106 @@
#! /usr/bin/perl
################################################################################
## task - a command line task list manager.
##
## Copyright 2006 - 2009, Paul Beckingham.
## All rights reserved.
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 2 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
## FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, write to the
##
## Free Software Foundation, Inc.,
## 51 Franklin Street, Fifth Floor,
## Boston, MA
## 02110-1301
## USA
##
################################################################################
use strict;
use warnings;
use Test::More tests => 19;
# Create the rc file.
if (open my $fh, '>', 'hasnt.rc')
{
print $fh "data.location=.\n",
"confirmation=no\n";
close $fh;
ok (-r 'hasnt.rc', 'Created hasnt.rc');
}
# 1
qx{../task rc:hasnt.rc add foo};
# 2
qx{../task rc:hasnt.rc add foo};
qx{../task rc:hasnt.rc 2 annotate bar};
# 3
qx{../task rc:hasnt.rc add foo};
qx{../task rc:hasnt.rc 3 annotate bar};
sleep 2;
qx{../task rc:hasnt.rc 3 annotate baz};
# 4
qx{../task rc:hasnt.rc add bar};
# 5
qx{../task rc:hasnt.rc add bar};
qx{../task rc:hasnt.rc 5 annotate foo};
# 6
qx{../task rc:hasnt.rc add bar};
qx{../task rc:hasnt.rc 6 annotate foo};
sleep 2;
qx{../task rc:hasnt.rc 6 annotate baz};
#7
qx{../task rc:hasnt.rc add one};
qx{../task rc:hasnt.rc 7 annotate two};
sleep 2;
qx{../task rc:hasnt.rc 7 annotate three};
my $output = qx{../task rc:hasnt.rc ls description.has:foo};
like ($output, qr/\n 1/, '1 has foo -> yes');
like ($output, qr/\n 2/, '2 has foo -> yes');
like ($output, qr/\n 3/, '3 has foo -> yes');
unlike ($output, qr/\n 4/, '4 has foo -> no');
like ($output, qr/\n 5/, '5 has foo -> yes');
like ($output, qr/\n 6/, '6 has foo -> yes');
unlike ($output, qr/\n 7/, '7 has foo -> no');
$output = qx{../task rc:hasnt.rc ls description.hasnt:foo};
unlike ($output, qr/\n 1/, '1 hasnt foo -> no');
unlike ($output, qr/\n 2/, '2 hasnt foo -> no');
unlike ($output, qr/\n 3/, '3 hasnt foo -> no');
like ($output, qr/\n 4/, '4 hasnt foo -> yes');
unlike ($output, qr/\n 5/, '5 hasnt foo -> no');
unlike ($output, qr/\n 6/, '6 hasnt foo -> no');
like ($output, qr/\n 7/, '7 hasnt foo -> yes');
# Cleanup.
unlink 'pending.data';
ok (!-r 'pending.data', 'Removed pending.data');
unlink 'completed.data';
ok (!-r 'completed.data', 'Removed completed.data');
unlink 'undo.data';
ok (!-r 'undo.data', 'Removed undo.data');
unlink 'hasnt.rc';
ok (!-r 'hasnt.rc', 'Removed hasnt.rc');
exit 0;

View file

@ -111,52 +111,25 @@ unlike ($output, qr/six/, 'g6');
unlike ($output, qr/seven/, 'g7'); unlike ($output, qr/seven/, 'g7');
$output = qx{../task rc:filter.rc list -tag}; $output = qx{../task rc:filter.rc list -tag};
unlike ($output, qr/one/, 'g1'); unlike ($output, qr/one/, 'h1');
like ($output, qr/two/, 'g2'); like ($output, qr/two/, 'h2');
like ($output, qr/three/, 'g3'); like ($output, qr/three/, 'h3');
like ($output, qr/four/, 'g4'); like ($output, qr/four/, 'h4');
unlike ($output, qr/five/, 'g5'); unlike ($output, qr/five/, 'h5');
like ($output, qr/six/, 'g6'); like ($output, qr/six/, 'h6');
like ($output, qr/seven/, 'g7'); like ($output, qr/seven/, 'h7');
$output = qx{../task rc:filter.rc list -missing}; $output = qx{../task rc:filter.rc list -missing};
like ($output, qr/one/, 'g1'); like ($output, qr/one/, 'i1');
like ($output, qr/two/, 'g2'); like ($output, qr/two/, 'i2');
like ($output, qr/three/, 'g3'); like ($output, qr/three/, 'i3');
like ($output, qr/four/, 'g4'); like ($output, qr/four/, 'i4');
like ($output, qr/five/, 'g5'); like ($output, qr/five/, 'i5');
like ($output, qr/six/, 'g6'); like ($output, qr/six/, 'i6');
like ($output, qr/seven/, 'g7'); like ($output, qr/seven/, 'i7');
$output = qx{../task rc:filter.rc list +tag -tag}; $output = qx{../task rc:filter.rc list +tag -tag};
unlike ($output, qr/one/, 'g1'); unlike ($output, qr/one/, 'j1');
unlike ($output, qr/two/, 'g2');
unlike ($output, qr/three/, 'g3');
unlike ($output, qr/four/, 'g4');
unlike ($output, qr/five/, 'g5');
unlike ($output, qr/six/, 'g6');
unlike ($output, qr/seven/, 'g7');
$output = qx{../task rc:filter.rc list project:A priority:H};
like ($output, qr/one/, 'h1');
like ($output, qr/two/, 'h2');
unlike ($output, qr/three/, 'h3');
unlike ($output, qr/four/, 'h4');
unlike ($output, qr/five/, 'h5');
unlike ($output, qr/six/, 'h6');
unlike ($output, qr/seven/, 'h7');
$output = qx{../task rc:filter.rc list project:A priority:};
unlike ($output, qr/one/, 'i1');
unlike ($output, qr/two/, 'i2');
like ($output, qr/three/, 'i3');
unlike ($output, qr/four/, 'i4');
unlike ($output, qr/five/, 'i5');
unlike ($output, qr/six/, 'i6');
unlike ($output, qr/seven/, 'i7');
$output = qx{../task rc:filter.rc list project:A foo};
like ($output, qr/one/, 'j1');
unlike ($output, qr/two/, 'j2'); unlike ($output, qr/two/, 'j2');
unlike ($output, qr/three/, 'j3'); unlike ($output, qr/three/, 'j3');
unlike ($output, qr/four/, 'j4'); unlike ($output, qr/four/, 'j4');
@ -164,25 +137,25 @@ unlike ($output, qr/five/, 'j5');
unlike ($output, qr/six/, 'j6'); unlike ($output, qr/six/, 'j6');
unlike ($output, qr/seven/, 'j7'); unlike ($output, qr/seven/, 'j7');
$output = qx{../task rc:filter.rc list project:A +tag}; $output = qx{../task rc:filter.rc list project:A priority:H};
like ($output, qr/one/, 'k1'); like ($output, qr/one/, 'k1');
unlike ($output, qr/two/, 'k2'); like ($output, qr/two/, 'k2');
unlike ($output, qr/three/, 'k3'); unlike ($output, qr/three/, 'k3');
unlike ($output, qr/four/, 'k4'); unlike ($output, qr/four/, 'k4');
unlike ($output, qr/five/, 'k5'); unlike ($output, qr/five/, 'k5');
unlike ($output, qr/six/, 'k6'); unlike ($output, qr/six/, 'k6');
unlike ($output, qr/seven/, 'k7'); unlike ($output, qr/seven/, 'k7');
$output = qx{../task rc:filter.rc list project:A priority:H foo}; $output = qx{../task rc:filter.rc list project:A priority:};
like ($output, qr/one/, 'l1'); unlike ($output, qr/one/, 'l1');
unlike ($output, qr/two/, 'l2'); unlike ($output, qr/two/, 'l2');
unlike ($output, qr/three/, 'l3'); like ($output, qr/three/, 'l3');
unlike ($output, qr/four/, 'l4'); unlike ($output, qr/four/, 'l4');
unlike ($output, qr/five/, 'l5'); unlike ($output, qr/five/, 'l5');
unlike ($output, qr/six/, 'l6'); unlike ($output, qr/six/, 'l6');
unlike ($output, qr/seven/, 'l7'); unlike ($output, qr/seven/, 'l7');
$output = qx{../task rc:filter.rc list project:A priority:H +tag}; $output = qx{../task rc:filter.rc list project:A foo};
like ($output, qr/one/, 'm1'); like ($output, qr/one/, 'm1');
unlike ($output, qr/two/, 'm2'); unlike ($output, qr/two/, 'm2');
unlike ($output, qr/three/, 'm3'); unlike ($output, qr/three/, 'm3');
@ -191,7 +164,7 @@ unlike ($output, qr/five/, 'm5');
unlike ($output, qr/six/, 'm6'); unlike ($output, qr/six/, 'm6');
unlike ($output, qr/seven/, 'm7'); unlike ($output, qr/seven/, 'm7');
$output = qx{../task rc:filter.rc list project:A priority:H foo +tag}; $output = qx{../task rc:filter.rc list project:A +tag};
like ($output, qr/one/, 'n1'); like ($output, qr/one/, 'n1');
unlike ($output, qr/two/, 'n2'); unlike ($output, qr/two/, 'n2');
unlike ($output, qr/three/, 'n3'); unlike ($output, qr/three/, 'n3');
@ -200,14 +173,41 @@ unlike ($output, qr/five/, 'n5');
unlike ($output, qr/six/, 'n6'); unlike ($output, qr/six/, 'n6');
unlike ($output, qr/seven/, 'n7'); unlike ($output, qr/seven/, 'n7');
$output = qx{../task rc:filter.rc list project:A priority:H foo};
like ($output, qr/one/, 'o1');
unlike ($output, qr/two/, 'o2');
unlike ($output, qr/three/, 'o3');
unlike ($output, qr/four/, 'o4');
unlike ($output, qr/five/, 'o5');
unlike ($output, qr/six/, 'o6');
unlike ($output, qr/seven/, 'o7');
$output = qx{../task rc:filter.rc list project:A priority:H +tag};
like ($output, qr/one/, 'p1');
unlike ($output, qr/two/, 'p2');
unlike ($output, qr/three/, 'p3');
unlike ($output, qr/four/, 'p4');
unlike ($output, qr/five/, 'p5');
unlike ($output, qr/six/, 'p6');
unlike ($output, qr/seven/, 'p7');
$output = qx{../task rc:filter.rc list project:A priority:H foo +tag};
like ($output, qr/one/, 'q1');
unlike ($output, qr/two/, 'q2');
unlike ($output, qr/three/, 'q3');
unlike ($output, qr/four/, 'q4');
unlike ($output, qr/five/, 'q5');
unlike ($output, qr/six/, 'q6');
unlike ($output, qr/seven/, 'q7');
$output = qx{../task rc:filter.rc list project:A priority:H foo +tag baz}; $output = qx{../task rc:filter.rc list project:A priority:H foo +tag baz};
unlike ($output, qr/one/, 'n1'); unlike ($output, qr/one/, 'r1');
unlike ($output, qr/two/, 'n2'); unlike ($output, qr/two/, 'r2');
unlike ($output, qr/three/, 'n3'); unlike ($output, qr/three/, 'r3');
unlike ($output, qr/four/, 'n4'); unlike ($output, qr/four/, 'r4');
unlike ($output, qr/five/, 'n5'); unlike ($output, qr/five/, 'r5');
unlike ($output, qr/six/, 'n6'); unlike ($output, qr/six/, 'r6');
unlike ($output, qr/seven/, 'n7'); unlike ($output, qr/seven/, 'r7');
# Cleanup. # Cleanup.
unlink 'pending.data'; unlink 'pending.data';