-
Notifications
You must be signed in to change notification settings - Fork 188
SONARARMOR-860 Parser should serialize popular syntax #5257
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
Conversation
cb8fe29
to
64bf8b9
Compare
64bf8b9
to
70eb540
Compare
@@ -262,15 +263,6 @@ describe('ast', () => { | |||
checkAstIsProperlySerializedAndDeserialized(ast as TSESTree.Program, protoMessage, 'foo.ts'); | |||
}); | |||
|
|||
test('Unknown node types in program body are not serialized', async () => { |
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.
This test was previously implemented to check that from a list of nodes we are able to filter out the unknown ones. With this PR we implement basic support for some nodes previously unsupported. After this, I could not find another test code to use to reproduce this scenario, so I removed this test, while I kept the business logic, as I am sure that it is still a possible scenario in production.
@@ -673,7 +673,7 @@ public record TSModuleDeclaration( | |||
Optional<TSModuleBlock> body, | |||
String kind | |||
) | |||
implements ModuleDeclaration {} | |||
implements Declaration {} |
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.
This fixes an error in the hierarchy introduced during the previous PR to support TSModuleDeclaration
module.
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.
Inspired by this comment in the previous PR, I added some UTs in this class, to check that given a piece of code we create the expected java nodes.
This PR contains the following:
|
test('should serialize some nodes to empty object', async () => { | ||
const codeMap = new Map<string, string>(); | ||
codeMap.set('TSTypeAliasDeclaration', `type A = { a: string };`); | ||
codeMap.set('TSInterfaceDeclaration', `interface A { a: string; }`); | ||
codeMap.set('TSEnumDeclaration', `enum Direction {}`); | ||
codeMap.set('TSDeclareFunction', `declare function foo()`); | ||
|
||
for (const [nodeType, code] of codeMap) { | ||
const ast = await parseSourceCode(code, parsersMap.typescript); | ||
const protoMessage = visitNode(ast as TSESTree.Program); | ||
|
||
expect(protoMessage.program.body[0].type).toEqual(NODE_TYPE_ENUM.values[`${nodeType}Type`]); | ||
const tSModuleDeclaration = protoMessage.program.body[0][lowerCaseFirstLetter(nodeType)]; | ||
expect(tSModuleDeclaration).toEqual({}); | ||
checkAstIsProperlySerializedAndDeserialized(ast as TSESTree.Program, protoMessage, 'foo.ts'); | ||
} | ||
}); |
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.
I think a better practice to implement would be to run the test in a loop. Sth like this:
test('should serialize some nodes to empty object', async () => { | |
const codeMap = new Map<string, string>(); | |
codeMap.set('TSTypeAliasDeclaration', `type A = { a: string };`); | |
codeMap.set('TSInterfaceDeclaration', `interface A { a: string; }`); | |
codeMap.set('TSEnumDeclaration', `enum Direction {}`); | |
codeMap.set('TSDeclareFunction', `declare function foo()`); | |
for (const [nodeType, code] of codeMap) { | |
const ast = await parseSourceCode(code, parsersMap.typescript); | |
const protoMessage = visitNode(ast as TSESTree.Program); | |
expect(protoMessage.program.body[0].type).toEqual(NODE_TYPE_ENUM.values[`${nodeType}Type`]); | |
const tSModuleDeclaration = protoMessage.program.body[0][lowerCaseFirstLetter(nodeType)]; | |
expect(tSModuleDeclaration).toEqual({}); | |
checkAstIsProperlySerializedAndDeserialized(ast as TSESTree.Program, protoMessage, 'foo.ts'); | |
} | |
}); | |
[ | |
{ nodeType: 'TSTypeAliasDeclaration', code: `type A = { a: string };` }, | |
{ nodeType: 'TSInterfaceDeclaration', code: `interface A { a: string; }`}, | |
{ nodeType: 'TSEnumDeclaration', code: `enum Direction {}`}, | |
{ nodeType: 'TSDeclareFunction', code: `declare function foo()`}, | |
].forEach(({ nodeType, code}) => test(`should serialize ${nodeType} to empty object`, async () => { | |
const ast = await parseSourceCode(code, parsersMap.typescript); | |
const protoMessage = visitNode(ast as TSESTree.Program); | |
expect(protoMessage.program.body[0].type).toEqual(NODE_TYPE_ENUM.values[`${nodeType}Type`]); | |
const tSModuleDeclaration = protoMessage.program.body[0][lowerCaseFirstLetter(nodeType)]; | |
expect(tSModuleDeclaration).toEqual({}); | |
checkAstIsProperlySerializedAndDeserialized(ast as TSESTree.Program, protoMessage, 'foo.ts'); | |
}) | |
}); |
Pardon if this is invalid js code, I was typing in this textbox freehand.
This way, you get the name of the node if it fails and its an actual unit-test.
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.
Nice, thanks for the suggestion!
@@ -26,14 +26,14 @@ class ESTreeTest { | |||
@Test | |||
void test() { | |||
Class<?>[] classes = ESTree.class.getDeclaredClasses(); | |||
assertThat(classes).hasSize(118); | |||
assertThat(classes).hasSize(125); |
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.
😢
@Test | ||
void should_create_ts_abstract_method_definition() { | ||
assertNodeTypeIsParsedToExpectedClass( | ||
NodeType.TSAbstractMethodDefinitionType, | ||
ESTree.TSAbstractMethodDefinition.class | ||
); | ||
} | ||
|
||
@Test | ||
void should_create_ts_declare_function() { | ||
assertNodeTypeIsParsedToExpectedClass( | ||
NodeType.TSDeclareFunctionType, | ||
ESTree.TSDeclareFunction.class | ||
); | ||
} | ||
|
||
@Test | ||
void should_create_ts_interface_declaration() { | ||
assertNodeTypeIsParsedToExpectedClass( | ||
NodeType.TSInterfaceDeclarationType, | ||
ESTree.TSInterfaceDeclaration.class | ||
); | ||
} | ||
|
||
@Test | ||
void should_create_ts_enum_declaration() { | ||
assertNodeTypeIsParsedToExpectedClass( | ||
NodeType.TSEnumDeclarationType, | ||
ESTree.TSEnumDeclaration.class | ||
); | ||
} | ||
|
||
@Test | ||
void should_create_ts_type_alias_declaration() { | ||
assertNodeTypeIsParsedToExpectedClass( | ||
NodeType.TSTypeAliasDeclarationType, | ||
ESTree.TSTypeAliasDeclaration.class | ||
); | ||
} | ||
|
||
@Test | ||
void should_create_ts_empty_body_function_expression() { | ||
assertNodeTypeIsParsedToExpectedClass( | ||
NodeType.TSEmptyBodyFunctionExpressionType, | ||
ESTree.TSEmptyBodyFunctionExpression.class | ||
); | ||
} |
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.
I'm not fluent in Java, but couldn't this be a @parametrizedTest with these test cases provided with a @methodSource? No need naming these tests and they all share a common implementation from line 1013?
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.
Good idea!
@Test | ||
void should_parse_exported_ts_module_declaration() { | ||
assertExportedNodeIsParsedToCorrectObjectType( | ||
"export declare module 'foo'", | ||
ESTree.TSModuleDeclaration.class | ||
); | ||
} | ||
|
||
@Test | ||
void should_parse_exported_ts_type_alias_declaration() { | ||
assertExportedNodeIsParsedToCorrectObjectType( | ||
"export type A = { a: 42 }", | ||
ESTree.TSTypeAliasDeclaration.class | ||
); | ||
} | ||
|
||
@Test | ||
void should_parse_exported_ts_enum_declaration() { | ||
assertExportedNodeIsParsedToCorrectObjectType( | ||
"export enum A {}", | ||
ESTree.TSEnumDeclaration.class | ||
); | ||
} | ||
|
||
@Test | ||
void should_parse_exported_ts_interface_declaration() { | ||
assertExportedNodeIsParsedToCorrectObjectType( | ||
"export interface A {}", | ||
ESTree.TSInterfaceDeclaration.class | ||
); | ||
} | ||
|
||
@Test | ||
void should_parse_exported_ts_declare_function() { | ||
assertExportedNodeIsParsedToCorrectObjectType( | ||
"export declare function foo()", | ||
ESTree.TSDeclareFunction.class | ||
); | ||
} |
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.
Same comment as before, could be parametrized to reduce code-bloat.
|
SONARARMOR-860
Part of