Merge branch '2.2.0' of tasktools.org:task into 2.2.0

This commit is contained in:
Paul Beckingham
2012-12-03 07:45:41 -05:00
18 changed files with 350 additions and 69 deletions

View File

@@ -11,6 +11,7 @@ contributions of the following people:
Wim Schuermann (Contributing Author) Wim Schuermann (Contributing Author)
Owen Clarke (Contributing Author) Owen Clarke (Contributing Author)
Louis-Claude Canon (Contributing Author) Louis-Claude Canon (Contributing Author)
Scott Kostyshak (Contributing Author)
The following submitted code, packages or analysis, and deserve special thanks: The following submitted code, packages or analysis, and deserve special thanks:
@@ -74,7 +75,6 @@ The following submitted code, packages or analysis, and deserve special thanks:
Oleksii Tsai Oleksii Tsai
Jörg Plate Jörg Plate
Markus Kuhn Markus Kuhn
Scott Kostyshak
Erik Wenzel Erik Wenzel
Štěpán Henek Štěpán Henek
Fidel Mato Fidel Mato
@@ -158,3 +158,7 @@ suggestions:
Stéphane Pezennec Stéphane Pezennec
Jim B Jim B
Jake Bell Jake Bell
Florian Hollerweger
Thomas Sullivan
Tim None

View File

@@ -7,11 +7,18 @@ Features
(thanks to Michelle Crane). (thanks to Michelle Crane).
+ Added Feature #953, which includes the total number of blocked and blocking + Added Feature #953, which includes the total number of blocked and blocking
tasks to the 'statistics' command output (thanks to T. Charles Yun). tasks to the 'statistics' command output (thanks to T. Charles Yun).
+ Added Feature #1039, which adds new date shortcuts, 'socm' and 'eocm',
meaning start and end of current month (thanks to Thomas Sullivan,
Louis-Claude Canon).
+ Added Feature #1061, which allows the 'columns' command to use a search
string for the column name (thanks to Uli Martens).
+ Added Feature #1069, which gives a clearer error when a UDA + Added Feature #1069, which gives a clearer error when a UDA
is added without the uda.<uda-name>.type variable. is added without the uda.<uda-name>.type variable.
+ Added Feature #1124, which provides a '_show' command that displays all + Added Feature #1124, which provides a '_show' command that displays all
configuration defaults and settings, for use by third-party software (thanks configuration defaults and settings, for use by third-party software (thanks
to Jake Bell). to Jake Bell).
+ Added Feature #1099, which supports the 'color.uda.<uda-name>' color rule
(thanks to Florian Hollerweger).
+ The 'projects' command now outputs abstract parents and reduces + The 'projects' command now outputs abstract parents and reduces
repetition by not printing parent names in front of children names. repetition by not printing parent names in front of children names.
+ Added framework for testing bash autocompletion. + Added framework for testing bash autocompletion.
@@ -24,13 +31,11 @@ Features
+ New 'modified' attribute, which contains the most recent modification date, + New 'modified' attribute, which contains the most recent modification date,
if a modification has occurred. if a modification has occurred.
+ Fixed the mechanism used for selecting translations (thanks to Fidel Mato). + Fixed the mechanism used for selecting translations (thanks to Fidel Mato).
+ Added new export script: export-tsv.pl.
Bugs Bugs
+ Improved hyphenation by splitting on commas (even if no whitespace after). + Fixed bug #947, #1031, which kept expanding aliases after the '--' operator
Leads to better output of, for example, 'task show', where comma-separated (thanks to Jim B).
lists are common.
+ Fixed bug #1031, which kept expanding aliases after the '--' operator (thanks
to Jim B).
+ Fixed bug #1038, which prints blank lines with bulk changes and when the + Fixed bug #1038, which prints blank lines with bulk changes and when the
verbose attributes does not specify it. Lines do a better separation between verbose attributes does not specify it. Lines do a better separation between
each changes also. each changes also.
@@ -47,6 +52,11 @@ Bugs
+ Fixed bug #1065, where CmdShow issued messages in incorrect situations. + Fixed bug #1065, where CmdShow issued messages in incorrect situations.
+ Partially fixed #1083, which showed 'task 0 ...' when modifying a non- + Partially fixed #1083, which showed 'task 0 ...' when modifying a non-
pending task (thanks to Aikido Guy). pending task (thanks to Aikido Guy).
+ Fixed bug #1123, which caused the undo of a 'log' command to corrupt the data
file (thanks to Tim None).
+ Improved hyphenation by splitting on commas (even if no whitespace after).
Leads to better output of, for example, 'task show', where comma-separated
lists are common.
+ No more bash completion of, for example, 'projABC:', or of 'proj:' if + No more bash completion of, for example, 'projABC:', or of 'proj:' if
abbreviation.minimum is greater than 4. abbreviation.minimum is greater than 4.
+ Fixed bug where shadow files are not properly created when there is a missing + Fixed bug where shadow files are not properly created when there is a missing

