@@ -2,7 +2,14 @@ import { describe, it, expect, beforeAll, afterAll } from 'vitest';
22import { Context } from '../../../src/context/Context' ;
33import { ContextManager } from '../../../src/context/ContextManager' ;
44import { TopLevelSection } from '../../../src/context/ContextType' ;
5- import { Parameter , Resource , Condition , Mapping , Unknown } from '../../../src/context/semantic/Entity' ;
5+ import {
6+ Parameter ,
7+ Resource ,
8+ Condition ,
9+ Mapping ,
10+ Unknown ,
11+ ForEachResource ,
12+ } from '../../../src/context/semantic/Entity' ;
613import { SyntaxTreeManager } from '../../../src/context/syntaxtree/SyntaxTreeManager' ;
714import { docPosition , Templates } from '../../utils/TemplateUtils' ;
815
@@ -679,4 +686,111 @@ Resources:
679686 expect ( context ! . textInQuotes ( ) ) . toBeUndefined ( ) ;
680687 } ) ;
681688 } ) ;
689+
690+ describe ( 'ForEachResource Entity Parsing' , ( ) => {
691+ const foreachYamlUri = Templates . foreach . yaml . fileName ;
692+ const foreachJsonUri = Templates . foreach . json . fileName ;
693+ const foreachYaml = Templates . foreach . yaml . contents ;
694+ const foreachJson = Templates . foreach . json . contents ;
695+
696+ beforeAll ( ( ) => {
697+ syntaxTreeManager . add ( foreachYamlUri , foreachYaml ) ;
698+ syntaxTreeManager . add ( foreachJsonUri , foreachJson ) ;
699+ } ) ;
700+
701+ describe ( 'YAML ForEach' , ( ) => {
702+ it ( 'should parse ForEach resource name' , ( ) => {
703+ const context = getContextAt ( 11 , 4 , foreachYamlUri ) ; // Position at "Fn::ForEach::Buckets:"
704+
705+ expect ( context ) . toBeDefined ( ) ;
706+ expect ( context ! . section ) . toBe ( TopLevelSection . Resources ) ;
707+ expect ( context ! . logicalId ) . toBe ( 'Fn::ForEach::Buckets' ) ;
708+ expect ( context ! . text ) . toBe ( 'Fn::ForEach::Buckets' ) ;
709+ } ) ;
710+
711+ it ( 'should create ForEachResource entity with correct properties' , ( ) => {
712+ const context = getContextAt ( 11 , 4 , foreachYamlUri ) ; // Fn::ForEach::Buckets
713+
714+ expect ( context ) . toBeDefined ( ) ;
715+ const entity = context ! . entity ;
716+ expect ( entity ) . toBeInstanceOf ( ForEachResource ) ;
717+
718+ const forEachResource = entity as ForEachResource ;
719+ expect ( forEachResource . name ) . toBe ( 'Buckets' ) ;
720+ expect ( forEachResource . identifier ) . toBe ( 'BucketName' ) ;
721+ expect ( forEachResource . collection ) . toBeDefined ( ) ;
722+ expect ( forEachResource . collection ) . toHaveProperty ( '!Ref' , 'BucketNames' ) ;
723+ expect ( forEachResource . resource ) . toBeInstanceOf ( Resource ) ;
724+ } ) ;
725+
726+ it ( 'should parse nested resource in ForEach' , ( ) => {
727+ const context = getContextAt ( 11 , 4 , foreachYamlUri ) ;
728+
729+ expect ( context ) . toBeDefined ( ) ;
730+ const entity = context ! . entity as ForEachResource ;
731+ const nestedResource = entity . resource ;
732+
733+ expect ( nestedResource ) . toBeInstanceOf ( Resource ) ;
734+ expect ( nestedResource ?. name ) . toBe ( 'S3Bucket${BucketName}' ) ;
735+ expect ( nestedResource ?. Type ) . toBe ( 'AWS::S3::Bucket' ) ;
736+ expect ( nestedResource ?. Properties ) . toBeDefined ( ) ;
737+ expect ( nestedResource ?. Properties ) . toHaveProperty ( 'BucketName' ) ;
738+ expect ( nestedResource ?. Properties ) . toHaveProperty ( 'VersioningConfiguration' ) ;
739+ expect ( nestedResource ?. Properties ?. VersioningConfiguration ) . toHaveProperty ( 'Status' , 'Enabled' ) ;
740+ expect ( nestedResource ?. Properties ) . toHaveProperty ( 'BucketEncryption' ) ;
741+ } ) ;
742+
743+ it ( 'should parse regular resource after ForEach' , ( ) => {
744+ const context = getContextAt ( 26 , 4 , foreachYamlUri ) ; // Position at "RegularResource:"
745+
746+ expect ( context ) . toBeDefined ( ) ;
747+ expect ( context ! . section ) . toBe ( TopLevelSection . Resources ) ;
748+ expect ( context ! . logicalId ) . toBe ( 'RegularResource' ) ;
749+ expect ( context ! . entity ) . toBeInstanceOf ( Resource ) ;
750+ expect ( context ! . entity ) . not . toBeInstanceOf ( ForEachResource ) ;
751+ } ) ;
752+ } ) ;
753+
754+ describe ( 'JSON ForEach' , ( ) => {
755+ it ( 'should parse ForEach resource name in JSON' , ( ) => {
756+ const context = getContextAt ( 12 , 8 , foreachJsonUri ) ; // Position at "Fn::ForEach::Buckets"
757+
758+ expect ( context ) . toBeDefined ( ) ;
759+ expect ( context ! . section ) . toBe ( TopLevelSection . Resources ) ;
760+ expect ( context ! . logicalId ) . toBe ( 'Fn::ForEach::Buckets' ) ;
761+ } ) ;
762+
763+ it ( 'should create ForEachResource entity from JSON' , ( ) => {
764+ const context = getContextAt ( 12 , 8 , foreachJsonUri ) ;
765+
766+ expect ( context ) . toBeDefined ( ) ;
767+ const entity = context ! . entity ;
768+ expect ( entity ) . toBeInstanceOf ( ForEachResource ) ;
769+
770+ const forEachResource = entity as ForEachResource ;
771+ expect ( forEachResource . name ) . toBe ( 'Buckets' ) ;
772+ expect ( forEachResource . identifier ) . toBe ( 'BucketName' ) ;
773+ expect ( forEachResource . collection ) . toBeDefined ( ) ;
774+ expect ( forEachResource . collection ) . toHaveProperty ( 'Ref' , 'BucketNames' ) ;
775+ expect ( forEachResource . resource ) . toBeInstanceOf ( Resource ) ;
776+ } ) ;
777+
778+ it ( 'should parse nested resource in JSON ForEach' , ( ) => {
779+ const context = getContextAt ( 12 , 8 , foreachJsonUri ) ;
780+
781+ expect ( context ) . toBeDefined ( ) ;
782+ const entity = context ! . entity as ForEachResource ;
783+ const nestedResource = entity . resource ;
784+
785+ expect ( nestedResource ) . toBeInstanceOf ( Resource ) ;
786+ expect ( nestedResource ?. name ) . toBe ( 'S3Bucket${BucketName}' ) ;
787+ expect ( nestedResource ?. Type ) . toBe ( 'AWS::S3::Bucket' ) ;
788+ expect ( nestedResource ?. Properties ) . toBeDefined ( ) ;
789+ expect ( nestedResource ?. Properties ) . toHaveProperty ( 'BucketName' ) ;
790+ expect ( nestedResource ?. Properties ?. BucketName ) . toHaveProperty ( 'Fn::Sub' ) ;
791+ expect ( nestedResource ?. Properties ) . toHaveProperty ( 'VersioningConfiguration' ) ;
792+ expect ( nestedResource ?. Properties ?. VersioningConfiguration ) . toHaveProperty ( 'Status' , 'Enabled' ) ;
793+ } ) ;
794+ } ) ;
795+ } ) ;
682796} ) ;
0 commit comments