Skip to content

Commit

Permalink
feat: add react-studio-form-renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
SwaySway committed Jul 11, 2022
1 parent 6db9807 commit 80d3c0e
Show file tree
Hide file tree
Showing 30 changed files with 1,644 additions and 214 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`form-render utils should generate a datastore function 1`] = `"const mySampleFormOnSubmit = useDataStoreCreateAction({ model: Post, fields: mySampleFormFields, schema: schema });"`;

exports[`form-render utils should generate before & complete types if datastore config is set 1`] = `
"{
onSubmitBefore?: (fields: Record<string, string>) => Record<string, string>;
onSubmitComplete?: ({ saveSuccessful, errorMessage }: {
saveSuccessful: string;
errorMessage?: string;
}) => void;
onCancel?: () => void;
}"
`;

exports[`form-render utils should generate regular onsubmit if dataSourceType is custom 1`] = `
"{
onSubmit: (fields: Record<string, string>) => void;
onCancel?: () => void;
}"
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
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 { StudioForm } from '@aws-amplify/codegen-ui';
import { EmitHint, Node } from 'typescript';
import { ImportCollection } from '../../imports';
import { buildFormPropNode, buildDataStoreActionStatement } from '../../forms';
import { buildPrinter, defaultRenderConfig } from '../../react-studio-template-renderer-helper';

describe('form-render utils', () => {
let printNode: (node: Node) => string;

beforeAll(() => {
const { printer, file } = buildPrinter('myFileMock', defaultRenderConfig);
printNode = (node: Node) => {
return printer.printNode(EmitHint.Unspecified, node, file);
};
});

it('should generate a datastore function', () => {
const form: StudioForm = {
name: 'mySampleForm',
formActionType: 'create',
dataType: { dataSourceType: 'DataStore', dataTypeName: 'Post' },
fields: {},
sectionalElements: {},
style: {},
};
const importCollection = new ImportCollection();
const mutationStatement: any = buildDataStoreActionStatement(form, importCollection);
expect(mutationStatement).toBeDefined();
const node = printNode(mutationStatement);
expect(node).toMatchSnapshot();
});

it('should generate before & complete types if datastore config is set', () => {
const form: StudioForm = {
name: 'mySampleForm',
formActionType: 'create',
dataType: { dataSourceType: 'DataStore', dataTypeName: 'Post' },
fields: {},
sectionalElements: {},
style: {},
};

const propSignatures = buildFormPropNode(form);
const node = printNode(propSignatures);
expect(node).toMatchSnapshot();
});

it('should generate regular onsubmit if dataSourceType is custom', () => {
const form: StudioForm = {
name: 'myCustomForm',
formActionType: 'create',
dataType: { dataSourceType: 'Custom', dataTypeName: 'Custom' },
fields: {},
sectionalElements: {},
style: {},
};
const propSignatures = buildFormPropNode(form);
const node = printNode(propSignatures);
expect(node).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
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 } from '@aws-amplify/codegen-ui/lib/template-renderer-factory';
import { DataStoreModelInfo, StudioForm, SchemaModel } from '@aws-amplify/codegen-ui';
import { ReactRenderConfig, AmplifyFormRenderer, ModuleKind, ScriptKind, ScriptTarget } from '..';
import { loadSchemaFromJSONFile } from './__utils__';

export const defaultCLIRenderConfig: ReactRenderConfig = {
module: ModuleKind.ES2020,
target: ScriptTarget.ES2020,
script: ScriptKind.JSX,
renderTypeDeclarations: true,
};

export const generateWithAmplifyFormRenderer = (
formJsonFile: string,
dataSchemaJsonFile: string | undefined,
renderConfig: ReactRenderConfig = defaultCLIRenderConfig,
): { componentText: string; declaration?: string } => {
let dataStoreInfo: DataStoreModelInfo | undefined;
if (dataSchemaJsonFile) {
const { fields } = loadSchemaFromJSONFile<SchemaModel>(dataSchemaJsonFile);
dataStoreInfo = { fields: Object.values(fields).map((value) => value) };
}
const rendererFactory = new StudioTemplateRendererFactory(
(component: StudioForm) => new AmplifyFormRenderer(component, dataStoreInfo, renderConfig),
);

const renderer = rendererFactory.buildRenderer(loadSchemaFromJSONFile<StudioForm>(formJsonFile));
return renderer.renderComponent();
};

describe('amplify form renderer tests', () => {
describe('datastore form tests', () => {
it('should generate a create form', () => {
const { componentText, declaration } = generateWithAmplifyFormRenderer(
'forms/post-datastore-create',
'datastore/post',
);
expect(componentText).toContain('useDataStoreCreateAction');
expect(componentText).toMatchSnapshot();
expect(declaration).toMatchSnapshot();
});

it('should generate a update form', () => {
const { componentText, declaration } = generateWithAmplifyFormRenderer(
'forms/post-datastore-update',
'datastore/post',
);
expect(componentText).toContain('useDataStoreUpdateAction');
expect(componentText).toMatchSnapshot();
expect(declaration).toMatchSnapshot();
});
});

describe('custom form tests', () => {
it('should render a custom backed form', () => {
const { componentText, declaration } = generateWithAmplifyFormRenderer('forms/post-custom-create', undefined);
expect(componentText).toContain('customDataFormOnSubmit(customDataFormFields)');
expect(componentText).toMatchSnapshot();
expect(declaration).toMatchSnapshot();
});
});
});
Loading

0 comments on commit 80d3c0e

Please sign in to comment.