5
NEWS
View File

@@ -8,6 +8,9 @@ New Features in taskwarrior 2.2.0
- Tasks now have a 'modified' attribute, which indicates the last time, if at - Tasks now have a 'modified' attribute, which indicates the last time, if at
all, that they were modified. all, that they were modified.
- Statistics now report total number of blocked and blocking tasks. - Statistics now report total number of blocked and blocking tasks.
- The 'columns' command now supports search term for the column name.
- New date shortcuts, 'socm' and 'eocm', meaning start and end of current
month.
New commands in taskwarrior 2.2.0 New commands in taskwarrior 2.2.0
@@ -15,7 +18,7 @@ New commands in taskwarrior 2.2.0
New configuration options in taskwarrior 2.2.0 New configuration options in taskwarrior 2.2.0
- - New color rule 'color.uda.<uda-name>'.
Newly deprecated features in taskwarrior 2.2.0 Newly deprecated features in taskwarrior 2.2.0

View File

@@ -155,9 +155,10 @@ Displays all possible colors, a named sample, or a legend containing all
currently defined colors. currently defined colors.
.TP .TP
.B task columns .B task columns [substring]
Displays all supported columns and formatting styles. Useful when creating Displays all supported columns and formatting styles. Useful when creating
custom reports. custom reports. If a substring is provided, only matching column names are
shown.
.TP .TP
.B task <filter> completed .B task <filter> completed

View File

@@ -844,6 +844,11 @@ Colors any task assigned to project X.
Colors any task where the description or any annotation contains X. Colors any task where the description or any annotation contains X.
.RE .RE
.TP
.B color.uda.X=on green
Colors any taks that has the user defined attribute X.
.RE
.TP .TP
.B color.error=green .B color.error=green
Colors any of the error messages. Colors any of the error messages.

View File

@@ -74,6 +74,7 @@ for my $task (split /,$/ms, qx{$command})
# annotations # annotations
# mask # mask
# imask # imask
# UDAs
} }
exit 0; exit 0;

83
scripts/add-ons/export-tsv.pl Executable file
View File

