From c8027a17c1d7de2ffd2a819a80521aabe3af4d35 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Mon, 5 Mar 2012 22:49:41 -0500 Subject: [PATCH] Feature - Missing data now tolerated for UDAs. - Info command includes all column data, even for unrecognized types. --- src/columns/ColUDA.cpp | 136 ++++++++++++++++++++------------------- src/commands/CmdInfo.cpp | 29 ++++++--- test/uda_date.t | 69 ++++++++++++++++++++ test/uda_duration.t | 4 +- 4 files changed, 163 insertions(+), 75 deletions(-) create mode 100755 test/uda_date.t diff --git a/src/columns/ColUDA.cpp b/src/columns/ColUDA.cpp index e8a15d706..fb003c8bb 100644 --- a/src/columns/ColUDA.cpp +++ b/src/columns/ColUDA.cpp @@ -62,38 +62,42 @@ ColumnUDA::~ColumnUDA () // void ColumnUDA::measure (Task& task, int& minimum, int& maximum) { + minimum = maximum = 0; + if (_style == "default") { std::string value = task.get (_name); + if (value != "") + { + if (_type == "date") + { + // Determine the output date format, which uses a hierarchy of definitions. + // rc.report..dateformat + // rc.dateformat.report + // rc.dateformat. + Date date ((time_t) strtol (value.c_str (), NULL, 10)); + std::string format = context.config.get ("report." + _report + ".dateformat"); + if (format == "") + format = context.config.get ("dateformat.report"); + if (format == "") + format = context.config.get ("dateformat"); - if (_type == "date") - { - // Determine the output date format, which uses a hierarchy of definitions. - // rc.report..dateformat - // rc.dateformat.report - // rc.dateformat. - Date date ((time_t) strtol (value.c_str (), NULL, 10)); - std::string format = context.config.get ("report." + _report + ".dateformat"); - if (format == "") - format = context.config.get ("dateformat.report"); - if (format == "") - format = context.config.get ("dateformat"); - - minimum = maximum = date.toString (format).length (); - } - else if (_type == "duration") - { - minimum = maximum = Duration (value).formatCompact ().length (); - } - else if (_type == "string") - { - std::string stripped = Color::strip (value); - maximum = longestLine (stripped); - minimum = longestWord (stripped); - } - else if (_type == "numeric") - { - minimum = maximum = value.length (); + minimum = maximum = date.toString (format).length (); + } + else if (_type == "duration") + { + minimum = maximum = Duration (value).formatCompact ().length (); + } + else if (_type == "string") + { + std::string stripped = Color::strip (value); + maximum = longestLine (stripped); + minimum = longestWord (stripped); + } + else if (_type == "numeric") + { + minimum = maximum = value.length (); + } } } else @@ -110,45 +114,47 @@ void ColumnUDA::render ( if (_style == "default") { std::string value = task.get (_name); + if (value != "") + { + if (_type == "date") + { + // Determine the output date format, which uses a hierarchy of definitions. + // rc.report..dateformat + // rc.dateformat.report + // rc.dateformat. + std::string format = context.config.get ("report." + _report + ".dateformat"); + if (format == "") + format = context.config.get ("dateformat.report"); + if (format == "") + format = context.config.get ("dateformat"); - if (_type == "date") - { - // Determine the output date format, which uses a hierarchy of definitions. - // rc.report..dateformat - // rc.dateformat.report - // rc.dateformat. - std::string format = context.config.get ("report." + _report + ".dateformat"); - if (format == "") - format = context.config.get ("dateformat.report"); - if (format == "") - format = context.config.get ("dateformat"); + lines.push_back ( + color.colorize ( + leftJustify ( + Date ((time_t) strtol (value.c_str (), NULL, 10)) + .toString (format), width))); + } + else if (_type == "duration") + { + lines.push_back ( + color.colorize ( + rightJustify ( + Duration (value).formatCompact (), + width))); + } + else if (_type == "string") + { + std::vector raw; + wrapText (raw, value, width, _hyphenate); - lines.push_back ( - color.colorize ( - leftJustify ( - Date ((time_t) strtol (value.c_str (), NULL, 10)) - .toString (format), width))); - } - else if (_type == "duration") - { - lines.push_back ( - color.colorize ( - rightJustify ( - Duration (value).formatCompact (), - width))); - } - else if (_type == "string") - { - std::vector raw; - wrapText (raw, value, width, _hyphenate); - - std::vector ::iterator i; - for (i = raw.begin (); i != raw.end (); ++i) - lines.push_back (color.colorize (leftJustify (*i, width))); - } - else if (_type == "numeric") - { - lines.push_back (color.colorize (rightJustify (value, width))); + std::vector ::iterator i; + for (i = raw.begin (); i != raw.end (); ++i) + lines.push_back (color.colorize (leftJustify (*i, width))); + } + else if (_type == "numeric") + { + lines.push_back (color.colorize (rightJustify (value, width))); + } } } } diff --git a/src/commands/CmdInfo.cpp b/src/commands/CmdInfo.cpp index eec218e03..8cd4de064 100644 --- a/src/commands/CmdInfo.cpp +++ b/src/commands/CmdInfo.cpp @@ -323,9 +323,11 @@ int CmdInfo::execute (std::string& output) // Show any UDAs std::vector all = task->all (); std::vector ::iterator att; + std::string type; for (att = all.begin (); att != all.end (); ++att) { - if (context.config.get ("uda." + *att + ".type") != "") + type = context.config.get ("uda." + *att + ".type"); + if (type != "") { Column* col = context.columns[*att]; if (col) @@ -335,14 +337,25 @@ int CmdInfo::execute (std::string& output) { row = view.addRow (); view.set (row, 0, col->label ()); + + if (type == "date") + { + // Determine the output date format, which uses a hierarchy of definitions. + // rc.report..dateformat + // rc.dateformat.report + // rc.dateformat. + std::string format = context.config.get ("report.info.dateformat"); + if (format == "") + format = context.config.get ("dateformat.report"); + if (format == "") + format = context.config.get ("dateformat"); + + value = Date (value).toString (format); + } + else if (type == "duration") + value = Duration (value).formatCompact (); + view.set (row, 1, value); -/* - std::vector lines; - Color color; - col->render (lines, *task, 0, color); - join (value, " ", lines); - view.set (row, 1, value); -*/ } } } diff --git a/test/uda_date.t b/test/uda_date.t new file mode 100755 index 000000000..44349c2fd --- /dev/null +++ b/test/uda_date.t @@ -0,0 +1,69 @@ +#! /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; +use Test::More tests => 5; + +# Create the rc file. +if (open my $fh, '>', 'uda.rc') +{ + print $fh "data.location=.\n", + "confirmation=off\n", + "uda.extra.type=date\n", + "uda.extra.label=Extra\n", + "report.uda.description=UDA Test\n", + "report.uda.columns=id,extra,description\n", + "report.uda.sort=extra,description\n", + "report.uda.labels=ID,Extra,Description\n"; + close $fh; + ok (-r 'uda.rc', 'Created uda.rc'); +} + +# Add tasks with and without the UDA. +qx{../src/task rc:uda.rc add with extra:tomorrow}; +qx{../src/task rc:uda.rc add without}; +my $output = qx{../src/task rc:uda.rc uda}; +like ($output, qr/1\s+[\d\/]+\s+with/, 'UDA date stored'); +like ($output, qr/2\s+without/, 'UDA date blank'); + +# Add bad data. +$output = qx{../src/task rc:uda.rc add bad extra:unrecognized_date}; +unlike ($output, qr/Created task \d+/, 'UDA date bad data not accepted'); + +# Cleanup. +unlink qw(pending.data completed.data undo.data backlog.data synch.key uda.rc); +ok (! -r 'pending.data' && + ! -r 'completed.data' && + ! -r 'undo.data' && + ! -r 'backlog.data' && + ! -r 'synch.key' && + ! -r 'uda.rc', 'Cleanup'); + +exit 0; + diff --git a/test/uda_duration.t b/test/uda_duration.t index 547d91373..8448c2d68 100755 --- a/test/uda_duration.t +++ b/test/uda_duration.t @@ -49,8 +49,8 @@ if (open my $fh, '>', 'uda.rc') qx{../src/task rc:uda.rc add with extra:1day}; qx{../src/task rc:uda.rc add without}; my $output = qx{../src/task rc:uda.rc uda}; -like ($output, qr/1\s+\S+\s+with/, 'UDA duration stored'); -like ($output, qr/2\s+-\s+without/, 'UDA duration blank'); +like ($output, qr/1\s+1d\s+with/, 'UDA duration stored'); +like ($output, qr/2\s+-\s+without/, 'UDA duration blank'); # Add bad data. $output = qx{../src/task rc:uda.rc add bad extra:unrecognized_duration};