roblox-opencode 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/README.md +112 -122
  2. package/commands/setup-game.md +108 -108
  3. package/commands/sync-check.md +53 -53
  4. package/core/roblox-core.md +93 -93
  5. package/dist/server.js +189 -167
  6. package/package.json +35 -35
  7. package/skills/roblox-analytics/SKILL.md +277 -277
  8. package/skills/roblox-analytics/references/event-batcher.luau +75 -75
  9. package/skills/roblox-animation-vfx/SKILL.md +1325 -1325
  10. package/skills/roblox-architecture/SKILL.md +863 -863
  11. package/skills/roblox-architecture/references/combat-systems.md +1381 -1381
  12. package/skills/roblox-code-review/SKILL.md +686 -686
  13. package/skills/roblox-data/SKILL.md +889 -889
  14. package/skills/roblox-data/references/inventory-systems.md +1729 -1729
  15. package/skills/roblox-debug/SKILL.md +98 -98
  16. package/skills/roblox-gui/SKILL.md +1103 -1103
  17. package/skills/roblox-gui-fusion/SKILL.md +150 -150
  18. package/skills/roblox-gui-fusion/references/inventory.luau +427 -427
  19. package/skills/roblox-gui-fusion/references/settings-menu.luau +579 -579
  20. package/skills/roblox-gui-fusion/references/shop.luau +411 -411
  21. package/skills/roblox-luau-mastery/SKILL.md +1519 -1519
  22. package/skills/roblox-monetization/SKILL.md +1084 -1084
  23. package/skills/roblox-monetization/references/process-receipt.luau +131 -131
  24. package/skills/roblox-networking/SKILL.md +669 -669
  25. package/skills/roblox-networking/references/remote-validator.luau +193 -193
  26. package/skills/roblox-publish-checklist/SKILL.md +127 -127
  27. package/skills/roblox-runtime/SKILL.md +753 -753
  28. package/skills/roblox-sharp-edges/SKILL.md +294 -294
  29. package/skills/roblox-sync/SKILL.md +126 -126
  30. package/skills/roblox-testing/SKILL.md +943 -943
  31. package/skills/roblox-tooling/SKILL.md +149 -149
  32. package/vendor/LICENSES/ProfileStore-LICENSE +201 -201
  33. package/vendor/LICENSES/RbxUtil-LICENSE +7 -7
  34. package/vendor/LICENSES/promise-LICENSE +20 -20
  35. package/vendor/LICENSES/t-LICENSE +21 -21
  36. package/vendor/LICENSES/testez-LICENSE +200 -200
  37. package/vendor/README.md +83 -83
  38. package/vendor/fusion/Animation/ExternalTime.luau +83 -83
  39. package/vendor/fusion/Animation/Spring.luau +321 -321
  40. package/vendor/fusion/Animation/Stopwatch.luau +127 -127
  41. package/vendor/fusion/Animation/Tween.luau +187 -187
  42. package/vendor/fusion/Animation/getTweenDuration.luau +27 -27
  43. package/vendor/fusion/Animation/getTweenRatio.luau +47 -47
  44. package/vendor/fusion/Animation/lerpType.luau +163 -163
  45. package/vendor/fusion/Animation/packType.luau +99 -99
  46. package/vendor/fusion/Animation/springCoefficients.luau +80 -80
  47. package/vendor/fusion/Animation/unpackType.luau +102 -102
  48. package/vendor/fusion/Colour/Oklab.luau +70 -70
  49. package/vendor/fusion/Colour/sRGB.luau +54 -54
  50. package/vendor/fusion/External.luau +167 -167
  51. package/vendor/fusion/ExternalDebug.luau +69 -69
  52. package/vendor/fusion/Graph/Observer.luau +113 -113
  53. package/vendor/fusion/Graph/castToGraph.luau +28 -28
  54. package/vendor/fusion/Graph/change.luau +80 -80
  55. package/vendor/fusion/Graph/depend.luau +32 -32
  56. package/vendor/fusion/Graph/evaluate.luau +55 -55
  57. package/vendor/fusion/Instances/Attribute.luau +57 -57
  58. package/vendor/fusion/Instances/AttributeChange.luau +46 -46
  59. package/vendor/fusion/Instances/AttributeOut.luau +63 -63
  60. package/vendor/fusion/Instances/Child.luau +21 -21
  61. package/vendor/fusion/Instances/Children.luau +147 -147
  62. package/vendor/fusion/Instances/Hydrate.luau +32 -32
  63. package/vendor/fusion/Instances/New.luau +52 -52
  64. package/vendor/fusion/Instances/OnChange.luau +49 -49
  65. package/vendor/fusion/Instances/OnEvent.luau +53 -53
  66. package/vendor/fusion/Instances/Out.luau +69 -69
  67. package/vendor/fusion/Instances/applyInstanceProps.luau +148 -148
  68. package/vendor/fusion/Instances/defaultProps.luau +194 -194
  69. package/vendor/fusion/LICENSE +21 -21
  70. package/vendor/fusion/Logging/formatError.luau +48 -48
  71. package/vendor/fusion/Logging/messages.luau +51 -51
  72. package/vendor/fusion/Logging/parseError.luau +24 -24
  73. package/vendor/fusion/Memory/checkLifetime.luau +133 -133
  74. package/vendor/fusion/Memory/deriveScope.luau +23 -23
  75. package/vendor/fusion/Memory/deriveScopeImpl.luau +44 -44
  76. package/vendor/fusion/Memory/doCleanup.luau +78 -78
  77. package/vendor/fusion/Memory/innerScope.luau +33 -33
  78. package/vendor/fusion/Memory/legacyCleanup.luau +17 -17
  79. package/vendor/fusion/Memory/needsDestruction.luau +16 -16
  80. package/vendor/fusion/Memory/poisonScope.luau +33 -33
  81. package/vendor/fusion/Memory/scopePool.luau +54 -54
  82. package/vendor/fusion/Memory/scoped.luau +26 -26
  83. package/vendor/fusion/Memory/whichLivesLonger.luau +74 -74
  84. package/vendor/fusion/RobloxExternal.luau +97 -97
  85. package/vendor/fusion/State/Computed.luau +138 -138
  86. package/vendor/fusion/State/For/Disassembly.luau +210 -210
  87. package/vendor/fusion/State/For/ForTypes.luau +30 -30
  88. package/vendor/fusion/State/For/init.luau +109 -109
  89. package/vendor/fusion/State/ForKeys.luau +93 -93
  90. package/vendor/fusion/State/ForPairs.luau +96 -96
  91. package/vendor/fusion/State/ForValues.luau +93 -93
  92. package/vendor/fusion/State/Value.luau +87 -87
  93. package/vendor/fusion/State/castToState.luau +25 -25
  94. package/vendor/fusion/State/peek.luau +30 -30
  95. package/vendor/fusion/Types.luau +314 -314
  96. package/vendor/fusion/Utility/Contextual.luau +90 -90
  97. package/vendor/fusion/Utility/Safe.luau +22 -22
  98. package/vendor/fusion/Utility/isSimilar.luau +29 -29
  99. package/vendor/fusion/Utility/merge.luau +35 -35
  100. package/vendor/fusion/Utility/nameOf.luau +34 -34
  101. package/vendor/fusion/Utility/never.luau +13 -13
  102. package/vendor/fusion/Utility/nicknames.luau +10 -10
  103. package/vendor/fusion/Utility/xtypeof.luau +26 -26
  104. package/vendor/fusion/init.luau +82 -82
  105. package/vendor/profilestore/init.luau +2242 -2242
  106. package/vendor/promise/init.luau +1982 -1982
  107. package/vendor/rbxutil/buffer-util/Buffer.test.luau +25 -25
  108. package/vendor/rbxutil/buffer-util/BufferReader.luau +228 -228
  109. package/vendor/rbxutil/buffer-util/BufferWriter.luau +269 -269
  110. package/vendor/rbxutil/buffer-util/DataTypeBuffer.luau +223 -223
  111. package/vendor/rbxutil/buffer-util/Types.luau +60 -60
  112. package/vendor/rbxutil/buffer-util/index.d.ts +153 -153
  113. package/vendor/rbxutil/buffer-util/init.luau +41 -41
  114. package/vendor/rbxutil/buffer-util/package.json +16 -16
  115. package/vendor/rbxutil/buffer-util/wally.toml +9 -9
  116. package/vendor/rbxutil/comm/Client/ClientComm.luau +232 -232
  117. package/vendor/rbxutil/comm/Client/ClientRemoteProperty.luau +156 -156
  118. package/vendor/rbxutil/comm/Client/ClientRemoteSignal.luau +109 -109
  119. package/vendor/rbxutil/comm/Client/init.luau +135 -135
  120. package/vendor/rbxutil/comm/Server/RemoteProperty.luau +295 -295
  121. package/vendor/rbxutil/comm/Server/RemoteSignal.luau +211 -211
  122. package/vendor/rbxutil/comm/Server/ServerComm.luau +211 -211
  123. package/vendor/rbxutil/comm/Server/init.luau +140 -140
  124. package/vendor/rbxutil/comm/Types.luau +18 -18
  125. package/vendor/rbxutil/comm/Util.luau +27 -27
  126. package/vendor/rbxutil/comm/init.luau +35 -35
  127. package/vendor/rbxutil/comm/wally.toml +13 -13
  128. package/vendor/rbxutil/component/init.luau +759 -759
  129. package/vendor/rbxutil/component/init.test.luau +311 -311
  130. package/vendor/rbxutil/component/wally.toml +14 -14
  131. package/vendor/rbxutil/concur/init.luau +542 -542
  132. package/vendor/rbxutil/concur/init.test.luau +364 -364
  133. package/vendor/rbxutil/concur/wally.toml +8 -8
  134. package/vendor/rbxutil/enum-list/init.luau +101 -101
  135. package/vendor/rbxutil/enum-list/init.test.luau +91 -91
  136. package/vendor/rbxutil/enum-list/wally.toml +8 -8
  137. package/vendor/rbxutil/find/index.d.ts +20 -20
  138. package/vendor/rbxutil/find/init.luau +44 -44
  139. package/vendor/rbxutil/find/package.json +17 -17
  140. package/vendor/rbxutil/find/wally.toml +8 -8
  141. package/vendor/rbxutil/input/Gamepad.luau +559 -559
  142. package/vendor/rbxutil/input/Keyboard.luau +124 -124
  143. package/vendor/rbxutil/input/Mouse.luau +278 -278
  144. package/vendor/rbxutil/input/PreferredInput.luau +91 -91
  145. package/vendor/rbxutil/input/Touch.luau +120 -120
  146. package/vendor/rbxutil/input/init.luau +33 -33
  147. package/vendor/rbxutil/input/wally.toml +12 -12
  148. package/vendor/rbxutil/loader/index.d.ts +15 -15
  149. package/vendor/rbxutil/loader/init.luau +137 -137
  150. package/vendor/rbxutil/loader/wally.toml +8 -8
  151. package/vendor/rbxutil/log/index.d.ts +38 -38
  152. package/vendor/rbxutil/log/init.luau +746 -746
  153. package/vendor/rbxutil/log/wally.toml +8 -8
  154. package/vendor/rbxutil/net/init.luau +190 -190
  155. package/vendor/rbxutil/net/wally.toml +8 -8
  156. package/vendor/rbxutil/option/index.d.ts +44 -44
  157. package/vendor/rbxutil/option/init.luau +489 -489
  158. package/vendor/rbxutil/option/init.test.luau +342 -342
  159. package/vendor/rbxutil/option/wally.toml +8 -8
  160. package/vendor/rbxutil/pid/index.d.ts +53 -53
  161. package/vendor/rbxutil/pid/init.luau +195 -195
  162. package/vendor/rbxutil/pid/package.json +16 -16
  163. package/vendor/rbxutil/pid/wally.toml +9 -9
  164. package/vendor/rbxutil/quaternion/index.d.ts +117 -117
  165. package/vendor/rbxutil/quaternion/init.luau +570 -570
  166. package/vendor/rbxutil/quaternion/package.json +16 -16
  167. package/vendor/rbxutil/quaternion/wally.toml +9 -9
  168. package/vendor/rbxutil/query/index.d.ts +43 -43
  169. package/vendor/rbxutil/query/init.luau +117 -117
  170. package/vendor/rbxutil/query/package.json +18 -18
  171. package/vendor/rbxutil/query/wally.toml +9 -9
  172. package/vendor/rbxutil/sequent/index.d.ts +28 -28
  173. package/vendor/rbxutil/sequent/init.luau +340 -340
  174. package/vendor/rbxutil/sequent/package.json +16 -16
  175. package/vendor/rbxutil/sequent/wally.toml +9 -9
  176. package/vendor/rbxutil/ser/init.luau +175 -175
  177. package/vendor/rbxutil/ser/init.test.luau +50 -50
  178. package/vendor/rbxutil/ser/wally.toml +11 -11
  179. package/vendor/rbxutil/shake/index.d.ts +36 -36
  180. package/vendor/rbxutil/shake/init.luau +532 -532
  181. package/vendor/rbxutil/shake/init.test.luau +267 -267
  182. package/vendor/rbxutil/shake/package.json +16 -16
  183. package/vendor/rbxutil/shake/wally.toml +9 -9
  184. package/vendor/rbxutil/signal/index.d.ts +100 -100
  185. package/vendor/rbxutil/signal/init.luau +432 -432
  186. package/vendor/rbxutil/signal/init.test.luau +190 -190
  187. package/vendor/rbxutil/signal/package.json +17 -17
  188. package/vendor/rbxutil/signal/wally.toml +9 -9
  189. package/vendor/rbxutil/silo/TableWatcher.luau +65 -65
  190. package/vendor/rbxutil/silo/Util.luau +55 -55
  191. package/vendor/rbxutil/silo/init.luau +338 -338
  192. package/vendor/rbxutil/silo/init.test.luau +215 -215
  193. package/vendor/rbxutil/silo/wally.toml +8 -8
  194. package/vendor/rbxutil/spring/index.d.ts +40 -40
  195. package/vendor/rbxutil/spring/init.luau +97 -97
  196. package/vendor/rbxutil/spring/package.json +17 -17
  197. package/vendor/rbxutil/spring/wally.toml +8 -8
  198. package/vendor/rbxutil/stream/index.d.ts +88 -88
  199. package/vendor/rbxutil/stream/init.luau +597 -597
  200. package/vendor/rbxutil/stream/package.json +18 -18
  201. package/vendor/rbxutil/stream/wally.toml +9 -9
  202. package/vendor/rbxutil/streamable/Streamable.luau +202 -202
  203. package/vendor/rbxutil/streamable/StreamableUtil.luau +80 -80
  204. package/vendor/rbxutil/streamable/init.luau +8 -8
  205. package/vendor/rbxutil/streamable/wally.toml +12 -12
  206. package/vendor/rbxutil/symbol/init.luau +56 -56
  207. package/vendor/rbxutil/symbol/init.test.luau +37 -37
  208. package/vendor/rbxutil/symbol/wally.toml +8 -8
  209. package/vendor/rbxutil/table-util/init.luau +938 -938
  210. package/vendor/rbxutil/table-util/init.test.luau +439 -439
  211. package/vendor/rbxutil/task-queue/index.d.ts +27 -27
  212. package/vendor/rbxutil/task-queue/init.luau +97 -97
  213. package/vendor/rbxutil/task-queue/wally.toml +8 -8
  214. package/vendor/rbxutil/timer/index.d.ts +81 -81
  215. package/vendor/rbxutil/timer/init.luau +249 -249
  216. package/vendor/rbxutil/timer/init.test.luau +73 -73
  217. package/vendor/rbxutil/timer/wally.toml +11 -11
  218. package/vendor/rbxutil/tree/index.d.ts +15 -15
  219. package/vendor/rbxutil/tree/init.luau +137 -137
  220. package/vendor/rbxutil/tree/wally.toml +8 -8
  221. package/vendor/rbxutil/trove/index.d.ts +46 -46
  222. package/vendor/rbxutil/trove/init.luau +787 -787
  223. package/vendor/rbxutil/trove/init.test.luau +203 -203
  224. package/vendor/rbxutil/trove/wally.toml +8 -8
  225. package/vendor/rbxutil/typed-remote/init.luau +196 -196
  226. package/vendor/rbxutil/typed-remote/wally.toml +8 -8
  227. package/vendor/rbxutil/wait-for/index.d.ts +17 -17
  228. package/vendor/rbxutil/wait-for/init.luau +257 -257
  229. package/vendor/rbxutil/wait-for/init.test.luau +182 -182
  230. package/vendor/rbxutil/wait-for/wally.toml +11 -11
  231. package/vendor/t/t.lua +1350 -1350
  232. package/vendor/testez/Context.lua +26 -26
  233. package/vendor/testez/Expectation.lua +311 -311
  234. package/vendor/testez/ExpectationContext.lua +38 -38
  235. package/vendor/testez/LifecycleHooks.lua +89 -89
  236. package/vendor/testez/Reporters/TeamCityReporter.lua +101 -101
  237. package/vendor/testez/Reporters/TextReporter.lua +105 -105
  238. package/vendor/testez/Reporters/TextReporterQuiet.lua +96 -96
  239. package/vendor/testez/TestBootstrap.lua +146 -146
  240. package/vendor/testez/TestEnum.lua +27 -27
  241. package/vendor/testez/TestPlan.lua +304 -304
  242. package/vendor/testez/TestPlanner.lua +39 -39
  243. package/vendor/testez/TestResults.lua +111 -111
  244. package/vendor/testez/TestRunner.lua +188 -188
  245. package/vendor/testez/TestSession.lua +243 -243
  246. package/vendor/testez/init.lua +39 -39
