Esempio n. 1
0
def test_inline_merge_source_add_to_line():
    "More elaborate test of cell deletions on both sides, onesided and agreed."
    # Note: Merge rendering of conflicted sources here will depend on git/diff/builtin params and availability
    base = code_nb([
        "first source",
        "other text",
        "this cell will be deleted and patched\nhere we add",
        "yet more content",
        "and a final line",
    ],
                   strip_ids=True)
    local = code_nb(
        [
            "1st source",  # onesided change
            "other text",
            #"this cell will be deleted and patched",
            "some more content",  # twosided equal change
            "And a Final line",  # twosided conflicted change
        ],
        strip_ids=True)
    remote = code_nb(
        [
            "first source",
            "other text?",  # onesided change
            "this cell will be deleted and patched\nhere we add text to a line",
            "some more content",  # equal
            "and The final Line",  # conflicted
        ],
        strip_ids=True)
    expected = code_nb(
        [
            "1st source",
            "other text?",
            #'<<<<<<< local <CELL DELETED>\n\n=======\nthis cell will be deleted and modified\n>>>>>>> remote'
            '<<<<<<< LOCAL CELL DELETED >>>>>>>\nthis cell will be deleted and patched\nhere we add text to a line',
            "some more content",  # equal
            '<<<<<<< local\nAnd a Final line\n=======\nand The final Line\n>>>>>>> remote'
        ],
        strip_ids=True)
    merged, decisions = merge_notebooks(base, local, remote)
    assert merged == expected
    expected = code_nb(
        [
            "1st source",
            "other text?",
            #'<<<<<<< local\nthis cell will be deleted and modified\n=======\n>>>>>>> remote <CELL DELETED>'
            '<<<<<<< REMOTE CELL DELETED >>>>>>>\nthis cell will be deleted and patched\nhere we add text to a line',
            "some more content",
            '<<<<<<< local\nand The final Line\n=======\nAnd a Final line\n>>>>>>> remote'
        ],
        strip_ids=True)
    merged, decisions = merge_notebooks(base, remote, local)
    assert merged == expected
Esempio n. 2
0
def test_metadata_union_strategy_not_applied_immutable_on_dict():
    # Conflicting cell inserts at same location as removing old cell
    expected_partial_source = [["remote\n", "some other\n", "lines\n", "to align\n"]]
    expected_partial_metadata = [{'myval': 5}]
    expected_partial_outputs = [["local\nsome other\nlines\nto align\n", "output2", "output3"]]
    base, local, remote, expected_partial = _make_notebook_with_multi_conflicts(
        expected_partial_source, expected_partial_metadata, expected_partial_outputs
    )
    base.cells[0].metadata['myval'] = 5
    local.cells[0].metadata['myval'] = 22
    remote.cells[0].metadata['myval'] = 13

    expected_conflicts = [{
        'action': 'base',
        'common_path': ('cells', 0, 'metadata'),
        'conflict': True,
        'local_diff': [{'key': 'myval', 'op': 'replace', 'value': 22}],
        'remote_diff': [{'key': 'myval', 'op': 'replace', 'value': 13}]
    }]
    merge_args = copy.deepcopy(args)
    merge_args.merge_strategy = "union"
    merge_args.input_strategy = "use-remote"
    merge_args.output_strategy = "use-local"

    partial, decisions = merge_notebooks(base, local, remote, merge_args)

    _check(partial, expected_partial, decisions, expected_conflicts)
Esempio n. 3
0
def test_metadata_union_strategy_not_applied_immutable_on_dict():
    # Conflicting cell inserts at same location as removing old cell
    expected_partial_source = [["remote\n", "some other\n", "lines\n", "to align\n"]]
    expected_partial_metadata = [{'myval': 5}]
    expected_partial_outputs = [["local\nsome other\nlines\nto align\n", "output2", "output3"]]
    base, local, remote, expected_partial = _make_notebook_with_multi_conflicts(
        expected_partial_source, expected_partial_metadata, expected_partial_outputs
    )
    base.cells[0].metadata['myval'] = 5
    local.cells[0].metadata['myval'] = 22
    remote.cells[0].metadata['myval'] = 13

    expected_conflicts = [{
        'action': 'base',
        'common_path': ('cells', 0, 'metadata'),
        'conflict': True,
        'local_diff': [{'key': 'myval', 'op': 'replace', 'value': 22}],
        'remote_diff': [{'key': 'myval', 'op': 'replace', 'value': 13}]
    }]
    merge_args = copy.deepcopy(args)
    merge_args.merge_strategy = "union"
    merge_args.input_strategy = "use-remote"
    merge_args.output_strategy = "use-local"

    partial, decisions = merge_notebooks(base, local, remote, merge_args)

    _check(partial, expected_partial, decisions, expected_conflicts)
def test_inline_merge_source_empty():
    base = new_notebook()
    local = new_notebook()
    remote = new_notebook()
    expected = new_notebook()
    merged, decisions = merge_notebooks(base, local, remote)
    assert merged == expected
def test_inline_merge_source_empty():
    base = new_notebook()
    local = new_notebook()
    remote = new_notebook()
    expected = new_notebook()
    merged, decisions = merge_notebooks(base, local, remote)
    assert merged == expected
def test_inline_merge_source_cell_deletions():
    "Cell deletions on both sides, onesided and agreed."
    base = code_nb([
        "first source",
        "other text",
        "yet more content",
        "and a final line",
        ])
    local = code_nb([
        #"first source",
        "other text",
        #"yet more content",
        #"and a final line",
        ])
    remote = code_nb([
        "first source",
        #"other text",
        "yet more content",
        #"and a final line",
        ])
    empty = code_nb([])
    expected = code_nb([])
    for a in [base, local, remote, empty]:
        for b in [base, local, remote, empty]:
            merged, decisions = merge_notebooks(base, a, b)
            if a is b:
                assert merged == a
            elif a is base:
                assert merged == b
            elif b is base:
                assert merged == a
            else:
                # All other combinations will delete all cells
                assert merged == empty
