generated from amazon-archives/__template_Apache-2.0
-
Notifications
You must be signed in to change notification settings - Fork 4
fix: display clean string literal values without quotes in docs #101
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
Open
Who-is-PS
wants to merge
10
commits into
main
Choose a base branch
from
dev-v3-philosr-language-selector
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 all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
3e84354
fix: display clean string literal values without quotes in docs
Who-is-PS 9d3c8e6
fix: linting issues
Who-is-PS 9cbf1a6
fix: union type display for string intersections
Who-is-PS cae3923
Merge branch 'main' into dev-v3-philosr-language-selector
Who-is-PS fbfb6c6
add: new unit test for union type display
Who-is-PS 7dc6300
fix: update object-definition test to use existing fixture
Who-is-PS d338fe8
improve: expand object-definition tests for better coverage
Who-is-PS 3d00ef8
fix: add new test
Who-is-PS 4666fec
Add tests for string intersection type handling and fix tsconfig
Who-is-PS afa61e9
fix: remove unnecessary comments
Who-is-PS 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
21 changes: 21 additions & 0 deletions
21
fixtures/components/string-intersection/code-editor/index.tsx
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 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| import * as React from 'react'; | ||
|
|
||
| export namespace CodeEditorProps { | ||
| // This simulates the pattern used in the code editor where we want: | ||
| // 1. Autocomplete for known language literals | ||
| // 2. Allow custom string values | ||
| export type Language = 'javascript' | 'html' | 'ruby' | 'python' | 'java' | (string & { _?: undefined }); | ||
| } | ||
|
|
||
| export interface CodeEditorProps { | ||
| /** | ||
| * Specifies the programming language. | ||
| */ | ||
| language: CodeEditorProps.Language; | ||
| } | ||
|
|
||
| export default function CodeEditor({ language }: CodeEditorProps) { | ||
| return <div data-language={language}>Code Editor</div>; | ||
| } |
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,4 @@ | ||
| { | ||
| "extends": "../tsconfig.json", | ||
| "include": ["./**/*.tsx"] | ||
| } |
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,105 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| import { expect, test, beforeAll } from 'vitest'; | ||
| import { ComponentDefinition } from '../../src/components/interfaces'; | ||
| import { buildProject } from './test-helpers'; | ||
|
|
||
| let simpleComponent: ComponentDefinition; | ||
| let complexTypesComponents: ComponentDefinition[]; | ||
|
|
||
| beforeAll(() => { | ||
| const simpleResult = buildProject('simple'); | ||
| expect(simpleResult).toHaveLength(1); | ||
| [simpleComponent] = simpleResult; | ||
|
|
||
| complexTypesComponents = buildProject('complex-types'); | ||
| expect(complexTypesComponents.length).toBeGreaterThan(0); | ||
| }); | ||
|
|
||
| test('object definition should handle basic types', () => { | ||
| expect(simpleComponent.name).toBe('Simple'); | ||
| expect(simpleComponent.properties).toBeDefined(); | ||
| }); | ||
|
|
||
| test('object definition should handle union types correctly', () => { | ||
| // Find a component with union types | ||
| const componentWithUnions = complexTypesComponents.find(comp => | ||
| comp.properties.some(prop => prop.inlineType?.type === 'union') | ||
| ); | ||
|
|
||
| if (componentWithUnions) { | ||
| const unionProp = componentWithUnions.properties.find(def => def.inlineType?.type === 'union'); | ||
|
|
||
| if (unionProp?.inlineType?.type === 'union') { | ||
| expect(unionProp.inlineType.values).toBeDefined(); | ||
| expect(Array.isArray(unionProp.inlineType.values)).toBe(true); | ||
| expect(unionProp.inlineType.values.length).toBeGreaterThan(0); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| test('object definition should handle string literal unions', () => { | ||
| // Test string literal union handling | ||
| const componentWithStringUnions = complexTypesComponents.find(comp => | ||
| comp.properties.some(prop => prop.inlineType?.type === 'union' && prop.type === 'string') | ||
| ); | ||
|
|
||
| if (componentWithStringUnions) { | ||
| const stringUnionProp = componentWithStringUnions.properties.find( | ||
| prop => prop.inlineType?.type === 'union' && prop.type === 'string' | ||
| ); | ||
|
|
||
| if (stringUnionProp?.inlineType?.type === 'union') { | ||
| expect(stringUnionProp.type).toBe('string'); | ||
| expect(stringUnionProp.inlineType.values).toBeDefined(); | ||
| // Should contain string values | ||
| expect(stringUnionProp.inlineType.values.some(v => typeof v === 'string')).toBe(true); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| test('object definition should handle number literal unions', () => { | ||
| // Test number literal union handling | ||
| const componentWithNumberUnions = complexTypesComponents.find(comp => | ||
| comp.properties.some(prop => prop.inlineType?.type === 'union' && prop.type === 'number') | ||
| ); | ||
|
|
||
| if (componentWithNumberUnions) { | ||
| const numberUnionProp = componentWithNumberUnions.properties.find( | ||
| prop => prop.inlineType?.type === 'union' && prop.type === 'number' | ||
| ); | ||
|
|
||
| if (numberUnionProp?.inlineType?.type === 'union') { | ||
| expect(numberUnionProp.type).toBe('number'); | ||
| expect(numberUnionProp.inlineType.values).toBeDefined(); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| test('object definition should preserve type information', () => { | ||
| const props = simpleComponent.properties; | ||
| expect(props.length).toBeGreaterThan(0); | ||
|
|
||
| props.forEach(prop => { | ||
| expect(prop.name).toBeDefined(); | ||
| expect(prop.type).toBeDefined(); | ||
| }); | ||
| }); | ||
|
|
||
| test('object definition should handle mixed union types', () => { | ||
| // Test mixed union types (not primitive) | ||
| const componentWithMixedUnions = complexTypesComponents.find(comp => | ||
| comp.properties.some(prop => prop.inlineType?.type === 'union' && prop.type !== 'string' && prop.type !== 'number') | ||
| ); | ||
|
|
||
| if (componentWithMixedUnions) { | ||
| const mixedUnionProp = componentWithMixedUnions.properties.find( | ||
| prop => prop.inlineType?.type === 'union' && prop.type !== 'string' && prop.type !== 'number' | ||
| ); | ||
|
|
||
| if (mixedUnionProp?.inlineType?.type === 'union') { | ||
| expect(mixedUnionProp.inlineType.values).toBeDefined(); | ||
| expect(mixedUnionProp.inlineType.name).toBeDefined(); | ||
| } | ||
| } | ||
| }); |
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,101 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| import { expect, test, beforeAll } from 'vitest'; | ||
| import { ComponentDefinition } from '../../src/components/interfaces'; | ||
| import { buildProject } from './test-helpers'; | ||
|
|
||
| let codeEditor: ComponentDefinition; | ||
|
|
||
| beforeAll(() => { | ||
| const result = buildProject('string-intersection'); | ||
| expect(result).toHaveLength(1); | ||
| [codeEditor] = result; | ||
| }); | ||
|
|
||
| test('should properly handle union types with string intersection for custom values', () => { | ||
| const languageProp = codeEditor.properties.find(def => def.name === 'language'); | ||
|
|
||
| expect(languageProp?.name).toBe('language'); | ||
| expect(languageProp?.description).toBe('Specifies the programming language.'); | ||
| expect(languageProp?.optional).toBe(false); | ||
| expect(languageProp?.type).toBe('string'); | ||
|
|
||
| // Check inline type structure | ||
| expect(languageProp?.inlineType?.name).toBe('CodeEditorProps.Language'); | ||
| expect(languageProp?.inlineType?.type).toBe('union'); | ||
| if (languageProp?.inlineType?.type === 'union') { | ||
| expect(languageProp.inlineType.valueDescriptions).toBeUndefined(); | ||
| } | ||
|
|
||
| // The intersection type "string & { _?: undefined; }" should be converted to "string" | ||
| // String literal values should appear without quotes | ||
| const values = (languageProp?.inlineType as any)?.values; | ||
| expect(values).toHaveLength(6); | ||
| expect(values).toContain('javascript'); | ||
| expect(values).toContain('html'); | ||
| expect(values).toContain('ruby'); | ||
| expect(values).toContain('python'); | ||
| expect(values).toContain('java'); | ||
| expect(values).toContain('string'); // The intersection type becomes "string" to indicate custom values are allowed | ||
| }); | ||
|
|
||
| test('should treat the union as primitive string type', () => { | ||
| const languageProp = codeEditor.properties.find(def => def.name === 'language'); | ||
|
|
||
| // The type should be 'string' not the full union name | ||
| expect(languageProp?.type).toBe('string'); | ||
| }); | ||
|
|
||
| test('should convert intersection helper to "string" in values array', () => { | ||
| const languageProp = codeEditor.properties.find(def => def.name === 'language'); | ||
|
|
||
| // Should not contain the raw "string & { _?: undefined; }" syntax | ||
| const hasRawIntersectionType = | ||
| languageProp?.inlineType?.type === 'union' && | ||
| languageProp.inlineType.values.some((value: string) => value.includes('string &') || value.includes('_?:')); | ||
|
|
||
| expect(hasRawIntersectionType).toBe(false); | ||
|
|
||
| // But should contain "string" to indicate custom values are allowed | ||
| const hasStringValue = | ||
| languageProp?.inlineType?.type === 'union' && languageProp.inlineType.values.includes('string'); | ||
|
|
||
| expect(hasStringValue).toBe(true); | ||
| }); | ||
|
|
||
| test('should detect intersection types with string & pattern', () => { | ||
| const languageProp = codeEditor.properties.find(def => def.name === 'language'); | ||
|
|
||
| // Verify that the union contains both string literals and the intersection type | ||
| expect(languageProp?.inlineType?.type).toBe('union'); | ||
|
|
||
| if (languageProp?.inlineType?.type === 'union') { | ||
| const values = languageProp.inlineType.values; | ||
|
|
||
| // Should have the literal values | ||
| expect(values).toContain('javascript'); | ||
| expect(values).toContain('html'); | ||
| expect(values).toContain('ruby'); | ||
| expect(values).toContain('python'); | ||
| expect(values).toContain('java'); | ||
|
|
||
| // Should have 'string' representing the intersection type | ||
| expect(values).toContain('string'); | ||
|
|
||
| // All values should be treated as string type (primitive detection) | ||
| expect(languageProp.type).toBe('string'); | ||
| } | ||
| }); | ||
|
|
||
| test('should recognize intersection type as string-compatible', () => { | ||
| const languageProp = codeEditor.properties.find(def => def.name === 'language'); | ||
|
|
||
| // The union with intersection type should be recognized as primitive string | ||
| expect(languageProp?.type).toBe('string'); | ||
|
|
||
| if (languageProp?.inlineType?.type === 'union') { | ||
| // All values in the union should be compatible with string type | ||
| const allValuesAreStrings = languageProp.inlineType.values.every((value: string) => typeof value === 'string'); | ||
| expect(allValuesAreStrings).toBe(true); | ||
| } | ||
| }); | ||
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.
I don't think that this is a valid representation of the type. For example, if we follow this through to the website, it would suggest that there would be an item "string" in the language selector dropdown, but that is not valid, as it's not a literal value, it's a type. We need to retain that differentiation between literal values and types in the documenter output.
The more that I think about this problem, the more that I think the problem is maybe not actually in the documenter but in the website: the documenter is currently generating output that accurately represents the underlying typings, the website just needs some extra logic to be able to handle some of the edge-cases better