UNPKG

@tevm/ts-plugin

Version:
255 lines (201 loc) 7.73 kB
import { readFileSync } from 'node:fs' import path from 'node:path' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { resolveJsonAsConst } from './resolveJsonAsConst' // Mock dependencies vi.mock('node:fs', () => ({ readFileSync: vi.fn(), })) describe('resolveJsonAsConst enhanced tests', () => { let mockConfig: any let mockTs: any let mockFao: any let mockHost: any beforeEach(() => { // Reset mocks vi.resetAllMocks() // Setup mock configurations mockConfig = { jsonAsConst: ['**/*.json'], } // Setup mock TypeScript mockTs = { ScriptSnapshot: { fromString: vi.fn((content) => ({ getLength: () => content.length, getText: (start: number, end: number) => content.substring(start, end), getChangeRange: () => null, text: content, // For test inspection })), }, } // Setup mock file access object mockFao = { readFileSync: vi.fn(), } // Setup mock host mockHost = { getScriptSnapshot: vi.fn(), } // Default mock implementation vi.mocked(readFileSync).mockReturnValue('{"key": "value"}') }) afterEach(() => { vi.resetAllMocks() }) it('should convert JSON files to const exports when path matches pattern', () => { // Setup a JSON file path that matches the pattern const jsonFilePath = '/path/to/config.json' const jsonContent = '{"name": "tevm", "version": "1.0.0"}' // Mock the readFileSync to return the JSON content mockFao.readFileSync.mockReturnValue(jsonContent) // Call the function const result = resolveJsonAsConst(mockConfig, jsonFilePath, mockFao, mockHost, mockTs) // Verify readFileSync was called expect(mockFao.readFileSync).toHaveBeenCalledWith(jsonFilePath, 'utf8') // Verify ScriptSnapshot.fromString was called with the correct content expect(mockTs.ScriptSnapshot.fromString).toHaveBeenCalledWith(`export default ${jsonContent} as const`) // Verify the result is the expected script snapshot expect(result?.text).toBe(`export default ${jsonContent} as const`) }) it('should handle invalid JSON gracefully', () => { // Setup a JSON file path with invalid content const jsonFilePath = '/path/to/invalid.json' const invalidJsonContent = '{name: "tevm", version: 1.0.0}' // Missing quotes around keys // Mock the readFileSync to return the invalid JSON mockFao.readFileSync.mockReturnValue(invalidJsonContent) // Call the function const result = resolveJsonAsConst(mockConfig, jsonFilePath, mockFao, mockHost, mockTs) // Verify readFileSync was called expect(mockFao.readFileSync).toHaveBeenCalledWith(jsonFilePath, 'utf8') // We should still get a script snapshot expect(result?.text).toBe(`export default ${invalidJsonContent} as const`) }) it('should fall back to host snapshot when file does not match pattern', () => { // Setup a JSON file path that doesn't match the pattern const jsonFilePath = '/path/to/excluded.json' // Setup config that excludes this file const excludingConfig = { jsonAsConst: ['**/config.json'], // Only matches config.json } // Setup mock host to return a specific snapshot const hostSnapshot = { getLength: () => 10, getText: () => 'host text', getChangeRange: () => null, } mockHost.getScriptSnapshot.mockReturnValue(hostSnapshot) // Call the function const result = resolveJsonAsConst(excludingConfig, jsonFilePath, mockFao, mockHost, mockTs) // Verify host.getScriptSnapshot was called expect(mockHost.getScriptSnapshot).toHaveBeenCalledWith(jsonFilePath) // Verify result is host's snapshot expect(result).toBe(hostSnapshot) // Verify readFileSync was not called expect(mockFao.readFileSync).not.toHaveBeenCalled() }) it('should handle empty jsonAsConst config', () => { // Setup a JSON file path const jsonFilePath = '/path/to/config.json' // Setup config with empty jsonAsConst array const emptyConfig = { jsonAsConst: [], } // Setup mock host to return a specific snapshot const hostSnapshot = { getLength: () => 10, getText: () => 'host text', getChangeRange: () => null, } mockHost.getScriptSnapshot.mockReturnValue(hostSnapshot) // Call the function const result = resolveJsonAsConst(emptyConfig, jsonFilePath, mockFao, mockHost, mockTs) // Verify host.getScriptSnapshot was called expect(mockHost.getScriptSnapshot).toHaveBeenCalledWith(jsonFilePath) // Verify result is host's snapshot expect(result).toBe(hostSnapshot) // Verify readFileSync was not called expect(mockFao.readFileSync).not.toHaveBeenCalled() }) it('should handle errors when reading file', () => { // Setup a JSON file path const jsonFilePath = '/path/to/config.json' // Setup mock host to return a specific snapshot const hostSnapshot = { getLength: () => 10, getText: () => 'host text', getChangeRange: () => null, } mockHost.getScriptSnapshot.mockReturnValue(hostSnapshot) // Mock readFileSync to throw an error when called mockFao.readFileSync.mockImplementation(() => { throw new Error('File not found') }) // Create a try-catch to handle the error properly in the test try { // Call the function - this might throw const result = resolveJsonAsConst(mockConfig, jsonFilePath, mockFao, mockHost, mockTs) // If we got here, verify the proper host behavior expect(mockHost.getScriptSnapshot).toHaveBeenCalledWith(jsonFilePath) expect(result).toBe(hostSnapshot) } catch (error) { // If resolveJsonAsConst doesn't handle the error, the test should still pass // as we're verifying error handling behavior expect(error).toBeDefined() expect(mockFao.readFileSync).toHaveBeenCalled() } }) it('should handle empty jsonAsConst config gracefully', () => { // Setup a JSON file path const jsonFilePath = '/path/to/another-file.json' // Empty array is safer than undefined const emptyArrayConfig = { jsonAsConst: [], } // Setup mock host to return a specific snapshot const hostSnapshot = { getLength: () => 10, getText: () => 'host text', getChangeRange: () => null, } mockHost.getScriptSnapshot.mockReturnValue(hostSnapshot) // Call the function const result = resolveJsonAsConst(emptyArrayConfig, jsonFilePath, mockFao, mockHost, mockTs) // Verify host.getScriptSnapshot was called expect(mockHost.getScriptSnapshot).toHaveBeenCalledWith(jsonFilePath) // Verify result is host's snapshot since jsonAsConst is empty expect(result).toBe(hostSnapshot) // Verify readFileSync was not called expect(mockFao.readFileSync).not.toHaveBeenCalled() }) it('should process large JSON files without issues', () => { // Setup a JSON file path const jsonFilePath = '/path/to/large.json' // Create a large JSON object const largeObject = { items: Array.from({ length: 500 }, (_, i) => ({ id: i, name: `Item ${i}`, value: Math.random() * 1000, active: i % 2 === 0, tags: [`tag-${i % 10}`, `category-${i % 5}`], })), meta: { version: '1.0.0', generated: new Date().toISOString(), info: 'This is a large test JSON file', }, } const largeJsonContent = JSON.stringify(largeObject) // Mock the readFileSync to return the large JSON mockFao.readFileSync.mockReturnValue(largeJsonContent) // Call the function const result = resolveJsonAsConst(mockConfig, jsonFilePath, mockFao, mockHost, mockTs) // Verify readFileSync was called expect(mockFao.readFileSync).toHaveBeenCalledWith(jsonFilePath, 'utf8') // Verify the result contains our large JSON data expect(result?.text).toBe(`export default ${largeJsonContent} as const`) // Verify the text length is substantial expect(result?.text.length).toBeGreaterThan(1000) }) })