Esempio n. 7
0
def test_autoresolve_notebook_ec():
    args = None
    # We need a source here otherwise the cells are not aligned
    source = "def foo(x, y):\n    return x**y"

    base = nbformat.v4.new_notebook()
    base["cells"].append(nbformat.v4.new_code_cell())
    base["cells"][0]["source"] = source
    base["cells"][0]["execution_count"] = 1

    local = copy.deepcopy(base)
    remote = copy.deepcopy(base)
    expected = copy.deepcopy(base)
    local["cells"][0]["execution_count"] = 2
    remote["cells"][0]["execution_count"] = 3
    expected["cells"][0]["execution_count"] = None

    merged, local_conflicts, remote_conflicts = merge_notebooks(base, local, remote, args)

    if 0:
        print()
        print(merged)
        print(local_conflicts)
        print(remote_conflicts)
        print()

    assert merged == expected
    assert local_conflicts == []
    assert remote_conflicts == []
Esempio n. 8
0
def test_autoresolve_notebook_ec():
    args = None
    # We need a source here otherwise the cells are not aligned
    source = "def foo(x, y):\n    return x**y"

    base = nbformat.v4.new_notebook()
    base["cells"].append(nbformat.v4.new_code_cell())
    base["cells"][0]["source"] = source
    base["cells"][0]["execution_count"] = 1

    local = copy.deepcopy(base)
    remote = copy.deepcopy(base)
    expected = copy.deepcopy(base)
    local["cells"][0]["execution_count"] = 2
    remote["cells"][0]["execution_count"] = 3
    expected["cells"][0]["execution_count"] = None

    merged, local_conflicts, remote_conflicts = merge_notebooks(
        base, local, remote, args)

    if 0:
        print()
        print(merged)
        print(local_conflicts)
        print(remote_conflicts)
        print()

    assert merged == expected
    assert local_conflicts == []
    assert remote_conflicts == []
Esempio n. 9
0
def test_autoresolve_inline_source_conflict(db):
    nbb = db["inline-conflict--1"]
    nbl = db["inline-conflict--2"]
    nbr = db["inline-conflict--3"]

    args = builder.parse_args(["", "", ""])
    args.merge_strategy = 'inline'
    merged, decisions = merge_notebooks(nbb, nbl, nbr, args)

    # Has conflicts
    assert any(d.conflict for d in decisions)

    source = merged.cells[0].source

    expected = """<<<<<<< local
x = 1
y = 3
z = 4
print(x * y / z)
||||||| base
x = 1
y = 3
print(x * y)
=======
x = 1
y = 3
print(x + q)
>>>>>>> remote"""
    assert source == expected
Esempio n. 10
0
def test_merge_cell_sources_separate_inserts():
    base = strip_cell_ids(
        sources_to_notebook([
            [
                "def f(x):",
                "    return x**2",
            ],
            [
                "def g(y):",
                "    return y + 2",
            ],
        ]))
    local = strip_cell_ids(
        sources_to_notebook([
            [
                "print(f(3))",
            ],
            [
                "def f(x):",
                "    return x**2",
            ],
            [
                "def g(y):",
                "    return y + 2",
            ],
        ]))
    remote = strip_cell_ids(
        sources_to_notebook([
            [
                "def f(x):",
                "    return x**2",
            ],
            [
                "def g(y):",
                "    return y + 2",
            ],
            [
                "print(f(7))",
            ],
        ]))
    expected = strip_cell_ids(
        sources_to_notebook([
            [
                "print(f(3))",
            ],
            [
                "def f(x):",
                "    return x**2",
            ],
            [
                "def g(y):",
                "    return y + 2",
            ],
            [
                "print(f(7))",
            ],
        ]))
    actual, decisions = merge_notebooks(base, local, remote, args)
    assert not any([d.conflict for d in decisions])
    assert actual == expected
def test_inline_merge_source_cell_deletions():
    "Cell deletions on both sides, onesided and agreed."
    base = code_nb([
        "first source",
        "other text",
        "yet more content",
        "and a final line",
    ])
    local = code_nb([
        #"first source",
        "other text",
        #"yet more content",
        #"and a final line",
    ])
    remote = code_nb([
        "first source",
        #"other text",
        "yet more content",
        #"and a final line",
    ])
    empty = code_nb([])
    expected = code_nb([])
    for a in [base, local, remote, empty]:
        for b in [base, local, remote, empty]:
            merged, decisions = merge_notebooks(base, a, b)
            if a is b:
                assert merged == a
            elif a is base:
                assert merged == b
            elif b is base:
                assert merged == a
            else:
                # All other combinations will delete all cells
                assert merged == empty
