Grafema Test Backend Usage
Problem
Tests querying the graph return malformed node data:
- •IDs are internal numeric strings instead of human-readable semantic IDs
- •
typefield is undefined (onlynodeTypeis set) - •
metadatais a raw JSON string instead of parsed object - •
originalIdand other metadata fields are missing from node
Context / Trigger Conditions
- •
Test uses
backend.clientto query nodes:javascriptconst graph = backend.client; // WRONG const nodes = await collectNodes(graph.queryNodes({ type: 'net:request' })); - •
Node ID is numeric instead of semantic:
codeExpected: "net:request#__network__" Actual: "52710336597754872375318185843222727675"
- •
node.typeis undefined butnode.nodeTypehas the correct value - •
Using
await graph.queryNodes()expecting an array (it's an async generator)
Solution
Issue 1: Use backend directly, not backend.client
// WRONG - returns unparsed wire format const graph = backend.client; // CORRECT - returns parsed nodes with human-readable IDs const graph = backend;
Why: backend is RFDBServerBackend which has _parseNode() that:
- •Extracts
originalIdfrom metadata and uses it as the node'sid - •Sets both
typeandnodeTypefrom wire format - •Parses and spreads metadata fields onto the node object
backend.client is the raw RFDBClient which returns the wire format without parsing.
Issue 2: Handle async generator properly
// WRONG - queryNodes returns async generator, not Promise<array>
const nodes = await graph.queryNodes({ type: 'net:request' });
nodes.length; // undefined - nodes is an async generator
// CORRECT - collect results into array
async function collectNodes(asyncGen) {
const results = [];
for await (const node of asyncGen) {
results.push(node);
}
return results;
}
const nodes = await collectNodes(graph.queryNodes({ type: 'net:request' }));
nodes.length; // works correctly
Issue 3: Use correct edge query methods
// WRONG - queryEdges doesn't exist
const edges = await graph.queryEdges({ type: 'CALLS', src: nodeId });
// CORRECT - use getOutgoingEdges or getIncomingEdges
const edges = await graph.getOutgoingEdges(nodeId, ['CALLS']);
Verification
After fixing, verify nodes have correct structure:
for await (const node of backend.queryNodes({ type: 'net:request' })) {
console.log('ID:', node.id); // Should be "net:request#__network__"
console.log('type:', node.type); // Should be "net:request"
console.log('nodeType:', node.nodeType); // Should be "net:request"
console.log('originalId:', node.originalId); // Should match id
}
Example
Full test pattern:
import { createTestBackend } from '../helpers/TestRFDB.js';
describe('My Test', () => {
let backend;
beforeEach(async () => {
backend = createTestBackend();
await backend.connect(); // Don't forget this!
});
afterEach(async () => {
if (backend) await backend.close();
});
it('should find nodes correctly', async () => {
// ... setup and analysis ...
// Use backend directly, not backend.client
const graph = backend;
// Collect async generator results
const nodes = [];
for await (const node of graph.queryNodes({ type: 'net:request' })) {
nodes.push(node);
}
// Now nodes is an array with properly parsed nodes
assert.strictEqual(nodes[0].id, 'net:request#__network__');
assert.strictEqual(nodes[0].type, 'net:request');
});
});
Notes
- •
RFDBServerBackend._parseNode()is responsible for the transformation - •The
originalIdis stored in the node'smetadataJSON field in the database - •Both
typeandnodeTypeare set to the same value after parsing - •Edge methods (
getOutgoingEdges,getIncomingEdges) return arrays, not generators - •Always call
backend.connect()inbeforeEach- the backend is not auto-connected