PC55654

UNC Test/Executor Lvl Test

Aug 7th, 2024
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 28.48 KB | Source Code | 0 0
  1. local passes, fails, undefined = 0, 0, 0
  2. local running = 0
  3.  
  4. local function getGlobal(path)
  5.     local value = getfenv(0)
  6.  
  7.     while value ~= nil and path ~= "" do
  8.         local name, nextValue = string.match(path, "^([^.]+)%.?(.*)$")
  9.         value = value[name]
  10.         path = nextValue
  11.     end
  12.  
  13.     return value
  14. end
  15.  
  16. local function test(name, aliases, callback)
  17.     running += 1
  18.  
  19.     task.spawn(function()
  20.         if not callback then
  21.             print("⏺️ " .. name)
  22.         elseif not getGlobal(name) then
  23.             fails += 1
  24.             warn("⛔ " .. name)
  25.         else
  26.             local success, message = pcall(callback)
  27.    
  28.             if success then
  29.                 passes += 1
  30.                 print("✅ " .. name .. (message and " • " .. message or ""))
  31.             else
  32.                 fails += 1
  33.                 warn("⛔ " .. name .. " failed: " .. message)
  34.             end
  35.         end
  36.    
  37.         local undefinedAliases = {}
  38.    
  39.         for _, alias in ipairs(aliases) do
  40.             if getGlobal(alias) == nil then
  41.                 table.insert(undefinedAliases, alias)
  42.             end
  43.         end
  44.    
  45.         if #undefinedAliases > 0 then
  46.             undefined += 1
  47.             warn("⚠️ " .. table.concat(undefinedAliases, ", "))
  48.         end
  49.  
  50.         running -= 1
  51.     end)
  52. end
  53.  
  54. -- Header and summary
  55.  
  56. print("\n")
  57.  
  58. print("UNC Environment Check")
  59. print("✅ - Pass, ⛔ - Fail, ⏺️ - No test, ⚠️ - Missing aliases\n")
  60.  
  61. task.defer(function()
  62.     repeat task.wait() until running == 0
  63.  
  64.     local rate = math.round(passes / (passes + fails) * 100)
  65.     local outOf = passes .. " out of " .. (passes + fails)
  66.  
  67.     print("\n")
  68.  
  69.     print("UNC Summary")
  70.     print("✅ Tested with a " .. rate .. "% success rate (" .. outOf .. ")")
  71.     print("⛔ " .. fails .. " tests failed")
  72.     print("⚠️ " .. undefined .. " globals are missing aliases")
  73. end)
  74.  
  75. -- Cache
  76.  
  77. test("cache.invalidate", {}, function()
  78.     local container = Instance.new("Folder")
  79.     local part = Instance.new("Part", container)
  80.     cache.invalidate(container:FindFirstChild("Part"))
  81.     assert(part ~= container:FindFirstChild("Part"), "Reference `part` could not be invalidated")
  82. end)
  83.  
  84. test("cache.iscached", {}, function()
  85.     local part = Instance.new("Part")
  86.     assert(cache.iscached(part), "Part should be cached")
  87.     cache.invalidate(part)
  88.     assert(not cache.iscached(part), "Part should not be cached")
  89. end)
  90.  
  91. test("cache.replace", {}, function()
  92.     local part = Instance.new("Part")
  93.     local fire = Instance.new("Fire")
  94.     cache.replace(part, fire)
  95.     assert(part ~= fire, "Part was not replaced with Fire")
  96. end)
  97.  
  98. test("cloneref", {}, function()
  99.     local part = Instance.new("Part")
  100.     local clone = cloneref(part)
  101.     assert(part ~= clone, "Clone should not be equal to original")
  102.     clone.Name = "Test"
  103.     assert(part.Name == "Test", "Clone should have updated the original")
  104. end)
  105.  
  106. test("compareinstances", {}, function()
  107.     local part = Instance.new("Part")
  108.     local clone = cloneref(part)
  109.     assert(part ~= clone, "Clone should not be equal to original")
  110.     assert(compareinstances(part, clone), "Clone should be equal to original when using compareinstances()")
  111. end)
  112.  
  113. -- Closures
  114.  
  115. local function shallowEqual(t1, t2)
  116.     if t1 == t2 then
  117.         return true
  118.     end
  119.  
  120.     local UNIQUE_TYPES = {
  121.         ["function"] = true,
  122.         ["table"] = true,
  123.         ["userdata"] = true,
  124.         ["thread"] = true,
  125.     }
  126.  
  127.     for k, v in pairs(t1) do
  128.         if UNIQUE_TYPES[type(v)] then
  129.             if type(t2[k]) ~= type(v) then
  130.                 return false
  131.             end
  132.         elseif t2[k] ~= v then
  133.             return false
  134.         end
  135.     end
  136.  
  137.     for k, v in pairs(t2) do
  138.         if UNIQUE_TYPES[type(v)] then
  139.             if type(t2[k]) ~= type(v) then
  140.                 return false
  141.             end
  142.         elseif t1[k] ~= v then
  143.             return false
  144.         end
  145.     end
  146.  
  147.     return true
  148. end
  149.  
  150. test("checkcaller", {}, function()
  151.     assert(checkcaller(), "Main scope should return true")
  152. end)
  153.  
  154. test("clonefunction", {}, function()
  155.     local function test()
  156.         return "success"
  157.     end
  158.     local copy = clonefunction(test)
  159.     assert(test() == copy(), "The clone should return the same value as the original")
  160.     assert(test ~= copy, "The clone should not be equal to the original")
  161. end)
  162.  
  163. test("getcallingscript", {})
  164.  
  165. test("getscriptclosure", {"getscriptfunction"}, function()
  166.     local module = game:GetService("CoreGui").RobloxGui.Modules.Common.Constants
  167.     local constants = getrenv().require(module)
  168.     local generated = getscriptclosure(module)()
  169.     assert(constants ~= generated, "Generated module should not match the original")
  170.     assert(shallowEqual(constants, generated), "Generated constant table should be shallow equal to the original")
  171. end)
  172.  
  173. test("hookfunction", {"replaceclosure"}, function()
  174.     local function test()
  175.         return true
  176.     end
  177.     local ref = hookfunction(test, function()
  178.         return false
  179.     end)
  180.     assert(test() == false, "Function should return false")
  181.     assert(ref() == true, "Original function should return true")
  182.     assert(test ~= ref, "Original function should not be same as the reference")
  183. end)
  184.  
  185. test("iscclosure", {}, function()
  186.     assert(iscclosure(print) == true, "Function 'print' should be a C closure")
  187.     assert(iscclosure(function() end) == false, "Executor function should not be a C closure")
  188. end)
  189.  
  190. test("islclosure", {}, function()
  191.     assert(islclosure(print) == false, "Function 'print' should not be a Lua closure")
  192.     assert(islclosure(function() end) == true, "Executor function should be a Lua closure")
  193. end)
  194.  
  195. test("isexecutorclosure", {"checkclosure", "isourclosure"}, function()
  196.     assert(isexecutorclosure(isexecutorclosure) == true, "Did not return true for an executor global")
  197.     assert(isexecutorclosure(newcclosure(function() end)) == true, "Did not return true for an executor C closure")
  198.     assert(isexecutorclosure(function() end) == true, "Did not return true for an executor Luau closure")
  199.     assert(isexecutorclosure(print) == false, "Did not return false for a Roblox global")
  200. end)
  201.  
  202. test("loadstring", {}, function()
  203.     local animate = game:GetService("Players").LocalPlayer.Character.Animate
  204.     local bytecode = getscriptbytecode(animate)
  205.     local func = loadstring(bytecode)
  206.     assert(type(func) ~= "function", "Luau bytecode should not be loadable!")
  207.     assert(assert(loadstring("return ... + 1"))(1) == 2, "Failed to do simple math")
  208.     assert(type(select(2, loadstring("f"))) == "string", "Loadstring did not return anything for a compiler error")
  209. end)
  210.  
  211. test("newcclosure", {}, function()
  212.     local function test()
  213.         return true
  214.     end
  215.     local testC = newcclosure(test)
  216.     assert(test() == testC(), "New C closure should return the same value as the original")
  217.     assert(test ~= testC, "New C closure should not be same as the original")
  218.     assert(iscclosure(testC), "New C closure should be a C closure")
  219. end)
  220.  
  221. -- Console
  222.  
  223. test("rconsoleclear", {"consoleclear"})
  224.  
  225. test("rconsolecreate", {"consolecreate"})
  226.  
  227. test("rconsoledestroy", {"consoledestroy"})
  228.  
  229. test("rconsoleinput", {"consoleinput"})
  230.  
  231. test("rconsoleprint", {"consoleprint"})
  232.  
  233. test("rconsolesettitle", {"rconsolename", "consolesettitle"})
  234.  
  235. -- Crypt
  236.  
  237. test("crypt.base64encode", {"crypt.base64.encode", "crypt.base64_encode", "base64.encode", "base64_encode"}, function()
  238.     assert(crypt.base64encode("test") == "dGVzdA==", "Base64 encoding failed")
  239. end)
  240.  
  241. test("crypt.base64decode", {"crypt.base64.decode", "crypt.base64_decode", "base64.decode", "base64_decode"}, function()
  242.     assert(crypt.base64decode("dGVzdA==") == "test", "Base64 decoding failed")
  243. end)
  244.  
  245. test("crypt.encrypt", {}, function()
  246.     local key = crypt.generatekey()
  247.     local encrypted, iv = crypt.encrypt("test", key, nil, "CBC")
  248.     assert(iv, "crypt.encrypt should return an IV")
  249.     local decrypted = crypt.decrypt(encrypted, key, iv, "CBC")
  250.     assert(decrypted == "test", "Failed to decrypt raw string from encrypted data")
  251. end)
  252.  
  253. test("crypt.decrypt", {}, function()
  254.     local key, iv = crypt.generatekey(), crypt.generatekey()
  255.     local encrypted = crypt.encrypt("test", key, iv, "CBC")
  256.     local decrypted = crypt.decrypt(encrypted, key, iv, "CBC")
  257.     assert(decrypted == "test", "Failed to decrypt raw string from encrypted data")
  258. end)
  259.  
  260. test("crypt.generatebytes", {}, function()
  261.     local size = math.random(10, 100)
  262.     local bytes = crypt.generatebytes(size)
  263.     assert(#crypt.base64decode(bytes) == size, "The decoded result should be " .. size .. " bytes long (got " .. #crypt.base64decode(bytes) .. " decoded, " .. #bytes .. " raw)")
  264. end)
  265.  
  266. test("crypt.generatekey", {}, function()
  267.     local key = crypt.generatekey()
  268.     assert(#crypt.base64decode(key) == 32, "Generated key should be 32 bytes long when decoded")
  269. end)
  270.  
  271. test("crypt.hash", {}, function()
  272.     local algorithms = {'sha1', 'sha384', 'sha512', 'md5', 'sha256', 'sha3-224', 'sha3-256', 'sha3-512'}
  273.     for _, algorithm in ipairs(algorithms) do
  274.         local hash = crypt.hash("test", algorithm)
  275.         assert(hash, "crypt.hash on algorithm '" .. algorithm .. "' should return a hash")
  276.     end
  277. end)
  278.  
  279. --- Debug
  280.  
  281. test("debug.getconstant", {}, function()
  282.     local function test()
  283.         print("Hello, world!")
  284.     end
  285.     assert(debug.getconstant(test, 1) == "print", "First constant must be print")
  286.     assert(debug.getconstant(test, 2) == nil, "Second constant must be nil")
  287.     assert(debug.getconstant(test, 3) == "Hello, world!", "Third constant must be 'Hello, world!'")
  288. end)
  289.  
  290. test("debug.getconstants", {}, function()
  291.     local function test()
  292.         local num = 5000 .. 50000
  293.         print("Hello, world!", num, warn)
  294.     end
  295.     local constants = debug.getconstants(test)
  296.     assert(constants[1] == 50000, "First constant must be 50000")
  297.     assert(constants[2] == "print", "Second constant must be print")
  298.     assert(constants[3] == nil, "Third constant must be nil")
  299.     assert(constants[4] == "Hello, world!", "Fourth constant must be 'Hello, world!'")
  300.     assert(constants[5] == "warn", "Fifth constant must be warn")
  301. end)
  302.  
  303. test("debug.getinfo", {}, function()
  304.     local types = {
  305.         source = "string",
  306.         short_src = "string",
  307.         func = "function",
  308.         what = "string",
  309.         currentline = "number",
  310.         name = "string",
  311.         nups = "number",
  312.         numparams = "number",
  313.         is_vararg = "number",
  314.     }
  315.     local function test(...)
  316.         print(...)
  317.     end
  318.     local info = debug.getinfo(test)
  319.     for k, v in pairs(types) do
  320.         assert(info[k] ~= nil, "Did not return a table with a '" .. k .. "' field")
  321.         assert(type(info[k]) == v, "Did not return a table with " .. k .. " as a " .. v .. " (got " .. type(info[k]) .. ")")
  322.     end
  323. end)
  324.  
  325. test("debug.getproto", {}, function()
  326.     local function test()
  327.         local function proto()
  328.             return true
  329.         end
  330.     end
  331.     local proto = debug.getproto(test, 1, true)[1]
  332.     local realproto = debug.getproto(test, 1)
  333.     assert(proto, "Failed to get the inner function")
  334.     assert(proto() == true, "The inner function did not return anything")
  335.     if not realproto() then
  336.         return "Proto return values are disabled on this executor"
  337.     end
  338. end)
  339.  
  340. test("debug.getprotos", {}, function()
  341.     local function test()
  342.         local function _1()
  343.             return true
  344.         end
  345.         local function _2()
  346.             return true
  347.         end
  348.         local function _3()
  349.             return true
  350.         end
  351.     end
  352.     for i in ipairs(debug.getprotos(test)) do
  353.         local proto = debug.getproto(test, i, true)[1]
  354.         local realproto = debug.getproto(test, i)
  355.         assert(proto(), "Failed to get inner function " .. i)
  356.         if not realproto() then
  357.             return "Proto return values are disabled on this executor"
  358.         end
  359.     end
  360. end)
  361.  
  362. test("debug.getstack", {}, function()
  363.     local _ = "a" .. "b"
  364.     assert(debug.getstack(1, 1) == "ab", "The first item in the stack should be 'ab'")
  365.     assert(debug.getstack(1)[1] == "ab", "The first item in the stack table should be 'ab'")
  366. end)
  367.  
  368. test("debug.getupvalue", {}, function()
  369.     local upvalue = function() end
  370.     local function test()
  371.         print(upvalue)
  372.     end
  373.     assert(debug.getupvalue(test, 1) == upvalue, "Unexpected value returned from debug.getupvalue")
  374. end)
  375.  
  376. test("debug.getupvalues", {}, function()
  377.     local upvalue = function() end
  378.     local function test()
  379.         print(upvalue)
  380.     end
  381.     local upvalues = debug.getupvalues(test)
  382.     assert(upvalues[1] == upvalue, "Unexpected value returned from debug.getupvalues")
  383. end)
  384.  
  385. test("debug.setconstant", {}, function()
  386.     local function test()
  387.         return "fail"
  388.     end
  389.     debug.setconstant(test, 1, "success")
  390.     assert(test() == "success", "debug.setconstant did not set the first constant")
  391. end)
  392.  
  393. test("debug.setstack", {}, function()
  394.     local function test()
  395.         return "fail", debug.setstack(1, 1, "success")
  396.     end
  397.     assert(test() == "success", "debug.setstack did not set the first stack item")
  398. end)
  399.  
  400. test("debug.setupvalue", {}, function()
  401.     local function upvalue()
  402.         return "fail"
  403.     end
  404.     local function test()
  405.         return upvalue()
  406.     end
  407.     debug.setupvalue(test, 1, function()
  408.         return "success"
  409.     end)
  410.     assert(test() == "success", "debug.setupvalue did not set the first upvalue")
  411. end)
  412.  
  413. -- Filesystem
  414.  
  415. if isfolder and makefolder and delfolder then
  416.     if isfolder(".tests") then
  417.         delfolder(".tests")
  418.     end
  419.     makefolder(".tests")
  420. end
  421.  
  422. test("readfile", {}, function()
  423.     writefile(".tests/readfile.txt", "success")
  424.     assert(readfile(".tests/readfile.txt") == "success", "Did not return the contents of the file")
  425. end)
  426.  
  427. test("listfiles", {}, function()
  428.     makefolder(".tests/listfiles")
  429.     writefile(".tests/listfiles/test_1.txt", "success")
  430.     writefile(".tests/listfiles/test_2.txt", "success")
  431.     local files = listfiles(".tests/listfiles")
  432.     assert(#files == 2, "Did not return the correct number of files")
  433.     assert(isfile(files[1]), "Did not return a file path")
  434.     assert(readfile(files[1]) == "success", "Did not return the correct files")
  435.     makefolder(".tests/listfiles_2")
  436.     makefolder(".tests/listfiles_2/test_1")
  437.     makefolder(".tests/listfiles_2/test_2")
  438.     local folders = listfiles(".tests/listfiles_2")
  439.     assert(#folders == 2, "Did not return the correct number of folders")
  440.     assert(isfolder(folders[1]), "Did not return a folder path")
  441. end)
  442.  
  443. test("writefile", {}, function()
  444.     writefile(".tests/writefile.txt", "success")
  445.     assert(readfile(".tests/writefile.txt") == "success", "Did not write the file")
  446.     local requiresFileExt = pcall(function()
  447.         writefile(".tests/writefile", "success")
  448.         assert(isfile(".tests/writefile.txt"))
  449.     end)
  450.     if not requiresFileExt then
  451.         return "This executor requires a file extension in writefile"
  452.     end
  453. end)
  454.  
  455. test("makefolder", {}, function()
  456.     makefolder(".tests/makefolder")
  457.     assert(isfolder(".tests/makefolder"), "Did not create the folder")
  458. end)
  459.  
  460. test("appendfile", {}, function()
  461.     writefile(".tests/appendfile.txt", "su")
  462.     appendfile(".tests/appendfile.txt", "cce")
  463.     appendfile(".tests/appendfile.txt", "ss")
  464.     assert(readfile(".tests/appendfile.txt") == "success", "Did not append the file")
  465. end)
  466.  
  467. test("isfile", {}, function()
  468.     writefile(".tests/isfile.txt", "success")
  469.     assert(isfile(".tests/isfile.txt") == true, "Did not return true for a file")
  470.     assert(isfile(".tests") == false, "Did not return false for a folder")
  471.     assert(isfile(".tests/doesnotexist.exe") == false, "Did not return false for a nonexistent path (got " .. tostring(isfile(".tests/doesnotexist.exe")) .. ")")
  472. end)
  473.  
  474. test("isfolder", {}, function()
  475.     assert(isfolder(".tests") == true, "Did not return false for a folder")
  476.     assert(isfolder(".tests/doesnotexist.exe") == false, "Did not return false for a nonexistent path (got " .. tostring(isfolder(".tests/doesnotexist.exe")) .. ")")
  477. end)
  478.  
  479. test("delfolder", {}, function()
  480.     makefolder(".tests/delfolder")
  481.     delfolder(".tests/delfolder")
  482.     assert(isfolder(".tests/delfolder") == false, "Failed to delete folder (isfolder = " .. tostring(isfolder(".tests/delfolder")) .. ")")
  483. end)
  484.  
  485. test("delfile", {}, function()
  486.     writefile(".tests/delfile.txt", "Hello, world!")
  487.     delfile(".tests/delfile.txt")
  488.     assert(isfile(".tests/delfile.txt") == false, "Failed to delete file (isfile = " .. tostring(isfile(".tests/delfile.txt")) .. ")")
  489. end)
  490.  
  491. test("loadfile", {}, function()
  492.     writefile(".tests/loadfile.txt", "return ... + 1")
  493.     assert(assert(loadfile(".tests/loadfile.txt"))(1) == 2, "Failed to load a file with arguments")
  494.     writefile(".tests/loadfile.txt", "f")
  495.     local callback, err = loadfile(".tests/loadfile.txt")
  496.     assert(err and not callback, "Did not return an error message for a compiler error")
  497. end)
  498.  
  499. test("dofile", {})
  500.  
  501. -- Input
  502.  
  503. test("isrbxactive", {"isgameactive"}, function()
  504.     assert(type(isrbxactive()) == "boolean", "Did not return a boolean value")
  505. end)
  506.  
  507. test("mouse1click", {})
  508.  
  509. test("mouse1press", {})
  510.  
  511. test("mouse1release", {})
  512.  
  513. test("mouse2click", {})
  514.  
  515. test("mouse2press", {})
  516.  
  517. test("mouse2release", {})
  518.  
  519. test("mousemoveabs", {})
  520.  
  521. test("mousemoverel", {})
  522.  
  523. test("mousescroll", {})
  524.  
  525. -- Instances
  526.  
  527. test("fireclickdetector", {}, function()
  528.     local detector = Instance.new("ClickDetector")
  529.     fireclickdetector(detector, 50, "MouseHoverEnter")
  530. end)
  531.  
  532. test("getcallbackvalue", {}, function()
  533.     local bindable = Instance.new("BindableFunction")
  534.     local function test()
  535.     end
  536.     bindable.OnInvoke = test
  537.     assert(getcallbackvalue(bindable, "OnInvoke") == test, "Did not return the correct value")
  538. end)
  539.  
  540. test("getconnections", {}, function()
  541.     local types = {
  542.         Enabled = "boolean",
  543.         ForeignState = "boolean",
  544.         LuaConnection = "boolean",
  545.         Function = "function",
  546.         Thread = "thread",
  547.         Fire = "function",
  548.         Defer = "function",
  549.         Disconnect = "function",
  550.         Disable = "function",
  551.         Enable = "function",
  552.     }
  553.     local bindable = Instance.new("BindableEvent")
  554.     bindable.Event:Connect(function() end)
  555.     local connection = getconnections(bindable.Event)[1]
  556.     for k, v in pairs(types) do
  557.         assert(connection[k] ~= nil, "Did not return a table with a '" .. k .. "' field")
  558.         assert(type(connection[k]) == v, "Did not return a table with " .. k .. " as a " .. v .. " (got " .. type(connection[k]) .. ")")
  559.     end
  560. end)
  561.  
  562. test("getcustomasset", {}, function()
  563.     writefile(".tests/getcustomasset.txt", "success")
  564.     local contentId = getcustomasset(".tests/getcustomasset.txt")
  565.     assert(type(contentId) == "string", "Did not return a string")
  566.     assert(#contentId > 0, "Returned an empty string")
  567.     assert(string.match(contentId, "rbxasset://") == "rbxasset://", "Did not return an rbxasset url")
  568. end)
  569.  
  570. test("gethiddenproperty", {}, function()
  571.     local fire = Instance.new("Fire")
  572.     local property, isHidden = gethiddenproperty(fire, "size_xml")
  573.     assert(property == 5, "Did not return the correct value")
  574.     assert(isHidden == true, "Did not return whether the property was hidden")
  575. end)
  576.  
  577. test("sethiddenproperty", {}, function()
  578.     local fire = Instance.new("Fire")
  579.     local hidden = sethiddenproperty(fire, "size_xml", 10)
  580.     assert(hidden, "Did not return true for the hidden property")
  581.     assert(gethiddenproperty(fire, "size_xml") == 10, "Did not set the hidden property")
  582. end)
  583.  
  584. test("gethui", {}, function()
  585.     assert(typeof(gethui()) == "Instance", "Did not return an Instance")
  586. end)
  587.  
  588. test("getinstances", {}, function()
  589.     assert(getinstances()[1]:IsA("Instance"), "The first value is not an Instance")
  590. end)
  591.  
  592. test("getnilinstances", {}, function()
  593.     assert(getnilinstances()[1]:IsA("Instance"), "The first value is not an Instance")
  594.     assert(getnilinstances()[1].Parent == nil, "The first value is not parented to nil")
  595. end)
  596.  
  597. test("isscriptable", {}, function()
  598.     local fire = Instance.new("Fire")
  599.     assert(isscriptable(fire, "size_xml") == false, "Did not return false for a non-scriptable property (size_xml)")
  600.     assert(isscriptable(fire, "Size") == true, "Did not return true for a scriptable property (Size)")
  601. end)
  602.  
  603. test("setscriptable", {}, function()
  604.     local fire = Instance.new("Fire")
  605.     local wasScriptable = setscriptable(fire, "size_xml", true)
  606.     assert(wasScriptable == false, "Did not return false for a non-scriptable property (size_xml)")
  607.     assert(isscriptable(fire, "size_xml") == true, "Did not set the scriptable property")
  608.     fire = Instance.new("Fire")
  609.     assert(isscriptable(fire, "size_xml") == false, "⚠️⚠️ setscriptable persists between unique instances ⚠️⚠️")
  610. end)
  611.  
  612. test("setrbxclipboard", {})
  613.  
  614. -- Metatable
  615.  
  616. test("getrawmetatable", {}, function()
  617.     local metatable = { __metatable = "Locked!" }
  618.     local object = setmetatable({}, metatable)
  619.     assert(getrawmetatable(object) == metatable, "Did not return the metatable")
  620. end)
  621.  
  622. test("hookmetamethod", {}, function()
  623.     local object = setmetatable({}, { __index = newcclosure(function() return false end), __metatable = "Locked!" })
  624.     local ref = hookmetamethod(object, "__index", function() return true end)
  625.     assert(object.test == true, "Failed to hook a metamethod and change the return value")
  626.     assert(ref() == false, "Did not return the original function")
  627. end)
  628.  
  629. test("getnamecallmethod", {}, function()
  630.     local method
  631.     local ref
  632.     ref = hookmetamethod(game, "__namecall", function(...)
  633.         if not method then
  634.             method = getnamecallmethod()
  635.         end
  636.         return ref(...)
  637.     end)
  638.     game:GetService("Lighting")
  639.     assert(method == "GetService", "Did not get the correct method (GetService)")
  640. end)
  641.  
  642. test("isreadonly", {}, function()
  643.     local object = {}
  644.     table.freeze(object)
  645.     assert(isreadonly(object), "Did not return true for a read-only table")
  646. end)
  647.  
  648. test("setrawmetatable", {}, function()
  649.     local object = setmetatable({}, { __index = function() return false end, __metatable = "Locked!" })
  650.     local objectReturned = setrawmetatable(object, { __index = function() return true end })
  651.     assert(object, "Did not return the original object")
  652.     assert(object.test == true, "Failed to change the metatable")
  653.     if objectReturned then
  654.         return objectReturned == object and "Returned the original object" or "Did not return the original object"
  655.     end
  656. end)
  657.  
  658. test("setreadonly", {}, function()
  659.     local object = { success = false }
  660.     table.freeze(object)
  661.     setreadonly(object, false)
  662.     object.success = true
  663.     assert(object.success, "Did not allow the table to be modified")
  664. end)
  665.  
  666. -- Miscellaneous
  667.  
  668. test("identifyexecutor", {"getexecutorname"}, function()
  669.     local name, version = identifyexecutor()
  670.     assert(type(name) == "string", "Did not return a string for the name")
  671.     return type(version) == "string" and "Returns version as a string" or "Does not return version"
  672. end)
  673.  
  674. test("lz4compress", {}, function()
  675.     local raw = "Hello, world!"
  676.     local compressed = lz4compress(raw)
  677.     assert(type(compressed) == "string", "Compression did not return a string")
  678.     assert(lz4decompress(compressed, #raw) == raw, "Decompression did not return the original string")
  679. end)
  680.  
  681. test("lz4decompress", {}, function()
  682.     local raw = "Hello, world!"
  683.     local compressed = lz4compress(raw)
  684.     assert(type(compressed) == "string", "Compression did not return a string")
  685.     assert(lz4decompress(compressed, #raw) == raw, "Decompression did not return the original string")
  686. end)
  687.  
  688. test("messagebox", {})
  689.  
  690. test("queue_on_teleport", {"queueonteleport"})
  691.  
  692. test("request", {"http.request", "http_request"}, function()
  693.     local response = request({
  694.         Url = "https://httpbin.org/user-agent",
  695.         Method = "GET",
  696.     })
  697.     assert(type(response) == "table", "Response must be a table")
  698.     assert(response.StatusCode == 200, "Did not return a 200 status code")
  699.     local data = game:GetService("HttpService"):JSONDecode(response.Body)
  700.     assert(type(data) == "table" and type(data["user-agent"]) == "string", "Did not return a table with a user-agent key")
  701.     return "User-Agent: " .. data["user-agent"]
  702. end)
  703.  
  704. test("setclipboard", {"toclipboard"})
  705.  
  706. test("setfpscap", {}, function()
  707.     local renderStepped = game:GetService("RunService").RenderStepped
  708.     local function step()
  709.         renderStepped:Wait()
  710.         local sum = 0
  711.         for _ = 1, 5 do
  712.             sum += 1 / renderStepped:Wait()
  713.         end
  714.         return math.round(sum / 5)
  715.     end
  716.     setfpscap(60)
  717.     local step60 = step()
  718.     setfpscap(0)
  719.     local step0 = step()
  720.     return step60 .. "fps @60 • " .. step0 .. "fps @0"
  721. end)
  722.  
  723. -- Scripts
  724.  
  725. test("getgc", {}, function()
  726.     local gc = getgc()
  727.     assert(type(gc) == "table", "Did not return a table")
  728.     assert(#gc > 0, "Did not return a table with any values")
  729. end)
  730.  
  731. test("getgenv", {}, function()
  732.     getgenv().__TEST_GLOBAL = true
  733.     assert(__TEST_GLOBAL, "Failed to set a global variable")
  734.     getgenv().__TEST_GLOBAL = nil
  735. end)
  736.  
  737. test("getloadedmodules", {}, function()
  738.     local modules = getloadedmodules()
  739.     assert(type(modules) == "table", "Did not return a table")
  740.     assert(#modules > 0, "Did not return a table with any values")
  741.     assert(typeof(modules[1]) == "Instance", "First value is not an Instance")
  742.     assert(modules[1]:IsA("ModuleScript"), "First value is not a ModuleScript")
  743. end)
  744.  
  745. test("getrenv", {}, function()
  746.     assert(_G ~= getrenv()._G, "The variable _G in the executor is identical to _G in the game")
  747. end)
  748.  
  749. test("getrunningscripts", {}, function()
  750.     local scripts = getrunningscripts()
  751.     assert(type(scripts) == "table", "Did not return a table")
  752.     assert(#scripts > 0, "Did not return a table with any values")
  753.     assert(typeof(scripts[1]) == "Instance", "First value is not an Instance")
  754.     assert(scripts[1]:IsA("ModuleScript") or scripts[1]:IsA("LocalScript"), "First value is not a ModuleScript or LocalScript")
  755. end)
  756.  
  757. test("getscriptbytecode", {"dumpstring"}, function()
  758.     local animate = game:GetService("Players").LocalPlayer.Character.Animate
  759.     local bytecode = getscriptbytecode(animate)
  760.     assert(type(bytecode) == "string", "Did not return a string for Character.Animate (a " .. animate.ClassName .. ")")
  761. end)
  762.  
  763. test("getscripthash", {}, function()
  764.     local animate = game:GetService("Players").LocalPlayer.Character.Animate:Clone()
  765.     local hash = getscripthash(animate)
  766.     local source = animate.Source
  767.     animate.Source = "print('Hello, world!')"
  768.     task.defer(function()
  769.         animate.Source = source
  770.     end)
  771.     local newHash = getscripthash(animate)
  772.     assert(hash ~= newHash, "Did not return a different hash for a modified script")
  773.     assert(newHash == getscripthash(animate), "Did not return the same hash for a script with the same source")
  774. end)
  775.  
  776. test("getscripts", {}, function()
  777.     local scripts = getscripts()
  778.     assert(type(scripts) == "table", "Did not return a table")
  779.     assert(#scripts > 0, "Did not return a table with any values")
  780.     assert(typeof(scripts[1]) == "Instance", "First value is not an Instance")
  781.     assert(scripts[1]:IsA("ModuleScript") or scripts[1]:IsA("LocalScript"), "First value is not a ModuleScript or LocalScript")
  782. end)
  783.  
  784. test("getsenv", {}, function()
  785.     local animate = game:GetService("Players").LocalPlayer.Character.Animate
  786.     local env = getsenv(animate)
  787.     assert(type(env) == "table", "Did not return a table for Character.Animate (a " .. animate.ClassName .. ")")
  788.     assert(env.script == animate, "The script global is not identical to Character.Animate")
  789. end)
  790.  
  791. test("getthreadidentity", {"getidentity", "getthreadcontext"}, function()
  792.     assert(type(getthreadidentity()) == "number", "Did not return a number")
  793. end)
  794.  
  795. test("setthreadidentity", {"setidentity", "setthreadcontext"}, function()
  796.     setthreadidentity(3)
  797.     assert(getthreadidentity() == 3, "Did not set the thread identity")
  798. end)
  799.  
  800. -- Drawing
  801.  
  802. test("Drawing", {})
  803.  
  804. test("Drawing.new", {}, function()
  805.     local drawing = Drawing.new("Square")
  806.     drawing.Visible = false
  807.     local canDestroy = pcall(function()
  808.         drawing:Destroy()
  809.     end)
  810.     assert(canDestroy, "Drawing:Destroy() should not throw an error")
  811. end)
  812.  
  813. test("Drawing.Fonts", {}, function()
  814.     assert(Drawing.Fonts.UI == 0, "Did not return the correct id for UI")
  815.     assert(Drawing.Fonts.System == 1, "Did not return the correct id for System")
  816.     assert(Drawing.Fonts.Plex == 2, "Did not return the correct id for Plex")
  817.     assert(Drawing.Fonts.Monospace == 3, "Did not return the correct id for Monospace")
  818. end)
  819.  
  820. test("isrenderobj", {}, function()
  821.     local drawing = Drawing.new("Image")
  822.     drawing.Visible = true
  823.     assert(isrenderobj(drawing) == true, "Did not return true for an Image")
  824.     assert(isrenderobj(newproxy()) == false, "Did not return false for a blank table")
  825. end)
  826.  
  827. test("getrenderproperty", {}, function()
  828.     local drawing = Drawing.new("Image")
  829.     drawing.Visible = true
  830.     assert(type(getrenderproperty(drawing, "Visible")) == "boolean", "Did not return a boolean value for Image.Visible")
  831.     local success, result = pcall(function()
  832.         return getrenderproperty(drawing, "Color")
  833.     end)
  834.     if not success or not result then
  835.         return "Image.Color is not supported"
  836.     end
  837. end)
  838.  
  839. test("setrenderproperty", {}, function()
  840.     local drawing = Drawing.new("Square")
  841.     drawing.Visible = true
  842.     setrenderproperty(drawing, "Visible", false)
  843.     assert(drawing.Visible == false, "Did not set the value for Square.Visible")
  844. end)
  845.  
  846. test("cleardrawcache", {}, function()
  847.     cleardrawcache()
  848. end)
  849.  
  850. -- WebSocket
  851.  
  852. test("WebSocket", {})
  853.  
  854. test("WebSocket.connect", {}, function()
  855.     local types = {
  856.         Send = "function",
  857.         Close = "function",
  858.         OnMessage = {"table", "userdata"},
  859.         OnClose = {"table", "userdata"},
  860.     }
  861.     local ws = WebSocket.connect("ws://echo.websocket.events")
  862.     assert(type(ws) == "table" or type(ws) == "userdata", "Did not return a table or userdata")
  863.     for k, v in pairs(types) do
  864.         if type(v) == "table" then
  865.             assert(table.find(v, type(ws[k])), "Did not return a " .. table.concat(v, ", ") .. " for " .. k .. " (a " .. type(ws[k]) .. ")")
  866.         else
  867.             assert(type(ws[k]) == v, "Did not return a " .. v .. " for " .. k .. " (a " .. type(ws[k]) .. ")")
  868.         end
  869.     end
  870.     ws:Close()
  871. end)
Add Comment
Please, Sign In to add comment