Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions pesde.lock
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ frktest = [{ name = "itsfrank/frktest", version = "^0.0.2", index = "https://git
luau-lsp = [{ name = "pesde/luau_lsp", version = "=1.39.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"]
stylua = [{ name = "pesde/stylua", version = "=2.0.2", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"]

[graph."beastslash/ijw@1.1.3 roblox"]
direct = ["ijw", { name = "beastslash/ijw", version = "^1.1.3", index = "default" }, "dev"]
[graph."beastslash/ijw@2.0.0 roblox"]
direct = ["ijw", { name = "beastslash/ijw", version = "^2.0.0", index = "default" }, "dev"]

[graph."beastslash/ijw@1.1.3 roblox".pkg_ref]
[graph."beastslash/ijw@2.0.0 roblox".pkg_ref]
ref_ty = "pesde"
index_url = "https://github.com/pesde-pkg/index"

[graph."beastslash/ijw@1.1.3 roblox".pkg_ref.dependencies]
[graph."beastslash/ijw@2.0.0 roblox".pkg_ref.dependencies]
luau_lsp = [{ name = "pesde/luau_lsp", version = "^1.48.0", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"]
rojo = [{ name = "pesde/rojo", version = "^7.5.1", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"]
scripts = [{ name = "pesde/scripts_rojo", version = "^0.1.0", index = "https://github.com/pesde-pkg/index", target = "lune" }, "dev"]
Expand Down
34 changes: 28 additions & 6 deletions src/DialogueEditor/components/Button/init.luau
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
local root = script.Parent.Parent.Parent;
local React = require(root.roblox_packages.react);
local useStudioColors = require(root.DialogueEditor.hooks.useStudioColors);
local VirtualService = require(root.VirtualService);

export type ButtonProperties = {
text: string;
Expand All @@ -20,20 +21,41 @@ local function Button(properties: ButtonProperties)
local text = properties.text;
local isDisabled = properties.isDisabled;
local onClick = properties.onClick;
local buttonRef = React.useRef(nil);

React.useEffect(function()

local button = buttonRef.current;
assert(button, "Button reference is nil.");

local activatedConnection = VirtualService.events.GuiButton.Activated:getSignal(button):Connect(function(self)

if not isDisabled then

onClick();

end;

end);

return function()

activatedConnection:Disconnect();

end;

end, {onClick});

return React.createElement("TextButton", {
AutomaticSize = Enum.AutomaticSize.XY;
BackgroundColor3 = backgroundColor;
Text = "";
LayoutOrder = layoutOrder;
Size = UDim2.fromOffset(0, 30);
[React.Event.Activated] = function()
ref = buttonRef;
[React.Event.Activated] = function(self)

if not isDisabled then

onClick();

end;
VirtualService.events.GuiButton.Activated:fireEvent(self);

end;
}, {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
--!strict

local root = script.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent;
local DialogueOptions = require(script.Parent);
local VirtualService = require(root.VirtualService);
local React = require(root.roblox_packages.react);
local ReactErrorBoundary = require(root.roblox_packages.ReactErrorBoundary);
local ErrorBoundary = ReactErrorBoundary.ErrorBoundary;
local ReactRoblox = require(root.roblox_packages["react-roblox"]);
local IJW = require(root.roblox_packages.ijw);
local expect = IJW.expect;
local describe = IJW.describe;
local it = IJW.it;

local screenGui: ScreenGui?;
local reactRoot: ReactRoblox.RootType?;
local propagatedErrorMessage;
local eventConnection: RBXScriptConnection?;

return {

describe("DialogueOptions", function()

local function MockComponent(properties: any)

local selectedScript = properties.selectedScript;
local onErrored = properties.onErrored or function() end;
local onRendered = properties.onRendered or function() end;

React.useEffect(function()

onRendered();

end, {onRendered});

return React.createElement(ErrorBoundary, {
FallbackComponent = React.Fragment;
onError = onErrored;
}, {
React.createElement(DialogueOptions, {
selectedScript = selectedScript;
plugin = VirtualService.mocks.globals.plugin;
selectedDialogueType = selectedScript:GetAttribute("DialogueType") or "Conversation";
layoutOrder = 1;
})
});

end;

local function verifyReactStatus()

if propagatedErrorMessage then

error(propagatedErrorMessage);

end;

end;

local function createDialogueScript(name: string)

local dialogueScript = Instance.new("ModuleScript");
dialogueScript:AddTag("DialogueMakerConversationScript");
return dialogueScript;

end;

local function render(): ModuleScript

assert(reactRoot, "React root should be initialized before running tests.");

local selectedScript = createDialogueScript("TestDialogueScript");
local didRender = false;
local element = React.createElement(MockComponent, {
selectedScript = selectedScript;
onErrored = function(errorMessage)

propagatedErrorMessage = errorMessage;

end;
onRendered = function()

didRender = true;

end;
});

reactRoot:render(element);
repeat task.wait() until didRender or propagatedErrorMessage;
verifyReactStatus();

return selectedScript;

end;

return {

it("can delete selected script", function()

expect(function()

local selectedScript = render();
local testFolder = Instance.new("Folder");
selectedScript.Parent = testFolder;

assert(screenGui, "ScreenGui should be initialized before running tests.");
local dialogueOptions = screenGui:FindFirstChildOfClass("Frame");
assert(dialogueOptions, "DialogueOptions should be rendered.");

local deleteButton = dialogueOptions:FindFirstChild("DeleteButton");
assert(deleteButton and deleteButton:IsA("TextButton"), "Delete button should be present in the DialogueOptions.");

local didChangeParent = false;
eventConnection = selectedScript:GetPropertyChangedSignal("Parent"):Once(function()

didChangeParent = true;

end);
VirtualService.events.GuiButton.Activated:fireEvent(deleteButton);
repeat task.wait() until didChangeParent or propagatedErrorMessage;
verifyReactStatus();
expect(selectedScript.Parent).toBe(nil);

end).toFinishBeforeSeconds(1);

end);

}

end, {
beforeEach = function()

local newScreenGui = Instance.new("ScreenGui");
screenGui = newScreenGui;
reactRoot = ReactRoblox.createRoot(newScreenGui);
VirtualService.mocks.isEnabled = true;

end;
afterEach = function()

if reactRoot then

reactRoot:unmount();
reactRoot = nil;

end;

if screenGui then

screenGui:Destroy();
screenGui = nil;

end;

if eventConnection then

eventConnection:Disconnect();
eventConnection = nil;

end;

propagatedErrorMessage = nil;
VirtualService.mocks.isEnabled = false;

end;
})
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ local DropdownOption = require(root.DialogueEditor.components.DropdownOption);
local useStudioColors = require(root.DialogueEditor.hooks.useStudioColors);
local useDialogueScriptType = require(root.DialogueEditor.hooks.useDialogueScriptType);
local useChangeHistory = require(root.DialogueEditor.hooks.useChangeHistory);
local VirtualService = require(root.VirtualService);

type DialogueScriptType = useDialogueScriptType.DialogueScriptType;

Expand All @@ -22,6 +23,8 @@ export type DialogueOptionsProperties = {

local function DialogueOptions(properties: DialogueOptionsProperties)

Selection = if VirtualService.mocks.isEnabled then VirtualService.mocks.services.Selection else Selection;

local selectedScript = properties.selectedScript;
local selectedDialogueType = properties.selectedDialogueType;
local layoutOrder = properties.layoutOrder;
Expand Down