File size: 7,279 Bytes
0ad74ed |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
import shutil
import textwrap
from pathlib import Path
import pytest
from gradio.cli.commands.components.build import _build
from gradio.cli.commands.components.create import _create, _create_utils
from gradio.cli.commands.components.install_component import _get_executable_path
from gradio.cli.commands.components.publish import _get_version_from_file
from gradio.cli.commands.components.show import _show
from gradio.utils import core_gradio_components
core = [
c.__name__
for c in core_gradio_components()
if not getattr(c, "is_template", False)
and c.__name__ not in ["Tab", "Form", "FormComponent"]
]
@pytest.mark.parametrize(
"template",
core,
)
def test_template_override_component(template, tmp_path):
"""When you add a new component this test will likely fail locally
because the js files have not been moved to the _frontend_code directory.
Just build the python package (python -m build -w) to move the latest state of the js directory to _frontend_code.
"""
_create(
"MyComponent",
tmp_path,
template=template,
overwrite=True,
install=False,
configure_metadata=False,
)
app = (tmp_path / "demo" / "app.py").read_text()
component_files = _create_utils._get_component_code(template)
answer = textwrap.dedent(
f"""
import gradio as gr
from gradio_mycomponent import MyComponent
{component_files.demo_code.format(name="MyComponent")}
if __name__ == "__main__":
demo.launch()
"""
)
assert app.strip() == answer.strip()
assert (tmp_path / "backend" / "gradio_mycomponent" / "mycomponent.py").exists()
source_code = (
tmp_path / "backend" / "gradio_mycomponent" / "mycomponent.py"
).read_text()
assert "@document()" not in source_code
def test_get_executable_path():
assert _get_executable_path(
"pip", None, "--pip-path", check_3=True
) == shutil.which("pip3")
assert _get_executable_path("pip", None, "--pip-path") == shutil.which("pip")
assert _get_executable_path(
"pip", shutil.which("pip"), "--pip-path"
) == shutil.which("pip")
assert _get_executable_path(
"gradio", None, "--pip-path", check_3=True
) == shutil.which("gradio")
with pytest.raises(
ValueError,
match=r"Could not find foo. Please ensure it is installed and in your PATH or pass the --foo-path parameter.",
):
_get_executable_path("foo", None, "--foo-path")
with pytest.raises(
ValueError,
match=r"The provided foo path \(/foo/bar/fum\) does not exist or is not a file.",
):
_get_executable_path("foo", "/foo/bar/fum", "--foo-path")
def test_raise_error_component_template_does_not_exist(tmp_path):
with pytest.raises(
ValueError,
match="Cannot find NonExistentComponent in gradio.components, gradio.layouts, or gradio._simple_templates",
):
_create(
"MyComponent",
tmp_path,
template="NonExistentComponent",
overwrite=True,
install=False,
configure_metadata=False,
)
def test_do_not_replace_class_name_in_import_statement(tmp_path):
_create(
"MyImage",
template="Image",
directory=tmp_path,
overwrite=True,
install=False,
configure_metadata=False,
)
code = (tmp_path / "backend" / "gradio_myimage" / "myimage.py").read_text()
assert "import PIL.Image" in code
assert "class MyImage" in code
assert "PIL.Image.Image" in code
def test_raises_if_directory_exists(tmp_path):
with pytest.raises(
Exception
): # Keeping it a general exception since the specific exception seems to differ between operating systems
_create("MyComponent", tmp_path, configure_metadata=False)
def test_show(capsys):
_show()
stdout, _ = capsys.readouterr()
assert "Form Component" in stdout
assert "Beginner Friendly" in stdout
assert "Layout" in stdout
assert "Dataframe" not in stdout
assert "Dataset" not in stdout
@pytest.mark.xfail
@pytest.mark.parametrize("template", ["Image"])
def test_build(template, virtualenv):
# Copy pnpm-lock.yaml to not cause unintended changes tracked by git
pnpm_lock = Path(__file__).parent / ".." / "pnpm-lock.yaml"
pnpm_copy = Path(__file__).parent / ".." / "pnpm-lock-copy.yaml"
shutil.copy(str(pnpm_lock), str(pnpm_copy))
# Using the js/preview/test directory will use the workspace code
dir_ = (
Path(__file__).parent / ".." / "js" / "preview" / "test" / "testtextbox"
).resolve()
shutil.rmtree(str(dir_), ignore_errors=True)
try:
# Local installs of gradio and gradio-client
gradio_dir = Path(__file__).parent / ".."
client = Path(__file__).parent / ".." / "client" / "python"
virtualenv.run("pip install build")
virtualenv.run(f"pip install -e {str(gradio_dir)}")
virtualenv.run(f"pip install -e {str(client)}")
virtualenv.run(
f"{shutil.which('gradio')} cc create TestTextbox --template {template} --no-configure-metadata --directory {str(dir_)}",
)
assert (dir_ / "frontend" / "node_modules").exists()
# need to reinstall local client because installing the custom component
# will pull latest stable version from pypi
virtualenv.run(f"pip install -e {str(client)}")
virtualenv.run(f"{shutil.which('gradio')} cc build {str(dir_)}")
template_dir: Path = dir_ / "backend" / "gradio_testtextbox" / "templates"
assert template_dir.exists() and template_dir.is_dir()
assert list(template_dir.glob("**/index.js"))
assert (dir_ / "dist").exists() and list((dir_ / "dist").glob("*.whl"))
finally:
shutil.move(str(pnpm_copy), str(pnpm_lock))
shutil.rmtree(str(dir_), ignore_errors=True)
def test_build_fails_if_component_not_installed(tmp_path):
_create(
"MyComponent",
tmp_path,
template="SimpleTextbox",
overwrite=True,
install=False,
configure_metadata=False,
)
with pytest.raises(
ValueError,
match=r"Your custom component package \(gradio_mycomponent\) is not installed!",
):
_build(tmp_path)
def test_fallback_template_app(tmp_path):
_create(
"SimpleComponent2",
directory=tmp_path,
overwrite=True,
install=False,
configure_metadata=False,
)
app = (tmp_path / "demo" / "app.py").read_text()
answer = textwrap.dedent(
"""
import gradio as gr
from gradio_simplecomponent2 import SimpleComponent2
with gr.Blocks() as demo:
gr.Markdown("# Change the value (keep it JSON) and the front-end will update automatically.")
SimpleComponent2(value={"message": "Hello from Gradio!"}, label="Static")
if __name__ == "__main__":
demo.launch()
"""
)
assert app.strip() == answer.strip()
def test_get_version_from_wheel():
assert (
_get_version_from_file(Path("gradio_textwithattachments-0.0.3-py3-none.whl"))
== "0.0.3"
)
assert (
_get_version_from_file(Path("gradio_textwithattachments-1.0.3b12-py3-none.whl"))
== "1.0.3b12"
)
|