From 2a55a288852191b6426262dffbb83430e8ef7ad9 Mon Sep 17 00:00:00 2001 From: Dane Pilcher Date: Wed, 27 Oct 2021 19:38:41 +0000 Subject: [PATCH] fix: simple property binding default value --- package.json | 2 +- .../studio-ui-codegen-react.test.ts.snap | 107 ++++++++++++++++++ .../__tests__/studio-ui-codegen-react.test.ts | 16 +++ .../boundDefaultValue.json | 18 +++ .../simpleAndBoundDefaultValue.json | 19 ++++ .../simplePropertyBindingDefaultValue.json | 18 +++ .../lib/react-studio-template-renderer.ts | 23 +++- .../integration/generated-components-spec.js | 56 +++++++++ .../src/ComponentTests.tsx | 12 ++ .../boundDefaultValue.json | 18 +++ .../default-value-components/index.js | 18 +++ .../simpleAndBoundDefaultValue.json | 19 ++++ .../simplePropertyBindingDefaultValue.json | 18 +++ .../test-generator/lib/components/index.ts | 1 + scripts/integ-templates.sh | 1 + 15 files changed, 344 insertions(+), 2 deletions(-) create mode 100644 packages/studio-ui-codegen-react/lib/__tests__/studio-ui-json/default-value-components/boundDefaultValue.json create mode 100644 packages/studio-ui-codegen-react/lib/__tests__/studio-ui-json/default-value-components/simpleAndBoundDefaultValue.json create mode 100644 packages/studio-ui-codegen-react/lib/__tests__/studio-ui-json/default-value-components/simplePropertyBindingDefaultValue.json create mode 100644 packages/test-generator/lib/components/default-value-components/boundDefaultValue.json create mode 100644 packages/test-generator/lib/components/default-value-components/index.js create mode 100644 packages/test-generator/lib/components/default-value-components/simpleAndBoundDefaultValue.json create mode 100644 packages/test-generator/lib/components/default-value-components/simplePropertyBindingDefaultValue.json diff --git a/package.json b/package.json index 106404885..cdcb580ee 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "integ": "npm run integ:setup && npm run integ:test", "integ:setup": "./scripts/integ-setup.sh", "integ:templates": "./scripts/integ-templates.sh", - "integ:templates:watch": "nodemon --watch packages/test-generator/integration-test-templates/ -e tsx,ts,js,json --exec 'npm run integ:templates'", + "integ:templates:watch": "nodemon --watch packages/test-generator/integration-test-templates/ --watch packages/test-generator/lib -e tsx,ts,js,json --exec 'npm run integ:templates'", "integ:test": "./scripts/integ-test.sh", "integ:clean": "npx rimraf packages/integration-test" }, diff --git a/packages/studio-ui-codegen-react/lib/__tests__/__snapshots__/studio-ui-codegen-react.test.ts.snap b/packages/studio-ui-codegen-react/lib/__tests__/__snapshots__/studio-ui-codegen-react.test.ts.snap index 0aa0f725a..1872fba5f 100644 --- a/packages/studio-ui-codegen-react/lib/__tests__/__snapshots__/studio-ui-codegen-react.test.ts.snap +++ b/packages/studio-ui-codegen-react/lib/__tests__/__snapshots__/studio-ui-codegen-react.test.ts.snap @@ -1066,6 +1066,113 @@ export default function Profile(props: ProfileProps): React.ReactElement; " `; +exports[`amplify render tests default value should render bound default value 1`] = ` +Object { + "componentText": "/* eslint-disable */ +import React from \\"react\\"; +import { + EscapeHatchProps, + Text, + TextProps, + getOverrideProps, +} from \\"@aws-amplify/ui-react\\"; + +export type BoundDefaultValueProps = Partial & { + label?: String; +} & { + overrides?: EscapeHatchProps | undefined | null; +}; +export default function BoundDefaultValue( + props: BoundDefaultValueProps +): React.ReactElement { + const { label, overrides: overridesProp, ...rest } = props; + const overrides = { ...overridesProp }; + return ( + + {label || \\"Bound Default\\"} + + ); +} +", + "declaration": undefined, + "renderComponentToFilesystem": [Function], +} +`; + +exports[`amplify render tests default value should render simple and bound default value 1`] = ` +Object { + "componentText": "/* eslint-disable */ +import React from \\"react\\"; +import { + EscapeHatchProps, + Text, + TextProps, + getOverrideProps, +} from \\"@aws-amplify/ui-react\\"; + +export type SimpleAndBoundDefaultValueProps = Partial & { + label?: String; +} & { + overrides?: EscapeHatchProps | undefined | null; +}; +export default function SimpleAndBoundDefaultValue( + props: SimpleAndBoundDefaultValueProps +): React.ReactElement { + const { + label = \\"Simple Double Default\\", + overrides: overridesProp, + ...rest + } = props; + const overrides = { ...overridesProp }; + return ( + + {label || \\"Bound Double Default\\"} + + ); +} +", + "declaration": undefined, + "renderComponentToFilesystem": [Function], +} +`; + +exports[`amplify render tests default value should render simple default value 1`] = ` +Object { + "componentText": "/* eslint-disable */ +import React from \\"react\\"; +import { + EscapeHatchProps, + Text, + TextProps, + getOverrideProps, +} from \\"@aws-amplify/ui-react\\"; + +export type SimplePropertyBindingDefaultValueProps = Partial & { + label?: String; +} & { + overrides?: EscapeHatchProps | undefined | null; +}; +export default function SimplePropertyBindingDefaultValue( + props: SimplePropertyBindingDefaultValueProps +): React.ReactElement { + const { + label = \\"Default Binding Property\\", + overrides: overridesProp, + ...rest + } = props; + const overrides = { ...overridesProp }; + return ( + + {label} + + ); +} +", + "declaration": undefined, + "renderComponentToFilesystem": [Function], +} +`; + exports[`amplify render tests sample code snippet tests should generate a sample code snippet for components 1`] = ` "/* eslint-disable */ import React from \\"react\\"; diff --git a/packages/studio-ui-codegen-react/lib/__tests__/studio-ui-codegen-react.test.ts b/packages/studio-ui-codegen-react/lib/__tests__/studio-ui-codegen-react.test.ts index 0795bc4f6..bd1ba6ba8 100644 --- a/packages/studio-ui-codegen-react/lib/__tests__/studio-ui-codegen-react.test.ts +++ b/packages/studio-ui-codegen-react/lib/__tests__/studio-ui-codegen-react.test.ts @@ -243,4 +243,20 @@ describe('amplify render tests', () => { it('should render navigation actions', () => { expect(generateWithAmplifyRenderer('componentWithActionNavigation')).toMatchSnapshot(); }); + + describe('default value', () => { + it('should render bound default value', () => { + expect(generateWithAmplifyRenderer('default-value-components/boundDefaultValue')).toMatchSnapshot(); + }); + + it('should render simple and bound default value', () => { + expect(generateWithAmplifyRenderer('default-value-components/simpleAndBoundDefaultValue')).toMatchSnapshot(); + }); + + it('should render simple default value', () => { + expect( + generateWithAmplifyRenderer('default-value-components/simplePropertyBindingDefaultValue'), + ).toMatchSnapshot(); + }); + }); }); diff --git a/packages/studio-ui-codegen-react/lib/__tests__/studio-ui-json/default-value-components/boundDefaultValue.json b/packages/studio-ui-codegen-react/lib/__tests__/studio-ui-json/default-value-components/boundDefaultValue.json new file mode 100644 index 000000000..a30f38de8 --- /dev/null +++ b/packages/studio-ui-codegen-react/lib/__tests__/studio-ui-json/default-value-components/boundDefaultValue.json @@ -0,0 +1,18 @@ +{ + "id": "1234-5678-9010", + "componentType": "Text", + "name": "BoundDefaultValue", + "bindingProperties": { + "label": { + "type": "String" + } + }, + "properties": { + "value": { + "bindingProperties": { + "property": "label" + }, + "defaultValue": "Bound Default" + } + } +} diff --git a/packages/studio-ui-codegen-react/lib/__tests__/studio-ui-json/default-value-components/simpleAndBoundDefaultValue.json b/packages/studio-ui-codegen-react/lib/__tests__/studio-ui-json/default-value-components/simpleAndBoundDefaultValue.json new file mode 100644 index 000000000..57ba279e6 --- /dev/null +++ b/packages/studio-ui-codegen-react/lib/__tests__/studio-ui-json/default-value-components/simpleAndBoundDefaultValue.json @@ -0,0 +1,19 @@ +{ + "id": "1234-5678-9010", + "componentType": "Text", + "name": "SimpleAndBoundDefaultValue", + "bindingProperties": { + "label": { + "type": "String", + "defaultValue": "Simple Double Default" + } + }, + "properties": { + "value": { + "bindingProperties": { + "property": "label" + }, + "defaultValue": "Bound Double Default" + } + } +} diff --git a/packages/studio-ui-codegen-react/lib/__tests__/studio-ui-json/default-value-components/simplePropertyBindingDefaultValue.json b/packages/studio-ui-codegen-react/lib/__tests__/studio-ui-json/default-value-components/simplePropertyBindingDefaultValue.json new file mode 100644 index 000000000..9091d20ce --- /dev/null +++ b/packages/studio-ui-codegen-react/lib/__tests__/studio-ui-json/default-value-components/simplePropertyBindingDefaultValue.json @@ -0,0 +1,18 @@ +{ + "id": "1234-5678-9010", + "componentType": "Text", + "name": "SimplePropertyBindingDefaultValue", + "bindingProperties": { + "label": { + "type": "String", + "defaultValue": "Default Binding Property" + } + }, + "properties": { + "value": { + "bindingProperties": { + "property": "label" + } + } + } +} diff --git a/packages/studio-ui-codegen-react/lib/react-studio-template-renderer.ts b/packages/studio-ui-codegen-react/lib/react-studio-template-renderer.ts index 0b1d99232..1787adad1 100644 --- a/packages/studio-ui-codegen-react/lib/react-studio-template-renderer.ts +++ b/packages/studio-ui-codegen-react/lib/react-studio-template-renderer.ts @@ -20,6 +20,7 @@ import { StudioComponentSort, StudioComponentVariant, StudioComponentAction, + StudioComponentSimplePropertyBinding, } from '@amzn/amplify-ui-codegen-schema'; import { StudioTemplateRenderer, @@ -53,6 +54,8 @@ import ts, { Identifier, ComputedPropertyName, ArrowFunction, + LiteralExpression, + BooleanLiteral, } from 'typescript'; import { ImportCollection } from './import-collection'; import { ReactOutputManager } from './react-output-manager'; @@ -430,7 +433,7 @@ export abstract class ReactStudioTemplateRenderer extends StudioTemplateRenderer undefined, undefined, factory.createIdentifier(propName), - undefined, + isSimplePropertyBinding(binding) ? this.getDefaultValue(binding) : undefined, ); elements.push(bindingElement); } @@ -935,5 +938,23 @@ export abstract class ReactStudioTemplateRenderer extends StudioTemplateRenderer return elements.filter((element) => element !== null && element !== undefined) as T[]; } + private getDefaultValue( + binding: StudioComponentSimplePropertyBinding, + ): LiteralExpression | BooleanLiteral | undefined { + if (binding.defaultValue !== undefined) { + switch (binding.type) { + case 'String': + return factory.createStringLiteral(binding.defaultValue); + case 'Number': + return factory.createNumericLiteral(binding.defaultValue); + case 'Boolean': + return JSON.parse(binding.defaultValue) ? factory.createTrue() : factory.createFalse(); + default: + throw new Error(`Could not parse binding with type ${binding.type}`); + } + } + return undefined; + } + abstract renderJsx(component: StudioComponent): JsxElement | JsxFragment; } diff --git a/packages/test-generator/integration-test-templates/cypress/integration/generated-components-spec.js b/packages/test-generator/integration-test-templates/cypress/integration/generated-components-spec.js index 227907cdb..26b89b594 100644 --- a/packages/test-generator/integration-test-templates/cypress/integration/generated-components-spec.js +++ b/packages/test-generator/integration-test-templates/cypress/integration/generated-components-spec.js @@ -108,6 +108,62 @@ describe('Generated Components', () => { describe('Collections', () => { // TODO: Write Collection Cases }); + + describe('Default Value', () => { + it('Renders simple property binding default value', () => { + cy.get('#default-value') + .get('#bound-simple-binding-default') + .invoke('text') + .then((text) => { + expect(text.trim()).equal('Default Binding Property'); + }); + }); + + it('Overrides simple property binding default value', () => { + cy.get('#default-value') + .get('#bound-simple-binding-override') + .invoke('text') + .then((text) => { + expect(text.trim()).equal('Override Simple Binding'); + }); + }); + + it('Renders bound default value', () => { + cy.get('#default-value') + .get('#bound-default') + .invoke('text') + .then((text) => { + expect(text.trim()).equal('Bound Default'); + }); + }); + + it('Overrides bound default value', () => { + cy.get('#default-value') + .get('#bound-override') + .invoke('text') + .then((text) => { + expect(text.trim()).equal('Override Bound'); + }); + }); + + it('Renders simple default value when simple and bound', () => { + cy.get('#default-value') + .get('#simple-and-bound-default') + .invoke('text') + .then((text) => { + expect(text.trim()).equal('Simple Double Default'); + }); + }); + + it('Overrides simple and bound default value', () => { + cy.get('#default-value') + .get('#simple-and-bound-override') + .invoke('text') + .then((text) => { + expect(text.trim()).equal('Override Simple And Bound'); + }); + }); + }); }); describe('Generated Themes', () => { diff --git a/packages/test-generator/integration-test-templates/src/ComponentTests.tsx b/packages/test-generator/integration-test-templates/src/ComponentTests.tsx index ab38c0a86..5b34351a7 100644 --- a/packages/test-generator/integration-test-templates/src/ComponentTests.tsx +++ b/packages/test-generator/integration-test-templates/src/ComponentTests.tsx @@ -32,6 +32,9 @@ import BasicComponentFlex from './ui-components/BasicComponentFlex'; import BasicComponentImage from './ui-components/BasicComponentImage'; import BasicComponentCustomRating from './ui-components/BasicComponentCustomRating'; import ComponentWithVariant from './ui-components/ComponentWithVariant'; +import SimplePropertyBindingDefaultValue from './ui-components/SimplePropertyBindingDefaultValue'; +import BoundDefaultValue from './ui-components/BoundDefaultValue'; +import SimpleAndBoundDefaultValue from './ui-components/SimpleAndBoundDefaultValue'; import theme from './ui-components/MyTheme'; /* eslint-enable import/extensions */ @@ -110,6 +113,15 @@ export default function ComponentTests() { +
+

Default Value

+ + + + + + +
); } diff --git a/packages/test-generator/lib/components/default-value-components/boundDefaultValue.json b/packages/test-generator/lib/components/default-value-components/boundDefaultValue.json new file mode 100644 index 000000000..a30f38de8 --- /dev/null +++ b/packages/test-generator/lib/components/default-value-components/boundDefaultValue.json @@ -0,0 +1,18 @@ +{ + "id": "1234-5678-9010", + "componentType": "Text", + "name": "BoundDefaultValue", + "bindingProperties": { + "label": { + "type": "String" + } + }, + "properties": { + "value": { + "bindingProperties": { + "property": "label" + }, + "defaultValue": "Bound Default" + } + } +} diff --git a/packages/test-generator/lib/components/default-value-components/index.js b/packages/test-generator/lib/components/default-value-components/index.js new file mode 100644 index 000000000..760186b17 --- /dev/null +++ b/packages/test-generator/lib/components/default-value-components/index.js @@ -0,0 +1,18 @@ +/* + 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. + */ +export { default as BoundDefaultValue } from './boundDefaultValue.json'; +export { default as SimplePropertyBindingDefaultValue } from './simplePropertyBindingDefaultValue.json'; +export { default as SimpleAndBouldDefaultValue } from './simpleAndBoundDefaultValue.json'; diff --git a/packages/test-generator/lib/components/default-value-components/simpleAndBoundDefaultValue.json b/packages/test-generator/lib/components/default-value-components/simpleAndBoundDefaultValue.json new file mode 100644 index 000000000..57ba279e6 --- /dev/null +++ b/packages/test-generator/lib/components/default-value-components/simpleAndBoundDefaultValue.json @@ -0,0 +1,19 @@ +{ + "id": "1234-5678-9010", + "componentType": "Text", + "name": "SimpleAndBoundDefaultValue", + "bindingProperties": { + "label": { + "type": "String", + "defaultValue": "Simple Double Default" + } + }, + "properties": { + "value": { + "bindingProperties": { + "property": "label" + }, + "defaultValue": "Bound Double Default" + } + } +} diff --git a/packages/test-generator/lib/components/default-value-components/simplePropertyBindingDefaultValue.json b/packages/test-generator/lib/components/default-value-components/simplePropertyBindingDefaultValue.json new file mode 100644 index 000000000..9091d20ce --- /dev/null +++ b/packages/test-generator/lib/components/default-value-components/simplePropertyBindingDefaultValue.json @@ -0,0 +1,18 @@ +{ + "id": "1234-5678-9010", + "componentType": "Text", + "name": "SimplePropertyBindingDefaultValue", + "bindingProperties": { + "label": { + "type": "String", + "defaultValue": "Default Binding Property" + } + }, + "properties": { + "value": { + "bindingProperties": { + "property": "label" + } + } + } +} diff --git a/packages/test-generator/lib/components/index.ts b/packages/test-generator/lib/components/index.ts index 3ce297810..b0627d79c 100644 --- a/packages/test-generator/lib/components/index.ts +++ b/packages/test-generator/lib/components/index.ts @@ -26,3 +26,4 @@ export { default as ComponentWithVariant } from './componentWithVariant.json'; export { default as ComponentWithActionSignOut } from './componentWithActionSignOut.json'; export { default as ComponentWithActionNavigation } from './componentWithActionNavigation.json'; export * from './basic-components'; +export * from './default-value-components'; diff --git a/scripts/integ-templates.sh b/scripts/integ-templates.sh index aa400fd4d..8c0932e7a 100755 --- a/scripts/integ-templates.sh +++ b/scripts/integ-templates.sh @@ -1,4 +1,5 @@ #!/bin/bash +lerna run build --scope @amzn/test-generator cp -r packages/test-generator/integration-test-templates/. packages/integration-test node packages/test-generator/dist/generators/GenerateTestApp.js