Spaces:
Running
Running
| /** | |
| * Unit tests for OpsetChecker.compute() | |
| * Validates: Requirements 22.1, 22.2, 22.3, 22.4, 22.5 | |
| */ | |
| import { describe, it, expect } from 'vitest'; | |
| const STANDARD_OPSETS = [7, 9, 11, 13, 15, 17, 18, 19, 20, 21]; | |
| /** | |
| * Mirror the pure compute logic from OpsetChecker for testability. | |
| */ | |
| function computeOpsetData(parsedModel) { | |
| const modelOpset = (parsedModel && parsedModel.metadata && parsedModel.metadata.opsetVersion) || 0; | |
| const compatibility = STANDARD_OPSETS.map((version) => ({ | |
| version, | |
| compatible: version >= modelOpset, | |
| })); | |
| const opsetImport = (parsedModel && parsedModel.metadata && Array.isArray(parsedModel.metadata.opsetImport)) | |
| ? parsedModel.metadata.opsetImport | |
| : []; | |
| const domains = opsetImport.map((op) => ({ | |
| domain: op.domain || 'ai.onnx (default)', | |
| version: op.version || 0, | |
| })); | |
| const nodes = (parsedModel && parsedModel.graph && parsedModel.graph.nodes) || []; | |
| const customOperators = []; | |
| const seen = new Set(); | |
| for (const node of nodes) { | |
| if (node.domain && node.domain !== '' && node.domain !== 'ai.onnx') { | |
| const key = `${node.domain}::${node.opType}`; | |
| if (!seen.has(key)) { | |
| seen.add(key); | |
| customOperators.push({ name: node.opType || 'Unknown', domain: node.domain }); | |
| } | |
| } | |
| } | |
| const allStandard = customOperators.length === 0; | |
| return { modelOpset, compatibility, domains, customOperators, allStandard }; | |
| } | |
| describe('OpsetChecker.compute', () => { | |
| it('should return the model opset version (Req 22.1)', () => { | |
| const model = { | |
| metadata: { opsetVersion: 13 }, | |
| graph: { nodes: [] }, | |
| }; | |
| const result = computeOpsetData(model); | |
| expect(result.modelOpset).toBe(13); | |
| }); | |
| it('should mark standard versions >= model opset as compatible (Req 22.2)', () => { | |
| const model = { | |
| metadata: { opsetVersion: 13 }, | |
| graph: { nodes: [] }, | |
| }; | |
| const result = computeOpsetData(model); | |
| for (const entry of result.compatibility) { | |
| if (entry.version >= 13) { | |
| expect(entry.compatible).toBe(true); | |
| } else { | |
| expect(entry.compatible).toBe(false); | |
| } | |
| } | |
| }); | |
| it('should mark all versions compatible when model opset is very low', () => { | |
| const model = { | |
| metadata: { opsetVersion: 1 }, | |
| graph: { nodes: [] }, | |
| }; | |
| const result = computeOpsetData(model); | |
| expect(result.compatibility.every((e) => e.compatible)).toBe(true); | |
| }); | |
| it('should mark most versions incompatible when model opset is very high', () => { | |
| const model = { | |
| metadata: { opsetVersion: 21 }, | |
| graph: { nodes: [] }, | |
| }; | |
| const result = computeOpsetData(model); | |
| const compatibleVersions = result.compatibility.filter((e) => e.compatible); | |
| expect(compatibleVersions.length).toBe(1); | |
| expect(compatibleVersions[0].version).toBe(21); | |
| }); | |
| it('should display all domains from opset_import (Req 22.3)', () => { | |
| const model = { | |
| metadata: { | |
| opsetVersion: 13, | |
| opsetImport: [ | |
| { domain: '', version: 13 }, | |
| { domain: 'ai.onnx.ml', version: 2 }, | |
| ], | |
| }, | |
| graph: { nodes: [] }, | |
| }; | |
| const result = computeOpsetData(model); | |
| expect(result.domains).toHaveLength(2); | |
| expect(result.domains[0].domain).toBe('ai.onnx (default)'); | |
| expect(result.domains[0].version).toBe(13); | |
| expect(result.domains[1].domain).toBe('ai.onnx.ml'); | |
| expect(result.domains[1].version).toBe(2); | |
| }); | |
| it('should list custom domain operators (Req 22.4)', () => { | |
| const model = { | |
| metadata: { opsetVersion: 13 }, | |
| graph: { | |
| nodes: [ | |
| { opType: 'Conv', domain: '' }, | |
| { opType: 'Relu', domain: '' }, | |
| { opType: 'CustomOp', domain: 'com.mycompany' }, | |
| { opType: 'AnotherOp', domain: 'com.mycompany' }, | |
| ], | |
| }, | |
| }; | |
| const result = computeOpsetData(model); | |
| expect(result.allStandard).toBe(false); | |
| expect(result.customOperators).toHaveLength(2); | |
| expect(result.customOperators[0]).toEqual({ name: 'CustomOp', domain: 'com.mycompany' }); | |
| expect(result.customOperators[1]).toEqual({ name: 'AnotherOp', domain: 'com.mycompany' }); | |
| }); | |
| it('should deduplicate custom operators with same domain and opType', () => { | |
| const model = { | |
| metadata: { opsetVersion: 13 }, | |
| graph: { | |
| nodes: [ | |
| { opType: 'CustomOp', domain: 'com.mycompany' }, | |
| { opType: 'CustomOp', domain: 'com.mycompany' }, | |
| { opType: 'CustomOp', domain: 'com.mycompany' }, | |
| ], | |
| }, | |
| }; | |
| const result = computeOpsetData(model); | |
| expect(result.customOperators).toHaveLength(1); | |
| }); | |
| it('should report allStandard=true when all operators are from default domain (Req 22.5)', () => { | |
| const model = { | |
| metadata: { opsetVersion: 13 }, | |
| graph: { | |
| nodes: [ | |
| { opType: 'Conv', domain: '' }, | |
| { opType: 'Relu', domain: '' }, | |
| { opType: 'Add', domain: '' }, | |
| ], | |
| }, | |
| }; | |
| const result = computeOpsetData(model); | |
| expect(result.allStandard).toBe(true); | |
| expect(result.customOperators).toHaveLength(0); | |
| }); | |
| it('should handle null/undefined model gracefully', () => { | |
| const result = computeOpsetData(null); | |
| expect(result.modelOpset).toBe(0); | |
| expect(result.compatibility.length).toBe(STANDARD_OPSETS.length); | |
| expect(result.domains).toHaveLength(0); | |
| expect(result.customOperators).toHaveLength(0); | |
| expect(result.allStandard).toBe(true); | |
| }); | |
| it('should handle model with no opsetImport', () => { | |
| const model = { | |
| metadata: { opsetVersion: 11 }, | |
| graph: { nodes: [] }, | |
| }; | |
| const result = computeOpsetData(model); | |
| expect(result.domains).toHaveLength(0); | |
| }); | |
| it('should treat ai.onnx domain nodes as standard', () => { | |
| const model = { | |
| metadata: { opsetVersion: 13 }, | |
| graph: { | |
| nodes: [ | |
| { opType: 'Conv', domain: 'ai.onnx' }, | |
| { opType: 'Relu', domain: '' }, | |
| ], | |
| }, | |
| }; | |
| const result = computeOpsetData(model); | |
| expect(result.allStandard).toBe(true); | |
| }); | |
| }); | |