diff --git a/package.json b/package.json
index 3ce71f7..a518011 100644
--- a/package.json
+++ b/package.json
@@ -52,7 +52,7 @@
"react": "16.3.1",
"react-dom": "16.3.1",
"react-native": "~0.55.4",
- "react-navigation": "^2.10.0",
+ "react-navigation": "^2.11.2",
"react-test-renderer": "16.3.1"
},
"peerDependencies": {
diff --git a/src/navigators/__tests__/.eslintrc b/src/navigators/__tests__/.eslintrc
new file mode 100644
index 0000000..2d17718
--- /dev/null
+++ b/src/navigators/__tests__/.eslintrc
@@ -0,0 +1,6 @@
+{
+ "extends": "../../../.eslintrc",
+ "env": {
+ "jest": true
+ },
+}
diff --git a/src/navigators/__tests__/NestedNavigator-test.js b/src/navigators/__tests__/NestedNavigator-test.js
new file mode 100644
index 0000000..8633bb3
--- /dev/null
+++ b/src/navigators/__tests__/NestedNavigator-test.js
@@ -0,0 +1,40 @@
+import React from 'react';
+import renderer from 'react-test-renderer';
+import StackNavigator from '../createContainedStackNavigator';
+
+const SubNavigator = StackNavigator({
+ Home: {
+ screen: () => null,
+ },
+});
+
+const NavNestedDirect = StackNavigator({
+ Sub: {
+ screen: SubNavigator,
+ },
+});
+
+const NavNestedIndirect = StackNavigator({
+ Sub: {
+ // eslint-disable-next-line react/display-name
+ screen: props => ,
+ },
+});
+
+/* Prevent React error boundaries from swallowing the errors */
+NavNestedIndirect.prototype.componentDidCatch = null;
+SubNavigator.prototype.componentDidCatch = null;
+
+describe('Nested navigators', () => {
+ it('renders succesfully as direct child', () => {
+ const rendered = renderer.create().toJSON();
+ expect(rendered).toMatchSnapshot();
+ });
+
+ it('throw when trying to pass navigation prop', () => {
+ const tryRender = () => {
+ renderer.create();
+ };
+ expect(tryRender).toThrowErrorMatchingSnapshot();
+ });
+});
diff --git a/src/navigators/__tests__/StackNavigator-test.js b/src/navigators/__tests__/StackNavigator-test.js
new file mode 100644
index 0000000..08b2786
--- /dev/null
+++ b/src/navigators/__tests__/StackNavigator-test.js
@@ -0,0 +1,93 @@
+import React, { Component } from 'react';
+import { StyleSheet, View } from 'react-native';
+import renderer from 'react-test-renderer';
+
+import StackNavigator from '../createContainedStackNavigator';
+import { withNavigation } from 'react-navigation';
+import NavigationTestUtils from 'react-navigation/NavigationTestUtils';
+
+const styles = StyleSheet.create({
+ header: {
+ opacity: 0.5,
+ },
+});
+
+class HomeScreen extends Component {
+ static navigationOptions = ({ navigation }) => ({
+ title: `Welcome ${
+ navigation.state.params ? navigation.state.params.user : 'anonymous'
+ }`,
+ gesturesEnabled: true,
+ headerStyle: [{ backgroundColor: 'red' }, styles.header],
+ });
+
+ render() {
+ return null;
+ }
+}
+
+const routeConfig = {
+ Home: {
+ screen: HomeScreen,
+ },
+};
+
+describe('StackNavigator', () => {
+ beforeEach(() => {
+ NavigationTestUtils.resetInternalState();
+ });
+
+ it('renders successfully', () => {
+ const MyStackNavigator = StackNavigator(routeConfig);
+ const rendered = renderer.create().toJSON();
+
+ expect(rendered).toMatchSnapshot();
+ });
+
+ it('applies correct values when headerRight is present', () => {
+ const MyStackNavigator = StackNavigator({
+ Home: {
+ screen: HomeScreen,
+ navigationOptions: {
+ headerRight: ,
+ },
+ },
+ });
+ const rendered = renderer.create().toJSON();
+
+ expect(rendered).toMatchSnapshot();
+ });
+
+ it('passes navigation to headerRight when wrapped in withNavigation', () => {
+ const spy = jest.fn();
+
+ class TestComponent extends React.Component {
+ render() {
+ return {this.props.onPress(this.props.navigation)};
+ }
+ }
+
+ const TestComponentWithNavigation = withNavigation(TestComponent);
+
+ class A extends React.Component {
+ static navigationOptions = {
+ headerRight: ,
+ };
+
+ render() {
+ return ;
+ }
+ }
+
+ const Nav = StackNavigator({ A: { screen: A } });
+
+ renderer.create();
+
+ expect(spy).toBeCalledWith(
+ expect.objectContaining({
+ navigate: expect.any(Function),
+ addListener: expect.any(Function),
+ })
+ );
+ });
+});
diff --git a/src/navigators/__tests__/__snapshots__/NestedNavigator-test.js.snap b/src/navigators/__tests__/__snapshots__/NestedNavigator-test.js.snap
new file mode 100644
index 0000000..9696d68
--- /dev/null
+++ b/src/navigators/__tests__/__snapshots__/NestedNavigator-test.js.snap
@@ -0,0 +1,367 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Nested navigators renders succesfully as direct child 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`Nested navigators throw when trying to pass navigation prop 1`] = `"No \\"routes\\" found in navigation state. Did you try to pass the navigation prop of a React component to a Navigator child? See https://reactnavigation.org/docs/en/custom-navigators.html#navigator-navigation-prop"`;
diff --git a/src/navigators/__tests__/__snapshots__/StackNavigator-test.js.snap b/src/navigators/__tests__/__snapshots__/StackNavigator-test.js.snap
new file mode 100644
index 0000000..4ad8b76
--- /dev/null
+++ b/src/navigators/__tests__/__snapshots__/StackNavigator-test.js.snap
@@ -0,0 +1,391 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`StackNavigator applies correct values when headerRight is present 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Welcome anonymous
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`StackNavigator renders successfully 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Welcome anonymous
+
+
+
+
+
+
+
+
+
+`;
diff --git a/src/views/__tests__/Transitioner-test.js b/src/views/__tests__/Transitioner-test.js
new file mode 100644
index 0000000..29e06b6
--- /dev/null
+++ b/src/views/__tests__/Transitioner-test.js
@@ -0,0 +1,49 @@
+/* eslint react/display-name:0 */
+import React from 'react';
+import renderer from 'react-test-renderer';
+import Transitioner from '../Transitioner';
+
+describe('Transitioner', () => {
+ it('should not trigger onTransitionStart and onTransitionEnd when route params are changed', () => {
+ const onTransitionStartCallback = jest.fn();
+ const onTransitionEndCallback = jest.fn();
+
+ const transitionerProps = {
+ configureTransition: (transitionProps, prevTransitionProps) => ({}),
+ navigation: {
+ state: {
+ index: 0,
+ routes: [
+ { key: '1', routeName: 'Foo' },
+ { key: '2', routeName: 'Bar' },
+ ],
+ },
+ goBack: () => false,
+ dispatch: () => false,
+ setParams: () => false,
+ navigate: () => false,
+ },
+ render: () =>
,
+ onTransitionStart: onTransitionStartCallback,
+ onTransitionEnd: onTransitionEndCallback,
+ };
+
+ const nextTransitionerProps = {
+ ...transitionerProps,
+ navigation: {
+ ...transitionerProps.navigation,
+ state: {
+ index: 0,
+ routes: [
+ { key: '1', routeName: 'Foo', params: { name: 'Zoom' } },
+ { key: '2', routeName: 'Bar' },
+ ],
+ },
+ },
+ };
+ const component = renderer.create();
+ component.update();
+ expect(onTransitionStartCallback).not.toBeCalled();
+ expect(onTransitionEndCallback).not.toBeCalled();
+ });
+});
diff --git a/yarn.lock b/yarn.lock
index 519bbf3..ae2a0a2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5087,9 +5087,9 @@ react-navigation-tabs@0.6.0:
react-native-safe-area-view "^0.7.0"
react-native-tab-view "^1.0.0"
-react-navigation@^2.10.0:
- version "2.11.0"
- resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-2.11.0.tgz#d3d56d67a199cc07a74326419939cb1ae80d3c1e"
+react-navigation@^2.11.2:
+ version "2.11.2"
+ resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-2.11.2.tgz#cd099f6d7d09efe48ef8463614a3abb113d45c01"
dependencies:
clamp "^1.0.1"
create-react-context "^0.2.1"