@@ -0,0 +1,83 @@
#! /usr/bin/perl
################################################################################
## taskwarrior - a command line task list manager.
##
## Copyright 2006-2012, Paul Beckingham, Federico Hernandez.
##
## Permission is hereby granted, free of charge, to any person obtaining a copy
## of this software and associated documentation files (the "Software"), to deal
## in the Software without restriction, including without limitation the rights
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
## copies of the Software, and to permit persons to whom the Software is
## furnished to do so, subject to the following conditions:
##
## The above copyright notice and this permission notice shall be included
## in all copies or substantial portions of the Software.
##
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
## SOFTWARE.
##
## http://www.opensource.org/licenses/mit-license.php
##
################################################################################
use strict;
use warnings;
# Give a nice error if the (non-standard) JSON module is not installed.
eval "use JSON";
if ($@)
{
print "Error: You need to install the JSON Perl module.\n";
exit 1;
}
# Use the taskwarrior 2.0+ export command to filter and return JSON
my $command = join (' ', ("env PATH=$ENV{PATH} task export", @ARGV));
if ($command =~ /No matches/)
{
printf STDERR $command;
exit 1;
}
# Generate output.
print "uuid\tstatus\ttags\tentry\tstart\tdue\trecur\tend\tproject\t",
"priority\tfg\tbg\tdescription\n";
for my $task (split /,$/ms, qx{$command})
{
my $data = from_json ($task);
print "$data->{'uuid'}\t",
"$data->{'status'}\t",
(exists $data->{'tags'} ? join (' ', @{$data->{'tags'}}) : ''), "\t",
"$data->{'entry'}\t",
($data->{'start'} || ''), "\t",
($data->{'due'} || ''), "\t",
($data->{'recur'} || ''), "\t",
($data->{'end'} || ''), "\t",
($data->{'project'} || ''), "\t",
($data->{'priority'} || ''), "\t",
($data->{'fg'} || ''), "\t",
($data->{'bg'} || ''), "\t",
"$data->{'description'}",
"\n";
# Note that this format ignores:
# wait
# until
# annotations
# mask
# imask
# UDAs
}
exit 0;
################################################################################

View File

@@ -211,6 +211,7 @@ std::string Config::_defaults =
"color.blocking=white on color6 # Color of blocking tasks\n" "color.blocking=white on color6 # Color of blocking tasks\n"
"#color.completed=on blue # Color of completed tasks\n" "#color.completed=on blue # Color of completed tasks\n"
"#color.deleted=on blue # Color of deleted tasks\n" "#color.deleted=on blue # Color of deleted tasks\n"
"#color.uda.estimate=on green # Color of UDA\n"
#else #else
"color.header=yellow # Color of header messages\n" "color.header=yellow # Color of header messages\n"
"color.footnote=yellow # Color of footnote messages\n" "color.footnote=yellow # Color of footnote messages\n"
@@ -265,12 +266,13 @@ std::string Config::_defaults =
"color.blocking=black on bright white # Color of blocking tasks\n" "color.blocking=black on bright white # Color of blocking tasks\n"
"#color.completed=on blue # Color of completed tasks\n" "#color.completed=on blue # Color of completed tasks\n"
"#color.deleted=on blue # Color of deleted tasks\n" "#color.deleted=on blue # Color of deleted tasks\n"
"#color.uda.estimate=on green # Color of UDA\n"
#endif #endif
"\n" "\n"
"# Here is the rule precedence order, highest to lowest.\n" "# Here is the rule precedence order, highest to lowest.\n"
"# Note that these are just the color rule names, without the leading 'color.'\n" "# Note that these are just the color rule names, without the leading 'color.'\n"
"# and any trailing '.value'.\n" "# and any trailing '.value'.\n"
"rule.precedence.color=due.today,active,blocking,blocked,overdue,due,scheduled,keyword.,project.,tag.,recurring,pri.,tagged,completed,deleted\n" "rule.precedence.color=due.today,active,blocking,blocked,overdue,due,scheduled,keyword.,project.,tag.,uda.,recurring,pri.,tagged,completed,deleted\n"
"\n" "\n"
"# Shadow file support\n" "# Shadow file support\n"
"#shadow.file=/tmp/shadow.txt # Location of shadow file\n" "#shadow.file=/tmp/shadow.txt # Location of shadow file\n"

View File

