Skip to content

Commit

Permalink
Merge pull request #12665 from lachieh/next
Browse files Browse the repository at this point in the history
Addon-docs: Fix type aliases and enum types from Angular Compodoc JSON
  • Loading branch information
shilman committed Dec 1, 2020
2 parents aec333f + 598591e commit 209dafb
Show file tree
Hide file tree
Showing 7 changed files with 259 additions and 5 deletions.
96 changes: 94 additions & 2 deletions addons/docs/src/frameworks/angular/compodoc.test.ts
@@ -1,5 +1,5 @@
import { extractType } from './compodoc';
import { Decorator } from './types';
import { extractType, setCompodocJson } from './compodoc';
import { CompodocJson, Decorator } from './types';

const makeProperty = (compodocType?: string) => ({
type: compodocType,
Expand All @@ -8,8 +8,96 @@ const makeProperty = (compodocType?: string) => ({
optional: true,
});

const getDummyCompodocJson = () => {
return {
miscellaneous: {
typealiases: [
{
name: 'EnumAlias',
ctype: 'miscellaneous',
subtype: 'typealias',
rawtype: 'EnumNumeric',
file: 'src/stories/component-with-enums/enums.component.ts',
description: '',
kind: 161,
},
{
name: 'TypeAlias',
ctype: 'miscellaneous',
subtype: 'typealias',
rawtype: '"Type Alias 1" | "Type Alias 2" | "Type Alias 3"',
file: 'src/stories/component-with-enums/enums.component.ts',
description: '',
kind: 168,
},
],
enumerations: [
{
name: 'EnumNumeric',
childs: [
{
name: 'FIRST',
},
{
name: 'SECOND',
},
{
name: 'THIRD',
},
],
ctype: 'miscellaneous',
subtype: 'enum',
description: '<p>Button Priority</p>\n',
file: 'src/stories/component-with-enums/enums.component.ts',
},
{
name: 'EnumNumericInitial',
childs: [
{
name: 'UNO',
value: '1',
},
{
name: 'DOS',
},
{
name: 'TRES',
},
],
ctype: 'miscellaneous',
subtype: 'enum',
description: '',
file: 'src/stories/component-with-enums/enums.component.ts',
},
{
name: 'EnumStringValues',
childs: [
{
name: 'PRIMARY',
value: 'PRIMARY',
},
{
name: 'SECONDARY',
value: 'SECONDARY',
},
{
name: 'TERTIARY',
value: 'TERTIARY',
},
],
ctype: 'miscellaneous',
subtype: 'enum',
description: '',
file: 'src/stories/component-with-enums/enums.component.ts',
},
],
},
} as CompodocJson;
};

describe('extractType', () => {
describe('with compodoc type', () => {
setCompodocJson(getDummyCompodocJson());
it.each([
['string', { name: 'string' }],
['boolean', { name: 'boolean' }],
Expand All @@ -21,6 +109,10 @@ describe('extractType', () => {
['T[]', { name: 'object' }],
['[]', { name: 'object' }],
['"primary" | "secondary"', { name: 'enum', value: ['primary', 'secondary'] }],
['TypeAlias', { name: 'enum', value: ['Type Alias 1', 'Type Alias 2', 'Type Alias 3'] }],
['EnumNumeric', { name: 'object' }],
['EnumNumericInitial', { name: 'object' }],
['EnumStringValues', { name: 'enum', value: ['PRIMARY', 'SECONDARY', 'TERTIARY'] }],
])('%s', (compodocType, expected) => {
expect(extractType(makeProperty(compodocType), null)).toEqual(expected);
});
Expand Down
20 changes: 17 additions & 3 deletions addons/docs/src/frameworks/angular/compodoc.ts
Expand Up @@ -25,7 +25,7 @@ export const setCompodocJson = (compodocJson: CompodocJson) => {
};

// @ts-ignore
export const getCompdocJson = (): CompodocJson => window.__STORYBOOK_COMPODOC_JSON__;
export const getCompodocJson = (): CompodocJson => window.__STORYBOOK_COMPODOC_JSON__;

export const checkValidComponentOrDirective = (component: Component | Directive) => {
if (!component.name) {
Expand Down Expand Up @@ -90,7 +90,7 @@ const getComponentData = (component: Component | Directive) => {
return null;
}
checkValidComponentOrDirective(component);
const compodocJson = getCompdocJson();
const compodocJson = getCompodocJson();
checkValidCompodocJson(compodocJson);
const { name } = component;
const metadata = findComponentByName(name, compodocJson);
Expand All @@ -113,6 +113,13 @@ const extractTypeFromValue = (defaultValue: any) => {
};

const extractEnumValues = (compodocType: any) => {
const compodocJson = getCompodocJson();
const enumType = compodocJson?.miscellaneous.enumerations.find((x) => x.name === compodocType);

if (enumType?.childs.every((x) => x.value)) {
return enumType.childs.map((x) => x.value);
}

if (typeof compodocType !== 'string' || compodocType.indexOf('|') === -1) {
return null;
}
Expand All @@ -135,7 +142,8 @@ export const extractType = (property: Property, defaultValue: any) => {
case null:
return { name: 'void' };
default: {
const enumValues = extractEnumValues(compodocType);
const resolvedType = resolveTypealias(compodocType);
const enumValues = extractEnumValues(resolvedType);
return enumValues ? { name: 'enum', value: enumValues } : { name: 'object' };
}
}
Expand All @@ -152,6 +160,12 @@ const extractDefaultValue = (property: Property) => {
}
};

const resolveTypealias = (compodocType: string): string => {
const compodocJson = getCompodocJson();
const typeAlias = compodocJson?.miscellaneous.typealiases.find((x) => x.name === compodocType);
return typeAlias ? resolveTypealias(typeAlias.rawtype) : compodocType;
};

export const extractArgTypesFromData = (componentData: Class | Directive | Injectable | Pipe) => {
const sectionToItems: Record<string, ArgType[]> = {};
const compodocClasses = ['component', 'directive'].includes(componentData.type)
Expand Down
30 changes: 30 additions & 0 deletions addons/docs/src/frameworks/angular/types.ts
Expand Up @@ -66,10 +66,40 @@ export interface Decorator {
name: string;
}

export interface TypeAlias {
name: string;
ctype: string;
subtype: string;
rawtype: string;
file: string;
kind: number;
description?: string;
rawdescription?: string;
}

export interface EnumType {
name: string;
childs: EnumTypeChild[];
ctype: string;
subtype: string;
file: string;
description?: string;
rawdescription?: string;
}

export interface EnumTypeChild {
name: string;
value?: string;
}

export interface CompodocJson {
directives: Directive[];
components: Component[];
pipes: Pipe[];
injectables: Injectable[];
classes: Class[];
miscellaneous?: {
typealiases?: TypeAlias[];
enumerations?: EnumType[];
};
}
@@ -0,0 +1,32 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Storyshots Enum Types Basic 1`] = `
<storybook-dynamic-app-root
cfr={[Function CodegenComponentFactoryResolver]}
data={[Function Object]}
target={[Function ViewContainerRef_]}
>
<app-enums>
<div>
<div>
unionType: union a
</div>
<div>
aliasedUnionType: Type Alias 1
</div>
<div>
enumNumeric:
</div>
<div>
enumNumericInitial: 1
</div>
<div>
enumStrings: PRIMARY
</div>
<div>
enumAlias:
</div>
</div>
</app-enums>
</storybook-dynamic-app-root>
`;
@@ -0,0 +1,8 @@
<div>
<div>unionType: {{ unionType }}</div>
<div>aliasedUnionType: {{ aliasedUnionType }}</div>
<div>enumNumeric: {{ enumNumeric }}</div>
<div>enumNumericInitial: {{ enumNumericInitial }}</div>
<div>enumStrings: {{ enumStrings }}</div>
<div>enumAlias: {{ enumAlias }}</div>
</div>
@@ -0,0 +1,25 @@
import { Story, Meta } from '@storybook/angular';
import {
EnumsComponent,
EnumNumeric,
EnumNumericInitial,
EnumStringValues,
} from './enums.component';

export default {
title: 'Enum Types',
component: EnumsComponent,
} as Meta;

export const Basic: Story = (args) => ({
component: EnumsComponent,
props: args,
});
Basic.args = {
unionType: 'union a',
aliasedUnionType: 'Type Alias 1',
enumNumeric: EnumNumeric.FIRST,
enumNumericInitial: EnumNumericInitial.UNO,
enumStrings: EnumStringValues.PRIMARY,
enumAlias: EnumNumeric.FIRST,
};
@@ -0,0 +1,53 @@
import { Component, Input } from '@angular/core';

/**
* This component is used for testing the various forms of enum types
*/
@Component({
selector: 'app-enums',
templateUrl: './enums.component.html',
})
export class EnumsComponent {
/** Union Type of string literals */
@Input() unionType: 'Union A' | 'Union B' | 'Union C';

/** Union Type assigned as a Type Alias */
@Input() aliasedUnionType: TypeAlias;

/** Base Enum Type with no assigned values */
@Input() enumNumeric: EnumNumeric;

/** Enum with initial numeric value and auto-incrementing subsequent values */
@Input() enumNumericInitial: EnumNumericInitial;

/** Enum with string values */
@Input() enumStrings: EnumStringValues;

/** Type Aliased Enum Type */
@Input() enumAlias: EnumAlias;
}

/**
* Button Priority
*/
export enum EnumNumeric {
FIRST,
SECOND,
THIRD,
}

export enum EnumNumericInitial {
UNO = 1,
DOS,
TRES,
}

export enum EnumStringValues {
PRIMARY = 'PRIMARY',
SECONDARY = 'SECONDARY',
TERTIARY = 'TERTIARY',
}

export type EnumAlias = EnumNumeric;

type TypeAlias = 'Type Alias 1' | 'Type Alias 2' | 'Type Alias 3';

0 comments on commit 209dafb

Please sign in to comment.