tools/test: check_all.sh (CI mirror + all scripted tests + demo forced open + LÖVE), hashes.sh (draw checksums vs a git rev), t_libhash (library-only draw checksum); regenerate PORT_STATUS
This commit is contained in:
+1089
-1089
File diff suppressed because it is too large
Load Diff
Executable
+46
@@ -0,0 +1,46 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# All local checks: CI's "Check" step (release.yml) + every scripted test + whole demo forced open + LÖVE.
|
||||||
|
# Usage: tools/test/check_all.sh (prints PASS/FAIL per check, exit 1 if any failed)
|
||||||
|
# HASHES=1 tools/test/check_all.sh (also prints the draw-data checksums, see hashes.sh)
|
||||||
|
cd "$(dirname "$0")/../.."
|
||||||
|
export PATH="$PATH:/nix/store/2m2ja613nndihc8qm10f2rhq6znp1nh4-luau-0.734/bin:/nix/store/4qxq4arv32ly13kl3g0m5q80gm3a35xr-luajit-2.1.1741730670/bin"
|
||||||
|
T=$(mktemp -d /tmp/imgui_check.XXXX)
|
||||||
|
R="python3 tools/test/run.py --quiet --roblox --timeout 600"
|
||||||
|
|
||||||
|
# name | expected output | command
|
||||||
|
CHECKS=(
|
||||||
|
"readme|README OK|$R --main tools/test/scripts/t_readme.luau --frames 30"
|
||||||
|
"readme-min|README OK|MINIFY=1 $R --main tools/test/scripts/t_readme.luau --frames 30"
|
||||||
|
"cached|CACHED OK|$R --main tools/test/scripts/t_cached_window.luau --frames 130"
|
||||||
|
"fixes|FIXES OK|$R --main tools/test/scripts/t_fixes.luau --frames 25"
|
||||||
|
"nodemo|NODEMO OK|NO_DEMO=1 $R --main tools/test/scripts/t_nodemo.luau --frames 25"
|
||||||
|
"widgets|OK|$R --main tools/test/scripts/t_widgets.luau --frames 80"
|
||||||
|
"tables|OK|$R --main tools/test/scripts/t_tables.luau --frames 150"
|
||||||
|
"tabs|scrollbtn.true|$R --main tools/test/scripts/t_tabs.luau --frames 60"
|
||||||
|
"modal|round trip ok|$R --main tools/test/scripts/t_modal.luau --frames 40"
|
||||||
|
"dock|DOCK OK|$R --main tools/test/scripts/t_dock.luau --frames 60"
|
||||||
|
"dock_close|DOCK CLOSE OK|$R --main tools/test/scripts/t_dock_close.luau --frames 60"
|
||||||
|
"dock_drag|OK|$R --main tools/test/scripts/t_dock_drag.luau --frames 80"
|
||||||
|
"dock_ini|ROUNDTRIP OK|$R --main tools/test/scripts/t_dock_ini.luau --frames 60"
|
||||||
|
"dock_move|OK|$R --main tools/test/scripts/t_dock_move.luau --frames 80"
|
||||||
|
"passthru|PASSTHRU OK|$R --main tools/test/scripts/t_passthru.luau --frames 40"
|
||||||
|
"textproxy|PROXY OK|$R --main tools/test/scripts/t_textproxy.luau --frames 30"
|
||||||
|
"style_editor|SE OK|$R --main tools/test/scripts/t_style_editor.luau --frames 20"
|
||||||
|
"style_leak|STYLE OK|$R --main tools/test/scripts/t_style_leak.luau --frames 60 --open"
|
||||||
|
"apps|APPS OK|$R --main tools/test/scripts/t_apps.luau --frames 120 --open"
|
||||||
|
"libhash|LIBHASH|NO_DEMO=1 $R --main tools/test/scripts/t_libhash.luau --frames 120"
|
||||||
|
"demo_open|DRAWHASH|$R --main tools/test/scripts/t_drawhash.luau --frames 150 --open"
|
||||||
|
"demo_random|^|python3 tools/test/run.py --roblox --timeout 600 --frames 400 --open"
|
||||||
|
"love|DRAWHASH|python3 tools/bundle.py --target love >/dev/null && luajit tools/test/love/t_drawhash.lua 60 Widgets,Basic && luajit tools/test/love/t_examples.lua"
|
||||||
|
)
|
||||||
|
|
||||||
|
run() { # $1=name $2=expect $3=cmd
|
||||||
|
bash -c "$3" > "$T/$1.txt" 2>&1; code=$?
|
||||||
|
if [ $code -eq 0 ] && grep -q "$2" "$T/$1.txt" && ! grep -qiE "error|traceback|stack begin|FAIL" "$T/$1.txt"; then echo "PASS $1"
|
||||||
|
else echo "FAIL $1 (exit $code, log $T/$1.txt)"; tail -5 "$T/$1.txt" | sed 's/^/ /'; fi
|
||||||
|
}
|
||||||
|
for c in "${CHECKS[@]}"; do IFS='|' read -r n e cmd <<< "$c"; run "$n" "$e" "$cmd" & done > "$T/summary.txt"
|
||||||
|
wait
|
||||||
|
sort "$T/summary.txt"
|
||||||
|
[ -n "$HASHES" ] && tools/test/hashes.sh
|
||||||
|
! grep -q "^FAIL" "$T/summary.txt"
|
||||||
Executable
+23
@@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Draw-data checksums of the working tree vs a git rev (default HEAD), to prove a change renders identically.
|
||||||
|
# tools/test/hashes.sh [rev]
|
||||||
|
# lib = t_libhash (library only, no demo): must stay equal unless rendering is meant to change
|
||||||
|
# demo = t_drawhash with Widgets,Basic / whole demo open: changes with any demo edit
|
||||||
|
cd "$(dirname "$0")/../.."
|
||||||
|
export PATH="$PATH:/nix/store/2m2ja613nndihc8qm10f2rhq6znp1nh4-luau-0.734/bin:/nix/store/4qxq4arv32ly13kl3g0m5q80gm3a35xr-luajit-2.1.1741730670/bin"
|
||||||
|
REV=${1:-HEAD}
|
||||||
|
hashes() { # $1 = repo dir
|
||||||
|
( cd "$1"
|
||||||
|
R="python3 tools/test/run.py --quiet --roblox --timeout 600"
|
||||||
|
echo "lib $(NO_DEMO=1 $R --main "$OLDPWD/tools/test/scripts/t_libhash.luau" --frames 120 | grep -o 'LIBHASH.*')" &
|
||||||
|
echo "demo-basic $($R --main tools/test/scripts/t_drawhash.luau --frames 150 --open-only Widgets,Basic | grep -o 'DRAWHASH.*')" &
|
||||||
|
echo "demo-all $($R --main tools/test/scripts/t_drawhash.luau --frames 150 --open | grep -o 'DRAWHASH.*')" &
|
||||||
|
echo "love-basic $(python3 tools/bundle.py --target love >/dev/null; luajit tools/test/love/t_drawhash.lua 60 Widgets,Basic | grep -o 'DRAWHASH.*')" &
|
||||||
|
wait ) | tr "\t" " " | sort
|
||||||
|
}
|
||||||
|
W=$(mktemp -d /tmp/imgui_rev.XXXX)
|
||||||
|
git worktree add -q --detach "$W" "$REV"
|
||||||
|
hashes "$W" > "$W.old" & hashes . > "$W.new"; wait
|
||||||
|
git worktree remove --force "$W"
|
||||||
|
echo "check $REV working tree"
|
||||||
|
paste "$W.old" "$W.new" | awk -F'\t' '{split($1,a," "); split($2,b," "); printf "%-12s %-30s %-30s %s\n", a[1], a[3], b[3], (a[3]==b[3]?"same":"CHANGED")}'
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
-- Library-only draw-data checksum (no demo, run with NO_DEMO=1): widgets + raw ImDrawList primitives with scripted input.
|
||||||
|
-- Must stay identical across demo edits; changes only when library rendering changes. Prints "LIBHASH <n>".
|
||||||
|
local G = require(game:GetService("ReplicatedStorage"):WaitForChild("ImGui"))
|
||||||
|
local ImGui, ImVec2, ImVec4 = G.ImGui, G.ImVec2, G.ImVec4
|
||||||
|
ImGui.CreateContext(); G.ImGui_ImplRoblox.Init(); G.ImGui_ImplRoblox.SetRenderRate(0)
|
||||||
|
local io = ImGui.GetIO()
|
||||||
|
local frame, h = 0, 0
|
||||||
|
local function mix(v) h = (h * 31 + math.floor(v * 64 + 0.5)) % 2147483647 end
|
||||||
|
local st = { b = false, f = 0.25, i = 42, c = ImVec4(0.2, 0.7, 0.4, 1.0), buf = ImGui.NewTextBuffer("hello", 64), r = 0, tab = 0, combo = 1, list = 2 }
|
||||||
|
local plot = {}
|
||||||
|
for i = 1, 40 do plot[i] = math.sin(i * 0.3) end
|
||||||
|
local poly = { ImVec2(0, 0), ImVec2(60, 10), ImVec2(30, 30), ImVec2(70, 60), ImVec2(0, 50) }
|
||||||
|
|
||||||
|
game:GetService("RunService").Stepped:Connect(function()
|
||||||
|
frame += 1
|
||||||
|
G.ImGui_ImplRoblox.NewFrame()
|
||||||
|
io.DeltaTime = 1 / 60
|
||||||
|
io:AddMousePosEvent(20 + (frame * 37) % 560, 20 + (frame * 53) % 560)
|
||||||
|
if frame % 7 == 0 then io:AddMouseButtonEvent(0, frame % 14 == 0) end
|
||||||
|
if frame % 11 == 0 then io:AddMouseWheelEvent(0, -1) end
|
||||||
|
ImGui.NewFrame()
|
||||||
|
|
||||||
|
ImGui.SetNextWindowPos(ImVec2(10, 10), G.ImGuiCond.Always); ImGui.SetNextWindowSize(ImVec2(320, 560), G.ImGuiCond.Always)
|
||||||
|
ImGui.Begin("Widgets")
|
||||||
|
ImGui.Text("Text %d", 123); ImGui.TextColored(ImVec4(1, 0.5, 0, 1), "Colored"); ImGui.TextWrapped("Wrapped text that is long enough to wrap around the window edge at least once.")
|
||||||
|
ImGui.Button("Button"); ImGui.SameLine(); ImGui.SmallButton("Small"); ImGui.SameLine(); ImGui.ArrowButton("##a", G.ImGuiDir.Left)
|
||||||
|
st.b = ImGui.Checkbox("Checkbox", st.b)
|
||||||
|
st.r = ImGui.RadioButton("R0", st.r, 0); ImGui.SameLine(); st.r = ImGui.RadioButton("R1", st.r, 1)
|
||||||
|
st.f = ImGui.SliderFloat("Slider", st.f, 0, 1); st.i = ImGui.DragInt("Drag", st.i, 1, 0, 100)
|
||||||
|
ImGui.InputText("Input", st.buf, 64)
|
||||||
|
ImGui.ColorEdit4("Color", st.c)
|
||||||
|
st.combo = ImGui.Combo("Combo", st.combo, { "AAA", "BBB", "CCC" })
|
||||||
|
st.list = ImGui.ListBox("List", st.list, { "one", "two", "three", "four" }, 4, 3)
|
||||||
|
ImGui.ProgressBar(0.4, ImVec2(-1, 0)); ImGui.ProgressBar(-1.0 * frame / 60, ImVec2(-1, 0), "busy")
|
||||||
|
ImGui.PlotLines("Lines", plot, nil, #plot); ImGui.PlotHistogram("Hist", plot, nil, #plot, 0, nil, -1, 1, ImVec2(0, 40))
|
||||||
|
ImGui.Bullet(); ImGui.Text("bullet"); ImGui.Separator(); ImGui.SeparatorText("Sep")
|
||||||
|
if ImGui.TreeNode("Tree") then ImGui.Text("inside"); ImGui.TreePop() end
|
||||||
|
ImGui.SetNextItemOpen(true, G.ImGuiCond.Once)
|
||||||
|
if ImGui.CollapsingHeader("Header") then
|
||||||
|
if ImGui.BeginTabBar("tabs") then
|
||||||
|
if ImGui.BeginTabItem("Tab A") then ImGui.Text("A"); ImGui.EndTabItem() end
|
||||||
|
if ImGui.BeginTabItem("Tab B") then ImGui.Text("B"); ImGui.EndTabItem() end
|
||||||
|
ImGui.EndTabBar()
|
||||||
|
end
|
||||||
|
if ImGui.BeginTable("t", 3, bit32.bor(G.ImGuiTableFlags.Borders, G.ImGuiTableFlags.RowBg, G.ImGuiTableFlags.Resizable)) then
|
||||||
|
ImGui.TableSetupColumn("One"); ImGui.TableSetupColumn("Two"); ImGui.TableSetupColumn("Three"); ImGui.TableHeadersRow()
|
||||||
|
for row = 0, 4 do ImGui.TableNextRow(); for col = 0, 2 do ImGui.TableSetColumnIndex(col); ImGui.Text("r%d c%d", row, col) end end
|
||||||
|
ImGui.EndTable()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ImGui.End()
|
||||||
|
|
||||||
|
ImGui.SetNextWindowPos(ImVec2(340, 10), G.ImGuiCond.Always); ImGui.SetNextWindowSize(ImVec2(300, 560), G.ImGuiCond.Always)
|
||||||
|
ImGui.Begin("Draw")
|
||||||
|
local dl, p = ImGui.GetWindowDrawList(), ImGui.GetCursorScreenPos()
|
||||||
|
local x, y, col = p.x + 4, p.y + 4, 0xFF40C0FF
|
||||||
|
for i, th in { 1.0, 2.5, 6.0 } do
|
||||||
|
local yy = y + (i - 1) * 70
|
||||||
|
dl:AddRect(ImVec2(x, yy), ImVec2(x + 50, yy + 50), col, 10.0, th)
|
||||||
|
dl:AddRectFilled(ImVec2(x + 60, yy), ImVec2(x + 110, yy + 50), col, 10.0, G.ImDrawFlags.RoundCornersTopLeft or 0)
|
||||||
|
dl:AddCircle(ImVec2(x + 145, yy + 25), 25, col, 0, th)
|
||||||
|
dl:AddNgon(ImVec2(x + 200, yy + 25), 25, col, 6, th)
|
||||||
|
dl:AddTriangle(ImVec2(x + 230, yy + 50), ImVec2(x + 255, yy), ImVec2(x + 280, yy + 50), col, th)
|
||||||
|
dl:AddLine(ImVec2(x, yy + 60), ImVec2(x + 280, yy + 55), col, th)
|
||||||
|
end
|
||||||
|
y += 210
|
||||||
|
dl:AddBezierCubic(ImVec2(x, y), ImVec2(x + 60, y - 30), ImVec2(x + 120, y + 60), ImVec2(x + 180, y), col, 3.0)
|
||||||
|
dl:AddBezierQuadratic(ImVec2(x, y + 30), ImVec2(x + 90, y - 10), ImVec2(x + 180, y + 30), col, 2.0)
|
||||||
|
dl:AddEllipse(ImVec2(x + 230, y + 15), ImVec2(40, 15), col, 0.5, 0, 2.0)
|
||||||
|
y += 50
|
||||||
|
local pts = {}
|
||||||
|
for i, v in poly do pts[i] = ImVec2(x + v.x, y + v.y) end
|
||||||
|
dl:AddConcavePolyFilled(pts, #pts, 0xFF8080FF)
|
||||||
|
for i, v in poly do pts[i] = ImVec2(x + 100 + v.x, y + v.y) end
|
||||||
|
dl:AddPolyline(pts, #pts, col, 4.0, G.ImDrawFlags.Closed)
|
||||||
|
for i, v in poly do pts[i] = ImVec2(x + 200 + v.x, y + v.y) end
|
||||||
|
dl:AddPolyline(pts, #pts, col, 1.0, 0)
|
||||||
|
y += 80
|
||||||
|
dl:AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x + 100, y + 40), 0xFF0000FF, 0xFF00FF00, 0xFFFF0000, 0xFFFFFFFF)
|
||||||
|
dl:AddCircleFilled(ImVec2(x + 140, y + 20), 20, col)
|
||||||
|
dl:AddEllipseFilled(ImVec2(x + 210, y + 20), ImVec2(30, 15), col, 0.3)
|
||||||
|
dl:AddText(ImVec2(x, y + 50), 0xFFFFFFFF, "AddText")
|
||||||
|
ImGui.End()
|
||||||
|
|
||||||
|
ImGui.Render()
|
||||||
|
for _, dl in ImGui.GetDrawData().CmdLists:iter() do
|
||||||
|
local vb, id = dl.VtxBuffer.Buf, dl.IdxBuffer.Data
|
||||||
|
for i = 1, dl.VtxBuffer.Size do local o = (i - 1) * 36; mix(buffer.readf64(vb, o)); mix(buffer.readf64(vb, o + 8)); mix(buffer.readf64(vb, o + 16) * 4096); mix(buffer.readf64(vb, o + 24) * 4096); mix(buffer.readu32(vb, o + 32) / 64) end
|
||||||
|
for i = 1, dl.IdxBuffer.Size do mix(id[i]) end
|
||||||
|
for _, c in dl.CmdBuffer:iter() do mix(c.ClipRect.x); mix(c.ClipRect.y); mix(c.ClipRect.z); mix(c.ClipRect.w); mix(c.ElemCount) end
|
||||||
|
end
|
||||||
|
G.ImGui_ImplRoblox.RenderDrawData(ImGui.GetDrawData())
|
||||||
|
if frame == ARG_FRAMES - 1 then print("LIBHASH", h) end
|
||||||
|
end)
|
||||||
Reference in New Issue
Block a user