diff --git a/src/DOM.cpp b/src/DOM.cpp index 1e787bf01..83269b000 100644 --- a/src/DOM.cpp +++ b/src/DOM.cpp @@ -190,6 +190,25 @@ bool DOM::get (const std::string& name, std::string& value) // . // . // +// For certain attributes: +// .year +// .month +// .day +// .hour +// .minute +// .second +// +// . Includes virtual tags +// +// ..entry +// ..entry.year +// ..entry.month +// ..entry.day +// ..entry.hour +// ..entry.minute +// ..entry.second +// ..description +// bool DOM::get (const std::string& name, const Task& task, std::string& value) { // @@ -205,83 +224,109 @@ bool DOM::get (const std::string& name, const Task& task, std::string& value) return true; } - std::string canonical; - if (task.size () && context.parser.canonicalize (canonical, "attribute", name)) - { - value = task.get (canonical); - return true; - } + // split name on '.' + std::vector elements; + split (elements, name, '.'); - // . - Nibbler n (name); - n.save (); - int id; - if (n.getInt (id)) + if (elements.size () == 1) { - if (n.skip ('.')) + std::string canonical; + if (task.size () && context.parser.canonicalize (canonical, "attribute", name)) { - Task ref; - if (id == task.id) - ref = task; + value = task.get (canonical); + return true; + } + } + else if (elements.size () > 1) + { + Task ref; + + Nibbler n (elements[0]); + n.save (); + int id; + std::string uuid; + bool proceed = false; + + if (n.getInt (id)) + { + if (n.skip ('.')) + { + if (id == task.id) + ref = task; + else + context.tdb2.get (id, ref); + + proceed = true; + } else - context.tdb2.get (id, ref); + n.restore (); + } + else if (n.getUUID (uuid)) + { + if (n.skip ('.')) + { + if (uuid == task.get ("uuid")) + ref = task; + else + context.tdb2.get (uuid, ref); - std::string attr; - n.getUntilEOS (attr); + proceed = true; + } + } - if (attr == "id") + if (proceed) + { + if (elements[1] == "id") { value = format (ref.id); return true; } - else if (attr == "urgency") + else if (elements[1] == "urgency") { value = format (ref.urgency_c ()); return true; } - else if (context.parser.canonicalize (canonical, "attribute", attr)) + + std::string canonical; + if (context.parser.canonicalize (canonical, "attribute", elements[1])) { - value = ref.get (canonical); - return true; + if (elements.size () == 2) + { + value = ref.get (canonical); + return true; + } + else if (elements.size () == 3) + { + // .year + // .month + // .day + // .hour + // .minute + // .second + + // . + if (elements[1] == "tag") + { + value = ref.hasTag (elements[2]) ? elements[2] : ""; + return true; + } + } + else if (elements.size () == 3) + { + // ..entry + // ..description + } + else if (elements.size () == 4) + { + // ..entry.year + // ..entry.month + // ..entry.day + // ..entry.hour + // ..entry.minute + // ..entry.second + } } } - - n.restore (); - } - - // . - std::string uuid; - if (n.getUUID (uuid)) - { - if (n.skip ('.')) - { - Task ref; - if (uuid == task.get ("uuid")) - ref = task; - else - context.tdb2.get (uuid, ref); - - std::string attr; - n.getUntilEOS (attr); - - if (attr == "id") - { - value = format (ref.id); - return true; - } - else if (attr == "urgency") - { - value = format (ref.urgency_c (), 4, 3); - return true; - } - else if (context.parser.canonicalize (canonical, "attribute", attr)) - { - value = ref.get (canonical); - return true; - } - } - - n.restore (); } // Delegate to the context-free version of DOM::get. diff --git a/test/dom.2.t b/test/dom.2.t index c1429bbbb..645723dd5 100755 --- a/test/dom.2.t +++ b/test/dom.2.t @@ -27,44 +27,71 @@ use strict; use warnings; -use Test::More tests => 5; +use Test::More tests => 12; # Ensure environment has no influence. delete $ENV{'TASKDATA'}; delete $ENV{'TASKRC'}; +use File::Basename; +my $ut = basename ($0); +my $rc = $ut . '.rc'; + # Create the rc file. -if (open my $fh, '>', 'dom.rc') +if (open my $fh, '>', $rc) { print $fh "data.location=.\n", "dateformat=YMD\n", - "dateformat.info=YMD\n"; + "dateformat.info=YMD\n", + "confirmation=off\n"; close $fh; } # DOM reference to other task. -qx{../src/task rc:dom.rc add one due:20110901 2>&1}; -qx{../src/task rc:dom.rc add two due:1.due 2>&1}; -my $output = qx{../src/task rc:dom.rc 2 info 2>&1}; -like ($output, qr/Due\s+20110901/, 'Found due date duplicated via dom'); +qx{../src/task rc:$rc add one due:20110901 2>&1}; +qx{../src/task rc:$rc add two due:1.due 2>&1}; +my $output = qx{../src/task rc:$rc 2 info 2>&1}; +like ($output, qr/Due\s+20110901/, "$ut: Found due date duplicated via dom"); # DOM reference to the current task. -qx{../src/task rc:dom.rc add three due:20110901 wait:due 2>&1}; -$output = qx{../src/task rc:dom.rc 3 info 2>&1}; -like ($output, qr/Waiting until\s+20110901/, 'Found wait date duplicated from due date'); +qx{../src/task rc:$rc add three due:20110901 wait:due +tag1 +tag2 2>&1}; +$output = qx{../src/task rc:$rc 3 info 2>&1}; +like ($output, qr/Waiting until\s+20110901/, "$ut: Found wait date duplicated from due date"); # ID <--> UUID <--> ID round trip via DOM. -$output = qx{../src/task rc:dom.rc _get 1.uuid 2>&1}; -like ($output, qr/^.{36}$/, 'DOM id --> uuid'); +$output = qx{../src/task rc:$rc _get 1.uuid 2>&1}; +like ($output, qr/^.{36}$/, "$ut: DOM id --> uuid"); my $uuid = chomp $output; -$output = qx{../src/task rc:dom.rc _get ${uuid}.id 2>&1}; -like ($output, qr/^1$/, 'DOM uuid --> id'); +$output = qx{../src/task rc:$rc _get ${uuid}.id 2>&1}; +like ($output, qr/^1$/, "$ut: DOM uuid --> id"); # Failed DOM lookup returns blank. -$output = qx{../src/task rc:dom.rc _get 4.description 2>&1}; +$output = qx{../src/task rc:$rc _get 4.description 2>&1}; like ($output, qr/^$/, "DOM 4.description --> ''"); +# Test extended DOM support (2.4.0) +$output = qx{../src/task rc:$rc _get 3.tags 2>&1}; +like ($output, qr/^tag1,tag2$/, "$ut: ."); + +$output = qx{../src/task rc:$rc _get 3.tag.tag1 2>&1}; +like ($output, qr/^tag1,tag2$/, "$ut: .tag.tag1"); + +$output = qx{../src/task rc:$rc _get 3.tag.OVERDUE 2>&1}; +like ($output, qr/^OVERDUE$/, "$ut: .tag."); + +$output = qx{../src/task rc:$rc _get 3.due.year 2>&1}; +like ($output, qr/^\d{4}$/, "$ut: .due.year"); + +qx{../src/task rc:$rc 3 annotate note 2>&1}; +ok ($? == 0, "$ut: add annotation"); + +$output = qx{../src/task rc:$rc _get 3.annotation.1.entry 2>&1}; +like ($output, qr/^\d+$/, "$ut: .annotation.1.entry"); + +$output = qx{../src/task rc:$rc _get 3.annotation.1.description 2>&1}; +like ($output, qr/^note$/, "$ut: .annotation.1.description"); + # Cleanup. -unlink qw(pending.data completed.data undo.data backlog.data dom.rc); +unlink qw(pending.data completed.data undo.data backlog.data), $rc; exit 0;