### Fixture Usage Example Source: https://github.com/atilioa/bg3-dribblespec/blob/main/DribbleSpec/Mods/DribbleSpec/ScriptExtender/Lua/Shared/DribbleSpec/Docs/CONSUMER_GUIDE.md Shows how to use fixtures to manage entity states and restore them after tests. ```APIDOC ## Fixture Usage Example ### Description This example demonstrates the use of DribbleSpec fixtures to create a snapshot of the game state, spawn an entity, and then restore the original state. ### Method N/A (This is a test setup example) ### Endpoint N/A ### Parameters N/A ### Request Example ```lua D.describe("Fixture usage", { tags = { "runtime", "entity" } }, function() D.test("spawn fallback fixture and restore state", function(ctx) local snapshot = ctx.fixture.state.snapshot({ player = true, }) local handle = ctx.fixture.entity("test_dummy") ctx.expect(handle).toBeTruthy() snapshot:restore() end) end) ``` ### Response N/A (This is a test example) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Manage Lifecycle Hooks Source: https://context7.com/atilioa/bg3-dribblespec/llms.txt Configures setup and teardown logic for test suites and individual cases using beforeAll, afterAll, beforeEach, and afterEach hooks. ```lua local D = RegisterTestGlobals() D.describe("Database Operations", function() local db D.beforeEach(function(ctx) db = { data = {} } end) D.test("inserts data", function(ctx) db.data["key"] = "value" ctx.expect(db.data["key"]).toBe("value") end) end) ``` -------------------------------- ### Doubles Example Source: https://github.com/atilioa/bg3-dribblespec/blob/main/DribbleSpec/Mods/DribbleSpec/ScriptExtender/Lua/Shared/DribbleSpec/Docs/CONSUMER_GUIDE.md Demonstrates the use of spies for tracking function calls and assertions in DribbleSpec. ```APIDOC ## Doubles Example ### Description This example shows how to use `ctx.spyOn` to track calls to a function and `ctx.expect` for assertions on the return value and call details. ### Method N/A (This is a test setup example) ### Endpoint N/A ### Parameters N/A ### Request Example ```lua D.describe("Doubles", { tags = { "unit" } }, function() D.test("spy and assertions", function(ctx) local target = { Add = function(a, b) return a + b end, } local spy = ctx.spyOn(target, "Add") local value = target.Add(2, 3) ctx.expect(value).toBe(5) ctx.expect(spy).toHaveBeenCalledTimes(1) ctx.expect(spy).toHaveBeenCalledWith(2, 3) end) end) ``` ### Response N/A (This is a test example) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Perform Unit Assertions Source: https://github.com/atilioa/bg3-dribblespec/blob/main/DribbleSpec/Mods/DribbleSpec/ScriptExtender/Lua/Shared/DribbleSpec/Docs/CONSUMER_GUIDE.md Example of using deep equality assertions within a unit test context. ```lua D.describe("Settings model", { tags = { "unit" } }, function() D.test("toEqual enabled", function() local expected = { stable = { enabled = true } } local actual = { stable = { enabled = true } } D.expect(actual).toEqual(expected) end) end) ``` -------------------------------- ### Write a Minimal DribbleSpec Test in Lua Source: https://github.com/atilioa/bg3-dribblespec/blob/main/README.md Demonstrates how to write a basic test case using DribbleSpec's `describe` and `test` functions. It includes an example of a simple truthiness assertion. ```lua D = Mods.Dribbles.RegisterTestGlobals() D.describe("MyMod smoke", { tags = { "unit" } }, function() D.test("basic truthiness", function() D.expect(true).toBeTruthy() end) end) ``` -------------------------------- ### Create BG3 Entity References with entityRef Source: https://context7.com/atilioa/bg3-dribblespec/llms.txt Illustrates the usage of the `entityRef` function to create resolvable references to Baldur's Gate 3 entities. It supports creation from GUID strings, table specifications including NetId, and custom resolver functions. ```lua local D = RegisterTestGlobals() D.describe("EntityRef", function() D.test("creates from GUID string", function(ctx) local ref = ctx.entityRef("3ed74f06-3c60-42dc-83f6-f034cb47c679") ctx.expect(ref:GetGuid()).toBe("3ed74f06-3c60-42dc-83f6-f034cb47c679") ctx.expect(ref:IsEntityRef()).toBeTruthy() end) D.test("creates from table spec", function(ctx) local ref = ctx.entityRef({ guid = "3ed74f06-3c60-42dc-83f6-f034cb47c679", netId = 12345, }) local entity = ref:Resolve() -- Attempts Ext.Entity.Get if entity then ctx.expect(entity).toBeEntity() end end) D.test("creates from custom resolver", function(ctx) local mockEntity = { GetComponent = function() end } local ref = ctx.entityRef({ resolve = function() return mockEntity end }) ctx.expect(ref:Resolve()).toBe(mockEntity) end) end) ``` -------------------------------- ### Extend DribbleSpec with Custom Fixture Providers Source: https://github.com/atilioa/bg3-dribblespec/blob/main/DribbleSpec/Mods/DribbleSpec/ScriptExtender/Lua/Shared/DribbleSpec/Docs/CONSUMER_GUIDE.md Configures the test runner with custom fixture providers to handle mod-specific entity resolution. This allows developers to map aliases to specific GUIDs or game entities. ```lua local run = D.RunMine({ fixtureProviders = { { name = "mod-preplaced", Resolve = function(request) if request.alias == "boss" then return { guid = "11111111-2222-3333-4444-555555555555", value = Ext.Entity.Get("11111111-2222-3333-4444-555555555555"), } end return nil end, }, }, }) ``` -------------------------------- ### entityRef Source: https://context7.com/atilioa/bg3-dribblespec/llms.txt Creates a resolvable reference to a BG3 entity from various source types (GUID string, NetId number, entity table, or custom resolver). Provides consistent entity resolution across different input formats. ```APIDOC ## entityRef Creates a resolvable reference to a BG3 entity from various source types (GUID string, NetId number, entity table, or custom resolver). Provides consistent entity resolution across different input formats. ### Usage ```lua local D = RegisterTestGlobals() D.describe("EntityRef", function() D.test("creates from GUID string", function(ctx) local ref = ctx.entityRef("3ed74f06-3c60-42dc-83f6-f034cb47c679") ctx.expect(ref:GetGuid()).toBe("3ed74f06-3c60-42dc-83f6-f034cb47c679") ctx.expect(ref:IsEntityRef()).toBeTruthy() end) D.test("creates from table spec", function(ctx) local ref = ctx.entityRef({ guid = "3ed74f06-3c60-42dc-83f6-f034cb47c679", netId = 12345, }) local entity = ref:Resolve() -- Attempts Ext.Entity.Get if entity then ctx.expect(entity).toBeEntity() end end) D.test("creates from custom resolver", function(ctx) local mockEntity = { GetComponent = function() end } local ref = ctx.entityRef({ resolve = function() return mockEntity end }) ctx.expect(ref:Resolve()).toBe(mockEntity) end) end) ``` ``` -------------------------------- ### Provision Test Fixtures and State Snapshots Source: https://context7.com/atilioa/bg3-dribblespec/llms.txt Shows how to provision entities and characters for testing with automatic cleanup. Also demonstrates state snapshotting to revert changes to game state after a test. ```lua local D = RegisterTestGlobals() D.describe("Fixture System", { tags = { "runtime", "entity" } }, function() D.test("state snapshot and restore", function(ctx) local gameState = { gold = 100 } local snapshot = ctx.fixture.state.snapshot({ get = function() return gameState end, set = function(val) gameState = val end, }) gameState.gold = 0 snapshot:restore() ctx.expect(gameState.gold).toBe(100) end) end) ``` -------------------------------- ### Manage Test Fixtures and State Source: https://github.com/atilioa/bg3-dribblespec/blob/main/DribbleSpec/Mods/DribbleSpec/ScriptExtender/Lua/Shared/DribbleSpec/Docs/CONSUMER_GUIDE.md Shows how to create snapshots of game state and spawn entities using fixtures. This ensures tests can modify the world and restore the original state upon completion. ```lua D.describe("Fixture usage", { tags = { "runtime", "entity" } }, function() D.test("spawn fallback fixture and restore state", function(ctx) local snapshot = ctx.fixture.state.snapshot({ player = true }) local handle = ctx.fixture.entity("test_dummy") ctx.expect(handle).toBeTruthy() snapshot:restore() end) end) ``` -------------------------------- ### Define Basic Test Suite Source: https://github.com/atilioa/bg3-dribblespec/blob/main/DribbleSpec/Mods/DribbleSpec/ScriptExtender/Lua/Shared/DribbleSpec/Docs/CONSUMER_GUIDE.md Shows the structure of a minimal test file using describe blocks and basic truthiness assertions. ```lua local D = RegisterTestGlobals() D.describe("MyMod smoke", { tags = { "unit" } }, function() D.test("basic truthiness", function() D.expect(true).toBeTruthy() end) end) ``` -------------------------------- ### Manage Runtime Context and Async Helpers Source: https://context7.com/atilioa/bg3-dribblespec/llms.txt Provides utilities for enforcing client/server execution environments, conditionally skipping tests, and handling asynchronous operations using tick-based waiting. ```lua local D = RegisterTestGlobals() D.describe("Runtime Helpers", function() D.test("server-only test", function(ctx) ctx.requireServer() ctx.expect(Ext.IsServer()).toBeTruthy() end) D.test("async waiting", function(ctx) local ready = false ctx.nextTick() ready = true local success, ticks = ctx.waitUntil(function() return ready end, { timeoutTicks = 10 }) ctx.expect(success).toBeTruthy() end) end) ``` -------------------------------- ### Execute BG3 Tests with DribbleSpec Console Commands and Runner Options Source: https://context7.com/atilioa/bg3-dribblespec/llms.txt Demonstrates how to execute tests using BG3 console commands with various filtering options such as tags, names, and execution context. It also shows programmatic test execution with custom fixture providers and command aliasing. ```lua -- Console commands: -- !dribbles Run all tests -- !d Shorthand for !dribbles -- !dribbles --help Show help -- !dribbles --name "pattern" Filter by test name -- !dribbles --tag unit Filter by tag -- !dribbles --tag unit --tag inventory Multiple tags (AND) -- !dribbles --context server Run only server context tests -- !dribbles --fail-fast Stop on first failure -- !dribbles --verbose Show detailed output -- !mytests Custom command (via commandAlias) -- Programmatic execution local D = RegisterTestGlobals({ ownerModuleUUID = ModuleUUID, commandAlias = "mytests" }) -- Run only this mod's tests programmatically local results = D.RunMine({ tags = { "unit" }, failFast = true, fixtureProviders = { { name = "custom-preplaced", Resolve = function(self, kind, spec, context) if spec.alias == "boss" then return { guid = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", value = Ext.Entity.Get("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"), } end return nil end, }, }, }) ``` -------------------------------- ### Initialize DribbleSpec Test Globals Source: https://github.com/atilioa/bg3-dribblespec/blob/main/DribbleSpec/Mods/DribbleSpec/ScriptExtender/Lua/Shared/DribbleSpec/Docs/CONSUMER_GUIDE.md Demonstrates how to register the DribbleSpec test globals, including optional configuration for custom console commands and tagging. ```lua local D = RegisterTestGlobals() local D = RegisterTestGlobals({ globalTags = { "mymod" }, commandAlias = "mytests", ownerModuleUUID = ModuleUUID }) ``` -------------------------------- ### Console Commands and Runner Options Source: https://context7.com/atilioa/bg3-dribblespec/llms.txt Execute tests via BG3 console with filtering options for tags, names, and execution context. ```APIDOC ## Console Commands and Runner Options Execute tests via BG3 console with filtering options for tags, names, and execution context. ### Console Commands - `!dribbles`: Run all tests. - `!d`: Shorthand for `!dribbles`. - `!dribbles --help`: Show help. - `!dribbles --name "pattern"`: Filter by test name. - `!dribbles --tag unit`: Filter by tag. - `!dribbles --tag unit --tag inventory`: Multiple tags (AND). - `!dribbles --context server`: Run only server context tests. - `!dribbles --fail-fast`: Stop on first failure. - `!dribbles --verbose`: Show detailed output. - `!mytests`: Custom command (via commandAlias). ### Programmatic Execution ```lua local D = RegisterTestGlobals({ ownerModuleUUID = ModuleUUID, commandAlias = "mytests" }) -- Run only this mod's tests programmatically local results = D.RunMine({ tags = { "unit" }, failFast = true, fixtureProviders = { { name = "custom-preplaced", Resolve = function(self, kind, spec, context) if spec.alias == "boss" then return { guid = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", value = Ext.Entity.Get("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"), } end return nil end, }, }, }) ``` ``` -------------------------------- ### Implement Test Doubles: Mocks, Spies, and Stubs Source: https://context7.com/atilioa/bg3-dribblespec/llms.txt Covers the creation of mocks, spies, and stubs to isolate test logic. Includes call tracking, behavior replacement, and subset argument matching for complex objects. ```lua local D = RegisterTestGlobals() D.describe("Test Doubles", function() D.test("mockFn creates callable mock", function(ctx) local mock = ctx.mockFn(function(x) return x * 2 end) local result = mock(5) ctx.expect(result).toBe(10) ctx.expect(mock).toHaveBeenCalled() ctx.expect(mock).toHaveBeenCalledTimes(1) ctx.expect(mock).toHaveBeenCalledWith(5) end) D.test("spyOn tracks calls without replacing behavior", function(ctx) local calculator = { add = function(a, b) return a + b end } local spy = ctx.spyOn(calculator, "add") local result = calculator.add(2, 3) ctx.expect(result).toBe(5) ctx.expect(spy).toHaveBeenCalledWith(2, 3) end) D.test("stub replaces implementation", function(ctx) local api = { fetchData = function() return "real data" end } local stub = ctx.stub(api, "fetchData", function() return "mocked data" end) ctx.expect(api.fetchData()).toBe("mocked data") ctx.expect(stub).toHaveBeenCalledTimes(1) end) end) ``` -------------------------------- ### Validate Game Entities and Components Source: https://context7.com/atilioa/bg3-dribblespec/llms.txt Demonstrates how to validate entity UUIDs, check for the existence of specific components, and use entity references within a test suite. It requires a server context and handles missing entities gracefully. ```lua local D = RegisterTestGlobals() D.describe("Entity Validation", { tags = { "entity", "server" } }, function() D.test("validates entity properties", function(ctx) ctx.requireServer() local guid = "3ed74f06-3c60-42dc-83f6-f034cb47c679" ctx.expect(guid).toBeUuid() local entity = Ext.Entity.Get(guid) if entity == nil then ctx.skip("Entity not in current save") end ctx.expect(entity).toBeEntity() ctx.expect(entity).toHaveComponent("DisplayName") ctx.expect(entity).toHaveComponent("Health") -- EntityRef wrapper local ref = ctx.entityRef(guid) ctx.expect(ref).toBeEntity() end) end) ``` -------------------------------- ### Perform Entity Assertions Source: https://github.com/atilioa/bg3-dribblespec/blob/main/DribbleSpec/Mods/DribbleSpec/ScriptExtender/Lua/Shared/DribbleSpec/Docs/CONSUMER_GUIDE.md Demonstrates server-side entity testing, including validating UUIDs, entity existence, and component presence. ```lua D.describe("Entity checks", { tags = { "entity", "server" } }, function() D.test("preplaced entity has DisplayName", function(ctx) ctx.requireServer() local guid = "3ed74f06-3c60-42dc-83f6-f034cb47c679" local entity = Ext.Entity.Get(guid) if entity == nil then return end ctx.expect(guid).toBeUuid() ctx.expect(entity).toBeEntity() ctx.expect(entity).toHaveComponent("DisplayName") local ref = ctx.entityRef(guid) ctx.expect(ref).toBeEntity() end) end) ``` -------------------------------- ### Define Test Suites with Describe Source: https://context7.com/atilioa/bg3-dribblespec/llms.txt Organizes tests into hierarchical suites using the describe function. Supports nested suites and metadata tags for selective test execution. ```lua local D = RegisterTestGlobals() D.describe("Inventory System", { tags = { "inventory", "unit" } }, function() D.describe("Item stacking", function() D.test("combines stackable items", function(ctx) ctx.expect(5 + 5).toBe(10) end) end) end) ``` -------------------------------- ### Skip Tests Dynamically Source: https://github.com/atilioa/bg3-dribblespec/blob/main/DribbleSpec/Mods/DribbleSpec/ScriptExtender/Lua/Shared/DribbleSpec/Docs/CONSUMER_GUIDE.md Demonstrates how to skip tests based on runtime conditions, such as checking for the existence of an entity in the current save. ```lua D.describe("Optional integration", { tags = { "entity" } }, function() D.test("resolves preplaced entity", function(ctx) ctx.expect(MY_GUID).toBeUuid() local entity = Ext.Entity.Get(MY_GUID) if entity == nil then D.skip("Entity not in current save") end ctx.expect(entity).toBeEntity() end) end) ``` -------------------------------- ### Inventory Service Stubbing Source: https://github.com/atilioa/bg3-dribblespec/blob/main/DribbleSpec/Mods/DribbleSpec/ScriptExtender/Lua/Shared/DribbleSpec/Docs/CONSUMER_GUIDE.md Illustrates how to use stubs to replace existing methods for isolated testing of the inventory service. ```APIDOC ## Inventory Service Stubbing ### Description This example demonstrates using `ctx.stub` to replace the `Count` method of the `inventory` object, allowing for controlled testing of its behavior. ### Method N/A (This is a test setup example) ### Endpoint N/A ### Parameters N/A ### Request Example ```lua D.describe("Inventory service", { tags = { "unit" } }, function() D.test("stub replaces an existing method for this test", function(ctx) local inventory = { Count = function(itemId) return 1 end, } local stub = ctx.stub(inventory, "Count", function(itemId) return 99 end) local count = inventory.Count("potion") ctx.expect(count).toBe(99) ctx.expect(stub).toHaveBeenCalledTimes(1) ctx.expect(stub).toHaveBeenCalledWith("potion") end) end) ``` ### Response N/A (This is a test example) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Implement Spies and Stubs in DribbleSpec Source: https://github.com/atilioa/bg3-dribblespec/blob/main/DribbleSpec/Mods/DribbleSpec/ScriptExtender/Lua/Shared/DribbleSpec/Docs/CONSUMER_GUIDE.md Demonstrates how to use spies to track function calls and stubs to override method behavior during unit tests. These tools allow for verifying interactions and isolating components within the game environment. ```lua D.describe("Doubles", { tags = { "unit" } }, function() D.test("spy and assertions", function(ctx) local target = { Add = function(a, b) return a + b end } local spy = ctx.spyOn(target, "Add") local value = target.Add(2, 3) ctx.expect(value).toBe(5) ctx.expect(spy).toHaveBeenCalledTimes(1) ctx.expect(spy).toHaveBeenCalledWith(2, 3) end) end) D.describe("Inventory service", { tags = { "unit" } }, function() D.test("stub replaces an existing method for this test", function(ctx) local inventory = { Count = function(itemId) return 1 end } local stub = ctx.stub(inventory, "Count", function(itemId) return 99 end) local count = inventory.Count("potion") ctx.expect(count).toBe(99) ctx.expect(stub).toHaveBeenCalledTimes(1) ctx.expect(stub).toHaveBeenCalledWith("potion") end) end) ``` -------------------------------- ### Define Individual Test Cases Source: https://context7.com/atilioa/bg3-dribblespec/llms.txt Creates specific test units using test or it aliases. Provides a context object for assertions and supports test-level modifiers like skip and only. ```lua local D = RegisterTestGlobals() D.describe("Character Stats", function() D.test("calculates health correctly", { tags = { "health" } }, function(ctx) local health = 10 + 5 ctx.expect(health).toBe(15) end) D.test.only("debug this test", function(ctx) ctx.expect(true).toBeTruthy() end) end) ``` -------------------------------- ### Extending DribbleSpec with Runner Options Source: https://github.com/atilioa/bg3-dribblespec/blob/main/DribbleSpec/Mods/DribbleSpec/ScriptExtender/Lua/Shared/DribbleSpec/Docs/CONSUMER_GUIDE.md Explains how to extend DribbleSpec's functionality by providing custom fixture providers via runner options. ```APIDOC ## Extending DribbleSpec for mod-specific needs ### Description This section details how to customize DribbleSpec's behavior, specifically by implementing custom fixture providers through runner options. ### Method N/A (This is a configuration example) ### Endpoint N/A ### Parameters N/A ### Request Example ```lua local run = D.RunMine({ fixtureProviders = { { name = "mod-preplaced", Resolve = function(request) if request.alias == "boss" then return { guid = "11111111-2222-3333-4444-555555555555", value = Ext.Entity.Get("11111111-2222-3333-4444-555555555555"), } end return nil end, }, }, }) ``` ### Response N/A (This is a configuration example) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Register DribbleSpec Test Globals Source: https://context7.com/atilioa/bg3-dribblespec/llms.txt Initializes the testing environment by registering global symbols. This function allows configuration of module ownership, global tags, and custom console command aliases. ```lua -- Basic registration local D = RegisterTestGlobals() -- Full registration with options local D = RegisterTestGlobals({ ownerModuleUUID = ModuleUUID, globalTags = { "mymod", "unit" }, commandAlias = "mytests", }) ``` -------------------------------- ### Require DribbleSpec Test Files in Lua Source: https://github.com/atilioa/bg3-dribblespec/blob/main/README.md Explains how to explicitly load test files within your mod's test initialization script. This ensures that all defined tests are available for execution. ```lua Ext.Require("Shared/MyMod/Tests/Smoke.test.lua") Ext.Require("Shared/MyMod/Tests/Runtime.test.lua") ``` -------------------------------- ### Utilize Expect Matchers Source: https://context7.com/atilioa/bg3-dribblespec/llms.txt Performs assertions on test values using chainable matchers. Supports equality, truthiness, containment, and error handling checks. ```lua local D = RegisterTestGlobals() D.test("core matchers", function(ctx) ctx.expect(42).toBe(42) ctx.expect(true).toBeTruthy() ctx.expect("hello world").toContain("world") ctx.expect(5).not.toBe(10) end) ``` -------------------------------- ### Register DribbleSpec Globals in Lua Source: https://github.com/atilioa/bg3-dribblespec/blob/main/README.md Registers the public API for DribbleSpec, allowing mods to use its testing functionalities. It requires owner module UUID and can include global tags and command aliases. ```lua D = Mods.Dribbles.RegisterTestGlobals({ ownerModuleUUID = ModuleUUID, globalTags = { "mymod" }, commandAlias = "mytests", }) ```