Skip to content

Commit

Permalink
Merge pull request #72 from nowsprinting/feature/relativepath
Browse files Browse the repository at this point in the history
Support relative path in LoadScene attribute
  • Loading branch information
nowsprinting committed Apr 29, 2024
2 parents cc6c306 + d117da9 commit 5519b78
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 4 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ It has the following benefits:
- Can be use same code for running Edit Mode tests, Play Mode tests in Editor, and on Player.
- Can be specified scenes that are **NOT** in "Scenes in Build".
- Can be specified path by glob pattern. However, there are restrictions, top level and scene name cannot be omitted.
- Can be specified path by relative path from the test class file.

- This attribute can attached to the test method only.
It can be used with sync Tests, async Tests, and UnityTest.
Expand All @@ -239,6 +240,20 @@ public class MyTestClass
var cube = GameObject.Find("Cube in TestScene");
Assert.That(cube, Is.Not.Null);
}

[Test]
[LoadScene("Packages/YourPackageName/**/SampleScene.unity")]
public void UsingGlobPattern()
{
// snip
}

[Test]
[LoadScene("../../Scenes/SampleScene.unity")]
public void UsingRelativePath()
{
// snip
}
}
```

Expand Down
39 changes: 36 additions & 3 deletions Runtime/Attributes/LoadSceneAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
// Copyright (c) 2023 Koji Hasegawa.
// Copyright (c) 2023-2024 Koji Hasegawa.
// This software is released under the MIT License.

using System;
using System.Collections;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.CompilerServices;
using NUnit.Framework;
using NUnit.Framework.Interfaces;
using TestHelper.Utils;
Expand Down Expand Up @@ -37,16 +40,46 @@ public class LoadSceneAttribute : NUnitAttribute, IOuterUnityTestAction
/// <summary>
/// Load scene before running test.
/// Can be specified path by glob pattern. However, there are restrictions, top level and scene name cannot be omitted.
/// Can be specified relative path.
/// </summary>
/// <param name="path">Scene file path.
/// The path starts with `Assets/` or `Packages/`.
/// And package name using `name` instead of `displayName`, when scenes in the package.
/// (e.g., `Packages/com.nowsprinting.test-helper/Tests/Scenes/Scene.unity`)
/// </param>
/// <seealso href="https://en.wikipedia.org/wiki/Glob_(programming)"/>
public LoadSceneAttribute(string path)
public LoadSceneAttribute(string path, [CallerFilePath] string callerFilePath = null)
{
ScenePath = path;
if (path.StartsWith("."))
{
ScenePath = GetAbsolutePath(path, callerFilePath);
}
else
{
ScenePath = path;
}
}

[SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")]
internal static string GetAbsolutePath(string relativePath, string callerFilePath)
{
var callerDirectory = Path.GetDirectoryName(callerFilePath);
var absolutePath = Path.GetFullPath(Path.Combine(callerDirectory, relativePath));

var assetsIndexOf = absolutePath.IndexOf("Assets", StringComparison.Ordinal);
if (assetsIndexOf > 0)
{
return absolutePath.Substring(assetsIndexOf);
}

var packageIndexOf = absolutePath.IndexOf("Packages", StringComparison.Ordinal);
if (packageIndexOf > 0)
{
return absolutePath.Substring(packageIndexOf);
}

throw new ArgumentException(
$"Can not resolve absolute path. relativePath: {relativePath}, callerFilePath: {callerFilePath}");
}

/// <inheritdoc />
Expand Down
24 changes: 23 additions & 1 deletion Tests/Runtime/Attributes/LoadSceneAttributeTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2023 Koji Hasegawa.
// Copyright (c) 2023-2024 Koji Hasegawa.
// This software is released under the MIT License.

using System.Collections;
Expand Down Expand Up @@ -56,5 +56,27 @@ public void UsingGlob_LoadedSceneNotInBuild()

Object.Destroy(cube); // For not giving false negatives in subsequent tests.
}

[Test]
[LoadScene("../../Scenes/NotInScenesInBuild.unity")]
public void UsingRelativePath_LoadedSceneNotInBuild()
{
var cube = GameObject.Find(ObjectName);
Assert.That(cube, Is.Not.Null);

Object.Destroy(cube); // For not giving false negatives in subsequent tests.
}

[TestCase("./Scene.unity", // include `./`
"Assets/Tests/Runtime/Caller.cs",
"Assets/Tests/Runtime/Scene.unity")]
[TestCase("../../BadPath/../Scenes/Scene.unity", // include `../`
"Packages/com.nowsprinting.test-helper/Tests/Runtime/Attributes/Caller.cs",
"Packages/com.nowsprinting.test-helper/Tests/Scenes/Scene.unity")]
public void GetAbsolutePath(string relativePath, string callerFilePath, string expected)
{
var actual = LoadSceneAttribute.GetAbsolutePath(relativePath, callerFilePath);
Assert.That(actual, Is.EqualTo(expected));
}
}
}

0 comments on commit 5519b78

Please sign in to comment.