diff --git a/docs/docs/CLI.md b/docs/docs/CLI.md index adcb621f..bad29391 100644 --- a/docs/docs/CLI.md +++ b/docs/docs/CLI.md @@ -9,31 +9,21 @@ title: runCLI Options The `Jest` packages exports `runCLI`, which is the main entrypoint to run Jest Lua tests. In your entrypoint script, import `runCLI` from the `Jest` package. A basic entrypoint script can look like the following: ```lua title="spec.lua" -local Packages = script.Parent.YourProject.Packages -local runCLI = require("@Packages/Jest").runCLI +local ReplicatedStorage = game:GetService("ReplicatedStorage") +local Packages = ReplicatedStorage.Packages -local processServiceExists, ProcessService = pcall(function() - return game:GetService("ProcessService") -end) +local Jest = require("@DevPackages/Jest") -local status, result = runCLI(Packages.Project, { +local runCLIOptions = { verbose = false, - ci = false -}, { Packages.Project }):awaitStatus() - -if status == "Rejected" then - print(result) -end - -if status == "Resolved" and result.results.numFailedTestSuites == 0 and result.results.numFailedTests == 0 then - if processServiceExists then - ProcessService:ExitAsync(0) - end -end - -if processServiceExists then - ProcessService:ExitAsync(1) -end + ci = false, +} + +local projects = { + Packages.Project, +} + +Jest.runCLI(script, runCLIOptions, projects):await() return nil ``` diff --git a/docs/docs/GettingStarted.md b/docs/docs/GettingStarted.md index b02d1b93..1335f150 100644 --- a/docs/docs/GettingStarted.md +++ b/docs/docs/GettingStarted.md @@ -8,6 +8,10 @@ The Jest Roblox API is similar to [the API used by JavaScript Jest.](https://jes Jest Lua currently requires [`run-in-roblox`](https://github.com/rojo-rbx/run-in-roblox) to run from the command line. It can also be run directly inside of Roblox Studio. See issue [#2](https://github.com/jsdotlua/jest-lua/issues/2) for more. +:::tip +Checkout the [example game](https://github.com/jsdotlua/jest-lua/tree/main/example-project) to see a full setup of Jest-Lua for a Roblox Library. +::: + Add the `JestGlobals` and `Jest` packages to your `dev-dependencies` in your `wally.toml`. ```yaml title="wally.toml" @@ -18,7 +22,7 @@ JestGlobals = "jsdotlua/jest-globals@3.10.0" Run `wally install` to install Jest Lua. -Create a `default.project.json` to set up your project structure and include the `Packages` directory created by `wally`. +Create a `default.project.json` to set up your project structure and include the `Packages` and `DevPackages` directories created by `wally`. ```json title="default.project.json" { @@ -30,6 +34,9 @@ Create a `default.project.json` to set up your project structure and include the "Project": { "$path": "src" } + }, + "DevPackages": { + "$path": "DevPackages" } } } @@ -39,31 +46,20 @@ Create a `run-tests.lua` to point the test runner to the correct directory with ```lua title="run-tests.lua" local ReplicatedStorage = game:GetService("ReplicatedStorage") +local Packages = ReplicatedStorage.Packages -local runCLI = require("@DevPackages/Jest").runCLI - -local processServiceExists, ProcessService = pcall(function() - return game:GetService("ProcessService") -end) +local Jest = require("@DevPackages/Jest") -local status, result = runCLI(ReplicatedStorage.Packages.Project, { +local runCLIOptions = { verbose = false, - ci = false -}, { ReplicatedStorage.Packages.Project }):awaitStatus() - -if status == "Rejected" then - print(result) -end + ci = false, +} -if status == "Resolved" and result.results.numFailedTestSuites == 0 and result.results.numFailedTests == 0 then - if processServiceExists then - ProcessService:ExitAsync(0) - end -end +local projects = { + Packages.Project, +} -if processServiceExists then - ProcessService:ExitAsync(1) -end +Jest.runCLI(script, runCLIOptions, projects):await() return nil ``` @@ -72,7 +68,13 @@ Inside `src`, create a basic [configuration](configuration) file. ```lua title="jest.config.lua" return { - testMatch = { "**/*.spec" } + testMatch = { + "**/__tests__/*.(spec|test)", + }, + testPathIgnorePatterns = { + "Packages", + "DevPackages", + }, } ``` @@ -105,13 +107,15 @@ Any functionality needed _must_ be explicitly required from `JestGlobals`, see [ Before you can run your tests, you need to enable the `debug.loadmodule` API. To do this, you must enable the `FFlagEnableLoadModule` flag. See issue [#3](https://github.com/jsdotlua/jest-lua/issues/3) for more. +To manage FastFlags for Studio, it is recommended that you use [Roblox Studio Mod Manager](https://github.com/MaximumADHD/Roblox-Studio-Mod-Manager) to set the `FFlagEnableLoadModule` FFlag to true. Or, you can edit your `ClientAppSettings.json` yourself. + ```json title="ClientAppSettings.json" { "FFlagEnableLoadModule": true } ``` -Finally, run your project using Roblox Studio or `run-in-roblox` to run the tests and your tests should pass! +Finally, run your project using Roblox Studio or use [run-in-roblox](https://github.com/rojo-rbx/run-in-roblox) to run the tests and your tests should pass! ```bash run-in-roblox --place test-place.rbxl --script scripts/run-tests.lua diff --git a/example-project/.darklua.json b/example-project/.darklua.json new file mode 100644 index 00000000..b5195e9b --- /dev/null +++ b/example-project/.darklua.json @@ -0,0 +1,24 @@ +{ + "process": [ + { + "rule": "convert_require", + "current": { + "name": "path", + "sources": { + "@Project": "src/", + "@DevPackages": "DevPackages/" + } + }, + "target": { + "name": "roblox", + "rojo_sourcemap": "sourcemap.json", + "indexing_style": "wait_for_child" + } + }, + { + "rule": "inject_global_value", + "identifier": "NOCOLOR", + "env": "NOCOLOR" + } + ] +} diff --git a/example-project/.gitignore b/example-project/.gitignore new file mode 100644 index 00000000..3ed8c96b --- /dev/null +++ b/example-project/.gitignore @@ -0,0 +1,10 @@ +/*.rbxlx.lock +/*.rbxl.lock +/*.rbxl +/*.rbxm + +DevPackages/ +dist/ + +sourcemap.json +wally.lock \ No newline at end of file diff --git a/example-project/.luaurc b/example-project/.luaurc new file mode 100644 index 00000000..23f1feaf --- /dev/null +++ b/example-project/.luaurc @@ -0,0 +1,6 @@ +{ + "aliases": { + "Project": "src/", + "DevPackages": "DevPackages/" + } +} \ No newline at end of file diff --git a/example-project/.vscode/settings.json b/example-project/.vscode/settings.json new file mode 100644 index 00000000..5591884c --- /dev/null +++ b/example-project/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "editor.formatOnSave": true, + "luau-lsp.completion.imports.enabled": true, + "luau-lsp.completion.imports.suggestServices": true, + "luau-lsp.completion.imports.suggestRequires": false, + "luau-lsp.require.mode": "relativeToFile", + "luau-lsp.ignoreGlobs": [ + "DevPackages/*", + "dist/*", + ] +} \ No newline at end of file diff --git a/example-project/README.md b/example-project/README.md new file mode 100644 index 00000000..88d789ab --- /dev/null +++ b/example-project/README.md @@ -0,0 +1,24 @@ +# Example Project + +This is an example of how to use Jest-Lua to create unit tests for a library. + +For a setup guide, see the [Getting Started](https://jsdotlua.github.io/jest-lua/) documentation page. + +## Running Tests + +This example has [run-in-roblox](https://github.com/rojo-rbx/run-in-roblox) setup to allow you to run tests from the CLI. +To do so, run the `scripts/test.sh` script and it will open up studio and run your tests. + +If you do not wish to use `run-in-roblox`, you can serve the project with Rojo by running the `scripts/dev.sh`. +Your tests will run and output the results when you run the server in Studio. + +## Project Structure + +You can find our `run-tests.luau` script in the `scripts` folder. +This is where we define our runCLI Options and our project directories for Jest. + +The `jest.config.luau` file can be found in `src`, this is where we tell Jest what should be considered a test and other options. + +The rest of the project has been setup for use with Darklua and String Requires, and provides scripts to make it simple to use. +The structure is based on [roblox-project-template](https://github.com/grilme99/roblox-project-template), +which provides a setup for a Roblox experience with Darklua and more. \ No newline at end of file diff --git a/example-project/build.project.json b/example-project/build.project.json new file mode 100644 index 00000000..7ff50303 --- /dev/null +++ b/example-project/build.project.json @@ -0,0 +1,6 @@ +{ + "name": "JestLuaProject", + "tree": { + "$path": "dist/src" + } +} \ No newline at end of file diff --git a/example-project/default.project.json b/example-project/default.project.json new file mode 100644 index 00000000..c4ece469 --- /dev/null +++ b/example-project/default.project.json @@ -0,0 +1,22 @@ +{ + "name": "JestLuaProject", + "tree": { + "$className": "DataModel", + "ReplicatedStorage": { + "DevPackages": { + "$path": "DevPackages" + }, + "Packages": { + "$className": "Folder", + "Project": { + "$path": "src" + } + } + }, + "ServerScriptService": { + "run-tests": { + "$path": "scripts/run-tests.server.luau" + } + } + } +} \ No newline at end of file diff --git a/example-project/dev.project.json b/example-project/dev.project.json new file mode 100644 index 00000000..9e6e5094 --- /dev/null +++ b/example-project/dev.project.json @@ -0,0 +1,22 @@ +{ + "name": "JestLuaProject", + "tree": { + "$className": "DataModel", + "ReplicatedStorage": { + "DevPackages": { + "$path": "DevPackages" + }, + "Packages": { + "$className": "Folder", + "Project": { + "$path": "dist/src" + } + } + }, + "ServerScriptService": { + "run-tests": { + "$path": "dist/run-tests.server.luau" + } + } + } +} \ No newline at end of file diff --git a/example-project/rokit.toml b/example-project/rokit.toml new file mode 100644 index 00000000..5c96bed6 --- /dev/null +++ b/example-project/rokit.toml @@ -0,0 +1,10 @@ +# This file lists tools managed by Rokit, a toolchain manager for Roblox projects. +# For more information, see https://github.com/rojo-rbx/rokit + +# New tools can be added by running `rokit add ` in a terminal. + +[tools] +rojo = "rojo-rbx/rojo@7.4.4" +run-in-roblox = "rojo-rbx/run-in-roblox@0.3.0" +wally = "upliftGames/wally@0.3.2" +darklua = "seaofvoices/darklua@0.13.1" diff --git a/example-project/scripts/build.sh b/example-project/scripts/build.sh new file mode 100644 index 00000000..f70750d3 --- /dev/null +++ b/example-project/scripts/build.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +set -e + +# If Packages aren't installed, install them. +if [ ! -d "DevPackages" ]; then + sh scripts/install-packages.sh +fi + +rojo sourcemap default.project.json -o sourcemap.json + +darklua process --config .darklua.json src/ dist/src +rojo build build.project.json -o JestLuaProject.rbxm \ No newline at end of file diff --git a/example-project/scripts/dev.sh b/example-project/scripts/dev.sh new file mode 100644 index 00000000..6ec7e772 --- /dev/null +++ b/example-project/scripts/dev.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +set -e + +# If Packages aren't installed, install them. +if [ ! -d "DevPackages" ]; then + sh scripts/install-packages.sh +fi + +rojo serve dev.project.json \ + & rojo sourcemap default.project.json -o sourcemap.json --watch \ + & darklua process --config .darklua.json --watch src/ dist/src \ + & NOCOLOR=1 darklua process --config .darklua.json --watch scripts/run-tests.server.luau dist/run-tests.server.luau \ No newline at end of file diff --git a/example-project/scripts/install-packages.sh b/example-project/scripts/install-packages.sh new file mode 100644 index 00000000..0176fe58 --- /dev/null +++ b/example-project/scripts/install-packages.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +set -e + +wally install diff --git a/example-project/scripts/run-tests.server.luau b/example-project/scripts/run-tests.server.luau new file mode 100644 index 00000000..ffb4e157 --- /dev/null +++ b/example-project/scripts/run-tests.server.luau @@ -0,0 +1,19 @@ +_G.NOCOLOR = _G.NOCOLOR + +local ReplicatedStorage = game:GetService("ReplicatedStorage") +local Packages = ReplicatedStorage.Packages + +local Jest = require("@DevPackages/Jest") + +local runCLIOptions = { + verbose = false, + ci = false, +} + +local projects = { + Packages.Project, +} + +Jest.runCLI(script, runCLIOptions, projects):await() + +return nil diff --git a/example-project/scripts/test.sh b/example-project/scripts/test.sh new file mode 100644 index 00000000..d381a2de --- /dev/null +++ b/example-project/scripts/test.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +set -e + +OUTPUT=JestLuaProject.rbxl + +# If Packages aren't installed, install them. +if [ ! -d "DevPackages" ]; then + sh scripts/install-packages.sh +fi + +darklua process --config .darklua.json src/ dist/src \ + && darklua process --config .darklua.json scripts/run-tests.server.luau dist/run-tests.server.luau \ + && rojo build dev.project.json --output $OUTPUT \ + && run-in-roblox --place $OUTPUT --script dist/run-tests.server.luau diff --git a/example-project/selene.toml b/example-project/selene.toml new file mode 100644 index 00000000..22aa0640 --- /dev/null +++ b/example-project/selene.toml @@ -0,0 +1,4 @@ +std = "selene_definitions" + +[rules] +global_usage = "allow" diff --git a/example-project/selene_definitions.yml b/example-project/selene_definitions.yml new file mode 100644 index 00000000..4bd464f5 --- /dev/null +++ b/example-project/selene_definitions.yml @@ -0,0 +1,7 @@ +base: roblox +name: selene_defs +globals: + # override Roblox require style with string requires + require: + args: + - type: string \ No newline at end of file diff --git a/example-project/src/Sum.luau b/example-project/src/Sum.luau new file mode 100644 index 00000000..1420000c --- /dev/null +++ b/example-project/src/Sum.luau @@ -0,0 +1,3 @@ +return function(a, b) + return a + b +end diff --git a/example-project/src/__tests__/sum.spec.lua b/example-project/src/__tests__/sum.spec.lua new file mode 100644 index 00000000..d9dc7e26 --- /dev/null +++ b/example-project/src/__tests__/sum.spec.lua @@ -0,0 +1,10 @@ +local JestGlobals = require("@DevPackages/JestGlobals") + +local it = JestGlobals.it +local expect = JestGlobals.expect + +local sum = require("@Project/Sum") + +it("adds 1 + 2 to equal 3", function() + expect(sum(1, 2)).toBe(3) +end) diff --git a/example-project/src/init.luau b/example-project/src/init.luau new file mode 100644 index 00000000..7163a0c5 --- /dev/null +++ b/example-project/src/init.luau @@ -0,0 +1,3 @@ +return { + Sum = require(script.Sum), +} diff --git a/example-project/src/jest.config.luau b/example-project/src/jest.config.luau new file mode 100644 index 00000000..2350a9ab --- /dev/null +++ b/example-project/src/jest.config.luau @@ -0,0 +1,9 @@ +return { + testMatch = { + "**/__tests__/*.(spec|test)", + }, + testPathIgnorePatterns = { + "Packages", + "DevPackages", + }, +} diff --git a/example-project/wally.toml b/example-project/wally.toml new file mode 100644 index 00000000..73cd543f --- /dev/null +++ b/example-project/wally.toml @@ -0,0 +1,9 @@ +[package] +name = "jsdotlua/jest-lua-example" +version = "0.1.0" +registry = "https://github.com/UpliftGames/wally-index" +realm = "shared" + +[dev-dependencies] +Jest = "jsdotlua/jest@3.6.1-rc.2" +JestGlobals = "jsdotlua/jest-globals@3.6.1-rc.2"