From 2678c4c3ffd02199f5b70e5212f0d265be91a61f Mon Sep 17 00:00:00 2001 From: AbigailBuccaneer Date: Thu, 19 Sep 2019 21:16:43 +0100 Subject: [PATCH 1/2] Add some tests for E2 Currently the tests are quite minimal: a test for the E2 parser, and a regression test for #1975. Soon there will be a test harness command that runs all the test E2s and watches for errors. --- data/expression2/tests/parsing.txt | 88 +++++++++++++++++++ data/expression2/tests/regressions/1975.txt | 11 +++ .../gmod_wire_expression2/core/core.lua | 8 ++ lua/wire/client/e2descriptions.lua | 2 + 4 files changed, 109 insertions(+) create mode 100644 data/expression2/tests/parsing.txt create mode 100644 data/expression2/tests/regressions/1975.txt diff --git a/data/expression2/tests/parsing.txt b/data/expression2/tests/parsing.txt new file mode 100644 index 0000000000..5fe3e48d50 --- /dev/null +++ b/data/expression2/tests/parsing.txt @@ -0,0 +1,88 @@ +@inputs In +@outputs Out + +local A = 0 + +if (A) { A = 0 } +if (A) { A = 0 } else { A = 0 } +if (A) { A = 0 } elseif (A) { A = 0 } +if (A) { A = 0 } elseif (A) { A = 0 } + +while (A) { A = 0 } + +for (B = 1, 2) { A = 0 } +for (B = 1, 2, 3) { A = 0 } + +foreach (K, V: number = array(1, 2, 3)) { A = 0 } + +while (A) { break } +while (A) { continue } + +A++ +A-- +A += 1 +A -= 1 +A *= 1 +A /= 1 + +local B = vec() +B[1] = 2 + +switch (A) { + case A + A, + A = 0 + A = 0 + case A + A + A, + A = 0 + break + default, + A = 0 +} + +function f() {} +function void f() {} +function void f() { return } +function number g() { return 0 } +function number f(X) { return X } +function vector f(X: vector) { return X } +function number f(X, Y) { return X + Y } +function number f(X, Y: vector) { return X } +function number f([X Y]) { return X + Y } +function number f([X Y]: number) { return X + Y } + +A ? A : A +A ?: A +A | A +A & A +A || A +A && A +A ^^ A +A == A +A != A +A > A +A < A +A >= A +A <= A +A << A +A >> A +A + A +A - A +A * A +A / A +A % A +A ^ A ++A +-A +!A + +array():count() +array()[0, number] +(A) +0 +"foo" +~In +$In +->In +A + +table(1 = 1, 2 = 2) diff --git a/data/expression2/tests/regressions/1975.txt b/data/expression2/tests/regressions/1975.txt new file mode 100644 index 0000000000..d94fbb6997 --- /dev/null +++ b/data/expression2/tests/regressions/1975.txt @@ -0,0 +1,11 @@ +vec() * 0 +0 * vec() + +local Calls = 0 +function number f() { + Calls++ + return 1 +} +f() * 0 +0 * f() +assert(Calls == 2) diff --git a/lua/entities/gmod_wire_expression2/core/core.lua b/lua/entities/gmod_wire_expression2/core/core.lua index 626cdca76a..de6097a7b1 100644 --- a/lua/entities/gmod_wire_expression2/core/core.lua +++ b/lua/entities/gmod_wire_expression2/core/core.lua @@ -318,6 +318,14 @@ e2function void error( string reason ) error(reason, 2) end +e2function void assert(condition) + if not condition then error("assert failed", 2) end +end + +e2function void assert(condition, string reason) + if not condition then error(reason, 2) end +end + -------------------------------------------------------------------------------- __e2setcost(100) -- approximation diff --git a/lua/wire/client/e2descriptions.lua b/lua/wire/client/e2descriptions.lua index 5f3b634e5f..e7c4813e42 100644 --- a/lua/wire/client/e2descriptions.lua +++ b/lua/wire/client/e2descriptions.lua @@ -824,6 +824,8 @@ E2Helper.Descriptions["setName(e:s)"] = "Set the name of another E2 or component E2Helper.Descriptions["cpuUsage()"] = "Returns the average time per tick the server spends running this E2, in seconds (multiply it by 1000000 to get the same value as is displayed on the E2 overlay)" E2Helper.Descriptions["cpuUsage(e:)"] = "Returns the average time per tick the server spends running the specified E2, in seconds (multiply it by 1000000 to get the same value as is displayed on the E2 overlay)" E2Helper.Descriptions["error(s)"] = "Shuts down the E2 with specified script error message" +E2Helper.Descriptions["assert(n)"] = "If the argument is 0, shut down the E2 with an error message" +E2Helper.Descriptions["assert(ns)"] = "If the first argument is 0, shut down the E2 with the given error message string" E2Helper.Descriptions["reset()"] = "Reset the expression itself as if it was just spawned, stops execution" E2Helper.Descriptions["exit()"] = "Stops the execution of any code after it" E2Helper.Descriptions["getCode()"] = "Returns the code of the E2 as a string" From ff8ab0da39845158d3e217a873aae7af9b5e32c5 Mon Sep 17 00:00:00 2001 From: AbigailBuccaneer Date: Fri, 20 Sep 2019 16:36:22 +0100 Subject: [PATCH 2/2] Don't add E2 tests to Wiremod's default data files These tests are for developers and so shouldn't be shipped to people who just install the addon through the workshop. --- lua/wire/default_data_decompressor.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lua/wire/default_data_decompressor.lua b/lua/wire/default_data_decompressor.lua index 9b899391a6..1038c87ee5 100644 --- a/lua/wire/default_data_decompressor.lua +++ b/lua/wire/default_data_decompressor.lua @@ -1,8 +1,13 @@ -- Garry has imposed a file extension whitelist for the Steam Workshop which does not permit the dangerous format .txt -- Therefore, we must store our .txt's in default_data_files.lua, and then extract them when first run +local ignored_dirs = { + ["expression2/tests"] = true, +} + -- Compress all files in addons/wire/data recursively into 1 json string local function ReadDir(root) + if ignored_dirs[root] then return nil end local tab = {} local files,dirs = file.Find("addons/wire/data/"..root.."*","GAME") for _, f in pairs(files) do @@ -16,7 +21,7 @@ local function ReadDir(root) return tab end -- Uncomment and Rename this file to wire/lua/wire/default_data_files.lua to update it -//file.Write("default_data_files.txt", "//"..util.TableToJSON(ReadDir(""))) +-- file.Write("default_data_files.txt", "//"..util.TableToJSON(ReadDir(""))) -- Decompress the json string wire/lua/wire/default_data_files.lua into the corresponding 36+ default data files local function WriteDir(tab) @@ -34,7 +39,7 @@ if not file.Exists("expression2/_helloworld_.txt", "DATA") then local compressed = file.Read("wire/default_data_files.lua","LUA") -- The client cannot read lua files sent by the server (for security?), so clientside this'll only work -- if the client actually has Wiremod installed, though with workshop autodownload that'll be common - if compressed != nil then + if compressed ~= nil then WriteDir(util.JSONToTable(string.sub(compressed, 3))) end end