{"version":3,"file":"testing.cjs","names":["SpanStatusCode","otelTrace","context"],"sources":["../src/testing.ts"],"sourcesContent":["/**\n * Testing Utilities\n *\n * Helpers for testing instrumented code and verifying telemetry.\n * Perfect for integration tests and QA in production validation.\n *\n * @example Verify traces are created\n * ```typescript\n * import { assertTraceCreated, collectTraces } from '@your-org/otel-decorators/testing'\n *\n * describe('UserService', () => {\n *   it('should create trace for user creation', async () => {\n *     const collector = collectTraces()\n *\n *     const service = new UserService()\n *     await service.createUser({ email: 'test@example.com' })\n *\n *     assertTraceCreated(collector, 'user.createUser')\n *   })\n * })\n * ```\n */\n\nimport {\n  SpanStatusCode,\n  type SpanStatus,\n  type Attributes,\n  type AttributeValue,\n  context,\n  trace as otelTrace,\n  type Span,\n  type SpanContext,\n  type TimeInput,\n  type Exception,\n  type SpanOptions,\n  type Context as OtelContext,\n  type Tracer,\n} from '@opentelemetry/api';\nimport { type Logger } from './logger';\nimport { configure } from './config';\n\n// Re-export events testing utilities\nexport {\n  createEventCollector,\n  assertEventTracked,\n  assertOutcomeTracked,\n  type EventCollector,\n  type EventData,\n  type EventsFunnelStep,\n  type EventsOutcome,\n  type EventsValue,\n} from './event-testing';\n\n/**\n * Note: OpenTelemetry exporters and processors have moved to dedicated modules\n * for better semantic clarity.\n *\n * For exporters (ConsoleSpanExporter, InMemorySpanExporter):\n * @see {@link autotel/exporters}\n *\n * For processors (SimpleSpanProcessor, BatchSpanProcessor):\n * @see {@link autotel/processors}\n *\n * This module focuses on high-level testing utilities with assertion helpers\n * and trace collectors.\n *\n * @example High-level testing (recommended)\n * ```typescript\n * import { createTraceCollector, assertTraceCreated } from 'autotel/testing'\n *\n * const collector = createTraceCollector()\n * await myService.doSomething()\n * assertTraceCreated(collector, 'myService.doSomething')\n * ```\n *\n * @example Low-level testing (when you need raw OTel spans)\n * ```typescript\n * import { InMemorySpanExporter } from 'autotel/exporters'\n * import { SimpleSpanProcessor } from 'autotel/processors'\n *\n * const exporter = new InMemorySpanExporter()\n * init({ service: 'test', spanProcessor: new SimpleSpanProcessor(exporter) })\n * ```\n */\n\n/**\n * Simplified span representation for testing\n */\nexport interface TestSpan {\n  name: string;\n  status: SpanStatus;\n  attributes: Attributes;\n  startTime: number;\n  endTime: number;\n  duration: number;\n}\n\n/**\n * In-memory trace collector for testing\n */\nexport interface TraceCollector {\n  /** Get all collected spans */\n  getSpans(): TestSpan[];\n  /** Get spans matching a name */\n  getSpansByName(name: string): TestSpan[];\n  /** Get spans matching attributes */\n  getSpansByAttributes(attributes: Record<string, unknown>): TestSpan[];\n  /** Clear all collected spans */\n  clear(): void;\n  /** Record a span (internal use) */\n  recordSpan(span: TestSpan): void;\n}\n\n/**\n * Create an in-memory trace collector for testing\n *\n * IMPORTANT: This automatically configures the global tracer to record spans.\n * Call this in your test's beforeEach() to ensure proper setup.\n *\n * @example\n * ```typescript\n * import { createTraceCollector } from 'autotel/testing'\n *\n * describe('MyService', () => {\n *   let collector: TraceCollector\n *\n *   beforeEach(() => {\n *     collector = createTraceCollector()\n *   })\n *\n *   it('should trace operations', async () => {\n *     await myService.doSomething()\n *\n *     const spans = collector.getSpansByName('myService.doSomething')\n *     expect(spans).toHaveLength(1)\n *   })\n * })\n * ```\n */\nexport function createTraceCollector(): TraceCollector {\n  const spans: TestSpan[] = [];\n\n  // Create mock span that captures data and implements full Span interface\n  const createMockSpan = (name: string, startTime: number): Span => {\n    const spanData: Partial<TestSpan> = {\n      name,\n      startTime,\n      attributes: {},\n      status: { code: SpanStatusCode.OK },\n    };\n\n    const spanContextData: SpanContext = {\n      traceId: '1234567890abcdef1234567890abcdef', // 128-bit trace ID (32 hex chars)\n      spanId: '1234567890abcdef', // 64-bit span ID (16 hex chars)\n      traceFlags: 1,\n      isRemote: false,\n    };\n\n    const mockSpan: Span = {\n      spanContext: () => spanContextData,\n\n      setStatus(status: SpanStatus) {\n        spanData.status = status;\n        return this;\n      },\n\n      setAttributes(attributes: Attributes) {\n        spanData.attributes = { ...spanData.attributes, ...attributes };\n        return this;\n      },\n\n      setAttribute(key: string, value: AttributeValue) {\n        spanData.attributes = spanData.attributes || {};\n        spanData.attributes[key] = value;\n        return this;\n      },\n\n      addEvent(\n        name: string,\n        attributesOrStartTime?: Attributes | TimeInput,\n        startTime?: TimeInput,\n      ) {\n        void name;\n        void attributesOrStartTime;\n        void startTime;\n        return this;\n      },\n\n      addLink(link: { context: SpanContext; attributes?: Attributes }) {\n        void link;\n        return this;\n      },\n\n      addLinks(\n        links: Array<{ context: SpanContext; attributes?: Attributes }>,\n      ) {\n        void links;\n        return this;\n      },\n\n      updateName(newName: string) {\n        spanData.name = newName;\n        return this;\n      },\n\n      isRecording() {\n        return true;\n      },\n\n      recordException(exception: Exception, time?: TimeInput) {\n        void exception;\n        void time;\n      },\n\n      end(endTimeArg?: TimeInput) {\n        void endTimeArg;\n        const endTime = performance.now();\n        spans.push({\n          name: spanData.name!,\n          status: spanData.status!,\n          attributes: spanData.attributes || {},\n          startTime: spanData.startTime!,\n          endTime,\n          duration: endTime - spanData.startTime!,\n        });\n      },\n    };\n\n    return mockSpan;\n  };\n\n  // Create mock tracer\n  const mockTracer: Tracer = {\n    startSpan(name: string, options?: SpanOptions, ctx?: OtelContext): Span {\n      void options;\n      void ctx;\n      const startTime = performance.now();\n      return createMockSpan(name, startTime);\n    },\n\n    startActiveSpan<F extends (span: Span) => unknown>(\n      name: string,\n      optionsOrFn: SpanOptions | F,\n      contextOrFn?: OtelContext | F,\n      fn?: F,\n    ): ReturnType<F> {\n      const callback = (() => {\n        if (typeof optionsOrFn === 'function') {\n          return optionsOrFn;\n        }\n        if (typeof contextOrFn === 'function') {\n          return contextOrFn;\n        }\n        if (fn) {\n          return fn;\n        }\n        throw new Error('startActiveSpan requires a callback');\n      })();\n\n      const startTime = performance.now();\n      const mockSpan = createMockSpan(name, startTime);\n\n      // Set span as active in context (makes otelTrace.getActiveSpan() work)\n      const ctx = otelTrace.setSpan(context.active(), mockSpan);\n      return context.with(ctx, () => callback(mockSpan)) as ReturnType<F>;\n    },\n  };\n\n  // Auto-configure global tracer\n  configure({ tracer: mockTracer });\n\n  return {\n    getSpans(): TestSpan[] {\n      return [...spans];\n    },\n\n    getSpansByName(name: string): TestSpan[] {\n      return spans.filter((span) => span.name === name);\n    },\n\n    getSpansByAttributes(attributes: Record<string, unknown>): TestSpan[] {\n      return spans.filter((span) => {\n        return Object.entries(attributes).every(\n          ([key, value]) => span.attributes[key] === value,\n        );\n      });\n    },\n\n    clear(): void {\n      spans.length = 0;\n    },\n\n    recordSpan(span: TestSpan): void {\n      spans.push(span);\n    },\n  };\n}\n\n/**\n * Assert that a trace was created for an operation\n *\n * @param collector - Trace collector\n * @param operationName - Expected operation name\n * @param options - Optional assertion options\n * @throws Error if trace was not found or doesn't match expectations\n *\n * @example\n * ```typescript\n * assertTraceCreated(collector, 'user.createUser')\n * assertTraceCreated(collector, 'user.createUser', {\n *   minCount: 1,\n *   maxCount: 1,\n *   status: SpanStatusCode.OK,\n *   attributes: { 'user.email': 'test@example.com' }\n * })\n * ```\n */\nexport function assertTraceCreated(\n  collector: TraceCollector,\n  operationName: string,\n  options?: {\n    minCount?: number;\n    maxCount?: number;\n    status?: SpanStatusCode;\n    attributes?: Record<string, unknown>;\n  },\n): void {\n  const spans = collector.getSpansByName(operationName);\n\n  if (options?.minCount !== undefined && spans.length < options.minCount) {\n    throw new Error(\n      `Expected at least ${options.minCount} traces for ${operationName}, got ${spans.length}`,\n    );\n  }\n\n  if (options?.maxCount !== undefined && spans.length > options.maxCount) {\n    throw new Error(\n      `Expected at most ${options.maxCount} traces for ${operationName}, got ${spans.length}`,\n    );\n  }\n\n  if (spans.length === 0) {\n    throw new Error(`No traces found for operation: ${operationName}`);\n  }\n\n  if (options?.status !== undefined) {\n    const matchingSpans = spans.filter(\n      (span) => span.status.code === options.status,\n    );\n    if (matchingSpans.length === 0) {\n      throw new Error(\n        `No traces with status ${options.status} found for ${operationName}`,\n      );\n    }\n  }\n\n  if (options?.attributes) {\n    const matchingSpans = spans.filter((span) => {\n      return Object.entries(options.attributes!).every(\n        ([key, value]) => span.attributes[key] === value,\n      );\n    });\n    if (matchingSpans.length === 0) {\n      throw new Error(\n        `No traces with attributes ${JSON.stringify(options.attributes)} found for ${operationName}`,\n      );\n    }\n  }\n}\n\n/**\n * Assert that no errors were logged\n *\n * Use this in smoke tests to verify critical paths don't have errors.\n *\n * @param collector - Trace collector\n * @throws Error if any error traces are found\n *\n * @example\n * ```typescript\n * // Run critical user flows\n * await runSmokeTests()\n *\n * // Verify no errors occurred\n * assertNoErrors(collector)\n * ```\n */\nexport function assertNoErrors(collector: TraceCollector): void {\n  const errorSpans = collector\n    .getSpans()\n    .filter((span) => span.status.code === SpanStatusCode.ERROR);\n\n  if (errorSpans.length > 0) {\n    const errorSummary = errorSpans\n      .map((span) => `${span.name}: ${span.status.message}`)\n      .join('\\n');\n    throw new Error(`Found ${errorSpans.length} error spans:\\n${errorSummary}`);\n  }\n}\n\n/**\n * Assert that a trace was created and succeeded\n *\n * @param collector - Trace collector\n * @param operationName - Expected operation name\n *\n * @example\n * ```typescript\n * assertTraceSucceeded(collector, 'user.createUser')\n * ```\n */\nexport function assertTraceSucceeded(\n  collector: TraceCollector,\n  operationName: string,\n): void {\n  assertTraceCreated(collector, operationName, { status: SpanStatusCode.OK });\n}\n\n/**\n * Assert that a trace was created and failed\n *\n * @param collector - Trace collector\n * @param operationName - Expected operation name\n * @param errorMessage - Optional expected error message\n *\n * @example\n * ```typescript\n * assertTraceFailed(collector, 'user.createUser', 'Invalid email')\n * ```\n */\nexport function assertTraceFailed(\n  collector: TraceCollector,\n  operationName: string,\n  errorMessage?: string,\n): void {\n  const spans = collector.getSpansByName(operationName);\n\n  if (spans.length === 0) {\n    throw new Error(`No traces found for operation: ${operationName}`);\n  }\n\n  const errorSpans = spans.filter(\n    (span) => span.status.code === SpanStatusCode.ERROR,\n  );\n\n  if (errorSpans.length === 0) {\n    throw new Error(`No error traces found for operation: ${operationName}`);\n  }\n\n  if (errorMessage) {\n    const matchingSpans = errorSpans.filter(\n      (span) => span.status.message === errorMessage,\n    );\n    if (matchingSpans.length === 0) {\n      throw new Error(\n        `No error traces with message \"${errorMessage}\" found for ${operationName}`,\n      );\n    }\n  }\n}\n\n/**\n * In-memory log collector for testing\n */\nexport interface LogCollector {\n  /** Get all collected logs */\n  getLogs(): LogEntry[];\n  /** Get logs by level */\n  getLogsByLevel(level: 'info' | 'warn' | 'error' | 'debug'): LogEntry[];\n  /** Get logs containing a message */\n  getLogsByMessage(message: string): LogEntry[];\n  /** Clear all collected logs */\n  clear(): void;\n}\n\n/**\n * Log entry\n */\nexport interface LogEntry {\n  level: 'info' | 'warn' | 'error' | 'debug';\n  message: string;\n  extra?: Record<string, unknown>;\n  error?: Error;\n}\n\n/**\n * Create an in-memory log collector for testing\n *\n * @example\n * ```typescript\n * const logger = createMockLogger()\n *\n * // Use logger in your code\n * service.log = logger\n * await service.doSomething()\n *\n * // Assert logs were created\n * const logs = logger.getLogs()\n * expect(logs).toHaveLength(2)\n * expect(logs[0].message).toBe('Operation started')\n * ```\n */\nexport function createMockLogger(): Logger & LogCollector {\n  const logs: LogEntry[] = [];\n\n  // Pino-compatible signature: supports both:\n  // - logger.info('message') - string only\n  // - logger.info({ extra }, 'message') - object first with optional message\n  const createLogMethod = (level: 'info' | 'warn' | 'debug') => {\n    return (objOrMsg: Record<string, unknown> | string, msg?: string): void => {\n      if (typeof objOrMsg === 'string') {\n        // String-only call: logger.info('message')\n        logs.push({\n          level,\n          message: objOrMsg,\n          extra: undefined,\n        });\n      } else {\n        // Pino style: logger.info({ extra }, 'message')\n        logs.push({\n          level,\n          message: msg || '',\n          extra: objOrMsg,\n        });\n      }\n    };\n  };\n\n  return {\n    info: createLogMethod('info'),\n    warn: createLogMethod('warn'),\n    debug: createLogMethod('debug'),\n\n    error(objOrMsg: Record<string, unknown> | string, msg?: string): void {\n      if (typeof objOrMsg === 'string') {\n        // String-only call: logger.error('message')\n        logs.push({\n          level: 'error',\n          message: objOrMsg,\n          extra: undefined,\n          error: undefined,\n        });\n        return;\n      }\n\n      // Pino style: logger.error({ err, ...extra }, 'message')\n      // Extract err from extra if present (Pino convention)\n      const { err, ...rest } = objOrMsg as Record<string, unknown> & {\n        err?: unknown;\n      };\n      logs.push({\n        level: 'error',\n        message: msg || '',\n        error: err instanceof Error ? err : undefined,\n        extra:\n          err !== undefined && !(err instanceof Error)\n            ? { err, ...rest }\n            : rest,\n      });\n    },\n\n    getLogs(): LogEntry[] {\n      return [...logs];\n    },\n\n    getLogsByLevel(level: 'info' | 'warn' | 'error' | 'debug'): LogEntry[] {\n      return logs.filter((log) => log.level === level);\n    },\n\n    getLogsByMessage(message: string): LogEntry[] {\n      return logs.filter((log) => log.message.includes(message));\n    },\n\n    clear(): void {\n      logs.length = 0;\n    },\n  };\n}\n\n/**\n * Assert that no error logs were created\n *\n * @param logger - Log collector\n * @throws Error if any error logs are found\n *\n * @example\n * ```typescript\n * assertNoErrorsLogged(logger)\n * ```\n */\nexport function assertNoErrorsLogged(logger: LogCollector): void {\n  const errorLogs = logger.getLogsByLevel('error');\n\n  if (errorLogs.length > 0) {\n    const errorSummary = errorLogs\n      .map(\n        (log) => `${log.message}${log.error ? ': ' + log.error.message : ''}`,\n      )\n      .join('\\n');\n    throw new Error(`Found ${errorLogs.length} error logs:\\n${errorSummary}`);\n  }\n}\n\n/**\n * Wait for a specific trace to be created\n *\n * Useful for async operations where you need to wait for telemetry.\n *\n * @param collector - Trace collector\n * @param operationName - Expected operation name\n * @param timeoutMs - Timeout in milliseconds (default 5000)\n * @returns Promise that resolves when trace is found\n * @throws Error if timeout is reached\n *\n * @example\n * ```typescript\n * // Start async operation\n * const promise = service.doAsyncWork()\n *\n * // Wait for trace\n * await waitForTrace(collector, 'service.doAsyncWork', 1000)\n *\n * // Now you can assert on the trace\n * assertTraceSucceeded(collector, 'service.doAsyncWork')\n * ```\n */\nexport async function waitForTrace(\n  collector: TraceCollector,\n  operationName: string,\n  timeoutMs: number = 5000,\n): Promise<void> {\n  const startTime = Date.now();\n\n  while (Date.now() - startTime < timeoutMs) {\n    const spans = collector.getSpansByName(operationName);\n    if (spans.length > 0) {\n      return;\n    }\n    await new Promise((resolve) => setTimeout(resolve, 10));\n  }\n\n  throw new Error(\n    `Timeout waiting for trace ${operationName} after ${timeoutMs}ms`,\n  );\n}\n\n/**\n * Get trace duration in milliseconds\n *\n * @param collector - Trace collector\n * @param operationName - Operation name\n * @returns Duration in milliseconds, or undefined if trace not found\n *\n * @example\n * ```typescript\n * const duration = getTraceDuration(collector, 'user.createUser')\n * expect(duration).toBeLessThan(1000) // Should be < 1s\n * ```\n */\nexport function getTraceDuration(\n  collector: TraceCollector,\n  operationName: string,\n): number | undefined {\n  const spans = collector.getSpansByName(operationName);\n  if (spans.length === 0) {\n    return undefined;\n  }\n\n  return spans[0]?.duration;\n}\n\n/**\n * Assert that an operation completed within a time threshold\n *\n * Perfect for performance testing and SLO validation.\n *\n * @param collector - Trace collector\n * @param operationName - Operation name\n * @param maxDurationMs - Maximum allowed duration in milliseconds\n * @throws Error if operation took too long\n *\n * @example\n * ```typescript\n * // Verify operation meets SLO\n * await service.createUser({ email: 'test@example.com' })\n * assertTraceDuration(collector, 'user.createUser', 500) // Must be < 500ms\n * ```\n */\nexport function assertTraceDuration(\n  collector: TraceCollector,\n  operationName: string,\n  maxDurationMs: number,\n): void {\n  const duration = getTraceDuration(collector, operationName);\n\n  if (duration === undefined) {\n    throw new Error(`No trace found for operation: ${operationName}`);\n  }\n\n  if (duration > maxDurationMs) {\n    throw new Error(\n      `Operation ${operationName} took ${duration.toFixed(2)}ms, exceeding ${maxDurationMs}ms threshold`,\n    );\n  }\n}\n"],"mappings":"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"}