-- Tests for bd-rmf / ra6 3k: WKT override-hook passthrough. -- -- A plan whose descriptor carries desc.encode / desc.decode dispatches -- straight to those overrides instead of walking fields. The Event -- message exercises every WKT shape we ship — Timestamp, Duration, -- Empty, the Value wrappers, Struct, Value, ListValue, Any, -- FieldMask — so byte-equality with mode=full proves the override is -- live at both the top level and when nested as a sub-message field. -- -- Acceptance per bd-rmf: hello.Event with WKT sub-messages round-trips -- byte-equal to mode=full pure-Lua, runtime/pb/wkt.lua is unmodified. local t = require('luatest') local datetime = require('datetime') local pb = require('pb') local c_runtime = pb.c_runtime local function skip_if_no_c() if c_runtime == nil then t.skip('PB_ENABLE_C not set or pb.c_runtime not available') end end local full_hello for _, mode in ipairs({'full', 'runtime'}) do local g = t.group('c_runtime_wkt.' .. mode) local hello g.before_all(function() skip_if_no_c() hello = require(mode .. '.hello.hello_pb') full_hello = require('full.hello.hello_pb') end) g.before_each(skip_if_no_c) -- ---------- Top-level override dispatch ---------- function g.test_timestamp_top_level_encode_decode() local plan = c_runtime.compile_plan(pb.wkt.Timestamp_descriptor) local dt = datetime.new({timestamp = 1700000000, nsec = 123}) local c_bytes = c_runtime.encode(plan, dt) t.assert_equals(c_bytes, pb.wkt.Timestamp_encode(dt)) local out = c_runtime.decode(plan, c_bytes) t.assert(datetime.is_datetime(out)) t.assert_equals(out.epoch, 1700000000) t.assert_equals(out.nsec, 123) end function g.test_duration_top_level_round_trip() local plan = c_runtime.compile_plan(pb.wkt.Duration_descriptor) local v = {seconds = 7200, nanos = 500} local c_bytes = c_runtime.encode(plan, v) t.assert_equals(c_bytes, pb.wkt.Duration_encode(v)) t.assert_equals(c_runtime.decode(plan, c_bytes), pb.wkt.Duration_decode(c_bytes)) end function g.test_empty_top_level_encode_is_zero_bytes() local plan = c_runtime.compile_plan(pb.wkt.Empty_descriptor) t.assert_equals(c_runtime.encode(plan, {}), '') end function g.test_int32value_wrapper_top_level() local plan = c_runtime.compile_plan(pb.wkt.Int32Value_descriptor) -- The wrapper accepts the bare scalar; presence is meaningful. t.assert_equals(c_runtime.encode(plan, 42), pb.wkt.Int32Value_encode(42)) end -- ---------- Nested override dispatch (sub-message field) ---------- function g.test_event_with_timestamp_byte_equal() local plan = c_runtime.compile_plan(hello.Event_descriptor) local msg = { title = 'hi', created_at = datetime.new( {timestamp = 1700000000, nsec = 123456789}), } t.assert_equals(c_runtime.encode(plan, msg), full_hello.Event_encode(msg)) end function g.test_event_with_duration_and_empty_byte_equal() local plan = c_runtime.compile_plan(hello.Event_descriptor) local msg = { title = 'hi', duration = {seconds = 60, nanos = 0}, ack = {}, } t.assert_equals(c_runtime.encode(plan, msg), full_hello.Event_encode(msg)) end function g.test_event_with_wrappers_byte_equal() local plan = c_runtime.compile_plan(hello.Event_descriptor) local msg = { retry_count = 5, note = 'remember', is_admin = true, } t.assert_equals(c_runtime.encode(plan, msg), full_hello.Event_encode(msg)) end function g.test_event_with_wrapper_zero_preserved() local plan = c_runtime.compile_plan(hello.Event_descriptor) -- Wrappers preserve presence at zero — the override must still -- emit tag + len(0). A naive "skip default" path would lose it. local msg = {retry_count = 0} t.assert_equals(c_runtime.encode(plan, msg), full_hello.Event_encode(msg)) end function g.test_event_with_fieldmask_byte_equal() local plan = c_runtime.compile_plan(hello.Event_descriptor) local msg = {update_mask = {paths = {'foo', 'bar.baz'}}} t.assert_equals(c_runtime.encode(plan, msg), full_hello.Event_encode(msg)) end -- ---------- Round-trip parity through the C path ---------- -- -- Encode in C, decode in C, compare against mode=full's decode of -- the same wire bytes. Asserts the override decode wrapper hands -- back the same Lua representation the pure-Lua codec does. function g.test_event_round_trip_through_c() local plan = c_runtime.compile_plan(hello.Event_descriptor) local dt = datetime.new({timestamp = 42, nsec = 500}) local msg = { title = 'x', created_at = dt, duration = {seconds = 1, nanos = 2}, ack = {}, retry_count = 7, note = 'hello', update_mask = {paths = {'a', 'b'}}, } local bytes = c_runtime.encode(plan, msg) local c_dec = c_runtime.decode(plan, bytes) local lua_dec = full_hello.Event_decode(bytes) t.assert_equals(c_dec.title, lua_dec.title) t.assert(datetime.is_datetime(c_dec.created_at)) t.assert_equals(c_dec.created_at.epoch, lua_dec.created_at.epoch) t.assert_equals(c_dec.created_at.nsec, lua_dec.created_at.nsec) t.assert_equals(tonumber(c_dec.duration.seconds), tonumber(lua_dec.duration.seconds)) t.assert_equals(c_dec.duration.nanos, lua_dec.duration.nanos) t.assert_equals(type(c_dec.ack), 'table') t.assert_equals(c_dec.retry_count, lua_dec.retry_count) t.assert_equals(c_dec.note, lua_dec.note) t.assert_equals(c_dec.update_mask.paths, lua_dec.update_mask.paths) end end