Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions crates/bevy_asset/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ pub enum ParseAssetPathError {
/// Error that occurs when a path string has an [`AssetPath::label`] delimiter `#` with no characters succeeding it. E.g. `file.test#`
#[error("Asset label must be at least one character. Either specify the label after the '#' or remove the '#'")]
MissingLabel,
// Error that occurs when a path string is empty
#[error("asset path cannot be empty")]
EmptyPath,
}

impl<'a> AssetPath<'a> {
Expand Down Expand Up @@ -123,6 +126,7 @@ impl<'a> AssetPath<'a> {
///
/// This will return a [`ParseAssetPathError`] if `asset_path` is in an invalid format.
pub fn try_parse(asset_path: &'a str) -> Result<AssetPath<'a>, ParseAssetPathError> {

let (source, path, label) = Self::parse_internal(asset_path)?;
Ok(Self {
source: match source {
Expand Down Expand Up @@ -189,6 +193,10 @@ impl<'a> AssetPath<'a> {
}
}
}
// If string is empty
if asset_path.trim().is_empty() {
return Err(ParseAssetPathError::EmptyPath);
}
// If we found an `AssetPath::label`
if let Some(range) = label_range.clone() {
// If the `AssetPath::label` contained a `://` substring, it is invalid.
Expand Down
58 changes: 58 additions & 0 deletions tests/asset/empty_asset.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use bevy::prelude::*;
use bevy::asset::LoadState;

#[test]
fn test_asset_load_valid_file() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bevy_asset/src/lib.rs already contains a bunch of tests, which you could use as examples. It might be better to just add a new test there rather than start something new here (especially since those tests already have a bunch of utilities for writing tests more conveniently).

let mut app = App::new();
app.add_plugins(MinimalPlugins)
.add_plugins(AssetPlugin::default())
.init_asset::<Image>();

let asset_server = app.world().resource::<AssetServer>();
let handle: Handle<Image> = asset_server.load("branding/bevy_bird_dark.png");

// Confirm the asset exists in Bevy's registry
let state = asset_server.get_load_state(handle.id());
assert!(
matches!(state, Some(LoadState::NotLoaded) | Some(LoadState::Loading) | Some(LoadState::Loaded)),
"Valid file should be in a valid load state, got {:?}",
state
);
}

#[test]
fn test_asset_load_invalid_file() {
let mut app = App::new();
app.add_plugins(MinimalPlugins)
.add_plugins(AssetPlugin::default())
.init_asset::<Image>();

let asset_server = app.world().resource::<AssetServer>();

// Bevy doesn't panic on invalid paths - it creates a handle and marks it as failed
let handle: Handle<Image> = asset_server.load("nonexistent/fake_file.png");

// The handle should be created successfully (no panic)
let state = asset_server.get_load_state(handle.id());

// We just verify that a handle was created - Bevy will handle the error internally
assert!(
state.is_some(),
"Invalid file should still create a handle, got {:?}",
state
);
}

#[test]
#[should_panic]
fn test_asset_load_empty_path_panics() {
let mut app = App::new();
app.add_plugins(MinimalPlugins)
.add_plugins(AssetPlugin::default())
.init_asset::<Image>();

let asset_server = app.world().resource::<AssetServer>();

// Test that load panics with empty string
let _handle: Handle<Image> = asset_server.load("");
}
Loading