Open generalmimon opened 7 months ago
The same problem occurs in Lua - enum_import.lua
also has no require("enum_0")
or require("enum_deep")
but refers to Enum0
and EnumDeep
:
-- This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
--
-- This file is compatible with Lua 5.3
local class = require("class")
require("kaitaistruct")
EnumImport = class.class(KaitaiStruct)
function EnumImport:_init(io, parent, root)
KaitaiStruct._init(self, io)
self._parent = parent
self._root = root or self
self:_read()
end
function EnumImport:_read()
self.pet_1 = Enum0.Animal(self._io:read_u4le())
self.pet_2 = EnumDeep.Container1.Container2.Animal(self._io:read_u4le())
end
Unlike Ruby, test_enum_import.lua
only contains require("enum_import")
and not require("enum_0")
(which is correct since none of the asserts refer to Enum0
, see https://github.com/kaitai-io/kaitai_struct_tests/pull/109). But like in Ruby, the require("enum_0")
is obviously present in test_enum_0.lua
:
-- Autogenerated from KST: please remove this line if doing any edits by hand!
local luaunit = require("luaunit")
-- require("enum_0")
TestEnum0 = {}
function TestEnum0:test_enum_0()
... and as long as it present, EnumImport
passes in Lua despite the missing require("enum_0")
in compiled/lua/enum_import.lua
. Only if you disable it as above, then the EnumImport
test finally breaks:
- 🔴 2 tests broken:
- Enum0: (...)
- EnumImport:
- {"status"=>"passed"}
- {"status"=>"failed",
- "failure"=>
- {"file_name"=>nil,
- "line_num"=>nil,
- "message"=>
- "compiled/lua/enum_import.lua:18: attempt to index a nil value (global 'Enum0')",
- "trace"=>
- "stack traceback:\n" +
- "\tcompiled/lua/enum_import.lua:18: in method '_read'\n" +
- "\tcompiled/lua/enum_import.lua:14: in local 'init'\n" +
- "\t../runtime/lua/class.lua:70: in function <../runtime/lua/class.lua:66>\n" +
- "\t(...tail calls...)\n" +
- "\tspec/lua/test_enum_import.lua:10: in upvalue 'TestEnumImport.test_enum_import'"}}
I was wondering how it is possible that the
EnumImport
test passes in Ruby (see https://ci.kaitai.io/ orci.json:239-243
of theruby/3.3-linux-x86_64
target).The
enum_import.ksy
spec imports two other .ksy specs (enum_0
andenum_deep
) and defines twoseq
fields, each of an enum type defined in one of the imported specs:The problem is that the
enum_import.rb
(still generated by the latest KSC at the time of writing, i.e.29f7a592
) looks like this:Notice that it refers to classes
Enum0
andEnumDeep
on these lines:... but there are no corresponding
require
statements, so the Ruby interpreter should have no idea what these names are. And yet this test passes in Ruby.It turns out that the
require
s in Ruby are "leaky", i.e. they pollute the global namespace. So if any format or test Ruby files running before the aboveenum_import.rb
containrequire 'enum_0'
andrequire 'enum_deep'
(which is what theEnumImport
class needs to run successfully) in the same Ruby interpreter process, the fact that theenum_import.rb
file doesn't itself have therequire
s it needs is not detected by tests.And if you search for
require 'enum_0'
and forrequire 'enum_deep'
, you can see that bothrequire
s have 2 occurrences in test specs.If you disable the
enum_0
inspec/ruby/enum_import_spec.rb
:... it's not enough (i.e. the
EnumImport
test will still pass), becauseenum_0
is also tested directly, sorequire 'enum_0'
is also inspec/ruby/enum_0_spec.rb
:EnumImport
will finally fail (as it should have all this time) only after you disable both theserequire
s: