generated from amazon-archives/__template_Apache-2.0
-
Notifications
You must be signed in to change notification settings - Fork 1
feat: add hover for output section fields #16
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
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
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
There are no files selected for viewing
This file contains hidden or 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,50 @@ | ||
| export const outputSectionFieldDocsMap = getOutputSectionFieldDocsMap(); | ||
|
|
||
| function getOutputSectionFieldDocsMap(): Map<string, string> { | ||
| const outputSectionFieldDocsMap = new Map<string, string>(); | ||
|
|
||
| outputSectionFieldDocsMap.set( | ||
| 'Description', | ||
| [ | ||
| '**Description (optional)**', | ||
| '\n', | ||
| '---', | ||
| 'A `String` type that describes the output value. ', | ||
| "The value for the description declaration must be a literal string that's between 0 and 1024 bytes in length. ", | ||
| "You can't use a parameter or function to specify the description. ", | ||
| '\n', | ||
| '[Source Documentation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html)', | ||
| ].join('\n'), | ||
| ); | ||
|
|
||
| outputSectionFieldDocsMap.set( | ||
| 'Value', | ||
| [ | ||
| '**Value (required)**', | ||
| '\n', | ||
| '---', | ||
| 'The value of the property returned by the [describe-stacks](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/service_code_examples.html#describe-stacks-sdk) command. ', | ||
| 'The value of an output can include literals, parameter references, pseudo parameters, a mapping value, or intrinsic functions. ', | ||
| '\n', | ||
| '[Source Documentation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html)', | ||
| ].join('\n'), | ||
| ); | ||
|
|
||
| outputSectionFieldDocsMap.set( | ||
| 'Export', | ||
| [ | ||
| '**Export (optional)**', | ||
| '\n', | ||
| '---', | ||
| 'The name of the resource output to be exported for a cross-stack reference.', | ||
| '\n', | ||
| 'You can use intrinsic functions to customize the Name value of an export. ', | ||
| '\n', | ||
| 'For more information, see [Get exported outputs from a deployed CloudFormation stack](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-stack-exports.html). ', | ||
| '\n', | ||
| '[Source Documentation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html)', | ||
| ].join('\n'), | ||
| ); | ||
|
|
||
| return outputSectionFieldDocsMap; | ||
| } | ||
This file contains hidden or 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 hidden or 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,21 @@ | ||
| import { outputSectionFieldDocsMap } from '../artifacts/OutputSectionFieldDocs'; | ||
| import { Context } from '../context/Context'; | ||
| import { HoverProvider } from './HoverProvider'; | ||
|
|
||
| export class OutputSectionFieldHoverProvider implements HoverProvider { | ||
| private static readonly OUTPUT_SECTION_FIELDS = new Set(['Description', 'Value', 'Export']); | ||
|
|
||
| getInformation(context: Context): string | undefined { | ||
| const attributeName = context.text; | ||
|
|
||
| if (!OutputSectionFieldHoverProvider.OUTPUT_SECTION_FIELDS.has(attributeName)) { | ||
| return undefined; | ||
| } | ||
|
|
||
| return outputSectionFieldDocsMap.get(attributeName); | ||
| } | ||
|
|
||
| static isOutputSectionField(text: string): boolean { | ||
| return OutputSectionFieldHoverProvider.OUTPUT_SECTION_FIELDS.has(text); | ||
| } | ||
| } |
This file contains hidden or 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 hidden or 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,173 @@ | ||
| import { describe, it, expect } from 'vitest'; | ||
| import { TopLevelSection } from '../../../src/context/ContextType'; | ||
| import { OutputSectionFieldHoverProvider } from '../../../src/hover/OutputSectionFieldHoverProvider'; | ||
| import { createMockContext } from '../../utils/MockContext'; | ||
|
|
||
| describe('OutputSectionFieldHoverProvider', () => { | ||
| const outputSectionFieldHoverProvider = new OutputSectionFieldHoverProvider(); | ||
|
|
||
| describe('Output Section Field Hover', () => { | ||
| it('should return Description documentation when hovering on Description attribute', () => { | ||
| const mockContext = createMockContext(TopLevelSection.Outputs, 'MyOutput', { | ||
| text: 'Description', | ||
| propertyPath: ['Outputs', 'MyOutput', 'Description'], | ||
| }); | ||
|
|
||
| const result = outputSectionFieldHoverProvider.getInformation(mockContext); | ||
|
|
||
| expect(result).toContain('**Description (optional)**'); | ||
| expect(result).toContain('A `String` type that describes the output value'); | ||
| expect(result).toContain('between 0 and 1024 bytes in length'); | ||
| expect(result).toContain("You can't use a parameter or function to specify the description"); | ||
| }); | ||
|
|
||
| it('should return Value documentation when hovering on Value attribute', () => { | ||
| const mockContext = createMockContext(TopLevelSection.Outputs, 'MyOutput', { | ||
| text: 'Value', | ||
| propertyPath: ['Outputs', 'MyOutput', 'Value'], | ||
| }); | ||
|
|
||
| const result = outputSectionFieldHoverProvider.getInformation(mockContext); | ||
|
|
||
| expect(result).toContain('**Value (required)**'); | ||
| expect(result).toContain('The value of the property returned by the [describe-stacks]'); | ||
| expect(result).toContain( | ||
| 'The value of an output can include literals, parameter references, pseudo parameters, a mapping value, or intrinsic functions', | ||
| ); | ||
| }); | ||
|
|
||
| it('should return Export documentation when hovering on Export attribute', () => { | ||
| const mockContext = createMockContext(TopLevelSection.Outputs, 'MyOutput', { | ||
| text: 'Export', | ||
| propertyPath: ['Outputs', 'MyOutput', 'Export'], | ||
| }); | ||
|
|
||
| const result = outputSectionFieldHoverProvider.getInformation(mockContext); | ||
|
|
||
| expect(result).toContain('**Export (optional)**'); | ||
| expect(result).toContain('The name of the resource output to be exported for a cross-stack reference'); | ||
| expect(result).toContain('You can use intrinsic functions to customize the Name value of an export'); | ||
| expect(result).toContain('Get exported outputs from a deployed CloudFormation stack'); | ||
| }); | ||
|
|
||
| it('should return undefined for non-output attributes', () => { | ||
| const mockContext = createMockContext(TopLevelSection.Outputs, 'MyOutput', { | ||
| text: 'InvalidAttribute', | ||
| propertyPath: ['Outputs', 'MyOutput', 'InvalidAttribute'], | ||
| }); | ||
|
|
||
| const result = outputSectionFieldHoverProvider.getInformation(mockContext); | ||
|
|
||
| expect(result).toBeUndefined(); | ||
| }); | ||
|
|
||
| it('should return undefined for empty text', () => { | ||
| const mockContext = createMockContext(TopLevelSection.Outputs, 'MyOutput', { | ||
| text: '', | ||
| propertyPath: ['Outputs', 'MyOutput'], | ||
| }); | ||
|
|
||
| const result = outputSectionFieldHoverProvider.getInformation(mockContext); | ||
|
|
||
| expect(result).toBeUndefined(); | ||
| }); | ||
|
|
||
| it('should return undefined for parameter attributes (case sensitivity)', () => { | ||
| const mockContext = createMockContext(TopLevelSection.Outputs, 'MyOutput', { | ||
| text: 'Type', | ||
| propertyPath: ['Outputs', 'MyOutput', 'Type'], | ||
| }); | ||
|
|
||
| const result = outputSectionFieldHoverProvider.getInformation(mockContext); | ||
|
|
||
| expect(result).toBeUndefined(); | ||
| }); | ||
|
|
||
| it('should return undefined for resource attributes', () => { | ||
| const mockContext = createMockContext(TopLevelSection.Outputs, 'MyOutput', { | ||
| text: 'DependsOn', | ||
| propertyPath: ['Outputs', 'MyOutput', 'DependsOn'], | ||
| }); | ||
|
|
||
| const result = outputSectionFieldHoverProvider.getInformation(mockContext); | ||
|
|
||
| expect(result).toBeUndefined(); | ||
| }); | ||
|
|
||
| it('should be case sensitive for attribute names', () => { | ||
| const mockContext = createMockContext(TopLevelSection.Outputs, 'MyOutput', { | ||
| text: 'description', | ||
| propertyPath: ['Outputs', 'MyOutput', 'description'], | ||
| }); | ||
|
|
||
| const result = outputSectionFieldHoverProvider.getInformation(mockContext); | ||
|
|
||
| expect(result).toBeUndefined(); | ||
| }); | ||
| }); | ||
|
|
||
| describe('isOutputSectionField static method', () => { | ||
| it('should return true for valid output attributes', () => { | ||
| const validAttributes = ['Description', 'Value', 'Export']; | ||
|
|
||
| for (const attribute of validAttributes) { | ||
| expect(OutputSectionFieldHoverProvider.isOutputSectionField(attribute)).toBe(true); | ||
| } | ||
| }); | ||
|
|
||
| it('should return false for invalid output attributes', () => { | ||
| const invalidAttributes = [ | ||
| 'InvalidAttribute', | ||
| 'Type', | ||
| 'Default', | ||
| 'Properties', | ||
| 'Condition', | ||
| 'DependsOn', | ||
| 'description', | ||
| 'value', | ||
| 'export', | ||
| '', | ||
| 'Name', // This is a property of Export, not a top-level output attribute | ||
| ]; | ||
|
|
||
| for (const attribute of invalidAttributes) { | ||
| expect(OutputSectionFieldHoverProvider.isOutputSectionField(attribute)).toBe(false); | ||
| } | ||
| }); | ||
|
|
||
| it('should return false for parameter attributes', () => { | ||
| const parameterAttributes = [ | ||
| 'Type', | ||
| 'Default', | ||
| 'AllowedValues', | ||
| 'AllowedPattern', | ||
| 'MinLength', | ||
| 'MaxLength', | ||
| 'MinValue', | ||
| 'MaxValue', | ||
| 'NoEcho', | ||
| 'ConstraintDescription', | ||
| ]; | ||
|
|
||
| for (const attribute of parameterAttributes) { | ||
| expect(OutputSectionFieldHoverProvider.isOutputSectionField(attribute)).toBe(false); | ||
| } | ||
| }); | ||
|
|
||
| it('should return false for resource attributes', () => { | ||
| const resourceAttributes = [ | ||
| 'CreationPolicy', | ||
| 'DeletionPolicy', | ||
| 'UpdatePolicy', | ||
| 'UpdateReplacePolicy', | ||
| 'Condition', | ||
| 'DependsOn', | ||
| 'Metadata', | ||
| ]; | ||
|
|
||
| for (const attribute of resourceAttributes) { | ||
| expect(OutputSectionFieldHoverProvider.isOutputSectionField(attribute)).toBe(false); | ||
| } | ||
| }); | ||
| }); | ||
| }); |
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.
Uh oh!
There was an error while loading. Please reload this page.