- Implemented `owl_to_mermaid.py` to convert OWL/Turtle files into Mermaid class diagrams. - Implemented `owl_to_plantuml.py` to convert OWL/Turtle files into PlantUML class diagrams. - Added two new PlantUML files for custodian multi-aspect diagrams.
156 lines
4.8 KiB
TypeScript
156 lines
4.8 KiB
TypeScript
/**
|
|
* Tests for useRdfParser Hook
|
|
*/
|
|
|
|
import { describe, it, expect, beforeEach } from 'vitest';
|
|
import { renderHook, waitFor } from '@testing-library/react';
|
|
import { useRdfParser } from '@/hooks/useRdfParser';
|
|
|
|
describe('useRdfParser', () => {
|
|
it('should initialize with default state', () => {
|
|
const { result } = renderHook(() => useRdfParser());
|
|
|
|
expect(result.current.isLoading).toBe(false);
|
|
expect(result.current.error).toBe(null);
|
|
expect(result.current.graphData).toBe(null);
|
|
expect(typeof result.current.parse).toBe('function');
|
|
});
|
|
|
|
it('should parse N-Triples format', async () => {
|
|
const { result } = renderHook(() => useRdfParser());
|
|
|
|
const ntriples = `
|
|
<http://example.org/subject> <http://example.org/predicate> <http://example.org/object> .
|
|
<http://example.org/subject> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Type> .
|
|
`.trim();
|
|
|
|
let parsePromise: Promise<any>;
|
|
|
|
await waitFor(() => {
|
|
parsePromise = result.current.parse(ntriples, 'application/n-triples');
|
|
});
|
|
|
|
await waitFor(() => {
|
|
expect(result.current.isLoading).toBe(false);
|
|
});
|
|
|
|
expect(result.current.error).toBe(null);
|
|
expect(result.current.graphData).not.toBe(null);
|
|
expect(result.current.graphData?.nodes.length).toBeGreaterThan(0);
|
|
expect(result.current.graphData?.links.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('should parse Turtle format', async () => {
|
|
const { result } = renderHook(() => useRdfParser());
|
|
|
|
const turtle = `
|
|
@prefix ex: <http://example.org/> .
|
|
|
|
ex:subject ex:predicate ex:object .
|
|
ex:subject a ex:Type .
|
|
`.trim();
|
|
|
|
await waitFor(() => {
|
|
result.current.parse(turtle, 'text/turtle');
|
|
});
|
|
|
|
await waitFor(() => {
|
|
expect(result.current.isLoading).toBe(false);
|
|
});
|
|
|
|
expect(result.current.error).toBe(null);
|
|
expect(result.current.graphData).not.toBe(null);
|
|
expect(result.current.graphData?.nodes.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('should handle parsing errors', async () => {
|
|
const { result } = renderHook(() => useRdfParser());
|
|
|
|
// N-Triples parser doesn't throw for invalid data - it just returns empty nodes/links
|
|
// This test verifies it doesn't crash on bad input
|
|
const invalid = 'This is not valid RDF';
|
|
|
|
await result.current.parse(invalid, 'application/n-triples');
|
|
|
|
await waitFor(() => {
|
|
expect(result.current.isLoading).toBe(false);
|
|
});
|
|
|
|
// Empty or minimal data is expected for invalid input
|
|
expect(result.current.graphData).not.toBe(null);
|
|
});
|
|
|
|
it('should handle unsupported format', async () => {
|
|
const { result } = renderHook(() => useRdfParser());
|
|
|
|
await waitFor(async () => {
|
|
try {
|
|
await result.current.parse('test', 'application/rdf+xml' as any);
|
|
} catch (err) {
|
|
expect(err).toBeInstanceOf(Error);
|
|
}
|
|
});
|
|
});
|
|
|
|
it('should update loading state during parsing', async () => {
|
|
const { result } = renderHook(() => useRdfParser());
|
|
|
|
const ntriples = '<http://example.org/s> <http://example.org/p> <http://example.org/o> .';
|
|
|
|
// Parsing is fast, so we just verify it completes
|
|
expect(result.current.isLoading).toBe(false);
|
|
|
|
await result.current.parse(ntriples, 'application/n-triples');
|
|
|
|
// Should finish loading
|
|
await waitFor(() => {
|
|
expect(result.current.isLoading).toBe(false);
|
|
expect(result.current.graphData).not.toBe(null);
|
|
});
|
|
});
|
|
|
|
it('should clear previous error on new parse', async () => {
|
|
const { result } = renderHook(() => useRdfParser());
|
|
|
|
// Parse unsupported format to trigger error
|
|
try {
|
|
await result.current.parse('test', 'application/rdf+xml' as any);
|
|
} catch (err) {
|
|
// Expected - unsupported format throws
|
|
}
|
|
|
|
await waitFor(() => {
|
|
expect(result.current.error).not.toBe(null);
|
|
});
|
|
|
|
// Second parse with valid data should clear error
|
|
const valid = '<http://example.org/s> <http://example.org/p> <http://example.org/o> .';
|
|
await result.current.parse(valid, 'application/n-triples');
|
|
|
|
await waitFor(() => {
|
|
expect(result.current.error).toBe(null);
|
|
expect(result.current.graphData).not.toBe(null);
|
|
});
|
|
});
|
|
|
|
it('should preserve parsed data after parsing', async () => {
|
|
const { result } = renderHook(() => useRdfParser());
|
|
|
|
const ntriples = `
|
|
<http://example.org/subject> <http://example.org/predicate> <http://example.org/object> .
|
|
<http://example.org/subject> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Type> .
|
|
`.trim();
|
|
|
|
await result.current.parse(ntriples, 'application/n-triples');
|
|
|
|
await waitFor(() => {
|
|
expect(result.current.graphData).not.toBe(null);
|
|
});
|
|
|
|
const data = result.current.graphData;
|
|
|
|
// Data should persist across re-renders
|
|
expect(data?.nodes.length).toBeGreaterThan(0);
|
|
expect(data?.links.length).toBeGreaterThan(0);
|
|
});
|
|
});
|