This guide shows you how to safely refactor code by writing tests first.
Note: All initial refactoring tasks from CODEBASE-ISSUES.md have been completed. Use this workflow for future refactoring work.
Example files that were refactored (now complete):
- ✅
src/lib/feature-flags.ts(Completed) - ✅
src/hooks/useStockData.ts(Completed) - ✅
src/lib/supabase/realtime-service.ts(Completed)
# For feature-flags.ts
touch src/lib/__tests__/feature-flags.refactor.test.ts
# For useStockData.ts
touch src/hooks/__tests__/useStockData.refactor.test.tsxImportant: Write tests that capture how the code works NOW, not how you want it to work.
Example:
// Test current behavior (returns boolean)
it('should return false when client unavailable', async () => {
const result = await checkFeatureFlag('test');
expect(result).toBe(false); // Current: boolean
});npm test -- src/lib/__tests__/feature-flags.refactor.test.ts✅ All tests should pass with current code.
Now refactor to use Result/Option types:
// Before: return boolean
export async function checkFeatureFlag(flagName: string): Promise<boolean> {
// ...
}
// After: return Result
export async function checkFeatureFlag(flagName: string): Promise<Result<boolean, Error>> {
// ...
}// Update test to use Result assertions
it('should return Ok(false) when client unavailable', async () => {
const result = await checkFeatureFlag('test');
expect(result.isOk()).toBe(true);
if (result.isOk()) {
expect(result.value).toBe(false);
}
});npm test -- src/lib/__tests__/feature-flags.refactor.test.ts✅ All tests should pass with refactored code.
npm test✅ No regressions in other tests.
npm run devVisit the app and manually verify the feature still works.
git add .
git commit -m "refactor(feature-flags): convert to Result types
- Convert checkFeatureFlag to return Result<boolean, Error>
- Add comprehensive tests
- Maintain backward compatibility"# 1. Create test file
touch src/lib/__tests__/feature-flags.refactor.test.ts
# 2. See testing-refactoring.mdc cursor rule for test examples
# (or use the provided example test file)
# 3. Run tests - should pass
npm test -- src/lib/__tests__/feature-flags.refactor.test.ts
# 4. Refactor feature-flags.ts
# (Edit the file to use Result types)
# 5. Update tests to use Result assertions
# (Edit the test file)
# 6. Run tests - should still pass
npm test -- src/lib/__tests__/feature-flags.refactor.test.ts
# 7. Run full suite
npm test
# 8. Check coverage
npm run test:coverage
# 9. Manual test
npm run dev
# Visit page that uses feature flags
# 10. Commit
git add .
git commit -m "refactor: convert feature-flags to Result types"# Run all tests
npm test
# Run specific test file
npm test -- src/lib/__tests__/feature-flags.refactor.test.ts
# Run tests in watch mode (auto-rerun on changes)
npm run test:watch
# Run with coverage
npm run test:coverage
# Run E2E tests
npm run test:e2e- Check the error message - What specifically failed?
- Compare before/after - Did behavior change unintentionally?
- Check mocks - Are mocks set up correctly?
- Verify imports - Are Result/Option types imported?
- Check integration - Are all call sites updated?
- Type checking - Run
npm run typecheck - Manual testing - Test in browser
- Check console - Any runtime errors?
- Start simple - Test one function at a time
- Use examples - Copy from provided test files
- Mock dependencies - Mock Supabase, contexts, etc.
- Ask for help - Review with team
- ✅ One file at a time - Don't refactor multiple files simultaneously
- ✅ Small changes - Make incremental improvements
- ✅ Test first - Write tests before refactoring
- ✅ Run tests often - After each small change
- ✅ Keep tests passing - Never commit failing tests
- ✅ Update call sites - Update all places that use refactored code
- ✅ Type check - Run
npm run typecheckbefore committing
Note: All initial refactoring tasks are complete. Use this workflow for future refactoring work.
- Identify files that need refactoring
- Start with simpler files first
- Follow the workflow above
- Move to next file when current one is complete