### Installing Arch with Wally Source: https://github.com/bohraz/arch/blob/main/docs/start.md Add the Arch library as a dependency in your wally.toml file to manage it using the Wally package manager. ```toml [dependencies] Arch = "bohraz/arch@latest" ``` -------------------------------- ### Starting the Arch State Machine Source: https://github.com/bohraz/arch/blob/main/docs/start.md Initiate the state machine by calling the `Start` method, which typically enters the initial state and executes its `OnEntry` action. ```lua myStateMachine:Start() ``` -------------------------------- ### Defining a State Machine with Arch Source: https://github.com/bohraz/arch/blob/main/docs/start.md Create a new state machine instance using `Arch.createMachine`, defining its initial state, nested states, entry/exit actions, and transitions triggered by events. ```lua local myStateMachine = Arch.createMachine({ id = "myStateMachine", initial = "idle", states = { idle = { OnEntry = function() print("Entering idle state") end, OnExit = function() print("Exiting idle state") end, events = { startRunning = "running" } }, running = { initial = "regularRunning", OnEntry = function() print("Entering running state") end, OnExit = function() print("Exiting running state") end, events = { stopRunning = "idle" }, states = { regularRunning = { events = { jump = "runningAndJumping" } }, runningAndJumping = { OnEntry = function() print("Entering running and jumping state") end, } } } } }) ``` -------------------------------- ### Quick Installation via Command Bar (Lua) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/Installation.md This snippet provides a quick way to install the Promise library directly into a Roblox Studio project using the command bar. It fetches the latest version from GitHub via HttpService and inserts it as a ModuleScript named 'Promise' into the selected object or ServerScriptService. ```Lua local Http = game:GetService("HttpService") local HttpEnabled = Http.HttpEnabled Http.HttpEnabled = true local m = Instance.new("ModuleScript") m.Parent = game:GetService("Selection"):Get()[1] or game:GetService("ServerScriptService") m.Name = "Promise" m.Source = Http:GetAsync("https://raw.githubusercontent.com/evaera/roblox-lua-promise/master/lib/init.lua") game:GetService("Selection"):Set({m}) Http.HttpEnabled = HttpEnabled ``` -------------------------------- ### Build and Install TestEZ CLI from Source (Bash) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/testez-cli/README.md Bash commands to build TestEZ CLI locally using `cargo build` or build and install it globally using `cargo install --path .`. ```Bash # To build locally cargo build # To build and install cargo install --path . ``` -------------------------------- ### Requiring Arch Library in Lua Source: https://github.com/bohraz/arch/blob/main/docs/start.md Require the Arch library in your Lua script, ensuring the correct path to the library after installation. ```lua local Arch = require(path.to.Arch) ``` -------------------------------- ### Run Tests with Roblox-CLI Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/CONTRIBUTING.md Executes tests using the Roblox-CLI tool, intended for Roblox engineers with a production Studio installation. ```Shell ./test/roblox-cli.sh ``` -------------------------------- ### Sending an Event to Arch State Machine Source: https://github.com/bohraz/arch/blob/main/docs/start.md Trigger a state transition by sending an event string to the state machine using the `Send` method. The machine will transition if a matching event is defined in the current state. ```lua myStateMachine:Send("startRunning") ``` -------------------------------- ### Build and Install TestEZ CLI Locally (Bash) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/testez-cli/README.md Provides commands to build the TestEZ CLI project locally using `cargo build` and to install it from the current directory using `cargo install --path .`, requiring Rust and Rojo. ```Bash cargo build ``` ```Bash cargo install --path . ``` -------------------------------- ### Initialize Git Submodules Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/CONTRIBUTING.md Updates and initializes the Git submodules required for the TestEZ repository. ```Shell git submodule update --init ``` -------------------------------- ### Run Luacheck Static Analysis Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/CONTRIBUTING.md Performs static analysis on the TestEZ source code directory ('src') using the Luacheck tool. ```Shell luacheck src ``` -------------------------------- ### Install TestEZ CLI with Foreman (TOML) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/testez-cli/README.md Configuration snippet for Foreman to install TestEZ CLI as a tool dependency, specifying the source and version. ```TOML [tools] testez = { source = "Roblox/testez", version = "0.2.0" } ``` -------------------------------- ### Example of Context in init.spec.lua (Part 1) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/docs/api-reference.md This code snippet shows how to use the context table within a beforeAll hook in an init.spec.lua file. It demonstrates adding a helper module to the context, making it available to tests in the same directory. ```Lua -- init.spec.lua return function() beforeAll(function(context) context.helpers = require(script.Parent.helpers) end) end ``` -------------------------------- ### Creating Cancellable Animation Sequence with Promises in Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/Examples.md Provides a comprehensive example of building a composable and cancellable animation sequence using Promise chaining and `finallyCall`. Includes helper functions for sleeping and running tweens, demonstrating how cancellation propagates up the chain and finalizes the animated object's state. ```lua local Promise = require(game.ReplicatedStorage.Promise) local TweenService = game:GetService("TweenService") local sleep = Promise.promisify(wait) local function apply(obj, props) for key, value in pairs(props) do obj[key] = value end end local function runTween(obj, props) return Promise.new(function(resolve, reject, onCancel) local tween = TweenService:Create(obj, TweenInfo.new(0.5), props) if onCancel(function() tween:Cancel() apply(obj, props) end) then return end tween.Completed:Connect(resolve) tween:Play() end) end local function runAnimation(part, intensity) return Promise.resolve() :finallyCall(sleep, 1) :finallyCall(runTween, part, { Reflectance = 1 * intensity }):finallyCall(runTween, part, { CFrame = CFrame.new(part.Position) * CFrame.Angles(0, math.rad(90 * intensity), 0) }):finallyCall(runTween, part, { Size = ( Vector3.new(10, 10, 10) * intensity ) + Vector3.new(1, 1, 1) }) end local animation = Promise.resolve() -- Begin Promise chain :finallyCall(runAnimation, workspace.Part, 1) :finallyCall(sleep, 1) :finallyCall(runAnimation, workspace.Part, 0) :catch(warn) wait(2) animation:cancel() -- Remove this line to see the full animation ``` -------------------------------- ### Run TestEZ Tests Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/CONTRIBUTING.md Executes all TestEZ tests using the Lua interpreter. ```Shell lua test/lemur.lua ``` -------------------------------- ### Example of Using FOCUS in TestEZ Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/docs/api-reference.md This example demonstrates how to use FOCUS() within a describe block. Only the block containing FOCUS() will execute, while other describe blocks will be skipped. ```Lua describe("Secret Feature X", function() FOCUS() it("should do something", function() end) end) describe("Secret Feature Y", function() it("should do nothing", function() -- This code will not run! end) end) ``` -------------------------------- ### Chaining Promises in Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/Examples.md Demonstrates how to chain multiple Promise-returning functions together. If any function in the chain rejects, execution jumps directly to the final `catch` handler. ```lua doSomething() :andThen(doSomethingElse) :andThen(doSomethingOtherThanThat) :andThen(doSomethingAgain) :catch(print) ``` -------------------------------- ### Generate LuaCov Coverage Report Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/CONTRIBUTING.md Runs tests with LuaCov enabled to collect coverage data, then generates the coverage report. ```Shell lua -lluacov test/lemur.lua luacov ``` -------------------------------- ### Configure TestEZ CLI with Foreman (TOML) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/testez-cli/README.md Configures Foreman to install TestEZ CLI as a development tool by specifying its source and version in the `tools` section of the Foreman configuration file. ```TOML [tools] testez = { source = "Roblox/testez", version = "0.2.0" } ``` -------------------------------- ### Grouping Tests - Testing Framework - Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/docs/api-reference.md Example demonstrating how to use `describe` to create a test suite for "This cheese", containing an `it` block to test a specific behavior. ```Lua describe("This cheese", function() it("should be moldy", function() expect(cheese.moldy).to.equal(true) end) end) ``` -------------------------------- ### Example Test Suite for Addition (Lua) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/DESIGN.md This Lua code snippet demonstrates how to define a test suite for basic addition using the TestEZ framework. It returns a function that uses `describe` to group related tests and `it` blocks to define individual test cases with assertions made using `expect`. ```Lua return function() describe("Addition", function() it("should be commutative", function() local a, b, c = 5, 8, 11 expect(a + b + c).to.equal(c + b + a) end) it("should be associative", function() local a, b, c = 7, 4, 9 expect((a + b) + c).to.equal(a + (b + c)) end) end) end ``` -------------------------------- ### Defining a Test Case - Testing Framework - Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/docs/api-reference.md Example showing how to use `it` to define a test case that checks if `1 + 1` equals `2` using the `expect` assertion. ```Lua it("should add 1 and 1", function() expect(1 + 1).to.equal(2) end) ``` -------------------------------- ### Focusing a Test Suite - Testing Framework - Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/docs/api-reference.md Example demonstrating how to use `FOCUS()` inside a `describe` block to ensure only the tests within that specific block are executed, skipping others. ```Lua describe("Secret Feature X", function() FOCUS() it("should do something", function() end) end) describe("Secret Feature Y", function() it("should do nothing", function() -- This code will not run! end) end) ``` -------------------------------- ### Using Assertions with Expect - Testing Framework - Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/docs/api-reference.md Examples demonstrating various assertion methods available on an expectation object created by `expect`, including equality, approximate equality, nil checking, type checking, and function throwing. ```Lua -- Equality expect(1).to.equal(1) expect(1).never.to.equal(2) -- Approximate equality expect(5).to.be.near(5 + 1e-8) expect(5).to.be.near(5 - 1e-8) expect(math.pi).never.to.be.near(3) -- Optional limit parameter expect(math.pi).to.be.near(3, 0.2) -- Nil checking expect(1).to.be.ok() expect(false).to.be.ok() expect(nil).never.to.be.ok() -- Type checking expect(1).to.be.a("number") expect(newproxy(true)).to.be.a("userdata") -- Function throwing expect(function() error("nope") end).to.throw() expect(function() -- I don't throw! end).never.to.throw() ``` -------------------------------- ### Wrapping Yielding Function with Promise in Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/Examples.md Shows how to convert a function that yields (like Roblox's `IsInGroup`) into a function that returns a Promise using `Promise.new`, resolving with the result of the original function. ```lua local function isPlayerInGroup(player, groupId) return Promise.new(function(resolve) resolve(player:IsInGroup(groupId)) end) end ``` -------------------------------- ### Wrapping Roblox TweenService with Promise in Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/Examples.md Illustrates how to wrap a Roblox API that uses events (`TweenService.Completed`) into a Promise-returning function. Includes handling for cancellation, ensuring the tween is cancelled and the object state is finalized if the Promise is cancelled. ```lua local function tween(obj, tweenInfo, props) return function() return Promise.new(function(resolve, reject, onCancel) local tween = TweenService:Create(obj, tweenInfo, props) if onCancel(function() tween:Cancel() end) then return end tween.Completed:Connect(resolve) tween:Play() end) end end ``` -------------------------------- ### Example of Context in init.spec.lua (Part 2) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/docs/api-reference.md This code snippet shows how a test (it block) in another spec file within the same directory can access data (the helpers module) previously added to the context table by a lifecycle hook in the init.spec.lua file. ```Lua -- test.spec.lua return function() it("a test using a helper", function(context) local user = context.helpers.makeUser(123) -- ... end) end ``` -------------------------------- ### Using Actions in State Machine Transitions (Lua) Source: https://github.com/bohraz/arch/blob/main/docs/concepts.md Illustrates how to define actions within a transition. Actions are functions or string references executed sequentially between exiting the source state and entering the target state. This example combines guards and actions for a directional movement system. ```Lua StateA = { events = { updateWalkDirection = { guards = { "isDifferentDirection" }, actions = { "exitAnimation", "enterWalking" } } } } ``` -------------------------------- ### Defining a Compound State in Arch Lua Source: https://github.com/bohraz/arch/blob/main/docs/concepts.md Provides an example of how to define a compound state within an Arch machine definition. It shows how to include a nested `states` table and specify an `initial` child state, which is required for compound states. ```lua local myMachineDefinition = { id = "myMachine", initial = "StateA", states = { StateA = { initial = "ChildStateA", states = { -- simply include a states table to make a compound state ChildStateA = {} } } } } ``` -------------------------------- ### Creating Promise-based HTTP GET Function (Lua) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/WhyUsePromises.md This snippet defines a Lua function `httpGet` that wraps `HttpService:GetAsync`. Instead of yielding, it returns a new `Promise`. The Promise's executor function calls `GetAsync` within a `pcall` and resolves the Promise with the result on success or rejects it with the error on failure. It requires the `Promise` library and `HttpService`. ```Lua local HttpService = game:GetService("HttpService") local function httpGet(url) return Promise.new(function(resolve, reject) local ok, result = pcall(HttpService.GetAsync, HttpService, url) if ok then resolve(result) else reject(result) end end) end ``` -------------------------------- ### Running Tests with TestEZ Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/docs/getting-started/running-tests.md This snippet demonstrates how to run a set of tests using the `TestBootstrap:run` method provided by TestEZ. It requires the TestEZ library to be imported and takes a table of test modules as an argument. The method executes the tests and returns results. ```lua local TestEZ = require() TestEZ.TestBootstrap:run({ MY_TESTS }) ``` -------------------------------- ### Using Lemur Habitat and Loading Modules in Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/modules/lemur/README.md This snippet demonstrates the basic usage of Lemur by creating a Habitat, loading files from the filesystem into the virtual environment, requiring a module from the loaded files, and invoking a method on it. It shows how to initialize the environment and interact with simulated Roblox objects. ```Lua local lemur = require("lemur") -- Create a Habitat local habitat = lemur.Habitat.new() local ReplicatedStorage = habitat.game:GetService("ReplicatedStorage") -- Load `src/roblox` as a Folder containing some ModuleScripts: local root = habitat:loadFromFs("src/roblox") root.Parent = ReplicatedStorage -- Locate src/roblox/CoolModule.lua from inside the habitat and load it! local CoolModule = habitat:require(root.CoolModule) -- Invoke a method on our Roblox module! CoolModule.doSomething() ``` -------------------------------- ### Defining a Simple Lua Module for Testing Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/docs/getting-started/writing-tests.md This snippet defines a basic Lua module named `Greeter`. It includes a single method `greet` that takes a person's name and returns a formatted greeting string. The module is returned at the end, making it available for other scripts (like test specs) to require. ```Lua local Greeter = {} function Greeter:greet(person) return "Hello, " .. person end return Greeter ``` -------------------------------- ### Configuring Arch Machine Options in Lua Source: https://github.com/bohraz/arch/blob/main/docs/concepts.md Illustrates the use of the optional `options` dictionary when creating an Arch machine. It lists common configuration properties like `context`, `actions`, `guards`, `maxLogs`, `logTime`, and `debugMode`, explaining their purpose. ```lua local options = { context = {}, -- the initial context of the machine passed to each state actions = {}, -- dictionary of actions that can be referenced by state and transition callbacks guards = {}, -- dictionary of guards that can be referenced by transitions maxLogs = 30, -- max logs in the log history, when the max is reached it deletes the oldest log logTime = true, -- determines whether or not to include a time property to each log debugMode = true, -- when set to true, the machine will print basic changes in the machine such as entering and exiting of states } local myMachine = Arch.createMachine(myMachineFile, options) ``` -------------------------------- ### Run TestEZ Tests with CLI (Bash) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/testez-cli/README.md Bash commands to execute tests using the TestEZ CLI, demonstrating how to target different environments like Lemur (default) or Roblox-CLI. ```Bash # Using Lemur (default) testez run --target lemur # Using Roblox-CLI (Roblox internal only for now) testez run --target roblox-cli ``` -------------------------------- ### Using Lemur Habitat in Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/modules/lemur/README.md This snippet demonstrates how to initialize a Lemur Habitat, load files from the filesystem into the simulated environment, require modules within the habitat, and interact with them. It requires the 'lemur' library. ```Lua local lemur = require("lemur") -- Create a Habitat local habitat = lemur.Habitat.new() local ReplicatedStorage = habitat.game:GetService("ReplicatedStorage") -- Load `src/roblox` as a Folder containing some ModuleScripts: local root = habitat:loadFromFs("src/roblox") root.Parent = ReplicatedStorage -- Locate src/roblox/CoolModule.lua from inside the habitat and load it! local CoolModule = habitat:require(root.CoolModule) -- Invoke a method on our Roblox module! CoolModule.doSomething() ``` -------------------------------- ### Run Tests with TestEZ CLI (Bash) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/testez-cli/README.md Demonstrates how to execute tests using the TestEZ CLI, showing commands to target either the Lemur environment (default) or the Roblox-CLI environment. ```Bash testez run --target lemur ``` ```Bash testez run --target roblox-cli ``` -------------------------------- ### Defining a Basic Arch Machine in Lua Source: https://github.com/bohraz/arch/blob/main/docs/concepts.md Demonstrates the minimal structure required for an Arch state machine definition, including `id`, `initial`, and `states`. It also shows how to instantiate the machine using `Arch.createMachine`. ```lua local myMachineDefinition = { id = "myMachine", initial = "StateA", states = { StateA = { initial = "ChildStateA", states = { ChildStateA = {} } } } } local myMachine = Arch.createMachine(myMachineDefinition) ``` -------------------------------- ### Creating Basic State Machine Transitions (Lua) Source: https://github.com/bohraz/arch/blob/main/docs/concepts.md Demonstrates the three primary ways to define transitions for a state in a state machine: a shorthand string for a simple target, an object with a 'target' property for more options, and an array of objects to allow multiple potential transitions for a single event. ```Lua StateA = { events = { Event1 = "StateB", -- shorthand Event2 = { target = "StateB" }, -- allows for greater customizability of the transition Event3 = { { target = "StateB" } }, -- allows for multiple transitions in a single event, we will cover this next } } ``` -------------------------------- ### TestEZ Spec for Greeter Module Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/docs/getting-started/writing-tests.md This snippet demonstrates the TestEZ specification file (`.spec.lua`) for the `Greeter` module. It requires the module and uses TestEZ's `describe`, `it`, and `expect` functions to define and run tests for the `greet` method, checking for expected output. ```lua return function() local Greeter = require(script.Parent.Greeter) describe("greet", function() it("should include the customary English greeting", function() local greeting = Greeter:greet("X") expect(greeting:match("Hello")).to.be.ok() end) it("should include the person being greeted", function() local greeting = Greeter:greet("Joe") expect(greeting:match("Joe")).to.be.ok() end) end) end ``` -------------------------------- ### Defining a Simple Lua Module Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/docs/getting-started/writing-tests.md This snippet shows a basic Lua module named `Greeter` that provides a single public function `greet`. This module is designed to be tested by a separate TestEZ spec file. ```lua local Greeter = {} function Greeter:greet(person) return "Hello, " .. person end return Greeter ``` -------------------------------- ### Running Tests with TestEZ Bootstrap (Lua) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/docs/getting-started/running-tests.md This snippet demonstrates how to run a collection of tests using the TestEZ library's TestBootstrap:run method. It requires the TestEZ module and passes a table containing the tests (MY_TESTS) to the run function. The method executes the tests and returns information about the run. ```lua local TestEZ = require() TestEZ.TestBootstrap:run({ MY_TESTS }) ``` -------------------------------- ### Creating a TestEZ Specification for a Lua Module Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/docs/getting-started/writing-tests.md This snippet shows a TestEZ specification file (`.spec.lua`) designed to test the `Greeter` module. It returns a function that uses TestEZ's `describe` to group tests for the `greet` method and `it` to define individual test cases. It demonstrates requiring the module and using `expect` to assert that the greeting contains the expected parts. ```Lua return function() local Greeter = require(script.Parent.Greeter) describe("greet", function() it("should include the customary English greeting", function() local greeting = Greeter:greet("X") expect(greeting:match("Hello")).to.be.ok() end) it("should include the person being greeted", function() local greeting = Greeter:greet("Joe") expect(greeting:match("Joe")).to.be.ok() end) end) end ``` -------------------------------- ### Defining a Test Suite using TestEZ Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/DESIGN.md This Lua code snippet demonstrates the basic structure of a test suite using TestEZ's domain-specific language. It defines a suite ('describe') for 'Addition' and includes two test cases ('it') that use the 'expect' function to assert properties like commutativity and associativity. Test files should return a function containing the suite definition. ```Lua return function() describe("Addition", function() it("should be commutative", function() local a, b, c = 5, 8, 11 expect(a + b + c).to.equal(c + b + a) end) it("should be associative", function() local a, b, c = 7, 4, 9 expect((a + b) + c).to.equal(a + (b + c)) end) end) end ``` -------------------------------- ### Creating a Promise from an Event with Promise.new - Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/Tour.md Shows how to create a Promise that resolves the first time a specific event (someEvent) fires. It connects to the event, resolves the Promise with the event arguments, and disconnects the connection. It also includes an onCancel handler to clean up the connection if the Promise is cancelled. ```lua local myFunction() return Promise.new(function(resolve, reject, onCancel) local connection connection = someEvent:Connect(function(...) connection:Disconnect() resolve(...) end) onCancel(function() connection:Disconnect() end) end) end myFunction():andThen(print) ``` -------------------------------- ### Creating a Promise with Promise.new (Basic) - Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/Tour.md Demonstrates the basic usage of Promise.new to create a new Promise. The executor function performs a yielding operation (somethingThatYields) and then resolves the Promise with a string value. The result is then printed using andThen. ```lua local function myFunction() return Promise.new(function(resolve, reject, onCancel) somethingThatYields() resolve("Hello world!") end) end myFunction():andThen(print) ``` -------------------------------- ### Using describeFOCUS and describeSKIP in TestEZ (Signatures) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/docs/api-reference.md describeFOCUS and describeSKIP are special versions of describe that automatically mark the created block as focused or skipped, respectively. fdescribe and xdescribe are aliases. ```Lua describeFOCUS(phrase: string) describeSKIP(phrase: string) ``` -------------------------------- ### Defining Delayed State Machine Transitions (Lua) Source: https://github.com/bohraz/arch/blob/main/docs/concepts.md Explains and demonstrates how to create transitions that automatically occur after a specified time interval. This is achieved by using the 'after' property within the state's events table, specifying the target state and the delay in seconds. ```Lua StateA = { events = { after = { target = "StateB", delay = 3 } -- automatically transitions to StateB after 3 seconds if no other transitions are called } } ``` -------------------------------- ### Using itFOCUS, itSKIP, and itFIXME in TestEZ (Signatures) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/docs/api-reference.md itFOCUS, itSKIP, and itFIXME are special versions of it that automatically mark the test block as focused, skipped, or marked as a FIXME. These are necessary because FOCUS, SKIP, and FIXME cannot be called inside it blocks. fit and xit are aliases for itFOCUS and itSKIP. ```Lua itFOCUS(phrase: string, callback(context: table)) itSKIP(phrase: string, callback(context: table)) itFIXME(phrase: string, callback(context: table)) ``` -------------------------------- ### Converting a Yielding Function with Promise.promisify - Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/Tour.md Demonstrates using Promise.promisify to convert a standard Lua yielding function (myYieldingFunction) into a function that returns a Promise. The resulting Promise can then be chained with andThen and catch handlers. ```lua local function myYieldingFunction(waitTime, text) wait(waitTime) return text end local myFunction = Promise.promisify(myYieldingFunction) myFunction(1.2, "Hello world!"):andThen(print):catch(function() warn("Oh no... goodbye world.") end) ``` -------------------------------- ### Resolving a Value Immediately with Promise.resolve - Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/Tour.md Illustrates how to create a Promise that is already resolved with a given value using Promise.resolve. This is useful for wrapping existing values in a Promise context. The resolved value is then printed. ```lua local myFunction() return Promise.resolve("Hello world!") end myFunction():andThen(print) ``` -------------------------------- ### Focusing or Skipping Individual Tests - Testing Framework - Signature Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/docs/api-reference.md Signatures for `itFOCUS` and `itSKIP`, special variants of `it` that automatically mark the test case for focused execution or skipping, respectively. ```Lua itFOCUS(phrase, callback) itSKIP(phrase, callback) ``` -------------------------------- ### Creating an Expectation - Testing Framework - Signature Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/docs/api-reference.md Signature for the `expect` function, which creates an expectation object for the given value, allowing chained assertion methods to be called on it. ```Lua expect(value) ``` -------------------------------- ### Launching a New Thread with Promise.try - Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/Tour.md Illustrates using Promise.try to execute a yielding function in a new thread without blocking the current execution flow. This is presented as a safer alternative to spawn for concurrent operations. ```lua Promise.try(function() somethingThatYields() end) -- Doesn't block this someCode() ``` -------------------------------- ### Using FOCUS and itFOCUS in TestEZ (Lua) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/docs/getting-started/debugging-tests.md This Lua snippet demonstrates how to use the TestEZ functions FOCUS() and itFOCUS() to selectively run specific test blocks during development. FOCUS() is used within a describe block to run its contents, while itFOCUS() is used directly on an it block. It also shows a describe block that will be skipped because it is not focused. ```Lua return function() describe("new", function() FOCUS() it("does really important things", function() -- This block will run! end) end) itFOCUS("has all methods we expect", function() -- Calling FOCUS() would be too late here, so we use itFOCUS instead. -- This block will run, too end) describe("Format()", function() it("formats things", function() -- This block will never run! end) end) end ``` -------------------------------- ### Defining a Describe Block - Testing Framework - Signature Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/docs/api-reference.md Signature for the `describe` function, used to group related test cases. It takes a phrase describing the group and a callback function containing the test definitions. ```Lua describe(phrase, callback) ``` -------------------------------- ### Sequencing Async Functions with andThen (Lua) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/WhyUsePromises.md Demonstrates how to execute a series of asynchronous functions sequentially using the `andThen` method of Promises. Each function is called only after the previous one resolves. Includes a `catch` block to handle errors occurring at any point in the chain. ```Lua async1() :andThen(async2) :andThen(async3) :andThen(async4) :andThen(async5) :catch(function(err) warn("Oh no! This went wrong somewhere along the line:", err) end) ``` -------------------------------- ### Using beforeAll Lifecycle Hook in Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/docs/api-reference.md Runs a function once before any tests within its scope begin. Useful for setting up state that will be used by multiple tests. ```Lua local globalState = {} beforeAll(function() globalState.foo = "bar" end) it("SHOULD have access to globalState", function() expect(globalState.foo).to.equal("bar") end) ``` -------------------------------- ### Focusing a Describe Block - Testing Framework - Signature Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/docs/api-reference.md Signature for the `FOCUS` function, used within a `describe` block to mark it for focused execution, causing only focused blocks to run. ```Lua FOCUS() ``` -------------------------------- ### Implementing Self State Machine Transitions (Lua) Source: https://github.com/bohraz/arch/blob/main/docs/concepts.md Demonstrates how to define a self-transition, where the target state is the same as the source state. This causes the state machine to exit and immediately re-enter the current state, often used to trigger entry/exit actions or refresh state-specific logic. ```Lua StateA = { events = { mySelfTransition = { target = "StateA" } } } ``` -------------------------------- ### Converting Yielding Functions to Promises (Lua) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/WhyUsePromises.md Shows how to use `Promise.promisify` to wrap a traditional Lua function that yields, allowing it to return a Promise and be integrated into Promise chains. ```lua -- Assuming myFunctionAsync is a function that yields. local myFunction = Promise.promisify(myFunctionAsync) myFunction("some", "arguments"):andThen(print):catch(warn) ``` -------------------------------- ### Chaining Promises with andThen (Basic) - Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/Tour.md Shows how to chain multiple andThen calls on a Promise. Each andThen receives the resolved value from the previous Promise, performs an operation (adding 1), and returns a new value which becomes the resolved value for the next andThen in the chain. ```lua somePromise:andThen(function(number) return number + 1 end):andThen(print) ``` -------------------------------- ### Defining an It Block - Testing Framework - Signature Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/docs/api-reference.md Signature for the `it` function, used to define individual test cases within a `describe` block. It takes a phrase describing the behavior being tested and a callback function containing the test assertions. ```Lua it(phrase, callback) ``` -------------------------------- ### Creating Targetless State Machine Transitions (Lua) Source: https://github.com/bohraz/arch/blob/main/docs/concepts.md Shows how to define a transition that executes its associated guards and actions but does not change the current state of the machine. This is useful for performing side effects or checks without a state change. ```Lua StateA = { events = { myTargetlessTransition = { guards = { "canDoMyTargetlessTransition" }, actions = { "updateSomething" } } } } ``` -------------------------------- ### Using Guards in State Machine Transitions (Lua) Source: https://github.com/bohraz/arch/blob/main/docs/concepts.md Shows how to include guards in transition definitions. Guards are functions or string references that must evaluate to true for a transition to be considered valid. When multiple transitions are defined for an event, they are checked in order until a transition with satisfied guards is found. ```Lua StateA = { events = { ToolActivated = { { target = "Jump Attack", guards = {"isJumping"} }, { target = "Trip Attack", guards = {"isCrouching"} } } } } ``` -------------------------------- ### Defining a History State in Arch Lua Source: https://github.com/bohraz/arch/blob/main/docs/concepts.md Demonstrates the definition of a history state in Arch. It shows how to include the `history` property set to "shallow" or "deep" and notes that an `initial` property is still required for the first entry. ```lua local myMachineDefinition = { id = "myMachine", initial = "myHistoryState", states = { myHistoryState = { initial = "ChildA", -- initial must still be included for the first time the history state is entered history = "shallow", -- or "deep" states = { ChildA = {}, ChildB = {} } } } } ``` -------------------------------- ### Skipping a Describe Block - Testing Framework - Signature Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/modules/testez/docs/api-reference.md Signature for the `SKIP` function, used within a `describe` block to mark it for skipping, preventing any tests within that block from executing. ```Lua SKIP() ``` -------------------------------- ### Using TestEZ FOCUS and itFOCUS in Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/docs/getting-started/debugging-tests.md This Lua snippet demonstrates how to use TestEZ's FOCUS() function on a 'describe' block and itFOCUS() on an 'it' block to selectively run tests. Blocks or tests without FOCUS/itFOCUS are skipped. ```Lua return function() describe("new", function() FOCUS() it("does really important things", function() -- This block will run! end) end) itFOCUS("has all methods we expect", function() -- Calling FOCUS() would be too late here, so we use itFOCUS instead. -- This block will run, too end) describe("Format()", function() it("formats things", function() -- This block will never run! end) end) end ``` -------------------------------- ### Creating a Time Delay with Promise.delay - Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/Tour.md Demonstrates using Promise.delay to create a Promise that resolves after a specified number of seconds. This provides a reliable alternative to wait for scheduling asynchronous operations. ```lua Promise.delay(5):andThen(function() print("5 seconds have passed!") end) ``` -------------------------------- ### Using FOCUS in TestEZ (Signature) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/docs/api-reference.md The FOCUS() function, when called inside a describe block, marks that block as focused. If any blocks are focused, only focused blocks will execute, skipping all others. This is useful for debugging specific test sets. ```Lua FOCUS() ``` -------------------------------- ### Running Multiple Async Functions Concurrently with Promise.all (Lua) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/WhyUsePromises.md Shows how to use `Promise.all` to run multiple asynchronous functions concurrently. It accepts an array of Promises and returns a new Promise that resolves when all input Promises resolve, or rejects if any input Promise rejects. The resolved value is an array of the individual resolved values. ```Lua Promise.all({ async1(), async2(), async3(), async4() }):andThen(function(arrayOfResolvedValues) print("Done running all 4 functions!") end):catch(function(err) warn("Uh oh, one of the Promises rejected! Abort mission!") end) ``` -------------------------------- ### Chaining Promise Handlers (Lua) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/WhyUsePromises.md This snippet shows how `andThen` and `catch` methods return new Promises, allowing for method chaining. The `andThen` and `catch` calls are chained directly onto the result of the `httpGet` call, providing a more concise way to attach resolution and rejection handlers. ```Lua httpGet("https://google.com") :andThen(function(body) print("Here's the Google homepage:", body) end) :catch(function(err) warn("We failed to get the Google homepage!", err) end) ``` -------------------------------- ### Using beforeEach Lifecycle Hook in Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/docs/api-reference.md Runs a function before each individual test within its scope. Useful for resetting state to a known baseline before each test runs. ```Lua local globalState = {} beforeEach(function() globalState.foo = 100 end) it("SHOULD be able to read foo", function() expect(globalState.foo).to.equal(100) end) it("SHOULD be able to write foo", function() globalState.foo = globalState.foo / 2 expect(globalState.foo).to.equal(50) end) ``` -------------------------------- ### Using Expect for Assertions in Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/docs/api-reference.md Creates a new Expectation object used for asserting properties of a given value. Supports various matchers like equality, approximate equality, nil checking, type checking, and function throwing. ```Lua -- Equality expect(1).to.equal(1) expect(1).never.to.equal(2) -- Approximate equality expect(5).to.be.near(5 + 1e-8) expect(5).to.be.near(5 - 1e-8) expect(math.pi).never.to.be.near(3) -- Optional limit parameter expect(math.pi).to.be.near(3, 0.2) -- Nil checking expect(1).to.be.ok() expect(false).to.be.ok() expect(nil).never.to.be.ok() -- Type checking expect(1).to.be.a("number") expect(newproxy(true)).to.be.a("userdata") -- Function throwing expect(function() error("nope") end).to.throw() expect(function() -- I don't throw! end).never.to.throw() expect(function() error("nope") end).to.throw("nope") expect(function() error("foo") end).never.to.throw("bar") ``` -------------------------------- ### Chaining Promises by Returning a Promise from andThen - Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/Tour.md Illustrates how returning a new Promise from an andThen handler results in the chain waiting for the returned Promise to resolve. The final andThen receives the resolved value of the returned Promise, allowing for sequential asynchronous operations. ```lua Promise.new(function(resolve) somethingThatYields() resolve(1) end):andThen(function(x) return Promise.new(function(resolve) somethingThatYields() resolve(x + 1) end) end):andThen(print) --> 2 ``` -------------------------------- ### Using afterAll Lifecycle Hook in Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/docs/api-reference.md Runs a function once after all tests within its scope have completed. Useful for cleaning up global state modified by multiple tests. ```Lua local DEFAULT_STATE = { hello = "world", } local globalState = DEFAULT_STATE afterAll(function() globalState = DEFAULT_STATE end) it("SHOULD read globalState", function() expect(globalState.hello).to.equal("world") end) it("SHOULD insert globalState", function() globalState.foo = "bar" expect(globalState.foo).to.equal("bar") end) ``` -------------------------------- ### Defining an It Block in Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/docs/api-reference.md Creates a new 'it' block, which defines a specific behavior or expectation of the subject under test. These blocks contain the actual test logic and assertions. ```Lua it("should add 1 and 1", function() expect(1 + 1).to.equal(2) end) ``` -------------------------------- ### Setting a Timeout on a Promise with timeout - Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/Tour.md Shows how to apply a timeout to an existing Promise using the :timeout method. If the original Promise does not resolve within the specified duration, the returned Promise will be rejected, allowing for handling operations that take too long. ```lua returnsAPromise():timeout(5):andThen(function() print("This returned in at most 5 seconds") end) ``` -------------------------------- ### Handling Promise Resolution and Rejection Separately (Lua) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/WhyUsePromises.md This snippet demonstrates how to use the `httpGet` function and attach separate handlers for the returned Promise. The `andThen` method is used to register a callback that executes if the Promise resolves, receiving the resolved value. The `catch` method registers a callback for when the Promise rejects, receiving the error. ```Lua local promise = httpGet("https://google.com") promise:andThen(function(body) print("Here's the Google homepage:", body) end) promise:catch(function(err) warn("We failed to get the Google homepage!", err) end) ``` -------------------------------- ### Defining a Parallel State in Arch Lua Source: https://github.com/bohraz/arch/blob/main/docs/concepts.md Explains how to define a parallel state by setting the `parallel` property to `true` at the state level. It notes that the `initial` property should be excluded for parallel states, as all child states become active simultaneously. ```lua local myMachineDefinition = { id = "myMachine", parallel = true, -- the initial property should be excluded if parallel is true states = { StateA = {}, -- both StateA and StateB will be active at the same time StateB = {}, } } ``` -------------------------------- ### Defining a Describe Block in Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/docs/api-reference.md Creates a new 'describe' block, which groups related tests. 'it' blocks should be placed inside 'describe' blocks to define specific behaviors being tested. ```Lua describe("This cheese", function() it("should be moldy", function() expect(cheese.moldy).to.equal(true) end) end) ``` -------------------------------- ### Creating a Cancellable Promise with onCancel and finally (Lua) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/WhyUsePromises.md Shows how to create a Promise that can be cancelled. The `onCancel` parameter in the executor function allows registering a callback to perform cleanup (like cancelling a tween) when the Promise is cancelled. The `finally` method is demonstrated, which executes regardless of whether the Promise resolves, rejects, or is cancelled. ```Lua local function tween(obj, tweenInfo, props) return Promise.new(function(resolve, reject, onCancel) local tween = TweenService:Create(obj, tweenInfo, props) -- Register a callback to be called if the Promise is cancelled. onCancel(function() tween:Cancel() end) tween.Completed:Connect(resolve) tween:Play() end) end -- Begin tweening immediately local promise = tween(workspace.Part, TweenInfo.new(2), { Transparency = 0.5 }):andThen(function() print("This is never printed.") end):catch(function() print("This is never printed.") end):finally(function() print("But this *is* printed!") end) wait(1) promise:cancel() -- Cancel the Promise, which cancels the tween. ``` -------------------------------- ### Using afterEach Lifecycle Hook in Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/docs/api-reference.md Runs a function after each individual test within its scope, regardless of test outcome. Useful for cleaning up temporary state created by each test. ```Lua local DEFAULT_STATE = { hello = "world", } local globalState = DEFAULT_STATE afterEach(function() globalState = DEFAULT_STATE end) it("SHOULD insert globalState", function() globalState.foo = "bar" expect(globalState.foo).to.equal("bar") end) it("SHOULD read globalState", function() expect(globalState.hello).to.equal("world") end) ``` -------------------------------- ### Chaining Promises by Returning a New Promise (Lua) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/WhyUsePromises.md This snippet illustrates advanced chaining where an `andThen` handler returns a new Promise. The subsequent `andThen` call in the chain will wait for the *returned* Promise to resolve before executing its callback. The final `catch` handler will catch errors from any Promise in the chain. ```Lua httpGet("https://google.com") :andThen(function(body) -- not doing anything with body for this example return httpGet("https://eryn.io") -- returning a new Promise here! end) :andThen(function(body) -- Doesn't get called until the above Promise resolves! print("Here's the eryn.io homepage:", body) end) :catch(warn) -- Still catches errors from both Promises! ``` -------------------------------- ### Using SKIP in TestEZ (Signature) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/roblox_testez@0.4.1/testez/docs/api-reference.md The SKIP() function, when called inside a describe block, marks that block as skipped. This prevents any test assertions within the block from being executed. ```Lua SKIP() ``` -------------------------------- ### Awaiting Another Promise Inside a Promise Executor (Lua) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/WhyUsePromises.md Illustrates how to use the `await` method within a Promise executor function to synchronously wait for the result of another Promise (`async2`). The result (`ok`, `value`) is then used to either resolve or reject the outer Promise. ```Lua local function async1() return Promise.new(function(resolve, reject) local ok, value = async2():await() if not ok then return reject(value) end resolve(value + 1) end) end ``` -------------------------------- ### Cancelling a Promise Chain (Lua) Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/WhyUsePromises.md Demonstrates how cancelling the final Promise in a chain propagates the cancellation upwards, effectively cancelling all preceding Promises in the sequence. ```lua local promise = async1() :andThen(async2) :andThen(async3) :andThen(async4) :andThen(async5) :catch(function(err) warn("Oh no! This went wrong somewhere along the line:", err) end) promise:cancel() ``` -------------------------------- ### Resolving a Promise with Another Promise - Lua Source: https://github.com/bohraz/arch/blob/main/Packages/_Index/evaera_promise@4.0.0/promise/docs/Tour.md Shows that resolving a Promise with another Promise causes the first Promise to adopt the state of the second Promise. The chain then continues from the point where the inner Promise resolves, effectively flattening nested Promises. ```lua Promise.new(function(resolve) somethingThatYields() resolve(Promise.new(function(resolve) somethingThatYields() resolve(1) end)) end):andThen(print) --> 1 ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.