Esempio n. 12
0
def test_inline_merge_source_patches_both_ends():
    "More elaborate test of cell deletions on both sides, onesided and agreed."
    # Note: Merge rendering of conflicted sources here will depend on git/diff/builtin params and availability
    base = code_nb([
        "first source will be modified",
        "other text",
        "this cell will be untouched",
        "yet more content",
        "and final line will be changed",
    ],
                   strip_ids=True)
    local = code_nb([
        "first source will be modified locally",
        "other text",
        "this cell will be untouched",
        "yet more content",
        "and final line will be changed locally",
    ],
                    strip_ids=True)
    remote = code_nb([
        "first source will be modified remotely",
        "other text",
        "this cell will be untouched",
        "yet more content",
        "and final line will be changed remotely",
    ],
                     strip_ids=True)
    expected = code_nb([
        '<<<<<<< local\nfirst source will be modified locally\n=======\nfirst source will be modified remotely\n>>>>>>> remote',
        "other text",
        "this cell will be untouched",
        "yet more content",
        '<<<<<<< local\nand final line will be changed locally\n=======\nand final line will be changed remotely\n>>>>>>> remote',
    ],
                       strip_ids=True)
    merged, decisions = merge_notebooks(base, local, remote)
    assert merged == expected
    expected = code_nb([
        '<<<<<<< local\nfirst source will be modified remotely\n=======\nfirst source will be modified locally\n>>>>>>> remote',
        "other text",
        "this cell will be untouched",
        "yet more content",
        '<<<<<<< local\nand final line will be changed remotely\n=======\nand final line will be changed locally\n>>>>>>> remote',
    ],
                       strip_ids=True)
    merged, decisions = merge_notebooks(base, remote, local)
    assert merged == expected
def test_inline_merge_attachments():
    # FIXME: Use output creation utils Vidar wrote in another test file
    base = new_notebook()
    local = new_notebook()
    remote = new_notebook()
    expected = new_notebook()
    merged, decisions = merge_notebooks(base, local, remote)
    assert merged == expected
def test_inline_merge_source_onesided_only():
    "A mix of changes on one side (delete, patch, remove)."
    base = code_nb([
        "first source",
        "other text",
        "yet more content",
    ])
    changed = code_nb([
        #"first source", # deleted
        "other text v2",
        "a different cell inserted",
        "yet more content",
    ])
    merged, decisions = merge_notebooks(base, changed, base)
    assert merged == changed
    merged, decisions = merge_notebooks(base, base, changed)
    assert merged == changed
def test_inline_merge_attachments():
    # FIXME: Use output creation utils Vidar wrote in another test file
    base = new_notebook()
    local = new_notebook()
    remote = new_notebook()
    expected = new_notebook()
    merged, decisions = merge_notebooks(base, local, remote)
    assert merged == expected
def test_inline_merge_source_onesided_only():
    "A mix of changes on one side (delete, patch, remove)."
    base = code_nb([
        "first source",
        "other text",
        "yet more content",
        ])
    changed = code_nb([
        #"first source", # deleted
        "other text v2",
        "a different cell inserted",
        "yet more content",
        ])
    merged, decisions = merge_notebooks(base, changed, base)
    assert merged == changed
    merged, decisions = merge_notebooks(base, base, changed)
    assert merged == changed
def test_inline_merge_dummy_notebooks():
    "Just the basic empty notebook passes through."
    base = new_notebook()
    local = new_notebook()
    remote = new_notebook()
    expected = new_notebook()
    merged, decisions = merge_notebooks(base, local, remote)
    assert expected == merged
def test_inline_merge_empty_notebooks():
    "Missing fields all around passes through."
    base = {}
    local = {}
    remote = {}
    expected = {}
    merged, decisions = merge_notebooks(base, local, remote)
    assert expected == merged
def test_inline_merge_notebook_version():
    "Minor version gets bumped to max."
    base = new_notebook(nbformat=4, nbformat_minor=0)
    local = new_notebook(nbformat=4, nbformat_minor=1)
    remote = new_notebook(nbformat=4, nbformat_minor=2)
    expected = new_notebook(nbformat=4, nbformat_minor=2)
    merged, decisions = merge_notebooks(base, local, remote)
    assert expected == merged
def test_inline_merge_notebook_version():
    "Minor version gets bumped to max."
    base = new_notebook(nbformat=4, nbformat_minor=0)
    local = new_notebook(nbformat=4, nbformat_minor=1)
    remote = new_notebook(nbformat=4, nbformat_minor=2)
    expected = new_notebook(nbformat=4, nbformat_minor=2)
    merged, decisions = merge_notebooks(base, local, remote)
    assert expected == merged
def test_inline_merge_dummy_notebooks():
    "Just the basic empty notebook passes through."
    base = new_notebook()
    local = new_notebook()
    remote = new_notebook()
    expected = new_notebook()
    merged, decisions = merge_notebooks(base, local, remote)
    assert expected == merged
def test_inline_merge_empty_notebooks():
    "Missing fields all around passes through."
    base = {}
    local = {}
    remote = {}
    expected = {}
    merged, decisions = merge_notebooks(base, local, remote)
    assert expected == merged
Esempio n. 23
0
def test_merge_cell_sources_separate_inserts():
    base = sources_to_notebook([
        [
            "def f(x):",
            "    return x**2",
        ],
        [
            "def g(y):",
            "    return y + 2",
        ],
    ])
    local = sources_to_notebook([
        [
            "print(f(3))",
        ],
        [
            "def f(x):",
            "    return x**2",
        ],
        [
            "def g(y):",
            "    return y + 2",
        ],
    ])
    remote = sources_to_notebook([
        [
            "def f(x):",
            "    return x**2",
        ],
        [
            "def g(y):",
            "    return y + 2",
        ],
        [
            "print(f(7))",
        ],
    ])
    expected = sources_to_notebook([
        [
            "print(f(3))",
        ],
        [
            "def f(x):",
            "    return x**2",
        ],
        [
            "def g(y):",
            "    return y + 2",
        ],
        [
            "print(f(7))",
        ],
    ])
    args = None
    actual, lco, rco = merge_notebooks(base, local, remote, args)
    assert not lco
    assert not rco
    assert actual == expected
