Merging in latest from upstream (TM/task:refs/heads/2.4.0)

* commit 'd8b7d914ac': (31 commits)
  TW-5
  TW-306
  Code Cleanup
  Documentation
  TW-285
  Unit Tests
  Unit Tests
  Code Cleanup
  TW-115
  TW-1257
  TW-1300
  Code Cleanup
  Bug
  ChangeLog
  TW-1301
  Bug TW-1302
  Diagnostics
  Bug TW-1254
  Documentation
  Bug TW-1295
  ...
This commit is contained in:
Renato Alves 2014-04-13 18:23:10 +00:00
commit 0b1732fcef
39 changed files with 1557 additions and 609 deletions

View file

@ -27,7 +27,7 @@
use strict;
use warnings;
use Test::More tests => 14;
use Test::More tests => 22;
# '15min' is seen as '15', 'min', not '15min' duration.
my $output = qx{../src/calc --debug --noambiguous '12 * 3600 + 34 * 60 + 56'};
@ -36,6 +36,7 @@ like ($output, qr/token infix '3600' Number/, 'Number 3600');
like ($output, qr/token infix '34' Number/, 'Number 60');
like ($output, qr/token infix '60' Number/, 'Number 60');
like ($output, qr/token infix '56' Number/, 'Number 56');
like ($output, qr/no errors/ms, 'No syntax errors');
like ($output, qr/^45296$/ms, 'Result 45296');
unlike ($output, qr/Error/, 'No errors');
@ -48,5 +49,14 @@ like ($output, qr/token postfix '56' Number/, 'Number 56');
like ($output, qr/^45296$/ms, 'Result 45296');
unlike ($output, qr/Error/, 'No errors');
$output = qx{../src/calc --debug --noambiguous '2--3'};
like ($output, qr/token infix '2' Number/ms, 'Number 2');
like ($output, qr/token infix '-' Operator/ms, 'Operator -');
like ($output, qr/token infix '_neg_' Operator/ms, 'operator _neg_');
like ($output, qr/token infix '3' Number/ms, 'Number 3');
like ($output, qr/no errors/ms, 'No syntax errors');
like ($output, qr/^5$/ms, 'Result 5');
unlike ($output, qr/Error/, 'No errors');
exit 0;

View file

@ -27,6 +27,7 @@
use strict;
use warnings;
use POSIX qw(mktime);
use Test::More tests => 7;
# Ensure environment has no influence.
@ -49,30 +50,38 @@ qx{../src/task rc:count.rc add three 2>&1};
qx{../src/task rc:count.rc 2 delete 2>&1};
qx{../src/task rc:count.rc add four wait:eom 2>&1};
# TODO This fails when today == eom. For example, on 2013-04-30 at 8:00:00, the
# value for 'eom' is 2013-04-30 0:00:00, which is already past due, which
# means a second child task is generated. This would be fixed by 'eom'
# expanding to 2013-04-30 24:00:00, as per ISO-8601.
qx{../src/task rc:count.rc add five due:eom recur:monthly 2>&1};
TODO: {
my @today = localtime;
my @tomorrow = @today;
$tomorrow[3] += 1;
@tomorrow = localtime(mktime(@tomorrow));
local $TODO = 'can fail when today == eom' if $today[4] != $tomorrow[4];
diag ("Problem: the next test fails at EOM");
my $output = qx{../src/task rc:count.rc count 2>&1};
like ($output, qr/^5\n/ms, 'count');
# TODO This fails when today == eom. For example, on 2013-04-30 at 8:00:00, the
# value for 'eom' is 2013-04-30 0:00:00, which is already past due, which
# means a second child task is generated. This would be fixed by 'eom'
# expanding to 2013-04-30 24:00:00, as per ISO-8601.
qx{../src/task rc:count.rc add five due:eom recur:monthly 2>&1};
$output = qx{../src/task rc:count.rc count status:deleted rc.debug:1 2>&1};
like ($output, qr/^1\n/ms, 'count status:deleted');
diag ("Problem: the next test fails at EOM");
my $output = qx{../src/task rc:count.rc count 2>&1};
like ($output, qr/^5\n/ms, 'count');
diag ("Problem: the next test fails at EOM");
$output = qx{../src/task rc:count.rc count e 2>&1};
like ($output, qr/^3\n/ms, 'count e');
$output = qx{../src/task rc:count.rc count status:deleted rc.debug:1 2>&1};
like ($output, qr/^1\n/ms, 'count status:deleted');
diag ("Problem: the next test fails at EOM");
$output = qx{../src/task rc:count.rc count description.startswith:f 2>&1};
like ($output, qr/^2\n/ms, 'count description.startswith:f');
diag ("Problem: the next test fails at EOM");
$output = qx{../src/task rc:count.rc count e 2>&1};
like ($output, qr/^3\n/ms, 'count e');
diag ("Problem: the next test fails at EOM");
$output = qx{../src/task rc:count.rc count due.any: 2>&1};
like ($output, qr/^1\n/ms, 'count due.any:');
diag ("Problem: the next test fails at EOM");
$output = qx{../src/task rc:count.rc count description.startswith:f 2>&1};
like ($output, qr/^2\n/ms, 'count description.startswith:f');
diag ("Problem: the next test fails at EOM");
$output = qx{../src/task rc:count.rc count due.any: 2>&1};
like ($output, qr/^1\n/ms, 'count due.any:');
}
# Cleanup.
unlink qw(pending.data completed.data undo.data backlog.data count.rc);

