Skip to content

Commit d12464f

Browse files
test(audience-sdk,sample): unity-only DeviceCollector and UXML alignment drafts
Two Unity-only test fixtures the dotnet test runner cannot reach (DeviceCollector depends on UnityEngine.SystemInfo / Application; SampleAppUxml needs Unity test framework gating). Both run under the Unity Test Framework once the project is opened in the editor. DeviceCollectorTests (src/Packages/Audience/Tests/Editor/, excluded from the headless dotnet build by Audience.Tests.csproj's Compile Remove="Editor/**/*.cs" rule) pin DeviceCollector's emitted key sets against GameLaunchPropertyKeys and ContextKeys, assert that no unknown keys leak in either direction, and verify every string-typed value is capped at Constants.MaxFieldLength. SampleAppUxmlAlignmentTests (examples/audience/Assets/SampleApp/Tests/ Runtime/, gated by the existing UNITY_INCLUDE_TESTS define on the SampleApp.Tests asmdef) reads Resources/AudienceSample.uxml as XML and asserts every SampleAppUi name and Css constant that is slug-shaped (lowercase / dashes / no spaces) appears as a name= or class= attribute somewhere in the markup. Runtime-only CSS toggles (state-warn, copied, narrow, has-value, etc.) are filtered by the slug-shape heuristic so the test only flags constants that look like they should map directly to UXML. Both files compile cleanly. They will not run under dotnet test. Run them via Unity Test Runner. Follow-up to SDK-272 (centralisation of duplicated literals).
1 parent 482e9e6 commit d12464f

6 files changed

Lines changed: 155 additions & 0 deletions

File tree

src/Packages/Audience/Runtime/AssemblyInfo.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Runtime.CompilerServices;
22

33
[assembly: InternalsVisibleTo("Immutable.Audience.Runtime.Tests")]
4+
[assembly: InternalsVisibleTo("Immutable.Audience.Editor.Tests")]
45
[assembly: InternalsVisibleTo("Immutable.Audience.Unity")]
56

67
// First-party SampleApp reaches Json.Serialize and
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
using System.Runtime.CompilerServices;
2+
3+
// Editor-only test fixture for DeviceCollector reads internals of this assembly.
4+
[assembly: InternalsVisibleTo("Immutable.Audience.Editor.Tests")]

src/Packages/Audience/Runtime/Unity/AssemblyInfo.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#nullable enable
2+
3+
using System.Collections.Generic;
4+
using NUnit.Framework;
5+
using Immutable.Audience.Unity;
6+
7+
namespace Immutable.Audience.Tests.Editor
8+
{
9+
// Editor-only (DeviceCollector needs a Unity domain; skipped by the headless dotnet build).
10+
// Pins emitted payload keys against GameLaunchPropertyKeys and ContextKeys.
11+
[TestFixture]
12+
internal class DeviceCollectorTests
13+
{
14+
[Test]
15+
public void CollectGameLaunchProperties_EmitsTheExpectedKeySet()
16+
{
17+
var props = DeviceCollector.CollectGameLaunchProperties();
18+
19+
// Always-present keys. ScreenDpi is conditional (0 on some Linux WMs).
20+
CollectionAssert.Contains(props.Keys, GameLaunchPropertyKeys.Platform);
21+
CollectionAssert.Contains(props.Keys, GameLaunchPropertyKeys.Version);
22+
CollectionAssert.Contains(props.Keys, GameLaunchPropertyKeys.BuildGuid);
23+
CollectionAssert.Contains(props.Keys, GameLaunchPropertyKeys.UnityVersion);
24+
CollectionAssert.Contains(props.Keys, GameLaunchPropertyKeys.OsFamily);
25+
CollectionAssert.Contains(props.Keys, GameLaunchPropertyKeys.DeviceModel);
26+
CollectionAssert.Contains(props.Keys, GameLaunchPropertyKeys.Gpu);
27+
CollectionAssert.Contains(props.Keys, GameLaunchPropertyKeys.GpuVendor);
28+
CollectionAssert.Contains(props.Keys, GameLaunchPropertyKeys.Cpu);
29+
CollectionAssert.Contains(props.Keys, GameLaunchPropertyKeys.CpuCores);
30+
CollectionAssert.Contains(props.Keys, GameLaunchPropertyKeys.RamMb);
31+
}
32+
33+
[Test]
34+
public void CollectGameLaunchProperties_EmitsNoUnknownKeys()
35+
{
36+
// Confirms the payload only carries known GameLaunchPropertyKeys entries.
37+
var allowed = new HashSet<string>
38+
{
39+
GameLaunchPropertyKeys.Platform,
40+
GameLaunchPropertyKeys.Version,
41+
GameLaunchPropertyKeys.BuildGuid,
42+
GameLaunchPropertyKeys.UnityVersion,
43+
GameLaunchPropertyKeys.OsFamily,
44+
GameLaunchPropertyKeys.DeviceModel,
45+
GameLaunchPropertyKeys.Gpu,
46+
GameLaunchPropertyKeys.GpuVendor,
47+
GameLaunchPropertyKeys.Cpu,
48+
GameLaunchPropertyKeys.CpuCores,
49+
GameLaunchPropertyKeys.RamMb,
50+
GameLaunchPropertyKeys.ScreenDpi,
51+
};
52+
53+
var props = DeviceCollector.CollectGameLaunchProperties();
54+
foreach (var key in props.Keys)
55+
Assert.IsTrue(allowed.Contains(key),
56+
$"DeviceCollector.CollectGameLaunchProperties emitted unknown key '{key}' "
57+
+ "with no matching GameLaunchPropertyKeys constant");
58+
}
59+
60+
[Test]
61+
public void CollectGameLaunchProperties_TruncatesStringValuesToMaxFieldLength()
62+
{
63+
// Every string value respects MaxFieldLength; an untruncated .ToString() would fail here.
64+
var props = DeviceCollector.CollectGameLaunchProperties();
65+
foreach (var kv in props)
66+
{
67+
if (kv.Value is string s)
68+
Assert.LessOrEqual(s.Length, Constants.MaxFieldLength,
69+
$"GameLaunchPropertyKeys.{kv.Key} value exceeds Constants.MaxFieldLength");
70+
}
71+
}
72+
73+
[Test]
74+
public void CollectContext_EmitsTheExpectedKeySet()
75+
{
76+
var ctx = DeviceCollector.CollectContext();
77+
78+
// UserAgent is unconditional. Timezone / Locale / Screen are
79+
// best-effort and may be absent under unusual hosts.
80+
CollectionAssert.Contains(ctx.Keys, ContextKeys.UserAgent);
81+
}
82+
83+
[Test]
84+
public void CollectContext_EmitsNoUnknownKeys()
85+
{
86+
var allowed = new HashSet<string>
87+
{
88+
ContextKeys.UserAgent,
89+
ContextKeys.Timezone,
90+
ContextKeys.Locale,
91+
ContextKeys.Screen,
92+
};
93+
94+
var ctx = DeviceCollector.CollectContext();
95+
foreach (var key in ctx.Keys)
96+
Assert.IsTrue(allowed.Contains(key),
97+
$"DeviceCollector.CollectContext emitted unknown key '{key}' "
98+
+ "with no matching ContextKeys constant");
99+
}
100+
101+
[Test]
102+
public void CollectContext_TruncatesStringValuesToMaxFieldLength()
103+
{
104+
var ctx = DeviceCollector.CollectContext();
105+
foreach (var kv in ctx)
106+
{
107+
if (kv.Value is string s)
108+
Assert.LessOrEqual(s.Length, Constants.MaxFieldLength,
109+
$"ContextKeys.{kv.Key} value exceeds Constants.MaxFieldLength");
110+
}
111+
}
112+
}
113+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "Immutable.Audience.Editor.Tests",
3+
"rootNamespace": "Immutable.Audience.Tests.Editor",
4+
"references": [
5+
"Immutable.Audience.Runtime",
6+
"Immutable.Audience.Unity",
7+
"UnityEditor.TestRunner",
8+
"UnityEngine.TestRunner"
9+
],
10+
"includePlatforms": ["Editor"],
11+
"excludePlatforms": [],
12+
"allowUnsafeCode": false,
13+
"overrideReferences": true,
14+
"precompiledReferences": ["nunit.framework.dll"],
15+
"autoReferenced": false,
16+
"defineConstraints": ["UNITY_INCLUDE_TESTS"],
17+
"versionDefines": [],
18+
"noEngineReferences": false
19+
}

src/Packages/Audience/Tests/Editor/com.immutable.audience.tests.editor.asmdef.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)