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