Created
February 8, 2023 06:18
-
-
Save kurapica/7cf53c2d468e70685b61cf6b817c2bb0 to your computer and use it in GitHub Desktop.
The Interceptor used for unit test, replace the global api in modules
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "PLoop" | |
require "PLoop.System.UnitTest" | |
-- Function defintion in _G | |
function UnitName() | |
return "player" | |
end | |
-- Define an interceptor | |
PLoop(function(_ENV) | |
System.Logger.Default:AddHandler(print) | |
-- The Access Interceptor | |
class "TestNS.AccessInterceptor" (function(_ENV) | |
local _interceptor = Toolset.newtable(true) | |
local function resetModule(module, parent, cache) | |
if cache[module] then return end | |
cache[module] = true | |
for k, v in pairs(module) do | |
if type(v) == "function" and rawget(parent, k) == v then | |
-- Clear module cache | |
rawset(module, k, nil) | |
elseif Class.Validate(v) then | |
-- Clear class defintion environment cache | |
for name, func in Class.GetMethods(v) do | |
resetModule(getfenv(func), parent, cache) | |
break | |
end | |
elseif Interface.Validate(v) then | |
-- Clear interface defintion environment cache | |
for name, func in Interface.GetMethods(v) do | |
resetModule(getfenv(func), parent, cache) | |
break | |
end | |
elseif Struct.Validate(v) then | |
-- Clear struct defintion environment cache | |
for name, func in Struct.GetMethods(v) do | |
resetModule(getfenv(func), parent, cache) | |
break | |
end | |
end | |
end | |
if module.GetModules then | |
for _, m in module:GetModules() do | |
resetModule(m, parent, cache) | |
end | |
end | |
end | |
-- Install the interceptor into module | |
__Arguments__{ Module } | |
function InstallModule(self, module) | |
resetModule(module, _G, {}) | |
for k, v in pairs(_interceptor[self]) do | |
rawset(module, k, v) | |
end | |
end | |
-- UnInstall the interceptor from the module | |
__Arguments__{ Module } | |
function UnInstallModule(self, module) | |
resetModule(module, _interceptor[self], {}) | |
end | |
__Arguments__{ Table } | |
function __ctor(self, table) | |
_interceptor[self] = table | |
end | |
end) | |
Module "TestModule" (function(_ENV) | |
namespace "TestNS" | |
class "A" (function(_ENV) | |
function GetUnitName() | |
return UnitName() | |
end | |
end) | |
end) | |
-- Declare the unit test for Test Module | |
UnitTest "Test.Example" (function(_ENV) | |
-- Prepare the interceptor | |
interceptor = TestNS.AccessInterceptor{ | |
UnitName = function() | |
return "target" | |
end | |
} | |
function OnInit(self) | |
-- Install the interceptor | |
interceptor:InstallModule(Module("TestModule")) | |
end | |
function OnFinal(self) | |
-- UnInstall the interceptor | |
interceptor:UnInstallModule(Module("TestModule")) | |
end | |
__Test__() function test1() | |
local object = TestNS.A() | |
Assert.Equal("target", object:GetUnitName()) | |
end | |
end) | |
print("Before UnitTest", TestNS.A():GetUnitName()) | |
UnitTest("Test"):Run() | |
print("After UnitTest", TestNS.A():GetUnitName()) | |
end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment