@@ -13,10 +13,11 @@ import {
1313 UpdatePolicyProperty ,
1414 AutoScalingRollingUpdateProperty ,
1515} from '../../../src/context/ContextType' ;
16+ import { ForEachResource , Resource } from '../../../src/context/semantic/Entity' ;
1617import { SyntaxTreeManager } from '../../../src/context/syntaxtree/SyntaxTreeManager' ;
1718import { ResourceSectionHoverProvider } from '../../../src/hover/ResourceSectionHoverProvider' ;
1819import { ResourceSchema } from '../../../src/schema/ResourceSchema' ;
19- import { createResourceContext } from '../../utils/MockContext' ;
20+ import { createMockContext , createResourceContext } from '../../utils/MockContext' ;
2021import { createMockSchemaRetriever } from '../../utils/MockServerComponents' ;
2122import { combinedSchemas , combineSchema , Schemas } from '../../utils/SchemaUtils' ;
2223import { docPosition , Templates } from '../../utils/TemplateUtils' ;
@@ -963,4 +964,89 @@ describe('ResourceSectionHoverProvider', () => {
963964 } ) ;
964965 } ) ;
965966 } ) ;
967+
968+ describe ( 'ForEach Resource Hover' , ( ) => {
969+ function createForEachResourceContext (
970+ text : string ,
971+ resourceType : string ,
972+ properties ?: Record < string , any > ,
973+ propertyPath ?: any [ ] ,
974+ ) : Context {
975+ const nestedResource = new Resource ( 'S3Bucket${BucketName}' , resourceType , properties ) ;
976+
977+ const forEachEntity = new ForEachResource ( 'Buckets' , 'BucketName' , { Ref : 'BucketNames' } , nestedResource ) ;
978+
979+ return createMockContext ( TopLevelSection . Resources , 'Fn::ForEach::Buckets' , {
980+ text,
981+ entity : forEachEntity ,
982+ propertyPath : propertyPath ?? [ 'Resources' , 'Fn::ForEach::Buckets' , 2 , 'S3Bucket${BucketName}' ] ,
983+ } ) ;
984+ }
985+
986+ it ( 'should return documentation for resource type in ForEach' , ( ) => {
987+ const mockContext = createForEachResourceContext ( 'AWS::S3::Bucket' , 'AWS::S3::Bucket' , undefined , [
988+ 'Resources' ,
989+ 'Fn::ForEach::Buckets' ,
990+ 2 ,
991+ 'S3Bucket${BucketName}' ,
992+ 'Type' ,
993+ ] ) ;
994+
995+ const result = hoverProvider . getInformation ( mockContext ) ;
996+
997+ expect ( result ) . toContain ( '### AWS::S3::Bucket' ) ;
998+ expect ( result ) . toContain ( 'The ``AWS::S3::Bucket`` resource creates an Amazon S3 bucket' ) ;
999+ } ) ;
1000+
1001+ it ( 'should return property documentation for ForEach resource property' , ( ) => {
1002+ const properties = { BucketName : 'my-bucket' } ;
1003+ const mockContext = createForEachResourceContext ( 'BucketName' , 'AWS::S3::Bucket' , properties , [
1004+ 'Resources' ,
1005+ 'Fn::ForEach::Buckets' ,
1006+ 2 ,
1007+ 'S3Bucket${BucketName}' ,
1008+ 'Properties' ,
1009+ 'BucketName' ,
1010+ ] ) ;
1011+
1012+ const result = hoverProvider . getInformation ( mockContext ) ;
1013+
1014+ expect ( result ) . toContain ( '```typescript' ) ;
1015+ expect ( result ) . toContain ( 'string' ) ;
1016+ expect ( result ) . toContain ( 'A name for the bucket' ) ;
1017+ } ) ;
1018+
1019+ it ( 'should return nested property documentation for ForEach resource' , ( ) => {
1020+ const properties = {
1021+ VersioningConfiguration : { Status : 'Enabled' } ,
1022+ } ;
1023+ const mockContext = createForEachResourceContext ( 'Status' , 'AWS::S3::Bucket' , properties , [
1024+ 'Resources' ,
1025+ 'Fn::ForEach::Buckets' ,
1026+ 2 ,
1027+ 'S3Bucket${BucketName}' ,
1028+ 'Properties' ,
1029+ 'VersioningConfiguration' ,
1030+ 'Status' ,
1031+ ] ) ;
1032+
1033+ const result = hoverProvider . getInformation ( mockContext ) ;
1034+
1035+ expect ( result ) . toBeDefined ( ) ;
1036+ expect ( result ) . toContain ( 'Status' ) ;
1037+ } ) ;
1038+
1039+ it ( 'should return undefined when ForEach resource has no nested resource' , ( ) => {
1040+ const forEachEntity = new ForEachResource ( 'Buckets' , 'BucketName' , { Ref : 'BucketNames' } , undefined ) ;
1041+
1042+ const mockContext = createMockContext ( TopLevelSection . Resources , 'Fn::ForEach::Buckets' , {
1043+ text : 'AWS::S3::Bucket' ,
1044+ entity : forEachEntity ,
1045+ } ) ;
1046+
1047+ const result = hoverProvider . getInformation ( mockContext ) ;
1048+
1049+ expect ( result ) . toBeUndefined ( ) ;
1050+ } ) ;
1051+ } ) ;
9661052} ) ;
0 commit comments