Beispiel #1
0
def fixture_link_updater():
    """ Fixture to create an updater with uncommitted updates """
    tree_model = TreeModel()
    individuals_model = IndividualsModel([])
    sources_model = SourcesModel([])

    old_value = "Altered Ancestor"
    new_value = "Foo"

    project = ResearchProject("")
    plan_altered = ResearchPlan()
    plan_altered.ancestor = old_value
    plan_altered.ancestor_link = "I001"
    project.plans.append(plan_altered)
    tree_model.set_project(project)

    context = DataContext(
        data_model=tree_model,
        individuals_model=individuals_model,
        sources_model=sources_model,
    )

    updater = LinkUpdater(context)
    plan_index = tree_model.index(0, TreeModelCols.TEXT, QModelIndex())
    updater.ancestor_updates = [{"index": plan_index, "value": new_value}]

    return (updater, old_value, new_value, tree_model, plan_index)
Beispiel #2
0
def test_delete_task_does_nothing_if_no_tasks():
    """ delete_task() does nothing if there are no tasks """
    # Given
    plan = ResearchPlan()

    # When
    plan.delete_task(1)

    # Then
    assert len(plan.tasks) == 0
Beispiel #3
0
def test_add_task_creates_and_returns():
    """ add_task() should return the newly created task """
    # Given
    plan = ResearchPlan()

    # When
    retval = plan.add_task()

    # Then
    assert len(plan.tasks) == 1
    assert retval is not None
Beispiel #4
0
def test_unset_fields_are_defaulted():
    """ Check that when converting a plan, any fields not set in py are defaulted """
    # Given
    plan = ResearchPlan()
    plan_data = {}

    # When
    plan.from_py(plan_data)

    # Then
    assert plan.ancestor != ""
Beispiel #5
0
def test_string_repr_includes_ancestor():
    """ The str() representation should include the ancestor """
    # Given
    plan = ResearchPlan()
    plan.ancestor = "ANCESTOR"

    # When
    string = str(plan)

    # Then
    assert plan.ancestor in string
Beispiel #6
0
def test_ancestor_matches_plan(ancestor, value):
    """ When the plan is passed and ancestor filter set, it should be applied """
    # Given
    task = ResearchTask()
    plan = ResearchPlan()
    matcher = TaskMatcher()
    matcher.ancestor_filter("Henry")

    # When
    plan.ancestor = ancestor

    # Then
    assert matcher.match(task, plan) is value
Beispiel #7
0
def test_to_py_sets_fields():
    """ The to_py() function should create a python data structure of the class fields """
    # Given
    plan = ResearchPlan()
    plan.ancestor = "ANCESTOR"
    plan.ancestor_link = 11

    # When
    data = plan.to_py()

    # Then
    assert data["ancestor"] == plan.ancestor
    assert data["ancestor_link"] == plan.ancestor_link
    assert data["goal"] == plan.goal
    assert data["tasks"] == plan.tasks
    assert len(data.keys()) == 4  # To verify nothing else was added
Beispiel #8
0
def test_data_returns_string_for_valid_index():
    """ When getting data, ancestor is returned for valid index """
    # Given
    model = TreeModel()
    project = ResearchProject("")
    plan = ResearchPlan()
    plan.ancestor = "Foo"
    project.plans.append(plan)

    model.set_project(project)
    plan_index = model.index(0, 0, model.plans_index)

    # When
    retval = model.data(plan_index, Qt.DisplayRole)

    # Then
    assert retval is plan.ancestor
Beispiel #9
0
def test_data_returns_qicon_for_decoration_role():
    """ When getting data, decoration role returns an icon """
    # Given
    model = TreeModel()
    project = ResearchProject("")
    plan = ResearchPlan()
    plan.ancestor = "Foo"
    project.plans.append(plan)

    model.set_project(project)
    plan_index = model.index(0, 0, model.plans_index)

    # When
    retval = model.data(plan_index, Qt.DecorationRole)

    # Then
    assert isinstance(retval, QIcon)
Beispiel #10
0
def test_data_returns_none_for_invalid_role():
    """ When getting data, invalid role returns None """
    # Given
    model = TreeModel()
    project = ResearchProject("")
    plan = ResearchPlan()
    plan.ancestor = "Foo"
    project.plans.append(plan)

    model.set_project(project)
    plan_index = model.index(0, 0, model.plans_index)

    # When
    retval = model.data(plan_index, Qt.UserRole)

    # Then
    assert retval is None
Beispiel #11
0
def test_delete_task_does_nothing_if_index_out_of_bounds():
    """ delete_task() does nothing if the index is too large """
    # Given
    plan = ResearchPlan()
    task_one = ResearchTask()
    task_two = ResearchTask()
    task_three = ResearchTask()

    plan.tasks.append(task_one)
    plan.tasks.append(task_two)
    plan.tasks.append(task_three)

    # When
    plan.delete_task(5)

    # Then
    assert len(plan.tasks) == 3
