Files
sbox-public/engine/Sandbox.Test/System/Json/PatchBasic.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

730 lines
15 KiB
C#

using System.Collections.Generic;
using System.Text.Json.Nodes;
namespace TestSystem.JsonTests;
[TestClass]
public class PatchBasic
{
[TestMethod]
public void RoundTrip_WithContainerPatternMatching()
{
var source = JsonNode.Parse(
"""
{
"company": {
"id": 100,
"name": "Acme Inc",
"departments": [
{
"id": 1,
"name": "Engineering",
"employees": [
{ "id": 101, "name": "Alice", "role": "Developer" },
{ "id": 102, "name": "Bob", "role": "Designer" }
]
},
{
"id": 2,
"name": "Marketing",
"employees": [
{ "id": 201, "name": "Charlie", "role": "Manager" }
]
}
]
}
}
""" ) as JsonObject;
var target = JsonNode.Parse(
"""
{
"company": {
"id": 100,
"name": "Acme Corp",
"departments": [
{
"id": 1,
"name": "Engineering",
"employees": [
{ "id": 101, "name": "Alice", "role": "Senior Developer" },
{ "id": 103, "name": "Eve", "role": "QA Engineer" }
]
},
{
"id": 2,
"name": "Marketing",
"employees": [
{ "id": 201, "name": "Charlie", "role": "Director" }
]
}
]
}
}
""" ) as JsonObject;
var definitions = new HashSet<Json.TrackedObjectDefinition>
{
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Root",
requiredFields: ["company"],
allowedAsRoot: true
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Company",
requiredFields: ["id", "name"],
idProperty: "id",
parentType: "Root"
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Department",
requiredFields: ["id", "name"],
idProperty: "id",
parentType: "Company"
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Employee",
requiredFields: ["id", "name", "role"],
idProperty: "id",
parentType: "Department"
)
};
JsonTestUtils.RunRoundTripTest( source, target, "Container Property Name Pattern Matching", definitions );
}
[TestMethod]
public void RoundTrip_SimilarObjectsWithDifferentParents()
{
var definitions = new HashSet<Json.TrackedObjectDefinition>
{
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Root",
requiredFields: ["university"],
allowedAsRoot: true
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "University",
requiredFields: ["id", "name"],
idProperty: "id",
parentType: "Root"
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "AcademicDepartment",
requiredFields: ["id", "name"],
idProperty: "id",
parentType: "University"
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Student",
requiredFields: ["id", "name", "major"],
idProperty: "id",
parentType: "University"
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Company",
requiredFields: ["id", "name", "employees"],
idProperty: "id",
parentType: "University"
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "CompanyDepartment",
requiredFields: ["id", "name"],
idProperty: "id",
parentType: "Company"
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Employee",
requiredFields: ["id", "name", "role"],
idProperty: "id",
parentType: "Company"
)
};
// Modified JSON structure - change company from direct property to an array
var sourceJson = JsonNode.Parse(
"""
{
"university": {
"id": 1,
"name": "State University",
"departments": [
{
"id": 101,
"name": "Computer Science",
"budget": 500000
}
],
"students": [
{
"id": 1001,
"name": "John",
"major": "Computer Science"
}
],
"companies": [
{
"id": 2,
"name": "University Corp",
"departments": [
{
"id": 201,
"name": "HR",
"budget": 300000
}
],
"employees": [
{
"id": 2001,
"name": "Jane",
"role": "HR Manager"
}
]
}
]
}
}
""" ).AsObject();
var targetJson = JsonNode.Parse(
"""
{
"university": {
"id": 1,
"name": "State University",
"departments": [
{
"id": 101,
"name": "Computer Science",
"budget": 600000
},
{
"id": 102,
"name": "Mathematics",
"budget": 400000
}
],
"students": [
{
"id": 1001,
"name": "John",
"major": "Computer Science"
},
{
"id": 1002,
"name": "Alice",
"major": "Mathematics"
}
],
"companies": [
{
"id": 2,
"name": "University Corp",
"departments": [
{
"id": 201,
"name": "HR",
"budget": 350000
},
{
"id": 202,
"name": "Finance",
"budget": 250000
}
],
"employees": [
{
"id": 2001,
"name": "Jane",
"role": "HR Director"
},
{
"id": 2002,
"name": "Bob",
"role": "Finance Manager"
}
]
}
]
}
}
""" ).AsObject();
JsonTestUtils.RunRoundTripTest( sourceJson, targetJson, "Similar Objects with Different Containers", definitions );
}
[TestMethod]
public void RoundTrip_NestedObjectModifications()
{
var definitions = new HashSet<Json.TrackedObjectDefinition>
{
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Root",
requiredFields: ["products"],
allowedAsRoot: true
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Product",
requiredFields: ["id", "name"],
idProperty: "id",
parentType: "Root"
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Category",
requiredFields: ["id", "name"],
idProperty: "id",
parentType: "Product"
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Specification",
requiredFields: ["id", "name"],
idProperty: "id",
parentType: "Product"
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "SpecificationDetail",
requiredFields: ["id", "key"],
idProperty: "id",
parentType: "Specification"
)
};
var sourceJson = JsonNode.Parse(
"""
{
"products": [
{
"id": 1,
"name": "Smartphone",
"price": 699.99,
"categories": [
{
"id": 101,
"name": "Electronics",
"description": "Electronic devices"
}
],
"specifications": [
{
"id": 201,
"name": "Display",
"details": [
{
"id": 301,
"key": "size",
"value": "6.1 inch"
},
{
"id": 302,
"key": "resolution",
"value": "1170 x 2532"
}
]
},
{
"id": 202,
"name": "Battery",
"details": [
{
"id": 303,
"key": "capacity",
"value": "3240 mAh"
}
]
}
]
}
]
}
""" ).AsObject();
var targetJson = JsonNode.Parse(
"""
{
"products": [
{
"id": 1,
"name": "Smartphone Pro",
"price": 899.99,
"inStock": true,
"categories": [
{
"id": 101,
"name": "Premium Electronics",
"description": "High-end electronic devices"
}
],
"specifications": [
{
"id": 201,
"name": "Display",
"details": [
{
"id": 301,
"key": "size",
"value": "6.7 inch"
},
{
"id": 302,
"key": "resolution",
"value": "1290 x 2796"
}
]
},
{
"id": 202,
"name": "Battery",
"details": [
{
"id": 303,
"key": "capacity",
"value": "4323 mAh"
},
{
"id": 304,
"key": "technology",
"value": "Li-ion"
}
]
}
]
}
]
}
""" ).AsObject();
JsonTestUtils.RunRoundTripTest( sourceJson, targetJson, "Nested Object Modifications", definitions );
}
[TestMethod]
public void RoundTrip_ArrayReorderingAndRemovals()
{
var definitions = new HashSet<Json.TrackedObjectDefinition>
{
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Root",
requiredFields: ["playlist"],
allowedAsRoot: true
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Playlist",
requiredFields: ["id", "name"],
idProperty: "id",
parentType: "Root"
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Song",
requiredFields: ["id", "title"],
idProperty: "id",
parentType: "Playlist"
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Artist",
requiredFields: ["id", "name"],
idProperty: "id",
parentType: "Song"
)
};
var sourceJson = JsonNode.Parse(
"""
{
"playlist": {
"id": 1,
"name": "My Favorites",
"createdAt": "2025-01-15",
"songs": [
{
"id": 101,
"title": "Song One",
"duration": 180,
"artist": {
"id": 501,
"name": "Artist A"
}
},
{
"id": 102,
"title": "Song Two",
"duration": 210,
"artist": {
"id": 502,
"name": "Artist B"
}
},
{
"id": 103,
"title": "Song Three",
"duration": 195,
"artist": {
"id": 501,
"name": "Artist A"
}
},
{
"id": 104,
"title": "Song Four",
"duration": 240,
"artist": {
"id": 503,
"name": "Artist C"
}
}
]
}
}
""" ).AsObject();
var targetJson = JsonNode.Parse(
"""
{
"playlist": {
"id": 1,
"name": "My Top Picks",
"createdAt": "2025-01-15",
"updatedAt": "2025-02-27",
"songs": [
{
"id": 104,
"title": "Song Four",
"duration": 240,
"artist": {
"id": 503,
"name": "Artist C"
}
},
{
"id": 105,
"title": "Song Five",
"duration": 225,
"artist": {
"id": 504,
"name": "Artist D"
}
},
{
"id": 101,
"title": "Song One",
"duration": 183,
"artist": {
"id": 501,
"name": "Artist A"
}
}
]
}
}
""" ).AsObject();
JsonTestUtils.RunRoundTripTest( sourceJson, targetJson, "Array Reordering and Removals", definitions );
}
[TestMethod]
public void RoundTrip_ComplexNestedStructures()
{
var definitions = new HashSet<Json.TrackedObjectDefinition>
{
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Root",
requiredFields: ["organization"],
allowedAsRoot: true
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Organization",
requiredFields: ["id", "name"],
idProperty: "id",
parentType: "Root"
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Project",
requiredFields: ["id", "name"],
idProperty: "id",
parentType: "Organization"
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Task",
requiredFields: ["id", "title"],
idProperty: "id",
parentType: "Project"
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "User",
requiredFields: ["id", "name"],
idProperty: "id",
parentType: "Organization"
),
Json.TrackedObjectDefinition.CreatePresenceBasedDefinition(
type: "Comment",
requiredFields: ["id", "text"],
idProperty: "id",
parentType: "Task"
)
};
var sourceJson = JsonNode.Parse(
"""
{
"organization": {
"id": 1,
"name": "Tech Solutions",
"description": "Software development company",
"projects": [
{
"id": 101,
"name": "Website Redesign",
"status": "In Progress",
"tasks": [
{
"id": 1001,
"title": "Design Homepage",
"status": "Completed",
"assignee": {
"id": 501,
"name": "Alice Johnson"
},
"comments": [
{
"id": 10001,
"text": "Initial design completed",
"author": {
"id": 501,
"name": "Alice Johnson"
}
}
]
},
{
"id": 1002,
"title": "Implement Contact Form",
"status": "In Progress",
"assignee": {
"id": 502,
"name": "Bob Smith"
},
"comments": []
}
]
}
],
"users": [
{
"id": 501,
"name": "Alice Johnson",
"role": "Designer"
},
{
"id": 502,
"name": "Bob Smith",
"role": "Developer"
}
]
}
}
""" ).AsObject();
var targetJson = JsonNode.Parse(
"""
{
"organization": {
"id": 1,
"name": "Tech Solutions Inc.",
"description": "Enterprise software development company",
"founded": "2010",
"projects": [
{
"id": 101,
"name": "Website Redesign",
"status": "In Progress",
"priority": "High",
"tasks": [
{
"id": 1001,
"title": "Design Homepage",
"status": "Completed",
"assignee": {
"id": 501,
"name": "Alice Johnson"
},
"comments": [
{
"id": 10001,
"text": "Initial design completed",
"author": {
"id": 501,
"name": "Alice Johnson"
}
},
{
"id": 10002,
"text": "Design approved by client",
"author": {
"id": 503,
"name": "Carol Williams"
}
}
]
},
{
"id": 1002,
"title": "Implement Contact Form",
"status": "Completed",
"assignee": {
"id": 502,
"name": "Bob Smith"
},
"comments": [
{
"id": 10003,
"text": "Form validation added",
"author": {
"id": 502,
"name": "Bob Smith"
}
}
]
},
{
"id": 1003,
"title": "Optimize Images",
"status": "New",
"assignee": {
"id": 503,
"name": "Carol Williams"
},
"comments": []
}
]
},
{
"id": 102,
"name": "Mobile App Development",
"status": "New",
"tasks": []
}
],
"users": [
{
"id": 501,
"name": "Alice Johnson",
"role": "Senior Designer"
},
{
"id": 502,
"name": "Bob Smith",
"role": "Lead Developer"
},
{
"id": 503,
"name": "Carol Williams",
"role": "QA Specialist"
}
]
}
}
""" ).AsObject();
JsonTestUtils.RunRoundTripTest( sourceJson, targetJson, "Complex Nested Structures", definitions );
}
}