|
| 1 | +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| 2 | +// SPDX-License-Identifier: Apache-2.0 |
| 3 | +import { expect, test, beforeAll } from 'vitest'; |
| 4 | +import { ComponentDefinition } from '../../src/components/interfaces'; |
| 5 | +import { buildProject } from './test-helpers'; |
| 6 | + |
| 7 | +let codeEditor: ComponentDefinition; |
| 8 | + |
| 9 | +beforeAll(() => { |
| 10 | + const result = buildProject('string-intersection'); |
| 11 | + expect(result).toHaveLength(1); |
| 12 | + [codeEditor] = result; |
| 13 | +}); |
| 14 | + |
| 15 | +test('should properly handle union types with string intersection for custom values', () => { |
| 16 | + const languageProp = codeEditor.properties.find(def => def.name === 'language'); |
| 17 | + |
| 18 | + expect(languageProp?.name).toBe('language'); |
| 19 | + expect(languageProp?.description).toBe('Specifies the programming language.'); |
| 20 | + expect(languageProp?.optional).toBe(false); |
| 21 | + expect(languageProp?.type).toBe('string'); |
| 22 | + |
| 23 | + // Check inline type structure |
| 24 | + expect(languageProp?.inlineType?.name).toBe('CodeEditorProps.Language'); |
| 25 | + expect(languageProp?.inlineType?.type).toBe('union'); |
| 26 | + if (languageProp?.inlineType?.type === 'union') { |
| 27 | + expect(languageProp.inlineType.valueDescriptions).toBeUndefined(); |
| 28 | + } |
| 29 | + |
| 30 | + // The intersection type "string & { _?: undefined; }" should be converted to "string" |
| 31 | + // String literal values should appear without quotes |
| 32 | + const values = (languageProp?.inlineType as any)?.values; |
| 33 | + expect(values).toHaveLength(6); |
| 34 | + expect(values).toContain('javascript'); |
| 35 | + expect(values).toContain('html'); |
| 36 | + expect(values).toContain('ruby'); |
| 37 | + expect(values).toContain('python'); |
| 38 | + expect(values).toContain('java'); |
| 39 | + expect(values).toContain('string'); // The intersection type becomes "string" to indicate custom values are allowed |
| 40 | +}); |
| 41 | + |
| 42 | +test('should treat the union as primitive string type', () => { |
| 43 | + const languageProp = codeEditor.properties.find(def => def.name === 'language'); |
| 44 | + |
| 45 | + // The type should be 'string' not the full union name |
| 46 | + expect(languageProp?.type).toBe('string'); |
| 47 | +}); |
| 48 | + |
| 49 | +test('should convert intersection helper to "string" in values array', () => { |
| 50 | + const languageProp = codeEditor.properties.find(def => def.name === 'language'); |
| 51 | + |
| 52 | + // Should not contain the raw "string & { _?: undefined; }" syntax |
| 53 | + const hasRawIntersectionType = |
| 54 | + languageProp?.inlineType?.type === 'union' && |
| 55 | + languageProp.inlineType.values.some((value: string) => value.includes('string &') || value.includes('_?:')); |
| 56 | + |
| 57 | + expect(hasRawIntersectionType).toBe(false); |
| 58 | + |
| 59 | + // But should contain "string" to indicate custom values are allowed |
| 60 | + const hasStringValue = |
| 61 | + languageProp?.inlineType?.type === 'union' && languageProp.inlineType.values.includes('string'); |
| 62 | + |
| 63 | + expect(hasStringValue).toBe(true); |
| 64 | +}); |
| 65 | + |
| 66 | +test('should detect intersection types with string & pattern', () => { |
| 67 | + const languageProp = codeEditor.properties.find(def => def.name === 'language'); |
| 68 | + |
| 69 | + // Verify that the union contains both string literals and the intersection type |
| 70 | + expect(languageProp?.inlineType?.type).toBe('union'); |
| 71 | + |
| 72 | + if (languageProp?.inlineType?.type === 'union') { |
| 73 | + const values = languageProp.inlineType.values; |
| 74 | + |
| 75 | + // Should have the literal values |
| 76 | + expect(values).toContain('javascript'); |
| 77 | + expect(values).toContain('html'); |
| 78 | + expect(values).toContain('ruby'); |
| 79 | + expect(values).toContain('python'); |
| 80 | + expect(values).toContain('java'); |
| 81 | + |
| 82 | + // Should have 'string' representing the intersection type |
| 83 | + expect(values).toContain('string'); |
| 84 | + |
| 85 | + // All values should be treated as string type (primitive detection) |
| 86 | + expect(languageProp.type).toBe('string'); |
| 87 | + } |
| 88 | +}); |
| 89 | + |
| 90 | +test('should recognize intersection type as string-compatible', () => { |
| 91 | + const languageProp = codeEditor.properties.find(def => def.name === 'language'); |
| 92 | + |
| 93 | + // The union with intersection type should be recognized as primitive string |
| 94 | + expect(languageProp?.type).toBe('string'); |
| 95 | + |
| 96 | + if (languageProp?.inlineType?.type === 'union') { |
| 97 | + // All values in the union should be compatible with string type |
| 98 | + const allValuesAreStrings = languageProp.inlineType.values.every((value: string) => typeof value === 'string'); |
| 99 | + expect(allValuesAreStrings).toBe(true); |
| 100 | + } |
| 101 | +}); |
0 commit comments