Beispiel #12
0
def test_data_returns_none_for_invalid_column():
    """ When getting data, invalid column returns None """
    # Given
    model = TreeModel()
    project = ResearchProject("")
    plan = ResearchPlan()
    plan.ancestor = "Foo"
    project.plans.append(plan)

    model.set_project(project)
    plan_index = model.index(0,
                             len(list(TreeModelCols)) + 1, model.plans_index)

    # When
    retval = model.data(plan_index, Qt.DisplayRole)

    # Then
    assert retval is None
Beispiel #13
0
def test_task_links_are_checked():
    """
    Check the following:
    * Unchanged links are respected
    * Broken links are identified
    * Updated links are identified
    """

    # Given
    project = ResearchProject("")
    individuals = []
    sources = []

    plan = ResearchPlan()

    source_linked = Source("S123", "Linked", "Author", "Pub", "abbr")
    sources.append(source_linked)
    task_linked = ResearchTask()
    task_linked.source = source_linked.autocomplete_name()
    task_linked.source_link = source_linked.pointer
    plan.tasks.append(task_linked)

    task_broken = ResearchTask()
    task_broken.source = "Broken Source"
    task_broken.source_link = "FooBar"
    plan.tasks.append(task_broken)

    source_altered = Source("S987", "Altered", "Author", "Pub", "abbr")
    sources.append(source_altered)
    task_altered = ResearchTask()
    task_altered.source = "Altered Source"
    task_altered.source_link = source_altered.pointer
    plan.tasks.append(task_altered)

    project.plans.append(plan)

    tree_model = TreeModel()
    tree_model.set_project(project)

    individuals_model = IndividualsModel(individuals)
    sources_model = SourcesModel(sources)

    context = DataContext(
        data_model=tree_model,
        individuals_model=individuals_model,
        sources_model=sources_model,
    )
    updater = LinkUpdater(context)

    # When
    updater.calculate_updates()

    # Then
    assert updater.has_pending_updates() is True
    assert len(updater.ancestor_updates) == 0
    assert len(updater.source_updates) == 1
Beispiel #14
0
def test_delete_task_deletes_the_specified_task():
    """ delete_task() does nothing if there are no tasks """
    # Given
    plan = ResearchPlan()
    task_one = ResearchTask()
    task_two = ResearchTask()
    task_three = ResearchTask()

    plan.tasks.append(task_one)
    plan.tasks.append(task_two)
    plan.tasks.append(task_three)

    # When
    plan.delete_task(1)

    # Then
    assert len(plan.tasks) == 2
    assert plan.tasks[0] == task_one
    assert plan.tasks[1] == task_three
Beispiel #15
0
def test_setdata_returns_false_on_invalid_index():
    """ When setting data, false is returned for invalid index """
    # Given
    model = TreeModel()
    project = ResearchProject("")
    plan = ResearchPlan()
    project.plans.append(plan)

    model.set_project(project)

    # When
    retval = model.setData(QModelIndex(), "Foo")

    assert retval is False
Beispiel #16
0
def test_delete_calls_signals(qtbot):
    """ The start and end row removal signals should be emitted """
    # Given
    model = TreeModel()
    project = ResearchProject("")
    plan = ResearchPlan()
    project.plans.append(plan)

    model.set_project(project)
    plan_index = model.index(0, 0, model.plans_index)

    # When
    with qtbot.waitSignals([model.rowsAboutToBeRemoved, model.rowsRemoved]):
        model.delete_node(plan_index)
Beispiel #17
0
def test_index_returns_index_for_valid_row():
    """ The start and end row removal signals should be emitted """
    # Given
    model = TreeModel()
    project = ResearchProject("")
    plan = ResearchPlan()
    project.plans.append(plan)

    model.set_project(project)

    # When
    plan_index = model.index(0, 0, model.plans_index)

    # Then
    assert plan_index.isValid() is True
Beispiel #18
0
def test_setdata_returns_false_on_invalid_column():
    """ When setting data, false is returned for invalid column """
    # Given
    model = TreeModel()
    project = ResearchProject("")
    plan = ResearchPlan()
    project.plans.append(plan)

    model.set_project(project)
    plan_index = model.index(0, model.columnCount(None) + 1, model.plans_index)

    # When
    retval = model.setData(plan_index, "Foo")

    assert retval is False
Beispiel #19
0
def test_data_returns_none_for_invalid_index():
    """ When getting data, nothing is returned for invalid index """
    # Given
    model = TreeModel()
    project = ResearchProject("")
    plan = ResearchPlan()
    project.plans.append(plan)

    model.set_project(project)

    # When
    retval = model.data(QModelIndex(), Qt.DisplayRole)

    # Then
    assert retval is None
Beispiel #20
0
def test_setdata_updates_description():
    """ setData() works on the description """
    # Given
    model = TreeModel()
    project = ResearchProject("")
    plan = ResearchPlan()
    project.plans.append(plan)

    model.set_project(project)
    plan_index = model.index(0, 1, model.plans_index)

    # When
    retval = model.setData(plan_index, "Foo")

    assert retval is True
    assert model.data(plan_index, Qt.DisplayRole) == "Foo"
