- TW-1300 _get could use return codes (thanks to Scott Kostyshak).
This commit is contained in:
Paul Beckingham 2014-04-12 13:32:35 -04:00
parent 32272addd0
commit 501194abfa
6 changed files with 107 additions and 5 deletions

View file

@ -35,6 +35,7 @@
Wilk). Wilk).
- TW-1296 make test/run_all exit with non-zero code if a test fail (thanks to - TW-1296 make test/run_all exit with non-zero code if a test fail (thanks to
Jakub Wilk). Jakub Wilk).
- TW-1300 _get could use return codes (thanks to Scott Kostyshak).
- TW-1301 Virtual tag +PENDING (thanks to Profpatsch). - TW-1301 Virtual tag +PENDING (thanks to Profpatsch).
- TW-1302 CmdShow.cpp:244: bad length in substr ? (thanks to David Binderman). - TW-1302 CmdShow.cpp:244: bad length in substr ? (thanks to David Binderman).
- Removed deprecated 'echo.command' setting, in favor of the 'header' and - Removed deprecated 'echo.command' setting, in favor of the 'header' and

1
NEWS
View file

@ -6,6 +6,7 @@ New Features in taskwarrior 2.4.0
- Portuguese (por-PRT) localization. - Portuguese (por-PRT) localization.
- Better handling for deletion of recurring tasks. - Better handling for deletion of recurring tasks.
- New virtual tags: YESTERDAY, TOMORROW, READY, PENDING, COMPLETED, DELETED. - New virtual tags: YESTERDAY, TOMORROW, READY, PENDING, COMPLETED, DELETED.
- The '_get' command properly uses exit codes.
New commands in taskwarrior 2.4.0 New commands in taskwarrior 2.4.0

View file

@ -537,6 +537,9 @@ from tasks, or the system. Supported DOM references are:
Note that the 'rc.<name>' reference may need to be escaped using '--' to prevent Note that the 'rc.<name>' reference may need to be escaped using '--' to prevent
the reference from being interpreted as an override. the reference from being interpreted as an override.
Note that if the DOM reference is not valid, or the reference evaluates to a
missing value, the command exits with 1.
.SH ATTRIBUTES AND METADATA .SH ATTRIBUTES AND METADATA
.TP .TP

View file

@ -157,9 +157,9 @@ const std::string DOM::get (const std::string& name, const Task& task)
std::string canonical; std::string canonical;
// <attr> // <attr>
if (name == "id") return format (task.id); if (task.size () && name == "id") return format (task.id);
else if (name == "urgency") return format (task.urgency_c ()); else if (task.size () && name == "urgency") return format (task.urgency_c ());
else if (A3::is_attribute (name, canonical)) return task.get (canonical); else if (task.size () && A3::is_attribute (name, canonical)) return task.get (canonical);
// <id>.<name> // <id>.<name>
if (n.getInt (id)) if (n.getInt (id))

View file

@ -52,17 +52,23 @@ int CmdGet::execute (std::string& output)
if (words.size () == 0) if (words.size () == 0)
throw std::string (STRING_CMD_GET_NO_DOM); throw std::string (STRING_CMD_GET_NO_DOM);
bool found = false;
std::vector <std::string> results; std::vector <std::string> results;
std::vector <std::string>::iterator word; std::vector <std::string>::iterator word;
for (word = words.begin (); word != words.end (); ++word) for (word = words.begin (); word != words.end (); ++word)
{ {
Task t; Task t;
results.push_back (context.dom.get (*word, t)); std::string result = context.dom.get (*word, t);
results.push_back (result);
if (result != "" &&
result != *word)
found = true;
} }
join (output, " ", results); join (output, " ", results);
output += "\n"; output += "\n";
return 0; return found ? 0 : 1;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

91
test/feature.1300.t Executable file
View file

@ -0,0 +1,91 @@
#!/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'
"""
args = ["rc:bug.rc", "_get", "context.program"]
self.run_command(args, 0)
def test_dom_exit_status_bad(self):
"""If the DOM does not recognize a reference, it should return '1'
"""
args = ["rc:bug.rc", "_get", "XYZ"]
self.run_command(args, 1)
def run_command(self, args, expected_status):
code, out, err = self.callTask(args)
# We shouldn't get a segmentation fault
# (negative exit code == 128 - real_exit_code)
expected = -signal.SIGSEGV
self.assertNotEqual(expected, code, "Task segfaulted")
# Instead we expect a clean exit
self.assertEqual(expected_status, code,
"Exit code was not ({0}), but ({0})".format(expected_status, code))
if __name__ == "__main__":
from simpletap import TAPTestRunner
import unittest
unittest.main(testRunner=TAPTestRunner())
# vim: ai sts=4 et sw=4