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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions tools/nevermore-cli/build-scripts/combine-test-places.luau
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
-- 1. Deserializes the .rbxl
-- 2. Reparents ServerScriptService children (the package root) into the combined ServerScriptService
-- 3. Reads the test script file and creates a Script under ReplicatedStorage._BatchScripts
--
-- The injected script is the ONLY thing tagged `_BatchTest_<slug>`, because that tag is how
-- batch-test-runner picks what to execute and it can only execute one thing. This used to tag every
-- Script under ServerScriptService instead, which is the same script right up until a project has
-- two -- and then the runner ran whichever the tag happened to list first, silently testing nothing.

local fs = require("@lune/fs")
local process = require("@lune/process")
Expand Down Expand Up @@ -40,17 +45,33 @@ local baseContents = fs.readFile(packages[1].rbxlPath)
local game = roblox.deserializePlace(baseContents)

local HttpService = game:GetService("HttpService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")

ServerScriptService.LoadStringEnabled = true

-- Process first package
for _, descendant in ServerScriptService:GetDescendants() do
if descendant:IsA("Script") then
descendant:AddTag("_BatchTest_" .. packages[1].slug)
local batchScripts = roblox.Instance.new("Folder")
batchScripts.Name = "_BatchScripts"
batchScripts.Parent = ReplicatedStorage

-- Carries the package's entry point as source for the runner to loadstring. Never runs on its own:
-- a Script under ReplicatedStorage is inert, and the runner wants to choose when it runs anyway.
local function injectTestScript(pkg)
if not fs.isFile(pkg.scriptPath) then
print(`[CombinePlaces] No script template for {pkg.slug} at {pkg.scriptPath}`)
process.exit(1)
end

local testScript = roblox.Instance.new("Script")
testScript.Name = pkg.slug
testScript.Source = fs.readFile(pkg.scriptPath)
testScript:AddTag("_BatchTest_" .. pkg.slug)
testScript.Parent = batchScripts
end

-- Process first package
injectTestScript(packages[1])

-- Process remaining packages: deserialize each and reparent ServerScriptService children.
-- NOTE: ObjectValues (links) within each package's subtree are preserved when the
-- whole subtree is reparented as a unit. This works because all ObjectValue targets
Expand All @@ -69,11 +90,7 @@ for idx = 2, #packages do
HttpService.HttpEnabled = true
end

for _, descendant in packageServerScriptService:GetDescendants() do
if descendant:IsA("Script") then
descendant:AddTag("_BatchTest_" .. pkg.slug)
end
end
injectTestScript(pkg)

-- Reparent all ServerScriptService children (non-recursively, just move the roots)
for _, child in packageServerScriptService:GetChildren() do
Expand Down
12 changes: 10 additions & 2 deletions tools/nevermore-cli/templates/batch-test-runner.luau
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,15 @@ local scriptSources = {}
for _, slug in packageSlugs do
local tagged = CollectionService:GetTagged(`_BatchTest_{slug}`)
local inst = tagged[1]
if inst then
if #tagged > 1 then
-- Refused rather than picked. Running whichever one the tag listed first is how this fails
-- quietly: a script that returns without erroring reports as a pass having tested nothing.
local fullNames = {}
for _, taggedInstance in tagged do
table.insert(fullNames, taggedInstance:GetFullName())
end
warn(`[BatchTest] {slug}: {#tagged} instances tagged _BatchTest_{slug}: {table.concat(fullNames, ", ")}`)
elseif inst then
scriptSources[slug] = inst.Source
else
warn(`[BatchTest] Failed to find script source for {slug}`)
Expand All @@ -42,7 +50,7 @@ for _, slug in packageSlugs do
local scriptSource = scriptSources[slug]
if not scriptSource then
print("===BATCH_TEST_BEGIN " .. slug .. "===")
warn(`[BatchTest] {slug}: No test script found for {slug}. Is it tagged with _BatchTest_{slug}?`)
warn(`[BatchTest] {slug}: No test script to run. Is exactly one instance tagged _BatchTest_{slug}?`)
print("===BATCH_TEST_END " .. slug .. " FAIL 0===")
table.insert(results, { slug = slug, success = false, durationMs = 0, error = "No test script found" })
continue
Expand Down
Loading