react-native-navigation
Version:
React Native Navigation - truly native navigation for iOS and Android
351 lines (350 loc) • 9.67 kB
JavaScript
;
import * as React from 'react';
import { Store } from "../components/Store.js";
import { mock, instance, when, anything } from 'ts-mockito';
import { OptionsCrawler } from "./OptionsCrawler.js";
import { UniqueIdProvider } from "../adapters/UniqueIdProvider.js";
describe('OptionsCrawler', () => {
let uut;
let mockedStore;
let mockedUniqueIdProvider;
beforeEach(() => {
mockedStore = mock(Store);
mockedUniqueIdProvider = mock(UniqueIdProvider);
when(mockedUniqueIdProvider.generate(anything())).thenCall(prefix => `${prefix}+UNIQUE_ID`);
const uniqueIdProvider = instance(mockedUniqueIdProvider);
uut = new OptionsCrawler(instance(mockedStore), uniqueIdProvider);
});
it('Components: injects options object', () => {
when(mockedStore.getComponentClassForName('theComponentName')).thenReturn(() => class extends React.Component {
static options = {
popGesture: true
};
});
const layout = {
component: {
id: 'testId',
name: 'theComponentName'
}
};
uut.crawl(layout);
expect(layout.component.options).toEqual({
popGesture: true
});
});
it('Components: injects options from original component class static property', () => {
when(mockedStore.getComponentClassForName('theComponentName')).thenReturn(() => class extends React.Component {
static options() {
return {
popGesture: true
};
}
});
const layout = {
component: {
id: 'testId',
name: 'theComponentName'
}
};
uut.crawl(layout);
expect(layout.component.options).toEqual({
popGesture: true
});
});
it('ExternalComponent: does nothing as there is no React component for external component', () => {
const layout = {
externalComponent: {
id: 'testId',
name: 'theComponentName'
}
};
uut.crawl(layout);
expect(layout.externalComponent.options).toEqual(undefined);
});
it('ExternalComponent: merge options with passed options', () => {
const layout = {
externalComponent: {
id: 'testId',
name: 'theComponentName',
options: {
popGesture: false
}
}
};
uut.crawl(layout);
expect(layout.externalComponent.options).toEqual({
popGesture: false
});
});
it('Stack: injects options from original component class static property', () => {
when(mockedStore.getComponentClassForName('theComponentName')).thenReturn(() => class extends React.Component {
static options() {
return {
popGesture: true
};
}
});
const layout = {
stack: {
children: [{
component: {
id: 'testId',
name: 'theComponentName'
}
}]
}
};
uut.crawl(layout);
expect(layout.stack.children[0].component.options).toEqual({
popGesture: true
});
});
it('SideMenu: injects options from original component class static property', () => {
when(mockedStore.getComponentClassForName('theComponentName')).thenReturn(() => class extends React.Component {
static options() {
return {
popGesture: true
};
}
});
const layout = {
sideMenu: {
left: {
component: {
id: 'testId',
name: 'theComponentName'
}
},
center: {
component: {
id: 'testId',
name: 'theComponentName'
}
},
right: {
component: {
id: 'testId',
name: 'theComponentName'
}
}
}
};
uut.crawl(layout);
expect(layout.sideMenu.center.component.options).toEqual({
popGesture: true
});
expect(layout.sideMenu.left.component.options).toEqual({
popGesture: true
});
expect(layout.sideMenu.right.component.options).toEqual({
popGesture: true
});
});
it('SplitView: injects options from original component class static property', () => {
when(mockedStore.getComponentClassForName('theComponentName')).thenReturn(() => class extends React.Component {
static options() {
return {
popGesture: true
};
}
});
const layout = {
splitView: {
master: {
component: {
id: 'testId',
name: 'theComponentName'
}
},
detail: {
component: {
id: 'testId',
name: 'theComponentName'
}
}
}
};
uut.crawl(layout);
expect(layout.splitView.master.component.options).toEqual({
popGesture: true
});
expect(layout.splitView.detail.component.options).toEqual({
popGesture: true
});
});
it('BottomTabs: injects options from original component class static property', () => {
when(mockedStore.getComponentClassForName('theComponentName')).thenReturn(() => class extends React.Component {
static options() {
return {
popGesture: true
};
}
});
const layout = {
bottomTabs: {
children: [{
component: {
id: 'testId',
name: 'theComponentName'
}
}, {
component: {
id: 'testId',
name: 'theComponentName'
}
}]
}
};
uut.crawl(layout);
expect(layout.bottomTabs.children[0].component.options).toEqual({
popGesture: true
});
expect(layout.bottomTabs.children[1].component.options).toEqual({
popGesture: true
});
});
it('TopTabs: injects options from original component class static property', () => {
when(mockedStore.getComponentClassForName('theComponentName')).thenReturn(() => class extends React.Component {
static options() {
return {
popGesture: true
};
}
});
const layout = {
topTabs: {
children: [{
component: {
id: 'testId',
name: 'theComponentName'
}
}, {
component: {
id: 'testId',
name: 'theComponentName'
}
}]
}
};
uut.crawl(layout);
expect(layout.topTabs.children[0].component.options).toEqual({
popGesture: true
});
expect(layout.topTabs.children[1].component.options).toEqual({
popGesture: true
});
});
it('Components: merges options from component class static property with passed options, favoring passed options', () => {
when(mockedStore.getComponentClassForName('theComponentName')).thenReturn(() => class extends React.Component {
static options() {
return {
topBar: {
title: {
text: 'this gets overriden'
},
subtitle: {
text: 'exists only in static'
}
}
};
}
});
const node = {
component: {
id: 'testId',
name: 'theComponentName',
options: {
topBar: {
title: {
text: 'exists only in passed'
}
}
}
}
};
uut.crawl(node);
expect(node.component.options).toEqual({
topBar: {
title: {
text: 'exists only in passed'
},
subtitle: {
text: 'exists only in static'
}
}
});
});
it('Components: options default obj', () => {
when(mockedStore.getComponentClassForName('theComponentName')).thenReturn(() => class extends React.Component {});
const node = {
component: {
name: 'theComponentName',
options: {},
id: 'testId'
},
children: []
};
uut.crawl(node);
expect(node.component.options).toEqual({});
});
it('Components: should generate component id', () => {
let componentIdInProps = '';
when(mockedStore.getComponentClassForName('theComponentName')).thenReturn(() => class extends React.Component {
static options(props) {
componentIdInProps = props.componentId;
}
});
const node = {
component: {
name: 'theComponentName',
options: {},
id: undefined
},
children: []
};
uut.crawl(node);
expect(componentIdInProps).toEqual('Component+UNIQUE_ID');
});
it('componentId is included in props passed to options generator', () => {
let componentIdInProps = '';
when(mockedStore.getComponentClassForName('theComponentName')).thenReturn(() => class extends React.Component {
static options(props) {
componentIdInProps = props.componentId;
return {};
}
});
const node = {
component: {
id: 'testId',
name: 'theComponentName',
passProps: {
someProp: 'here'
}
}
};
uut.crawl(node);
expect(componentIdInProps).toEqual('testId');
});
it('componentId does not override componentId in passProps', () => {
let componentIdInProps = '';
when(mockedStore.getComponentClassForName('theComponentName')).thenReturn(() => class extends React.Component {
static options(props) {
componentIdInProps = props.componentId;
return {};
}
});
const node = {
component: {
id: 'testId',
name: 'theComponentName',
passProps: {
someProp: 'here',
componentId: 'compIdFromPassProps'
}
}
};
uut.crawl(node);
expect(componentIdInProps).toEqual('compIdFromPassProps');
});
});
//# sourceMappingURL=OptionsCrawler.test.js.map