@@ -1,304 +1,304 @@
1
- --[[
2
- Represents a tree of tests that have been loaded but not necessarily
3
- executed yet.
4
-
5
- TestPlan objects are produced by TestPlanner.
6
- ]]
7
-
8
- local TestEnum = require(script.Parent.TestEnum)
9
- local Expectation = require(script.Parent.Expectation)
10
-
11
- local function newEnvironment(currentNode, extraEnvironment)
12
- local env = {}
13
-
14
- if extraEnvironment then
15
- if type(extraEnvironment) ~= "table" then
16
- error(("Bad argument #2 to newEnvironment. Expected table, got %s"):format(
17
- typeof(extraEnvironment)), 2)
18
- end
19
-
20
- for key, value in pairs(extraEnvironment) do
21
- env[key] = value
22
- end
23
- end
24
-
25
- local function addChild(phrase, callback, nodeType, nodeModifier)
26
- local node = currentNode:addChild(phrase, nodeType, nodeModifier)
27
- node.callback = callback
28
- if nodeType == TestEnum.NodeType.Describe then
29
- node:expand()
30
- end
31
- return node
32
- end
33
-
34
- function env.describeFOCUS(phrase, callback)
35
- addChild(phrase, callback, TestEnum.NodeType.Describe, TestEnum.NodeModifier.Focus)
36
- end
37
-
38
- function env.describeSKIP(phrase, callback)
39
- addChild(phrase, callback, TestEnum.NodeType.Describe, TestEnum.NodeModifier.Skip)
40
- end
41
-
42
- function env.describe(phrase, callback, nodeModifier)
43
- addChild(phrase, callback, TestEnum.NodeType.Describe, TestEnum.NodeModifier.None)
44
- end
45
-
46
- function env.itFOCUS(phrase, callback)
47
- addChild(phrase, callback, TestEnum.NodeType.It, TestEnum.NodeModifier.Focus)
48
- end
49
-
50
- function env.itSKIP(phrase, callback)
51
- addChild(phrase, callback, TestEnum.NodeType.It, TestEnum.NodeModifier.Skip)
52
- end
53
-
54
- function env.itFIXME(phrase, callback)
55
- local node = addChild(phrase, callback, TestEnum.NodeType.It, TestEnum.NodeModifier.Skip)
56
- warn("FIXME: broken test", node:getFullName())
57
- end
58
-
59
- function env.it(phrase, callback, nodeModifier)
60
- addChild(phrase, callback, TestEnum.NodeType.It, TestEnum.NodeModifier.None)
61
- end
62
-
63
- -- Incrementing counter used to ensure that beforeAll, afterAll, beforeEach, afterEach have unique phrases
64
- local lifecyclePhaseId = 0
65
-
66
- local lifecycleHooks = {
67
- [TestEnum.NodeType.BeforeAll] = "beforeAll",
68
- [TestEnum.NodeType.AfterAll] = "afterAll",
69
- [TestEnum.NodeType.BeforeEach] = "beforeEach",
70
- [TestEnum.NodeType.AfterEach] = "afterEach"
71
- }
72
-
73
- for nodeType, name in pairs(lifecycleHooks) do
74
- env[name] = function(callback)
75
- addChild(name .. "_" .. tostring(lifecyclePhaseId), callback, nodeType, TestEnum.NodeModifier.None)
76
- lifecyclePhaseId = lifecyclePhaseId + 1
77
- end
78
- end
79
-
80
- function env.FIXME(optionalMessage)
81
- warn("FIXME: broken test", currentNode:getFullName(), optionalMessage or "")
82
-
83
- currentNode.modifier = TestEnum.NodeModifier.Skip
84
- end
85
-
86
- function env.FOCUS()
87
- currentNode.modifier = TestEnum.NodeModifier.Focus
88
- end
89
-
90
- function env.SKIP()
91
- currentNode.modifier = TestEnum.NodeModifier.Skip
92
- end
93
-
94
- --[[
95
- This function is deprecated. Calling it is a no-op beyond generating a
96
- warning.
97
- ]]
98
- function env.HACK_NO_XPCALL()
99
- warn("HACK_NO_XPCALL is deprecated. It is now safe to yield in an " ..
100
- "xpcall, so this is no longer necessary. It can be safely deleted.")
101
- end
102
-
103
- env.fit = env.itFOCUS
104
- env.xit = env.itSKIP
105
- env.fdescribe = env.describeFOCUS
106
- env.xdescribe = env.describeSKIP
107
-
108
- env.expect = setmetatable({
109
- extend = function(...)
110
- error("Cannot call \"expect.extend\" from within a \"describe\" node.")
111
- end,
112
- }, {
113
- __call = function(_self, ...)
114
- return Expectation.new(...)
115
- end,
116
- })
117
-
118
- return env
119
- end
120
-
121
- local TestNode = {}
122
- TestNode.__index = TestNode
123
-
124
- --[[
125
- Create a new test node. A pointer to the test plan, a phrase to describe it
126
- and the type of node it is are required. The modifier is optional and will
127
- be None if left blank.
128
- ]]
129
- function TestNode.new(plan, phrase, nodeType, nodeModifier)
130
- nodeModifier = nodeModifier or TestEnum.NodeModifier.None
131
-
132
- local node = {
133
- plan = plan,
134
- phrase = phrase,
135
- type = nodeType,
136
- modifier = nodeModifier,
137
- children = {},
138
- callback = nil,
139
- parent = nil,
140
- }
141
-
142
- node.environment = newEnvironment(node, plan.extraEnvironment)
143
- return setmetatable(node, TestNode)
144
- end
145
-
146
- local function getModifier(name, pattern, modifier)
147
- if pattern and (modifier == nil or modifier == TestEnum.NodeModifier.None) then
148
- if name:match(pattern) then
149
- return TestEnum.NodeModifier.Focus
150
- else
151
- return TestEnum.NodeModifier.Skip
152
- end
153
- end
154
- return modifier
155
- end
156
-
157
- function TestNode:addChild(phrase, nodeType, nodeModifier)
158
- if nodeType == TestEnum.NodeType.It then
159
- for _, child in pairs(self.children) do
160
- if child.phrase == phrase then
161
- error("Duplicate it block found: " .. child:getFullName())
162
- end
163
- end
164
- end
165
-
166
- local childName = self:getFullName() .. " " .. phrase
167
- nodeModifier = getModifier(childName, self.plan.testNamePattern, nodeModifier)
168
- local child = TestNode.new(self.plan, phrase, nodeType, nodeModifier)
169
- child.parent = self
170
- table.insert(self.children, child)
171
- return child
172
- end
173
-
174
- --[[
175
- Join the names of all the nodes back to the parent.
176
- ]]
177
- function TestNode:getFullName()
178
- if self.parent then
179
- local parentPhrase = self.parent:getFullName()
180
- if parentPhrase then
181
- return parentPhrase .. " " .. self.phrase
182
- end
183
- end
184
- return self.phrase
185
- end
186
-
187
- --[[
188
- Expand a node by setting its callback environment and then calling it. Any
189
- further it and describe calls within the callback will be added to the tree.
190
- ]]
191
- function TestNode:expand()
192
- local originalEnv = getfenv(self.callback)
193
- local callbackEnv = setmetatable({}, { __index = originalEnv })
194
- for key, value in pairs(self.environment) do
195
- callbackEnv[key] = value
196
- end
197
- -- Copy 'script' directly to new env to make Studio debugger happy.
198
- -- Studio debugger does not look into __index, because of security reasons
199
- callbackEnv.script = originalEnv.script
200
- setfenv(self.callback, callbackEnv)
201
-
202
- local success, result = xpcall(self.callback, function(message)
203
- return debug.traceback(tostring(message), 2)
204
- end)
205
-
206
- if not success then
207
- self.loadError = result
208
- end
209
- end
210
-
211
- local TestPlan = {}
212
- TestPlan.__index = TestPlan
213
-
214
- --[[
215
- Create a new, empty TestPlan.
216
- ]]
217
- function TestPlan.new(testNamePattern, extraEnvironment)
218
- local plan = {
219
- children = {},
220
- testNamePattern = testNamePattern,
221
- extraEnvironment = extraEnvironment,
222
- }
223
-
224
- return setmetatable(plan, TestPlan)
225
- end
226
-
227
- --[[
228
- Add a new child under the test plan's root node.
229
- ]]
230
- function TestPlan:addChild(phrase, nodeType, nodeModifier)
231
- nodeModifier = getModifier(phrase, self.testNamePattern, nodeModifier)
232
- local child = TestNode.new(self, phrase, nodeType, nodeModifier)
233
- table.insert(self.children, child)
234
- return child
235
- end
236
-
237
- --[[
238
- Add a new describe node with the given method as a callback. Generates or
239
- reuses all the describe nodes along the path.
240
- ]]
241
- function TestPlan:addRoot(path, method)
242
- local curNode = self
243
- for i = #path, 1, -1 do
244
- local nextNode = nil
245
-
246
- for _, child in ipairs(curNode.children) do
247
- if child.phrase == path[i] then
248
- nextNode = child
249
- break
250
- end
251
- end
252
-
253
- if nextNode == nil then
254
- nextNode = curNode:addChild(path[i], TestEnum.NodeType.Describe)
255
- end
256
-
257
- curNode = nextNode
258
- end
259
-
260
- curNode.callback = method
261
- curNode:expand()
262
- end
263
-
264
- --[[
265
- Calls the given callback on all nodes in the tree, traversed depth-first.
266
- ]]
267
- function TestPlan:visitAllNodes(callback, root, level)
268
- root = root or self
269
- level = level or 0
270
-
271
- for _, child in ipairs(root.children) do
272
- callback(child, level)
273
-
274
- self:visitAllNodes(callback, child, level + 1)
275
- end
276
- end
277
-
278
- --[[
279
- Visualizes the test plan in a simple format, suitable for debugging the test
280
- plan's structure.
281
- ]]
282
- function TestPlan:visualize()
283
- local buffer = {}
284
- self:visitAllNodes(function(node, level)
285
- table.insert(buffer, (" "):rep(3 * level) .. node.phrase)
286
- end)
287
- return table.concat(buffer, "\n")
288
- end
289
-
290
- --[[
291
- Gets a list of all nodes in the tree for which the given callback returns
292
- true.
293
- ]]
294
- function TestPlan:findNodes(callback)
295
- local results = {}
296
- self:visitAllNodes(function(node)
297
- if callback(node) then
298
- table.insert(results, node)
299
- end
300
- end)
301
- return results
302
- end
303
-
304
- return TestPlan
1
+ --[[
2
+ Represents a tree of tests that have been loaded but not necessarily
3
+ executed yet.
4
+
5
+ TestPlan objects are produced by TestPlanner.
6
+ ]]
7
+
8
+ local TestEnum = require(script.Parent.TestEnum)
9
+ local Expectation = require(script.Parent.Expectation)
10
+
11
+ local function newEnvironment(currentNode, extraEnvironment)
12
+ local env = {}
13
+
14
+ if extraEnvironment then
15
+ if type(extraEnvironment) ~= "table" then
16
+ error(("Bad argument #2 to newEnvironment. Expected table, got %s"):format(
17
+ typeof(extraEnvironment)), 2)
18
+ end
19
+
20
+ for key, value in pairs(extraEnvironment) do
21
+ env[key] = value
22
+ end
23
+ end
24
+
25
+ local function addChild(phrase, callback, nodeType, nodeModifier)
26
+ local node = currentNode:addChild(phrase, nodeType, nodeModifier)
27
+ node.callback = callback
28
+ if nodeType == TestEnum.NodeType.Describe then
29
+ node:expand()
30
+ end
31
+ return node
32
+ end
33
+
34
+ function env.describeFOCUS(phrase, callback)
35
+ addChild(phrase, callback, TestEnum.NodeType.Describe, TestEnum.NodeModifier.Focus)
36
+ end
37
+
38
+ function env.describeSKIP(phrase, callback)
39
+ addChild(phrase, callback, TestEnum.NodeType.Describe, TestEnum.NodeModifier.Skip)
40
+ end
41
+
42
+ function env.describe(phrase, callback, nodeModifier)
43
+ addChild(phrase, callback, TestEnum.NodeType.Describe, TestEnum.NodeModifier.None)
44
+ end
45
+
46
+ function env.itFOCUS(phrase, callback)
47
+ addChild(phrase, callback, TestEnum.NodeType.It, TestEnum.NodeModifier.Focus)
48
+ end
49
+
50
+ function env.itSKIP(phrase, callback)
51
+ addChild(phrase, callback, TestEnum.NodeType.It, TestEnum.NodeModifier.Skip)
52
+ end
53
+
54
+ function env.itFIXME(phrase, callback)
55
+ local node = addChild(phrase, callback, TestEnum.NodeType.It, TestEnum.NodeModifier.Skip)
56
+ warn("FIXME: broken test", node:getFullName())
57
+ end
58
+
59
+ function env.it(phrase, callback, nodeModifier)
60
+ addChild(phrase, callback, TestEnum.NodeType.It, TestEnum.NodeModifier.None)
61
+ end
62
+
63
+ -- Incrementing counter used to ensure that beforeAll, afterAll, beforeEach, afterEach have unique phrases
64
+ local lifecyclePhaseId = 0
65
+
66
+ local lifecycleHooks = {
67
+ [TestEnum.NodeType.BeforeAll] = "beforeAll",
68
+ [TestEnum.NodeType.AfterAll] = "afterAll",
69
+ [TestEnum.NodeType.BeforeEach] = "beforeEach",
70
+ [TestEnum.NodeType.AfterEach] = "afterEach"
71
+ }
72
+
73
+ for nodeType, name in pairs(lifecycleHooks) do
74
+ env[name] = function(callback)
75
+ addChild(name .. "_" .. tostring(lifecyclePhaseId), callback, nodeType, TestEnum.NodeModifier.None)
76
+ lifecyclePhaseId = lifecyclePhaseId + 1
77
+ end
78
+ end
79
+
80
+ function env.FIXME(optionalMessage)
81
+ warn("FIXME: broken test", currentNode:getFullName(), optionalMessage or "")
82
+
83
+ currentNode.modifier = TestEnum.NodeModifier.Skip
84
+ end
85
+
86
+ function env.FOCUS()
87
+ currentNode.modifier = TestEnum.NodeModifier.Focus
88
+ end
89
+
90
+ function env.SKIP()
91
+ currentNode.modifier = TestEnum.NodeModifier.Skip
92
+ end
93
+
94
+ --[[
95
+ This function is deprecated. Calling it is a no-op beyond generating a
96
+ warning.
97
+ ]]
98
+ function env.HACK_NO_XPCALL()
99
+ warn("HACK_NO_XPCALL is deprecated. It is now safe to yield in an " ..
100
+ "xpcall, so this is no longer necessary. It can be safely deleted.")
101
+ end
102
+
103
+ env.fit = env.itFOCUS
104
+ env.xit = env.itSKIP
105
+ env.fdescribe = env.describeFOCUS
106
+ env.xdescribe = env.describeSKIP
107
+
108
+ env.expect = setmetatable({
109
+ extend = function(...)
110
+ error("Cannot call \"expect.extend\" from within a \"describe\" node.")
111
+ end,
112
+ }, {
113
+ __call = function(_self, ...)
114
+ return Expectation.new(...)
115
+ end,
116
+ })
117
+
118
+ return env
119
+ end
120
+
121
+ local TestNode = {}
122
+ TestNode.__index = TestNode
123
+
124
+ --[[
125
+ Create a new test node. A pointer to the test plan, a phrase to describe it
126
+ and the type of node it is are required. The modifier is optional and will
127
+ be None if left blank.
128
+ ]]
129
+ function TestNode.new(plan, phrase, nodeType, nodeModifier)
130
+ nodeModifier = nodeModifier or TestEnum.NodeModifier.None
131
+
132
+ local node = {
133
+ plan = plan,
134
+ phrase = phrase,
135
+ type = nodeType,
136
+ modifier = nodeModifier,
137
+ children = {},
138
+ callback = nil,
139
+ parent = nil,
140
+ }
141
+
142
+ node.environment = newEnvironment(node, plan.extraEnvironment)
143
+ return setmetatable(node, TestNode)
144
+ end
145
+
146
+ local function getModifier(name, pattern, modifier)
147
+ if pattern and (modifier == nil or modifier == TestEnum.NodeModifier.None) then
148
+ if name:match(pattern) then
149
+ return TestEnum.NodeModifier.Focus
150
+ else
151
+ return TestEnum.NodeModifier.Skip
152
+ end
153
+ end
154
+ return modifier
155
+ end
156
+
157
+ function TestNode:addChild(phrase, nodeType, nodeModifier)
158
+ if nodeType == TestEnum.NodeType.It then
159
+ for _, child in pairs(self.children) do
160
+ if child.phrase == phrase then
161
+ error("Duplicate it block found: " .. child:getFullName())
162
+ end
163
+ end
164
+ end
165
+
166
+ local childName = self:getFullName() .. " " .. phrase
167
+ nodeModifier = getModifier(childName, self.plan.testNamePattern, nodeModifier)
168
+ local child = TestNode.new(self.plan, phrase, nodeType, nodeModifier)
169
+ child.parent = self
170
+ table.insert(self.children, child)
171
+ return child
172
+ end
173
+
174
+ --[[
175
+ Join the names of all the nodes back to the parent.
176
+ ]]
177
+ function TestNode:getFullName()
178
+ if self.parent then
179
+ local parentPhrase = self.parent:getFullName()
180
+ if parentPhrase then
181
+ return parentPhrase .. " " .. self.phrase
182
+ end
183
+ end
184
+ return self.phrase
185
+ end
186
+
187
+ --[[
188
+ Expand a node by setting its callback environment and then calling it. Any
189
+ further it and describe calls within the callback will be added to the tree.
190
+ ]]
191
+ function TestNode:expand()
192
+ local originalEnv = getfenv(self.callback)
193
+ local callbackEnv = setmetatable({}, { __index = originalEnv })
194
+ for key, value in pairs(self.environment) do
195
+ callbackEnv[key] = value
196
+ end
197
+ -- Copy 'script' directly to new env to make Studio debugger happy.
198
+ -- Studio debugger does not look into __index, because of security reasons
199
+ callbackEnv.script = originalEnv.script
200
+ setfenv(self.callback, callbackEnv)
201
+
202
+ local success, result = xpcall(self.callback, function(message)
203
+ return debug.traceback(tostring(message), 2)
204
+ end)
205
+
206
+ if not success then
207
+ self.loadError = result
208
+ end
209
+ end
210
+
211
+ local TestPlan = {}
212
+ TestPlan.__index = TestPlan
213
+
214
+ --[[
215
+ Create a new, empty TestPlan.
216
+ ]]
217
+ function TestPlan.new(testNamePattern, extraEnvironment)
218
+ local plan = {
219
+ children = {},
220
+ testNamePattern = testNamePattern,
221
+ extraEnvironment = extraEnvironment,
222
+ }
223
+
224
+ return setmetatable(plan, TestPlan)
225
+ end
226
+
227
+ --[[
228
+ Add a new child under the test plan's root node.
229
+ ]]
230
+ function TestPlan:addChild(phrase, nodeType, nodeModifier)
231
+ nodeModifier = getModifier(phrase, self.testNamePattern, nodeModifier)
232
+ local child = TestNode.new(self, phrase, nodeType, nodeModifier)
233
+ table.insert(self.children, child)
234
+ return child
235
+ end
236
+
237
+ --[[
238
+ Add a new describe node with the given method as a callback. Generates or
239
+ reuses all the describe nodes along the path.
240
+ ]]
241
+ function TestPlan:addRoot(path, method)
242
+ local curNode = self
243
+ for i = #path, 1, -1 do
244
+ local nextNode = nil
245
+
246
+ for _, child in ipairs(curNode.children) do
247
+ if child.phrase == path[i] then
248
+ nextNode = child
249
+ break
250
+ end
251
+ end
252
+
253
+ if nextNode == nil then
254
+ nextNode = curNode:addChild(path[i], TestEnum.NodeType.Describe)
255
+ end
256
+
257
+ curNode = nextNode
258
+ end
259
+
260
+ curNode.callback = method
261
+ curNode:expand()
262
+ end
263
+
264
+ --[[
265
+ Calls the given callback on all nodes in the tree, traversed depth-first.
266
+ ]]
267
+ function TestPlan:visitAllNodes(callback, root, level)
268
+ root = root or self
269
+ level = level or 0
270
+
271
+ for _, child in ipairs(root.children) do
272
+ callback(child, level)
273
+
274
+ self:visitAllNodes(callback, child, level + 1)
275
+ end
276
+ end
277
+
278
+ --[[
279
+ Visualizes the test plan in a simple format, suitable for debugging the test
280
+ plan's structure.
281
+ ]]
282
+ function TestPlan:visualize()
283
+ local buffer = {}
284
+ self:visitAllNodes(function(node, level)
285
+ table.insert(buffer, (" "):rep(3 * level) .. node.phrase)
286
+ end)
287
+ return table.concat(buffer, "\n")
288
+ end
289
+
290
+ --[[
291
+ Gets a list of all nodes in the tree for which the given callback returns
292
+ true.
293
+ ]]
294
+ function TestPlan:findNodes(callback)
295
+ local results = {}
296
+ self:visitAllNodes(function(node)
297
+ if callback(node) then
298
+ table.insert(results, node)
299
+ end
300
+ end)
301
+ return results
302
+ end
303
+
304
+ return TestPlan
@@ -1,40 +1,40 @@
1
- --[[
2
- Turns a series of specification functions into a test plan.
3
-
4
- Uses a TestPlanBuilder to keep track of the state of the tree being built.
5
- ]]
6
- local TestPlan = require(script.Parent.TestPlan)
7
-
8
- local TestPlanner = {}
9
-
10
- --[[
11
- Create a new TestPlan from a list of specification functions.
12
-
13
- These functions should call a combination of `describe` and `it` (and their
14
- variants), which will be turned into a test plan to be executed.
15
-
16
- Parameters:
17
- - modulesList - list of tables describing test modules {
18
- method, -- specification function described above
19
- path, -- array of parent entires, first element is the leaf that owns `method`
20
- pathStringForSorting -- a string representation of `path`, used for sorting of the test plan
21
- }
22
- - testNamePattern - Only tests matching this Lua pattern string will run. Pass empty or nil to run all tests
23
- - extraEnvironment - Lua table holding additional functions and variables to be injected into the specification
24
- function during execution
25
- ]]
26
- function TestPlanner.createPlan(modulesList, testNamePattern, extraEnvironment)
27
- local plan = TestPlan.new(testNamePattern, extraEnvironment)
28
-
29
- table.sort(modulesList, function(a, b)
30
- return a.pathStringForSorting < b.pathStringForSorting
31
- end)
32
-
33
- for _, module in ipairs(modulesList) do
34
- plan:addRoot(module.path, module.method)
35
- end
36
-
37
- return plan
38
- end
39
-
1
+ --[[
2
+ Turns a series of specification functions into a test plan.
3
+
4
+ Uses a TestPlanBuilder to keep track of the state of the tree being built.
5
+ ]]
6
+ local TestPlan = require(script.Parent.TestPlan)
7
+
8
+ local TestPlanner = {}
9
+
10
+ --[[
11
+ Create a new TestPlan from a list of specification functions.
12
+
13
+ These functions should call a combination of `describe` and `it` (and their
14
+ variants), which will be turned into a test plan to be executed.
15
+
16
+ Parameters:
17
+ - modulesList - list of tables describing test modules {
18
+ method, -- specification function described above
19
+ path, -- array of parent entires, first element is the leaf that owns `method`
20
+ pathStringForSorting -- a string representation of `path`, used for sorting of the test plan
21
+ }
22
+ - testNamePattern - Only tests matching this Lua pattern string will run. Pass empty or nil to run all tests
23
+ - extraEnvironment - Lua table holding additional functions and variables to be injected into the specification
24
+ function during execution
25
+ ]]
26
+ function TestPlanner.createPlan(modulesList, testNamePattern, extraEnvironment)
27
+ local plan = TestPlan.new(testNamePattern, extraEnvironment)
28
+
29
+ table.sort(modulesList, function(a, b)
30
+ return a.pathStringForSorting < b.pathStringForSorting
31
+ end)
32
+
33
+ for _, module in ipairs(modulesList) do
34
+ plan:addRoot(module.path, module.method)
35
+ end
36
+
37
+ return plan
38
+ end
39
+
40
40
  return TestPlanner