|
|
@@ -0,0 +1,144 @@
|
|
|
+using Invercargill;
|
|
|
+using Invercargill.DataStructures;
|
|
|
+using InvercargillJson;
|
|
|
+using Json;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Regression tests for the ValueElement -> JsonElement.from_element scalar
|
|
|
+ * dispatch (upstream issues I-1, I-2, I-3).
|
|
|
+ *
|
|
|
+ * These mirror the downstream Statum path where a GObject property is wrapped
|
|
|
+ * in `new ValueElement(value)` and then serialised via
|
|
|
+ * `JsonElement.from_properties` / `from_element`.
|
|
|
+ */
|
|
|
+void from_element_scalar_tests() {
|
|
|
+
|
|
|
+ // --- I-1: int64 ValueElement must serialise as a JSON number, not segfault ---
|
|
|
+ Test.add_func("/invercargill/from_element/int64_is_number", () => {
|
|
|
+ if (Test.subprocess()) {
|
|
|
+ var v = Value(typeof(int64));
|
|
|
+ v.set_int64(99);
|
|
|
+ try {
|
|
|
+ var j = new JsonElement.from_element(new ValueElement(v));
|
|
|
+ assert_cmpstr(j.stringify(), CompareOperator.EQ, "99");
|
|
|
+ } catch (Error e) { assert_no_error(e); }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Test.trap_subprocess(null, 0, 0);
|
|
|
+ Test.trap_assert_passed();
|
|
|
+ });
|
|
|
+
|
|
|
+ // --- I-1 (variant): uint64 ValueElement must serialise as a number, not segfault ---
|
|
|
+ Test.add_func("/invercargill/from_element/uint64_is_number", () => {
|
|
|
+ if (Test.subprocess()) {
|
|
|
+ var v = Value(typeof(uint64));
|
|
|
+ v.set_uint64(99);
|
|
|
+ try {
|
|
|
+ var j = new JsonElement.from_element(new ValueElement(v));
|
|
|
+ assert_cmpstr(j.stringify(), CompareOperator.EQ, "99");
|
|
|
+ } catch (Error e) { assert_no_error(e); }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Test.trap_subprocess(null, 0, 0);
|
|
|
+ Test.trap_assert_passed();
|
|
|
+ });
|
|
|
+
|
|
|
+ // --- I-1: large int64 round-trips without precision loss (2^53 + 1) ---
|
|
|
+ Test.add_func("/invercargill/from_element/int64_large_precision", () => {
|
|
|
+ if (Test.subprocess()) {
|
|
|
+ int64 big = (int64)9007199254740993;
|
|
|
+ var v = Value(typeof(int64));
|
|
|
+ v.set_int64(big);
|
|
|
+ try {
|
|
|
+ var j = new JsonElement.from_element(new ValueElement(v));
|
|
|
+ assert_cmpstr(j.stringify(), CompareOperator.EQ, "9007199254740993");
|
|
|
+ } catch (Error e) { assert_no_error(e); }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Test.trap_subprocess(null, 0, 0);
|
|
|
+ Test.trap_assert_passed();
|
|
|
+ });
|
|
|
+
|
|
|
+ // --- I-3: long (glong) ValueElement must be a JSON number, not a quoted string ---
|
|
|
+ Test.add_func("/invercargill/from_element/long_is_number", () => {
|
|
|
+ var v = Value(typeof(long));
|
|
|
+ v.set_long(7);
|
|
|
+ try {
|
|
|
+ var j = new JsonElement.from_element(new ValueElement(v));
|
|
|
+ // A number serialises as `7`; a string would serialise as `"7"`.
|
|
|
+ assert_cmpstr(j.stringify(), CompareOperator.EQ, "7");
|
|
|
+ } catch (Error e) { assert_no_error(e); }
|
|
|
+ });
|
|
|
+
|
|
|
+ // --- I-3: ulong (gulong) ValueElement must be a JSON number, not a quoted string ---
|
|
|
+ Test.add_func("/invercargill/from_element/ulong_is_number", () => {
|
|
|
+ var v = Value(typeof(ulong));
|
|
|
+ v.set_ulong(7);
|
|
|
+ try {
|
|
|
+ var j = new JsonElement.from_element(new ValueElement(v));
|
|
|
+ assert_cmpstr(j.stringify(), CompareOperator.EQ, "7");
|
|
|
+ } catch (Error e) { assert_no_error(e); }
|
|
|
+ });
|
|
|
+
|
|
|
+ // --- I-2: bool ValueElement must serialise as a JSON boolean ---
|
|
|
+ Test.add_func("/invercargill/from_element/bool_value", () => {
|
|
|
+ var v = Value(typeof(bool));
|
|
|
+ v.set_boolean(true);
|
|
|
+ try {
|
|
|
+ var j = new JsonElement.from_element(new ValueElement(v));
|
|
|
+ assert_cmpstr(j.stringify(), CompareOperator.EQ, "true");
|
|
|
+ } catch (Error e) { assert_no_error(e); }
|
|
|
+ });
|
|
|
+
|
|
|
+ // --- Comprehensive: the whole numeric family keeps its JSON wire type ---
|
|
|
+ Test.add_func("/invercargill/from_element/numeric_family", () => {
|
|
|
+ string check(string label, Value v, string expected) {
|
|
|
+ try {
|
|
|
+ var j = new JsonElement.from_element(new ValueElement(v));
|
|
|
+ assert_cmpstr(label, CompareOperator.EQ, label); // keep label on failure
|
|
|
+ return j.stringify();
|
|
|
+ } catch (Error e) {
|
|
|
+ assert_no_error(e);
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ var vi = Value(typeof(int)); vi.set_int(42);
|
|
|
+ assert_cmpstr(check("int", vi, ""), CompareOperator.EQ, "42");
|
|
|
+ var vu = Value(typeof(uint)); vu.set_uint(42u);
|
|
|
+ assert_cmpstr(check("uint", vu, ""), CompareOperator.EQ, "42");
|
|
|
+ var vc = Value(typeof(int8)); vc.set_schar(-3);
|
|
|
+ assert_cmpstr(check("int8", vc, ""), CompareOperator.EQ, "-3");
|
|
|
+ var vuc = Value(typeof(uint8)); vuc.set_uchar(3);
|
|
|
+ assert_cmpstr(check("uint8", vuc, ""), CompareOperator.EQ, "3");
|
|
|
+ var vd = Value(typeof(double)); vd.set_double(3.5);
|
|
|
+ assert_cmpstr(check("double", vd, ""), CompareOperator.EQ, "3.5");
|
|
|
+ var vf = Value(typeof(float)); vf.set_float(2.5f);
|
|
|
+ assert_cmpstr(check("float", vf, ""), CompareOperator.EQ, "2.5");
|
|
|
+ });
|
|
|
+
|
|
|
+ // --- Reported encryption path: from_properties with mixed scalars ---
|
|
|
+ Test.add_func("/invercargill/from_properties/mixed_scalars_roundtrip", () => {
|
|
|
+ if (Test.subprocess()) {
|
|
|
+ var dict = new PropertyDictionary();
|
|
|
+ var vi = Value(typeof(int64)); vi.set_int64(12345678901234);
|
|
|
+ dict.set("id", new ValueElement(vi));
|
|
|
+ var vb = Value(typeof(bool)); vb.set_boolean(true);
|
|
|
+ dict.set("admin", new ValueElement(vb));
|
|
|
+ var vl = Value(typeof(long)); vl.set_long(7);
|
|
|
+ dict.set("count", new ValueElement(vl));
|
|
|
+ try {
|
|
|
+ var j = new JsonElement.from_properties(dict);
|
|
|
+ var obj = new JsonElement.from_string(j.stringify()).assert_as<JsonObject>();
|
|
|
+ int64 id = obj.get_integer("id");
|
|
|
+ assert(id == (int64)12345678901234);
|
|
|
+ assert(obj.get_bool("admin") == true);
|
|
|
+ int64 count = obj.get_integer("count");
|
|
|
+ assert(count == (int64)7);
|
|
|
+ } catch (Error e) { assert_no_error(e); }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Test.trap_subprocess(null, 0, 0);
|
|
|
+ Test.trap_assert_passed();
|
|
|
+ });
|
|
|
+
|
|
|
+}
|