@@ -9,8 +9,10 @@ import * as fs from 'fs';
99import * as path from 'path' ;
1010import * as os from 'os' ;
1111import { CodeGraph } from '../src' ;
12- import { extractFromSource } from '../src/extraction' ;
12+ import { extractFromSource , scanDirectory , shouldIncludeFile } from '../src/extraction' ;
1313import { detectLanguage , isLanguageSupported , getSupportedLanguages } from '../src/extraction/grammars' ;
14+ import { normalizePath } from '../src/utils' ;
15+ import { DEFAULT_CONFIG } from '../src/types' ;
1416
1517// Create a temporary directory for each test
1618function createTempDir ( ) : string {
@@ -1981,3 +1983,106 @@ export function multiply(a: number, b: number): number {
19811983 cg . close ( ) ;
19821984 } ) ;
19831985} ) ;
1986+
1987+ describe ( 'Path Normalization' , ( ) => {
1988+ it ( 'should convert backslashes to forward slashes' , ( ) => {
1989+ expect ( normalizePath ( 'gui\\node_modules\\foo' ) ) . toBe ( 'gui/node_modules/foo' ) ;
1990+ expect ( normalizePath ( 'src\\components\\Button.tsx' ) ) . toBe ( 'src/components/Button.tsx' ) ;
1991+ } ) ;
1992+
1993+ it ( 'should leave forward-slash paths unchanged' , ( ) => {
1994+ expect ( normalizePath ( 'src/components/Button.tsx' ) ) . toBe ( 'src/components/Button.tsx' ) ;
1995+ } ) ;
1996+
1997+ it ( 'should handle empty string' , ( ) => {
1998+ expect ( normalizePath ( '' ) ) . toBe ( '' ) ;
1999+ } ) ;
2000+ } ) ;
2001+
2002+ describe ( 'Directory Exclusion' , ( ) => {
2003+ let tempDir : string ;
2004+
2005+ beforeEach ( ( ) => {
2006+ tempDir = createTempDir ( ) ;
2007+ } ) ;
2008+
2009+ afterEach ( ( ) => {
2010+ cleanupTempDir ( tempDir ) ;
2011+ } ) ;
2012+
2013+ it ( 'should exclude node_modules directories' , ( ) => {
2014+ // Create structure: src/index.ts + node_modules/pkg/index.js
2015+ const srcDir = path . join ( tempDir , 'src' ) ;
2016+ const nmDir = path . join ( tempDir , 'node_modules' , 'pkg' ) ;
2017+ fs . mkdirSync ( srcDir , { recursive : true } ) ;
2018+ fs . mkdirSync ( nmDir , { recursive : true } ) ;
2019+ fs . writeFileSync ( path . join ( srcDir , 'index.ts' ) , 'export const x = 1;' ) ;
2020+ fs . writeFileSync ( path . join ( nmDir , 'index.js' ) , 'module.exports = {};' ) ;
2021+
2022+ const config = { ...DEFAULT_CONFIG , rootDir : tempDir } ;
2023+ const files = scanDirectory ( tempDir , config ) ;
2024+
2025+ expect ( files ) . toContain ( 'src/index.ts' ) ;
2026+ expect ( files . every ( ( f ) => ! f . includes ( 'node_modules' ) ) ) . toBe ( true ) ;
2027+ } ) ;
2028+
2029+ it ( 'should exclude nested node_modules directories' , ( ) => {
2030+ // Create structure: packages/app/node_modules/pkg/index.js
2031+ const srcDir = path . join ( tempDir , 'packages' , 'app' , 'src' ) ;
2032+ const nmDir = path . join ( tempDir , 'packages' , 'app' , 'node_modules' , 'pkg' ) ;
2033+ fs . mkdirSync ( srcDir , { recursive : true } ) ;
2034+ fs . mkdirSync ( nmDir , { recursive : true } ) ;
2035+ fs . writeFileSync ( path . join ( srcDir , 'index.ts' ) , 'export const x = 1;' ) ;
2036+ fs . writeFileSync ( path . join ( nmDir , 'index.js' ) , 'module.exports = {};' ) ;
2037+
2038+ const config = { ...DEFAULT_CONFIG , rootDir : tempDir } ;
2039+ const files = scanDirectory ( tempDir , config ) ;
2040+
2041+ expect ( files ) . toContain ( 'packages/app/src/index.ts' ) ;
2042+ expect ( files . every ( ( f ) => ! f . includes ( 'node_modules' ) ) ) . toBe ( true ) ;
2043+ } ) ;
2044+
2045+ it ( 'should exclude .git directories' , ( ) => {
2046+ const srcDir = path . join ( tempDir , 'src' ) ;
2047+ const gitDir = path . join ( tempDir , '.git' , 'objects' ) ;
2048+ fs . mkdirSync ( srcDir , { recursive : true } ) ;
2049+ fs . mkdirSync ( gitDir , { recursive : true } ) ;
2050+ fs . writeFileSync ( path . join ( srcDir , 'index.ts' ) , 'export const x = 1;' ) ;
2051+ fs . writeFileSync ( path . join ( gitDir , 'pack.ts' ) , 'export const y = 2;' ) ;
2052+
2053+ const config = { ...DEFAULT_CONFIG , rootDir : tempDir } ;
2054+ const files = scanDirectory ( tempDir , config ) ;
2055+
2056+ expect ( files ) . toContain ( 'src/index.ts' ) ;
2057+ expect ( files . every ( ( f ) => ! f . includes ( '.git' ) ) ) . toBe ( true ) ;
2058+ } ) ;
2059+
2060+ it ( 'should return forward-slash paths on all platforms' , ( ) => {
2061+ const srcDir = path . join ( tempDir , 'src' , 'components' ) ;
2062+ fs . mkdirSync ( srcDir , { recursive : true } ) ;
2063+ fs . writeFileSync ( path . join ( srcDir , 'Button.tsx' ) , 'export function Button() {}' ) ;
2064+
2065+ const config = { ...DEFAULT_CONFIG , rootDir : tempDir } ;
2066+ const files = scanDirectory ( tempDir , config ) ;
2067+
2068+ expect ( files . length ) . toBe ( 1 ) ;
2069+ expect ( files [ 0 ] ) . toBe ( 'src/components/Button.tsx' ) ;
2070+ expect ( files [ 0 ] ) . not . toContain ( '\\' ) ;
2071+ } ) ;
2072+
2073+ it ( 'should respect .codegraphignore marker' , ( ) => {
2074+ const srcDir = path . join ( tempDir , 'src' ) ;
2075+ const vendorDir = path . join ( tempDir , 'vendor' ) ;
2076+ fs . mkdirSync ( srcDir , { recursive : true } ) ;
2077+ fs . mkdirSync ( vendorDir , { recursive : true } ) ;
2078+ fs . writeFileSync ( path . join ( srcDir , 'index.ts' ) , 'export const x = 1;' ) ;
2079+ fs . writeFileSync ( path . join ( vendorDir , 'lib.ts' ) , 'export const y = 2;' ) ;
2080+ fs . writeFileSync ( path . join ( vendorDir , '.codegraphignore' ) , '' ) ;
2081+
2082+ const config = { ...DEFAULT_CONFIG , rootDir : tempDir } ;
2083+ const files = scanDirectory ( tempDir , config ) ;
2084+
2085+ expect ( files ) . toContain ( 'src/index.ts' ) ;
2086+ expect ( files . every ( ( f ) => ! f . includes ( 'vendor' ) ) ) . toBe ( true ) ;
2087+ } ) ;
2088+ } ) ;
0 commit comments