Initial commit of 001code-html Scratch frontend project.
Includes scratch-gui, scratch-vm, scratch-blocks, scratch-render, scratch-l10n, and deployment config. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ButtonComponent matches snapshot 1`] = `
|
||||
<span
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
className={undefined}
|
||||
/>
|
||||
</span>
|
||||
`;
|
||||
@@ -0,0 +1,22 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`IconButtonComponent matches snapshot 1`] = `
|
||||
<div
|
||||
className="custom-class-name"
|
||||
onClick={[Function]}
|
||||
role="button"
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="imgSrc"
|
||||
/>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div>
|
||||
Text
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -0,0 +1,565 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Sound Editor Component matches snapshot 1`] = `
|
||||
<div
|
||||
className={undefined}
|
||||
onMouseDown={undefined}
|
||||
>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<label
|
||||
className={undefined}
|
||||
>
|
||||
<span
|
||||
className={undefined}
|
||||
>
|
||||
Sound
|
||||
</span>
|
||||
<input
|
||||
className=""
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onKeyPress={[Function]}
|
||||
onSubmit={[Function]}
|
||||
tabIndex="1"
|
||||
type="text"
|
||||
value="sound name"
|
||||
/>
|
||||
</label>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<button
|
||||
className={undefined}
|
||||
disabled={false}
|
||||
onClick={[Function]}
|
||||
title="Undo"
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
className={undefined}
|
||||
disabled={true}
|
||||
onClick={[Function]}
|
||||
title="Redo"
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
onClick={undefined}
|
||||
role="button"
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
Copy
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
onClick={undefined}
|
||||
role="button"
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
Paste
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
onClick={undefined}
|
||||
role="button"
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
Copy to New
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
role="button"
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
Delete
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<svg
|
||||
className={undefined}
|
||||
viewBox="0 0 600 160"
|
||||
>
|
||||
<g
|
||||
transform="scale(1, -1) translate(0, -80)"
|
||||
>
|
||||
<path
|
||||
className={undefined}
|
||||
d="M0 0Q0 80 150 120 Q300 160 450 200 Q600 240 600 0 Q600 -240 450 -200 Q300 -160 150 -120 Q0 -80 0 0Z"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={1}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
<div
|
||||
className=""
|
||||
onMouseDown={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
style={
|
||||
Object {
|
||||
"alignContent": undefined,
|
||||
"alignItems": undefined,
|
||||
"alignSelf": undefined,
|
||||
"flexBasis": undefined,
|
||||
"flexDirection": undefined,
|
||||
"flexGrow": undefined,
|
||||
"flexShrink": undefined,
|
||||
"flexWrap": undefined,
|
||||
"height": undefined,
|
||||
"justifyContent": undefined,
|
||||
"left": "20%",
|
||||
"width": "60.00000000000001%",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
style={
|
||||
Object {
|
||||
"alignContent": undefined,
|
||||
"alignItems": undefined,
|
||||
"alignSelf": undefined,
|
||||
"flexBasis": undefined,
|
||||
"flexDirection": undefined,
|
||||
"flexGrow": undefined,
|
||||
"flexShrink": undefined,
|
||||
"flexWrap": undefined,
|
||||
"height": undefined,
|
||||
"justifyContent": undefined,
|
||||
"width": undefined,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<div
|
||||
className=""
|
||||
onMouseDown={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"alignContent": undefined,
|
||||
"alignItems": undefined,
|
||||
"alignSelf": undefined,
|
||||
"flexBasis": undefined,
|
||||
"flexDirection": undefined,
|
||||
"flexGrow": undefined,
|
||||
"flexShrink": undefined,
|
||||
"flexWrap": undefined,
|
||||
"height": undefined,
|
||||
"justifyContent": undefined,
|
||||
"width": undefined,
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
style={
|
||||
Object {
|
||||
"alignContent": undefined,
|
||||
"alignItems": undefined,
|
||||
"alignSelf": undefined,
|
||||
"flexBasis": undefined,
|
||||
"flexDirection": undefined,
|
||||
"flexGrow": undefined,
|
||||
"flexShrink": undefined,
|
||||
"flexWrap": undefined,
|
||||
"height": undefined,
|
||||
"justifyContent": undefined,
|
||||
"width": undefined,
|
||||
}
|
||||
}
|
||||
>
|
||||
<img
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
style={
|
||||
Object {
|
||||
"alignContent": undefined,
|
||||
"alignItems": undefined,
|
||||
"alignSelf": undefined,
|
||||
"flexBasis": undefined,
|
||||
"flexDirection": undefined,
|
||||
"flexGrow": undefined,
|
||||
"flexShrink": undefined,
|
||||
"flexWrap": undefined,
|
||||
"height": undefined,
|
||||
"justifyContent": undefined,
|
||||
"width": undefined,
|
||||
}
|
||||
}
|
||||
>
|
||||
<img
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
onMouseDown={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"alignContent": undefined,
|
||||
"alignItems": undefined,
|
||||
"alignSelf": undefined,
|
||||
"flexBasis": undefined,
|
||||
"flexDirection": undefined,
|
||||
"flexGrow": undefined,
|
||||
"flexShrink": undefined,
|
||||
"flexWrap": undefined,
|
||||
"height": undefined,
|
||||
"justifyContent": undefined,
|
||||
"width": undefined,
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
style={
|
||||
Object {
|
||||
"alignContent": undefined,
|
||||
"alignItems": undefined,
|
||||
"alignSelf": undefined,
|
||||
"flexBasis": undefined,
|
||||
"flexDirection": undefined,
|
||||
"flexGrow": undefined,
|
||||
"flexShrink": undefined,
|
||||
"flexWrap": undefined,
|
||||
"height": undefined,
|
||||
"justifyContent": undefined,
|
||||
"width": undefined,
|
||||
}
|
||||
}
|
||||
>
|
||||
<img
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
style={
|
||||
Object {
|
||||
"alignContent": undefined,
|
||||
"alignItems": undefined,
|
||||
"alignSelf": undefined,
|
||||
"flexBasis": undefined,
|
||||
"flexDirection": undefined,
|
||||
"flexGrow": undefined,
|
||||
"flexShrink": undefined,
|
||||
"flexWrap": undefined,
|
||||
"height": undefined,
|
||||
"justifyContent": undefined,
|
||||
"width": undefined,
|
||||
}
|
||||
}
|
||||
>
|
||||
<img
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
style={
|
||||
Object {
|
||||
"transform": "translateX(50%)",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
>
|
||||
<button
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
title="Stop"
|
||||
>
|
||||
<img
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
role="button"
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<span>
|
||||
Faster
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
role="button"
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<span>
|
||||
Slower
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
role="button"
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<span>
|
||||
Louder
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
role="button"
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<span>
|
||||
Softer
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
onClick={undefined}
|
||||
role="button"
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<span>
|
||||
Mute
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
onClick={undefined}
|
||||
role="button"
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<span>
|
||||
Fade in
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
onClick={undefined}
|
||||
role="button"
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<span>
|
||||
Fade out
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
role="button"
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<span>
|
||||
Reverse
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
role="button"
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<span>
|
||||
Robot
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
role="button"
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<span>
|
||||
Echo
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
00:00.30 / 00:00.60
|
||||
</div>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
Hz
|
||||
<span>
|
||||
Mono
|
||||
</span>
|
||||
(10.51KB)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -0,0 +1,179 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`SpriteSelectorItemComponent matches snapshot when given a number and details to show 1`] = `
|
||||
<div
|
||||
className="react-contextmenu-wrapper ponies undefined"
|
||||
onClick={[Function]}
|
||||
onContextMenu={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseEnter={undefined}
|
||||
onMouseLeave={undefined}
|
||||
onMouseOut={[Function]}
|
||||
onMouseUp={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
5
|
||||
</div>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="https://scratch.mit.edu/foo/bar/pony"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
Pony sprite
|
||||
</div>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
480 x 360
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Delete"
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<nav
|
||||
className="react-contextmenu"
|
||||
onContextMenu={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
role="menu"
|
||||
style={
|
||||
Object {
|
||||
"opacity": 0,
|
||||
"pointerEvents": "none",
|
||||
"position": "fixed",
|
||||
}
|
||||
}
|
||||
tabIndex="-1"
|
||||
>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-orientation={null}
|
||||
className="react-contextmenu-item"
|
||||
onClick={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseMove={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
role="menuitem"
|
||||
tabIndex="-1"
|
||||
>
|
||||
<span>
|
||||
delete
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`SpriteSelectorItemComponent matches snapshot when selected 1`] = `
|
||||
<div
|
||||
className="react-contextmenu-wrapper ponies undefined"
|
||||
onClick={[Function]}
|
||||
onContextMenu={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseEnter={undefined}
|
||||
onMouseLeave={undefined}
|
||||
onMouseOut={[Function]}
|
||||
onMouseUp={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
draggable={false}
|
||||
src="https://scratch.mit.edu/foo/bar/pony"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
Pony sprite
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Delete"
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<img
|
||||
className={undefined}
|
||||
src="test-file-stub"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<nav
|
||||
className="react-contextmenu"
|
||||
onContextMenu={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
role="menu"
|
||||
style={
|
||||
Object {
|
||||
"opacity": 0,
|
||||
"pointerEvents": "none",
|
||||
"position": "fixed",
|
||||
}
|
||||
}
|
||||
tabIndex="-1"
|
||||
>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-orientation={null}
|
||||
className="react-contextmenu-item"
|
||||
onClick={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onMouseMove={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
role="menuitem"
|
||||
tabIndex="-1"
|
||||
>
|
||||
<span>
|
||||
delete
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
`;
|
||||
23
scratch-gui/test/unit/components/button.test.jsx
Normal file
23
scratch-gui/test/unit/components/button.test.jsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
import {shallow} from 'enzyme';
|
||||
import ButtonComponent from '../../../src/components/button/button';
|
||||
import renderer from 'react-test-renderer';
|
||||
|
||||
describe('ButtonComponent', () => {
|
||||
test('matches snapshot', () => {
|
||||
const onClick = jest.fn();
|
||||
const component = renderer.create(
|
||||
<ButtonComponent onClick={onClick} />
|
||||
);
|
||||
expect(component.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('triggers callback when clicked', () => {
|
||||
const onClick = jest.fn();
|
||||
const componentShallowWrapper = shallow(
|
||||
<ButtonComponent onClick={onClick} />
|
||||
);
|
||||
componentShallowWrapper.simulate('click');
|
||||
expect(onClick).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
62
scratch-gui/test/unit/components/cards.test.jsx
Normal file
62
scratch-gui/test/unit/components/cards.test.jsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import React from 'react';
|
||||
import {mountWithIntl} from '../../helpers/intl-helpers.jsx';
|
||||
|
||||
// Mock this utility because it uses dynamic imports that do not work with jest
|
||||
jest.mock('../../../src/lib/libraries/decks/translate-image.js', () => {});
|
||||
|
||||
import Cards, {ImageStep, VideoStep} from '../../../src/components/cards/cards.jsx';
|
||||
|
||||
describe('Cards component', () => {
|
||||
const defaultProps = () => ({
|
||||
activeDeckId: 'id1',
|
||||
content: {
|
||||
id1: {
|
||||
name: 'id1 - name',
|
||||
img: 'id1 - img',
|
||||
steps: [{video: 'videoUrl'}]
|
||||
}
|
||||
},
|
||||
dragging: false,
|
||||
expanded: true,
|
||||
isRtl: false,
|
||||
locale: 'en',
|
||||
onActivateDeckFactory: jest.fn(),
|
||||
onCloseCards: jest.fn(),
|
||||
onDrag: jest.fn(),
|
||||
onEndDrag: jest.fn(),
|
||||
onNextStep: jest.fn(),
|
||||
onPrevStep: jest.fn(),
|
||||
onShowAll: jest.fn(),
|
||||
onShrinkExpandCards: jest.fn(),
|
||||
onStartDrag: jest.fn(),
|
||||
showVideos: true,
|
||||
step: 0,
|
||||
x: 0,
|
||||
y: 0
|
||||
});
|
||||
|
||||
test('showVideos=true shows the video step', () => {
|
||||
const component = mountWithIntl(
|
||||
<Cards
|
||||
{...defaultProps()}
|
||||
showVideos
|
||||
/>
|
||||
);
|
||||
expect(component.find(ImageStep).exists()).toEqual(false);
|
||||
expect(component.find(VideoStep).exists()).toEqual(true);
|
||||
});
|
||||
|
||||
test('showVideos=false shows the title image/name instead of video step', () => {
|
||||
const component = mountWithIntl(
|
||||
<Cards
|
||||
{...defaultProps()}
|
||||
showVideos={false}
|
||||
/>
|
||||
);
|
||||
expect(component.find(VideoStep).exists()).toEqual(false);
|
||||
|
||||
const imageStep = component.find(ImageStep);
|
||||
expect(imageStep.props().image).toEqual('id1 - img');
|
||||
expect(imageStep.props().title).toEqual('id1 - name');
|
||||
});
|
||||
});
|
||||
40
scratch-gui/test/unit/components/controls.test.jsx
Normal file
40
scratch-gui/test/unit/components/controls.test.jsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import React from 'react';
|
||||
import {mountWithIntl} from '../../helpers/intl-helpers.jsx';
|
||||
import Controls from '../../../src/components/controls/controls';
|
||||
import TurboMode from '../../../src/components/turbo-mode/turbo-mode';
|
||||
import GreenFlag from '../../../src/components/green-flag/green-flag';
|
||||
import StopAll from '../../../src/components/stop-all/stop-all';
|
||||
|
||||
describe('Controls component', () => {
|
||||
const defaultProps = () => ({
|
||||
active: false,
|
||||
onGreenFlagClick: jest.fn(),
|
||||
onStopAllClick: jest.fn(),
|
||||
turbo: false
|
||||
});
|
||||
|
||||
test('shows turbo mode when in turbo mode', () => {
|
||||
const component = mountWithIntl(
|
||||
<Controls
|
||||
{...defaultProps()}
|
||||
/>
|
||||
);
|
||||
expect(component.find(TurboMode).exists()).toEqual(false);
|
||||
component.setProps({turbo: true});
|
||||
expect(component.find(TurboMode).exists()).toEqual(true);
|
||||
});
|
||||
|
||||
test('triggers the right callbacks when clicked', () => {
|
||||
const props = defaultProps();
|
||||
const component = mountWithIntl(
|
||||
<Controls
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
component.find(GreenFlag).simulate('click');
|
||||
expect(props.onGreenFlagClick).toHaveBeenCalled();
|
||||
|
||||
component.find(StopAll).simulate('click');
|
||||
expect(props.onStopAllClick).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
43
scratch-gui/test/unit/components/error-boundary-hoc.test.jsx
Normal file
43
scratch-gui/test/unit/components/error-boundary-hoc.test.jsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import React from 'react';
|
||||
import {Provider} from 'react-redux';
|
||||
const {mountWithIntl} = require('../../helpers/intl-helpers.jsx');
|
||||
|
||||
import configureStore from 'redux-mock-store';
|
||||
|
||||
import CrashMessageComponent from '../../../src/components/crash-message/crash-message.jsx';
|
||||
import ErrorBoundary from '../../../src/containers/error-boundary.jsx';
|
||||
|
||||
const ChildComponent = () => <div>hello</div>;
|
||||
|
||||
describe('ErrorBoundary', () => {
|
||||
const mockStore = configureStore();
|
||||
let store;
|
||||
|
||||
beforeEach(() => {
|
||||
store = mockStore({
|
||||
locales: {
|
||||
isRtl: false,
|
||||
locale: 'en-US'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('ErrorBoundary shows children before error and CrashMessageComponent after', () => {
|
||||
const child = <ChildComponent />;
|
||||
const wrapper = mountWithIntl(
|
||||
<Provider store={store}><ErrorBoundary action="test">{child}</ErrorBoundary></Provider>
|
||||
);
|
||||
const errorSite = wrapper.childAt(0).childAt(0);
|
||||
|
||||
// @ts-ignore: 'onReload' prop is absent because this component will only be used for pattern matching
|
||||
const crashMessagePattern = <CrashMessageComponent />;
|
||||
|
||||
expect(wrapper.containsMatchingElement(child)).toBeTruthy();
|
||||
expect(wrapper.containsMatchingElement(crashMessagePattern)).toBeFalsy();
|
||||
|
||||
errorSite.simulateError(new Error('fake error for testing purposes'));
|
||||
|
||||
expect(wrapper.containsMatchingElement(child)).toBeFalsy();
|
||||
expect(wrapper.containsMatchingElement(crashMessagePattern)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
37
scratch-gui/test/unit/components/icon-button.test.jsx
Normal file
37
scratch-gui/test/unit/components/icon-button.test.jsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import React from 'react';
|
||||
import {shallow} from 'enzyme';
|
||||
import IconButton from '../../../src/components/icon-button/icon-button';
|
||||
import renderer from 'react-test-renderer';
|
||||
|
||||
describe('IconButtonComponent', () => {
|
||||
test('matches snapshot', () => {
|
||||
const onClick = jest.fn();
|
||||
const title = <div>Text</div>;
|
||||
const imgSrc = 'imgSrc';
|
||||
const className = 'custom-class-name';
|
||||
const component = renderer.create(
|
||||
<IconButton
|
||||
className={className}
|
||||
img={imgSrc}
|
||||
title={title}
|
||||
onClick={onClick}
|
||||
/>
|
||||
);
|
||||
expect(component.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('triggers callback when clicked', () => {
|
||||
const onClick = jest.fn();
|
||||
const title = <div>Text</div>;
|
||||
const imgSrc = 'imgSrc';
|
||||
const componentShallowWrapper = shallow(
|
||||
<IconButton
|
||||
img={imgSrc}
|
||||
title={title}
|
||||
onClick={onClick}
|
||||
/>
|
||||
);
|
||||
componentShallowWrapper.simulate('click');
|
||||
expect(onClick).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
64
scratch-gui/test/unit/components/menu-bar.test.jsx
Normal file
64
scratch-gui/test/unit/components/menu-bar.test.jsx
Normal file
@@ -0,0 +1,64 @@
|
||||
describe('no-op', () => {
|
||||
test('no-op', () => {});
|
||||
});
|
||||
// tw: these seem to be hopelessly broken to the increasing scope of changes we make to the menu bar, disable for now...
|
||||
/*
|
||||
import React from 'react';
|
||||
import {mountWithIntl} from '../../helpers/intl-helpers';
|
||||
import MenuBar from '../../../src/components/menu-bar/menu-bar';
|
||||
import {menuInitialState} from '../../../src/reducers/menus';
|
||||
import {LoadingState} from '../../../src/reducers/project-state';
|
||||
import {DEFAULT_THEME} from '../../../src/lib/themes';
|
||||
|
||||
import configureStore from 'redux-mock-store';
|
||||
import {Provider} from 'react-redux';
|
||||
import VM from 'scratch-vm';
|
||||
|
||||
describe('MenuBar Component', () => {
|
||||
const store = configureStore()({
|
||||
locales: {
|
||||
isRtl: false,
|
||||
locale: 'en-US'
|
||||
},
|
||||
scratchGui: {
|
||||
menus: menuInitialState,
|
||||
projectState: {
|
||||
loadingState: LoadingState.NOT_LOADED
|
||||
},
|
||||
theme: {
|
||||
theme: DEFAULT_THEME
|
||||
},
|
||||
timeTravel: {
|
||||
year: 'NOW'
|
||||
},
|
||||
vm: new VM()
|
||||
}
|
||||
});
|
||||
|
||||
const getComponent = function (props = {}) {
|
||||
return <Provider store={store}><MenuBar {...props} /></Provider>;
|
||||
};
|
||||
|
||||
test('menu bar with no About handler has no About button', () => {
|
||||
const menuBar = mountWithIntl(getComponent());
|
||||
const button = menuBar.find('AboutButton');
|
||||
expect(button.exists()).toBe(false);
|
||||
});
|
||||
|
||||
test('menu bar with an About handler has an About button', () => {
|
||||
const onClickAbout = jest.fn();
|
||||
const menuBar = mountWithIntl(getComponent({onClickAbout}));
|
||||
const button = menuBar.find('AboutButton');
|
||||
expect(button.exists()).toBe(true);
|
||||
});
|
||||
|
||||
test('clicking on About button calls the handler', () => {
|
||||
const onClickAbout = jest.fn();
|
||||
const menuBar = mountWithIntl(getComponent({onClickAbout}));
|
||||
const button = menuBar.find('AboutButton');
|
||||
expect(onClickAbout).toHaveBeenCalledTimes(0);
|
||||
button.simulate('click');
|
||||
expect(onClickAbout).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
*/
|
||||
78
scratch-gui/test/unit/components/monitor-list.test.jsx
Normal file
78
scratch-gui/test/unit/components/monitor-list.test.jsx
Normal file
@@ -0,0 +1,78 @@
|
||||
import React from 'react';
|
||||
import {OrderedMap} from 'immutable';
|
||||
import configureStore from 'redux-mock-store';
|
||||
import {Provider} from 'react-redux';
|
||||
import {mountWithIntl} from '../../helpers/intl-helpers.jsx';
|
||||
import MonitorList from '../../../src/components/monitor-list/monitor-list.jsx';
|
||||
import {DEFAULT_THEME} from '../../../src/lib/themes';
|
||||
|
||||
describe('MonitorListComponent', () => {
|
||||
const store = configureStore()({scratchGui: {
|
||||
monitorLayout: {
|
||||
monitors: {},
|
||||
savedMonitorPositions: {}
|
||||
},
|
||||
theme: {
|
||||
theme: DEFAULT_THEME
|
||||
},
|
||||
toolbox: {
|
||||
toolboxXML: ''
|
||||
},
|
||||
vm: {
|
||||
runtime: {
|
||||
requestUpdateMonitor: () => {},
|
||||
getLabelForOpcode: () => ''
|
||||
}
|
||||
}
|
||||
}});
|
||||
const draggable = false;
|
||||
const onMonitorChange = jest.fn();
|
||||
const stageSize = {
|
||||
width: 100,
|
||||
height: 100,
|
||||
widthDefault: 100,
|
||||
heightDefault: 100
|
||||
};
|
||||
|
||||
let monitors = OrderedMap({});
|
||||
|
||||
// Wrap this in a function so it gets test specific states and can be reused.
|
||||
const getComponent = function () {
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<MonitorList
|
||||
draggable={draggable}
|
||||
monitors={monitors}
|
||||
stageSize={stageSize}
|
||||
onMonitorChange={onMonitorChange}
|
||||
/>
|
||||
</Provider>
|
||||
);
|
||||
};
|
||||
|
||||
test('it renders the correct step size for discrete sliders', () => {
|
||||
monitors = OrderedMap({
|
||||
id1: {
|
||||
visible: true,
|
||||
mode: 'slider',
|
||||
isDiscrete: true
|
||||
}
|
||||
});
|
||||
const wrapper = mountWithIntl(getComponent());
|
||||
const input = wrapper.find('input');
|
||||
expect(input.props().step).toBe(1);
|
||||
});
|
||||
|
||||
test('it renders the correct step size for non-discrete sliders', () => {
|
||||
monitors = OrderedMap({
|
||||
id1: {
|
||||
visible: true,
|
||||
mode: 'slider',
|
||||
isDiscrete: false
|
||||
}
|
||||
});
|
||||
const wrapper = mountWithIntl(getComponent());
|
||||
const input = wrapper.find('input');
|
||||
expect(input.props().step).toBe(0.01);
|
||||
});
|
||||
});
|
||||
56
scratch-gui/test/unit/components/monitor.test.jsx
Normal file
56
scratch-gui/test/unit/components/monitor.test.jsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import React from 'react';
|
||||
import {shallow} from 'enzyme';
|
||||
import DefaultMonitor from '../../../src/components/monitor/default-monitor';
|
||||
import Monitor from '../../../src/components/monitor/monitor';
|
||||
import {DARK_THEME, DEFAULT_THEME} from '../../../src/lib/themes';
|
||||
|
||||
jest.mock('../../../src/lib/themes/default');
|
||||
jest.mock('../../../src/lib/themes/dark');
|
||||
|
||||
describe('Monitor Component', () => {
|
||||
test('it selects the correct colors based on default theme', () => {
|
||||
const noop = () => {};
|
||||
|
||||
const wrapper = shallow(<Monitor
|
||||
category="motion"
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
componentRef={noop}
|
||||
draggable={false}
|
||||
label="My label"
|
||||
mode="default"
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onDragEnd={noop}
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onNextMode={noop}
|
||||
theme={DEFAULT_THEME}
|
||||
/>);
|
||||
|
||||
const defaultMonitor = wrapper.find(DefaultMonitor);
|
||||
|
||||
// selects colors from mock value in src/lib/themes/__mocks__/default-colors.js
|
||||
expect(defaultMonitor.props().categoryColor).toEqual({background: '#111111', text: '#444444'});
|
||||
});
|
||||
|
||||
test('it selects the correct colors based on dark mode theme', () => {
|
||||
const noop = () => {};
|
||||
|
||||
const wrapper = shallow(<Monitor
|
||||
category="motion"
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
componentRef={noop}
|
||||
draggable={false}
|
||||
label="My label"
|
||||
mode="default"
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onDragEnd={noop}
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onNextMode={noop}
|
||||
theme={DARK_THEME}
|
||||
/>);
|
||||
|
||||
const defaultMonitor = wrapper.find(DefaultMonitor);
|
||||
|
||||
// selects colors from mock value in src/lib/themes/__mocks__/dark-mode.js
|
||||
expect(defaultMonitor.props().categoryColor).toEqual({background: '#AAAAAA', text: '#BBBBBB'});
|
||||
});
|
||||
});
|
||||
146
scratch-gui/test/unit/components/sound-editor.test.jsx
Normal file
146
scratch-gui/test/unit/components/sound-editor.test.jsx
Normal file
@@ -0,0 +1,146 @@
|
||||
import React from 'react';
|
||||
import {mountWithIntl, componentWithIntl} from '../../helpers/intl-helpers.jsx';
|
||||
import SoundEditor from '../../../src/components/sound-editor/sound-editor';
|
||||
|
||||
describe('Sound Editor Component', () => {
|
||||
let props;
|
||||
beforeEach(() => {
|
||||
props = {
|
||||
isStereo: false,
|
||||
duration: 1,
|
||||
size: 10507,
|
||||
canUndo: true,
|
||||
canRedo: false,
|
||||
chunkLevels: [1, 2, 3],
|
||||
name: 'sound name',
|
||||
playhead: 0.5,
|
||||
trimStart: 0.2,
|
||||
trimEnd: 0.8,
|
||||
onChangeName: jest.fn(),
|
||||
onDelete: jest.fn(),
|
||||
onPlay: jest.fn(),
|
||||
onRedo: jest.fn(),
|
||||
onReverse: jest.fn(),
|
||||
onSofter: jest.fn(),
|
||||
onLouder: jest.fn(),
|
||||
onRobot: jest.fn(),
|
||||
onEcho: jest.fn(),
|
||||
onFaster: jest.fn(),
|
||||
onSlower: jest.fn(),
|
||||
onSetTrimEnd: jest.fn(),
|
||||
onSetTrimStart: jest.fn(),
|
||||
onStop: jest.fn(),
|
||||
onUndo: jest.fn()
|
||||
};
|
||||
});
|
||||
|
||||
test('matches snapshot', () => {
|
||||
const component = componentWithIntl(<SoundEditor {...props} />);
|
||||
expect(component.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('delete button appears when selection is not null', () => {
|
||||
const wrapper = mountWithIntl(
|
||||
<SoundEditor
|
||||
{...props}
|
||||
trimEnd={0.75}
|
||||
trimStart={0.25}
|
||||
/>
|
||||
);
|
||||
wrapper.find('[children="Delete"]').simulate('click');
|
||||
expect(props.onDelete).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('play button appears when playhead is null', () => {
|
||||
const wrapper = mountWithIntl(
|
||||
<SoundEditor
|
||||
{...props}
|
||||
playhead={null}
|
||||
/>
|
||||
);
|
||||
wrapper.find('button[title="Play"]').simulate('click');
|
||||
expect(props.onPlay).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('stop button appears when playhead is not null', () => {
|
||||
const wrapper = mountWithIntl(
|
||||
<SoundEditor
|
||||
{...props}
|
||||
playhead={0.5}
|
||||
/>
|
||||
);
|
||||
wrapper.find('button[title="Stop"]').simulate('click');
|
||||
expect(props.onStop).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('submitting name calls the callback', () => {
|
||||
const wrapper = mountWithIntl(
|
||||
<SoundEditor {...props} />
|
||||
);
|
||||
wrapper.find('input')
|
||||
.simulate('change', {target: {value: 'hello'}})
|
||||
.simulate('blur');
|
||||
expect(props.onChangeName).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('effect buttons call the correct callbacks', () => {
|
||||
const wrapper = mountWithIntl(
|
||||
<SoundEditor {...props} />
|
||||
);
|
||||
|
||||
wrapper.find('[children="Reverse"]').simulate('click');
|
||||
expect(props.onReverse).toHaveBeenCalled();
|
||||
|
||||
wrapper.find('[children="Robot"]').simulate('click');
|
||||
expect(props.onRobot).toHaveBeenCalled();
|
||||
|
||||
wrapper.find('[children="Faster"]').simulate('click');
|
||||
expect(props.onFaster).toHaveBeenCalled();
|
||||
|
||||
wrapper.find('[children="Slower"]').simulate('click');
|
||||
expect(props.onSlower).toHaveBeenCalled();
|
||||
|
||||
wrapper.find('[children="Louder"]').simulate('click');
|
||||
expect(props.onLouder).toHaveBeenCalled();
|
||||
|
||||
wrapper.find('[children="Softer"]').simulate('click');
|
||||
expect(props.onSofter).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('undo and redo buttons can be disabled by canUndo/canRedo', () => {
|
||||
let wrapper = mountWithIntl(
|
||||
<SoundEditor
|
||||
{...props}
|
||||
canUndo
|
||||
canRedo={false}
|
||||
/>
|
||||
);
|
||||
expect(wrapper.find('button[title="Undo"]').prop('disabled')).toBe(false);
|
||||
expect(wrapper.find('button[title="Redo"]').prop('disabled')).toBe(true);
|
||||
|
||||
wrapper = mountWithIntl(
|
||||
<SoundEditor
|
||||
{...props}
|
||||
canRedo
|
||||
canUndo={false}
|
||||
/>
|
||||
);
|
||||
expect(wrapper.find('button[title="Undo"]').prop('disabled')).toBe(true);
|
||||
expect(wrapper.find('button[title="Redo"]').prop('disabled')).toBe(false);
|
||||
});
|
||||
|
||||
test.skip('undo/redo buttons call the correct callback', () => {
|
||||
const wrapper = mountWithIntl(
|
||||
<SoundEditor
|
||||
{...props}
|
||||
canRedo
|
||||
canUndo
|
||||
/>
|
||||
);
|
||||
wrapper.find('button[title="Undo"]').simulate('click');
|
||||
expect(props.onUndo).toHaveBeenCalled();
|
||||
|
||||
wrapper.find('button[title="Redo"]').simulate('click');
|
||||
expect(props.onRedo).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,83 @@
|
||||
import React from 'react';
|
||||
import {mountWithIntl, shallowWithIntl, componentWithIntl} from '../../helpers/intl-helpers.jsx';
|
||||
import SpriteSelectorItemComponent from '../../../src/components/sprite-selector-item/sprite-selector-item';
|
||||
import DeleteButton from '../../../src/components/delete-button/delete-button';
|
||||
|
||||
describe('SpriteSelectorItemComponent', () => {
|
||||
let className;
|
||||
let costumeURL;
|
||||
let name;
|
||||
let onClick;
|
||||
let onDeleteButtonClick;
|
||||
let selected;
|
||||
let number;
|
||||
let details;
|
||||
|
||||
// Wrap this in a function so it gets test specific states and can be reused.
|
||||
const getComponent = function () {
|
||||
return (
|
||||
<SpriteSelectorItemComponent
|
||||
className={className}
|
||||
costumeURL={costumeURL}
|
||||
details={details}
|
||||
name={name}
|
||||
number={number}
|
||||
selected={selected}
|
||||
onClick={onClick}
|
||||
onDeleteButtonClick={onDeleteButtonClick}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
className = 'ponies';
|
||||
costumeURL = 'https://scratch.mit.edu/foo/bar/pony';
|
||||
name = 'Pony sprite';
|
||||
onClick = jest.fn();
|
||||
onDeleteButtonClick = jest.fn();
|
||||
selected = true;
|
||||
// Reset to undefined since they are optional props
|
||||
number = undefined; // eslint-disable-line no-undefined
|
||||
details = undefined; // eslint-disable-line no-undefined
|
||||
});
|
||||
|
||||
test('matches snapshot when selected', () => {
|
||||
const component = componentWithIntl(getComponent());
|
||||
expect(component.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('matches snapshot when given a number and details to show', () => {
|
||||
number = 5;
|
||||
details = '480 x 360';
|
||||
const component = componentWithIntl(getComponent());
|
||||
expect(component.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('does not have a close box when not selected', () => {
|
||||
selected = false;
|
||||
const wrapper = shallowWithIntl(getComponent());
|
||||
expect(wrapper.find(DeleteButton).exists()).toBe(false);
|
||||
});
|
||||
|
||||
test('triggers callback when Box component is clicked', () => {
|
||||
// Use `mount` here because of the way ContextMenuTrigger consumes onClick
|
||||
const wrapper = mountWithIntl(getComponent());
|
||||
wrapper.simulate('click');
|
||||
expect(onClick).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('triggers callback when CloseButton component is clicked', () => {
|
||||
const wrapper = shallowWithIntl(getComponent());
|
||||
wrapper.find(DeleteButton).simulate('click');
|
||||
expect(onDeleteButtonClick).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('it has a context menu with delete menu item and callback', () => {
|
||||
const wrapper = mountWithIntl(getComponent());
|
||||
const contextMenu = wrapper.find('ContextMenu');
|
||||
expect(contextMenu.exists()).toBe(true);
|
||||
|
||||
contextMenu.find('[children="delete"]').simulate('click');
|
||||
expect(onDeleteButtonClick).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
52
scratch-gui/test/unit/components/toggle-buttons.test.jsx
Normal file
52
scratch-gui/test/unit/components/toggle-buttons.test.jsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import React from 'react';
|
||||
import {shallow} from 'enzyme';
|
||||
import ToggleButtons from '../../../src/components/toggle-buttons/toggle-buttons';
|
||||
|
||||
describe('ToggleButtons', () => {
|
||||
test('renders multiple buttons', () => {
|
||||
const component = shallow(<ToggleButtons
|
||||
buttons={[
|
||||
{
|
||||
title: 'Button 1',
|
||||
handleClick: () => {},
|
||||
icon: 'Button 1 icon'
|
||||
},
|
||||
{
|
||||
title: 'Button 2',
|
||||
handleClick: () => {},
|
||||
icon: 'Button 2 icon'
|
||||
}
|
||||
]}
|
||||
/>);
|
||||
|
||||
const buttons = component.find('button');
|
||||
|
||||
expect(buttons).toHaveLength(2);
|
||||
expect(buttons.get(0).props.title).toBe('Button 1');
|
||||
expect(buttons.get(1).props.title).toBe('Button 2');
|
||||
});
|
||||
|
||||
test('calls correct click handler', () => {
|
||||
const onClick1 = jest.fn();
|
||||
const onClick2 = jest.fn();
|
||||
const component = shallow(<ToggleButtons
|
||||
buttons={[
|
||||
{
|
||||
title: 'Button 1',
|
||||
handleClick: onClick1,
|
||||
icon: 'Button 1 icon'
|
||||
},
|
||||
{
|
||||
title: 'Button 2',
|
||||
handleClick: onClick2,
|
||||
icon: 'Button 2 icon'
|
||||
}
|
||||
]}
|
||||
/>);
|
||||
const button2 = component.find('button[title="Button 2"]');
|
||||
button2.simulate('click');
|
||||
|
||||
expect(onClick2).toHaveBeenCalled();
|
||||
expect(onClick1).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user