def test_add_custom_extension_and_pretend(tmpfolder): args = ["--no-config", "--pretend", EXT_FLAG, "my_project", "-p", "my_package"] # --no-config: avoid extra config from dev's machine interference cli.main(args) assert not Path("my_project/README.md").exists() assert not Path("my_project").exists()
def test_tox(tmpfolder): args = [ "--no-config", "--custom-extension", "pyscaffoldext-some_extension" ] # --no-config: avoid extra config from dev's machine interference cli.main(args) assert Path("pyscaffoldext-some_extension/tox.ini").exists()
def test_main_when_updating(tmpfolder, capsys, git_mock): args = ["my-project"] cli.main(args) args = ["--update", "my-project"] cli.main(args) assert os.path.exists(args[1]) out, _ = capsys.readouterr() assert "Update accomplished!" in out
def test_pre_commit(tmpfolder): args = [ "--no-config", "--custom-extension", "pyscaffoldext-some_extension" ] # --no-config: avoid extra config from dev's machine interference cli.main(args) assert Path( "pyscaffoldext-some_extension/.pre-commit-config.yaml").exists()
def test_no_skeleton(tmpfolder): args = [ "--no-config", "--custom-extension", "pyscaffoldext-some_extension" ] # --no-config: avoid extra config from dev's machine interference cli.main(args) file = "pyscaffoldext-some_extension/src/pyscaffoldext/some_extension/skeleton.py" assert not Path(file).exists()
def test_generated_extension(tmpfolder): args = ["--no-config", "--venv", "--pre-commit", EXT_FLAG, "my_project"] # --no-config: avoid extra config from dev's machine interference # --venv: generate a venv so we can install the resulting project # --pre-commit: ensure generated files respect repository conventions cli.main(args) with chdir("my_project"): # Testing a project generated by the custom extension run_common_tasks()
def test_cli_with_save_config_and_pretend(default_file, tmpfolder): # Given a global config file does not exist assert not default_file.exists() # when the CLI is invoked with --save-config and --pretend cli.main("proj --pretend -l MPL-2.0 --namespace ns --cirrus --save-config". split()) # then the file should not be created assert not default_file.exists() # (or even the project) assert not (tmpfolder / "proj").exists()
def test_project_with_args(tmpdir): # noqa old_args = ["my_project", "-u", "http://www.blue-yonder.com/", "-d", "my description"] cli.main(old_args) args = ["my_project", "-u", "http://www.google.com/", "-d", "other description"] opts = cli.parse_args(args) new_opts = info.project(opts) assert new_opts['url'] == "http://www.blue-yonder.com/" assert new_opts['package'] == "my_project" assert new_opts['description'] == "my description"
def test_entry_point(tmpfolder): args = ["--no-config", "--custom-extension", "pyscaffoldext-some_extension"] # --no-config: avoid extra config from dev's machine interference cli.main(args) assert Path("pyscaffoldext-some_extension/setup.cfg").exists() setup_cfg = ConfigUpdater() setup_cfg.read_string(Path("pyscaffoldext-some_extension/setup.cfg").read_text()) entry_point = setup_cfg.get("options.entry_points", "pyscaffold.cli").value expected = "\nsome_extension = pyscaffoldext.some_extension.extension:SomeExtension" assert entry_point == expected
def test_add_custom_extension(tmpfolder): args = [ "pyscaffoldext-my_project", "--no-config", # <- Avoid extra config from dev's machine interference "--custom-extension", "--package", "my_extension", ] cli.main(args) extension = "pyscaffoldext-my_project/src/pyscaffoldext/my_extension/extension.py" assert Path(extension).exists()
def test_cli_with_venv_and_pretend(tmpfolder): proj_path = Path(tmpfolder) / "proj" venv_path = proj_path / ".venv" # Given the venv does not exist yet assert not venv_path.exists() # when the CLI is invoked with --venv, --venv-install and --pretend cli.main( ["proj", "--pretend", "--venv", "--venv-install", "pytest>=6.0.0"]) # then the venv will not be created, or even the project itself assert not venv_path.exists() assert not proj_path.exists()
def test_add_custom_extension_with_namespace(tmpfolder): # We expect the second namespace to be just ignored args = [ "--no-config", # <- Avoid extra config from dev's machine interference "--namespace", "test", "--custom-extension", "pyscaffoldext-some_extension", ] with pytest.raises(NamespaceError): cli.main(args)
def test_add_custom_extension_and_pretend(tmpfolder): args = [ "pyscaffoldext-my_project", "--no-config", # <- Avoid extra config from dev's machine interference "--pretend", "--custom-extension", "--package", "my_extension", ] cli.main(args) assert not Path("pyscaffoldext-my_project").exists()
def test_add_custom_extension(tmpfolder): args = ["--no-config", "-vv", EXT_FLAG, "my_project", "-p", "my_package"] # --no-config: avoid extra config from dev's machine interference cli.main(args) with chdir("my_project"): assert not Path("README.rst").exists() for path in EXPECTED_DIRS: assert Path(path).is_dir() for path in EXPECTED_FILES: assert Path(path).is_file()
def test_project_without_args(tmpfolder): old_args = ["my_project", "-u", "http://www.blue-yonder.com/", "-d", "my description"] cli.main(old_args) args = ["my_project"] opts = cli.parse_args(args) new_opts = info.project(opts) assert new_opts['url'] == "http://www.blue-yonder.com/" assert new_opts['package'] == "my_project" assert new_opts['license'] == "mit" assert new_opts['description'] == "my description"
def test_cli_with_venv(tmpfolder): venv_path = Path(tmpfolder) / "proj/.venv" # Given the venv does not exist yet assert not venv_path.exists() # when the CLI is invoked with --venv and --venv-install cli.main(["proj", "--venv", "--venv-install", "pytest>=6.0.0"]) # then the venv will be created accordingly assert venv_path.is_dir() # with python, pip and the installed executables assert list(venv_path.glob("*/python*")) assert list(venv_path.glob("*/pip*")) assert list(venv_path.glob("*/pytest*"))
def test_cli_with_save_config(default_file, tmpfolder): # Given a global config file does not exist assert not default_file.exists() # when the CLI is invoked with --save-config cli.main("proj -l MPL-2.0 --namespace ns --cirrus --save-config".split()) # then the file will be created accordingly assert default_file.exists() parsed = info.read_setupcfg(default_file).to_dict() assert parsed["metadata"]["license"] == "MPL-2.0" assert parsed["pyscaffold"]["namespace"] == "ns" assert "cirrus" in parsed["pyscaffold"]["extensions"] # and since the config extension has persist = False, it will not be stored assert "config" not in parsed["pyscaffold"]["extensions"]
def test_generated_extension_without_prefix(tmpfolder, caplog): caplog.set_level(logging.WARNING) # Ensure prefix is added by default args = ["--no-config", "--custom-extension", "some_extension"] # --no-config: avoid extra config from dev's machine interference cli.main(args) assert Path("pyscaffoldext-some_extension").exists() # Ensure an explanation on how to use # `--force` to avoid preffixing is given logs = caplog.text assert "--force" in logs
def test_main_with_list_actions(capsys, isolated_logger): # When putup is called with --list-actions, args = ["my-project", "--tox", "--list-actions"] cli.main(args) # then the action list should be printed, out, _ = capsys.readouterr() assert "Planned Actions" in out assert "pyscaffold.api:get_default_options" in out assert "pyscaffold.structure:define_structure" in out assert "pyscaffold.extensions.tox:add_files" in out assert "pyscaffold.structure:create_structure" in out assert "pyscaffold.api:init_git" in out # but no project should be created assert not os.path.exists(args[0])
def test_add_install_requires(tmpfolder): args = [ "--no-config", "--custom-extension", "pyscaffoldext-some_extension" ] # --no-config: avoid extra config from dev's machine interference cli.main(args) assert Path("pyscaffoldext-some_extension/setup.cfg").exists() setup_cfg = ConfigUpdater() setup_cfg.read_string( Path("pyscaffoldext-some_extension/setup.cfg").read_text()) install_requires = setup_cfg.get("options", "install_requires").value assert "pyscaffold" in install_requires
def test_verbose_main(tmpfolder, git_mock, caplog): args = ["my-project", "--verbose"] cli.main(args) assert os.path.exists(args[0]) # Check for some log messages assert find_report(caplog, "invoke", "get_default_options") assert find_report(caplog, "invoke", "verify_options_consistency") assert find_report(caplog, "invoke", "define_structure") assert find_report(caplog, "invoke", "create_structure") assert find_report(caplog, "create", "setup.py") assert find_report(caplog, "create", lp("my_project/__init__.py")) assert find_report(caplog, "run", "git init") assert find_report(caplog, "run", "git add")
def test_files(tmpfolder): args = [ "--no-config", "--custom-extension", "pyscaffoldext-some_extension" ] # --no-config: avoid extra config from dev's machine interference cli.main(args) files = ( "README.rst", "CONTRIBUTING.rst", ".pre-commit-config.yaml", ".github/workflows/publish-package.yml", ) for file in files: assert Path("pyscaffoldext-some_extension", file).exists()
def test_wrong_extension(monkeypatch, tmpfolder): # Given an entry point with some problems is registered in the pyscaffold.cli group # (e.g. failing implementation, wrong dependencies that cause the python file to # fail to evaluate) fake = EntryPoint("fake", "pyscaffoldext.SOOO__fake__:Fake", "pyscaffold.cli") entry_points_mock = Mock(return_value={"pyscaffold.cli": [fake]}) monkeypatch.setattr("pyscaffold.extensions.entry_points", entry_points_mock) with pytest.raises(ErrorLoadingExtension, match=r".*error loading.*fake.*"): # When putup is called with the corresponding flag args = ["my-project"] cli.main(args) entry_points_mock.assert_called()
def test_verbose_main(tmpfolder, git_mock, caplog): args = ["my-project", "--verbose"] cli.main(args) assert os.path.exists(args[0]) # Check for some log messages assert find_report(caplog, 'invoke', 'get_default_options') assert find_report(caplog, 'invoke', 'verify_options_consistency') assert find_report(caplog, 'invoke', 'define_structure') assert find_report(caplog, 'invoke', 'create_structure') assert find_report(caplog, 'create', 'setup.py') assert find_report(caplog, 'create', 'requirements.txt') assert find_report(caplog, 'create', 'my_project/__init__.py') assert find_report(caplog, 'run', 'git init') assert find_report(caplog, 'run', 'git add')
def test_verbose_main(tmpfolder, git_mock, caplog): args = ["my-project", "--verbose"] cli.main(args) assert os.path.exists(args[0]) # Check for some log messages assert find_report(caplog, 'invoke', 'get_default_options') assert find_report(caplog, 'invoke', 'verify_options_consistency') assert find_report(caplog, 'invoke', 'define_structure') assert find_report(caplog, 'invoke', 'create_structure') assert find_report(caplog, 'create', 'setup.py') assert find_report(caplog, 'create', 'requirements.txt') assert find_report(caplog, 'create', lp('my_project/__init__.py')) assert find_report(caplog, 'run', 'git init') assert find_report(caplog, 'run', 'git add')
def test_project_without_args(tmpfolder): old_args = [ "my_project", "-u", "http://www.blue-yonder.com/", "-d", "my description", ] cli.main(old_args) args = ["my_project"] opts = cli.parse_args(args) new_opts = info.project(opts) assert new_opts["url"] == "http://www.blue-yonder.com/" assert new_opts["package"] == "my_project" assert new_opts["license"] == "MIT" assert new_opts["description"] == "my description"
def test_pretend_main(tmpfolder, git_mock, caplog): for flag in ["--pretend", "-P"]: args = ["my-project", flag] cli.main(args) assert not os.path.exists(args[0]) # Check for some log messages assert find_report(caplog, "invoke", "get_default_options") assert find_report(caplog, "invoke", "verify_options_consistency") assert find_report(caplog, "invoke", "define_structure") assert find_report(caplog, "invoke", "create_structure") assert find_report(caplog, "create", "setup.py") assert find_report(caplog, "create", "requirements.txt") assert find_report(caplog, "create", lp("my_project/__init__.py")) assert find_report(caplog, "run", "git init") assert find_report(caplog, "run", "git add")
def test_project_with_args(tmpfolder): old_args = [ "my_project", "-u", "http://www.blue-yonder.com/", "-d", "my description", ] cli.main(old_args) args = [ "my_project", "-u", "http://www.google.com/", "-d", "other description" ] opts = cli.parse_args(args) opts = cli.process_opts(opts) new_opts = info.project(opts) assert new_opts["url"] == "http://www.google.com/" assert new_opts["package"] == "my_project" assert new_opts["description"] == "other description"
def test_cli_with_markdown_and_update(tmpfolder): # Given a project exists with the markdown extension opts = dict( project_path="proj", package="pkg", version=pyscaffold_version, extensions=[Markdown()], config_files=api.NO_CONFIG, ) api.create_project(opts) # when the project is updated args = ["--no-config", "--update", "proj"] cli.main(args) # then markdown files should still exist, and not rst equivalent should be created for file in CONV_FILES: assert (tmpfolder / f"proj/{file}.md").exists() assert not (tmpfolder / f"proj/{file}.rst").exists()
def test_generated_extension(tmpfolder): args = [ "--no-config", # <- avoid extra config from dev's machine interference "--venv", # <- generate a venv that we will use to install the project "--custom-extension", "pyscaffoldext-some_extension", ] cli.main(args) with chdir("pyscaffoldext-some_extension"): try: run_common_tasks() except CalledProcessError as ex: if os.name == "nt" and "too long" in ex.output: pytest.skip("Windows really have a problem with long paths....") else: raise putup = shell.get_executable("putup", prefix=".venv", include_path=False) assert putup run(putup, "--some-extension", "the_actual_project") assert Path("the_actual_project/setup.cfg").exists()
def test_main_with_old_setuptools(old_setuptools_mock): args = ["my-project"] with pytest.raises(OldSetuptools): cli.main(args)
def test_main_with_license(tmpdir, git_mock): # noqa args = ["my-project", "-l", "new-bsd"] cli.main(args) assert os.path.exists(args[0])
def test_main_when_updating_with_wrong_setup(tmpdir, git_mock): # noqa os.mkdir("my_project") open("my_project/setup.py", "a").close() args = ["--update", "my_project"] with pytest.raises(RuntimeError): cli.main(args)
def test_main_when_updating_project_doesnt_exist(tmpdir, git_mock): # noqa args = ["--update", "my_project"] with pytest.raises(RuntimeError): cli.main(args)
def test_main_when_updating(tmpdir, git_mock): # noqa args = ["my-project"] cli.main(args) args = ["--update", "my-project"] cli.main(args) assert os.path.exists(args[1])
def test_main(tmpdir, git_mock): # noqa args = ["my-project"] cli.main(args) assert os.path.exists(args[0])
def test_main_when_folder_exists(tmpdir, git_mock): # noqa args = ["my-project"] os.mkdir(args[0]) with pytest.raises(RuntimeError): cli.main(args)
def test_main_with_git_not_configured(noconfgit_mock): # noqa args = ["my-project"] with pytest.raises(RuntimeError): cli.main(args)
def test_main_with_nogit(nogit_mock): # noqa args = ["my-project"] with pytest.raises(RuntimeError): cli.main(args)