From d6a1cee1129313770150d720e8bc1f8a18ba2fb5 Mon Sep 17 00:00:00 2001 From: Alexander Harris Date: Thu, 20 Jan 2022 17:08:36 -0800 Subject: [PATCH] feat: expose renderThemeJson method to generating themes in studio ui --- ...react-component-render-helper.test.ts.snap | 2 - ...heme-studio-template-renderer.test.ts.snap | 114 ++++++++++++++++++ .../studio-ui-codegen-react.test.ts.snap | 87 ------------- .../react-component-render-helper.test.ts | 3 +- ...act-theme-studio-template-renderer.test.ts | 60 +++++++++ .../__tests__/studio-ui-codegen-react.test.ts | 31 +---- .../react-theme-studio-template-renderer.ts | 14 +++ 7 files changed, 191 insertions(+), 120 deletions(-) create mode 100644 packages/codegen-ui-react/lib/__tests__/__snapshots__/react-theme-studio-template-renderer.test.ts.snap create mode 100644 packages/codegen-ui-react/lib/__tests__/react-theme-studio-template-renderer.test.ts diff --git a/packages/codegen-ui-react/lib/__tests__/__snapshots__/react-component-render-helper.test.ts.snap b/packages/codegen-ui-react/lib/__tests__/__snapshots__/react-component-render-helper.test.ts.snap index 6a1373bce..71fb406c8 100644 --- a/packages/codegen-ui-react/lib/__tests__/__snapshots__/react-component-render-helper.test.ts.snap +++ b/packages/codegen-ui-react/lib/__tests__/__snapshots__/react-component-render-helper.test.ts.snap @@ -296,8 +296,6 @@ exports[`react-component-render-helper buildFixedJsxExpression string wrapped ob exports[`react-component-render-helper buildFixedJsxExpression type mismatch error 1`] = `"Parsed value type \\"boolean\\" and specified type \\"number\\" mismatch"`; -exports[`react-component-render-helper buildFixedJsxExpression unsupported type 1`] = `"Invalid type object for \\"Sun Dec 17 1995 03:24:00 GMT+0000 (Coordinated Universal Time)\\""`; - exports[`react-component-render-helper getSyntaxKindToken eq 1`] = ` TokenObject { "end": -1, diff --git a/packages/codegen-ui-react/lib/__tests__/__snapshots__/react-theme-studio-template-renderer.test.ts.snap b/packages/codegen-ui-react/lib/__tests__/__snapshots__/react-theme-studio-template-renderer.test.ts.snap new file mode 100644 index 000000000..c272f08de --- /dev/null +++ b/packages/codegen-ui-react/lib/__tests__/__snapshots__/react-theme-studio-template-renderer.test.ts.snap @@ -0,0 +1,114 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`react theme renderer tests renderThemeJson should render theme json correctly 1`] = ` +"{ + name: \\"MyTheme\\", + tokens: { + components: { + alert: { + backgroundColor: \\"hsl(210, 5%, 90%)\\", + padding: \\"0.75rem 1rem\\", + info: { backgroundColor: \\"hsl(220, 85%, 85%)\\" }, + error: { backgroundColor: \\"hsl(0, 75%, 85%)\\" }, + warning: { backgroundColor: \\"hsl(30, 75%, 85%)\\" }, + success: { backgroundColor: \\"hsl(130, 75%, 85%)\\" }, + }, + }, + }, + overrides: [ + { + colorMode: \\"dark\\", + tokens: { + colors: { black: { value: \\"#fff\\" }, white: { value: \\"#000\\" } }, + }, + }, + ], +}" +`; + +exports[`react theme renderer tests theme should render the theme 1`] = ` +"/* eslint-disable */ +import { createTheme } from \\"@aws-amplify/ui-react\\"; +export default createTheme({ + name: \\"MyTheme\\", + tokens: { + components: { + alert: { + backgroundColor: \\"hsl(210, 5%, 90%)\\", + padding: \\"0.75rem 1rem\\", + info: { backgroundColor: \\"hsl(220, 85%, 85%)\\" }, + error: { backgroundColor: \\"hsl(0, 75%, 85%)\\" }, + warning: { backgroundColor: \\"hsl(30, 75%, 85%)\\" }, + success: { backgroundColor: \\"hsl(130, 75%, 85%)\\" }, + }, + }, + }, + overrides: [ + { + colorMode: \\"dark\\", + tokens: { + colors: { black: { value: \\"#fff\\" }, white: { value: \\"#000\\" } }, + }, + }, + ], +}); +" +`; + +exports[`react theme renderer tests theme should render the theme with ES5 1`] = ` +"/* eslint-disable */ +import { createTheme } from \\"@aws-amplify/ui-react\\"; +export default createTheme({ + name: \\"MyTheme\\", + tokens: { + components: { + alert: { + backgroundColor: \\"hsl(210, 5%, 90%)\\", + padding: \\"0.75rem 1rem\\", + info: { backgroundColor: \\"hsl(220, 85%, 85%)\\" }, + error: { backgroundColor: \\"hsl(0, 75%, 85%)\\" }, + warning: { backgroundColor: \\"hsl(30, 75%, 85%)\\" }, + success: { backgroundColor: \\"hsl(130, 75%, 85%)\\" }, + }, + }, + }, + overrides: [ + { + colorMode: \\"dark\\", + tokens: { + colors: { black: { value: \\"#fff\\" }, white: { value: \\"#000\\" } }, + }, + }, + ], +}); +" +`; + +exports[`react theme renderer tests theme should render the theme with TSX 1`] = ` +"/* eslint-disable */ +import { createTheme } from \\"@aws-amplify/ui-react\\"; +export default createTheme({ + name: \\"MyTheme\\", + tokens: { + components: { + alert: { + backgroundColor: \\"hsl(210, 5%, 90%)\\", + padding: \\"0.75rem 1rem\\", + info: { backgroundColor: \\"hsl(220, 85%, 85%)\\" }, + error: { backgroundColor: \\"hsl(0, 75%, 85%)\\" }, + warning: { backgroundColor: \\"hsl(30, 75%, 85%)\\" }, + success: { backgroundColor: \\"hsl(130, 75%, 85%)\\" }, + }, + }, + }, + overrides: [ + { + colorMode: \\"dark\\", + tokens: { + colors: { black: { value: \\"#fff\\" }, white: { value: \\"#000\\" } }, + }, + }, + ], +}); +" +`; diff --git a/packages/codegen-ui-react/lib/__tests__/__snapshots__/studio-ui-codegen-react.test.ts.snap b/packages/codegen-ui-react/lib/__tests__/__snapshots__/studio-ui-codegen-react.test.ts.snap index 8b96b3914..938502173 100644 --- a/packages/codegen-ui-react/lib/__tests__/__snapshots__/studio-ui-codegen-react.test.ts.snap +++ b/packages/codegen-ui-react/lib/__tests__/__snapshots__/studio-ui-codegen-react.test.ts.snap @@ -5884,93 +5884,6 @@ export default function Profile(props) { " `; -exports[`amplify render tests theme should render the theme 1`] = ` -"/* eslint-disable */ -import { createTheme } from \\"@aws-amplify/ui-react\\"; -export default createTheme({ - name: \\"MyTheme\\", - tokens: { - components: { - alert: { - backgroundColor: \\"hsl(210, 5%, 90%)\\", - padding: \\"0.75rem 1rem\\", - info: { backgroundColor: \\"hsl(220, 85%, 85%)\\" }, - error: { backgroundColor: \\"hsl(0, 75%, 85%)\\" }, - warning: { backgroundColor: \\"hsl(30, 75%, 85%)\\" }, - success: { backgroundColor: \\"hsl(130, 75%, 85%)\\" }, - }, - }, - }, - overrides: [ - { - colorMode: \\"dark\\", - tokens: { - colors: { black: { value: \\"#fff\\" }, white: { value: \\"#000\\" } }, - }, - }, - ], -}); -" -`; - -exports[`amplify render tests theme should render the theme with ES5 1`] = ` -"/* eslint-disable */ -import { createTheme } from \\"@aws-amplify/ui-react\\"; -export default createTheme({ - name: \\"MyTheme\\", - tokens: { - components: { - alert: { - backgroundColor: \\"hsl(210, 5%, 90%)\\", - padding: \\"0.75rem 1rem\\", - info: { backgroundColor: \\"hsl(220, 85%, 85%)\\" }, - error: { backgroundColor: \\"hsl(0, 75%, 85%)\\" }, - warning: { backgroundColor: \\"hsl(30, 75%, 85%)\\" }, - success: { backgroundColor: \\"hsl(130, 75%, 85%)\\" }, - }, - }, - }, - overrides: [ - { - colorMode: \\"dark\\", - tokens: { - colors: { black: { value: \\"#fff\\" }, white: { value: \\"#000\\" } }, - }, - }, - ], -}); -" -`; - -exports[`amplify render tests theme should render the theme with TSX 1`] = ` -"/* eslint-disable */ -import { createTheme } from \\"@aws-amplify/ui-react\\"; -export default createTheme({ - name: \\"MyTheme\\", - tokens: { - components: { - alert: { - backgroundColor: \\"hsl(210, 5%, 90%)\\", - padding: \\"0.75rem 1rem\\", - info: { backgroundColor: \\"hsl(220, 85%, 85%)\\" }, - error: { backgroundColor: \\"hsl(0, 75%, 85%)\\" }, - warning: { backgroundColor: \\"hsl(30, 75%, 85%)\\" }, - success: { backgroundColor: \\"hsl(130, 75%, 85%)\\" }, - }, - }, - }, - overrides: [ - { - colorMode: \\"dark\\", - tokens: { - colors: { black: { value: \\"#fff\\" }, white: { value: \\"#000\\" } }, - }, - }, - ], -}); -" -`; - exports[`amplify render tests user specific attributes should render user specific attributes 1`] = ` "/* eslint-disable */ import React from \\"react\\"; diff --git a/packages/codegen-ui-react/lib/__tests__/react-component-render-helper.test.ts b/packages/codegen-ui-react/lib/__tests__/react-component-render-helper.test.ts index b99d2178b..58d1da08f 100644 --- a/packages/codegen-ui-react/lib/__tests__/react-component-render-helper.test.ts +++ b/packages/codegen-ui-react/lib/__tests__/react-component-render-helper.test.ts @@ -173,7 +173,8 @@ describe('react-component-render-helper', () => { test('unsupported type', () => { expect(() => buildFixedJsxExpression({ value: new Date('December 17, 1995 03:24:00'), type: 'unsupported' }), - ).toThrowErrorMatchingSnapshot(); + ).toThrowError(); + // Not using a snapshot here since the error message changes based on timezone }); }); diff --git a/packages/codegen-ui-react/lib/__tests__/react-theme-studio-template-renderer.test.ts b/packages/codegen-ui-react/lib/__tests__/react-theme-studio-template-renderer.test.ts new file mode 100644 index 000000000..12ee05acf --- /dev/null +++ b/packages/codegen-ui-react/lib/__tests__/react-theme-studio-template-renderer.test.ts @@ -0,0 +1,60 @@ +/* + Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"). + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ +import { StudioTemplateRendererFactory, StudioTheme } from '@aws-amplify/codegen-ui'; +import fs from 'fs'; +import { join } from 'path'; +import { ScriptTarget, ScriptKind, ReactRenderConfig } from '..'; +import { ReactThemeStudioTemplateRenderer } from '../react-theme-studio-template-renderer'; + +function loadThemeFromJSONFile(jsonThemeFile: string): StudioTheme { + return JSON.parse( + fs.readFileSync(join(__dirname, 'studio-ui-json', `${jsonThemeFile}.json`), 'utf-8'), + ) as StudioTheme; +} + +function generateWithThemeRenderer(jsonFile: string, renderConfig: ReactRenderConfig = {}): string { + const rendererFactory = new StudioTemplateRendererFactory( + (theme: StudioTheme) => new ReactThemeStudioTemplateRenderer(theme, renderConfig), + ); + const theme = loadThemeFromJSONFile(jsonFile); + return rendererFactory.buildRenderer(theme).renderComponent().componentText; +} + +describe('react theme renderer tests', () => { + describe('theme', () => { + it('should render the theme', () => { + expect(generateWithThemeRenderer('theme')).toMatchSnapshot(); + }); + + it('should render the theme with TSX', () => { + expect(generateWithThemeRenderer('theme', { script: ScriptKind.TSX })).toMatchSnapshot(); + }); + + it('should render the theme with ES5', () => { + expect(generateWithThemeRenderer('theme', { target: ScriptTarget.ES5, script: ScriptKind.JS })).toMatchSnapshot(); + }); + }); + + describe('renderThemeJson', () => { + it('should render theme json correctly', () => { + const rendererFactory = new StudioTemplateRendererFactory( + (theme: StudioTheme) => new ReactThemeStudioTemplateRenderer(theme, {}), + ); + const theme = loadThemeFromJSONFile('theme'); + expect(rendererFactory.buildRenderer(theme).renderThemeJson()).toMatchSnapshot(); + }); + }); +}); diff --git a/packages/codegen-ui-react/lib/__tests__/studio-ui-codegen-react.test.ts b/packages/codegen-ui-react/lib/__tests__/studio-ui-codegen-react.test.ts index 497a2d3f2..32f9d42a8 100644 --- a/packages/codegen-ui-react/lib/__tests__/studio-ui-codegen-react.test.ts +++ b/packages/codegen-ui-react/lib/__tests__/studio-ui-codegen-react.test.ts @@ -13,12 +13,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { StudioTemplateRendererFactory, StudioComponent, StudioTheme } from '@aws-amplify/codegen-ui'; +import { StudioTemplateRendererFactory, StudioComponent } from '@aws-amplify/codegen-ui'; import fs from 'fs'; import { join } from 'path'; import { ModuleKind, ScriptTarget, ScriptKind, ReactRenderConfig } from '..'; import { AmplifyRenderer } from '../amplify-ui-renderers/amplify-renderer'; -import { ReactThemeStudioTemplateRenderer } from '../react-theme-studio-template-renderer'; function loadSchemaFromJSONFile(jsonSchemaFile: string): StudioComponent { return JSON.parse( @@ -26,12 +25,6 @@ function loadSchemaFromJSONFile(jsonSchemaFile: string): StudioComponent { ) as StudioComponent; } -function loadThemeFromJSONFile(jsonThemeFile: string): StudioTheme { - return JSON.parse( - fs.readFileSync(join(__dirname, 'studio-ui-json', `${jsonThemeFile}.json`), 'utf-8'), - ) as StudioTheme; -} - function generateWithAmplifyRenderer( jsonSchemaFile: string, renderConfig: ReactRenderConfig = {}, @@ -47,14 +40,6 @@ function generateWithAmplifyRenderer( return rendererFactory.buildRenderer(schema).renderComponent(); } -function generateWithThemeRenderer(jsonFile: string, renderConfig: ReactRenderConfig = {}): string { - const rendererFactory = new StudioTemplateRendererFactory( - (theme: StudioTheme) => new ReactThemeStudioTemplateRenderer(theme, renderConfig), - ); - const theme = loadThemeFromJSONFile(jsonFile); - return rendererFactory.buildRenderer(theme).renderComponent().componentText; -} - describe('amplify render tests', () => { describe('basic component tests', () => { it('should generate a simple view component', () => { @@ -308,20 +293,6 @@ describe('amplify render tests', () => { }); }); - describe('theme', () => { - it('should render the theme', () => { - expect(generateWithThemeRenderer('theme')).toMatchSnapshot(); - }); - - it('should render the theme with TSX', () => { - expect(generateWithThemeRenderer('theme', { script: ScriptKind.TSX })).toMatchSnapshot(); - }); - - it('should render the theme with ES5', () => { - expect(generateWithThemeRenderer('theme', { target: ScriptTarget.ES5, script: ScriptKind.JS })).toMatchSnapshot(); - }); - }); - describe('actions', () => { it('should render sign out action', () => { expect(generateWithAmplifyRenderer('componentWithActionSignOut')).toMatchSnapshot(); diff --git a/packages/codegen-ui-react/lib/react-theme-studio-template-renderer.ts b/packages/codegen-ui-react/lib/react-theme-studio-template-renderer.ts index f0204f780..764794cc2 100644 --- a/packages/codegen-ui-react/lib/react-theme-studio-template-renderer.ts +++ b/packages/codegen-ui-react/lib/react-theme-studio-template-renderer.ts @@ -29,6 +29,7 @@ import { StudioThemeValue, validateThemeSchema, InvalidInputError, + handleCodegenErrors, } from '@aws-amplify/codegen-ui'; import { ReactRenderConfig, scriptKindToFileExtensionNonReact } from './react-render-config'; import { ImportCollection, ImportValue } from './imports'; @@ -38,6 +39,7 @@ import { buildPrinter, defaultRenderConfig, getDeclarationFilename, + formatCode, } from './react-studio-template-renderer-helper'; import { RequiredKeys } from './utils/type-utils'; @@ -87,6 +89,18 @@ export class ReactThemeStudioTemplateRenderer extends StudioTemplateRenderer< }; } + /** + * Exposing an additional method to allow rendering the theme json object + * from the API response type. + */ + @handleCodegenErrors + renderThemeJson(): string { + const { printer, file } = buildPrinter(this.fileName, this.renderConfig); + const themeJson = printer.printNode(EmitHint.Unspecified, this.buildThemeObject(), file); + // prettier fails if we don't provide a valid statement, so wrapping in a statement and removing after formatting + return formatCode(`const a = ${themeJson};`).replace('const a =', '').replace(';', '').trim(); + } + /* * import { createTheme } from "@aws-amplify/ui-react"; */