From 7d3e2bd2c4cfd1296d1d6f996d7548de26540d41 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Fri, 15 Feb 2013 16:27:18 -0800 Subject: Sync with 8 months of Google-internal development. Many things have changed and been simplified. The memory-management story for upb_def and upb_handlers is much more robust; upb_def and upb_handlers should be fairly stable interfaces now. There is still much work to do for the runtime component (upb_sink). --- bindings/lua/test.lua | 345 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 249 insertions(+), 96 deletions(-) (limited to 'bindings/lua/test.lua') diff --git a/bindings/lua/test.lua b/bindings/lua/test.lua index 42bce25..6b162a9 100644 --- a/bindings/lua/test.lua +++ b/bindings/lua/test.lua @@ -1,109 +1,262 @@ -require "upb" +local upb = require "upb" +local lunit = require "lunitx" -symtab = upb.SymbolTable{ - upb.MessageDef{fqname="A", fields={ - upb.FieldDef{name="a", type=upb.TYPE_INT32, number=1}, - upb.FieldDef{name="b", type=upb.TYPE_DOUBLE, number=2}} +if _VERSION >= 'Lua 5.2' then + _ENV = lunit.module("testupb", "seeall") +else + module("testupb", lunit.testcase, package.seeall) +end + +function test_fielddef() + local f = upb.FieldDef() + assert_false(f:is_frozen()) + assert_nil(f:number()) + assert_nil(f:name()) + assert_equal(upb.LABEL_OPTIONAL, f:label()) + + f:set_name("foo_field") + f:set_number(3) + f:set_label(upb.LABEL_REPEATED) + f:set_type(upb.TYPE_FLOAT) + + assert_equal("foo_field", f:name()) + assert_equal(3, f:number()) + assert_equal(upb.LABEL_REPEATED, f:label()) + assert_equal(upb.TYPE_FLOAT, f:type()) + + local f2 = upb.FieldDef{ + name = "foo", number = 5, type = upb.TYPE_DOUBLE, label = upb.LABEL_REQUIRED } -} - -symtab = upb.SymbolTable{ - upb.MessageDef{fqname="A", fields={ - upb.FieldDef{name="a", type=upb.TYPE_INT32, number=1}, - upb.FieldDef{name="b", type=upb.TYPE_DOUBLE, number=2}} - }, - upb.MessageDef{fqname="B"} -} -A, B, C = symtab:lookup("A", "B") -print(A) -print(B) -print(C) - -a = A() -a2 = upb.Message(A) -print("YO! a.a=" .. tostring(a.a) .. ", a2.a=" .. tostring(a2.a)) -a.a = 2 -a2.a = 3 -print("YO! a.a=" .. tostring(a.a) .. ", a2.a=" .. tostring(a2.a)) - -A = symtab:lookup("A") -if not A then - error("Could not find A") + + assert_equal("foo", f2:name()) + assert_equal(5, f2:number()) + assert_equal(upb.TYPE_DOUBLE, f2:type()) + assert_equal(upb.LABEL_REQUIRED, f2:label()) end -f = io.open("../../upb/descriptor.pb") -if not f then - error("Couldn't open descriptor.pb, try running 'make descriptorgen'") +function test_enumdef() + local e = upb.EnumDef() + assert_equal(0, #e) + assert_nil(e:value(5)) + assert_nil(e:value("NONEXISTENT_NAME")) + + for name, value in e:values() do + fail() + end + + e:add("VAL1", 1) + e:add("VAL2", 2) + + local values = {} + for name, value in e:values() do + values[name] = value + end + + assert_equal(1, values["VAL1"]) + assert_equal(2, values["VAL2"]) + + local e2 = upb.EnumDef{ + values = { + {"FOO", 1}, + {"BAR", 77}, + } + } + + assert_equal(1, e2:value("FOO")) + assert_equal(77, e2:value("BAR")) + assert_equal("FOO", e2:value(1)) + assert_equal("BAR", e2:value(77)) end -symtab:parsedesc(f:read("*all")) -symtab:load_descriptor() -symtab:load_descriptor_file() -upb.pb.load_descriptor(f:read("*all")) +function test_empty_msgdef() + local md = upb.MessageDef() + assert_nil(md:full_name()) -- Def without name is anonymous. + assert_false(md:is_frozen()) + assert_equal(0, #md) + assert_nil(md:field("nonexistent_field")) + assert_nil(md:field(3)) + for field in md:fields() do + fail() + end + + upb.freeze(md) + assert_true(md:is_frozen()) + assert_equal(0, #md) + assert_nil(md:field("nonexistent_field")) + assert_nil(md:field(3)) + for field in md:fields() do + fail() + end +end + +function test_msgdef_constructor() + local f1 = upb.FieldDef{name = "field1", number = 7, type = upb.TYPE_INT32} + local f2 = upb.FieldDef{name = "field2", number = 8, type = upb.TYPE_INT32} + local md = upb.MessageDef{ + full_name = "TestMessage", + fields = {f1, f2} + } + assert_equal("TestMessage", md:full_name()) + assert_false(md:is_frozen()) + assert_equal(2, #md) + assert_equal(f1, md:field("field1")) + assert_equal(f2, md:field("field2")) + assert_equal(f1, md:field(7)) + assert_equal(f2, md:field(8)) + local count = 0 + local found = {} + for field in md:fields() do + count = count + 1 + found[field] = true + end + assert_equal(2, count) + assert_true(found[f1]) + assert_true(found[f2]) -upb.pb.load_descriptor_file("../../src/descriptor.pb", symtab) + upb.freeze(md) +end + +function test_msgdef_setters() + local md = upb.MessageDef() + md:set_full_name("Message1") + assert_equal("Message1", md:full_name()) + local f = upb.FieldDef{name = "field1", number = 3, type = upb.TYPE_DOUBLE} + md:add{f} + assert_equal(1, #md) + assert_equal(f, md:field("field1")) +end + +function test_msgdef_errors() + assert_error(function() upb.MessageDef{bad_initializer_key = 5} end) + local md = upb.MessageDef() + assert_error(function() + -- Duplicate field number. + upb.MessageDef{ + fields = { + upb.FieldDef{name = "field1", number = 1, type = upb.TYPE_INT32}, + upb.FieldDef{name = "field2", number = 1, type = upb.TYPE_INT32} + } + } + end) + assert_error(function() + -- Duplicate field name. + upb.MessageDef{ + fields = { + upb.FieldDef{name = "field1", number = 1, type = upb.TYPE_INT32}, + upb.FieldDef{name = "field1", number = 2, type = upb.TYPE_INT32} + } + } + end) + + -- attempt to set a name with embedded NULLs. + assert_error_match("names cannot have embedded NULLs", function() + md:set_full_name("abc\0def") + end) + + upb.freeze(md) + -- Attempt to mutate frozen MessageDef. + -- TODO(haberman): better error message and test for message. + assert_error(function() + md:add{upb.FieldDef{name = "field1", number = 1, type = upb.TYPE_INT32}} + end) + assert_error(function() + md:set_full_name("abc") + end) + + -- Attempt to freeze a msgdef without freezing its subdef. + assert_error_match("is not frozen or being frozen", function() + m1 = upb.MessageDef() + upb.freeze( + upb.MessageDef{ + fields = { + upb.FieldDef{name = "f1", number = 1, type = upb.TYPE_MESSAGE, + subdef = m1} + } + } + ) + end) +end + +function test_symtab() + local empty = upb.SymbolTable() + assert_equal(0, #empty:getdefs(upb.DEF_ANY)) + + local symtab = upb.SymbolTable{ + upb.MessageDef{full_name = "TestMessage"}, + upb.MessageDef{full_name = "ContainingMessage", fields = { + upb.FieldDef{name = "field1", number = 1, type = upb.TYPE_INT32}, + upb.FieldDef{name = "field2", number = 2, type = upb.TYPE_MESSAGE, + subdef_name = ".TestMessage"} + } + } + } + + local msgdef1 = symtab:lookup("TestMessage") + local msgdef2 = symtab:lookup("ContainingMessage") + assert_not_nil(msgdef1) + assert_not_nil(msgdef2) + assert_equal(msgdef1, msgdef2:field("field2"):subdef()) + assert_true(msgdef1:is_frozen()) + assert_true(msgdef2:is_frozen()) + + symtab:add{ + upb.MessageDef{full_name = "ContainingMessage2", fields = { + upb.FieldDef{name = "field5", number = 5, type = upb.TYPE_MESSAGE, + subdef = msgdef2} + } + } + } + + local msgdef3 = symtab:lookup("ContainingMessage2") + assert_not_nil(msgdef3) + assert_equal(msgdef3:field("field5"):subdef(), msgdef2) +end -f = io.open("../../benchmarks/google_messages.proto.pb") -if not f then - error("Couldn't open google_messages.proto.pb, try running 'make benchmarks'") +-- Lua 5.1 and 5.2 have slightly different semantics for how a finalizer +-- can be defined in Lua. +if _VERSION >= 'Lua 5.2' then + function defer(fn) + setmetatable({}, { __gc = fn }) + end +else + function defer(fn) + getmetatable(newproxy(true)).__gc = fn + end end -symtab:parsedesc(f:read("*all")) -for _, def in ipairs(symtab:getdefs(-1)) do - print(def:name()) +function test_finalizer() + -- Tests that we correctly handle a call into an already-finalized object. + -- Collectible objects are finalized in the opposite order of creation. + do + local t = {} + defer(function() + assert_error_match("called into dead def", function() + -- Generic def call. + t[1]:full_name() + end) + assert_error_match("called into dead msgdef", function() + -- Specific msgdef call. + t[1]:add() + end) + assert_error_match("called into dead enumdef", function() + t[2]:values() + end) + assert_error_match("called into dead fielddef", function() + t[3]:number() + end) + assert_error_match("called into dead symtab", + function() t[4]:lookup() + end) + end) + t = { + upb.MessageDef(), + upb.EnumDef(), + upb.FieldDef(), + upb.SymbolTable(), + } + end + collectgarbage() end -SpeedMessage1 = symtab:lookup("benchmarks.SpeedMessage1") -SpeedMessage2 = symtab:lookup("benchmarks.SpeedMessage2") -print(SpeedMessage1:name()) - -msg = MyType() -msg:Decode(str) - -msg:DecodeJSON(str) - -msg = upb.pb.decode(str, MyType) -str = upb.pb.encode(msg) - -msg = upb.pb.decode_text(str, MyType) -str = upb.pb.encode_text(msg) - -upb.clear(msg) -upb.msgdef(msg) -upb.has(msg, "foo_bar") - -msg = upb.json.decode(str, MyType) - -msg = upb.pb.DecodeText(str) -msg = upb.pb.EncodeText(msg) -upb. - -upb.pb.decode_into(msg, str) - -str = upb.json.Encode(msg) -upb.json.DecodeInto(msg, str) -f = assert(io.open("../../benchmarks/google_message1.dat")) -msg:Parse(f:read("*all")) -print(msg:ToText()) -print(upb.json.encode(msg)) - -msg = SpeedMessage2() -f = assert(io.open("../../benchmarks/google_message2.dat")) -msg:Parse(f:read("*all")) -print(msg:ToText()) ---msg:Serialize() ---msg:FromText(str) --- print(msg.field129) --- print(msg.field271) ---print(msg.field15.field15) ---msg.field15.field15 = "my override" ---print(msg.field15.field15) --- print(msg.field1) --- print(msg.field1) --- msg.field1 = "YEAH BABY!" --- print(msg.field1) --- print(msg.field129) --- msg.field129 = 5 --- print(msg.field129) ---]] +lunit.main() -- cgit v1.2.3