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.
- package/README.md +112 -122
- package/commands/setup-game.md +108 -108
- package/commands/sync-check.md +53 -53
- package/core/roblox-core.md +93 -93
- package/dist/server.js +189 -167
- package/package.json +35 -35
- package/skills/roblox-analytics/SKILL.md +277 -277
- package/skills/roblox-analytics/references/event-batcher.luau +75 -75
- package/skills/roblox-animation-vfx/SKILL.md +1325 -1325
- package/skills/roblox-architecture/SKILL.md +863 -863
- package/skills/roblox-architecture/references/combat-systems.md +1381 -1381
- package/skills/roblox-code-review/SKILL.md +686 -686
- package/skills/roblox-data/SKILL.md +889 -889
- package/skills/roblox-data/references/inventory-systems.md +1729 -1729
- package/skills/roblox-debug/SKILL.md +98 -98
- package/skills/roblox-gui/SKILL.md +1103 -1103
- package/skills/roblox-gui-fusion/SKILL.md +150 -150
- package/skills/roblox-gui-fusion/references/inventory.luau +427 -427
- package/skills/roblox-gui-fusion/references/settings-menu.luau +579 -579
- package/skills/roblox-gui-fusion/references/shop.luau +411 -411
- package/skills/roblox-luau-mastery/SKILL.md +1519 -1519
- package/skills/roblox-monetization/SKILL.md +1084 -1084
- package/skills/roblox-monetization/references/process-receipt.luau +131 -131
- package/skills/roblox-networking/SKILL.md +669 -669
- package/skills/roblox-networking/references/remote-validator.luau +193 -193
- package/skills/roblox-publish-checklist/SKILL.md +127 -127
- package/skills/roblox-runtime/SKILL.md +753 -753
- package/skills/roblox-sharp-edges/SKILL.md +294 -294
- package/skills/roblox-sync/SKILL.md +126 -126
- package/skills/roblox-testing/SKILL.md +943 -943
- package/skills/roblox-tooling/SKILL.md +149 -149
- package/vendor/LICENSES/ProfileStore-LICENSE +201 -201
- package/vendor/LICENSES/RbxUtil-LICENSE +7 -7
- package/vendor/LICENSES/promise-LICENSE +20 -20
- package/vendor/LICENSES/t-LICENSE +21 -21
- package/vendor/LICENSES/testez-LICENSE +200 -200
- package/vendor/README.md +83 -83
- package/vendor/fusion/Animation/ExternalTime.luau +83 -83
- package/vendor/fusion/Animation/Spring.luau +321 -321
- package/vendor/fusion/Animation/Stopwatch.luau +127 -127
- package/vendor/fusion/Animation/Tween.luau +187 -187
- package/vendor/fusion/Animation/getTweenDuration.luau +27 -27
- package/vendor/fusion/Animation/getTweenRatio.luau +47 -47
- package/vendor/fusion/Animation/lerpType.luau +163 -163
- package/vendor/fusion/Animation/packType.luau +99 -99
- package/vendor/fusion/Animation/springCoefficients.luau +80 -80
- package/vendor/fusion/Animation/unpackType.luau +102 -102
- package/vendor/fusion/Colour/Oklab.luau +70 -70
- package/vendor/fusion/Colour/sRGB.luau +54 -54
- package/vendor/fusion/External.luau +167 -167
- package/vendor/fusion/ExternalDebug.luau +69 -69
- package/vendor/fusion/Graph/Observer.luau +113 -113
- package/vendor/fusion/Graph/castToGraph.luau +28 -28
- package/vendor/fusion/Graph/change.luau +80 -80
- package/vendor/fusion/Graph/depend.luau +32 -32
- package/vendor/fusion/Graph/evaluate.luau +55 -55
- package/vendor/fusion/Instances/Attribute.luau +57 -57
- package/vendor/fusion/Instances/AttributeChange.luau +46 -46
- package/vendor/fusion/Instances/AttributeOut.luau +63 -63
- package/vendor/fusion/Instances/Child.luau +21 -21
- package/vendor/fusion/Instances/Children.luau +147 -147
- package/vendor/fusion/Instances/Hydrate.luau +32 -32
- package/vendor/fusion/Instances/New.luau +52 -52
- package/vendor/fusion/Instances/OnChange.luau +49 -49
- package/vendor/fusion/Instances/OnEvent.luau +53 -53
- package/vendor/fusion/Instances/Out.luau +69 -69
- package/vendor/fusion/Instances/applyInstanceProps.luau +148 -148
- package/vendor/fusion/Instances/defaultProps.luau +194 -194
- package/vendor/fusion/LICENSE +21 -21
- package/vendor/fusion/Logging/formatError.luau +48 -48
- package/vendor/fusion/Logging/messages.luau +51 -51
- package/vendor/fusion/Logging/parseError.luau +24 -24
- package/vendor/fusion/Memory/checkLifetime.luau +133 -133
- package/vendor/fusion/Memory/deriveScope.luau +23 -23
- package/vendor/fusion/Memory/deriveScopeImpl.luau +44 -44
- package/vendor/fusion/Memory/doCleanup.luau +78 -78
- package/vendor/fusion/Memory/innerScope.luau +33 -33
- package/vendor/fusion/Memory/legacyCleanup.luau +17 -17
- package/vendor/fusion/Memory/needsDestruction.luau +16 -16
- package/vendor/fusion/Memory/poisonScope.luau +33 -33
- package/vendor/fusion/Memory/scopePool.luau +54 -54
- package/vendor/fusion/Memory/scoped.luau +26 -26
- package/vendor/fusion/Memory/whichLivesLonger.luau +74 -74
- package/vendor/fusion/RobloxExternal.luau +97 -97
- package/vendor/fusion/State/Computed.luau +138 -138
- package/vendor/fusion/State/For/Disassembly.luau +210 -210
- package/vendor/fusion/State/For/ForTypes.luau +30 -30
- package/vendor/fusion/State/For/init.luau +109 -109
- package/vendor/fusion/State/ForKeys.luau +93 -93
- package/vendor/fusion/State/ForPairs.luau +96 -96
- package/vendor/fusion/State/ForValues.luau +93 -93
- package/vendor/fusion/State/Value.luau +87 -87
- package/vendor/fusion/State/castToState.luau +25 -25
- package/vendor/fusion/State/peek.luau +30 -30
- package/vendor/fusion/Types.luau +314 -314
- package/vendor/fusion/Utility/Contextual.luau +90 -90
- package/vendor/fusion/Utility/Safe.luau +22 -22
- package/vendor/fusion/Utility/isSimilar.luau +29 -29
- package/vendor/fusion/Utility/merge.luau +35 -35
- package/vendor/fusion/Utility/nameOf.luau +34 -34
- package/vendor/fusion/Utility/never.luau +13 -13
- package/vendor/fusion/Utility/nicknames.luau +10 -10
- package/vendor/fusion/Utility/xtypeof.luau +26 -26
- package/vendor/fusion/init.luau +82 -82
- package/vendor/profilestore/init.luau +2242 -2242
- package/vendor/promise/init.luau +1982 -1982
- package/vendor/rbxutil/buffer-util/Buffer.test.luau +25 -25
- package/vendor/rbxutil/buffer-util/BufferReader.luau +228 -228
- package/vendor/rbxutil/buffer-util/BufferWriter.luau +269 -269
- package/vendor/rbxutil/buffer-util/DataTypeBuffer.luau +223 -223
- package/vendor/rbxutil/buffer-util/Types.luau +60 -60
- package/vendor/rbxutil/buffer-util/index.d.ts +153 -153
- package/vendor/rbxutil/buffer-util/init.luau +41 -41
- package/vendor/rbxutil/buffer-util/package.json +16 -16
- package/vendor/rbxutil/buffer-util/wally.toml +9 -9
- package/vendor/rbxutil/comm/Client/ClientComm.luau +232 -232
- package/vendor/rbxutil/comm/Client/ClientRemoteProperty.luau +156 -156
- package/vendor/rbxutil/comm/Client/ClientRemoteSignal.luau +109 -109
- package/vendor/rbxutil/comm/Client/init.luau +135 -135
- package/vendor/rbxutil/comm/Server/RemoteProperty.luau +295 -295
- package/vendor/rbxutil/comm/Server/RemoteSignal.luau +211 -211
- package/vendor/rbxutil/comm/Server/ServerComm.luau +211 -211
- package/vendor/rbxutil/comm/Server/init.luau +140 -140
- package/vendor/rbxutil/comm/Types.luau +18 -18
- package/vendor/rbxutil/comm/Util.luau +27 -27
- package/vendor/rbxutil/comm/init.luau +35 -35
- package/vendor/rbxutil/comm/wally.toml +13 -13
- package/vendor/rbxutil/component/init.luau +759 -759
- package/vendor/rbxutil/component/init.test.luau +311 -311
- package/vendor/rbxutil/component/wally.toml +14 -14
- package/vendor/rbxutil/concur/init.luau +542 -542
- package/vendor/rbxutil/concur/init.test.luau +364 -364
- package/vendor/rbxutil/concur/wally.toml +8 -8
- package/vendor/rbxutil/enum-list/init.luau +101 -101
- package/vendor/rbxutil/enum-list/init.test.luau +91 -91
- package/vendor/rbxutil/enum-list/wally.toml +8 -8
- package/vendor/rbxutil/find/index.d.ts +20 -20
- package/vendor/rbxutil/find/init.luau +44 -44
- package/vendor/rbxutil/find/package.json +17 -17
- package/vendor/rbxutil/find/wally.toml +8 -8
- package/vendor/rbxutil/input/Gamepad.luau +559 -559
- package/vendor/rbxutil/input/Keyboard.luau +124 -124
- package/vendor/rbxutil/input/Mouse.luau +278 -278
- package/vendor/rbxutil/input/PreferredInput.luau +91 -91
- package/vendor/rbxutil/input/Touch.luau +120 -120
- package/vendor/rbxutil/input/init.luau +33 -33
- package/vendor/rbxutil/input/wally.toml +12 -12
- package/vendor/rbxutil/loader/index.d.ts +15 -15
- package/vendor/rbxutil/loader/init.luau +137 -137
- package/vendor/rbxutil/loader/wally.toml +8 -8
- package/vendor/rbxutil/log/index.d.ts +38 -38
- package/vendor/rbxutil/log/init.luau +746 -746
- package/vendor/rbxutil/log/wally.toml +8 -8
- package/vendor/rbxutil/net/init.luau +190 -190
- package/vendor/rbxutil/net/wally.toml +8 -8
- package/vendor/rbxutil/option/index.d.ts +44 -44
- package/vendor/rbxutil/option/init.luau +489 -489
- package/vendor/rbxutil/option/init.test.luau +342 -342
- package/vendor/rbxutil/option/wally.toml +8 -8
- package/vendor/rbxutil/pid/index.d.ts +53 -53
- package/vendor/rbxutil/pid/init.luau +195 -195
- package/vendor/rbxutil/pid/package.json +16 -16
- package/vendor/rbxutil/pid/wally.toml +9 -9
- package/vendor/rbxutil/quaternion/index.d.ts +117 -117
- package/vendor/rbxutil/quaternion/init.luau +570 -570
- package/vendor/rbxutil/quaternion/package.json +16 -16
- package/vendor/rbxutil/quaternion/wally.toml +9 -9
- package/vendor/rbxutil/query/index.d.ts +43 -43
- package/vendor/rbxutil/query/init.luau +117 -117
- package/vendor/rbxutil/query/package.json +18 -18
- package/vendor/rbxutil/query/wally.toml +9 -9
- package/vendor/rbxutil/sequent/index.d.ts +28 -28
- package/vendor/rbxutil/sequent/init.luau +340 -340
- package/vendor/rbxutil/sequent/package.json +16 -16
- package/vendor/rbxutil/sequent/wally.toml +9 -9
- package/vendor/rbxutil/ser/init.luau +175 -175
- package/vendor/rbxutil/ser/init.test.luau +50 -50
- package/vendor/rbxutil/ser/wally.toml +11 -11
- package/vendor/rbxutil/shake/index.d.ts +36 -36
- package/vendor/rbxutil/shake/init.luau +532 -532
- package/vendor/rbxutil/shake/init.test.luau +267 -267
- package/vendor/rbxutil/shake/package.json +16 -16
- package/vendor/rbxutil/shake/wally.toml +9 -9
- package/vendor/rbxutil/signal/index.d.ts +100 -100
- package/vendor/rbxutil/signal/init.luau +432 -432
- package/vendor/rbxutil/signal/init.test.luau +190 -190
- package/vendor/rbxutil/signal/package.json +17 -17
- package/vendor/rbxutil/signal/wally.toml +9 -9
- package/vendor/rbxutil/silo/TableWatcher.luau +65 -65
- package/vendor/rbxutil/silo/Util.luau +55 -55
- package/vendor/rbxutil/silo/init.luau +338 -338
- package/vendor/rbxutil/silo/init.test.luau +215 -215
- package/vendor/rbxutil/silo/wally.toml +8 -8
- package/vendor/rbxutil/spring/index.d.ts +40 -40
- package/vendor/rbxutil/spring/init.luau +97 -97
- package/vendor/rbxutil/spring/package.json +17 -17
- package/vendor/rbxutil/spring/wally.toml +8 -8
- package/vendor/rbxutil/stream/index.d.ts +88 -88
- package/vendor/rbxutil/stream/init.luau +597 -597
- package/vendor/rbxutil/stream/package.json +18 -18
- package/vendor/rbxutil/stream/wally.toml +9 -9
- package/vendor/rbxutil/streamable/Streamable.luau +202 -202
- package/vendor/rbxutil/streamable/StreamableUtil.luau +80 -80
- package/vendor/rbxutil/streamable/init.luau +8 -8
- package/vendor/rbxutil/streamable/wally.toml +12 -12
- package/vendor/rbxutil/symbol/init.luau +56 -56
- package/vendor/rbxutil/symbol/init.test.luau +37 -37
- package/vendor/rbxutil/symbol/wally.toml +8 -8
- package/vendor/rbxutil/table-util/init.luau +938 -938
- package/vendor/rbxutil/table-util/init.test.luau +439 -439
- package/vendor/rbxutil/task-queue/index.d.ts +27 -27
- package/vendor/rbxutil/task-queue/init.luau +97 -97
- package/vendor/rbxutil/task-queue/wally.toml +8 -8
- package/vendor/rbxutil/timer/index.d.ts +81 -81
- package/vendor/rbxutil/timer/init.luau +249 -249
- package/vendor/rbxutil/timer/init.test.luau +73 -73
- package/vendor/rbxutil/timer/wally.toml +11 -11
- package/vendor/rbxutil/tree/index.d.ts +15 -15
- package/vendor/rbxutil/tree/init.luau +137 -137
- package/vendor/rbxutil/tree/wally.toml +8 -8
- package/vendor/rbxutil/trove/index.d.ts +46 -46
- package/vendor/rbxutil/trove/init.luau +787 -787
- package/vendor/rbxutil/trove/init.test.luau +203 -203
- package/vendor/rbxutil/trove/wally.toml +8 -8
- package/vendor/rbxutil/typed-remote/init.luau +196 -196
- package/vendor/rbxutil/typed-remote/wally.toml +8 -8
- package/vendor/rbxutil/wait-for/index.d.ts +17 -17
- package/vendor/rbxutil/wait-for/init.luau +257 -257
- package/vendor/rbxutil/wait-for/init.test.luau +182 -182
- package/vendor/rbxutil/wait-for/wally.toml +11 -11
- package/vendor/t/t.lua +1350 -1350
- package/vendor/testez/Context.lua +26 -26
- package/vendor/testez/Expectation.lua +311 -311
- package/vendor/testez/ExpectationContext.lua +38 -38
- package/vendor/testez/LifecycleHooks.lua +89 -89
- package/vendor/testez/Reporters/TeamCityReporter.lua +101 -101
- package/vendor/testez/Reporters/TextReporter.lua +105 -105
- package/vendor/testez/Reporters/TextReporterQuiet.lua +96 -96
- package/vendor/testez/TestBootstrap.lua +146 -146
- package/vendor/testez/TestEnum.lua +27 -27
- package/vendor/testez/TestPlan.lua +304 -304
- package/vendor/testez/TestPlanner.lua +39 -39
- package/vendor/testez/TestResults.lua +111 -111
- package/vendor/testez/TestRunner.lua +188 -188
- package/vendor/testez/TestSession.lua +243 -243
- 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
|