Beispiel #21
0
def test_setdata_doesnot_fire_signal_if_no_change(qtbot):
    """ When setting data, the dataChanged signal should only be emitted on actual changes """
    # Given
    model = TreeModel()
    project = ResearchProject("")
    plan = ResearchPlan()
    project.plans.append(plan)

    model.set_project(project)
    plan_index = model.index(0, 0, model.plans_index)

    # When
    with qtbot.assertNotEmitted(model.dataChanged):
        retval = model.setData(plan_index, plan.ancestor)

    assert retval is True
Beispiel #22
0
def test_setdata_fires_signal_on_change(qtbot):
    """ When setting data, the dataChanged signal is emitted on changes """
    # Given
    model = TreeModel()
    project = ResearchProject("")
    plan = ResearchPlan()
    project.plans.append(plan)

    model.set_project(project)
    plan_index = model.index(0, 0, model.plans_index)

    # When
    with qtbot.waitSignal(model.dataChanged):
        retval = model.setData(plan_index, "Foo")

    assert retval is True
Beispiel #23
0
def test_add_creates_task():
    """ Add should create a new task in the underlying data structure """
    # Given
    model = TreeModel()
    project = ResearchProject("")
    plan = ResearchPlan()
    project.plans.append(plan)

    model.set_project(project)
    plan_index = model.index(0, 0, model.plans_index)

    # When
    model.add_node(plan_index)

    # Then
    assert len(project.plans) == 1
    assert len(plan.tasks) == 1
Beispiel #24
0
def test_delete_removes_plan():
    """ Delete removes plan from underlying data structure """
    # Given
    model = TreeModel()
    project = ResearchProject("")
    plan = ResearchPlan()
    task = ResearchTask()
    plan.tasks.append(task)
    project.plans.append(plan)

    model.set_project(project)
    plan_index = model.index(0, 0, model.plans_index)

    # When
    model.delete_node(plan_index)

    # Then
    assert len(project.plans) == 0
Beispiel #25
0
def test_setdata_updates_link():
    """ setData() works on the link """
    # Given
    model = TreeModel()
    project = ResearchProject("")
    plan = ResearchPlan()
    project.plans.append(plan)
    project.plans[0].add_task()

    model.set_project(project)
    plan_index = model.index(0, 0, model.plans_index)
    task_index = model.index(0, TreeModelCols.LINK, plan_index)

    # When
    retval = model.setData(task_index, 1234)

    assert retval is True
    assert model.data(task_index, Qt.DisplayRole) == 1234
Beispiel #26
0
def test_get_font_returns_strikeout_for_task_with_result():
    """ A task with a nil result should show up as strike-out """
    # Given
    model = TreeModel()
    project = ResearchProject("")
    plan = ResearchPlan()
    task = ResearchTask()
    task.result = ResearchResult(False)
    plan.tasks.append(task)
    project.plans.append(plan)

    model.set_project(project)

    plan_index = model.index(0, 0, model.plans_index)
    task_index = model.index(0, 0, plan_index)

    # When
    font = model.data(task_index, Qt.FontRole)

    # Then
    assert font.strikeOut() is True
Beispiel #27
0
def test_setdata_updates_result():
    """ setData() works on the result """
    # Given
    model = TreeModel()
    project = ResearchProject("")
    plan = ResearchPlan()
    project.plans.append(plan)
    project.plans[0].add_task()

    model.set_project(project)
    plan_index = model.index(0, 0, model.plans_index)
    task_index = model.index(0, 2, plan_index)

    result = ResearchResult(True)
    result.description = "Test"

    # When
    retval = model.setData(task_index, result)

    assert retval is True
    assert model.data(task_index, Qt.DisplayRole) == result
Beispiel #28
0
def test_plan_links_are_checked():
    """
    Check the following:
    * Unchanged links are respected
    * Broken links are identified
    * Updated links are identified
    """

    # Given
    project = ResearchProject("")
    individuals = []
    sources = []

    indi_linked = Individual("I1234", "Link", "Indi", 1000, 2000)
    individuals.append(indi_linked)
    plan_linked = ResearchPlan()
    plan_linked.ancestor = indi_linked.autocomplete_name()
    plan_linked.ancestor_link = indi_linked.pointer
    project.plans.append(plan_linked)

    plan_broken = ResearchPlan()
    plan_broken.ancestor = "Broken Ancestor 1234/5678"
    plan_broken.ancestor_link = "FooBar"
    project.plans.append(plan_broken)

    indi_altered = Individual("I9876", "Altered", "Indi", 1000, 2000)
    individuals.append(indi_altered)
    plan_altered = ResearchPlan()
    plan_altered.ancestor = "Altered Ancestor 1000/2000"
    plan_altered.ancestor_link = indi_altered.pointer
    project.plans.append(plan_altered)

    tree_model = TreeModel()
    tree_model.set_project(project)

    individuals_model = IndividualsModel(individuals)
    sources_model = SourcesModel(sources)

    context = DataContext(
        data_model=tree_model,
        individuals_model=individuals_model,
        sources_model=sources_model,
    )
    updater = LinkUpdater(context)

    # When
    updater.calculate_updates()

    # Then
    assert updater.has_pending_updates() is True
    assert len(updater.ancestor_updates) == 1
    assert len(updater.source_updates) == 0