Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Update Documentation and add an Example Game
Documentation now provides clear instructions on how to use Jest Lua
  • Loading branch information
YetAnotherClown committed Aug 30, 2024
commit 1ef2056243ee87102b922328d60f42e1b530af01
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,3 @@ roblox.toml
# Editor files
.vscode/launch.json
.idea
.vscode
34 changes: 12 additions & 22 deletions docs/docs/CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,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
```
Expand Down
50 changes: 27 additions & 23 deletions docs/docs/GettingStarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ The Jest Lua API is similar to [the API used by JavaScript Jest.](https://jestjs

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-game) 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"
Expand All @@ -18,7 +22,7 @@ JestGlobals = "jsdotlua/[email protected]"

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"
{
Expand All @@ -30,6 +34,9 @@ Create a `default.project.json` to set up your project structure and include the
"Project": {
"$path": "src"
}
},
"DevPackages": {
"$path": "DevPackages"
}
}
}
Expand All @@ -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
```
Expand All @@ -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",
},
}
```

Expand Down Expand Up @@ -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!
Comment on lines 108 to +118
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't technically related to your PR, but debug.loadmodule is no longer necessary to run Jest, so that whole line can just be removed. Alternatively, you could add an info block that it is necessary in older versions.

run-in-roblox also isn't necessary anymore thanks to Open Cloud execution. Not sure if this is the best time to change that line though since we don't have a good out-of-the-box story for running Jest in Open Cloud yet. Thoughts?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that's cool. I didn't know debug.loadmodule was no longer needed, I guess I need to update my dependencies.

As for run-in-roblox, I think we leave it for now and decide again on this in the future. I do think we could expand the documentation and provide the different options users have for running Jest in the future though.


```bash
run-in-roblox --place test-place.rbxl --script scripts/run-tests.lua
Expand Down
24 changes: 24 additions & 0 deletions example-game/.darklua.json
Original file line number Diff line number Diff line change
@@ -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"
}
]
}
10 changes: 10 additions & 0 deletions example-game/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*.rbxlx.lock
/*.rbxl.lock
/*.rbxl
/*.rbxm

DevPackages/
dist/

sourcemap.json
wally.lock
15 changes: 15 additions & 0 deletions example-game/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"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.require.directoryAliases": {
"@Project": "src/",
"@DevPackages": "DevPackages/"
},
"luau-lsp.ignoreGlobs": [
"DevPackages/*",
"dist/*",
]
}
24 changes: 24 additions & 0 deletions example-game/README.md
Original file line number Diff line number Diff line change
@@ -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.
6 changes: 6 additions & 0 deletions example-game/build.project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "JestLuaProject",
"tree": {
"$path": "dist/src"
}
}
22 changes: 22 additions & 0 deletions example-game/default.project.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
}
22 changes: 22 additions & 0 deletions example-game/dev.project.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
}
10 changes: 10 additions & 0 deletions example-game/rokit.toml
Original file line number Diff line number Diff line change
@@ -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 <tool>` in a terminal.

[tools]
rojo = "rojo-rbx/[email protected]"
run-in-roblox = "rojo-rbx/[email protected]"
wally = "upliftGames/[email protected]"
darklua = "seaofvoices/[email protected]"
13 changes: 13 additions & 0 deletions example-game/scripts/build.sh
Original file line number Diff line number Diff line change
@@ -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
13 changes: 13 additions & 0 deletions example-game/scripts/dev.sh
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions example-game/scripts/install-packages.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh

set -e

wally install
19 changes: 19 additions & 0 deletions example-game/scripts/run-tests.server.luau
Original file line number Diff line number Diff line change
@@ -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
15 changes: 15 additions & 0 deletions example-game/scripts/test.sh
Original file line number Diff line number Diff line change
@@ -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 --watch src/ dist/src \
& darklua process --config .darklua.json --watch 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
4 changes: 4 additions & 0 deletions example-game/selene.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
std = "selene_definitions"

[rules]
global_usage = "allow"
7 changes: 7 additions & 0 deletions example-game/selene_definitions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
base: roblox
name: selene_defs
globals:
# override Roblox require style with string requires
require:
args:
- type: string
3 changes: 3 additions & 0 deletions example-game/src/Sum.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
return function(a, b)
return a + b
end
Loading