Skip to content

Commit

Permalink
Merge pull request #26 from nickovchinnikov/nick/gameWithHooks
Browse files Browse the repository at this point in the history
Compose components to the static game
  • Loading branch information
nickovchinnikov authored Aug 5, 2021
2 parents 495f253 + d084cd1 commit 0e10084
Show file tree
Hide file tree
Showing 29 changed files with 985 additions and 314 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@
### Cell component tests
### Custom hooks
### Game Field (grid) component

### Static game

[Pull request](https://github.com/nickovchinnikov/minesweeper/pull/26)

### Components library review

[Pull request](https://github.com/nickovchinnikov/minesweeper/pull/18)
Expand Down
26 changes: 26 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^12.0.0",
"@testing-library/react-hooks": "^7.0.1",
"@testing-library/user-event": "^13.2.1",
"@types/jest": "^26.0.23",
"@types/react": "^17.0.13",
"@types/react-dom": "^17.0.8",
Expand Down
54 changes: 54 additions & 0 deletions src/components/Game/Game.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react';
import { Story, Meta } from '@storybook/react';

import { CellState, Field } from '@/helpers/Field';

import { Grid } from '@/components/Grid';
import { Top } from '@/components/Top';
import { Scoreboard } from '@/components/Scoreboard';

import { GameArea } from './GameArea';
import { Wrapper, WrapperProps } from './Wrapper';
import { GameOver } from './GameOver';

export default {
title: 'Game/Example',
component: Wrapper,
} as Meta;

const Template: Story<WrapperProps> = (args) => <Wrapper {...args} />;

export const GameExample = Template.bind({});

const { empty: e, hidden: h, bomb: b, flag: f } = CellState;

const defautGameField: Field = [
[f, f, h, h, h],
[b, 3, 1, e, e],
[1, 1, h, 1, 1],
[1, e, e, 1, b],
[2, 1, e, 1, e],
];

GameExample.args = {
children: (
<>
<Top feature="Flag" firstAction="right click">
Minesweeper
</Top>
<GameArea>
<Scoreboard
time="000"
bombs="000"
levels={['beginner', 'intermediate', 'expert']}
onReset={() => null}
onChange={() => null}
/>
<GameOver onClick={() => null} isWin={true} />
<Grid onClick={() => null} onContextMenu={() => null}>
{defautGameField}
</Grid>
</GameArea>
</>
),
};
38 changes: 38 additions & 0 deletions src/components/Game/Game.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import { GameOver } from './GameOver';

describe('Game Over test cases', () => {
it('GameOver render win correctly', () => {
const onReset = jest.fn();

const { asFragment } = render(<GameOver onClick={onReset} isWin={true} />);

const element = screen.getByText('😎');

expect(element).toBeInTheDocument();

userEvent.click(element);

expect(onReset).toHaveBeenCalled();

expect(asFragment()).toMatchSnapshot();
});
it('GameOver render fail correctly', () => {
const onReset = jest.fn();

const { asFragment } = render(<GameOver onClick={onReset} isWin={false} />);

const element = screen.getByText('🙁');

expect(element).toBeInTheDocument();

userEvent.click(element);

expect(onReset).toHaveBeenCalled();

expect(asFragment()).toMatchSnapshot();
});
});
22 changes: 22 additions & 0 deletions src/components/Game/GameArea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React, { FC, ReactNode } from 'react';
import styled from '@emotion/styled';

export interface GameAreaProps {
/**
* Game items
*/
children: ReactNode;
}

export const GameArea: FC<GameAreaProps> = ({ children }) => (
<Frame>{children}</Frame>
);

const Frame = styled.div`
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
border: 6px solid #e3e3e3;
background-color: #e3e3e3;
`;
21 changes: 21 additions & 0 deletions src/components/Game/GameOver.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import { Story, Meta } from '@storybook/react';

import { GameOver, GameOverProps } from './GameOver';

export default {
title: 'Game/GameOver',
component: GameOver,
} as Meta;

const Template: Story<GameOverProps> = (args) => <GameOver {...args} />;

export const GameOverWinExample = Template.bind({});
GameOverWinExample.args = {
isWin: true,
};

export const GameOverLooseExample = Template.bind({});
GameOverLooseExample.args = {
isWin: false,
};
41 changes: 41 additions & 0 deletions src/components/Game/GameOver.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { FC } from 'react';
import styled from '@emotion/styled';

export interface GameOverProps extends FrameProps {
/**
* Click handler
*/
onClick: () => void;
}

export const GameOver: FC<GameOverProps> = ({ onClick, isWin }) => (
<Frame onClick={onClick} isWin={isWin}>
{isWin ? '😎' : '🙁'}
</Frame>
);

interface FrameProps {
/**
* Is user win flag
*/
isWin: boolean;
}

const Frame = styled.div<FrameProps>`
top: 60%;
left: 50%;
z-index: 11;
width: 8vw;
height: 8vw;
font-size: 4vw;
text-align: center;
user-select: none;
cursor: pointer;
line-height: 8vw;
position: absolute;
border-radius: 50%;
pointer-events: auto;
background-color: #d1d1d1;
transform: translate(-50%, -50%);
border: 1px solid rgba(51, 51, 51, 0.25);
`;
21 changes: 21 additions & 0 deletions src/components/Game/Wrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React, { FC, ReactNode } from 'react';
import styled from '@emotion/styled';

export interface WrapperProps {
/**
* Game items
*/
children: ReactNode;
}

export const Wrapper: FC<WrapperProps> = ({ children }) => (
<Frame>{children}</Frame>
);

const Frame = styled.div`
position: relative;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
`;
71 changes: 71 additions & 0 deletions src/components/Game/__snapshots__/Game.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Game Over test cases GameOver render fail correctly 1`] = `
<DocumentFragment>
.emotion-0 {
top: 60%;
left: 50%;
z-index: 11;
width: 8vw;
height: 8vw;
font-size: 4vw;
text-align: center;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
cursor: pointer;
line-height: 8vw;
position: absolute;
border-radius: 50%;
pointer-events: auto;
background-color: #d1d1d1;
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
border: 1px solid rgba(51, 51, 51, 0.25);
}
<div
class="emotion-0"
>
🙁
</div>
</DocumentFragment>
`;

exports[`Game Over test cases GameOver render win correctly 1`] = `
<DocumentFragment>
.emotion-0 {
top: 60%;
left: 50%;
z-index: 11;
width: 8vw;
height: 8vw;
font-size: 4vw;
text-align: center;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
cursor: pointer;
line-height: 8vw;
position: absolute;
border-radius: 50%;
pointer-events: auto;
background-color: #d1d1d1;
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
border: 1px solid rgba(51, 51, 51, 0.25);
}
<div
class="emotion-0"
>
😎
</div>
</DocumentFragment>
`;
3 changes: 3 additions & 0 deletions src/components/Game/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { GameArea } from './GameArea';
export { Wrapper } from './Wrapper';
export { GameOver } from './GameOver';
4 changes: 2 additions & 2 deletions src/components/Grid/Cell.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe('Cell component check', () => {

render(<Cell {...props}>{cell}</Cell>);

const cellComp = screen.getByTestId(`${cell}_${coords}`);
const cellComp = screen.getByTestId(`${coords}`);

const contextMenuEvent = createEvent.contextMenu(cellComp);
fireEvent(cellComp, contextMenuEvent);
Expand All @@ -50,7 +50,7 @@ describe('Cell component check', () => {

render(<Cell {...props}>{cell}</Cell>);

const cellComp = screen.getByTestId(`${cell}_${coords}`);
const cellComp = screen.getByTestId(`${coords}`);

fireEvent.click(cellComp);
fireEvent.contextMenu(cellComp);
Expand Down
Loading

0 comments on commit 0e10084

Please sign in to comment.