From 5e5fc77173fe937b6021cbafc1ef24be4af0fa8c Mon Sep 17 00:00:00 2001 From: Noah Crowley Date: Tue, 2 Nov 2021 12:04:40 -0400 Subject: [PATCH 1/4] Add installation instructions to README --- README.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8ec37df..4221ef9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Lua Linear Algebra +# Lua Linear Algebra ===
@@ -12,7 +12,22 @@ Lua Linear Algebra A simple script to implement linear algebra functions not provided by the Lua standard API, developed especially for use on Roblox -Documentation +## Installation +### Wally +[Wally](https://github.com/UpliftGames/wally/) users can install this package by adding the following line to their `Wally.toml` under `[dependencies]`: +``` +linalg = "bytebit/linalg@0.0.1" +``` + +Then just run `wally install`. + +### From model file +Model files are uploaded to every release as `.rbxmx` files. You can download the file from the [Releases page](https://github.com/Bytebit-Org/lua-linalg/releases) and load it into your project however you see fit. + +### From model asset +New versions of the asset are uploaded with every release. The asset can be added to your Roblox Inventory and then inserted into your Place via Toolbox by getting it [here.](https://www.roblox.com/library/7881451885/linalg-Package) + +## Documentation --- ### Matrix Functions From e667b45ee3e6f09178a2f9bd849040bfc537d6c2 Mon Sep 17 00:00:00 2001 From: Noah Crowley Date: Tue, 2 Nov 2021 12:33:34 -0400 Subject: [PATCH 2/4] Try adding everything at once --- .github/workflows/CI.yml | 36 + .github/workflows/Release.yml | 61 + .gitignore | 1 + .luacheckrc | 23 - .luacov | 8 - .travis.yml | 29 - CHANGELOG.md | 1 + foreman.toml | 4 + modules/lemur/LICENSE.md | 9 - modules/lemur/init.lua | 1 - modules/lemur/lib/Enum/ConnectionState.lua | 6 - modules/lemur/lib/Enum/CreatorType.lua | 6 - modules/lemur/lib/Enum/EasingDirection.lua | 7 - modules/lemur/lib/Enum/EasingStyle.lua | 12 - modules/lemur/lib/Enum/FillDirection.lua | 6 - modules/lemur/lib/Enum/Font.lua | 23 - .../lemur/lib/Enum/HorizontalAlignment.lua | 7 - modules/lemur/lib/Enum/Platform.lua | 24 - modules/lemur/lib/Enum/PlaybackState.lua | 10 - modules/lemur/lib/Enum/ScaleType.lua | 9 - modules/lemur/lib/Enum/ScrollingDirection.lua | 7 - modules/lemur/lib/Enum/SizeConstraint.lua | 7 - modules/lemur/lib/Enum/SortOrder.lua | 7 - modules/lemur/lib/Enum/TextXAlignment.lua | 7 - modules/lemur/lib/Enum/TextYAlignment.lua | 7 - modules/lemur/lib/Enum/ThumbnailSize.lua | 11 - modules/lemur/lib/Enum/ThumbnailType.lua | 7 - modules/lemur/lib/Enum/VerticalAlignment.lua | 7 - modules/lemur/lib/Enum/VirtualInputMode.lua | 7 - modules/lemur/lib/Enum/ZIndexBehavior.lua | 6 - modules/lemur/lib/Enum/init.lua | 32 - modules/lemur/lib/Habitat.lua | 131 - modules/lemur/lib/Instance.lua | 18 - modules/lemur/lib/InstanceProperty.lua | 65 - modules/lemur/lib/Instance_spec.lua | 33 - modules/lemur/lib/Signal.lua | 90 - modules/lemur/lib/Signal_spec.lua | 62 - modules/lemur/lib/TaskScheduler.lua | 45 - modules/lemur/lib/assign.lua | 17 - modules/lemur/lib/baste.lua | 332 - modules/lemur/lib/createEnum.lua | 59 - modules/lemur/lib/createEnumGroup.lua | 34 - modules/lemur/lib/createEnumGroup_spec.lua | 43 - modules/lemur/lib/createEnum_spec.lua | 55 - modules/lemur/lib/createEnvironment.lua | 50 - modules/lemur/lib/createSettings.lua | 68 - modules/lemur/lib/createSettings_spec.lua | 91 - modules/lemur/lib/fs.lua | 33 - modules/lemur/lib/fs_spec.lua | 18 - modules/lemur/lib/functions/init.lua | 13 - .../lib/functions/settings/RenderSettings.lua | 56 - .../settings/RenderSettings_spec.lua | 40 - modules/lemur/lib/functions/tick.lua | 10 - modules/lemur/lib/functions/tick_spec.lua | 7 - modules/lemur/lib/functions/typeof.lua | 21 - modules/lemur/lib/functions/typeof_spec.lua | 21 - modules/lemur/lib/functions/warn.lua | 15 - modules/lemur/lib/functions/warn_spec.lua | 33 - modules/lemur/lib/init.lua | 9 - modules/lemur/lib/init_spec.lua | 7 - .../lemur/lib/instances/AnalyticsService.lua | 4 - .../lib/instances/AnalyticsService_spec.lua | 9 - modules/lemur/lib/instances/BaseInstance.lua | 375 - .../lemur/lib/instances/BaseInstance_spec.lua | 661 -- modules/lemur/lib/instances/BindableEvent.lua | 17 - .../lib/instances/BindableEvent_spec.lua | 21 - modules/lemur/lib/instances/BoolValue.lua | 18 - .../lemur/lib/instances/BoolValue_spec.lua | 11 - modules/lemur/lib/instances/Camera.lua | 15 - modules/lemur/lib/instances/Camera_spec.lua | 15 - .../lemur/lib/instances/ContentProvider.lua | 11 - .../lib/instances/ContentProvider_spec.lua | 15 - modules/lemur/lib/instances/CoreGui.lua | 11 - modules/lemur/lib/instances/CoreGui_spec.lua | 18 - modules/lemur/lib/instances/CorePackages.lua | 4 - .../lemur/lib/instances/CorePackages_spec.lua | 9 - modules/lemur/lib/instances/Folder.lua | 5 - modules/lemur/lib/instances/Folder_spec.lua | 9 - modules/lemur/lib/instances/Frame.lua | 5 - modules/lemur/lib/instances/Frame_spec.lua | 9 - modules/lemur/lib/instances/Game.lua | 109 - modules/lemur/lib/instances/Game_spec.lua | 42 - modules/lemur/lib/instances/GuiButton.lua | 24 - .../lemur/lib/instances/GuiButton_spec.lua | 18 - modules/lemur/lib/instances/GuiObject.lua | 134 - .../lemur/lib/instances/GuiObject_spec.lua | 131 - modules/lemur/lib/instances/GuiService.lua | 28 - .../lemur/lib/instances/GuiService_spec.lua | 33 - modules/lemur/lib/instances/HttpService.lua | 14 - .../lemur/lib/instances/HttpService_spec.lua | 21 - modules/lemur/lib/instances/ImageButton.lua | 35 - .../lemur/lib/instances/ImageButton_spec.lua | 20 - modules/lemur/lib/instances/ImageLabel.lua | 35 - .../lemur/lib/instances/ImageLabel_spec.lua | 20 - modules/lemur/lib/instances/IntValue.lua | 18 - modules/lemur/lib/instances/IntValue_spec.lua | 11 - modules/lemur/lib/instances/LocalScript.lua | 18 - .../lemur/lib/instances/LocalScript_spec.lua | 10 - .../lib/instances/LocalizationService.lua | 17 - .../instances/LocalizationService_spec.lua | 39 - .../lemur/lib/instances/LocalizationTable.lua | 35 - .../lib/instances/LocalizationTable_spec.lua | 47 - modules/lemur/lib/instances/Model.lua | 5 - modules/lemur/lib/instances/Model_spec.lua | 9 - modules/lemur/lib/instances/ModuleScript.lua | 14 - .../lemur/lib/instances/ModuleScript_spec.lua | 10 - .../lib/instances/NotificationService.lua | 5 - .../instances/NotificationService_spec.lua | 9 - modules/lemur/lib/instances/ObjectValue.lua | 14 - .../lemur/lib/instances/ObjectValue_spec.lua | 19 - modules/lemur/lib/instances/Player.lua | 21 - modules/lemur/lib/instances/Player_spec.lua | 22 - modules/lemur/lib/instances/Players.lua | 13 - modules/lemur/lib/instances/Players_spec.lua | 17 - .../lemur/lib/instances/ReplicatedStorage.lua | 3 - .../lib/instances/ReplicatedStorage_spec.lua | 9 - modules/lemur/lib/instances/RunService.lua | 23 - .../lemur/lib/instances/RunService_spec.lua | 28 - modules/lemur/lib/instances/ScreenGui.lua | 42 - .../lemur/lib/instances/ScreenGui_spec.lua | 45 - modules/lemur/lib/instances/Script.lua | 18 - modules/lemur/lib/instances/Script_spec.lua | 10 - .../lemur/lib/instances/ScrollingFrame.lua | 72 - .../lib/instances/ScrollingFrame_spec.lua | 68 - .../lib/instances/ServerScriptService.lua | 4 - .../instances/ServerScriptService_spec.lua | 9 - modules/lemur/lib/instances/Stats.lua | 4 - modules/lemur/lib/instances/Stats_spec.lua | 9 - modules/lemur/lib/instances/StringValue.lua | 18 - .../lemur/lib/instances/StringValue_spec.lua | 11 - modules/lemur/lib/instances/TestService.lua | 10 - .../lemur/lib/instances/TestService_spec.lua | 27 - modules/lemur/lib/instances/TextButton.lua | 54 - .../lemur/lib/instances/TextButton_spec.lua | 27 - modules/lemur/lib/instances/TextLabel.lua | 54 - .../lemur/lib/instances/TextLabel_spec.lua | 27 - modules/lemur/lib/instances/TextService.lua | 25 - .../lemur/lib/instances/TextService_spec.lua | 46 - modules/lemur/lib/instances/TweenService.lua | 3 - .../lemur/lib/instances/TweenService_spec.lua | 9 - .../lemur/lib/instances/UIGridStyleLayout.lua | 34 - .../lib/instances/UIGridStyleLayout_spec.lua | 28 - modules/lemur/lib/instances/UIListLayout.lua | 15 - .../lemur/lib/instances/UIListLayout_spec.lua | 22 - modules/lemur/lib/instances/UIPadding.lua | 33 - .../lemur/lib/instances/UIPadding_spec.lua | 18 - .../lemur/lib/instances/UserInputService.lua | 3 - .../lib/instances/UserInputService_spec.lua | 9 - .../lib/instances/VirtualInputManager.lua | 3 - .../instances/VirtualInputManager_spec.lua | 9 - modules/lemur/lib/instances/Workspace.lua | 16 - .../lemur/lib/instances/Workspace_spec.lua | 28 - modules/lemur/lib/instances/init.lua | 55 - modules/lemur/lib/json.lua | 18 - modules/lemur/lib/taskFunctions/init.lua | 12 - modules/lemur/lib/taskFunctions/spawn.lua | 5 - .../lemur/lib/taskFunctions/spawn_spec.lua | 21 - modules/lemur/lib/taskFunctions/wait.lua | 10 - modules/lemur/lib/taskFunctions/wait_spec.lua | 95 - modules/lemur/lib/typeKey.lua | 15 - modules/lemur/lib/types/Color3.lua | 130 - modules/lemur/lib/types/Color3_spec.lua | 82 - modules/lemur/lib/types/Rect.lua | 71 - modules/lemur/lib/types/Rect_spec.lua | 84 - modules/lemur/lib/types/UDim.lua | 62 - modules/lemur/lib/types/UDim2.lua | 95 - modules/lemur/lib/types/UDim2_spec.lua | 117 - modules/lemur/lib/types/UDim_spec.lua | 59 - modules/lemur/lib/types/Vector2.lua | 62 - modules/lemur/lib/types/Vector2_spec.lua | 60 - modules/lemur/lib/types/init.lua | 15 - modules/lemur/lib/validateType.lua | 8 - modules/lemur/lib/validateType_spec.lua | 20 - modules/testez/.editorconfig | 8 - modules/testez/.gitignore | 2 - modules/testez/.gitmodules | 3 - modules/testez/.luacheckrc | 15 - modules/testez/.travis.yml | 26 - modules/testez/CHANGELOG.md | 7 - modules/testez/CONTRIBUTING.md | 70 - modules/testez/DESIGN.md | 66 - modules/testez/LICENSE | 201 - modules/testez/README.md | 32 - modules/testez/docs/api-reference.md | 123 - .../docs/getting-started/debugging-tests.md | 37 - .../docs/getting-started/installation.md | 11 - .../docs/getting-started/running-tests.md | 11 - .../docs/getting-started/writing-tests.md | 45 - modules/testez/docs/index.md | 5 - modules/testez/docs/requirements.txt | 3 - modules/testez/lib/Expectation.lua | 252 - .../testez/lib/Reporters/TeamCityReporter.lua | 102 - modules/testez/lib/Reporters/TextReporter.lua | 100 - modules/testez/lib/Stack.lua | 38 - modules/testez/lib/TestBootstrap.lua | 114 - modules/testez/lib/TestEnum.lua | 25 - modules/testez/lib/TestPlan.lua | 102 - modules/testez/lib/TestPlanBuilder.lua | 87 - modules/testez/lib/TestPlanner.lua | 168 - modules/testez/lib/TestResults.lua | 112 - modules/testez/lib/TestRunner.lua | 152 - modules/testez/lib/TestSession.lua | 149 - modules/testez/lib/init.lua | 40 - modules/testez/mkdocs.yml | 27 - modules/testez/spec.lua | 99 - modules/testez/tests/api.lua | 4 - package-lock.json | 6 + requirements.txt | 1 + roblox-testez.toml | 24 + roblox.toml | 8105 +++++++++++++++++ scripts/get_wally_version_string.py | 4 + scripts/upload_model.py | 37 + selene.toml | 4 + spec.lua | 26 - spec.server.lua | 13 + {lib => src}/linalg.lua | 0 {lib => src}/linalg.spec.lua | 0 standalone-model.project.json | 6 + unit-tests.project.json | 37 + wally.lock | 13 + wally.toml | 10 + 221 files changed, 8363 insertions(+), 8251 deletions(-) create mode 100644 .github/workflows/CI.yml create mode 100644 .github/workflows/Release.yml delete mode 100644 .luacheckrc delete mode 100644 .luacov delete mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 foreman.toml delete mode 100755 modules/lemur/LICENSE.md delete mode 100755 modules/lemur/init.lua delete mode 100755 modules/lemur/lib/Enum/ConnectionState.lua delete mode 100755 modules/lemur/lib/Enum/CreatorType.lua delete mode 100755 modules/lemur/lib/Enum/EasingDirection.lua delete mode 100755 modules/lemur/lib/Enum/EasingStyle.lua delete mode 100755 modules/lemur/lib/Enum/FillDirection.lua delete mode 100755 modules/lemur/lib/Enum/Font.lua delete mode 100755 modules/lemur/lib/Enum/HorizontalAlignment.lua delete mode 100755 modules/lemur/lib/Enum/Platform.lua delete mode 100755 modules/lemur/lib/Enum/PlaybackState.lua delete mode 100755 modules/lemur/lib/Enum/ScaleType.lua delete mode 100755 modules/lemur/lib/Enum/ScrollingDirection.lua delete mode 100755 modules/lemur/lib/Enum/SizeConstraint.lua delete mode 100755 modules/lemur/lib/Enum/SortOrder.lua delete mode 100755 modules/lemur/lib/Enum/TextXAlignment.lua delete mode 100755 modules/lemur/lib/Enum/TextYAlignment.lua delete mode 100755 modules/lemur/lib/Enum/ThumbnailSize.lua delete mode 100755 modules/lemur/lib/Enum/ThumbnailType.lua delete mode 100755 modules/lemur/lib/Enum/VerticalAlignment.lua delete mode 100755 modules/lemur/lib/Enum/VirtualInputMode.lua delete mode 100755 modules/lemur/lib/Enum/ZIndexBehavior.lua delete mode 100755 modules/lemur/lib/Enum/init.lua delete mode 100755 modules/lemur/lib/Habitat.lua delete mode 100755 modules/lemur/lib/Instance.lua delete mode 100755 modules/lemur/lib/InstanceProperty.lua delete mode 100755 modules/lemur/lib/Instance_spec.lua delete mode 100755 modules/lemur/lib/Signal.lua delete mode 100755 modules/lemur/lib/Signal_spec.lua delete mode 100755 modules/lemur/lib/TaskScheduler.lua delete mode 100755 modules/lemur/lib/assign.lua delete mode 100755 modules/lemur/lib/baste.lua delete mode 100755 modules/lemur/lib/createEnum.lua delete mode 100755 modules/lemur/lib/createEnumGroup.lua delete mode 100755 modules/lemur/lib/createEnumGroup_spec.lua delete mode 100755 modules/lemur/lib/createEnum_spec.lua delete mode 100755 modules/lemur/lib/createEnvironment.lua delete mode 100755 modules/lemur/lib/createSettings.lua delete mode 100755 modules/lemur/lib/createSettings_spec.lua delete mode 100755 modules/lemur/lib/fs.lua delete mode 100755 modules/lemur/lib/fs_spec.lua delete mode 100755 modules/lemur/lib/functions/init.lua delete mode 100755 modules/lemur/lib/functions/settings/RenderSettings.lua delete mode 100755 modules/lemur/lib/functions/settings/RenderSettings_spec.lua delete mode 100755 modules/lemur/lib/functions/tick.lua delete mode 100755 modules/lemur/lib/functions/tick_spec.lua delete mode 100755 modules/lemur/lib/functions/typeof.lua delete mode 100755 modules/lemur/lib/functions/typeof_spec.lua delete mode 100755 modules/lemur/lib/functions/warn.lua delete mode 100755 modules/lemur/lib/functions/warn_spec.lua delete mode 100755 modules/lemur/lib/init.lua delete mode 100755 modules/lemur/lib/init_spec.lua delete mode 100755 modules/lemur/lib/instances/AnalyticsService.lua delete mode 100755 modules/lemur/lib/instances/AnalyticsService_spec.lua delete mode 100755 modules/lemur/lib/instances/BaseInstance.lua delete mode 100755 modules/lemur/lib/instances/BaseInstance_spec.lua delete mode 100755 modules/lemur/lib/instances/BindableEvent.lua delete mode 100755 modules/lemur/lib/instances/BindableEvent_spec.lua delete mode 100755 modules/lemur/lib/instances/BoolValue.lua delete mode 100755 modules/lemur/lib/instances/BoolValue_spec.lua delete mode 100755 modules/lemur/lib/instances/Camera.lua delete mode 100755 modules/lemur/lib/instances/Camera_spec.lua delete mode 100755 modules/lemur/lib/instances/ContentProvider.lua delete mode 100755 modules/lemur/lib/instances/ContentProvider_spec.lua delete mode 100755 modules/lemur/lib/instances/CoreGui.lua delete mode 100755 modules/lemur/lib/instances/CoreGui_spec.lua delete mode 100755 modules/lemur/lib/instances/CorePackages.lua delete mode 100755 modules/lemur/lib/instances/CorePackages_spec.lua delete mode 100755 modules/lemur/lib/instances/Folder.lua delete mode 100755 modules/lemur/lib/instances/Folder_spec.lua delete mode 100755 modules/lemur/lib/instances/Frame.lua delete mode 100755 modules/lemur/lib/instances/Frame_spec.lua delete mode 100755 modules/lemur/lib/instances/Game.lua delete mode 100755 modules/lemur/lib/instances/Game_spec.lua delete mode 100755 modules/lemur/lib/instances/GuiButton.lua delete mode 100755 modules/lemur/lib/instances/GuiButton_spec.lua delete mode 100755 modules/lemur/lib/instances/GuiObject.lua delete mode 100755 modules/lemur/lib/instances/GuiObject_spec.lua delete mode 100755 modules/lemur/lib/instances/GuiService.lua delete mode 100755 modules/lemur/lib/instances/GuiService_spec.lua delete mode 100755 modules/lemur/lib/instances/HttpService.lua delete mode 100755 modules/lemur/lib/instances/HttpService_spec.lua delete mode 100755 modules/lemur/lib/instances/ImageButton.lua delete mode 100755 modules/lemur/lib/instances/ImageButton_spec.lua delete mode 100755 modules/lemur/lib/instances/ImageLabel.lua delete mode 100755 modules/lemur/lib/instances/ImageLabel_spec.lua delete mode 100755 modules/lemur/lib/instances/IntValue.lua delete mode 100755 modules/lemur/lib/instances/IntValue_spec.lua delete mode 100755 modules/lemur/lib/instances/LocalScript.lua delete mode 100755 modules/lemur/lib/instances/LocalScript_spec.lua delete mode 100755 modules/lemur/lib/instances/LocalizationService.lua delete mode 100755 modules/lemur/lib/instances/LocalizationService_spec.lua delete mode 100755 modules/lemur/lib/instances/LocalizationTable.lua delete mode 100755 modules/lemur/lib/instances/LocalizationTable_spec.lua delete mode 100755 modules/lemur/lib/instances/Model.lua delete mode 100755 modules/lemur/lib/instances/Model_spec.lua delete mode 100755 modules/lemur/lib/instances/ModuleScript.lua delete mode 100755 modules/lemur/lib/instances/ModuleScript_spec.lua delete mode 100755 modules/lemur/lib/instances/NotificationService.lua delete mode 100755 modules/lemur/lib/instances/NotificationService_spec.lua delete mode 100755 modules/lemur/lib/instances/ObjectValue.lua delete mode 100755 modules/lemur/lib/instances/ObjectValue_spec.lua delete mode 100755 modules/lemur/lib/instances/Player.lua delete mode 100755 modules/lemur/lib/instances/Player_spec.lua delete mode 100755 modules/lemur/lib/instances/Players.lua delete mode 100755 modules/lemur/lib/instances/Players_spec.lua delete mode 100755 modules/lemur/lib/instances/ReplicatedStorage.lua delete mode 100755 modules/lemur/lib/instances/ReplicatedStorage_spec.lua delete mode 100755 modules/lemur/lib/instances/RunService.lua delete mode 100755 modules/lemur/lib/instances/RunService_spec.lua delete mode 100755 modules/lemur/lib/instances/ScreenGui.lua delete mode 100755 modules/lemur/lib/instances/ScreenGui_spec.lua delete mode 100755 modules/lemur/lib/instances/Script.lua delete mode 100755 modules/lemur/lib/instances/Script_spec.lua delete mode 100755 modules/lemur/lib/instances/ScrollingFrame.lua delete mode 100755 modules/lemur/lib/instances/ScrollingFrame_spec.lua delete mode 100755 modules/lemur/lib/instances/ServerScriptService.lua delete mode 100755 modules/lemur/lib/instances/ServerScriptService_spec.lua delete mode 100755 modules/lemur/lib/instances/Stats.lua delete mode 100755 modules/lemur/lib/instances/Stats_spec.lua delete mode 100755 modules/lemur/lib/instances/StringValue.lua delete mode 100755 modules/lemur/lib/instances/StringValue_spec.lua delete mode 100755 modules/lemur/lib/instances/TestService.lua delete mode 100755 modules/lemur/lib/instances/TestService_spec.lua delete mode 100755 modules/lemur/lib/instances/TextButton.lua delete mode 100755 modules/lemur/lib/instances/TextButton_spec.lua delete mode 100755 modules/lemur/lib/instances/TextLabel.lua delete mode 100755 modules/lemur/lib/instances/TextLabel_spec.lua delete mode 100755 modules/lemur/lib/instances/TextService.lua delete mode 100755 modules/lemur/lib/instances/TextService_spec.lua delete mode 100755 modules/lemur/lib/instances/TweenService.lua delete mode 100755 modules/lemur/lib/instances/TweenService_spec.lua delete mode 100755 modules/lemur/lib/instances/UIGridStyleLayout.lua delete mode 100755 modules/lemur/lib/instances/UIGridStyleLayout_spec.lua delete mode 100755 modules/lemur/lib/instances/UIListLayout.lua delete mode 100755 modules/lemur/lib/instances/UIListLayout_spec.lua delete mode 100755 modules/lemur/lib/instances/UIPadding.lua delete mode 100755 modules/lemur/lib/instances/UIPadding_spec.lua delete mode 100755 modules/lemur/lib/instances/UserInputService.lua delete mode 100755 modules/lemur/lib/instances/UserInputService_spec.lua delete mode 100755 modules/lemur/lib/instances/VirtualInputManager.lua delete mode 100755 modules/lemur/lib/instances/VirtualInputManager_spec.lua delete mode 100755 modules/lemur/lib/instances/Workspace.lua delete mode 100755 modules/lemur/lib/instances/Workspace_spec.lua delete mode 100755 modules/lemur/lib/instances/init.lua delete mode 100755 modules/lemur/lib/json.lua delete mode 100755 modules/lemur/lib/taskFunctions/init.lua delete mode 100755 modules/lemur/lib/taskFunctions/spawn.lua delete mode 100755 modules/lemur/lib/taskFunctions/spawn_spec.lua delete mode 100755 modules/lemur/lib/taskFunctions/wait.lua delete mode 100755 modules/lemur/lib/taskFunctions/wait_spec.lua delete mode 100755 modules/lemur/lib/typeKey.lua delete mode 100755 modules/lemur/lib/types/Color3.lua delete mode 100755 modules/lemur/lib/types/Color3_spec.lua delete mode 100755 modules/lemur/lib/types/Rect.lua delete mode 100755 modules/lemur/lib/types/Rect_spec.lua delete mode 100755 modules/lemur/lib/types/UDim.lua delete mode 100755 modules/lemur/lib/types/UDim2.lua delete mode 100755 modules/lemur/lib/types/UDim2_spec.lua delete mode 100755 modules/lemur/lib/types/UDim_spec.lua delete mode 100755 modules/lemur/lib/types/Vector2.lua delete mode 100755 modules/lemur/lib/types/Vector2_spec.lua delete mode 100755 modules/lemur/lib/types/init.lua delete mode 100755 modules/lemur/lib/validateType.lua delete mode 100755 modules/lemur/lib/validateType_spec.lua delete mode 100755 modules/testez/.editorconfig delete mode 100755 modules/testez/.gitignore delete mode 100755 modules/testez/.gitmodules delete mode 100755 modules/testez/.luacheckrc delete mode 100755 modules/testez/.travis.yml delete mode 100755 modules/testez/CHANGELOG.md delete mode 100755 modules/testez/CONTRIBUTING.md delete mode 100755 modules/testez/DESIGN.md delete mode 100755 modules/testez/LICENSE delete mode 100755 modules/testez/README.md delete mode 100755 modules/testez/docs/api-reference.md delete mode 100755 modules/testez/docs/getting-started/debugging-tests.md delete mode 100755 modules/testez/docs/getting-started/installation.md delete mode 100755 modules/testez/docs/getting-started/running-tests.md delete mode 100755 modules/testez/docs/getting-started/writing-tests.md delete mode 100755 modules/testez/docs/index.md delete mode 100755 modules/testez/docs/requirements.txt delete mode 100755 modules/testez/lib/Expectation.lua delete mode 100755 modules/testez/lib/Reporters/TeamCityReporter.lua delete mode 100755 modules/testez/lib/Reporters/TextReporter.lua delete mode 100755 modules/testez/lib/Stack.lua delete mode 100755 modules/testez/lib/TestBootstrap.lua delete mode 100755 modules/testez/lib/TestEnum.lua delete mode 100755 modules/testez/lib/TestPlan.lua delete mode 100755 modules/testez/lib/TestPlanBuilder.lua delete mode 100755 modules/testez/lib/TestPlanner.lua delete mode 100755 modules/testez/lib/TestResults.lua delete mode 100755 modules/testez/lib/TestRunner.lua delete mode 100755 modules/testez/lib/TestSession.lua delete mode 100755 modules/testez/lib/init.lua delete mode 100755 modules/testez/mkdocs.yml delete mode 100755 modules/testez/spec.lua delete mode 100755 modules/testez/tests/api.lua create mode 100644 package-lock.json create mode 100644 requirements.txt create mode 100644 roblox-testez.toml create mode 100644 roblox.toml create mode 100644 scripts/get_wally_version_string.py create mode 100644 scripts/upload_model.py create mode 100644 selene.toml delete mode 100644 spec.lua create mode 100644 spec.server.lua rename {lib => src}/linalg.lua (100%) rename {lib => src}/linalg.spec.lua (100%) create mode 100644 standalone-model.project.json create mode 100644 unit-tests.project.json create mode 100644 wally.lock create mode 100644 wally.toml diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml new file mode 100644 index 0000000..f419740 --- /dev/null +++ b/.github/workflows/CI.yml @@ -0,0 +1,36 @@ +name: CI + +on: [push, workflow_dispatch] + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: install selene + run: | + curl https://github.com/Kampfkarren/selene/releases/download/0.9.1/selene-linux -L -o selene + chmod +x ./selene + - name: run selene + run: ./selene ./src + unit-tests: + runs-on: windows-latest + steps: + - uses: actions/checkout@v1 + - name: download roblox install script + run: Invoke-WebRequest -Uri "https://raw.githubusercontent.com/OrbitalOwen/roblox-win-installer/master/install.py" -OutFile install.py + - name: download settings file + run: Invoke-WebRequest -Uri "https://raw.githubusercontent.com/OrbitalOwen/roblox-win-installer/master/GlobalSettings_13.xml" -OutFile GlobalSettings_13.xml + - name: install pip deps + run: pip install wget psutil + - name: install roblox + run: python install.py "${{ secrets.ROBLOSECURITY }}" + - name: install foreman + uses: rojo-rbx/setup-foreman@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + - name: install foreman packages (rojo, run-in-roblox) + run: foreman install + - name: run rojo build + run: rojo build -o .\\unit_tests.rbxlx .\\unit-tests.project.json + - name: run tests + run: run-in-roblox --place .\\unit_tests.rbxlx --script .\\spec.server.lua diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml new file mode 100644 index 0000000..48dde8e --- /dev/null +++ b/.github/workflows/Release.yml @@ -0,0 +1,61 @@ +name: Release + +on: [workflow_dispatch] + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: install python dependencies + run: pip3 install -r requirements.txt + - name: get wally version + id: get_wally_version + run: echo "::set-output name=version-string::$(python3 ./scripts/get_wally_version_string.py)" + - name: install foreman + uses: rojo-rbx/setup-foreman@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + - name: install foreman packages (rojo, run-in-roblox) + run: foreman install + - name: run rojo build + run: rojo build -o ./linalg-${{ steps.get_wally_version.outputs.version-string }}.rbxmx ./standalone-model.project.json + - name: create-release + uses: actions/create-release@latest + id: create_release + with: + draft: false + prerelease: false + release_name: ${{ steps.get_wally_version.outputs.version-string }} + tag_name: ${{ steps.get_wally_version.outputs.version-string }} + body_path: CHANGELOG.md + env: + GITHUB_TOKEN: ${{ github.token }} + - name: upload rbxmx file to release + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ github.token }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./linalg-${{ steps.get_wally_version.outputs.version-string }}.rbxmx + asset_name: linalg-${{ steps.get_wally_version.outputs.version-string }}.rbxmx + asset_content_type: form + - name: upload rbxmx file to Roblox + run: | + cd ./scripts + python upload_model.py -a ${{ secrets.ASSET_ID }} -f ../linalg-${{ steps.get_wally_version.outputs.version-string }}.rbxmx -r "${{ secrets.UPLOADER_BOT_ROBLOSECURITY }}" + cd .. + - name: prepare wally package contents + run: | + mkdir -p ~/temp/linalg + cp -r ./{include,out} ~/temp/linalg/ + cp ./{CHANGELOG.md,LICENSE,README.md,wally.lock,wally.toml} ~/temp/linalg/ + cp ./standalone-model.project.json ~/temp/linalg/default.project.json + mkdir ~/temp/linalg/node_modules + cp -r ./node_modules/@rbxts ~/temp/linalg/node_modules/ + - name: prepare wally auth + run: | + mkdir ~/.wally + echo -e '${{ secrets.WALLY_AUTH }}' > ~/.wally/auth.toml + - name: publish wally package + run: wally publish --project-path ~/temp/linalg/ diff --git a/.gitignore b/.gitignore index dd092bc..4768a3d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .vscode quickTesting.lua luacov.stats.out +Packages \ No newline at end of file diff --git a/.luacheckrc b/.luacheckrc deleted file mode 100644 index 51127fc..0000000 --- a/.luacheckrc +++ /dev/null @@ -1,23 +0,0 @@ --- luacheck: ignore -globals = { - -- global variables - "script", - - -- global functions - "unpack", - - -- math library - "math.abs", "math.sqrt", - "math.ceil", "math.floor", - "math.min", "math.max", - "math.cos", "math.sin", "math.tan", "math.atan2", - - -- test functions - "it", "expect", -} - --- prevent max line lengths -max_line_length = false -max_code_line_length = false -max_string_line_length = false -max_comment_line_length = false \ No newline at end of file diff --git a/.luacov b/.luacov deleted file mode 100644 index 46b2abe..0000000 --- a/.luacov +++ /dev/null @@ -1,8 +0,0 @@ -return { - include = { - "^lib", - }, - exclude = { - "%.spec$", - }, -} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 4369e79..0000000 --- a/.travis.yml +++ /dev/null @@ -1,29 +0,0 @@ -# http://kiki.to/blog/2016/02/04/talk-continuous-integration-with-lua/ -language: python -sudo: false - -branches: - only: - - master - -env: - - LUA="lua=5.1" - -before_install: - - pip install hererocks - - hererocks lua_install -r^ --$LUA - - export PATH=$PATH:$PWD/lua_install/bin - -install: - - luarocks install luafilesystem - - luarocks install busted - - luarocks install luacov - - luarocks install luacov-coveralls - - luarocks install luacheck - -script: - - luacheck lib - - lua -lluacov spec.lua - -after_success: - - luacov-coveralls -e $TRAVIS_BUILD_DIR/lua_install \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..274d1c4 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1 @@ +Releases! diff --git a/foreman.toml b/foreman.toml new file mode 100644 index 0000000..30d4c14 --- /dev/null +++ b/foreman.toml @@ -0,0 +1,4 @@ +[tools] +rojo = { source = "rojo-rbx/rojo", version = "6" } +run-in-roblox = { source = "rojo-rbx/run-in-roblox", version = "0.3.0" } +wally = { source = "UpliftGames/wally", version = "0.2.1" } diff --git a/modules/lemur/LICENSE.md b/modules/lemur/LICENSE.md deleted file mode 100755 index 7d0bc1c..0000000 --- a/modules/lemur/LICENSE.md +++ /dev/null @@ -1,9 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 Lucien Greathouse - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/modules/lemur/init.lua b/modules/lemur/init.lua deleted file mode 100755 index 8d3e33c..0000000 --- a/modules/lemur/init.lua +++ /dev/null @@ -1 +0,0 @@ -return require((...) .. ".lib") \ No newline at end of file diff --git a/modules/lemur/lib/Enum/ConnectionState.lua b/modules/lemur/lib/Enum/ConnectionState.lua deleted file mode 100755 index 497e060..0000000 --- a/modules/lemur/lib/Enum/ConnectionState.lua +++ /dev/null @@ -1,6 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("ConnectionState", { - CONNECTED = 0, - DISCONNECTED = 1, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/CreatorType.lua b/modules/lemur/lib/Enum/CreatorType.lua deleted file mode 100755 index bd5939b..0000000 --- a/modules/lemur/lib/Enum/CreatorType.lua +++ /dev/null @@ -1,6 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("CreatorType", { - User = 0, - Group = 1, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/EasingDirection.lua b/modules/lemur/lib/Enum/EasingDirection.lua deleted file mode 100755 index 06a51ee..0000000 --- a/modules/lemur/lib/Enum/EasingDirection.lua +++ /dev/null @@ -1,7 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("EasingDirection", { - In = 0, - Out = 1, - InOut = 2, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/EasingStyle.lua b/modules/lemur/lib/Enum/EasingStyle.lua deleted file mode 100755 index 9610fa6..0000000 --- a/modules/lemur/lib/Enum/EasingStyle.lua +++ /dev/null @@ -1,12 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("EasingStyle", { - Linear = 0, - Sine = 1, - Back = 2, - Quad = 3, - Quart = 4, - Quint = 5, - Bounce = 6, - Elastic = 7, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/FillDirection.lua b/modules/lemur/lib/Enum/FillDirection.lua deleted file mode 100755 index a79e21d..0000000 --- a/modules/lemur/lib/Enum/FillDirection.lua +++ /dev/null @@ -1,6 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("FillDirection", { - Horizontal = 0, - Vertical = 1, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/Font.lua b/modules/lemur/lib/Enum/Font.lua deleted file mode 100755 index aec8be6..0000000 --- a/modules/lemur/lib/Enum/Font.lua +++ /dev/null @@ -1,23 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("Font", { - Legacy = 0, - Arial = 1, - ArialBold = 2, - SourceSans = 3, - SourceSansBold = 4, - SourceSansLight = 5, - SourceSansItalic = 6, - Bodoni = 7, - Garamond = 8, - Cartoon = 9, - Code = 10, - Highway = 11, - Scifi = 12, - Arcade = 13, - Fantasy = 14, - Antique = 15, - SourceSansSemiBold = 16, - Count = 17, - Fallback = 17, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/HorizontalAlignment.lua b/modules/lemur/lib/Enum/HorizontalAlignment.lua deleted file mode 100755 index 5cfd88b..0000000 --- a/modules/lemur/lib/Enum/HorizontalAlignment.lua +++ /dev/null @@ -1,7 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("HorizontalAlignment", { - Center = 0, - Left = 1, - Right = 2, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/Platform.lua b/modules/lemur/lib/Enum/Platform.lua deleted file mode 100755 index 39d2887..0000000 --- a/modules/lemur/lib/Enum/Platform.lua +++ /dev/null @@ -1,24 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("Platform", { - Windows = 0, - OSX = 1, - IOS = 2, - Android = 3, - XBoxOne = 4, - PS4 = 5, - PS3 = 6, - XBox360 = 7, - WiiU = 8, - NX = 9, - Ouya = 10, - AndroidTV = 11, - Chromecast = 12, - Linux = 13, - SteamOS = 14, - WebOS = 15, - DOS = 16, - BeOS = 17, - UWP = 18, - None = 19, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/PlaybackState.lua b/modules/lemur/lib/Enum/PlaybackState.lua deleted file mode 100755 index a31cbb8..0000000 --- a/modules/lemur/lib/Enum/PlaybackState.lua +++ /dev/null @@ -1,10 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("PlaybackState", { - Begin = 0, - Delayed = 1, - Playing = 2, - Paused = 3, - Completed = 4, - Cancelled = 5, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/ScaleType.lua b/modules/lemur/lib/Enum/ScaleType.lua deleted file mode 100755 index 5641cf0..0000000 --- a/modules/lemur/lib/Enum/ScaleType.lua +++ /dev/null @@ -1,9 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("ScaleType", { - Stretch = 0, - Slice = 1, - Tile = 2, - Fit = 3, - Crop = 4, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/ScrollingDirection.lua b/modules/lemur/lib/Enum/ScrollingDirection.lua deleted file mode 100755 index ab8a972..0000000 --- a/modules/lemur/lib/Enum/ScrollingDirection.lua +++ /dev/null @@ -1,7 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("ScrollingDirection", { - X = 1, - Y = 2, - XY = 4, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/SizeConstraint.lua b/modules/lemur/lib/Enum/SizeConstraint.lua deleted file mode 100755 index 3fe147f..0000000 --- a/modules/lemur/lib/Enum/SizeConstraint.lua +++ /dev/null @@ -1,7 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("SizeConstraint", { - RelativeXY = 0, - RelativeXX = 1, - RelativeYY = 2, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/SortOrder.lua b/modules/lemur/lib/Enum/SortOrder.lua deleted file mode 100755 index 8113522..0000000 --- a/modules/lemur/lib/Enum/SortOrder.lua +++ /dev/null @@ -1,7 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("SortOrder", { - Name = 0, - Custom = 1, - LayoutOrder = 2, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/TextXAlignment.lua b/modules/lemur/lib/Enum/TextXAlignment.lua deleted file mode 100755 index 9b78d8a..0000000 --- a/modules/lemur/lib/Enum/TextXAlignment.lua +++ /dev/null @@ -1,7 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("TextXAlignment", { - Left = 0, - Right = 1, - Center = 2, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/TextYAlignment.lua b/modules/lemur/lib/Enum/TextYAlignment.lua deleted file mode 100755 index cb22bca..0000000 --- a/modules/lemur/lib/Enum/TextYAlignment.lua +++ /dev/null @@ -1,7 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("TextYAlignment", { - Top = 0, - Center = 1, - Bottom = 2, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/ThumbnailSize.lua b/modules/lemur/lib/Enum/ThumbnailSize.lua deleted file mode 100755 index 5d9ffe1..0000000 --- a/modules/lemur/lib/Enum/ThumbnailSize.lua +++ /dev/null @@ -1,11 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("ThumbnailSize", { - Size48x48 = 0, - Size180x180 = 1, - Size420x420 = 2, - Size60x60 = 3, - Size100x100 = 4, - Size150x150 = 5, - Size352x352 = 6, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/ThumbnailType.lua b/modules/lemur/lib/Enum/ThumbnailType.lua deleted file mode 100755 index d97a18d..0000000 --- a/modules/lemur/lib/Enum/ThumbnailType.lua +++ /dev/null @@ -1,7 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("ThumbnailType", { - HeadShot = 0, - AvatarBust = 1, - AvatarThumbnail = 2, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/VerticalAlignment.lua b/modules/lemur/lib/Enum/VerticalAlignment.lua deleted file mode 100755 index ef2cc4c..0000000 --- a/modules/lemur/lib/Enum/VerticalAlignment.lua +++ /dev/null @@ -1,7 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("VerticalAlignment", { - Center = 0, - Top = 1, - Bottom = 2, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/VirtualInputMode.lua b/modules/lemur/lib/Enum/VirtualInputMode.lua deleted file mode 100755 index 6dc2f8d..0000000 --- a/modules/lemur/lib/Enum/VirtualInputMode.lua +++ /dev/null @@ -1,7 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("VirtualInputMode", { - None = 0, - Recording = 1, - Playing = 2, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/ZIndexBehavior.lua b/modules/lemur/lib/Enum/ZIndexBehavior.lua deleted file mode 100755 index 1e297fd..0000000 --- a/modules/lemur/lib/Enum/ZIndexBehavior.lua +++ /dev/null @@ -1,6 +0,0 @@ -local createEnum = import("../createEnum") - -return createEnum("ZIndexBehavior", { - Global = 0, - Sibling = 1, -}) \ No newline at end of file diff --git a/modules/lemur/lib/Enum/init.lua b/modules/lemur/lib/Enum/init.lua deleted file mode 100755 index 88b76c8..0000000 --- a/modules/lemur/lib/Enum/init.lua +++ /dev/null @@ -1,32 +0,0 @@ -local createEnumGroup = import("../createEnumGroup") - -local names = { - "ConnectionState", - "CreatorType", - "EasingDirection", - "EasingStyle", - "FillDirection", - "Font", - "HorizontalAlignment", - "Platform", - "PlaybackState", - "ScaleType", - "ScrollingDirection", - "SizeConstraint", - "SortOrder", - "TextXAlignment", - "TextYAlignment", - "ThumbnailSize", - "ThumbnailType", - "VerticalAlignment", - "VirtualInputMode", - "ZIndexBehavior", -} - -local enums = {} - -for _, name in ipairs(names) do - enums[name] = import("./" .. name) -end - -return createEnumGroup(enums) \ No newline at end of file diff --git a/modules/lemur/lib/Habitat.lua b/modules/lemur/lib/Habitat.lua deleted file mode 100755 index 0d76885..0000000 --- a/modules/lemur/lib/Habitat.lua +++ /dev/null @@ -1,131 +0,0 @@ ---[[ - A Lemur Habitat is an instance of an emulated Roblox environment. - - It is the root instance of the emulated hierarchy. -]] - -local Instance = import("./Instance") -local TaskScheduler = import("./TaskScheduler") -local createEnvironment = import("./createEnvironment") -local fs = import("./fs") -local Game = import("./instances/Game") -local validateType = import("./validateType") -local assign = import("./assign") - -local defaultLoadFromFsOptions = { - loadInitModules = true, -} - -local Habitat = {} -Habitat.__index = Habitat - -function Habitat.new(settings) - local habitat = { - game = Game:new(), - taskScheduler = TaskScheduler.new(), - settings = settings or {}, - environment = nil, - } - - setmetatable(habitat, Habitat) - - habitat.environment = createEnvironment(habitat) - - return habitat -end - -function Habitat:loadFromFs(path, passedOptions) - validateType("path", path, "string") - - if passedOptions ~= nil then - validateType("passedOptions", passedOptions, "table") - end - - local options = assign({}, defaultLoadFromFsOptions, passedOptions) - - if fs.isFile(path) then - if path:find("%.lua$") then - local instance = Instance.new("ModuleScript") - local contents = assert(fs.read(path)) - - instance.Name = path:match("([^/]-)%.lua$") - instance.Source = contents - - getmetatable(instance).instance.modulePath = path - - return instance - end - elseif fs.isDirectory(path) then - local instance = Instance.new("Folder") - instance.Name = path:match("([^/]-)$") - - for name in fs.dir(path) do - -- Why are these even in the iterator? - if name ~= "." and name ~= ".." then - local childPath = path .. "/" .. name - - local childInstance = Habitat:loadFromFs(childPath, passedOptions) - if childInstance ~= nil then - childInstance.Parent = instance - end - end - end - - if options.loadInitModules then - local init = instance:FindFirstChild("init") - - if init ~= nil then - for _, child in ipairs(instance:GetChildren()) do - if child ~= init then - child.Parent = init - end - end - - init.Name = instance.Name - init.Parent = nil - - instance:Destroy() - - instance = init - end - end - - return instance - end - - return nil -end - ---[[ - Equivalent to Roblox's 'require', called on an emulated Roblox instance. -]] -function Habitat:require(instance) - validateType("instance", instance, "Instance") - - if not instance:IsA("ModuleScript") then - local message = ("Attempted to require non-ModuleScript object %q (%s)"):format( - instance.Name, - instance.ClassName - ) - error(message, 2) - end - - local internalInstance = getmetatable(instance).instance - if internalInstance.moduleLoaded then - return internalInstance.moduleResult - end - - local chunk = assert(loadstring(instance.Source, "@" .. internalInstance.modulePath)) - - local environment = assign({}, self.environment, { script = instance }) - setfenv(chunk, environment) - - local result = chunk() - - internalInstance.moduleLoaded = true - internalInstance.moduleResult = result - - return result -end - -return Habitat \ No newline at end of file diff --git a/modules/lemur/lib/Instance.lua b/modules/lemur/lib/Instance.lua deleted file mode 100755 index 9587eed..0000000 --- a/modules/lemur/lib/Instance.lua +++ /dev/null @@ -1,18 +0,0 @@ -local instances = import("./instances") - -local Instance = {} - -function Instance.new(className, parent) - local class = instances[className] - - if class == nil or not class.options.creatable then - error(string.format("Can't make an instance of type %q", tostring(className)), 2) - end - - local instance = class:new() - instance.Parent = parent - - return instance -end - -return Instance \ No newline at end of file diff --git a/modules/lemur/lib/InstanceProperty.lua b/modules/lemur/lib/InstanceProperty.lua deleted file mode 100755 index 537a696..0000000 --- a/modules/lemur/lib/InstanceProperty.lua +++ /dev/null @@ -1,65 +0,0 @@ -local typeof = import("./functions/typeof") -local assign = import("./assign") - -local InstanceProperty = {} - -function InstanceProperty.normal(config) - return assign({}, { - get = function(self, key) - return getmetatable(self).instance.properties[key] - end, - set = function(self, key, value) - getmetatable(self).instance.properties[key] = value - end, - getDefault = function() - return nil - end, - }, config) -end - -function InstanceProperty.readOnly(config) - return assign(InstanceProperty.normal(config), { - set = function(self, key, value) - error(string.format("Unable to assign property %s. Script write access is restricted.", key)) - end, - }, config) -end - ---[[ - This method forces the value of a setter to be typed. - - `type` is a string paramater that is compared to typeof(value) -]] -function InstanceProperty.typed(type, config) - return assign(InstanceProperty.normal(config), { - set = function(self, key, value) - local passedType = typeof(value) - - if passedType ~= type then - error(string.format("%s must be of type %s, received type %s", key, type, passedType), 2) - end - - getmetatable(self).instance.properties[key] = value - end, - }, config) -end - -function InstanceProperty.enum(enum, config) - return assign(InstanceProperty.normal(config), { - set = function(self, key, value) - local passedType = typeof(value) - - if passedType ~= "EnumItem" then - error(string.format("Expected enum from %s, received type %s", tostring(enum), passedType), 2) - end - - if value.EnumType ~= enum then - error(string.format("Expected enum from %s, got enum from %s", tostring(enum), tostring(value.EnumType)), 2) - end - - getmetatable(self).instance.properties[key] = value - end, - }, config) -end - -return InstanceProperty \ No newline at end of file diff --git a/modules/lemur/lib/Instance_spec.lua b/modules/lemur/lib/Instance_spec.lua deleted file mode 100755 index c60ec58..0000000 --- a/modules/lemur/lib/Instance_spec.lua +++ /dev/null @@ -1,33 +0,0 @@ -local Instance = import("./Instance") - -describe("Instance", function() - it("should create instances of objects", function() - local new = Instance.new("Folder") - - assert.not_nil(new) - end) - - it("should error when given invalid instance names", function() - assert.has.errors(function() - Instance.new("ugh no") - end) - end) - - describe("Parent", function() - it("should be set to nil by default", function() - local instance = Instance.new("Folder") - - assert.equal(instance.Parent, nil) - end) - - it("should be set to the given value if available", function() - local parent = Instance.new("Folder") - - local child = Instance.new("Folder", parent) - child.Name = "foo" - - assert.equal(child.Parent, parent) - assert.equal(parent:FindFirstChild("foo"), child) - end) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/Signal.lua b/modules/lemur/lib/Signal.lua deleted file mode 100755 index 70f4c07..0000000 --- a/modules/lemur/lib/Signal.lua +++ /dev/null @@ -1,90 +0,0 @@ ---[[ - A limited, simple implementation of a Signal. - - Handlers are fired in order, and (dis)connections are properly handled when - executing an event. -]] - -local typeKey = import("./typeKey") - -local function immutableAppend(list, ...) - local new = {} - local len = #list - - for key = 1, len do - new[key] = list[key] - end - - for i = 1, select("#", ...) do - new[len + i] = select(i, ...) - end - - return new -end - -local function immutableRemoveValue(list, removeValue) - local new = {} - - for i = 1, #list do - if list[i] ~= removeValue then - table.insert(new, list[i]) - end - end - - return new -end - -local Signal = {} - -Signal.__index = Signal - -function Signal.new() - local internal = { - listeners = {}, - } - - local self = newproxy(true) - getmetatable(self).__index = Signal - getmetatable(self).internal = internal - getmetatable(self)[typeKey] = "RBXScriptSignal" - - return self -end - -function Signal:Connect(callback) - local internal = getmetatable(self).internal - - internal.listeners = immutableAppend(internal.listeners, callback) - - local function disconnect() - internal.listeners = immutableRemoveValue(internal.listeners, callback) - end - - return { - Disconnect = disconnect - } -end - -function Signal:Fire(...) - -- TODO: Move this function somewhere else, since it isn't part of the - -- public API that Roblox exposes. - - local internal = getmetatable(self).internal - - for _, listener in ipairs(internal.listeners) do - listener(...) - end -end - -function Signal:Wait() - -- Once Lemur has an event loop, this can be revisited. - error("Signal:Wait is not implemented in Lemur", 2) -end - -function Signal:_DisconnectAllListeners() - local internal = getmetatable(self).internal - - internal.listeners = {} -end - -return Signal \ No newline at end of file diff --git a/modules/lemur/lib/Signal_spec.lua b/modules/lemur/lib/Signal_spec.lua deleted file mode 100755 index 2cf0fe9..0000000 --- a/modules/lemur/lib/Signal_spec.lua +++ /dev/null @@ -1,62 +0,0 @@ -local Signal = import("./Signal") - -describe("Signal", function() - it("should be instantiable", function() - local signal = Signal.new() - - assert.is_userdata(signal) - assert.is_function(signal.Connect) - assert.is_function(signal.Wait) - - -- This isn't a standard function, but it's how users of Signal fire it! - assert.is_function(signal.Fire) - end) - - it("should handle connections", function() - local signal = Signal.new() - local spy = spy.new(function() end) - - local connection = signal:Connect(spy) - - assert.not_nil(connection) - - signal:Fire() - assert.spy(spy).was_called(1) - - signal:Fire() - assert.spy(spy).was_called(2) - - connection:Disconnect() - signal:Fire() - assert.spy(spy).was_called(2) - end) - - it("should preserve other connections on disconnect", function() - local signal = Signal.new() - local spyA = spy.new(function() end) - local spyB = spy.new(function() end) - - local connectionA = signal:Connect(spyA) - signal:Connect(spyB) - - signal:Fire() - - assert.spy(spyA).was_called(1) - assert.spy(spyB).was_called(1) - - connectionA:Disconnect() - signal:Fire() - - assert.spy(spyA).was_called(1) - assert.spy(spyB).was_called(2) - end) - - -- Remove this when the event loop is made - it("should error on Wait", function() - local signal = Signal.new() - - assert.has.errors(function() - signal:Wait() - end) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/TaskScheduler.lua b/modules/lemur/lib/TaskScheduler.lua deleted file mode 100755 index 1ff9b41..0000000 --- a/modules/lemur/lib/TaskScheduler.lua +++ /dev/null @@ -1,45 +0,0 @@ -local function taskCompare(a, b) - return a.time > b.time -end - -local TaskScheduler = {} -TaskScheduler.prototype = {} -TaskScheduler.__index = TaskScheduler.prototype - -function TaskScheduler.new() - local self = {} - - self.currentTime = 0 - self._tasks = {} - - setmetatable(self, TaskScheduler) - - return self -end - -function TaskScheduler.prototype:schedule(delay, co) - local task = { - co = co, - time = self.currentTime + delay, - } - - table.insert(self._tasks, task) - table.sort(self._tasks, taskCompare) -end - -function TaskScheduler.prototype:step(deltaTime) - self.currentTime = self.currentTime + deltaTime - - while true do - local top = self._tasks[#self._tasks] - - if top == nil or top.time > self.currentTime then - break - end - - self._tasks[#self._tasks] = nil - assert(coroutine.resume(top.co)) - end -end - -return TaskScheduler \ No newline at end of file diff --git a/modules/lemur/lib/assign.lua b/modules/lemur/lib/assign.lua deleted file mode 100755 index b47e864..0000000 --- a/modules/lemur/lib/assign.lua +++ /dev/null @@ -1,17 +0,0 @@ ---[[ - An implementation of JavaScript's Object.assign -]] - -return function(target, ...) - for i = 1, select("#", ...) do - local source = select(i, ...) - - if source ~= nil then - for key, value in pairs(source) do - target[key] = value - end - end - end - - return target -end \ No newline at end of file diff --git a/modules/lemur/lib/baste.lua b/modules/lemur/lib/baste.lua deleted file mode 100755 index fb88065..0000000 --- a/modules/lemur/lib/baste.lua +++ /dev/null @@ -1,332 +0,0 @@ --- luacheck: ignore - ---[[ - Baste, a module system for Lua - Version 1.2.0-dev - - MIT License - - Copyright (c) 2017 Lucien Greathouse - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -]] - -local baste = {} - -local function componentsFromPathString(input) - local components = {} - local sliceStart = 1 - local sliceEnd = 0 - - for i = 1, #input do - local char = input:sub(i, i) - - if char == "/" or char == "\\" then - if sliceEnd ~= 0 then - local slice = input:sub(sliceStart, sliceEnd) - - if slice == ".." then - local lastComponent = components[#components] - - if lastComponent ~= nil and lastComponent ~= ".." then - table.remove(components) - else - table.insert(components, slice) - end - elseif slice ~= "." then - table.insert(components, slice) - end - end - - sliceStart = i + 1 - sliceEnd = 0 - else - sliceEnd = i - end - end - - if sliceEnd ~= 0 then - local slice = input:sub(sliceStart, sliceEnd) - table.insert(components, slice) - end - - return components -end - -local Path = {} -Path.prototype = {} -Path.__index = Path.prototype - -function Path.fromString(input) - if type(input) ~= "string" then - error("Path.fromString expects a string, but got " .. type(input), 2) - end - - local isAbsolute = input:sub(1, 1) == "/" - - local path = { - isAbsolute = isAbsolute, - components = componentsFromPathString(input), - } - - setmetatable(path, Path) - - return path -end - -function Path:__tostring() - if self.__stringRepresentation ~= nil then - return self.__stringRepresentation - end - - local output = table.concat(self.components, "/") - - if self.isAbsolute then - output = "/" .. output - end - - self.__stringRepresentation = output - - return output -end - -function Path.prototype:getExtension() - local lastComponent = self.components[#self.components] - - if lastComponent == nil then - return nil - end - - -- TODO: Handle files that start with a dot? - - return lastComponent:match("%.[^.]+") -end - -function Path.prototype:clone() - local components = {} - - for _, component in ipairs(self.components) do - table.insert(components, component) - end - - local newPath = { - isAbsolute = self.isAbsolute, - components = components, - } - - setmetatable(newPath, getmetatable(self)) - - return newPath -end - -function Path.prototype:push(input) - self = self:clone() - - local newComponents = componentsFromPathString(input) - - for _, component in ipairs(newComponents) do - if component == ".." then - if #self.components > 0 then - table.remove(self.components) - else - table.insert(self.components, component) - end - elseif component ~= "." then - table.insert(self.components, component) - end - end - - return self -end - -function Path.prototype:pop() - self = self:clone() - table.remove(self.components) - - return self -end - -function Path.prototype:addExtension(extension) - self = self:clone() - self.components[#self.components] = self.components[#self.components] .. extension - - return self -end - -baste._Path = Path - --- Abstraction over loadstring and load -local loadWithEnv -if setfenv then - -- 5.1, LuaJIT - loadWithEnv = function(source, name, env) - local chunk, err = loadstring(source, name) - - if not chunk then - return nil, err - end - - if env then - setfenv(chunk, env) - end - - return chunk - end -else - -- 5.2+ - loadWithEnv = function(source, name, env) - return load(source, name, "bt", env) - end -end - --- Abstraction over filesystem APIs -local function readFile(path) - local handle, err = io.open(path, "r") - - if not handle then - return nil, err - end - - local contents = handle:read("*all") - handle:close() - - return contents -end - -if love then - local oldReadFile = readFile - - readFile = function(path) - local contents = love.filesystem.read(path) - - -- It could still exist outside the sandbox! - if not contents then - return oldReadFile(path) - end - - return contents - end -end - -local loadedModules = {} -local moduleResults = {} - ---[[ - Because of tail-call optimization, trying to get the file location of a - chunk whose contents are just a return statement fails. - - Using an 'import function factory' solves thie problem by injecting the - file's path into the generated function. This also reduces the number of - debug library calls. -]] -local function makeImport(rootPath) - return function(modulePath) - local currentPath = rootPath - - if currentPath == nil then - currentPath = Path.fromString(debug.getinfo(2, "S").source:gsub("^@", "")) - end - - if type(modulePath) ~= "string" then - local message = "Bad argument #1 to import, expected string but got %s" - error(string.format(message, type(modulePath)), 2) - end - - -- Relative import! - if modulePath:sub(1, 1) == "." then - local currentDirectory = currentPath:pop() - local relativeModulePath = currentDirectory:push(modulePath) - - local pathsToTry = {relativeModulePath} - - if Path.fromString(modulePath):getExtension() == nil then - table.insert(pathsToTry, relativeModulePath:addExtension(".lua")) - table.insert(pathsToTry, relativeModulePath:push("init.lua")) - end - - -- TODO: Plug-in point for adding additional paths to try - - -- Have we loaded this module before? - for _, path in ipairs(pathsToTry) do - if loadedModules[tostring(path)] then - return moduleResults[tostring(path)] - end - end - - -- Let's try to load from these paths! - for _, path in ipairs(pathsToTry) do - -- Hand-craft an environment for the module we're loading - -- The module won't be able to iterate over globals! - local env = setmetatable({ - import = makeImport(path), - }, { - __index = _G, - __newindex = _G, - }) - - -- TODO: Plug-in point for adding extra loaders - - local source = readFile(tostring(path)) - - if source then - local chunk, err = loadWithEnv(source, "@" .. tostring(path), env) - - if chunk then - local result = chunk() - loadedModules[tostring(path)] = true - moduleResults[tostring(path)] = result - - return result - else - -- Syntax error! - error(err, 2) - end - end - end - - local pathsToTryAsStrings = {} - - for _, path in ipairs(pathsToTry) do - table.insert(pathsToTryAsStrings, tostring(path)) - end - - -- We didn't find any modules. - local message = string.format("Couldn't import %q from file %s, tried:\n\t%s", - modulePath, - tostring(currentPath), - table.concat(pathsToTryAsStrings, "\n\t") - ) - - error(message, 2) - else - -- TODO: check `baste_modules` folder (or similar) - return require(modulePath) - end - end -end - -baste.import = makeImport() - -function baste.global() - _G.import = baste.import - - return baste -end - -return baste \ No newline at end of file diff --git a/modules/lemur/lib/createEnum.lua b/modules/lemur/lib/createEnum.lua deleted file mode 100755 index 540f981..0000000 --- a/modules/lemur/lib/createEnum.lua +++ /dev/null @@ -1,59 +0,0 @@ -local typeKey = import("./typeKey") - -local function createEnumVariant(enum, variantName, variantValue) - local enumVariant = newproxy(true) - - local internal = { - Value = variantValue, - Name = variantName, - EnumType = enum, - } - - getmetatable(enumVariant)[typeKey] = "EnumItem" - - getmetatable(enumVariant).__tostring = function() - return ("Enum.%s.%s"):format(tostring(enum), variantName) - end - - getmetatable(enumVariant).__index = function(self, key) - local value = internal[key] - - if value == nil then - error(("%s is not a valid member"):format(tostring(key)), 2) - end - - return value - end - - return enumVariant -end - -local function createEnum(enumName, variantValues) - local enum = newproxy(true) - - local variants = {} - - for variantName, value in pairs(variantValues) do - variants[variantName] = createEnumVariant(enum, variantName, value) - end - - getmetatable(enum)[typeKey] = "Enum" - - getmetatable(enum).__tostring = function() - return enumName - end - - getmetatable(enum).__index = function(self, key) - local variant = variants[key] - - if variant == nil then - error(("%s is not a valid EnumItem"):format(tostring(key)), 2) - end - - return variant - end - - return enum -end - -return createEnum \ No newline at end of file diff --git a/modules/lemur/lib/createEnumGroup.lua b/modules/lemur/lib/createEnumGroup.lua deleted file mode 100755 index 46c5cdf..0000000 --- a/modules/lemur/lib/createEnumGroup.lua +++ /dev/null @@ -1,34 +0,0 @@ -local typeKey = import("./typeKey") -local typeof = import("./functions/typeof") - -local function createEnumGroup(enums) - for enumName, enum in pairs(enums) do - if typeof(enum) ~= "Enum" then - error(("Invalid enum in enum group %s"):format(tostring(enumName)), 2) - end - end - - local enumGroup = newproxy(true) - - getmetatable(enumGroup)[typeKey] = "Enums" - - getmetatable(enumGroup).__tostring = function() - return "Enums" - end - - getmetatable(enumGroup).__index = function(self, key) - local enum = enums[key] - - if enum == nil then - -- Roblox mistakenly says that we tried to access an EnumItem; this - -- message is corrected. - error(("%s is not a valid Enum"):format(tostring(key)), 2) - end - - return enum - end - - return enumGroup -end - -return createEnumGroup \ No newline at end of file diff --git a/modules/lemur/lib/createEnumGroup_spec.lua b/modules/lemur/lib/createEnumGroup_spec.lua deleted file mode 100755 index 4184c19..0000000 --- a/modules/lemur/lib/createEnumGroup_spec.lua +++ /dev/null @@ -1,43 +0,0 @@ -local typeof = import("./functions/typeof") -local createEnum = import("./createEnum") - -local createEnumGroup = import("./createEnumGroup") - -describe("createEnumGroup", function() - it("should stringify as 'Enums'", function() - local group = createEnumGroup({}) - - assert.equal(tostring(group), "Enums") - end) - - it("should have type 'Enums'", function() - local group = createEnumGroup({}) - - assert.equal(typeof(group), "Enums") - end) - - it("should contain all input enums", function() - local Foo = createEnum("Foo", {}) - local group = createEnumGroup({ - Foo = Foo, - }) - - assert.equal(group.Foo, Foo) - end) - - it("should throw when passing non-enum values in", function() - assert.has.errors(function() - createEnumGroup({ - something = {}, - }) - end) - end) - - it("should throw when indexing with unknown keys", function() - local group = createEnumGroup({}) - - assert.has.errors(function() - tostring(group.whatever) - end) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/createEnum_spec.lua b/modules/lemur/lib/createEnum_spec.lua deleted file mode 100755 index 6963d53..0000000 --- a/modules/lemur/lib/createEnum_spec.lua +++ /dev/null @@ -1,55 +0,0 @@ -local createEnum = import("./createEnum") -local typeof = import("./functions/typeof") - -describe("createEnum", function() - it("should stringify as the input name", function() - local enum = createEnum("Foo", {}) - - assert.equal(tostring(enum), "Foo") - end) - - it("should have typeof 'Enum'", function() - local enum = createEnum("Bar", {}) - - assert.equal(typeof(enum), "Enum") - end) - - it("should have members for each input", function() - local values = { - a = 1, - b = 2, - } - - local enum = createEnum("Bar", values) - - for name, value in pairs(values) do - local enumValue = enum[name] - - assert.equal(typeof(enumValue), "EnumItem") - assert.equal(tostring(enumValue), string.format("Enum.Bar.%s", name)) - assert.equal(enumValue.Value, value) - assert.equal(enumValue.Name, name) - assert.equal(enumValue.EnumType, enum) - end - end) - - it("should throw when accessing invalid members", function() - local enum = createEnum("Frobulon", {}) - - assert.has.errors(function() - tostring(enum.whatever) - end) - end) - - it("should throw when accessing invalid members of an enum variant", function() - local enum = createEnum("Mungulation", { - foo = 5, - }) - - local variant = enum.foo - - assert.has.errors(function() - tostring(variant.something) - end) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/createEnvironment.lua b/modules/lemur/lib/createEnvironment.lua deleted file mode 100755 index 6a79bf9..0000000 --- a/modules/lemur/lib/createEnvironment.lua +++ /dev/null @@ -1,50 +0,0 @@ -local createSettings = import("./createSettings") -local functions = import("./functions") -local taskFunctions = import("./taskFunctions") -local types = import("./types") -local Enum = import("./Enum") -local Instance = import("./Instance") - -local baseEnvironment = {} - -for key, value in pairs(_G) do - baseEnvironment[key] = value -end - -for key, value in pairs(types) do - baseEnvironment[key] = value -end - -baseEnvironment.Instance = Instance -baseEnvironment.Enum = Enum - ---[[ - Create a new script environment, suitable for use with the given habitat. -]] -local function createEnvironment(habitat) - local environment = {} - - for key, value in pairs(baseEnvironment) do - environment[key] = value - end - - for key, fn in pairs(functions) do - environment[key] = fn - end - - for key, fnCreator in pairs(taskFunctions) do - environment[key] = fnCreator(habitat.taskScheduler) - end - - environment.settings = createSettings(habitat.settings) - - environment.require = function(path) - return habitat:require(path) - end - - environment.game = habitat.game - - return environment -end - -return createEnvironment \ No newline at end of file diff --git a/modules/lemur/lib/createSettings.lua b/modules/lemur/lib/createSettings.lua deleted file mode 100755 index 85bed46..0000000 --- a/modules/lemur/lib/createSettings.lua +++ /dev/null @@ -1,68 +0,0 @@ ---[[ - This file creates the settings() method. - Since settings implements the GetFFlag method, we need to pass fast flags - from a Habitat instance. -]] -local assign = import("./assign") -local RenderSettings = import("./functions/settings/RenderSettings") - -local Settings = {} - -setmetatable(Settings, { - __tostring = function() - return "Settings" - end, -}) - -local prototype = {} - ---[[ - GetFFlag will throw on missing fast flags if ignoreMissingFFlags setting is false/nil -]] -function prototype:GetFFlag(name) - if self.settings.flags[name] == nil then - error(string.format("Fast flag %s does not exist", name), 2) - end - - return self.settings.flags[name] -end - -local metatable = {} -metatable.type = Settings - -function metatable:__index(key) - local internal = getmetatable(self).internal - - if internal[key] ~= nil then - return internal[key] - end - - if prototype[key] ~= nil then - return prototype[key] - end - - error(string.format("%s is not a valid member of Settings", tostring(key)), 2) -end - -function Settings.new(settings) - local internalInstance = { - settings = settings or {}, - Rendering = RenderSettings.new() - } - - internalInstance.settings.flags = internalInstance.settings.flags or {} - - local instance = newproxy(true) - - assign(getmetatable(instance), metatable) - getmetatable(instance).internal = internalInstance - - return instance -end - -return function(settings) - local instance = Settings.new(settings) - return function() - return instance - end -end diff --git a/modules/lemur/lib/createSettings_spec.lua b/modules/lemur/lib/createSettings_spec.lua deleted file mode 100755 index 9b14e7a..0000000 --- a/modules/lemur/lib/createSettings_spec.lua +++ /dev/null @@ -1,91 +0,0 @@ -local createSettings = import("./createSettings") -local typeof = import("./functions/typeof") - -describe("functions.settings", function() - it("should be a function", function() - assert.is_function(createSettings) - end) - - it("should return the actual settings() function", function() - local settings = createSettings({}) - local instance = settings() - assert.equals(type(instance), "userdata") - end) - - it("should always return the same object", function() - local settings = createSettings({}) - - local instance = settings() - local instance2 = settings() - assert.equals(instance, instance2) - end) - - describe("GetFFlag", function() - it("should check fast flags", function() - local settings = createSettings({ - flags = { - FFTest = true, - FFTest2 = true, - FFDoesSomethingHappen = false, - } - }) - - local instance = settings() - assert.True(instance:GetFFlag("FFTest")) - assert.True(instance:GetFFlag("FFTest2")) - assert.False(instance:GetFFlag("FFDoesSomethingHappen")) - end) - - it("should throw if a fast flag does not exist", function() - local settings = createSettings({ - flags = { - FFTest = true, - FFTest2 = true, - FFDoesSomethingHappen = false, - } - }) - local instance = settings() - - assert.has.errors(function() - instance:GetFFlag("FFUndefinedFastFlag") - end) - end) - end) - - it("should have a property Rendering", function() - local settings = createSettings({}) - - local instance = settings() - local renderSettings = instance.Rendering - - assert.not_nil(renderSettings) - assert.equals(typeof(renderSettings), "RenderSettings") - end) - - it("should not allow me to set the Rendering property", function() - local settings = createSettings({}) - - local instance = settings() - assert.has.errors(function() - instance.Rendering = true - end) - end) - - it("should not allow me to access undefined properties", function() - local settings = createSettings({}) - - local instance = settings() - assert.has.errors(function() - tostring(instance.thisDoesNotExist) - end) - end) - - it("should not allow me to set undefined properties", function() - local settings = createSettings({}) - - local instance = settings() - assert.has.errors(function() - instance.thisDoesNotExist = "this should throw" - end) - end) -end) diff --git a/modules/lemur/lib/fs.lua b/modules/lemur/lib/fs.lua deleted file mode 100755 index 67eed66..0000000 --- a/modules/lemur/lib/fs.lua +++ /dev/null @@ -1,33 +0,0 @@ -local ok, lfs = pcall(require, "lfs") - -if not ok then - error("Lemur requires LuaFileSystem, which couldn't be found: " .. lfs) -end - -local fs = {} - -function fs.isFile(path) - return lfs.attributes(path, "mode") == "file" -end - -function fs.isDirectory(path) - return lfs.attributes(path, "mode") == "directory" -end - -function fs.read(path) - local handle, err = io.open(path, "r") - - if not handle then - return nil, err - end - - local contents = handle:read("*all") - - handle:close() - - return contents -end - -fs.dir = lfs.dir - -return fs \ No newline at end of file diff --git a/modules/lemur/lib/fs_spec.lua b/modules/lemur/lib/fs_spec.lua deleted file mode 100755 index 78d5f23..0000000 --- a/modules/lemur/lib/fs_spec.lua +++ /dev/null @@ -1,18 +0,0 @@ -describe("fs", function() - local fs = import("./fs") - - it("should return errors when failing to open a file", function() - local contents, err = fs.read("nuclear launch codes.txt") - - assert.is_nil(contents) - assert.is_not_nil(err) - end) - - it("should return contents of files read", function() - local contents, err = fs.read("init.lua") - - assert.is_not_nil(contents) - assert.is_nil(err) - assert.is_true(#contents > 0) - end) -end) diff --git a/modules/lemur/lib/functions/init.lua b/modules/lemur/lib/functions/init.lua deleted file mode 100755 index fb2e603..0000000 --- a/modules/lemur/lib/functions/init.lua +++ /dev/null @@ -1,13 +0,0 @@ -local names = { - "typeof", - "warn", - "tick", -} - -local functions = {} - -for _, name in ipairs(names) do - functions[name] = import("./" .. name) -end - -return functions \ No newline at end of file diff --git a/modules/lemur/lib/functions/settings/RenderSettings.lua b/modules/lemur/lib/functions/settings/RenderSettings.lua deleted file mode 100755 index c9537c4..0000000 --- a/modules/lemur/lib/functions/settings/RenderSettings.lua +++ /dev/null @@ -1,56 +0,0 @@ -local assign = import("../../assign") -local typeKey = import("../../typeKey") - -local RenderSettings = {} - -setmetatable(RenderSettings, { - __tostring = function() - return "RenderSettings" - end, -}) - -local prototype = {} - -local metatable = {} -metatable[typeKey] = "RenderSettings" - -function metatable:__index(key) - local internal = getmetatable(self).internal - - if internal[key] ~= nil then - return internal[key] - end - - if prototype[key] ~= nil then - return prototype[key] - end - - error(string.format("%s is not a valid member of RenderSettings", tostring(key)), 2) -end - -function metatable:__newindex(key, value) - local internal = getmetatable(self).internal - - if internal[key] ~= nil then - internal[key] = value - return - end - - error(string.format("%q is not a valid member of RenderSettings", tostring(key)), 2) -end - - -function RenderSettings.new() - local internalInstance = { - QualityLevel = 0, - } - - local instance = newproxy(true) - - assign(getmetatable(instance), metatable) - getmetatable(instance).internal = internalInstance - - return instance -end - -return RenderSettings \ No newline at end of file diff --git a/modules/lemur/lib/functions/settings/RenderSettings_spec.lua b/modules/lemur/lib/functions/settings/RenderSettings_spec.lua deleted file mode 100755 index a2650de..0000000 --- a/modules/lemur/lib/functions/settings/RenderSettings_spec.lua +++ /dev/null @@ -1,40 +0,0 @@ -local RenderSettings = import("./RenderSettings") -local typeof = import("../typeof") - -describe("functions.settings.RenderSettings", function() - it("should be an object", function() - local instance = RenderSettings.new() - assert.not_nil(instance) - assert.equals(typeof(instance), "RenderSettings") - end) - - it("should be of type RenderSettings", function() - local instance = RenderSettings.new() - assert.equals(typeof(instance), "RenderSettings") - end) - - it("should have a property QualityLevel", function() - local instance = RenderSettings.new() - assert.equals(instance.QualityLevel, 0) - end) - - it("should allow me to set the property QualityLevel", function() - local instance = RenderSettings.new() - instance.QualityLevel = 1 - assert.equals(instance.QualityLevel, 1) - end) - - it("should not allow me to access undefined properties", function() - local instance = RenderSettings.new() - assert.has.errors(function() - tostring(instance.thisDoesNotExist) - end) - end) - - it("should not allow me to set undefined properties", function() - local instance = RenderSettings.new() - assert.has.errors(function() - instance.thisDoesNotExist = "this should throw" - end) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/functions/tick.lua b/modules/lemur/lib/functions/tick.lua deleted file mode 100755 index 4250e22..0000000 --- a/modules/lemur/lib/functions/tick.lua +++ /dev/null @@ -1,10 +0,0 @@ -local success, socket = pcall(require, "socket") - -local tick -if success then - tick = socket.gettime -else - tick = os.clock -end - -return tick \ No newline at end of file diff --git a/modules/lemur/lib/functions/tick_spec.lua b/modules/lemur/lib/functions/tick_spec.lua deleted file mode 100755 index 7eb9421..0000000 --- a/modules/lemur/lib/functions/tick_spec.lua +++ /dev/null @@ -1,7 +0,0 @@ -local tick = import("./tick") - -describe("functions.tick", function() - it("returns a number", function() - assert.is.number(tick()) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/functions/typeof.lua b/modules/lemur/lib/functions/typeof.lua deleted file mode 100755 index ab9bd28..0000000 --- a/modules/lemur/lib/functions/typeof.lua +++ /dev/null @@ -1,21 +0,0 @@ -local typeKey = import("../typeKey") - -local function typeof(object) - local realType = type(object) - - if realType == "userdata" then - local metatable = getmetatable(object) - - if metatable == nil then - return "userdata" - end - - if metatable[typeKey] ~= nil then - return metatable[typeKey] - end - end - - return realType -end - -return typeof \ No newline at end of file diff --git a/modules/lemur/lib/functions/typeof_spec.lua b/modules/lemur/lib/functions/typeof_spec.lua deleted file mode 100755 index 8451981..0000000 --- a/modules/lemur/lib/functions/typeof_spec.lua +++ /dev/null @@ -1,21 +0,0 @@ -local typeof = import("./typeof") - -describe("functions.typeof", function() - it("should identify all Lua primitives", function() - local values = { - true, false, 0, "hello", {}, newproxy(true), - } - - for _, value in ipairs(values) do - assert.equal(type(value), typeof(value)) - end - end) - - it("should identify all Instances as Instance", function() - local instances = import("../instances") - - for _, instance in pairs(instances) do - assert.equal("Instance", typeof(instance:new())) - end - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/functions/warn.lua b/modules/lemur/lib/functions/warn.lua deleted file mode 100755 index f36552d..0000000 --- a/modules/lemur/lib/functions/warn.lua +++ /dev/null @@ -1,15 +0,0 @@ -local function warn(...) - local count = select("#", ...) - for i = 1, count do - local piece = select(i, ...) - io.stderr:write(piece) - - if i < count then - io.stderr:write("\t") - end - end - - io.stderr:write("\n") -end - -return warn \ No newline at end of file diff --git a/modules/lemur/lib/functions/warn_spec.lua b/modules/lemur/lib/functions/warn_spec.lua deleted file mode 100755 index a82b26b..0000000 --- a/modules/lemur/lib/functions/warn_spec.lua +++ /dev/null @@ -1,33 +0,0 @@ -local warn = import("./warn") - -local function setupWarnDetour() - local oldErr = io.stderr - - local writeSpy = spy.new(function() end) - - io.stderr = { -- luacheck: ignore - write = writeSpy - } - - return oldErr, writeSpy -end - -describe("functions.warn", function() - it("should be a function", function() - assert.is_function(warn) - end) - - it("should warn", function() - local oldErr, writeSpy = setupWarnDetour() - warn("Doge has taken over the world!") - assert.spy(writeSpy).was_called_with(io.stderr, "Doge has taken over the world!") - io.stderr = oldErr -- luacheck: ignore - end) - - it("should warn with multiple arguments", function() - local oldErr, writeSpy = setupWarnDetour() - warn("IT'S DOGE!", "AAH!") - assert.spy(writeSpy).was.called(4) -- IT'S DOGE, \t, AAH!, \n - io.stderr = oldErr -- luacheck: ignore - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/init.lua b/modules/lemur/lib/init.lua deleted file mode 100755 index 8b213c0..0000000 --- a/modules/lemur/lib/init.lua +++ /dev/null @@ -1,9 +0,0 @@ -local baste = require((...) .. ".baste") - -local Habitat = baste.import("./Habitat") -local Instance = baste.import("./Instance") - -return { - Habitat = Habitat, - Instance = Instance, -} \ No newline at end of file diff --git a/modules/lemur/lib/init_spec.lua b/modules/lemur/lib/init_spec.lua deleted file mode 100755 index b1aed4d..0000000 --- a/modules/lemur/lib/init_spec.lua +++ /dev/null @@ -1,7 +0,0 @@ -local lemur = require("lib") - -describe("init", function() - it("should load", function() - assert.not_nil(lemur) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/AnalyticsService.lua b/modules/lemur/lib/instances/AnalyticsService.lua deleted file mode 100755 index d62cf2e..0000000 --- a/modules/lemur/lib/instances/AnalyticsService.lua +++ /dev/null @@ -1,4 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local AnalyticsService = BaseInstance:extend("AnalyticsService") - -return AnalyticsService \ No newline at end of file diff --git a/modules/lemur/lib/instances/AnalyticsService_spec.lua b/modules/lemur/lib/instances/AnalyticsService_spec.lua deleted file mode 100755 index b2c25bc..0000000 --- a/modules/lemur/lib/instances/AnalyticsService_spec.lua +++ /dev/null @@ -1,9 +0,0 @@ -local AnalyticsService = import("./AnalyticsService") - -describe("instances.AnalyticsService", function() - it("should instantiate", function() - local instance = AnalyticsService:new() - - assert.not_nil(instance) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/BaseInstance.lua b/modules/lemur/lib/instances/BaseInstance.lua deleted file mode 100755 index 01b36e4..0000000 --- a/modules/lemur/lib/instances/BaseInstance.lua +++ /dev/null @@ -1,375 +0,0 @@ ---[[ - Provides a base implementation for all Instances in Lemur. - - When adding a new instance, you can define: - * properties, using helpers in InstanceProperty - * prototype, used for defining methods and static values - * init, called by the class's constructor -]] - -local assign = import("../assign") -local InstanceProperty = import("../InstanceProperty") -local Signal = import("../Signal") -local typeKey = import("../typeKey") - -local function isInstance(value) - local metatable = getmetatable(value) - - return metatable and metatable.instance ~= nil -end - -local BaseInstance = {} - -BaseInstance.options = { - creatable = false, -} - -BaseInstance.name = "Instance" - -BaseInstance.properties = {} - -BaseInstance.properties.Name = InstanceProperty.normal({ - getDefault = function(self) - return getmetatable(self).class.name - end, -}) - -BaseInstance.properties.ClassName = InstanceProperty.readOnly({ - getDefault = function(self) - return getmetatable(self).class.name - end, -}) - -BaseInstance.properties.AncestryChanged = InstanceProperty.readOnly({ - getDefault = function() - return Signal.new() - end, -}) - -BaseInstance.properties.Changed = InstanceProperty.readOnly({ - getDefault = function() - return Signal.new() - end, -}) - -BaseInstance.properties.Parent = InstanceProperty.normal({ - set = function(self, key, value) - local instance = getmetatable(self).instance - - if instance.destroyed then - error("Attempt to set parent after being destroyed!") - end - - if instance.properties.Parent == value then - return - end - - if value ~= nil and not isInstance(value) then - error(string.format("Can't set Parent to %q; Parent must be an Instance!"), tostring(value)) - end - - if instance.properties.Parent ~= nil then - getmetatable(instance.properties.Parent).instance.children[self] = nil - end - - instance.properties.Parent = value - - if value ~= nil then - getmetatable(value).instance.children[self] = true - end - - self:_PropagateAncestryChanged(self, value) - end, -}) - -BaseInstance.prototype = {} - -function BaseInstance.prototype:ClearAllChildren() - local children = getmetatable(self).instance.children - - for child in pairs(children) do - child:Destroy() - end -end - -function BaseInstance.prototype:FindFirstAncestor(name) - local level = self.Parent - - while level do - if level.Name == name then - return level - end - - level = level.Parent - end -end - -function BaseInstance.prototype:FindFirstAncestorOfClass(name) - local level = self.Parent - - while level do - if level.ClassName == name then - return level - end - - level = level.Parent - end -end - -function BaseInstance.prototype:FindFirstAncestorWhichIsA(className) - local level = self.Parent - - while level do - if level:IsA(className) then - return level - end - - level = level.Parent - end -end - -function BaseInstance.prototype:FindFirstChild(name) - local children = getmetatable(self).instance.children - - -- Search for existing children - -- This is a set stored by child instead of by name, since names are not unique. - for child in pairs(children) do - if child.Name == name then - return child - end - end - - return nil -end - -function BaseInstance.prototype:FindFirstChildOfClass(className) - local children = getmetatable(self).instance.children - - -- Search for existing children - -- This is a set stored by child instead of by name, since names are not unique. - for child in pairs(children) do - if child.ClassName == className then - return child - end - end - - return nil -end - -function BaseInstance.prototype:FindFirstChildWhichIsA(className) - local children = getmetatable(self).instance.children - - -- Search for existing children - -- This is a set stored by child instead of by name, since names are not unique. - for child in pairs(children) do - if child:IsA(className) then - return child - end - end - - return nil -end - -function BaseInstance.prototype:GetChildren() - local children = getmetatable(self).instance.children - local result = {} - - for child in pairs(children) do - table.insert(result, child) - end - - return result -end - -function BaseInstance.prototype:GetDescendants() - local stack = {} - local descendants = {} - local current = self - - while current do - local children = current:GetChildren() - - for _, child in pairs(children) do - descendants[#descendants + 1] = child - stack[#stack + 1] = child - end - - current = stack[#stack] - stack[#stack] = nil - end - - return descendants -end - -function BaseInstance.prototype:IsA(className) - local currentClass = getmetatable(self).class - - while currentClass ~= nil do - if currentClass.name == className then - return true - end - - currentClass = currentClass.super - end - - return false -end - -function BaseInstance.prototype:Destroy() - self:ClearAllChildren() - - if self.Parent ~= nil then - self.Parent = nil - end - - self:_DisconnectAllChangedListeners() - - getmetatable(self).instance.destroyed = true -end - -function BaseInstance.prototype:GetPropertyChangedSignal(key) - local properties = getmetatable(self).class.properties - local propertySignals = getmetatable(self).instance.propertySignals - - local listener = propertySignals[key] - - if not listener then - assert(properties[key], key .. " is not a valid property name.") - - listener = Signal.new() - propertySignals[key] = listener - end - - return listener -end - -function BaseInstance.prototype:GetFullName() - local name = self.Name - local level = self.Parent - - while level and getmetatable(level).class.name ~= "DataModel" do - name = level.Name .. "." .. name - level = level.Parent - end - - return name -end - -function BaseInstance.prototype:WaitForChild(name, delay) - return self:FindFirstChild(name) -end - -function BaseInstance.prototype:_DisconnectAllChangedListeners() - local propertySignals = getmetatable(self).instance.propertySignals - - for _, signal in pairs(propertySignals) do - signal:_DisconnectAllListeners() - end - - self.Changed:_DisconnectAllListeners() -end - -function BaseInstance.prototype:_PropagateAncestryChanged(instance, parent) - self.AncestryChanged:Fire(instance, parent) - - local children = getmetatable(self).instance.children - - for child in pairs(children) do - child:_PropagateAncestryChanged(instance, parent) - end -end - -BaseInstance.metatable = {} -BaseInstance.metatable[typeKey] = "Instance" - -function BaseInstance.metatable.__index(self, key) - local class = getmetatable(self).class - - if class.properties[key] then - return class.properties[key].get(self, key) - end - - if class.prototype[key] then - return class.prototype[key] - end - - local object = self:FindFirstChild(key) - if object then - return object - end - - error(string.format("%q is not a valid member of %s", tostring(key), self.ClassName), 2) -end - -function BaseInstance.metatable.__newindex(self, key, value) - local class = getmetatable(self).class - - if class.properties[key] then - class.properties[key].set(self, key, value) - - self.Changed:Fire(key) - - local propertyChangedSignal = getmetatable(self).instance.propertySignals[key] - - if propertyChangedSignal then - propertyChangedSignal:Fire() - end - - return - end - - error(string.format("%q is not a valid member of %s", tostring(key), self.ClassName), 2) -end - -function BaseInstance.metatable:__tostring() - return self.Name -end - -function BaseInstance:new(...) - local internalInstance = { - destroyed = false, - properties = {}, - propertySignals = {}, - children = {}, - } - - local instance = newproxy(true) - - -- Because userdata have a fixed metatable, merge values onto it. - assign(getmetatable(instance), self.metatable) - getmetatable(instance).instance = internalInstance - getmetatable(instance).class = self - - for key, property in pairs(self.properties) do - internalInstance.properties[key] = property.getDefault(instance) - end - - self:init(instance, ...) - - return instance -end - -function BaseInstance:init(instance, ...) -end - ---[[ - Create a new instance class with the given name. -]] -function BaseInstance:extend(name, options) - assert(type(name) == "string", "Expected string 'name' as argument #1.") - assert(type(options) == "table" or options == nil, "Expected optional table 'options' as argument #2.") - - local newClass = assign({}, self) - - newClass.name = name - newClass.super = self - - newClass.properties = assign({}, self.properties) - newClass.prototype = assign({}, self.prototype) - newClass.metatable = assign({}, self.metatable) - newClass.options = assign({}, self.options, options or {}) - - return newClass -end - -return BaseInstance \ No newline at end of file diff --git a/modules/lemur/lib/instances/BaseInstance_spec.lua b/modules/lemur/lib/instances/BaseInstance_spec.lua deleted file mode 100755 index 944abd0..0000000 --- a/modules/lemur/lib/instances/BaseInstance_spec.lua +++ /dev/null @@ -1,661 +0,0 @@ -local Game = import("./Game") -local Folder = import("./Folder") -local typeof = import("../functions/typeof") - -local BaseInstance = import("./BaseInstance") - -describe("instances.BaseInstance", function() - it("should error when parenting instances to invalid objects", function() - local new = BaseInstance:new() - - assert.has.errors(function() - new.Parent = 7 - end) - end) - - it("should error when setting unknown values", function() - local new = BaseInstance:new() - - assert.has.errors(function() - new.frobulations = 6 - end) - end) - - it("should error when indexing invalid instances", function() - local instance = BaseInstance:new() - - local function nop() - end - - assert.has.errors(function() - nop(instance.neverWillEXIST) - end) - end) - - it("should be identified by typeof", function() - local instance = BaseInstance:new() - - assert.equal(typeof(instance), "Instance") - end) - - it("should allow the change and read of Name", function() - local instance = BaseInstance:new() - assert.equal(instance.Name, "Instance") - - instance.Name = "Foobar" - assert.equal(instance.Name, "Foobar") - end) - - it("should not allow the change of ClassName", function() - local instance = BaseInstance:new() - - assert.has.errors(function() - instance.ClassName = "Foobar" - end) - end) - - describe("Parent", function() - it("should set to nil", function() - local parent = BaseInstance:new() - - local child = BaseInstance:new() - child.Parent = parent - child.Name = "foo" - - assert.equal(parent:FindFirstChild("foo"), child) - - child.Parent = nil - - assert.equal(parent:FindFirstChild("foo"), nil) - end) - - it("should set to other instances", function() - local parent1 = BaseInstance:new() - local parent2 = BaseInstance:new() - - local child = BaseInstance:new() - child.Parent = parent1 - child.Name = "foo" - - assert.equal(parent1:FindFirstChild("foo"), child) - - child.Parent = parent2 - - assert.equal(parent1:FindFirstChild("foo"), nil) - assert.equal(child.Parent, parent2) - assert.equal(parent2:FindFirstChild("foo"), child) - end) - - -- This may seem like a weird test, but it's for 100% coverage - it("shouldn't react differently when setting the parent to the existing parent", function() - local parent = BaseInstance:new() - local child = BaseInstance:new() - child.Parent = parent - - assert.has_no_errors(function() - child.Parent = parent - end) - end) - end) - - describe("FindFirstChild", function() - it("should never error on invalid index", function() - local instance = BaseInstance:new() - - assert.equal(instance:FindFirstChild("NEVER. WILL. EXIST!"), nil) - end) - end) - - describe("GetChildren", function() - it("should return no children for empty instances", function() - local instance = BaseInstance:new() - - assert.equal(#instance:GetChildren(), 0) - end) - - it("should yield all children", function() - local parent = BaseInstance:new() - - local child1 = BaseInstance:new() - child1.Parent = parent - - local child2 = BaseInstance:new() - child2.Parent = parent - - assert.equal(#parent:GetChildren(), 2) - - local child1Seen = false - local child2Seen = false - for _, child in ipairs(parent:GetChildren()) do - if child == child1 then - child1Seen = true - elseif child == child2 then - child2Seen = true - else - error("Invalid child found") - end - end - - assert.equal(child1Seen, true) - assert.equal(child2Seen, true) - end) - end) - - describe("GetDescendants", function() - it("should return no descendants for empty instances", function() - local instance = BaseInstance:new() - - assert.equal(#instance:GetDescendants(), 0) - end) - - it("should return all first level children", function() - local parent = BaseInstance:new() - - local child1 = BaseInstance:new() - child1.Parent = parent - - local child2 = BaseInstance:new() - child2.Parent = parent - - assert.equal(#parent:GetDescendants(), 2) - - local child1Seen = false - local child2Seen = false - for _, child in ipairs(parent:GetDescendants()) do - if child == child1 then - child1Seen = true - elseif child == child2 then - child2Seen = true - else - error("Invalid child found") - end - end - - assert.equal(child1Seen, true) - assert.equal(child2Seen, true) - end) - - it("should return all descendants", function() - local parent = BaseInstance:new() - - local child1 = BaseInstance:new() - child1.Parent = parent - - local child2 = BaseInstance:new() - child2.Parent = parent - - local child3 = BaseInstance:new() - child3.Parent = child2 - - assert.equal(#parent:GetDescendants(), 3) - - local child1Seen = false - local child2Seen = false - local child3Seen = false - for _, child in ipairs(parent:GetDescendants()) do - if child == child1 then - child1Seen = true - elseif child == child2 then - child2Seen = true - elseif child == child3 then - child3Seen = true - else - error("Invalid child found") - end - end - - assert.equal(child1Seen, true) - assert.equal(child2Seen, true) - assert.equal(child3Seen, true) - end) - end) - - describe("WaitForChild", function() - it("should work just like FindFirstChild", function() - local parent = BaseInstance:new() - - local child = BaseInstance:new() - child.Parent = parent - child.Name = "foo" - - local result = parent:WaitForChild("foo") - assert.equal(result, child) - - child.Parent = nil - result = parent:WaitForChild("foo") - assert.equal(result, nil) - end) - end) - - describe("Destroy", function() - it("should set the instance's Parent to nil", function() - local parent = BaseInstance:new() - local child = BaseInstance:new() - child.Parent = parent - - assert.equal(child.Parent, parent) - - child:Destroy() - - assert.equal(child.Parent, nil) - end) - - it("should set the children's parents to nil", function() - local parent = BaseInstance:new() - local child = BaseInstance:new() - child.Parent = parent - - parent:Destroy() - assert.equal(child.Parent, nil) - end) - - it("should lock the parent property", function() - local instance = BaseInstance:new() - local badParent = BaseInstance:new() - - instance:Destroy() - - assert.has.errors(function() - instance.Parent = badParent - end) - end) - - it("should only lock its own instance, and not all of the same type", function() - local destroyFolder = BaseInstance:new() - destroyFolder:Destroy() - assert.equal(destroyFolder.Parent, nil) - - local goodParent = BaseInstance:new() - local goodFolder = BaseInstance:new() - - assert.has_no.errors(function() - goodFolder.Parent = goodParent - end) - end) - - it("should disconnect all Changed listeners", function() - local instance = BaseInstance:new() - - local calls = 0 - instance.Changed:Connect(function() - calls = calls + 1 - end) - - instance.Name = "Foo" - - assert.equal(calls, 1) - - instance:Destroy() - instance.Name = "Bar" - - assert.equal(calls, 1) - end) - - it("should disconnect all GetPropertyChangedSignal listeners", function() - local instance = BaseInstance:new() - - local callsA = 0 - local callsB = 0 - - instance:GetPropertyChangedSignal("Name"):Connect(function() - callsA = callsA + 1 - end) - - instance:GetPropertyChangedSignal("Name"):Connect(function() - callsB = callsB + 1 - end) - - instance.Name = "Foo" - - assert.equal(callsA, 1) - assert.equal(callsB, 1) - - instance:Destroy() - instance.Name = "Bar" - - assert.equal(callsA, 1) - assert.equal(callsB, 1) - end) - end) - - describe("IsA", function() - it("should check the class's hierarchy", function() - local ClassA = BaseInstance:extend("ClassA") - local ClassB = ClassA:extend("ClassB") - local ClassC = ClassB:extend("ClassC") - - local instance = BaseInstance:new() - local objA = ClassA:new() - local objB = ClassB:new() - local objC = ClassC:new() - - assert.False(instance:IsA("ClassC")) - assert.False(instance:IsA("ClassB")) - assert.False(instance:IsA("ClassA")) - assert.True(instance:IsA("Instance")) - - assert.False(objA:IsA("ClassC")) - assert.False(objA:IsA("ClassB")) - assert.True(objA:IsA("ClassA")) - assert.True(objA:IsA("Instance")) - - assert.False(objB:IsA("ClassC")) - assert.True(objB:IsA("ClassB")) - assert.True(objB:IsA("ClassA")) - assert.True(objB:IsA("Instance")) - - assert.True(objC:IsA("ClassC")) - assert.True(objC:IsA("ClassB")) - assert.True(objC:IsA("ClassA")) - assert.True(objC:IsA("Instance")) - end) - end) - - describe("GetFullName", function() - it("should get the full name", function() - local instance = BaseInstance:new() - instance.Name = "Test" - local other = BaseInstance:new() - other.Name = "Parent" - - instance.Parent = other - - local fullName = instance:GetFullName() - assert.equal("Parent.Test", fullName) - end) - - it("should exclude game", function() - local instance = BaseInstance:new() - instance.Name = "Test" - local other = Game:new() - other.Name = "Parent" - - instance.Parent = other - - local fullName = instance:GetFullName() - assert.equal("Test", fullName) - end) - - it("should return the instance name if there is no parent", function() - local instance = BaseInstance:new() - instance.Name = "Test" - - local fullName = instance:GetFullName() - assert.equal("Test", fullName) - end) - end) - - describe("tostring", function() - it("should match the name of the instance", function() - local instance = BaseInstance:new() - instance.Name = "foo" - - assert.equal(tostring(instance), "foo") - end) - end) - - describe("Changed", function() - it("should fire Changed", function() - local instance = BaseInstance:new() - - local changedSpy = spy.new(function() end) - instance.Changed:Connect(changedSpy) - - instance.Name = "NameChange" - assert.spy(changedSpy).was.called_with("Name") - end) - end) - - describe("GetPropertyChangedSignal", function() - it("should fire property signals for the right property", function() - local instance = BaseInstance:new() - local spy = spy.new(function() end) - instance:GetPropertyChangedSignal("Name"):Connect(spy) - instance.Name = "NameChange" - assert.spy(spy).was.called() - end) - - it("should not fire property signals for the incorrect property", function() - local instance = BaseInstance:new() - local spy = spy.new(function() end) - instance:GetPropertyChangedSignal("Parent"):Connect(spy) - instance.Name = "NameChange2" - assert.spy(spy).was_not_called() - end) - - it("should error when given an invalid property name", function() - local instance = BaseInstance:new() - assert.has.errors(function() - instance:GetPropertyChangedSignal("CanDestroyTheWorld"):Connect(function() end) - end) - end) - end) - - describe("ClearAllChildren", function() - it("should clear children", function() - local parent = BaseInstance:new() - local child = BaseInstance:new() - child.Parent = parent - - parent:ClearAllChildren() - assert.equal(child.Parent, nil) - end) - end) - - describe("FindFirstAncestor", function() - it("should find ancestors", function() - local parent = BaseInstance:new() - parent.Name = "Ancestor" - - local child = BaseInstance:new() - child.Parent = parent - - assert.equal(child:FindFirstAncestor("Ancestor"), parent) - end) - - it("should return nil with no matching ancestor", function() - local parent = BaseInstance:new() - local child = BaseInstance:new() - child.Parent = parent - - assert.equal(child:FindFirstAncestor("Ancestor"), nil) - end) - - it("should return nil with no ancestor", function() - local child = BaseInstance:new() - - assert.equal(child:FindFirstAncestor("Ancestor"), nil) - end) - end) - - describe("FindFirstAncestorOfClass", function() - it("should find ancestors", function() - local parent = BaseInstance:new() - local child = BaseInstance:new() - child.Parent = parent - - assert.equal(child:FindFirstAncestorOfClass("Instance"), parent) - end) - - it("should return nil with no matching ancestor", function() - local parent = BaseInstance:new() - local child = BaseInstance:new() - child.Parent = parent - - assert.equal(child:FindFirstAncestorOfClass("Ancestor"), nil) - end) - - it("should return nil with no ancestor", function() - local child = BaseInstance:new() - - assert.equal(child:FindFirstAncestorOfClass("Instance"), nil) - end) - end) - - describe("FindFirstAncestorWhichIsA", function() - it("should find ancestors", function() - local parent = BaseInstance:new() - local child = BaseInstance:new() - child.Parent = parent - - assert.equal(child:FindFirstAncestorOfClass("Instance"), parent) - end) - - it("should return nil with no matching ancestor", function() - local parent = BaseInstance:new() - local child = BaseInstance:new() - child.Parent = parent - - assert.equal(child:FindFirstAncestorOfClass("Ancestor"), nil) - end) - - it("should return nil with no ancestor", function() - local child = BaseInstance:new() - - assert.equal(child:FindFirstAncestorOfClass("Instance"), nil) - end) - - it("should handle narrower ancestor classes", function() - local child = BaseInstance:new() - local parent = Folder:new() - child.Parent = parent - - assert.equal(child:FindFirstAncestorWhichIsA("Instance"), parent) - end) - end) - - describe("FindFirstChildOfClass", function() - it("should find instances", function() - local parent = BaseInstance:new() - local childCorrect = BaseInstance:new() - childCorrect.Parent = parent - - local childIncorrect = Folder:new() - childIncorrect.Parent = parent - - assert.equal(parent:FindFirstChildOfClass("Instance"), childCorrect) - end) - - it("should return nil with no matching child", function() - local parent = BaseInstance:new() - - local childIncorrect = BaseInstance:new() - childIncorrect.Parent = parent - - assert.equal(parent:FindFirstChildOfClass("Folder"), nil) - end) - - it("should return nil with no children", function() - local parent = BaseInstance:new() - - assert.equal(parent:FindFirstChildOfClass("Folder"), nil) - end) - end) - - describe("FindFirstChildOfClass", function() - it("should find instances", function() - local parent = BaseInstance:new() - local childCorrect = BaseInstance:new() - childCorrect.Parent = parent - - local childIncorrect = Folder:new() - childIncorrect.Parent = parent - - assert.equal(parent:FindFirstChildWhichIsA("Instance"), childCorrect) - end) - - it("should return nil with no matching child", function() - local parent = BaseInstance:new() - - local childIncorrect = BaseInstance:new() - childIncorrect.Parent = parent - - assert.equal(parent:FindFirstChildWhichIsA("Folder"), nil) - end) - - it("should return nil with no children", function() - local parent = BaseInstance:new() - - assert.equal(parent:FindFirstChildWhichIsA("Folder"), nil) - end) - end) - - describe("super", function() - it("should reference the parent class", function() - local ClassA = BaseInstance:extend("ClassA") - local ClassB = ClassA:extend("ClassB") - local ClassC = ClassB:extend("ClassC") - - assert.equals(ClassC.super, ClassB) - assert.equals(ClassB.super, ClassA) - assert.equals(ClassA.super, BaseInstance) - assert.equals(BaseInstance.super, nil) - end) - end) - - describe("AncestryChanged", function() - it("should fire when my parent changes", function() - local parent = BaseInstance:new() - local parentSpy = spy.new(function() end) - parent.AncestryChanged:Connect(parentSpy) - - local child = BaseInstance:new() - local childSpy = spy.new(function() end) - child.AncestryChanged:Connect(childSpy) - - child.Parent = parent - assert.spy(parentSpy).was_not_called() - assert.spy(childSpy).was_called_with(child, parent) - - child.Parent = nil - assert.spy(parentSpy).was_not_called() - assert.spy(childSpy).was_called_with(child, nil) - end) - - it("should fire when my ancestor changes", function() - local parent = BaseInstance:new() - local parentSpy = spy.new(function() end) - parent.AncestryChanged:Connect(parentSpy) - - local child = BaseInstance:new() - local childSpy = spy.new(function() end) - child.AncestryChanged:Connect(childSpy) - - local grandchild = BaseInstance:new() - local grandchildSpy = spy.new(function() end) - grandchild.AncestryChanged:Connect(grandchildSpy) - - grandchild.Parent = child - assert.spy(parentSpy).was_not_called() - assert.spy(childSpy).was_not_called() - assert.spy(grandchildSpy).was_called_with(grandchild, child) - - parentSpy:clear() - childSpy:clear() - grandchildSpy:clear() - - child.Parent = parent - assert.spy(parentSpy).was_not_called() - assert.spy(childSpy).was_called_with(child, parent) - assert.spy(grandchildSpy).was_called_with(child, parent) - - parentSpy:clear() - childSpy:clear() - grandchildSpy:clear() - - child.Parent = nil - assert.spy(parentSpy).was_not_called() - assert.spy(childSpy).was_called_with(child, nil) - assert.spy(grandchildSpy).was_called_with(child, nil) - - parentSpy:clear() - childSpy:clear() - grandchildSpy:clear() - - grandchild.Parent = nil - assert.spy(parentSpy).was_not_called() - assert.spy(childSpy).was_not_called() - assert.spy(grandchildSpy).was_called_with(grandchild, nil) - end) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/BindableEvent.lua b/modules/lemur/lib/instances/BindableEvent.lua deleted file mode 100755 index f7d5ff8..0000000 --- a/modules/lemur/lib/instances/BindableEvent.lua +++ /dev/null @@ -1,17 +0,0 @@ -local Signal = import("../Signal") -local BaseInstance = import("./BaseInstance") -local InstanceProperty = import("../InstanceProperty") - -local BindableEvent = BaseInstance:extend("BindableEvent", { - creatable = true, -}) - -BindableEvent.properties.Event = InstanceProperty.readOnly({ - getDefault = Signal.new, -}) - -function BindableEvent.prototype:Fire(...) - self.Event:Fire(...) -end - -return BindableEvent \ No newline at end of file diff --git a/modules/lemur/lib/instances/BindableEvent_spec.lua b/modules/lemur/lib/instances/BindableEvent_spec.lua deleted file mode 100755 index c3e63bc..0000000 --- a/modules/lemur/lib/instances/BindableEvent_spec.lua +++ /dev/null @@ -1,21 +0,0 @@ -local Instance = import("../Instance") - -describe("instances.BindableEvent", function() - it("should instantiate", function() - local instance = Instance.new("BindableEvent") - - assert.not_nil(instance) - assert.not_nil(instance.Event) - end) - - it("should fire Event when fired", function() - local instance = Instance.new("BindableEvent") - - local testSpy = spy.new(function() end) - instance.Event:Connect(testSpy) - - instance:Fire() - - assert.spy(testSpy).was_called(1) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/BoolValue.lua b/modules/lemur/lib/instances/BoolValue.lua deleted file mode 100755 index 3d030a6..0000000 --- a/modules/lemur/lib/instances/BoolValue.lua +++ /dev/null @@ -1,18 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local InstanceProperty = import("../InstanceProperty") - -local BoolValue = BaseInstance:extend("BoolValue", { - creatable = true, -}) - -BoolValue.properties.Value = InstanceProperty.normal({ - getDefault = function() - return false - end, -}) - -function BoolValue:init(instance) - instance.Name = "Value" -end - -return BoolValue \ No newline at end of file diff --git a/modules/lemur/lib/instances/BoolValue_spec.lua b/modules/lemur/lib/instances/BoolValue_spec.lua deleted file mode 100755 index 9ffd760..0000000 --- a/modules/lemur/lib/instances/BoolValue_spec.lua +++ /dev/null @@ -1,11 +0,0 @@ -local Instance = import("../Instance") - -describe("instances.BoolValue", function() - it("should instantiate", function() - local instance = Instance.new("BoolValue") - - assert.not_nil(instance) - assert.equal("Value", instance.Name) - assert.equal(false, instance.Value) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/Camera.lua b/modules/lemur/lib/instances/Camera.lua deleted file mode 100755 index 2829153..0000000 --- a/modules/lemur/lib/instances/Camera.lua +++ /dev/null @@ -1,15 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local Vector2 = import("../types/Vector2") -local InstanceProperty = import("../InstanceProperty") - -local Camera = BaseInstance:extend("Camera", { - creatable = true, -}) - -Camera.properties.ViewportSize = InstanceProperty.normal({ - getDefault = function() - return Vector2.new(800, 600) - end, -}) - -return Camera \ No newline at end of file diff --git a/modules/lemur/lib/instances/Camera_spec.lua b/modules/lemur/lib/instances/Camera_spec.lua deleted file mode 100755 index 3f66b58..0000000 --- a/modules/lemur/lib/instances/Camera_spec.lua +++ /dev/null @@ -1,15 +0,0 @@ -local Instance = import("../Instance") -local typeof = import("../functions/typeof") - -describe("instances.Camera", function() - it("should instantiate", function() - local instance = Instance.new("Camera") - - assert.not_nil(instance) - end) - - it("should have properties defined", function() - local instance = Instance.new("Camera") - assert.equal(typeof(instance.ViewportSize), "Vector2") - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/ContentProvider.lua b/modules/lemur/lib/instances/ContentProvider.lua deleted file mode 100755 index 8de1570..0000000 --- a/modules/lemur/lib/instances/ContentProvider.lua +++ /dev/null @@ -1,11 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local InstanceProperty = import("../InstanceProperty") -local ContentProvider = BaseInstance:extend("ContentProvider") - -ContentProvider.properties.BaseUrl = InstanceProperty.normal({ - getDefault = function() - return "https://www.roblox.com/" - end, -}) - -return ContentProvider \ No newline at end of file diff --git a/modules/lemur/lib/instances/ContentProvider_spec.lua b/modules/lemur/lib/instances/ContentProvider_spec.lua deleted file mode 100755 index 898948c..0000000 --- a/modules/lemur/lib/instances/ContentProvider_spec.lua +++ /dev/null @@ -1,15 +0,0 @@ -local ContentProvider = import("./ContentProvider") - -describe("instances.ContentProvider", function() - it("should instantiate", function() - local instance = ContentProvider:new() - - assert.not_nil(instance) - end) - - it("should have a string property BaseUrl", function() - local instance = ContentProvider:new() - - assert.equals(type(instance.BaseUrl), "string") - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/CoreGui.lua b/modules/lemur/lib/instances/CoreGui.lua deleted file mode 100755 index 3de04b6..0000000 --- a/modules/lemur/lib/instances/CoreGui.lua +++ /dev/null @@ -1,11 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local CoreGui = BaseInstance:extend("CoreGui") -local ScreenGui = import("./ScreenGui") - -function CoreGui:init(instance) - local RobloxGui = ScreenGui:new() - RobloxGui.Name = "RobloxGui" - RobloxGui.Parent = instance -end - -return CoreGui \ No newline at end of file diff --git a/modules/lemur/lib/instances/CoreGui_spec.lua b/modules/lemur/lib/instances/CoreGui_spec.lua deleted file mode 100755 index 1b31b91..0000000 --- a/modules/lemur/lib/instances/CoreGui_spec.lua +++ /dev/null @@ -1,18 +0,0 @@ -local CoreGui = import("./CoreGui") - -describe("instances.CoreGui", function() - it("should instantiate", function() - local instance = CoreGui:new() - - assert.not_nil(instance) - end) - - it("should have a ScreenGui child named RobloxGui", function() - local instance = CoreGui:new() - - local robloxGui = instance:FindFirstChild("RobloxGui") - - assert.not_nil(robloxGui) - assert.equal(robloxGui.ClassName, "ScreenGui") - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/CorePackages.lua b/modules/lemur/lib/instances/CorePackages.lua deleted file mode 100755 index a08b00e..0000000 --- a/modules/lemur/lib/instances/CorePackages.lua +++ /dev/null @@ -1,4 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local CorePackages = BaseInstance:extend("CorePackages") - -return CorePackages \ No newline at end of file diff --git a/modules/lemur/lib/instances/CorePackages_spec.lua b/modules/lemur/lib/instances/CorePackages_spec.lua deleted file mode 100755 index f485088..0000000 --- a/modules/lemur/lib/instances/CorePackages_spec.lua +++ /dev/null @@ -1,9 +0,0 @@ -local CorePackages = import("./CorePackages") - -describe("instances.CorePackages", function() - it("should instantiate", function() - local instance = CorePackages:new() - - assert.not_nil(instance) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/Folder.lua b/modules/lemur/lib/instances/Folder.lua deleted file mode 100755 index d26636f..0000000 --- a/modules/lemur/lib/instances/Folder.lua +++ /dev/null @@ -1,5 +0,0 @@ -local BaseInstance = import("./BaseInstance") - -return BaseInstance:extend("Folder", { - creatable = true, -}) \ No newline at end of file diff --git a/modules/lemur/lib/instances/Folder_spec.lua b/modules/lemur/lib/instances/Folder_spec.lua deleted file mode 100755 index ab96d61..0000000 --- a/modules/lemur/lib/instances/Folder_spec.lua +++ /dev/null @@ -1,9 +0,0 @@ -local Instance = import("../Instance") - -describe("instances.Folder", function() - it("should instantiate", function() - local instance = Instance.new("Folder") - - assert.not_nil(instance) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/Frame.lua b/modules/lemur/lib/instances/Frame.lua deleted file mode 100755 index d48fb9e..0000000 --- a/modules/lemur/lib/instances/Frame.lua +++ /dev/null @@ -1,5 +0,0 @@ -local GuiObject = import("./GuiObject") - -return GuiObject:extend("Frame", { - creatable = true, -}) \ No newline at end of file diff --git a/modules/lemur/lib/instances/Frame_spec.lua b/modules/lemur/lib/instances/Frame_spec.lua deleted file mode 100755 index 3aed9f9..0000000 --- a/modules/lemur/lib/instances/Frame_spec.lua +++ /dev/null @@ -1,9 +0,0 @@ -local Instance = import("../Instance") - -describe("instances.Frame", function() - it("should instantiate", function() - local instance = Instance.new("Frame") - - assert.not_nil(instance) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/Game.lua b/modules/lemur/lib/instances/Game.lua deleted file mode 100755 index fbedb7f..0000000 --- a/modules/lemur/lib/instances/Game.lua +++ /dev/null @@ -1,109 +0,0 @@ -local BaseInstance = import("./BaseInstance") - -local AnalyticsService = import("./AnalyticsService") -local ContentProvider = import("./ContentProvider") -local CoreGui = import("./CoreGui") -local CorePackages = import("./CorePackages") -local CreatorType = import("../Enum/CreatorType") -local GuiService = import("./GuiService") -local HttpService = import("./HttpService") -local InstanceProperty = import("../InstanceProperty") -local LocalizationService = import("./LocalizationService") -local NotificationService = import("./NotificationService") -local Players = import("./Players") -local ReplicatedStorage = import("./ReplicatedStorage") -local RunService = import("./RunService") -local ServerScriptService = import("./ServerScriptService") -local Stats = import("./Stats") -local TestService = import("./TestService") -local TextService = import("./TextService") -local TweenService = import("./TweenService") -local UserInputService = import("./UserInputService") -local VirtualInputManager = import("./VirtualInputManager") -local Workspace = import("./Workspace") - -local Game = BaseInstance:extend("DataModel") - -function Game:init(instance) - AnalyticsService:new().Parent = instance - ContentProvider:new().Parent = instance - CoreGui:new().Parent = instance - CorePackages:new().Parent = instance - GuiService:new().Parent = instance - HttpService:new().Parent = instance - LocalizationService:new().Parent = instance - NotificationService:new().Parent = instance - Players:new().Parent = instance - ReplicatedStorage:new().Parent = instance - RunService:new().Parent = instance - ServerScriptService:new().Parent = instance - Stats:new().Parent = instance - TestService:new().Parent = instance - TextService:new().Parent = instance - TweenService:new().Parent = instance - UserInputService:new().Parent = instance - VirtualInputManager:new().Parent = instance - Workspace:new().Parent = instance -end - -function Game.prototype:GetService(serviceName) - local service = self:FindFirstChildOfClass(serviceName) - - if service then - return service - end - - -- TODO: Load the service if possible? - - error(string.format("Cannot get service %q", tostring(serviceName)), 2) -end - -Game.properties.CreatorId = InstanceProperty.readOnly({ - getDefault = function() - return 0 - end, -}) - -Game.properties.CreatorType = InstanceProperty.readOnly({ - getDefault = function() - return CreatorType.User - end, -}) - -Game.properties.GameId = InstanceProperty.readOnly({ - getDefault = function() - return 0 - end, -}) - -Game.properties.JobId = InstanceProperty.readOnly({ - getDefault = function() - return "" - end, -}) - -Game.properties.PlaceId = InstanceProperty.readOnly({ - getDefault = function() - return 0 - end, -}) - -Game.properties.PlaceVersion = InstanceProperty.readOnly({ - getDefault = function() - return 0 - end, -}) - -Game.properties.VIPServerId = InstanceProperty.readOnly({ - getDefault = function() - return "" - end, -}) - -Game.properties.VIPServerOwnerId = InstanceProperty.readOnly({ - getDefault = function() - return 0 - end, -}) - -return Game \ No newline at end of file diff --git a/modules/lemur/lib/instances/Game_spec.lua b/modules/lemur/lib/instances/Game_spec.lua deleted file mode 100755 index 1090995..0000000 --- a/modules/lemur/lib/instances/Game_spec.lua +++ /dev/null @@ -1,42 +0,0 @@ -local Game = import("./Game") -local typeof = import("../functions/typeof") - -describe("instances.Game", function() - it("should instantiate", function() - local instance = Game:new() - - assert.not_nil(instance) - end) - - describe("GetService", function() - it("should have GetService", function() - local instance = Game:new() - - local ReplicatedStorage = instance:GetService("ReplicatedStorage") - - assert.not_nil(ReplicatedStorage) - assert.equal(instance.ReplicatedStorage, ReplicatedStorage) - end) - - it("should throw when given invalid service names", function() - local instance = Game:new() - - assert.has.errors(function() - instance:GetService("SOMETHING THAT WILL NEVER EXIST") - end) - end) - end) - - it("should have properties defined", function() - local instance = Game:new() - - assert.equal(typeof(instance.CreatorId), "number") - assert.equal(typeof(instance.CreatorType), "EnumItem") - assert.equal(typeof(instance.GameId), "number") - assert.equal(typeof(instance.JobId), "string") - assert.equal(typeof(instance.PlaceId), "number") - assert.equal(typeof(instance.PlaceVersion), "number") - assert.equal(typeof(instance.VIPServerId), "string") - assert.equal(typeof(instance.VIPServerOwnerId), "number") - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/GuiButton.lua b/modules/lemur/lib/instances/GuiButton.lua deleted file mode 100755 index b2a0a10..0000000 --- a/modules/lemur/lib/instances/GuiButton.lua +++ /dev/null @@ -1,24 +0,0 @@ -local GuiObject = import("./GuiObject") -local InstanceProperty = import("../InstanceProperty") -local Signal = import("../Signal") -local GuiButton = GuiObject:extend("GuiButton") - -GuiButton.properties.Activated = InstanceProperty.readOnly({ - getDefault = function() - return Signal.new() - end, -}) - -GuiButton.properties.AutoButtonColor = InstanceProperty.typed("boolean", { - getDefault = function() - return false - end, -}) - -GuiButton.properties.MouseButton1Click = InstanceProperty.readOnly({ - getDefault = function() - return Signal.new() - end, -}) - -return GuiButton \ No newline at end of file diff --git a/modules/lemur/lib/instances/GuiButton_spec.lua b/modules/lemur/lib/instances/GuiButton_spec.lua deleted file mode 100755 index 9367975..0000000 --- a/modules/lemur/lib/instances/GuiButton_spec.lua +++ /dev/null @@ -1,18 +0,0 @@ -local typeof = import("../functions/typeof") - -local GuiButton = import("./GuiButton") - -describe("instances.GuiButton", function() - it("should instantiate", function() - local instance = GuiButton:new() - - assert.not_nil(instance) - end) - - it("should have properties defined", function() - local instance = GuiButton:new() - assert.equal(typeof(instance.Activated), "RBXScriptSignal") - assert.equal(typeof(instance.AutoButtonColor), "boolean") - assert.equal(typeof(instance.MouseButton1Click), "RBXScriptSignal") - end) -end) diff --git a/modules/lemur/lib/instances/GuiObject.lua b/modules/lemur/lib/instances/GuiObject.lua deleted file mode 100755 index 22a9d7f..0000000 --- a/modules/lemur/lib/instances/GuiObject.lua +++ /dev/null @@ -1,134 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local Color3 = import("../types/Color3") -local InstanceProperty = import("../InstanceProperty") -local Signal = import("../Signal") -local SizeConstraint = import("../Enum/SizeConstraint") -local UDim2 = import("../types/UDim2") -local Vector2 = import("../types/Vector2") - -local GuiObject = BaseInstance:extend("GuiObject") - -GuiObject.properties.AbsolutePosition = InstanceProperty.readOnly({ - get = function(self) - if self:FindFirstAncestorOfClass("ScreenGui") == nil then - return Vector2.new() - end - - local parentAbsolutePosition = self.Parent.AbsolutePosition - local parentAbsoluteSize = self.Parent.AbsoluteSize - local position = self.Position - - return Vector2.new( - parentAbsolutePosition.X + position.X.Scale * parentAbsoluteSize.X + position.X.Offset, - parentAbsolutePosition.Y + position.Y.Scale * parentAbsoluteSize.Y + position.Y.Offset - ) - end, -}) - -GuiObject.properties.AbsoluteSize = InstanceProperty.readOnly({ - get = function(self) - if self:FindFirstAncestorOfClass("ScreenGui") == nil then - return Vector2.new() - end - - local size = self.Size - local scaleX, scaleY = 0, 0 - - if self.Parent ~= nil and (self.Parent:IsA("GuiObject") or self.Parent:IsA("ScreenGui")) then - local parentSize = self.Parent.AbsoluteSize - scaleX = parentSize.X - scaleY = parentSize.Y - end - - return Vector2.new( - scaleX * size.X.Scale + size.X.Offset, - scaleY * size.Y.Scale + size.Y.Offset - ) - end, -}) - -GuiObject.properties.Active = InstanceProperty.typed("boolean", { - getDefault = function() - return true - end, -}) - -GuiObject.properties.AnchorPoint = InstanceProperty.typed("Vector2", { - getDefault = function() - return Vector2.new() - end, -}) - -GuiObject.properties.BackgroundColor3 = InstanceProperty.typed("Color3", { - getDefault = function() - return Color3.new() - end, -}) - -GuiObject.properties.BackgroundTransparency = InstanceProperty.typed("number", { - getDefault = function() - return 0 - end, -}) - -GuiObject.properties.BorderSizePixel = InstanceProperty.typed("number", { - getDefault = function() - return 0 - end, -}) - -GuiObject.properties.ClipsDescendants = InstanceProperty.typed("boolean", { - getDefault = function() - return false - end, -}) - -GuiObject.properties.InputBegan = InstanceProperty.readOnly({ - getDefault = function() - return Signal.new() - end, -}) - -GuiObject.properties.InputEnded = InstanceProperty.readOnly({ - getDefault = function() - return Signal.new() - end, -}) - -GuiObject.properties.LayoutOrder = InstanceProperty.typed("number", { - getDefault = function() - return 0 - end, -}) - -GuiObject.properties.Position = InstanceProperty.typed("UDim2", { - getDefault = function() - return UDim2.new() - end, -}) - -GuiObject.properties.Size = InstanceProperty.typed("UDim2", { - getDefault = function() - return UDim2.new() - end, -}) - -GuiObject.properties.SizeConstraint = InstanceProperty.enum(SizeConstraint, { - getDefault = function() - return SizeConstraint.RelativeXY - end, -}) - -GuiObject.properties.Visible = InstanceProperty.typed("boolean", { - getDefault = function() - return true - end, -}) - -GuiObject.properties.ZIndex = InstanceProperty.typed("number", { - getDefault = function() - return 1 - end, -}) - -return GuiObject \ No newline at end of file diff --git a/modules/lemur/lib/instances/GuiObject_spec.lua b/modules/lemur/lib/instances/GuiObject_spec.lua deleted file mode 100755 index df3a468..0000000 --- a/modules/lemur/lib/instances/GuiObject_spec.lua +++ /dev/null @@ -1,131 +0,0 @@ -local ScreenGui = import("./ScreenGui") -local UDim2 = import("../types/UDim2") -local typeof = import("../functions/typeof") -local SizeConstraint = import("../Enum/SizeConstraint") - -local GuiObject = import("./GuiObject") - -local function extractVector2(v) - return { v.X, v.Y } -end - -describe("instances.GuiObject", function() - it("should instantiate", function() - local instance = GuiObject:new() - - assert.not_nil(instance) - end) - - it("should have properties defined", function() - local instance = GuiObject:new() - - assert.equal(typeof(instance.Active), "boolean") - assert.equal(typeof(instance.AnchorPoint), "Vector2") - assert.equal(typeof(instance.BackgroundColor3), "Color3") - assert.equal(typeof(instance.BackgroundTransparency), "number") - assert.equal(typeof(instance.BorderSizePixel), "number") - assert.equal(typeof(instance.ClipsDescendants), "boolean") - assert.equal(typeof(instance.InputBegan), "RBXScriptSignal") - assert.equal(typeof(instance.InputEnded), "RBXScriptSignal") - assert.equal(typeof(instance.LayoutOrder), "number") - assert.equal(typeof(instance.Position), "UDim2") - assert.equal(typeof(instance.Size), "UDim2") - assert.equal(typeof(instance.SizeConstraint), "EnumItem") - assert.equal(instance.SizeConstraint.EnumType, SizeConstraint) - assert.equal(typeof(instance.Visible), "boolean") - assert.equal(typeof(instance.ZIndex), "number") - end) - - describe("AbsolutePosition", function() - it("should return (0, 0) when it is not a child of ScreenGui", function() - local parent = GuiObject:new() - parent.Size = UDim2.new(0, 320, 0, 240) - - local child = GuiObject:new() - child.Size = UDim2.new(0.5, 20, 0.5, 20) - child.Parent = parent - - assert.are.same(extractVector2(parent.AbsolutePosition), {0, 0}) - assert.are.same(extractVector2(child.AbsolutePosition), {0, 0}) - end) - - it("should propagate position from a ScreenGui", function() - local screenGui = ScreenGui:new() - local screenGuiSize = screenGui.AbsoluteSize - - local parent = GuiObject:new() - parent.Parent = screenGui - parent.Position = UDim2.new(0.1, 50, 0.2, 100) - parent.Size = UDim2.new(0.5, 100, 0.1, 200) - - local parentAbsolutePosition = parent.AbsolutePosition - local parentAbsoluteSize = parent.AbsoluteSize - assert.are.same( - extractVector2(parentAbsolutePosition), - { - 0.1 * screenGuiSize.X + 50, - 0.2 * screenGuiSize.Y + 100, - } - ) - - local child = GuiObject:new() - child.Parent = parent - child.Position = UDim2.new(0.5, 0, 0.2, 10) - child.Size = UDim2.new(2, 50, 4, 10) - - local childAbsolutePosition = child.AbsolutePosition - assert.are.same( - extractVector2(childAbsolutePosition), - { - parentAbsolutePosition.X + 0.5 * parentAbsoluteSize.X, - parentAbsolutePosition.Y + 0.2 * parentAbsoluteSize.Y + 10, - } - ) - end) - end) - - describe("AbsoluteSize", function() - it("should return (0, 0) when it is not a child of ScreenGui", function() - local parent = GuiObject:new() - parent.Size = UDim2.new(0, 320, 0, 240) - - local child = GuiObject:new() - child.Size = UDim2.new(0.5, 20, 0.5, 20) - child.Parent = parent - - assert.are.same(extractVector2(parent.AbsoluteSize), {0, 0}) - assert.are.same(extractVector2(child.AbsoluteSize), {0, 0}) - end) - - it("should propagate size from a ScreenGui", function() - local screenGui = ScreenGui:new() - local screenGuiSize = screenGui.AbsoluteSize - - local parent = GuiObject:new() - parent.Parent = screenGui - parent.Size = UDim2.new(0.5, 100, 0.1, 200) - - local parentAbsoluteSize = parent.AbsoluteSize - assert.are.same( - extractVector2(parentAbsoluteSize), - { - 0.5 * screenGuiSize.X + 100, - 0.1 * screenGuiSize.Y + 200, - } - ) - - local child = GuiObject:new() - child.Parent = parent - child.Size = UDim2.new(2, 50, 4, 10) - - local childAbsoluteSize = child.AbsoluteSize - assert.are.same( - extractVector2(childAbsoluteSize), - { - 2 * parentAbsoluteSize.X + 50, - 4 * parentAbsoluteSize.Y + 10, - } - ) - end) - end) -end) diff --git a/modules/lemur/lib/instances/GuiService.lua b/modules/lemur/lib/instances/GuiService.lua deleted file mode 100755 index 31d6d1f..0000000 --- a/modules/lemur/lib/instances/GuiService.lua +++ /dev/null @@ -1,28 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local validateType = import("../validateType") - -local GuiService = BaseInstance:extend("GuiService") - -function GuiService.prototype.BroadcastNotification(data, notification) - validateType("data", data, "string") - validateType("noficiation", notification, "number") -end - -function GuiService.prototype.GetNotificationTypeList() - return { - VIEW_SUB_PAGE_IN_MORE = "VIEW_SUB_PAGE_IN_MORE", - ACTION_LOG_OUT = "ACTION_LOG_OUT", - } -end - -function GuiService.prototype.SetGlobalGuiInset(x1, y1, x2, y2) - validateType("x1", x1, "number") - validateType("y1", y1, "number") - validateType("x2", x2, "number") - validateType("y2", y2, "number") -end - -function GuiService.prototype.SafeZoneOffsetsChanged() -end - -return GuiService \ No newline at end of file diff --git a/modules/lemur/lib/instances/GuiService_spec.lua b/modules/lemur/lib/instances/GuiService_spec.lua deleted file mode 100755 index 68a79b1..0000000 --- a/modules/lemur/lib/instances/GuiService_spec.lua +++ /dev/null @@ -1,33 +0,0 @@ -local GuiService = import("./GuiService") - -describe("instances.GuiService", function() - it("should instantiate", function() - local instance = GuiService:new() - - assert.not_nil(instance) - end) - - describe("BroadcastNotification", function() - it("should exist", function() - GuiService:new().BroadcastNotification("test", 123) - end) - end) - - describe("GetNotificationTypeList", function() - it("should return a table", function() - assert.equal(type(GuiService:new().GetNotificationTypeList()), "table") - end) - end) - - describe("SetGlobalGuiInset", function() - it("should exist", function() - GuiService:new().SetGlobalGuiInset(1, 2, 3, 4) - end) - end) - - describe("SafeZoneOffsetsChanged", function() - it("should exist", function() - GuiService:new().SafeZoneOffsetsChanged() - end) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/HttpService.lua b/modules/lemur/lib/instances/HttpService.lua deleted file mode 100755 index 3601a79..0000000 --- a/modules/lemur/lib/instances/HttpService.lua +++ /dev/null @@ -1,14 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local json = import("../json") - -local HttpService = BaseInstance:extend("HttpService") - -function HttpService.prototype:JSONEncode(input) - return json.encode(input) -end - -function HttpService.prototype:JSONDecode(input) - return json.decode(input) -end - -return HttpService \ No newline at end of file diff --git a/modules/lemur/lib/instances/HttpService_spec.lua b/modules/lemur/lib/instances/HttpService_spec.lua deleted file mode 100755 index 52ce55a..0000000 --- a/modules/lemur/lib/instances/HttpService_spec.lua +++ /dev/null @@ -1,21 +0,0 @@ -local HttpService = import("./HttpService") - -describe("instances.HttpService", function() - it("should instantiate", function() - local instance = HttpService:new() - - assert.not_nil(instance) - end) - - it("should json encode properly", function() - local instance = HttpService:new() - - assert.equal(instance:JSONEncode({ 1, true }), "[1,true]") - end) - - it("should json decode properly", function() - local instance = HttpService:new() - - assert.are.same(instance:JSONDecode("[1,true]"), { 1, true }) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/ImageButton.lua b/modules/lemur/lib/instances/ImageButton.lua deleted file mode 100755 index f308672..0000000 --- a/modules/lemur/lib/instances/ImageButton.lua +++ /dev/null @@ -1,35 +0,0 @@ -local Color3 = import("../types/Color3") -local GuiButton = import("./GuiButton") -local InstanceProperty = import("../InstanceProperty") -local Rect = import("../types/Rect") -local ScaleType = import("../Enum/ScaleType") - -local ImageButton = GuiButton:extend("ImageButton", { - creatable = true, -}) - -ImageButton.properties.Image = InstanceProperty.typed("string", { - getDefault = function() - return "" - end, -}) - -ImageButton.properties.ImageColor3 = InstanceProperty.typed("Color3", { - getDefault = function() - return Color3.new() - end, -}) - -ImageButton.properties.ScaleType = InstanceProperty.enum(ScaleType, { - getDefault = function() - return ScaleType.Stretch - end, -}) - -ImageButton.properties.SliceCenter = InstanceProperty.typed("Rect", { - getDefault = function() - return Rect.new(0, 0, 1, 1) - end, -}) - -return ImageButton \ No newline at end of file diff --git a/modules/lemur/lib/instances/ImageButton_spec.lua b/modules/lemur/lib/instances/ImageButton_spec.lua deleted file mode 100755 index b739fcf..0000000 --- a/modules/lemur/lib/instances/ImageButton_spec.lua +++ /dev/null @@ -1,20 +0,0 @@ -local Instance = import("../Instance") -local typeof = import("../functions/typeof") -local ScaleType = import("../Enum/ScaleType") - -describe("instances.ImageButton", function() - it("should instantiate", function() - local instance = Instance.new("ImageButton") - - assert.not_nil(instance) - end) - - it("should have properties defined", function() - local instance = Instance.new("ImageButton") - assert.equals(typeof(instance.Image), "string") - assert.equals(typeof(instance.ImageColor3), "Color3") - assert.equals(typeof(instance.ScaleType), "EnumItem") - assert.equal(instance.ScaleType.EnumType, ScaleType) - assert.equals(typeof(instance.SliceCenter), "Rect") - end) -end) diff --git a/modules/lemur/lib/instances/ImageLabel.lua b/modules/lemur/lib/instances/ImageLabel.lua deleted file mode 100755 index 35ea578..0000000 --- a/modules/lemur/lib/instances/ImageLabel.lua +++ /dev/null @@ -1,35 +0,0 @@ -local Color3 = import("../types/Color3") -local GuiObject = import("./GuiObject") -local InstanceProperty = import("../InstanceProperty") -local Rect = import("../types/Rect") -local ScaleType = import("../Enum/ScaleType") - -local ImageLabel = GuiObject:extend("ImageLabel", { - creatable = true, -}) - -ImageLabel.properties.Image = InstanceProperty.typed("string", { - getDefault = function() - return "" - end, -}) - -ImageLabel.properties.ImageColor3 = InstanceProperty.typed("Color3", { - getDefault = function() - return Color3.new() - end, -}) - -ImageLabel.properties.ScaleType = InstanceProperty.enum(ScaleType, { - getDefault = function() - return ScaleType.Stretch - end, -}) - -ImageLabel.properties.SliceCenter = InstanceProperty.typed("Rect", { - getDefault = function() - return Rect.new(0, 0, 1, 1) - end, -}) - -return ImageLabel \ No newline at end of file diff --git a/modules/lemur/lib/instances/ImageLabel_spec.lua b/modules/lemur/lib/instances/ImageLabel_spec.lua deleted file mode 100755 index ba3d985..0000000 --- a/modules/lemur/lib/instances/ImageLabel_spec.lua +++ /dev/null @@ -1,20 +0,0 @@ -local Instance = import("../Instance") -local typeof = import("../functions/typeof") -local ScaleType = import("../Enum/ScaleType") - -describe("instances.ImageLabel", function() - it("should instantiate", function() - local instance = Instance.new("ImageLabel") - - assert.not_nil(instance) - end) - - it("should have properties defined", function() - local instance = Instance.new("ImageLabel") - assert.equals(typeof(instance.Image), "string") - assert.equals(typeof(instance.ImageColor3), "Color3") - assert.equals(typeof(instance.ScaleType), "EnumItem") - assert.equals(instance.ScaleType.EnumType, ScaleType) - assert.equals(typeof(instance.SliceCenter), "Rect") - end) -end) diff --git a/modules/lemur/lib/instances/IntValue.lua b/modules/lemur/lib/instances/IntValue.lua deleted file mode 100755 index 302842b..0000000 --- a/modules/lemur/lib/instances/IntValue.lua +++ /dev/null @@ -1,18 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local InstanceProperty = import("../InstanceProperty") - -local IntValue = BaseInstance:extend("IntValue", { - creatable = true, -}) - -IntValue.properties.Value = InstanceProperty.normal({ - getDefault = function() - return 0 - end, -}) - -function IntValue:init(instance) - instance.Name = "Value" -end - -return IntValue \ No newline at end of file diff --git a/modules/lemur/lib/instances/IntValue_spec.lua b/modules/lemur/lib/instances/IntValue_spec.lua deleted file mode 100755 index fac487f..0000000 --- a/modules/lemur/lib/instances/IntValue_spec.lua +++ /dev/null @@ -1,11 +0,0 @@ -local Instance = import("../Instance") - -describe("instances.IntValue", function() - it("should instantiate", function() - local instance = Instance.new("IntValue") - - assert.not_nil(instance) - assert.equal("Value", instance.Name) - assert.equal(0, instance.Value) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/LocalScript.lua b/modules/lemur/lib/instances/LocalScript.lua deleted file mode 100755 index 3bcd8b6..0000000 --- a/modules/lemur/lib/instances/LocalScript.lua +++ /dev/null @@ -1,18 +0,0 @@ ---[[ - Serves as just a source container right now. -]] - -local BaseInstance = import("./BaseInstance") -local InstanceProperty = import("../InstanceProperty") - -local LocalScript = BaseInstance:extend("LocalScript", { - creatable = true, -}) - -LocalScript.properties.Source = InstanceProperty.normal({ - getDefault = function() - return "" - end, -}) - -return LocalScript \ No newline at end of file diff --git a/modules/lemur/lib/instances/LocalScript_spec.lua b/modules/lemur/lib/instances/LocalScript_spec.lua deleted file mode 100755 index 074c23d..0000000 --- a/modules/lemur/lib/instances/LocalScript_spec.lua +++ /dev/null @@ -1,10 +0,0 @@ -local Instance = import("../Instance") - -describe("instances.LocalScript", function() - it("should instantiate", function() - local instance = Instance.new("LocalScript") - - assert.not_nil(instance) - assert.is.string(instance.Source) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/LocalizationService.lua b/modules/lemur/lib/instances/LocalizationService.lua deleted file mode 100755 index fef13b4..0000000 --- a/modules/lemur/lib/instances/LocalizationService.lua +++ /dev/null @@ -1,17 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local InstanceProperty = import("../InstanceProperty") -local LocalizationService = BaseInstance:extend("LocalizationService") - -LocalizationService.properties.SystemLocaleId = InstanceProperty.readOnly({ - getDefault = function() - return "en-us" - end, -}) - -LocalizationService.properties.RobloxLocaleId = InstanceProperty.readOnly({ - getDefault = function() - return "en-us" - end, -}) - -return LocalizationService \ No newline at end of file diff --git a/modules/lemur/lib/instances/LocalizationService_spec.lua b/modules/lemur/lib/instances/LocalizationService_spec.lua deleted file mode 100755 index f31f84c..0000000 --- a/modules/lemur/lib/instances/LocalizationService_spec.lua +++ /dev/null @@ -1,39 +0,0 @@ -local LocalizationService = import("./LocalizationService") - -describe("instances.LocalizationService", function() - it("should instantiate", function() - local instance = LocalizationService:new() - - assert.not_nil(instance) - end) - - describe("SystemLocaleId", function() - it("should have a string value", function() - local instance = LocalizationService:new() - assert.not_nil(instance.SystemLocaleId) - assert.equals(type(instance.SystemLocaleId), "string") - end) - - it("should be read-only", function() - local instance = LocalizationService:new() - assert.has.errors(function() - instance.SystemLocaleId = "es-mx" - end) - end) - end) - - describe("RobloxLocaleId", function() - it("should have a string value", function() - local instance = LocalizationService:new() - assert.not_nil(instance.RobloxLocaleId) - assert.equals(type(instance.RobloxLocaleId), "string") - end) - - it("should be read-only", function() - local instance = LocalizationService:new() - assert.has.errors(function() - instance.RobloxLocaleId = "es-mx" - end) - end) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/LocalizationTable.lua b/modules/lemur/lib/instances/LocalizationTable.lua deleted file mode 100755 index baf5369..0000000 --- a/modules/lemur/lib/instances/LocalizationTable.lua +++ /dev/null @@ -1,35 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local InstanceProperty = import("../InstanceProperty") -local json = import("../json") - -local LocalizationTable = BaseInstance:extend("LocalizationTable", { - creatable = true, -}) - -LocalizationTable.properties.SourceLocaleId = InstanceProperty.normal({ - getDefault = function() - return "en-us" - end, -}) - -function LocalizationTable:init(instance) - getmetatable(instance).instance.contents = {} -end - -function LocalizationTable.prototype:SetContents(contents) - getmetatable(self).instance.contents = json.decode(contents) -end - -function LocalizationTable.prototype:GetString(targetLocaleId, key) - local contents = getmetatable(self).instance.contents - - for _, entry in ipairs(contents) do - if entry.key == key then - return entry.values[targetLocaleId] - end - end - - return nil -end - -return LocalizationTable \ No newline at end of file diff --git a/modules/lemur/lib/instances/LocalizationTable_spec.lua b/modules/lemur/lib/instances/LocalizationTable_spec.lua deleted file mode 100755 index 04e7da0..0000000 --- a/modules/lemur/lib/instances/LocalizationTable_spec.lua +++ /dev/null @@ -1,47 +0,0 @@ -local Instance = import("../Instance") -local typeof = import("../functions/typeof") - -describe("instances.LocalizationTable", function() - it("should instantiate", function() - local instance = Instance.new("LocalizationTable") - - assert.not_nil(instance) - end) - - describe("SourceLocaleId", function() - it("should be a string", function() - local instance = Instance.new("LocalizationTable") - assert.equals(typeof(instance.SourceLocaleId), "string") - end) - - it("should be writeable", function() - local instance = Instance.new("LocalizationTable") - local value = "TestValue" - instance.SourceLocaleId = value - assert.equals(instance.SourceLocaleId, value) - end) - end) - - it("should translate text", function() - local instance = Instance.new("LocalizationTable") - - local translationDictionary = [[ - [ - { - "key": "TEST_STRING", - "values": { - "es-mx": "SPANISH", - "en-us": "VALUE" - } - } - ] - ]] - - instance:SetContents(translationDictionary) - - assert.equals(instance:GetString("en-us", "TEST_STRING"), "VALUE") - assert.equals(instance:GetString("es-mx", "TEST_STRING"), "SPANISH") - assert.equals(instance:GetString("language-not-defined", "TEST_STRING"), nil) - assert.equals(instance:GetString("en-us", "STRING_KEY_NOT_DEFINED"), nil) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/Model.lua b/modules/lemur/lib/instances/Model.lua deleted file mode 100755 index b31bc86..0000000 --- a/modules/lemur/lib/instances/Model.lua +++ /dev/null @@ -1,5 +0,0 @@ -local BaseInstance = import("./BaseInstance") - -return BaseInstance:extend("Model", { - creatable = true, -}) \ No newline at end of file diff --git a/modules/lemur/lib/instances/Model_spec.lua b/modules/lemur/lib/instances/Model_spec.lua deleted file mode 100755 index 1da307c..0000000 --- a/modules/lemur/lib/instances/Model_spec.lua +++ /dev/null @@ -1,9 +0,0 @@ -local Instance = import("../Instance") - -describe("instances.Model", function() - it("should instantiate", function() - local instance = Instance.new("Model") - - assert.not_nil(instance) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/ModuleScript.lua b/modules/lemur/lib/instances/ModuleScript.lua deleted file mode 100755 index db0567b..0000000 --- a/modules/lemur/lib/instances/ModuleScript.lua +++ /dev/null @@ -1,14 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local InstanceProperty = import("../InstanceProperty") - -local ModuleScript = BaseInstance:extend("ModuleScript", { - creatable = true, -}) - -ModuleScript.properties.Source = InstanceProperty.normal({ - getDefault = function() - return "" - end, -}) - -return ModuleScript \ No newline at end of file diff --git a/modules/lemur/lib/instances/ModuleScript_spec.lua b/modules/lemur/lib/instances/ModuleScript_spec.lua deleted file mode 100755 index c6e45c3..0000000 --- a/modules/lemur/lib/instances/ModuleScript_spec.lua +++ /dev/null @@ -1,10 +0,0 @@ -local Instance = import("../Instance") - -describe("instances.ModuleScript", function() - it("should instantiate", function() - local instance = Instance.new("ModuleScript") - - assert.not_nil(instance) - assert.is.string(instance.Source) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/NotificationService.lua b/modules/lemur/lib/instances/NotificationService.lua deleted file mode 100755 index 025602e..0000000 --- a/modules/lemur/lib/instances/NotificationService.lua +++ /dev/null @@ -1,5 +0,0 @@ -local BaseInstance = import("./BaseInstance") - -return BaseInstance:extend("NotificationService", { - creatable = true, -}) \ No newline at end of file diff --git a/modules/lemur/lib/instances/NotificationService_spec.lua b/modules/lemur/lib/instances/NotificationService_spec.lua deleted file mode 100755 index 87cc769..0000000 --- a/modules/lemur/lib/instances/NotificationService_spec.lua +++ /dev/null @@ -1,9 +0,0 @@ -local Instance = import("../Instance") - -describe("instances.NotificationService", function() - it("should instantiate", function() - local instance = Instance.new("NotificationService") - - assert.not_nil(instance) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/ObjectValue.lua b/modules/lemur/lib/instances/ObjectValue.lua deleted file mode 100755 index 469e04f..0000000 --- a/modules/lemur/lib/instances/ObjectValue.lua +++ /dev/null @@ -1,14 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local InstanceProperty = import("../InstanceProperty") - -local ObjectValue = BaseInstance:extend("ObjectValue", { - creatable = true, -}) - -ObjectValue.properties.Value = InstanceProperty.normal({}) - -function ObjectValue:init(instance) - instance.Name = "Value" -end - -return ObjectValue \ No newline at end of file diff --git a/modules/lemur/lib/instances/ObjectValue_spec.lua b/modules/lemur/lib/instances/ObjectValue_spec.lua deleted file mode 100755 index bb885e6..0000000 --- a/modules/lemur/lib/instances/ObjectValue_spec.lua +++ /dev/null @@ -1,19 +0,0 @@ -local Instance = import("../Instance") - -describe("instances.ObjectValue", function() - it("should instantiate", function() - local instance = Instance.new("ObjectValue") - - assert.not_nil(instance) - assert.equal("Value", instance.Name) - assert.equal(nil, instance.Value) - end) - - it("should set values", function() - local instance = Instance.new("ObjectValue") - - instance.Value = instance - - assert.equal(instance.Value, instance) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/Player.lua b/modules/lemur/lib/instances/Player.lua deleted file mode 100755 index 9dd3f60..0000000 --- a/modules/lemur/lib/instances/Player.lua +++ /dev/null @@ -1,21 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local InstanceProperty = import("../InstanceProperty") -local Player = BaseInstance:extend("Player") - -function Player:init(instance, userId) - if userId ~= nil then - if type(userId) ~= "number" then - error("userId must be an int64", 2) - end - - getmetatable(instance).instance.properties.UserId = userId - end -end - -Player.properties.UserId = InstanceProperty.readOnly({ - getDefault = function() - return 0 - end, -}) - -return Player \ No newline at end of file diff --git a/modules/lemur/lib/instances/Player_spec.lua b/modules/lemur/lib/instances/Player_spec.lua deleted file mode 100755 index 99853d5..0000000 --- a/modules/lemur/lib/instances/Player_spec.lua +++ /dev/null @@ -1,22 +0,0 @@ -local Player = import("./Player") - -describe("instances.Player", function() - it("should instantiate", function() - local instance = Player:new() - - assert.not_nil(instance) - assert.equals(instance.UserId, 0) - end) - - it("should take a userId", function() - local instance = Player:new(1234) - - assert.equals(instance.UserId, 1234) - end) - - it("should throw when userId is not a number", function() - assert.has.errors(function() - Player:new("1234") - end) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/Players.lua b/modules/lemur/lib/instances/Players.lua deleted file mode 100755 index 723d4c6..0000000 --- a/modules/lemur/lib/instances/Players.lua +++ /dev/null @@ -1,13 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local InstanceProperty = import("../InstanceProperty") -local Player = import("./Player") - -local Players = BaseInstance:extend("Players") - -Players.properties.LocalPlayer = InstanceProperty.normal({ - getDefault = function() - return Player:new() - end, -}) - -return Players \ No newline at end of file diff --git a/modules/lemur/lib/instances/Players_spec.lua b/modules/lemur/lib/instances/Players_spec.lua deleted file mode 100755 index 7925345..0000000 --- a/modules/lemur/lib/instances/Players_spec.lua +++ /dev/null @@ -1,17 +0,0 @@ -local typeof = import("../functions/typeof") - -local Players = import("./Players") - -describe("instances.Players", function() - it("should instantiate", function() - local instance = Players:new() - - assert.not_nil(instance) - end) - - it("should have properties defined", function() - local instance = Players:new() - - assert.equal(typeof(instance.LocalPlayer), "Instance") - end) -end) diff --git a/modules/lemur/lib/instances/ReplicatedStorage.lua b/modules/lemur/lib/instances/ReplicatedStorage.lua deleted file mode 100755 index 96040d5..0000000 --- a/modules/lemur/lib/instances/ReplicatedStorage.lua +++ /dev/null @@ -1,3 +0,0 @@ -local BaseInstance = import("./BaseInstance") - -return BaseInstance:extend("ReplicatedStorage") \ No newline at end of file diff --git a/modules/lemur/lib/instances/ReplicatedStorage_spec.lua b/modules/lemur/lib/instances/ReplicatedStorage_spec.lua deleted file mode 100755 index 4be4ec8..0000000 --- a/modules/lemur/lib/instances/ReplicatedStorage_spec.lua +++ /dev/null @@ -1,9 +0,0 @@ -local ReplicatedStorage = import("./ReplicatedStorage") - -describe("instances.ReplicatedStorage", function() - it("should instantiate", function() - local instance = ReplicatedStorage:new() - - assert.not_nil(instance) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/RunService.lua b/modules/lemur/lib/instances/RunService.lua deleted file mode 100755 index f1e0423..0000000 --- a/modules/lemur/lib/instances/RunService.lua +++ /dev/null @@ -1,23 +0,0 @@ -local Signal = import("../Signal") -local BaseInstance = import("./BaseInstance") -local InstanceProperty = import("../InstanceProperty") - -local RunService = BaseInstance:extend("RunService") - -function RunService:init(instance) - instance.Name = "Run Service" -end - -RunService.properties.Heartbeat = InstanceProperty.readOnly({ - getDefault = Signal.new, -}) - -RunService.prototype.IsStudio = function() - return false -end - -RunService.properties.RenderStepped = InstanceProperty.readOnly({ - getDefault = Signal.new, -}) - -return RunService diff --git a/modules/lemur/lib/instances/RunService_spec.lua b/modules/lemur/lib/instances/RunService_spec.lua deleted file mode 100755 index e10dfea..0000000 --- a/modules/lemur/lib/instances/RunService_spec.lua +++ /dev/null @@ -1,28 +0,0 @@ -local RunService = import("./RunService") -local Signal = import("../Signal") - -describe("instances.RunService", function() - it("should instantiate", function() - local instance = RunService:new() - - assert.not_nil(instance) - assert.not_nil(instance.Heartbeat) - end) - - it("should have the name 'Run Service'", function() - local instance = RunService:new() - assert.is_equal(instance.Name, "Run Service") - end) - - it("should return false when IsStudio() is called", function() - local instance = RunService:new() - assert.is_equal(instance.IsStudio(), false) - end) - - it("should have properties defined", function() - local instance = RunService:new() - - assert.equals(instance.Heartbeat.__index, Signal) - assert.equals(instance.RenderStepped.__index, Signal) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/ScreenGui.lua b/modules/lemur/lib/instances/ScreenGui.lua deleted file mode 100755 index 9e56e7d..0000000 --- a/modules/lemur/lib/instances/ScreenGui.lua +++ /dev/null @@ -1,42 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local InstanceProperty = import("../InstanceProperty") -local Vector2 = import("../types/Vector2") -local ZIndexBehavior = import("../Enum/ZIndexBehavior") - -local ScreenGui = BaseInstance:extend("ScreenGui", { - creatable = true, -}) - -ScreenGui.properties.AbsolutePosition = InstanceProperty.readOnly({ - get = function(self) - return Vector2.new(0, 0) - end, -}) - -ScreenGui.properties.AbsoluteSize = InstanceProperty.readOnly({ - get = function(self) - return Vector2.new(800, 600) - end, -}) - -ScreenGui.properties.DisplayOrder = InstanceProperty.normal({ - set = function(self, key, value) - if type(value) ~= "number" then - error(string.format("%s must be a number", key), 2) - end - - getmetatable(self).instance.properties[key] = value - end, - - getDefault = function() - return 0 - end, -}) - -ScreenGui.properties.ZIndexBehavior = InstanceProperty.enum(ZIndexBehavior, { - getDefault = function() - return ZIndexBehavior.Global - end, -}) - -return ScreenGui \ No newline at end of file diff --git a/modules/lemur/lib/instances/ScreenGui_spec.lua b/modules/lemur/lib/instances/ScreenGui_spec.lua deleted file mode 100755 index 953bfb4..0000000 --- a/modules/lemur/lib/instances/ScreenGui_spec.lua +++ /dev/null @@ -1,45 +0,0 @@ -local Instance = import("../Instance") -local typeof = import("../functions/typeof") -local ZIndexBehavior = import("../Enum/ZIndexBehavior") - -describe("instances.ScreenGui", function() - it("should instantiate", function() - local instance = Instance.new("ScreenGui") - - assert.not_nil(instance) - end) - - it("should have properties defined", function() - local instance = Instance.new("ScreenGui") - assert.equals(typeof(instance.AbsolutePosition), "Vector2") - assert.equals(typeof(instance.ZIndexBehavior), "EnumItem") - assert.equals(instance.ZIndexBehavior.EnumType, ZIndexBehavior) - end) - - describe("DisplayOrder", function() - it("should have a value that is a number", function() - local instance = Instance.new("ScreenGui") - assert.equals(type(instance.DisplayOrder), "number") - end) - - it("should be settable", function() - local instance = Instance.new("ScreenGui") - instance.DisplayOrder = 2 - assert.equals(instance.DisplayOrder, 2) - end) - - it("should only accept numbers", function() - local instance = Instance.new("ScreenGui") - assert.has.errors(function() - instance.DisplayOrder = "string" - end) - end) - end) - - describe("AbsoluteSize", function() - it("should return a Vector2", function() - local instance = Instance.new("ScreenGui") - assert.equals(typeof(instance.AbsoluteSize), "Vector2") - end) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/Script.lua b/modules/lemur/lib/instances/Script.lua deleted file mode 100755 index 23c8054..0000000 --- a/modules/lemur/lib/instances/Script.lua +++ /dev/null @@ -1,18 +0,0 @@ ---[[ - Serves as just a source container right now. -]] - -local BaseInstance = import("./BaseInstance") -local InstanceProperty = import("../InstanceProperty") - -local Script = BaseInstance:extend("Script", { - creatable = true, -}) - -Script.properties.Source = InstanceProperty.normal({ - getDefault = function() - return "" - end, -}) - -return Script \ No newline at end of file diff --git a/modules/lemur/lib/instances/Script_spec.lua b/modules/lemur/lib/instances/Script_spec.lua deleted file mode 100755 index 875f4e2..0000000 --- a/modules/lemur/lib/instances/Script_spec.lua +++ /dev/null @@ -1,10 +0,0 @@ -local Instance = import("../Instance") - -describe("instances.Script", function() - it("should instantiate", function() - local instance = Instance.new("Script") - - assert.not_nil(instance) - assert.is.string(instance.Source) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/ScrollingFrame.lua b/modules/lemur/lib/instances/ScrollingFrame.lua deleted file mode 100755 index 0559387..0000000 --- a/modules/lemur/lib/instances/ScrollingFrame.lua +++ /dev/null @@ -1,72 +0,0 @@ -local ScrollingDirection = import("../Enum/ScrollingDirection") -local GuiObject = import("./GuiObject") -local InstanceProperty = import("../InstanceProperty") -local UDim2 = import("../types/UDim2") -local Vector2 = import("../types/Vector2") - -local ScrollingFrame = GuiObject:extend("ScrollingFrame", { - creatable = true, -}) - -ScrollingFrame.properties.AbsoluteWindowSize = InstanceProperty.readOnly({ - get = function(self) - local size = self.AbsoluteSize - - local thickness = self.ScrollBarThickness - local marginX = 0 - local marginY = 0 - - if self:_canScrollHorizontal() then - marginX = thickness - end - - if self:_canScrollVertical() then - marginY = thickness - end - - return Vector2.new( - math.max(0, size.X - marginX), - math.max(0, size.Y - marginY) - ) - end, -}) - -ScrollingFrame.properties.CanvasSize = InstanceProperty.typed("UDim2", { - getDefault = function() - return UDim2.new() - end, -}) - -ScrollingFrame.properties.ScrollBarThickness = InstanceProperty.typed("number", { - getDefault = function() - return 12 - end, -}) - -ScrollingFrame.properties.ScrollingDirection = InstanceProperty.enum(ScrollingDirection, { - getDefault = function() - return ScrollingDirection.XY - end, -}) - -ScrollingFrame.properties.ScrollingEnabled = InstanceProperty.typed("boolean", { - getDefault = function() - return true - end, -}) - -function ScrollingFrame.prototype:_canScrollHorizontal() - local scrollDir = self.ScrollingDirection - return self.ScrollingEnabled and - (scrollDir == ScrollingDirection.X or - scrollDir == ScrollingDirection.XY) -end - -function ScrollingFrame.prototype:_canScrollVertical() - local scrollDir = self.ScrollingDirection - return self.ScrollingEnabled and - (scrollDir == ScrollingDirection.Y or - scrollDir == ScrollingDirection.XY) -end - -return ScrollingFrame \ No newline at end of file diff --git a/modules/lemur/lib/instances/ScrollingFrame_spec.lua b/modules/lemur/lib/instances/ScrollingFrame_spec.lua deleted file mode 100755 index ca92f1b..0000000 --- a/modules/lemur/lib/instances/ScrollingFrame_spec.lua +++ /dev/null @@ -1,68 +0,0 @@ -local Instance = import("../Instance") -local ScrollingDirection = import("../Enum/ScrollingDirection") -local typeof = import("../functions/typeof") -local UDim2 = import("../types/UDim2") - -local function extractVector2(vector2) - return { vector2.X, vector2.Y } -end - -describe("instances.ScrollingFrame", function() - it("should instantiate", function() - local instance = Instance.new("ScrollingFrame") - assert.not_nil(instance) - end) - - it("should have properties defined", function() - local instance = Instance.new("ScrollingFrame") - - assert.equal(typeof(instance.CanvasSize), "UDim2") - assert.equal(typeof(instance.ScrollBarThickness), "number") - assert.equal(typeof(instance.ScrollingDirection), "EnumItem") - assert.equal(instance.ScrollingDirection.EnumType, ScrollingDirection) - assert.equal(typeof(instance.ScrollingEnabled), "boolean") - end) - - describe("AbsoluteWindowSize", function() - it("it should be affected by scrolling", function() - local screenGui = Instance.new("ScreenGui") - local screenGuiSize = screenGui.AbsoluteSize - - local instance = Instance.new("ScrollingFrame", screenGui) - instance.Size = UDim2.new(1, 0, 1, 0) - - instance.ScrollingEnabled = false - assert.same(extractVector2(screenGuiSize), extractVector2(instance.AbsoluteWindowSize)) - - instance.ScrollingEnabled = true - instance.ScrollingDirection = ScrollingDirection.XY - assert.same( - { - screenGuiSize.X - instance.ScrollBarThickness, - screenGuiSize.Y - instance.ScrollBarThickness, - }, - extractVector2(instance.AbsoluteWindowSize) - ) - - instance.ScrollingDirection = ScrollingDirection.X - instance.ScrollingEnabled = true - assert.same( - { - screenGuiSize.X - instance.ScrollBarThickness, - screenGuiSize.Y, - }, - extractVector2(instance.AbsoluteWindowSize) - ) - - instance.ScrollingDirection = ScrollingDirection.Y - instance.ScrollingEnabled = true - assert.same( - { - screenGuiSize.X, - screenGuiSize.Y - instance.ScrollBarThickness, - }, - extractVector2(instance.AbsoluteWindowSize) - ) - end) - end) -end) diff --git a/modules/lemur/lib/instances/ServerScriptService.lua b/modules/lemur/lib/instances/ServerScriptService.lua deleted file mode 100755 index b04f17b..0000000 --- a/modules/lemur/lib/instances/ServerScriptService.lua +++ /dev/null @@ -1,4 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local ServerScriptService = BaseInstance:extend("ServerScriptService") - -return ServerScriptService \ No newline at end of file diff --git a/modules/lemur/lib/instances/ServerScriptService_spec.lua b/modules/lemur/lib/instances/ServerScriptService_spec.lua deleted file mode 100755 index be8450f..0000000 --- a/modules/lemur/lib/instances/ServerScriptService_spec.lua +++ /dev/null @@ -1,9 +0,0 @@ -local ServerScriptService = import("./ServerScriptService") - -describe("instances.ServerScriptService", function() - it("should instantiate", function() - local instance = ServerScriptService:new() - - assert.not_nil(instance) - end) -end) diff --git a/modules/lemur/lib/instances/Stats.lua b/modules/lemur/lib/instances/Stats.lua deleted file mode 100755 index e731416..0000000 --- a/modules/lemur/lib/instances/Stats.lua +++ /dev/null @@ -1,4 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local Stats = BaseInstance:extend("Stats") - -return Stats \ No newline at end of file diff --git a/modules/lemur/lib/instances/Stats_spec.lua b/modules/lemur/lib/instances/Stats_spec.lua deleted file mode 100755 index c1dec39..0000000 --- a/modules/lemur/lib/instances/Stats_spec.lua +++ /dev/null @@ -1,9 +0,0 @@ -local Stats = import("./Stats") - -describe("instances.Stats", function() - it("should instantiate", function() - local instance = Stats:new() - - assert.not_nil(instance) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/StringValue.lua b/modules/lemur/lib/instances/StringValue.lua deleted file mode 100755 index 304f752..0000000 --- a/modules/lemur/lib/instances/StringValue.lua +++ /dev/null @@ -1,18 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local InstanceProperty = import("../InstanceProperty") - -local StringValue = BaseInstance:extend("StringValue", { - creatable = true, -}) - -StringValue.properties.Value = InstanceProperty.normal({ - getDefault = function() - return "" - end, -}) - -function StringValue:init(instance) - instance.Name = "Value" -end - -return StringValue \ No newline at end of file diff --git a/modules/lemur/lib/instances/StringValue_spec.lua b/modules/lemur/lib/instances/StringValue_spec.lua deleted file mode 100755 index 52cd16d..0000000 --- a/modules/lemur/lib/instances/StringValue_spec.lua +++ /dev/null @@ -1,11 +0,0 @@ -local Instance = import("../Instance") - -describe("instances.StringValue", function() - it("should instantiate", function() - local instance = Instance.new("StringValue") - - assert.not_nil(instance) - assert.equal("Value", instance.Name) - assert.equal("", instance.Value) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/TestService.lua b/modules/lemur/lib/instances/TestService.lua deleted file mode 100755 index 6c97381..0000000 --- a/modules/lemur/lib/instances/TestService.lua +++ /dev/null @@ -1,10 +0,0 @@ -local BaseInstance = import("./BaseInstance") - -local TestService = BaseInstance:extend("TestService") - -function TestService.prototype:Error(message) - io.stderr:write(message) - io.stderr:write("\n") -end - -return TestService \ No newline at end of file diff --git a/modules/lemur/lib/instances/TestService_spec.lua b/modules/lemur/lib/instances/TestService_spec.lua deleted file mode 100755 index c325574..0000000 --- a/modules/lemur/lib/instances/TestService_spec.lua +++ /dev/null @@ -1,27 +0,0 @@ -local TestService = import("./TestService") - -describe("instances.TestService", function() - it("should instantiate", function() - local instance = TestService:new() - - assert.not_nil(instance) - assert.not_nil(instance.Error) - end) - - it("should write to stderr", function() - local instance = TestService:new() - local oldErr = io.stderr - - local writeSpy = spy.new(function(_, msg) end) - - io.stderr = { -- luacheck: ignore - write = writeSpy - } - - instance:Error("Testing tests in a library for testing?") - - assert.spy(writeSpy).was_called_with(io.stderr, "Testing tests in a library for testing?") - - io.stderr = oldErr -- luacheck: ignore - end) -end) diff --git a/modules/lemur/lib/instances/TextButton.lua b/modules/lemur/lib/instances/TextButton.lua deleted file mode 100755 index ddc3a33..0000000 --- a/modules/lemur/lib/instances/TextButton.lua +++ /dev/null @@ -1,54 +0,0 @@ -local Color3 = import("../types/Color3") -local Font = import("../Enum/Font") -local GuiButton = import("./GuiButton") -local InstanceProperty = import("../InstanceProperty") -local TextXAlignment = import("../Enum/TextXAlignment") -local TextYAlignment = import("../Enum/TextYAlignment") - -local TextButton = GuiButton:extend("TextButton", { - creatable = true, -}) - -TextButton.properties.Font = InstanceProperty.enum(Font, { - getDefault = function() - return Font.Legacy - end, -}) - -TextButton.properties.Text = InstanceProperty.typed("string", { - getDefault = function() - return "Button" - end, -}) - -TextButton.properties.TextColor3 = InstanceProperty.typed("Color3", { - getDefault = function() - return Color3.new(27, 42, 53) - end, -}) - -TextButton.properties.TextSize = InstanceProperty.typed("number", { - getDefault = function() - return 14 - end, -}) - -TextButton.properties.TextWrapped = InstanceProperty.typed("boolean", { - getDefault = function() - return false - end, -}) - -TextButton.properties.TextXAlignment = InstanceProperty.enum(TextXAlignment, { - getDefault = function() - return TextXAlignment.Left - end, -}) - -TextButton.properties.TextYAlignment = InstanceProperty.enum(TextYAlignment, { - getDefault = function() - return TextYAlignment.Top - end, -}) - -return TextButton diff --git a/modules/lemur/lib/instances/TextButton_spec.lua b/modules/lemur/lib/instances/TextButton_spec.lua deleted file mode 100755 index 92673d7..0000000 --- a/modules/lemur/lib/instances/TextButton_spec.lua +++ /dev/null @@ -1,27 +0,0 @@ -local Font = import("../Enum/Font") -local Instance = import("../Instance") -local TextXAlignment = import("../Enum/TextXAlignment") -local TextYAlignment = import("../Enum/TextYAlignment") -local typeof = import("../functions/typeof") - -describe("instances.TextButton", function() - it("should instantiate", function() - local instance = Instance.new("TextButton") - - assert.not_nil(instance) - end) - - it("should have properties defined", function() - local instance = Instance.new("TextButton") - assert.equal(typeof(instance.Font), "EnumItem") - assert.equal(instance.Font.EnumType, Font) - assert.equal(typeof(instance.Text), "string") - assert.equal(typeof(instance.TextColor3), "Color3") - assert.equal(typeof(instance.TextSize), "number") - assert.equal(typeof(instance.TextWrapped), "boolean") - assert.equal(typeof(instance.TextXAlignment), "EnumItem") - assert.equal(instance.TextXAlignment.EnumType, TextXAlignment) - assert.equal(typeof(instance.TextYAlignment), "EnumItem") - assert.equal(instance.TextYAlignment.EnumType, TextYAlignment) - end) -end) diff --git a/modules/lemur/lib/instances/TextLabel.lua b/modules/lemur/lib/instances/TextLabel.lua deleted file mode 100755 index 0f4a464..0000000 --- a/modules/lemur/lib/instances/TextLabel.lua +++ /dev/null @@ -1,54 +0,0 @@ -local Color3 = import("../types/Color3") -local Font = import("../Enum/Font") -local GuiObject = import("./GuiObject") -local InstanceProperty = import("../InstanceProperty") -local TextXAlignment = import("../Enum/TextXAlignment") -local TextYAlignment = import("../Enum/TextYAlignment") - -local TextLabel = GuiObject:extend("TextLabel", { - creatable = true, -}) - -TextLabel.properties.Font = InstanceProperty.enum(Font, { - getDefault = function() - return Font.Legacy - end, -}) - -TextLabel.properties.Text = InstanceProperty.typed("string", { - getDefault = function() - return "Label" - end, -}) - -TextLabel.properties.TextColor3 = InstanceProperty.typed("Color3", { - getDefault = function() - return Color3.new(27, 42, 53) - end, -}) - -TextLabel.properties.TextSize = InstanceProperty.typed("number", { - getDefault = function() - return 14 - end, -}) - -TextLabel.properties.TextWrapped = InstanceProperty.typed("boolean", { - getDefault = function() - return false - end, -}) - -TextLabel.properties.TextXAlignment = InstanceProperty.enum(TextXAlignment, { - getDefault = function() - return TextXAlignment.Left - end, -}) - -TextLabel.properties.TextYAlignment = InstanceProperty.enum(TextYAlignment, { - getDefault = function() - return TextYAlignment.Top - end, -}) - -return TextLabel diff --git a/modules/lemur/lib/instances/TextLabel_spec.lua b/modules/lemur/lib/instances/TextLabel_spec.lua deleted file mode 100755 index 6b88c15..0000000 --- a/modules/lemur/lib/instances/TextLabel_spec.lua +++ /dev/null @@ -1,27 +0,0 @@ -local Font = import("../Enum/Font") -local Instance = import("../Instance") -local TextXAlignment = import("../Enum/TextXAlignment") -local TextYAlignment = import("../Enum/TextYAlignment") -local typeof = import("../functions/typeof") - -describe("instances.TextLabel", function() - it("should instantiate", function() - local instance = Instance.new("TextLabel") - - assert.not_nil(instance) - end) - - it("should have properties defined", function() - local instance = Instance.new("TextLabel") - assert.equal(typeof(instance.Font), "EnumItem") - assert.equal(instance.Font.EnumType, Font) - assert.equal(typeof(instance.Text), "string") - assert.equal(typeof(instance.TextColor3), "Color3") - assert.equal(typeof(instance.TextSize), "number") - assert.equal(typeof(instance.TextWrapped), "boolean") - assert.equal(typeof(instance.TextXAlignment), "EnumItem") - assert.equal(instance.TextXAlignment.EnumType, TextXAlignment) - assert.equal(typeof(instance.TextYAlignment), "EnumItem") - assert.equal(instance.TextYAlignment.EnumType, TextYAlignment) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/TextService.lua b/modules/lemur/lib/instances/TextService.lua deleted file mode 100755 index 4299e3d..0000000 --- a/modules/lemur/lib/instances/TextService.lua +++ /dev/null @@ -1,25 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local Font = import("../Enum/Font") -local typeof = import("../functions/typeof") -local Vector2 = import("../types/Vector2") - -local TextService = BaseInstance:extend("TextService") - --- right now this is just a lazy [fontSize * len(text), fontSize] clipped by frameSize -function TextService.prototype:GetTextSize(text, fontSize, font, frameSize) - if typeof(text) ~= "string" then - error("text must be a string", 2) - elseif typeof(fontSize) ~= "number" then - error("fontSize must be a number", 2) - elseif typeof(font) ~= "EnumItem" and font.EnumType ~= Font then - error("font must be an Enum.Font", 2) - elseif typeof(frameSize) ~= "Vector2" then - error("frameSize must be a Vector2", 2) - end - - local width = text:len() * fontSize - - return Vector2.new(math.min(width, frameSize.X), math.min(fontSize, frameSize.Y)) -end - -return TextService \ No newline at end of file diff --git a/modules/lemur/lib/instances/TextService_spec.lua b/modules/lemur/lib/instances/TextService_spec.lua deleted file mode 100755 index 86549e3..0000000 --- a/modules/lemur/lib/instances/TextService_spec.lua +++ /dev/null @@ -1,46 +0,0 @@ -local Font = import("../Enum/Font") -local Vector2 = import("../types/Vector2") -local typeof = import("../functions/typeof") - -local TextService = import("./TextService") - -describe("instances.TextService", function() - it("should instantiate", function() - local instance = TextService:new() - - assert.not_nil(instance) - end) - - describe("GetTextSize", function() - it("should verify parameters", function() - local instance = TextService:new() - - assert.has.errors(function() - instance:GetTextSize(100, 36, Font.Legacy, Vector2.new(1, 1)) - end) - assert.has.errors(function() - instance:GetTextSize("text", "str", Font.Legacy, Vector2.new(1, 1)) - end) - assert.has.errors(function() - instance:GetTextSize("text", 36, "hey", Vector2.new(1, 1)) - end) - assert.has.errors(function() - instance:GetTextSize("text", 36, Font.Legacy, 100) - end) - end) - - it("should return a Vector2", function() - local instance = TextService:new() - local result = instance:GetTextSize("text", 36, Font.Legacy, Vector2.new(1000, 1000)) - - assert.equals(typeof(result), "Vector2") - end) - - it("should clip the rect down", function() - local instance = TextService:new() - local result = instance:GetTextSize("VERY LARGE TEXT", 36, Font.Legacy, Vector2.new(1, 1)) - - assert.same({result.X, result.Y}, {1, 1}) - end) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/TweenService.lua b/modules/lemur/lib/instances/TweenService.lua deleted file mode 100755 index 0f2cc80..0000000 --- a/modules/lemur/lib/instances/TweenService.lua +++ /dev/null @@ -1,3 +0,0 @@ -local BaseInstance = import("./BaseInstance") - -return BaseInstance:extend("TweenService") \ No newline at end of file diff --git a/modules/lemur/lib/instances/TweenService_spec.lua b/modules/lemur/lib/instances/TweenService_spec.lua deleted file mode 100755 index 5d7c853..0000000 --- a/modules/lemur/lib/instances/TweenService_spec.lua +++ /dev/null @@ -1,9 +0,0 @@ -local TweenService = import("./TweenService") - -describe("instances.TweenService", function() - it("should instantiate", function() - local instance = TweenService:new() - - assert.not_nil(instance) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/UIGridStyleLayout.lua b/modules/lemur/lib/instances/UIGridStyleLayout.lua deleted file mode 100755 index 741dc80..0000000 --- a/modules/lemur/lib/instances/UIGridStyleLayout.lua +++ /dev/null @@ -1,34 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local FillDirection = import("../Enum/FillDirection") -local HorizontalAlignment = import("../Enum/HorizontalAlignment") -local InstanceProperty = import("../InstanceProperty") -local SortOrder = import("../Enum/SortOrder") -local VerticalAlignment = import("../Enum/VerticalAlignment") - -local UIGridStyleLayout = BaseInstance:extend("UIGridStyleLayout") - -UIGridStyleLayout.properties.FillDirection = InstanceProperty.enum(FillDirection, { - getDefault = function() - return FillDirection.Horizontal - end, -}) - -UIGridStyleLayout.properties.HorizontalAlignment = InstanceProperty.enum(HorizontalAlignment, { - getDefault = function() - return HorizontalAlignment.Center - end, -}) - -UIGridStyleLayout.properties.SortOrder = InstanceProperty.enum(SortOrder, { - getDefault = function() - return SortOrder.Name - end, -}) - -UIGridStyleLayout.properties.VerticalAlignment = InstanceProperty.enum(VerticalAlignment, { - getDefault = function() - return VerticalAlignment.Center - end, -}) - -return UIGridStyleLayout \ No newline at end of file diff --git a/modules/lemur/lib/instances/UIGridStyleLayout_spec.lua b/modules/lemur/lib/instances/UIGridStyleLayout_spec.lua deleted file mode 100755 index f6b48d5..0000000 --- a/modules/lemur/lib/instances/UIGridStyleLayout_spec.lua +++ /dev/null @@ -1,28 +0,0 @@ -local FillDirection = import("../Enum/FillDirection") -local HorizontalAlignment = import("../Enum/HorizontalAlignment") -local SortOrder = import("../Enum/SortOrder") -local typeof = import("../functions/typeof") -local VerticalAlignment = import("../Enum/VerticalAlignment") - -local UIGridStyleLayout = import("./UIGridStyleLayout") - -describe("instances.UIGridStyleLayout", function() - it("should instantiate", function() - local instance = UIGridStyleLayout:new() - - assert.not_nil(instance) - end) - - it("should have properties defined", function() - local instance = UIGridStyleLayout:new() - - assert.equals(typeof(instance.FillDirection), "EnumItem") - assert.equals(instance.FillDirection.EnumType, FillDirection) - assert.equals(typeof(instance.HorizontalAlignment), "EnumItem") - assert.equals(instance.HorizontalAlignment.EnumType, HorizontalAlignment) - assert.equals(typeof(instance.SortOrder), "EnumItem") - assert.equals(instance.SortOrder.EnumType, SortOrder) - assert.equals(typeof(instance.VerticalAlignment), "EnumItem") - assert.equal(instance.VerticalAlignment.EnumType, VerticalAlignment) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/UIListLayout.lua b/modules/lemur/lib/instances/UIListLayout.lua deleted file mode 100755 index 1561ca8..0000000 --- a/modules/lemur/lib/instances/UIListLayout.lua +++ /dev/null @@ -1,15 +0,0 @@ -local UIGridStyleLayout = import("./UIGridStyleLayout") -local InstanceProperty = import("../InstanceProperty") -local UDim = import("../types/UDim") - -local UIListLayout = UIGridStyleLayout:extend("UIListLayout", { - creatable = true, -}) - -UIListLayout.properties.Padding = InstanceProperty.typed("UDim", { - getDefault = function() - return UDim.new() - end, -}) - -return UIListLayout \ No newline at end of file diff --git a/modules/lemur/lib/instances/UIListLayout_spec.lua b/modules/lemur/lib/instances/UIListLayout_spec.lua deleted file mode 100755 index ddee74d..0000000 --- a/modules/lemur/lib/instances/UIListLayout_spec.lua +++ /dev/null @@ -1,22 +0,0 @@ -local Instance = import("../Instance") -local typeof = import("../functions/typeof") - -describe("instances.UIListLayout", function() - it("should instantiate", function() - local instance = Instance.new("UIListLayout") - - assert.not_nil(instance) - end) - - it("should inherit from UIGridStyleLayout", function() - local instance = Instance.new("UIListLayout") - - assert.True(instance:IsA("UIGridStyleLayout")) - end) - - it("should have properties defined", function() - local instance = Instance.new("UIListLayout") - - assert.equals(typeof(instance.Padding), "UDim") - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/UIPadding.lua b/modules/lemur/lib/instances/UIPadding.lua deleted file mode 100755 index eb31fff..0000000 --- a/modules/lemur/lib/instances/UIPadding.lua +++ /dev/null @@ -1,33 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local InstanceProperty = import("../InstanceProperty") -local UDim = import("../types/UDim") - -local UIPadding = BaseInstance:extend("UIPadding", { - creatable = true, -}) - -UIPadding.properties.PaddingBottom = InstanceProperty.typed("UDim", { - getDefault = function() - return UDim.new() - end, -}) - -UIPadding.properties.PaddingLeft = InstanceProperty.typed("UDim", { - getDefault = function() - return UDim.new() - end, -}) - -UIPadding.properties.PaddingRight = InstanceProperty.typed("UDim", { - getDefault = function() - return UDim.new() - end, -}) - -UIPadding.properties.PaddingTop = InstanceProperty.typed("UDim", { - getDefault = function() - return UDim.new() - end, -}) - -return UIPadding \ No newline at end of file diff --git a/modules/lemur/lib/instances/UIPadding_spec.lua b/modules/lemur/lib/instances/UIPadding_spec.lua deleted file mode 100755 index 2c79db2..0000000 --- a/modules/lemur/lib/instances/UIPadding_spec.lua +++ /dev/null @@ -1,18 +0,0 @@ -local Instance = import("../Instance") -local typeof = import("../functions/typeof") - -describe("instances.UIPadding", function() - it("should instantiate", function() - local instance = Instance.new("UIPadding") - - assert.not_nil(instance) - end) - - it("should have properties defined", function() - local instance = Instance.new("UIPadding") - assert.equal(typeof(instance.PaddingBottom), "UDim") - assert.equal(typeof(instance.PaddingLeft), "UDim") - assert.equal(typeof(instance.PaddingRight), "UDim") - assert.equal(typeof(instance.PaddingTop), "UDim") - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/UserInputService.lua b/modules/lemur/lib/instances/UserInputService.lua deleted file mode 100755 index 74beaac..0000000 --- a/modules/lemur/lib/instances/UserInputService.lua +++ /dev/null @@ -1,3 +0,0 @@ -local BaseInstance = import("./BaseInstance") - -return BaseInstance:extend("UserInputService") \ No newline at end of file diff --git a/modules/lemur/lib/instances/UserInputService_spec.lua b/modules/lemur/lib/instances/UserInputService_spec.lua deleted file mode 100755 index 418ffa3..0000000 --- a/modules/lemur/lib/instances/UserInputService_spec.lua +++ /dev/null @@ -1,9 +0,0 @@ -local UserInputService = import("./UserInputService") - -describe("instances.UserInputService", function() - it("should instantiate", function() - local instance = UserInputService:new() - - assert.not_nil(instance) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/VirtualInputManager.lua b/modules/lemur/lib/instances/VirtualInputManager.lua deleted file mode 100755 index e47cf0f..0000000 --- a/modules/lemur/lib/instances/VirtualInputManager.lua +++ /dev/null @@ -1,3 +0,0 @@ -local BaseInstance = import("./BaseInstance") - -return BaseInstance:extend("VirtualInputManager") \ No newline at end of file diff --git a/modules/lemur/lib/instances/VirtualInputManager_spec.lua b/modules/lemur/lib/instances/VirtualInputManager_spec.lua deleted file mode 100755 index 746ad6c..0000000 --- a/modules/lemur/lib/instances/VirtualInputManager_spec.lua +++ /dev/null @@ -1,9 +0,0 @@ -local VirtualInputManager = import("./VirtualInputManager") - -describe("instances.VirtualInputManager", function() - it("should instantiate", function() - local instance = VirtualInputManager:new() - - assert.not_nil(instance) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/Workspace.lua b/modules/lemur/lib/instances/Workspace.lua deleted file mode 100755 index bfc5fc8..0000000 --- a/modules/lemur/lib/instances/Workspace.lua +++ /dev/null @@ -1,16 +0,0 @@ -local BaseInstance = import("./BaseInstance") -local Camera = import("./Camera") -local InstanceProperty = import("../InstanceProperty") - -local Workspace = BaseInstance:extend("Workspace") - -function Workspace:init(instance) - local camera = Camera:new() - camera.Name = "Camera" - camera.Parent = instance - instance.CurrentCamera = camera -end - -Workspace.properties.CurrentCamera = InstanceProperty.normal({}) - -return Workspace \ No newline at end of file diff --git a/modules/lemur/lib/instances/Workspace_spec.lua b/modules/lemur/lib/instances/Workspace_spec.lua deleted file mode 100755 index 41693a8..0000000 --- a/modules/lemur/lib/instances/Workspace_spec.lua +++ /dev/null @@ -1,28 +0,0 @@ -local Workspace = import("./Workspace") -local typeof = import("../functions/typeof") - -describe("instances.Workspace", function() - it("should instantiate", function() - local instance = Workspace:new() - - assert.not_nil(instance) - end) - - describe("CurrentCamera", function() - it("should be an object of type Camera", function() - local instance = Workspace:new() - local camera = instance.CurrentCamera - - assert.not_nil(camera) - assert.equal(typeof(camera), "Instance") - end) - - it("should be accessible as a child named Camera", function() - local instance = Workspace:new() - local camera = instance:WaitForChild("Camera") - - assert.not_nil(camera) - assert.equals(instance.CurrentCamera, camera) - end) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/instances/init.lua b/modules/lemur/lib/instances/init.lua deleted file mode 100755 index d820298..0000000 --- a/modules/lemur/lib/instances/init.lua +++ /dev/null @@ -1,55 +0,0 @@ -local names = { - "AnalyticsService", - "BindableEvent", - "BoolValue", - "Camera", - "ContentProvider", - "CoreGui", - "CorePackages", - "Folder", - "Frame", - "Game", - "GuiButton", - "GuiObject", - "GuiService", - "HttpService", - "ImageButton", - "ImageLabel", - "IntValue", - "LocalizationService", - "LocalizationTable", - "LocalScript", - "Model", - "ModuleScript", - "NotificationService", - "ObjectValue", - "Player", - "Players", - "ReplicatedStorage", - "RunService", - "ScreenGui", - "Script", - "ScrollingFrame", - "ServerScriptService", - "Stats", - "StringValue", - "TestService", - "TextButton", - "TextLabel", - "TextService", - "TweenService", - "UIGridStyleLayout", - "UIListLayout", - "UIPadding", - "UserInputService", - "VirtualInputManager", - "Workspace", -} - -local instances = {} - -for _, name in ipairs(names) do - instances[name] = import("./" .. name) -end - -return instances \ No newline at end of file diff --git a/modules/lemur/lib/json.lua b/modules/lemur/lib/json.lua deleted file mode 100755 index 34b3de8..0000000 --- a/modules/lemur/lib/json.lua +++ /dev/null @@ -1,18 +0,0 @@ -local exists, dkjson = pcall(require, "dkjson") - -local json = {} - -function json.encode(input) - error("Please install `dkjson` to use JSON features.", 2) -end - -function json.decode(input) - error("Please install `dkjson` to use JSON features.", 2) -end - -if exists then - json.encode = dkjson.encode - json.decode = dkjson.decode -end - -return json \ No newline at end of file diff --git a/modules/lemur/lib/taskFunctions/init.lua b/modules/lemur/lib/taskFunctions/init.lua deleted file mode 100755 index d8c903d..0000000 --- a/modules/lemur/lib/taskFunctions/init.lua +++ /dev/null @@ -1,12 +0,0 @@ -local names = { - "spawn", - "wait", -} - -local taskFunctions = {} - -for _, name in ipairs(names) do - taskFunctions[name] = import("./" .. name) -end - -return taskFunctions \ No newline at end of file diff --git a/modules/lemur/lib/taskFunctions/spawn.lua b/modules/lemur/lib/taskFunctions/spawn.lua deleted file mode 100755 index d15dbe1..0000000 --- a/modules/lemur/lib/taskFunctions/spawn.lua +++ /dev/null @@ -1,5 +0,0 @@ -return function(taskScheduler) - return function(fn) - taskScheduler:schedule(0.03, coroutine.create(fn)) - end -end \ No newline at end of file diff --git a/modules/lemur/lib/taskFunctions/spawn_spec.lua b/modules/lemur/lib/taskFunctions/spawn_spec.lua deleted file mode 100755 index d3bfa94..0000000 --- a/modules/lemur/lib/taskFunctions/spawn_spec.lua +++ /dev/null @@ -1,21 +0,0 @@ -local createSpawn = import("./spawn") -local TaskScheduler = import("../TaskScheduler") - -describe("taskFunctions.spawn", function() - it("should schedule after a small amount of time", function() - local scheduler = TaskScheduler.new() - local spawn = createSpawn(scheduler) - - local count = 0 - - spawn(function() - count = count + 1 - end) - - assert.equal(count, 0) - - scheduler:step(0.2) - - assert.equal(count, 1) - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/taskFunctions/wait.lua b/modules/lemur/lib/taskFunctions/wait.lua deleted file mode 100755 index 11e6af2..0000000 --- a/modules/lemur/lib/taskFunctions/wait.lua +++ /dev/null @@ -1,10 +0,0 @@ -return function(taskScheduler) - return function(delay) - if delay == nil then - delay = 0.03 - end - - taskScheduler:schedule(delay, coroutine.running()) - coroutine.yield() - end -end \ No newline at end of file diff --git a/modules/lemur/lib/taskFunctions/wait_spec.lua b/modules/lemur/lib/taskFunctions/wait_spec.lua deleted file mode 100755 index db0b5ad..0000000 --- a/modules/lemur/lib/taskFunctions/wait_spec.lua +++ /dev/null @@ -1,95 +0,0 @@ -local createWait = import("./wait") -local TaskScheduler = import("../TaskScheduler") - -describe("taskFunctions.wait", function() - it("should reschedule self after the specified time", function() - local scheduler = TaskScheduler.new() - local wait = createWait(scheduler) - - local aCount = 0 - local bCount = 0 - local cCount = 0 - - local co = coroutine.create(function() - aCount = aCount + 1 - wait(1) - - bCount = bCount + 1 - wait(1) - - cCount = cCount + 1 - end) - - assert(coroutine.resume(co)) - - assert.equal(aCount, 1) - assert.equal(bCount, 0) - assert.equal(coroutine.status(co), "suspended") - - scheduler:step(1) - - assert.equal(aCount, 1) - assert.equal(bCount, 1) - assert.equal(cCount, 0) - assert.equal(coroutine.status(co), "suspended") - - scheduler:step(1) - - assert.equal(aCount, 1) - assert.equal(bCount, 1) - assert.equal(cCount, 1) - assert.equal(coroutine.status(co), "dead") - end) - - it("should reschedule after a small amount of time with no argument", function() - local scheduler = TaskScheduler.new() - local wait = createWait(scheduler) - - local aCount = 0 - local bCount = 0 - - local co = coroutine.create(function() - aCount = aCount + 1 - wait() - bCount = bCount + 1 - end) - - assert(coroutine.resume(co)) - - assert.equal(aCount, 1) - assert.equal(bCount, 0) - assert.equal(coroutine.status(co), "suspended") - - scheduler:step(0.2) - - assert.equal(aCount, 1) - assert.equal(bCount, 1) - assert.equal(coroutine.status(co), "dead") - end) - - it("should reschedule after a small amount of time with a zero argument", function() - local scheduler = TaskScheduler.new() - local wait = createWait(scheduler) - - local aCount = 0 - local bCount = 0 - - local co = coroutine.create(function() - aCount = aCount + 1 - wait(0) - bCount = bCount + 1 - end) - - assert(coroutine.resume(co)) - - assert.equal(aCount, 1) - assert.equal(bCount, 0) - assert.equal(coroutine.status(co), "suspended") - - scheduler:step(0.2) - - assert.equal(aCount, 1) - assert.equal(bCount, 1) - assert.equal(coroutine.status(co), "dead") - end) -end) \ No newline at end of file diff --git a/modules/lemur/lib/typeKey.lua b/modules/lemur/lib/typeKey.lua deleted file mode 100755 index ea6fa7d..0000000 --- a/modules/lemur/lib/typeKey.lua +++ /dev/null @@ -1,15 +0,0 @@ ---[[ - This key is used to mark Roblox objects and make typeof return the correct - value. - - Use it as a key into a userdata object's metatable; its value will be what - is returned by typeof. -]] - -local typeKey = newproxy(true) - -getmetatable(typeKey).__tostring = function() - return "" -end - -return typeKey \ No newline at end of file diff --git a/modules/lemur/lib/types/Color3.lua b/modules/lemur/lib/types/Color3.lua deleted file mode 100755 index b8086ff..0000000 --- a/modules/lemur/lib/types/Color3.lua +++ /dev/null @@ -1,130 +0,0 @@ -local assign = import("../assign") -local typeKey = import("../typeKey") - -local function lerpNumber(a, b, alpha) - return (1 - alpha) * a + b * alpha -end - -local Color3 = {} - -setmetatable(Color3, { - __tostring = function() - return "Color3" - end, -}) - -local prototype = {} - -function prototype:lerp(goal, alpha) - return Color3.new( - lerpNumber(self.r, goal.r, alpha), - lerpNumber(self.g, goal.g, alpha), - lerpNumber(self.b, goal.b, alpha) - ) -end - -local metatable = {} -metatable[typeKey] = "Color3" - -function metatable:__index(key) - local internal = getmetatable(self).internal - - if internal[key] ~= nil then - return internal[key] - end - - if prototype[key] ~= nil then - return prototype[key] - end - - error(string.format("%s is not a valid member of Color3", tostring(key)), 2) -end - -function metatable:__eq(other) - return self.r == other.r and self.g == other.g and self.b == other.b -end - -function Color3.new(...) - if select("#", ...) == 0 then - return Color3.new(0, 0, 0) - end - - local r, g, b = ... - - local internalInstance = { - r = r, - g = g, - b = b, - } - - local instance = newproxy(true) - - assign(getmetatable(instance), metatable) - getmetatable(instance).internal = internalInstance - - return instance -end - -function Color3.fromRGB(r, g, b) - return Color3.new(r / 255, g / 255, b / 255) -end - -function Color3.fromHSV(h, s, v) - -- Convert h to a 360-degree value (inputs as between 0 and 1) - h = h * 360 - - -- Sector of the HSV color space (there are 6) that the hue falls in - local sector = h / 60 - local chroma = s * v - local x = chroma * (1 - math.abs(sector % 2 - 1)) - local m = v - chroma - - local r, g, b - - if sector >= 0 and sector <= 1 then - r, g, b = chroma, x, 0 - elseif sector >= 1 and sector <= 2 then - r, g, b = x, chroma, 0 - elseif sector >= 2 and sector <= 3 then - r, g, b = 0, chroma, x - elseif sector >= 3 and sector <= 4 then - r, g, b = 0, x, chroma - elseif sector >= 4 and sector <= 5 then - r, g, b = x, 0, chroma - elseif sector >= 5 and sector < 6 then - r, g, b = chroma, 0, x - else - -- Return a default value of 0, 0, 0. This will happen if h is not between 0 and 1. - return Color3.new(0, 0, 0) - end - - return Color3.new(r + m, g + m, b + m) -end - -function Color3.toHSV(color) - local minComponent = math.min(color.r, color.g, color.b) - local maxComponent = math.max(color.r, color.g, color.b) - - -- Grayscale color. - -- Hue and saturation are 0; value is equal to the RGB value. - if minComponent == maxComponent then - return 0, 0, minComponent - end - - local delta = maxComponent - minComponent - local hue - local saturation = delta / maxComponent - local value = maxComponent - - if color.r == maxComponent then - hue = (color.g - color.b) / delta - elseif color.g == maxComponent then - hue = 2 + (color.b - color.r) / delta - else - hue = 4 + (color.r - color.g) / delta - end - - return (hue * 60) / 360, saturation, value -end - -return Color3 diff --git a/modules/lemur/lib/types/Color3_spec.lua b/modules/lemur/lib/types/Color3_spec.lua deleted file mode 100755 index 1a46526..0000000 --- a/modules/lemur/lib/types/Color3_spec.lua +++ /dev/null @@ -1,82 +0,0 @@ -local Color3 = import("./Color3") - -local typeof = import("../functions/typeof") - -local function extractColors(color) - return { - color.r, - color.g, - color.b - } -end - -describe("types.Color3", function() - it("should have an empty constructor", function() - local color = Color3.new() - - assert.not_nil(color) - assert.are.same({ 0, 0, 0 }, extractColors(color)) - end) - - it("should have a constructor that takes rgb values 0-1", function() - local color = Color3.new(0, 0, 0) - - assert.not_nil(color) - end) - - it("should have the fromRGB method", function() - local color = Color3.fromRGB(255, 0, 0) - - assert.are.same({ 1, 0, 0 }, extractColors(color)) - end) - - it("should have the fromHSV method", function() - local color = Color3.fromHSV(120 / 360, 0.5, 0.75) - - -- Round the colors to the nearest whole number - -- This ensures we don't get errors from rounding, which are - -- ultimately fairly unimportant. - local r = math.floor(color.r * 255 + 0.5) - local g = math.floor(color.g * 255 + 0.5) - local b = math.floor(color.b * 255 + 0.5) - - assert.are.same({ 96, 191, 96 }, { r, g, b }) - end) - - it("should have the toHSV method", function() - local color = Color3.fromHSV(120 / 360, 0.5, 0.75) - local h, s, v = Color3.toHSV(color) - - assert.are.same({ 120 / 360, 0.5, 0.75 }, { h, s, v }) - end) - - describe("lerp", function() - local a = Color3.new(0, 0, 0) - local b = Color3.new(1, 1, 1) - - it("should lerp colors", function() - -- Middle used to avoid rounding / float precision issues. - local middle = a:lerp(b, 0.5) - assert.are.same({ 0.5, 0.5, 0.5 }, extractColors(middle)) - end) - - it("should equal the goal when alpha is 1", function() - assert.are.same({ 1, 1, 1 }, extractColors(a:lerp(b, 1))) - end) - - it("should equal the start when alpha is 0", function() - assert.are.same({ 0, 0, 0 }, extractColors(a:lerp(b, 0))) - end) - end) - - it("should compare Color3s", function() - local c1, c2 = Color3.new(0, 1, 0), Color3.new(0, 1, 0) - assert.are.equal(c1, c2) - assert.are_not_equal(c1, Color3.new(0, 0, 0)) - end) - - it("should be detected by typeof", function() - local type = typeof(Color3.new()) - assert.are.equal("Color3", type) - end) -end) diff --git a/modules/lemur/lib/types/Rect.lua b/modules/lemur/lib/types/Rect.lua deleted file mode 100755 index 9ad93c1..0000000 --- a/modules/lemur/lib/types/Rect.lua +++ /dev/null @@ -1,71 +0,0 @@ -local assign = import("../assign") -local typeKey = import("../typeKey") -local typeof = import("../functions/typeof") -local Vector2 = import("./Vector2") - -local Rect = {} - -setmetatable(Rect, { - __tostring = function() - return "Rect" - end, -}) - -local prototype = {} - -local metatable = {} -metatable[typeKey] = "Rect" - -function metatable:__index(key) - local internal = getmetatable(self).internal - - if internal[key] ~= nil then - return internal[key] - end - - if prototype[key] ~= nil then - return prototype[key] - end - - error(string.format("%s is not a valid member of Rect", tostring(key)), 2) -end - -function metatable:__eq(other) - return self.Min == other.Min and self.Max == other.Max -end - -function Rect.new(...) - if select("#", ...) == 4 then - local minX, minY, maxX, maxY = ... - if type(minX) ~= "number" or type(minY) ~= "number" or - type(maxX) ~= "number" or type(maxY) ~= "number" then - error("Rect.new(minX, minY, maxX, maxY) takes in 4 numbers", 2) - end - - return Rect.new( - Vector2.new(minX, minY), - Vector2.new(maxX, maxY) - ) - end - - local min, max = ... - - if typeof(min) ~= "Vector2" or typeof(max) ~= "Vector2" then - error("Rect.new(min, max) takes in 2 Vector2s", 2) - end - - local internalInstance = { - Min = min, - Max = max, - Width = max.X - min.X, - Height = max.Y - min.Y, - } - local instance = newproxy(true) - - assign(getmetatable(instance), metatable) - getmetatable(instance).internal = internalInstance - - return instance -end - -return Rect diff --git a/modules/lemur/lib/types/Rect_spec.lua b/modules/lemur/lib/types/Rect_spec.lua deleted file mode 100755 index d278074..0000000 --- a/modules/lemur/lib/types/Rect_spec.lua +++ /dev/null @@ -1,84 +0,0 @@ -local Rect = import("./Rect") -local Vector2 = import("./Vector2") -local typeof = import("../functions/typeof") - -local function extractRect(r) - return { r.Min.X, r.Min.Y, r.Max.X, r.Max.Y, r.Width, r.Height } -end - -describe("types.Rect", function() - it("should not have an empty constructor", function() - assert.has.errors(function() - Rect.new() - end) - end) - - it("should have a constructor with two parameters", function() - local r = Rect.new(Vector2.new(10, 20), Vector2.new(50, 100)) - - assert.not_nil(r) - assert.are.same({10, 20, 50, 100, 40, 80}, extractRect(r)) - end) - - it("should have a constructor with four parameters", function() - local r = Rect.new(10, 20, 50, 100) - - assert.not_nil(r) - assert.are.same({10, 20, 50, 100, 40, 80}, extractRect(r)) - end) - - it("should be type Rect", function() - assert.equal(typeof(Rect.new(0, 0, 0, 0)), "Rect") - end) - - it("should throw when bad params are passed to the 4-param constructor", function() - assert.has.errors(function() - Rect.new("test", 1, 2, 3) - end) - - assert.has.errors(function() - Rect.new(1, "test", 2, 3) - end) - - assert.has.errors(function() - Rect.new(1, 2, "test", 3) - end) - - assert.has.errors(function() - Rect.new(1, 2, 3, "test") - end) - end) - - it("should throw when bad params are passed to the 2-param constructor", function() - assert.has.errors(function() - Rect.new("test", Vector2.new()) - end) - - assert.has.errors(function() - Rect.new(Vector2.new(), "test") - end) - end) - - it("should equal another Rect with the same values", function() - local r1 = Rect.new(10, 30, 50, 200) - local r2 = Rect.new(Vector2.new(10, 30), Vector2.new(50, 200)) - - assert.equals(r1, r1) - assert.equals(r1, r2) - assert.equals(r2, r2) - end) - - it("should not equal another Rect with different min and max values", function() - local rectA = Rect.new(10, 30, 50, 200) - - local rectB1 = Rect.new(11, 30, 50, 200) - local rectB2 = Rect.new(10, 16, 50, 200) - local rectB3 = Rect.new(10, 30, 40, 200) - local rectB4 = Rect.new(10, 30, 50, 205) - - assert.not_equals(rectA, rectB1) - assert.not_equals(rectA, rectB2) - assert.not_equals(rectA, rectB3) - assert.not_equals(rectA, rectB4) - end) -end) diff --git a/modules/lemur/lib/types/UDim.lua b/modules/lemur/lib/types/UDim.lua deleted file mode 100755 index ac46fea..0000000 --- a/modules/lemur/lib/types/UDim.lua +++ /dev/null @@ -1,62 +0,0 @@ -local assign = import("../assign") -local typeKey = import("../typeKey") - -local UDim = {} - -setmetatable(UDim, { - __tostring = function() - return "UDim" - end, -}) - -local prototype = {} - -local metatable = {} -metatable[typeKey] = "UDim" - -function metatable:__index(key) - local internal = getmetatable(self).internal - - if internal[key] ~= nil then - return internal[key] - end - - if prototype[key] ~= nil then - return prototype[key] - end - - error(string.format("%s is not a valid member of UDim", tostring(key)), 2) -end - -function metatable:__add(other) - return UDim.new(self.Scale + other.Scale, self.Offset + other.Offset) -end - -function metatable:__eq(other) - return self.Scale == other.Scale and self.Offset == other.Offset -end - -function UDim.new(...) - if select("#", ...) == 0 then - return UDim.new(0, 0) - end - - local Scale, Offset = ... - if type(Scale) ~= "number" or type(Offset) ~= "number" then - error("UDim.new must take in 2 numbers", 2) - end - - local internalInstance = { - Scale = Scale, - Offset = Offset, - } - - local instance = newproxy(true) - - assign(getmetatable(instance), metatable) - getmetatable(instance).internal = internalInstance - - return instance -end - -return UDim diff --git a/modules/lemur/lib/types/UDim2.lua b/modules/lemur/lib/types/UDim2.lua deleted file mode 100755 index 2b2c5e8..0000000 --- a/modules/lemur/lib/types/UDim2.lua +++ /dev/null @@ -1,95 +0,0 @@ -local assign = import("../assign") -local typeKey = import("../typeKey") -local typeof = import("../functions/typeof") -local UDim = import("./UDim") - -local function lerpNumber(a, b, alpha) - return (1 - alpha) * a + b * alpha -end - -local UDim2 = {} - -setmetatable(UDim2, { - __tostring = function() - return "UDim2" - end, -}) - -local prototype = {} - -function prototype:Lerp(goal, alpha) - return UDim2.new( - lerpNumber(self.X.Scale, goal.X.Scale, alpha), - lerpNumber(self.X.Offset, goal.X.Offset, alpha), - lerpNumber(self.Y.Scale, goal.Y.Scale, alpha), - lerpNumber(self.Y.Offset, goal.Y.Offset, alpha) - ) -end - -local metatable = {} -metatable[typeKey] = "UDim2" - -function metatable:__index(key) - local internal = getmetatable(self).internal - - if internal[key] ~= nil then - return internal[key] - end - - if prototype[key] ~= nil then - return prototype[key] - end - - error(string.format("%s is not a valid member of UDim2", tostring(key)), 2) -end - -function metatable:__eq(other) - return self.X == other.X and self.Y == other.Y -end - -function metatable:__add(other) - return UDim2.new(self.X + other.X, self.Y + other.Y) -end - -function UDim2.new(...) - if select("#", ...) == 0 then - return UDim2.new( - UDim.new(0, 0), - UDim.new(0, 0) - ) - end - - if select("#", ...) == 4 then - local xScale, xOffset, yScale, yOffset = ... - if type(xScale) ~= "number" or type(xOffset) ~= "number" or - type(yScale) ~= "number" or type(yOffset) ~= "number" then - error("UDim2.new(xScale, xOffset, yScale, yOffset) takes in 4 numbers", 2) - end - - return UDim2.new( - UDim.new(xScale, xOffset), - UDim.new(yScale, yOffset) - ) - end - - local xDim, yDim = ... - - if typeof(xDim) ~= "UDim" or typeof(yDim) ~= "UDim" then - error("UDim2.new(xDim, yDim) takes in 2 UDims", 2) - end - - local internalInstance = { - X = xDim, - Y = yDim, - Width = xDim, - Height = yDim, - } - local instance = newproxy(true) - - assign(getmetatable(instance), metatable) - getmetatable(instance).internal = internalInstance - - return instance -end - -return UDim2 diff --git a/modules/lemur/lib/types/UDim2_spec.lua b/modules/lemur/lib/types/UDim2_spec.lua deleted file mode 100755 index dd9b41b..0000000 --- a/modules/lemur/lib/types/UDim2_spec.lua +++ /dev/null @@ -1,117 +0,0 @@ -local UDim = import("./UDim") -local UDim2 = import("./UDim2") - -local function extractUDim2(udim) - return { udim.X.Scale, udim.X.Offset, udim.Y.Scale, udim.Y.Offset } -end - -describe("types.UDim2", function() - it("should have an empty constructor", function() - local udim = UDim2.new() - - assert.not_nil(udim) - assert.are.same({0, 0, 0, 0}, extractUDim2(udim)) - end) - - it("should have a constructor with two parameters", function() - local udim = UDim2.new(UDim.new(10, 20), UDim.new(50, 100)) - - assert.not_nil(udim) - assert.are.same({10, 20, 50, 100}, extractUDim2(udim)) - end) - - it("should have a constructor with four parameters", function() - local udim = UDim2.new(10, 20, 50, 100) - - assert.not_nil(udim) - assert.are.same({10, 20, 50, 100}, extractUDim2(udim)) - end) - - it("should throw when bad params are passed to the 4-param constructor", function() - assert.has.errors(function() - UDim2.new("test", 1, 2, 3) - end) - - assert.has.errors(function() - UDim2.new(1, "test", 2, 3) - end) - - assert.has.errors(function() - UDim2.new(1, 2, "test", 3) - end) - - assert.has.errors(function() - UDim2.new(1, 2, 3, "test") - end) - end) - - it("should throw when bad params are passed to the 2-param constructor", function() - assert.has.errors(function() - -- luacheck: push ignore udim - local udim = UDim2.new("test", UDim.new()) - -- luacheck: pop - end) - - assert.has.errors(function() - -- luacheck: push ignore udim - local udim = UDim2.new(UDim.new(), "test") - -- luacheck: pop - end) - end) - - it("should have property X equal property Width", function() - local udim = UDim2.new(10, 20, 50, 100) - - assert.not_nil(udim) - assert.equals(udim.X, udim.Width) - end) - - - it("should have property Y equal property Height", function() - local udim = UDim2.new(10, 20, 50, 100) - - assert.not_nil(udim) - assert.equals(udim.Y, udim.Height) - end) - - it("should add another UDim2", function() - local udimA = UDim2.new(10, 30, 50, 200) - local udimB = UDim2.new(UDim.new(20, 40), UDim.new(100, 500)) - local udim = udimA + udimB - - assert.not_nil(udim) - assert.are.same({30, 70, 150, 700}, extractUDim2(udim)) - end) - - it("should equal another UDim2 with the same values", function() - local udimA = UDim2.new(10, 30, 50, 200) - local udimB = UDim2.new(10, 30, 50, 200) - - assert.equals(udimA, udimB) - end) - - it("should not equal another UDim with different scale and offset", function() - local udimA = UDim2.new(10, 30, 50, 200) - - local udimB1 = UDim2.new(11, 30, 50, 200) - local udimB2 = UDim2.new(10, 15, 50, 200) - local udimB3 = UDim2.new(10, 30, 60, 200) - local udimB4 = UDim2.new(10, 30, 50, 100) - local udimB5 = UDim2.new(1, 2, 3, 4) - - assert.not_equals(udimA, udimB1) - assert.not_equals(udimA, udimB2) - assert.not_equals(udimA, udimB3) - assert.not_equals(udimA, udimB4) - assert.not_equals(udimA, udimB5) - end) - - it("should lerp", function() - local udimA = UDim2.new(0, 100, 200, 300) - local udimB = UDim2.new(100, 200, 300, 400) - - assert.are.same({0, 100, 200, 300}, extractUDim2(udimA:Lerp(udimB, 0))) - assert.are.same({50, 150, 250, 350}, extractUDim2(udimA:Lerp(udimB, 0.5))) - assert.are.same({100, 200, 300, 400}, extractUDim2(udimA:Lerp(udimB, 1))) - end) -end) diff --git a/modules/lemur/lib/types/UDim_spec.lua b/modules/lemur/lib/types/UDim_spec.lua deleted file mode 100755 index 3c25ce9..0000000 --- a/modules/lemur/lib/types/UDim_spec.lua +++ /dev/null @@ -1,59 +0,0 @@ -local UDim = import("./UDim") - -local function extractValues(udim) - return { udim.Scale, udim.Offset } -end - -describe("types.UDim", function() - it("should have an empty constructor", function() - local udim = UDim.new() - - assert.not_nil(udim) - assert.are.same({0, 0}, extractValues(udim)) - end) - - it("should have a constructor with two parameters", function() - local udim = UDim.new(1, 200) - - assert.not_nil(udim) - assert.are.same({1, 200}, extractValues(udim)) - end) - - it("should throw when bad params are passed to the constructor", function() - assert.has.errors(function() - UDim.new(1, "test") - end) - - assert.has.errors(function() - UDim.new("test", 10) - end) - end) - - it("should add another UDim", function() - local udimA = UDim.new(1, 200) - local udimB = UDim.new(100, 500) - local udim = udimA + udimB - - assert.not_nil(udim) - assert.are.same({101, 700}, extractValues(udim)) - end) - - it("should equal another UDim with the same scale and offset", function() - local udimA = UDim.new(1, 200) - local udimB = UDim.new(1, 200) - - assert.equals(udimA, udimB) - end) - - it("should not equal another UDim with different scale and offset", function() - local udimA = UDim.new(1, 200) - - local udimB1 = UDim.new(1, 201) - local udimB2 = UDim.new(50, 200) - local udimB3 = UDim.new(3, 7) - - assert.not_equals(udimA, udimB1) - assert.not_equals(udimA, udimB2) - assert.not_equals(udimA, udimB3) - end) -end) diff --git a/modules/lemur/lib/types/Vector2.lua b/modules/lemur/lib/types/Vector2.lua deleted file mode 100755 index 631a852..0000000 --- a/modules/lemur/lib/types/Vector2.lua +++ /dev/null @@ -1,62 +0,0 @@ -local assign = import("../assign") -local typeKey = import("../typeKey") - -local Vector2 = {} - -setmetatable(Vector2, { - __tostring = function() - return "Vector2" - end, -}) - -local prototype = {} - -local metatable = {} -metatable[typeKey] = "Vector2" - -function metatable:__index(key) - local internal = getmetatable(self).internal - - if internal[key] ~= nil then - return internal[key] - end - - if prototype[key] ~= nil then - return prototype[key] - end - - error(string.format("%s is not a valid member of Vector2", tostring(key)), 2) -end - -function metatable:__add(other) - return Vector2.new(self.X + other.X, self.Y + other.Y) -end - -function metatable:__eq(other) - return self.X == other.X and self.Y == other.Y -end - -function Vector2.new(...) - if select("#", ...) == 0 then - return Vector2.new(0, 0) - end - - local X, Y = ... - if type(X) ~= "number" or type(Y) ~= "number" then - error("Vector2.new takes in 2 numbers", 2) - end - - local internalInstance = { - X = X, - Y = Y, - } - - local instance = newproxy(true) - - assign(getmetatable(instance), metatable) - getmetatable(instance).internal = internalInstance - - return instance -end - -return Vector2 diff --git a/modules/lemur/lib/types/Vector2_spec.lua b/modules/lemur/lib/types/Vector2_spec.lua deleted file mode 100755 index ce9be1a..0000000 --- a/modules/lemur/lib/types/Vector2_spec.lua +++ /dev/null @@ -1,60 +0,0 @@ -local Vector2 = import("./Vector2") - -local function extractValues(v) - return { v.X, v.Y } -end - - -describe("types.Vector2", function() - it("should have an empty constructor", function() - local v = Vector2.new() - - assert.not_nil(v) - assert.are.same({0, 0}, extractValues(v)) - end) - - it("should have a constructor with two parameters", function() - local v = Vector2.new(1, 200) - - assert.not_nil(v) - assert.are.same({1, 200}, extractValues(v)) - end) - - it("should throw when bad params are passed to the constructor", function() - assert.has.errors(function() - Vector2.new(1, "test") - end) - - assert.has.errors(function() - Vector2.new("test", 10) - end) - end) - - it("should add another Vector2", function() - local vectorA = Vector2.new(1, 200) - local vectorB = Vector2.new(100, 500) - local v = vectorA + vectorB - - assert.not_nil(v) - assert.are.same({101, 700}, extractValues(v)) - end) - - it("should equal another Vector2 with the same x and y", function() - local vectorA = Vector2.new(1, 200) - local vectorB = Vector2.new(1, 200) - - assert.equals(vectorA, vectorB) - end) - - it("should not equal another UDim with different scale and offset", function() - local vectorA = Vector2.new(1, 200) - - local vectorB1 = Vector2.new(10, 200) - local vectorB2 = Vector2.new(1, 300) - local vectorB3 = Vector2.new(5, 10) - - assert.not_equals(vectorA, vectorB1) - assert.not_equals(vectorA, vectorB2) - assert.not_equals(vectorA, vectorB3) - end) -end) diff --git a/modules/lemur/lib/types/init.lua b/modules/lemur/lib/types/init.lua deleted file mode 100755 index fdaf69d..0000000 --- a/modules/lemur/lib/types/init.lua +++ /dev/null @@ -1,15 +0,0 @@ -local names = { - "Color3", - "Rect", - "UDim", - "UDim2", - "Vector2", -} - -local types = {} - -for _, name in ipairs(names) do - types[name] = import("./" .. name) -end - -return types \ No newline at end of file diff --git a/modules/lemur/lib/validateType.lua b/modules/lemur/lib/validateType.lua deleted file mode 100755 index 7d3d6e6..0000000 --- a/modules/lemur/lib/validateType.lua +++ /dev/null @@ -1,8 +0,0 @@ -local typeof = import("./functions/typeof") - -return function(name, value, expectedTypeAsString) - local actualType = typeof(value) - if actualType ~= expectedTypeAsString then - error(string.format("%s must be type `%s`, got type `%s`", name, expectedTypeAsString, actualType), 3) - end -end diff --git a/modules/lemur/lib/validateType_spec.lua b/modules/lemur/lib/validateType_spec.lua deleted file mode 100755 index 470bcfb..0000000 --- a/modules/lemur/lib/validateType_spec.lua +++ /dev/null @@ -1,20 +0,0 @@ -local validateType = import("./validateType") - -describe("validateType", function() - it("should be a function", function() - assert.not_nil(validateType) - assert.equals(type(validateType), "function") - end) - - it("should accept valid types", function() - validateType("", 123, "number") - validateType("", "test", "string") - validateType("", true, "boolean") - end) - - it("should throw on mismatched types", function() - assert.has.errors(function() - validateType("text", {}, "string") - end) - end) -end) \ No newline at end of file diff --git a/modules/testez/.editorconfig b/modules/testez/.editorconfig deleted file mode 100755 index bd538e0..0000000 --- a/modules/testez/.editorconfig +++ /dev/null @@ -1,8 +0,0 @@ -root = true - -[*.lua] -indent_style = tab -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = false \ No newline at end of file diff --git a/modules/testez/.gitignore b/modules/testez/.gitignore deleted file mode 100755 index a96d1d7..0000000 --- a/modules/testez/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/luacov.* -/site \ No newline at end of file diff --git a/modules/testez/.gitmodules b/modules/testez/.gitmodules deleted file mode 100755 index 5731b25..0000000 --- a/modules/testez/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "modules/lemur"] - path = modules/lemur - url = https://github.com/LPGhatguy/lemur.git diff --git a/modules/testez/.luacheckrc b/modules/testez/.luacheckrc deleted file mode 100755 index a0b3d08..0000000 --- a/modules/testez/.luacheckrc +++ /dev/null @@ -1,15 +0,0 @@ -stds.roblox = { - globals = { - "game" - }, - read_globals = { - -- Roblox globals - "script", - - -- -- Extra functions - "typeof", - "tick", "warn", - } -} - -std = "lua51+roblox" \ No newline at end of file diff --git a/modules/testez/.travis.yml b/modules/testez/.travis.yml deleted file mode 100755 index 65ae0bc..0000000 --- a/modules/testez/.travis.yml +++ /dev/null @@ -1,26 +0,0 @@ -# http://kiki.to/blog/2016/02/04/talk-continuous-integration-with-lua/ -language: python -sudo: false - -branches: - only: - - master - -env: - - LUA="lua=5.1" - -before_install: - - pip install hererocks - - hererocks lua_install -r^ --$LUA - - export PATH=$PATH:$PWD/lua_install/bin - -install: - - luarocks install luafilesystem - - luarocks install busted - - luarocks install luacov - - luarocks install luacov-coveralls - - luarocks install luacheck - -script: - - luacheck lib - - lua spec.lua \ No newline at end of file diff --git a/modules/testez/CHANGELOG.md b/modules/testez/CHANGELOG.md deleted file mode 100755 index 2e4daca..0000000 --- a/modules/testez/CHANGELOG.md +++ /dev/null @@ -1,7 +0,0 @@ -# TestEZ Changelog - -## Current master -* No changes - -## 1.0.0 (TODO: Date) -* Initial release \ No newline at end of file diff --git a/modules/testez/CONTRIBUTING.md b/modules/testez/CONTRIBUTING.md deleted file mode 100755 index b05ab1f..0000000 --- a/modules/testez/CONTRIBUTING.md +++ /dev/null @@ -1,70 +0,0 @@ -# Contributing to TestEZ -Thanks for considering contributing to TestEZ! This guide has a few tips and guidelines to make contributing to the project as easy as possible. - -## Bug Reports -Any bugs (or things that look like bugs) can be reported on the [GitHub issue tracker](https://github.com/Roblox/TestEZ/issues). - -Make sure you check to see if someone has already reported your bug first! Don't fret about it; if we notice a duplicate we'll send you a link to the right issue! - -## Feature Requests -If there are any features you think are missing from TestEZ, you can post a request in the [GitHub issue tracker](https://github.com/Roblox/TestEZ/issues). - -Just like bug reports, take a peak at the issue tracker for duplicates before opening a new feature request. - -## Working on TestEZ -To get started working on TestEZ, you'll need: -* Git -* Lua 5.1 -* [LuaFileSystem](https://keplerproject.github.io/luafilesystem/) (`luarocks install luafilesystem`) -* [Luacheck](https://github.com/mpeterv/luacheck) (`luarocks install luacheck`) -* [LuaCov](https://keplerproject.github.io/luacov) (`luarocks install luacov`) - -Once you have all of these installed, you can run `lua bin/install-dependencies.lua` script to grab a couple additional local dependencies automatically. - -Finally, you can run all of TestEZ's tests with: - -```sh -lua spec.lua -``` - -Or, to generate a LuaCov coverage report: - -```sh -lua -lluacov spec.lua -luacov -``` - -## Pull Requests -Before starting a pull request, open an issue about the feature or bug. This helps us prevent duplicated and wasted effort. These issues are a great place to ask for help if you run into problems! - -Before you submit a new pull request, check: -* Code Style: Match the existing code! -* Changelog: Add an entry to [CHANGELOG.md](CHANGELOG.md) -* Luacheck: Run [Luacheck](https://github.com/mpeterv/luacheck) on your code, no warnings allowed! -* Tests: They all need to pass! - -### Code Style -Try to match the existing code style! In short: - -* Tabs for indentation -* Double quotes -* One statement per line - -Eventually we'll have a tool to check these things automatically. - -### Changelog -Adding an entry to [CHANGELOG.md](CHANGELOG.md) alongside your commit makes it easier for everyone to keep track of what's been changed. - -Add a line under the "Current master" heading. When we make a new release, all of those bullet points will be attached to a new version and the "Current master" section will become empty again. - -### Luacheck -We use [Luacheck](https://github.com/mpeterv/luacheck) for static analysis of Lua on all of our projects. - -From the command line, just run `luacheck lib` to check the TestEZ source. - -You should get it working on your system, and then get a plugin for the editor you use. There are plugins available for most popular editors! - -### Tests -When submitting a bug fix, create a test that verifies the broken behavior and that the bug fix works. This helps us avoid regressions! - -We use [LuaCov](https://keplerproject.github.io/luacov) for keeping track of code coverage. We'd like it to be as close to 100% as possible, but it's not always easy. \ No newline at end of file diff --git a/modules/testez/DESIGN.md b/modules/testez/DESIGN.md deleted file mode 100755 index a5e8417..0000000 --- a/modules/testez/DESIGN.md +++ /dev/null @@ -1,66 +0,0 @@ -# TestEZ Design Notes - -## Test Flow -Testing using this module is broken down into four steps: - -1. Load tests -2. Create test plan -3. Execute test plan -4. Report results - -Before executing the test plan, we can also modify it to change semantics separately from the code. - -### #1: Load tests -All ModuleScript objects that have a name ending in `.spec` are loaded as tests. On the filesystem, they appear as `.spec.lua` files. - -These tests should return a function that describes the actual test using the `describe`, `it`, and `expect` functions. These functions are automatically injected into the test environment when available. - -A test suite for addition might look like this: - -```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 -``` - -All test assertions should be contained inside the `it` blocks. - -### #2: Create test plan -A tree of tests is constructed out of all the `describe` and `it` calls in the tree. No test code is actually run. - -This allows us to potentially output a tree of the tests in the system without actually running them. It also gives us a mechanism to run only specific tests. - -This step is carried out by `TestPlanner`. It uses `TestPlanBuilder` to hold temporary state relevant only when building the plan, and then returns a `TestPlan` object. - -To debug the test plan tree, use `plan:visualize()` - -### #3: Execute test plan -A tree of test results is created that mirrors the test plan nodes. - -This step is carried out by `TestRunner`. It creates a `TestSession` using the `TestPlan` from the previous step. This object holds state only relevant when building the test results, then returns a `TestResults` object. - -To debug the result tree, use `results:visualize()` - -### #4: Report results -Reporting is handled by a test reporter object, which is just a table with a `report` method on it. It takes a `TestResults` object and outputs it to standard output, creates a GUI, or tells TestService about the results. - -This is pluggable, and could conceivably output in any format. - -## System Architecture -The system is broken down in a way that eliminates global state, provides multiple abstraction layers for each operation, and stores plain data in a way that's agnostic to the operations performed upon it. - -In both the planning and running phases of tests, a stateless module (`TestPlanner` and `TestRunner`) creates a temporary object to hold state about the operation it's trying to perform. These objects (`TestPlanBuilder` and `TestSession`) allow the code to traverse and build trees without passing around extra state between iterations. - -When the modules are done using these builder objects, they call `finalize` on them to receive a `TestPlan` or `TestResults` object. These objects are passed back to the original caller. - -`TestBootStrap` packages up use of the stages of testing into a simpler interface that also automatically locates test modules. When more advanced functionality is desired, it's easy to stop using TestBootstrap and instead call the underlying objects directly. \ No newline at end of file diff --git a/modules/testez/LICENSE b/modules/testez/LICENSE deleted file mode 100755 index f49a4e1..0000000 --- a/modules/testez/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/modules/testez/README.md b/modules/testez/README.md deleted file mode 100755 index ffe6009..0000000 --- a/modules/testez/README.md +++ /dev/null @@ -1,32 +0,0 @@ -

TestEZ

-
- - Travis-CI Build Status - - - Documentation - -
- -
- BDD-style Roblox Lua testing framework -
- -
 
- -TestEZ can run within Roblox itself, as well as inside [Lemur](https://github.com/LPGhatguy/Lemur) for testing on CI systems. - -We use TestEZ at Roblox for testing our apps, in-game core scripts, built-in Roblox Studio plugins, as well as libraries like [Roact](https://github.com/Roblox/roact) and [Rodux](https://github.com/Roblox/rodux). - -It provides an API that can run all of your tests with a single method call as well as a more granular API that exposes each step of the pipeline. - -## Inspiration and Prior Work -The `describe` and `it` syntax in TestEZ is based on the [Behavior-Driven Development](https://en.wikipedia.org/wiki/Behavior-driven_development) methodology, notably as implemented in RSpec (Ruby), busted (Lua), Mocha (JavaScript), and Ginkgo (Go). - -The `expect` syntax is based on Chai, a JavaScript assertion library commonly used with Mocha. Similar expectation systems are also used in RSpec and Ginkgo, with slightly different syntax. - -## Contributing -Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for information. - -## License -TestEZ is available under the Apache 2.0 license. See [LICENSE](LICENSE) for details. \ No newline at end of file diff --git a/modules/testez/docs/api-reference.md b/modules/testez/docs/api-reference.md deleted file mode 100755 index 637fbac..0000000 --- a/modules/testez/docs/api-reference.md +++ /dev/null @@ -1,123 +0,0 @@ -## Inside Tests - -### describe -``` -describe(phrase, callback) -``` - -This function creates a new `describe` block. These blocks correspond to the **things** that are being tested. - -Put `it` blocks inside of `describe` blocks to describe what behavior should be correct. - -For example: - -```lua -describe("This cheese", function() - it("should be moldy", function() - expect(cheese.moldy).to.equal(true) - end) -end) -``` - -### it -``` -it(phrase, callback) -``` - -This function creates a new 'it' block. These blocks correspond to the **behaviors** that should be expected of the thing you're testing. - -For example: - -```lua -it("should add 1 and 1", function() - expect(1 + 1).to.equal(2) -end) -``` - -### itFOCUS and itSKIP -``` -itFOCUS(phrase, callback) -itSKIP(phrase, callback) -``` - -These methods are special versions of `it` that automatically mark the `it` block as *focused* or *skipped*. They're necessary because `FOCUS` and `SKIP` can't be called inside `it` blocks! - -### FOCUS -``` -FOCUS() -``` - -When called inside a `describe` block, `FOCUS()` marks that block as *focused*. If there are any focused blocks inside your test tree, *only* focused blocks will be executed, and all other tests will be skipped. - -When you're writing a new set of tests as part of a larger codebase, use `FOCUS()` while debugging them to reduce the amount of noise you need to scroll through. - -For example: - -```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) -``` - -!!! note - `FOCUS` does not work inside an `it` block. The bodies of these blocks aren't executed until the tests run, which is too late to change which tests will run. - -### SKIP -``` -SKIP() -``` - -This function works similarly to `FOCUS()`, except instead of marking a block as *focused*, it will mark a block as *skipped*, which stops any of the test assertions in the block from being executed. - -!!!note - `SKIP` does not work inside an `it` block. The bodies of these blocks aren't executed until the tests run, which is too late to change which tests will run. - -### expect -``` -expect(value) -``` - -Creates a new `Expectation`, used for testing the properties of the given value. - -Expectations are intended to be read like English assertions. These are all true: - -```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() -``` \ No newline at end of file diff --git a/modules/testez/docs/getting-started/debugging-tests.md b/modules/testez/docs/getting-started/debugging-tests.md deleted file mode 100755 index 5de1af0..0000000 --- a/modules/testez/docs/getting-started/debugging-tests.md +++ /dev/null @@ -1,37 +0,0 @@ -Often during development, you'll want to only run the test that's concerned with the specific code you're working on. - -TestEZ provides the `SKIP()` and `FOCUS()` functions to either skip or focus the block that the call is contained in. - -This mechanism does not work for `it` blocks; use `itSKIP` and `itFOCUS` instead. Code inside `it` blocks is not run until tests are executed, while `describe` blocks are run immediately to figure out what tests a project contains. - -For example, you might want to run the tests targeting a specific method or two for a `DateTime` module: - -`DateTime.spec.lua` -```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 -``` - -!!! warning - `FOCUS` and `SKIP` are intended exclusively for development. It's not recommended that tests containing these calls are checked into version contorl. - - Future versions of TeztEZ will be able to detect this when running in a CI system and fail tests to prevent that from happening. \ No newline at end of file diff --git a/modules/testez/docs/getting-started/installation.md b/modules/testez/docs/getting-started/installation.md deleted file mode 100755 index 74f05ff..0000000 --- a/modules/testez/docs/getting-started/installation.md +++ /dev/null @@ -1,11 +0,0 @@ -*In the future, TestEZ will have pre-built model files for use within Roblox without other tools.* - -### Method 1: Rojo (Roblox) -* Copy the `lib` directory into your codebase -* Rename the folder to `TestEZ` -* Use [Rojo](https://github.com/LPGhatguy/rojo) to sync the files into a place - -### Method 2: Lemur (CI Systems) -You can use [Lemur](https://github.com/LPGhatguy/Lemur) paired together with a regular Lua 5.1 interpreter to run tests written with TestEZ. - -This is the best approach when testing Roblox Lua libraries using existing continuous integration systems like Travis-CI. We use this technique to run tests for [Rodux](https://github.com/Roblox/Rodux) and other libraries. \ No newline at end of file diff --git a/modules/testez/docs/getting-started/running-tests.md b/modules/testez/docs/getting-started/running-tests.md deleted file mode 100755 index 228e409..0000000 --- a/modules/testez/docs/getting-started/running-tests.md +++ /dev/null @@ -1,11 +0,0 @@ -TestEZ provides a convenient method to run tests in a single pass: - -```lua -local TestEZ = require() - -TestEZ.TestBootstrap:run(MY_TESTS) -``` - -The method also returns information about the test run that can be used to take further action! - -The internals of TestEZ are being reworked, so accessing other APIs at this time isn't recommended. \ No newline at end of file diff --git a/modules/testez/docs/getting-started/writing-tests.md b/modules/testez/docs/getting-started/writing-tests.md deleted file mode 100755 index 9aed0f1..0000000 --- a/modules/testez/docs/getting-started/writing-tests.md +++ /dev/null @@ -1,45 +0,0 @@ -Create `.spec.lua` files (or Roblox objects with the `.spec` suffix) for each module you want to test. These modules should return a function that in turn calls functions from TestEZ. - -A simple module and associated TestEZ spec might look like: - -`Greeter.lua` -```lua -local Greeter = {} - -function Greeter:greet(person) - return "Hello, " .. person -end - -return Greeter -``` - -`Greeter.spec.lua` -```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 -``` - -The functions `describe`, `it`, and `expect` are injected by TestEZ and automatically hook into the current testing context. - -Every module is implicitly scoped according to its path, meaning the tree that the above test represents might be: - -``` -LuaChat - Greeter - greet - [+] should include the customary English greeting - [+] should include the person being greeted -``` \ No newline at end of file diff --git a/modules/testez/docs/index.md b/modules/testez/docs/index.md deleted file mode 100755 index 0837cd7..0000000 --- a/modules/testez/docs/index.md +++ /dev/null @@ -1,5 +0,0 @@ -TestEZ is a BDD-style testing framework for Roblox Lua. - -We use TestEZ at Roblox for testing our apps, in-game core scripts, built-in Roblox Studio plugins, as well as libraries like [Roact](https://github.com/Roblox/roact) and [Rodux](https://github.com/Roblox/rodux). - -It provides an API that can run all of your tests with a single method call as well as a more granular API that exposes each step of the pipeline. \ No newline at end of file diff --git a/modules/testez/docs/requirements.txt b/modules/testez/docs/requirements.txt deleted file mode 100755 index 51b61b7..0000000 --- a/modules/testez/docs/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -mkdocs -mkdocs-material -pymdown-extensions \ No newline at end of file diff --git a/modules/testez/lib/Expectation.lua b/modules/testez/lib/Expectation.lua deleted file mode 100755 index bdbcc4e..0000000 --- a/modules/testez/lib/Expectation.lua +++ /dev/null @@ -1,252 +0,0 @@ ---[[ - Allows creation of expectation statements designed for behavior-driven - testing (BDD). See Chai (JS) or RSpec (Ruby) for examples of other BDD - frameworks. - - The Expectation class is exposed to tests as a function called `expect`: - - expect(5).to.equal(5) - expect(foo()).to.be.ok() - - Expectations can be negated using .never: - - expect(true).never.to.equal(false) - - Expectations throw errors when their conditions are not met. -]] - -local Expectation = {} - ---[[ - These keys don't do anything except make expectations read more cleanly -]] -local SELF_KEYS = { - to = true, - be = true, - been = true, - have = true, - was = true, - at = true, -} - ---[[ - These keys invert the condition expressed by the Expectation. -]] -local NEGATION_KEYS = { - never = true, -} - ---[[ - Extension of Lua's 'assert' that lets you specify an error level. -]] -local function assertLevel(condition, message, level) - message = message or "Assertion failed!" - level = level or 1 - - if not condition then - error(message, level + 1) - end -end - ---[[ - Returns a version of the given method that can be called with either . or : -]] -local function bindSelf(self, method) - return function(firstArg, ...) - if firstArg == self then - return method(self, ...) - else - return method(self, firstArg, ...) - end - end -end - -local function formatMessage(result, trueMessage, falseMessage) - if result then - return trueMessage - else - return falseMessage - end -end - ---[[ - Create a new expectation -]] -function Expectation.new(value) - local self = { - value = value, - successCondition = true, - condition = false - } - - setmetatable(self, Expectation) - - self.a = bindSelf(self, self.a) - self.an = self.a - self.ok = bindSelf(self, self.ok) - self.equal = bindSelf(self, self.equal) - self.throw = bindSelf(self, self.throw) - self.near = bindSelf(self, self.near) - - return self -end - -function Expectation.__index(self, key) - -- Keys that don't do anything except improve readability - if SELF_KEYS[key] then - return self - end - - -- Invert your assertion - if NEGATION_KEYS[key] then - local newExpectation = Expectation.new(self.value) - newExpectation.successCondition = not self.successCondition - - return newExpectation - end - - -- Fall back to methods provided by Expectation - return Expectation[key] -end - ---[[ - Called by expectation terminators to reset modifiers in a statement. - - This makes chains like: - - expect(5) - .never.to.equal(6) - .to.equal(5) - - Work as expected. -]] -function Expectation:_resetModifiers() - self.successCondition = true -end - ---[[ - Assert that the expectation value is the given type. - - expect(5).to.be.a("number") -]] -function Expectation:a(typeName) - local result = (type(self.value) == typeName) == self.successCondition - - local message = formatMessage(self.successCondition, - ("Expected value of type %q, got value %q of type %s"):format( - typeName, - tostring(self.value), - type(self.value) - ), - ("Expected value not of type %q, got value %q of type %s"):format( - typeName, - tostring(self.value), - type(self.value) - ) - ) - - assertLevel(result, message, 3) - self:_resetModifiers() - - return self -end - ---[[ - Assert that our expectation value is truthy -]] -function Expectation:ok() - local result = (self.value ~= nil) == self.successCondition - - local message = formatMessage(self.successCondition, - ("Expected value %q to be non-nil"):format( - tostring(self.value) - ), - ("Expected value %q to be nil"):format( - tostring(self.value) - ) - ) - - assertLevel(result, message, 3) - self:_resetModifiers() - - return self -end - ---[[ - Assert that our expectation value is equal to another value -]] -function Expectation:equal(otherValue) - local result = (self.value == otherValue) == self.successCondition - - local message = formatMessage(self.successCondition, - ("Expected value %q (%s), got %q (%s) instead"):format( - tostring(otherValue), - type(otherValue), - tostring(self.value), - type(self.value) - ), - ("Expected anything but value %q (%s)"):format( - tostring(otherValue), - type(otherValue) - ) - ) - - assertLevel(result, message, 3) - self:_resetModifiers() - - return self -end - ---[[ - Assert that our expectation value is equal to another value within some - inclusive limit. -]] -function Expectation:near(otherValue, limit) - assert(type(self.value) == "number", "Expectation value must be a number to use 'near'") - assert(type(otherValue) == "number", "otherValue must be a number") - assert(type(limit) == "number" or limit == nil, "limit must be a number or nil") - - limit = limit or 1e-7 - - local result = (math.abs(self.value - otherValue) <= limit) == self.successCondition - - local message = formatMessage(self.successCondition, - ("Expected value to be near %f (within %f) but got %f instead"):format( - otherValue, - limit, - self.value - ), - ("Expected value to not be near %f (within %f) but got %f instead"):format( - otherValue, - limit, - self.value - ) - ) - - assertLevel(result, message, 3) - self:_resetModifiers() - - return self -end - ---[[ - Assert that our functoid expectation value throws an error when called -]] -function Expectation:throw() - local ok, err = pcall(self.value) - local result = ok ~= self.successCondition - - local message = formatMessage(self.successCondition, - ("Expected function to succeed, but it threw an error: %s"):format( - tostring(err) - ), - "Expected function to throw an error, but it did not." - ) - - assertLevel(result, message, 3) - self:_resetModifiers() - - return self -end - -return Expectation \ No newline at end of file diff --git a/modules/testez/lib/Reporters/TeamCityReporter.lua b/modules/testez/lib/Reporters/TeamCityReporter.lua deleted file mode 100755 index bab37e5..0000000 --- a/modules/testez/lib/Reporters/TeamCityReporter.lua +++ /dev/null @@ -1,102 +0,0 @@ -local TestService = game:GetService("TestService") - -local TestEnum = require(script.Parent.Parent.TestEnum) - -local TeamCityReporter = {} - -local function teamCityEscape(str) - str = string.gsub(str, "([]|'[])","|%1") - str = string.gsub(str, "\r", "|r") - str = string.gsub(str, "\n", "|n") - return str -end - -local function teamCityEnterSuite(suiteName) - return string.format("##teamcity[testSuiteStarted name='%s']", teamCityEscape(suiteName)) -end - -local function teamCityLeaveSuite(suiteName) - return string.format("##teamcity[testSuiteFinished name='%s']", teamCityEscape(suiteName)) -end - -local function teamCityEnterCase(caseName) - return string.format("##teamcity[testStarted name='%s']", teamCityEscape(caseName)) -end - -local function teamCityLeaveCase(caseName) - return string.format("##teamcity[testFinished name='%s']", teamCityEscape(caseName)) -end - -local function teamCityFailCase(caseName, errorMessage) - return string.format("##teamcity[testFailed name='%s' message='%s']", - teamCityEscape(caseName), teamCityEscape(errorMessage)) -end - -local function reportNode(node, buffer, level) - buffer = buffer or {} - level = level or 0 - if node.status == TestEnum.TestStatus.Skipped then - return buffer - end - if node.planNode.type == TestEnum.NodeType.Describe then - table.insert(buffer, teamCityEnterSuite(node.planNode.phrase)) - for _, child in ipairs(node.children) do - reportNode(child, buffer, level + 1) - end - table.insert(buffer, teamCityLeaveSuite(node.planNode.phrase)) - else - table.insert(buffer, teamCityEnterCase(node.planNode.phrase)) - if node.status == TestEnum.TestStatus.Failure then - table.insert(buffer, teamCityFailCase(node.planNode.phrase, table.concat(node.errors,"\n"))) - end - table.insert(buffer, teamCityLeaveCase(node.planNode.phrase)) - end -end - -local function reportRoot(node) - local buffer = {} - - for _, child in ipairs(node.children) do - reportNode(child, buffer, 0) - end - - return buffer -end - -local function report(root) - local buffer = reportRoot(root) - - return table.concat(buffer, "\n") -end - -function TeamCityReporter.report(results) - local resultBuffer = { - "Test results:", - report(results), - ("%d passed, %d failed, %d skipped"):format( - results.successCount, - results.failureCount, - results.skippedCount - ) - } - - print(table.concat(resultBuffer, "\n")) - - if results.failureCount > 0 then - print(("%d test nodes reported failures."):format(results.failureCount)) - end - - if #results.errors > 0 then - print("Errors reported by tests:") - print("") - - for _, message in ipairs(results.errors) do - TestService:Error(message) - - -- Insert a blank line after each error - print("") - end - end -end - -return TeamCityReporter \ No newline at end of file diff --git a/modules/testez/lib/Reporters/TextReporter.lua b/modules/testez/lib/Reporters/TextReporter.lua deleted file mode 100755 index 0521c2d..0000000 --- a/modules/testez/lib/Reporters/TextReporter.lua +++ /dev/null @@ -1,100 +0,0 @@ ---[[ - The TextReporter uses the results from a completed test to output text to - standard output and TestService. -]] - -local TestService = game:GetService("TestService") - -local TestEnum = require(script.Parent.Parent.TestEnum) - -local INDENT = (" "):rep(3) -local STATUS_SYMBOLS = { - [TestEnum.TestStatus.Success] = "+", - [TestEnum.TestStatus.Failure] = "-", - [TestEnum.TestStatus.Skipped] = "~" -} -local UNKNOWN_STATUS_SYMBOL = "?" - -local TextReporter = {} - -local function reportNode(node, buffer, level) - buffer = buffer or {} - level = level or 0 - - if node.status == TestEnum.TestStatus.Skipped then - return buffer - end - - local line - - if node.status then - local symbol = STATUS_SYMBOLS[node.status] or UNKNOWN_STATUS_SYMBOL - - line = ("%s[%s] %s"):format( - INDENT:rep(level), - symbol, - node.planNode.phrase - ) - else - line = ("%s%s"):format( - INDENT:rep(level), - node.planNode.phrase - ) - end - - table.insert(buffer, line) - - for _, child in ipairs(node.children) do - reportNode(child, buffer, level + 1) - end - - return buffer -end - -local function reportRoot(node) - local buffer = {} - - for _, child in ipairs(node.children) do - reportNode(child, buffer, 0) - end - - return buffer -end - -local function report(root) - local buffer = reportRoot(root) - - return table.concat(buffer, "\n") -end - -function TextReporter.report(results) - local resultBuffer = { - "Test results:", - report(results), - ("%d passed, %d failed, %d skipped"):format( - results.successCount, - results.failureCount, - results.skippedCount - ) - } - - print(table.concat(resultBuffer, "\n")) - - if results.failureCount > 0 then - print(("%d test nodes reported failures."):format(results.failureCount)) - end - - if #results.errors > 0 then - print("Errors reported by tests:") - print("") - - for _, message in ipairs(results.errors) do - TestService:Error(message) - - -- Insert a blank line after each error - print("") - end - end -end - -return TextReporter \ No newline at end of file diff --git a/modules/testez/lib/Stack.lua b/modules/testez/lib/Stack.lua deleted file mode 100755 index 09c2f9c..0000000 --- a/modules/testez/lib/Stack.lua +++ /dev/null @@ -1,38 +0,0 @@ -local Stack = {} -Stack.__index = Stack - -function Stack.new() - local self = {} - setmetatable(self, Stack) - self.data = {} - return self -end - -function Stack:size() - return #self.data -end - -function Stack:push(obj) - self.data[self:size()+1] = obj - return self -end - -function Stack:pop() - local result = self:getBack() - table.remove(self.data,self:size()) - return result -end - -function Stack:getBack() - if self:size() == 0 then error("stack is empty") end - local result = self.data[self:size()] - return result -end - -function Stack:setBack(obj) - if self:size() == 0 then error("stack is empty") end - self.data[self:size()] = obj - return self -end - -return Stack \ No newline at end of file diff --git a/modules/testez/lib/TestBootstrap.lua b/modules/testez/lib/TestBootstrap.lua deleted file mode 100755 index a413915..0000000 --- a/modules/testez/lib/TestBootstrap.lua +++ /dev/null @@ -1,114 +0,0 @@ ---[[ - Provides an interface to quickly run and report tests from a given object. -]] - -local TestPlanner = require(script.Parent.TestPlanner) -local TestRunner = require(script.Parent.TestRunner) -local TextReporter = require(script.Parent.Reporters.TextReporter) - -local TestBootstrap = {} - -local function stripSpecSuffix(name) - return (name:gsub("%.spec$", "")) -end - -local function getPath(module, root) - root = root or game - - local path = {} - local last = module - - while last ~= nil and last ~= root do - table.insert(path, stripSpecSuffix(last.Name)) - last = last.Parent - end - - return path -end - ---[[ - Find all the ModuleScripts in this tree that are tests. -]] -function TestBootstrap:getModules(root, modules, current) - modules = modules or {} - current = current or root - - for _, child in ipairs(current:GetChildren()) do - if child:IsA("ModuleScript") and child.Name:match("%.spec$") then - local method = require(child) - local path = getPath(child, root) - - table.insert(modules, { - method = method, - path = path - }) - else - self:getModules(root, modules, child) - end - end - - table.sort(modules, function(a, b) - return a.path[#a.path]:lower() < b.path[#b.path]:lower() - end) - - return modules -end - ---[[ - Runs all test and reports the results using the given test reporter. - - If no reporter is specified, a reasonable default is provided. - - This function demonstrates the expected workflow with this testing system: - 1. Locate test modules - 2. Generate test plan - 3. Run test plan - 4. Report test results - - This means we could hypothetically present a GUI to the developer that shows - the test plan before we execute it, allowing them to toggle specific tests - before they're run, but after they've been identified! -]] -function TestBootstrap:run(root, reporter, showTimingInfo, noXpcallByDefault) - noXpcallByDefault = noXpcallByDefault or false - if not root then - error("You must provide a root object to search for tests in!", 2) - end - - reporter = reporter or TextReporter - - local startTime = tick() - - local modules - if type(root) == "function" then - modules = {{method = root, path = {}}} - else - modules = self:getModules(root) - end - - local afterModules = tick() - - local plan = TestPlanner.createPlan(modules, noXpcallByDefault) - local afterPlan = tick() - - local results = TestRunner.runPlan(plan) - local afterRun = tick() - - reporter.report(results) - local afterReport = tick() - - if showTimingInfo then - local timing = { - ("Took %f seconds to locate test modules"):format(afterModules - startTime), - ("Took %f seconds to create test plan"):format(afterPlan - afterModules), - ("Took %f seconds to run tests"):format(afterRun - afterPlan), - ("Took %f seconds to report tests"):format(afterReport - afterRun), - } - - print(table.concat(timing, "\n")) - end - - return results -end - -return TestBootstrap \ No newline at end of file diff --git a/modules/testez/lib/TestEnum.lua b/modules/testez/lib/TestEnum.lua deleted file mode 100755 index 68fd276..0000000 --- a/modules/testez/lib/TestEnum.lua +++ /dev/null @@ -1,25 +0,0 @@ ---[[ - Constants used throughout the testing framework. -]] - -local TestEnum = {} - -TestEnum.TestStatus = { - Success = "Success", - Failure = "Failure", - Skipped = "Skipped" -} - -TestEnum.NodeType = { - Try = "Try", - Describe = "Describe", - It = "It" -} - -TestEnum.NodeModifier = { - None = "None", - Skip = "Skip", - Focus = "Focus" -} - -return TestEnum \ No newline at end of file diff --git a/modules/testez/lib/TestPlan.lua b/modules/testez/lib/TestPlan.lua deleted file mode 100755 index 237a07c..0000000 --- a/modules/testez/lib/TestPlan.lua +++ /dev/null @@ -1,102 +0,0 @@ ---[[ - Represents a tree of tests that have been loaded but not necessarily - executed yet. - - TestPlan objects are produced by TestPlanner and TestPlanBuilder. -]] - -local TestEnum = require(script.Parent.TestEnum) - -local TestPlan = {} - -TestPlan.__index = TestPlan - ---[[ - Create a new, empty TestPlan. -]] -function TestPlan.new() - local self = { - children = {} - } - - setmetatable(self, TestPlan) - - return self -end - ---[[ - Calls the given callback on all nodes in the tree, traversed depth-first. -]] -function TestPlan:visitAllNodes(callback, root) - root = root or self - - for _, child in ipairs(root.children) do - callback(child) - - self:visitAllNodes(callback, child) - end -end - ---[[ - Creates a new node that would be suitable to insert into the TestPlan. -]] -function TestPlan.createNode(phrase, nodeType, nodeModifier) - nodeModifier = nodeModifier or TestEnum.NodeModifier.None - - local node = { - phrase = phrase, - type = nodeType, - modifier = nodeModifier, - children = {}, - callback = nil - } - - return node -end - ---[[ - Visualizes the test plan in a simple format, suitable for debugging the test - plan's structure. -]] -function TestPlan:visualize(root, level) - root = root or self - level = level or 0 - - local buffer = {} - - for _, child in ipairs(root.children) do - if child.type == TestEnum.NodeType.It then - table.insert(buffer, (" "):rep(3 * level) .. child.phrase) - else - table.insert(buffer, (" "):rep(3 * level) .. child.phrase) - end - - if #child.children > 0 then - local text = self:visualize(child, level + 1) - table.insert(buffer, text) - end - end - - return table.concat(buffer, "\n") -end - ---[[ - Gets a list of all nodes in the tree for which the given callback returns - true. -]] -function TestPlan:findNodes(callback, results, node) - node = node or self - results = results or {} - - for _, childNode in ipairs(node.children) do - if callback(childNode) then - table.insert(results, childNode) - end - - self:findNodes(callback, results, childNode) - end - - return results -end - -return TestPlan \ No newline at end of file diff --git a/modules/testez/lib/TestPlanBuilder.lua b/modules/testez/lib/TestPlanBuilder.lua deleted file mode 100755 index 015f09c..0000000 --- a/modules/testez/lib/TestPlanBuilder.lua +++ /dev/null @@ -1,87 +0,0 @@ ---[[ - Represents the ephermal state used for building a TestPlan from some other - representation. - - TestPlanBuilder keeps track of a stack of nodes that represents the current - position in the hierarchy, allowing the consumer to move up and down the - tree as new nodes are discovered. -]] - -local TestPlan = require(script.Parent.TestPlan) - -local TestPlanBuilder = {} - -TestPlanBuilder.__index = TestPlanBuilder - ---[[ - Create a new TestPlanBuilder, used for creating a TestPlan. -]] -function TestPlanBuilder.new() - local self = { - plan = TestPlan.new(), - nodeStack = {}, - noXpcallByDefault = false, - } - - setmetatable(self, TestPlanBuilder) - - return self -end - ---[[ - Verify that the TestPlanBuilder's state is valid and get a TestPlan from it. -]] -function TestPlanBuilder:finalize() - if #self.nodeStack ~= 0 then - error("Cannot finalize a TestPlan with nodes still on the stack!", 2) - end - - return self.plan -end - ---[[ - Grab the current node being worked on by the TestPlanBuilder. -]] -function TestPlanBuilder:getCurrentNode() - return self.nodeStack[#self.nodeStack] or self.plan -end - ---[[ - Creates and pushes a node onto the navigation stack. -]] -function TestPlanBuilder:pushNode(phrase, nodeType, nodeModifier) - local lastNode = self.nodeStack[#self.nodeStack] or self.plan - - -- Find an existing node with this phrase to use - local useNode - for _, child in ipairs(lastNode.children) do - if child.phrase == phrase then - useNode = child - break - end - end - - -- Didn't find one, create a new node - if not useNode then - useNode = TestPlan.createNode(phrase, nodeType, nodeModifier) - useNode.parent = lastNode - - table.insert(lastNode.children, useNode) - end - - table.insert(self.nodeStack, useNode) - - useNode.HACK_NO_XPCALL = self.noXpcallByDefault - - return useNode -end - ---[[ - Pops a node off of the node navigation stack. -]] -function TestPlanBuilder:popNode() - assert(#self.nodeStack > 0, "Tried to pop from an empty node stack!") - return table.remove(self.nodeStack, #self.nodeStack) -end - -return TestPlanBuilder \ No newline at end of file diff --git a/modules/testez/lib/TestPlanner.lua b/modules/testez/lib/TestPlanner.lua deleted file mode 100755 index 7c58bb5..0000000 --- a/modules/testez/lib/TestPlanner.lua +++ /dev/null @@ -1,168 +0,0 @@ ---[[ - Turns a series of specification functions into a test plan. - - Uses a TestPlanBuilder to keep track of the state of the tree being built. -]] - -local TestEnum = require(script.Parent.TestEnum) -local TestPlanBuilder = require(script.Parent.TestPlanBuilder) - -local TestPlanner = {} - -local function buildPlan(builder, module, env) - local currentEnv = getfenv(module.method) - - for key, value in pairs(env) do - currentEnv[key] = value - end - - local nodeCount = #module.path - - -- Dive into auto-named nodes for this module - for i = nodeCount, 1, -1 do - local name = module.path[i] - builder:pushNode(name, TestEnum.NodeType.Describe) - end - - local ok, err = xpcall(module.method, function(err) - return err .. "\n" .. debug.traceback() - end) - - -- This is an error outside of any describe/it blocks. - -- We attach it to the node we generate automatically per-file. - if not ok then - local node = builder:getCurrentNode() - node.loadError = err - end - - -- Back out of auto-named nodes - for _ = 1, nodeCount do - builder:popNode() - end -end - ---[[ - Create a new environment with functions for defining the test plan structure - using the given TestPlanBuilder. - - These functions illustrate the advantage of the stack-style tree navigation - as state doesn't need to be passed around between functions or explicitly - global. -]] -function TestPlanner.createEnvironment(builder) - local env = {} - - function env.describe(phrase, callback) - local node = builder:pushNode(phrase, TestEnum.NodeType.Describe) - - local ok, err = pcall(callback) - - -- loadError on a TestPlan node is an automatic failure - if not ok then - node.loadError = err - end - - builder:popNode() - end - - function env.try(phrase, callback) - local node = builder:pushNode(phrase, TestEnum.NodeType.Try) - - local ok, err = pcall(callback) - - -- loadError on a TestPlan node is an automatic failure - if not ok then - node.loadError = err - end - - builder:popNode() - end - - function env.it(phrase, callback) - local node = builder:pushNode(phrase, TestEnum.NodeType.It) - - node.callback = callback - - builder:popNode() - end - - function env.itFOCUS(phrase, callback) - local node = builder:pushNode(phrase, TestEnum.NodeType.It, TestEnum.NodeModifier.Focus) - - node.callback = callback - - builder:popNode() - end - - function env.itSKIP(phrase, callback) - local node = builder:pushNode(phrase, TestEnum.NodeType.It, TestEnum.NodeModifier.Skip) - - node.callback = callback - - builder:popNode() - end - - function env.FOCUS() - local currentNode = builder:getCurrentNode() - - currentNode.modifier = TestEnum.NodeModifier.Focus - end - - function env.SKIP() - local currentNode = builder:getCurrentNode() - - currentNode.modifier = TestEnum.NodeModifier.Skip - end - - --[[ - These method is intended to disable the use of xpcall when running - nodes contained in the same node that this function is called in. - This is because xpcall breaks badly if the method passed yields. - - This function is intended to be hideous and seldom called. - - Once xpcall is able to yield, this function is obsolete. - ]] - function env.HACK_NO_XPCALL() - local currentNode = builder:getCurrentNode() - - currentNode.HACK_NO_XPCALL = true - end - - env.step = env.it - - function env.include(...) - local args = {...} - local method, path - if #args == 1 then - method = args[1] - path = {} - elseif #args == 2 then - method = args[2] - path = {args[1]} - end - buildPlan(builder, {path = path, method = method}, env) - end - - return env -end - ---[[ - Create a new TestPlan from a list of specification functions. - - These functions should call a combination of `describe` and `it` (and their - variants), which will be turned into a test plan to be executed. -]] -function TestPlanner.createPlan(specFunctions, noXpcallByDefault) - local builder = TestPlanBuilder.new() - builder.noXpcallByDefault = noXpcallByDefault - local env = TestPlanner.createEnvironment(builder) - - for _, module in ipairs(specFunctions) do - buildPlan(builder, module, env) - end - - return builder:finalize() -end - -return TestPlanner \ No newline at end of file diff --git a/modules/testez/lib/TestResults.lua b/modules/testez/lib/TestResults.lua deleted file mode 100755 index ab8924c..0000000 --- a/modules/testez/lib/TestResults.lua +++ /dev/null @@ -1,112 +0,0 @@ ---[[ - Represents a tree of test results. - - Each node in the tree corresponds directly to a node in a corresponding - TestPlan, accessible via the 'planNode' field. - - TestResults objects are produced by TestRunner using TestSession as state. -]] - -local TestEnum = require(script.Parent.TestEnum) - -local STATUS_SYMBOLS = { - [TestEnum.TestStatus.Success] = "+", - [TestEnum.TestStatus.Failure] = "-", - [TestEnum.TestStatus.Skipped] = "~" -} - -local TestResults = {} - -TestResults.__index = TestResults - ---[[ - Create a new TestResults tree that's linked to the given TestPlan. -]] -function TestResults.new(plan) - local self = { - successCount = 0, - failureCount = 0, - skippedCount = 0, - planNode = plan, - children = {}, - errors = {} - } - - setmetatable(self, TestResults) - - return self -end - ---[[ - Create a new result node that can be inserted into a TestResult tree. -]] -function TestResults.createNode(planNode) - local node = { - planNode = planNode, - children = {}, - errors = {}, - status = nil - } - - return node -end - ---[[ - Visit all test result nodes, depth-first. -]] -function TestResults:visitAllNodes(callback, root) - root = root or self - - for _, child in ipairs(root.children) do - callback(child) - - self:visitAllNodes(callback, child) - end -end - ---[[ - Creates a debug visualization of the test results. -]] -function TestResults:visualize(root, level) - root = root or self - level = level or 0 - - local buffer = {} - - for _, child in ipairs(root.children) do - if child.planNode.type == TestEnum.NodeType.It then - local symbol = STATUS_SYMBOLS[child.status] or "?" - local str = ("%s[%s] %s"):format( - (" "):rep(3 * level), - symbol, - child.planNode.phrase - ) - - if #child.messages > 0 then - str = str .. "\n " .. (" "):rep(3 * level) .. table.concat(child.messages, "\n " .. (" "):rep(3 * level)) - end - - table.insert(buffer, str) - else - local str = ("%s%s"):format( - (" "):rep(3 * level), - child.planNode.phrase - ) - - if child.status then - str = str .. (" (%s)"):format(child.status) - end - - table.insert(buffer, str) - - if #child.children > 0 then - local text = self:visualize(child, level + 1) - table.insert(buffer, text) - end - end - end - - return table.concat(buffer, "\n") -end - -return TestResults \ No newline at end of file diff --git a/modules/testez/lib/TestRunner.lua b/modules/testez/lib/TestRunner.lua deleted file mode 100755 index 8f7b806..0000000 --- a/modules/testez/lib/TestRunner.lua +++ /dev/null @@ -1,152 +0,0 @@ ---[[ - Contains the logic to run a test plan and gather test results from it. - - TestRunner accepts a TestPlan object, executes the planned tests, and - produces a TestResults object. While the tests are running, the system's - state is contained inside a TestSession object. -]] - -local Expectation = require(script.Parent.Expectation) -local TestEnum = require(script.Parent.TestEnum) -local TestSession = require(script.Parent.TestSession) -local Stack = require(script.Parent.Stack) - -local RUNNING_GLOBAL = "__TESTEZ_RUNNING_TEST__" - -local TestRunner = { - environment = {} -} - -function TestRunner.environment.expect(...) - return Expectation.new(...) -end - ---[[ - Runs the given TestPlan and returns a TestResults object representing the - results of the run. -]] -function TestRunner.runPlan(plan) - local session = TestSession.new(plan) - local tryStack = Stack.new() - - local exclusiveNodes = plan:findNodes(function(node) - return node.modifier == TestEnum.NodeModifier.Focus - end) - - session.hasFocusNodes = #exclusiveNodes > 0 - - TestRunner.runPlanNode(session, plan, tryStack) - - return session:finalize() -end - ---[[ - Run the given test plan node and its descendants, using the given test - session to store all of the results. -]] -function TestRunner.runPlanNode(session, planNode, tryStack, noXpcall) - for _, childPlanNode in ipairs(planNode.children) do - local childResultNode = session:pushNode(childPlanNode) - - if childPlanNode.type == TestEnum.NodeType.It then - if session:shouldSkip() then - childResultNode.status = TestEnum.TestStatus.Skipped - else - if tryStack:size() > 0 and tryStack:getBack().isOk == false then - childResultNode.status = TestEnum.TestStatus.Failure - table.insert(childResultNode.errors, - string.format("%q failed without trying, because test case %q failed", - childPlanNode.phrase, tryStack:getBack().failedNode.phrase)) - else - -- Errors can be set either via `error` propagating upwards or - -- by a test calling fail([message]). - local success = true - local errorMessage - - local testEnvironment = getfenv(childPlanNode.callback) - - for key, value in pairs(TestRunner.environment) do - testEnvironment[key] = value - end - - testEnvironment.fail = function(message) - if message == nil then - message = "fail() was called." - end - - success = false - errorMessage = message .. "\n" .. debug.traceback() - end - - -- We prefer xpcall, but yielding doesn't work from xpcall. - -- As a workaround, you can mark nodes as "not xpcallable" - local call = noXpcall and pcall or xpcall - - -- Any code can check RUNNING_GLOBAL to fork behavior based on - -- whether a test is running. We use this to avoid accessing - -- protected APIs; it's a workaround that will go away someday. - _G[RUNNING_GLOBAL] = true - - local nodeSuccess, nodeResult = call(childPlanNode.callback, function(message) - return message .. "\n" .. debug.traceback() - end) - - _G[RUNNING_GLOBAL] = nil - - -- If a node threw an error, we prefer to use that message over - -- one created by fail() if it was set. - if not nodeSuccess then - success = false - errorMessage = nodeResult - end - - if success then - childResultNode.status = TestEnum.TestStatus.Success - else - childResultNode.status = TestEnum.TestStatus.Failure - table.insert(childResultNode.errors, errorMessage) - end - end - end - elseif childPlanNode.type == TestEnum.NodeType.Describe or childPlanNode.type == TestEnum.NodeType.Try then - if childPlanNode.type == TestEnum.NodeType.Try then tryStack:push({isOk = true, failedNode = nil}) end - TestRunner.runPlanNode(session, childPlanNode, tryStack, childPlanNode.HACK_NO_XPCALL) - if childPlanNode.type == TestEnum.NodeType.Try then tryStack:pop() end - - local status = TestEnum.TestStatus.Success - - -- Did we have an error trying build a test plan? - if childPlanNode.loadError then - status = TestEnum.TestStatus.Failure - - local message = "Error during planning: " .. childPlanNode.loadError - - table.insert(childResultNode.errors, message) - else - local skipped = true - - -- If all children were skipped, then we were skipped - -- If any child failed, then we failed! - for _, child in ipairs(childResultNode.children) do - if child.status ~= TestEnum.TestStatus.Skipped then - skipped = false - - if child.status == TestEnum.TestStatus.Failure then - status = TestEnum.TestStatus.Failure - end - end - end - - if skipped then - status = TestEnum.TestStatus.Skipped - end - end - - childResultNode.status = status - end - - session:popNode() - end -end - -return TestRunner \ No newline at end of file diff --git a/modules/testez/lib/TestSession.lua b/modules/testez/lib/TestSession.lua deleted file mode 100755 index 203cc08..0000000 --- a/modules/testez/lib/TestSession.lua +++ /dev/null @@ -1,149 +0,0 @@ ---[[ - Represents the state relevant while executing a test plan. - - Used by TestRunner to produce a TestResults object. - - Uses the same tree building structure as TestPlanBuilder; TestSession keeps - track of a stack of nodes that represent the current path through the tree. -]] - -local TestEnum = require(script.Parent.TestEnum) -local TestResults = require(script.Parent.TestResults) - -local TestSession = {} - -TestSession.__index = TestSession - ---[[ - Create a TestSession related to the given TestPlan. - - The resulting TestResults object will be linked to this TestPlan. -]] -function TestSession.new(plan) - local self = { - results = TestResults.new(plan), - nodeStack = {}, - hasFocusNodes = false - } - - setmetatable(self, TestSession) - - return self -end - ---[[ - Calculate success, failure, and skipped test counts in the tree at the - current point in the execution. -]] -function TestSession:calculateTotals() - local results = self.results - - results.successCount = 0 - results.failureCount = 0 - results.skippedCount = 0 - - results:visitAllNodes(function(node) - local status = node.status - local nodeType = node.planNode.type - - if nodeType == TestEnum.NodeType.It then - if status == TestEnum.TestStatus.Success then - results.successCount = results.successCount + 1 - elseif status == TestEnum.TestStatus.Failure then - results.failureCount = results.failureCount + 1 - elseif status == TestEnum.TestStatus.Skipped then - results.skippedCount = results.skippedCount + 1 - end - end - end) -end - ---[[ - Gathers all of the errors reported by tests and puts them at the top level - of the TestResults object. -]] -function TestSession:gatherErrors() - local results = self.results - - results.errors = {} - - results:visitAllNodes(function(node) - if #node.errors > 0 then - for _, message in ipairs(node.errors) do - table.insert(results.errors, message) - end - end - end) -end - ---[[ - Calculates test totals, verifies the tree is valid, and returns results. -]] -function TestSession:finalize() - if #self.nodeStack ~= 0 then - error("Cannot finalize TestResults with nodes still on the stack!", 2) - end - - self:calculateTotals() - self:gatherErrors() - - return self.results -end - ---[[ - Create a new test result node and push it onto the navigation stack. -]] -function TestSession:pushNode(planNode) - local node = TestResults.createNode(planNode) - - local lastNode = self.nodeStack[#self.nodeStack] or self.results - - table.insert(lastNode.children, node) - table.insert(self.nodeStack, node) - - return node -end - ---[[ - Pops a node off of the navigation stack. -]] -function TestSession:popNode() - assert(#self.nodeStack > 0, "Tried to pop from an empty node stack!") - return table.remove(self.nodeStack, #self.nodeStack) -end - ---[[ - Tells whether the current test we're in should be skipped. -]] -function TestSession:shouldSkip() - -- If our test tree had any exclusive tests, then normal tests are skipped! - if self.hasFocusNodes then - for i = #self.nodeStack, 1, -1 do - local node = self.nodeStack[i] - - -- Skipped tests are still skipped - if node.planNode.modifier == TestEnum.NodeModifier.Skip then - return true - end - - -- Focused tests are the only ones that aren't skipped - if node.planNode.modifier == TestEnum.NodeModifier.Focus then - return false - end - end - - return true - else - for i = #self.nodeStack, 1, -1 do - local node = self.nodeStack[i] - - if node.planNode.modifier == TestEnum.NodeModifier.Skip then - return true - end - end - end - - return false -end - -return TestSession \ No newline at end of file diff --git a/modules/testez/lib/init.lua b/modules/testez/lib/init.lua deleted file mode 100755 index 326dcfe..0000000 --- a/modules/testez/lib/init.lua +++ /dev/null @@ -1,40 +0,0 @@ -local Expectation = require(script.Expectation) -local TestBootstrap = require(script.TestBootstrap) -local TestEnum = require(script.TestEnum) -local TestPlan = require(script.TestPlan) -local TestPlanBuilder = require(script.TestPlanBuilder) -local TestPlanner = require(script.TestPlanner) -local TestResults = require(script.TestResults) -local TestRunner = require(script.TestRunner) -local TestSession = require(script.TestSession) -local TextReporter = require(script.Reporters.TextReporter) -local TeamCityReporter = require(script.Reporters.TeamCityReporter) - -local function run(testRoot, callback) - local modules = TestBootstrap:getModules(testRoot) - local plan = TestPlanner.createPlan(modules) - local results = TestRunner.runPlan(plan) - - callback(results) -end - -local TestEZ = { - run = run, - - Expectation = Expectation, - TestBootstrap = TestBootstrap, - TestEnum = TestEnum, - TestPlan = TestPlan, - TestPlanBuilder = TestPlanBuilder, - TestPlanner = TestPlanner, - TestResults = TestResults, - TestRunner = TestRunner, - TestSession = TestSession, - - Reporters = { - TextReporter = TextReporter, - TeamCityReporter = TeamCityReporter, - }, -} - -return TestEZ \ No newline at end of file diff --git a/modules/testez/mkdocs.yml b/modules/testez/mkdocs.yml deleted file mode 100755 index 424fa05..0000000 --- a/modules/testez/mkdocs.yml +++ /dev/null @@ -1,27 +0,0 @@ -site_name: TestEZ Documentation -site_url: https://roblox.github.io/testez/ -repo_name: Roblox/testez -repo_url: https://github.com/Roblox/testez - -theme: - name: material - palette: - primary: 'Light Blue' - accent: 'Light Blue' - -pages: - - Home: index.md - - Getting Started: - - Installation: getting-started/installation.md - - Running Tests: getting-started/running-tests.md - - Writing Tests: getting-started/writing-tests.md - - Debugging Tests: getting-started/debugging-tests.md - - API Reference: api-reference.md - -markdown_extensions: - - admonition - - codehilite: - guess_lang: false - - toc: - permalink: true - - pymdownx.superfences \ No newline at end of file diff --git a/modules/testez/spec.lua b/modules/testez/spec.lua deleted file mode 100755 index 592b406..0000000 --- a/modules/testez/spec.lua +++ /dev/null @@ -1,99 +0,0 @@ -local LOAD_MODULES = { - {"lib", "TestEZ"}, - {"tests", "TestEZTests"}, -} - --- This makes sure we can load Lemur and other libraries that depend on init.lua -package.path = package.path .. ";?/init.lua" - --- If this fails, make sure you've cloned all Git submodules. -local lemur = require("modules.lemur") - ---[[ - Collapses ModuleScripts named 'init' into their parent folders. - - This is the same behavior as Rojo. -]] -local function collapse(root) - local init = root:FindFirstChild("init") - if init then - init.Name = root.Name - init.Parent = root.Parent - - for _, child in ipairs(root:GetChildren()) do - child.Parent = init - end - - root:Destroy() - root = init - end - - for _, child in ipairs(root:GetChildren()) do - if child:IsA("Folder") then - collapse(child) - end - end - - return root -end - -local habitat = lemur.Habitat.new() - -local root = lemur.Instance.new("Folder") -root.Name = "Root" - -for _, module in ipairs(LOAD_MODULES) do - local container = habitat:loadFromFs(module[1]) - container.Name = module[2] - container.Parent = root -end - -root = collapse(root) - -local function findUnitTests(container, foundTests) - foundTests = foundTests or {} - - for _, child in ipairs(container:GetChildren()) do - if child.Name:match("%.spec$") then - table.insert(foundTests, child) - end - - findUnitTests(child, foundTests) - end - - return foundTests -end - -local function findIntegrationTests(container, foundTests) - foundTests = foundTests or {} - - for _, child in ipairs(container:GetChildren()) do - if child:IsA("ModuleScript") then - table.insert(foundTests, child) - end - - findUnitTests(child, foundTests) - end - - return foundTests -end - --- Run all unit tests, which are located in .spec.lua files next to the source -local unitTests = findUnitTests(root.TestEZ) -print(("Running %d unit tests..."):format(#unitTests)) - --- Unit tests are expected to load individual files relative to themselves -for _, test in ipairs(unitTests) do - habitat:require(test)() -end - --- Run all integration tests, which are located in the 'tests' folder -local integrationTests = findIntegrationTests(root.TestEZTests) -print(("Running %d integration tests..."):format(#integrationTests)) - --- Integration tests should be passed the root TestEZ object -for _, test in ipairs(integrationTests) do - habitat:require(test)(habitat:require(root.TestEZ)) -end - -print("All tests passed.") \ No newline at end of file diff --git a/modules/testez/tests/api.lua b/modules/testez/tests/api.lua deleted file mode 100755 index f32025c..0000000 --- a/modules/testez/tests/api.lua +++ /dev/null @@ -1,4 +0,0 @@ -return function(TestEZ) - assert(typeof(TestEZ) == "table") - assert(typeof(TestEZ.run) == "function") -end \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..c8537c3 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "@rbxts/lua-linalg", + "lockfileVersion": 2, + "requires": true, + "packages": {} +} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..b549a37 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +toml == 0.10.2 \ No newline at end of file diff --git a/roblox-testez.toml b/roblox-testez.toml new file mode 100644 index 0000000..b277aa6 --- /dev/null +++ b/roblox-testez.toml @@ -0,0 +1,24 @@ +[selene] +base = "roblox" +name = "roblox-testez" + +[describe] +[[describe.args]] +type = "string" +required = true + +[[describe.args]] +type = "function" +required = true + +[[it.args]] +type = "string" +required = true + +[[it.args]] +type = "function" +required = true + +[[expect.args]] +type = "any" +required = true diff --git a/roblox.toml b/roblox.toml new file mode 100644 index 0000000..b4b3be2 --- /dev/null +++ b/roblox.toml @@ -0,0 +1,8105 @@ +# This file was @generated by generate-roblox-std +[selene] +base = "lua51" +name = "roblox" +[selene.structs.BasePart."*"] +struct = "Instance" + +[selene.structs.BasePart.AncestryChanged] +struct = "Event" + +[selene.structs.BasePart.Anchored] +property = true +writable = "overridden" + +[selene.structs.BasePart.Archivable] +property = true +writable = "overridden" + +[selene.structs.BasePart.AttributeChanged] +struct = "Event" + +[selene.structs.BasePart.BackParamA] +property = true +writable = "overridden" + +[selene.structs.BasePart.BackParamB] +property = true +writable = "overridden" + +[selene.structs.BasePart.BackSurface] +property = true +writable = "overridden" + +[selene.structs.BasePart.BackSurfaceInput] +property = true +writable = "overridden" + +[selene.structs.BasePart.BottomParamA] +property = true +writable = "overridden" + +[selene.structs.BasePart.BottomParamB] +property = true +writable = "overridden" + +[selene.structs.BasePart.BottomSurface] +property = true +writable = "overridden" + +[selene.structs.BasePart.BottomSurfaceInput] +property = true +writable = "overridden" + +[selene.structs.BasePart.BreakJoints] +method = true +args = [] + +[selene.structs.BasePart.BrickColor] +property = true +writable = "overridden" + +[selene.structs.BasePart.CFrame] +property = true +writable = "overridden" + +[selene.structs.BasePart.CanCollide] +property = true +writable = "overridden" + +[selene.structs.BasePart.CanCollideWith] +method = true + +[[selene.structs.BasePart.CanCollideWith.args]] +required = false +type = "any" + +[selene.structs.BasePart.CanSetNetworkOwnership] +method = true +args = [] + +[selene.structs.BasePart.CastShadow] +property = true +writable = "overridden" + +[selene.structs.BasePart.CenterOfMass] +property = true + +[selene.structs.BasePart.Changed] +struct = "Event" + +[selene.structs.BasePart.ChildAdded] +struct = "Event" + +[selene.structs.BasePart.ChildRemoved] +struct = "Event" + +[selene.structs.BasePart.ClassName] +property = true + +[selene.structs.BasePart.ClearAllChildren] +method = true +args = [] + +[selene.structs.BasePart.Clone] +method = true +args = [] + +[selene.structs.BasePart.CollisionGroupId] +property = true +writable = "overridden" + +[selene.structs.BasePart.Color] +property = true +writable = "overridden" + +[selene.structs.BasePart.CustomPhysicalProperties] +property = true +writable = "overridden" + +[selene.structs.BasePart.DescendantAdded] +struct = "Event" + +[selene.structs.BasePart.DescendantRemoving] +struct = "Event" + +[selene.structs.BasePart.Destroy] +method = true +args = [] + +[selene.structs.BasePart.FindFirstAncestor] +method = true + +[[selene.structs.BasePart.FindFirstAncestor.args]] +required = false +type = "any" + +[selene.structs.BasePart.FindFirstAncestorOfClass] +method = true + +[[selene.structs.BasePart.FindFirstAncestorOfClass.args]] +required = false +type = "any" + +[selene.structs.BasePart.FindFirstAncestorWhichIsA] +method = true + +[[selene.structs.BasePart.FindFirstAncestorWhichIsA.args]] +required = false +type = "any" + +[selene.structs.BasePart.FindFirstChild] +method = true + +[[selene.structs.BasePart.FindFirstChild.args]] +required = false +type = "any" + +[[selene.structs.BasePart.FindFirstChild.args]] +required = false +type = "any" + +[selene.structs.BasePart.FindFirstChildOfClass] +method = true + +[[selene.structs.BasePart.FindFirstChildOfClass.args]] +required = false +type = "any" + +[selene.structs.BasePart.FindFirstChildWhichIsA] +method = true + +[[selene.structs.BasePart.FindFirstChildWhichIsA.args]] +required = false +type = "any" + +[[selene.structs.BasePart.FindFirstChildWhichIsA.args]] +required = false +type = "any" + +[selene.structs.BasePart.FrontParamA] +property = true +writable = "overridden" + +[selene.structs.BasePart.FrontParamB] +property = true +writable = "overridden" + +[selene.structs.BasePart.FrontSurface] +property = true +writable = "overridden" + +[selene.structs.BasePart.FrontSurfaceInput] +property = true +writable = "overridden" + +[selene.structs.BasePart.GetAttribute] +method = true + +[[selene.structs.BasePart.GetAttribute.args]] +required = false +type = "any" + +[selene.structs.BasePart.GetAttributeChangedSignal] +method = true + +[[selene.structs.BasePart.GetAttributeChangedSignal.args]] +required = false +type = "any" + +[selene.structs.BasePart.GetAttributes] +method = true +args = [] + +[selene.structs.BasePart.GetChildren] +method = true +args = [] + +[selene.structs.BasePart.GetConnectedParts] +method = true + +[[selene.structs.BasePart.GetConnectedParts.args]] +required = false +type = "any" + +[selene.structs.BasePart.GetDebugId] +method = true + +[[selene.structs.BasePart.GetDebugId.args]] +required = false +type = "any" + +[selene.structs.BasePart.GetDescendants] +method = true +args = [] + +[selene.structs.BasePart.GetFullName] +method = true +args = [] + +[selene.structs.BasePart.GetJoints] +method = true +args = [] + +[selene.structs.BasePart.GetMass] +method = true +args = [] + +[selene.structs.BasePart.GetNetworkOwner] +method = true +args = [] + +[selene.structs.BasePart.GetNetworkOwnershipAuto] +method = true +args = [] + +[selene.structs.BasePart.GetPropertyChangedSignal] +method = true + +[[selene.structs.BasePart.GetPropertyChangedSignal.args]] +required = false +type = "any" + +[selene.structs.BasePart.GetRootPart] +method = true +args = [] + +[selene.structs.BasePart.GetTouchingParts] +method = true +args = [] + +[selene.structs.BasePart.IsA] +method = true + +[[selene.structs.BasePart.IsA.args]] +required = false +type = "any" + +[selene.structs.BasePart.IsAncestorOf] +method = true + +[[selene.structs.BasePart.IsAncestorOf.args]] +required = false +type = "any" + +[selene.structs.BasePart.IsDescendantOf] +method = true + +[[selene.structs.BasePart.IsDescendantOf.args]] +required = false +type = "any" + +[selene.structs.BasePart.IsGrounded] +method = true +args = [] + +[selene.structs.BasePart.LeftParamA] +property = true +writable = "overridden" + +[selene.structs.BasePart.LeftParamB] +property = true +writable = "overridden" + +[selene.structs.BasePart.LeftSurface] +property = true +writable = "overridden" + +[selene.structs.BasePart.LeftSurfaceInput] +property = true +writable = "overridden" + +[selene.structs.BasePart.LocalTransparencyModifier] +property = true +writable = "overridden" + +[selene.structs.BasePart.Locked] +property = true +writable = "overridden" + +[selene.structs.BasePart.MakeJoints] +method = true +args = [] + +[selene.structs.BasePart.Mass] +property = true + +[selene.structs.BasePart.Massless] +property = true +writable = "overridden" + +[selene.structs.BasePart.Material] +property = true +writable = "overridden" + +[selene.structs.BasePart.Name] +property = true +writable = "overridden" + +[selene.structs.BasePart.Orientation] +property = true +writable = "overridden" + +[selene.structs.BasePart.Parent] +struct = "Instance" + +[selene.structs.BasePart.Position] +property = true +writable = "overridden" + +[selene.structs.BasePart.ReceiveAge] +property = true + +[selene.structs.BasePart.Reflectance] +property = true +writable = "overridden" + +[selene.structs.BasePart.Resize] +method = true + +[[selene.structs.BasePart.Resize.args]] +required = false +type = "any" + +[[selene.structs.BasePart.Resize.args]] +required = false +type = "any" + +[selene.structs.BasePart.ResizeIncrement] +property = true + +[selene.structs.BasePart.ResizeableFaces] +property = true + +[selene.structs.BasePart.RightParamA] +property = true +writable = "overridden" + +[selene.structs.BasePart.RightParamB] +property = true +writable = "overridden" + +[selene.structs.BasePart.RightSurface] +property = true +writable = "overridden" + +[selene.structs.BasePart.RightSurfaceInput] +property = true +writable = "overridden" + +[selene.structs.BasePart.RootPriority] +property = true +writable = "overridden" + +[selene.structs.BasePart.RotVelocity] +property = true +writable = "overridden" + +[selene.structs.BasePart.Rotation] +property = true +writable = "overridden" + +[selene.structs.BasePart.SetAttribute] +method = true + +[[selene.structs.BasePart.SetAttribute.args]] +required = false +type = "any" + +[[selene.structs.BasePart.SetAttribute.args]] +required = false +type = "any" + +[selene.structs.BasePart.SetNetworkOwner] +method = true + +[[selene.structs.BasePart.SetNetworkOwner.args]] +required = false +type = "any" + +[selene.structs.BasePart.SetNetworkOwnershipAuto] +method = true +args = [] + +[selene.structs.BasePart.Size] +property = true +writable = "overridden" + +[selene.structs.BasePart.SubtractAsync] +method = true + +[[selene.structs.BasePart.SubtractAsync.args]] +required = false +type = "any" + +[[selene.structs.BasePart.SubtractAsync.args]] +required = false +type = "any" + +[[selene.structs.BasePart.SubtractAsync.args]] +required = false +type = "any" + +[selene.structs.BasePart.TopParamA] +property = true +writable = "overridden" + +[selene.structs.BasePart.TopParamB] +property = true +writable = "overridden" + +[selene.structs.BasePart.TopSurface] +property = true +writable = "overridden" + +[selene.structs.BasePart.TopSurfaceInput] +property = true +writable = "overridden" + +[selene.structs.BasePart.TouchEnded] +struct = "Event" + +[selene.structs.BasePart.Touched] +struct = "Event" + +[selene.structs.BasePart.Transparency] +property = true +writable = "overridden" + +[selene.structs.BasePart.UnionAsync] +method = true + +[[selene.structs.BasePart.UnionAsync.args]] +required = false +type = "any" + +[[selene.structs.BasePart.UnionAsync.args]] +required = false +type = "any" + +[[selene.structs.BasePart.UnionAsync.args]] +required = false +type = "any" + +[selene.structs.BasePart.Velocity] +property = true +writable = "overridden" + +[selene.structs.BasePart.WaitForChild] +method = true + +[[selene.structs.BasePart.WaitForChild.args]] +required = false +type = "any" + +[[selene.structs.BasePart.WaitForChild.args]] +required = false +type = "any" +[selene.structs.Camera."*"] +struct = "Instance" + +[selene.structs.Camera.AncestryChanged] +struct = "Event" + +[selene.structs.Camera.Archivable] +property = true +writable = "overridden" + +[selene.structs.Camera.AttributeChanged] +struct = "Event" + +[selene.structs.Camera.CFrame] +property = true +writable = "overridden" + +[selene.structs.Camera.CameraSubject] +struct = "Instance" + +[selene.structs.Camera.CameraType] +property = true +writable = "overridden" + +[selene.structs.Camera.Changed] +struct = "Event" + +[selene.structs.Camera.ChildAdded] +struct = "Event" + +[selene.structs.Camera.ChildRemoved] +struct = "Event" + +[selene.structs.Camera.ClassName] +property = true + +[selene.structs.Camera.ClearAllChildren] +method = true +args = [] + +[selene.structs.Camera.Clone] +method = true +args = [] + +[selene.structs.Camera.DescendantAdded] +struct = "Event" + +[selene.structs.Camera.DescendantRemoving] +struct = "Event" + +[selene.structs.Camera.Destroy] +method = true +args = [] + +[selene.structs.Camera.FieldOfView] +property = true +writable = "overridden" + +[selene.structs.Camera.FindFirstAncestor] +method = true + +[[selene.structs.Camera.FindFirstAncestor.args]] +required = false +type = "any" + +[selene.structs.Camera.FindFirstAncestorOfClass] +method = true + +[[selene.structs.Camera.FindFirstAncestorOfClass.args]] +required = false +type = "any" + +[selene.structs.Camera.FindFirstAncestorWhichIsA] +method = true + +[[selene.structs.Camera.FindFirstAncestorWhichIsA.args]] +required = false +type = "any" + +[selene.structs.Camera.FindFirstChild] +method = true + +[[selene.structs.Camera.FindFirstChild.args]] +required = false +type = "any" + +[[selene.structs.Camera.FindFirstChild.args]] +required = false +type = "any" + +[selene.structs.Camera.FindFirstChildOfClass] +method = true + +[[selene.structs.Camera.FindFirstChildOfClass.args]] +required = false +type = "any" + +[selene.structs.Camera.FindFirstChildWhichIsA] +method = true + +[[selene.structs.Camera.FindFirstChildWhichIsA.args]] +required = false +type = "any" + +[[selene.structs.Camera.FindFirstChildWhichIsA.args]] +required = false +type = "any" + +[selene.structs.Camera.FirstPersonTransition] +struct = "Event" + +[selene.structs.Camera.Focus] +property = true +writable = "overridden" + +[selene.structs.Camera.GetAttribute] +method = true + +[[selene.structs.Camera.GetAttribute.args]] +required = false +type = "any" + +[selene.structs.Camera.GetAttributeChangedSignal] +method = true + +[[selene.structs.Camera.GetAttributeChangedSignal.args]] +required = false +type = "any" + +[selene.structs.Camera.GetAttributes] +method = true +args = [] + +[selene.structs.Camera.GetChildren] +method = true +args = [] + +[selene.structs.Camera.GetDebugId] +method = true + +[[selene.structs.Camera.GetDebugId.args]] +required = false +type = "any" + +[selene.structs.Camera.GetDescendants] +method = true +args = [] + +[selene.structs.Camera.GetFullName] +method = true +args = [] + +[selene.structs.Camera.GetPanSpeed] +method = true +args = [] + +[selene.structs.Camera.GetPartsObscuringTarget] +method = true + +[[selene.structs.Camera.GetPartsObscuringTarget.args]] +required = false +type = "any" + +[[selene.structs.Camera.GetPartsObscuringTarget.args]] +required = false +type = "any" + +[selene.structs.Camera.GetPropertyChangedSignal] +method = true + +[[selene.structs.Camera.GetPropertyChangedSignal.args]] +required = false +type = "any" + +[selene.structs.Camera.GetRenderCFrame] +method = true +args = [] + +[selene.structs.Camera.GetRoll] +method = true +args = [] + +[selene.structs.Camera.GetTiltSpeed] +method = true +args = [] + +[selene.structs.Camera.HeadLocked] +property = true +writable = "overridden" + +[selene.structs.Camera.HeadScale] +property = true +writable = "overridden" + +[selene.structs.Camera.InterpolationFinished] +struct = "Event" + +[selene.structs.Camera.IsA] +method = true + +[[selene.structs.Camera.IsA.args]] +required = false +type = "any" + +[selene.structs.Camera.IsAncestorOf] +method = true + +[[selene.structs.Camera.IsAncestorOf.args]] +required = false +type = "any" + +[selene.structs.Camera.IsDescendantOf] +method = true + +[[selene.structs.Camera.IsDescendantOf.args]] +required = false +type = "any" + +[selene.structs.Camera.Name] +property = true +writable = "overridden" + +[selene.structs.Camera.NearPlaneZ] +property = true + +[selene.structs.Camera.Parent] +struct = "Instance" + +[selene.structs.Camera.ScreenPointToRay] +method = true + +[[selene.structs.Camera.ScreenPointToRay.args]] +required = false +type = "any" + +[[selene.structs.Camera.ScreenPointToRay.args]] +required = false +type = "any" + +[[selene.structs.Camera.ScreenPointToRay.args]] +required = false +type = "any" + +[selene.structs.Camera.SetAttribute] +method = true + +[[selene.structs.Camera.SetAttribute.args]] +required = false +type = "any" + +[[selene.structs.Camera.SetAttribute.args]] +required = false +type = "any" + +[selene.structs.Camera.SetCameraPanMode] +method = true + +[[selene.structs.Camera.SetCameraPanMode.args]] +required = false +type = "any" + +[selene.structs.Camera.SetImageServerView] +method = true + +[[selene.structs.Camera.SetImageServerView.args]] +required = false +type = "any" + +[selene.structs.Camera.SetRoll] +method = true + +[[selene.structs.Camera.SetRoll.args]] +required = false +type = "any" + +[selene.structs.Camera.ViewportPointToRay] +method = true + +[[selene.structs.Camera.ViewportPointToRay.args]] +required = false +type = "any" + +[[selene.structs.Camera.ViewportPointToRay.args]] +required = false +type = "any" + +[[selene.structs.Camera.ViewportPointToRay.args]] +required = false +type = "any" + +[selene.structs.Camera.ViewportSize] +property = true + +[selene.structs.Camera.WaitForChild] +method = true + +[[selene.structs.Camera.WaitForChild.args]] +required = false +type = "any" + +[[selene.structs.Camera.WaitForChild.args]] +required = false +type = "any" + +[selene.structs.Camera.WorldToScreenPoint] +method = true + +[[selene.structs.Camera.WorldToScreenPoint.args]] +required = false +type = "any" + +[selene.structs.Camera.WorldToViewportPoint] +method = true + +[[selene.structs.Camera.WorldToViewportPoint.args]] +required = false +type = "any" + +[selene.structs.Camera.Zoom] +method = true + +[[selene.structs.Camera.Zoom.args]] +required = false +type = "any" +[selene.structs.DataModel."*"] +struct = "Instance" + +[selene.structs.DataModel.AncestryChanged] +struct = "Event" + +[selene.structs.DataModel.Archivable] +property = true +writable = "overridden" + +[selene.structs.DataModel.AttributeChanged] +struct = "Event" + +[selene.structs.DataModel.BindToClose] +method = true + +[[selene.structs.DataModel.BindToClose.args]] +required = false +type = "any" + +[selene.structs.DataModel.Changed] +struct = "Event" + +[selene.structs.DataModel.ChildAdded] +struct = "Event" + +[selene.structs.DataModel.ChildRemoved] +struct = "Event" + +[selene.structs.DataModel.ClassName] +property = true + +[selene.structs.DataModel.ClearAllChildren] +method = true +args = [] + +[selene.structs.DataModel.Clone] +method = true +args = [] + +[selene.structs.DataModel.Close] +struct = "Event" + +[selene.structs.DataModel.CloseLate] +struct = "Event" + +[selene.structs.DataModel.CreatorId] +property = true + +[selene.structs.DataModel.CreatorType] +property = true + +[selene.structs.DataModel.DefineFastFlag] +method = true + +[[selene.structs.DataModel.DefineFastFlag.args]] +required = false +type = "any" + +[[selene.structs.DataModel.DefineFastFlag.args]] +required = false +type = "any" + +[selene.structs.DataModel.DefineFastInt] +method = true + +[[selene.structs.DataModel.DefineFastInt.args]] +required = false +type = "any" + +[[selene.structs.DataModel.DefineFastInt.args]] +required = false +type = "any" + +[selene.structs.DataModel.DefineFastString] +method = true + +[[selene.structs.DataModel.DefineFastString.args]] +required = false +type = "any" + +[[selene.structs.DataModel.DefineFastString.args]] +required = false +type = "any" + +[selene.structs.DataModel.DescendantAdded] +struct = "Event" + +[selene.structs.DataModel.DescendantRemoving] +struct = "Event" + +[selene.structs.DataModel.Destroy] +method = true +args = [] + +[selene.structs.DataModel.FindFirstAncestor] +method = true + +[[selene.structs.DataModel.FindFirstAncestor.args]] +required = false +type = "any" + +[selene.structs.DataModel.FindFirstAncestorOfClass] +method = true + +[[selene.structs.DataModel.FindFirstAncestorOfClass.args]] +required = false +type = "any" + +[selene.structs.DataModel.FindFirstAncestorWhichIsA] +method = true + +[[selene.structs.DataModel.FindFirstAncestorWhichIsA.args]] +required = false +type = "any" + +[selene.structs.DataModel.FindFirstChild] +method = true + +[[selene.structs.DataModel.FindFirstChild.args]] +required = false +type = "any" + +[[selene.structs.DataModel.FindFirstChild.args]] +required = false +type = "any" + +[selene.structs.DataModel.FindFirstChildOfClass] +method = true + +[[selene.structs.DataModel.FindFirstChildOfClass.args]] +required = false +type = "any" + +[selene.structs.DataModel.FindFirstChildWhichIsA] +method = true + +[[selene.structs.DataModel.FindFirstChildWhichIsA.args]] +required = false +type = "any" + +[[selene.structs.DataModel.FindFirstChildWhichIsA.args]] +required = false +type = "any" + +[selene.structs.DataModel.FindService] +method = true + +[[selene.structs.DataModel.FindService.args]] +required = false +type = "any" + +[selene.structs.DataModel.GameId] +property = true + +[selene.structs.DataModel.Genre] +property = true + +[selene.structs.DataModel.GetAttribute] +method = true + +[[selene.structs.DataModel.GetAttribute.args]] +required = false +type = "any" + +[selene.structs.DataModel.GetAttributeChangedSignal] +method = true + +[[selene.structs.DataModel.GetAttributeChangedSignal.args]] +required = false +type = "any" + +[selene.structs.DataModel.GetAttributes] +method = true +args = [] + +[selene.structs.DataModel.GetChildren] +method = true +args = [] + +[selene.structs.DataModel.GetDebugId] +method = true + +[[selene.structs.DataModel.GetDebugId.args]] +required = false +type = "any" + +[selene.structs.DataModel.GetDescendants] +method = true +args = [] + +[selene.structs.DataModel.GetFastFlag] +method = true + +[[selene.structs.DataModel.GetFastFlag.args]] +required = false +type = "any" + +[selene.structs.DataModel.GetFastInt] +method = true + +[[selene.structs.DataModel.GetFastInt.args]] +required = false +type = "any" + +[selene.structs.DataModel.GetFastString] +method = true + +[[selene.structs.DataModel.GetFastString.args]] +required = false +type = "any" + +[selene.structs.DataModel.GetFullName] +method = true +args = [] + +[selene.structs.DataModel.GetJobIntervalPeakFraction] +method = true + +[[selene.structs.DataModel.GetJobIntervalPeakFraction.args]] +required = false +type = "any" + +[[selene.structs.DataModel.GetJobIntervalPeakFraction.args]] +required = false +type = "any" + +[selene.structs.DataModel.GetJobTimePeakFraction] +method = true + +[[selene.structs.DataModel.GetJobTimePeakFraction.args]] +required = false +type = "any" + +[[selene.structs.DataModel.GetJobTimePeakFraction.args]] +required = false +type = "any" + +[selene.structs.DataModel.GetJobsExtendedStats] +method = true +args = [] + +[selene.structs.DataModel.GetJobsInfo] +method = true +args = [] + +[selene.structs.DataModel.GetObjects] +method = true + +[[selene.structs.DataModel.GetObjects.args]] +required = false +type = "any" + +[selene.structs.DataModel.GetObjectsAsync] +method = true + +[[selene.structs.DataModel.GetObjectsAsync.args]] +required = false +type = "any" + +[selene.structs.DataModel.GetObjectsList] +method = true + +[[selene.structs.DataModel.GetObjectsList.args]] +required = false +type = "any" + +[selene.structs.DataModel.GetPropertyChangedSignal] +method = true + +[[selene.structs.DataModel.GetPropertyChangedSignal.args]] +required = false +type = "any" + +[selene.structs.DataModel.GetService] +method = true + +[[selene.structs.DataModel.GetService.args]] +type = ["ABTestService", "AdService", "AnalyticsService", "AssetManagerService", "AssetService", "BadgeService", "CoreGui", "StarterGui", "BrowserService", "BulkImportService", "CacheableContentProvider", "MeshContentProvider", "SolidModelContentProvider", "ChangeHistoryService", "Chat", "ClusterPacketCache", "CollectionService", "ContentProvider", "ContextActionService", "ControllerService", "CookiesService", "CorePackages", "CoreScriptSyncService", "DataStoreService", "Debris", "DraftsService", "EventIngestService", "FlagStandService", "FlyweightService", "CSGDictionaryService", "NonReplicatedCSGDictionaryService", "FriendService", "GamePassService", "GamepadService", "Geometry", "GoogleAnalyticsConfiguration", "GroupService", "GuiService", "GuidRegistryService", "HapticService", "Hopper", "HttpRbxApiService", "HttpService", "InsertService", "JointsService", "KeyboardService", "KeyframeSequenceProvider", "LanguageService", "Lighting", "LocalStorageService", "AppStorageService", "UserStorageService", "LocalizationService", "LogService", "LoginService", "LuaWebService", "MarketplaceService", "MemStorageService", "MessagingService", "MouseService", "NetworkClient", "NetworkServer", "NetworkSettings", "NotificationService", "Workspace", "PackageService", "PathfindingService", "PermissionsService", "PhysicsService", "PlayerEmulatorService", "Players", "PluginDebugService", "PluginGuiService", "PointsService", "PolicyService", "RbxAnalyticsService", "RenderSettings", "ReplicatedFirst", "ReplicatedStorage", "RobloxPluginGuiService", "RobloxReplicatedStorage", "RunService", "RuntimeScriptService", "ScriptContext", "ScriptService", "Selection", "ServerScriptService", "ServerStorage", "SessionService", "SocialService", "SoundService", "SpawnerService", "StarterPack", "StarterPlayer", "Stats", "StopWatchReporter", "Studio", "StudioData", "StudioService", "TaskScheduler", "Teams", "TeleportService", "TestService", "TextService", "ThirdPartyUserService", "TimerService", "TouchInputService", "TweenService", "UGCValidationService", "UserInputService", "UserService", "VRService", "VersionControlService", "VirtualInputManager", "VirtualUser", "Visit"] + +[selene.structs.DataModel.GraphicsQualityChangeRequest] +struct = "Event" + +[selene.structs.DataModel.HttpGetAsync] +method = true + +[[selene.structs.DataModel.HttpGetAsync.args]] +required = false +type = "any" + +[[selene.structs.DataModel.HttpGetAsync.args]] +required = false +type = "any" + +[selene.structs.DataModel.HttpPostAsync] +method = true + +[[selene.structs.DataModel.HttpPostAsync.args]] +required = false +type = "any" + +[[selene.structs.DataModel.HttpPostAsync.args]] +required = false +type = "any" + +[[selene.structs.DataModel.HttpPostAsync.args]] +required = false +type = "any" + +[[selene.structs.DataModel.HttpPostAsync.args]] +required = false +type = "any" + +[selene.structs.DataModel.InsertObjectsAndJoinIfLegacyAsync] +method = true + +[[selene.structs.DataModel.InsertObjectsAndJoinIfLegacyAsync.args]] +required = false +type = "any" + +[selene.structs.DataModel.IsA] +method = true + +[[selene.structs.DataModel.IsA.args]] +required = false +type = "any" + +[selene.structs.DataModel.IsAncestorOf] +method = true + +[[selene.structs.DataModel.IsAncestorOf.args]] +required = false +type = "any" + +[selene.structs.DataModel.IsDescendantOf] +method = true + +[[selene.structs.DataModel.IsDescendantOf.args]] +required = false +type = "any" + +[selene.structs.DataModel.IsLoaded] +method = true +args = [] + +[selene.structs.DataModel.JobId] +property = true + +[selene.structs.DataModel.Load] +method = true + +[[selene.structs.DataModel.Load.args]] +required = false +type = "any" + +[selene.structs.DataModel.Loaded] +struct = "Event" + +[selene.structs.DataModel.Name] +property = true +writable = "overridden" + +[selene.structs.DataModel.OpenScreenshotsFolder] +method = true +args = [] + +[selene.structs.DataModel.OpenVideosFolder] +method = true +args = [] + +[selene.structs.DataModel.Parent] +struct = "Instance" + +[selene.structs.DataModel.PlaceId] +property = true + +[selene.structs.DataModel.PlaceVersion] +property = true + +[selene.structs.DataModel.PrivateServerId] +property = true + +[selene.structs.DataModel.PrivateServerOwnerId] +property = true + +[selene.structs.DataModel.ReportInGoogleAnalytics] +method = true + +[[selene.structs.DataModel.ReportInGoogleAnalytics.args]] +required = false +type = "any" + +[[selene.structs.DataModel.ReportInGoogleAnalytics.args]] +required = false +type = "any" + +[[selene.structs.DataModel.ReportInGoogleAnalytics.args]] +required = false +type = "any" + +[[selene.structs.DataModel.ReportInGoogleAnalytics.args]] +required = false +type = "any" + +[selene.structs.DataModel.ScreenshotReady] +struct = "Event" + +[selene.structs.DataModel.ServiceAdded] +struct = "Event" + +[selene.structs.DataModel.ServiceRemoving] +struct = "Event" + +[selene.structs.DataModel.SetAttribute] +method = true + +[[selene.structs.DataModel.SetAttribute.args]] +required = false +type = "any" + +[[selene.structs.DataModel.SetAttribute.args]] +required = false +type = "any" + +[selene.structs.DataModel.SetFastFlagForTesting] +method = true + +[[selene.structs.DataModel.SetFastFlagForTesting.args]] +required = false +type = "any" + +[[selene.structs.DataModel.SetFastFlagForTesting.args]] +required = false +type = "any" + +[selene.structs.DataModel.SetFastIntForTesting] +method = true + +[[selene.structs.DataModel.SetFastIntForTesting.args]] +required = false +type = "any" + +[[selene.structs.DataModel.SetFastIntForTesting.args]] +required = false +type = "any" + +[selene.structs.DataModel.SetFastStringForTesting] +method = true + +[[selene.structs.DataModel.SetFastStringForTesting.args]] +required = false +type = "any" + +[[selene.structs.DataModel.SetFastStringForTesting.args]] +required = false +type = "any" + +[selene.structs.DataModel.SetPlaceId] +method = true + +[[selene.structs.DataModel.SetPlaceId.args]] +required = false +type = "any" + +[selene.structs.DataModel.SetUniverseId] +method = true + +[[selene.structs.DataModel.SetUniverseId.args]] +required = false +type = "any" + +[selene.structs.DataModel.Shutdown] +method = true +args = [] + +[selene.structs.DataModel.WaitForChild] +method = true + +[[selene.structs.DataModel.WaitForChild.args]] +required = false +type = "any" + +[[selene.structs.DataModel.WaitForChild.args]] +required = false +type = "any" + +[selene.structs.DataModel.Workspace] +struct = "Workspace" +[selene.structs.EnumItem.Name] +property = true + +[selene.structs.EnumItem.Value] +property = true +[selene.structs.Event.Connect] +method = true + +[[selene.structs.Event.Connect.args]] +type = "function" + +[selene.structs.Event.Wait] +method = true +args = [] +[selene.structs.Instance."*"] +any = true +[selene.structs.Plugin."*"] +struct = "Instance" + +[selene.structs.Plugin.Activate] +method = true + +[[selene.structs.Plugin.Activate.args]] +required = false +type = "any" + +[selene.structs.Plugin.AncestryChanged] +struct = "Event" + +[selene.structs.Plugin.Archivable] +property = true +writable = "overridden" + +[selene.structs.Plugin.AttributeChanged] +struct = "Event" + +[selene.structs.Plugin.Changed] +struct = "Event" + +[selene.structs.Plugin.ChildAdded] +struct = "Event" + +[selene.structs.Plugin.ChildRemoved] +struct = "Event" + +[selene.structs.Plugin.ClassName] +property = true + +[selene.structs.Plugin.ClearAllChildren] +method = true +args = [] + +[selene.structs.Plugin.Clone] +method = true +args = [] + +[selene.structs.Plugin.CollisionEnabled] +property = true + +[selene.structs.Plugin.CreateDockWidgetPluginGui] +method = true + +[[selene.structs.Plugin.CreateDockWidgetPluginGui.args]] +required = false +type = "any" + +[[selene.structs.Plugin.CreateDockWidgetPluginGui.args]] +required = false +type = "any" + +[selene.structs.Plugin.CreatePluginAction] +method = true + +[[selene.structs.Plugin.CreatePluginAction.args]] +required = false +type = "any" + +[[selene.structs.Plugin.CreatePluginAction.args]] +required = false +type = "any" + +[[selene.structs.Plugin.CreatePluginAction.args]] +required = false +type = "any" + +[[selene.structs.Plugin.CreatePluginAction.args]] +required = false +type = "any" + +[[selene.structs.Plugin.CreatePluginAction.args]] +required = false +type = "any" + +[selene.structs.Plugin.CreatePluginMenu] +method = true + +[[selene.structs.Plugin.CreatePluginMenu.args]] +required = false +type = "any" + +[[selene.structs.Plugin.CreatePluginMenu.args]] +required = false +type = "any" + +[[selene.structs.Plugin.CreatePluginMenu.args]] +required = false +type = "any" + +[selene.structs.Plugin.CreateQWidgetPluginGui] +method = true + +[[selene.structs.Plugin.CreateQWidgetPluginGui.args]] +required = false +type = "any" + +[[selene.structs.Plugin.CreateQWidgetPluginGui.args]] +required = false +type = "any" + +[selene.structs.Plugin.CreateToolbar] +method = true + +[[selene.structs.Plugin.CreateToolbar.args]] +required = false +type = "any" + +[selene.structs.Plugin.Deactivate] +method = true +args = [] + +[selene.structs.Plugin.Deactivation] +struct = "Event" + +[selene.structs.Plugin.DescendantAdded] +struct = "Event" + +[selene.structs.Plugin.DescendantRemoving] +struct = "Event" + +[selene.structs.Plugin.Destroy] +method = true +args = [] + +[selene.structs.Plugin.FindFirstAncestor] +method = true + +[[selene.structs.Plugin.FindFirstAncestor.args]] +required = false +type = "any" + +[selene.structs.Plugin.FindFirstAncestorOfClass] +method = true + +[[selene.structs.Plugin.FindFirstAncestorOfClass.args]] +required = false +type = "any" + +[selene.structs.Plugin.FindFirstAncestorWhichIsA] +method = true + +[[selene.structs.Plugin.FindFirstAncestorWhichIsA.args]] +required = false +type = "any" + +[selene.structs.Plugin.FindFirstChild] +method = true + +[[selene.structs.Plugin.FindFirstChild.args]] +required = false +type = "any" + +[[selene.structs.Plugin.FindFirstChild.args]] +required = false +type = "any" + +[selene.structs.Plugin.FindFirstChildOfClass] +method = true + +[[selene.structs.Plugin.FindFirstChildOfClass.args]] +required = false +type = "any" + +[selene.structs.Plugin.FindFirstChildWhichIsA] +method = true + +[[selene.structs.Plugin.FindFirstChildWhichIsA.args]] +required = false +type = "any" + +[[selene.structs.Plugin.FindFirstChildWhichIsA.args]] +required = false +type = "any" + +[selene.structs.Plugin.GetAttribute] +method = true + +[[selene.structs.Plugin.GetAttribute.args]] +required = false +type = "any" + +[selene.structs.Plugin.GetAttributeChangedSignal] +method = true + +[[selene.structs.Plugin.GetAttributeChangedSignal.args]] +required = false +type = "any" + +[selene.structs.Plugin.GetAttributes] +method = true +args = [] + +[selene.structs.Plugin.GetChildren] +method = true +args = [] + +[selene.structs.Plugin.GetDebugId] +method = true + +[[selene.structs.Plugin.GetDebugId.args]] +required = false +type = "any" + +[selene.structs.Plugin.GetDescendants] +method = true +args = [] + +[selene.structs.Plugin.GetFullName] +method = true +args = [] + +[selene.structs.Plugin.GetItem] +method = true + +[[selene.structs.Plugin.GetItem.args]] +required = false +type = "any" + +[[selene.structs.Plugin.GetItem.args]] +required = false +type = "any" + +[selene.structs.Plugin.GetJoinMode] +method = true +args = [] + +[selene.structs.Plugin.GetMouse] +method = true +args = [] + +[selene.structs.Plugin.GetPropertyChangedSignal] +method = true + +[[selene.structs.Plugin.GetPropertyChangedSignal.args]] +required = false +type = "any" + +[selene.structs.Plugin.GetSelectedRibbonTool] +method = true +args = [] + +[selene.structs.Plugin.GetSetting] +method = true + +[[selene.structs.Plugin.GetSetting.args]] +required = false +type = "any" + +[selene.structs.Plugin.GridSize] +property = true + +[selene.structs.Plugin.ImportFbxAnimation] +method = true + +[[selene.structs.Plugin.ImportFbxAnimation.args]] +required = false +type = "any" + +[[selene.structs.Plugin.ImportFbxAnimation.args]] +required = false +type = "any" + +[selene.structs.Plugin.ImportFbxRig] +method = true + +[[selene.structs.Plugin.ImportFbxRig.args]] +required = false +type = "any" + +[selene.structs.Plugin.Invoke] +method = true + +[[selene.structs.Plugin.Invoke.args]] +required = false +type = "any" + +[[selene.structs.Plugin.Invoke.args]] +required = false +type = "any" + +[selene.structs.Plugin.IsA] +method = true + +[[selene.structs.Plugin.IsA.args]] +required = false +type = "any" + +[selene.structs.Plugin.IsActivated] +method = true +args = [] + +[selene.structs.Plugin.IsActivatedWithExclusiveMouse] +method = true +args = [] + +[selene.structs.Plugin.IsAncestorOf] +method = true + +[[selene.structs.Plugin.IsAncestorOf.args]] +required = false +type = "any" + +[selene.structs.Plugin.IsDescendantOf] +method = true + +[[selene.structs.Plugin.IsDescendantOf.args]] +required = false +type = "any" + +[selene.structs.Plugin.Name] +property = true +writable = "overridden" + +[selene.structs.Plugin.Negate] +method = true + +[[selene.structs.Plugin.Negate.args]] +required = false +type = "any" + +[selene.structs.Plugin.OnInvoke] +method = true + +[[selene.structs.Plugin.OnInvoke.args]] +required = false +type = "any" + +[[selene.structs.Plugin.OnInvoke.args]] +required = false +type = "any" + +[selene.structs.Plugin.OnSetItem] +method = true + +[[selene.structs.Plugin.OnSetItem.args]] +required = false +type = "any" + +[[selene.structs.Plugin.OnSetItem.args]] +required = false +type = "any" + +[selene.structs.Plugin.OpenScript] +method = true + +[[selene.structs.Plugin.OpenScript.args]] +required = false +type = "any" + +[[selene.structs.Plugin.OpenScript.args]] +required = false +type = "any" + +[selene.structs.Plugin.OpenWikiPage] +method = true + +[[selene.structs.Plugin.OpenWikiPage.args]] +required = false +type = "any" + +[selene.structs.Plugin.Parent] +struct = "Instance" + +[selene.structs.Plugin.PauseSound] +method = true + +[[selene.structs.Plugin.PauseSound.args]] +required = false +type = "any" + +[selene.structs.Plugin.PlaySound] +method = true + +[[selene.structs.Plugin.PlaySound.args]] +required = false +type = "any" + +[selene.structs.Plugin.PromptForExistingAssetId] +method = true + +[[selene.structs.Plugin.PromptForExistingAssetId.args]] +required = false +type = "any" + +[selene.structs.Plugin.PromptSaveSelection] +method = true + +[[selene.structs.Plugin.PromptSaveSelection.args]] +required = false +type = "any" + +[selene.structs.Plugin.ResumeSound] +method = true + +[[selene.structs.Plugin.ResumeSound.args]] +required = false +type = "any" + +[selene.structs.Plugin.SaveSelectedToRoblox] +method = true +args = [] + +[selene.structs.Plugin.SelectRibbonTool] +method = true + +[[selene.structs.Plugin.SelectRibbonTool.args]] +required = false +type = "any" + +[[selene.structs.Plugin.SelectRibbonTool.args]] +required = false +type = "any" + +[selene.structs.Plugin.Separate] +method = true + +[[selene.structs.Plugin.Separate.args]] +required = false +type = "any" + +[selene.structs.Plugin.SetAttribute] +method = true + +[[selene.structs.Plugin.SetAttribute.args]] +required = false +type = "any" + +[[selene.structs.Plugin.SetAttribute.args]] +required = false +type = "any" + +[selene.structs.Plugin.SetItem] +method = true + +[[selene.structs.Plugin.SetItem.args]] +required = false +type = "any" + +[[selene.structs.Plugin.SetItem.args]] +required = false +type = "any" + +[selene.structs.Plugin.SetSetting] +method = true + +[[selene.structs.Plugin.SetSetting.args]] +required = false +type = "any" + +[[selene.structs.Plugin.SetSetting.args]] +required = false +type = "any" + +[selene.structs.Plugin.StartDecalDrag] +method = true + +[[selene.structs.Plugin.StartDecalDrag.args]] +required = false +type = "any" + +[selene.structs.Plugin.StartDrag] +method = true + +[[selene.structs.Plugin.StartDrag.args]] +required = false +type = "any" + +[selene.structs.Plugin.StopAllSounds] +method = true +args = [] + +[selene.structs.Plugin.Union] +method = true + +[[selene.structs.Plugin.Union.args]] +required = false +type = "any" + +[selene.structs.Plugin.Unloading] +struct = "Event" + +[selene.structs.Plugin.WaitForChild] +method = true + +[[selene.structs.Plugin.WaitForChild.args]] +required = false +type = "any" + +[[selene.structs.Plugin.WaitForChild.args]] +required = false +type = "any" +[selene.structs.Script."*"] +struct = "Instance" + +[selene.structs.Script.AncestryChanged] +struct = "Event" + +[selene.structs.Script.Archivable] +property = true +writable = "overridden" + +[selene.structs.Script.AttributeChanged] +struct = "Event" + +[selene.structs.Script.Changed] +struct = "Event" + +[selene.structs.Script.ChildAdded] +struct = "Event" + +[selene.structs.Script.ChildRemoved] +struct = "Event" + +[selene.structs.Script.ClassName] +property = true + +[selene.structs.Script.ClearAllChildren] +method = true +args = [] + +[selene.structs.Script.Clone] +method = true +args = [] + +[selene.structs.Script.CurrentEditor] +struct = "Instance" + +[selene.structs.Script.DescendantAdded] +struct = "Event" + +[selene.structs.Script.DescendantRemoving] +struct = "Event" + +[selene.structs.Script.Destroy] +method = true +args = [] + +[selene.structs.Script.Disabled] +property = true +writable = "overridden" + +[selene.structs.Script.FindFirstAncestor] +method = true + +[[selene.structs.Script.FindFirstAncestor.args]] +required = false +type = "any" + +[selene.structs.Script.FindFirstAncestorOfClass] +method = true + +[[selene.structs.Script.FindFirstAncestorOfClass.args]] +required = false +type = "any" + +[selene.structs.Script.FindFirstAncestorWhichIsA] +method = true + +[[selene.structs.Script.FindFirstAncestorWhichIsA.args]] +required = false +type = "any" + +[selene.structs.Script.FindFirstChild] +method = true + +[[selene.structs.Script.FindFirstChild.args]] +required = false +type = "any" + +[[selene.structs.Script.FindFirstChild.args]] +required = false +type = "any" + +[selene.structs.Script.FindFirstChildOfClass] +method = true + +[[selene.structs.Script.FindFirstChildOfClass.args]] +required = false +type = "any" + +[selene.structs.Script.FindFirstChildWhichIsA] +method = true + +[[selene.structs.Script.FindFirstChildWhichIsA.args]] +required = false +type = "any" + +[[selene.structs.Script.FindFirstChildWhichIsA.args]] +required = false +type = "any" + +[selene.structs.Script.GetAttribute] +method = true + +[[selene.structs.Script.GetAttribute.args]] +required = false +type = "any" + +[selene.structs.Script.GetAttributeChangedSignal] +method = true + +[[selene.structs.Script.GetAttributeChangedSignal.args]] +required = false +type = "any" + +[selene.structs.Script.GetAttributes] +method = true +args = [] + +[selene.structs.Script.GetChildren] +method = true +args = [] + +[selene.structs.Script.GetDebugId] +method = true + +[[selene.structs.Script.GetDebugId.args]] +required = false +type = "any" + +[selene.structs.Script.GetDescendants] +method = true +args = [] + +[selene.structs.Script.GetFullName] +method = true +args = [] + +[selene.structs.Script.GetHash] +method = true +args = [] + +[selene.structs.Script.GetPropertyChangedSignal] +method = true + +[[selene.structs.Script.GetPropertyChangedSignal.args]] +required = false +type = "any" + +[selene.structs.Script.IsA] +method = true + +[[selene.structs.Script.IsA.args]] +required = false +type = "any" + +[selene.structs.Script.IsAncestorOf] +method = true + +[[selene.structs.Script.IsAncestorOf.args]] +required = false +type = "any" + +[selene.structs.Script.IsDescendantOf] +method = true + +[[selene.structs.Script.IsDescendantOf.args]] +required = false +type = "any" + +[selene.structs.Script.LinkedSource] +property = true +writable = "overridden" + +[selene.structs.Script.Name] +property = true +writable = "overridden" + +[selene.structs.Script.Parent] +struct = "Instance" + +[selene.structs.Script.SetAttribute] +method = true + +[[selene.structs.Script.SetAttribute.args]] +required = false +type = "any" + +[[selene.structs.Script.SetAttribute.args]] +required = false +type = "any" + +[selene.structs.Script.WaitForChild] +method = true + +[[selene.structs.Script.WaitForChild.args]] +required = false +type = "any" + +[[selene.structs.Script.WaitForChild.args]] +required = false +type = "any" +[selene.structs.Workspace."*"] +struct = "Instance" + +[selene.structs.Workspace.AllowThirdPartySales] +property = true +writable = "overridden" + +[selene.structs.Workspace.AncestryChanged] +struct = "Event" + +[selene.structs.Workspace.Archivable] +property = true +writable = "overridden" + +[selene.structs.Workspace.AttributeChanged] +struct = "Event" + +[selene.structs.Workspace.BreakJoints] +method = true +args = [] + +[selene.structs.Workspace.CalculateJumpPower] +method = true + +[[selene.structs.Workspace.CalculateJumpPower.args]] +required = false +type = "any" + +[[selene.structs.Workspace.CalculateJumpPower.args]] +required = false +type = "any" + +[selene.structs.Workspace.Changed] +struct = "Event" + +[selene.structs.Workspace.ChildAdded] +struct = "Event" + +[selene.structs.Workspace.ChildRemoved] +struct = "Event" + +[selene.structs.Workspace.ClassName] +property = true + +[selene.structs.Workspace.ClearAllChildren] +method = true +args = [] + +[selene.structs.Workspace.Clone] +method = true +args = [] + +[selene.structs.Workspace.CurrentCamera] +struct = "Camera" + +[selene.structs.Workspace.DescendantAdded] +struct = "Event" + +[selene.structs.Workspace.DescendantRemoving] +struct = "Event" + +[selene.structs.Workspace.Destroy] +method = true +args = [] + +[selene.structs.Workspace.DistributedGameTime] +property = true +writable = "overridden" + +[selene.structs.Workspace.ExperimentalSolverIsEnabled] +method = true +args = [] + +[selene.structs.Workspace.FindFirstAncestor] +method = true + +[[selene.structs.Workspace.FindFirstAncestor.args]] +required = false +type = "any" + +[selene.structs.Workspace.FindFirstAncestorOfClass] +method = true + +[[selene.structs.Workspace.FindFirstAncestorOfClass.args]] +required = false +type = "any" + +[selene.structs.Workspace.FindFirstAncestorWhichIsA] +method = true + +[[selene.structs.Workspace.FindFirstAncestorWhichIsA.args]] +required = false +type = "any" + +[selene.structs.Workspace.FindFirstChild] +method = true + +[[selene.structs.Workspace.FindFirstChild.args]] +required = false +type = "any" + +[[selene.structs.Workspace.FindFirstChild.args]] +required = false +type = "any" + +[selene.structs.Workspace.FindFirstChildOfClass] +method = true + +[[selene.structs.Workspace.FindFirstChildOfClass.args]] +required = false +type = "any" + +[selene.structs.Workspace.FindFirstChildWhichIsA] +method = true + +[[selene.structs.Workspace.FindFirstChildWhichIsA.args]] +required = false +type = "any" + +[[selene.structs.Workspace.FindFirstChildWhichIsA.args]] +required = false +type = "any" + +[selene.structs.Workspace.FindPartOnRay] +method = true + +[[selene.structs.Workspace.FindPartOnRay.args]] +required = false +type = "any" + +[[selene.structs.Workspace.FindPartOnRay.args]] +required = false +type = "any" + +[[selene.structs.Workspace.FindPartOnRay.args]] +required = false +type = "any" + +[[selene.structs.Workspace.FindPartOnRay.args]] +required = false +type = "any" + +[selene.structs.Workspace.FindPartOnRayWithIgnoreList] +method = true + +[[selene.structs.Workspace.FindPartOnRayWithIgnoreList.args]] +required = false +type = "any" + +[[selene.structs.Workspace.FindPartOnRayWithIgnoreList.args]] +required = false +type = "any" + +[[selene.structs.Workspace.FindPartOnRayWithIgnoreList.args]] +required = false +type = "any" + +[[selene.structs.Workspace.FindPartOnRayWithIgnoreList.args]] +required = false +type = "any" + +[selene.structs.Workspace.FindPartOnRayWithWhitelist] +method = true + +[[selene.structs.Workspace.FindPartOnRayWithWhitelist.args]] +required = false +type = "any" + +[[selene.structs.Workspace.FindPartOnRayWithWhitelist.args]] +required = false +type = "any" + +[[selene.structs.Workspace.FindPartOnRayWithWhitelist.args]] +required = false +type = "any" + +[selene.structs.Workspace.FindPartsInRegion3] +method = true + +[[selene.structs.Workspace.FindPartsInRegion3.args]] +required = false +type = "any" + +[[selene.structs.Workspace.FindPartsInRegion3.args]] +required = false +type = "any" + +[[selene.structs.Workspace.FindPartsInRegion3.args]] +required = false +type = "any" + +[selene.structs.Workspace.FindPartsInRegion3WithIgnoreList] +method = true + +[[selene.structs.Workspace.FindPartsInRegion3WithIgnoreList.args]] +required = false +type = "any" + +[[selene.structs.Workspace.FindPartsInRegion3WithIgnoreList.args]] +required = false +type = "any" + +[[selene.structs.Workspace.FindPartsInRegion3WithIgnoreList.args]] +required = false +type = "any" + +[selene.structs.Workspace.FindPartsInRegion3WithWhiteList] +method = true + +[[selene.structs.Workspace.FindPartsInRegion3WithWhiteList.args]] +required = false +type = "any" + +[[selene.structs.Workspace.FindPartsInRegion3WithWhiteList.args]] +required = false +type = "any" + +[[selene.structs.Workspace.FindPartsInRegion3WithWhiteList.args]] +required = false +type = "any" + +[selene.structs.Workspace.GetAttribute] +method = true + +[[selene.structs.Workspace.GetAttribute.args]] +required = false +type = "any" + +[selene.structs.Workspace.GetAttributeChangedSignal] +method = true + +[[selene.structs.Workspace.GetAttributeChangedSignal.args]] +required = false +type = "any" + +[selene.structs.Workspace.GetAttributes] +method = true +args = [] + +[selene.structs.Workspace.GetBoundingBox] +method = true +args = [] + +[selene.structs.Workspace.GetChildren] +method = true +args = [] + +[selene.structs.Workspace.GetDebugId] +method = true + +[[selene.structs.Workspace.GetDebugId.args]] +required = false +type = "any" + +[selene.structs.Workspace.GetDescendants] +method = true +args = [] + +[selene.structs.Workspace.GetExtentsSize] +method = true +args = [] + +[selene.structs.Workspace.GetFullName] +method = true +args = [] + +[selene.structs.Workspace.GetNumAwakeParts] +method = true +args = [] + +[selene.structs.Workspace.GetPhysicsThrottling] +method = true +args = [] + +[selene.structs.Workspace.GetPrimaryPartCFrame] +method = true +args = [] + +[selene.structs.Workspace.GetPropertyChangedSignal] +method = true + +[[selene.structs.Workspace.GetPropertyChangedSignal.args]] +required = false +type = "any" + +[selene.structs.Workspace.GetRealPhysicsFPS] +method = true +args = [] + +[selene.structs.Workspace.Gravity] +property = true +writable = "overridden" + +[selene.structs.Workspace.IkMoveTo] +method = true + +[[selene.structs.Workspace.IkMoveTo.args]] +required = false +type = "any" + +[[selene.structs.Workspace.IkMoveTo.args]] +required = false +type = "any" + +[[selene.structs.Workspace.IkMoveTo.args]] +required = false +type = "any" + +[[selene.structs.Workspace.IkMoveTo.args]] +required = false +type = "any" + +[[selene.structs.Workspace.IkMoveTo.args]] +required = false +type = "any" + +[selene.structs.Workspace.IsA] +method = true + +[[selene.structs.Workspace.IsA.args]] +required = false +type = "any" + +[selene.structs.Workspace.IsAncestorOf] +method = true + +[[selene.structs.Workspace.IsAncestorOf.args]] +required = false +type = "any" + +[selene.structs.Workspace.IsDescendantOf] +method = true + +[[selene.structs.Workspace.IsDescendantOf.args]] +required = false +type = "any" + +[selene.structs.Workspace.IsRegion3Empty] +method = true + +[[selene.structs.Workspace.IsRegion3Empty.args]] +required = false +type = "any" + +[[selene.structs.Workspace.IsRegion3Empty.args]] +required = false +type = "any" + +[selene.structs.Workspace.IsRegion3EmptyWithIgnoreList] +method = true + +[[selene.structs.Workspace.IsRegion3EmptyWithIgnoreList.args]] +required = false +type = "any" + +[[selene.structs.Workspace.IsRegion3EmptyWithIgnoreList.args]] +required = false +type = "any" + +[selene.structs.Workspace.JoinToOutsiders] +method = true + +[[selene.structs.Workspace.JoinToOutsiders.args]] +required = false +type = "any" + +[[selene.structs.Workspace.JoinToOutsiders.args]] +required = false +type = "any" + +[selene.structs.Workspace.MakeJoints] +method = true +args = [] + +[selene.structs.Workspace.MoveTo] +method = true + +[[selene.structs.Workspace.MoveTo.args]] +required = false +type = "any" + +[selene.structs.Workspace.Name] +property = true +writable = "overridden" + +[selene.structs.Workspace.PGSIsEnabled] +method = true +args = [] + +[selene.structs.Workspace.Parent] +struct = "Instance" + +[selene.structs.Workspace.PrimaryPart] +struct = "BasePart" + +[selene.structs.Workspace.Raycast] +method = true + +[[selene.structs.Workspace.Raycast.args]] +required = false +type = "any" + +[[selene.structs.Workspace.Raycast.args]] +required = false +type = "any" + +[[selene.structs.Workspace.Raycast.args]] +required = false +type = "any" + +[selene.structs.Workspace.SetAttribute] +method = true + +[[selene.structs.Workspace.SetAttribute.args]] +required = false +type = "any" + +[[selene.structs.Workspace.SetAttribute.args]] +required = false +type = "any" + +[selene.structs.Workspace.SetPhysicsThrottleEnabled] +method = true + +[[selene.structs.Workspace.SetPhysicsThrottleEnabled.args]] +required = false +type = "any" + +[selene.structs.Workspace.SetPrimaryPartCFrame] +method = true + +[[selene.structs.Workspace.SetPrimaryPartCFrame.args]] +required = false +type = "any" + +[selene.structs.Workspace.StreamingMinRadius] +property = true +writable = "overridden" + +[selene.structs.Workspace.StreamingPauseMode] +property = true +writable = "overridden" + +[selene.structs.Workspace.StreamingTargetRadius] +property = true +writable = "overridden" + +[selene.structs.Workspace.TemporaryLegacyPhysicsSolverOverride] +property = true +writable = "overridden" + +[selene.structs.Workspace.Terrain] +struct = "Instance" + +[selene.structs.Workspace.TranslateBy] +method = true + +[[selene.structs.Workspace.TranslateBy.args]] +required = false +type = "any" + +[selene.structs.Workspace.UnjoinFromOutsiders] +method = true + +[[selene.structs.Workspace.UnjoinFromOutsiders.args]] +required = false +type = "any" + +[selene.structs.Workspace.WaitForChild] +method = true + +[[selene.structs.Workspace.WaitForChild.args]] +required = false +type = "any" + +[[selene.structs.Workspace.WaitForChild.args]] +required = false +type = "any" + +[selene.structs.Workspace.ZoomToExtents] +method = true +args = [] +[BrickColor.Black] +args = [] + +[BrickColor.Blue] +args = [] + +[BrickColor.DarkGray] +args = [] + +[BrickColor.Gray] +args = [] + +[BrickColor.Green] +args = [] + +[BrickColor.Red] +args = [] + +[BrickColor.White] +args = [] + +[BrickColor.Yellow] +args = [] +[[BrickColor.new.args]] +type = "any" + +[[BrickColor.new.args]] +required = false +type = "number" + +[[BrickColor.new.args]] +required = false +type = "number" +[[BrickColor.palette.args]] +type = "number" + +[BrickColor.random] +args = [] +[[CFrame.Angles.args]] +required = false +type = "number" + +[[CFrame.Angles.args]] +required = false +type = "number" + +[[CFrame.Angles.args]] +required = false +type = "number" +[[CFrame.fromAxisAngle.args]] +[CFrame.fromAxisAngle.args.type] +display = "Vector3" + +[[CFrame.fromAxisAngle.args]] +type = "number" +[[CFrame.fromEulerAnglesXYZ.args]] +type = "number" + +[[CFrame.fromEulerAnglesXYZ.args]] +type = "number" + +[[CFrame.fromEulerAnglesXYZ.args]] +type = "number" +[[CFrame.fromEulerAnglesYXZ.args]] +type = "number" + +[[CFrame.fromEulerAnglesYXZ.args]] +type = "number" + +[[CFrame.fromEulerAnglesYXZ.args]] +type = "number" +[[CFrame.fromMatrix.args]] +[CFrame.fromMatrix.args.type] +display = "Vector3" + +[[CFrame.fromMatrix.args]] +[CFrame.fromMatrix.args.type] +display = "Vector3" + +[[CFrame.fromMatrix.args]] +[CFrame.fromMatrix.args.type] +display = "Vector3" + +[[CFrame.fromMatrix.args]] +[CFrame.fromMatrix.args.type] +display = "Vector3" +[[CFrame.fromOrientation.args]] +type = "number" + +[[CFrame.fromOrientation.args]] +type = "number" + +[[CFrame.fromOrientation.args]] +type = "number" +[[CFrame.new.args]] +required = false +type = "any" + +[[CFrame.new.args]] +required = false +type = "any" + +[[CFrame.new.args]] +required = false +type = "number" + +[[CFrame.new.args]] +required = false +type = "number" + +[[CFrame.new.args]] +required = false +type = "number" + +[[CFrame.new.args]] +required = false +type = "number" + +[[CFrame.new.args]] +required = false +type = "number" + +[[CFrame.new.args]] +required = false +type = "number" + +[[CFrame.new.args]] +required = false +type = "number" + +[[CFrame.new.args]] +required = false +type = "number" + +[[CFrame.new.args]] +required = false +type = "number" + +[[CFrame.new.args]] +required = false +type = "number" +[[Color3.fromHSV.args]] +type = "number" + +[[Color3.fromHSV.args]] +type = "number" + +[[Color3.fromHSV.args]] +type = "number" +[[Color3.fromRGB.args]] +type = "number" + +[[Color3.fromRGB.args]] +type = "number" + +[[Color3.fromRGB.args]] +type = "number" +[[Color3.new.args]] +required = false +type = "number" + +[[Color3.new.args]] +required = false +type = "number" + +[[Color3.new.args]] +required = false +type = "number" +[[Color3.toHSV.args]] +required = false + +[Color3.toHSV.args.type] +display = "Color3" +[[ColorSequence.new.args]] +type = "any" + +[[ColorSequence.new.args]] +required = false + +[ColorSequence.new.args.type] +display = "Color3" +[[ColorSequenceKeypoint.new.args]] +type = "number" + +[[ColorSequenceKeypoint.new.args]] +[ColorSequenceKeypoint.new.args.type] +display = "Color3" +[[DockWidgetPluginGuiInfo.new.args]] +required = false + +[DockWidgetPluginGuiInfo.new.args.type] +display = "InitialDockState" + +[[DockWidgetPluginGuiInfo.new.args]] +required = false +type = "bool" + +[[DockWidgetPluginGuiInfo.new.args]] +required = false +type = "bool" + +[[DockWidgetPluginGuiInfo.new.args]] +required = false +type = "number" + +[[DockWidgetPluginGuiInfo.new.args]] +required = false +type = "number" + +[[DockWidgetPluginGuiInfo.new.args]] +required = false +type = "number" + +[[DockWidgetPluginGuiInfo.new.args]] +required = false +type = "number" +[Enum.ActionType.Draw] +struct = "EnumItem" + +[Enum.ActionType.GetEnumItems] +args = [] +method = true + +[Enum.ActionType.Lose] +struct = "EnumItem" + +[Enum.ActionType.Nothing] +struct = "EnumItem" + +[Enum.ActionType.Pause] +struct = "EnumItem" + +[Enum.ActionType.Win] +struct = "EnumItem" +[Enum.ActuatorRelativeTo.Attachment0] +struct = "EnumItem" + +[Enum.ActuatorRelativeTo.Attachment1] +struct = "EnumItem" + +[Enum.ActuatorRelativeTo.GetEnumItems] +args = [] +method = true + +[Enum.ActuatorRelativeTo.World] +struct = "EnumItem" +[Enum.ActuatorType.GetEnumItems] +args = [] +method = true + +[Enum.ActuatorType.Motor] +struct = "EnumItem" + +[Enum.ActuatorType.None] +struct = "EnumItem" + +[Enum.ActuatorType.Servo] +struct = "EnumItem" +[Enum.AlignType.GetEnumItems] +args = [] +method = true + +[Enum.AlignType.Parallel] +struct = "EnumItem" + +[Enum.AlignType.Perpendicular] +struct = "EnumItem" +[Enum.AlphaMode.GetEnumItems] +args = [] +method = true + +[Enum.AlphaMode.Overlay] +struct = "EnumItem" + +[Enum.AlphaMode.Transparency] +struct = "EnumItem" +[Enum.AnimationPriority.Action] +struct = "EnumItem" + +[Enum.AnimationPriority.Core] +struct = "EnumItem" + +[Enum.AnimationPriority.GetEnumItems] +args = [] +method = true + +[Enum.AnimationPriority.Idle] +struct = "EnumItem" + +[Enum.AnimationPriority.Movement] +struct = "EnumItem" +[Enum.AppShellActionType.AvatarEditorPageLoaded] +struct = "EnumItem" + +[Enum.AppShellActionType.GamePageLoaded] +struct = "EnumItem" + +[Enum.AppShellActionType.GetEnumItems] +args = [] +method = true + +[Enum.AppShellActionType.HomePageLoaded] +struct = "EnumItem" + +[Enum.AppShellActionType.None] +struct = "EnumItem" + +[Enum.AppShellActionType.OpenApp] +struct = "EnumItem" + +[Enum.AppShellActionType.ReadConversation] +struct = "EnumItem" + +[Enum.AppShellActionType.TapAvatarTab] +struct = "EnumItem" + +[Enum.AppShellActionType.TapChatTab] +struct = "EnumItem" + +[Enum.AppShellActionType.TapConversationEntry] +struct = "EnumItem" + +[Enum.AppShellActionType.TapGamePageTab] +struct = "EnumItem" + +[Enum.AppShellActionType.TapHomePageTab] +struct = "EnumItem" +[Enum.AspectType.FitWithinMaxSize] +struct = "EnumItem" + +[Enum.AspectType.GetEnumItems] +args = [] +method = true + +[Enum.AspectType.ScaleWithParentSize] +struct = "EnumItem" +[Enum.AssetFetchStatus.Failure] +struct = "EnumItem" + +[Enum.AssetFetchStatus.GetEnumItems] +args = [] +method = true + +[Enum.AssetFetchStatus.Success] +struct = "EnumItem" +[Enum.AssetType.Animation] +struct = "EnumItem" + +[Enum.AssetType.Audio] +struct = "EnumItem" + +[Enum.AssetType.BackAccessory] +struct = "EnumItem" + +[Enum.AssetType.Badge] +struct = "EnumItem" + +[Enum.AssetType.ClimbAnimation] +struct = "EnumItem" + +[Enum.AssetType.DeathAnimation] +struct = "EnumItem" + +[Enum.AssetType.Decal] +struct = "EnumItem" + +[Enum.AssetType.EarAccessory] +struct = "EnumItem" + +[Enum.AssetType.EmoteAnimation] +struct = "EnumItem" + +[Enum.AssetType.EyeAccessory] +struct = "EnumItem" + +[Enum.AssetType.Face] +struct = "EnumItem" + +[Enum.AssetType.FaceAccessory] +struct = "EnumItem" + +[Enum.AssetType.FallAnimation] +struct = "EnumItem" + +[Enum.AssetType.FrontAccessory] +struct = "EnumItem" + +[Enum.AssetType.GamePass] +struct = "EnumItem" + +[Enum.AssetType.Gear] +struct = "EnumItem" + +[Enum.AssetType.GetEnumItems] +args = [] +method = true + +[Enum.AssetType.HairAccessory] +struct = "EnumItem" + +[Enum.AssetType.Hat] +struct = "EnumItem" + +[Enum.AssetType.Head] +struct = "EnumItem" + +[Enum.AssetType.IdleAnimation] +struct = "EnumItem" + +[Enum.AssetType.Image] +struct = "EnumItem" + +[Enum.AssetType.JumpAnimation] +struct = "EnumItem" + +[Enum.AssetType.LeftArm] +struct = "EnumItem" + +[Enum.AssetType.LeftLeg] +struct = "EnumItem" + +[Enum.AssetType.Lua] +struct = "EnumItem" + +[Enum.AssetType.Mesh] +struct = "EnumItem" + +[Enum.AssetType.MeshPart] +struct = "EnumItem" + +[Enum.AssetType.Model] +struct = "EnumItem" + +[Enum.AssetType.NeckAccessory] +struct = "EnumItem" + +[Enum.AssetType.Package] +struct = "EnumItem" + +[Enum.AssetType.Pants] +struct = "EnumItem" + +[Enum.AssetType.Place] +struct = "EnumItem" + +[Enum.AssetType.Plugin] +struct = "EnumItem" + +[Enum.AssetType.PoseAnimation] +struct = "EnumItem" + +[Enum.AssetType.RightArm] +struct = "EnumItem" + +[Enum.AssetType.RightLeg] +struct = "EnumItem" + +[Enum.AssetType.RunAnimation] +struct = "EnumItem" + +[Enum.AssetType.Shirt] +struct = "EnumItem" + +[Enum.AssetType.ShoulderAccessory] +struct = "EnumItem" + +[Enum.AssetType.SwimAnimation] +struct = "EnumItem" + +[Enum.AssetType.TeeShirt] +struct = "EnumItem" + +[Enum.AssetType.Torso] +struct = "EnumItem" + +[Enum.AssetType.WaistAccessory] +struct = "EnumItem" + +[Enum.AssetType.WalkAnimation] +struct = "EnumItem" +[Enum.AvatarContextMenuOption.Chat] +struct = "EnumItem" + +[Enum.AvatarContextMenuOption.Emote] +struct = "EnumItem" + +[Enum.AvatarContextMenuOption.Friend] +struct = "EnumItem" + +[Enum.AvatarContextMenuOption.GetEnumItems] +args = [] +method = true + +[Enum.AvatarContextMenuOption.InspectMenu] +struct = "EnumItem" +[Enum.AvatarJointPositionType.ArtistIntent] +struct = "EnumItem" + +[Enum.AvatarJointPositionType.Fixed] +struct = "EnumItem" + +[Enum.AvatarJointPositionType.GetEnumItems] +args = [] +method = true +[Enum.Axis.GetEnumItems] +args = [] +method = true + +[Enum.Axis.X] +struct = "EnumItem" + +[Enum.Axis.Y] +struct = "EnumItem" + +[Enum.Axis.Z] +struct = "EnumItem" +[Enum.BinType.Clone] +struct = "EnumItem" + +[Enum.BinType.GameTool] +struct = "EnumItem" + +[Enum.BinType.GetEnumItems] +args = [] +method = true + +[Enum.BinType.Grab] +struct = "EnumItem" + +[Enum.BinType.Hammer] +struct = "EnumItem" + +[Enum.BinType.Script] +struct = "EnumItem" +[Enum.BodyPart.GetEnumItems] +args = [] +method = true + +[Enum.BodyPart.Head] +struct = "EnumItem" + +[Enum.BodyPart.LeftArm] +struct = "EnumItem" + +[Enum.BodyPart.LeftLeg] +struct = "EnumItem" + +[Enum.BodyPart.RightArm] +struct = "EnumItem" + +[Enum.BodyPart.RightLeg] +struct = "EnumItem" + +[Enum.BodyPart.Torso] +struct = "EnumItem" +[Enum.BodyPartR15.GetEnumItems] +args = [] +method = true + +[Enum.BodyPartR15.Head] +struct = "EnumItem" + +[Enum.BodyPartR15.LeftFoot] +struct = "EnumItem" + +[Enum.BodyPartR15.LeftHand] +struct = "EnumItem" + +[Enum.BodyPartR15.LeftLowerArm] +struct = "EnumItem" + +[Enum.BodyPartR15.LeftLowerLeg] +struct = "EnumItem" + +[Enum.BodyPartR15.LeftUpperArm] +struct = "EnumItem" + +[Enum.BodyPartR15.LeftUpperLeg] +struct = "EnumItem" + +[Enum.BodyPartR15.LowerTorso] +struct = "EnumItem" + +[Enum.BodyPartR15.RightFoot] +struct = "EnumItem" + +[Enum.BodyPartR15.RightHand] +struct = "EnumItem" + +[Enum.BodyPartR15.RightLowerArm] +struct = "EnumItem" + +[Enum.BodyPartR15.RightLowerLeg] +struct = "EnumItem" + +[Enum.BodyPartR15.RightUpperArm] +struct = "EnumItem" + +[Enum.BodyPartR15.RightUpperLeg] +struct = "EnumItem" + +[Enum.BodyPartR15.RootPart] +struct = "EnumItem" + +[Enum.BodyPartR15.Unknown] +struct = "EnumItem" + +[Enum.BodyPartR15.UpperTorso] +struct = "EnumItem" +[Enum.BorderMode.GetEnumItems] +args = [] +method = true + +[Enum.BorderMode.Inset] +struct = "EnumItem" + +[Enum.BorderMode.Middle] +struct = "EnumItem" + +[Enum.BorderMode.Outline] +struct = "EnumItem" +[Enum.BreakReason.Error] +struct = "EnumItem" + +[Enum.BreakReason.GetEnumItems] +args = [] +method = true + +[Enum.BreakReason.Other] +struct = "EnumItem" + +[Enum.BreakReason.SpecialBreakpoint] +struct = "EnumItem" + +[Enum.BreakReason.UserBreakpoint] +struct = "EnumItem" +[Enum.Button.Dismount] +struct = "EnumItem" + +[Enum.Button.GetEnumItems] +args = [] +method = true + +[Enum.Button.Jump] +struct = "EnumItem" +[Enum.ButtonStyle.Custom] +struct = "EnumItem" + +[Enum.ButtonStyle.GetEnumItems] +args = [] +method = true + +[Enum.ButtonStyle.RobloxButton] +struct = "EnumItem" + +[Enum.ButtonStyle.RobloxButtonDefault] +struct = "EnumItem" + +[Enum.ButtonStyle.RobloxRoundButton] +struct = "EnumItem" + +[Enum.ButtonStyle.RobloxRoundDefaultButton] +struct = "EnumItem" + +[Enum.ButtonStyle.RobloxRoundDropdownButton] +struct = "EnumItem" +[Enum.CameraMode.Classic] +struct = "EnumItem" + +[Enum.CameraMode.GetEnumItems] +args = [] +method = true + +[Enum.CameraMode.LockFirstPerson] +struct = "EnumItem" +[Enum.CameraPanMode.Classic] +struct = "EnumItem" + +[Enum.CameraPanMode.EdgeBump] +struct = "EnumItem" + +[Enum.CameraPanMode.GetEnumItems] +args = [] +method = true +[Enum.CameraType.Attach] +struct = "EnumItem" + +[Enum.CameraType.Custom] +struct = "EnumItem" + +[Enum.CameraType.Fixed] +struct = "EnumItem" + +[Enum.CameraType.Follow] +struct = "EnumItem" + +[Enum.CameraType.GetEnumItems] +args = [] +method = true + +[Enum.CameraType.Orbital] +struct = "EnumItem" + +[Enum.CameraType.Scriptable] +struct = "EnumItem" + +[Enum.CameraType.Track] +struct = "EnumItem" + +[Enum.CameraType.Watch] +struct = "EnumItem" +[Enum.CellBlock.CornerWedge] +struct = "EnumItem" + +[Enum.CellBlock.GetEnumItems] +args = [] +method = true + +[Enum.CellBlock.HorizontalWedge] +struct = "EnumItem" + +[Enum.CellBlock.InverseCornerWedge] +struct = "EnumItem" + +[Enum.CellBlock.Solid] +struct = "EnumItem" + +[Enum.CellBlock.VerticalWedge] +struct = "EnumItem" +[Enum.CellMaterial.Aluminum] +struct = "EnumItem" + +[Enum.CellMaterial.Asphalt] +struct = "EnumItem" + +[Enum.CellMaterial.BluePlastic] +struct = "EnumItem" + +[Enum.CellMaterial.Brick] +struct = "EnumItem" + +[Enum.CellMaterial.Cement] +struct = "EnumItem" + +[Enum.CellMaterial.CinderBlock] +struct = "EnumItem" + +[Enum.CellMaterial.Empty] +struct = "EnumItem" + +[Enum.CellMaterial.GetEnumItems] +args = [] +method = true + +[Enum.CellMaterial.Gold] +struct = "EnumItem" + +[Enum.CellMaterial.Granite] +struct = "EnumItem" + +[Enum.CellMaterial.Grass] +struct = "EnumItem" + +[Enum.CellMaterial.Gravel] +struct = "EnumItem" + +[Enum.CellMaterial.Iron] +struct = "EnumItem" + +[Enum.CellMaterial.MossyStone] +struct = "EnumItem" + +[Enum.CellMaterial.RedPlastic] +struct = "EnumItem" + +[Enum.CellMaterial.Sand] +struct = "EnumItem" + +[Enum.CellMaterial.Water] +struct = "EnumItem" + +[Enum.CellMaterial.WoodLog] +struct = "EnumItem" + +[Enum.CellMaterial.WoodPlank] +struct = "EnumItem" +[Enum.CellOrientation.GetEnumItems] +args = [] +method = true + +[Enum.CellOrientation.NegX] +struct = "EnumItem" + +[Enum.CellOrientation.NegZ] +struct = "EnumItem" + +[Enum.CellOrientation.X] +struct = "EnumItem" + +[Enum.CellOrientation.Z] +struct = "EnumItem" +[Enum.CenterDialogType.GetEnumItems] +args = [] +method = true + +[Enum.CenterDialogType.ModalDialog] +struct = "EnumItem" + +[Enum.CenterDialogType.PlayerInitiatedDialog] +struct = "EnumItem" + +[Enum.CenterDialogType.QuitDialog] +struct = "EnumItem" + +[Enum.CenterDialogType.UnsolicitedDialog] +struct = "EnumItem" +[Enum.ChatCallbackType.GetEnumItems] +args = [] +method = true + +[Enum.ChatCallbackType.OnClientFormattingMessage] +struct = "EnumItem" + +[Enum.ChatCallbackType.OnClientSendingMessage] +struct = "EnumItem" + +[Enum.ChatCallbackType.OnCreatingChatWindow] +struct = "EnumItem" + +[Enum.ChatCallbackType.OnServerReceivingMessage] +struct = "EnumItem" +[Enum.ChatColor.Blue] +struct = "EnumItem" + +[Enum.ChatColor.GetEnumItems] +args = [] +method = true + +[Enum.ChatColor.Green] +struct = "EnumItem" + +[Enum.ChatColor.Red] +struct = "EnumItem" + +[Enum.ChatColor.White] +struct = "EnumItem" +[Enum.ChatMode.GetEnumItems] +args = [] +method = true + +[Enum.ChatMode.Menu] +struct = "EnumItem" + +[Enum.ChatMode.TextAndMenu] +struct = "EnumItem" +[Enum.ChatPrivacyMode.AllUsers] +struct = "EnumItem" + +[Enum.ChatPrivacyMode.Friends] +struct = "EnumItem" + +[Enum.ChatPrivacyMode.GetEnumItems] +args = [] +method = true + +[Enum.ChatPrivacyMode.NoOne] +struct = "EnumItem" +[Enum.ChatStyle.Bubble] +struct = "EnumItem" + +[Enum.ChatStyle.Classic] +struct = "EnumItem" + +[Enum.ChatStyle.ClassicAndBubble] +struct = "EnumItem" + +[Enum.ChatStyle.GetEnumItems] +args = [] +method = true +[Enum.CollisionFidelity.Box] +struct = "EnumItem" + +[Enum.CollisionFidelity.Default] +struct = "EnumItem" + +[Enum.CollisionFidelity.GetEnumItems] +args = [] +method = true + +[Enum.CollisionFidelity.Hull] +struct = "EnumItem" + +[Enum.CollisionFidelity.PreciseConvexDecomposition] +struct = "EnumItem" +[Enum.CollisionsMode.GetEnumItems] +args = [] +method = true + +[Enum.CollisionsMode.IncludeContactedMechanisms] +struct = "EnumItem" + +[Enum.CollisionsMode.NoCollisions] +struct = "EnumItem" + +[Enum.CollisionsMode.OtherMechanismsAnchored] +struct = "EnumItem" +[Enum.ComputerCameraMovementMode.CameraToggle] +struct = "EnumItem" + +[Enum.ComputerCameraMovementMode.Classic] +struct = "EnumItem" + +[Enum.ComputerCameraMovementMode.Default] +struct = "EnumItem" + +[Enum.ComputerCameraMovementMode.Follow] +struct = "EnumItem" + +[Enum.ComputerCameraMovementMode.GetEnumItems] +args = [] +method = true + +[Enum.ComputerCameraMovementMode.Orbital] +struct = "EnumItem" +[Enum.ComputerMovementMode.ClickToMove] +struct = "EnumItem" + +[Enum.ComputerMovementMode.Default] +struct = "EnumItem" + +[Enum.ComputerMovementMode.GetEnumItems] +args = [] +method = true + +[Enum.ComputerMovementMode.KeyboardMouse] +struct = "EnumItem" +[Enum.ConnectionError.DisconnectBadhash] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectBlockedIP] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectBySecurityPolicy] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectCloudEditKick] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectConnectionLost] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectDevMaintenance] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectDuplicatePlayer] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectDuplicateTicket] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectErrors] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectEvicted] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectHashTimeout] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectIdle] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectIllegalTeleport] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectLuaKick] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectNewSecurityKeyMismatch] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectOnRemoteSysStats] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectPlayerless] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectProtocolMismatch] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectRaknetErrors] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectReceivePacketError] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectReceivePacketStreamError] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectRejoin] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectRobloxMaintenance] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectSecurityKeyMismatch] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectSendPacketError] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectTimeout] +struct = "EnumItem" + +[Enum.ConnectionError.DisconnectWrongVersion] +struct = "EnumItem" + +[Enum.ConnectionError.GetEnumItems] +args = [] +method = true + +[Enum.ConnectionError.OK] +struct = "EnumItem" + +[Enum.ConnectionError.PlacelaunchCustomMessage] +struct = "EnumItem" + +[Enum.ConnectionError.PlacelaunchDisabled] +struct = "EnumItem" + +[Enum.ConnectionError.PlacelaunchError] +struct = "EnumItem" + +[Enum.ConnectionError.PlacelaunchErrors] +struct = "EnumItem" + +[Enum.ConnectionError.PlacelaunchFlooded] +struct = "EnumItem" + +[Enum.ConnectionError.PlacelaunchGameEnded] +struct = "EnumItem" + +[Enum.ConnectionError.PlacelaunchGameFull] +struct = "EnumItem" + +[Enum.ConnectionError.PlacelaunchHashException] +struct = "EnumItem" + +[Enum.ConnectionError.PlacelaunchHashExpired] +struct = "EnumItem" + +[Enum.ConnectionError.PlacelaunchHttpError] +struct = "EnumItem" + +[Enum.ConnectionError.PlacelaunchOtherError] +struct = "EnumItem" + +[Enum.ConnectionError.PlacelaunchPartyCannotFit] +struct = "EnumItem" + +[Enum.ConnectionError.PlacelaunchRestricted] +struct = "EnumItem" + +[Enum.ConnectionError.PlacelaunchUnauthorized] +struct = "EnumItem" + +[Enum.ConnectionError.PlacelaunchUserLeft] +struct = "EnumItem" + +[Enum.ConnectionError.TeleportErrors] +struct = "EnumItem" + +[Enum.ConnectionError.TeleportFailure] +struct = "EnumItem" + +[Enum.ConnectionError.TeleportFlooded] +struct = "EnumItem" + +[Enum.ConnectionError.TeleportGameEnded] +struct = "EnumItem" + +[Enum.ConnectionError.TeleportGameFull] +struct = "EnumItem" + +[Enum.ConnectionError.TeleportGameNotFound] +struct = "EnumItem" + +[Enum.ConnectionError.TeleportIsTeleporting] +struct = "EnumItem" + +[Enum.ConnectionError.TeleportUnauthorized] +struct = "EnumItem" +[Enum.ConnectionState.Connected] +struct = "EnumItem" + +[Enum.ConnectionState.Disconnected] +struct = "EnumItem" + +[Enum.ConnectionState.GetEnumItems] +args = [] +method = true +[Enum.ContextActionPriority.Default] +struct = "EnumItem" + +[Enum.ContextActionPriority.GetEnumItems] +args = [] +method = true + +[Enum.ContextActionPriority.High] +struct = "EnumItem" + +[Enum.ContextActionPriority.Low] +struct = "EnumItem" + +[Enum.ContextActionPriority.Medium] +struct = "EnumItem" +[Enum.ContextActionResult.GetEnumItems] +args = [] +method = true + +[Enum.ContextActionResult.Pass] +struct = "EnumItem" + +[Enum.ContextActionResult.Sink] +struct = "EnumItem" +[Enum.ControlMode.Classic] +struct = "EnumItem" + +[Enum.ControlMode.GetEnumItems] +args = [] +method = true + +[Enum.ControlMode.MouseLockSwitch] +struct = "EnumItem" +[Enum.CoreGuiType.All] +struct = "EnumItem" + +[Enum.CoreGuiType.Backpack] +struct = "EnumItem" + +[Enum.CoreGuiType.Chat] +struct = "EnumItem" + +[Enum.CoreGuiType.EmotesMenu] +struct = "EnumItem" + +[Enum.CoreGuiType.GetEnumItems] +args = [] +method = true + +[Enum.CoreGuiType.Health] +struct = "EnumItem" + +[Enum.CoreGuiType.PlayerList] +struct = "EnumItem" +[Enum.CreatorType.GetEnumItems] +args = [] +method = true + +[Enum.CreatorType.Group] +struct = "EnumItem" + +[Enum.CreatorType.User] +struct = "EnumItem" +[Enum.CurrencyType.Default] +struct = "EnumItem" + +[Enum.CurrencyType.GetEnumItems] +args = [] +method = true + +[Enum.CurrencyType.Robux] +struct = "EnumItem" + +[Enum.CurrencyType.Tix] +struct = "EnumItem" +[Enum.CustomCameraMode.Classic] +struct = "EnumItem" + +[Enum.CustomCameraMode.Default] +struct = "EnumItem" + +[Enum.CustomCameraMode.Follow] +struct = "EnumItem" + +[Enum.CustomCameraMode.GetEnumItems] +args = [] +method = true +[Enum.DataStoreRequestType.GetAsync] +struct = "EnumItem" + +[Enum.DataStoreRequestType.GetEnumItems] +args = [] +method = true + +[Enum.DataStoreRequestType.GetSortedAsync] +struct = "EnumItem" + +[Enum.DataStoreRequestType.OnUpdate] +struct = "EnumItem" + +[Enum.DataStoreRequestType.SetIncrementAsync] +struct = "EnumItem" + +[Enum.DataStoreRequestType.SetIncrementSortedAsync] +struct = "EnumItem" + +[Enum.DataStoreRequestType.UpdateAsync] +struct = "EnumItem" +[Enum.DevCameraOcclusionMode.GetEnumItems] +args = [] +method = true + +[Enum.DevCameraOcclusionMode.Invisicam] +struct = "EnumItem" + +[Enum.DevCameraOcclusionMode.Zoom] +struct = "EnumItem" +[Enum.DevComputerCameraMovementMode.CameraToggle] +struct = "EnumItem" + +[Enum.DevComputerCameraMovementMode.Classic] +struct = "EnumItem" + +[Enum.DevComputerCameraMovementMode.Follow] +struct = "EnumItem" + +[Enum.DevComputerCameraMovementMode.GetEnumItems] +args = [] +method = true + +[Enum.DevComputerCameraMovementMode.Orbital] +struct = "EnumItem" + +[Enum.DevComputerCameraMovementMode.UserChoice] +struct = "EnumItem" +[Enum.DevComputerMovementMode.ClickToMove] +struct = "EnumItem" + +[Enum.DevComputerMovementMode.GetEnumItems] +args = [] +method = true + +[Enum.DevComputerMovementMode.KeyboardMouse] +struct = "EnumItem" + +[Enum.DevComputerMovementMode.Scriptable] +struct = "EnumItem" + +[Enum.DevComputerMovementMode.UserChoice] +struct = "EnumItem" +[Enum.DevTouchCameraMovementMode.Classic] +struct = "EnumItem" + +[Enum.DevTouchCameraMovementMode.Follow] +struct = "EnumItem" + +[Enum.DevTouchCameraMovementMode.GetEnumItems] +args = [] +method = true + +[Enum.DevTouchCameraMovementMode.Orbital] +struct = "EnumItem" + +[Enum.DevTouchCameraMovementMode.UserChoice] +struct = "EnumItem" +[Enum.DevTouchMovementMode.ClickToMove] +struct = "EnumItem" + +[Enum.DevTouchMovementMode.DPad] +struct = "EnumItem" + +[Enum.DevTouchMovementMode.DynamicThumbstick] +struct = "EnumItem" + +[Enum.DevTouchMovementMode.GetEnumItems] +args = [] +method = true + +[Enum.DevTouchMovementMode.Scriptable] +struct = "EnumItem" + +[Enum.DevTouchMovementMode.Thumbpad] +struct = "EnumItem" + +[Enum.DevTouchMovementMode.Thumbstick] +struct = "EnumItem" + +[Enum.DevTouchMovementMode.UserChoice] +struct = "EnumItem" +[Enum.DeveloperMemoryTag.Animation] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.GetEnumItems] +args = [] +method = true + +[Enum.DeveloperMemoryTag.GraphicsMeshParts] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.GraphicsParticles] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.GraphicsParts] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.GraphicsSolidModels] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.GraphicsSpatialHash] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.GraphicsTerrain] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.GraphicsTexture] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.GraphicsTextureCharacter] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.Gui] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.HttpCache] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.Instances] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.Internal] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.LuaHeap] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.Navigation] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.PhysicsCollision] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.PhysicsParts] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.Script] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.Signals] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.Sounds] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.StreamingSounds] +struct = "EnumItem" + +[Enum.DeveloperMemoryTag.TerrainVoxels] +struct = "EnumItem" +[Enum.DeviceType.Desktop] +struct = "EnumItem" + +[Enum.DeviceType.GetEnumItems] +args = [] +method = true + +[Enum.DeviceType.Phone] +struct = "EnumItem" + +[Enum.DeviceType.Tablet] +struct = "EnumItem" + +[Enum.DeviceType.Unknown] +struct = "EnumItem" +[Enum.DialogBehaviorType.GetEnumItems] +args = [] +method = true + +[Enum.DialogBehaviorType.MultiplePlayers] +struct = "EnumItem" + +[Enum.DialogBehaviorType.SinglePlayer] +struct = "EnumItem" +[Enum.DialogPurpose.GetEnumItems] +args = [] +method = true + +[Enum.DialogPurpose.Help] +struct = "EnumItem" + +[Enum.DialogPurpose.Quest] +struct = "EnumItem" + +[Enum.DialogPurpose.Shop] +struct = "EnumItem" +[Enum.DialogTone.Enemy] +struct = "EnumItem" + +[Enum.DialogTone.Friendly] +struct = "EnumItem" + +[Enum.DialogTone.GetEnumItems] +args = [] +method = true + +[Enum.DialogTone.Neutral] +struct = "EnumItem" +[Enum.DominantAxis.GetEnumItems] +args = [] +method = true + +[Enum.DominantAxis.Height] +struct = "EnumItem" + +[Enum.DominantAxis.Width] +struct = "EnumItem" +[Enum.DraftStatusCode.DraftCommitted] +struct = "EnumItem" + +[Enum.DraftStatusCode.DraftOutdated] +struct = "EnumItem" + +[Enum.DraftStatusCode.GetEnumItems] +args = [] +method = true + +[Enum.DraftStatusCode.OK] +struct = "EnumItem" + +[Enum.DraftStatusCode.ScriptRemoved] +struct = "EnumItem" +[Enum.EasingDirection.GetEnumItems] +args = [] +method = true + +[Enum.EasingDirection.In] +struct = "EnumItem" + +[Enum.EasingDirection.InOut] +struct = "EnumItem" + +[Enum.EasingDirection.Out] +struct = "EnumItem" +[Enum.EasingStyle.Back] +struct = "EnumItem" + +[Enum.EasingStyle.Bounce] +struct = "EnumItem" + +[Enum.EasingStyle.Circular] +struct = "EnumItem" + +[Enum.EasingStyle.Cubic] +struct = "EnumItem" + +[Enum.EasingStyle.Elastic] +struct = "EnumItem" + +[Enum.EasingStyle.Exponential] +struct = "EnumItem" + +[Enum.EasingStyle.GetEnumItems] +args = [] +method = true + +[Enum.EasingStyle.Linear] +struct = "EnumItem" + +[Enum.EasingStyle.Quad] +struct = "EnumItem" + +[Enum.EasingStyle.Quart] +struct = "EnumItem" + +[Enum.EasingStyle.Quint] +struct = "EnumItem" + +[Enum.EasingStyle.Sine] +struct = "EnumItem" +[Enum.ElasticBehavior.Always] +struct = "EnumItem" + +[Enum.ElasticBehavior.GetEnumItems] +args = [] +method = true + +[Enum.ElasticBehavior.Never] +struct = "EnumItem" + +[Enum.ElasticBehavior.WhenScrollable] +struct = "EnumItem" +[Enum.EnviromentalPhysicsThrottle.Always] +struct = "EnumItem" + +[Enum.EnviromentalPhysicsThrottle.DefaultAuto] +struct = "EnumItem" + +[Enum.EnviromentalPhysicsThrottle.Disabled] +struct = "EnumItem" + +[Enum.EnviromentalPhysicsThrottle.GetEnumItems] +args = [] +method = true + +[Enum.EnviromentalPhysicsThrottle.Skip16] +struct = "EnumItem" + +[Enum.EnviromentalPhysicsThrottle.Skip2] +struct = "EnumItem" + +[Enum.EnviromentalPhysicsThrottle.Skip4] +struct = "EnumItem" + +[Enum.EnviromentalPhysicsThrottle.Skip8] +struct = "EnumItem" +[Enum.ExplosionType.Craters] +struct = "EnumItem" + +[Enum.ExplosionType.GetEnumItems] +args = [] +method = true + +[Enum.ExplosionType.NoCraters] +struct = "EnumItem" +[Enum.FillDirection.GetEnumItems] +args = [] +method = true + +[Enum.FillDirection.Horizontal] +struct = "EnumItem" + +[Enum.FillDirection.Vertical] +struct = "EnumItem" +[Enum.FilterResult.Accepted] +struct = "EnumItem" + +[Enum.FilterResult.GetEnumItems] +args = [] +method = true + +[Enum.FilterResult.Rejected] +struct = "EnumItem" +[Enum.Font.Antique] +struct = "EnumItem" + +[Enum.Font.Arcade] +struct = "EnumItem" + +[Enum.Font.Arial] +struct = "EnumItem" + +[Enum.Font.ArialBold] +struct = "EnumItem" + +[Enum.Font.Bodoni] +struct = "EnumItem" + +[Enum.Font.Cartoon] +struct = "EnumItem" + +[Enum.Font.Code] +struct = "EnumItem" + +[Enum.Font.Fantasy] +struct = "EnumItem" + +[Enum.Font.Garamond] +struct = "EnumItem" + +[Enum.Font.GetEnumItems] +args = [] +method = true + +[Enum.Font.Gotham] +struct = "EnumItem" + +[Enum.Font.GothamBlack] +struct = "EnumItem" + +[Enum.Font.GothamBold] +struct = "EnumItem" + +[Enum.Font.GothamSemibold] +struct = "EnumItem" + +[Enum.Font.Highway] +struct = "EnumItem" + +[Enum.Font.Legacy] +struct = "EnumItem" + +[Enum.Font.SciFi] +struct = "EnumItem" + +[Enum.Font.SourceSans] +struct = "EnumItem" + +[Enum.Font.SourceSansBold] +struct = "EnumItem" + +[Enum.Font.SourceSansItalic] +struct = "EnumItem" + +[Enum.Font.SourceSansLight] +struct = "EnumItem" + +[Enum.Font.SourceSansSemibold] +struct = "EnumItem" +[Enum.FontSize.GetEnumItems] +args = [] +method = true + +[Enum.FontSize.Size10] +struct = "EnumItem" + +[Enum.FontSize.Size11] +struct = "EnumItem" + +[Enum.FontSize.Size12] +struct = "EnumItem" + +[Enum.FontSize.Size14] +struct = "EnumItem" + +[Enum.FontSize.Size18] +struct = "EnumItem" + +[Enum.FontSize.Size24] +struct = "EnumItem" + +[Enum.FontSize.Size28] +struct = "EnumItem" + +[Enum.FontSize.Size32] +struct = "EnumItem" + +[Enum.FontSize.Size36] +struct = "EnumItem" + +[Enum.FontSize.Size42] +struct = "EnumItem" + +[Enum.FontSize.Size48] +struct = "EnumItem" + +[Enum.FontSize.Size60] +struct = "EnumItem" + +[Enum.FontSize.Size8] +struct = "EnumItem" + +[Enum.FontSize.Size9] +struct = "EnumItem" + +[Enum.FontSize.Size96] +struct = "EnumItem" +[Enum.FormFactor.Brick] +struct = "EnumItem" + +[Enum.FormFactor.Custom] +struct = "EnumItem" + +[Enum.FormFactor.GetEnumItems] +args = [] +method = true + +[Enum.FormFactor.Plate] +struct = "EnumItem" + +[Enum.FormFactor.Symmetric] +struct = "EnumItem" +[Enum.FrameStyle.ChatBlue] +struct = "EnumItem" + +[Enum.FrameStyle.ChatGreen] +struct = "EnumItem" + +[Enum.FrameStyle.ChatRed] +struct = "EnumItem" + +[Enum.FrameStyle.Custom] +struct = "EnumItem" + +[Enum.FrameStyle.DropShadow] +struct = "EnumItem" + +[Enum.FrameStyle.GetEnumItems] +args = [] +method = true + +[Enum.FrameStyle.RobloxRound] +struct = "EnumItem" + +[Enum.FrameStyle.RobloxSquare] +struct = "EnumItem" +[Enum.FramerateManagerMode.Automatic] +struct = "EnumItem" + +[Enum.FramerateManagerMode.GetEnumItems] +args = [] +method = true + +[Enum.FramerateManagerMode.Off] +struct = "EnumItem" + +[Enum.FramerateManagerMode.On] +struct = "EnumItem" +[Enum.FriendRequestEvent.Accept] +struct = "EnumItem" + +[Enum.FriendRequestEvent.Deny] +struct = "EnumItem" + +[Enum.FriendRequestEvent.GetEnumItems] +args = [] +method = true + +[Enum.FriendRequestEvent.Issue] +struct = "EnumItem" + +[Enum.FriendRequestEvent.Revoke] +struct = "EnumItem" +[Enum.FriendStatus.Friend] +struct = "EnumItem" + +[Enum.FriendStatus.FriendRequestReceived] +struct = "EnumItem" + +[Enum.FriendStatus.FriendRequestSent] +struct = "EnumItem" + +[Enum.FriendStatus.GetEnumItems] +args = [] +method = true + +[Enum.FriendStatus.NotFriend] +struct = "EnumItem" + +[Enum.FriendStatus.Unknown] +struct = "EnumItem" +[Enum.FunctionalTestResult.Error] +struct = "EnumItem" + +[Enum.FunctionalTestResult.GetEnumItems] +args = [] +method = true + +[Enum.FunctionalTestResult.Passed] +struct = "EnumItem" + +[Enum.FunctionalTestResult.Warning] +struct = "EnumItem" +[Enum.GameAvatarType.GetEnumItems] +args = [] +method = true + +[Enum.GameAvatarType.PlayerChoice] +struct = "EnumItem" + +[Enum.GameAvatarType.R15] +struct = "EnumItem" + +[Enum.GameAvatarType.R6] +struct = "EnumItem" +[Enum.GearGenreSetting.AllGenres] +struct = "EnumItem" + +[Enum.GearGenreSetting.GetEnumItems] +args = [] +method = true + +[Enum.GearGenreSetting.MatchingGenreOnly] +struct = "EnumItem" +[Enum.GearType.BuildingTools] +struct = "EnumItem" + +[Enum.GearType.Explosives] +struct = "EnumItem" + +[Enum.GearType.GetEnumItems] +args = [] +method = true + +[Enum.GearType.MeleeWeapons] +struct = "EnumItem" + +[Enum.GearType.MusicalInstruments] +struct = "EnumItem" + +[Enum.GearType.NavigationEnhancers] +struct = "EnumItem" + +[Enum.GearType.PowerUps] +struct = "EnumItem" + +[Enum.GearType.RangedWeapons] +struct = "EnumItem" + +[Enum.GearType.SocialItems] +struct = "EnumItem" + +[Enum.GearType.Transport] +struct = "EnumItem" +[Enum.Genre.Adventure] +struct = "EnumItem" + +[Enum.Genre.All] +struct = "EnumItem" + +[Enum.Genre.Fantasy] +struct = "EnumItem" + +[Enum.Genre.Funny] +struct = "EnumItem" + +[Enum.Genre.GetEnumItems] +args = [] +method = true + +[Enum.Genre.Ninja] +struct = "EnumItem" + +[Enum.Genre.Pirate] +struct = "EnumItem" + +[Enum.Genre.Scary] +struct = "EnumItem" + +[Enum.Genre.SciFi] +struct = "EnumItem" + +[Enum.Genre.SkatePark] +struct = "EnumItem" + +[Enum.Genre.Sports] +struct = "EnumItem" + +[Enum.Genre.TownAndCity] +struct = "EnumItem" + +[Enum.Genre.Tutorial] +struct = "EnumItem" + +[Enum.Genre.War] +struct = "EnumItem" + +[Enum.Genre.WildWest] +struct = "EnumItem" +[Enum.GraphicsMode.Automatic] +struct = "EnumItem" + +[Enum.GraphicsMode.Direct3D11] +struct = "EnumItem" + +[Enum.GraphicsMode.Direct3D9] +struct = "EnumItem" + +[Enum.GraphicsMode.GetEnumItems] +args = [] +method = true + +[Enum.GraphicsMode.Metal] +struct = "EnumItem" + +[Enum.GraphicsMode.NoGraphics] +struct = "EnumItem" + +[Enum.GraphicsMode.OpenGL] +struct = "EnumItem" + +[Enum.GraphicsMode.Vulkan] +struct = "EnumItem" +[Enum.HandlesStyle.GetEnumItems] +args = [] +method = true + +[Enum.HandlesStyle.Movement] +struct = "EnumItem" + +[Enum.HandlesStyle.Resize] +struct = "EnumItem" +[Enum.HorizontalAlignment.Center] +struct = "EnumItem" + +[Enum.HorizontalAlignment.GetEnumItems] +args = [] +method = true + +[Enum.HorizontalAlignment.Left] +struct = "EnumItem" + +[Enum.HorizontalAlignment.Right] +struct = "EnumItem" +[Enum.HoverAnimateSpeed.Fast] +struct = "EnumItem" + +[Enum.HoverAnimateSpeed.GetEnumItems] +args = [] +method = true + +[Enum.HoverAnimateSpeed.Medium] +struct = "EnumItem" + +[Enum.HoverAnimateSpeed.Slow] +struct = "EnumItem" + +[Enum.HoverAnimateSpeed.VeryFast] +struct = "EnumItem" + +[Enum.HoverAnimateSpeed.VerySlow] +struct = "EnumItem" +[Enum.HttpCachePolicy.DataOnly] +struct = "EnumItem" + +[Enum.HttpCachePolicy.Default] +struct = "EnumItem" + +[Enum.HttpCachePolicy.Full] +struct = "EnumItem" + +[Enum.HttpCachePolicy.GetEnumItems] +args = [] +method = true + +[Enum.HttpCachePolicy.InternalRedirectRefresh] +struct = "EnumItem" + +[Enum.HttpCachePolicy.None] +struct = "EnumItem" +[Enum.HttpContentType.ApplicationJson] +struct = "EnumItem" + +[Enum.HttpContentType.ApplicationUrlEncoded] +struct = "EnumItem" + +[Enum.HttpContentType.ApplicationXml] +struct = "EnumItem" + +[Enum.HttpContentType.GetEnumItems] +args = [] +method = true + +[Enum.HttpContentType.TextPlain] +struct = "EnumItem" + +[Enum.HttpContentType.TextXml] +struct = "EnumItem" +[Enum.HttpError.Aborted] +struct = "EnumItem" + +[Enum.HttpError.ConnectFail] +struct = "EnumItem" + +[Enum.HttpError.DnsResolve] +struct = "EnumItem" + +[Enum.HttpError.GetEnumItems] +args = [] +method = true + +[Enum.HttpError.InvalidRedirect] +struct = "EnumItem" + +[Enum.HttpError.InvalidUrl] +struct = "EnumItem" + +[Enum.HttpError.NetFail] +struct = "EnumItem" + +[Enum.HttpError.OK] +struct = "EnumItem" + +[Enum.HttpError.OutOfMemory] +struct = "EnumItem" + +[Enum.HttpError.SslConnectFail] +struct = "EnumItem" + +[Enum.HttpError.TimedOut] +struct = "EnumItem" + +[Enum.HttpError.TooManyRedirects] +struct = "EnumItem" + +[Enum.HttpError.Unknown] +struct = "EnumItem" +[Enum.HttpRequestType.Analytics] +struct = "EnumItem" + +[Enum.HttpRequestType.Avatar] +struct = "EnumItem" + +[Enum.HttpRequestType.Chat] +struct = "EnumItem" + +[Enum.HttpRequestType.Default] +struct = "EnumItem" + +[Enum.HttpRequestType.GetEnumItems] +args = [] +method = true + +[Enum.HttpRequestType.Localization] +struct = "EnumItem" + +[Enum.HttpRequestType.MarketplaceService] +struct = "EnumItem" + +[Enum.HttpRequestType.Players] +struct = "EnumItem" +[Enum.HumanoidCollisionType.GetEnumItems] +args = [] +method = true + +[Enum.HumanoidCollisionType.InnerBox] +struct = "EnumItem" + +[Enum.HumanoidCollisionType.OuterBox] +struct = "EnumItem" +[Enum.HumanoidDisplayDistanceType.GetEnumItems] +args = [] +method = true + +[Enum.HumanoidDisplayDistanceType.None] +struct = "EnumItem" + +[Enum.HumanoidDisplayDistanceType.Subject] +struct = "EnumItem" + +[Enum.HumanoidDisplayDistanceType.Viewer] +struct = "EnumItem" +[Enum.HumanoidHealthDisplayType.AlwaysOff] +struct = "EnumItem" + +[Enum.HumanoidHealthDisplayType.AlwaysOn] +struct = "EnumItem" + +[Enum.HumanoidHealthDisplayType.DisplayWhenDamaged] +struct = "EnumItem" + +[Enum.HumanoidHealthDisplayType.GetEnumItems] +args = [] +method = true +[Enum.HumanoidRigType.GetEnumItems] +args = [] +method = true + +[Enum.HumanoidRigType.R15] +struct = "EnumItem" + +[Enum.HumanoidRigType.R6] +struct = "EnumItem" +[Enum.HumanoidStateType.Climbing] +struct = "EnumItem" + +[Enum.HumanoidStateType.Dead] +struct = "EnumItem" + +[Enum.HumanoidStateType.FallingDown] +struct = "EnumItem" + +[Enum.HumanoidStateType.Flying] +struct = "EnumItem" + +[Enum.HumanoidStateType.Freefall] +struct = "EnumItem" + +[Enum.HumanoidStateType.GetEnumItems] +args = [] +method = true + +[Enum.HumanoidStateType.GettingUp] +struct = "EnumItem" + +[Enum.HumanoidStateType.Jumping] +struct = "EnumItem" + +[Enum.HumanoidStateType.Landed] +struct = "EnumItem" + +[Enum.HumanoidStateType.None] +struct = "EnumItem" + +[Enum.HumanoidStateType.Physics] +struct = "EnumItem" + +[Enum.HumanoidStateType.PlatformStanding] +struct = "EnumItem" + +[Enum.HumanoidStateType.Ragdoll] +struct = "EnumItem" + +[Enum.HumanoidStateType.Running] +struct = "EnumItem" + +[Enum.HumanoidStateType.RunningNoPhysics] +struct = "EnumItem" + +[Enum.HumanoidStateType.Seated] +struct = "EnumItem" + +[Enum.HumanoidStateType.StrafingNoPhysics] +struct = "EnumItem" + +[Enum.HumanoidStateType.Swimming] +struct = "EnumItem" +[Enum.InOut.Center] +struct = "EnumItem" + +[Enum.InOut.Edge] +struct = "EnumItem" + +[Enum.InOut.GetEnumItems] +args = [] +method = true + +[Enum.InOut.Inset] +struct = "EnumItem" +[Enum.InfoType.Asset] +struct = "EnumItem" + +[Enum.InfoType.Bundle] +struct = "EnumItem" + +[Enum.InfoType.GamePass] +struct = "EnumItem" + +[Enum.InfoType.GetEnumItems] +args = [] +method = true + +[Enum.InfoType.Product] +struct = "EnumItem" + +[Enum.InfoType.Subscription] +struct = "EnumItem" +[Enum.InitialDockState.Bottom] +struct = "EnumItem" + +[Enum.InitialDockState.Float] +struct = "EnumItem" + +[Enum.InitialDockState.GetEnumItems] +args = [] +method = true + +[Enum.InitialDockState.Left] +struct = "EnumItem" + +[Enum.InitialDockState.Right] +struct = "EnumItem" + +[Enum.InitialDockState.Top] +struct = "EnumItem" +[Enum.InlineAlignment.Bottom] +struct = "EnumItem" + +[Enum.InlineAlignment.Center] +struct = "EnumItem" + +[Enum.InlineAlignment.GetEnumItems] +args = [] +method = true + +[Enum.InlineAlignment.Top] +struct = "EnumItem" +[Enum.InputType.Constant] +struct = "EnumItem" + +[Enum.InputType.GetEnumItems] +args = [] +method = true + +[Enum.InputType.NoInput] +struct = "EnumItem" + +[Enum.InputType.Sin] +struct = "EnumItem" +[Enum.JointCreationMode.All] +struct = "EnumItem" + +[Enum.JointCreationMode.GetEnumItems] +args = [] +method = true + +[Enum.JointCreationMode.None] +struct = "EnumItem" + +[Enum.JointCreationMode.Surface] +struct = "EnumItem" +[Enum.KeyCode.A] +struct = "EnumItem" + +[Enum.KeyCode.Ampersand] +struct = "EnumItem" + +[Enum.KeyCode.Asterisk] +struct = "EnumItem" + +[Enum.KeyCode.At] +struct = "EnumItem" + +[Enum.KeyCode.B] +struct = "EnumItem" + +[Enum.KeyCode.BackSlash] +struct = "EnumItem" + +[Enum.KeyCode.Backquote] +struct = "EnumItem" + +[Enum.KeyCode.Backspace] +struct = "EnumItem" + +[Enum.KeyCode.Break] +struct = "EnumItem" + +[Enum.KeyCode.ButtonA] +struct = "EnumItem" + +[Enum.KeyCode.ButtonB] +struct = "EnumItem" + +[Enum.KeyCode.ButtonL1] +struct = "EnumItem" + +[Enum.KeyCode.ButtonL2] +struct = "EnumItem" + +[Enum.KeyCode.ButtonL3] +struct = "EnumItem" + +[Enum.KeyCode.ButtonR1] +struct = "EnumItem" + +[Enum.KeyCode.ButtonR2] +struct = "EnumItem" + +[Enum.KeyCode.ButtonR3] +struct = "EnumItem" + +[Enum.KeyCode.ButtonSelect] +struct = "EnumItem" + +[Enum.KeyCode.ButtonStart] +struct = "EnumItem" + +[Enum.KeyCode.ButtonX] +struct = "EnumItem" + +[Enum.KeyCode.ButtonY] +struct = "EnumItem" + +[Enum.KeyCode.C] +struct = "EnumItem" + +[Enum.KeyCode.CapsLock] +struct = "EnumItem" + +[Enum.KeyCode.Caret] +struct = "EnumItem" + +[Enum.KeyCode.Clear] +struct = "EnumItem" + +[Enum.KeyCode.Colon] +struct = "EnumItem" + +[Enum.KeyCode.Comma] +struct = "EnumItem" + +[Enum.KeyCode.Compose] +struct = "EnumItem" + +[Enum.KeyCode.D] +struct = "EnumItem" + +[Enum.KeyCode.DPadDown] +struct = "EnumItem" + +[Enum.KeyCode.DPadLeft] +struct = "EnumItem" + +[Enum.KeyCode.DPadRight] +struct = "EnumItem" + +[Enum.KeyCode.DPadUp] +struct = "EnumItem" + +[Enum.KeyCode.Delete] +struct = "EnumItem" + +[Enum.KeyCode.Dollar] +struct = "EnumItem" + +[Enum.KeyCode.Down] +struct = "EnumItem" + +[Enum.KeyCode.E] +struct = "EnumItem" + +[Enum.KeyCode.Eight] +struct = "EnumItem" + +[Enum.KeyCode.End] +struct = "EnumItem" + +[Enum.KeyCode.Equals] +struct = "EnumItem" + +[Enum.KeyCode.Escape] +struct = "EnumItem" + +[Enum.KeyCode.Euro] +struct = "EnumItem" + +[Enum.KeyCode.F] +struct = "EnumItem" + +[Enum.KeyCode.F1] +struct = "EnumItem" + +[Enum.KeyCode.F10] +struct = "EnumItem" + +[Enum.KeyCode.F11] +struct = "EnumItem" + +[Enum.KeyCode.F12] +struct = "EnumItem" + +[Enum.KeyCode.F13] +struct = "EnumItem" + +[Enum.KeyCode.F14] +struct = "EnumItem" + +[Enum.KeyCode.F15] +struct = "EnumItem" + +[Enum.KeyCode.F2] +struct = "EnumItem" + +[Enum.KeyCode.F3] +struct = "EnumItem" + +[Enum.KeyCode.F4] +struct = "EnumItem" + +[Enum.KeyCode.F5] +struct = "EnumItem" + +[Enum.KeyCode.F6] +struct = "EnumItem" + +[Enum.KeyCode.F7] +struct = "EnumItem" + +[Enum.KeyCode.F8] +struct = "EnumItem" + +[Enum.KeyCode.F9] +struct = "EnumItem" + +[Enum.KeyCode.Five] +struct = "EnumItem" + +[Enum.KeyCode.Four] +struct = "EnumItem" + +[Enum.KeyCode.G] +struct = "EnumItem" + +[Enum.KeyCode.GetEnumItems] +args = [] +method = true + +[Enum.KeyCode.GreaterThan] +struct = "EnumItem" + +[Enum.KeyCode.H] +struct = "EnumItem" + +[Enum.KeyCode.Hash] +struct = "EnumItem" + +[Enum.KeyCode.Help] +struct = "EnumItem" + +[Enum.KeyCode.Home] +struct = "EnumItem" + +[Enum.KeyCode.I] +struct = "EnumItem" + +[Enum.KeyCode.Insert] +struct = "EnumItem" + +[Enum.KeyCode.J] +struct = "EnumItem" + +[Enum.KeyCode.K] +struct = "EnumItem" + +[Enum.KeyCode.KeypadDivide] +struct = "EnumItem" + +[Enum.KeyCode.KeypadEight] +struct = "EnumItem" + +[Enum.KeyCode.KeypadEnter] +struct = "EnumItem" + +[Enum.KeyCode.KeypadEquals] +struct = "EnumItem" + +[Enum.KeyCode.KeypadFive] +struct = "EnumItem" + +[Enum.KeyCode.KeypadFour] +struct = "EnumItem" + +[Enum.KeyCode.KeypadMinus] +struct = "EnumItem" + +[Enum.KeyCode.KeypadMultiply] +struct = "EnumItem" + +[Enum.KeyCode.KeypadNine] +struct = "EnumItem" + +[Enum.KeyCode.KeypadOne] +struct = "EnumItem" + +[Enum.KeyCode.KeypadPeriod] +struct = "EnumItem" + +[Enum.KeyCode.KeypadPlus] +struct = "EnumItem" + +[Enum.KeyCode.KeypadSeven] +struct = "EnumItem" + +[Enum.KeyCode.KeypadSix] +struct = "EnumItem" + +[Enum.KeyCode.KeypadThree] +struct = "EnumItem" + +[Enum.KeyCode.KeypadTwo] +struct = "EnumItem" + +[Enum.KeyCode.KeypadZero] +struct = "EnumItem" + +[Enum.KeyCode.L] +struct = "EnumItem" + +[Enum.KeyCode.Left] +struct = "EnumItem" + +[Enum.KeyCode.LeftAlt] +struct = "EnumItem" + +[Enum.KeyCode.LeftBracket] +struct = "EnumItem" + +[Enum.KeyCode.LeftControl] +struct = "EnumItem" + +[Enum.KeyCode.LeftCurly] +struct = "EnumItem" + +[Enum.KeyCode.LeftMeta] +struct = "EnumItem" + +[Enum.KeyCode.LeftParenthesis] +struct = "EnumItem" + +[Enum.KeyCode.LeftShift] +struct = "EnumItem" + +[Enum.KeyCode.LeftSuper] +struct = "EnumItem" + +[Enum.KeyCode.LessThan] +struct = "EnumItem" + +[Enum.KeyCode.M] +struct = "EnumItem" + +[Enum.KeyCode.Menu] +struct = "EnumItem" + +[Enum.KeyCode.Minus] +struct = "EnumItem" + +[Enum.KeyCode.Mode] +struct = "EnumItem" + +[Enum.KeyCode.N] +struct = "EnumItem" + +[Enum.KeyCode.Nine] +struct = "EnumItem" + +[Enum.KeyCode.NumLock] +struct = "EnumItem" + +[Enum.KeyCode.O] +struct = "EnumItem" + +[Enum.KeyCode.One] +struct = "EnumItem" + +[Enum.KeyCode.P] +struct = "EnumItem" + +[Enum.KeyCode.PageDown] +struct = "EnumItem" + +[Enum.KeyCode.PageUp] +struct = "EnumItem" + +[Enum.KeyCode.Pause] +struct = "EnumItem" + +[Enum.KeyCode.Percent] +struct = "EnumItem" + +[Enum.KeyCode.Period] +struct = "EnumItem" + +[Enum.KeyCode.Pipe] +struct = "EnumItem" + +[Enum.KeyCode.Plus] +struct = "EnumItem" + +[Enum.KeyCode.Power] +struct = "EnumItem" + +[Enum.KeyCode.Print] +struct = "EnumItem" + +[Enum.KeyCode.Q] +struct = "EnumItem" + +[Enum.KeyCode.Question] +struct = "EnumItem" + +[Enum.KeyCode.Quote] +struct = "EnumItem" + +[Enum.KeyCode.QuotedDouble] +struct = "EnumItem" + +[Enum.KeyCode.R] +struct = "EnumItem" + +[Enum.KeyCode.Return] +struct = "EnumItem" + +[Enum.KeyCode.Right] +struct = "EnumItem" + +[Enum.KeyCode.RightAlt] +struct = "EnumItem" + +[Enum.KeyCode.RightBracket] +struct = "EnumItem" + +[Enum.KeyCode.RightControl] +struct = "EnumItem" + +[Enum.KeyCode.RightCurly] +struct = "EnumItem" + +[Enum.KeyCode.RightMeta] +struct = "EnumItem" + +[Enum.KeyCode.RightParenthesis] +struct = "EnumItem" + +[Enum.KeyCode.RightShift] +struct = "EnumItem" + +[Enum.KeyCode.RightSuper] +struct = "EnumItem" + +[Enum.KeyCode.S] +struct = "EnumItem" + +[Enum.KeyCode.ScrollLock] +struct = "EnumItem" + +[Enum.KeyCode.Semicolon] +struct = "EnumItem" + +[Enum.KeyCode.Seven] +struct = "EnumItem" + +[Enum.KeyCode.Six] +struct = "EnumItem" + +[Enum.KeyCode.Slash] +struct = "EnumItem" + +[Enum.KeyCode.Space] +struct = "EnumItem" + +[Enum.KeyCode.SysReq] +struct = "EnumItem" + +[Enum.KeyCode.T] +struct = "EnumItem" + +[Enum.KeyCode.Tab] +struct = "EnumItem" + +[Enum.KeyCode.Three] +struct = "EnumItem" + +[Enum.KeyCode.Thumbstick1] +struct = "EnumItem" + +[Enum.KeyCode.Thumbstick2] +struct = "EnumItem" + +[Enum.KeyCode.Tilde] +struct = "EnumItem" + +[Enum.KeyCode.Two] +struct = "EnumItem" + +[Enum.KeyCode.U] +struct = "EnumItem" + +[Enum.KeyCode.Underscore] +struct = "EnumItem" + +[Enum.KeyCode.Undo] +struct = "EnumItem" + +[Enum.KeyCode.Unknown] +struct = "EnumItem" + +[Enum.KeyCode.Up] +struct = "EnumItem" + +[Enum.KeyCode.V] +struct = "EnumItem" + +[Enum.KeyCode.W] +struct = "EnumItem" + +[Enum.KeyCode.World0] +struct = "EnumItem" + +[Enum.KeyCode.World1] +struct = "EnumItem" + +[Enum.KeyCode.World10] +struct = "EnumItem" + +[Enum.KeyCode.World11] +struct = "EnumItem" + +[Enum.KeyCode.World12] +struct = "EnumItem" + +[Enum.KeyCode.World13] +struct = "EnumItem" + +[Enum.KeyCode.World14] +struct = "EnumItem" + +[Enum.KeyCode.World15] +struct = "EnumItem" + +[Enum.KeyCode.World16] +struct = "EnumItem" + +[Enum.KeyCode.World17] +struct = "EnumItem" + +[Enum.KeyCode.World18] +struct = "EnumItem" + +[Enum.KeyCode.World19] +struct = "EnumItem" + +[Enum.KeyCode.World2] +struct = "EnumItem" + +[Enum.KeyCode.World20] +struct = "EnumItem" + +[Enum.KeyCode.World21] +struct = "EnumItem" + +[Enum.KeyCode.World22] +struct = "EnumItem" + +[Enum.KeyCode.World23] +struct = "EnumItem" + +[Enum.KeyCode.World24] +struct = "EnumItem" + +[Enum.KeyCode.World25] +struct = "EnumItem" + +[Enum.KeyCode.World26] +struct = "EnumItem" + +[Enum.KeyCode.World27] +struct = "EnumItem" + +[Enum.KeyCode.World28] +struct = "EnumItem" + +[Enum.KeyCode.World29] +struct = "EnumItem" + +[Enum.KeyCode.World3] +struct = "EnumItem" + +[Enum.KeyCode.World30] +struct = "EnumItem" + +[Enum.KeyCode.World31] +struct = "EnumItem" + +[Enum.KeyCode.World32] +struct = "EnumItem" + +[Enum.KeyCode.World33] +struct = "EnumItem" + +[Enum.KeyCode.World34] +struct = "EnumItem" + +[Enum.KeyCode.World35] +struct = "EnumItem" + +[Enum.KeyCode.World36] +struct = "EnumItem" + +[Enum.KeyCode.World37] +struct = "EnumItem" + +[Enum.KeyCode.World38] +struct = "EnumItem" + +[Enum.KeyCode.World39] +struct = "EnumItem" + +[Enum.KeyCode.World4] +struct = "EnumItem" + +[Enum.KeyCode.World40] +struct = "EnumItem" + +[Enum.KeyCode.World41] +struct = "EnumItem" + +[Enum.KeyCode.World42] +struct = "EnumItem" + +[Enum.KeyCode.World43] +struct = "EnumItem" + +[Enum.KeyCode.World44] +struct = "EnumItem" + +[Enum.KeyCode.World45] +struct = "EnumItem" + +[Enum.KeyCode.World46] +struct = "EnumItem" + +[Enum.KeyCode.World47] +struct = "EnumItem" + +[Enum.KeyCode.World48] +struct = "EnumItem" + +[Enum.KeyCode.World49] +struct = "EnumItem" + +[Enum.KeyCode.World5] +struct = "EnumItem" + +[Enum.KeyCode.World50] +struct = "EnumItem" + +[Enum.KeyCode.World51] +struct = "EnumItem" + +[Enum.KeyCode.World52] +struct = "EnumItem" + +[Enum.KeyCode.World53] +struct = "EnumItem" + +[Enum.KeyCode.World54] +struct = "EnumItem" + +[Enum.KeyCode.World55] +struct = "EnumItem" + +[Enum.KeyCode.World56] +struct = "EnumItem" + +[Enum.KeyCode.World57] +struct = "EnumItem" + +[Enum.KeyCode.World58] +struct = "EnumItem" + +[Enum.KeyCode.World59] +struct = "EnumItem" + +[Enum.KeyCode.World6] +struct = "EnumItem" + +[Enum.KeyCode.World60] +struct = "EnumItem" + +[Enum.KeyCode.World61] +struct = "EnumItem" + +[Enum.KeyCode.World62] +struct = "EnumItem" + +[Enum.KeyCode.World63] +struct = "EnumItem" + +[Enum.KeyCode.World64] +struct = "EnumItem" + +[Enum.KeyCode.World65] +struct = "EnumItem" + +[Enum.KeyCode.World66] +struct = "EnumItem" + +[Enum.KeyCode.World67] +struct = "EnumItem" + +[Enum.KeyCode.World68] +struct = "EnumItem" + +[Enum.KeyCode.World69] +struct = "EnumItem" + +[Enum.KeyCode.World7] +struct = "EnumItem" + +[Enum.KeyCode.World70] +struct = "EnumItem" + +[Enum.KeyCode.World71] +struct = "EnumItem" + +[Enum.KeyCode.World72] +struct = "EnumItem" + +[Enum.KeyCode.World73] +struct = "EnumItem" + +[Enum.KeyCode.World74] +struct = "EnumItem" + +[Enum.KeyCode.World75] +struct = "EnumItem" + +[Enum.KeyCode.World76] +struct = "EnumItem" + +[Enum.KeyCode.World77] +struct = "EnumItem" + +[Enum.KeyCode.World78] +struct = "EnumItem" + +[Enum.KeyCode.World79] +struct = "EnumItem" + +[Enum.KeyCode.World8] +struct = "EnumItem" + +[Enum.KeyCode.World80] +struct = "EnumItem" + +[Enum.KeyCode.World81] +struct = "EnumItem" + +[Enum.KeyCode.World82] +struct = "EnumItem" + +[Enum.KeyCode.World83] +struct = "EnumItem" + +[Enum.KeyCode.World84] +struct = "EnumItem" + +[Enum.KeyCode.World85] +struct = "EnumItem" + +[Enum.KeyCode.World86] +struct = "EnumItem" + +[Enum.KeyCode.World87] +struct = "EnumItem" + +[Enum.KeyCode.World88] +struct = "EnumItem" + +[Enum.KeyCode.World89] +struct = "EnumItem" + +[Enum.KeyCode.World9] +struct = "EnumItem" + +[Enum.KeyCode.World90] +struct = "EnumItem" + +[Enum.KeyCode.World91] +struct = "EnumItem" + +[Enum.KeyCode.World92] +struct = "EnumItem" + +[Enum.KeyCode.World93] +struct = "EnumItem" + +[Enum.KeyCode.World94] +struct = "EnumItem" + +[Enum.KeyCode.World95] +struct = "EnumItem" + +[Enum.KeyCode.X] +struct = "EnumItem" + +[Enum.KeyCode.Y] +struct = "EnumItem" + +[Enum.KeyCode.Z] +struct = "EnumItem" + +[Enum.KeyCode.Zero] +struct = "EnumItem" +[Enum.KeywordFilterType.Exclude] +struct = "EnumItem" + +[Enum.KeywordFilterType.GetEnumItems] +args = [] +method = true + +[Enum.KeywordFilterType.Include] +struct = "EnumItem" +[Enum.Language.Default] +struct = "EnumItem" + +[Enum.Language.GetEnumItems] +args = [] +method = true +[Enum.LanguagePreference.English] +struct = "EnumItem" + +[Enum.LanguagePreference.GetEnumItems] +args = [] +method = true + +[Enum.LanguagePreference.SimplifiedChinese] +struct = "EnumItem" + +[Enum.LanguagePreference.SystemDefault] +struct = "EnumItem" +[Enum.LeftRight.Center] +struct = "EnumItem" + +[Enum.LeftRight.GetEnumItems] +args = [] +method = true + +[Enum.LeftRight.Left] +struct = "EnumItem" + +[Enum.LeftRight.Right] +struct = "EnumItem" +[Enum.LevelOfDetailSetting.GetEnumItems] +args = [] +method = true + +[Enum.LevelOfDetailSetting.High] +struct = "EnumItem" + +[Enum.LevelOfDetailSetting.Low] +struct = "EnumItem" + +[Enum.LevelOfDetailSetting.Medium] +struct = "EnumItem" +[Enum.Limb.GetEnumItems] +args = [] +method = true + +[Enum.Limb.Head] +struct = "EnumItem" + +[Enum.Limb.LeftArm] +struct = "EnumItem" + +[Enum.Limb.LeftLeg] +struct = "EnumItem" + +[Enum.Limb.RightArm] +struct = "EnumItem" + +[Enum.Limb.RightLeg] +struct = "EnumItem" + +[Enum.Limb.Torso] +struct = "EnumItem" + +[Enum.Limb.Unknown] +struct = "EnumItem" +[Enum.ListDisplayMode.GetEnumItems] +args = [] +method = true + +[Enum.ListDisplayMode.Horizontal] +struct = "EnumItem" + +[Enum.ListDisplayMode.Vertical] +struct = "EnumItem" +[Enum.ListenerType.CFrame] +struct = "EnumItem" + +[Enum.ListenerType.Camera] +struct = "EnumItem" + +[Enum.ListenerType.GetEnumItems] +args = [] +method = true + +[Enum.ListenerType.ObjectCFrame] +struct = "EnumItem" + +[Enum.ListenerType.ObjectPosition] +struct = "EnumItem" +[Enum.Material.Air] +struct = "EnumItem" + +[Enum.Material.Asphalt] +struct = "EnumItem" + +[Enum.Material.Basalt] +struct = "EnumItem" + +[Enum.Material.Brick] +struct = "EnumItem" + +[Enum.Material.Cobblestone] +struct = "EnumItem" + +[Enum.Material.Concrete] +struct = "EnumItem" + +[Enum.Material.CorrodedMetal] +struct = "EnumItem" + +[Enum.Material.CrackedLava] +struct = "EnumItem" + +[Enum.Material.DiamondPlate] +struct = "EnumItem" + +[Enum.Material.Fabric] +struct = "EnumItem" + +[Enum.Material.Foil] +struct = "EnumItem" + +[Enum.Material.ForceField] +struct = "EnumItem" + +[Enum.Material.GetEnumItems] +args = [] +method = true + +[Enum.Material.Glacier] +struct = "EnumItem" + +[Enum.Material.Glass] +struct = "EnumItem" + +[Enum.Material.Granite] +struct = "EnumItem" + +[Enum.Material.Grass] +struct = "EnumItem" + +[Enum.Material.Ground] +struct = "EnumItem" + +[Enum.Material.Ice] +struct = "EnumItem" + +[Enum.Material.LeafyGrass] +struct = "EnumItem" + +[Enum.Material.Limestone] +struct = "EnumItem" + +[Enum.Material.Marble] +struct = "EnumItem" + +[Enum.Material.Metal] +struct = "EnumItem" + +[Enum.Material.Mud] +struct = "EnumItem" + +[Enum.Material.Neon] +struct = "EnumItem" + +[Enum.Material.Pavement] +struct = "EnumItem" + +[Enum.Material.Pebble] +struct = "EnumItem" + +[Enum.Material.Plastic] +struct = "EnumItem" + +[Enum.Material.Rock] +struct = "EnumItem" + +[Enum.Material.Salt] +struct = "EnumItem" + +[Enum.Material.Sand] +struct = "EnumItem" + +[Enum.Material.Sandstone] +struct = "EnumItem" + +[Enum.Material.Slate] +struct = "EnumItem" + +[Enum.Material.SmoothPlastic] +struct = "EnumItem" + +[Enum.Material.Snow] +struct = "EnumItem" + +[Enum.Material.Water] +struct = "EnumItem" + +[Enum.Material.Wood] +struct = "EnumItem" + +[Enum.Material.WoodPlanks] +struct = "EnumItem" +[Enum.MembershipType.BuildersClub] +struct = "EnumItem" + +[Enum.MembershipType.GetEnumItems] +args = [] +method = true + +[Enum.MembershipType.None] +struct = "EnumItem" + +[Enum.MembershipType.OutrageousBuildersClub] +struct = "EnumItem" + +[Enum.MembershipType.Premium] +struct = "EnumItem" + +[Enum.MembershipType.TurboBuildersClub] +struct = "EnumItem" +[Enum.MeshType.Brick] +struct = "EnumItem" + +[Enum.MeshType.CornerWedge] +struct = "EnumItem" + +[Enum.MeshType.Cylinder] +struct = "EnumItem" + +[Enum.MeshType.FileMesh] +struct = "EnumItem" + +[Enum.MeshType.GetEnumItems] +args = [] +method = true + +[Enum.MeshType.Head] +struct = "EnumItem" + +[Enum.MeshType.ParallelRamp] +struct = "EnumItem" + +[Enum.MeshType.Prism] +struct = "EnumItem" + +[Enum.MeshType.Pyramid] +struct = "EnumItem" + +[Enum.MeshType.RightAngleRamp] +struct = "EnumItem" + +[Enum.MeshType.Sphere] +struct = "EnumItem" + +[Enum.MeshType.Torso] +struct = "EnumItem" + +[Enum.MeshType.Wedge] +struct = "EnumItem" +[Enum.MessageType.GetEnumItems] +args = [] +method = true + +[Enum.MessageType.MessageError] +struct = "EnumItem" + +[Enum.MessageType.MessageInfo] +struct = "EnumItem" + +[Enum.MessageType.MessageOutput] +struct = "EnumItem" + +[Enum.MessageType.MessageWarning] +struct = "EnumItem" +[Enum.ModifierKey.Alt] +struct = "EnumItem" + +[Enum.ModifierKey.Ctrl] +struct = "EnumItem" + +[Enum.ModifierKey.GetEnumItems] +args = [] +method = true + +[Enum.ModifierKey.Meta] +struct = "EnumItem" + +[Enum.ModifierKey.Shift] +struct = "EnumItem" +[Enum.MouseBehavior.Default] +struct = "EnumItem" + +[Enum.MouseBehavior.GetEnumItems] +args = [] +method = true + +[Enum.MouseBehavior.LockCenter] +struct = "EnumItem" + +[Enum.MouseBehavior.LockCurrentPosition] +struct = "EnumItem" +[Enum.MoveState.AirFree] +struct = "EnumItem" + +[Enum.MoveState.Coasting] +struct = "EnumItem" + +[Enum.MoveState.GetEnumItems] +args = [] +method = true + +[Enum.MoveState.Pushing] +struct = "EnumItem" + +[Enum.MoveState.Stopped] +struct = "EnumItem" + +[Enum.MoveState.Stopping] +struct = "EnumItem" +[Enum.NameOcclusion.EnemyOcclusion] +struct = "EnumItem" + +[Enum.NameOcclusion.GetEnumItems] +args = [] +method = true + +[Enum.NameOcclusion.NoOcclusion] +struct = "EnumItem" + +[Enum.NameOcclusion.OccludeAll] +struct = "EnumItem" +[Enum.NetworkOwnership.Automatic] +struct = "EnumItem" + +[Enum.NetworkOwnership.GetEnumItems] +args = [] +method = true + +[Enum.NetworkOwnership.Manual] +struct = "EnumItem" + +[Enum.NetworkOwnership.OnContact] +struct = "EnumItem" +[Enum.NormalId.Back] +struct = "EnumItem" + +[Enum.NormalId.Bottom] +struct = "EnumItem" + +[Enum.NormalId.Front] +struct = "EnumItem" + +[Enum.NormalId.GetEnumItems] +args = [] +method = true + +[Enum.NormalId.Left] +struct = "EnumItem" + +[Enum.NormalId.Right] +struct = "EnumItem" + +[Enum.NormalId.Top] +struct = "EnumItem" +[Enum.OutputLayoutMode.GetEnumItems] +args = [] +method = true + +[Enum.OutputLayoutMode.Horizontal] +struct = "EnumItem" + +[Enum.OutputLayoutMode.Vertical] +struct = "EnumItem" +[Enum.OverrideMouseIconBehavior.ForceHide] +struct = "EnumItem" + +[Enum.OverrideMouseIconBehavior.ForceShow] +struct = "EnumItem" + +[Enum.OverrideMouseIconBehavior.GetEnumItems] +args = [] +method = true + +[Enum.OverrideMouseIconBehavior.None] +struct = "EnumItem" +[Enum.PacketPriority.GetEnumItems] +args = [] +method = true + +[Enum.PacketPriority.HIGH_PRIORITY] +struct = "EnumItem" + +[Enum.PacketPriority.IMMEDIATE_PRIORITY] +struct = "EnumItem" + +[Enum.PacketPriority.LOW_PRIORITY] +struct = "EnumItem" + +[Enum.PacketPriority.MEDIUM_PRIORITY] +struct = "EnumItem" +[Enum.PartType.Ball] +struct = "EnumItem" + +[Enum.PartType.Block] +struct = "EnumItem" + +[Enum.PartType.Cylinder] +struct = "EnumItem" + +[Enum.PartType.GetEnumItems] +args = [] +method = true +[Enum.PathStatus.ClosestNoPath] +struct = "EnumItem" + +[Enum.PathStatus.ClosestOutOfRange] +struct = "EnumItem" + +[Enum.PathStatus.FailFinishNotEmpty] +struct = "EnumItem" + +[Enum.PathStatus.FailStartNotEmpty] +struct = "EnumItem" + +[Enum.PathStatus.GetEnumItems] +args = [] +method = true + +[Enum.PathStatus.NoPath] +struct = "EnumItem" + +[Enum.PathStatus.Success] +struct = "EnumItem" +[Enum.PathWaypointAction.GetEnumItems] +args = [] +method = true + +[Enum.PathWaypointAction.Jump] +struct = "EnumItem" + +[Enum.PathWaypointAction.Walk] +struct = "EnumItem" +[Enum.PermissionLevelShown.Game] +struct = "EnumItem" + +[Enum.PermissionLevelShown.GetEnumItems] +args = [] +method = true + +[Enum.PermissionLevelShown.Roblox] +struct = "EnumItem" + +[Enum.PermissionLevelShown.RobloxGame] +struct = "EnumItem" + +[Enum.PermissionLevelShown.RobloxScript] +struct = "EnumItem" + +[Enum.PermissionLevelShown.Studio] +struct = "EnumItem" +[Enum.Platform.Android] +struct = "EnumItem" + +[Enum.Platform.AndroidTV] +struct = "EnumItem" + +[Enum.Platform.BeOS] +struct = "EnumItem" + +[Enum.Platform.Chromecast] +struct = "EnumItem" + +[Enum.Platform.DOS] +struct = "EnumItem" + +[Enum.Platform.GetEnumItems] +args = [] +method = true + +[Enum.Platform.IOS] +struct = "EnumItem" + +[Enum.Platform.Linux] +struct = "EnumItem" + +[Enum.Platform.NX] +struct = "EnumItem" + +[Enum.Platform.None] +struct = "EnumItem" + +[Enum.Platform.OSX] +struct = "EnumItem" + +[Enum.Platform.Ouya] +struct = "EnumItem" + +[Enum.Platform.PS3] +struct = "EnumItem" + +[Enum.Platform.PS4] +struct = "EnumItem" + +[Enum.Platform.SteamOS] +struct = "EnumItem" + +[Enum.Platform.UWP] +struct = "EnumItem" + +[Enum.Platform.WebOS] +struct = "EnumItem" + +[Enum.Platform.WiiU] +struct = "EnumItem" + +[Enum.Platform.Windows] +struct = "EnumItem" + +[Enum.Platform.XBox360] +struct = "EnumItem" + +[Enum.Platform.XBoxOne] +struct = "EnumItem" +[Enum.PlaybackState.Begin] +struct = "EnumItem" + +[Enum.PlaybackState.Cancelled] +struct = "EnumItem" + +[Enum.PlaybackState.Completed] +struct = "EnumItem" + +[Enum.PlaybackState.Delayed] +struct = "EnumItem" + +[Enum.PlaybackState.GetEnumItems] +args = [] +method = true + +[Enum.PlaybackState.Paused] +struct = "EnumItem" + +[Enum.PlaybackState.Playing] +struct = "EnumItem" +[Enum.PlayerActions.CharacterBackward] +struct = "EnumItem" + +[Enum.PlayerActions.CharacterForward] +struct = "EnumItem" + +[Enum.PlayerActions.CharacterJump] +struct = "EnumItem" + +[Enum.PlayerActions.CharacterLeft] +struct = "EnumItem" + +[Enum.PlayerActions.CharacterRight] +struct = "EnumItem" + +[Enum.PlayerActions.GetEnumItems] +args = [] +method = true +[Enum.PlayerChatType.All] +struct = "EnumItem" + +[Enum.PlayerChatType.GetEnumItems] +args = [] +method = true + +[Enum.PlayerChatType.Team] +struct = "EnumItem" + +[Enum.PlayerChatType.Whisper] +struct = "EnumItem" +[Enum.PoseEasingDirection.GetEnumItems] +args = [] +method = true + +[Enum.PoseEasingDirection.In] +struct = "EnumItem" + +[Enum.PoseEasingDirection.InOut] +struct = "EnumItem" + +[Enum.PoseEasingDirection.Out] +struct = "EnumItem" +[Enum.PoseEasingStyle.Bounce] +struct = "EnumItem" + +[Enum.PoseEasingStyle.Constant] +struct = "EnumItem" + +[Enum.PoseEasingStyle.Cubic] +struct = "EnumItem" + +[Enum.PoseEasingStyle.Elastic] +struct = "EnumItem" + +[Enum.PoseEasingStyle.GetEnumItems] +args = [] +method = true + +[Enum.PoseEasingStyle.Linear] +struct = "EnumItem" +[Enum.PrivilegeType.Admin] +struct = "EnumItem" + +[Enum.PrivilegeType.Banned] +struct = "EnumItem" + +[Enum.PrivilegeType.GetEnumItems] +args = [] +method = true + +[Enum.PrivilegeType.Member] +struct = "EnumItem" + +[Enum.PrivilegeType.Owner] +struct = "EnumItem" + +[Enum.PrivilegeType.Visitor] +struct = "EnumItem" +[Enum.ProductPurchaseDecision.GetEnumItems] +args = [] +method = true + +[Enum.ProductPurchaseDecision.NotProcessedYet] +struct = "EnumItem" + +[Enum.ProductPurchaseDecision.PurchaseGranted] +struct = "EnumItem" +[Enum.QualityLevel.Automatic] +struct = "EnumItem" + +[Enum.QualityLevel.GetEnumItems] +args = [] +method = true + +[Enum.QualityLevel.Level01] +struct = "EnumItem" + +[Enum.QualityLevel.Level02] +struct = "EnumItem" + +[Enum.QualityLevel.Level03] +struct = "EnumItem" + +[Enum.QualityLevel.Level04] +struct = "EnumItem" + +[Enum.QualityLevel.Level05] +struct = "EnumItem" + +[Enum.QualityLevel.Level06] +struct = "EnumItem" + +[Enum.QualityLevel.Level07] +struct = "EnumItem" + +[Enum.QualityLevel.Level08] +struct = "EnumItem" + +[Enum.QualityLevel.Level09] +struct = "EnumItem" + +[Enum.QualityLevel.Level10] +struct = "EnumItem" + +[Enum.QualityLevel.Level11] +struct = "EnumItem" + +[Enum.QualityLevel.Level12] +struct = "EnumItem" + +[Enum.QualityLevel.Level13] +struct = "EnumItem" + +[Enum.QualityLevel.Level14] +struct = "EnumItem" + +[Enum.QualityLevel.Level15] +struct = "EnumItem" + +[Enum.QualityLevel.Level16] +struct = "EnumItem" + +[Enum.QualityLevel.Level17] +struct = "EnumItem" + +[Enum.QualityLevel.Level18] +struct = "EnumItem" + +[Enum.QualityLevel.Level19] +struct = "EnumItem" + +[Enum.QualityLevel.Level20] +struct = "EnumItem" + +[Enum.QualityLevel.Level21] +struct = "EnumItem" +[Enum.R15CollisionType.GetEnumItems] +args = [] +method = true + +[Enum.R15CollisionType.InnerBox] +struct = "EnumItem" + +[Enum.R15CollisionType.OuterBox] +struct = "EnumItem" +[Enum.RaycastFilterType.Blacklist] +struct = "EnumItem" + +[Enum.RaycastFilterType.GetEnumItems] +args = [] +method = true + +[Enum.RaycastFilterType.Whitelist] +struct = "EnumItem" +[Enum.RenderFidelity.Automatic] +struct = "EnumItem" + +[Enum.RenderFidelity.GetEnumItems] +args = [] +method = true + +[Enum.RenderFidelity.Precise] +struct = "EnumItem" +[Enum.RenderPriority.Camera] +struct = "EnumItem" + +[Enum.RenderPriority.Character] +struct = "EnumItem" + +[Enum.RenderPriority.First] +struct = "EnumItem" + +[Enum.RenderPriority.GetEnumItems] +args = [] +method = true + +[Enum.RenderPriority.Input] +struct = "EnumItem" + +[Enum.RenderPriority.Last] +struct = "EnumItem" +[Enum.RenderingTestComparisonMethod.GetEnumItems] +args = [] +method = true + +[Enum.RenderingTestComparisonMethod.diff] +struct = "EnumItem" + +[Enum.RenderingTestComparisonMethod.psnr] +struct = "EnumItem" +[Enum.ReturnKeyType.Default] +struct = "EnumItem" + +[Enum.ReturnKeyType.Done] +struct = "EnumItem" + +[Enum.ReturnKeyType.GetEnumItems] +args = [] +method = true + +[Enum.ReturnKeyType.Go] +struct = "EnumItem" + +[Enum.ReturnKeyType.Next] +struct = "EnumItem" + +[Enum.ReturnKeyType.Search] +struct = "EnumItem" + +[Enum.ReturnKeyType.Send] +struct = "EnumItem" +[Enum.ReverbType.Alley] +struct = "EnumItem" + +[Enum.ReverbType.Arena] +struct = "EnumItem" + +[Enum.ReverbType.Auditorium] +struct = "EnumItem" + +[Enum.ReverbType.Bathroom] +struct = "EnumItem" + +[Enum.ReverbType.CarpettedHallway] +struct = "EnumItem" + +[Enum.ReverbType.Cave] +struct = "EnumItem" + +[Enum.ReverbType.City] +struct = "EnumItem" + +[Enum.ReverbType.ConcertHall] +struct = "EnumItem" + +[Enum.ReverbType.Forest] +struct = "EnumItem" + +[Enum.ReverbType.GenericReverb] +struct = "EnumItem" + +[Enum.ReverbType.GetEnumItems] +args = [] +method = true + +[Enum.ReverbType.Hallway] +struct = "EnumItem" + +[Enum.ReverbType.Hangar] +struct = "EnumItem" + +[Enum.ReverbType.LivingRoom] +struct = "EnumItem" + +[Enum.ReverbType.Mountains] +struct = "EnumItem" + +[Enum.ReverbType.NoReverb] +struct = "EnumItem" + +[Enum.ReverbType.PaddedCell] +struct = "EnumItem" + +[Enum.ReverbType.ParkingLot] +struct = "EnumItem" + +[Enum.ReverbType.Plain] +struct = "EnumItem" + +[Enum.ReverbType.Quarry] +struct = "EnumItem" + +[Enum.ReverbType.Room] +struct = "EnumItem" + +[Enum.ReverbType.SewerPipe] +struct = "EnumItem" + +[Enum.ReverbType.StoneCorridor] +struct = "EnumItem" + +[Enum.ReverbType.StoneRoom] +struct = "EnumItem" + +[Enum.ReverbType.UnderWater] +struct = "EnumItem" +[Enum.RibbonTool.ColorPicker] +struct = "EnumItem" + +[Enum.RibbonTool.GetEnumItems] +args = [] +method = true + +[Enum.RibbonTool.Group] +struct = "EnumItem" + +[Enum.RibbonTool.MaterialPicker] +struct = "EnumItem" + +[Enum.RibbonTool.Move] +struct = "EnumItem" + +[Enum.RibbonTool.None] +struct = "EnumItem" + +[Enum.RibbonTool.Rotate] +struct = "EnumItem" + +[Enum.RibbonTool.Scale] +struct = "EnumItem" + +[Enum.RibbonTool.Select] +struct = "EnumItem" + +[Enum.RibbonTool.Transform] +struct = "EnumItem" + +[Enum.RibbonTool.Ungroup] +struct = "EnumItem" +[Enum.RollOffMode.GetEnumItems] +args = [] +method = true + +[Enum.RollOffMode.Inverse] +struct = "EnumItem" + +[Enum.RollOffMode.InverseTapered] +struct = "EnumItem" + +[Enum.RollOffMode.Linear] +struct = "EnumItem" + +[Enum.RollOffMode.LinearSquare] +struct = "EnumItem" +[Enum.RotationType.CameraRelative] +struct = "EnumItem" + +[Enum.RotationType.GetEnumItems] +args = [] +method = true + +[Enum.RotationType.MovementRelative] +struct = "EnumItem" +[Enum.RuntimeUndoBehavior.Aggregate] +struct = "EnumItem" + +[Enum.RuntimeUndoBehavior.GetEnumItems] +args = [] +method = true + +[Enum.RuntimeUndoBehavior.Hybrid] +struct = "EnumItem" + +[Enum.RuntimeUndoBehavior.Snapshot] +struct = "EnumItem" +[Enum.SaveFilter.GetEnumItems] +args = [] +method = true + +[Enum.SaveFilter.SaveAll] +struct = "EnumItem" + +[Enum.SaveFilter.SaveGame] +struct = "EnumItem" + +[Enum.SaveFilter.SaveWorld] +struct = "EnumItem" +[Enum.SavedQualitySetting.Automatic] +struct = "EnumItem" + +[Enum.SavedQualitySetting.GetEnumItems] +args = [] +method = true + +[Enum.SavedQualitySetting.QualityLevel1] +struct = "EnumItem" + +[Enum.SavedQualitySetting.QualityLevel10] +struct = "EnumItem" + +[Enum.SavedQualitySetting.QualityLevel2] +struct = "EnumItem" + +[Enum.SavedQualitySetting.QualityLevel3] +struct = "EnumItem" + +[Enum.SavedQualitySetting.QualityLevel4] +struct = "EnumItem" + +[Enum.SavedQualitySetting.QualityLevel5] +struct = "EnumItem" + +[Enum.SavedQualitySetting.QualityLevel6] +struct = "EnumItem" + +[Enum.SavedQualitySetting.QualityLevel7] +struct = "EnumItem" + +[Enum.SavedQualitySetting.QualityLevel8] +struct = "EnumItem" + +[Enum.SavedQualitySetting.QualityLevel9] +struct = "EnumItem" +[Enum.ScaleType.Crop] +struct = "EnumItem" + +[Enum.ScaleType.Fit] +struct = "EnumItem" + +[Enum.ScaleType.GetEnumItems] +args = [] +method = true + +[Enum.ScaleType.Slice] +struct = "EnumItem" + +[Enum.ScaleType.Stretch] +struct = "EnumItem" + +[Enum.ScaleType.Tile] +struct = "EnumItem" +[Enum.ScreenOrientation.GetEnumItems] +args = [] +method = true + +[Enum.ScreenOrientation.LandscapeLeft] +struct = "EnumItem" + +[Enum.ScreenOrientation.LandscapeRight] +struct = "EnumItem" + +[Enum.ScreenOrientation.LandscapeSensor] +struct = "EnumItem" + +[Enum.ScreenOrientation.Portrait] +struct = "EnumItem" + +[Enum.ScreenOrientation.Sensor] +struct = "EnumItem" +[Enum.ScrollBarInset.Always] +struct = "EnumItem" + +[Enum.ScrollBarInset.GetEnumItems] +args = [] +method = true + +[Enum.ScrollBarInset.None] +struct = "EnumItem" + +[Enum.ScrollBarInset.ScrollBar] +struct = "EnumItem" +[Enum.ScrollingDirection.GetEnumItems] +args = [] +method = true + +[Enum.ScrollingDirection.X] +struct = "EnumItem" + +[Enum.ScrollingDirection.XY] +struct = "EnumItem" + +[Enum.ScrollingDirection.Y] +struct = "EnumItem" +[Enum.ServerAudioBehavior.Enabled] +struct = "EnumItem" + +[Enum.ServerAudioBehavior.GetEnumItems] +args = [] +method = true + +[Enum.ServerAudioBehavior.Muted] +struct = "EnumItem" + +[Enum.ServerAudioBehavior.OnlineGame] +struct = "EnumItem" +[Enum.SizeConstraint.GetEnumItems] +args = [] +method = true + +[Enum.SizeConstraint.RelativeXX] +struct = "EnumItem" + +[Enum.SizeConstraint.RelativeXY] +struct = "EnumItem" + +[Enum.SizeConstraint.RelativeYY] +struct = "EnumItem" +[Enum.SortOrder.Custom] +struct = "EnumItem" + +[Enum.SortOrder.GetEnumItems] +args = [] +method = true + +[Enum.SortOrder.LayoutOrder] +struct = "EnumItem" + +[Enum.SortOrder.Name] +struct = "EnumItem" +[Enum.SoundType.Boing] +struct = "EnumItem" + +[Enum.SoundType.Bomb] +struct = "EnumItem" + +[Enum.SoundType.Break] +struct = "EnumItem" + +[Enum.SoundType.Click] +struct = "EnumItem" + +[Enum.SoundType.Clock] +struct = "EnumItem" + +[Enum.SoundType.GetEnumItems] +args = [] +method = true + +[Enum.SoundType.NoSound] +struct = "EnumItem" + +[Enum.SoundType.Page] +struct = "EnumItem" + +[Enum.SoundType.Ping] +struct = "EnumItem" + +[Enum.SoundType.Slingshot] +struct = "EnumItem" + +[Enum.SoundType.Snap] +struct = "EnumItem" + +[Enum.SoundType.Splat] +struct = "EnumItem" + +[Enum.SoundType.Step] +struct = "EnumItem" + +[Enum.SoundType.StepOn] +struct = "EnumItem" + +[Enum.SoundType.Swoosh] +struct = "EnumItem" + +[Enum.SoundType.Victory] +struct = "EnumItem" +[Enum.SpecialKey.ChatHotkey] +struct = "EnumItem" + +[Enum.SpecialKey.End] +struct = "EnumItem" + +[Enum.SpecialKey.GetEnumItems] +args = [] +method = true + +[Enum.SpecialKey.Home] +struct = "EnumItem" + +[Enum.SpecialKey.Insert] +struct = "EnumItem" + +[Enum.SpecialKey.PageDown] +struct = "EnumItem" + +[Enum.SpecialKey.PageUp] +struct = "EnumItem" +[Enum.StartCorner.BottomLeft] +struct = "EnumItem" + +[Enum.StartCorner.BottomRight] +struct = "EnumItem" + +[Enum.StartCorner.GetEnumItems] +args = [] +method = true + +[Enum.StartCorner.TopLeft] +struct = "EnumItem" + +[Enum.StartCorner.TopRight] +struct = "EnumItem" +[Enum.Status.Confusion] +struct = "EnumItem" + +[Enum.Status.GetEnumItems] +args = [] +method = true + +[Enum.Status.Poison] +struct = "EnumItem" +[Enum.StreamingPauseMode.ClientPhysicsPause] +struct = "EnumItem" + +[Enum.StreamingPauseMode.Default] +struct = "EnumItem" + +[Enum.StreamingPauseMode.Disabled] +struct = "EnumItem" + +[Enum.StreamingPauseMode.GetEnumItems] +args = [] +method = true +[Enum.StudioDataModelType.Edit] +struct = "EnumItem" + +[Enum.StudioDataModelType.GetEnumItems] +args = [] +method = true + +[Enum.StudioDataModelType.None] +struct = "EnumItem" + +[Enum.StudioDataModelType.PlayClient] +struct = "EnumItem" + +[Enum.StudioDataModelType.PlayServer] +struct = "EnumItem" + +[Enum.StudioDataModelType.RobloxPlugin] +struct = "EnumItem" + +[Enum.StudioDataModelType.UserPlugin] +struct = "EnumItem" +[Enum.StudioStyleGuideColor.Border] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.BrightText] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.Button] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ButtonBorder] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ButtonText] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.CategoryItem] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.CheckedFieldBackground] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.CheckedFieldBorder] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.CheckedFieldIndicator] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ColorPickerFrame] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.CurrentMarker] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.Dark] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DebuggerCurrentLine] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DebuggerErrorLine] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DialogButton] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DialogButtonBorder] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DialogButtonText] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DialogMainButton] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DialogMainButtonText] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DiffFilePathBackground] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DiffFilePathBorder] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DiffFilePathText] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DiffLineNum] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DiffLineNumAdditionBackground] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DiffLineNumDeletionBackground] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DiffLineNumNoChangeBackground] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DiffLineNumSeparatorBackground] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DiffTextAddition] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DiffTextAdditionBackground] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DiffTextDeletion] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DiffTextDeletionBackground] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DiffTextHunkInfo] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DiffTextNoChange] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DiffTextNoChangeBackground] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DiffTextSeparatorBackground] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.DimmedText] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.Dropdown] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.EmulatorBar] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.EmulatorDropDown] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ErrorText] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.GameSettingsTableItem] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.GameSettingsTooltip] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.GetEnumItems] +args = [] +method = true + +[Enum.StudioStyleGuideColor.HeaderSection] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.InfoText] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.InputFieldBackground] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.InputFieldBorder] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.Item] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.Light] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.LinkText] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.MainBackground] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.MainButton] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.MainText] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.Mid] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.Midlight] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.Notification] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.RibbonButton] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.RibbonTab] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.RibbonTabTopBar] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ScriptBackground] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ScriptBuiltInFunction] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ScriptComment] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ScriptError] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ScriptFindSelectionBackground] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ScriptKeyword] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ScriptMatchingWordSelectionBackground] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ScriptNumber] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ScriptOperator] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ScriptPreprocessor] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ScriptSelectionBackground] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ScriptSelectionText] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ScriptSideWidget] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ScriptString] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ScriptText] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ScriptWarning] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ScrollBar] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ScrollBarBackground] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.SensitiveText] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.Separator] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.Shadow] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.StatusBar] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.SubText] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.Tab] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.TabBar] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.TableItem] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.Titlebar] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.TitlebarText] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.Tooltip] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.ViewPortBackground] +struct = "EnumItem" + +[Enum.StudioStyleGuideColor.WarningText] +struct = "EnumItem" +[Enum.StudioStyleGuideModifier.Default] +struct = "EnumItem" + +[Enum.StudioStyleGuideModifier.Disabled] +struct = "EnumItem" + +[Enum.StudioStyleGuideModifier.GetEnumItems] +args = [] +method = true + +[Enum.StudioStyleGuideModifier.Hover] +struct = "EnumItem" + +[Enum.StudioStyleGuideModifier.Pressed] +struct = "EnumItem" + +[Enum.StudioStyleGuideModifier.Selected] +struct = "EnumItem" +[Enum.Style.AlternatingSupports] +struct = "EnumItem" + +[Enum.Style.BridgeStyleSupports] +struct = "EnumItem" + +[Enum.Style.GetEnumItems] +args = [] +method = true + +[Enum.Style.NoSupports] +struct = "EnumItem" +[Enum.SurfaceConstraint.GetEnumItems] +args = [] +method = true + +[Enum.SurfaceConstraint.Hinge] +struct = "EnumItem" + +[Enum.SurfaceConstraint.Motor] +struct = "EnumItem" + +[Enum.SurfaceConstraint.None] +struct = "EnumItem" + +[Enum.SurfaceConstraint.SteppingMotor] +struct = "EnumItem" +[Enum.SurfaceGuiSizingMode.FixedSize] +struct = "EnumItem" + +[Enum.SurfaceGuiSizingMode.GetEnumItems] +args = [] +method = true + +[Enum.SurfaceGuiSizingMode.PixelsPerStud] +struct = "EnumItem" +[Enum.SurfaceType.GetEnumItems] +args = [] +method = true + +[Enum.SurfaceType.Glue] +struct = "EnumItem" + +[Enum.SurfaceType.Hinge] +struct = "EnumItem" + +[Enum.SurfaceType.Inlet] +struct = "EnumItem" + +[Enum.SurfaceType.Motor] +struct = "EnumItem" + +[Enum.SurfaceType.Smooth] +struct = "EnumItem" + +[Enum.SurfaceType.SmoothNoOutlines] +struct = "EnumItem" + +[Enum.SurfaceType.SteppingMotor] +struct = "EnumItem" + +[Enum.SurfaceType.Studs] +struct = "EnumItem" + +[Enum.SurfaceType.Universal] +struct = "EnumItem" + +[Enum.SurfaceType.Weld] +struct = "EnumItem" +[Enum.SwipeDirection.Down] +struct = "EnumItem" + +[Enum.SwipeDirection.GetEnumItems] +args = [] +method = true + +[Enum.SwipeDirection.Left] +struct = "EnumItem" + +[Enum.SwipeDirection.None] +struct = "EnumItem" + +[Enum.SwipeDirection.Right] +struct = "EnumItem" + +[Enum.SwipeDirection.Up] +struct = "EnumItem" +[Enum.TableMajorAxis.ColumnMajor] +struct = "EnumItem" + +[Enum.TableMajorAxis.GetEnumItems] +args = [] +method = true + +[Enum.TableMajorAxis.RowMajor] +struct = "EnumItem" +[Enum.Technology.Compatibility] +struct = "EnumItem" + +[Enum.Technology.GetEnumItems] +args = [] +method = true + +[Enum.Technology.Legacy] +struct = "EnumItem" + +[Enum.Technology.ShadowMap] +struct = "EnumItem" + +[Enum.Technology.Voxel] +struct = "EnumItem" +[Enum.TeleportResult.Failure] +struct = "EnumItem" + +[Enum.TeleportResult.Flooded] +struct = "EnumItem" + +[Enum.TeleportResult.GameEnded] +struct = "EnumItem" + +[Enum.TeleportResult.GameFull] +struct = "EnumItem" + +[Enum.TeleportResult.GameNotFound] +struct = "EnumItem" + +[Enum.TeleportResult.GetEnumItems] +args = [] +method = true + +[Enum.TeleportResult.IsTeleporting] +struct = "EnumItem" + +[Enum.TeleportResult.Success] +struct = "EnumItem" + +[Enum.TeleportResult.Unauthorized] +struct = "EnumItem" +[Enum.TeleportState.Failed] +struct = "EnumItem" + +[Enum.TeleportState.GetEnumItems] +args = [] +method = true + +[Enum.TeleportState.InProgress] +struct = "EnumItem" + +[Enum.TeleportState.RequestedFromServer] +struct = "EnumItem" + +[Enum.TeleportState.Started] +struct = "EnumItem" + +[Enum.TeleportState.WaitingForServer] +struct = "EnumItem" +[Enum.TeleportType.GetEnumItems] +args = [] +method = true + +[Enum.TeleportType.ToInstance] +struct = "EnumItem" + +[Enum.TeleportType.ToPlace] +struct = "EnumItem" + +[Enum.TeleportType.ToReservedServer] +struct = "EnumItem" +[Enum.TextFilterContext.GetEnumItems] +args = [] +method = true + +[Enum.TextFilterContext.PrivateChat] +struct = "EnumItem" + +[Enum.TextFilterContext.PublicChat] +struct = "EnumItem" +[Enum.TextInputType.Default] +struct = "EnumItem" + +[Enum.TextInputType.Email] +struct = "EnumItem" + +[Enum.TextInputType.GetEnumItems] +args = [] +method = true + +[Enum.TextInputType.NoSuggestions] +struct = "EnumItem" + +[Enum.TextInputType.Number] +struct = "EnumItem" + +[Enum.TextInputType.Password] +struct = "EnumItem" + +[Enum.TextInputType.Phone] +struct = "EnumItem" +[Enum.TextTruncate.AtEnd] +struct = "EnumItem" + +[Enum.TextTruncate.GetEnumItems] +args = [] +method = true + +[Enum.TextTruncate.None] +struct = "EnumItem" +[Enum.TextXAlignment.Center] +struct = "EnumItem" + +[Enum.TextXAlignment.GetEnumItems] +args = [] +method = true + +[Enum.TextXAlignment.Left] +struct = "EnumItem" + +[Enum.TextXAlignment.Right] +struct = "EnumItem" +[Enum.TextYAlignment.Bottom] +struct = "EnumItem" + +[Enum.TextYAlignment.Center] +struct = "EnumItem" + +[Enum.TextYAlignment.GetEnumItems] +args = [] +method = true + +[Enum.TextYAlignment.Top] +struct = "EnumItem" +[Enum.TextureMode.GetEnumItems] +args = [] +method = true + +[Enum.TextureMode.Static] +struct = "EnumItem" + +[Enum.TextureMode.Stretch] +struct = "EnumItem" + +[Enum.TextureMode.Wrap] +struct = "EnumItem" +[Enum.TextureQueryType.GetEnumItems] +args = [] +method = true + +[Enum.TextureQueryType.Humanoid] +struct = "EnumItem" + +[Enum.TextureQueryType.HumanoidOrphaned] +struct = "EnumItem" + +[Enum.TextureQueryType.NonHumanoid] +struct = "EnumItem" + +[Enum.TextureQueryType.NonHumanoidOrphaned] +struct = "EnumItem" +[Enum.ThreadPoolConfig.Auto] +struct = "EnumItem" + +[Enum.ThreadPoolConfig.GetEnumItems] +args = [] +method = true + +[Enum.ThreadPoolConfig.PerCore1] +struct = "EnumItem" + +[Enum.ThreadPoolConfig.PerCore2] +struct = "EnumItem" + +[Enum.ThreadPoolConfig.PerCore3] +struct = "EnumItem" + +[Enum.ThreadPoolConfig.PerCore4] +struct = "EnumItem" + +[Enum.ThreadPoolConfig.Threads1] +struct = "EnumItem" + +[Enum.ThreadPoolConfig.Threads16] +struct = "EnumItem" + +[Enum.ThreadPoolConfig.Threads2] +struct = "EnumItem" + +[Enum.ThreadPoolConfig.Threads3] +struct = "EnumItem" + +[Enum.ThreadPoolConfig.Threads4] +struct = "EnumItem" + +[Enum.ThreadPoolConfig.Threads8] +struct = "EnumItem" +[Enum.ThrottlingPriority.Default] +struct = "EnumItem" + +[Enum.ThrottlingPriority.ElevatedOnServer] +struct = "EnumItem" + +[Enum.ThrottlingPriority.Extreme] +struct = "EnumItem" + +[Enum.ThrottlingPriority.GetEnumItems] +args = [] +method = true +[Enum.ThumbnailSize.GetEnumItems] +args = [] +method = true + +[Enum.ThumbnailSize.Size100x100] +struct = "EnumItem" + +[Enum.ThumbnailSize.Size150x150] +struct = "EnumItem" + +[Enum.ThumbnailSize.Size180x180] +struct = "EnumItem" + +[Enum.ThumbnailSize.Size352x352] +struct = "EnumItem" + +[Enum.ThumbnailSize.Size420x420] +struct = "EnumItem" + +[Enum.ThumbnailSize.Size48x48] +struct = "EnumItem" + +[Enum.ThumbnailSize.Size60x60] +struct = "EnumItem" +[Enum.ThumbnailType.AvatarBust] +struct = "EnumItem" + +[Enum.ThumbnailType.AvatarThumbnail] +struct = "EnumItem" + +[Enum.ThumbnailType.GetEnumItems] +args = [] +method = true + +[Enum.ThumbnailType.HeadShot] +struct = "EnumItem" +[Enum.TickCountSampleMethod.Benchmark] +struct = "EnumItem" + +[Enum.TickCountSampleMethod.Fast] +struct = "EnumItem" + +[Enum.TickCountSampleMethod.GetEnumItems] +args = [] +method = true + +[Enum.TickCountSampleMethod.Precise] +struct = "EnumItem" +[Enum.TopBottom.Bottom] +struct = "EnumItem" + +[Enum.TopBottom.Center] +struct = "EnumItem" + +[Enum.TopBottom.GetEnumItems] +args = [] +method = true + +[Enum.TopBottom.Top] +struct = "EnumItem" +[Enum.TouchCameraMovementMode.Classic] +struct = "EnumItem" + +[Enum.TouchCameraMovementMode.Default] +struct = "EnumItem" + +[Enum.TouchCameraMovementMode.Follow] +struct = "EnumItem" + +[Enum.TouchCameraMovementMode.GetEnumItems] +args = [] +method = true + +[Enum.TouchCameraMovementMode.Orbital] +struct = "EnumItem" +[Enum.TouchMovementMode.ClickToMove] +struct = "EnumItem" + +[Enum.TouchMovementMode.DPad] +struct = "EnumItem" + +[Enum.TouchMovementMode.Default] +struct = "EnumItem" + +[Enum.TouchMovementMode.DynamicThumbstick] +struct = "EnumItem" + +[Enum.TouchMovementMode.GetEnumItems] +args = [] +method = true + +[Enum.TouchMovementMode.Thumbpad] +struct = "EnumItem" + +[Enum.TouchMovementMode.Thumbstick] +struct = "EnumItem" +[Enum.TweenStatus.Canceled] +struct = "EnumItem" + +[Enum.TweenStatus.Completed] +struct = "EnumItem" + +[Enum.TweenStatus.GetEnumItems] +args = [] +method = true +[Enum.UITheme.Dark] +struct = "EnumItem" + +[Enum.UITheme.GetEnumItems] +args = [] +method = true + +[Enum.UITheme.Light] +struct = "EnumItem" +[Enum.UiMessageType.GetEnumItems] +args = [] +method = true + +[Enum.UiMessageType.UiMessageError] +struct = "EnumItem" + +[Enum.UiMessageType.UiMessageInfo] +struct = "EnumItem" +[Enum.UploadSetting.Always] +struct = "EnumItem" + +[Enum.UploadSetting.Ask] +struct = "EnumItem" + +[Enum.UploadSetting.GetEnumItems] +args = [] +method = true + +[Enum.UploadSetting.Never] +struct = "EnumItem" +[Enum.UserCFrame.GetEnumItems] +args = [] +method = true + +[Enum.UserCFrame.Head] +struct = "EnumItem" + +[Enum.UserCFrame.LeftHand] +struct = "EnumItem" + +[Enum.UserCFrame.RightHand] +struct = "EnumItem" +[Enum.UserInputState.Begin] +struct = "EnumItem" + +[Enum.UserInputState.Cancel] +struct = "EnumItem" + +[Enum.UserInputState.Change] +struct = "EnumItem" + +[Enum.UserInputState.End] +struct = "EnumItem" + +[Enum.UserInputState.GetEnumItems] +args = [] +method = true + +[Enum.UserInputState.None] +struct = "EnumItem" +[Enum.UserInputType.Accelerometer] +struct = "EnumItem" + +[Enum.UserInputType.Focus] +struct = "EnumItem" + +[Enum.UserInputType.Gamepad1] +struct = "EnumItem" + +[Enum.UserInputType.Gamepad2] +struct = "EnumItem" + +[Enum.UserInputType.Gamepad3] +struct = "EnumItem" + +[Enum.UserInputType.Gamepad4] +struct = "EnumItem" + +[Enum.UserInputType.Gamepad5] +struct = "EnumItem" + +[Enum.UserInputType.Gamepad6] +struct = "EnumItem" + +[Enum.UserInputType.Gamepad7] +struct = "EnumItem" + +[Enum.UserInputType.Gamepad8] +struct = "EnumItem" + +[Enum.UserInputType.GetEnumItems] +args = [] +method = true + +[Enum.UserInputType.Gyro] +struct = "EnumItem" + +[Enum.UserInputType.InputMethod] +struct = "EnumItem" + +[Enum.UserInputType.Keyboard] +struct = "EnumItem" + +[Enum.UserInputType.MouseButton1] +struct = "EnumItem" + +[Enum.UserInputType.MouseButton2] +struct = "EnumItem" + +[Enum.UserInputType.MouseButton3] +struct = "EnumItem" + +[Enum.UserInputType.MouseMovement] +struct = "EnumItem" + +[Enum.UserInputType.MouseWheel] +struct = "EnumItem" + +[Enum.UserInputType.None] +struct = "EnumItem" + +[Enum.UserInputType.TextInput] +struct = "EnumItem" + +[Enum.UserInputType.Touch] +struct = "EnumItem" +[Enum.VRTouchpad.GetEnumItems] +args = [] +method = true + +[Enum.VRTouchpad.Left] +struct = "EnumItem" + +[Enum.VRTouchpad.Right] +struct = "EnumItem" +[Enum.VRTouchpadMode.ABXY] +struct = "EnumItem" + +[Enum.VRTouchpadMode.GetEnumItems] +args = [] +method = true + +[Enum.VRTouchpadMode.Touch] +struct = "EnumItem" + +[Enum.VRTouchpadMode.VirtualThumbstick] +struct = "EnumItem" +[Enum.VerticalAlignment.Bottom] +struct = "EnumItem" + +[Enum.VerticalAlignment.Center] +struct = "EnumItem" + +[Enum.VerticalAlignment.GetEnumItems] +args = [] +method = true + +[Enum.VerticalAlignment.Top] +struct = "EnumItem" +[Enum.VerticalScrollBarPosition.GetEnumItems] +args = [] +method = true + +[Enum.VerticalScrollBarPosition.Left] +struct = "EnumItem" + +[Enum.VerticalScrollBarPosition.Right] +struct = "EnumItem" +[Enum.VibrationMotor.GetEnumItems] +args = [] +method = true + +[Enum.VibrationMotor.Large] +struct = "EnumItem" + +[Enum.VibrationMotor.LeftHand] +struct = "EnumItem" + +[Enum.VibrationMotor.LeftTrigger] +struct = "EnumItem" + +[Enum.VibrationMotor.RightHand] +struct = "EnumItem" + +[Enum.VibrationMotor.RightTrigger] +struct = "EnumItem" + +[Enum.VibrationMotor.Small] +struct = "EnumItem" +[Enum.VideoQualitySettings.GetEnumItems] +args = [] +method = true + +[Enum.VideoQualitySettings.HighResolution] +struct = "EnumItem" + +[Enum.VideoQualitySettings.LowResolution] +struct = "EnumItem" + +[Enum.VideoQualitySettings.MediumResolution] +struct = "EnumItem" +[Enum.VirtualInputMode.GetEnumItems] +args = [] +method = true + +[Enum.VirtualInputMode.None] +struct = "EnumItem" + +[Enum.VirtualInputMode.Playing] +struct = "EnumItem" + +[Enum.VirtualInputMode.Recording] +struct = "EnumItem" +[Enum.WaterDirection.GetEnumItems] +args = [] +method = true + +[Enum.WaterDirection.NegX] +struct = "EnumItem" + +[Enum.WaterDirection.NegY] +struct = "EnumItem" + +[Enum.WaterDirection.NegZ] +struct = "EnumItem" + +[Enum.WaterDirection.X] +struct = "EnumItem" + +[Enum.WaterDirection.Y] +struct = "EnumItem" + +[Enum.WaterDirection.Z] +struct = "EnumItem" +[Enum.WaterForce.GetEnumItems] +args = [] +method = true + +[Enum.WaterForce.Max] +struct = "EnumItem" + +[Enum.WaterForce.Medium] +struct = "EnumItem" + +[Enum.WaterForce.None] +struct = "EnumItem" + +[Enum.WaterForce.Small] +struct = "EnumItem" + +[Enum.WaterForce.Strong] +struct = "EnumItem" +[Enum.ZIndexBehavior.GetEnumItems] +args = [] +method = true + +[Enum.ZIndexBehavior.Global] +struct = "EnumItem" + +[Enum.ZIndexBehavior.Sibling] +struct = "EnumItem" +[[Instance.new.args]] +type = ["Accoutrement", "Accessory", "Hat", "AdvancedDragger", "Animation", "AnimationController", "Animator", "Attachment", "Backpack", "HopperBin", "Tool", "Flag", "Beam", "BindableEvent", "BindableFunction", "BodyAngularVelocity", "BodyForce", "BodyGyro", "BodyPosition", "BodyThrust", "BodyVelocity", "RocketPropulsion", "Camera", "BodyColors", "CharacterMesh", "Pants", "Shirt", "ShirtGraphic", "Skin", "ClickDetector", "Configuration", "AlignOrientation", "AlignPosition", "AngularVelocity", "BallSocketConstraint", "HingeConstraint", "LineForce", "RodConstraint", "RopeConstraint", "CylindricalConstraint", "PrismaticConstraint", "SpringConstraint", "Torque", "VectorForce", "HumanoidController", "SkateboardController", "VehicleController", "CustomEvent", "CustomEventReceiver", "BlockMesh", "CylinderMesh", "FileMesh", "SpecialMesh", "DebuggerWatch", "Dialog", "DialogChoice", "Dragger", "Explosion", "Decal", "Texture", "Hole", "MotorFeature", "Fire", "FlyweightService", "CSGDictionaryService", "NonReplicatedCSGDictionaryService", "Folder", "ForceField", "FunctionalTest", "Frame", "ImageButton", "TextButton", "ImageLabel", "TextLabel", "ScrollingFrame", "TextBox", "VideoFrame", "ViewportFrame", "BillboardGui", "ScreenGui", "GuiMain", "SurfaceGui", "FloorWire", "SelectionBox", "BoxHandleAdornment", "ConeHandleAdornment", "CylinderHandleAdornment", "ImageHandleAdornment", "LineHandleAdornment", "SphereHandleAdornment", "ParabolaAdornment", "SelectionSphere", "ArcHandles", "Handles", "SurfaceSelection", "SelectionPartLasso", "SelectionPointLasso", "Humanoid", "HumanoidDescription", "RotateP", "RotateV", "Glue", "ManualGlue", "ManualWeld", "Motor", "Motor6D", "Rotate", "Snap", "VelocityMotor", "Weld", "Keyframe", "KeyframeMarker", "KeyframeSequence", "PointLight", "SpotLight", "SurfaceLight", "LocalizationTable", "Script", "LocalScript", "ModuleScript", "Message", "Hint", "NoCollisionConstraint", "CornerWedgePart", "Part", "FlagStand", "Seat", "SkateboardPlatform", "SpawnLocation", "WedgePart", "MeshPart", "PartOperation", "NegateOperation", "UnionOperation", "TrussPart", "VehicleSeat", "Model", "WorldModel", "PartOperationAsset", "ParticleEmitter", "Player", "PluginAction", "Pose", "BloomEffect", "BlurEffect", "ColorCorrectionEffect", "SunRaysEffect", "ReflectionMetadata", "ReflectionMetadataCallbacks", "ReflectionMetadataClasses", "ReflectionMetadataEnums", "ReflectionMetadataEvents", "ReflectionMetadataFunctions", "ReflectionMetadataClass", "ReflectionMetadataEnum", "ReflectionMetadataEnumItem", "ReflectionMetadataMember", "ReflectionMetadataProperties", "ReflectionMetadataYieldFunctions", "RemoteEvent", "RemoteFunction", "RenderingTest", "Sky", "Smoke", "Sound", "ChorusSoundEffect", "CompressorSoundEffect", "DistortionSoundEffect", "EchoSoundEffect", "EqualizerSoundEffect", "FlangeSoundEffect", "PitchShiftSoundEffect", "ReverbSoundEffect", "TremoloSoundEffect", "SoundGroup", "Sparkles", "StandalonePluginScripts", "StarterGear", "SurfaceAppearance", "Team", "TerrainRegion", "TestService", "Trail", "Tween", "UIAspectRatioConstraint", "UISizeConstraint", "UITextSizeConstraint", "UIGradient", "UIGridLayout", "UIInlineLayout", "UIListLayout", "UIPageLayout", "UITableLayout", "UIPadding", "UIScale", "BinaryStringValue", "BoolValue", "BrickColorValue", "CFrameValue", "Color3Value", "DoubleConstrainedValue", "IntConstrainedValue", "IntValue", "NumberValue", "ObjectValue", "RayValue", "StringValue", "Vector3Value", "VirtualInputManager", "WeldConstraint"] +[[NumberRange.new.args]] +type = "number" + +[[NumberRange.new.args]] +required = false +type = "number" +[[NumberSequence.new.args]] +type = "any" + +[[NumberSequence.new.args]] +required = false +type = "number" +[[NumberSequenceKeypoint.new.args]] +type = "number" + +[[NumberSequenceKeypoint.new.args]] +type = "number" + +[[NumberSequenceKeypoint.new.args]] +required = false +type = "number" +[[PhysicalProperties.new.args]] +type = "any" + +[[PhysicalProperties.new.args]] +required = false +type = "number" + +[[PhysicalProperties.new.args]] +required = false +type = "number" + +[[PhysicalProperties.new.args]] +required = false +type = "number" + +[[PhysicalProperties.new.args]] +required = false +type = "number" +[[Random.new.args]] +required = false +type = "number" +[[Ray.new.args]] +[Ray.new.args.type] +display = "Vector3" + +[[Ray.new.args]] +[Ray.new.args.type] +display = "Vector3" +[[Rect.new.args]] +type = "any" + +[[Rect.new.args]] +type = "any" + +[[Rect.new.args]] +required = false +type = "any" + +[[Rect.new.args]] +required = false +type = "any" +[[Region3.new.args]] +[Region3.new.args.type] +display = "Vector3" + +[[Region3.new.args]] +[Region3.new.args.type] +display = "Vector3" +[[Region3int16.new.args]] +[Region3int16.new.args.type] +display = "Vector3" + +[[Region3int16.new.args]] +[Region3int16.new.args.type] +display = "Vector3" +[[TweenInfo.new.args]] +required = false +type = "number" + +[[TweenInfo.new.args]] +required = false + +[TweenInfo.new.args.type] +display = "EasingStyle" + +[[TweenInfo.new.args]] +required = false + +[TweenInfo.new.args.type] +display = "EasingDirection" + +[[TweenInfo.new.args]] +required = false +type = "number" + +[[TweenInfo.new.args]] +required = false +type = "bool" + +[[TweenInfo.new.args]] +required = false +type = "number" +[[UDim.new.args]] +type = "number" + +[[UDim.new.args]] +type = "number" +[[UDim2.fromOffset.args]] +type = "number" + +[[UDim2.fromOffset.args]] +type = "number" +[[UDim2.fromScale.args]] +type = "number" + +[[UDim2.fromScale.args]] +type = "number" +[[UDim2.new.args]] +required = false +type = "any" + +[[UDim2.new.args]] +required = false +type = "any" + +[[UDim2.new.args]] +required = false +type = "any" + +[[UDim2.new.args]] +required = false +type = "any" + +[UserSettings] +args = [] +[[Vector2.new.args]] +required = false +type = "number" + +[[Vector2.new.args]] +required = false +type = "number" +[[Vector2int16.new.args]] +required = false +type = "number" + +[[Vector2int16.new.args]] +required = false +type = "number" +[[Vector3.FromAxis.args]] +[Vector3.FromAxis.args.type] +display = "Axis" +[[Vector3.FromNormalId.args]] +[Vector3.FromNormalId.args.type] +display = "NormalId" +[[Vector3.new.args]] +required = false +type = "number" + +[[Vector3.new.args]] +required = false +type = "number" + +[[Vector3.new.args]] +required = false +type = "number" +[[Vector3int16.new.args]] +required = false +type = "number" + +[[Vector3int16.new.args]] +required = false +type = "number" + +[[Vector3int16.new.args]] +required = false +type = "number" +[[bit32.arshift.args]] +type = "number" + +[[bit32.arshift.args]] +type = "number" +[[bit32.band.args]] +type = "number" +[[bit32.bnot.args]] +type = "number" +[[bit32.bor.args]] +type = "..." +[[bit32.btest.args]] +type = "..." +[[bit32.bxor.args]] +type = "..." +[[bit32.extract.args]] +type = "number" + +[[bit32.extract.args]] +type = "number" + +[[bit32.extract.args]] +required = false +type = "number" +[[bit32.lrotate.args]] +type = "number" + +[[bit32.lrotate.args]] +type = "number" +[[bit32.lshift.args]] +type = "number" + +[[bit32.lshift.args]] +type = "number" +[[bit32.replace.args]] +type = "number" + +[[bit32.replace.args]] +type = "number" + +[[bit32.replace.args]] +required = false +type = "number" +[[bit32.rrotate.args]] +type = "number" + +[[bit32.rrotate.args]] +type = "number" +[[bit32.rshift.args]] +type = "number" + +[[bit32.rshift.args]] +type = "number" +[[collectgarbage.args]] +type = ["count"] +[coroutine.isyieldable] +args = [] +[debug.debug] +removed = true + +[debug.getfenv] +removed = true + +[debug.gethook] +removed = true + +[debug.getinfo] +removed = true + +[debug.getmetatable] +removed = true + +[debug.getregistry] +removed = true + +[debug.getupvalue] +removed = true +[[debug.profilebegin.args]] +type = "string" + +[debug.profileend] +args = [] + +[debug.setfenv] +removed = true + +[debug.sethook] +removed = true + +[debug.setlocal] +removed = true + +[debug.setmetatable] +removed = true + +[debug.setupvalue] +removed = true +[[delay.args]] +type = "number" + +[[delay.args]] +type = "function" + +[dofile] +removed = true + +[game] +struct = "DataModel" + +[io] +removed = true + +[load] +removed = true + +[loadfile] +removed = true +[[math.clamp.args]] +type = "number" + +[[math.clamp.args]] +type = "number" + +[[math.clamp.args]] +type = "number" +[[math.log.args]] +type = "number" + +[[math.log.args]] +required = false +type = "number" +[[math.noise.args]] +type = "number" + +[[math.noise.args]] +required = false +type = "number" + +[[math.noise.args]] +required = false +type = "number" +[[math.sign.args]] +type = "number" + +[module] +removed = true +[os.clock] +removed = true + +[os.execute] +removed = true + +[os.exit] +removed = true + +[os.getenv] +removed = true + +[os.remove] +removed = true + +[os.rename] +removed = true + +[os.setlocale] +removed = true + +[os.tmpname] +removed = true + +[plugin] +struct = "Plugin" + +[script] +struct = "Script" + +[settings] +args = [] + +[shared] +property = true +writable = "new-fields" +[[spawn.args]] +type = "function" +[[string.split.args]] +type = "string" + +[[string.split.args]] +required = false +type = "string" +[[table.create.args]] +type = "number" + +[[table.create.args]] +required = false +type = "any" +[[table.find.args]] +type = "table" + +[[table.find.args]] +type = "any" + +[[table.find.args]] +required = false +type = "number" +[[table.move.args]] +type = "table" + +[[table.move.args]] +type = "number" + +[[table.move.args]] +type = "number" + +[[table.move.args]] +type = "number" + +[[table.move.args]] +required = false +type = "table" +[[table.pack.args]] +type = "..." +[[table.unpack.args]] +type = "table" + +[[table.unpack.args]] +required = false +type = "number" + +[[table.unpack.args]] +required = false +type = "number" + +[tick] +args = [] + +[time] +args = [] +[[typeof.args]] +type = "any" +[[utf8.char.args]] +required = "utf8.char should be used with an argument despite it not throwing" +type = "number" + +[[utf8.char.args]] +required = false +type = "..." + +[utf8.charpattern] +property = true +[[utf8.codepoint.args]] +type = "string" + +[[utf8.codepoint.args]] +required = false +type = "number" + +[[utf8.codepoint.args]] +required = false +type = "number" +[[utf8.codes.args]] +type = "string" +[[utf8.graphemes.args]] +type = "string" + +[[utf8.graphemes.args]] +required = false +type = "number" + +[[utf8.graphemes.args]] +required = false +type = "number" +[[utf8.len.args]] +type = "string" + +[[utf8.len.args]] +required = false +type = "number" + +[[utf8.len.args]] +required = false +type = "number" +[[utf8.nfcnormalize.args]] +type = "string" +[[utf8.nfdnormalize.args]] +type = "string" +[[utf8.offset.args]] +type = "string" + +[[utf8.offset.args]] +required = false +type = "number" + +[[utf8.offset.args]] +required = false +type = "number" +[[wait.args]] +required = false +type = "number" +[[warn.args]] +type = "string" + +[[warn.args]] +required = false +type = "..." + +[workspace] +struct = "Workspace" diff --git a/scripts/get_wally_version_string.py b/scripts/get_wally_version_string.py new file mode 100644 index 0000000..8ca9a25 --- /dev/null +++ b/scripts/get_wally_version_string.py @@ -0,0 +1,4 @@ +import toml + +wally_manifest = toml.load('wally.toml') +print(wally_manifest['package']['version'], end='') diff --git a/scripts/upload_model.py b/scripts/upload_model.py new file mode 100644 index 0000000..14e97d3 --- /dev/null +++ b/scripts/upload_model.py @@ -0,0 +1,37 @@ +from argparse import ArgumentParser +import requests + +parser = ArgumentParser() +parser.add_argument("-a", "--assetid", dest="assetid", required=True) +parser.add_argument("-f", "--file", dest="filepath", required=True) +parser.add_argument("-r", "--roblosecurity", + dest="roblosecurity", required=True) + +args = parser.parse_args() + +url = "https://data.roblox.com/Data/Upload.ashx?assetid=" + args.assetid +cookies = {'.ROBLOSECURITY': args.roblosecurity} +headers = { + 'Content-Type': 'application/xml', + 'User-Agent': 'roblox', + 'x-csrf-token': ''} + +with open(args.filepath, 'rb') as file_reader: + payload = file_reader.read() + + response = requests.post( + url=url, + data=payload, + cookies=cookies, + headers=headers) + + if response.status_code == 403: + headers['x-csrf-token'] = response.headers['x-csrf-token'] + response = requests.post( + url=url, + data=payload, + cookies=cookies, + headers=headers) + + if response.status_code != 200: + raise Exception("Request did not succeed") diff --git a/selene.toml b/selene.toml new file mode 100644 index 0000000..2b7bbf6 --- /dev/null +++ b/selene.toml @@ -0,0 +1,4 @@ +std = "roblox-testez" + +[config.unused_variable] +allow_unused_self = true diff --git a/spec.lua b/spec.lua deleted file mode 100644 index 56f9d29..0000000 --- a/spec.lua +++ /dev/null @@ -1,26 +0,0 @@ --- borrowed from Roact - -local LOAD_MODULES = { - {"lib", "Library"}, - {"modules/testez/lib", "TestEZ"}, -} - -package.path = package.path .. ";?/init.lua" -local lemur = require("modules.lemur") -local habitat = lemur.Habitat.new() - -local Root = lemur.Instance.new("Folder") -Root.Name = "Root" - -for _, module in ipairs(LOAD_MODULES) do - local container = habitat:loadFromFs(module[1]) - container.Name = module[2] - container.Parent = Root -end - -local TestEZ = habitat:require(Root.TestEZ) -local results = TestEZ.TestBootstrap:run(Root.Library, TestEZ.Reporters.TextReporter) - -if results.failureCount > 0 then - os.exit(1) -end \ No newline at end of file diff --git a/spec.server.lua b/spec.server.lua new file mode 100644 index 0000000..8cad646 --- /dev/null +++ b/spec.server.lua @@ -0,0 +1,13 @@ +local ReplicatedStorage = game:GetService("ReplicatedStorage") + +local TestEZ = require(ReplicatedStorage.wally_packages.testez) + +local testRoots = { + ReplicatedStorage.src, +} +local results = TestEZ.TestBootstrap:run(testRoots, TestEZ.Reporters.TextReporter) + +-- Did something go wrong? +if #results.errors > 0 or results.failureCount > 0 then + error("Tests failed") +end diff --git a/lib/linalg.lua b/src/linalg.lua similarity index 100% rename from lib/linalg.lua rename to src/linalg.lua diff --git a/lib/linalg.spec.lua b/src/linalg.spec.lua similarity index 100% rename from lib/linalg.spec.lua rename to src/linalg.spec.lua diff --git a/standalone-model.project.json b/standalone-model.project.json new file mode 100644 index 0000000..8386caa --- /dev/null +++ b/standalone-model.project.json @@ -0,0 +1,6 @@ +{ + "name": "signals-tooling", + "tree": { + "$path": "src" + } +} \ No newline at end of file diff --git a/unit-tests.project.json b/unit-tests.project.json new file mode 100644 index 0000000..e7a0ce1 --- /dev/null +++ b/unit-tests.project.json @@ -0,0 +1,37 @@ +{ + "name": "test-rojo-proj", + "globIgnorePaths": [ + "**/package.json", + "**/tsconfig.json", + "**/*.project.json", + "**/.editorconfig", + "**/.git*", + "**/.vscode", + "**/*.md", + "**/*.toml", + "**/*.yaml", + "**/*.yml", + "**/*.lock" + ], + "tree": { + "$className": "DataModel", + "ReplicatedStorage": { + "$className": "ReplicatedStorage", + "wally_packages": { + "$path": "Packages", + "node_modules": { + "$path": "./node_modules/@rbxts" + } + }, + "src": { + "$path": "./src" + } + }, + "ServerScriptService": { + "$className": "ServerScriptService", + "TestRunner": { + "$path": "./spec.server.lua" + } + } + } +} \ No newline at end of file diff --git a/wally.lock b/wally.lock new file mode 100644 index 0000000..776e56f --- /dev/null +++ b/wally.lock @@ -0,0 +1,13 @@ +# This file is automatically @generated by Wally. +# It is not intended for manual editing. +registry = "test" + +[[package]] +name = "bytebit/linalg" +version = "0.0.1" +dependencies = [["testez", "roblox/testez@0.4.1"]] + +[[package]] +name = "roblox/testez" +version = "0.4.1" +dependencies = [] diff --git a/wally.toml b/wally.toml new file mode 100644 index 0000000..aac4c45 --- /dev/null +++ b/wally.toml @@ -0,0 +1,10 @@ +[package] +name = "bytebit/linalg" +description = "A simple script to implement linear algebra functions not provided by the Lua standard API, developed especially for use on Roblox" +version = "0.0.1" +license = "MIT" +registry = "https://github.com/UpliftGames/wally-index" +realm = "shared" + +[dependencies] +testez = "roblox/testez@0.4.1" \ No newline at end of file From a2855696a0deb07c849546c7239d077511d95b63 Mon Sep 17 00:00:00 2001 From: Noah Crowley Date: Tue, 2 Nov 2021 12:34:21 -0400 Subject: [PATCH 3/4] install wally packages in workflows --- .github/workflows/CI.yml | 2 ++ .github/workflows/Release.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f419740..ae2c3b1 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -30,6 +30,8 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: install foreman packages (rojo, run-in-roblox) run: foreman install + - name: install wally packages + run: wally install - name: run rojo build run: rojo build -o .\\unit_tests.rbxlx .\\unit-tests.project.json - name: run tests diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index 48dde8e..76482af 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -18,6 +18,8 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: install foreman packages (rojo, run-in-roblox) run: foreman install + - name: install wally packages + run: wally install - name: run rojo build run: rojo build -o ./linalg-${{ steps.get_wally_version.outputs.version-string }}.rbxmx ./standalone-model.project.json - name: create-release From 391b1eaeba0d8a914a9e55c834609ff06bcdff9a Mon Sep 17 00:00:00 2001 From: Noah Crowley Date: Tue, 2 Nov 2021 12:37:21 -0400 Subject: [PATCH 4/4] Clean up project.json files --- standalone-model.project.json | 2 +- unit-tests.project.json | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/standalone-model.project.json b/standalone-model.project.json index 8386caa..eb0367a 100644 --- a/standalone-model.project.json +++ b/standalone-model.project.json @@ -1,5 +1,5 @@ { - "name": "signals-tooling", + "name": "linalg", "tree": { "$path": "src" } diff --git a/unit-tests.project.json b/unit-tests.project.json index e7a0ce1..4f0b3e8 100644 --- a/unit-tests.project.json +++ b/unit-tests.project.json @@ -1,5 +1,5 @@ { - "name": "test-rojo-proj", + "name": "unit-tests", "globIgnorePaths": [ "**/package.json", "**/tsconfig.json", @@ -18,10 +18,7 @@ "ReplicatedStorage": { "$className": "ReplicatedStorage", "wally_packages": { - "$path": "Packages", - "node_modules": { - "$path": "./node_modules/@rbxts" - } + "$path": "Packages" }, "src": { "$path": "./src"