Skip to content
Merged
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
45 changes: 45 additions & 0 deletions .github/workflows/test-audience-sdk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Audience package — Unit Tests

on:
push:
branches: [main]
paths:
- 'src/Packages/Audience/**'
- '.github/workflows/test-audience-sdk.yml'
pull_request:
paths:
- 'src/Packages/Audience/**'
- '.github/workflows/test-audience-sdk.yml'

jobs:
test:
name: Unit Tests (.NET)
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'

- name: Restore dependencies
run: dotnet restore src/Packages/Audience/Tests/Audience.Tests.csproj

- name: Build
run: dotnet build src/Packages/Audience/Tests/Audience.Tests.csproj --no-restore --configuration Release

- name: Run tests
run: >
dotnet test src/Packages/Audience/Tests/Audience.Tests.csproj
--no-build --configuration Release
--logger "trx;LogFileName=test-results.trx"
--logger "console;verbosity=normal"

- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: audience-test-results
path: '**/test-results.trx'
3 changes: 3 additions & 0 deletions src/Packages/Audience/Runtime/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("Immutable.Audience.Runtime.Tests")]
14 changes: 14 additions & 0 deletions src/Packages/Audience/Runtime/Audience.Runtime.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<LangVersion>9.0</LangVersion>
<Nullable>disable</Nullable>
<!-- Match the Unity asmdef assembly name so InternalsVisibleTo works in both contexts -->
<AssemblyName>Immutable.Audience.Runtime</AssemblyName>
</PropertyGroup>
<!--
Exclude modules that depend on Unity APIs (added in later PRs).
These compile fine in Unity but cannot be built with the .NET SDK alone.
Update this list as Unity-specific modules are added under Collection/ and Utility/MainThreadDispatcher.cs.
-->
</Project>
132 changes: 132 additions & 0 deletions src/Packages/Audience/Runtime/Utility/Json.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;

namespace Immutable.Audience
{
internal static class Json
{
internal static string Serialize(Dictionary<string, object> data)
{
var sb = new StringBuilder();
WriteObject(sb, data);
return sb.ToString();
}

private static void WriteValue(StringBuilder sb, object value)
{
if (value == null)
{
sb.Append("null");
}
else if (value is string s)
{
WriteString(sb, s);
}
else if (value is bool b)
{
sb.Append(b ? "true" : "false");
}
else if (value is int i)
{
sb.Append(i);
}
else if (value is long l)
{
sb.Append(l);
}
else if (value is float f)
{
if (float.IsNaN(f) || float.IsInfinity(f))
sb.Append("null");
else
sb.Append(f.ToString("R", CultureInfo.InvariantCulture));
}
else if (value is double d)
{
if (double.IsNaN(d) || double.IsInfinity(d))
sb.Append("null");
else
sb.Append(d.ToString("R", CultureInfo.InvariantCulture));
}
else if (value is decimal dec)
{
sb.Append(dec.ToString(CultureInfo.InvariantCulture));
}
else if (value is Dictionary<string, object> dict)
{
WriteObject(sb, dict);
}
else if (value is IList list)
{
WriteArray(sb, list);
}
else
{
WriteString(sb, value.ToString());
}
}

private static void WriteObject(StringBuilder sb, Dictionary<string, object> dict)
{
sb.Append('{');
var first = true;
foreach (var kvp in dict)
{
if (!first)
sb.Append(',');
first = false;
WriteString(sb, kvp.Key);
sb.Append(':');
WriteValue(sb, kvp.Value);
}
sb.Append('}');
}

private static void WriteArray(StringBuilder sb, IList list)
{
sb.Append('[');
for (var i = 0; i < list.Count; i++)
{
if (i > 0)
sb.Append(',');
WriteValue(sb, list[i]);
}
sb.Append(']');
}

private static void WriteString(StringBuilder sb, string s)
{
sb.Append('"');
foreach (var c in s)
{
switch (c)
{
case '\\':
sb.Append("\\\\");
break;
case '"':
sb.Append("\\\"");
break;
case '\n':
sb.Append("\\n");
break;
case '\r':
sb.Append("\\r");
break;
case '\t':
sb.Append("\\t");
break;
default:
if (c < 0x20)
sb.Append("\\u").Append(((int)c).ToString("X4"));
else
sb.Append(c);
break;
}
}
sb.Append('"');
}
}
}
18 changes: 18 additions & 0 deletions src/Packages/Audience/Tests/Audience.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>9.0</LangVersion>
<Nullable>disable</Nullable>
<IsPackable>false</IsPackable>
<!-- Match the Unity asmdef assembly name so InternalsVisibleTo("Immutable.Audience.Runtime.Tests") resolves correctly -->
<AssemblyName>Immutable.Audience.Runtime.Tests</AssemblyName>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../Runtime/Audience.Runtime.csproj" />
</ItemGroup>
</Project>
Loading
Loading