Skip to content

release: 0.2.x #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Dec 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .docs/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 6 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
charset = utf-8
trim_trailing_whitespace = true

[*.{js,json,ts,tsx,html,svg,css}]
indent_size = 2
indent_style = space
indent_size = 2
max_line_length = 80
3 changes: 3 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
16 changes: 16 additions & 0 deletions .github/workflows/check-code.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: check-code-style
on: push

jobs:
check-code-style:
runs-on: ubuntu-latest

steps:
- name: Checkout 🛎️
uses: actions/checkout@v4

- name: Setup Node.js ⚙️ - Cache dependencies ⚡ - Install dependencies 🔧
uses: ./.github/workflows/setup-node

- name: Code style ✅
run: npm run check-code
16 changes: 16 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: lint
on: push

jobs:
lint:
runs-on: ubuntu-latest

steps:
- name: Checkout 🛎️
uses: actions/checkout@v4

- name: Setup Node.js ⚙️ - Cache dependencies ⚡ - Install dependencies 🔧
uses: ./.github/workflows/setup-node

- name: Lint ✅
run: npm run lint
52 changes: 52 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: publish-to-github-pages
on:
push:
branches:
- master
- release/0.2.x

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: "pages"
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout 🛎️
uses: actions/checkout@v4

- name: Setup Node.js ⚙️ - Cache dependencies ⚡ - Install dependencies 🔧
uses: ./.github/workflows/setup-node

- name: Setup Pages ⚙️
uses: actions/configure-pages@v4
with:
static_site_generator: next

- name: Build with Next.js 🏗️
run: npx next build

- name: Upload artifact 📡
uses: actions/upload-pages-artifact@v3
with:
path: ./out

deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}

runs-on: ubuntu-latest
needs: build

steps:
- name: Publish to GitHub Pages 🚀
id: deployment
uses: actions/deploy-pages@v4
21 changes: 21 additions & 0 deletions .github/workflows/setup-node/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: setup-node
description: "Setup Node.js ⚙️ - Cache dependencies ⚡ - Install dependencies 🔧"
runs:
using: "composite"
steps:
- name: Setup Node.js ⚙️
uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"

- name: Cache dependencies ⚡
id: cache_dependencies
uses: actions/cache@v3
with:
path: node_modules
key: node-modules-${{ hashFiles('package-lock.json') }}

- name: Install dependencies 🔧
shell: bash
if: steps.cache_dependencies.outputs.cache-hit != 'true'
run: npm ci
16 changes: 16 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: test
on: push

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Checkout 🛎️
uses: actions/checkout@v4

- name: Setup Node.js ⚙️ - Cache dependencies ⚡ - Install dependencies 🔧
uses: ./.github/workflows/setup-node

- name: Test 🧪
run: npm run test-coverage
20 changes: 16 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,28 @@
# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20.10.0
1 change: 0 additions & 1 deletion .prettierignore

This file was deleted.

1 change: 0 additions & 1 deletion .prettierrc.json → .prettierrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
{
"useTabs": false,
"tabWidth": 2
}
21 changes: 0 additions & 21 deletions LICENSE

This file was deleted.

52 changes: 28 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,41 @@
# Getting Started with 2048
# 2048-in-react

This game (2048) was built using **React** and **TypeScript**. The unique part of this example is animations. The animations in React aren't that straightforward, so I hope you can learn something new from it.
[![Open issues][issues-badge]][issues-url]
[![CI][lint-badge]][lint-url]
[![CI][test-badge]][test-url]
[![TypeScript][typescript-badge]][typescript-url]

