diff options
| author | ruki <[email protected]> | 2023-10-07 16:57:13 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-10-07 16:57:13 +0800 |
| commit | 720f0eb9c5ba51a5a76ef31e7285b6ea1b08b400 (patch) | |
| tree | 4b324d9ecf8c561712cc6531a3d28ded21ac2045 | |
| parent | bceea4e7fe7553b90ac7d14e4ea854bbb2d3e04a (diff) | |
| parent | 2bfdd8a805baa9753ffed3dac771b6f3dce077bf (diff) | |
Merge pull request #4259 from xmake-io/tests
Add `xmake test` support
| -rw-r--r-- | CHANGELOG.md | 2 | ||||
| -rw-r--r-- | tests/actions/test/.gitignore | 8 | ||||
| -rw-r--r-- | tests/actions/test/src/test_1.cpp | 10 | ||||
| -rw-r--r-- | tests/actions/test/src/test_2.cpp | 10 | ||||
| -rw-r--r-- | tests/actions/test/src/test_3.cpp | 10 | ||||
| -rw-r--r-- | tests/actions/test/src/test_4.cpp | 10 | ||||
| -rw-r--r-- | tests/actions/test/src/test_5.cpp | 10 | ||||
| -rw-r--r-- | tests/actions/test/src/test_6.cpp | 10 | ||||
| -rw-r--r-- | tests/actions/test/src/test_7.cpp | 10 | ||||
| -rw-r--r-- | tests/actions/test/src/test_8.cpp | 9 | ||||
| -rw-r--r-- | tests/actions/test/src/test_9.cpp | 10 | ||||
| -rw-r--r-- | tests/actions/test/test.lua | 4 | ||||
| -rw-r--r-- | tests/actions/test/xmake.lua | 14 | ||||
| -rw-r--r-- | xmake/actions/build/build.lua | 26 | ||||
| -rw-r--r-- | xmake/actions/build/check.lua | 8 | ||||
| -rw-r--r-- | xmake/actions/build/main.lua | 96 | ||||
| -rw-r--r-- | xmake/actions/run/main.lua | 4 | ||||
| -rw-r--r-- | xmake/actions/test/main.lua | 362 | ||||
| -rw-r--r-- | xmake/actions/test/xmake.lua | 48 | ||||
| -rw-r--r-- | xmake/core/project/rule.lua | 3 | ||||
| -rw-r--r-- | xmake/core/project/target.lua | 4 |
21 files changed, 606 insertions, 62 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 6324e935f..00bd1580d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * [#4250](https://github.com/xmake-io/xmake/pull/4250): Improve link mechanism and order * [#1438](https://github.com/xmake-io/xmake/issues/1438): Support code amalgamation +* [#3381](https://github.com/xmake-io/xmake/issues/3381): Add `xmake test` support ## v2.8.3 @@ -1671,6 +1672,7 @@ * [#4250](https://github.com/xmake-io/xmake/pull/4250): 支持链接顺序调整,链接组 * [#1438](https://github.com/xmake-io/xmake/issues/1438): 支持代码 amalgamation +* [#3381](https://github.com/xmake-io/xmake/issues/3381): 添加 `xmake test` 支持 ## v2.8.3 diff --git a/tests/actions/test/.gitignore b/tests/actions/test/.gitignore new file mode 100644 index 000000000..152105761 --- /dev/null +++ b/tests/actions/test/.gitignore @@ -0,0 +1,8 @@ +# Xmake cache +.xmake/ +build/ + +# MacOS Cache +.DS_Store + + diff --git a/tests/actions/test/src/test_1.cpp b/tests/actions/test/src/test_1.cpp new file mode 100644 index 000000000..f454e99f3 --- /dev/null +++ b/tests/actions/test/src/test_1.cpp @@ -0,0 +1,10 @@ +#include <iostream> + +using namespace std; + +int main(int argc, char** argv) +{ + char const* arg = argc > 1? argv[1] : "xmake"; + cout << "hello " << arg << endl; + return 0; +} diff --git a/tests/actions/test/src/test_2.cpp b/tests/actions/test/src/test_2.cpp new file mode 100644 index 000000000..f454e99f3 --- /dev/null +++ b/tests/actions/test/src/test_2.cpp @@ -0,0 +1,10 @@ +#include <iostream> + +using namespace std; + +int main(int argc, char** argv) +{ + char const* arg = argc > 1? argv[1] : "xmake"; + cout << "hello " << arg << endl; + return 0; +} diff --git a/tests/actions/test/src/test_3.cpp b/tests/actions/test/src/test_3.cpp new file mode 100644 index 000000000..f454e99f3 --- /dev/null +++ b/tests/actions/test/src/test_3.cpp @@ -0,0 +1,10 @@ +#include <iostream> + +using namespace std; + +int main(int argc, char** argv) +{ + char const* arg = argc > 1? argv[1] : "xmake"; + cout << "hello " << arg << endl; + return 0; +} diff --git a/tests/actions/test/src/test_4.cpp b/tests/actions/test/src/test_4.cpp new file mode 100644 index 000000000..f454e99f3 --- /dev/null +++ b/tests/actions/test/src/test_4.cpp @@ -0,0 +1,10 @@ +#include <iostream> + +using namespace std; + +int main(int argc, char** argv) +{ + char const* arg = argc > 1? argv[1] : "xmake"; + cout << "hello " << arg << endl; + return 0; +} diff --git a/tests/actions/test/src/test_5.cpp b/tests/actions/test/src/test_5.cpp new file mode 100644 index 000000000..dad841287 --- /dev/null +++ b/tests/actions/test/src/test_5.cpp @@ -0,0 +1,10 @@ +#include <iostream> + +using namespace std; + +int main(int argc, char** argv) +{ + char const* arg = argc > 1? argv[1] : "xmake"; + cout << "hello2 " << arg << endl; + return 0; +} diff --git a/tests/actions/test/src/test_6.cpp b/tests/actions/test/src/test_6.cpp new file mode 100644 index 000000000..f454e99f3 --- /dev/null +++ b/tests/actions/test/src/test_6.cpp @@ -0,0 +1,10 @@ +#include <iostream> + +using namespace std; + +int main(int argc, char** argv) +{ + char const* arg = argc > 1? argv[1] : "xmake"; + cout << "hello " << arg << endl; + return 0; +} diff --git a/tests/actions/test/src/test_7.cpp b/tests/actions/test/src/test_7.cpp new file mode 100644 index 000000000..dae685668 --- /dev/null +++ b/tests/actions/test/src/test_7.cpp @@ -0,0 +1,10 @@ +#include <iostream> + +using namespace std; + +int main(int argc, char** argv) +{ + char const* arg = argc > 1? argv[1] : "xmake"; + cout << "hello " << arg << endl; + return -1; +} diff --git a/tests/actions/test/src/test_8.cpp b/tests/actions/test/src/test_8.cpp new file mode 100644 index 000000000..8669ff781 --- /dev/null +++ b/tests/actions/test/src/test_8.cpp @@ -0,0 +1,9 @@ +#include <iostream> + +using namespace std; + +int main(int argc, char** argv) +{ + cout << "hello xmake" << endl; + return 0; +} diff --git a/tests/actions/test/src/test_9.cpp b/tests/actions/test/src/test_9.cpp new file mode 100644 index 000000000..f454e99f3 --- /dev/null +++ b/tests/actions/test/src/test_9.cpp @@ -0,0 +1,10 @@ +#include <iostream> + +using namespace std; + +int main(int argc, char** argv) +{ + char const* arg = argc > 1? argv[1] : "xmake"; + cout << "hello " << arg << endl; + return 0; +} diff --git a/tests/actions/test/test.lua b/tests/actions/test/test.lua new file mode 100644 index 000000000..45ce0b914 --- /dev/null +++ b/tests/actions/test/test.lua @@ -0,0 +1,4 @@ +function main(t) + os.exec("xmake test") +end + diff --git a/tests/actions/test/xmake.lua b/tests/actions/test/xmake.lua new file mode 100644 index 000000000..086734631 --- /dev/null +++ b/tests/actions/test/xmake.lua @@ -0,0 +1,14 @@ +add_rules("mode.debug", "mode.release") + +for _, file in ipairs(os.files("src/test_*.cpp")) do + local name = path.basename(file) + target(name) + set_kind("binary") + set_default(false) + add_files("src/" .. name .. ".cpp") + add_tests("default") + add_tests("args", {runargs = {"foo", "bar"}}) + add_tests("pass_output", {trim_output = true, runargs = "foo", pass_outputs = "hello foo"}) + add_tests("fail_output", {fail_outputs = {"hello2 .*", "hello xmake"}}) +end + diff --git a/xmake/actions/build/build.lua b/xmake/actions/build/build.lua index 5cea43185..bb0b61cc1 100644 --- a/xmake/actions/build/build.lua +++ b/xmake/actions/build/build.lua @@ -229,19 +229,21 @@ function _add_batchjobs_for_target_and_deps(batchjobs, rootjob, jobrefs, target) end -- get batch jobs, @note we need to export it for private.diagnosis.dump_buildjobs -function get_batchjobs(targetname, group_pattern) +function get_batchjobs(targetnames, group_pattern) -- get root targets local targets_root = {} - if targetname then - local target = project.target(targetname) - if target then - table.insert(targets_root, target) - if option.get("rebuild") then - target:data_set("rebuilt", true) - if not option.get("shallow") then - for _, dep in ipairs(target:orderdeps()) do - dep:data_set("rebuilt", true) + if targetnames then + for _, targetname in ipairs(table.wrap(targetnames)) do + local target = project.target(targetname) + if target then + table.insert(targets_root, target) + if option.get("rebuild") then + target:data_set("rebuilt", true) + if not option.get("shallow") then + for _, dep in ipairs(target:orderdeps()) do + dep:data_set("rebuilt", true) + end end end end @@ -280,7 +282,7 @@ function get_batchjobs(targetname, group_pattern) end -- the main entry -function main(targetname, group_pattern) +function main(targetnames, group_pattern) -- enable distcc? local distcc @@ -289,7 +291,7 @@ function main(targetname, group_pattern) end -- build all jobs - local batchjobs = get_batchjobs(targetname, group_pattern) + local batchjobs = get_batchjobs(targetnames, group_pattern) if batchjobs and batchjobs:size() > 0 then local curdir = os.curdir() runjobs("build", batchjobs, {on_exit = function (errors) diff --git a/xmake/actions/build/check.lua b/xmake/actions/build/check.lua index e26e4f0d0..f468acfb1 100644 --- a/xmake/actions/build/check.lua +++ b/xmake/actions/build/check.lua @@ -44,13 +44,15 @@ function _show(str, opt) end end -function main(targetname, opt) +function main(targetnames, opt) opt = opt or {} -- get targets local targets = {} - if targetname then - table.insert(targets, project.target(targetname)) + if targetnames then + for _, targetname in ipairs(table.wrap(targetnames)) do + table.insert(targets, project.target(targetname)) + end else for _, target in pairs(project.targets()) do if target:is_enabled() then diff --git a/xmake/actions/build/main.lua b/xmake/actions/build/main.lua index 58456ba70..43897578a 100644 --- a/xmake/actions/build/main.lua +++ b/xmake/actions/build/main.lua @@ -129,61 +129,26 @@ function _on_exit(ok, errors) end end --- main -function main() - - -- try building it using third-party buildsystem if xmake.lua not exists - if not os.isfile(project.rootfile()) and _try_build() then - return - end - - -- post statistics before locking project - statistics.post() - - -- do action for remote? - if remote_build_action.enabled() then - return remote_build_action() - end - - -- lock the whole project - project.lock() - - -- config it first - local targetname - local group_pattern = option.get("group") - if group_pattern then - group_pattern = "^" .. path.pattern(group_pattern) .. "$" - else - targetname = option.get("target") - end - task.run("config", {}, {disable_dump = true}) - - -- enter project directory - local oldir = os.cd(project.directory()) - - -- clean up temporary files once a day - cleaner.cleanup() +-- build targets +function build_targets(targetnames, opt) + opt = opt or {} -- register exit callbacks os.atexit(_on_exit) - local build_time + local group_pattern = opt.group_pattern try { function () - local time = os.mclock() -- do rules before building _do_project_rules("build_before") -- do build - _do_build(targetname, group_pattern) + _do_build(targetnames, group_pattern) -- do check - check_targets(targetname, {build = true}) - - -- get build time - build_time = os.mclock() - time + check_targets(targetnames, {build = true}) -- dump cache stats if option.get("diagnosis") then @@ -206,8 +171,9 @@ function main() raise(errors) elseif group_pattern then raise("build targets with group(%s) failed!", group_pattern) - elseif targetname then - raise("build target: %s failed!", targetname) + elseif targetnames then + targetnames = table.wrap(targetnames) + raise("build target: %s failed!", table.concat(targetnames, ", ")) else raise("build target failed!") end @@ -217,13 +183,53 @@ function main() -- do rules after building _do_project_rules("build_after") +end - -- unlock the whole project - project.unlock() +function main() + + -- try building it using third-party buildsystem if xmake.lua not exists + if not os.isfile(project.rootfile()) and _try_build() then + return + end + + -- post statistics before locking project + statistics.post() + + -- do action for remote? + if remote_build_action.enabled() then + return remote_build_action() + end + + -- lock the whole project + project.lock() + + -- config it first + local targetname + local group_pattern = option.get("group") + if group_pattern then + group_pattern = "^" .. path.pattern(group_pattern) .. "$" + else + targetname = option.get("target") + end + task.run("config", {}, {disable_dump = true}) + + -- enter project directory + local oldir = os.cd(project.directory()) + + -- clean up temporary files once a day + cleaner.cleanup() + + -- build targets + local build_time = os.mclock() + build_targets(targetname, {group_pattern = group_pattern}) + build_time = os.mclock() - build_time -- leave project directory os.cd(oldir) + -- unlock the whole project + project.unlock() + -- trace local str = "" if build_time then diff --git a/xmake/actions/run/main.lua b/xmake/actions/run/main.lua index 70a277a86..217f87c66 100644 --- a/xmake/actions/run/main.lua +++ b/xmake/actions/run/main.lua @@ -44,7 +44,7 @@ function _do_run_target(target) -- get the absolute target file path local targetfile = path.absolute(target:targetfile()) - -- build run environments + -- get the run environments local addenvs, setenvs = runenvs.make(target) -- get run arguments @@ -77,7 +77,7 @@ function _on_run_target(target) _do_run_target(target) end --- recursively target add env +-- recursively add target envs function _add_target_pkgenvs(target, targets_added) if targets_added[target:name()] then return diff --git a/xmake/actions/test/main.lua b/xmake/actions/test/main.lua new file mode 100644 index 000000000..d39c80a18 --- /dev/null +++ b/xmake/actions/test/main.lua @@ -0,0 +1,362 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, TBOOX Open Source Group. +-- +-- @author ruki +-- @file main.lua +-- + +-- imports +import("core.base.option") +import("core.base.task") +import("core.project.config") +import("core.base.global") +import("core.project.project") +import("core.platform.platform") +import("core.theme.theme") +import("async.runjobs") +import("private.action.run.runenvs") +import("private.service.remote_build.action", {alias = "remote_build_action"}) +import("actions.build.main", {rootdir = os.programdir(), alias = "build_action"}) + +-- test target +function _do_test_target(target, opt) + opt = opt or {} + + -- get run environments + local envs = opt.runenvs + if not envs then + local addenvs, setenvs = runenvs.make(target) + envs = runenvs.join(addenvs, setenvs) + end + + -- run test + local outdata + local errors + local rundir = opt.rundir or target:rundir() + local targetfile = path.absolute(target:targetfile()) + local runargs = table.wrap(opt.runargs or target:get("runargs")) + local outfile = os.tmpfile() + local errfile = os.tmpfile() + local ok, syserrors = os.execv(targetfile, runargs, {try = true, curdir = rundir, envs = envs, stdout = outfile, stderr = errfile}) + local outdata = os.isfile(outfile) and io.readfile(outfile) or "" + if opt.trim_output then + outdata = outdata:trim() + end + if ok ~= 0 then + local errdata = os.isfile(errfile) and io.readfile(errfile) + errors = errdata or errors + if not errors or #errors == 0 then + if ok ~= nil then + errors = string.format("run failed, exit code: %d", ok) + else + errors = string.format("run failed, exit error: %s", syserrors and syserrors or "unknown reason") + end + end + end + os.tryrm(outfile) + os.tryrm(errfile) + + if ok == 0 then + local passed + local pass_outputs = table.wrap(opt.pass_outputs) + local fail_outputs = table.wrap(opt.fail_outputs) + for _, pass_output in ipairs(pass_outputs) do + if opt.plain then + if pass_output == outdata then + passed = true + break + end + else + if outdata:match("^" .. pass_output .. "$") then + passed = true + break + end + end + end + for _, fail_output in ipairs(fail_outputs) do + if opt.plain then + if fail_output == outdata then + passed = false + if not errors or #errors == 0 then + errors = string.format("matched failed output: ${color.failure}%s${clear}", fail_output) + local actual_output = outdata + if not option.get("diagnosis") then + actual_output = outdata:sub(1, 64) + if #outdata > #actual_output then + actual_output = actual_output .. "..." + end + end + errors = errors .. ", actual output: ${color.failure}" .. actual_output + end + break + end + else + if outdata:match("^" .. fail_output .. "$") then + passed = false + if not errors or #errors == 0 then + errors = string.format("matched failed output: ${color.failure}%s${clear}", fail_output) + local actual_output = outdata + if not option.get("diagnosis") then + actual_output = outdata:sub(1, 64) + if #outdata > #actual_output then + actual_output = actual_output .. "..." + end + end + errors = errors .. ", actual output: ${color.failure}" .. actual_output + end + break + end + end + end + if passed == nil then + if #pass_outputs == 0 then + passed = true + else + passed = false + if not errors or #errors == 0 then + errors = string.format("not matched passed output: ${color.success}%s${clear}", table.concat(pass_outputs, ", ")) + local actual_output = outdata + if not option.get("diagnosis") then + actual_output = outdata:sub(1, 64) + if #outdata > #actual_output then + actual_output = actual_output .. "..." + end + end + errors = errors .. ", actual output: ${color.failure}" .. actual_output + end + end + end + return passed, errors + end + return false, errors +end + +-- test target +function _on_test_target(target, opt) + + -- build target with rules + local passed + local errors + local done = false + for _, r in ipairs(target:orderules()) do + local on_test = r:script("test") + if on_test then + passed, errors = on_test(target, opt) + done = true + end + end + if done then + return passed, errors + end + + -- do test + return _do_test_target(target, opt) +end + +-- recursively add target envs +function _add_target_pkgenvs(target, targets_added) + if targets_added[target:name()] then + return + end + targets_added[target:name()] = true + os.addenvs(target:pkgenvs()) + for _, dep in ipairs(target:orderdeps()) do + _add_target_pkgenvs(dep, targets_added) + end +end + +-- run the given test +function _run_test(target, test) + + -- enter the environments of the target packages + local oldenvs = os.getenvs() + _add_target_pkgenvs(target, {}) + + -- the target scripts + local scripts = + { + target:script("test_before") + , function (target, opt) + for _, r in ipairs(target:orderules()) do + local before_test = r:script("test_before") + if before_test then + before_test(target, opt) + end + end + end + , target:script("test", _on_test_target) + , function (target, opt) + for _, r in ipairs(target:orderules()) do + local after_test = r:script("test_after") + if after_test then + after_test(target, opt) + end + end + end + , target:script("test_after") + } + + -- run the target scripts + local passed + local errors + for i = 1, 5 do + local script = scripts[i] + if script ~= nil then + local ok, errs = script(target, test) + if i == 3 then + passed = ok + errors = errs + end + end + end + + -- leave the environments of the target packages + os.setenvs(oldenvs) + return passed, errors +end + +-- run tests +function _run_tests(tests) + local ordertests = {} + local maxwidth = 0 + for name, testinfo in table.orderpairs(tests) do + table.insert(ordertests, testinfo) + if #testinfo.name > maxwidth then + maxwidth = #testinfo.name + end + end + if #ordertests == 0 then + print("nothing to test") + return + end + + -- do test + local spent = os.mclock() + print("running tests ...") + local report = {passed = 0, total = #ordertests} + local jobs = tonumber(option.get("jobs") or "1") + runjobs("run_tests", function (index) + local testinfo = ordertests[index] + if testinfo then + local target = testinfo.target + testinfo.target = nil + local spent = os.mclock() + local passed, errors = _run_test(target, testinfo) + spent = os.mclock() - spent + if passed then + report.passed = report.passed + 1 + end + local status_color = passed and "${color.success}" or "${color.failure}" + local progress_format = status_color .. theme.get("text.build.progress_format") .. ":${clear} " + if option.get("verbose") then + progress_format = progress_format .. "${dim}" + end + local progress = math.floor(index * 100 / #ordertests) + local padding = maxwidth - #testinfo.name + cprint(progress_format .. "%s%s .................................... " .. status_color .. "%s${clear} ${bright}%0.3fs", + progress, testinfo.name, (" "):rep(padding), passed and "passed" or "failed", spent) + if not passed and errors and (option.get("verbose") or option.get("diagnosis")) then + cprint(errors) + end + end + end, {total = #ordertests, + comax = jobs, + isolate = true}) + + -- generate report + spent = os.mclock() - spent + local passed_rate = math.floor(report.passed * 100 / report.total) + print("") + cprint("${color.success}%d%%${clear} tests passed, ${color.failure}%d${clear} tests failed out of ${bright}%d${clear}, spent ${bright}%0.3fs", + passed_rate, report.total - report.passed, report.total, spent / 1000) +end + +function main() + + -- do action for remote? + if remote_build_action.enabled() then + return remote_build_action() + end + + -- lock the whole project + project.lock() + + -- load config first + task.run("config", {}, {disable_dump = true}) + + -- load targets + project.load_targets() + + -- get tests + local tests = {} + local group_pattern = option.get("group") + if group_pattern then + group_pattern = "^" .. path.pattern(group_pattern) .. "$" + end + for _, target in ipairs(project.ordertargets()) do + if target:is_binary() or target:script("run") then + for _, name in ipairs(target:get("tests")) do + local extra = target:extraconf("tests", name) + local testname = target:name() .. "/" .. name + local testinfo = {name = testname, target = target} + if extra then + table.join2(testinfo, extra) + end + if not testinfo.group then + testinfo.group = target:get("group") + end + + local group = testinfo.group + if (not group_pattern) or (group_pattern and group and group:match(group_pattern)) then + tests[testname] = testinfo + end + end + end + end + local test_patterns = option.get("tests") + if test_patterns then + local tests_new = {} + for _, pattern in ipairs(test_patterns) do + pattern = "^" .. path.pattern(pattern) .. "$" + for name, testinfo in pairs(tests) do + if name:match(pattern) then + tests_new[name] = testinfo + end + end + end + tests = tests_new + end + + -- enter project directory + local oldir = os.cd(project.directory()) + + -- build targets with the given tests first + local targetnames = {} + for _, testinfo in table.orderpairs(tests) do + table.insert(targetnames, testinfo.target:name()) + end + build_action.build_targets(targetnames) + + -- run tests + _run_tests(tests) + + -- leave project directory + os.cd(oldir) + + -- unlock the whole project + project.unlock() +end + diff --git a/xmake/actions/test/xmake.lua b/xmake/actions/test/xmake.lua new file mode 100644 index 000000000..c892d1840 --- /dev/null +++ b/xmake/actions/test/xmake.lua @@ -0,0 +1,48 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, TBOOX Open Source Group. +-- +-- @author ruki +-- @file xmake.lua +-- + +task("test") + set_category("action") + on_run("main") + set_menu { + usage = "xmake test [options] [target] [arguments]", + description = "Run the project tests.", + options = { + {'g', "group", "kv", nil , "Run all tests of the given group. It support path pattern matching.", + "e.g.", + " xmake test -g test", + " xmake test -g test_*", + " xmake test --group=benchmark/*" }, + {'w', "workdir", "kv", nil , "Work directory of running targets, default is folder of targetfile", + "e.g.", + " xmake test -w .", + " xmake test --workdir=`pwd`" }, + {'j', "jobs", "kv", "1", "Set the number of parallel compilation jobs." }, + {}, + {nil, "tests", "vs", nil , "The test names. It support pattern matching.", + "e.g.", + " xmake test foo", + " xmake test */foo", + " xmake test targetname/*" } + } + } + + + diff --git a/xmake/core/project/rule.lua b/xmake/core/project/rule.lua index 4d2a058a0..57510b45a 100644 --- a/xmake/core/project/rule.lua +++ b/xmake/core/project/rule.lua @@ -308,6 +308,7 @@ function rule.apis() { -- rule.on_xxx "rule.on_run" + , "rule.on_test" , "rule.on_load" , "rule.on_config" , "rule.on_link" @@ -324,6 +325,7 @@ function rule.apis() , "rule.on_buildcmd_files" -- rule.before_xxx , "rule.before_run" + , "rule.before_test" , "rule.before_load" , "rule.before_link" , "rule.before_build" @@ -339,6 +341,7 @@ function rule.apis() , "rule.before_buildcmd_files" -- rule.after_xxx , "rule.after_run" + , "rule.after_test" , "rule.after_load" , "rule.after_link" , "rule.after_build" diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua index 61501648f..607bc68cc 100644 --- a/xmake/core/project/target.lua +++ b/xmake/core/project/target.lua @@ -2455,6 +2455,7 @@ function target.apis() , "target.add_languages" , "target.add_vectorexts" , "target.add_toolchains" + , "target.add_tests" } , keyvalues = { @@ -2493,6 +2494,7 @@ function target.apis() { -- target.on_xxx "target.on_run" + , "target.on_test" , "target.on_load" , "target.on_config" , "target.on_link" @@ -2505,6 +2507,7 @@ function target.apis() , "target.on_uninstall" -- target.before_xxx , "target.before_run" + , "target.before_test" , "target.before_link" , "target.before_build" , "target.before_build_file" @@ -2515,6 +2518,7 @@ function target.apis() , "target.before_uninstall" -- target.after_xxx , "target.after_run" + , "target.after_test" , "target.after_load" , "target.after_link" , "target.after_build" |
