codeSnippets.json•20.1 kB
{
  "schema": "memory_document_v2",
  "metadata": {
    "id": "1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6p",
    "title": "統合テスト実装コードスニペット",
    "documentType": "code_snippets",
    "path": "codeSnippets.json",
    "tags": [
      "code-snippets",
      "integration-tests",
      "examples"
    ],
    "lastModified": "2025-03-30T16:15:00.000Z",
    "createdAt": "2025-03-30T16:15:00.000Z",
    "version": 1
  },
  "content": {
    "overview": "統合テスト実装で使用するコードスニペットのリファレンスです。これらのコードは、実際の実装時に参照するテンプレートとして使用できます。",
    "snippets": [
      {
        "id": "snippet-1",
        "name": "jest.config.ts",
        "description": "統合テスト用のJest設定ファイル",
        "code": "/** @type {import('jest').Config} */\nexport default {\n  preset: 'ts-jest/presets/default-esm',\n  testEnvironment: 'node',\n  rootDir: '.',\n  testMatch: ['<rootDir>/**/*.integration.test.ts'],\n  transform: {\n    '^.+\\\\.tsx?$': ['ts-jest', {\n      useESM: true,\n      tsconfig: '../../tsconfig.json',\n      isolatedModules: true // Skip type checking for tests\n    }]\n  },\n  moduleNameMapper: {\n    '^(\\\\.{1,2}/.*)\\\\.js$': '$1', // ESM import support\n    '^@memory-bank/schemas(.*)$': '<rootDir>/../../schemas/src$1',\n    '^@/(.*)$': '<rootDir>/../../src/$1',\n    '^fast-json-patch$': '<rootDir>/../../node_modules/fast-json-patch/index.ts'\n  },\n  modulePaths: ['<rootDir>', '<rootDir>/../../src'],\n  moduleDirectories: ['node_modules', 'src'],\n  extensionsToTreatAsEsm: ['.ts'],\n  moduleFileExtensions: ['ts', 'js', 'json'],\n  verbose: true,\n  testTimeout: 60000,\n  maxWorkers: 1,\n  transformIgnorePatterns: [\n    '/node_modules/(?!@modelcontextprotocol/sdk)(?!uuid)(?!fast-json-patch)/'\n  ],\n  // Skip type checking to focus on functionality\n  globals: {\n    'ts-jest': {\n      isolatedModules: true\n    }\n  },\n  // Setup files to run before tests\n  setupFilesAfterEnv: ['<rootDir>/setup.ts']\n};"
      },
      {
        "id": "snippet-2",
        "name": "setup.ts",
        "description": "統合テスト用のセットアップファイル",
        "code": "/**\n * Integration tests setup file\n */\nimport { jest } from '@jest/globals';\nimport 'fs-extra';\n\n// Set longer timeout for integration tests\njest.setTimeout(30000);\n\n// Global Jest configuration\nglobal.jest = jest;\n\n// Suppress console logs during tests\nconst originalConsoleLog = console.log;\nconst originalConsoleError = console.error;\nconst originalConsoleWarn = console.warn;\n\n// Uncomment to silence logging during tests\n/*\nglobal.console.log = (...args) => {\n  // Keep test running output\n  if (args[0] && typeof args[0] === 'string' && args[0].includes('Running test')) {\n    originalConsoleLog(...args);\n  }\n};\nglobal.console.error = (...args) => {\n  // Keep test error output\n  originalConsoleError(...args);\n};\nglobal.console.warn = (...args) => {\n  // Silence warnings\n};\n*/\n\n// Restore console functions after all tests\nafterAll(() => {\n  global.console.log = originalConsoleLog;\n  global.console.error = originalConsoleError;\n  global.console.warn = originalConsoleWarn;\n});"
      },
      {
        "id": "snippet-3",
        "name": "test-env.ts",
        "description": "テスト環境の管理ヘルパー",
        "code": "/**\n * Test environment helpers\n */\nimport * as fs from 'fs-extra';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { v4 as uuid } from 'uuid';\n\n/**\n * Test environment interface\n */\nexport interface TestEnv {\n  docRoot: string;\n  tempDir: string;\n  branchMemoryPath: string;\n  globalMemoryPath: string;\n}\n\n/**\n * Setup test environment\n * Creates temporary directories for test files\n */\nexport async function setupTestEnv(): Promise<TestEnv> {\n  // Create unique temp directory\n  const tempDir = path.join(os.tmpdir(), 'memory-bank-test', uuid());\n  const docRoot = path.join(tempDir, 'docs');\n  const branchMemoryPath = path.join(docRoot, 'branch-memory-bank');\n  const globalMemoryPath = path.join(docRoot, 'global-memory-bank');\n  \n  // Ensure directories exist\n  await fs.ensureDir(docRoot);\n  await fs.ensureDir(branchMemoryPath);\n  await fs.ensureDir(globalMemoryPath);\n  \n  return { \n    docRoot, \n    tempDir,\n    branchMemoryPath,\n    globalMemoryPath\n  };\n}\n\n/**\n * Cleanup test environment\n * Removes temporary directories\n */\nexport async function cleanupTestEnv(env: TestEnv): Promise<void> {\n  try {\n    await fs.remove(env.tempDir);\n  } catch (error) {\n    console.error('Error cleaning up test environment:', error);\n  }\n}\n\n/**\n * Create a branch directory in the test environment\n */\nexport async function createBranchDir(env: TestEnv, branchName: string): Promise<string> {\n  const branchDir = path.join(env.branchMemoryPath, branchName);\n  await fs.ensureDir(branchDir);\n  return branchDir;\n}"
      },
      {
        "id": "snippet-4",
        "name": "fixtures-loader.ts",
        "description": "テストファクスチャの読み込みヘルパー",
        "code": "/**\n * Test fixtures loader\n */\nimport * as fs from 'fs-extra';\nimport * as path from 'path';\n\nconst FIXTURES_ROOT = path.join(__dirname, '../fixtures');\n\n/**\n * Load fixtures for a branch\n * @param branchDir Branch directory path\n * @param fixtureName Fixture name (subdirectory in fixtures/branch-documents/)\n */\nexport async function loadBranchFixture(branchDir: string, fixtureName: string): Promise<void> {\n  const sourceDir = path.join(FIXTURES_ROOT, 'branch-documents', fixtureName);\n  \n  // Check if fixture exists\n  if (!await fs.pathExists(sourceDir)) {\n    throw new Error(`Branch fixture not found: ${fixtureName}`);\n  }\n  \n  // Copy fixture files to branch directory\n  await fs.copy(sourceDir, branchDir);\n}\n\n/**\n * Load fixtures for global memory bank\n * @param globalDir Global memory bank directory path\n * @param fixtureName Fixture name (subdirectory in fixtures/global-documents/)\n */\nexport async function loadGlobalFixture(globalDir: string, fixtureName: string): Promise<void> {\n  const sourceDir = path.join(FIXTURES_ROOT, 'global-documents', fixtureName);\n  \n  // Check if fixture exists\n  if (!await fs.pathExists(sourceDir)) {\n    throw new Error(`Global fixture not found: ${fixtureName}`);\n  }\n  \n  // Copy fixture files to global directory\n  await fs.copy(sourceDir, globalDir);\n}\n\n/**\n * Get fixture JSON content\n * @param fixturePath Path to fixture JSON file, relative to fixtures root\n */\nexport async function getFixtureContent(fixturePath: string): Promise<any> {\n  const fullPath = path.join(FIXTURES_ROOT, fixturePath);\n  \n  // Check if fixture exists\n  if (!await fs.pathExists(fullPath)) {\n    throw new Error(`Fixture not found: ${fixturePath}`);\n  }\n  \n  // Read and parse JSON content\n  const content = await fs.readFile(fullPath, 'utf-8');\n  return JSON.parse(content);\n}"
      },
      {
        "id": "snippet-5",
        "name": "app-factory.ts",
        "description": "テスト用のApplicationインスタンス生成ヘルパー",
        "code": "/**\n * Application factory for tests\n */\nimport { Application } from '../../../src/main/Application.js';\nimport type { Language } from '@memory-bank/schemas';\n\n/**\n * Application factory options\n */\nexport interface AppFactoryOptions {\n  docsRoot: string;\n  language?: Language;\n  verbose?: boolean;\n}\n\n/**\n * Create and initialize an Application instance for testing\n */\nexport async function createTestApplication(options: AppFactoryOptions): Promise<Application> {\n  // Create application instance\n  const app = new Application({\n    docsRoot: options.docsRoot,\n    language: options.language || 'ja',\n    verbose: options.verbose || false\n  });\n  \n  // Initialize application\n  await app.initialize();\n  \n  return app;\n}"
      },
      {
        "id": "snippet-6",
        "name": "ContextController.integration.test.ts",
        "description": "ContextControllerの統合テストサンプル",
        "code": "/**\n * @jest-environment node\n */\nimport { setupTestEnv, cleanupTestEnv, createBranchDir, type TestEnv } from '../helpers/test-env.js';\nimport { loadBranchFixture, loadGlobalFixture } from '../helpers/fixtures-loader.js';\nimport { createTestApplication } from '../helpers/app-factory.js';\nimport { Application } from '../../../src/main/Application.js';\n\ndescribe('ContextController Integration Tests', () => {\n  let testEnv: TestEnv;\n  let app: Application;\n  const TEST_BRANCH = 'feature/test-branch';\n\n  beforeEach(async () => {\n    // Setup test environment\n    testEnv = await setupTestEnv();\n    \n    // Create test branch directory\n    await createBranchDir(testEnv, TEST_BRANCH);\n    \n    // Initialize application\n    app = await createTestApplication({ docsRoot: testEnv.docRoot });\n  });\n\n  afterEach(async () => {\n    // Cleanup test environment\n    await cleanupTestEnv(testEnv);\n  });\n\n  describe('readContext', () => {\n    it('正常系: 空のブランチメモリバンクから読み取りができること', async () => {\n      // No fixtures loaded - empty memory bank\n      \n      // Execute test\n      const controller = app.getContextController();\n      const result = await controller.readContext({\n        branch: TEST_BRANCH,\n        language: 'ja'\n      });\n      \n      // Assert\n      expect(result.success).toBe(true);\n      expect(result.data).toBeDefined();\n      expect(result.data?.branchMemory).toEqual({});\n      expect(result.data?.globalMemory).toEqual({});\n      expect(result.data?.rules).toBeDefined();\n    });\n    \n    it('正常系: ブランチとグローバルメモリバンクの両方から読み取りができること', async () => {\n      // Load fixtures\n      await loadBranchFixture(path.join(testEnv.branchMemoryPath, TEST_BRANCH), 'basic');\n      await loadGlobalFixture(testEnv.globalMemoryPath, 'minimal');\n      \n      // Execute test\n      const controller = app.getContextController();\n      const result = await controller.readContext({\n        branch: TEST_BRANCH,\n        language: 'ja'\n      });\n      \n      // Assert\n      expect(result.success).toBe(true);\n      expect(result.data).toBeDefined();\n      expect(Object.keys(result.data?.branchMemory || {}).length).toBeGreaterThan(0);\n      expect(Object.keys(result.data?.globalMemory || {}).length).toBeGreaterThan(0);\n      expect(result.data?.rules).toBeDefined();\n      \n      // Check specific documents exist\n      expect(result.data?.branchMemory).toHaveProperty('branchContext.json');\n      expect(result.data?.globalMemory).toHaveProperty('core/navigation.json');\n    });\n    \n    it('異常系: 存在しないブランチのアクセスでエラーにならないこと', async () => {\n      // Execute test with non-existent branch\n      const controller = app.getContextController();\n      const result = await controller.readContext({\n        branch: 'non-existent-branch',\n        language: 'ja'\n      });\n      \n      // Should still succeed with empty branch memory\n      expect(result.success).toBe(true);\n      expect(result.data).toBeDefined();\n      expect(result.data?.branchMemory).toEqual({});\n    });\n  });\n  \n  describe('readRules', () => {\n    it('正常系: 日本語のルールを取得できること', async () => {\n      // Execute test\n      const controller = app.getContextController();\n      const result = await controller.readRules('ja');\n      \n      // Assert\n      expect(result.success).toBe(true);\n      expect(result.data).toBeDefined();\n      expect(result.data.language).toBe('ja');\n      expect(result.data.content).toBeDefined();\n    });\n    \n    it('正常系: 英語のルールを取得できること', async () => {\n      // Execute test\n      const controller = app.getContextController();\n      const result = await controller.readRules('en');\n      \n      // Assert\n      expect(result.success).toBe(true);\n      expect(result.data).toBeDefined();\n      expect(result.data.language).toBe('en');\n      expect(result.data.content).toBeDefined();\n    });\n    \n    it('異常系: サポートされていない言語でもエラーにならず空文字を返すこと', async () => {\n      // Execute test with unsupported language\n      const controller = app.getContextController();\n      const result = await controller.readRules('fr' as any);\n      \n      // Should still return success but with empty content\n      expect(result.success).toBe(false);\n      expect(result.error).toContain('RULES_NOT_FOUND');\n    });\n  });\n});"
      },
      {
        "id": "snippet-7",
        "name": "GlobalController.integration.test.ts",
        "description": "GlobalControllerの統合テストサンプル",
        "code": "/**\n * @jest-environment node\n */\nimport { setupTestEnv, cleanupTestEnv, type TestEnv } from '../helpers/test-env.js';\nimport { loadGlobalFixture, getFixtureContent } from '../helpers/fixtures-loader.js';\nimport { createTestApplication } from '../helpers/app-factory.js';\nimport { Application } from '../../../src/main/Application.js';\nimport * as path from 'path';\n\ndescribe('GlobalController Integration Tests', () => {\n  let testEnv: TestEnv;\n  let app: Application;\n\n  beforeEach(async () => {\n    // Setup test environment\n    testEnv = await setupTestEnv();\n    \n    // Initialize application\n    app = await createTestApplication({ docsRoot: testEnv.docRoot });\n  });\n\n  afterEach(async () => {\n    // Cleanup test environment\n    await cleanupTestEnv(testEnv);\n  });\n\n  describe('readDocument', () => {\n    it('正常系: グローバルメモリバンクからドキュメントを読み取れること', async () => {\n      // Load fixtures\n      await loadGlobalFixture(testEnv.globalMemoryPath, 'minimal');\n      \n      // Execute test\n      const controller = app.getGlobalController();\n      const result = await controller.readDocument('core/navigation.json');\n      \n      // Assert\n      expect(result.success).toBe(true);\n      expect(result.data).toBeDefined();\n      expect(typeof result.data).toBe('string');\n      \n      // Validate JSON content\n      const parsed = JSON.parse(result.data);\n      expect(parsed).toHaveProperty('schema');\n      expect(parsed).toHaveProperty('metadata');\n      expect(parsed).toHaveProperty('content');\n    });\n    \n    it('異常系: 存在しないドキュメントの読み取りでエラーが返されること', async () => {\n      // Execute test with non-existent document\n      const controller = app.getGlobalController();\n      const result = await controller.readDocument('non-existent.json');\n      \n      // Assert\n      expect(result.success).toBe(false);\n      expect(result.error).toBeDefined();\n    });\n  });\n  \n  describe('writeDocument', () => {\n    it('正常系: 新規グローバルドキュメントを作成できること', async () => {\n      // Get test fixture content\n      const fixtureContent = await getFixtureContent('samples/new-document.json');\n      \n      // Execute test\n      const controller = app.getGlobalController();\n      const writeResult = await controller.writeDocument({\n        path: 'test/new-document.json',\n        content: JSON.stringify(fixtureContent, null, 2)\n      });\n      \n      // Assert write success\n      expect(writeResult.success).toBe(true);\n      \n      // Verify document exists by reading it back\n      const readResult = await controller.readDocument('test/new-document.json');\n      expect(readResult.success).toBe(true);\n      expect(readResult.data).toBeDefined();\n      \n      // Validate content\n      const parsed = JSON.parse(readResult.data);\n      expect(parsed).toMatchObject(fixtureContent);\n    });\n    \n    it('正常系: 既存グローバルドキュメントを更新できること', async () => {\n      // Load fixtures\n      await loadGlobalFixture(testEnv.globalMemoryPath, 'minimal');\n      \n      // Get updated content from fixture\n      const updatedContent = await getFixtureContent('samples/updated-document.json');\n      \n      // Execute test\n      const controller = app.getGlobalController();\n      const writeResult = await controller.writeDocument({\n        path: 'core/navigation.json',\n        content: JSON.stringify(updatedContent, null, 2)\n      });\n      \n      // Assert write success\n      expect(writeResult.success).toBe(true);\n      \n      // Verify document was updated\n      const readResult = await controller.readDocument('core/navigation.json');\n      expect(readResult.success).toBe(true);\n      \n      // Validate updated content\n      const parsed = JSON.parse(readResult.data);\n      expect(parsed.metadata.version).toBe(updatedContent.metadata.version);\n      expect(parsed.content).toMatchObject(updatedContent.content);\n    });\n    \n    it('異常系: 無効なJSONコンテンツの書き込みでエラーが返されること', async () => {\n      // Invalid JSON content\n      const invalidContent = '{\"schema\": \"memory_document_v2\", \"metadata\": {}';\n      \n      // Execute test\n      const controller = app.getGlobalController();\n      const result = await controller.writeDocument({\n        path: 'test/invalid.json',\n        content: invalidContent\n      });\n      \n      // Assert\n      expect(result.success).toBe(false);\n      expect(result.error).toBeDefined();\n    });\n  });\n});"
      },
      {
        "id": "snippet-8",
        "name": "basic-fixture",
        "description": "ブランチメモリバンクの基本テストファクスチャ例",
        "code": "// fixtures/branch-documents/basic/branchContext.json\n{\n  \"schema\": \"memory_document_v2\",\n  \"metadata\": {\n    \"id\": \"test-branch-context\",\n    \"title\": \"テストブランチコンテキスト\",\n    \"documentType\": \"branch_context\",\n    \"path\": \"branchContext.json\",\n    \"tags\": [\"branch-context\", \"test\"],\n    \"lastModified\": \"2025-03-30T00:00:00.000Z\",\n    \"createdAt\": \"2025-03-30T00:00:00.000Z\",\n    \"version\": 1\n  },\n  \"content\": {\n    \"branchName\": \"feature/test-branch\",\n    \"purpose\": \"テスト用のブランチ\",\n    \"createdAt\": \"2025-03-30T00:00:00.000Z\",\n    \"userStories\": [\n      {\n        \"id\": \"test-story-1\",\n        \"description\": \"テストユーザーストーリー1\",\n        \"completed\": false,\n        \"priority\": 1\n      }\n    ],\n    \"additionalNotes\": \"テスト用のブランチコンテキストです\"\n  }\n}\n\n// fixtures/branch-documents/basic/activeContext.json\n{\n  \"schema\": \"memory_document_v2\",\n  \"metadata\": {\n    \"id\": \"test-active-context\",\n    \"title\": \"テストアクティブコンテキスト\",\n    \"documentType\": \"active_context\",\n    \"path\": \"activeContext.json\",\n    \"tags\": [\"active-context\", \"test\"],\n    \"lastModified\": \"2025-03-30T00:00:00.000Z\",\n    \"createdAt\": \"2025-03-30T00:00:00.000Z\",\n    \"version\": 1\n  },\n  \"content\": {\n    \"currentWork\": \"テスト作業\",\n    \"recentChanges\": [\n      {\n        \"date\": \"2025-03-30T00:00:00.000Z\",\n        \"description\": \"テスト変更\"\n      }\n    ],\n    \"activeDecisions\": [\n      {\n        \"id\": \"test-decision\",\n        \"description\": \"テスト決定事項\"\n      }\n    ],\n    \"considerations\": [\n      {\n        \"id\": \"test-consideration\",\n        \"description\": \"テスト検討事項\",\n        \"status\": \"open\"\n      }\n    ],\n    \"nextSteps\": [\n      {\n        \"id\": \"test-step\",\n        \"description\": \"テスト次のステップ\",\n        \"priority\": \"high\"\n      }\n    ]\n  }\n}"
      }
    ]
  }
}