Merge pull request #167 from lowdefy/blocks-antd-notification

feat(blocksAntd): notification examples (need to test button, add exa…
This commit is contained in:
Sam 2020-11-20 13:02:52 +02:00 committed by GitHub
commit caa13b41ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 3890 additions and 1180 deletions

View File

@ -7,6 +7,7 @@ module.exports = {
'<rootDir>/dist/',
'<rootDir>/tests/',
'runRenderTests.js',
'runMethodTests.js',
'runBlockSchemaTests.js',
'mockBlock.js',
],

View File

@ -23,6 +23,7 @@ import makeCssClass from './makeCssClass.js';
import mediaToCssObject from './mediaToCssObject.js';
import mockBlock from './mockBlock';
import runBlockSchemaTests from './runBlockSchemaTests';
import runMethodTests from './runMethodTests';
import runRenderTests from './runRenderTests';
import Skeleton from './Skeleton/Skeleton';
import SkeletonAvatar from './Skeleton/SkeletonAvatar';
@ -43,6 +44,7 @@ export {
mediaToCssObject,
mockBlock,
runBlockSchemaTests,
runMethodTests,
runRenderTests,
Skeleton,
SkeletonAvatar,

View File

@ -0,0 +1,67 @@
/*
Copyright 2020 Lowdefy, Inc
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 React from 'react';
import { type } from '@lowdefy/helpers';
import mockBlock from './mockBlock';
const runMethodTests = ({ Block, enzyme, examples, logger, meta, mocks }) => {
const { before, methods, getProps } = mockBlock({ meta, logger });
beforeEach(() => {
before();
});
const values = meta.values
? [type.enforceType(meta.valueType, null), ...meta.values]
: [type.enforceType(meta.valueType, null)];
examples.forEach((ex) => {
values.forEach((value, v) => {
if (meta.test && meta.test.methods) {
meta.test.methods.forEach((method) => {
mocks.forEach((mock) => {
test(`Mock for method: ${JSON.stringify(method)} - ${ex.id} - value[${v}] - ${
mock.name
}`, () => {
const Shell = () => {
const props = getProps(ex);
props.methods = { ...methods, registerMethod: props.methods.registerMethod };
return (
<>
<Block {...props} value={value} />
<button
id={`${ex.id}_button`}
onClick={() => {
props.registeredMethods[method.name](method.args);
}}
data-testid="btn_method"
/>
</>
);
};
const wrapper = enzyme.mount(<Shell />);
wrapper.find('[data-testid="btn_method"]').simulate('click');
expect(mock.fn.mock.calls).toMatchSnapshot();
});
});
});
}
});
});
};
export default runMethodTests;

View File

@ -23,7 +23,6 @@ import mockBlock from './mockBlock';
const runRenderTests = ({
Block,
enzyme,
examples,
logger,
meta,
@ -32,7 +31,6 @@ const runRenderTests = ({
}) => {
const { before, methods, getProps } = mockBlock({ meta, logger });
beforeEach(before);
beforeEach(() => {
reset();
before();
@ -89,32 +87,6 @@ const runRenderTests = ({
comp.unmount();
});
}
if (meta.test && meta.test.methods) {
meta.test.methods.forEach((method) => {
test(`Render for method: ${JSON.stringify(method)} - ${ex.id} - value[${v}]`, () => {
const Shell = () => {
const props = getProps(ex);
props.methods = { ...methods, registerMethod: props.methods.registerMethod };
return (
<>
<Block {...props} value={value} />
<button
id={`${ex.id}_button`}
onClick={() => {
props.registeredMethods[method.name](method.args);
}}
data-testid="btn_method"
/>
</>
);
};
const wrapper = enzyme.mount(<Shell />);
wrapper.find('[data-testid="btn_method"]').simulate('click');
expect(document.body.innerHTML).toMatchSnapshot();
});
});
}
});
});
};

View File

@ -1,13 +1,75 @@
- id: default
type: Notification
- id: properties.message
- id: "properties.message"
type: Notification
properties:
message: Notification message
- id: areas.content
- id: "properties.description:"
type: Notification
areas:
content:
blocks:
- id: testArea
type: Test
properties:
description: "Notification status type."
- id: "properties.bottom: 250 placement: bottomLeft"
type: Notification
properties:
placement: bottomLeft
bottom: 250
message: Notification message
- id: "properties.top: 250 placement: topLeft"
type: Notification
properties:
placement: topLeft
top: 250
message: Notification message
- id: "properties.button: icon"
type: Notification
properties:
button:
icon: SaveOutlined
title: Close
message: Notification message
- id: "properties.duration: 6"
type: Notification
properties:
duration: 6
message: Notification message
- id: "properties.icon"
type: Notification
properties:
icon: AccountBookFilled
message: Notification message
- id: "properties.closeIcon: AlertOutlined"
type: Notification
properties:
closeIcon: AlertOutlined
message: Notification message
- id: "properties.placement: topLeft"
type: Notification
properties:
placement: topLeft
message: Notification message
- id: "properties.placement: bottomLeft"
type: Notification
properties:
placement: bottomLeft
message: Notification message
- id: "properties.placement: bottomRight"
type: Notification
properties:
placement: bottomRight
message: Notification message
- id: "properties.status: error"
type: Notification
properties:
status: error
message: Notification message
- id: "properties.status: info"
type: Notification
properties:
status: info
message: Notification message
- id: "properties.status: warning"
type: Notification
properties:
status: warning
message: Notification message
description: "Notification status type."

View File

@ -25,22 +25,19 @@ const NotificationBlock = ({ blockId, properties, methods, onClose, onClick }) =
useEffect(() => {
methods.registerMethod('open', (args = {}) => {
notification[args.status || properties.status || 'success']({
id: blockId,
id: `${blockId}_notification`,
bottom: properties.bottom,
btn:
properties.button &&
(() => (
<Button
blockId={`${blockId}_button`}
properties={properties.button}
methods={methods}
onClick={properties.button.onClick}
/>
)),
btn: properties.button && (
<Button
blockId={`${blockId}_button`}
properties={properties.button}
methods={methods}
onClick={() => methods.callAction({ action: 'onClose' })}
/>
),
className: methods.makeCssClass(properties.notificationStyle),
description: args.description || properties.description || blockId,
description: args.description || properties.description,
duration: type.isNone(args.duration) ? properties.duration : args.duration,
getContainer: () => document.getElementById(`${blockId}_notification`),
icon: properties.icon && <Icon properties={properties.icon} methods={methods} />,
closeIcon: properties.closeIcon && (
<Icon
@ -49,7 +46,6 @@ const NotificationBlock = ({ blockId, properties, methods, onClose, onClick }) =
methods={methods}
/>
),
key: blockId,
message: args.message || properties.message || blockId,
onClose: onClose || (() => methods.callAction({ action: 'onClose' })),
onClick: onClick || (() => methods.callAction({ action: 'onClick' })),
@ -58,7 +54,7 @@ const NotificationBlock = ({ blockId, properties, methods, onClose, onClick }) =
});
});
}, [methods.registerMethod]);
return <div id={`${blockId}_notification`} />;
return <div id={blockId} />;
};
NotificationBlock.defaultProps = blockDefaultProps;

View File

@ -1,6 +1,38 @@
{
"category": "display",
"loading": false,
"test": {
"methods": [
{
"name": "open",
"args": {}
},
{
"name": "open",
"args": {
"status": "warning"
}
},
{
"name": "open",
"args": {
"message": "Args message"
}
},
{
"name": "open",
"args": {
"description": "Args description"
}
},
{
"name": "open",
"args": {
"duration": 1
}
}
]
},
"schema": {
"properties": {
"type": "object",
@ -13,7 +45,7 @@
},
"button": {
"type": "object",
"description": "Customized close button."
"description": "Button object to customized the close button. Fires onClose action when clicked."
},
"description": {
"type": "string",

View File

@ -14,24 +14,48 @@
limitations under the License.
*/
import { runBlockSchemaTests, runRenderTests } from '@lowdefy/block-tools';
import { runBlockSchemaTests, runMethodTests } from '@lowdefy/block-tools';
import Enzyme, { mount } from 'enzyme';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import { message } from 'antd';
Enzyme.configure({ adapter: new Adapter() });
import Message from '../src/blocks/Message/Message';
import examples from '../demo/examples/Message.yaml';
import meta from '../src/blocks/Message/Message.json';
const reset = () => {
document.body.childNodes.forEach((node) => {
node.childNodes.forEach((childNode) => {
childNode.childNodes.forEach((childChildNode) => {
childChildNode.innerHTML = '';
});
});
});
};
jest.mock('antd/lib/message', () => {
return {
error: jest.fn(),
info: jest.fn(),
loading: jest.fn(),
success: jest.fn(),
warning: jest.fn(),
};
});
runRenderTests({ examples, Block: Message, meta, reset, enzyme: { mount } });
const mocks = [
{
name: 'error',
fn: message.error,
},
{
name: 'info',
fn: message.info,
},
{
name: 'loading',
fn: message.loading,
},
{
name: 'success',
fn: message.success,
},
{
name: 'warning',
fn: message.warning,
},
];
runMethodTests({ examples, Block: Message, meta, mocks, enzyme: { mount } });
runBlockSchemaTests({ examples, meta });

View File

@ -14,11 +14,43 @@
limitations under the License.
*/
import { runBlockSchemaTests, runRenderTests } from '@lowdefy/block-tools';
import { runBlockSchemaTests, runMethodTests } from '@lowdefy/block-tools';
import Enzyme, { mount } from 'enzyme';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import { notification } from 'antd';
Enzyme.configure({ adapter: new Adapter() });
import Notification from '../src/blocks/Notification/Notification';
import examples from '../demo/examples/Notification.yaml';
import meta from '../src/blocks/Notification/Notification.json';
runRenderTests({ examples, Block: Notification, meta });
jest.mock('antd/lib/notification', () => {
return {
error: jest.fn(),
info: jest.fn(),
success: jest.fn(),
warning: jest.fn(),
};
});
const mocks = [
{
name: 'error',
fn: notification.error,
},
{
name: 'info',
fn: notification.info,
},
{
name: 'success',
fn: notification.success,
},
{
name: 'warning',
fn: notification.warning,
},
];
runMethodTests({ examples, Block: Notification, meta, mocks, enzyme: { mount } });
runBlockSchemaTests({ examples, meta });

File diff suppressed because it is too large Load Diff