mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-04 04:30:04 +00:00
chore: migrate tests from tests-ui/ to colocate with source files (#7811)
## Summary Migrates all unit tests from `tests-ui/` to colocate with their source files in `src/`, improving discoverability and maintainability. ## Changes - **What**: Relocated all unit tests to be adjacent to the code they test, following the `<source>.test.ts` naming convention - **Config**: Updated `vitest.config.ts` to remove `tests-ui` include pattern and `@tests-ui` alias - **Docs**: Moved testing documentation to `docs/testing/` with updated paths and patterns ## Review Focus - Migration patterns documented in `temp/plans/migrate-tests-ui-to-src.md` - Tests use `@/` path aliases instead of relative imports - Shared fixtures placed in `__fixtures__/` directories ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7811-chore-migrate-tests-from-tests-ui-to-colocate-with-source-files-2da6d73d36508147a4cce85365dee614) by [Unito](https://www.unito.io) --------- Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
163
src/scripts/metadata/gltf.test.ts
Normal file
163
src/scripts/metadata/gltf.test.ts
Normal file
@@ -0,0 +1,163 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { ASCII, GltfSizeBytes } from '@/types/metadataTypes'
|
||||
|
||||
import { getGltfBinaryMetadata } from './gltf'
|
||||
|
||||
describe('GLTF binary metadata parser', () => {
|
||||
const createGLTFFileStructure = () => {
|
||||
const header = new ArrayBuffer(GltfSizeBytes.HEADER)
|
||||
const headerView = new DataView(header)
|
||||
return { header, headerView }
|
||||
}
|
||||
|
||||
const jsonToBinary = (json: object) => {
|
||||
const jsonString = JSON.stringify(json)
|
||||
const jsonData = new TextEncoder().encode(jsonString)
|
||||
return jsonData
|
||||
}
|
||||
|
||||
const createJSONChunk = (jsonData: ArrayBuffer) => {
|
||||
const chunkHeader = new ArrayBuffer(GltfSizeBytes.CHUNK_HEADER)
|
||||
const chunkView = new DataView(chunkHeader)
|
||||
chunkView.setUint32(0, jsonData.byteLength, true)
|
||||
chunkView.setUint32(4, ASCII.JSON, true)
|
||||
return chunkHeader
|
||||
}
|
||||
|
||||
const setVersionHeader = (headerView: DataView, version: number) => {
|
||||
headerView.setUint32(4, version, true)
|
||||
}
|
||||
|
||||
const setTypeHeader = (headerView: DataView, type: number) => {
|
||||
headerView.setUint32(0, type, true)
|
||||
}
|
||||
|
||||
const setTotalLengthHeader = (headerView: DataView, length: number) => {
|
||||
headerView.setUint32(8, length, true)
|
||||
}
|
||||
|
||||
const setHeaders = (headerView: DataView, jsonData: ArrayBuffer) => {
|
||||
setTypeHeader(headerView, ASCII.GLTF)
|
||||
setVersionHeader(headerView, 2)
|
||||
setTotalLengthHeader(
|
||||
headerView,
|
||||
GltfSizeBytes.HEADER + GltfSizeBytes.CHUNK_HEADER + jsonData.byteLength
|
||||
)
|
||||
}
|
||||
|
||||
function createMockGltfFile(jsonContent: object): File {
|
||||
const jsonData = jsonToBinary(jsonContent)
|
||||
const { header, headerView } = createGLTFFileStructure()
|
||||
|
||||
setHeaders(headerView, jsonData.buffer)
|
||||
|
||||
const chunkHeader = createJSONChunk(jsonData.buffer)
|
||||
|
||||
const fileContent = new Uint8Array(
|
||||
header.byteLength + chunkHeader.byteLength + jsonData.byteLength
|
||||
)
|
||||
fileContent.set(new Uint8Array(header), 0)
|
||||
fileContent.set(new Uint8Array(chunkHeader), header.byteLength)
|
||||
fileContent.set(jsonData, header.byteLength + chunkHeader.byteLength)
|
||||
|
||||
return new File([fileContent], 'test.glb', { type: 'model/gltf-binary' })
|
||||
}
|
||||
|
||||
it('should extract workflow metadata from GLTF binary file', async () => {
|
||||
const testWorkflow = {
|
||||
nodes: [
|
||||
{
|
||||
id: 1,
|
||||
type: 'TestNode',
|
||||
pos: [100, 100]
|
||||
}
|
||||
],
|
||||
links: []
|
||||
}
|
||||
|
||||
const mockFile = createMockGltfFile({
|
||||
asset: {
|
||||
version: '2.0',
|
||||
generator: 'ComfyUI GLTF Test',
|
||||
extras: {
|
||||
workflow: testWorkflow
|
||||
}
|
||||
},
|
||||
scenes: []
|
||||
})
|
||||
|
||||
const metadata = await getGltfBinaryMetadata(mockFile)
|
||||
|
||||
expect(metadata).toBeDefined()
|
||||
expect(metadata.workflow).toBeDefined()
|
||||
|
||||
const workflow = metadata.workflow as {
|
||||
nodes: Array<{ id: number; type: string }>
|
||||
}
|
||||
expect(workflow.nodes[0].id).toBe(1)
|
||||
expect(workflow.nodes[0].type).toBe('TestNode')
|
||||
})
|
||||
|
||||
it('should extract prompt metadata from GLTF binary file', async () => {
|
||||
const testPrompt = {
|
||||
node1: {
|
||||
class_type: 'TestNode',
|
||||
inputs: {
|
||||
seed: 123456
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const mockFile = createMockGltfFile({
|
||||
asset: {
|
||||
version: '2.0',
|
||||
generator: 'ComfyUI GLTF Test',
|
||||
extras: {
|
||||
prompt: testPrompt
|
||||
}
|
||||
},
|
||||
scenes: []
|
||||
})
|
||||
|
||||
const metadata = await getGltfBinaryMetadata(mockFile)
|
||||
expect(metadata).toBeDefined()
|
||||
expect(metadata.prompt).toBeDefined()
|
||||
|
||||
const prompt = metadata.prompt as Record<string, any>
|
||||
expect(prompt.node1.class_type).toBe('TestNode')
|
||||
expect(prompt.node1.inputs.seed).toBe(123456)
|
||||
})
|
||||
|
||||
it('should handle string JSON content', async () => {
|
||||
const workflowStr = JSON.stringify({
|
||||
nodes: [{ id: 1, type: 'StringifiedNode' }],
|
||||
links: []
|
||||
})
|
||||
|
||||
const mockFile = createMockGltfFile({
|
||||
asset: {
|
||||
version: '2.0',
|
||||
extras: {
|
||||
workflow: workflowStr // As string instead of object
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const metadata = await getGltfBinaryMetadata(mockFile)
|
||||
|
||||
expect(metadata).toBeDefined()
|
||||
expect(metadata.workflow).toBeDefined()
|
||||
|
||||
const workflow = metadata.workflow as {
|
||||
nodes: Array<{ id: number; type: string }>
|
||||
}
|
||||
expect(workflow.nodes[0].type).toBe('StringifiedNode')
|
||||
})
|
||||
|
||||
it('should handle invalid GLTF binary files gracefully', async () => {
|
||||
const invalidEmptyFile = new File([], 'invalid.glb')
|
||||
const metadata = await getGltfBinaryMetadata(invalidEmptyFile)
|
||||
expect(metadata).toEqual({})
|
||||
})
|
||||
})
|
||||
448
src/scripts/metadata/ply.test.ts
Normal file
448
src/scripts/metadata/ply.test.ts
Normal file
@@ -0,0 +1,448 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { isPLYAsciiFormat, parseASCIIPLY } from '@/scripts/metadata/ply'
|
||||
|
||||
function createPLYBuffer(content: string): ArrayBuffer {
|
||||
return new TextEncoder().encode(content).buffer
|
||||
}
|
||||
|
||||
describe('PLY metadata parser', () => {
|
||||
describe('isPLYAsciiFormat', () => {
|
||||
it('should return true for ASCII format PLY', () => {
|
||||
const ply = `ply
|
||||
format ascii 1.0
|
||||
element vertex 3
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
end_header
|
||||
0 0 0
|
||||
1 0 0
|
||||
0 1 0`
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
expect(isPLYAsciiFormat(buffer)).toBe(true)
|
||||
})
|
||||
|
||||
it('should return false for binary format PLY', () => {
|
||||
const ply = `ply
|
||||
format binary_little_endian 1.0
|
||||
element vertex 3
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
end_header`
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
expect(isPLYAsciiFormat(buffer)).toBe(false)
|
||||
})
|
||||
|
||||
it('should return false for binary big endian format', () => {
|
||||
const ply = `ply
|
||||
format binary_big_endian 1.0
|
||||
element vertex 3
|
||||
end_header`
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
expect(isPLYAsciiFormat(buffer)).toBe(false)
|
||||
})
|
||||
|
||||
it('should handle empty buffer', () => {
|
||||
const buffer = new ArrayBuffer(0)
|
||||
expect(isPLYAsciiFormat(buffer)).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('parseASCIIPLY', () => {
|
||||
it('should parse simple PLY with positions only', () => {
|
||||
const ply = `ply
|
||||
format ascii 1.0
|
||||
element vertex 3
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
end_header
|
||||
0.0 0.0 0.0
|
||||
1.0 0.0 0.0
|
||||
0.0 1.0 0.0`
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
const result = parseASCIIPLY(buffer)
|
||||
|
||||
expect(result).not.toBeNull()
|
||||
expect(result!.vertexCount).toBe(3)
|
||||
expect(result!.colors).toBeNull()
|
||||
expect(result!.positions).toBeInstanceOf(Float32Array)
|
||||
expect(result!.positions.length).toBe(9)
|
||||
|
||||
expect(result!.positions[0]).toBeCloseTo(0.0)
|
||||
expect(result!.positions[1]).toBeCloseTo(0.0)
|
||||
expect(result!.positions[2]).toBeCloseTo(0.0)
|
||||
|
||||
expect(result!.positions[3]).toBeCloseTo(1.0)
|
||||
expect(result!.positions[4]).toBeCloseTo(0.0)
|
||||
expect(result!.positions[5]).toBeCloseTo(0.0)
|
||||
|
||||
expect(result!.positions[6]).toBeCloseTo(0.0)
|
||||
expect(result!.positions[7]).toBeCloseTo(1.0)
|
||||
expect(result!.positions[8]).toBeCloseTo(0.0)
|
||||
})
|
||||
|
||||
it('should parse PLY with positions and colors', () => {
|
||||
const ply = `ply
|
||||
format ascii 1.0
|
||||
element vertex 2
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
property uchar red
|
||||
property uchar green
|
||||
property uchar blue
|
||||
end_header
|
||||
1.0 2.0 3.0 255 128 0
|
||||
-1.0 -2.0 -3.0 0 255 128`
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
const result = parseASCIIPLY(buffer)
|
||||
|
||||
expect(result).not.toBeNull()
|
||||
expect(result!.vertexCount).toBe(2)
|
||||
expect(result!.colors).not.toBeNull()
|
||||
expect(result!.colors).toBeInstanceOf(Float32Array)
|
||||
expect(result!.colors!.length).toBe(6)
|
||||
|
||||
// First vertex position
|
||||
expect(result!.positions[0]).toBeCloseTo(1.0)
|
||||
expect(result!.positions[1]).toBeCloseTo(2.0)
|
||||
expect(result!.positions[2]).toBeCloseTo(3.0)
|
||||
|
||||
// First vertex color (normalized to 0-1)
|
||||
expect(result!.colors![0]).toBeCloseTo(1.0) // 255/255
|
||||
expect(result!.colors![1]).toBeCloseTo(128 / 255)
|
||||
expect(result!.colors![2]).toBeCloseTo(0.0)
|
||||
|
||||
// Second vertex color
|
||||
expect(result!.colors![3]).toBeCloseTo(0.0)
|
||||
expect(result!.colors![4]).toBeCloseTo(1.0)
|
||||
expect(result!.colors![5]).toBeCloseTo(128 / 255)
|
||||
})
|
||||
|
||||
it('should handle properties in non-standard order', () => {
|
||||
const ply = `ply
|
||||
format ascii 1.0
|
||||
element vertex 1
|
||||
property uchar red
|
||||
property float z
|
||||
property uchar green
|
||||
property float x
|
||||
property uchar blue
|
||||
property float y
|
||||
end_header
|
||||
255 3.0 128 1.0 64 2.0`
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
const result = parseASCIIPLY(buffer)
|
||||
|
||||
expect(result).not.toBeNull()
|
||||
expect(result!.vertexCount).toBe(1)
|
||||
|
||||
expect(result!.positions[0]).toBeCloseTo(1.0)
|
||||
expect(result!.positions[1]).toBeCloseTo(2.0)
|
||||
expect(result!.positions[2]).toBeCloseTo(3.0)
|
||||
|
||||
expect(result!.colors![0]).toBeCloseTo(1.0)
|
||||
expect(result!.colors![1]).toBeCloseTo(128 / 255)
|
||||
expect(result!.colors![2]).toBeCloseTo(64 / 255)
|
||||
})
|
||||
|
||||
it('should handle extra properties', () => {
|
||||
const ply = `ply
|
||||
format ascii 1.0
|
||||
element vertex 1
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
property float nx
|
||||
property float ny
|
||||
property float nz
|
||||
property uchar red
|
||||
property uchar green
|
||||
property uchar blue
|
||||
property uchar alpha
|
||||
end_header
|
||||
1.0 2.0 3.0 0.0 1.0 0.0 255 128 64 255`
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
const result = parseASCIIPLY(buffer)
|
||||
|
||||
expect(result).not.toBeNull()
|
||||
expect(result!.positions[0]).toBeCloseTo(1.0)
|
||||
expect(result!.positions[1]).toBeCloseTo(2.0)
|
||||
expect(result!.positions[2]).toBeCloseTo(3.0)
|
||||
|
||||
expect(result!.colors![0]).toBeCloseTo(1.0)
|
||||
expect(result!.colors![1]).toBeCloseTo(128 / 255)
|
||||
expect(result!.colors![2]).toBeCloseTo(64 / 255)
|
||||
})
|
||||
|
||||
it('should handle negative coordinates', () => {
|
||||
const ply = `ply
|
||||
format ascii 1.0
|
||||
element vertex 1
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
end_header
|
||||
-1.5 -2.5 -3.5`
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
const result = parseASCIIPLY(buffer)
|
||||
|
||||
expect(result).not.toBeNull()
|
||||
expect(result!.positions[0]).toBeCloseTo(-1.5)
|
||||
expect(result!.positions[1]).toBeCloseTo(-2.5)
|
||||
expect(result!.positions[2]).toBeCloseTo(-3.5)
|
||||
})
|
||||
|
||||
it('should handle scientific notation', () => {
|
||||
const ply = `ply
|
||||
format ascii 1.0
|
||||
element vertex 1
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
end_header
|
||||
1.5e-3 2.5e+2 -3.5e1`
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
const result = parseASCIIPLY(buffer)
|
||||
|
||||
expect(result).not.toBeNull()
|
||||
expect(result!.positions[0]).toBeCloseTo(0.0015)
|
||||
expect(result!.positions[1]).toBeCloseTo(250)
|
||||
expect(result!.positions[2]).toBeCloseTo(-35)
|
||||
})
|
||||
|
||||
it('should skip empty lines in vertex data', () => {
|
||||
const ply = `ply
|
||||
format ascii 1.0
|
||||
element vertex 2
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
end_header
|
||||
|
||||
1.0 0.0 0.0
|
||||
|
||||
0.0 1.0 0.0
|
||||
`
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
const result = parseASCIIPLY(buffer)
|
||||
|
||||
expect(result).not.toBeNull()
|
||||
expect(result!.vertexCount).toBe(2)
|
||||
expect(result!.positions[0]).toBeCloseTo(1.0)
|
||||
expect(result!.positions[3]).toBeCloseTo(0.0)
|
||||
expect(result!.positions[4]).toBeCloseTo(1.0)
|
||||
})
|
||||
|
||||
it('should handle whitespace variations', () => {
|
||||
const ply = `ply
|
||||
format ascii 1.0
|
||||
element vertex 1
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
end_header
|
||||
1.0 2.0 3.0 `
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
const result = parseASCIIPLY(buffer)
|
||||
|
||||
expect(result).not.toBeNull()
|
||||
expect(result!.positions[0]).toBeCloseTo(1.0)
|
||||
expect(result!.positions[1]).toBeCloseTo(2.0)
|
||||
expect(result!.positions[2]).toBeCloseTo(3.0)
|
||||
})
|
||||
|
||||
it('should return null for invalid header - missing vertex count', () => {
|
||||
const ply = `ply
|
||||
format ascii 1.0
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
end_header
|
||||
1.0 2.0 3.0`
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
const result = parseASCIIPLY(buffer)
|
||||
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
|
||||
it('should return null for invalid header - missing x property', () => {
|
||||
const ply = `ply
|
||||
format ascii 1.0
|
||||
element vertex 1
|
||||
property float y
|
||||
property float z
|
||||
end_header
|
||||
2.0 3.0`
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
const result = parseASCIIPLY(buffer)
|
||||
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
|
||||
it('should return null for invalid header - missing y property', () => {
|
||||
const ply = `ply
|
||||
format ascii 1.0
|
||||
element vertex 1
|
||||
property float x
|
||||
property float z
|
||||
end_header
|
||||
1.0 3.0`
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
const result = parseASCIIPLY(buffer)
|
||||
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
|
||||
it('should return null for invalid header - missing z property', () => {
|
||||
const ply = `ply
|
||||
format ascii 1.0
|
||||
element vertex 1
|
||||
property float x
|
||||
property float y
|
||||
end_header
|
||||
1.0 2.0`
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
const result = parseASCIIPLY(buffer)
|
||||
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
|
||||
it('should return null for empty buffer', () => {
|
||||
const buffer = new ArrayBuffer(0)
|
||||
const result = parseASCIIPLY(buffer)
|
||||
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
|
||||
it('should handle large vertex count', () => {
|
||||
const vertexCount = 1000
|
||||
let plyContent = `ply
|
||||
format ascii 1.0
|
||||
element vertex ${vertexCount}
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
end_header
|
||||
`
|
||||
for (let i = 0; i < vertexCount; i++) {
|
||||
plyContent += `${i} ${i * 2} ${i * 3}\n`
|
||||
}
|
||||
|
||||
const buffer = createPLYBuffer(plyContent)
|
||||
const result = parseASCIIPLY(buffer)
|
||||
|
||||
expect(result).not.toBeNull()
|
||||
expect(result!.vertexCount).toBe(vertexCount)
|
||||
expect(result!.positions.length).toBe(vertexCount * 3)
|
||||
|
||||
expect(result!.positions[0]).toBeCloseTo(0)
|
||||
expect(result!.positions[1]).toBeCloseTo(0)
|
||||
expect(result!.positions[2]).toBeCloseTo(0)
|
||||
|
||||
const lastIdx = (vertexCount - 1) * 3
|
||||
expect(result!.positions[lastIdx]).toBeCloseTo(vertexCount - 1)
|
||||
expect(result!.positions[lastIdx + 1]).toBeCloseTo((vertexCount - 1) * 2)
|
||||
expect(result!.positions[lastIdx + 2]).toBeCloseTo((vertexCount - 1) * 3)
|
||||
})
|
||||
|
||||
it('should handle partial color properties', () => {
|
||||
const ply = `ply
|
||||
format ascii 1.0
|
||||
element vertex 1
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
property uchar red
|
||||
end_header
|
||||
1.0 2.0 3.0 255`
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
const result = parseASCIIPLY(buffer)
|
||||
|
||||
expect(result).not.toBeNull()
|
||||
// hasColor is true but green/blue indices are -1, so colors won't be parsed
|
||||
expect(result!.positions[0]).toBeCloseTo(1.0)
|
||||
})
|
||||
|
||||
it('should handle double property type', () => {
|
||||
const ply = `ply
|
||||
format ascii 1.0
|
||||
element vertex 1
|
||||
property double x
|
||||
property double y
|
||||
property double z
|
||||
end_header
|
||||
1.123456789 2.987654321 3.111111111`
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
const result = parseASCIIPLY(buffer)
|
||||
|
||||
expect(result).not.toBeNull()
|
||||
expect(result!.positions[0]).toBeCloseTo(1.123456789)
|
||||
expect(result!.positions[1]).toBeCloseTo(2.987654321)
|
||||
expect(result!.positions[2]).toBeCloseTo(3.111111111)
|
||||
})
|
||||
|
||||
it('should stop parsing at vertex count limit', () => {
|
||||
const ply = `ply
|
||||
format ascii 1.0
|
||||
element vertex 2
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
end_header
|
||||
1.0 0.0 0.0
|
||||
0.0 1.0 0.0
|
||||
0.0 0.0 1.0
|
||||
999 999 999`
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
const result = parseASCIIPLY(buffer)
|
||||
|
||||
expect(result).not.toBeNull()
|
||||
expect(result!.vertexCount).toBe(2)
|
||||
expect(result!.positions.length).toBe(6)
|
||||
})
|
||||
|
||||
it('should handle face elements after vertices', () => {
|
||||
const ply = `ply
|
||||
format ascii 1.0
|
||||
element vertex 3
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
element face 1
|
||||
property list uchar int vertex_indices
|
||||
end_header
|
||||
0.0 0.0 0.0
|
||||
1.0 0.0 0.0
|
||||
0.0 1.0 0.0
|
||||
3 0 1 2`
|
||||
|
||||
const buffer = createPLYBuffer(ply)
|
||||
const result = parseASCIIPLY(buffer)
|
||||
|
||||
expect(result).not.toBeNull()
|
||||
expect(result!.vertexCount).toBe(3)
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user