**Wondering how was that built?** You can find a video tutorial on [my YouTube Channel](https://www.youtube.com/channel/UCJV16_5c4A0amyBZSI4yP6A)
[![](.docs/demo.gif)](https://mateuszsokola.github.io/2048-in-react/)

## How To Play?
## [Play 2048 💥](https://mateuszsokola.github.io/2048-in-react/)

You can play 2048 on [Github pages](https://mateuszsokola.github.io/2048-in-react/)
## Features

## Available Scripts
- Fully-functional 2048 clone
- Animations
- Supports **keyboard**, **mouse** and **touch** events

In the project directory, you can run:
## Development

### `yarn start`
_Easily set up a local development environment!_

Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
Just start dev server on [localhost](http://localhost:3000):

The page will reload if you make edits.\
You will also see any lint errors in the console.
- clone
- `npm install`
- `npm run dev`

### `yarn build`
**Start coding!** 🎉

Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.
## Contributing

The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!
All contributions are welcome!

See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.

## Learn More

You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).

To learn React, check out the [React documentation](https://reactjs.org/).
[lint-badge]: https://github.com/mateuszsokola/2048-in-react/actions/workflows/lint.yml/badge.svg
[lint-url]: https://github.com/mateuszsokola/2048-in-react/actions/workflows/actions/workflows/lint.yml
[test-badge]: https://github.com/mateuszsokola/2048-in-react/actions/workflows/test.yml/badge.svg
[test-url]: https://github.com/mateuszsokola/2048-in-react/actions/workflows/test.yml
[issues-badge]: https://img.shields.io/github/issues/mateuszsokola/2048-in-react
[issues-url]: https://github.com/mateuszsokola/2048-in-react/issues
[typescript-badge]: https://badges.frapsoft.com/typescript/code/typescript.svg?v=101
[typescript-url]: https://github.com/microsoft/TypeScript
27 changes: 27 additions & 0 deletions __tests__/compontents/board.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { render } from "@testing-library/react";
import Board from "@/components/board";
import GameProvider from "@/context/game-context";

describe("Board", () => {
it("should render board with 16 cells", () => {
const { container } = render(
<GameProvider>
<Board />
</GameProvider>,
);
const cellElements = container.querySelectorAll(".cell");

expect(cellElements.length).toEqual(16);
});

it("should render board with 2 tiles", async () => {
const { container } = render(
<GameProvider>
<Board />
</GameProvider>,
);
const tiles = container.querySelectorAll(".tile");

expect(tiles.length).toEqual(2);
});
});
49 changes: 49 additions & 0 deletions __tests__/compontents/mobile-swiper.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from "react";
import { render, fireEvent } from "@testing-library/react";
import MobileSwiper, { SwipeInput } from "@/components/mobile-swiper";

describe("MobileSwiper", () => {
it("should trigger onSwipe with correct input on touch end", () => {
const onSwipeMock = jest.fn();
const { container } = render(
<MobileSwiper onSwipe={onSwipeMock}>
<div data-testid="swipe-target">Swipe me!</div>
</MobileSwiper>,
);

const swipeTarget = container.querySelector(
"[data-testid='swipe-target']",
) as HTMLElement;

fireEvent.touchStart(swipeTarget, {
touches: [{ clientX: 0, clientY: 0 }],
});
fireEvent.touchEnd(swipeTarget, {
changedTouches: [{ clientX: 50, clientY: 0 }],
});

expect(onSwipeMock).toHaveBeenCalledWith({ deltaX: 50, deltaY: 0 });
});

it("should not trigger onSwipe if touch is outside the component", () => {
const onSwipeMock = jest.fn();
const { container } = render(
<MobileSwiper onSwipe={onSwipeMock}>
<div data-testid="swipe-target">Swipe me!</div>
</MobileSwiper>,
);

const swipeTarget = container.querySelector(
"[data-testid='swipe-target']",
) as HTMLElement;

fireEvent.touchStart(swipeTarget, {
touches: [{ clientX: 0, clientY: 0 }],
});
fireEvent.touchEnd(document.body, {
changedTouches: [{ clientX: 50, clientY: 0 }],
});

expect(onSwipeMock).not.toHaveBeenCalled();
});
});
17 changes: 17 additions & 0 deletions __tests__/compontents/score.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { render } from "@testing-library/react";
import GameProvider from "@/context/game-context";
import Board from "@/components/board";
import Score from "@/components/score";

describe("Score", () => {
it("should display score", () => {
const { container } = render(
<GameProvider>
<Score />
<Board />
</GameProvider>,
);

expect(container.querySelector(".score > div")?.textContent).toEqual("0");
});
});
Loading