Skip to content
This repository has been archived by the owner on Feb 25, 2020. It is now read-only.

Fix test --coverage errors related to TS #8

Merged
merged 16 commits into from
Oct 25, 2018
Merged
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules/
dist/
jest-setup.js
coverage/
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,10 @@ android/keystores/debug.keystore

# Build
dist/

# TypeScript-generated files
*.d.ts
!src/react-navigation.d.ts

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.


# Code coverage files
coverage/
31 changes: 23 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@
],
"react-native": "src/index.js",
"scripts": {
"pretest": "yarn lint && yarn build",
"test": "jest",
"lint": "eslint .",
"format": "eslint . --fix",
"build": "babel --no-babelrc --plugins=transform-es2015-block-scoping,transform-es2015-modules-commonjs,transform-react-jsx,transform-class-properties,transform-object-rest-spread,transform-flow-strip-types src --copy-files --out-dir dist --ignore '**/__tests__/**'",
"babel": "babel --no-babelrc --plugins=transform-es2015-block-scoping,transform-es2015-modules-commonjs,transform-react-jsx,transform-class-properties,transform-object-rest-spread,transform-flow-strip-types src --copy-files --out-dir dist --ignore '**/__tests__/**'",
"tsc": "tsc",
"build": "yarn babel && yarn tsc",
"prepare": "yarn build",
"release": "release-it"
},
Expand Down Expand Up @@ -60,34 +63,46 @@
"eslint": "^4.12.1",
"eslint-config-satya164": "^1.0.1",
"eslint-plugin-react-native-globals": "^0.1.0",
"husky": "^0.14.3",
"husky": "^1.1.2",
"jest": "^22.1.3",
"jest-expo": "^30.0.0",
"prettier": "^1.8.2",
"react": "16.3.1",
"react-dom": "16.3.1",
"react-native": "^0.55.4",
"react-test-renderer": "16.3.1",
"release-it": "^7.6.1"
"release-it": "^7.6.1",
"ts-jest": "^23.10.4",
"typescript": "^3.1.3"
},
"peerDependencies": {
"react": "*"
},
"jest": {
"preset": "react-native",
"testRegex": "/__tests__/[^/]+-test\\.js$",
"testRegex": "/__tests__/[^/]+-test\\.[jt]sx?$",

This comment was marked as abuse.

This comment was marked as abuse.

This comment was marked as abuse.

"setupFiles": [
"<rootDir>/jest-setup.js"
],
"coveragePathIgnorePatterns": [
"jest-setup.js"
],
"modulePathIgnorePatterns": [
"<rootDir>/example/"
],
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native|react-clone-referenced-element)"
]
],
"transform": {
"^.+\\.tsx?$": "ts-jest"
},
"globals": {
"ts-jest": {
"tsConfig": "./tsconfig.test.json",
"diagnostics": {
"ignoreCodes": [
151001

This comment was marked as abuse.

This comment was marked as abuse.

]
}
}
}
},
"prettier": {
"trailingComma": "es5",
Expand Down
186 changes: 186 additions & 0 deletions src/getChildEventSubscriber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
/*
* This is used to extract one children's worth of events from a stream of navigation action events
*
* Based on the 'action' events that get fired for this navigation state, this utility will fire
* focus and blur events for this child
*/
export default function getChildEventSubscriber(
addListener: (
eventName: string,
eventHandler: EventHandler
) => { remove: () => void },
key: string
) {
const actionSubscribers = new Set<EventHandler>();
const willFocusSubscribers = new Set<EventHandler>();
const didFocusSubscribers = new Set<EventHandler>();
const willBlurSubscribers = new Set<EventHandler>();
const didBlurSubscribers = new Set<EventHandler>();

const removeAll = () => {
[
actionSubscribers,
willFocusSubscribers,
didFocusSubscribers,
willBlurSubscribers,
didBlurSubscribers,
].forEach(set => set.clear());

upstreamSubscribers.forEach(subs => subs && subs.remove());
};

const getChildSubscribers = (evtName: string) => {
switch (evtName) {
case 'action':
return actionSubscribers;
case 'willFocus':
return willFocusSubscribers;
case 'didFocus':
return didFocusSubscribers;
case 'willBlur':
return willBlurSubscribers;
case 'didBlur':
return didBlurSubscribers;
default:
return null;
}
};

const emit = (type: string, payload: IPayload) => {
const payloadWithType = { ...payload, type };
const subscribers = getChildSubscribers(type);
if (subscribers) {
subscribers.forEach(subs => {
subs(payloadWithType);
});
}
};

// lastEmittedEvent keeps track of focus state for one route. First we assume
// we are blurred. If we are focused on initialization, the first 'action'
// event will cause onFocus+willFocus events because we had previously been
// considered blurred
let lastEmittedEvent = 'didBlur';

const upstreamEvents = [
'willFocus',
'didFocus',
'willBlur',
'didBlur',
'action',
];

const upstreamSubscribers = upstreamEvents.map((eventName: string) =>
addListener(eventName, payload => {
const { state, lastState, action } = payload;
const lastRoutes = lastState && lastState.routes;
const routes = state && state.routes;

// const lastFocusKey =
// lastState && lastState.routes && lastState.routes[lastState.index].key;
const focusKey = routes && routes[state.index].key;

const isChildFocused = focusKey === key;
const lastRoute =
lastRoutes && lastRoutes.find(route => route.key === key);
const newRoute = routes && routes.find(route => route.key === key);
const childPayload: IPayload = {
context: `${key}:${action.type}_${payload.context || 'Root'}`,
state: newRoute,
lastState: lastRoute,
action,
type: eventName,
};
const isTransitioning = !!state && state.isTransitioning;

const previouslyLastEmittedEvent = lastEmittedEvent;

if (lastEmittedEvent === 'didBlur') {
// The child is currently blurred. Look for willFocus conditions
if (eventName === 'willFocus' && isChildFocused) {
emit((lastEmittedEvent = 'willFocus'), childPayload);
} else if (eventName === 'action' && isChildFocused) {
emit((lastEmittedEvent = 'willFocus'), childPayload);
}
}
if (lastEmittedEvent === 'willFocus') {
// We are currently mid-focus. Look for didFocus conditions.
// If state.isTransitioning is false, this child event happens immediately after willFocus
if (eventName === 'didFocus' && isChildFocused && !isTransitioning) {
emit((lastEmittedEvent = 'didFocus'), childPayload);
} else if (
eventName === 'action' &&
isChildFocused &&
!isTransitioning
) {
emit((lastEmittedEvent = 'didFocus'), childPayload);
}
}

if (lastEmittedEvent === 'didFocus') {
// The child is currently focused. Look for blurring events
if (!isChildFocused) {
// The child is no longer focused within this navigation state
emit((lastEmittedEvent = 'willBlur'), childPayload);
} else if (eventName === 'willBlur') {
// The parent is getting a willBlur event
emit((lastEmittedEvent = 'willBlur'), childPayload);
} else if (
eventName === 'action' &&
previouslyLastEmittedEvent === 'didFocus'
) {
// While focused, pass action events to children for grandchildren focus
emit('action', childPayload);
}
}

if (lastEmittedEvent === 'willBlur') {
// The child is mid-blur. Wait for transition to end
if (eventName === 'action' && !isChildFocused && !isTransitioning) {
// The child is done blurring because transitioning is over, or isTransitioning
// never began and didBlur fires immediately after willBlur
emit((lastEmittedEvent = 'didBlur'), childPayload);
} else if (eventName === 'didBlur') {
// Pass through the parent didBlur event if it happens
emit((lastEmittedEvent = 'didBlur'), childPayload);
}
}

if (lastEmittedEvent === 'didBlur' && !newRoute) {
removeAll();
}
})
);

return {
addListener(eventName: string, eventHandler: EventHandler) {
const subscribers = getChildSubscribers(eventName);
if (!subscribers) {
throw new Error(`Invalid event name "${eventName}"`);
}
subscribers.add(eventHandler);
const remove = () => {
subscribers.delete(eventHandler);
};
return { remove };
},
};
}

export type EventHandler = (payload: IPayload) => void;

export interface IPayload {
action: { type: string };
context?: string;
lastState: IRoute;
state: IRoute;
type: string;
}

export interface IRoute {
index: number;
isTransitioning: boolean;
key?: string;
routeName?: string;
routes: any[];
}
2 changes: 1 addition & 1 deletion src/getChildNavigation.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import getChildEventSubscriber from './getChildEventSubscriber';
import getChildRouter from './getChildRouter';
import getChildRouter from './getChildRouter.ts';
import getNavigationActionCreators from './routers/getNavigationActionCreators';

const createParamGetter = route => (paramName, defaultValue) => {
Expand Down
2 changes: 1 addition & 1 deletion src/getChildRouter.js → src/getChildRouter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default function getChildRouter(router, routeName) {
export default function getChildRouter(router: any, routeName: string) {
if (router.childRouters && router.childRouters[routeName]) {
return router.childRouters[routeName];
}
Expand Down
11 changes: 0 additions & 11 deletions src/routers/KeyGenerator.js

This file was deleted.

11 changes: 11 additions & 0 deletions src/routers/KeyGenerator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
let uniqueBaseId: string = `id-${Date.now()}`;
let uuidCount: number = 0;

export function _TESTING_ONLY_normalize_keys(): void {
uniqueBaseId = 'id';
uuidCount = 0;
}

export function generateKey(): string {
return `${uniqueBaseId}-${uuidCount++}`;
}
2 changes: 1 addition & 1 deletion src/routers/StackRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import getScreenForRouteName from './getScreenForRouteName';
import StateUtils from '../StateUtils';
import validateRouteConfigMap from './validateRouteConfigMap';
import invariant from '../utils/invariant';
import { generateKey } from './KeyGenerator';
import { generateKey } from './KeyGenerator.ts';
import { createPathParser } from './pathUtils';

function behavesLikePushAction(action) {
Expand Down
2 changes: 1 addition & 1 deletion src/routers/__tests__/PathHandling-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import SwitchRouter from '../SwitchRouter';
import StackRouter from '../StackRouter';
import TabRouter from '../TabRouter';
import NavigationActions from '../../NavigationActions';
import { _TESTING_ONLY_normalize_keys } from '../KeyGenerator';
import { _TESTING_ONLY_normalize_keys } from '../KeyGenerator.ts';

beforeEach(() => {
_TESTING_ONLY_normalize_keys();
Expand Down
2 changes: 1 addition & 1 deletion src/routers/__tests__/Routers-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import TabRouter from '../TabRouter';
import SwitchRouter from '../SwitchRouter';

import NavigationActions from '../../NavigationActions';
import { _TESTING_ONLY_normalize_keys } from '../KeyGenerator';
import { _TESTING_ONLY_normalize_keys } from '../KeyGenerator.ts';

beforeEach(() => {
_TESTING_ONLY_normalize_keys();
Expand Down
2 changes: 1 addition & 1 deletion src/routers/__tests__/StackRouter-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import React from 'react';
import StackRouter from '../StackRouter';
import StackActions from '../StackActions';
import NavigationActions from '../../NavigationActions';
import { _TESTING_ONLY_normalize_keys } from '../KeyGenerator';
import { _TESTING_ONLY_normalize_keys } from '../KeyGenerator.ts';

beforeEach(() => {
_TESTING_ONLY_normalize_keys();
Expand Down
7 changes: 7 additions & 0 deletions tsconfig.test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"sourceMap": true
}
}
15 changes: 15 additions & 0 deletions tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"extends": "tslint:recommended",
"rules": {
"arrow-parens": [true, "ban-single-arg-parens"],
"arrow-return-shorthand": [true, "multiline"],
"trailing-comma": false,
"quotemark": {
"options": [
"single",
"avoid-escape"
]
},
"object-literal-sort-keys": false
}
}
Loading