Skip to content

Commit

Permalink
Component test
Browse files Browse the repository at this point in the history
  • Loading branch information
Sleitnick committed Dec 10, 2024
1 parent a71af41 commit eeb977d
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 57 deletions.
49 changes: 35 additions & 14 deletions ci/Test.luau
Original file line number Diff line number Diff line change
Expand Up @@ -255,24 +255,40 @@ export type TestContext = {
Test: (self: TestContext, name: string, fn: () -> ()) -> (),
Describe: (self: TestContext, name: string, fn: () -> ()) -> (),
Expect: (self: TestContext, value: any) -> TestExpect,
BeforeAll: (self: TestContext, fn: () -> ()) -> (),
AfterAll: (self: TestContext, fn: () -> ()) -> (),
BeforeEach: (self: TestContext, fn: () -> ()) -> (),
AfterEach: (self: TestContext, fn: () -> ()) -> (),
}

type TestContextGroup = {
Name: string,
Items: { any },
AnyFail: boolean,
AfterAllFns: { () -> () },
BeforeEachFns: { () -> () },
AfterEachFns: { () -> () },
}

local function CreateGroup(name: string): TestContextGroup
return {
Name = name,
Items = {},
AnyFail = false,
AfterAllFns = {},
BeforeEachFns = {},
AfterEachFns = {},
}
end

local TestContext = {}
TestContext.__index = TestContext

function TestContext.new(root: string): TestContext
local testContext = setmetatable({
TotalTests = 0,
TotalFails = 0,
Group = {
Name = root,
Items = {},
AnyFail = false,
BeforeEachFns = {},
AfterEachFns = {},
},
Group = CreateGroup(root),
}, TestContext) :: any

testContext.Current = testContext.Group
Expand Down Expand Up @@ -301,13 +317,7 @@ end

function TestContext:Describe(name: string, fn: () -> ())
local parentGroup = self.Current
local group = {
Name = name,
Items = {},
AnyFail = false,
BeforeEachFns = {},
AfterEachFns = {},
}
local group = CreateGroup(name)
self.Current = group
parentGroup.Items[name] = group
for _, fn in parentGroup.BeforeEachFns do
Expand All @@ -318,6 +328,9 @@ function TestContext:Describe(name: string, fn: () -> ())
if group.AnyFail then
parentGroup.AnyFail = true
end
for _, fn in group.AfterAllFns do
fn()
end
for _, fn in parentGroup.AfterEachFns do
fn()
end
Expand All @@ -333,6 +346,14 @@ function TestContext:Expect(value: any): TestExpect
return setmetatable({ Value = resolvedValue, Success = success, Err = err, Flip = false }, TestExpect) :: any
end

function TestContext:BeforeAll(fn: () -> ())
fn()
end

function TestContext:AfterAll(fn: () -> ())
table.insert(self.Current.AfterAllFns, fn)
end

function TestContext:BeforeEach(fn: () -> ())
table.insert(self.Current.BeforeEachFns, fn)
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
return function()
local Component = require(script.Parent)
local CollectionService = game:GetService("CollectionService")
local RunService = game:GetService("RunService")
local ServerScriptService = game:GetService("ServerScriptService")

local Test = require(ServerScriptService.TestRunner.Test)

local CollectionService = game:GetService("CollectionService")
local RunService = game:GetService("RunService")
return function(ctx: Test.TestContext)
local Component = require(script.Parent)

local TAG = "__KnitTestComponent__"

Expand Down Expand Up @@ -79,24 +82,24 @@ return function()
self.DidRenderStepped = true
end

