-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Test(analytics): Introduce tests for the Twig scanner
refs #DS-874
- Loading branch information
Showing
9 changed files
with
340 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import scanner from 'react-scanner'; | ||
import { path } from 'zx'; | ||
import { runner } from '../runner'; | ||
import { RunnerConfig } from '../types'; | ||
|
||
jest.mock('../scanners/twigScanner', () => { | ||
return jest.fn(() => Promise.resolve({ test: 'test' })); | ||
}); | ||
|
||
describe('runner', () => { | ||
jest.spyOn(path, 'resolve').mockImplementation((...args: string[]) => args.join('/')); | ||
|
||
it('should return tracked data for react type', async () => { | ||
const config = { | ||
react: {}, | ||
twig: {}, | ||
} as RunnerConfig; | ||
const source = '/path/to/source'; | ||
const type = 'react'; | ||
jest.spyOn(scanner, 'run').mockResolvedValue({ test: 'test' }); | ||
|
||
const trackedData = await runner(config, source, type); | ||
|
||
expect(trackedData.spiritVersion).toBeDefined(); | ||
expect(trackedData.trackedData.react).toEqual({ test: 'test' }); | ||
expect(trackedData.trackedData.twig).toEqual({}); | ||
}); | ||
|
||
it('should return tracked data for twig type', async () => { | ||
const config = { | ||
react: {}, | ||
twig: {}, | ||
} as RunnerConfig; | ||
const source = '/path/to/source'; | ||
const type = 'twig'; | ||
|
||
const trackedData = await runner(config, source, type); | ||
|
||
expect(trackedData.spiritVersion).toBeDefined(); | ||
expect(trackedData.trackedData.react).toEqual({}); | ||
expect(trackedData.trackedData.twig).toEqual({ test: 'test' }); | ||
}); | ||
|
||
it('should return tracked data for both react and twig types', async () => { | ||
const config = { | ||
react: {}, | ||
twig: {}, | ||
} as RunnerConfig; | ||
const source = '/path/to/source'; | ||
const type = null; | ||
jest.spyOn(scanner, 'run').mockResolvedValue({ test: 'test' }); | ||
|
||
const trackedData = await runner(config, source, type); | ||
|
||
expect(trackedData.spiritVersion).toBeDefined(); | ||
expect(trackedData.trackedData.react).toEqual({ test: 'test' }); | ||
expect(trackedData.trackedData.twig).toEqual({ test: 'test' }); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
packages/analytics/src/scanners/__tests__/reactScanner.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import scanner from 'react-scanner'; | ||
import reactScanner from '../reactScanner'; | ||
|
||
describe('reactScanner', () => { | ||
it('should return the output of the scanner', async () => { | ||
const mockedScannerRun = jest.spyOn(scanner, 'run'); | ||
mockedScannerRun.mockResolvedValue('scanner output'); | ||
|
||
const config = { | ||
crawlFrom: 'path/to/crawl/from', | ||
config: 'path/to/config', | ||
}; | ||
|
||
const output = await reactScanner(config); | ||
|
||
expect(output).toBe('scanner output'); | ||
expect(mockedScannerRun).toHaveBeenCalledWith(config); | ||
}); | ||
}); |
224 changes: 224 additions & 0 deletions
224
packages/analytics/src/scanners/__tests__/twigScanner.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,224 @@ | ||
import { fs, path } from 'zx'; | ||
import * as twigScanner from '../twigScanner'; | ||
|
||
describe('twigScanner', () => { | ||
describe('getComponentsFromDirectory', () => { | ||
it('should return an array of component names, capitalize first letter and remove `.twig` extension', () => { | ||
const mockedReaddirSync = jest | ||
.spyOn(fs, 'readdirSync') | ||
// @ts-expect-error TS2322: Type 'string' is not assignable to type 'Dirent'. | ||
.mockReturnValue(['component1.twig', 'component2.twig', 'component3.twig']); | ||
const directoryPath = '/path/to/directory'; | ||
const expectedComponents = ['Component1', 'Component2', 'Component3']; | ||
|
||
const result = twigScanner.getComponentsFromDirectory(directoryPath); | ||
|
||
expect(result).toEqual(expectedComponents); | ||
expect(mockedReaddirSync).toHaveBeenCalledWith(directoryPath); | ||
}); | ||
}); | ||
|
||
describe('getPathsFromYamlConfig', () => { | ||
it('should return an array of component names, capitalize first letter and remove `.twig` extension', () => { | ||
const twigConfig = ` | ||
spirit_web_twig: | ||
paths: | ||
- "%kernel.project_dir%/app/Resources/views" | ||
- "%kernel.project_dir%/../spirit-web-twig-bundle/docs/twig-components" | ||
icons: | ||
paths: | ||
- "%kernel.project_dir%/../spirit-web-twig-bundle/static" | ||
`; | ||
const mockedReadFileSync = jest.spyOn(fs, 'readFileSync').mockReturnValue(twigConfig); | ||
const configFile = '/path/to/config/file'; | ||
const expectedResult = [ | ||
'./app/Resources/views/*.twig', | ||
'./../spirit-web-twig-bundle/docs/twig-components/*.twig', | ||
'./../spirit-web-twig-bundle/static/*.twig', | ||
]; | ||
|
||
const result = twigScanner.getPathsFromYamlConfig(configFile); | ||
|
||
expect(result).toEqual(expectedResult); | ||
expect(mockedReadFileSync).toHaveBeenCalledWith(configFile, 'utf8'); | ||
}); | ||
}); | ||
|
||
describe('determineModuleNameFromComponents', () => { | ||
it('should return "local_component" if the nodeName is in the localComponents array', () => { | ||
const nodeName = 'Component1'; | ||
const localComponents = ['Component1', 'Component2', 'Component3']; | ||
const baseComponents = ['BaseComponent1', 'BaseComponent2']; | ||
|
||
const result = twigScanner.determineModuleNameFromComponents(nodeName, localComponents, baseComponents); | ||
|
||
expect(result).toBe('local_component'); | ||
}); | ||
|
||
it('should return "@lmc-eu/spirit-web-twig" if the nodeName is in the baseComponents array', () => { | ||
const nodeName = 'BaseComponent2'; | ||
const localComponents = ['Component1', 'Component2', 'Component3']; | ||
const baseComponents = ['BaseComponent1', 'BaseComponent2']; | ||
|
||
const result = twigScanner.determineModuleNameFromComponents(nodeName, localComponents, baseComponents); | ||
|
||
expect(result).toBe('@lmc-eu/spirit-web-twig'); | ||
}); | ||
|
||
it('should return "html_element" if the nodeName is not in the localComponents or baseComponents array', () => { | ||
const nodeName = 'UnknownComponent'; | ||
const localComponents = ['Component1', 'Component2', 'Component3']; | ||
const baseComponents = ['BaseComponent1', 'BaseComponent2']; | ||
|
||
const result = twigScanner.determineModuleNameFromComponents(nodeName, localComponents, baseComponents); | ||
|
||
expect(result).toBe('html_element'); | ||
}); | ||
}); | ||
|
||
describe('searchFileForComponents', () => { | ||
it('should return an empty object if file content is empty', () => { | ||
const file = ''; | ||
const localComponents: Array<string> = []; | ||
const baseComponents: Array<string> = []; | ||
jest.spyOn(fs, 'readFileSync').mockReturnValue(file); | ||
|
||
const result = twigScanner.searchFileForComponents(file, localComponents, baseComponents); | ||
|
||
expect(result).toEqual({}); | ||
}); | ||
|
||
it('should return the correct components with their props', () => { | ||
const file = 'app/Resources/views/.../card.twig'; | ||
const fileContent = ` | ||
<Button color="primary" size="small">Click me</Button> | ||
<Input type="text" placeholder="Enter your name" /> | ||
<CustomComponent prop1="value1" prop2="value2" /> | ||
`; | ||
const localComponents = ['Button', 'Input', 'CustomComponent']; | ||
const baseComponents: Array<string> = []; | ||
jest.spyOn(fs, 'readFileSync').mockReturnValue(fileContent); | ||
|
||
const result = twigScanner.searchFileForComponents(file, localComponents, baseComponents); | ||
|
||
expect(result).toEqual({ | ||
'local_component:Button': [ | ||
{ | ||
path: 'app/Resources/views/.../card.twig:2', | ||
props: { | ||
color: 'primary', | ||
size: 'small', | ||
}, | ||
}, | ||
], | ||
'local_component:CustomComponent': [ | ||
{ | ||
path: 'app/Resources/views/.../card.twig:4', | ||
props: { | ||
prop1: 'value1', | ||
prop2: 'value2', | ||
}, | ||
}, | ||
], | ||
'local_component:Input': [ | ||
{ | ||
path: 'app/Resources/views/.../card.twig:3', | ||
props: { | ||
placeholder: 'Enter your name', | ||
type: 'text', | ||
}, | ||
}, | ||
], | ||
}); | ||
}); | ||
}); | ||
|
||
describe('searchDirectoryForComponents', () => { | ||
it('should return an empty object if the directory is excluded', () => { | ||
const dir = '/path/to/excluded/directory'; | ||
const localComponents: Array<string> = []; | ||
const baseComponents: Array<string> = []; | ||
const exclude: Array<string> = ['/path/to/excluded/directory']; | ||
|
||
const lstatResult = { isDirectory: () => false } as fs.Stats; | ||
const dirContent: fs.Dirent[] = ['file1.twig', 'file2.twig'] as unknown as fs.Dirent[]; | ||
jest.spyOn(fs, 'readdirSync').mockReturnValue(dirContent); | ||
jest.spyOn(fs, 'lstatSync').mockReturnValue(lstatResult); | ||
jest.spyOn(path, 'extname').mockReturnValue('.twig'); | ||
jest.spyOn(path, 'basename').mockReturnValue(dir); | ||
jest.spyOn(path, 'join').mockImplementation((directory, file) => `${directory}/${file}`); | ||
|
||
const result = twigScanner.searchDirectoryForComponents(dir, localComponents, baseComponents, exclude); | ||
|
||
expect(result).toEqual({}); | ||
}); | ||
|
||
it('should return an empty object if the directory is empty', () => { | ||
const dir = '/path/to/empty/directory'; | ||
const localComponents: Array<string> = []; | ||
const baseComponents: Array<string> = []; | ||
const exclude: Array<string> = []; | ||
|
||
const lstatResult = { isDirectory: () => false } as fs.Stats; | ||
jest.spyOn(fs, 'lstatSync').mockReturnValue(lstatResult); | ||
jest.spyOn(path, 'extname').mockReturnValue('.twig'); | ||
jest.spyOn(path, 'join').mockImplementation((directory, file) => `${directory}/${file}`); | ||
jest.spyOn(fs, 'readdirSync').mockReturnValue([]); | ||
|
||
const result = twigScanner.searchDirectoryForComponents(dir, localComponents, baseComponents, exclude); | ||
|
||
expect(result).toEqual({}); | ||
expect(fs.readdirSync).toHaveBeenCalledWith(dir); | ||
}); | ||
|
||
it('should recursively search the directory for .twig files and call searchFileForComponents', () => { | ||
const dir = '/path/to/directory'; | ||
const localComponents = ['Button', 'Input', 'CustomComponent']; | ||
const baseComponents: Array<string> = []; | ||
const exclude: Array<string> = []; | ||
const lstatResult = { isDirectory: () => false } as fs.Stats; | ||
const dirContent: fs.Dirent[] = ['file1.twig', 'file2.twig'] as unknown as fs.Dirent[]; | ||
|
||
const mockedReaddirSync = jest.spyOn(fs, 'readdirSync').mockReturnValue(dirContent); | ||
const lstatSync = jest.spyOn(fs, 'lstatSync').mockReturnValue(lstatResult); | ||
const mockedExtname = jest.spyOn(path, 'extname').mockReturnValue('.twig'); | ||
const mockedPathJoin = jest.spyOn(path, 'join').mockImplementation((directory, file) => `${directory}/${file}`); | ||
|
||
const result = twigScanner.searchDirectoryForComponents(dir, localComponents, baseComponents, exclude); | ||
|
||
expect(result).toEqual({ | ||
'local_component:Button': [ | ||
{ | ||
path: '/path/to/directory/file2.twig:2', | ||
props: { | ||
color: 'primary', | ||
size: 'small', | ||
}, | ||
}, | ||
], | ||
'local_component:CustomComponent': [ | ||
{ | ||
path: '/path/to/directory/file2.twig:4', | ||
props: { | ||
prop1: 'value1', | ||
prop2: 'value2', | ||
}, | ||
}, | ||
], | ||
'local_component:Input': [ | ||
{ | ||
path: '/path/to/directory/file2.twig:3', | ||
props: { | ||
placeholder: 'Enter your name', | ||
type: 'text', | ||
}, | ||
}, | ||
], | ||
}); | ||
expect(mockedReaddirSync).toHaveBeenCalledWith(dir); | ||
expect(lstatSync).toHaveBeenCalledTimes(2); | ||
expect(mockedExtname).toHaveBeenCalledTimes(2); | ||
expect(mockedPathJoin).toHaveBeenCalledTimes(2); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.