Esempio n. 24
0
def test_autoresolve_inline_source_conflict(db):
    nbb = db["inline-conflict--1"]
    nbl = db["inline-conflict--2"]
    nbr = db["inline-conflict--3"]

    args = builder.parse_args(["", "", ""])
    args.merge_strategy = 'inline'
    merged, decisions = merge_notebooks(nbb, nbl, nbr, args)

    # Has conflicts
    assert any(d.conflict for d in decisions)

    source = merged.cells[0].source

    git_expected = """\
x = 1
<<<<<<< local
y = 3
print(x * y)
=======
q = 3.1
print(x + q)
>>>>>>> remote
"""

    builtin_expected_course = """\
<<<<<<< local
x = 1
y = 3
z = 4
print(x * y / z)
=======
x = 1
q = 3.1
print(x + q)
>>>>>>> remote
"""
    # ||||||| base
    # x = 1
    # y = 3
    # print(x * y)

    builtin_expected_finegrained = """\
x = 1
<<<<<<< local
y = 3
z = 4
print(x * y / z)
=======
q = 3.1
print(x + q)
>>>>>>> remote
"""

    expected = builtin_expected_finegrained

    assert source == expected
Esempio n. 25
0
def test_autoresolve_inline_source_conflict(db):
    nbb = db["inline-conflict--1"]
    nbl = db["inline-conflict--2"]
    nbr = db["inline-conflict--3"]

    args = builder.parse_args(["", "", ""])
    args.merge_strategy = 'inline'
    merged, decisions = merge_notebooks(nbb, nbl, nbr, args)

    # Has conflicts
    assert any(d.conflict for d in decisions)

    source = merged.cells[0].source

    git_expected = """\
x = 1
<<<<<<< local
y = 3
print(x * y)
=======
q = 3.1
print(x + q)
>>>>>>> remote
"""

    builtin_expected_course = """\
<<<<<<< local
x = 1
y = 3
z = 4
print(x * y / z)
=======
x = 1
q = 3.1
print(x + q)
>>>>>>> remote
"""
    # ||||||| base
    # x = 1
    # y = 3
    # print(x * y)

    builtin_expected_finegrained = """\
x = 1
<<<<<<< local
y = 3
z = 4
print(x * y / z)
=======
q = 3.1
print(x + q)
>>>>>>> remote
"""

    expected = builtin_expected_finegrained

    assert source == expected
def test_inline_merge_source_add_to_line():
    "More elaborate test of cell deletions on both sides, onesided and agreed."
    # Note: Merge rendering of conflicted sources here will depend on git/diff/builtin params and availability
    base = code_nb([
        "first source",
        "other text",
        "this cell will be deleted and patched\nhere we add",
        "yet more content",
        "and a final line",
        ])
    local = code_nb([
        "1st source",  # onesided change
        "other text",
        #"this cell will be deleted and patched",
        "some more content",  # twosided equal change
        "And a Final line",  # twosided conflicted change
        ])
    remote = code_nb([
        "first source",
        "other text?",  # onesided change
        "this cell will be deleted and patched\nhere we add text to a line",
        "some more content",   # equal
        "and The final Line",  # conflicted
        ])
    expected = code_nb([
        "1st source",
        "other text?",
        #'<<<<<<< local <CELL DELETED>\n\n=======\nthis cell will be deleted and modified\n>>>>>>> remote'
        '<<<<<<< LOCAL CELL DELETED >>>>>>>\nthis cell will be deleted and patched\nhere we add text to a line',
        "some more content",  # equal
        '<<<<<<< local\nAnd a Final line\n=======\nand The final Line\n>>>>>>> remote'
        ])
    merged, decisions = merge_notebooks(base, local, remote)
    assert merged == expected
    expected = code_nb([
        "1st source",
        "other text?",
        #'<<<<<<< local\nthis cell will be deleted and modified\n=======\n>>>>>>> remote <CELL DELETED>'
        '<<<<<<< REMOTE CELL DELETED >>>>>>>\nthis cell will be deleted and patched\nhere we add text to a line',
        "some more content",
        '<<<<<<< local\nand The final Line\n=======\nAnd a Final line\n>>>>>>> remote'
        ])
    merged, decisions = merge_notebooks(base, remote, local)
    assert merged == expected
Esempio n. 27
0
def _check_sources(base, local, remote, expected_partial, expected_conflicts, merge_args=None):
    base = src2nb(base)
    local = src2nb(local)
    remote = src2nb(remote)
    expected_partial = src2nb(expected_partial)
    merge_args = merge_args or args

    partial, decisions = merge_notebooks(base, local, remote, merge_args)

    _check(partial, expected_partial, decisions, expected_conflicts)
Esempio n. 28
0
def _check_sources(base, local, remote, expected_partial, expected_conflicts, merge_args=None):
    base = src2nb(base)
    local = src2nb(local)
    remote = src2nb(remote)
    expected_partial = src2nb(expected_partial)
    merge_args = merge_args or args

    partial, decisions = merge_notebooks(base, local, remote, merge_args)

    _check(partial, expected_partial, decisions, expected_conflicts)
Esempio n. 29
0
def _check_outputs(base, local, remote, expected_partial, expected_conflicts, merge_args=None):
    base = outputs_to_notebook(base)
    local = outputs_to_notebook(local)
    remote = outputs_to_notebook(remote)
    expected_partial = outputs_to_notebook(expected_partial)
    merge_args = merge_args or args

    partial, decisions = merge_notebooks(base, local, remote, merge_args)

    _check(partial, expected_partial, decisions, expected_conflicts)
Esempio n. 30
0
def _check_outputs(base, local, remote, expected_partial, expected_conflicts, merge_args=None):
    base = outputs_to_notebook(base)
    local = outputs_to_notebook(local)
    remote = outputs_to_notebook(remote)
    expected_partial = outputs_to_notebook(expected_partial)
    merge_args = merge_args or args

    partial, decisions = merge_notebooks(base, local, remote, merge_args)

    _check(partial, expected_partial, decisions, expected_conflicts)
