~bigbes/tarantool

tarantool-protobuf

ref: 2df86386f587e8b84867c9f144bd76a801c3a9d6 tarantool-protobuf/test/codegen_lua_package_test.lua -rw-r--r-- 4.0 KiB
2df86386 — Eugene Blikh beads: close drm (encode/decode B/op floor investigation) 2 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
-- Regression test for (tarantool.lua_package) file option.
--
-- The option lives on FileOptions as extension field 60001 and overrides
-- the default `<pkg>.<file>_pb` Lua require path. The plugin parses the
-- extension via protoreflect/protoregistry, so this test guards against
-- the option silently becoming a no-op when the extension is not
-- registered in the global type registry (the failure mode is that
-- proto.GetExtension returns "" and the override is lost).
--
-- Coverage:
--   * The on-disk output path follows `lua_package`, not `<pkg>/<file>_pb`.
--   * Cross-file `import "other.proto"` rewrites to `require("<lua_package>")`.

local t = require('luatest')
local fio = require('fio')

local g = t.group('codegen_lua_package')

local REPO_ROOT = fio.abspath(fio.pathjoin(
    fio.dirname(debug.getinfo(1, 'S').source:sub(2)), '..'))
local OPTIONS_DIR = fio.pathjoin(REPO_ROOT, 'options')
local PLUGIN = fio.pathjoin(REPO_ROOT, 'protoc-gen-tarantool')

local function spit(path, content)
    local f = assert(io.open(path, 'wb'))
    f:write(content)
    f:close()
end

local function slurp(path)
    local f = assert(io.open(path, 'rb'))
    local s = f:read('*a')
    f:close()
    return s
end

local function ensure_plugin()
    if fio.path.exists(PLUGIN) then return end
    local cmd = string.format('cd %q && go build -o %s ./cmd/protoc-gen-tarantool',
                              REPO_ROOT, fio.basename(PLUGIN))
    assert(os.execute(cmd) == 0 or os.execute(cmd) == true,
           'failed to build plugin: ' .. cmd)
end

local SAMPLE_PROTO = [[
syntax = "proto3";
package sample;
import "tarantool/tarantool.proto";
option (tarantool.lua_package) = "myapp.proto.sample";
message Foo { int32 x = 1; }
]]

local OTHER_PROTO = [[
syntax = "proto3";
package other;
import "tarantool/tarantool.proto";
import "sample.proto";
option (tarantool.lua_package) = "myapp.proto.other";
message Bar { sample.Foo foo = 1; }
]]

local function run_plugin(mode)
    local tmp = fio.tempdir()
    local proto_dir = fio.pathjoin(tmp, 'proto')
    local out_dir = fio.pathjoin(tmp, 'out')
    assert(fio.mkdir(proto_dir))
    assert(fio.mkdir(out_dir))
    spit(fio.pathjoin(proto_dir, 'sample.proto'), SAMPLE_PROTO)
    spit(fio.pathjoin(proto_dir, 'other.proto'), OTHER_PROTO)

    local cmd = string.format(
        'protoc --plugin=%q --tarantool_out=%q --tarantool_opt=mode=%s '
        ..'-I %q -I %q %q %q',
        PLUGIN, out_dir, mode, proto_dir, OPTIONS_DIR,
        fio.pathjoin(proto_dir, 'sample.proto'),
        fio.pathjoin(proto_dir, 'other.proto'))
    local ok = os.execute(cmd)
    assert(ok == 0 or ok == true, 'plugin failed: ' .. cmd)
    return out_dir
end

g.before_all(function()
    ensure_plugin()
end)

for _, mode in ipairs({'full', 'runtime'}) do
    g['test_output_path_honors_lua_package_'..mode] = function()
        local out = run_plugin(mode)
        t.assert(fio.path.exists(fio.pathjoin(out, 'myapp', 'proto', 'sample.lua')),
                 'expected sample.lua under lua_package path, got: '
                 .. table.concat(fio.glob(fio.pathjoin(out, '**', '*.lua')) or {}, ', '))
        t.assert(fio.path.exists(fio.pathjoin(out, 'myapp', 'proto', 'other.lua')),
                 'expected other.lua under lua_package path')
        -- Default `<pkg>/<file>_pb.lua` layout must NOT be present —
        -- that's the regression signature (extension dropped, fallback used).
        t.assert_not(fio.path.exists(fio.pathjoin(out, 'sample', 'sample_pb.lua')),
                     'fallback path was emitted — lua_package option was ignored')
    end

    g['test_cross_file_require_honors_lua_package_'..mode] = function()
        local out = run_plugin(mode)
        local body = slurp(fio.pathjoin(out, 'myapp', 'proto', 'other.lua'))
        t.assert_str_contains(body, 'require("myapp.proto.sample")', false,
            'cross-file import should resolve via lua_package, not the default path')
        t.assert_not(string.find(body, 'require("sample.sample_pb")', 1, true),
                     'default require path leaked into cross-file import')
    end
end