<commit_before>from collections import deque

import pytest

from doit.exceptions import InvalidDodoFile, InvalidCommand
from doit.task import InvalidTask, Task, DelayedLoader
from doit.control import TaskControl, TaskDispatcher, ExecNode
from doit.control import no_none



class TestTaskControlInit(object):

    def test_addTask(self):
        t1 = Task("taskX", None)
        t2 = Task("taskY", None)
        tc = TaskControl([t1, t2])
        assert 2 == len(tc.tasks)

    def test_targetDependency(self):
        t1 = Task("taskX", None,[],['intermediate'])
        t2 = Task("taskY", None,['intermediate'],[])
        TaskControl([t1, t2])
        assert ['taskX'] == t2.task_dep

    # 2 tasks can not have the same name
    def test_addTaskSameName(self):
        t1 = Task("taskX", None)
        t2 = Task("taskX", None)
        pytest.raises(InvalidDodoFile, TaskControl, [t1, t2])

    def test_addInvalidTask(self):
        pytest.raises(InvalidTask, TaskControl, [666])

    def test_userErrorTaskDependency(self):
        tasks = [Task('wrong', None, task_dep=["typo"])]
        pytest.raises(InvalidTask, TaskControl, tasks)

    def test_userErrorSetupTask(self):
        tasks = [Task('wrong', None, setup=["typo"])]
        pytest.raises(InvalidTask, TaskControl, tasks)

    def test_sameTarget(self):
        tasks = [Task('t1',None,[],["fileX"]),
                 Task('t2',None,[],["fileX"])]
        pytest.raises(InvalidTask, TaskControl, tasks)


    def test_wild(self):
        tasks = [Task('t1',None, task_dep=['foo*']),
                 Task('foo4',None,)]
        TaskControl(tasks)
        assert 'foo4' in tasks[0].task_dep

    def test_bug770150_task_dependency_from_target(self):
        t1 = Task("taskX", None, file_dep=[], targets=['intermediate'])
        t2 = Task("taskY", None, file_dep=['intermediate'], task_dep=['taskZ'])
        t3 = Task("taskZ", None)
        TaskControl([t1, t2, t3])
        assert ['taskZ', 'taskX'] == t2.task_dep


TASKS_SAMPLE = [Task("t1", [""], doc="t1 doc string"),
                Task("t2", [""], doc="t2 doc string"),
                Task("g1", None, doc="g1 doc string"),
                Task("g1.a", [""], doc="g1.a doc string", is_subtask=True),
                Task("g1.b", [""], doc="g1.b doc string", is_subtask=True),
                Task("t3", [""], doc="t3 doc string",
                     params=[{'name':'opt1','long':'message','default':''}])]


