Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e3176ed70 | ||
|
|
1c5068edb2 | ||
|
|
eb09f4da9a | ||
|
|
112d0d8771 | ||
|
|
31bbc0ea2f | ||
|
|
8cd43ce2b2 | ||
|
|
bbd8a9556e | ||
|
|
68c1ca3f69 | ||
|
|
d868294d90 | ||
|
|
36e3317907 | ||
|
|
da37c08dbd | ||
|
|
89a7f2a459 | ||
|
|
98da8ddcb8 | ||
|
|
cf634a22c9 | ||
|
|
4400a6f6ca |
@@ -1,5 +1,4 @@
|
|||||||
cmake_minimum_required (VERSION 2.8)
|
cmake_minimum_required (VERSION 2.8)
|
||||||
set(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required
|
|
||||||
|
|
||||||
include (CheckFunctionExists)
|
include (CheckFunctionExists)
|
||||||
include (CheckStructHasMember)
|
include (CheckStructHasMember)
|
||||||
@@ -7,7 +6,7 @@ include (CheckStructHasMember)
|
|||||||
set (HAVE_CMAKE true)
|
set (HAVE_CMAKE true)
|
||||||
|
|
||||||
project (task)
|
project (task)
|
||||||
set (PROJECT_VERSION "2.1.1")
|
set (PROJECT_VERSION "2.1.2")
|
||||||
|
|
||||||
SET (TASK_MAN1DIR share/man/man1 CACHE STRING "Installation directory for man pages, section 1")
|
SET (TASK_MAN1DIR share/man/man1 CACHE STRING "Installation directory for man pages, section 1")
|
||||||
SET (TASK_MAN5DIR share/man/man5 CACHE STRING "Installation directory for man pages, section 5")
|
SET (TASK_MAN5DIR share/man/man5 CACHE STRING "Installation directory for man pages, section 5")
|
||||||
|
|||||||
14
ChangeLog
14
ChangeLog
@@ -1,14 +1,22 @@
|
|||||||
------ current release ---------------------------
|
------ current release ---------------------------
|
||||||
|
|
||||||
2.1.1 (2012-07-24)
|
2.1.2 (2012-09-18)
|
||||||
|
|
||||||
|
Bugs
|
||||||
|
+ Bug fix release regarding #1104, which causes duplicate UUIDs during
|
||||||
|
the merge command.
|
||||||
|
+ Fixed bug where shadow files are not properly created when there is a missing
|
||||||
|
.taskrc file (thanks to Pietro Cerutti).
|
||||||
|
|
||||||
|
------ old releases ------------------------------
|
||||||
|
|
||||||
|
2.1.1 (2012-07-24) 46c5f8b826838ce96d9df7fcd3039de3c43483dd
|
||||||
|
|
||||||
Bugs
|
Bugs
|
||||||
+ Fixed bug that caused miplaced commas in JSON export (thanks to greenskeleton).
|
+ Fixed bug that caused miplaced commas in JSON export (thanks to greenskeleton).
|
||||||
+ Fixed bug #1036, which prevents 'until' attributes to be modified for
|
+ Fixed bug #1036, which prevents 'until' attributes to be modified for
|
||||||
non-recurring tasks (thanks to Stéphane Pezennec).
|
non-recurring tasks (thanks to Stéphane Pezennec).
|
||||||
|
|
||||||
------ old releases ------------------------------
|
|
||||||
|
|
||||||
2.1.0 (2012-07-23) a413331c9450b48065f94639e7ab0455eaa74293
|
2.1.0 (2012-07-23) a413331c9450b48065f94639e7ab0455eaa74293
|
||||||
|
|
||||||
Features
|
Features
|
||||||
|
|||||||
33
NEWS
33
NEWS
@@ -1,34 +1,21 @@
|
|||||||
|
|
||||||
New Features in taskwarrior 2.1.0
|
New bug fixes in taskwarrior 2.1.2
|
||||||
|
|
||||||
- The new 'project.indented' format is available and used in the 'projects'
|
- Important bug fix release regarding duplicate UUIDs during the merge command.
|
||||||
and 'summary' commands.
|
|
||||||
- Support for the 'scheduled' date for a task, which represent the earliest
|
|
||||||
opportunity to work on a task.
|
|
||||||
- All tasks may now be given an 'until' date, after which they will expire
|
|
||||||
and are deleted.
|
|
||||||
- Improved UTF8 handling for wide characters.
|
|
||||||
- User defined attributes.
|
|
||||||
- Partial UUIDs must now be at least 14 characters, up from 9. This
|
|
||||||
disambiguates a commonly date format.
|
|
||||||
|
|
||||||
Please refer to the ChangeLog file for full details. There are too many to
|
New features in taskwarrior 2.1.2
|
||||||
list here.
|
|
||||||
|
|
||||||
New commands in taskwarrior 2.1.0
|
- None
|
||||||
|
|
||||||
- New 'ready' report that lists tasks ready for work, sorted by urgency.
|
New commands in taskwarrior 2.1.2
|
||||||
- New 'udas' command shows UDA details and warnings.
|
|
||||||
- New '_udas' helper command lists UDA names for completion purposes.
|
|
||||||
|
|
||||||
New configuration options in taskwarrior 2.1.0
|
- None
|
||||||
|
|
||||||
- urgency.scheduled.coefficient
|
New configuration options in taskwarrior 2.1.2
|
||||||
- urgency.uda.<name>.coefficient
|
|
||||||
- color.scheduled
|
|
||||||
- color.blocking
|
|
||||||
|
|
||||||
Newly deprecated features in taskwarrior 2.1.0
|
- None
|
||||||
|
|
||||||
|
Newly deprecated features in taskwarrior 2.1.2
|
||||||
|
|
||||||
- None
|
- None
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ Override PACKAGE_LANGUAGE, then
|
|||||||
#cmakedefine NETBSD
|
#cmakedefine NETBSD
|
||||||
#cmakedefine HAIKU
|
#cmakedefine HAIKU
|
||||||
#cmakedefine SOLARIS
|
#cmakedefine SOLARIS
|
||||||
#cmakedefine WIN32
|
|
||||||
#cmakedefine UNKNOWN
|
#cmakedefine UNKNOWN
|
||||||
|
|
||||||
/* Found the lua library */
|
/* Found the lua library */
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.TH task-color 5 2012-07-24 "${PACKAGE_STRING}" "User Manuals"
|
.TH task-color 5 2012-09-18 "${PACKAGE_STRING}" "User Manuals"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
task-color \- A color tutorial for the taskwarrior command line todo manager.
|
task-color \- A color tutorial for the taskwarrior command line todo manager.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.TH task-faq 5 2012-07-24 "${PACKAGE_STRING}" "User Manuals"
|
.TH task-faq 5 2012-09-18 "${PACKAGE_STRING}" "User Manuals"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
task-faq \- A FAQ for the task(1) command line todo manager.
|
task-faq \- A FAQ for the task(1) command line todo manager.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.TH task-sync 5 2012-07-24 "${PACKAGE_STRING}" "User Manuals"
|
.TH task-sync 5 2012-09-18 "${PACKAGE_STRING}" "User Manuals"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
task-sync \- A tutorial for the task(1) data synchronization capabilities.
|
task-sync \- A tutorial for the task(1) data synchronization capabilities.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.TH task-tutorial 5 2012-07-24 "${PACKAGE_STRING}" "User Manuals"
|
.TH task-tutorial 5 2012-09-18 "${PACKAGE_STRING}" "User Manuals"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
task-tutorial \- A tutorial for the task(1) command line todo manager.
|
task-tutorial \- A tutorial for the task(1) command line todo manager.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.TH task 1 2012-07-24 "${PACKAGE_STRING}" "User Manuals"
|
.TH task 1 2012-09-18 "${PACKAGE_STRING}" "User Manuals"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
task \- A command line todo manager.
|
task \- A command line todo manager.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.TH taskrc 5 2012-07-24 "${PACKAGE_STRING}" "User Manuals"
|
.TH taskrc 5 2012-09-18 "${PACKAGE_STRING}" "User Manuals"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
taskrc \- Configuration file for the task(1) command
|
taskrc \- Configuration file for the task(1) command
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -503,6 +503,7 @@ void Context::shadow ()
|
|||||||
{
|
{
|
||||||
std::string file_name = config.get ("shadow.file");
|
std::string file_name = config.get ("shadow.file");
|
||||||
std::string command = config.get ("shadow.command");
|
std::string command = config.get ("shadow.command");
|
||||||
|
std::string rcfile = rc_file;
|
||||||
|
|
||||||
// A missing shadow file command uses the default command instead.
|
// A missing shadow file command uses the default command instead.
|
||||||
if (command == "")
|
if (command == "")
|
||||||
@@ -534,13 +535,14 @@ void Context::shadow ()
|
|||||||
|
|
||||||
// Compose the command. Put the rc overrides up front, so that they may
|
// Compose the command. Put the rc overrides up front, so that they may
|
||||||
// be overridden by rc.shadow.command.
|
// be overridden by rc.shadow.command.
|
||||||
command = program +
|
command = program +
|
||||||
" rc.detection:off" + // No need to determine terminal size
|
" rc.detection:off" + // No need to determine terminal size
|
||||||
" rc.color:off" + // Color off by default
|
" rc.color:off" + // Color off by default
|
||||||
" rc.gc:off " + // GC off, to reduce headaches
|
" rc.gc:off " + // GC off, to reduce headaches
|
||||||
command + // User specified command
|
" rc:" + rcfile + " " + // Use specified rc file
|
||||||
" >" + // Capture
|
command + // User specified command
|
||||||
shadow_file._data; // User specified file
|
" >" + // Capture
|
||||||
|
shadow_file._data; // User specified file
|
||||||
|
|
||||||
debug ("Running shadow command: " + command);
|
debug ("Running shadow command: " + command);
|
||||||
system (command.c_str ());
|
system (command.c_str ());
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ std::string Duration::formatPrecise () const
|
|||||||
std::string Duration::formatSeconds () const
|
std::string Duration::formatSeconds () const
|
||||||
{
|
{
|
||||||
char formatted[24];
|
char formatted[24];
|
||||||
sprintf (formatted, "%s%ldsec", (_negative ? "-" : ""), _secs);
|
sprintf (formatted, "%s%llusec", (_negative ? "-" : ""), (unsigned long long)_secs);
|
||||||
return std::string (formatted);
|
return std::string (formatted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
40
src/TDB2.cpp
40
src/TDB2.cpp
@@ -759,6 +759,10 @@ void TDB2::merge (const std::string& mergeFile)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
undo_lines.push_back (lline + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
// Add some color.
|
// Add some color.
|
||||||
Color colorAdded (context.config.get ("color.sync.added"));
|
Color colorAdded (context.config.get ("color.sync.added"));
|
||||||
@@ -768,10 +772,12 @@ void TDB2::merge (const std::string& mergeFile)
|
|||||||
// at this point we can assume: (lline==rline) || (lit == l.end())
|
// at this point we can assume: (lline==rline) || (lit == l.end())
|
||||||
// thus we search for the first non-equal lines or the EOF
|
// thus we search for the first non-equal lines or the EOF
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for ( ; (lit != l.end ()) && (rit != r.end ()); ++lit, ++rit)
|
for (std::vector<std::string>::const_iterator tmp_lit = lit, tmp_rit = rit;
|
||||||
|
(tmp_lit != l.end ()) && (tmp_rit != r.end ());
|
||||||
|
++tmp_lit, ++tmp_rit)
|
||||||
{
|
{
|
||||||
lline = *lit;
|
lline = *tmp_lit;
|
||||||
rline = *rit;
|
rline = *tmp_rit;
|
||||||
|
|
||||||
// found first non-matching lines?
|
// found first non-matching lines?
|
||||||
if (lline.compare (rline) != 0)
|
if (lline.compare (rline) != 0)
|
||||||
@@ -779,13 +785,28 @@ void TDB2::merge (const std::string& mergeFile)
|
|||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else if (tmp_lit->substr (0, 3) == "---")
|
||||||
{
|
{
|
||||||
// push the line to the new undo.data
|
while (lit != tmp_lit)
|
||||||
undo_lines.push_back (lline + "\n");
|
{
|
||||||
|
++lit;
|
||||||
|
++rit;
|
||||||
|
undo_lines.push_back(*lit + "\n");
|
||||||
|
}
|
||||||
|
// at this point, all iterators (tmp_{lit,rit}, lit and rit) are at the same line
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
// set iterators to r.end() or l.end() if they are point to the last line
|
||||||
|
if (++rit != r.end())
|
||||||
|
--rit;
|
||||||
|
|
||||||
|
if (++lit != l.end())
|
||||||
|
--lit;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// branch-off point found:
|
// branch-off point found:
|
||||||
if (found)
|
if (found)
|
||||||
@@ -1003,8 +1024,8 @@ void TDB2::merge (const std::string& mergeFile)
|
|||||||
mods.splice (mods.begin (), rmods);
|
mods.splice (mods.begin (), rmods);
|
||||||
|
|
||||||
DEBUG_STR ("sorting taskmod list");
|
DEBUG_STR ("sorting taskmod list");
|
||||||
mods.sort ();
|
mods.sort (compareTaskmod);
|
||||||
mods_history.sort ();
|
mods_history.sort (compareTaskmod);
|
||||||
}
|
}
|
||||||
else if (rit == r.end ())
|
else if (rit == r.end ())
|
||||||
{
|
{
|
||||||
@@ -1211,7 +1232,7 @@ void TDB2::merge (const std::string& mergeFile)
|
|||||||
// at this point undo contains the lines up to the branch-off point
|
// at this point undo contains the lines up to the branch-off point
|
||||||
// now we merge mods (new modifications from mergefile)
|
// now we merge mods (new modifications from mergefile)
|
||||||
// with lmods (part of old undo.data)
|
// with lmods (part of old undo.data)
|
||||||
lmods.sort();
|
lmods.sort(compareTaskmod);
|
||||||
mods.merge (lmods);
|
mods.merge (lmods);
|
||||||
mods.merge (mods_history);
|
mods.merge (mods_history);
|
||||||
|
|
||||||
@@ -1883,3 +1904,4 @@ void TDB2::dump ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// vim: ts=2 et sw=2
|
||||||
|
|||||||
@@ -33,22 +33,38 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <Taskmod.h>
|
#include <Taskmod.h>
|
||||||
|
|
||||||
|
unsigned long Taskmod::curSequenceNumber = 0;
|
||||||
|
|
||||||
|
bool compareTaskmod (Taskmod first, Taskmod second)
|
||||||
|
{
|
||||||
|
if (first._timestamp == second._timestamp)
|
||||||
|
{
|
||||||
|
return first._sequenceNumber < second._sequenceNumber;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return first._timestamp < second._timestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
Taskmod::Taskmod ()
|
Taskmod::Taskmod ()
|
||||||
{
|
{
|
||||||
_timestamp = 0;
|
_timestamp = 0;
|
||||||
_bAfterSet = false;
|
_bAfterSet = false;
|
||||||
_bBeforeSet = false;
|
_bBeforeSet = false;
|
||||||
|
_sequenceNumber = curSequenceNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
Taskmod::Taskmod (const Taskmod& other)
|
Taskmod::Taskmod (const Taskmod& other)
|
||||||
{
|
{
|
||||||
this->_before = other._before;
|
this->_before = other._before;
|
||||||
this->_after = other._after;
|
this->_after = other._after;
|
||||||
this->_timestamp = other._timestamp;
|
this->_timestamp = other._timestamp;
|
||||||
this->_bAfterSet = other._bAfterSet;
|
this->_bAfterSet = other._bAfterSet;
|
||||||
this->_bBeforeSet = other._bBeforeSet;
|
this->_bBeforeSet = other._bBeforeSet;
|
||||||
|
this->_sequenceNumber = other._sequenceNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -87,11 +103,12 @@ Taskmod& Taskmod::operator= (const Taskmod& other)
|
|||||||
{
|
{
|
||||||
if (this != &other)
|
if (this != &other)
|
||||||
{
|
{
|
||||||
this->_before = other._before;
|
this->_before = other._before;
|
||||||
this->_after = other._after;
|
this->_after = other._after;
|
||||||
this->_timestamp = other._timestamp;
|
this->_timestamp = other._timestamp;
|
||||||
this->_bAfterSet = other._bAfterSet;
|
this->_bAfterSet = other._bAfterSet;
|
||||||
this->_bBeforeSet = other._bBeforeSet;
|
this->_bBeforeSet = other._bBeforeSet;
|
||||||
|
this->_sequenceNumber = other._sequenceNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@@ -100,9 +117,10 @@ Taskmod& Taskmod::operator= (const Taskmod& other)
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void Taskmod::reset (long timestamp)
|
void Taskmod::reset (long timestamp)
|
||||||
{
|
{
|
||||||
this->_bAfterSet = false;
|
this->_bAfterSet = false;
|
||||||
this->_bBeforeSet = false;
|
this->_bBeforeSet = false;
|
||||||
this->_timestamp = timestamp;
|
this->_timestamp = timestamp;
|
||||||
|
this->_sequenceNumber = curSequenceNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -177,6 +195,12 @@ void Taskmod::setTimestamp (long timestamp)
|
|||||||
this->_timestamp = timestamp;
|
this->_timestamp = timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void Taskmod::incSequenceNumber ()
|
||||||
|
{
|
||||||
|
this->_sequenceNumber++;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
Task& Taskmod::getAfter ()
|
Task& Taskmod::getAfter ()
|
||||||
{
|
{
|
||||||
@@ -195,6 +219,12 @@ long Taskmod::getTimestamp () const
|
|||||||
return _timestamp;
|
return _timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
unsigned long Taskmod::getSequenceNumber () const
|
||||||
|
{
|
||||||
|
return _sequenceNumber;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string Taskmod::getTimeStr () const
|
std::string Taskmod::getTimeStr () const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,6 +33,8 @@
|
|||||||
#include <Task.h>
|
#include <Task.h>
|
||||||
|
|
||||||
class Taskmod {
|
class Taskmod {
|
||||||
|
friend bool compareTaskmod (Taskmod first, Taskmod second);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Taskmod ();
|
Taskmod ();
|
||||||
Taskmod (const Taskmod& other);
|
Taskmod (const Taskmod& other);
|
||||||
@@ -59,11 +61,13 @@ public:
|
|||||||
void setAfter (const Task& after);
|
void setAfter (const Task& after);
|
||||||
void setBefore (const Task& before);
|
void setBefore (const Task& before);
|
||||||
void setTimestamp (long timestamp);
|
void setTimestamp (long timestamp);
|
||||||
|
void incSequenceNumber ();
|
||||||
|
|
||||||
// getter
|
// getter
|
||||||
Task& getAfter ();
|
Task& getAfter ();
|
||||||
Task& getBefore ();
|
Task& getBefore ();
|
||||||
long getTimestamp () const;
|
long getTimestamp () const;
|
||||||
|
unsigned long getSequenceNumber () const;
|
||||||
std::string getTimeStr () const;
|
std::string getTimeStr () const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -72,7 +76,12 @@ protected:
|
|||||||
long _timestamp;
|
long _timestamp;
|
||||||
bool _bAfterSet;
|
bool _bAfterSet;
|
||||||
bool _bBeforeSet;
|
bool _bBeforeSet;
|
||||||
|
unsigned long _sequenceNumber;
|
||||||
|
|
||||||
|
static unsigned long curSequenceNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool compareTaskmod (Taskmod first, Taskmod second);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
1
test/.gitignore
vendored
1
test/.gitignore
vendored
@@ -26,3 +26,4 @@ view.t
|
|||||||
|
|
||||||
json_test
|
json_test
|
||||||
|
|
||||||
|
run_all
|
||||||
|
|||||||
@@ -10,7 +10,17 @@ set (test_SRCS autocomplete.t color.t config.t date.t directory.t dom.t
|
|||||||
duration.t file.t i18n.t json.t list.t nibbler.t path.t rx.t
|
duration.t file.t i18n.t json.t list.t nibbler.t path.t rx.t
|
||||||
t.t t2.t taskmod.t tdb2.t text.t uri.t util.t view.t json_test)
|
t.t t2.t taskmod.t tdb2.t text.t uri.t util.t view.t json_test)
|
||||||
|
|
||||||
add_custom_target (test ./run_all DEPENDS ${test_SRCS} task_executable
|
message ("-- Configuring run_all")
|
||||||
|
set (TESTBLOB "*.t")
|
||||||
|
if (CYGWIN)
|
||||||
|
set (TESTBLOB "*.t *.t.exe")
|
||||||
|
endif (CYGWIN)
|
||||||
|
configure_file (
|
||||||
|
${CMAKE_SOURCE_DIR}/test/run_all.in
|
||||||
|
${CMAKE_SOURCE_DIR}/test/run_all)
|
||||||
|
|
||||||
|
add_custom_target (test ./run_all --verbose
|
||||||
|
DEPENDS ${test_SRCS} task_executable
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/test)
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/test)
|
||||||
|
|
||||||
add_custom_target (build_tests DEPENDS ${test_SRCS}
|
add_custom_target (build_tests DEPENDS ${test_SRCS}
|
||||||
|
|||||||
169
test/bug.1104.t
Executable file
169
test/bug.1104.t
Executable file
@@ -0,0 +1,169 @@
|
|||||||
|
#! /usr/bin/env 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 File::Copy;
|
||||||
|
use File::Path;
|
||||||
|
use Test::More tests => 28;
|
||||||
|
|
||||||
|
mkdir("1", 0755);
|
||||||
|
mkdir("2", 0755);
|
||||||
|
mkdir("3", 0755);
|
||||||
|
mkdir("dropbox", 0755);
|
||||||
|
|
||||||
|
ok (-e "1", 'Created directory 1/');
|
||||||
|
ok (-e "2", 'Created directory 2/');
|
||||||
|
ok (-e "3", 'Created directory 3/');
|
||||||
|
ok (-e "dropbox", 'Created directory dropbox/');
|
||||||
|
|
||||||
|
# Create the rc file.
|
||||||
|
if (open my $fh, '>', '1.rc')
|
||||||
|
{
|
||||||
|
print $fh "data.location=1/\n";
|
||||||
|
print $fh "confirmation=no\n";
|
||||||
|
print $fh "merge.autopush=yes\n";
|
||||||
|
print $fh "merge.default.uri=./dropbox/\n";
|
||||||
|
print $fh "push.default.uri=./dropbox/\n";
|
||||||
|
print $fh "pull.default.uri=./dropbox/\n";
|
||||||
|
|
||||||
|
close $fh;
|
||||||
|
ok (-r '1.rc', 'Created 1.rc');
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create the rc file.
|
||||||
|
if (open my $fh, '>', '2.rc')
|
||||||
|
{
|
||||||
|
print $fh "data.location=2/\n";
|
||||||
|
print $fh "confirmation=no\n";
|
||||||
|
print $fh "merge.autopush=yes\n";
|
||||||
|
print $fh "merge.default.uri=./dropbox/\n";
|
||||||
|
print $fh "push.default.uri=./dropbox/\n";
|
||||||
|
print $fh "pull.default.uri=./dropbox/\n";
|
||||||
|
|
||||||
|
close $fh;
|
||||||
|
ok (-r '2.rc', 'Created 2.rc');
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create the rc file.
|
||||||
|
if (open my $fh, '>', '3.rc')
|
||||||
|
{
|
||||||
|
print $fh "data.location=3/\n";
|
||||||
|
print $fh "confirmation=no\n";
|
||||||
|
print $fh "merge.autopush=yes\n";
|
||||||
|
print $fh "merge.default.uri=./dropbox/\n";
|
||||||
|
print $fh "push.default.uri=./dropbox/\n";
|
||||||
|
print $fh "pull.default.uri=./dropbox/\n";
|
||||||
|
|
||||||
|
close $fh;
|
||||||
|
ok (-r '3.rc', 'Created 3.rc');
|
||||||
|
}
|
||||||
|
|
||||||
|
# Once-only push from 1 --> dropbox
|
||||||
|
my $output = qx{../src/task rc:1.rc add one 2>&1};
|
||||||
|
ok ($? == 0, 'Exit status check');
|
||||||
|
$output = qx{../src/task rc:1.rc add two 2>&1};
|
||||||
|
ok ($? == 0, 'Exit status check');
|
||||||
|
$output = qx{../src/task rc:1.rc add three 2>&1};
|
||||||
|
ok ($? == 0, 'Exit status check');
|
||||||
|
$output = qx{../src/task rc:1.rc push 2>&1};
|
||||||
|
ok ($? == 0, 'Exit status check');
|
||||||
|
|
||||||
|
# Merges to 2 and 3
|
||||||
|
$output = qx{../src/task rc:2.rc merge 2>&1};
|
||||||
|
ok ($? == 0, 'Exit status check');
|
||||||
|
$output = qx{../src/task rc:3.rc merge 2>&1};
|
||||||
|
ok ($? == 0, 'Exit status check');
|
||||||
|
|
||||||
|
# Make a different change in both locations
|
||||||
|
$output = qx{../src/task rc:1.rc add four 2>&1};
|
||||||
|
ok ($? == 0, 'Exit status check');
|
||||||
|
$output = qx{../src/task rc:1.rc four done 2>&1};
|
||||||
|
ok ($? == 0, 'Exit status check');
|
||||||
|
$output = qx{../src/task rc:2.rc one done 2>&1};
|
||||||
|
ok ($? == 0, 'Exit status check');
|
||||||
|
$output = qx{../src/task rc:3.rc three delete 2>&1};
|
||||||
|
ok ($? == 0, 'Exit status check');
|
||||||
|
|
||||||
|
# Merges 1 and 2
|
||||||
|
$output = qx{../src/task rc:1.rc merge 2>&1};
|
||||||
|
ok ($? == 0, 'Exit status check');
|
||||||
|
$output = qx{../src/task rc:2.rc merge 2>&1};
|
||||||
|
ok ($? == 0, 'Exit status check');
|
||||||
|
|
||||||
|
# see if undo.data is corrupt
|
||||||
|
$output = qx{cat 2/undo.data};
|
||||||
|
unlike ($output, qr/time 0/, "undo.data corrupt");
|
||||||
|
|
||||||
|
# merge again in order to stimulate duplications
|
||||||
|
$output = qx{../src/task rc:1.rc merge 2>&1};
|
||||||
|
ok ($? == 0, 'Exit status check');
|
||||||
|
$output = qx{../src/task rc:1.rc diag 2>&1};
|
||||||
|
unlike ($output, qr/Found duplicate/, "Found duplicate");
|
||||||
|
|
||||||
|
# Merges 3
|
||||||
|
$output = qx{../src/task rc:3.rc merge 2>&1};
|
||||||
|
ok ($? == 0, 'Exit status check');
|
||||||
|
unlike ($output, qr/Retaining/, "Must not retain changes");
|
||||||
|
|
||||||
|
# Merges 1
|
||||||
|
$output = qx{../src/task rc:1.rc merge 2>&1};
|
||||||
|
ok ($? == 0, 'Exit status check');
|
||||||
|
unlike ($output, qr/Retaining/, "Must not retain changes");
|
||||||
|
|
||||||
|
# Cleanup.
|
||||||
|
unlink qw(1.rc 1/pending.data 1/completed.data 1/undo.data 1/backlog.data 1/synch.key 2/pending.data 2/completed.data 2/undo.data 2.rc 2/backlog.data 2/synch.key dropbox/completed.data dropbox/pending.data dropbox/undo.data 3/pending.data 3/undo.data 3/completed.data 3/backlog.data 3/synch.key 3.rc);
|
||||||
|
ok (! -r '1/pending.data' &&
|
||||||
|
! -r '1/completed.data' &&
|
||||||
|
! -r '1/undo.data' &&
|
||||||
|
! -r '1/backlog.data' &&
|
||||||
|
! -r '1/synch.key' &&
|
||||||
|
! -r '1.rc' &&
|
||||||
|
! -r '2/pending.data' &&
|
||||||
|
! -r '2/completed.data' &&
|
||||||
|
! -r '2/undo.data' &&
|
||||||
|
! -r '2/backlog.data' &&
|
||||||
|
! -r '2/synch.key' &&
|
||||||
|
! -r '2.rc' &&
|
||||||
|
! -r '3/pending.data' &&
|
||||||
|
! -r '3/completed.data' &&
|
||||||
|
! -r '3/undo.data' &&
|
||||||
|
! -r '3/backlog.data' &&
|
||||||
|
! -r '3/synch.key' &&
|
||||||
|
! -r '3.rc' &&
|
||||||
|
! -r 'dropbox/pending.data' &&
|
||||||
|
! -r 'dropbox/completed.data' &&
|
||||||
|
! -r 'dropbox/undo.data' , 'Cleanup');
|
||||||
|
|
||||||
|
rmtree (['1', '2', '3', 'dropbox'], 0, 1);
|
||||||
|
ok (! -e '1' &&
|
||||||
|
! -e '2' &&
|
||||||
|
! -e '3' &&
|
||||||
|
! -e 'dropbox', 'Removed directories');
|
||||||
|
|
||||||
|
exit 0;
|
||||||
@@ -142,37 +142,37 @@ int main (int argc, char** argv)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Regular unit tests.
|
// Regular unit tests.
|
||||||
t.is (json::encode ("1\b2"), "1\\b2", "json::encode \\b -> \\\\b");
|
t.is (json::encode ("1\b2"), "1\\b2", "json::encode slashslashb -> slashslashslashslashb");
|
||||||
t.is (json::decode ("1\\b2"), "1\b2", "json::decode \\\\b -> \\b");
|
t.is (json::decode ("1\\b2"), "1\b2", "json::decode slashslashslashslashb -> slashslashb");
|
||||||
|
|
||||||
t.is (json::encode ("1\n2"), "1\\n2", "json::encode \\n -> \\\\n");
|
t.is (json::encode ("1\n2"), "1\\n2", "json::encode slashslashn -> slashslashslashslashn");
|
||||||
t.is (json::decode ("1\\n2"), "1\n2", "json::decode \\\\n -> \\n");
|
t.is (json::decode ("1\\n2"), "1\n2", "json::decode slashslashslashslashn -> slashslashn");
|
||||||
|
|
||||||
t.is (json::encode ("1\r2"), "1\\r2", "json::encode \\r -> \\\\r");
|
t.is (json::encode ("1\r2"), "1\\r2", "json::encode slashslashr -> slashslashslashslashr");
|
||||||
t.is (json::decode ("1\\r2"), "1\r2", "json::decode \\\\r -> \\r");
|
t.is (json::decode ("1\\r2"), "1\r2", "json::decode slashslashslashslashr -> slashslashr");
|
||||||
|
|
||||||
t.is (json::encode ("1\t2"), "1\\t2", "json::encode \\t -> \\\\t");
|
t.is (json::encode ("1\t2"), "1\\t2", "json::encode slashslasht -> slashslashslashslasht");
|
||||||
t.is (json::decode ("1\\t2"), "1\t2", "json::decode \\\\t -> \\t");
|
t.is (json::decode ("1\\t2"), "1\t2", "json::decode slashslashslashslasht -> slashslasht");
|
||||||
|
|
||||||
t.is (json::encode ("1\\2"), "1\\\\2", "json::encode \\ -> \\\\");
|
t.is (json::encode ("1\\2"), "1\\\\2", "json::encode slashslash -> slashslashslashslash");
|
||||||
t.is (json::decode ("1\\\\2"), "1\\2", "json::decode \\\\ -> \\");
|
t.is (json::decode ("1\\\\2"), "1\\2", "json::decode slashslashslashslash -> slashslash");
|
||||||
|
|
||||||
t.is (json::encode ("1\x2"), "1\x2", "json::encode \\x -> \\x (NOP)");
|
t.is (json::encode ("1\x2"), "1\x2", "json::encode slashslashx -> slashslashx(NOP)");
|
||||||
t.is (json::decode ("1\x2"), "1\x2", "json::decode \\x -> \\x (NOP)");
|
t.is (json::decode ("1\x2"), "1\x2", "json::decode slashslashx -> slashslashx(NOP)");
|
||||||
|
|
||||||
t.is (json::encode ("1€2"), "1€2", "json::encode € -> €");
|
t.is (json::encode ("1€2"), "1€2", "json::encode € -> €");
|
||||||
t.is (json::decode ("1\\u20ac2"), "1€2", "json::decode \\u20ac -> €");
|
t.is (json::decode ("1\\u20ac2"), "1€2", "json::decode slashslashu20ac -> €");
|
||||||
|
|
||||||
std::string encoded = json::encode ("one\\");
|
std::string encoded = json::encode ("one\\");
|
||||||
t.is (encoded, "one\\\\", "json::encode one\\\\ -> one\\\\\\\\");
|
t.is (encoded, "one\\\\", "json::encode oneslashslashslashslash -> oneslashslashslashslashslashslashslashslash");
|
||||||
t.is ((int)encoded.length (), 5, "json::encode one\\\\ -> length 5");
|
t.is ((int)encoded.length (), 5, "json::encode oneslashslashslashslash -> length 5");
|
||||||
t.is (encoded[0], 'o', "json::encode one\\\\[0] -> o");
|
t.is (encoded[0], 'o', "json::encode oneslashslashslashslash[0] -> o");
|
||||||
t.is (encoded[1], 'n', "json::encode one\\\\[1] -> n");
|
t.is (encoded[1], 'n', "json::encode oneslashslashslashslash[1] -> n");
|
||||||
t.is (encoded[2], 'e', "json::encode one\\\\[2] -> e");
|
t.is (encoded[2], 'e', "json::encode oneslashslashslashslash[2] -> e");
|
||||||
t.is (encoded[3], '\\', "json::encode one\\\\[3] -> \\");
|
t.is (encoded[3], '\\', "json::encode oneslashslashslashslash[3] -> slashslash");
|
||||||
t.is (encoded[4], '\\', "json::encode one\\\\[4] -> \\");
|
t.is (encoded[4], '\\', "json::encode oneslashslashslashslash[4] -> slashslash");
|
||||||
|
|
||||||
t.is (json::decode (encoded), "one\\", "json::decode one\\\\\\\\ -> one\\\\");
|
t.is (json::decode (encoded), "one\\", "json::decode oneslashslashslashslashslashslashslashslash -> oneslashslashslashslash");
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (std::string& e) {t.diag (e);}
|
catch (std::string& e) {t.diag (e);}
|
||||||
|
|||||||
39
test/run_all
39
test/run_all
@@ -1,39 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
|
|
||||||
date > all.log
|
|
||||||
STARTEPOCH=`perl -e 'print time'`
|
|
||||||
|
|
||||||
VRAMSTEG=/usr/local/bin/vramsteg
|
|
||||||
BAR=0
|
|
||||||
if [ -x $VRAMSTEG ]; then
|
|
||||||
BAR=1
|
|
||||||
COUNT=0
|
|
||||||
TOTAL=$(ls *.t | wc -l)
|
|
||||||
START=$($VRAMSTEG --now)
|
|
||||||
fi
|
|
||||||
|
|
||||||
for i in *.t
|
|
||||||
do
|
|
||||||
echo '#' $i >>all.log
|
|
||||||
|
|
||||||
if [ $BAR == 1 ]; then
|
|
||||||
$VRAMSTEG --label 'All tests' --min 0 --max $TOTAL --current $COUNT --percentage --start $START --estimate
|
|
||||||
COUNT=$[COUNT + 1]
|
|
||||||
fi
|
|
||||||
|
|
||||||
./$i >> all.log 2>&1
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ $BAR == 1 ]; then
|
|
||||||
$VRAMSTEG --remove
|
|
||||||
fi
|
|
||||||
|
|
||||||
date >> all.log
|
|
||||||
ENDEPOCH=`perl -e 'print time'`
|
|
||||||
|
|
||||||
RUNTIME=$(($ENDEPOCH - $STARTEPOCH))
|
|
||||||
|
|
||||||
printf "Pass: %5d\n" $(grep -c ^ok all.log)
|
|
||||||
printf "Fail: %5d\n" $(grep -c ^not all.log)
|
|
||||||
printf "Skipped: %5d\n" $(grep -c ^skip all.log)
|
|
||||||
printf "Runtime: %5d seconds\n" $RUNTIME
|
|
||||||
56
test/run_all.in
Executable file
56
test/run_all.in
Executable file
@@ -0,0 +1,56 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
if [ x"$1" = x"--verbose" ];
|
||||||
|
then
|
||||||
|
for i in ${TESTBLOB}
|
||||||
|
do
|
||||||
|
echo '#' $i
|
||||||
|
./$i > test.log 2>&1
|
||||||
|
while read LINE
|
||||||
|
do
|
||||||
|
echo $LINE
|
||||||
|
done < test.log
|
||||||
|
rm test.log
|
||||||
|
done
|
||||||
|
else
|
||||||
|
date > all.log
|
||||||
|
|
||||||
|
# Perl is used here to get the time in seconds
|
||||||
|
# because 'date +%s' isn't supported on Solaris.
|
||||||
|
STARTEPOCH=`perl -e 'print time'`
|
||||||
|
|
||||||
|
VRAMSTEG=`which vramsteg`
|
||||||
|
BAR=0
|
||||||
|
if [ -x "$VRAMSTEG" ]; then
|
||||||
|
BAR=1
|
||||||
|
COUNT=0
|
||||||
|
TOTAL=`ls ${TESTBLOB} | wc -l`
|
||||||
|
START=`$VRAMSTEG --now`
|
||||||
|
fi
|
||||||
|
|
||||||
|
for i in ${TESTBLOB}
|
||||||
|
do
|
||||||
|
echo '#' $i >>all.log
|
||||||
|
|
||||||
|
if [ $BAR -eq 1 ]; then
|
||||||
|
$VRAMSTEG --label 'All tests' --min 0 --max $TOTAL --current $COUNT --percentage --start $START --estimate
|
||||||
|
COUNT=`expr $COUNT + 1`
|
||||||
|
fi
|
||||||
|
|
||||||
|
./$i >> all.log 2>&1
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $BAR -eq 1 ]; then
|
||||||
|
$VRAMSTEG --remove
|
||||||
|
fi
|
||||||
|
|
||||||
|
date >> all.log
|
||||||
|
|
||||||
|
ENDEPOCH=`perl -e 'print time'`
|
||||||
|
RUNTIME=`expr $ENDEPOCH - $STARTEPOCH`
|
||||||
|
|
||||||
|
printf "Pass: %5d\n" `grep -c '^ok' all.log`
|
||||||
|
printf "Fail: %5d\n" `grep -c '^not' all.log`
|
||||||
|
printf "Skipped: %5d\n" `grep -c '^skip' all.log`
|
||||||
|
printf "Runtime: %5d seconds\n" $RUNTIME
|
||||||
|
fi
|
||||||
@@ -88,7 +88,7 @@ int main (int argc, char** argv)
|
|||||||
ut.ok (r9.match (start, end, text), "e there are matches");
|
ut.ok (r9.match (start, end, text), "e there are matches");
|
||||||
ut.is (start.size (), (size_t) 6, "e == 6 matches");
|
ut.is (start.size (), (size_t) 6, "e == 6 matches");
|
||||||
|
|
||||||
#ifdef DARWIN
|
#if defined(DARWIN) || defined(CYGWIN) || defined(FREEBSD)
|
||||||
text = "this is the end.";
|
text = "this is the end.";
|
||||||
ut.pass (text + " =~ /\\bthe/");
|
ut.pass (text + " =~ /\\bthe/");
|
||||||
ut.pass (text + " =~ /the\\b/");
|
ut.pass (text + " =~ /the\\b/");
|
||||||
|
|||||||
Reference in New Issue
Block a user