beforeAll(function()
ctx:BeforeAll(function()
taggedInstanceFolder = Instance.new("Folder")
taggedInstanceFolder.Name = "KnitComponentTest"
taggedInstanceFolder.Archivable = false
taggedInstanceFolder.Parent = workspace
end)

afterEach(function()
ctx:AfterEach(function()
taggedInstanceFolder:ClearAllChildren()
end)

afterAll(function()
ctx:AfterAll(function()
taggedInstanceFolder:Destroy()
TestComponentMain:Destroy()
end)

describe("Component", function()
it("should capture start and stop events", function()
ctx:Describe("Component", function()
ctx:Test("should capture start and stop events", function()
local didStart = 0
local didStop = 0
local started = TestComponentMain.Started:Connect(function()
Expand All @@ -111,18 +114,18 @@ return function()
task.wait()
started:Disconnect()
stopped:Disconnect()
expect(didStart).to.equal(1)
expect(didStop).to.equal(1)
ctx:Expect(didStart):ToBe(1)
ctx:Expect(didStop):ToBe(1)
end)

it("should be able to get component from the instance", function()
ctx:Test("should be able to get component from the instance", function()
local instance = CreateTaggedInstance()
task.wait()
local component = TestComponentMain:FromInstance(instance)
expect(component).to.be.ok()
ctx:Expect(component):ToBeOk()
end)

it("should be able to get all component instances existing", function()
ctx:Test("should be able to get all component instances existing", function()
local numComponents = 3
local instances = table.create(numComponents)
for i = 1, numComponents do
Expand All @@ -131,37 +134,37 @@ return function()
end
task.wait()
local components = TestComponentMain:GetAll()
expect(components).to.be.a("table")
expect(#components).to.equal(numComponents)
ctx:Expect(components):ToBeA("table")
ctx:Expect(#components):ToBe(numComponents)
for _, c in ipairs(components) do
expect(table.find(instances, c.Instance)).to.be.ok()
ctx:Expect(table.find(instances, c.Instance)):ToBeOk()
end
end)

it("should call lifecycle methods and extension functions", function()
ctx:Test("should call lifecycle methods and extension functions", function()
local instance = CreateTaggedInstance()
task.wait(0.2)
local component = TestComponentMain:FromInstance(instance)
expect(component).to.be.ok()
expect(component.Data).to.equal("abcdef")
expect(component.DidHeartbeat).to.equal(true)
expect(component.DidStepped).to.equal(RunService:IsRunning())
expect(component.DidRenderStepped).to.never.equal(true)
ctx:Expect(component):ToBeOk()
ctx:Expect(component.Data):ToBe("abcdef")
ctx:Expect(component.DidHeartbeat):ToBe(true)
ctx:Expect(component.DidStepped):ToBe(RunService:IsRunning())
ctx:Expect(component.DidRenderStepped):Not():ToBe(true)
instance:Destroy()
task.wait()
expect(component.Data).to.equal("abcdefghi")
ctx:Expect(component.Data):ToBe("abcdefghi")
end)

it("should get another component linked to the same instance", function()
ctx:Test("should get another component linked to the same instance", function()
local instance = CreateTaggedInstance()
task.wait()
local component = TestComponentMain:FromInstance(instance)
expect(component).to.be.ok()
expect(component.Another).to.be.ok()
expect(component.Another:GetData()).to.equal(true)
ctx:Expect(component):ToBeOk()
ctx:Expect(component.Another):ToBeOk()
ctx:Expect(component.Another:GetData()):ToBe(true)
end)

it("should use extension to decide whether or not to construct", function()
ctx:Test("should use extension to decide whether or not to construct", function()
local e1 = { c = true }
function e1.ShouldConstruct(_component)
return e1.c
Expand Down Expand Up @@ -190,9 +193,9 @@ return function()
local function Check(inst, comp, shouldExist)
local c = comp:FromInstance(inst)
if shouldExist then
expect(c).to.be.ok()
ctx:Expect(c):ToBeOk()
else
expect(c).to.never.be.ok()
ctx:Expect(c):ToBeNil()
end
end

Expand Down Expand Up @@ -221,7 +224,7 @@ return function()
CreateAndCheckAll(false, false, false)
end)

it("should decide whether or not to use extend", function()
ctx:Test("should decide whether or not to use extend", function()
local e1 = { extend = true }
function e1.ShouldExtend(_component)
return e1.extend
Expand All @@ -246,16 +249,16 @@ return function()
local instance = CreateTaggedInstance()
task.wait()
local component = TestComponent:FromInstance(instance)
expect(component).to.be.ok()
ctx:Expect(component):ToBeOk()
if ex1 then
expect(component.E1).to.equal(true)
ctx:Expect(component.E1):ToBe(true)
else
expect(component.E1).to.never.be.ok()
ctx:Expect(component.E1):ToBeNil()
end
if ex2 then
expect(component.E2).to.equal(true)
ctx:Expect(component.E2):ToBe(true)
else
expect(component.E2).to.never.be.ok()
ctx:Expect(component.E2):ToBeNil()
end
end

Expand All @@ -265,7 +268,7 @@ return function()
SetAndCheck(false, true)
end)

it("should allow yielding within construct", function()
ctx:Test("should allow yielding within construct", function()
local CUSTOM_TAG = "CustomTag"

local TestComponent = Component.new({ Tag = CUSTOM_TAG })
Expand All @@ -286,22 +289,22 @@ return function()

task.wait(0.6)

expect(numConstruct).to.equal(1)
ctx:Expect(numConstruct):ToBe(1)
p:Destroy()
newP:Destroy()
end)

it("should wait for instance", function()
ctx:Test("should wait for instance", function()
local p = Instance.new("Part")
p.Anchored = true
p.Parent = workspace
task.delay(0.1, function()
CollectionService:AddTag(p, TAG)
end)
local success, c = TestComponentMain:WaitForInstance(p):timeout(1):await()
expect(success).to.equal(true)
expect(c).to.be.a("table")
expect(c.Instance).to.equal(p)
ctx:Expect(success):ToBe(true)
ctx:Expect(c):ToBeA("table")
ctx:Expect(c.Instance):ToBe(p)
p:Destroy()
end)
end)
Expand Down

0 comments on commit eeb977d

Please sign in to comment.