-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore(enum-updater): add enum updater tool #33681
Open
paulhcsun
wants to merge
17
commits into
aws:main
Choose a base branch
from
paulhcsun:enum-updater-tool
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
51189a5
chore(enum-updater): add enum updater tool
paulhcsun a2345c0
update parseCdk method to include enumLike flag
paulhcsun c490248
remove format matching for missing values, remove similar name check …
paulhcsun 7c12d5b
Add simple enum-like update logic
967c457
Merge branch 'enum-updater-tool' of https://github.com/paulhcsun/aws-…
9b9f6dc
Ensure the replacement logic works properly
160f06c
Place values in the right place and comment them
8a27fbd
add logic for updating regular enums
paulhcsun e464a45
update spacing for code updates
paulhcsun fde6057
update to not add extra empty lines
paulhcsun 6d600c7
extract code writing logic to enum-updater tool + add workflow file
paulhcsun 0341da9
Cleanup indentation and whatnot
8226a3d
Merge branch 'aws:main' into enum-updater-tool
paulhcsun 69716c9
refactor + add tests
paulhcsun eb169bb
add additional unit tests
paulhcsun 48fdeb8
Merge branch 'main' into enum-updater-tool
xazhao e00c3f4
Change data source to cfn lint
xazhao File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
add additional unit tests
- Loading branch information
commit eb169bbc6303974e031e2246f4534bb6e3374b15
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
File renamed without changes.
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
223 changes: 223 additions & 0 deletions
223
tools/@aws-cdk/enum-updater/test/missing-enum-updater.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,223 @@ | ||
import { MissingEnumsUpdater } from '../lib/missing-enum-updater'; | ||
import { Project, SourceFile, EnumDeclaration, ClassDeclaration, SyntaxKind } from 'ts-morph'; | ||
import * as path from 'path'; | ||
import * as fs from 'fs'; | ||
|
||
// Mock dependencies | ||
jest.mock('ts-morph'); | ||
jest.mock('fs'); | ||
jest.mock('path'); | ||
jest.mock('tmp'); | ||
|
||
describe('MissingEnumsUpdater', () => { | ||
let updater: MissingEnumsUpdater; | ||
let mockSourceFile: jest.Mocked<SourceFile>; | ||
let mockEnumDeclaration: jest.Mocked<EnumDeclaration>; | ||
let mockClassDeclaration: jest.Mocked<ClassDeclaration>; | ||
|
||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
|
||
// Setup Project mock | ||
(Project as jest.Mock).mockImplementation(() => ({ | ||
addSourceFilesAtPaths: jest.fn(), | ||
getSourceFiles: jest.fn().mockReturnValue([]), | ||
getSourceFile: jest.fn().mockReturnValue(mockSourceFile) | ||
})); | ||
|
||
// Mock file system operations | ||
(fs.readdirSync as jest.Mock).mockReturnValue([]); | ||
(fs.statSync as jest.Mock).mockReturnValue({ isDirectory: () => false }); | ||
(fs.readFileSync as jest.Mock).mockReturnValue('{}'); | ||
(path.resolve as jest.Mock).mockImplementation((...args) => args.join('/')); | ||
|
||
updater = new MissingEnumsUpdater('./test-dir'); | ||
}); | ||
|
||
describe('constructor', () => { | ||
it('should initialize with correct project settings', () => { | ||
expect(Project).toHaveBeenCalledWith({ | ||
tsConfigFilePath: expect.stringMatching(/tsconfig\.json$/), | ||
manipulationSettings: expect.any(Object) | ||
}); | ||
}); | ||
}); | ||
describe('readTypescriptFiles', () => { | ||
it('should skip specified directories', () => { | ||
const mockFiles = ['node_modules', 'dist', 'test', 'valid.ts']; | ||
(fs.readdirSync as jest.Mock).mockReturnValue(mockFiles); | ||
(path.join as jest.Mock).mockImplementation((...args) => args.join('/')); | ||
(fs.statSync as jest.Mock).mockImplementation((filePath) => ({ | ||
isDirectory: () => !filePath.includes('.ts') | ||
})); | ||
|
||
const result = (updater as any).readTypescriptFiles('./test-dir'); | ||
expect(result).toEqual(['./test-dir/valid.ts']); | ||
}); | ||
|
||
it('should filter out invalid typescript files', () => { | ||
const mockFiles = ['file.ts', 'file.generated.ts', 'file.d.ts', 'file.test.ts']; | ||
(fs.readdirSync as jest.Mock).mockReturnValue(mockFiles); | ||
(path.join as jest.Mock).mockImplementation((...args) => args.join('/')); | ||
(fs.statSync as jest.Mock).mockReturnValue({ isDirectory: () => false }); | ||
|
||
const result = (updater as any).readTypescriptFiles('./test-dir'); | ||
expect(result).toEqual(['./test-dir/file.ts']); | ||
}); | ||
}); | ||
|
||
describe('updateEnum', () => { | ||
beforeEach(() => { | ||
mockEnumDeclaration = { | ||
getFullText: jest.fn().mockReturnValue('enum Test {\n VALUE1 = "value1"\n}'), | ||
replaceWithText: jest.fn(), | ||
} as any; | ||
|
||
mockSourceFile = { | ||
getEnum: jest.fn().mockReturnValue(mockEnumDeclaration), | ||
saveSync: jest.fn(), | ||
} as any; | ||
|
||
// Update Project mock implementation | ||
(Project as jest.Mock).mockImplementation(() => ({ | ||
addSourceFilesAtPaths: jest.fn(), | ||
getSourceFiles: jest.fn().mockReturnValue([]), | ||
getSourceFile: jest.fn().mockReturnValue(mockSourceFile) | ||
})); | ||
|
||
updater = new MissingEnumsUpdater('./test-dir'); | ||
}); | ||
|
||
it('should update enum with missing values', () => { | ||
const missingValue = { | ||
cdk_path: 'path/to/enum', | ||
missing_values: ['value2'] | ||
}; | ||
|
||
(updater as any).updateEnum('TestEnum', missingValue); | ||
|
||
expect(mockEnumDeclaration.replaceWithText).toHaveBeenCalled(); | ||
expect(mockSourceFile.saveSync).toHaveBeenCalled(); | ||
}); | ||
|
||
it('should throw error if source file not found', () => { | ||
// Update Project mock to return null for getSourceFile | ||
(Project as jest.Mock).mockImplementation(() => ({ | ||
addSourceFilesAtPaths: jest.fn(), | ||
getSourceFiles: jest.fn().mockReturnValue([]), | ||
getSourceFile: jest.fn().mockReturnValue(null) | ||
})); | ||
|
||
updater = new MissingEnumsUpdater('./test-dir'); | ||
|
||
expect(() => { | ||
(updater as any).updateEnum('TestEnum', { | ||
cdk_path: 'invalid/path', | ||
missing_values: ['value'] | ||
}); | ||
}).toThrow('Source file not found'); | ||
}); | ||
}); | ||
|
||
describe('updateEnumLike', () => { | ||
beforeEach(() => { | ||
mockClassDeclaration = { | ||
forEachChild: jest.fn(), | ||
addProperty: jest.fn().mockReturnValue({ | ||
setOrder: jest.fn(), | ||
addJsDoc: jest.fn() | ||
}), | ||
} as any; | ||
|
||
mockSourceFile = { | ||
getClass: jest.fn().mockReturnValue(mockClassDeclaration), | ||
saveSync: jest.fn(), | ||
} as any; | ||
|
||
// Update Project mock implementation | ||
(Project as jest.Mock).mockImplementation(() => ({ | ||
addSourceFilesAtPaths: jest.fn(), | ||
getSourceFiles: jest.fn().mockReturnValue([]), | ||
getSourceFile: jest.fn().mockReturnValue(mockSourceFile) | ||
})); | ||
|
||
updater = new MissingEnumsUpdater('./test-dir'); | ||
}); | ||
|
||
it('should update enum-like class with missing values', () => { | ||
const missingValue = { | ||
cdk_path: 'path/to/class', | ||
missing_values: ['new-value'] | ||
}; | ||
|
||
// Mock PropertyDeclaration | ||
const mockProperty = { | ||
getText: jest.fn().mockReturnValue('public static readonly EXISTING = new TestClass("existing")'), | ||
getInitializer: jest.fn().mockReturnValue({ | ||
getKind: () => SyntaxKind.NewExpression | ||
}), | ||
getName: jest.fn().mockReturnValue('EXISTING'), | ||
getInitializerIfKind: jest.fn().mockReturnValue({ | ||
getArguments: jest.fn().mockReturnValue(['existing']) | ||
}) | ||
} as any; | ||
|
||
mockClassDeclaration.forEachChild.mockImplementation(callback => callback(mockProperty)); | ||
|
||
(updater as any).updateEnumLike('testModule', 'TestClass', missingValue); | ||
|
||
expect(mockClassDeclaration.addProperty).toHaveBeenCalled(); | ||
expect(mockSourceFile.saveSync).toHaveBeenCalled(); | ||
}); | ||
}); | ||
describe('execute', () => { | ||
it('should execute the update process', async () => { | ||
const mockMissingValuesPath = '/tmp/missing-values.json'; | ||
|
||
// Mock the methods | ||
const analyzeMissingEnumValuesSpy = jest.spyOn(updater as any, 'analyzeMissingEnumValues') | ||
.mockResolvedValue(mockMissingValuesPath); | ||
const updateEnumLikeValuesSpy = jest.spyOn(updater as any, 'updateEnumLikeValues') | ||
.mockImplementation(() => {}); | ||
const updateEnumValuesSpy = jest.spyOn(updater as any, 'updateEnumValues') | ||
.mockImplementation(() => {}); | ||
|
||
await updater.execute(); | ||
|
||
expect(analyzeMissingEnumValuesSpy).toHaveBeenCalled(); | ||
expect(updateEnumLikeValuesSpy).toHaveBeenCalledWith(mockMissingValuesPath); | ||
expect(updateEnumValuesSpy).toHaveBeenCalledWith(mockMissingValuesPath); | ||
}); | ||
}); | ||
|
||
describe('removeAwsCdkPrefix', () => { | ||
it('should remove aws-cdk prefix', () => { | ||
expect((updater as any).removeAwsCdkPrefix('aws-cdk/path/to/file')).toBe('path/to/file'); | ||
expect((updater as any).removeAwsCdkPrefix('path/to/file')).toBe('path/to/file'); | ||
}); | ||
}); | ||
|
||
describe('getParsedEnumValues and getParsedEnumLikeValues', () => { | ||
beforeEach(() => { | ||
const mockFileContent = JSON.stringify({ | ||
module1: { | ||
enum1: { enumLike: false, values: ['value1'] }, | ||
enum2: { enumLike: true, values: ['value2'] } | ||
} | ||
}); | ||
(fs.readFileSync as jest.Mock).mockReturnValue(mockFileContent); | ||
}); | ||
|
||
it('should return only regular enums', () => { | ||
const result = (updater as any).getParsedEnumValues(); | ||
expect(result.module1.enum1).toBeDefined(); | ||
expect(result.module1.enum2).toBeUndefined(); | ||
}); | ||
|
||
it('should return only enum-likes', () => { | ||
const result = (updater as any).getParsedEnumLikeValues(); | ||
expect(result.module1.enum1).toBeUndefined(); | ||
expect(result.module1.enum2).toBeDefined(); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't it should be
update-missing-enums
instead?