Esempio n. 1
0
def test_autoresolve_empty_strategies():
    """Check that a autoresolve works with empty strategies"""
    expected_partial_source = [["base\n", "some other\n", "lines\n", "to align\n"]]
    expected_partial_metadata = [{'myval': 'base'}]
    expected_partial_outputs = [["base\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 = [
        {
            'action': 'base',
            'common_path': ('cells', 0, 'source'),
            'conflict': True,
            'local_diff': [{'key': 0, 'op': 'addrange', 'valuelist': ['local\n']},
                           {'key': 0, 'length': 1, 'op': 'removerange'}],
            'remote_diff': [{'key': 0, 'op': 'addrange', 'valuelist': ['remote\n']},
                            {'key': 0, 'length': 1, 'op': 'removerange'}]
        },
        {
            'action': 'base',
            'common_path': ('cells', 0, 'outputs', 0, 'data', 'text/plain'),
            'conflict': True,
            'local_diff': [{'key': 0, 'op': 'addrange', 'valuelist': ['local\n']},
                           {'key': 0, 'length': 1, 'op': 'removerange'}],
            'remote_diff': [{'key': 0, 'op': 'addrange', 'valuelist': ['remote\n']},
                            {'key': 0, 'length': 1, 'op': 'removerange'}]
        },
        {
            'action': 'base',
            'common_path': ('cells', 0, 'metadata', 'myval'),
            'conflict': True,
            'local_diff': [{'key': 0, 'op': 'addrange', 'valuelist': ['local']},
                           {'key': 0, 'length': 1, 'op': 'removerange'}],
            'remote_diff': [{'key': 0, 'op': 'addrange', 'valuelist': ['remote']},
                            {'key': 0, 'length': 1, 'op': 'removerange'}]
        }
    ]

    # Since we cannot pass directly a strategies object, include copy of relevant code:
    local_diffs = diff_notebooks(base, local)
    remote_diffs = diff_notebooks(base, remote)

    strategies = Strategies()
    decisions = decide_merge_with_diff(
        base, local, remote,
        local_diffs, remote_diffs,
        strategies)

    partial = apply_decisions(base, decisions)

    _check(partial, expected_partial, decisions, expected_conflicts)
def test_autoresolve_empty_strategies():
    """Check that a autoresolve works with empty strategies"""
    expected_partial_source = [["base\n", "some other\n", "lines\n", "to align\n"]]
    expected_partial_metadata = [{'myval': 'base'}]
    expected_partial_outputs = [["base\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 = [
        {
            'action': 'base',
            'common_path': ('cells', 0, 'source'),
            'conflict': True,
            'local_diff': [{'key': 0, 'op': 'addrange', 'valuelist': ['local\n']},
                           {'key': 0, 'length': 1, 'op': 'removerange'}],
            'remote_diff': [{'key': 0, 'op': 'addrange', 'valuelist': ['remote\n']},
                            {'key': 0, 'length': 1, 'op': 'removerange'}]
        },
        {
            'action': 'base',
            'common_path': ('cells', 0, 'outputs', 0, 'data', 'text/plain'),
            'conflict': True,
            'local_diff': [{'key': 0, 'op': 'addrange', 'valuelist': ['local\n']},
                           {'key': 0, 'length': 1, 'op': 'removerange'}],
            'remote_diff': [{'key': 0, 'op': 'addrange', 'valuelist': ['remote\n']},
                            {'key': 0, 'length': 1, 'op': 'removerange'}]
        },
        {
            'action': 'base',
            'common_path': ('cells', 0, 'metadata', 'myval'),
            'conflict': True,
            'local_diff': [{'key': 0, 'op': 'addrange', 'valuelist': ['local']},
                           {'key': 0, 'length': 1, 'op': 'removerange'}],
            'remote_diff': [{'key': 0, 'op': 'addrange', 'valuelist': ['remote']},
                            {'key': 0, 'length': 1, 'op': 'removerange'}]
        }
    ]

    # Since we cannot pass directly a strategies object, include copy of relevant code:
    local_diffs = diff_notebooks(base, local)
    remote_diffs = diff_notebooks(base, remote)

    strategies = Strategies()
    decisions = decide_merge_with_diff(
        base, local, remote,
        local_diffs, remote_diffs,
        strategies)

    partial = apply_decisions(base, decisions)

    _check(partial, expected_partial, decisions, expected_conflicts)
Esempio n. 3
0
def _handle_agreed_deletion(base_fn, output_fn, args=None):
    """Handle merge when file has been deleted both locally and remotely"""
    assert base_fn != EXPLICIT_MISSING_FILE, (
        "sanity check failed: cannot have agreed decision on base %r" %
        base_fn)
    b = read_package_json(base_fn)
    if args and args.decisions:
        # Print merge decision (delete all)
        from nbdime.diffing.notebooks import diff_notebooks
        from nbdime.merging.decisions import MergeDecisionBuilder

        # Build diff for deleting all content:
        diff = diff_notebooks(b, {})
        # Make agreed decision from diff:
        bld = MergeDecisionBuilder()
        bld.agreement([], local_diff=diff, remote_diff=diff)
        decisions = bld.validated(b)
        # Print decition
        config = prettyprint_config_from_args(args, out=io.StringIO())
        pretty_print_merge_decisions(b, decisions, config=config)
        logger.warning("Decisions:\n%s", config.out.getvalue())

    elif output_fn:
        # Delete file if existing, if not do nothing
        if os.path.exists(output_fn):
            os.remove(output_fn)
            logger.info("Output file deleted: %s", output_fn)
Esempio n. 4
0
def main_diff(args):
    afn = args.base
    bfn = args.remote
    dfn = args.output

    for fn in (afn, bfn):
        if not os.path.exists(fn):
            print("Missing file {}".format(fn))
            return 1

    a = nbformat.read(afn, as_version=4)
    b = nbformat.read(bfn, as_version=4)

    d = diff_notebooks(a, b)

    if dfn:
        with io.open(dfn, "w", encoding="utf8") as df:
            # Compact version:
            # json.dump(d, df)
            # Verbose version:
            json.dump(d, df, indent=2, separators=(",", ": "))
    else:
        # This printer is to keep the unit tests passing,
        # some tests capture output with capsys which doesn't
        # pick up on sys.stdout.write()
        class Printer:
            def write(self, text):
                print(text, end="")

        pretty_print_notebook_diff(afn, bfn, a, d, Printer())

    return 0
Esempio n. 5
0
def handle_agreed_deletion(base_fn, output_fn, print_decisions=False):
    """Handle merge when file has been deleted both locally and remotely"""
    assert base_fn != EXPLICIT_MISSING_FILE, (
        'sanity check failed: cannot have agreed decision on base %r' %
        base_fn)
    b = read_notebook(base_fn, on_null='minimal')
    if print_decisions:
        # Print merge decision (delete all)
        from nbdime.diffing.notebooks import diff_notebooks
        from nbdime.merging.decisions import MergeDecisionBuilder
        # Build diff for deleting all content:
        diff = diff_notebooks(b, {})
        # Make agreed decision from diff:
        bld = MergeDecisionBuilder()
        bld.agreement([], local_diff=diff, remote_diff=diff)
        decisions = bld.validated(b)
        # Print decition
        config = PrettyPrintConfig(out=io.StringIO())
        pretty_print_merge_decisions(b, decisions, config=config)
        nbdime.log.warning("Decisions:\n%s", out.getvalue())

    elif output_fn:
        # Delete file if existing, if not do nothing
        if os.path.exists(output_fn):
            os.remove(output_fn)
            nbdime.log.info("Output file deleted: %s", output_fn)
Esempio n. 6
0
def main_diff(args):
    afn = args.base
    bfn = args.remote
    dfn = args.output

    for fn in (afn, bfn):
        if not os.path.exists(fn):
            print("Missing file {}".format(fn))
            return 1

    a = nbformat.read(afn, as_version=4)
    b = nbformat.read(bfn, as_version=4)

    d = diff_notebooks(a, b)

    if dfn:
        with io.open(dfn, "w", encoding="utf8") as df:
            # Compact version:
            #json.dump(d, df)
            # Verbose version:
            json.dump(d, df, indent=2, separators=(",", ": "))
    else:
        # This printer is to keep the unit tests passing,
        # some tests capture output with capsys which doesn't
        # pick up on sys.stdout.write()
        class Printer:
            def write(self, text):
                print(text, end="")

        pretty_print_notebook_diff(afn, bfn, a, d, Printer())

    return 0
Esempio n. 7
0
def handle_agreed_deletion(base_fn, output_fn, print_decisions=False):
    """Handle merge when file has been deleted both locally and remotely"""
    assert base_fn != EXPLICIT_MISSING_FILE, (
        'sanity check failed: cannot have agreed decision on base %r' % base_fn)
    b = read_notebook(base_fn, on_null='minimal')
    if print_decisions:
        # Print merge decision (delete all)
        from nbdime.diffing.notebooks import diff_notebooks
        from nbdime.merging.decisions import MergeDecisionBuilder
        # Build diff for deleting all content:
        diff = diff_notebooks(b, {})
        # Make agreed decision from diff:
        bld = MergeDecisionBuilder()
        bld.agreement([], local_diff=diff, remote_diff=diff)
        decisions = bld.validated(b)
        # Print decition
        config = PrettyPrintConfig(out=io.StringIO())
        pretty_print_merge_decisions(b, decisions, config=config)
        nbdime.log.warning("Decisions:\n%s", out.getvalue())

    elif output_fn:
        # Delete file if existing, if not do nothing
        if os.path.exists(output_fn):
            os.remove(output_fn)
            nbdime.log.info("Output file deleted: %s", output_fn)
Esempio n. 8
0
def check_set(PATH, BUILDER):
    if sys.version_info.major == 2:
        GENERATED_IPYNB_FILES = python27_glob(
            PATH + "/_build/" + BUILDER + "/", "*.ipynb")
        GENERATED_IPYNB_FILES = [
            fl for fl in GENERATED_IPYNB_FILES if "/executed/" not in fl
        ]  #Only compare Generated Versions (not Executed)
        ref_files = python27_glob(PATH + "/ipynb/", "*.ipynb")
        REFERENCE_IPYNB_FILES = [fl.split("ipynb/")[-1] for fl in ref_files]
    else:
        GENERATED_IPYNB_FILES = glob.glob(PATH + "/_build/" + BUILDER +
                                          "/**/*.ipynb",
                                          recursive=True)
        GENERATED_IPYNB_FILES = [
            fl for fl in GENERATED_IPYNB_FILES if "/executed/" not in fl
        ]  #Only compare Generated Versions (not Executed)
        ref_files = glob.glob(PATH + "/ipynb/**/*.ipynb", recursive=True)
        REFERENCE_IPYNB_FILES = [fl.split("ipynb/")[-1] for fl in ref_files]
    failed = 0
    for fl in GENERATED_IPYNB_FILES:
        flname = fl.split(BUILDER + "/")[-1]
        #Check for Sphinx Version Specific Excludes
        SKIP = False
        if SPHINX_VERSION[0] in SPHINX_VERSION_EXCLUDE.keys():
            exclude_patterns = SPHINX_VERSION_EXCLUDE[SPHINX_VERSION[0]]
            for pattern in exclude_patterns:
                pattern = re.compile(pattern)
                if pattern.search(flname):
                    print(
                        "Excluding: {} (due to SPHINX_VERSION_EXCLUDE)".format(
                            fl))
                    SKIP = True
        if SKIP:
            continue
        else:
            print("Testing {} ...".format(fl))
            if flname not in REFERENCE_IPYNB_FILES:
                print("[FAIL] Notebook {} has no matching test case in ipynb/".
                      format(flname))
                failed += 1
                continue
            nb1 = nbformat.read(fl, NB_VERSION)
            nb2 = nbformat.read(os.path.join(PATH + "/ipynb", flname),
                                NB_VERSION)
            diff = diff_notebooks(nb1, nb2)
            if len(diff) != 0:
                print("[FAIL] {} and {} are different:".format(
                    fl, os.path.join("ipynb", flname)))
                print(diff)
                failed += 1
    return failed
Esempio n. 9
0
 def _check_nbs(obtained_filename, expected_filename):
     obtained_nb = nbf.read(str(obtained_filename), nbf.NO_CONVERT)
     expect_nb = nbf.read(str(expected_filename), nbf.NO_CONVERT)
     for cell in expect_nb.cells:
         empty_non_deterministic_outputs(cell)
     for cell in obtained_nb.cells:
         empty_non_deterministic_outputs(cell)
     diff = diff_notebooks(obtained_nb, expect_nb)
     filename_without_path = str(
         expected_filename)[str(expected_filename).rfind("/") + 1:]
     if diff:
         raise AssertionError(
             pretty_print_diff(obtained_nb, diff,
                               str(filename_without_path)))
Esempio n. 10
0
def _handle_diff(base, remote, output, args):
    """Handles diffs of files, either as filenames or file-like objects"""
    # Check that if args are filenames they either exist, or are
    # explicitly marked as missing (added/removed):
    for fn in (base, remote):
        if (isinstance(fn, string_types) and not os.path.exists(fn)
                and fn != EXPLICIT_MISSING_FILE):
            print("Missing file {}".format(fn))
            return 1
    # Both files cannot be missing
    assert not (base == EXPLICIT_MISSING_FILE and remote
                == EXPLICIT_MISSING_FILE), ('cannot diff %r against %r' %
                                            (base, remote))

    # Perform actual work:
    a = read_notebook(base, on_null='empty')
    b = read_notebook(remote, on_null='empty')

    d = diff_notebooks(a, b)

    # Output as JSON to file, or print to stdout:
    if output:
        with open(output, "w") as df:
            # Compact version:
            #json.dump(d, df)
            # Verbose version:
            json.dump(d, df, indent=2, separators=(",", ": "))
    else:
        # This printer is to keep the unit tests passing,
        # some tests capture output with capsys which doesn't
        # pick up on sys.stdout.write()
        class Printer:
            def write(self, text):
                print(text, end="")

        # This sets up what to ignore:
        config = PrettyPrintConfig(out=Printer(),
                                   include=args,
                                   color_words=args.color_words)
        # Separate out filenames:
        base_name = base if isinstance(base, string_types) else base.name
        remote_name = remote if isinstance(remote,
                                           string_types) else remote.name
        pretty_print_notebook_diff(base_name, remote_name, a, d, config)

    return 0
Esempio n. 11
0
def _handle_diff(base, remote, output, args):
    """Handles diffs of files, either as filenames or file-like objects"""
    # Check that if args are filenames they either exist, or are
    # explicitly marked as missing (added/removed):
    for fn in (base, remote):
        if (isinstance(fn, string_types) and not os.path.exists(fn) and
                fn != EXPLICIT_MISSING_FILE):
            print("Missing file {}".format(fn))
            return 1
    # Both files cannot be missing
    assert not (base == EXPLICIT_MISSING_FILE and remote == EXPLICIT_MISSING_FILE), (
        'cannot diff %r against %r' % (base, remote))

    # Perform actual work:
    a = read_notebook(base, on_null='empty')
    b = read_notebook(remote, on_null='empty')

    d = diff_notebooks(a, b)

    # Output as JSON to file, or print to stdout:
    if output:
        with open(output, "w") as df:
            # Compact version:
            #json.dump(d, df)
            # Verbose version:
            json.dump(d, df, indent=2, separators=(",", ": "))
    else:
        # This printer is to keep the unit tests passing,
        # some tests capture output with capsys which doesn't
        # pick up on sys.stdout.write()
        class Printer:
            def write(self, text):
                print(text, end="")
        # This sets up what to ignore:
        config = PrettyPrintConfig(out=Printer(), include=args, color_words=args.color_words)
        # Separate out filenames:
        base_name = base if isinstance(base, string_types) else base.name
        remote_name = remote if isinstance(remote, string_types) else remote.name
        pretty_print_notebook_diff(base_name, remote_name, a, d, config)

    return 0
Esempio n. 12
0
def main_diff(args):
    # Get input notebooks:
    afn = args.base
    bfn = args.remote
    dfn = args.out

    process_diff_args(args)

    for fn in (afn, bfn):
        if not os.path.exists(fn) and fn != EXPLICIT_MISSING_FILE:
            print("Missing file {}".format(fn))
            return 1
    # Both files cannot be missing
    assert not (afn == EXPLICIT_MISSING_FILE and bfn == EXPLICIT_MISSING_FILE)

    a = read_notebook(afn, on_null='empty')
    b = read_notebook(bfn, on_null='empty')

    # Perform actual diff:
    d = diff_notebooks(a, b)

    # Output diff:
    if dfn:
        with open(dfn, "w") as df:
            # Compact version:
            #json.dump(d, df)
            # Verbose version:
            json.dump(d, df, indent=2, separators=(",", ": "))
    else:
        # This printer is to keep the unit tests passing,
        # some tests capture output with capsys which doesn't
        # pick up on sys.stdout.write()
        class Printer:
            def write(self, text):
                print(text, end="")

        pretty_print_notebook_diff(afn, bfn, a, d, Printer())

    return 0
def check_set(PATH):
    GENERATED_IPYNB_FILES = glob.glob(PATH + "/_build/jupyter/*.ipynb")
    REFERENCE_IPYNB_FILES = [
        os.path.basename(fl) for fl in glob.glob(PATH + "/ipynb/*.ipynb")
    ]
    failed = 0
    for fl in GENERATED_IPYNB_FILES:
        flname = fl.split("/")[-1]
        #Check for Sphinx Version Specific Excludes
        SKIP = False
        if SPHINX_VERSION[0] in SPHINX_VERSION_EXCLUDE.keys():
            exclude_patterns = SPHINX_VERSION_EXCLUDE[SPHINX_VERSION[0]]
            for pattern in exclude_patterns:
                pattern = re.compile(pattern)
                if pattern.search(flname):
                    print(
                        "Excluding: {} (due to SPHINX_VERSION_EXCLUDE)".format(
                            fl))
                    SKIP = True
        if SKIP:
            continue
        else:
            print("Testing {} ...".format(fl))
            if flname not in REFERENCE_IPYNB_FILES:
                print("[FAIL] Notebook {} has no matching test case in ipynb/".
                      format(flname))
                failed += 1
                continue
            nb1 = nbformat.read(fl, NB_VERSION)
            nb2 = nbformat.read(os.path.join(PATH + "/ipynb", flname),
                                NB_VERSION)
            diff = diff_notebooks(nb1, nb2)
            if len(diff) != 0:
                print("[FAIL] {} and {} are different:".format(
                    fl, os.path.join("ipynb", flname)))
                print(diff)
                failed += 1
    return failed
Esempio n. 14
0
def check_set(PATH):
    GENERATED_IPYNB_FILES = glob.glob(PATH + "/_build/jupyter/*.ipynb")
    REFERENCE_IPYNB_FILES = [
        os.path.basename(fl) for fl in glob.glob(PATH + "/ipynb/*.ipynb")
    ]
    failed = 0
    for fl in GENERATED_IPYNB_FILES:
        flname = fl.split("/")[-1]
        print("Testing {} ...".format(fl))
        if flname not in REFERENCE_IPYNB_FILES:
            print("[FAIL] Notebook {} has no matching test case in ipynb/".
                  format(flname))
            failed += 1
            continue
        nb1 = nbformat.read(fl, NB_VERSION)
        nb2 = nbformat.read(os.path.join(PATH + "/ipynb", flname), NB_VERSION)
        diff = diff_notebooks(nb1, nb2)
        if len(diff) != 0:
            print("[FAIL] {} and {} are different:".format(
                fl, os.path.join("ipynb", flname)))
            print(diff)
            failed += 1
    return failed
Esempio n. 15
0
NB_VERSION = 4
GENERATED_IPYNB_FILES = glob.glob("_build/jupyter/*.ipynb")
REFERENCE_IPYNB_FILES = [
    os.path.basename(fl) for fl in glob.glob("ipynb/*.ipynb")
]
SKIP = ["index.ipynb"]

#-Diff Configuration-#
set_notebook_diff_targets(metadata=False)

for fl in GENERATED_IPYNB_FILES:
    flname = fl.split("/")[-1]
    if flname in SKIP:
        continue
    print("Testing {} ...".format(fl))
    if flname not in REFERENCE_IPYNB_FILES:
        print("[FAIL] Notebook {} has no matching test case in ipynb/".format(
            flname))
        exit(1)
    nb1 = nbformat.read(fl, NB_VERSION)
    nb2 = nbformat.read(os.path.join("ipynb", flname), NB_VERSION)
    diff = diff_notebooks(nb1, nb2)
    if len(diff) != 0:
        print("[FAIL] {} and {} are different:".format(
            fl, os.path.join("ipynb", flname)))
        print(diff)
        exit(1)

exit(0)