Skip to main content
Glama
readFile.property.test.ts3.47 kB
/** * Property-based tests for read_file tool * Tests file read completeness */ import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import * as fc from 'fast-check'; import fs from 'fs/promises'; import path from 'path'; import os from 'os'; import { executeReadFile } from '../src/tools/readFile.js'; import { ServerConfig } from '../src/config.js'; describe('read_file Tool - Property Tests', () => { let testWorkspace: string; let config: ServerConfig; beforeEach(async () => { // Create a temporary workspace for testing const tempBase = path.join(os.tmpdir(), 'readfile-pbt-' + Date.now()); await fs.mkdir(tempBase, { recursive: true }); testWorkspace = tempBase; config = { workspaceRoot: testWorkspace, allowedCommands: [], readOnly: false, logLevel: 'error', commandTimeout: 300000, }; }); afterEach(async () => { // Clean up temporary workspace try { await fs.rm(testWorkspace, { recursive: true, force: true }); } catch (error) { // Ignore cleanup errors } }); // Generator for valid file names const validFileNameGenerator = () => fc .stringMatching(/^[a-zA-Z0-9_-]+$/) .filter(s => s.length > 0 && s.length <= 20) .map(s => s + '.txt'); // Generator for file content (including various UTF-8 characters) const fileContentGenerator = () => fc.string({ minLength: 0, maxLength: 500 }); /** * Property 4: File read completeness * For any file in the workspace, reading that file should return its complete * content as UTF-8 text along with path, size, and last modified metadata. * * Feature: mcp-workspace-server, Property 4: File read completeness * Validates: Requirements 2.1 */ it('Property 4: should return complete content and correct metadata', async () => { // Generator for file data const fileDataGenerator = fc.record({ fileName: validFileNameGenerator(), content: fileContentGenerator(), }); await fc.assert( fc.asyncProperty(fileDataGenerator, async (fileData) => { // Create the file const filePath = path.join(testWorkspace, fileData.fileName); await fs.writeFile(filePath, fileData.content, 'utf-8'); // Get expected metadata const stats = await fs.stat(filePath); const expectedSize = stats.size; const expectedLastModified = stats.mtime.toISOString(); // Read the file using the tool const result = await executeReadFile({ path: fileData.fileName }, config); // Verify content matches exactly expect(result.content).toBe(fileData.content); // Verify path is correct expect(result.path).toBe(fileData.fileName); // Verify size matches expect(result.size).toBe(expectedSize); // Verify lastModified is defined and is a valid ISO date expect(result.lastModified).toBeDefined(); expect(() => new Date(result.lastModified)).not.toThrow(); // Verify lastModified is close to expected (within 1 second tolerance for filesystem timing) const resultDate = new Date(result.lastModified); const expectedDate = new Date(expectedLastModified); const timeDiff = Math.abs(resultDate.getTime() - expectedDate.getTime()); expect(timeDiff).toBeLessThan(1000); }), { numRuns: 100 } ); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ShayYeffet/mcp_server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server