Skip to content

Commit

Permalink
Fix constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
lauft committed Mar 8, 2025
1 parent 3a93db6 commit 5add2af
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 56 deletions.
15 changes: 5 additions & 10 deletions test/basetest/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ def __init__(self, original, error):


def json_decoder(string):
"""Attempt to decode a JSON string and in case of error return an
InvalidJSON object
"""Attempt to decode a JSON string and in case of error return an InvalidJSON object
"""
decoder = json.JSONDecoder().decode

Expand All @@ -39,9 +38,7 @@ def json_decoder(string):


class Hooks(object):
"""
Abstraction to help interact with hooks (add, remove) during tests and
keep track of which are active.
"""Abstraction to help interact with hooks (add, remove) during tests and keep track of which are active.
"""
def __init__(self, datadir):
"""
Expand Down Expand Up @@ -69,8 +66,7 @@ def __repr__(self):
enabled = ", ".join(enabled) or None
disabled = ", ".join(disabled) or None

return "<Hooks: enabled: {0} | disabled: {1}>".format(enabled,
disabled)
return "<Hooks: enabled: {0} | disabled: {1}>".format(enabled, disabled)

def __getitem__(self, name):
return self._hooks[name]
Expand Down Expand Up @@ -312,8 +308,7 @@ def __init__(self, *args, **kwargs):
self.wrappedname = "original_" + self.hookname
self.wrappedfile = os.path.join(self.hookdir, self.wrappedname)

self.original_wrapper = os.path.join(self.default_hookpath,
"wrapper.sh")
self.original_wrapper = os.path.join(self.default_hookpath, "wrapper.sh")

self.hooklog_in = self.wrappedfile + ".log.in"
self.hooklog_out = self.wrappedfile + ".log.out"
Expand Down Expand Up @@ -373,7 +368,7 @@ def _use_cache(self):
# Cache is outdated
return False
else:
# Cache is up to date
# Cache is up-to-date
return True

def enable(self):
Expand Down
20 changes: 8 additions & 12 deletions test/basetest/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,21 @@

class Task(object):
"""
Manage a task warrior instance
Manage a Taskwarrior instance
A temporary folder is used as data store of task warrior.
This class can be instantiated multiple times if multiple taskw clients are
needed.
This class can be given a Taskd instance for simplified configuration.
A temporary folder is used as data store of Taskwarrior.
This class can be instantiated multiple times if multiple taskw clients are needed.
A taskw client should not be used after being destroyed.
"""
DEFAULT_TASK = task_binary_location()

def __init__(self, taskw=DEFAULT_TASK, datadir=tempfile.mkdtemp(prefix="task_"), taskrc=None):
"""
Initialize a Task warrior (client) that can interact with a taskd server.
The task client runs in a temporary folder.
Initialize a Taskwarrior (client) that can interact with a taskd server.
The program runs in a temporary folder.
:arg taskw: Task binary to use as client (defaults: task in PATH)
:arg taskw: Taskwarrior binary to use as client (defaults: task in PATH)
"""
self.taskw = taskw

Expand Down Expand Up @@ -118,8 +115,7 @@ def export(self, export_filter=None):
if export_filter is None:
export_filter = ""

code, out, err = self.runSuccess("rc.json.array=1 {0} export"
"".format(export_filter))
code, out, err = self.runSuccess("rc.json.array=1 {0} export".format(export_filter))

return json.loads(out)

Expand Down Expand Up @@ -254,7 +250,7 @@ def destroy(self):
self.destroy = lambda: None

def __destroyed(self, *args, **kwargs):
raise AttributeError("Task instance has been destroyed. "
raise AttributeError("Taskwarrior instance has been destroyed. "
"Create a new instance if you need a new client.")

def diag(self, merge_streams_with=None):
Expand Down
67 changes: 33 additions & 34 deletions test/basetest/timew.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Timew(object):
"""
Manage a Timewarrior instance
A temporary folder is used as data store of timewarrior.
A temporary folder is used as data store of Timewarrior.
A timew client should not be used after being destroyed.
"""
Expand All @@ -26,7 +26,7 @@ def __init__(self,
datadir=tempfile.mkdtemp(prefix="timew_"),
configdir=tempfile.mkdtemp(prefix="timew_")):
"""
Initialize a timewarrior (client).
Initialize a Timewarrior client.
The program runs in a temporary folder.
:arg timew: Timewarrior binary to use as client (defaults: timew in PATH)
Expand All @@ -48,6 +48,14 @@ def __init__(self,

self.reset_env()

def __repr__(self):
txt = super(Timew, self).__repr__()
return "{0} running from {1}>".format(txt[:-1], self.datadir)

def __call__(self, *args, **kwargs):
"""aka t = Timew() ; t() which is now an alias to t.runSuccess()"""
return self.runSuccess(*args, **kwargs)

def reset(self, keep_config=False, keep_extensions=False):
"""Reset this instance to its maiden state"""

Expand All @@ -70,14 +78,6 @@ def add_default_extension(self, filename):

shutil.copy(os.path.join(DEFAULT_EXTENSION_PATH, filename), extfile)

def __repr__(self):
txt = super(Timew, self).__repr__()
return "{0} running from {1}>".format(txt[:-1], self.datadir)

def __call__(self, *args, **kwargs):
"""aka t = Timew() ; t() which is now an alias to t.runSuccess()"""
return self.runSuccess(*args, **kwargs)

def reset_env(self):
"""Set a new environment derived from the one used to launch the test"""
# Copy all env variables to avoid clashing subprocess environments
Expand All @@ -86,8 +86,7 @@ def reset_env(self):
# As well as TIMEWARRIORDB
self.env["TIMEWARRIORDB"] = self.datadir

# As well as MANPATH, so that the help tests can find the
# uninstalled man pages
# As well as MANPATH, so that the help tests can find the uninstalled man pages
parts = self.timew.split(os.path.sep)[0:-2]
parts.append("doc")
self.env["MANPATH"] = os.path.sep.join(parts)
Expand All @@ -97,6 +96,27 @@ def config(self, var, value):
cmd = (self.timew, ":yes", "config", var, value)
return run_cmd_wait(cmd, env=self.env)

def del_config(self, var):
"""Remove `var` from timew config"""
cmd = (self.timew, ":yes", "config", var)
return run_cmd_wait(cmd, env=self.env)

@property
def timewrc_content(self):
"""Returns the contents of the timewrc file."""

with open(self.timewrc, "r") as f:
return f.readlines()

def export(self, export_filter=None):
"""Run "timew export", return JSON array of exported intervals."""
if export_filter is None:
export_filter = ""

code, out, err = self.runSuccess("{0} export".format(export_filter))

return json.loads(out)

@staticmethod
def _create_exclusion_interval(interval):
if not isinstance(interval, tuple):
Expand Down Expand Up @@ -134,27 +154,6 @@ def configure_exclusions(self, intervals):
self.config("exclusions.saturday", exclusion)
self.config("exclusions.sunday", exclusion)

def del_config(self, var):
"""Remove `var` from timew config"""
cmd = (self.timew, ":yes", "config", var)
return run_cmd_wait(cmd, env=self.env)

@property
def timewrc_content(self):
"""Returns the contents of the timewrc file."""

with open(self.timewrc, "r") as f:
return f.readlines()

def export(self, export_filter=None):
"""Run "timew export", return JSON array of exported intervals."""
if export_filter is None:
export_filter = ""

code, out, err = self.runSuccess("{0} export".format(export_filter))

return json.loads(out)

@staticmethod
def _split_string_args_if_string(args):
"""
Expand Down Expand Up @@ -258,7 +257,7 @@ def destroy(self):
self.destroy = lambda: None

def __destroyed(self, *args, **kwargs):
raise AttributeError("Program instance has been destroyed. "
raise AttributeError("Timewarrior instance has been destroyed. "
"Create a new instance if you need a new client.")

def faketime(self, faketime=None):
Expand Down
11 changes: 11 additions & 0 deletions test/test_on-modify_e2e.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def setUp(self):
self.task.reset(keep_config=True, keep_hooks=True)
self.task.deactivate_hooks()

#@pytest.mark.skip
def test_hook_should_process_annotate(self):
"""on-modify hook should process 'task annotate'"""
self.task.deactivate_hooks()
Expand All @@ -67,6 +68,7 @@ def test_hook_should_process_annotate(self):
self.assertEqual(len(j), 1)
self.assertOpenInterval(j[0], expectedTags=["Foo"], expectedAnnotation="Annotation")

#@pytest.mark.skip
def test_hook_should_process_append(self):
"""on-modify hook should process 'task append'"""
self.task.deactivate_hooks()
Expand All @@ -81,6 +83,7 @@ def test_hook_should_process_append(self):
self.assertEqual(len(j), 1)
self.assertOpenInterval(j[0], expectedTags=["Foo Bar"])

#@pytest.mark.skip
def test_hook_should_process_delete(self):
"""on-modify hook should process 'task delete'"""
self.task.deactivate_hooks()
Expand All @@ -95,6 +98,7 @@ def test_hook_should_process_delete(self):
self.assertEqual(len(j), 1)
self.assertClosedInterval(j[0], expectedTags=["Foo"])

#@pytest.mark.skip
def test_hook_should_process_denotate(self):
"""on-modify hook should process 'task denotate'"""
self.task.deactivate_hooks()
Expand All @@ -111,6 +115,7 @@ def test_hook_should_process_denotate(self):
self.assertEqual(len(j), 1)
self.assertOpenInterval(j[0], expectedTags=["Foo"], expectedAnnotation="")

#@pytest.mark.skip
def test_hook_should_process_done(self):
"""on-modify hook should process 'task done'"""
self.task.deactivate_hooks()
Expand All @@ -125,6 +130,7 @@ def test_hook_should_process_done(self):
self.assertEqual(len(j), 1)
self.assertClosedInterval(j[0], expectedTags=["Foo"])

#@pytest.mark.skip
def test_hook_should_process_modify_description(self):
"""on-modify hook should process 'task modify' for changing description"""
self.task.deactivate_hooks()
Expand All @@ -139,6 +145,7 @@ def test_hook_should_process_modify_description(self):
self.assertEqual(len(j), 1)
self.assertOpenInterval(j[0], expectedTags=["Bar"])

#@pytest.mark.skip
def test_hook_should_process_modify_tags(self):
"""on-modify hook should process 'task modify' for changing tags"""
self.task.deactivate_hooks()
Expand All @@ -154,6 +161,7 @@ def test_hook_should_process_modify_tags(self):
self.assertEqual(len(j), 1)
self.assertOpenInterval(j[0], expectedTags=["Foo", "Tag", "Baz"])

#@pytest.mark.skip
def test_hook_should_process_modify_project(self):
"""on-modify hook should process 'task modify' for changing project"""
self.task.deactivate_hooks()
Expand All @@ -168,6 +176,7 @@ def test_hook_should_process_modify_project(self):
self.assertEqual(len(j), 1)
self.assertOpenInterval(j[0], expectedTags=["Foo", "test"])

#@pytest.mark.skip
def test_hook_should_process_prepend(self):
"""on-modify hook should process 'task prepend'"""
self.task.deactivate_hooks()
Expand All @@ -182,6 +191,7 @@ def test_hook_should_process_prepend(self):
self.assertEqual(len(j), 1)
self.assertOpenInterval(j[0], expectedTags=["Prefix Foo"])

#@pytest.mark.skip
def test_hook_should_process_start(self):
"""on-modify hook should process 'task start'"""
self.task.deactivate_hooks()
Expand All @@ -194,6 +204,7 @@ def test_hook_should_process_start(self):
self.assertEqual(len(j), 1)
self.assertOpenInterval(j[0], expectedTags=["Foo"])

#@pytest.mark.skip
def test_hook_should_process_stop(self):
"""on-modify hook should process 'task stop'"""
self.task.deactivate_hooks()
Expand Down

0 comments on commit 5add2af

Please sign in to comment.