test: add unit tests for TechStackDetector module#503
test: add unit tests for TechStackDetector module#503nikolasdehor wants to merge 3 commits intoSynkraAI:mainfrom
Conversation
84 tests covering: - Constructor and package.json caching - Empty profile structure validation - Database detection (Supabase, Prisma, pg, MongoDB, MySQL, SQLite) - RLS detection in SQL migrations - Environment variable detection - Frontend detection (React, Vue, Angular, Svelte, Next, Nuxt) - Build tool detection (Vite, Webpack, esbuild, Parcel) - Styling detection (Tailwind, styled-components, Emotion, SCSS) - Component library detection (shadcn, MUI, Chakra, Ant Design) - Backend detection (Express, Fastify, NestJS, Hono, Edge Functions) - API route detection (api/, pages/api/, app/api/) - TypeScript and test framework detection - Applicable phase computation - Confidence score calculation with cap at 100 - Static getSummary with all combinations - Full integration test (empty project + full-stack project)
|
@nikolasdehor is attempting to deploy a commit to the Pedro Valério Lopez's projects Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughAdds a comprehensive unit test suite for the TechStackDetector module, covering constructor/state, package.json loading/caching, dependency- and filesystem-based detection for database/frontend/backend, TypeScript/tests detection, phase computation, confidence scoring, and end-to-end detection flows (including timestamp validation). Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Suggested labels
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Adds a comprehensive Jest unit test suite for the TechStackDetector orchestration module, aiming to validate deterministic stack detection behavior via fully mocked filesystem operations.
Changes:
- Adds 84 unit tests covering database/frontend/backend/TypeScript/tests detection, applicable phases, confidence scoring, summary formatting, and end-to-end
detect()behavior. - Introduces a full
fs-extramock strategy to keep tests deterministic (no real I/O).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const fs = require('fs-extra'); | ||
| const TechStackDetector = require('../../../.aios-core/core/orchestration/tech-stack-detector'); | ||
|
|
||
| // Mock fs-extra | ||
| jest.mock('fs-extra'); | ||
|
|
There was a problem hiding this comment.
jest.mock('fs-extra') is declared after require('fs-extra') and after importing TechStackDetector. With this repo’s Jest setup (no transform/hoisting configured in jest.config.js), the module under test will likely keep a reference to the real fs-extra, and fs.pathExists.mockResolvedValue(...) will throw because pathExists won’t be a Jest mock. Move the jest.mock('fs-extra') call above all require(...) statements that import fs-extra directly or indirectly (i.e., before requiring TechStackDetector).
| const fs = require('fs-extra'); | |
| const TechStackDetector = require('../../../.aios-core/core/orchestration/tech-stack-detector'); | |
| // Mock fs-extra | |
| jest.mock('fs-extra'); | |
| // Mock fs-extra | |
| jest.mock('fs-extra'); | |
| const fs = require('fs-extra'); | |
| const TechStackDetector = require('../../../.aios-core/core/orchestration/tech-stack-detector'); |
| /** | ||
| * Testes unitários para o módulo tech-stack-detector | ||
| * | ||
| * Testa a classe TechStackDetector que detecta a stack tecnológica | ||
| * do projeto de forma determinística usando operações de filesystem. | ||
| */ |
There was a problem hiding this comment.
PR description mentions improving coverage for .aios-core/core/orchestration/tech-stack-detector.js, but Jest coverage collection currently excludes .aios-core/core/orchestration/** (jest.config.js collectCoverageFrom). These tests will run, but they won’t change the reported coverage numbers unless that exclusion is adjusted.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
tests/core/orchestration/tech-stack-detector.test.js (1)
166-172: Consolidate repeated dependency mock setup helper
setupDepsis duplicated across threedescribeblocks. Consider extracting a single helper (or factory) to reduce drift and make future test updates safer.Also applies to: 343-349, 503-509
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/core/orchestration/tech-stack-detector.test.js` around lines 166 - 172, The test file repeats the setupDeps helper in multiple describe blocks; extract a single shared helper (e.g., a top-level setupDepsFactory or setupDeps function) and replace the duplicated implementations in the three describe blocks with calls to that single helper. Move the helper near the top of the test file (before any describe blocks) and have it encapsulate the fs.pathExists.mockImplementation and fs.readJson.mockResolvedValue logic (checking path.join(PROJECT_ROOT, 'package.json') and returning the provided deps), then update each test block to call the shared setupDeps instead of redefining it.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@tests/core/orchestration/tech-stack-detector.test.js`:
- Line 335: The test is using an invalid Jest matcher chain on
detector._detectDatabase(profile): `.resolves.not.toThrow()` is wrong because
`.resolves` unwraps the fulfilled value (undefined) and `.toThrow()` expects a
function; change the assertion to assert the resolved value instead — replace
the matcher with `.resolves.toBeUndefined()` (or alternatively assert the
promise resolves without rejecting via `.resolves.not.toBeDefined()` if you
prefer) to correctly verify the promise fulfills without throwing.
---
Nitpick comments:
In `@tests/core/orchestration/tech-stack-detector.test.js`:
- Around line 166-172: The test file repeats the setupDeps helper in multiple
describe blocks; extract a single shared helper (e.g., a top-level
setupDepsFactory or setupDeps function) and replace the duplicated
implementations in the three describe blocks with calls to that single helper.
Move the helper near the top of the test file (before any describe blocks) and
have it encapsulate the fs.pathExists.mockImplementation and
fs.readJson.mockResolvedValue logic (checking path.join(PROJECT_ROOT,
'package.json') and returning the provided deps), then update each test block to
call the shared setupDeps instead of redefining it.
- Extrai setupDeps para nível superior do describe (evita duplicação)
- Move jest.mock('fs-extra') antes dos requires por clareza
- Troca .resolves.not.toThrow() por .resolves.toBeUndefined()
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
tests/core/orchestration/tech-stack-detector.test.js (1)
345-566: Add explicit failure-path tests for frontend/backend filesystem calls.Happy path coverage is strong, but there is no explicit assertion that
_detectFrontendand_detectBackendtoleratefserrors (similar to the DB migration error-path test). Adding those tests will harden reliability expectations.As per coding guidelines, "Verify error handling is comprehensive."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/core/orchestration/tech-stack-detector.test.js` around lines 345 - 566, Add negative-path unit tests that simulate filesystem errors for detector._detectFrontend and detector._detectBackend: mock fs.pathExists/fs.readJson/fs.readdir to throw (or reject) and call detector._detectFrontend(profile) / detector._detectBackend(profile) using detector._createEmptyProfile(), then assert the call does not throw and that profile.hasFrontend/profile.hasBackend remain false (or unchanged) and any related flags (frontend.buildTool/backend.hasAPI) are not set; follow the existing DB migration error-path test pattern and reuse setupDeps when appropriate to keep test structure consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@tests/core/orchestration/tech-stack-detector.test.js`:
- Around line 312-325: Update the "detecta env vars de banco de dados" test to
cover the other env-file variants the detector supports: adjust the
fs.pathExists mock in tests/core/orchestration/tech-stack-detector.test.js so it
returns true for paths ending with '.env', '.env.local', and '.env.example' (or
add separate test cases for each filename), and ensure
fs.readFile.mockResolvedValue returns content containing the DB env var for
those files (or mock multiple readFile calls accordingly) so
detector._detectDatabase and the test for profile.database.envVarsConfigured
exercise all supported env-file branches.
- Around line 541-565: Add coverage for src/api and app/api by adding tests
analogous to the existing 'detecta rotas API em api/' and 'detecta rotas API em
pages/api/': for each new test mock fs.pathExists to return true for
path.join(PROJECT_ROOT, 'src/api') and path.join(PROJECT_ROOT, 'app/api')
respectively, keep fs.readJson.mockResolvedValue({ dependencies: {} }), call
detector._createEmptyProfile() and await detector._detectBackend(profile), and
assert expect(profile.backend.hasAPI).toBe(true); this ensures
detector._detectBackend and profile.backend.hasAPI behavior is exercised for
src/api and app/api paths.
---
Nitpick comments:
In `@tests/core/orchestration/tech-stack-detector.test.js`:
- Around line 345-566: Add negative-path unit tests that simulate filesystem
errors for detector._detectFrontend and detector._detectBackend: mock
fs.pathExists/fs.readJson/fs.readdir to throw (or reject) and call
detector._detectFrontend(profile) / detector._detectBackend(profile) using
detector._createEmptyProfile(), then assert the call does not throw and that
profile.hasFrontend/profile.hasBackend remain false (or unchanged) and any
related flags (frontend.buildTool/backend.hasAPI) are not set; follow the
existing DB migration error-path test pattern and reuse setupDeps when
appropriate to keep test structure consistent.
|
@coderabbitai review Issues resolvidas no commit anterior:
|
🧩 Analysis chain
🏁 Script executed: Length of output: 3199 🏁 Script executed: Length of output: 894 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 23 🏁 Script executed: Length of output: 2 🏁 Script executed: Length of output: 2 🏁 Script executed: Length of output: 79
✅ jest.mock('fs-extra') - Now correctly placed on line 10, before the Also confirmed 84 test cases as described in the PR summary. The test structure looks clean and well-organized. I'll now perform a comprehensive review of the entire PR. ✅ Actions performedReview triggered.
|
- Env vars de banco: cobre .env, .env.local e .env.example - Rotas API: cobre api/, src/api/, pages/api/ e app/api/
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tests/core/orchestration/tech-stack-detector.test.js (1)
349-467: Consider table-driving more dependency-detection tests to reduce repetition.The repeated “setup deps → detect → assert type” pattern can be condensed, making additions easier and reducing maintenance overhead.
Example refactor pattern
+ test.each([ + [{ react: '^18' }, 'react'], + [{ vue: '^3' }, 'vue'], + [{ '@angular/core': '^17' }, 'angular'], + [{ svelte: '^4' }, 'svelte'], + ])('detecta framework %p => %s', async (deps, expected) => { + setupDeps(deps); + const profile = detector._createEmptyProfile(); + await detector._detectFrontend(profile); + expect(profile.frontend.framework).toBe(expected); + });Also applies to: 501-529
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/core/orchestration/tech-stack-detector.test.js` around lines 349 - 467, The tests repeat the same "setupDeps → detector._createEmptyProfile → detector._detectFrontend → expect" flow; refactor by table-driving cases: create an array of {name, deps, expectedPath, expectedValue} and iterate (use test.each or forEach) to call setupDeps(deps), build profile via detector._createEmptyProfile(), await detector._detectFrontend(profile), and assert the expected field (e.g., profile.frontend.framework, buildTool, styling, componentLibrary) matches expectedValue; reference functions setupDeps, detector._createEmptyProfile and detector._detectFrontend and the profile assertions to replace the many near-duplicate test blocks with a single parametrized loop for each assertion category.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@tests/core/orchestration/tech-stack-detector.test.js`:
- Around line 349-467: The tests repeat the same "setupDeps →
detector._createEmptyProfile → detector._detectFrontend → expect" flow; refactor
by table-driving cases: create an array of {name, deps, expectedPath,
expectedValue} and iterate (use test.each or forEach) to call setupDeps(deps),
build profile via detector._createEmptyProfile(), await
detector._detectFrontend(profile), and assert the expected field (e.g.,
profile.frontend.framework, buildTool, styling, componentLibrary) matches
expectedValue; reference functions setupDeps, detector._createEmptyProfile and
detector._detectFrontend and the profile assertions to replace the many
near-duplicate test blocks with a single parametrized loop for each assertion
category.
Resumo
.aios-core/core/orchestration/tech-stack-detector.jsfs-extrapara testes determinísticosÁreas testadas
ENABLE ROW LEVEL SECURITYeCREATE POLICYem migrações SQLPlano de teste
fs-extratotalmente mockado (sem I/O real)Summary by CodeRabbit