View file

@ -35,16 +35,18 @@ Context context;
// A few hard-coded symbols.
bool get (const std::string& name, Variant& value)
{
if (name == "pi") {value = Variant (3.14159165); return true;}
else if (name == "x") {value = Variant (true); return true;}
if (name == "x")
value = Variant (true);
else
return false;
return false;
return true;
}
////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)
{
UnitTest t (43);
UnitTest t (46);
// Test the source independently.
Variant v;
@ -54,10 +56,6 @@ int main (int argc, char** argv)
t.is (v.type (), Variant::type_boolean, "get(x) --> boolean");
t.is (v.get_bool (), true, "get(x) --> true");
t.ok (get ("pi", v), "true <-- get(pi)");
t.is (v.type (), Variant::type_real, "get(pi) --> real");
t.is (v.get_real (), 3.141592, 0.00001, "get(pi) --> 3.14159265");
Eval e;
e.addSource (get);
Variant result;
@ -138,6 +136,20 @@ int main (int argc, char** argv)
t.is (result.type (), Variant::type_integer, "infix '2*3+1' --> integer");
t.is (result.get_integer (), 7, "infix '2*3+1' --> 7");
// TW-1254 - Unary minus support.
e.evaluateInfixExpression ("2--3", result);
t.is (result.type (), Variant::type_integer, "infix '2--3' --> integer");
t.is (result.get_integer (), 5, "infix '2--3' --> 5");
//e.debug ();
e.evaluateInfixExpression ("!false", result);
t.is (result.type (), Variant::type_boolean, "infix '!false' --> boolean");
t.is (result.get_bool (), true, "infix '!false' --> true");
e.evaluateInfixExpression ("!true", result);
t.is (result.type (), Variant::type_boolean, "infix '!true' --> boolean");
t.is (result.get_bool (), false, "infix '!true' --> false");
return 0;
}

View file

