Skip to content

Update setup instructions to be clear and add an example project #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
34 changes: 12 additions & 22 deletions docs/docs/CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
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 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"
Expand All @@ -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"
{
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
Member

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-project/.darklua.json
Copy link
Member

Choose a reason for hiding this comment

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

Could you change the example project to not be using Darklua? It complicates a minimal example and we'll also eventually be moving away from it for most Roblox code thanks to native string requires (though Jest doesn't support this yet.)

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-project/.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
6 changes: 6 additions & 0 deletions example-project/.luaurc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"aliases": {
"Project": "src/",
"DevPackages": "DevPackages/"
}
}
11 changes: 11 additions & 0 deletions example-project/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -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/*",
]
}
24 changes: 24 additions & 0 deletions example-project/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-project/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-project/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-project/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-project/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/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"
13 changes: 13 additions & 0 deletions example-project/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-project/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-project/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-project/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-project/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 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
4 changes: 4 additions & 0 deletions example-project/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-project/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-project/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
10 changes: 10 additions & 0 deletions example-project/src/__tests__/sum.spec.lua
Original file line number Diff line number Diff line change
@@ -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)
Loading