@snutsjs/core aims to be a robust and extensible static analysis tool designed to identify and report common "smells" or anti-patterns in JavaScript and TypeScript test files. By integrating with your development workflow, it helps maintain high-quality, readable, and effective test suites.
npm install @snutsjs/coreimport { DetectorRunner, detectors } from "@snutsjs/core";
const detectorInstances = Object.values(detectors).map((DetectorClass) => new DetectorClass());
const runner = new DetectorRunner(detectorInstances);
const smells = await runner.run("/absolute/path/to/example.test.ts");
console.log(smells);Use the runtime subpath when you want the side-effectful watcher behavior:
import "@snutsjs/core/runtime/watch";The root package import is side-effect free and safe for VS Code extension integration.
npx @snutsjs/core watch .You can also point to a specific directory:
npx @snutsjs/core watch srcβββ lib/
β βββ ast/ # AST (Abstract Syntax Tree) related services for parsing and querying
β β βββ ast.service.test.ts
β β βββ ast.service.ts
β βββ core/ # Core logic for detector runner and file watching
β β βββ detector.interface.ts
β β βββ detector-runner.test.ts
β β βββ detector-runner.ts
β β βββ watcher.test.ts
β β βββ watcher.ts
β βββ detectors/ # Collection of predefined test smell detectors
β β βββ anonymousTestLogic.ts
β β βββ anonymousTestLogic.test.ts
β β βββ commentsOnlyTestLogic.test.ts
β β βββ commentsOnlyTestLogic.ts
β β βββ conditionalTestLogic.test.ts
β β βββ conditionalTestLogic.ts
β β βββ identicalDescriptionTestLogic.test.ts
β β βββ identicalDescriptionTestLogic.ts
β β βββ index.ts
β β βββ overcommentedTestLogic.test.ts
β β βββ overcommentedTestLogic.ts
β βββ runtime/
β β βββ watch.ts
β βββ shared/ # Shared utilities, constants, and plugins
β β βββ aliases/ # Module aliases configuration
β β β βββ index.ts
β β βββ constants.ts
β β βββ logger/ # Logging utility
β β β βββ index.ts
β β βββ plugins/ # Plugin system for extensibility
β β βββ index.ts
β βββ test/ # Internal testing utilities and builders
β β βββ builders/
β β βββ astNodeBuilder.ts
β βββ index.ts # Main entry point for the library
βββ .gitignore
βββ .prettierignore
βββ .prettierrc.json
βββ eslint.config.js
βββ jest.config.js
βββ LICENSE
βββ package.json
βββ README.md
βββ tsconfig.json
βββ tsconfig.test.json
βββ yarn.lock
This project is licensed under the GPL-3.0 License. See the LICENSE file for details.
- π§ Static Analysis: Identifies anti-patterns in test files using AST parsing.
- π¬ Extensible Detectors: Easily add new test smell detection logic.
- π οΈ Real-time File Watching: Monitors your codebase for changes and re-runs detectors automatically.
- π§ͺ Jest Testing: Integrated testing setup for robust development.
- π‘ TypeScript Support: Built with TypeScript for type safety and improved developer experience.
- π CLI Tool: Command-line interface for easy interaction.
- TypeScript: Primary language for the project.
- @babel/parser: Used for parsing JavaScript/TypeScript code into an AST.
- @babel/types: Utilities for working with Babel AST nodes.
- esquery: Powerful tool for querying ASTs with CSS-like selectors.
- chokidar: File system watcher for real-time monitoring of file changes.
- commander: Node.js command-line interfaces made easy.
- Jest: JavaScript testing framework.
- ts-jest: TypeScript preprocessor for Jest.
To run this project, you will need:
- Node.js (recommended v18+)
- Yarn or npm as package manager
- A code editor (recommendation: Visual Studio Code)
-
Clone this repository to your local machine.
-
Install the project dependencies:
yarn install
-
To start watching your files for smelly tests, run:
yarn start
@snutsjs/corewill automatically watch all files in the selected directory and its subdirectories and report findings.
yarn lint
yarn test
yarn typecheck
yarn build
npm pack --dry-runCreate a changeset:
yarn changesetVersion packages and changelog:
yarn version-packagesPublish to npm:
yarn releaseGitHub Actions workflows are configured to run CI on pull requests and publish through Changesets on merges to main.
Want to contribute? Here's how you can help:
- Create a new branch for your changes:
git checkout -b feature/your-feature-name
- Implement your changes and commit them with a meaningful message (e.g.,
:sparkles: feat: Your message here):git commit -m "feat: Add new detector for unused imports" - Push your branch to the remote repository:
git push origin feature/your-feature-name
- Open a pull request and request a code review.
- Create a new branch:
git checkout -b your-branch-name
- Switch to a branch:
git checkout branch-name
- Commit your changes:
git commit -m "Your commit message" - Push changes to remote:
git push
- Pull updates from remote:
git pull
This project uses path aliases for cleaner imports. Instead of relative paths like ../../../shared/constants, you can use:
// Before
import { MY_CONSTANT } from "../../../shared/constants";
// After
import { MY_CONSTANT } from "@/shared/constants";Path aliases are configured in:
tsconfig.json- For TypeScript resolutionbabel.config.js- For Babel transpilation (if applicable)jest.config.js- For testing with Jest
If VS Code or Jest doesn't recognize path aliases:
- Restart TypeScript server:
Ctrl+Shift+Pβ "TypeScript: Restart TS Server" - Ensure
tsconfig.jsonhas correctbaseUrlandpathsconfigurations. - Run
yarn tsc --noEmitto verify TypeScript configuration.
If the file watcher (chokidar) doesn't seem to be picking up changes:
- Ensure you are running
yarn startfrom the project's root directory. - Check for any system-level file watch limits (e.g.,
fs.inotify.max_user_watcheson Linux) that might be preventingchokidarfrom functioning correctly in large projects.