Skip to content

Commit

Permalink
overhaul tests to typescript, update ts configs
Browse files Browse the repository at this point in the history
  • Loading branch information
Emil Hartz committed Jul 14, 2020
1 parent cdf5d93 commit 83ef4d2
Show file tree
Hide file tree
Showing 12 changed files with 283 additions and 104 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: './tsconfig.json',
project: './tsconfig.all.json',
},
extends: [
'eslint:recommended',
Expand Down
19 changes: 19 additions & 0 deletions __tests__/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {MockedSwipeFunctions} from '../useSwipeable.spec';

const expectSwipingDir = (fns: jest.Mock, dir: string) => {
fns.mock.calls.forEach((call) => {
expect(call[0].dir).toBe(dir);
});
};

export const expectSwipeFuncsDir = (sf: MockedSwipeFunctions, dir: string): void => {
Object.keys(sf).forEach((s) => {
if (s.endsWith(dir) || s === "onSwiped") {
expect(sf[s as keyof MockedSwipeFunctions]).toHaveBeenCalled();
} else if (s === "onSwiping") {
expectSwipingDir(sf[s], dir);
} else {
expect(sf[s as keyof MockedSwipeFunctions]).not.toHaveBeenCalled();
}
});
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
/* global document, jest, expect, beforeAll */
import React from "react";
import * as React from "react";
import { render, fireEvent, act } from "@testing-library/react";
import { useSwipeable, LEFT, RIGHT, UP, DOWN } from "../index";
import { useSwipeable, LEFT, RIGHT, UP, DOWN } from "../src/index";
import { expectSwipeFuncsDir } from "./helpers";

const DIRECTIONS = [LEFT, RIGHT, UP, DOWN];

function getMockedSwipeFunctions() {
const DIRECTIONS: [typeof LEFT, typeof RIGHT, typeof UP, typeof DOWN] = [
LEFT,
RIGHT,
UP,
DOWN,
];

export type MockedSwipeFunctions = {
onSwiping: jest.Mock;
onSwiped: jest.Mock;
onSwipedLeft: jest.Mock;
onSwipedRight: jest.Mock;
onSwipedUp: jest.Mock;
onSwipedDown: jest.Mock;
};
function getMockedSwipeFunctions(): MockedSwipeFunctions {
const onSwiped = "onSwiped";
return DIRECTIONS.reduce(
(acc, dir) => ({ ...acc, [`onSwiped${dir}`]: jest.fn() }),
(acc, dir) => ({ ...acc, [onSwiped + dir]: jest.fn() }),
{
onSwiping: jest.fn(),
onSwiped: jest.fn(),
}
} as MockedSwipeFunctions
);
}

Expand All @@ -22,7 +35,7 @@ const TESTING_TEXT = "touch here";
*/
function SwipeableUsingHook({ nodeName = "div", ...rest }) {
const eventHandlers = useSwipeable(rest);
const Elem = nodeName;
const Elem = nodeName as React.ElementType;
return (
<Elem {...eventHandlers}>
<span>{TESTING_TEXT}</span>
Expand All @@ -37,11 +50,18 @@ const TS = "touchStart";
const TM = "touchMove";
const TE = "touchEnd";

const createClientXYObject = (x, y) => ({ clientX: x, clientY: y });
const createClientXYObject = (x?: number, y?: number) => ({
clientX: x,
clientY: y,
});
// Create touch event
const cte = ({ x, y }) => ({ touches: [createClientXYObject(x, y)] });
const cte = ({ x, y }: { x?: number; y?: number }) => ({
touches: [createClientXYObject(x, y)],
});
// Create Mouse Event
const cme = ({ x, y }) => ({ ...createClientXYObject(x, y) });
const cme = ({ x, y }: { x?: number; y?: number }) => ({
...createClientXYObject(x, y),
});

describe("useSwipeable", () => {
let defaultPrevented = 0;
Expand Down Expand Up @@ -336,7 +356,9 @@ describe("useSwipeable", () => {

expect(swipeFuncs.onSwiping).toHaveBeenCalledTimes(8);
[LEFT, UP, DOWN].forEach((dir) => {
expect(swipeFuncs[`onSwiped${dir}`]).not.toHaveBeenCalled();
expect(
swipeFuncs[`onSwiped${dir}` as keyof MockedSwipeFunctions]
).not.toHaveBeenCalled();
});
});

Expand Down Expand Up @@ -397,10 +419,10 @@ describe("useSwipeable", () => {
expect(onSwipedDown).toHaveBeenCalledTimes(2);
});

it(`handles new prop swipe callbacks from rerenders`, () => {
it(`handles new prop swipe callbacks from re-renders`, () => {
const onSwipedSpy = jest.fn();

function TestHookComponent({ next }) {
function TestHookComponent({ next }: { next: () => void }) {
const handlers = useSwipeable({ onSwiped: next });
return <div {...handlers}>{TESTING_TEXT}</div>;
}
Expand Down
19 changes: 12 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
"jsnext:main": "./dist/react-swipeable.modern.js",
"module": "./dist/react-swipeable.module.js",
"source": "./src/index.ts",
"types": "./dist/index.d.ts",
"typings": "./dist/index.d.ts",
"scripts": {
"build": "microbundle --no-compress --name swipeable --output dist",
"build:examples": "webpack -p --config ./examples/webpack.config.min.js",
"build:publish:examples": "npm run build:examples && rimraf examples/node_modules && gh-pages -d examples",
"clean": "rimraf dist",
"format": "prettier --write src/",
"lint": "eslint .",
"format": "prettier --write src __tests__",
"lint": "eslint . --ext .ts,.tsx",
"prebuild": "npm run clean",
"prepare": "npm run build",
"pretest": "npm run lint",
Expand All @@ -32,10 +34,9 @@
}
],
"jest": {
"testPathIgnorePatterns": [
"/node_modules/",
"/types/",
"/__tests__/helpers/"
"preset": "ts-jest",
"testMatch": [
"<rootDir>/__tests__/**/*.(test|spec).ts?(x)"
]
},
"keywords": [
Expand Down Expand Up @@ -68,14 +69,16 @@
"types/index.d.ts"
],
"license": "MIT",
"types": "types",
"devDependencies": {
"@babel/plugin-proposal-class-properties": "^7.2.0",
"@babel/plugin-proposal-object-rest-spread": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"@babel/preset-react": "^7.10.4",
"@testing-library/react": "^10.4.3",
"@types/jest": "^26.0.4",
"@types/react": "^16.8.12",
"@typescript-eslint/eslint-plugin": "^3.6.1",
"@typescript-eslint/parser": "^3.6.1",
"babel-jest": "^26.1.0",
"babel-loader": "^8.0.5",
"coveralls": "^3.0.3",
Expand All @@ -94,11 +97,13 @@
"rollup": "^1.1.2",
"rollup-plugin-babel": "^4.3.2",
"size-limit": "^1.3.5",
"ts-jest": "^26.1.2",
"typescript": "^3.9.6",
"webpack": "^4.29.0",
"webpack-cli": "^3.2.1",
"webpack-dev-server": "^3.1.14"
},
"dependencies": {},
"peerDependencies": {
"react": ">= 16.8.0"
}
Expand Down
17 changes: 0 additions & 17 deletions src/__tests__/helpers/index.js

This file was deleted.

33 changes: 20 additions & 13 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* global document */
import * as React from "react";

export type HandledEvents = MouseEvent | TouchEvent;
export type HandledEvents = React.MouseEvent | TouchEvent | MouseEvent;
export type Vector2 = [number, number];
export type EventData = {
event: HandledEvents;
Expand Down Expand Up @@ -36,7 +36,7 @@ export interface SwipeableOptions {

export interface SwipeableHandlers {
ref(element: HTMLElement | null): void;
onMouseDown?(event: HandledEvents): void;
onMouseDown?(event: React.MouseEvent): void;
}

type StateEventData = {
Expand Down Expand Up @@ -137,21 +137,22 @@ function getHandlers(
): [
{
ref: (element: HTMLElement | null) => void;
onMouseDown?: (event: HandledEvents) => void;
onMouseDown?: (event: React.MouseEvent) => void;
},
(el: any) => (() => void) | undefined
] {
const onStart = (event: HandledEvents) => {
// if more than a single touch don't track, for now...
if (event && ('touches' in event) && event.touches.length > 1) return;
if (event && "touches" in event && event.touches.length > 1) return;

set((state, props) => {
// setup mouse listeners on document to track swipe since swipe can leave container
if (props.trackMouse) {
document.addEventListener(mouseMove, onMove);
document.addEventListener(mouseUp, onUp);
}
const { clientX, clientY } = ('touches' in event) ? event.touches[0] : event;
const { clientX, clientY } =
"touches" in event ? event.touches[0] : event;
const xy = rotateXYByAngle([clientX, clientY], props.rotationAngle);
return {
...state,
Expand All @@ -168,11 +169,12 @@ function getHandlers(
if (
!state.xy[0] ||
!state.xy[1] ||
(('touches' in event) && event.touches.length > 1)
("touches" in event && event.touches.length > 1)
) {
return state;
}
const { clientX, clientY } = ('touches' in event) ? event.touches[0] : event;
const { clientX, clientY } =
"touches" in event ? event.touches[0] : event;
const [x, y] = rotateXYByAngle([clientX, clientY], props.rotationAngle);
const deltaX = state.xy[0] - x;
const deltaY = state.xy[1] - y;
Expand Down Expand Up @@ -202,7 +204,7 @@ function getHandlers(
// track if a swipe is cancelable(handler for swiping or swiped(dir) exists)
// so we can call preventDefault if needed
let cancelablePageSwipe = false;
if (props.onSwiping || props.onSwiped || (`onSwiped${dir}` in props)) {
if (props.onSwiping || props.onSwiped || `onSwiped${dir}` in props) {
cancelablePageSwipe = true;
}

Expand Down Expand Up @@ -232,7 +234,7 @@ function getHandlers(
props.onSwiped && props.onSwiped(eventData);

const onSwipedDir = `onSwiped${eventData.dir}`;
if ((onSwipedDir in props)) {
if (onSwipedDir in props) {
(props as any)[onSwipedDir](eventData);
}
}
Expand All @@ -254,7 +256,10 @@ function getHandlers(
const attachTouch = (el: HTMLElement) => {
if (el && el.addEventListener) {
// attach touch event listeners and handlers
const tls: [typeof touchStart | typeof touchMove | typeof touchEnd, (e: HandledEvents) => void][] = [
const tls: [
typeof touchStart | typeof touchMove | typeof touchEnd,
(e: HandledEvents) => void
][] = [
[touchStart, onStart],
[touchMove, onMove],
[touchEnd, onEnd],
Expand All @@ -273,7 +278,7 @@ function getHandlers(
// if the same DOM el as previous just return state
if (state.el === el) return state;

let addState: { cleanUpTouch?: (() => void) | null } = {};
const addState: { cleanUpTouch?: (() => void) | null } = {};
// if new DOM el clean up old DOM and reset cleanUpTouch
if (state.el && state.el !== el && state.cleanUpTouch) {
state.cleanUpTouch();
Expand All @@ -290,7 +295,9 @@ function getHandlers(
};

// set ref callback to attach touch event listeners
const output: { ref: typeof onRef, onMouseDown?: typeof onStart} = { ref: onRef };
const output: { ref: typeof onRef; onMouseDown?: typeof onStart } = {
ref: onRef,
};

// if track mouse attach mouse down listener
if (handlerProps.trackMouse) {
Expand All @@ -305,7 +312,7 @@ function updateTransientState(
props: Props,
attachTouch: (el: any) => (() => void) | undefined
) {
let addState: { cleanUpTouch?(): void } = {};
const addState: { cleanUpTouch?(): void } = {};
// clean up touch handlers if no longer tracking touches
if (!props.trackTouch && state.cleanUpTouch) {
state.cleanUpTouch();
Expand Down
4 changes: 4 additions & 0 deletions tsconfig.all.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "./tsconfig.base.json",
"include": ["src/**/*", "__tests__"],
}
21 changes: 21 additions & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",
"esModuleInterop": true,
"jsx": "react",
"lib": ["ESNext", "dom"],
"module": "ESNext",
"moduleResolution": "node",
"noImplicitAny": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"outDir": "lib/",
"pretty": true,
"rootDirs": ["./src", "./stories"],
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"target": "ESNext"
}
}
23 changes: 2 additions & 21 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,4 @@
{
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",
"esModuleInterop": true,
"jsx": "react",
"lib": ["esnext", "dom"],
"module": "es2015",
"moduleResolution": "node",
"noImplicitAny": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"outDir": "lib/",
"pretty": true,
"rootDirs": ["./src", "./stories"],
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"target": "esnext"
},
"extends": "./tsconfig.base.json",
"include": ["src/**/*"],
"exclude": ["examples/**/*"]
}
}
4 changes: 4 additions & 0 deletions tsconfig.test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "./tsconfig.base.json",
"include": ["__tests__"],
}
Loading

0 comments on commit 83ef4d2

Please sign in to comment.