def test_inline_merge_source_patch_delete_conflicts_both_ends():
    "More elaborate test of cell deletions on both sides, onesided and agreed."
    # Note: Merge rendering of conflicted sources here will depend on git/diff/builtin params and availability
    base = code_nb([
        "first source will be modified",
        "other text",
        "this cell will be untouched",
        "yet more content",
        "and final line will be changed",
        ])
    local = code_nb([
        "first source will be modified on one side",
        "other text",
        "this cell will be untouched",
        "yet more content",
        #"and final line will be deleted locally",
        ])
    remote = code_nb([
        #"first source will be deleted remotely",
        "other text",
        "this cell will be untouched",
        "yet more content",
        "and final line will be changed on one side",
        ])
    expected = code_nb([
        '<<<<<<< REMOTE CELL DELETED >>>>>>>\nfirst source will be modified on one side',
        "other text",
        "this cell will be untouched",
        "yet more content",
        '<<<<<<< LOCAL CELL DELETED >>>>>>>\nand final line will be changed on one side',
        ])
    merged, decisions = merge_notebooks(base, local, remote)
    assert merged == expected
    expected = code_nb([
        '<<<<<<< LOCAL CELL DELETED >>>>>>>\nfirst source will be modified on one side',
        "other text",
        "this cell will be untouched",
        "yet more content",
        '<<<<<<< REMOTE CELL DELETED >>>>>>>\nand final line will be changed on one side',
        ])
    merged, decisions = merge_notebooks(base, remote, local)
    assert merged == expected
def test_inline_merge_source_patch_delete_conflicts_both_ends():
    "More elaborate test of cell deletions on both sides, onesided and agreed."
    # Note: Merge rendering of conflicted sources here will depend on git/diff/builtin params and availability
    base = code_nb([
        "first source will be modified",
        "other text",
        "this cell will be untouched",
        "yet more content",
        "and final line will be changed",
    ])
    local = code_nb([
        "first source will be modified on one side",
        "other text",
        "this cell will be untouched",
        "yet more content",
        #"and final line will be deleted locally",
    ])
    remote = code_nb([
        #"first source will be deleted remotely",
        "other text",
        "this cell will be untouched",
        "yet more content",
        "and final line will be changed on one side",
    ])
    expected = code_nb([
        '<<<<<<< REMOTE CELL DELETED >>>>>>>\nfirst source will be modified on one side',
        "other text",
        "this cell will be untouched",
        "yet more content",
        '<<<<<<< LOCAL CELL DELETED >>>>>>>\nand final line will be changed on one side',
    ])
    merged, decisions = merge_notebooks(base, local, remote)
    assert merged == expected
    expected = code_nb([
        '<<<<<<< LOCAL CELL DELETED >>>>>>>\nfirst source will be modified on one side',
        "other text",
        "this cell will be untouched",
        "yet more content",
        '<<<<<<< REMOTE CELL DELETED >>>>>>>\nand final line will be changed on one side',
    ])
    merged, decisions = merge_notebooks(base, remote, local)
    assert merged == expected
def test_inline_merge_source_all_equal():
    base = code_nb([
        "first source",
        "other text",
        "yet more content",
    ])
    local = base
    remote = base
    expected = base
    merged, decisions = merge_notebooks(base, local, remote)
    assert merged == expected
def test_inline_merge_source_all_equal():
    base = code_nb([
        "first source",
        "other text",
        "yet more content",
    ])
    local = base
    remote = base
    expected = base
    merged, decisions = merge_notebooks(base, local, remote)
    assert merged == expected
def test_inline_merge_cells_replacement_similar():
    base = sources_to_notebook([['unmodified'], ['base']],
                               cell_type='markdown')
    local = sources_to_notebook([['unmodified'], ['local']],
                                cell_type='markdown')
    remote = sources_to_notebook([['unmodified'], ['remote']],
                                 cell_type='markdown')
    expected = sources_to_notebook([['unmodified'],
                                    [("<" * 7) + ' local\n', 'local\n',
                                     ("=" * 7) + '\n', 'remote\n',
                                     (">" * 7) + ' remote']],
                                   cell_type='markdown')
    merged, decisions = merge_notebooks(base, local, remote)
    assert merged == expected
def test_inline_merge_cells_replacement_unsimilar():
    base = sources_to_notebook([['unmodified'], ['base']], cell_type='markdown')
    local = sources_to_notebook([['unmodified'], ['local\n', 'friendly faces\n', '3.14']], cell_type='markdown')
    remote = sources_to_notebook([['unmodified'], ['remote\n', 'foo bar baz\n']], cell_type='markdown')
    expected = sources_to_notebook([
        ['unmodified'],
        [_cell_marker_format(("<"*7) + ' local')],
        ['local\n', 'friendly faces\n', '3.14'],
        [_cell_marker_format("="*7)],
        ['remote\n', 'foo bar baz\n'],
        [_cell_marker_format((">"*7) + ' remote')],
    ], cell_type='markdown')
    merged, decisions = merge_notebooks(base, local, remote)
    assert merged == expected
Esempio n. 37
0
def _check(base, local, remote, expected_partial, expected_lco, expected_rco):
    base = src2nb(base)
    local = src2nb(local)
    remote = src2nb(remote)
    expected_partial = src2nb(expected_partial)

    args = None
    partial, lco, rco = merge_notebooks(base, local, remote, args)

    sources = [cell["source"] for cell in partial["cells"]]
    expected_sources = [cell["source"] for cell in expected_partial["cells"]]
    assert sources == expected_sources

    assert partial == expected_partial
    assert lco == expected_lco
    assert rco == expected_rco
