finding-seams

Identifies substitution points in tightly-coupled TypeScript code to make legacy dependencies testable.

Updated May 18, 2024
One-click install
npx skills add https://github.com/joshhornby/dotfiles --skill finding-seams-joshhornby
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: finding-seams
Source: https://github.com/joshhornby/dotfiles/tree/main/.claude/skills/finding-seams
Command: npx skills add https://github.com/joshhornby/dotfiles --skill finding-seams-joshhornby

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes references (resource) components.

What problem does it solve? Legacy or tightly-coupled code often cannot be tested because functions directly construct collaborators, call static or global functions, or reach external systems without any substitution point. This Skill guides you to find and introduce seams — places where behavior can be altered without editing the call site — so existing behavior can be placed under test. ## Core Features & Use Cases - Seam Identification: Locates existing seams in function parameters, default values, module imports, configuration, React props/context, and hard-coded dependencies. - FP-First Seam Creation: Provides TypeScript techniques including parameter injection with production defaults, higher-order function factories, narrow type extraction, and wrapping global calls like Date.now() or process.env. - Legacy OOP Patterns: Covers extract-and-override and constructor injection for class-based code, with a migration path toward functional parameter injection. - Use Case: You need to test a scheduleDelivery function that calls an external transit API directly. The Skill shows how to add a resolveTransitDays parameter with a production default, letting tests pass a fake while production call sites stay unchanged. ## Quick Start Ask the assistant to find seams in a tightly-coupled TypeScript function so it can be tested without hitting its real external dependencies.

Frequently Asked Questions about finding-seams

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I make legacy TypeScript code testable without rewriting it?

Introduce a seam by adding the hidden dependency as a function parameter with a production default. Tests pass a fake at the argument list while production call sites remain unchanged, so no call-site edits are required.

What is a seam in legacy code testing?

A seam is a place where you can alter program behavior without editing that place, from Michael Feathers' Working Effectively with Legacy Code. Every seam has an enabling point, such as an argument list, where you choose which behavior to activate.

Should I use vi.mock or dependency injection for testing?

Prefer function parameter injection because it is explicit and type-safe. Use vi.mock only as temporary scaffolding when you cannot change the signature yet, since module mocks bypass TypeScript's type system and require cleanup between tests.

How do I test functions that call Date.now or process.env?

Wrap the global call in a default parameter, such as `(now = Date.now)` or `(getEnv = () => process.env.X)`. Tests then pass a fixed fake while production uses the real global through the default.

When should I not create a seam in my code?

Skip seams for pure utility functions, same-module functions without external effects, and fast deterministic standard library operations. Create seams only for dependencies that reach outside the process, are slow or non-deterministic, or cross bounded contexts.

How do I handle class-based legacy code that constructs its own dependencies?

Use extract-and-override to pull the problematic call into a protected method overridden in a test subclass, or parameterize the constructor to accept the dependency. Migrate toward function parameter injection once tests are in place.