@ -91,21 +91,24 @@ int main (int argc, char** argv)
int local_s = (local_now->tm_hour * 3600) +
(local_now->tm_min * 60) +
local_now->tm_sec;
local_now->tm_hour = 0;
local_now->tm_min = 0;
local_now->tm_sec = 0;
local_now->tm_hour = 0;
local_now->tm_min = 0;
local_now->tm_sec = 0;
local_now->tm_isdst = -1;
time_t local = mktime (local_now);
std::cout << "# local midnight today " << local << "\n";
local_now->tm_year = 2013 - 1900;
local_now->tm_mon = 12 - 1;
local_now->tm_mday = 6;
local_now->tm_year = 2013 - 1900;
local_now->tm_mon = 12 - 1;
local_now->tm_mday = 6;
local_now->tm_isdst = 0;
time_t local6 = mktime (local_now);
std::cout << "# local midnight 2013-12-06 " << local6 << "\n";
local_now->tm_year = 2013 - 1900;
local_now->tm_mon = 12 - 1;
local_now->tm_mday = 1;
local_now->tm_year = 2013 - 1900;
local_now->tm_mon = 12 - 1;
local_now->tm_mday = 1;
local_now->tm_isdst = 0;
time_t local1 = mktime (local_now);
std::cout << "# local midnight 2013-12-01 " << local1 << "\n";
@ -113,21 +116,24 @@ int main (int argc, char** argv)
int utc_s = (utc_now->tm_hour * 3600) +
(utc_now->tm_min * 60) +
utc_now->tm_sec;
utc_now->tm_hour = 0;
utc_now->tm_min = 0;
utc_now->tm_sec = 0;
utc_now->tm_hour = 0;
utc_now->tm_min = 0;
utc_now->tm_sec = 0;
utc_now->tm_isdst = -1;
time_t utc = timegm (utc_now);
std::cout << "# utc midnight today " << utc << "\n";
utc_now->tm_year = 2013 - 1900;
utc_now->tm_mon = 12 - 1;
utc_now->tm_mday = 6;
utc_now->tm_year = 2013 - 1900;
utc_now->tm_mon = 12 - 1;
utc_now->tm_mday = 6;
utc_now->tm_isdst = 0;
time_t utc6 = timegm (utc_now);
std::cout << "# utc midnight 2013-12-06 " << utc6 << "\n";
utc_now->tm_year = 2013 - 1900;
utc_now->tm_mon = 12 - 1;
utc_now->tm_mday = 1;
utc_now->tm_year = 2013 - 1900;
utc_now->tm_mon = 12 - 1;
utc_now->tm_mday = 1;
utc_now->tm_isdst = 0;
time_t utc1 = timegm (utc_now);
std::cout << "# utc midnight 2013-12-01 " << utc1 << "\n";

View file

@ -1,5 +1,6 @@
#! /bin/sh
rc=0
if [ x"$1" = x"--verbose" ];
then
for i in ${TESTBLOB}
@ -9,9 +10,10 @@ then
while read LINE
do
echo "$LINE"
done < test.log
done < test.log || rc=1
rm test.log
done
exit $rc
else
date > all.log
@ -37,7 +39,7 @@ else
COUNT=`expr $COUNT + 1`
fi
$i >> all.log 2>&1
$i >> all.log 2>&1 || rc=1
done
if [ $BAR -eq 1 ]; then
@ -53,4 +55,5 @@ else
printf "Fail: %5d\n" `grep -c '^not' all.log`
printf "Skipped: %5d\n" `grep -c '^skip' all.log`
printf "Runtime: %5d seconds\n" $RUNTIME
exit $rc
fi

View file

@ -28,6 +28,7 @@
#include <iomanip>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <test.h>
///////////////////////////////////////////////////////////////////////////////
@ -84,6 +85,7 @@ UnitTest::~UnitTest ()
<< " skipped. "
<< std::setprecision (3) << percentPassed
<< "% passed.\n";
exit (_failed > 0);
}
///////////////////////////////////////////////////////////////////////////////

75
test/tw-1300.t Executable file
View file

@ -0,0 +1,75 @@
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
################################################################################
##
## Copyright 2006 - 2014, 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
##
################################################################################
import sys
import os
import signal
from glob import glob
# Ensure python finds the local simpletap and basetest modules
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from basetest import BaseTestCase
class BaseTestBug1300(BaseTestCase):
@classmethod
def prepare(cls):
with open("bug.rc", 'w') as fh:
fh.write("data.location=.\n"
"confirmation=no\n")
def tearDown(self):
"""Needed after each test or setUp will cause duplicated data at start
of the next test.
"""
for file in glob("*.data"):
os.remove(file)
@classmethod
def cleanup(cls):
os.remove("bug.rc")
class TestBug1300(BaseTestBug1300):
def test_dom_exit_status_good(self):
"""If the DOM recognizes a reference, it should return '0'
"""
self.callTaskSuccess(["rc:bug.rc", "_get", "context.program"])
def test_dom_exit_status_bad(self):
"""If the DOM does not recognize a reference, it should return '1'
"""
self.callTaskError(["rc:bug.rc", "_get", "XYZ"])
if __name__ == "__main__":
from simpletap import TAPTestRunner
import unittest
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4