class TestTaskControlCmdOptions(object):
    def testFilter(self):
        filter_ = ['t2', 't3']
        tc = TaskControl(TASKS_SAMPLE)
        assert filter_ == tc._filter_tasks(filter_)

    def testProcessSelection(self):
        filter_ = ['t2', 't3']
        tc = TaskControl(TASKS_SAMPLE)
        tc.process(filter_)
        assert filter_ == tc.selected_tasks

    def testProcessAll(self):
        tc = TaskControl(TASKS_SAMPLE)
        tc.process(None)
        assert ['t1', 't2', 'g1', 'g1.a', 'g1.b', 't3'] == tc.selected_tasks

    def testFilterPattern(self):
        tc = TaskControl(TASKS_SAMPLE)
        assert ['t1', 'g1', 'g1.a', 'g1.b'] == tc._filter_tasks(['*1*'])

    def testFilterSubtask(self):
        filter_ = ["t1", "g1.b"]
        tc =  TaskControl(TASKS_SAMPLE)
        assert filter_ == tc._filter_tasks(filter_)

    def testFilterTarget(self):
        tasks = list(TASKS_SAMPLE)
        tasks.append(Task("tX", [""],[],["targetX"]))
        tc =  TaskControl(tasks)
        assert ['tX'] == tc._filter_tasks(["targetX"])

    def test_filter_delayed_subtask(self):
        t1 = Task("taskX", None)
        t2 = Task("taskY", None, loader=DelayedLoader(lambda: None))
        control = TaskControl([t1, t2])
        control._filter_tasks(['taskY:foo'])
        assert isinstance(t2.loader, DelayedLoader)
        # sub-task will use same loader, and keep parent basename
        assert control.tasks['taskY:foo'].loader.basename == 'taskY'
        assert control.tasks['taskY:foo'].loader is t2.loader

    def test_filter_delayed_regex_single(self):
        t1 = Task("taskX", None)
        t2 = Task("taskY", None,
                  loader=DelayedLoader(lambda: None, target_regex='a.*'))
        t3 = Task("taskZ", None,
                  loader=DelayedLoader(lambda: None, target_regex='b.*'))
        t4 = Task("taskW", None,
                  loader=DelayedLoader(lambda: None))
        control = TaskControl([t1, t2, t3, t4], auto_delayed_regex=False)
        selected = control._filter_tasks(['abc'])
        assert isinstance(t2.loader, DelayedLoader)
        assert len(selected) == 1
        assert selected[0] == '_regex_target_abc:taskY'
        sel_task = control.tasks['_regex_target_abc:taskY']
        assert sel_task.file_dep == {'abc'}
        assert sel_task.loader.basename == 'taskY'
        assert sel_task.loader is t2.loader

    def test_filter_delayed_regex_multiple(self):
        t1 = Task("taskX", None)
        t2 = Task("taskY", None,
                  loader=DelayedLoader(lambda: None, target_regex='a.*'))
        t3 = Task("taskZ", None,
                  loader=DelayedLoader(lambda: None, target_regex='ab.'))
        t4 = Task("taskW", None,
                  loader=DelayedLoader(lambda: None))
        control = TaskControl([t1, t2, t3, t4], auto_delayed_regex=False)
        selected = control._filter_tasks(['abc'])
        assert len(selected) == 2
        assert (sorted(selected) ==
                ['_regex_target_abc:taskY', '_regex_target_abc:taskZ'])
        assert control.tasks[selected[0]].file_dep == {'abc'}
        assert control.tasks[selected[1]].file_dep == {'abc'}
        assert control.tasks[selected[0]].loader.basename == t2.name
        assert control.tasks[selected[1]].loader.basename == t3.name

    def test_filter_delayed_regex_auto(self):
        t1 = Task("taskX", None)
        t2 = Task("taskY", None,
                  loader=DelayedLoader(lambda: None, target_regex='a.*'))
        t3 = Task("taskZ", None,
                  loader=DelayedLoader(lambda: None))
        control = TaskControl([t1, t2, t3], auto_delayed_regex=True)
        selected = control._filter_tasks(['abc'])
        assert len(selected) == 2
        assert (sorted(selected) ==
                ['_regex_target_abc:taskY', '_regex_target_abc:taskZ'])
        assert control.tasks[selected[0]].file_dep == {'abc'}
        assert control.tasks[selected[1]].file_dep == {'abc'}
        assert control.tasks[selected[0]].loader.basename == t2.name
        assert control.tasks[selected[1]].loader.basename == t3.name


    # filter a non-existent task raises an error
    def testFilterWrongName(self):
        tc =  TaskControl(TASKS_SAMPLE)
        pytest.raises(InvalidCommand, tc._filter_tasks, ['no'])

    def testFilterEmptyList(self):
        filter_ = []
        tc = TaskControl(TASKS_SAMPLE)<commit_msg>fix flaky test<commit_after>from collections import deque

import pytest

from doit.exceptions import InvalidDodoFile, InvalidCommand
from doit.task import InvalidTask, Task, DelayedLoader
from doit.control import TaskControl, TaskDispatcher, ExecNode
from doit.control import no_none