@@ -56,12 +56,14 @@ static const char* relatives[] =
"eow", "eow",
"eoww", "eoww",
"eocw", "eocw",
"eocm",
"eom", "eom",
"eoq", "eoq",
"eoy", "eoy",
"sow", "sow",
"soww", "soww",
"socw", "socw",
"socm",
"som", "som",
"soq", "soq",
"soy", "soy",
@@ -828,7 +830,8 @@ bool Date::isRelativeDate (const std::string& input)
found == "eocw" || found == "eocw" ||
found == "sow" || found == "sow" ||
found == "soww" || found == "soww" ||
found == "socw") found == "socw" ||
found == "socm")
{ {
if (found == "eow" || found == "eoww") if (found == "eow" || found == "eoww")
dow = 5; dow = 5;
@@ -847,6 +850,9 @@ bool Date::isRelativeDate (const std::string& input)
else else
today += (dow - today.dayOfWeek ()) * 86400; today += (dow - today.dayOfWeek ()) * 86400;
if (found == "socm")
today -= (today.day () - 1) * 86400;
int m, d, y; int m, d, y;
today.toMDY (m, d, y); today.toMDY (m, d, y);
Date then (m, d, y); Date then (m, d, y);
@@ -878,7 +884,7 @@ bool Date::isRelativeDate (const std::string& input)
_t = then._t - 86400; _t = then._t - 86400;
return true; return true;
} }
else if (found == "eom") else if (found == "eom" || found == "eocm")
{ {
Date then (today.month (), Date then (today.month (),
daysInMonth (today.month (), today.year ()), daysInMonth (today.month (), today.year ()),

View File

@@ -1576,26 +1576,37 @@ void TDB2::revert ()
{ {
context.debug ("TDB::undo - task found in completed.data"); context.debug ("TDB::undo - task found in completed.data");
// If task now belongs back in pending.data // Either revert if there was a prior state, or remove the task.
if (prior.find ("status:\"pending\"") != std::string::npos || if (prior != "")
prior.find ("status:\"waiting\"") != std::string::npos ||
prior.find ("status:\"recurring\"") != std::string::npos)
{ {
c.erase (task); *task = prior;
p.push_back (prior); if (task->find ("status:\"pending\"") != std::string::npos ||
File::write (completed._file._data, c); task->find ("status:\"waiting\"") != std::string::npos ||
File::write (pending._file._data, p); task->find ("status:\"recurring\"") != std::string::npos)
File::write (undo._file._data, u); {
std::cout << STRING_TDB2_REVERTED << "\n"; c.erase (task);
context.debug ("TDB::undo - task belongs in pending.data"); p.push_back (prior);
File::write (completed._file._data, c);
File::write (pending._file._data, p);
File::write (undo._file._data, u);
std::cout << STRING_TDB2_REVERTED << "\n";
context.debug ("TDB::undo - task belongs in pending.data");
}
else
{
File::write (completed._file._data, c);
File::write (undo._file._data, u);
std::cout << STRING_TDB2_REVERTED << "\n";
context.debug ("TDB::undo - task belongs in completed.data");
}
} }
else else
{ {
*task = prior; c.erase (task);
File::write (completed._file._data, c); File::write (completed._file._data, c);
File::write (undo._file._data, u); File::write (undo._file._data, u);
std::cout << STRING_TDB2_REVERTED << "\n"; std::cout << STRING_TDB2_REVERTED << "\n";
context.debug ("TDB::undo - task belongs in completed.data"); context.debug ("TDB::undo - task removed");
} }
std::cout << STRING_TDB2_UNDO_COMPLETE << "\n"; std::cout << STRING_TDB2_UNDO_COMPLETE << "\n";

View File

@@ -42,7 +42,7 @@ extern Context context;
CmdColumns::CmdColumns () CmdColumns::CmdColumns ()
{ {
_keyword = "columns"; _keyword = "columns";
_usage = "task columns"; _usage = "task columns [substring]";
_description = STRING_CMD_COLUMNS_USAGE; _description = STRING_CMD_COLUMNS_USAGE;
_read_only = true; _read_only = true;
_displays_id = false; _displays_id = false;
@@ -51,6 +51,12 @@ CmdColumns::CmdColumns ()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int CmdColumns::execute (std::string& output) int CmdColumns::execute (std::string& output)
{ {
// Obtain the arguments from the description. That way, things like '--'
// have already been handled.
std::vector <std::string> words = context.a3.extract_words ();
if (words.size () > 1)
throw std::string (STRING_CMD_COLUMNS_ARGS);
// Include all columns in the table. // Include all columns in the table.
std::vector <std::string> names; std::vector <std::string> names;
std::map <std::string, Column*>::const_iterator col; std::map <std::string, Column*>::const_iterator col;
@@ -73,15 +79,19 @@ int CmdColumns::execute (std::string& output)
std::vector <std::string>::iterator name; std::vector <std::string>::iterator name;
for (name = names.begin (); name != names.end (); ++name) for (name = names.begin (); name != names.end (); ++name)
{ {
const std::vector <std::string> styles = context.columns[*name]->styles (); if (words.size () == 0 ||
const std::vector <std::string> examples = context.columns[*name]->examples (); find (*name, words[0], false) != std::string::npos)
for (unsigned int i = 0; i < styles.size (); ++i)
{ {
int row = formats.addRow (); const std::vector <std::string> styles = context.columns[*name]->styles ();
formats.set (row, 0, i == 0 ? *name : ""); const std::vector <std::string> examples = context.columns[*name]->examples ();
formats.set (row, 1, styles[i] + (i == 0 ? "*" : ""));
formats.set (row, 2, i < examples.size () ? examples[i] : ""); for (unsigned int i = 0; i < styles.size (); ++i)
{
int row = formats.addRow ();
formats.set (row, 0, i == 0 ? *name : "");
formats.set (row, 1, styles[i] + (i == 0 ? "*" : ""));
formats.set (row, 2, i < examples.size () ? examples[i] : "");
}
} }
} }

View File

@@ -229,6 +229,7 @@ int CmdShow::execute (std::string& output)
if (i->substr (0, 14) != "color.keyword." && if (i->substr (0, 14) != "color.keyword." &&
i->substr (0, 14) != "color.project." && i->substr (0, 14) != "color.project." &&
i->substr (0, 10) != "color.tag." && i->substr (0, 10) != "color.tag." &&
i->substr (0, 10) != "color.uda." &&
i->substr (0, 8) != "holiday." && i->substr (0, 8) != "holiday." &&
i->substr (0, 7) != "report." && i->substr (0, 7) != "report." &&
i->substr (0, 6) != "alias." && i->substr (0, 6) != "alias." &&

View File

@@ -388,6 +388,7 @@
#define STRING_CMD_COLUMNS_USAGE "All supported columns and formatting styles" #define STRING_CMD_COLUMNS_USAGE "All supported columns and formatting styles"
#define STRING_CMD_COLUMNS_NOTE "* Means default format, and therefore optional. For example, 'due' and 'due.formatted' are equivalent." #define STRING_CMD_COLUMNS_NOTE "* Means default format, and therefore optional. For example, 'due' and 'due.formatted' are equivalent."
#define STRING_CMD_COLUMNS_USAGE2 "Displays only a list of supported columns" #define STRING_CMD_COLUMNS_USAGE2 "Displays only a list of supported columns"
#define STRING_CMD_COLUMNS_ARGS "You can only specify one search string."
#define STRING_CMD_DENO_USAGE "Deletes an annotation" #define STRING_CMD_DENO_USAGE "Deletes an annotation"
#define STRING_CMD_DENO_WORDS "An annotation pattern must be provided." #define STRING_CMD_DENO_WORDS "An annotation pattern must be provided."
@@ -550,6 +551,7 @@
// Date // Date
#define STRING_DATE_INVALID_FORMAT "'{1}' is not a valid date in the '{2}' format." #define STRING_DATE_INVALID_FORMAT "'{1}' is not a valid date in the '{2}' format."
#define STRING_DATE_BAD_WEEKSTART "The 'weekstart' configuration variable may only contain 'Sunday' or 'Monday'." #define STRING_DATE_BAD_WEEKSTART "The 'weekstart' configuration variable may only contain 'Sunday' or 'Monday'."
#define STRING_DATE_TOO_MUCH "The date is too far into the future."
#define STRING_DATE_JANUARY_LONG "january" #define STRING_DATE_JANUARY_LONG "january"
#define STRING_DATE_FEBRUARY_LONG "february" #define STRING_DATE_FEBRUARY_LONG "february"

View File

@@ -398,8 +398,8 @@
#define STRING_CMD_COLUMNS_USAGE "Todas las columnas y estilos de formato soportados" #define STRING_CMD_COLUMNS_USAGE "Todas las columnas y estilos de formato soportados"
#define STRING_CMD_COLUMNS_NOTE "* Significa formato por defecto, y por lo tanto opcional. Por ejemplo 'due' y 'due.formatted' son equivalentes." #define STRING_CMD_COLUMNS_NOTE "* Significa formato por defecto, y por lo tanto opcional. Por ejemplo 'due' y 'due.formatted' son equivalentes."
#define STRING_CMD_COLUMNS_USAGE2 "Muestra una lista de columnas (solo nombres) soportadas" #define STRING_CMD_COLUMNS_USAGE2 "Muestra una lista de columnas (solo nombres) soportadas"
#define STRING_CMD_COLUMNS_ARGS "Solo puede especificar un término de búsqueda."
#define STRING_CMD_DENO_USAGE "Elimina una anotación" #define STRING_CMD_DENO_USAGE "Elimina una anotación"
#define STRING_CMD_DENO_WORDS "Se debe proporcionar un patrón de anotación." #define STRING_CMD_DENO_WORDS "Se debe proporcionar un patrón de anotación."
@@ -565,6 +565,7 @@
// Date // Date
#define STRING_DATE_INVALID_FORMAT "'{1}' no es una fecha válida según el formato '{2}'." #define STRING_DATE_INVALID_FORMAT "'{1}' no es una fecha válida según el formato '{2}'."
#define STRING_DATE_BAD_WEEKSTART "La variable de configuración 'weekstart' solamente puede contener 'Sunday' (domingo) o 'Monday' (lunes)." #define STRING_DATE_BAD_WEEKSTART "La variable de configuración 'weekstart' solamente puede contener 'Sunday' (domingo) o 'Monday' (lunes)."
#define STRING_DATE_TOO_MUCH "The date is too far into the future."
#define STRING_DATE_JANUARY_LONG "enero" #define STRING_DATE_JANUARY_LONG "enero"
#define STRING_DATE_FEBRUARY_LONG "febrero" #define STRING_DATE_FEBRUARY_LONG "febrero"

View File

@@ -211,6 +211,13 @@ static void colorizeKeyword (Task& task, const std::string& rule, const Color& b
} }
} }
////////////////////////////////////////////////////////////////////////////////
static void colorizeUDA (Task& task, const std::string& rule, const Color& base, Color& c)
{
if (task.has (rule.substr (10)))
c.blend (base);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeDue (Task& task, const Color& base, Color& c) static void colorizeDue (Task& task, const Color& base, Color& c)
{ {
@@ -313,6 +320,7 @@ void autoColorize (Task& task, Color& c)
else if (r->substr (0, 10) == "color.tag.") colorizeTag (task, *r, base, c); else if (r->substr (0, 10) == "color.tag.") colorizeTag (task, *r, base, c);
else if (r->substr (0, 14) == "color.project.") colorizeProject (task, *r, base, c); else if (r->substr (0, 14) == "color.project.") colorizeProject (task, *r, base, c);
else if (r->substr (0, 14) == "color.keyword.") colorizeKeyword (task, *r, base, c); else if (r->substr (0, 14) == "color.keyword.") colorizeKeyword (task, *r, base, c);
else if (r->substr (0, 10) == "color.uda.") colorizeUDA (task, *r, base, c);
} }
} }
} }

63
test/color.uda.t Executable file
View File

@@ -0,0 +1,63 @@
#! /usr/bin/env perl
################################################################################
## taskwarrior - a command line task list manager.
##
## Copyright 2006-2012, Paul Beckingham, Federico Hernandez.
##
## Permission is hereby granted, free of charge, to any person obtaining a copy
## of this software and associated documentation files (the "Software"), to deal
## in the Software without restriction, including without limitation the rights
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
## copies of the Software, and to permit persons to whom the Software is
## furnished to do so, subject to the following conditions:
##
## The above copyright notice and this permission notice shall be included
## in all copies or substantial portions of the Software.
##
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
## SOFTWARE.
##
## http://www.opensource.org/licenses/mit-license.php
##
################################################################################
use strict;
use warnings;
use Test::More tests => 4;
# Create the rc file.
if (open my $fh, '>', 'color.rc')
{
print $fh "data.location=.\n",
"color.uda.x=red\n",
"uda.x.type=numeric\n",
"uda.x.label=X\n",
"color.alternate=\n",
"_forcecolor=1\n";
close $fh;
ok (-r 'color.rc', 'Created color.rc');
}
qx{../src/task rc:color.rc add one 2>&1};
qx{../src/task rc:color.rc add two x:3 2>&1};
my $output = qx{../src/task rc:color.rc list 2>/dev/null};
unlike ($output, qr/ \033\[32m .* one .* \033\[0m /x, 'No color.uda');
like ($output, qr/ \033\[31m .* two .* \033\[0m /x, 'Found color.uda');
# Cleanup.
unlink qw(pending.data completed.data undo.data backlog.data synch.key color.rc);
ok (! -r 'pending.data' &&
! -r 'completed.data' &&
! -r 'undo.data' &&
! -r 'backlog.data' &&
! -r 'synch.key' &&
! -r 'color.rc', 'Cleanup');
exit 0;

View File

@@ -35,7 +35,7 @@ Context context;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv) int main (int argc, char** argv)
{ {
UnitTest t (179); UnitTest t (181);
try try
{ {
@@ -324,26 +324,32 @@ int main (int argc, char** argv)
Date r11 ("eow"); Date r11 ("eow");
t.ok (r11 < now + (8 * 86400), "eow < 7 days away"); t.ok (r11 < now + (8 * 86400), "eow < 7 days away");
Date r20 ("eocw"); Date r12 ("eocw");
t.ok (r20 < now + (8 * 86400), "eocw < 7 days away"); t.ok (r12 < now + (8 * 86400), "eocw < 7 days away");
Date r12 ("eom"); Date r13 ("eom");
t.ok (r12.sameMonth (now), "eom in same month as now"); t.ok (r13.sameMonth (now), "eom in same month as now");
Date r13 ("eoy"); Date r14 ("eocm");
t.ok (r13.sameYear (now), "eoy in same year as now"); t.ok (r14.sameMonth (now), "eocm in same month as now");
Date r14 ("sow"); Date r15 ("eoy");
t.ok (r14 < now + (8 * 86400), "sow < 7 days away"); t.ok (r15.sameYear (now), "eoy in same year as now");
Date r21 ("socw"); Date r16 ("sow");
t.ok (r21 < now + (8 * 86400), "sow < 7 days away"); t.ok (r16 < now + (8 * 86400), "sow < 7 days away");
Date r15 ("som"); Date r23 ("socw");
t.notok (r15.sameMonth (now), "som not in same month as now"); t.ok (r23 < now + (8 * 86400), "sow < 7 days away");
Date r16 ("soy"); Date r17 ("som");
t.notok (r16.sameYear (now), "soy not in same year as now"); t.notok (r17.sameMonth (now), "som not in same month as now");
Date r18 ("socm");
t.ok (r18.sameMonth (now), "socm in same month as now");
Date r19 ("soy");
t.notok (r19.sameYear (now), "soy not in same year as now");
Date first ("1st"); Date first ("1st");
t.notok (first.sameMonth (now), "1st not in same month as now"); t.notok (first.sameMonth (now), "1st not in same month as now");
@@ -372,34 +378,34 @@ int main (int argc, char** argv)
t.ok (eoq.sameYear (now), "eoq is in same year as now"); t.ok (eoq.sameYear (now), "eoq is in same year as now");
// Date::sameHour // Date::sameHour
Date r17 ("6/7/2010 01:00:00", "m/d/Y H:N:S"); Date r20 ("6/7/2010 01:00:00", "m/d/Y H:N:S");
Date r18 ("6/7/2010 01:59:59", "m/d/Y H:N:S"); Date r21 ("6/7/2010 01:59:59", "m/d/Y H:N:S");
t.ok (r17.sameHour (r18), "two dates within the same hour"); t.ok (r20.sameHour (r21), "two dates within the same hour");
Date r19 ("6/7/2010 00:59:59", "m/d/Y H:N:S"); Date r22 ("6/7/2010 00:59:59", "m/d/Y H:N:S");
t.notok (r17.sameHour (r19), "two dates not within the same hour"); t.notok (r20.sameHour (r22), "two dates not within the same hour");
// Date::operator- // Date::operator-
Date r22 (1234567890); Date r25 (1234567890);
t.is ((r22 - 1).toEpoch (), 1234567889, "1234567890 - 1 = 1234567889"); t.is ((r25 - 1).toEpoch (), 1234567889, "1234567890 - 1 = 1234567889");
// Date::operator-- // Date::operator--
Date r23 (11, 7, 2010, 23, 59, 59); Date r26 (11, 7, 2010, 23, 59, 59);
r23--; r26--;
t.is (r23.toString ("YMDHNS"), "20101106235959", "decrement across fall DST boundary"); t.is (r26.toString ("YMDHNS"), "20101106235959", "decrement across fall DST boundary");
Date r24 (3, 14, 2010, 23, 59, 59); Date r27 (3, 14, 2010, 23, 59, 59);
r24--; r27--;
t.is (r24.toString ("YMDHNS"), "20100313235959", "decrement across spring DST boundary"); t.is (r27.toString ("YMDHNS"), "20100313235959", "decrement across spring DST boundary");
// Date::operator++ // Date::operator++
Date r25 (11, 6, 2010, 23, 59, 59); Date r28 (11, 6, 2010, 23, 59, 59);
r25++; r28++;
t.is (r25.toString ("YMDHNS"), "20101107235959", "increment across fall DST boundary"); t.is (r28.toString ("YMDHNS"), "20101107235959", "increment across fall DST boundary");
Date r26 (3, 13, 2010, 23, 59, 59); Date r29 (3, 13, 2010, 23, 59, 59);
r26++; r29++;
t.is (r26.toString ("YMDHNS"), "20100314235959", "increment across spring DST boundary"); t.is (r29.toString ("YMDHNS"), "20100314235959", "increment across spring DST boundary");
} }
catch (const std::string& e) catch (const std::string& e)

64
test/feature.1061.t Executable file
View File

@@ -0,0 +1,64 @@
#! /usr/bin/env perl
################################################################################
## taskwarrior - a command line task list manager.
##
## Copyright 2006-2012, Paul Beckingham, Federico Hernandez.
##
## Permission is hereby granted, free of charge, to any person obtaining a copy
## of this software and associated documentation files (the "Software"), to deal
## in the Software without restriction, including without limitation the rights
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
## copies of the Software, and to permit persons to whom the Software is
## furnished to do so, subject to the following conditions:
##
## The above copyright notice and this permission notice shall be included
## in all copies or substantial portions of the Software.
##
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
## SOFTWARE.
##
## http://www.opensource.org/licenses/mit-license.php
##
################################################################################
use strict;
use warnings;
use Test::More tests => 8;
# Create the rc file.
if (open my $fh, '>', 'bug.rc')
{
print $fh "data.location=.\n",
"color=off\n";
close $fh;
ok (-r 'bug.rc', 'Created bug.rc');
}
# Test: task columns
# task columns descr
my $output = qx{../src/task rc:bug.rc columns 2>/dev/null};
like ($output, qr/description/, 'columns - found description');
like ($output, qr/uuid/, 'columns - found uuid');
like ($output, qr/project/, 'columns - found project');
$output = qx{../src/task rc:bug.rc columns escr 2>/dev/null};
like ($output, qr/description/, 'columns - found \'escr\' in description');
unlike ($output, qr/uuid/, 'columns - did not find \'escr\' in uuid');
unlike ($output, qr/project/, 'columns - did not find \'escr\' in project');
# Cleanup.
unlink qw(pending.data completed.data undo.data backlog.data synch.key bug.rc);
ok (! -r 'pending.data' &&
! -r 'completed.data' &&
! -r 'undo.data' &&
! -r 'backlog.data' &&
! -r 'synch.key' &&
! -r 'bug.rc', 'Cleanup');
exit 0;