116
test/tw-285.t Executable file
View file

@ -0,0 +1,116 @@
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
################################################################################
##
## Copyright 2006 - 2014, 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
##
################################################################################
import sys
import os
import signal
from glob import glob
# Ensure python finds the local simpletap and basetest modules
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from basetest import BaseTestCase
class BaseTest285(BaseTestCase):
@classmethod
def prepare(cls):
with open("bug.rc", 'w') as fh:
fh.write("data.location=.\n"
"verbose=nothing\n"
"confirmation=no\n")
def setUp(self):
"""Executed before each test in the class"""
# OVERDUE YESTERDAY DUE TODAY TOMORROW WEEK MONTH YEAR
# due:-1week Y - - - - ? ? ?
# due:-1day Y Y - - - ? ? ?
# due:today Y - Y Y - ? ? ?
# due:tomorrow - - Y - Y ? ? ?
# due:3days - - Y - - ? ? ?
# due:1month - - - - - - - ?
# due:1year - - - - - - - -
self.callTaskSuccess(['rc:bug.rc', 'add', 'due_last_week', 'due:-1week'])
self.callTaskSuccess(['rc:bug.rc', 'add', 'due_yesterday', 'due:-1day'])
self.callTaskSuccess(['rc:bug.rc', 'add', 'due_earlier_today', 'due:today'])
self.callTaskSuccess(['rc:bug.rc', 'add', 'due_later_today', 'due:tomorrow'])
self.callTaskSuccess(['rc:bug.rc', 'add', 'due_three_days', 'due:3days'])
self.callTaskSuccess(['rc:bug.rc', 'add', 'due_next_month', 'due:1month'])
self.callTaskSuccess(['rc:bug.rc', 'add', 'due_next_year', 'due:1year'])
def tearDown(self):
"""Needed after each test or setUp will cause duplicated data at start
of the next test.
"""
for file in glob("*.data"):
os.remove(file)
@classmethod
def cleanup(cls):
os.remove("bug.rc")
class Test285(BaseTest285):
def test_overdue(self):
"""+OVERDUE"""
code, out, err = self.callTaskSuccess(["rc:bug.rc", "+OVERDUE", "count"])
self.assertEqual(out, "3\n", "+OVERDUE == 3 tasks")
def test_yesterday(self):
"""+YESTERDAY"""
code, out, err = self.callTaskSuccess(["rc:bug.rc", "+YESTERDAY", "count"])
self.assertEqual(out, "1\n", "+YESTERDAY == 1 task")
def test_due(self):
"""+DUE"""
code, out, err = self.callTaskSuccess(["rc:bug.rc", "+DUE", "count"])
self.assertEqual(out, "3\n", "+DUE == 3 task")
def test_today(self):
"""+TODAY"""
code, out, err = self.callTaskSuccess(["rc:bug.rc", "+TODAY", "count"])
self.assertEqual(out, "1\n", "+TODAY == 1 task")
def test_duetoday(self):
"""+DUETODAY"""
code, out, err = self.callTaskSuccess(["rc:bug.rc", "+DUETODAY", "count"])
self.assertEqual(out, "1\n", "+DUETODAY == 1 task")
def test_tomorrow(self):
"""+TOMORROW"""
code, out, err = self.callTaskSuccess(["rc:bug.rc", "+TOMORROW", "count"])
self.assertEqual(out, "1\n", "+TOMORROW == 1 task")
if __name__ == "__main__":
from simpletap import TAPTestRunner
import unittest
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4