mirror of
https://github.com/GothenburgBitFactory/timewarrior.git
synced 2025-06-26 10:54:28 +02:00
Add functions to add/remove a set of tags to/from an interval
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
This commit is contained in:
parent
c2c4691a23
commit
8e96ad5229
6 changed files with 44 additions and 11 deletions
|
@ -70,7 +70,7 @@ public:
|
||||||
bool getComplementaryHint (const std::string&, bool) const;
|
bool getComplementaryHint (const std::string&, bool) const;
|
||||||
bool getHint(const std::string&, bool) const;
|
bool getHint(const std::string&, bool) const;
|
||||||
std::set <int> getIds () const;
|
std::set <int> getIds () const;
|
||||||
std::set<std::string> getTags () const;
|
std::set <std::string> getTags () const;
|
||||||
std::string getAnnotation() const;
|
std::string getAnnotation() const;
|
||||||
Duration getDuration() const;
|
Duration getDuration() const;
|
||||||
std::vector<std::string> getDomReferences () const;
|
std::vector<std::string> getDomReferences () const;
|
||||||
|
|
|
@ -75,8 +75,13 @@ const std::set <std::string>& Interval::tags () const
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void Interval::tag (const std::string& tag)
|
void Interval::tag (const std::string& tag)
|
||||||
{
|
{
|
||||||
if (_tags.find (tag) == _tags.end ())
|
_tags.insert (tag);
|
||||||
_tags.insert (tag);
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void Interval::tag (const std::set<std::string>& tags)
|
||||||
|
{
|
||||||
|
_tags.insert (tags.begin (), tags.end ());
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -85,6 +90,20 @@ void Interval::untag (const std::string& tag)
|
||||||
_tags.erase (tag);
|
_tags.erase (tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void Interval::untag (const std::set <std::string>& tags)
|
||||||
|
{
|
||||||
|
std::set<std::string> updated;
|
||||||
|
|
||||||
|
std::set_difference (
|
||||||
|
_tags.begin (), _tags.end (),
|
||||||
|
tags.begin (), tags.end (),
|
||||||
|
std::inserter (updated, updated.end ())
|
||||||
|
);
|
||||||
|
|
||||||
|
_tags = updated;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void Interval::clearTags ()
|
void Interval::clearTags ()
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,7 +46,9 @@ public:
|
||||||
bool hasTag (const std::string&) const;
|
bool hasTag (const std::string&) const;
|
||||||
const std::set <std::string>& tags () const;
|
const std::set <std::string>& tags () const;
|
||||||
void tag (const std::string&);
|
void tag (const std::string&);
|
||||||
|
void tag (const std::set<std::string>&);
|
||||||
void untag (const std::string&);
|
void untag (const std::string&);
|
||||||
|
void untag (const std::set<std::string>&);
|
||||||
void clearTags ();
|
void clearTags ();
|
||||||
|
|
||||||
void setRange (const Range& range);
|
void setRange (const Range& range);
|
||||||
|
|
|
@ -103,10 +103,7 @@ int CmdTag (
|
||||||
{
|
{
|
||||||
Interval modified {interval};
|
Interval modified {interval};
|
||||||
|
|
||||||
for (auto& tag : tags)
|
modified.tag (tags);
|
||||||
{
|
|
||||||
modified.tag (tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
database.modifyInterval (interval, modified, verbose);
|
database.modifyInterval (interval, modified, verbose);
|
||||||
|
|
||||||
|
|
|
@ -103,10 +103,7 @@ int CmdUntag (
|
||||||
{
|
{
|
||||||
Interval modified {interval};
|
Interval modified {interval};
|
||||||
|
|
||||||
for (auto& tag : tags)
|
modified.untag (tags);
|
||||||
{
|
|
||||||
modified.untag (tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
database.modifyInterval (interval, modified, verbose);
|
database.modifyInterval (interval, modified, verbose);
|
||||||
|
|
||||||
|
|
18
test/tag.t
Executable file → Normal file
18
test/tag.t
Executable file → Normal file
|
@ -206,6 +206,15 @@ class TestTag(TestCase):
|
||||||
expectedTags=["foo"],
|
expectedTags=["foo"],
|
||||||
description="unmodified interval")
|
description="unmodified interval")
|
||||||
|
|
||||||
|
def test_tag_with_identical_tags(self):
|
||||||
|
self.t("track 2016-01-01T00:00:00 - 2016-01-01T01:00:00")
|
||||||
|
self.t("tag @1 foo foo")
|
||||||
|
|
||||||
|
j = self.t.export()
|
||||||
|
|
||||||
|
self.assertEquals(len(j), 1)
|
||||||
|
self.assertEqual(j[0]['tags'], ['foo'])
|
||||||
|
|
||||||
def test_tag_with_identical_ids(self):
|
def test_tag_with_identical_ids(self):
|
||||||
"""Call 'tag' with identical ids"""
|
"""Call 'tag' with identical ids"""
|
||||||
now_utc = datetime.now().utcnow()
|
now_utc = datetime.now().utcnow()
|
||||||
|
@ -271,6 +280,15 @@ class TestTag(TestCase):
|
||||||
code, out, err = self.t.runError("tag @2 foo")
|
code, out, err = self.t.runError("tag @2 foo")
|
||||||
self.assertIn("ID '@2' does not correspond to any tracking.", err)
|
self.assertIn("ID '@2' does not correspond to any tracking.", err)
|
||||||
|
|
||||||
|
def test_untag_with_identical_tags(self):
|
||||||
|
self.t("track 2016-01-01T00:00:00 - 2016-01-01T01:00:00 foo bar")
|
||||||
|
self.t("untag @1 foo foo")
|
||||||
|
|
||||||
|
j = self.t.export()
|
||||||
|
|
||||||
|
self.assertEquals(len(j), 1)
|
||||||
|
self.assertEqual(j[0]['tags'], ['bar'])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
from simpletap import TAPTestRunner
|
from simpletap import TAPTestRunner
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue