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 _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)
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
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)
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
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
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)))
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
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
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
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
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)