Esempio n. 38
0
def _check_sources(base,
                   local,
                   remote,
                   expected_partial,
                   expected_conflicts,
                   merge_args=None,
                   ignore_cell_ids=False):
    base = src2nb(base, strip_ids=ignore_cell_ids)
    local = src2nb(local, strip_ids=ignore_cell_ids)
    remote = src2nb(remote, strip_ids=ignore_cell_ids)
    expected_partial = src2nb(expected_partial, strip_ids=ignore_cell_ids)
    merge_args = merge_args or args

    partial, decisions = merge_notebooks(base, local, remote, merge_args)

    _check(partial, expected_partial, decisions, expected_conflicts)
Esempio n. 39
0
def _check(base, local, remote, expected_partial, expected_lco, expected_rco):
    base = src2nb(base)
    local = src2nb(local)
    remote = src2nb(remote)
    expected_partial = src2nb(expected_partial)

    args = None
    partial, lco, rco = merge_notebooks(base, local, remote, args)

    sources = [cell["source"] for cell in partial["cells"]]
    expected_sources = [cell["source"] for cell in expected_partial["cells"]]
    assert sources == expected_sources

    assert partial == expected_partial
    assert lco == expected_lco
    assert rco == expected_rco
Esempio n. 40
0
    def post(self):
        base_nb = self.get_notebook_argument("base")
        local_nb = self.get_notebook_argument("local")
        remote_nb = self.get_notebook_argument("remote")

        try:
            merged, lco, rco = nbdime.merge_notebooks(base_nb, local_nb, remote_nb)
        except Exception as e:
            raise web.HTTPError(400, "Error while attempting to merge documents.")

        data = {
            "base": base_nb,
            "local_conflicts": lco,
            "remote_conflicts": rco,
            }
        self.finish(data)
Esempio n. 41
0
def test_only_outputs(db, reset_diff_targets):
    base = db["mixed-conflicts--1"]
    local = db["mixed-conflicts--2"]
    remote = db["mixed-conflicts--3"]
    set_notebook_diff_targets(False, True, False, False)

    merge_args = copy.deepcopy(args)
    merge_args.merge_strategy = "mergetool"

    partial, decisions = merge_notebooks(base, local, remote, merge_args)

    assert len(decisions) > 0
    for d in decisions:
        path = d['common_path']
        # Still have some decisions on cell root, so avoid with len == 2 check
        assert len(path) == 2 or path[2] == 'outputs'
def test_inline_merge_cells_replacement_similar():
    base = sources_to_notebook([['unmodified'], ['base']], cell_type='markdown')
    local = sources_to_notebook([['unmodified'], ['local']], cell_type='markdown')
    remote = sources_to_notebook([['unmodified'], ['remote']], cell_type='markdown')
    expected = sources_to_notebook([
        ['unmodified'],
        [
            ("<"*7) + ' local\n',
            'local\n',
            ("="*7) + '\n',
            'remote\n',
            (">"*7) + ' remote'
        ]
    ], cell_type='markdown')
    merged, decisions = merge_notebooks(base, local, remote)
    assert merged == expected
Esempio n. 43
0
    def post(self):
        base_nb = self.get_notebook_argument("base")
        local_nb = self.get_notebook_argument("local")
        remote_nb = self.get_notebook_argument("remote")

        try:
            merged, lco, rco = nbdime.merge_notebooks(base_nb, local_nb, remote_nb)
        except Exception as e:
            raise web.HTTPError(400, "Error while attempting to merge documents.")

        data = {
            "base": base_nb,
            "local_conflicts": lco,
            "remote_conflicts": rco,
            }
        self.finish(data)
Esempio n. 44
0
def test_only_outputs(db, reset_diff_targets):
    base = db["mixed-conflicts--1"]
    local = db["mixed-conflicts--2"]
    remote = db["mixed-conflicts--3"]
    set_notebook_diff_targets(False, True, False, False)

    merge_args = copy.deepcopy(args)
    merge_args.merge_strategy = "mergetool"

    partial, decisions = merge_notebooks(base, local, remote, merge_args)

    assert len(decisions) > 0
    for d in decisions:
        path = d['common_path']
        # Still have some decisions on cell root, so avoid with len == 2 check
        assert len(path) == 2 or path[2] == 'outputs'
Esempio n. 45
0
def _check_outputs(base,
                   local,
                   remote,
                   expected_partial,
                   expected_conflicts,
                   merge_args=None,
                   ignore_cell_ids=False):
    base = outputs_to_notebook(base, strip_ids=ignore_cell_ids)
    local = outputs_to_notebook(local, strip_ids=ignore_cell_ids)
    remote = outputs_to_notebook(remote, strip_ids=ignore_cell_ids)
    expected_partial = outputs_to_notebook(expected_partial,
                                           strip_ids=ignore_cell_ids)
    merge_args = merge_args or args

    partial, decisions = merge_notebooks(base, local, remote, merge_args)

    _check(partial, expected_partial, decisions, expected_conflicts)
Esempio n. 46
0
def test_merge_cell_sources_separate_inserts():
    base = sources_to_notebook([[
        "def f(x):",
        "    return x**2",
        ], [
        "def g(y):",
        "    return y + 2",
        ],
        ])
    local = sources_to_notebook([[
        "print(f(3))",
        ], [
        "def f(x):",
        "    return x**2",
        ], [
        "def g(y):",
        "    return y + 2",
        ],
        ])
    remote = sources_to_notebook([[
        "def f(x):",
        "    return x**2",
        ], [
        "def g(y):",
        "    return y + 2",
        ], [
        "print(f(7))",
        ],
        ])
    expected = sources_to_notebook([[
        "print(f(3))",
        ], [
        "def f(x):",
        "    return x**2",
        ], [
        "def g(y):",
        "    return y + 2",
        ], [
        "print(f(7))",
        ],
        ])
    args = None
    actual, lco, rco = merge_notebooks(base, local, remote, args)
    assert not lco
    assert not rco
    assert actual == expected