class TestTaskControlInit(object):

    def test_addTask(self):
        t1 = Task("taskX", None)
        t2 = Task("taskY", None)
        tc = TaskControl([t1, t2])
        assert 2 == len(tc.tasks)

    def test_targetDependency(self):
        t1 = Task("taskX", None,[],['intermediate'])
        t2 = Task("taskY", None,['intermediate'],[])
        TaskControl([t1, t2])
        assert ['taskX'] == t2.task_dep

    # 2 tasks can not have the same name
    def test_addTaskSameName(self):
        t1 = Task("taskX", None)
        t2 = Task("taskX", None)
        pytest.raises(InvalidDodoFile, TaskControl, [t1, t2])

    def test_addInvalidTask(self):
        pytest.raises(InvalidTask, TaskControl, [666])

    def test_userErrorTaskDependency(self):
        tasks = [Task('wrong', None, task_dep=["typo"])]
        pytest.raises(InvalidTask, TaskControl, tasks)

    def test_userErrorSetupTask(self):
        tasks = [Task('wrong', None, setup=["typo"])]
        pytest.raises(InvalidTask, TaskControl, tasks)

    def test_sameTarget(self):
        tasks = [Task('t1',None,[],["fileX"]),
                 Task('t2',None,[],["fileX"])]
        pytest.raises(InvalidTask, TaskControl, tasks)


    def test_wild(self):
        tasks = [Task('t1',None, task_dep=['foo*']),
                 Task('foo4',None,)]
        TaskControl(tasks)
        assert 'foo4' in tasks[0].task_dep

    def test_bug770150_task_dependency_from_target(self):
        t1 = Task("taskX", None, file_dep=[], targets=['intermediate'])
        t2 = Task("taskY", None, file_dep=['intermediate'], task_dep=['taskZ'])
        t3 = Task("taskZ", None)
        TaskControl([t1, t2, t3])
        assert ['taskZ', 'taskX'] == t2.task_dep


TASKS_SAMPLE = [Task("t1", [""], doc="t1 doc string"),
                Task("t2", [""], doc="t2 doc string"),
                Task("g1", None, doc="g1 doc string"),
                Task("g1.a", [""], doc="g1.a doc string", is_subtask=True),
                Task("g1.b", [""], doc="g1.b doc string", is_subtask=True),
                Task("t3", [""], doc="t3 doc string",
                     params=[{'name':'opt1','long':'message','default':''}])]


