| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Text.Encodings.Web;
- using NUnit.Framework;
- namespace SharpGLTF.IO
- {
- class _TestStructure
- {
- public string Author { get; set; }
- public int Integer1 { get; set; }
- public bool Bool1 { get; set; }
- public float Single1 { get; set; }
- public float Single2 { get; set; }
- public float Single3 { get; set; }
- // public float SinglePI { get; set; } // Fails on .Net Framework 471
- public double Double1 { get; set; }
- public double Double2 { get; set; }
- public double Double3 { get; set; }
- public double DoublePI { get; set; }
- public List<int> Array1 { get; set; }
- public List<float> Array2 { get; set; }
- public List<int[]> Array3 { get; set; }
- public List<_TestStructure2> Array4 { get; set; }
- public _TestStructure2 Dict1 { get; set; }
- public _TestStructure3 Dict2 { get; set; }
-
- public static Dictionary<string,object> CreateCompatibleDictionary()
- {
- var dict = new Dictionary<string, Object>();
- dict["author"] = "me";
- dict["integer1"] = 17;
- dict["bool1"] = true;
- dict["single1"] = 15.3f;
- dict["single2"] = 1.1f;
- dict["single3"] = -1.1f;
- // dict["singlePI"] = (float)Math.PI; // Fails on .Net Framework 471
- dict["double1"] = 15.3;
- dict["double2"] = 1.1;
- dict["double3"] = -1.1;
- dict["doublePI"] = Math.PI;
- dict["array1"] = new int[] { 1, 2, 3 };
- dict["array2"] = new float[] { 1.1f, 2.2f, 3.3f };
- dict["array3"] = new object[]
- {
- new int[] { 1,2,3 },
- new int[] { 4,5,6 }
- };
- dict["array4"] = new object[]
- {
- new Dictionary<string, int> { ["a0"] = 5, ["a1"] = 6 },
- new Dictionary<string, int> { ["a0"] = 7, ["a1"] = 8 }
- };
- dict["dict1"] = new Dictionary<string, int> { ["a0"] = 2, ["a1"] = 3 };
- dict["dict2"] = new Dictionary<string, Object>
- {
- ["a"] = 16,
- ["b"] = "delta",
- ["c"] = new List<int>() { 4, 6, 7 },
- ["d"] = new Dictionary<string, int> { ["a0"] = 1, ["a1"] = 2 }
- };
- if (!JsonContentTests.IsJsonRoundtripReady)
- {
- dict["array2"] = new float[] { 1, 2, 3 };
- }
- return dict;
- }
- }
- struct _TestStructure2
- {
- public int A0 { get; set; }
- public int A1 { get; set; }
- }
- class _TestStructure3
- {
- public int A { get; set; }
- public string B { get; set; }
- public int[] C { get; set; }
- public _TestStructure2 D { get; set; }
- }
- [Category("Core.IO")]
- public class JsonContentTests
- {
- public static bool IsJsonRoundtripReady
- {
- get
- {
- // when serializing a JsonContent object, it's important to take into account floating point values roundtrips.
- // it seems that prior NetCore3.1, System.Text.JSon was not roundtrip ready, so some values might have some
- // error margin when they complete a roundtrip.
- // On newer, NetCore System.Text.Json versions, it seems to use "G9" and "G17" text formatting are used.
- // https://devblogs.microsoft.com/dotnet/floating-point-parsing-and-formatting-improvements-in-net-core-3-0/
- // https://github.com/dotnet/runtime/blob/76904319b41a1dd0823daaaaae6e56769ed19ed3/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs#L101
- // pull requests:
- // https://github.com/dotnet/corefx/pull/40408
- // https://github.com/dotnet/corefx/pull/38322
- // https://github.com/dotnet/corefx/pull/32268
- var framework = System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription;
- return !framework.StartsWith(".NET Framework 4");
- }
- }
- public static bool AreEqual(System.Text.Json.Nodes.JsonNode a, System.Text.Json.Nodes.JsonNode b)
- {
- if (Object.ReferenceEquals(a, b)) return true;
- if (Object.ReferenceEquals(a, null)) return false;
- if (Object.ReferenceEquals(b, null)) return false;
- // A JsonContent ultimately represents a json block, so it seems fit to do the comparison that way.
- // also, there's the problem of floating point json writing, that can slightly change between
- // different frameworks.
- var ajson = a.ToJsonString();
- var bjson = b.ToJsonString();
- if (ajson == bjson) return true;
- // Net6.0 has better roundtrip handling that netstandard/net4
- #if NET6_0_OR_GREATER
- return false;
- #endif
- return true;
- }
- }
- [Category("Core.IO")]
- public class JsonSerializationTests
- {
- const string UNESCAPED = "你好";
- const string ESCAPED = "\u4f60\u597d";
- [Test]
- public void TestJsonExtendedCharacters()
- {
- TestContext.CurrentContext.AttachGltfValidatorLinks();
- // create a test model
- var model = Schema2.ModelRoot.CreateModel();
- var extras = new System.Text.Json.Nodes.JsonArray();
- extras.Add(UNESCAPED);
- extras.Add(ESCAPED);
- extras.Add(UNESCAPED);
- model.Asset.Copyright = UNESCAPED;
- model.UseScene(UNESCAPED);
- model.Asset.Extras = extras;
- model.CreateImage().Content = Memory.MemoryImage.DefaultPngImage;
- // create write settings
- var joptions = new System.Text.Json.JsonWriterOptions
- {
- Indented = true,
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
- };
- var wsettings = new Schema2.WriteSettings();
- wsettings.JsonOptions = joptions;
- // model save-load roundtrip
- var roundtripPath = model.AttachToCurrentTest("extended 你好 characters.gltf", wsettings);
- var roundtripJson = System.IO.File.ReadAllText(roundtripPath);
- var roundtripModel = Schema2.ModelRoot.Load(roundtripPath);
- // checks
- TestContext.WriteLine(roundtripJson);
- Assert.That(roundtripJson, Does.Contain("你好"));
-
- // https://github.com/KhronosGroup/glTF/issues/1978#issuecomment-831744624
- Assert.That(roundtripJson, Does.Contain("extended%20%E4%BD%A0%E5%A5%BD%20characters.png"));
- Assert.That(roundtripModel.LogicalImages[0].Content.IsPng, Is.True);
- }
- }
- }
|