Esempio n. 47
0
def test_merge_cell_sources_separate_inserts():
    base = [[
        "def f(x):",
        "    return x**2",
        ], [
        "def g(y):",
        "    return y + 2",
        ],
        ]
    local = [[
        "print(f(3))",
        ], [
        "def f(x):",
        "    return x**2",
        ], [
        "def g(y):",
        "    return y + 2",
        ],
        ]
    remote = [[
        "def f(x):",
        "    return x**2",
        ], [
        "def g(y):",
        "    return y + 2",
        ], [
        "print(f(7))",
        ],
        ]
    expected = sources_to_notebook([[
        "print(f(3))",
        ], [
        "def f(x):",
        "    return x**2",
        ], [
        "def g(y):",
        "    return y + 2",
        ], [
        "print(f(7))",
        ],
        ])
    actual, lco, rco = merge_notebooks(sources_to_notebook(base), sources_to_notebook(local), sources_to_notebook(remote))
    assert not lco
    assert not rco
    assert actual == expected
def test_inline_merge_cells_insertion_unsimilar():
    base = sources_to_notebook([['unmodified']], cell_type='markdown')
    local = sources_to_notebook(
        [['unmodified'], ['local\n', 'friendly faces\n', '3.14']],
        cell_type='markdown')
    remote = sources_to_notebook(
        [['unmodified'], ['remote\n', 'foo bar baz\n']], cell_type='markdown')
    expected = sources_to_notebook([
        ['unmodified'],
        [_cell_marker_format(("<" * 7) + ' local')],
        ['local\n', 'friendly faces\n', '3.14'],
        [_cell_marker_format("=" * 7)],
        ['remote\n', 'foo bar baz\n'],
        [_cell_marker_format((">" * 7) + ' remote')],
    ],
                                   cell_type='markdown')
    merged, decisions = merge_notebooks(base, local, remote)
    assert merged == expected
Esempio n. 49
0
def test_inline_merge_outputs_conflicting_insert_in_empty():
    # One cell with two outputs:
    base = outputs_to_notebook([[]], strip_ids=True)
    local = outputs_to_notebook([['local']], strip_ids=True)
    remote = outputs_to_notebook([['remote']], strip_ids=True)
    expected = outputs_to_notebook([[
        nbformat.v4.new_output(
            output_type='stream', name='stderr', text='<<<<<<< local\n'),
        'local',
        nbformat.v4.new_output(
            output_type='stream', name='stderr', text='=======\n'),
        'remote',
        nbformat.v4.new_output(
            output_type='stream', name='stderr', text='>>>>>>> remote\n'),
    ]],
                                   strip_ids=True)
    merged, decisions = merge_notebooks(base, local, remote)
    assert merged == expected
Esempio n. 50
0
def test_merge_mix_strategies():
    # Conflicting cell inserts at same location as removing old cell
    expected_partial_source = [["remote\n", "some other\n", "lines\n", "to align\n"]]
    expected_partial_metadata = [{'myval': 'local'}]
    expected_partial_outputs = [["local\nremote\nsome other\nlines\nto align\n", "output2", "output3"]]
    base, local, remote, expected_partial = _make_notebook_with_multi_conflicts(
        expected_partial_source, expected_partial_metadata, expected_partial_outputs
    )

    expected_conflicts = []
    merge_args = copy.deepcopy(args)
    merge_args.merge_strategy = "use-local"
    merge_args.input_strategy = "use-remote"
    merge_args.output_strategy = "union"

    partial, decisions = merge_notebooks(base, local, remote, merge_args)

    _check(partial, expected_partial, decisions, expected_conflicts)
Esempio n. 51
0
def test_merge_mix_strategies():
    # Conflicting cell inserts at same location as removing old cell
    expected_partial_source = [["remote\n", "some other\n", "lines\n", "to align\n"]]
    expected_partial_metadata = [{'myval': 'local'}]
    expected_partial_outputs = [["local\nremote\nsome other\nlines\nto align\n", "output2", "output3"]]
    base, local, remote, expected_partial = _make_notebook_with_multi_conflicts(
        expected_partial_source, expected_partial_metadata, expected_partial_outputs
    )

    expected_conflicts = []
    merge_args = copy.deepcopy(args)
    merge_args.merge_strategy = "use-local"
    merge_args.input_strategy = "use-remote"
    merge_args.output_strategy = "union"

    partial, decisions = merge_notebooks(base, local, remote, merge_args)

    _check(partial, expected_partial, decisions, expected_conflicts)
Esempio n. 52
0
def test_merge_cell_sources_separate_inserts():
    base = sources_to_notebook([[
        "def f(x):",
        "    return x**2",
        ], [
        "def g(y):",
        "    return y + 2",
        ],
        ])
    local = sources_to_notebook([[
        "print(f(3))",
        ], [
        "def f(x):",
        "    return x**2",
        ], [
        "def g(y):",
        "    return y + 2",
        ],
        ])
    remote = sources_to_notebook([[
        "def f(x):",
        "    return x**2",
        ], [
        "def g(y):",
        "    return y + 2",
        ], [
        "print(f(7))",
        ],
        ])
    expected = sources_to_notebook([[
        "print(f(3))",
        ], [
        "def f(x):",
        "    return x**2",
        ], [
        "def g(y):",
        "    return y + 2",
        ], [
        "print(f(7))",
        ],
        ])
    actual, decisions = merge_notebooks(base, local, remote, args)
    assert not any([d.conflict for d in decisions])
    assert actual == expected
