@mflrevan/ucp 0.6.1 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bridge/com.ucp.bridge/CHANGELOG.md +110 -0
- package/bridge/com.ucp.bridge/Editor/Bridge/BridgeServer.cs +61 -6
- package/bridge/com.ucp.bridge/Editor/Bridge/EditorStateSummary.cs +165 -0
- package/bridge/com.ucp.bridge/Editor/Bridge/EditorStateSummary.cs.meta +11 -0
- package/bridge/com.ucp.bridge/Editor/Compatibility/UnityObjectCompat.cs +22 -5
- package/bridge/com.ucp.bridge/Editor/Controllers/EditorController.cs +1 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/HierarchyController.cs +10 -10
- package/bridge/com.ucp.bridge/Editor/Controllers/LogsController.cs +71 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/MaterialController.cs +2 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/ObjectLocator.cs +4 -4
- package/bridge/com.ucp.bridge/Editor/Controllers/ObjectReferenceResolver.cs +3 -3
- package/bridge/com.ucp.bridge/Editor/Controllers/PrefabController.cs +6 -6
- package/bridge/com.ucp.bridge/Editor/Controllers/PropertyController.cs +30 -14
- package/bridge/com.ucp.bridge/Editor/Controllers/RecordingController.cs +732 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/RecordingController.cs.meta +11 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/SceneChangeTracker.cs +3 -3
- package/bridge/com.ucp.bridge/Editor/Controllers/SceneController.cs +3 -3
- package/bridge/com.ucp.bridge/Editor/Controllers/SnapshotController.cs +5 -5
- package/bridge/com.ucp.bridge/Editor/Controllers/TestRunnerController.cs +11 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/TransformController.cs +1 -1
- package/bridge/com.ucp.bridge/Editor/Controllers/UiController.cs +70 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/UiController.cs.meta +11 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ViewController.cs +1 -1
- package/bridge/com.ucp.bridge/Editor/Protocol/MiniJson.cs +1 -1
- package/bridge/com.ucp.bridge/Editor/Ui/UiHost.cs +468 -0
- package/bridge/com.ucp.bridge/Editor/Ui/UiHost.cs.meta +11 -0
- package/bridge/com.ucp.bridge/Editor/Ui/UiLintService.cs +554 -0
- package/bridge/com.ucp.bridge/Editor/Ui/UiLintService.cs.meta +11 -0
- package/bridge/com.ucp.bridge/Editor/Ui/UiOperationManager.cs +870 -0
- package/bridge/com.ucp.bridge/Editor/Ui/UiOperationManager.cs.meta +11 -0
- package/bridge/com.ucp.bridge/Editor/Ui/UiScenarioApplier.cs +496 -0
- package/bridge/com.ucp.bridge/Editor/Ui/UiScenarioApplier.cs.meta +11 -0
- package/bridge/com.ucp.bridge/Editor/Ui/UiScenarioLoader.cs +854 -0
- package/bridge/com.ucp.bridge/Editor/Ui/UiScenarioLoader.cs.meta +11 -0
- package/bridge/com.ucp.bridge/Editor/Ui/UiScenarioModels.cs +374 -0
- package/bridge/com.ucp.bridge/Editor/Ui/UiScenarioModels.cs.meta +11 -0
- package/bridge/com.ucp.bridge/Editor/Ui/UiVisualTreeInspector.cs +690 -0
- package/bridge/com.ucp.bridge/Editor/Ui/UiVisualTreeInspector.cs.meta +11 -0
- package/bridge/com.ucp.bridge/{Runtime.meta → Editor/Ui.meta} +1 -1
- package/bridge/com.ucp.bridge/Tests/Editor/ControllerSmokeTests.cs +191 -3
- package/bridge/com.ucp.bridge/Tests/Editor/SpatialVisualControllerTests.cs +2 -2
- package/bridge/com.ucp.bridge/Tests/Editor/UiControllerTests.cs +547 -0
- package/bridge/com.ucp.bridge/Tests/Editor/UiControllerTests.cs.meta +11 -0
- package/bridge/com.ucp.bridge/Tests/Editor/UiLintServiceTests.cs +253 -0
- package/bridge/com.ucp.bridge/Tests/Editor/UiLintServiceTests.cs.meta +11 -0
- package/bridge/com.ucp.bridge/Tests/Editor/UiScenarioTests.cs +587 -0
- package/bridge/com.ucp.bridge/Tests/Editor/UiScenarioTests.cs.meta +11 -0
- package/bridge/com.ucp.bridge/package.json +1 -1
- package/package.json +1 -1
- package/bridge/com.ucp.bridge/Runtime/UCP.Bridge.Runtime.asmdef +0 -14
- package/bridge/com.ucp.bridge/Runtime/UCP.Bridge.Runtime.asmdef.meta +0 -7
|
@@ -7,6 +7,7 @@ using NUnit.Framework;
|
|
|
7
7
|
using UnityEditor;
|
|
8
8
|
using UnityEditor.SceneManagement;
|
|
9
9
|
using UnityEngine;
|
|
10
|
+
using UnityEngine.SceneManagement;
|
|
10
11
|
using UnityEngine.Profiling;
|
|
11
12
|
using UnityEngine.TestTools;
|
|
12
13
|
|
|
@@ -46,6 +47,7 @@ namespace UCP.Bridge.Tests
|
|
|
46
47
|
PlayModeController.Register(_router);
|
|
47
48
|
ReferenceController.Register(_router);
|
|
48
49
|
LogsController.Register(_router);
|
|
50
|
+
RecordingController.Register(_router);
|
|
49
51
|
HierarchyController.Register(_router);
|
|
50
52
|
ProfilerController.Register(_router);
|
|
51
53
|
PropertyController.Register(_router);
|
|
@@ -72,6 +74,7 @@ namespace UCP.Bridge.Tests
|
|
|
72
74
|
DeleteTempLocalPackage();
|
|
73
75
|
RemoveTempLocalPackageDependencyIfPresent();
|
|
74
76
|
LogsController.ClearHistoryForTests();
|
|
77
|
+
RecordingController.ResetForTests();
|
|
75
78
|
AssetImportSupport.ClearTestState();
|
|
76
79
|
Profiler.enabled = false;
|
|
77
80
|
Profiler.enableBinaryLog = false;
|
|
@@ -97,6 +100,7 @@ namespace UCP.Bridge.Tests
|
|
|
97
100
|
DeleteTempLocalPackage();
|
|
98
101
|
RemoveTempLocalPackageDependencyIfPresent();
|
|
99
102
|
LogsController.ClearHistoryForTests();
|
|
103
|
+
RecordingController.ResetForTests();
|
|
100
104
|
AssetImportSupport.ClearTestState();
|
|
101
105
|
Profiler.enabled = false;
|
|
102
106
|
Profiler.enableBinaryLog = false;
|
|
@@ -123,6 +127,115 @@ namespace UCP.Bridge.Tests
|
|
|
123
127
|
Assert.That(Convert.ToBoolean(capabilities["sessionControl"]), Is.True);
|
|
124
128
|
}
|
|
125
129
|
|
|
130
|
+
[Test]
|
|
131
|
+
public void RecordingController_RegistersLifecycleMethodsAndReportsIdle()
|
|
132
|
+
{
|
|
133
|
+
Assert.That(_router.HasMethod("record/start"), Is.True);
|
|
134
|
+
Assert.That(_router.HasMethod("record/stop"), Is.True);
|
|
135
|
+
Assert.That(_router.HasMethod("record/status"), Is.True);
|
|
136
|
+
Assert.That(_router.HasMethod("record/arm"), Is.True);
|
|
137
|
+
Assert.That(_router.HasMethod("record/signal"), Is.True);
|
|
138
|
+
|
|
139
|
+
var response = _router.Dispatch("record/status", 1, "{}");
|
|
140
|
+
Assert.That(response.error, Is.Null);
|
|
141
|
+
var result = (Dictionary<string, object>)response.result;
|
|
142
|
+
Assert.That(result["state"], Is.EqualTo("idle"));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
[Test]
|
|
146
|
+
public void RecordingController_ResolvesEvenAspectPreservingDimensions()
|
|
147
|
+
{
|
|
148
|
+
Assert.That(RecordingController.ResolveDimensionsForTests(16f / 9f, 960, null, null),
|
|
149
|
+
Is.EqualTo((960, 540)));
|
|
150
|
+
Assert.That(RecordingController.ResolveDimensionsForTests(9f / 16f, 960, null, null),
|
|
151
|
+
Is.EqualTo((540, 960)));
|
|
152
|
+
Assert.That(RecordingController.ResolveDimensionsForTests(4f / 3f, 960, 640, null),
|
|
153
|
+
Is.EqualTo((640, 480)));
|
|
154
|
+
Assert.That(RecordingController.ResolveDimensionsForTests(4f / 3f, 960, null, 600),
|
|
155
|
+
Is.EqualTo((800, 600)));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
[Test]
|
|
159
|
+
public void RecordingController_ArmsAndMatchesNamedSignal()
|
|
160
|
+
{
|
|
161
|
+
var response = _router.Dispatch(
|
|
162
|
+
"record/arm",
|
|
163
|
+
1,
|
|
164
|
+
"{\"trigger\":\"signal:not-this-one\",\"duration\":1,\"timeout\":5}");
|
|
165
|
+
Assert.That(response.error, Is.Null);
|
|
166
|
+
|
|
167
|
+
var signal = _router.Dispatch("record/signal", 2, "{\"name\":\"different\"}");
|
|
168
|
+
Assert.That(signal.error, Is.Null);
|
|
169
|
+
var result = (Dictionary<string, object>)signal.result;
|
|
170
|
+
Assert.That(Convert.ToBoolean(result["matched"]), Is.False);
|
|
171
|
+
Assert.That(result["state"], Is.EqualTo("armed"));
|
|
172
|
+
|
|
173
|
+
var stop = _router.Dispatch("record/stop", 3, "{}");
|
|
174
|
+
Assert.That(stop.error, Is.Null);
|
|
175
|
+
var stopped = (Dictionary<string, object>)stop.result;
|
|
176
|
+
Assert.That(stopped["state"], Is.EqualTo("idle"));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
[Test]
|
|
180
|
+
public void GetProperty_ReturnsCompositeValuesRatherThanTypeNames()
|
|
181
|
+
{
|
|
182
|
+
// Regression: when SerializedObject.FindProperty resolves a name, the value it returns
|
|
183
|
+
// is already JSON-shaped. That result used to be converted a second time, match no
|
|
184
|
+
// case, and fall through to value.ToString() -- so a Vector3 arrived as
|
|
185
|
+
// "System.Collections.Generic.List`1[System.Object]". Querying the serialized name
|
|
186
|
+
// (m_LocalPosition) is what forces the FindProperty path; the public alias (position)
|
|
187
|
+
// has no serialized entry and takes the reflection fallback instead, which is why that
|
|
188
|
+
// one never looked broken.
|
|
189
|
+
var go = new GameObject("UcpPropertyProbe");
|
|
190
|
+
try
|
|
191
|
+
{
|
|
192
|
+
go.transform.localPosition = new Vector3(1.5f, 2.5f, 3.5f);
|
|
193
|
+
var id = go.GetId();
|
|
194
|
+
|
|
195
|
+
var serialized = _router.Dispatch("object/get-property", 1, "{\"instanceId\":ID,\"component\":\"Transform\",\"property\":\"m_LocalPosition\"}".Replace("ID", id.ToString()));
|
|
196
|
+
Assert.That(serialized.error, Is.Null);
|
|
197
|
+
var serializedResult = (Dictionary<string, object>)serialized.result;
|
|
198
|
+
var localPosition = serializedResult["value"] as IList;
|
|
199
|
+
Assert.That(localPosition, Is.Not.Null,
|
|
200
|
+
"a serialized Vector3 must come back as an array, not a stringified type name");
|
|
201
|
+
Assert.That(localPosition.Count, Is.EqualTo(3));
|
|
202
|
+
Assert.That(Convert.ToDouble(localPosition[0]), Is.EqualTo(1.5d).Within(1e-4));
|
|
203
|
+
Assert.That(Convert.ToDouble(localPosition[2]), Is.EqualTo(3.5d).Within(1e-4));
|
|
204
|
+
Assert.That(serializedResult["type"], Is.EqualTo("Vector3"),
|
|
205
|
+
"type must describe the field, not the container it was shaped into");
|
|
206
|
+
|
|
207
|
+
// Reflection fallback: no serialized entry named "position".
|
|
208
|
+
var reflected = _router.Dispatch("object/get-property", 2, "{\"instanceId\":ID,\"component\":\"Transform\",\"property\":\"position\"}".Replace("ID", id.ToString()));
|
|
209
|
+
Assert.That(reflected.error, Is.Null);
|
|
210
|
+
var reflectedResult = (Dictionary<string, object>)reflected.result;
|
|
211
|
+
Assert.That(reflectedResult["value"] as IList, Is.Not.Null);
|
|
212
|
+
Assert.That(reflectedResult["type"], Is.EqualTo("Vector3"));
|
|
213
|
+
}
|
|
214
|
+
finally
|
|
215
|
+
{
|
|
216
|
+
UnityEngine.Object.DestroyImmediate(go);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
[Test]
|
|
221
|
+
public void RecordingController_ValidatesSlowdownRange()
|
|
222
|
+
{
|
|
223
|
+
// --slowdown exists to raise effective temporal resolution for models that sample a
|
|
224
|
+
// clip at a fixed low rate, so an out-of-range factor must fail loudly rather than
|
|
225
|
+
// silently producing a file whose playback rate is meaningless.
|
|
226
|
+
var tooLarge = _router.Dispatch("record/arm", 1, "{\"trigger\":\"signal:sd\",\"duration\":1,\"timeout\":5,\"slowdown\":40}");
|
|
227
|
+
Assert.That(tooLarge.error, Is.Not.Null, "a slowdown above the supported range must be rejected");
|
|
228
|
+
|
|
229
|
+
var accepted = _router.Dispatch("record/arm", 2, "{\"trigger\":\"signal:sd\",\"duration\":1,\"timeout\":5,\"slowdown\":6}");
|
|
230
|
+
Assert.That(accepted.error, Is.Null);
|
|
231
|
+
var armed = (Dictionary<string, object>)accepted.result;
|
|
232
|
+
Assert.That(armed["state"], Is.EqualTo("armed"));
|
|
233
|
+
|
|
234
|
+
var stop = _router.Dispatch("record/stop", 3, "{}");
|
|
235
|
+
Assert.That(stop.error, Is.Null);
|
|
236
|
+
Assert.That(((Dictionary<string, object>)stop.result)["state"], Is.EqualTo("idle"));
|
|
237
|
+
}
|
|
238
|
+
|
|
126
239
|
[Test]
|
|
127
240
|
public void ProfilerSessionStartStop_TogglesProfilerState()
|
|
128
241
|
{
|
|
@@ -545,6 +658,80 @@ namespace UCP.Bridge.Tests
|
|
|
545
658
|
Assert.That(getResult["stackTrace"], Is.EqualTo("stack line 1\nstack line 2"));
|
|
546
659
|
}
|
|
547
660
|
|
|
661
|
+
[Test]
|
|
662
|
+
public void EditorStateSummary_ReportsModeSceneAndConsoleAndCountsNewEntries()
|
|
663
|
+
{
|
|
664
|
+
var cursor = LogsController.GetLatestId();
|
|
665
|
+
var summary = EditorStateSummary.Capture(cursor);
|
|
666
|
+
|
|
667
|
+
Assert.That(summary["mode"], Is.EqualTo("edit"));
|
|
668
|
+
var scene = (Dictionary<string, object>)summary["scene"];
|
|
669
|
+
Assert.That(scene["name"], Is.EqualTo(SceneManager.GetActiveScene().name));
|
|
670
|
+
Assert.That(scene["dirty"], Is.EqualTo(SceneManager.GetActiveScene().isDirty));
|
|
671
|
+
var console = (Dictionary<string, object>)summary["console"];
|
|
672
|
+
Assert.That(Convert.ToInt32(console["errors"]), Is.GreaterThanOrEqualTo(0));
|
|
673
|
+
Assert.That(Convert.ToInt32(console["warnings"]), Is.GreaterThanOrEqualTo(0));
|
|
674
|
+
Assert.That(console.ContainsKey("newWarnings"), Is.False, "nothing was logged after the cursor");
|
|
675
|
+
Assert.That(summary.ContainsKey("recording"), Is.False);
|
|
676
|
+
|
|
677
|
+
LogAssert.Expect(LogType.Warning, "ucp summary probe warning");
|
|
678
|
+
Debug.LogWarning("ucp summary probe warning");
|
|
679
|
+
|
|
680
|
+
var after = (Dictionary<string, object>)EditorStateSummary.Capture(cursor)["console"];
|
|
681
|
+
Assert.That(Convert.ToInt32(after["newWarnings"]), Is.EqualTo(1));
|
|
682
|
+
Assert.That(after.ContainsKey("newErrors"), Is.False);
|
|
683
|
+
LogsController.CountLevels(cursor, out var errors, out var warnings);
|
|
684
|
+
Assert.That(errors, Is.EqualTo(0));
|
|
685
|
+
Assert.That(warnings, Is.EqualTo(1));
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
[Test]
|
|
689
|
+
public void EditorStateSummary_ReadsTheConsoleBadgeCounts()
|
|
690
|
+
{
|
|
691
|
+
Assert.That(EditorStateSummary.TryReadConsoleCounts(out var errors, out var warnings), Is.True,
|
|
692
|
+
"UnityEditor.LogEntries.GetCountsByType must be reachable on this editor");
|
|
693
|
+
Assert.That(errors, Is.GreaterThanOrEqualTo(0));
|
|
694
|
+
Assert.That(warnings, Is.GreaterThanOrEqualTo(0));
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
[Test]
|
|
698
|
+
public void Responses_CarryTheEditorSummaryOnlyWhenDispatchedOnTheMainThread()
|
|
699
|
+
{
|
|
700
|
+
var response = JsonRpcResponse.Success(7, new Dictionary<string, object> { ["ok"] = true });
|
|
701
|
+
|
|
702
|
+
var offThread = BridgeServer.ResponseToDict(response);
|
|
703
|
+
Assert.That(offThread.ContainsKey("editor"), Is.False);
|
|
704
|
+
|
|
705
|
+
var onThread = BridgeServer.ResponseToDict(response, LogsController.GetLatestId());
|
|
706
|
+
var editor = (Dictionary<string, object>)onThread["editor"];
|
|
707
|
+
Assert.That(editor["mode"], Is.EqualTo("edit"));
|
|
708
|
+
Assert.That(onThread["result"], Is.SameAs(response.result));
|
|
709
|
+
|
|
710
|
+
var json = MiniJson.Serialize(onThread);
|
|
711
|
+
var parsed = (Dictionary<string, object>)MiniJson.Deserialize(json);
|
|
712
|
+
Assert.That(((Dictionary<string, object>)parsed["editor"]).ContainsKey("console"), Is.True);
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
[Test]
|
|
716
|
+
public void TestGuard_IgnoresLogsInsideIgnoreFailingMessagesWindows()
|
|
717
|
+
{
|
|
718
|
+
var entries = new List<string>
|
|
719
|
+
{
|
|
720
|
+
"real error before",
|
|
721
|
+
"\n" + LogsController.IgnoreFailingMessagesOnMarker,
|
|
722
|
+
"expected importer error",
|
|
723
|
+
"expected warning",
|
|
724
|
+
LogsController.IgnoreFailingMessagesOffMarker + "\n",
|
|
725
|
+
"real error after",
|
|
726
|
+
LogsController.IgnoreFailingMessagesOnMarker,
|
|
727
|
+
"still ignored when a test never resets the flag"
|
|
728
|
+
};
|
|
729
|
+
|
|
730
|
+
var kept = LogsController.ExcludeExpectedNoise(entries, entry => entry);
|
|
731
|
+
|
|
732
|
+
Assert.That(kept, Is.EqualTo(new[] { "real error before", "real error after" }));
|
|
733
|
+
}
|
|
734
|
+
|
|
548
735
|
[Test]
|
|
549
736
|
public void ObjectLifecycle_CreateMutateAndDelete_WorksEndToEnd()
|
|
550
737
|
{
|
|
@@ -552,7 +739,7 @@ namespace UCP.Bridge.Tests
|
|
|
552
739
|
Assert.That(create.error, Is.Null);
|
|
553
740
|
|
|
554
741
|
var createResult = (Dictionary<string, object>)create.result;
|
|
555
|
-
var instanceId = Convert.
|
|
742
|
+
var instanceId = Convert.ToInt64(createResult["instanceId"]);
|
|
556
743
|
|
|
557
744
|
var rename = _router.Dispatch("object/set-name", 1, "{\"instanceId\":" + instanceId + ",\"name\":\"RenamedSmoke\"}");
|
|
558
745
|
Assert.That(rename.error, Is.Null);
|
|
@@ -1264,7 +1451,7 @@ namespace UCP.Bridge.Tests
|
|
|
1264
1451
|
{
|
|
1265
1452
|
var create = _router.Dispatch("object/create", 1, "{\"name\":\"PrefabSource\"}");
|
|
1266
1453
|
Assert.That(create.error, Is.Null);
|
|
1267
|
-
var sourceId = Convert.
|
|
1454
|
+
var sourceId = Convert.ToInt64(((Dictionary<string, object>)create.result)["instanceId"]);
|
|
1268
1455
|
|
|
1269
1456
|
var createPrefab = _router.Dispatch(
|
|
1270
1457
|
"prefab/create",
|
|
@@ -1279,7 +1466,7 @@ namespace UCP.Bridge.Tests
|
|
|
1279
1466
|
"{\"prefab\":\"Assets/UcpControllerSmoke.prefab\",\"name\":\"PrefabInstance\"}"
|
|
1280
1467
|
);
|
|
1281
1468
|
Assert.That(instantiate.error, Is.Null);
|
|
1282
|
-
var instanceId = Convert.
|
|
1469
|
+
var instanceId = Convert.ToInt64(((Dictionary<string, object>)instantiate.result)["instanceId"]);
|
|
1283
1470
|
|
|
1284
1471
|
var status = _router.Dispatch("prefab/status", 1, "{\"instanceId\":" + instanceId + "}");
|
|
1285
1472
|
Assert.That(status.error, Is.Null);
|
|
@@ -1647,4 +1834,5 @@ namespace UCP.Bridge.Tests
|
|
|
1647
1834
|
public SearchRootAsset referenceAsset;
|
|
1648
1835
|
}
|
|
1649
1836
|
}
|
|
1837
|
+
|
|
1650
1838
|
}
|
|
@@ -62,7 +62,7 @@ namespace UCP.Bridge.Tests
|
|
|
62
62
|
{
|
|
63
63
|
var res = Result(_router.Dispatch("object/create", 1,
|
|
64
64
|
"{\"name\":\"Greybox\",\"primitive\":\"Cube\"}"));
|
|
65
|
-
var id = Convert.
|
|
65
|
+
var id = Convert.ToInt64(res["instanceId"]);
|
|
66
66
|
var go = ObjectLocator.FindByInstanceId(id);
|
|
67
67
|
_spawned.Add(go);
|
|
68
68
|
|
|
@@ -179,7 +179,7 @@ namespace UCP.Bridge.Tests
|
|
|
179
179
|
var res = Result(_router.Dispatch("physics/raycast", 1,
|
|
180
180
|
"{\"origin\":[0,5,0],\"direction\":[0,-1,0]}"));
|
|
181
181
|
Assert.That(Convert.ToBoolean(res["hit"]), Is.True);
|
|
182
|
-
Assert.That(Convert.
|
|
182
|
+
Assert.That(Convert.ToInt64(res["instanceId"]), Is.EqualTo(ground.GetId()));
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
[Test]
|