### Jest Lua Configuration File Example Source: https://jsdotlua.github.io/jest-lua/configuration Example `jest.config.lua` file demonstrating how to specify `setupFilesAfterEnv` to include custom setup scripts for the Jest Lua testing environment. ```Lua return { setupFilesAfterEnv = { Workspace.setupJest }, } ``` -------------------------------- ### Example Jest-Lua Test File Source: https://jsdotlua.github.io/jest-lua/upgrading-to-jest3 A basic example of a Jest-Lua test file demonstrating a simple test definition. This snippet illustrates the standard structure of a test, which can then be targeted by filtering configurations. ```Lua test('the data is peanut butter', function() -- ... end) ``` -------------------------------- ### Execute Jest Lua Tests with run-in-roblox Source: https://jsdotlua.github.io/jest-lua/index This shell command demonstrates how to run Jest Lua tests using the `run-in-roblox` utility. It specifies the Roblox place file and the entry-point script (`run-tests.lua`) to execute the test suite. ```Shell run-in-roblox --place test-place.rbxl --script scripts/run-tests.lua ``` -------------------------------- ### Understanding Jest Lua Hook Execution Order Source: https://jsdotlua.github.io/jest-lua/setup-teardown Provides a detailed example illustrating the execution order of `beforeAll`, `afterAll`, `beforeEach`, and `afterEach` hooks, including how they interact with nested `describe` blocks, to help predict test flow. ```Lua beforeAll(function() print('1 - beforeAll') end) afterAll(function() print('1 - afterAll') end) beforeEach(function() print('1 - beforeEach') end) afterEach(function() print('1 - afterEach') end) test('', function() print('1 - test') end) describe('Scoped / Nested block', function() beforeAll(function() print('2 - beforeAll') end) afterAll(function() print('2 - afterAll') end) beforeEach(function() print('2 - beforeEach') end) afterEach(function() print('2 - afterEach') end) test('', function() print('2 - test') end) end) -- 1 - beforeAll -- 1 - beforeEach -- 1 - test -- 1 - afterEach -- 2 - beforeAll -- 1 - beforeEach -- 2 - beforeEach -- 2 - test -- 2 - afterEach -- 1 - afterEach -- 2 - afterAll -- 1 - afterAll ``` -------------------------------- ### Configure Jest Lua Dependencies with Wally Source: https://jsdotlua.github.io/jest-lua/index This TOML configuration snippet specifies Jest and JestGlobals as development dependencies for a Roblox project using Wally, enabling Jest Lua for testing. ```TOML [dev-dependencies] Jest = "jsdotlua/jest@3.10.0" JestGlobals = "jsdotlua/jest-globals@3.10.0" ``` -------------------------------- ### Run Jest Lua Tests from Command Line Source: https://jsdotlua.github.io/jest-lua/index This Lua script serves as the entry point for running Jest Lua tests. It initializes the Jest CLI, points it to the project's test directory, and handles the exit status based on test results, integrating with Roblox's ProcessService for command-line execution. ```Lua local ReplicatedStorage = game:GetService("ReplicatedStorage") local runCLI = require("@DevPackages/Jest").runCLI local processServiceExists, ProcessService = pcall(function() return game:GetService("ProcessService") end) local status, result = runCLI(ReplicatedStorage.Packages.Project, { verbose = false, ci = false }, { ReplicatedStorage.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 return nil ``` -------------------------------- ### Example of Descriptive Snapshot Names in Jest Lua Source: https://jsdotlua.github.io/jest-lua/snapshot-testing Provides an example of well-named snapshot exports (e.g., `should be nil`), which clearly convey the expected content. This practice significantly improves the readability of pull requests and simplifies the process of verifying or updating snapshots. ```Lua exports[ [=[should be nil 1]=] ] = [=[ nil]=] exports[ [=[should be Alan Turing 1]=] ] = [=[ "Alan Turing"]=] ``` -------------------------------- ### One-Time Setup with beforeAll and afterAll in Jest Lua Source: https://jsdotlua.github.io/jest-lua/setup-teardown Shows how to use `beforeAll` and `afterAll` hooks to perform setup and teardown operations only once at the beginning and end of a test file, which is efficient for reusable resources or asynchronous setup. ```Lua beforeAll(function() return initializeCityDatabase() end) afterAll(function() return clearCityDatabase() end) test('city database has Vienna', function() expect(isCity('Vienna')).toBeTruthy() end) test('city database has San Juan', function() expect(isCity('San Juan')).toBeTruthy() end) ``` -------------------------------- ### Repeating Setup with beforeEach and afterEach in Jest Lua Source: https://jsdotlua.github.io/jest-lua/setup-teardown Demonstrates how to use `beforeEach` and `afterEach` hooks to perform setup and teardown operations repeatedly before and after each test in Jest Lua, ensuring a clean state for every test. ```Lua beforeEach(function() initializeCityDatabase() end) afterEach(function() clearCityDatabase() end) test('city database has Vienna', function() expect(isCity('Vienna')).toBeTruthy() end) test('city database has San Juan', function() expect(isCity('San Juan')).toBeTruthy() end) ``` -------------------------------- ### Jest Lua setupFilesAfterEnv Example: Custom Matcher and Teardown Source: https://jsdotlua.github.io/jest-lua/configuration Example Lua script demonstrating how to use `setupFilesAfterEnv` to extend Jest's `expect` with a custom matcher and register an `afterEach` hook for test cleanup, such as resetting timers. ```Lua local JestGlobals = require("@DevPackages/JestGlobals") local jest = JestGlobals.jest local expect = JestGlobals.expect local afterEach = JestGlobals.afterEach expect.extend({ newMatcher = function(self, received, expected) -- ... end) }) afterEach(function() jest.useRealTimers() end) ``` -------------------------------- ### Define Roblox Project Structure with default.project.json Source: https://jsdotlua.github.io/jest-lua/index This JSON configuration defines the project structure for a Roblox application, mapping the 'Packages' directory (for Wally dependencies) and the 'src' directory to a 'Project' folder within the Roblox game tree. ```JSON { "name": "YourProject", "tree": { "$className": "Folder", "Packages": { "$path": "Packages", "Project": { "$path": "src" } } } } ``` -------------------------------- ### Handling Asynchronous beforeEach in Jest Lua Source: https://jsdotlua.github.io/jest-lua/setup-teardown Illustrates how `beforeEach` can handle asynchronous setup operations by returning a promise, ensuring that the setup completes before any tests in the block are executed. ```Lua beforeEach(function() return initializeCityDatabase() end) ``` -------------------------------- ### Example of Undescriptive Snapshot Names in Jest Lua Source: https://jsdotlua.github.io/jest-lua/snapshot-testing Presents an example of poorly named snapshot exports (e.g., `test case 1`), which lack clarity regarding their expected content. Such naming conventions hinder reviewability and make debugging failed tests more challenging. ```Lua exports[ [=[test case 1]=] ] = [=[ nil]=] exports[ [=[some other test case 1]=] ] = [=[ "Alan Turing"]=] ``` -------------------------------- ### Configure Jest Lua Test Match Pattern Source: https://jsdotlua.github.io/jest-lua/index This Lua configuration file for Jest Lua defines the `testMatch` pattern, specifying that only files ending with `.spec` should be considered as test files within the project. ```Lua return { testMatch = { "**/*.spec" } } ``` -------------------------------- ### Enable Roblox debug.loadmodule API Source: https://jsdotlua.github.io/jest-lua/index This JSON configuration for Roblox's ClientAppSettings enables the `FFlagEnableLoadModule` flag, which is necessary for Jest Lua to utilize the `debug.loadmodule` API for test execution. ```JSON { "FFlagEnableLoadModule": true } ``` -------------------------------- ### Scoping Setup and Teardown Hooks with describe Blocks in Jest Lua Source: https://jsdotlua.github.io/jest-lua/setup-teardown Demonstrates how `beforeEach` and `beforeAll` hooks can be scoped to specific test groups using `describe` blocks, allowing different setup logic for different sets of tests within the same file. ```Lua -- Applies to all tests in this file beforeEach(function() return initializeCityDatabase() end) test('city database has Vienna', function() expect(isCity('Vienna')).toBeTruthy() end) test('city database has San Juan', function() expect(isCity('San Juan')).toBeTruthy() end) describe('matching cities to foods', function() -- Applies only to tests in this describe block beforeEach(function() return initializeFoodDatabase() end) test('Vienna <3 veal', function() expect(isValidCityFoodPair('Vienna', 'Wiener Schnitzel')).toBe(true) end) test('San Juan <3 plantains', function() expect(isValidCityFoodPair('San Juan', 'Mofongo')).toBe(true) end) end) ``` -------------------------------- ### Jest Lua Configuration Options Reference Source: https://jsdotlua.github.io/jest-lua/configuration Comprehensive reference for available configuration options in `jest.config.lua`, including their types, default values, detailed descriptions, and usage examples. ```APIDOC clearmocks [boolean] Default: false Description: Automatically clear mock calls, instances, contexts and results before every test. Equivalent to calling `jest.clearAllMocks()` before each test. This does not remove any mock implementation that may have been provided. displayName [string, table] Default: nil Description: Allows for a label to be printed alongside a test while it is running. This becomes more useful in multi-project repositories where there can be many jest configuration files. This visually tells which project a test belongs to. Example (string): ```lua return { displayName = 'CLIENT', } ``` Example (table with color): ```lua return { displayName = { name = 'CLIENT', color = 'blue', } } ``` projects [array] Default: nil Description: When the `projects` configuration is provided with an array of instances, Jest Lua will run tests in all of the specified projects at the same time. This is great for monorepos or when working on multiple projects at the same time. Example: ```lua return { projects = { Workspace.ProjectB, Workspace.ProjectB }, } ``` ``` -------------------------------- ### Jest Lua v2.x test file structure example Source: https://jsdotlua.github.io/jest-lua/upgrading-to-jest3 This Lua snippet illustrates the typical structure of a test file in Jest Lua v2.x. It shows how test logic, including `expect` and `it` calls, was encapsulated within a function returned by the module. ```Lua return function() local JestGlobals = require("@DevPackages/JestGlobals") local expect = JestGlobals.expect it("1 does not equal 2", function() expect(1).toBe(2) end) end ``` -------------------------------- ### Jest Lua v3.x updated test file structure example Source: https://jsdotlua.github.io/jest-lua/upgrading-to-jest3 This Lua snippet demonstrates the revised test file structure for Jest Lua v3.x. Unlike v2.x, test files no longer return a callback. It also highlights the necessity of explicitly importing `it` (along with `expect`) from `JestGlobals`. ```Lua local JestGlobals = require("@DevPackages/JestGlobals") local expect = JestGlobals.expect local it = JestGlobals.it it("1 does not equal 2", function() expect(1).toBe(2) end) ``` -------------------------------- ### Write a Basic Jest Lua Test for Sum Function Source: https://jsdotlua.github.io/jest-lua/index This Lua test file uses Jest Lua's `it` and `expect` functions to verify the `sum` function. It asserts that `sum(1, 2)` correctly returns `3`, demonstrating a fundamental unit test. ```Lua 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) ``` -------------------------------- ### Start and Stop Profiler Sections Source: https://jsdotlua.github.io/jest-lua/jest-benchmark Shows the basic usage of `Profiler.start` and `Profiler.stop` to define and measure a profiling segment. ```Lua Profiler.start("section1") Profiler.stop() ``` -------------------------------- ### Example of a generated Jest Lua snapshot artifact Source: https://jsdotlua.github.io/jest-lua/snapshot-testing This snippet shows the structure of a snapshot file generated by Jest Lua. It's a human-readable representation of the Lua table captured by the `toMatchSnapshot` assertion, used for comparison on subsequent test runs. These artifacts are typically committed to version control. ```Lua exports[ [=[describe table 1]=] ] = [=[ Table { "a": 1, "b": "test", "c": Table { "array", "of", "strings", }, } ]=] ``` -------------------------------- ### Illustrating Jest Lua beforeEach and afterEach Hook Execution Source: https://jsdotlua.github.io/jest-lua/setup-teardown This example demonstrates the execution order of `beforeEach` and `afterEach` hooks in Jest Lua, including how they behave with nested `describe` blocks. It shows that `beforeEach` hooks run in declaration order, and `afterEach` hooks run in reverse declaration order for the current scope, with enclosing scope `afterEach` hooks running first, which is crucial for managing dependent resources. ```Lua beforeEach(function() print('connection setup') end) beforeEach(function() print('database setup') end) afterEach(function() print('database teardown') end) afterEach(function() print('connection teardown') end) test('test 1', function() print('test 1') end) describe('extra', function() beforeEach(function() print('extra database setup') end) afterEach(function() print('extra database teardown') end) test('test 2', function() print('test 2') end) end) -- connection setup -- database setup -- test 1 -- database teardown -- connection teardown -- connection setup -- database setup -- extra database setup -- test 2 -- extra database teardown -- database teardown -- connection teardown ``` -------------------------------- ### Set up before each test with Jest Lua's beforeEach Source: https://jsdotlua.github.io/jest-lua/api Shows how to use `beforeEach(fn, timeout)` to run a setup function before each individual test. This is beneficial for resetting global state or preparing a fresh environment for every test. The function can be asynchronous, and a `timeout` can be configured. ```Lua local globalDatabase = makeGlobalDatabase() beforeEach(function() -- Clears the database and adds some testing data. -- Jest Lua will wait for this promise to resolve before running tests. return globalDatabase:clear() :then(function() return globalDatabase:insert({testData = 'foo'}) end) end) test('can find things', function() return globalDatabase:find('thing', {}, function(results) expect(#results).toBeGreaterThan(0) end) end) test('can insert a thing', function() return globalDatabase:insert('thing', makeThing(), function(response) expect(response.success).toBeTruthy() end) end) ``` -------------------------------- ### JestBenchmark Core Functions and Reporter API Source: https://jsdotlua.github.io/jest-lua/jest-benchmark Comprehensive documentation for the JestBenchmark library's main 'benchmark' function and the 'Reporter' object, detailing how to initialize, start, stop, report values, and finalize metric collection. ```APIDOC benchmark(name: string, fn: function, timeout?: number) - Description: A wrapper around `test` providing automatic profiling for FPS and benchmark running time. Supports `benchmark.only` and `benchmark.skip`. - Parameters: - name: The name of the benchmark. - fn: The function containing the code to benchmark. Receives `Profiler` and `reporters` as arguments. - timeout: Optional. The maximum time for the benchmark to run. - Example Usage: describe("Home Page Benchmarks", function() benchmark("First Render Performance", function(Profiler, reporters) render(React.createElement(HomePage)) local GameCarousel = screen.getByText("Continue"):expect() expect(GameCarousel).toBeDefined() end) end) Reporter Object - Description: Collects and aggregates data during a benchmark. initializeReporter(metricName: string, fn: function) - Description: Creates a `Reporter` object. - Parameters: - metricName: The label for the collected data. - fn: A collector function (e.g., `average`) that accepts a list of numbers and reduces them to a single value. - Returns: Reporter object - Example Collector Function: local function average(nums: { number }): num if #nums == 0 then return 0 end local sum = 0 for _, v in nums do sum += v end return sum / #nums end - Example Initialization: local averageReporter = initializeReporter("average", average) Reporter.start(sectionName: string) - Description: Initializes a reporting segment. All values reported within this segment are grouped and reduced by `Reporter.finish`. Segments can be nested. Must be concluded by `Reporter.stop`. - Parameters: - sectionName: The name of the reporting segment. Reporter.stop() - Description: Pops the current reporter section from the stack, marking reported values for collection at the end of the benchmark. Reporter.report(value: T) - Description: Adds a value to the report queue. Values are reduced when `reporter.finish` is called. - Parameters: - value: The value to add to the report queue. Reporter.finish() - Description: Finalizes the reporting process, performs collection, and returns section names and their reduced values. - Returns: tuple (sectionNames: {string}, sectionValues: {number}) - Example Usage: averageReporter.start("total") averageReporter.start("section1") averageReporter.report(1) averageReporter.report(3) averageReporter.stop() -- closes section1 averageReporter.start("section2") averageReporter.report(5) averageReporter.report(7) averageReporter.stop() -- closes section2 averageReporter.stop() -- closes total local sectionNames, sectionValues = averageReporter.finish() -- sectionNames: {"section1", "section2", "total"} -- sectionValues: {2, 6, 4} ``` -------------------------------- ### Jest-Lua Mock Function API Reference and Examples Source: https://jsdotlua.github.io/jest-lua/mock-function-api Detailed API documentation for Jest-Lua mock function properties and methods, including `mock.lastCall`, `mockClear()`, `mockReset()`, and `mockImplementation(fn)`, along with practical Lua code examples demonstrating their usage. ```APIDOC mockFn.mock.lastCall - Type: Array (Lua table) - Description: An array containing the call arguments of the last call that was made to this mock function. - Returns: An array of arguments, or `nil` if the function was not called. mockFn.mockClear() - Description: Clears all information stored in the `mockFn.mock.calls`, `mockFn.mock.instances`, and `mockFn.mock.results` arrays. - Purpose: Useful for cleaning up a mock's usage data between two assertions. - Note: `mockClear` will replace `mockFn.mock`. Avoid assigning `mockFn.mock` to other variables to prevent stale data access. - Related: The `clearMocks` configuration option can clear mocks automatically before each test. mockFn.mockReset() - Description: Performs all actions of `mockFn.mockClear()` and additionally removes any mocked return values or implementations. - Purpose: To completely reset a mock back to its initial state. - Note: Resetting a spy will result in a function with no return value. `mockReset` will replace `mockFn.mock`. - Related: The `resetMocks` configuration option can reset mocks automatically before each test. mockFn.mockImplementation(fn) - Parameters: - fn: A function that should be used as the implementation of the mock. - Description: Accepts a function that will be executed when the mock is called. The mock itself will still record all calls and instances. - Shorthand: `jest.fn(implementation)` is a shorthand for `jest.fn().mockImplementation(implementation)`. - Caution: Mocks should be lightweight. Favor `mockReturnValue` over `mockImplementation` or `mockImplementationOnce` where possible. ``` ```Lua {'arg3', 'arg4'} ``` ```Lua local mockFn = jest.fn().mockImplementation(function(scalar) return 42 + scalar end) -- or: jest.fn(function(scalar) return 42 + scalar end) local a = mockFn(0) local b = mockFn(1) a == 42 == true b == 43 == true mockFn.mock.calls[1][1] == 0 -- true mockFn.mock.calls[2][1] == 1 -- true ``` -------------------------------- ### Define a Simple Sum Function in Lua Source: https://jsdotlua.github.io/jest-lua/index This Lua snippet defines a basic function named `sum` that takes two numerical arguments, `a` and `b`, and returns their sum. This function is intended to be tested by Jest Lua. ```Lua return function(a, b) return a + b end ``` -------------------------------- ### Implement and Use Custom Reporters Source: https://jsdotlua.github.io/jest-lua/jest-benchmark Illustrates how to add custom reporters to the `Profiler` using `CustomReporters.useCustomReporters` and `CustomReporters.useDefaultReporters`. This example defines a 'sum' reporter and integrates it into a benchmark. ```Lua local MetricLogger = JestBenchmarks.CustomReporters beforeEach(function() CustomReporters.useCustomReporters({ sum = initializeReporter("sum", function(nums) local sum = 0 for _, v in nums do sum += v end return sum end) }) end) benchmark("Total renders", function(Profiler, reporters) local renderCount = getRenderCount() reporters.sum.report(renderCount) end) afterEach(function() CustomReporters.useDefaultReporters() end) ``` -------------------------------- ### Set up once before all tests with Jest Lua's beforeAll Source: https://jsdotlua.github.io/jest-lua/api Illustrates the use of `beforeAll(fn, timeout)` to execute a setup function once before any tests in the file run. This is ideal for establishing global state, such as populating a database, that will be used by multiple tests. It supports asynchronous operations via promises and allows a `timeout`. ```Lua local globalDatabase = makeGlobalDatabase() beforeAll(function() -- Clears the database and adds some testing data. -- Jest Lua will wait for this promise to resolve before running tests. return globalDatabase:clear() :then(function() return globalDatabase:insert({testData = 'foo'}) end) end) -- Since we only set up the database once in this example, it's important -- that our tests don't modify it. test('can find things', function() return globalDatabase:find('thing', {}, function(results) expect(#results).toBeGreaterThan(0) end) end) ``` -------------------------------- ### Jest Lua Snapshot Output: Custom Serializer Example Source: https://jsdotlua.github.io/jest-lua/configuration This is the rendered snapshot output when the custom serializer is applied. It shows how the `foo` field of the table is formatted with the 'Pretty foo: ' prefix, demonstrating the effect of the custom `serialize` function. ```Lua Pretty foo: Table {\n "x": 1,\n "y": 2,\n} ``` -------------------------------- ### Migrate `spec.lua` to `Jest.runCLI` entrypoint Source: https://jsdotlua.github.io/jest-lua/upgrading-to-jest3 This Lua snippet demonstrates the updated `spec.lua` bootstrap script for Jest Lua v3.0. It replaces `TestEZ.TestBootStrap:run` with `Jest.runCLI` as the primary test runner, showing how to pass project source, configuration options, and handle test execution results, including process exit codes. ```Lua local YourProject = script.Parent.YourProject local runCLI = require("@DevPackages/Jest").runCLI local processServiceExists, ProcessService = pcall(function() return game:GetService("ProcessService") end) local status, result = runCLI(YourProject.Source, { verbose = false, ci = false }, { YourProject.Source }):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 return nil ``` -------------------------------- ### Example of Jest Lua Requiring Actual Module with `jest.requireActual` Source: https://jsdotlua.github.io/jest-lua/jest-object Shows how to use `jest.requireActual` to bypass any existing mocks and load the original, unmocked version of a module directly. ```Lua it("mockedModule also should not be mocked", function() mockedModule = jest.requireActual(Workspace.mockedModule) expect(mockedModule).toEqual({}) end) ``` -------------------------------- ### Enable `FFlagEnableLoadModule` in `ClientAppSettings.json` Source: https://jsdotlua.github.io/jest-lua/upgrading-to-jest3 This JSON snippet shows how to add the `FFlagEnableLoadModule` fast flag to your Roblox Studio `ClientAppSettings.json` file. This flag is a mandatory requirement for Jest Lua v3.0 to function correctly. ```JSON { "FFlagEnableLoadModule": true } ``` -------------------------------- ### Jest-Lua: Example Snapshot Output for Error Matching Source: https://jsdotlua.github.io/jest-lua/expect The generated snapshot content for the `toThrowErrorMatchingSnapshot` test. This shows how Jest-Lua stores the error message in the `.snap` file for future comparisons. ```Lua exports["drinking flavors throws on octopus 1"] = [=[ yuck, octopus flavor]=] ``` -------------------------------- ### Match string against pattern or regex in Lua Source: https://jsdotlua.github.io/jest-lua/expect Examples illustrating the use of `.toMatch()` to assert if a string matches a specified Lua string pattern or a regular expression. The first example uses a simple string pattern, and the second uses a `RegExp` object. ```Lua describe('an essay on the best flavor', function() it('mentions grapefruit', function() expect(essayOnTheBestFlavor()).toMatch('grapefruit') end) end) ``` ```Lua describe('an essay on the best flavor', function() it('mentions grapefruit or orange', function() expect(essayOnTheBestFlavor()).toMatch(RegExp('grapefruit|orange')) end) end) ``` -------------------------------- ### Demonstrating Jest Lua Describe and Test Execution Order Source: https://jsdotlua.github.io/jest-lua/setup-teardown This snippet illustrates the execution order of `describe` and `test` blocks in Jest Lua. It shows that all `describe` blocks are executed first, followed by the `test` blocks in the order they were encountered during the collection phase, even when nested. The comments indicate the console output order. ```Lua describe('describe outer', function() print('describe outer-a') describe('describe inner 1', function() print('describe inner 1') test('test 1', function() print('test 1') end) end) print('describe outer-b') test('test 2', function() print('test 2') end) describe('describe inner 2', function() print('describe inner 2') test('test 3', function() print('test 3') end) end) print('describe outer-c') end) -- describe outer-a -- describe inner 1 -- describe outer-b -- describe inner 2 -- describe outer-c -- test 1 -- test 2 -- test 3 ``` -------------------------------- ### Example of Jest Lua Module Mocking with `jest.mock` Source: https://jsdotlua.github.io/jest-lua/jest-object Demonstrates how to use `jest.mock` to mock a Lua module. It includes a `beforeEach` block to reset modules and define a mock implementation, and an `it` block to verify that the mocked module returns the expected values. ```Lua -- mockedModule.lua return {} ``` ```Lua -- __tests__/testMockedModule.spec.lua beforeEach(function() jest.resetModules() jest.mock(Workspace.mockedModule, function() return { default = jest.fn(function() return 42 end), foo = jest.fn(function() return 43 end) } end) end) local mockedModule it("mockedModule should be mocked", function() mockedModule = require(Workspace.mockedModule) expect(mockedModule.default()).toBe(42) expect(mockedModule.foo()).toBe(43) end) ``` -------------------------------- ### Configure `jest.config.lua` for test discovery Source: https://jsdotlua.github.io/jest-lua/upgrading-to-jest3 This Lua snippet provides a basic `jest.config.lua` file, which is a new requirement for Jest Lua v3.0. It specifies `testMatch` to define patterns for discovering test files, in this case, all files ending with `.spec`. ```Lua return { testMatch = { "**/*.spec" }, } ``` -------------------------------- ### Jest-like Matchers for Lua Testing Framework Source: https://jsdotlua.github.io/jest-lua/expect Comprehensive documentation for various Jest-inspired matchers adapted for Lua, providing methods to assert property existence, compare floating-point numbers, and check for defined or falsy values. Each matcher includes its signature, parameters, return values (implicit in assertions), and usage examples. ```APIDOC .toHaveProperty(keyPath, value?) - Checks if a property exists at `keyPath` for an object, optionally comparing its value. Supports dot notation or array for deep references. - Parameters: - keyPath: string | table (array) - The path to the property. Can be dot-notation string or an array of keys for deep references. - value: any (optional) - The value to compare against the property's value (deep equality). - Usage Example: local houseForSale = { bath = true, bedrooms = 4, kitchen = { amenities = {'oven', 'stove', 'washer'}, area = 20, wallColor = 'white', 'nice.oven' = true, }, 'ceiling.height' = 2, } it('this house has my desired features', function() expect(houseForSale).toHaveProperty('bath') expect(houseForSale).toHaveProperty('bedrooms', 4) expect(houseForSale).never.toHaveProperty('pool') expect(houseForSale).toHaveProperty('kitchen.area', 20) expect(houseForSale).toHaveProperty('kitchen.amenities', { 'oven', 'stove', 'washer', }) expect(houseForSale).never.toHaveProperty('kitchen.open') expect(houseForSale).toHaveProperty({'kitchen', 'area'}, 20) expect(houseForSale).toHaveProperty( {'kitchen', 'amenities'}, {'oven', 'stove', 'washer'} ) expect(houseForSale).toHaveProperty({'kitchen', 'amenities', 1}, 'oven') expect(houseForSale).toHaveProperty({'kitchen', 'nice.oven'}) expect(houseForSale).never.toHaveProperty({'kitchen', 'open'}) expect(houseForSale).toHaveProperty({'ceiling.height'}, 'tall') end) .toBeCloseTo(number, numDigits?) - Compares floating point numbers for approximate equality, addressing common rounding errors. - Parameters: - number: number - The expected number. - numDigits: number (optional) - The number of digits to check after the decimal point (default: 2). - Usage Example: it('adding works sanely with decimals', function() expect(0.2 + 0.1).toBe(0.3) -- Fails! (0.30000000000000004) expect(0.2 + 0.1).toBeCloseTo(0.3, 5) -- Passes end) .toBeDefined() - Checks that a variable is not `nil`. - Note: Functionally identical to `.never.toBeNil()`, which is preferred. - Usage Example: it('there is a new flavor idea', function() expect(fetchNewFlavorIdea()).toBeDefined() end) .toBeFalsy() - Ensures a value is false in a boolean context. - Falsy values in Lua: `false`, `nil`. All other values are truthy. - Usage Example: it('drinking La Croix does not lead to errors', function() drinkSomeLaCroix() expect(getErrors()).toBeFalsy() end) ``` -------------------------------- ### Create a basic snapshot test in Jest Lua Source: https://jsdotlua.github.io/jest-lua/snapshot-testing This snippet demonstrates how to create a basic snapshot test in Jest Lua. It defines a test case that expects a Lua table to match a snapshot, which will be generated on the first run. This is the fundamental way to capture a UI or data state. ```Lua it('table', function() expect({ a = 1, b = "test", c = { "array", "of", "strings" } }).toMatchSnapshot() end) ``` -------------------------------- ### Create Custom Snapshot Matchers in Lua Source: https://jsdotlua.github.io/jest-lua/expect Demonstrates how to extend Jest-like matchers in Lua to support snapshot testing. This example shows a `toMatchTrimmedSnapshot` matcher that trims a string before storing it as a snapshot, leveraging the `JestSnapshot` module. ```Lua local JestSnapshot = require("@DevPackages/JestSnapshot") local toMatchSnapshot = JestRoblox.JestSnapshot.toMatchSnapshot expect.extend({ toMatchTrimmedSnapshot = function(self, received, length) return toMatchSnapshot( self, string.sub(received, 1, length), 'toMatchTrimmedSnapshot' ) end }) it('stores only 10 characters', function() expect('extra long string oh my gerd').toMatchTrimmedSnapshot(10) end) -- Stored snapshot will look like: -- exports["another package custom snapshot matcher: toMatchTrimmedSnapshot 1"] = [=[ -- "extra long"]=] ``` -------------------------------- ### Implement `toBe` Matcher with `jest-matcher-utils` in Jest Lua Source: https://jsdotlua.github.io/jest-lua/expect Shows an example of implementing a `toBe` matcher in Jest Lua, demonstrating the use of `self.utils.matcherHint`, `self.utils.printExpected`, and `self.utils.printReceived` for generating informative and consistent error messages. This leverages `jest-matcher-utils` for a better developer experience when assertions fail. ```Lua expect.extend({ toBe = function(self, received, expected) local options = { comment = 'shallow equality', isNot = self.isNot, promise = self.promise, } local pass = received == expected local message if pass then message = function() return self.utils.matcherHint('toBe', nil, nil, options) .. '\n\n' .. string.format('Expected: never %s\n', self.utils.printExpected(expected)) .. string.format('Received: %s', self.utils.printReceived(expected)) end else message = function() return self.utils.matcherHint('toBe', nil, nil, options) .. '\n\n' .. string.format('Expected: %s\n', self.utils.printExpected(expected)) .. string.format('Received: %s', self.utils.printReceived(expected)) end end return {actual = received, pass = pass, message = message} end }) ``` -------------------------------- ### Parameterized tests with describe.each(...args) in Lua Source: https://jsdotlua.github.io/jest-lua/api Example demonstrating the use of `describe.each(...args)` for running parameterized tests in Lua. It shows how to define column headers in the first argument and then provide data rows, accessing parameters by name within the test function. ```Lua describe.each('a | b | expected', {1, 1, 2}, {1, 2, 3}, {2, 1, 3} )('.add($a, $b)', function(ref) local a, b, expected = ref.a, ref.b, ref.expected test('returns $expected', function() expect(a + b).toBe(expected) end) test('returned value not be greater than $expected', function() expect(a + b).never.toBeGreaterThan(expected) end) test('returned value not be less than $expected', function() expect(a + b).never.toBeLessThan(expected) end) end) ``` -------------------------------- ### Running a Single Test with Jest Lua's test.only Source: https://jsdotlua.github.io/jest-lua/setup-teardown This snippet demonstrates how to use `test.only` in Jest Lua to isolate and run a specific test. This is a valuable debugging technique for failing tests, as it ensures only the designated test executes, preventing potential interference or side effects from other tests in the suite. ```Lua test.only('this will be the only test that runs', function() expect(true).toBe(false) end) test('this test will not run', function() expect('A').toBe('A') end) ``` -------------------------------- ### Update `rotriever.toml` for Jest Lua v3.0 dependencies Source: https://jsdotlua.github.io/jest-lua/upgrading-to-jest3 This TOML snippet shows how to modify your `rotriever.toml` file to include `Jest` and `JestGlobals` as development dependencies, which are essential for Jest Lua v3.0 functionality, particularly for accessing the `runCLI` entrypoint. ```TOML [dev-dependencies] Jest = "jsdotlua/jest@3.10.0" JestGlobals = "jsdotlua/jest-globals@3.10.0" ``` -------------------------------- ### Apply mock functions in continuation-passing style with Jest Lua Source: https://jsdotlua.github.io/jest-lua/mock-functions This example illustrates the use of mock functions in a functional continuation-passing style. By configuring `mockReturnValueOnce()` for a `filterTestFn`, it shows how to inject controlled behavior into iterative processes, making tests more focused and predictable. ```Lua local filterTestFn = jest.fn() -- Make the mock return `true` for the first call, -- and `false` for the second call filterTestFn.mockReturnValueOnce(true).mockReturnValueOnce(false) local result = {} for _, num in ipairs({11, 12}) do if filterTestFn(num) then table.insert(result, num) end end print(result) -- > {11} print(filterTestFn.mock.calls) -- > {{11}, {12}} ``` -------------------------------- ### Roblox CLI flags for enabling snapshot write permissions Source: https://jsdotlua.github.io/jest-lua/snapshot-testing These are essential command-line flags required for `roblox-cli` to grant Jest Lua the necessary permissions to write updated snapshot files to the file system. Without these, snapshot updates will fail due to insufficient access. ```Shell --load.asRobloxScript --fs.readwrite="$(pwd)" ``` -------------------------------- ### Use Jest-Lua Custom Matchers for Mock Function Assertions Source: https://jsdotlua.github.io/jest-lua/mock-functions Provides examples of common custom matchers in Jest-Lua for asserting how mock functions have been called. These matchers offer a concise and readable way to verify mock interactions, such as whether a function was called at all or with specific arguments. ```Lua -- The mock function was called at least once expect(mockFunc).toHaveBeenCalled() -- The mock function was called at least once with the specified args expect(mockFunc).toHaveBeenCalledWith(arg1, arg2) -- The last call to the mock function was called with the specified args expect(mockFunc).toHaveBeenLastCalledWith(arg1, arg2) ``` -------------------------------- ### Jest-Lua Test Filtering Configuration Options Source: https://jsdotlua.github.io/jest-lua/upgrading-to-jest3 Details the primary configuration options available in Jest-Lua for selectively running tests. These options allow users to filter tests by file path or by test name, providing fine-grained control over test execution. ```APIDOC Configuration Option: testMatch - Type: string[] - Description: An array of glob patterns or regular expressions that Jest-Lua uses to find test files. - Behavior: Only test files matching these patterns will be executed. - Context: Can be set in `runCLI` options or `jest.config.lua`. - Example: `testMatch = { "**/peanutButter.spec" }` Configuration Option: testNamePattern - Type: string - Description: A regular expression that matches the full name of the test to run. - Behavior: Only tests whose names match this pattern within the selected test files will be executed. - Context: Typically passed into `runCLI` options. - Example: `testNamePattern = "the data is peanut butter"` ``` -------------------------------- ### Test forEach function using Jest Lua mock functions Source: https://jsdotlua.github.io/jest-lua/mock-functions This example demonstrates how to test the `forEach` utility function using `jest.fn()` to create a mock callback. It asserts that the mock function was called the correct number of times and with the expected arguments, verifying the `forEach` function's behavior. ```Lua local mockCallback = jest.fn() forEach({0, 1}, mockCallback) -- The mock function is called twice expect(#mockCallback.mock.calls).toBe(2) -- The first argument of the first call to the function was 0 expect(mockCallback.mock.calls[1][1]).toBe(0) -- The first argument of the second call to the function was 1 expect(mockCallback.mock.calls[2][1]).toBe(1) ``` -------------------------------- ### Assert detailed mock function call information in Jest Lua Source: https://jsdotlua.github.io/jest-lua/mock-functions This example showcases how to use various properties of the `.mock` object to assert detailed information about mock function calls. It covers checking the number of calls, specific arguments passed to calls, return values, and the number of times the mock was instantiated. ```Lua -- The function was called exactly once expect(#someMockFunction.mock.calls).toBe(1) -- The first arg of the first call to the function was 'first arg' expect(someMockFunction.mock.calls[1][1]).toBe('first arg') -- The second arg of the first call to the function was 'second arg' expect(someMockFunction.mock.calls[1][3]).toBe('second arg') -- The return value of the first call to the function was 'return value' expect(someMockFunction.mock.results[1].value).toBe('return value') -- This function was instantiated exactly twice expect(#someMockFunction.mock.instances).toBe(2) ``` -------------------------------- ### Combining Exact Values and Property Matchers in Jest Lua Snapshots Source: https://jsdotlua.github.io/jest-lua/snapshot-testing Shows the flexibility of Jest Lua snapshot testing, where specific properties can be matched exactly while others use asymmetric matchers like `expect.any()`. This allows precise control over which parts of an object are strictly snapshotted versus those that are matched by type. ```Lua it("will check the values and pass", function() local user = { createdAt = DateTime.now(), name = "Bond... James Bond" } expect(user).toMatchSnapshot({ createdAt = expect.any("DateTime"), name = "Bond... James Bond" }) end) -- Snapshot exports[ [=[will check the values and pass 1]=] ] = [=[ Table { "createdAt": Any, "name": "Bond... James Bond", } ]=] ``` -------------------------------- ### Initialize Profiler with Reporters and Output Function Source: https://jsdotlua.github.io/jest-lua/jest-benchmark Demonstrates how to initialize the `Profiler` object by providing a list of reporters and a custom output function for displaying benchmark results. ```Lua local reporters = { initializeReporter("average", average), initializeReporter("sectionTime", sectionTime), } local outputFn = function(metricName: string, value: any) print(`{metricName}, {value}`) end local profiler = initializeProfiler(reporters, outputFn) ``` -------------------------------- ### Jest Lua Configuration Options Reference Source: https://jsdotlua.github.io/jest-lua/configuration Comprehensive reference for Jest Lua configuration parameters, detailing their types, default values, and purpose in setting up the testing environment. ```APIDOC rootDir: Instance Default: The root of the directory containing your Jest Lua config file. Description: The root directory that Jest Lua should scan for tests and modules within. Notes: Oftentimes, you'll want to set this to your main workspace, corresponding to where in your repository the code is stored. roots: array Default: {} Description: A list of paths to directories that Jest Lua should use to search for files in. Notes: Useful for limiting Jest Lua to search in a single sub-directory (e.g., `src/`) and preventing access to the rest of the repository. setupFiles: array Default: {} Description: A list of ModuleScripts that run some code to configure or set up the testing environment. Each setupFile will be run once per test file. Notes: These scripts are executed in the testing environment before `setupFilesAfterEnv` and before the test code itself, as every test runs in its own environment. setupFilesAfterEnv: array Default: {} Description: A list of ModuleScripts that run some code to configure or set up the testing framework before each test file in the suite is executed. Notes: This script file allows running code immediately after the test framework has been installed but before the test code itself. `setupFilesAfterEnv` modules are meant for code which is repeating in each test file, providing access to Jest globals, `jest` object, and `expect` (e.g., adding extra matchers or calling setup/teardown hooks). slowTestThreshold: number Default: 5 Description: The number of seconds after which a test is considered as slow and reported as such in the results. ``` -------------------------------- ### Basic Jest Lua Configuration Source: https://jsdotlua.github.io/jest-lua/configuration Demonstrates the simplest way to define Jest Lua configuration in `jest.config.lua` by returning a table with configuration properties. ```Lua return { verbose = true, } ```