def _make_dummy() -> Tuple[Path, Path]: """Create filter_town and CMakeLists.txt, return the paths.""" filter_town = Path(".").resolve() / "filter_town" rm_rf(filter_town) mkdir_p(filter_town) cmake_lists_txt = filter_town / "CMakeLists.txt" with cmake_lists_txt.open("w") as cml: cml.write(_please_stop) return (filter_town, cmake_lists_txt)
def make_children(parent, next_spec): for key, item in next_spec.items(): this_kid = parent / key if isinstance(item, str): with this_kid.open("w") as f: f.write(item) all_files.append(this_kid) else: # assumed to be dict! mkdir_p(this_kid) all_directories.append(this_kid) make_children(this_kid, item)
def test_mkdir_p(capsys): """Validate that |mkdir_p| creates directories as expected.""" # Relative paths should be ok. hello = Path("hello") rm_rf(hello) # in case previous tests failed, start clean mkdir_p(hello) assert hello.is_dir() # Already exists, but this is ok (real test is that it doesn't fail). hello = hello.resolve() mkdir_p(hello) assert hello.is_dir() # Strings are allowed. mkdir_p("hello") assert hello.is_dir() # Long chains should be allowed. hello_there = hello / "there" hello_there_beautiful = hello_there / "beautiful" hello_there_beautiful_world = hello_there_beautiful / "world" def repeat(): mkdir_p(hello_there_beautiful_world) assert hello.is_dir() assert hello_there.is_dir() assert hello_there_beautiful.is_dir() assert hello_there_beautiful_world.is_dir() repeat() # because repeat() # why repeat() # not? xD # Cleanup hello/there/beautiful/world and create file hello/there to test errors. rm_rf(hello_there) assert hello.is_dir() with hello_there.open("w") as f: f.write("beautiful world\n") assert hello_there.is_file() with pytest.raises(SystemExit): mkdir_p(hello_there) captured = capsys.readouterr() assert captured.out == "" assert "Unable to mkdir_p" in captured.err if platform.system() == "Windows": assert "file already exists" in captured.err else: assert "File exists:" in captured.err # TODO: how to safely engineer permission access errors on all platforms? # Concern: don't eff people over if they ran tests as `root` # Cleanup rm_rf(hello) assert not hello.is_dir()
def test_cd(capsys): """Validate |cd| behaves as expected.""" def wrap_cd(*, src: Union[Path, str], dest: Union[Path, str], create: bool, err_endswith: Optional[str] = None, err_has: Optional[list] = None): """ Test both versions of cd (decorator and context manager). Parameters ---------- src : Path or str The directory to start in. Assumed to be a valid place to cd to. dest : Path or str The directory to test changing to. create : bool Pass-through argument to ``cd``: whether or not to create ``dest``. err_endswith : str or None If this string is provided, then it is assumed that ``cd`` to ``dest`` will cause an error and we should validate that the captured ``stderr`` ends with the value supplied here. err_has : list or None If provided, this list contains strings to check ``x in`` captured ``stderr`` for each ``x in err_has``. """ # NOTE: see cd.__init__ for why we are avoiding resolve() src_path = Path(os.path.abspath(str(Path(src).expanduser()))) dest_path = Path(os.path.abspath(str(Path(dest).expanduser()))) # Double-whammy testing. with cd(src): # Make sure we ended up in src assert str(Path.cwd()) == str(src_path) # Version 1: context manager approach. def context_cd(): with cd(dest, create=create): assert str(Path.cwd()) == str(dest_path) # Version 2: decorator approach. @cd(dest, create=create) def decorated_cd(): assert str(Path.cwd()) == str(dest_path) # Convenience wrapper for checking both succeed or error. def assert_cd(func): if any([err_endswith, err_has]): with pytest.raises(SystemExit): func() captured = capsys.readouterr() assert captured.out == "" if err_endswith: assert captured.err.strip().endswith(err_endswith) if err_has: for err in err_has: assert err in captured.err else: func() # Start clean with each test. Allow existing file tests to fail. if create and dest_path.is_dir(): rm_rf(dest) assert_cd(context_cd) assert str(Path.cwd()) == str( src_path) # Make sure we end up back in src. # Start clean with each test. Allow existing file tests to fail. if create and dest_path.is_dir(): rm_rf(dest) assert_cd(decorated_cd) assert str(Path.cwd()) == str( src_path) # Make sure we end up back in src. starting_cwd = str(Path.cwd()) # Make sure we can navigate to the same place. Because why not? with cd(starting_cwd): assert str(Path.cwd()) == starting_cwd with cd(starting_cwd): assert str(Path.cwd()) == starting_cwd with cd(starting_cwd): assert str(Path.cwd()) == starting_cwd assert str(Path.cwd()) == starting_cwd assert str(Path.cwd()) == starting_cwd assert str(Path.cwd()) == starting_cwd # Make sure we can get to directories that currently exist. wrap_cd(src=".", dest="..", create=False) assert str(Path.cwd()) == starting_cwd wrap_cd(src=".", dest="~", create=False) assert str(Path.cwd()) == starting_cwd # With create=True on something that is a file, error ripples from mkdir_p. supertest = Path(".").resolve() / "supertest" with supertest.open("w") as f: f.write("supertest!\n") err_has = ["Unable to mkdir_p"] if platform.system() == "Windows": err_has.append("file already exists") else: err_has.append("File exists:") wrap_cd(src=".", dest=supertest, create=True, err_has=err_has) rm_rf(supertest) assert str(Path.cwd()) == starting_cwd # When create=False with directory that does not exist we expect a failure. not_a_directory = "not_a_directory" rm_rf(not_a_directory) wrap_cd( src=".", dest=not_a_directory, create=False, err_endswith="not_a_directory' is not a directory, but create=False.") assert not Path(not_a_directory).is_dir() assert str(Path.cwd()) == starting_cwd # Make sure that we can create it as expected. mkdir_p(not_a_directory ) # only here for coverage in wrap_cd (first rm_rf(dest)) wrap_cd(src=".", dest=not_a_directory, create=True) assert Path(not_a_directory).is_dir() rm_rf(not_a_directory) assert str(Path.cwd()) == starting_cwd # v2: multiple directories that don't exist with create=False expects failure. not_a_directory = Path("not") / "a" / "directory" rm_rf("not") wrap_cd(src=".", dest=not_a_directory, create=False, err_endswith="directory' is not a directory, but create=False.") assert not Path("not").is_dir() assert not (Path("not") / "a").is_dir() assert not not_a_directory.is_dir() assert str(Path.cwd()) == starting_cwd # Make sure we can create multiple directories at once. rm_rf("not") wrap_cd(src=".", dest=not_a_directory, create=True) assert Path("not").is_dir() assert (Path("not") / "a").is_dir() assert not_a_directory.is_dir() rm_rf("not") assert str(Path.cwd()) == starting_cwd # Test first failure case in cd.__enter__ where cwd() cannot be found. Maybe there # is an easier way to test this? def uh_uh_uh(*args, **kwargs): raise RuntimeError("You didn't say the magic word!") first = Path(".").resolve() / "first" second = first / "second" third = second / "third" path_cwd = Path.cwd Path.cwd = uh_uh_uh with pytest.raises(SystemExit): with cd(third, create=True): pass # pragma: nocover captured = capsys.readouterr() assert captured.out == "" assert captured.err.strip().endswith( "cd: could not get current working directory: You didn't say the magic word!" ) Path.cwd = path_cwd assert str(Path.cwd()) == starting_cwd # Test second failure case in cd.__enter__ where os.chdir does not succeed. rm_rf(first) os_chdir = os.chdir os.chdir = uh_uh_uh with pytest.raises(SystemExit): with cd(third, create=True): pass # pragma: nocover captured = capsys.readouterr() assert captured.out == "" assert captured.err.strip().endswith( "cd: could not change directories to '" + str(third) + "': You didn't say the magic word!") os.chdir = os_chdir rm_rf(first) assert str(Path.cwd()) == starting_cwd # Test failure case in cd.__exit__ where we cannot return. with pytest.raises(SystemExit): with cd(third, create=True): with cd(second): rm_rf(first) captured = capsys.readouterr() assert captured.out == "" assert "cd: could not return to " + str(third) in captured.err assert str(Path.cwd()) == starting_cwd
def repeat(): mkdir_p(hello_there_beautiful_world) assert hello.is_dir() assert hello_there.is_dir() assert hello_there_beautiful.is_dir() assert hello_there_beautiful_world.is_dir()