agentsclimarketplace

Code test

Skill jjmendezrodriguez/jm-claude-plugin/skills/code-test

Testing guide for Vitest, React Testing Library, and Supabase mocks. Use this when writing unit or integration tests, setting up test infrastructure, mocking Supabase, testing hooks/components, or deciding what to test first. Trigger on: "add tests", "how do I test this?", "mock supabase", any new feature/hook/service.From its SKILL.md

Install
npx -y skills add jjmendezrodriguez/jm-claude-plugin --skill code-test

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

5.6 KB, as published. Nobody here has run it

Testing — Vitest / React Testing Library

Staff Engineer standard: tests prove behavior, not implementation.


1. Testing Priority (highest ROI first)

1. Utils & validators (pure functions — easiest, highest value)
2. Zod schemas (safeParse edge cases)
3. Service functions (business logic)
4. Custom hooks (useAuth, useForm)
5. Components (user interactions)
6. API integrations (Supabase queries)

2. Test Structure

tests/
├── unit/
│   ├── utils/
│   │   └── validators.test.ts
│   └── services/
│       └── auth.test.ts
├── integration/
│   └── api/
│       └── users.test.ts
└── e2e/                    → See e2etesting skill
    └── specs/

3. Vitest Best Practices

import { describe, it, expect, vi, beforeEach } from "vitest";
import { validateEmail } from "@/utils/validators";

// ✅ GOOD — descriptive names, one assertion per test, AAA pattern
describe("validateEmail", () => {
  it("returns true for valid email format", () => {
    expect(validateEmail("[email protected]")).toBe(true);
  });

  it("returns false when missing @ symbol", () => {
    expect(validateEmail("invalid-email")).toBe(false);
  });

  it("returns false for empty string", () => {
    expect(validateEmail("")).toBe(false);
  });
});

// ❌ BAD — vague name, multiple assertions, no structure
it("email test", () => {
  expect(validateEmail("[email protected]")).toBe(true);
  expect(validateEmail("bad")).toBe(false);
  expect(validateEmail("")).toBe(false);
});

4. Testing React Components

import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { LoginForm } from "@/components/LoginForm";

describe("LoginForm", () => {
  const mockOnSubmit = vi.fn();

  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("submits with email and password", async () => {
    const user = userEvent.setup();
    render(<LoginForm onSubmit={mockOnSubmit} />);

    await user.type(screen.getByLabelText(/email/i), "[email protected]");
    await user.type(screen.getByLabelText(/password/i), "securePass123");
    await user.click(screen.getByRole("button", { name: /sign in/i }));

    expect(mockOnSubmit).toHaveBeenCalledWith({
      email: "[email protected]",
      password: "securePass123",
    });
  });

  it("shows error when fields are empty", async () => {
    const user = userEvent.setup();
    render(<LoginForm onSubmit={mockOnSubmit} />);

    await user.click(screen.getByRole("button", { name: /sign in/i }));

    expect(screen.getByText(/email is required/i)).toBeInTheDocument();
    expect(mockOnSubmit).not.toHaveBeenCalled();
  });
});

Query priority (Testing Library):

1. getByRole      → accessible, resilient
2. getByLabelText → form elements
3. getByText      → static content
4. getByTestId    → last resort (data-testid)

5. Mocking Supabase

// tests/mocks/supabase.ts
import { vi } from "vitest";

export const mockSupabase = {
  from: vi.fn().mockReturnThis(),
  select: vi.fn().mockReturnThis(),
  insert: vi.fn().mockReturnThis(),
  update: vi.fn().mockReturnThis(),
  delete: vi.fn().mockReturnThis(),
  eq: vi.fn().mockReturnThis(),
  single: vi.fn(),
  auth: {
    signInWithPassword: vi.fn(),
    signUp: vi.fn(),
    signOut: vi.fn(),
    getSession: vi.fn(),
    onAuthStateChange: vi.fn(() => ({
      data: { subscription: { unsubscribe: vi.fn() } },
    })),
  },
};

vi.mock("@/lib/supabase", () => ({
  supabase: mockSupabase,
}));

// Usage in test
import { mockSupabase } from "../mocks/supabase";

it("fetches user by id", async () => {
  mockSupabase.single.mockResolvedValueOnce({
    data: { id: "1", email: "[email protected]" },
    error: null,
  });

  const user = await getUser("1");
  expect(user.email).toBe("[email protected]");
});

6. Testing Custom Hooks

import { renderHook, act } from "@testing-library/react";
import { useCounter } from "@/hooks/useCounter";

it("increments counter", () => {
  const { result } = renderHook(() => useCounter(0));

  act(() => result.current.increment());

  expect(result.current.count).toBe(1);
});

7. Rules

✅ DO:
- Mock external services (Supabase, APIs, PostHog)
- Test behavior, not implementation details
- Keep tests independent (no shared state)
- Aim for 70%+ coverage on critical paths
- Use vi.clearAllMocks() in beforeEach

❌ DON'T:
- Test implementation details (internal state, private methods)
- Share state between tests
- Use production data
- Test third-party library behavior
- Snapshot test everything (snapshots are brittle)

8. Deep-Dive References (Vitest API)

references/ contains the full Vitest 3.x API reference library — 16 files covering: mocking, coverage, snapshot testing, browser mode, workspace config, CLI flags, TypeScript integration, watch mode, and migration from Jest.


9. Quick Checklist

[ ] Tests follow AAA pattern (Arrange, Act, Assert)
[ ] Descriptive test names explain the behavior
[ ] Supabase/external services properly mocked
[ ] No shared state between tests
[ ] Critical paths have tests (auth, payments, data mutations)
[ ] All tests pass: pnpm test

Keep looking

Skills are one crate of 626,474. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.