class TestTaskControlCmdOptions(object):
    def testFilter(self):
        filter_ = ['t2', 't3']
        tc = TaskControl(TASKS_SAMPLE)
        assert filter_ == tc._filter_tasks(filter_)

    def testProcessSelection(self):
        filter_ = ['t2', 't3']
        tc = TaskControl(TASKS_SAMPLE)
        tc.process(filter_)
        assert filter_ == tc.selected_tasks

    def testProcessAll(self):
        tc = TaskControl(TASKS_SAMPLE)
        tc.process(None)
        assert ['t1', 't2', 'g1', 'g1.a', 'g1.b', 't3'] == tc.selected_tasks

    def testFilterPattern(self):
        tc = TaskControl(TASKS_SAMPLE)
        assert ['t1', 'g1', 'g1.a', 'g1.b'] == tc._filter_tasks(['*1*'])

    def testFilterSubtask(self):
        filter_ = ["t1", "g1.b"]
        tc =  TaskControl(TASKS_SAMPLE)
        assert filter_ == tc._filter_tasks(filter_)

    def testFilterTarget(self):
        tasks = list(TASKS_SAMPLE)
        tasks.append(Task("tX", [""],[],["targetX"]))
        tc =  TaskControl(tasks)
        assert ['tX'] == tc._filter_tasks(["targetX"])

    def test_filter_delayed_subtask(self):
        t1 = Task("taskX", None)
        t2 = Task("taskY", None, loader=DelayedLoader(lambda: None))
        control = TaskControl([t1, t2])
        control._filter_tasks(['taskY:foo'])
        assert isinstance(t2.loader, DelayedLoader)
        # sub-task will use same loader, and keep parent basename
        assert control.tasks['taskY:foo'].loader.basename == 'taskY'
        assert control.tasks['taskY:foo'].loader is t2.loader

    def test_filter_delayed_regex_single(self):
        t1 = Task("taskX", None)
        t2 = Task("taskY", None,
                  loader=DelayedLoader(lambda: None, target_regex='a.*'))
        t3 = Task("taskZ", None,
                  loader=DelayedLoader(lambda: None, target_regex='b.*'))
        t4 = Task("taskW", None,
                  loader=DelayedLoader(lambda: None))
        control = TaskControl([t1, t2, t3, t4], auto_delayed_regex=False)
        selected = control._filter_tasks(['abc'])
        assert isinstance(t2.loader, DelayedLoader)
        assert len(selected) == 1
        assert selected[0] == '_regex_target_abc:taskY'
        sel_task = control.tasks['_regex_target_abc:taskY']
        assert sel_task.file_dep == {'abc'}
        assert sel_task.loader.basename == 'taskY'
        assert sel_task.loader is t2.loader

    def test_filter_delayed_regex_multiple(self):
        t1 = Task("taskX", None)
        t2 = Task("taskY", None,
                  loader=DelayedLoader(lambda: None, target_regex='a.*'))
        t3 = Task("taskZ", None,
                  loader=DelayedLoader(lambda: None, target_regex='ab.'))
        t4 = Task("taskW", None,
                  loader=DelayedLoader(lambda: None))
        control = TaskControl([t1, t2, t3, t4], auto_delayed_regex=False)
        selected = control._filter_tasks(['abc'])
        assert len(selected) == 2
        assert (sorted(selected) ==
                ['_regex_target_abc:taskY', '_regex_target_abc:taskZ'])
        assert control.tasks['_regex_target_abc:taskY'].file_dep == {'abc'}
        assert control.tasks['_regex_target_abc:taskZ'].file_dep == {'abc'}
        assert (control.tasks['_regex_target_abc:taskY'].loader.basename ==
                t2.name)
        assert (control.tasks['_regex_target_abc:taskZ'].loader.basename ==
                t3.name)

    def test_filter_delayed_regex_auto(self):
        t1 = Task("taskX", None)
        t2 = Task("taskY", None,
                  loader=DelayedLoader(lambda: None, target_regex='a.*'))
        t3 = Task("taskZ", None,
                  loader=DelayedLoader(lambda: None))
        control = TaskControl([t1, t2, t3], auto_delayed_regex=True)
        selected = control._filter_tasks(['abc'])
        assert len(selected) == 2
        assert (sorted(selected) ==
                ['_regex_target_abc:taskY', '_regex_target_abc:taskZ'])
        assert control.tasks['_regex_target_abc:taskY'].file_dep == {'abc'}
        assert control.tasks['_regex_target_abc:taskZ'].file_dep == {'abc'}
        assert (control.tasks['_regex_target_abc:taskY'].loader.basename ==
                t2.name)
        assert (control.tasks['_regex_target_abc:taskZ'].loader.basename ==
                t3.name)


    # filter a non-existent task raises an error
    def testFilterWrongName(self):
        tc =  TaskControl(TASKS_SAMPLE)
        pytest.raises(InvalidCommand, tc._filter_tasks, ['no'])

    def testFilterEmptyList(self):
        filter_ = []
        tc = TaskControl(TASKS_SAMPLE)
{'fraction_non_alphanumeric': 0.14866719641696163, 'fraction_numerical': 0.015748031496062992, 'mean_word_length': 2.8253661232384637, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5793310', 'n_tokens_mistral': 4508, 'n_tokens_neox': 4402, 'n_words': 861}