minor improvements, add more tests
This commit is contained in:
parent
1c4c9fd515
commit
bec31ff406
@ -9,7 +9,7 @@ from reflex import constants
|
||||
|
||||
|
||||
def asset(
|
||||
filename: str,
|
||||
path: str,
|
||||
subfolder: Optional[str] = None,
|
||||
shared: Optional[bool] = None,
|
||||
) -> str:
|
||||
@ -29,7 +29,7 @@ def asset(
|
||||
```
|
||||
|
||||
Args:
|
||||
filename: The relative filename of the asset.
|
||||
path: The relative path of the asset.
|
||||
subfolder: The directory to place the asset in.
|
||||
shared: Whether to expose the asset to other apps. None means auto-detect.
|
||||
|
||||
@ -44,16 +44,13 @@ def asset(
|
||||
calling_file = inspect.stack()[1].filename
|
||||
module = inspect.getmodule(inspect.stack()[1][0])
|
||||
assert module is not None
|
||||
caller_module_path = module.__name__.replace(".", "/")
|
||||
|
||||
subfolder = f"{caller_module_path}/{subfolder}" if subfolder else caller_module_path
|
||||
|
||||
cwd = Path.cwd()
|
||||
assets = constants.Dirs.APP_ASSETS
|
||||
external = constants.Dirs.EXTERNAL_APP_ASSETS
|
||||
|
||||
src_file_shared = Path(calling_file).parent / filename
|
||||
src_file_local = cwd / assets / subfolder / filename
|
||||
src_file_shared = Path(calling_file).parent / path
|
||||
src_file_local = cwd / assets / path
|
||||
|
||||
shared_exists = src_file_shared.exists()
|
||||
local_exists = src_file_local.exists()
|
||||
@ -62,7 +59,7 @@ def asset(
|
||||
if shared is None:
|
||||
if shared_exists and local_exists:
|
||||
raise ValueError(
|
||||
f"Both shared and local assets exist for {filename}. "
|
||||
f"Both shared and local assets exist for {path}. "
|
||||
+ "Please explicitly set shared=True or shared=False."
|
||||
)
|
||||
if not shared_exists and not local_exists:
|
||||
@ -73,26 +70,31 @@ def asset(
|
||||
|
||||
# Local asset handling
|
||||
if not shared:
|
||||
if subfolder is not None:
|
||||
raise ValueError("Subfolder is not supported for local assets.")
|
||||
if not local_exists:
|
||||
raise FileNotFoundError(f"File not found: {src_file_local}")
|
||||
return f"/{filename}"
|
||||
return f"/{path}"
|
||||
|
||||
# Shared asset handling
|
||||
if not shared_exists:
|
||||
raise FileNotFoundError(f"File not found: {src_file_shared}")
|
||||
|
||||
caller_module_path = module.__name__.replace(".", "/")
|
||||
subfolder = f"{caller_module_path}/{subfolder}" if subfolder else caller_module_path
|
||||
|
||||
# Symlink the asset to the app's external assets directory if running frontend.
|
||||
if not os.environ.get(constants.ENV_BACKEND_ONLY):
|
||||
# Create the asset folder in the currently compiling app.
|
||||
asset_folder = Path.cwd() / assets / external / subfolder
|
||||
asset_folder.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
dst_file = asset_folder / filename
|
||||
dst_file = asset_folder / path
|
||||
|
||||
if not dst_file.exists() and (
|
||||
not dst_file.is_symlink() or dst_file.resolve() != src_file_shared.resolve()
|
||||
):
|
||||
dst_file.symlink_to(src_file_shared)
|
||||
|
||||
asset_url = f"/{external}/{subfolder}/{filename}"
|
||||
asset_url = f"/{external}/{subfolder}/{path}"
|
||||
return asset_url
|
||||
|
@ -1,14 +1,15 @@
|
||||
import shutil
|
||||
from collections.abc import Generator
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
import reflex as rx
|
||||
import reflex.constants as constants
|
||||
|
||||
|
||||
def test_asset():
|
||||
# Test the asset function.
|
||||
|
||||
def test_shared_asset() -> None:
|
||||
"""Test shared assets."""
|
||||
# The asset function copies a file to the app's external assets directory.
|
||||
asset = rx._x.asset("custom_script.js", "subfolder")
|
||||
assert asset == "/external/test_assets/subfolder/custom_script.js"
|
||||
@ -34,3 +35,65 @@ def test_asset():
|
||||
|
||||
# Nothing is done to assets when file does not exist.
|
||||
assert not Path(Path.cwd() / "assets/external").exists()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"path,shared",
|
||||
[
|
||||
pytest.param("non_existing_file", True),
|
||||
pytest.param("non_existing_file", False),
|
||||
],
|
||||
)
|
||||
def test_invalid_assets(path: str, shared: bool) -> None:
|
||||
"""Test that asset raises an error when the file does not exist.
|
||||
|
||||
Args:
|
||||
path: The path to the asset.
|
||||
shared: Whether the asset should be shared.
|
||||
"""
|
||||
with pytest.raises(FileNotFoundError):
|
||||
_ = rx._x.asset(path, shared=shared)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def custom_script_in_asset_dir() -> Generator[Path, None, None]:
|
||||
"""Create a custom_script.js file in the app's assets directory.
|
||||
|
||||
Yields:
|
||||
The path to the custom_script.js file.
|
||||
"""
|
||||
asset_dir = Path.cwd() / constants.Dirs.APP_ASSETS
|
||||
asset_dir.mkdir(exist_ok=True)
|
||||
path = asset_dir / "custom_script.js"
|
||||
path.touch()
|
||||
yield path
|
||||
path.unlink()
|
||||
|
||||
|
||||
def test_both_existing_implicit(custom_script_in_asset_dir: Path) -> None:
|
||||
"""Test that asset raises an error if shared is not set and both files exist.
|
||||
|
||||
Args:
|
||||
custom_script_in_asset_dir: Fixture that creates a custom_script.js file in the app's assets directory.
|
||||
|
||||
"""
|
||||
with pytest.raises(ValueError) as e:
|
||||
_ = rx._x.asset("custom_script.js")
|
||||
assert (
|
||||
str(e.value)
|
||||
== "Both shared and local assets exist for custom_script.js. Please explicitly set shared=True or shared=False."
|
||||
)
|
||||
|
||||
|
||||
def test_both_existing_explicit(custom_script_in_asset_dir: Path) -> None:
|
||||
"""Test that no error is raised if shared is set and both files exist.
|
||||
|
||||
Args:
|
||||
custom_script_in_asset_dir: Fixture that creates a custom_script.js file in the app's assets directory.
|
||||
|
||||
"""
|
||||
asset = rx._x.asset("custom_script.js", shared=True)
|
||||
assert asset == "/external/test_assets/custom_script.js"
|
||||
|
||||
asset = rx._x.asset("custom_script.js", shared=False)
|
||||
assert asset == "/custom_script.js"
|
||||
|
Loading…
Reference in New Issue
Block a user