Esempio n. 53
0
def test_inline_merge_cells_insertion_similar():
    base = sources_to_notebook([['unmodified']],
                               cell_type='markdown',
                               strip_ids=True)
    local = sources_to_notebook([['unmodified'], ['local']],
                                cell_type='markdown',
                                strip_ids=True)
    remote = sources_to_notebook([['unmodified'], ['remote']],
                                 cell_type='markdown',
                                 strip_ids=True)
    expected = sources_to_notebook([
        'unmodified',
        [("<" * 7) + ' local\n', 'local\n', ("=" * 7) + '\n', 'remote\n',
         (">" * 7) + ' remote']
    ],
                                   cell_type='markdown',
                                   strip_ids=True)
    merged, decisions = merge_notebooks(base, local, remote)
    assert merged == expected
Esempio n. 54
0
def test_autoresolve_notebook_ec():
    # We need a source here otherwise the cells are not aligned
    source = "def foo(x, y):\n    return x**y"

    base = nbformat.v4.new_notebook()
    base["cells"].append(nbformat.v4.new_code_cell())
    base["cells"][0]["source"] = source
    base["cells"][0]["execution_count"] = 1

    local = copy.deepcopy(base)
    remote = copy.deepcopy(base)
    expected = copy.deepcopy(base)
    local["cells"][0]["execution_count"] = 2
    remote["cells"][0]["execution_count"] = 3
    expected["cells"][0]["execution_count"] = None

    merged, decisions = merge_notebooks(base, local, remote, args)

    assert merged == expected
    assert not any(d.conflict for d in decisions)
Esempio n. 55
0
def test_autoresolve_notebook_ignore_fallback():
    args = builder.parse_args(["", "", ""])
    args.ignore_transients = True
    args.merge_strategy = 'use-remote'

    source = "def foo(x, y):\n    return x**y"
    base = {"cells": [{
        "source": source, "execution_count": 1, "cell_type": "code",
        "outputs": None}]}
    local = {"cells": [{
        "source": source, "execution_count": 2, "cell_type": "code",
        "outputs": None}]}
    remote = {"cells": [{
        "source": source, "execution_count": 3, "cell_type": "code",
        "outputs": None}]}
    merged, decisions = merge_notebooks(base, local, remote, args)
    assert merged == {"cells": [{
        "source": source, "execution_count": None, "outputs": None,
        "cell_type": "code"}]}
    assert not any(d.conflict for d in decisions)
Esempio n. 56
0
def test_autoresolve_notebook_no_ignore():
    args = builder.parse_args(["", "", ""])
    args.ignore_transients = False

    source = "def foo(x, y):\n    return x**y"
    base = {"cells": [{
        "source": source, "execution_count": 1, "cell_type": "code",
        "outputs": None}]}
    local = {"cells": [{
        "source": source, "execution_count": 2, "cell_type": "code",
        "outputs": None}]}
    remote = {"cells": [{
        "source": source, "execution_count": 3, "cell_type": "code",
        "outputs": None}]}
    merged, decisions = merge_notebooks(base, local, remote, args)
    assert merged == {"cells": [{
        "source": source, "execution_count": 1, "outputs": None,
        "cell_type": "code"}]}
    assert decisions[0].conflict is True
    assert len(decisions) == 1
Esempio n. 57
0
def test_autoresolve_notebook_ec():
    # Tests here assume default autoresolve behaviour at time of writing,
    # this may change and tests should then be updated
    args = None

    source = "def foo(x, y):\n    return x**y"
    base = {"cells": [{
        "source": source, "execution_count": 1, "cell_type": "code",
        "outputs": None}]}
    local = {"cells": [{
        "source": source, "execution_count": 2, "cell_type": "code",
        "outputs": None}]}
    remote = {"cells": [{
        "source": source, "execution_count": 3, "cell_type": "code",
        "outputs": None}]}
    merged, decisions = merge_notebooks(base, local, remote, args)
    assert merged == {"cells": [{
        "source": source, "execution_count": None, "outputs": None,
        "cell_type": "code"}]}
    assert not any(d.conflict for d in decisions)
Esempio n. 58
0
def test_autoresolve_notebook_ec():
    # We need a source here otherwise the cells are not aligned
    source = "def foo(x, y):\n    return x**y"

    base = nbformat.v4.new_notebook()
    base["cells"].append(nbformat.v4.new_code_cell())
    base["cells"][0]["source"] = source
    base["cells"][0]["execution_count"] = 1

    local = copy.deepcopy(base)
    remote = copy.deepcopy(base)
    expected = copy.deepcopy(base)
    local["cells"][0]["execution_count"] = 2
    remote["cells"][0]["execution_count"] = 3
    expected["cells"][0]["execution_count"] = None

    merged, decisions = merge_notebooks(base, local, remote, args)

    assert merged == expected
    assert not any(d.conflict for d in decisions)
def test_inline_merge_outputs():
    # One cell with two outputs:
    base = outputs_to_notebook([['unmodified', 'base']])
    local = outputs_to_notebook([['unmodified', 'local']])
    remote = outputs_to_notebook([['unmodified', 'remote']])
    expected = outputs_to_notebook([[
        'unmodified',
        nbformat.v4.new_output(
            output_type='stream', name='stderr',
            text='<<<<<<< local <modified: text/plain>\n'),
        'local',
        nbformat.v4.new_output(
            output_type='stream', name='stderr',
            text='=======\n'),
        'remote',
        nbformat.v4.new_output(
            output_type='stream', name='stderr',
            text='>>>>>>> remote <modified: text/plain>\n'),
    ]])
    merged, decisions = merge_notebooks(base, local, remote)
    assert merged == expected
Esempio n. 60
0
def test_merge_matching_notebooks(matching_nb_triplets, reset_log):
    "Test merge on pairs of notebooks with the same basename in the test suite."
    base, local, remote = matching_nb_triplets
    merged, decisions = merge_notebooks(base, local, remote)