2016-03-21 18:13:59 +00:00
|
|
|
/**
|
|
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
|
2016-04-28 02:15:28 +00:00
|
|
|
jest.unmock('NavigationScenesReducer');
|
2016-03-21 18:13:59 +00:00
|
|
|
|
|
|
|
const NavigationScenesReducer = require('NavigationScenesReducer');
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Simulate scenes transtion with changes of navigation states.
|
|
|
|
*/
|
|
|
|
function testTransition(states) {
|
2016-05-21 01:09:57 +00:00
|
|
|
const routes = states.map(keys => {
|
2016-03-21 18:13:59 +00:00
|
|
|
return {
|
2016-06-27 19:03:51 +00:00
|
|
|
index: 0,
|
2016-05-22 23:27:53 +00:00
|
|
|
routes: keys.map(key => {
|
2016-03-21 18:13:59 +00:00
|
|
|
return { key };
|
|
|
|
}),
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
let scenes = [];
|
|
|
|
let prevState = null;
|
2016-05-21 01:09:57 +00:00
|
|
|
routes.forEach((nextState) => {
|
2016-03-21 18:13:59 +00:00
|
|
|
scenes = NavigationScenesReducer(scenes, nextState, prevState);
|
|
|
|
prevState = nextState;
|
|
|
|
});
|
|
|
|
|
|
|
|
return scenes;
|
|
|
|
}
|
|
|
|
|
|
|
|
describe('NavigationScenesReducer', () => {
|
|
|
|
|
|
|
|
it('gets initial scenes', () => {
|
|
|
|
const scenes = testTransition([
|
|
|
|
['1', '2'],
|
|
|
|
]);
|
|
|
|
|
|
|
|
expect(scenes).toEqual([
|
|
|
|
{
|
2016-06-27 19:03:51 +00:00
|
|
|
index: 0,
|
|
|
|
isActive: true,
|
|
|
|
isStale: false,
|
|
|
|
key: 'scene_1',
|
|
|
|
route: {
|
|
|
|
key: '1'
|
2016-03-21 18:13:59 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2016-06-27 19:03:51 +00:00
|
|
|
index: 1,
|
|
|
|
isActive: false,
|
|
|
|
isStale: false,
|
|
|
|
key: 'scene_2',
|
|
|
|
route: {
|
|
|
|
key: '2'
|
2016-03-21 18:13:59 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('pushes new scenes', () => {
|
|
|
|
// Transition from ['1', '2'] to ['1', '2', '3'].
|
|
|
|
const scenes = testTransition([
|
|
|
|
['1', '2'],
|
|
|
|
['1', '2', '3'],
|
|
|
|
]);
|
|
|
|
|
|
|
|
expect(scenes).toEqual([
|
|
|
|
{
|
2016-06-27 19:03:51 +00:00
|
|
|
index: 0,
|
|
|
|
isActive: true,
|
|
|
|
isStale: false,
|
|
|
|
key: 'scene_1',
|
|
|
|
route: {
|
|
|
|
key: '1'
|
2016-03-21 18:13:59 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2016-06-27 19:03:51 +00:00
|
|
|
index: 1,
|
|
|
|
isActive: false,
|
|
|
|
isStale: false,
|
|
|
|
key: 'scene_2',
|
|
|
|
route: {
|
|
|
|
key: '2'
|
2016-03-21 18:13:59 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2016-06-27 19:03:51 +00:00
|
|
|
index: 2,
|
|
|
|
isActive: false,
|
|
|
|
isStale: false,
|
|
|
|
key: 'scene_3',
|
|
|
|
route: {
|
|
|
|
key: '3'
|
2016-03-21 18:13:59 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
2016-06-27 19:03:51 +00:00
|
|
|
it('gets active scene when index changes', () => {
|
|
|
|
const state1 = {
|
|
|
|
index: 0,
|
|
|
|
routes: [{key: '1'}, {key: '2'}],
|
|
|
|
};
|
|
|
|
|
|
|
|
const state2 = {
|
|
|
|
index: 1,
|
|
|
|
routes: [{key: '1'}, {key: '2'}],
|
|
|
|
};
|
|
|
|
|
|
|
|
const scenes1 = NavigationScenesReducer([], state1, null);
|
|
|
|
const scenes2 = NavigationScenesReducer(scenes1, state2, state1);
|
|
|
|
const route = scenes2.find((scene) => scene.isActive).route;
|
|
|
|
expect(route).toEqual({key: '2'});
|
|
|
|
});
|
|
|
|
|
2016-05-25 18:26:22 +00:00
|
|
|
it('gets same scenes', () => {
|
|
|
|
const state1 = {
|
|
|
|
index: 0,
|
|
|
|
routes: [{key: '1'}, {key: '2'}],
|
|
|
|
};
|
|
|
|
|
|
|
|
const state2 = {
|
|
|
|
index: 0,
|
|
|
|
routes: [{key: '1'}, {key: '2'}],
|
|
|
|
};
|
|
|
|
|
|
|
|
const scenes1 = NavigationScenesReducer([], state1, null);
|
|
|
|
const scenes2 = NavigationScenesReducer(scenes1, state2, state1);
|
|
|
|
expect(scenes1).toBe(scenes2);
|
|
|
|
});
|
|
|
|
|
Fix UIExplorer Search
Summary:
In UI explorer, the route is made of an object which look like this.
```
{key: 'AppList', filter: 'query string from the search box'}
```
When a new search query is enter, a new `filter` value is applied, and the key `AppList`
remains the same.
In NavigationScenesReducer, we should compare the routes with both their keys and references.
The current implementation only compares the keys, which unfortunately depends on the a weak
assumption that all routes immutable and keys are unique.
In UI Explore, the route key is always 'AppList', which makes sense since we use the key
to match the scene, and whenever a new search query is provides, a new route will be created.
Reviewed By: nicklockwood
Differential Revision: D3357023
fbshipit-source-id: a3c9e98092f5ce555e5dbb4cc806bab2e67d8014
2016-05-27 19:02:55 +00:00
|
|
|
it('gets different scenes when keys are different', () => {
|
2016-05-25 18:26:22 +00:00
|
|
|
const state1 = {
|
|
|
|
index: 0,
|
|
|
|
routes: [{key: '1'}, {key: '2'}],
|
|
|
|
};
|
|
|
|
|
|
|
|
const state2 = {
|
|
|
|
index: 0,
|
|
|
|
routes: [{key: '2'}, {key: '1'}],
|
|
|
|
};
|
|
|
|
|
|
|
|
const scenes1 = NavigationScenesReducer([], state1, null);
|
|
|
|
const scenes2 = NavigationScenesReducer(scenes1, state2, state1);
|
|
|
|
expect(scenes1).not.toBe(scenes2);
|
|
|
|
});
|
|
|
|
|
Fix UIExplorer Search
Summary:
In UI explorer, the route is made of an object which look like this.
```
{key: 'AppList', filter: 'query string from the search box'}
```
When a new search query is enter, a new `filter` value is applied, and the key `AppList`
remains the same.
In NavigationScenesReducer, we should compare the routes with both their keys and references.
The current implementation only compares the keys, which unfortunately depends on the a weak
assumption that all routes immutable and keys are unique.
In UI Explore, the route key is always 'AppList', which makes sense since we use the key
to match the scene, and whenever a new search query is provides, a new route will be created.
Reviewed By: nicklockwood
Differential Revision: D3357023
fbshipit-source-id: a3c9e98092f5ce555e5dbb4cc806bab2e67d8014
2016-05-27 19:02:55 +00:00
|
|
|
it('gets different scenes when routes are different', () => {
|
|
|
|
const state1 = {
|
|
|
|
index: 0,
|
|
|
|
routes: [{key: '1', x: 1}, {key: '2', x: 2}],
|
|
|
|
};
|
|
|
|
|
|
|
|
const state2 = {
|
|
|
|
index: 0,
|
|
|
|
routes: [{key: '1', x: 3}, {key: '2', x: 4}],
|
|
|
|
};
|
|
|
|
|
|
|
|
const scenes1 = NavigationScenesReducer([], state1, null);
|
|
|
|
const scenes2 = NavigationScenesReducer(scenes1, state2, state1);
|
|
|
|
expect(scenes1).not.toBe(scenes2);
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2016-06-27 19:03:51 +00:00
|
|
|
it('gets different scenes when state index changes', () => {
|
|
|
|
const state1 = {
|
|
|
|
index: 0,
|
|
|
|
routes: [{key: '1', x: 1}, {key: '2', x: 2}],
|
|
|
|
};
|
|
|
|
|
|
|
|
const state2 = {
|
|
|
|
index: 1,
|
|
|
|
routes: [{key: '1', x: 1}, {key: '2', x: 2}],
|
|
|
|
};
|
|
|
|
|
|
|
|
const scenes1 = NavigationScenesReducer([], state1, null);
|
|
|
|
const scenes2 = NavigationScenesReducer(scenes1, state2, state1);
|
|
|
|
expect(scenes1).not.toBe(scenes2);
|
|
|
|
});
|
|
|
|
|
2016-03-21 18:13:59 +00:00
|
|
|
it('pops scenes', () => {
|
|
|
|
// Transition from ['1', '2', '3'] to ['1', '2'].
|
|
|
|
const scenes = testTransition([
|
|
|
|
['1', '2', '3'],
|
|
|
|
['1', '2'],
|
|
|
|
]);
|
|
|
|
|
|
|
|
expect(scenes).toEqual([
|
|
|
|
{
|
2016-06-27 19:03:51 +00:00
|
|
|
index: 0,
|
|
|
|
isActive: true,
|
|
|
|
isStale: false,
|
|
|
|
key: 'scene_1',
|
|
|
|
route: {
|
|
|
|
key: '1'
|
2016-03-21 18:13:59 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2016-06-27 19:03:51 +00:00
|
|
|
index: 1,
|
|
|
|
isActive: false,
|
|
|
|
isStale: false,
|
|
|
|
key: 'scene_2',
|
|
|
|
route: {
|
|
|
|
key: '2'
|
2016-03-21 18:13:59 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2016-06-27 19:03:51 +00:00
|
|
|
index: 2,
|
|
|
|
isActive: false,
|
|
|
|
isStale: true,
|
|
|
|
key: 'scene_3',
|
|
|
|
route: {
|
|
|
|
key: '3'
|
2016-03-21 18:13:59 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('replaces scenes', () => {
|
|
|
|
const scenes = testTransition([
|
|
|
|
['1', '2'],
|
|
|
|
['3'],
|
|
|
|
]);
|
|
|
|
|
|
|
|
expect(scenes).toEqual([
|
|
|
|
{
|
2016-06-27 19:03:51 +00:00
|
|
|
index: 0,
|
|
|
|
isActive: false,
|
|
|
|
isStale: true,
|
|
|
|
key: 'scene_1',
|
|
|
|
route: {
|
|
|
|
key: '1'
|
2016-03-21 18:13:59 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2016-06-27 19:03:51 +00:00
|
|
|
index: 0,
|
|
|
|
isActive: true,
|
|
|
|
isStale: false,
|
|
|
|
key: 'scene_3',
|
|
|
|
route: {
|
|
|
|
key: '3'
|
2016-03-21 18:13:59 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2016-06-27 19:03:51 +00:00
|
|
|
index: 1,
|
|
|
|
isActive: false,
|
|
|
|
isStale: true,
|
|
|
|
key: 'scene_2',
|
|
|
|
route: {
|
|
|
|
key: '2'
|
2016-03-21 18:13:59 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('revives scenes', () => {
|
|
|
|
const scenes = testTransition([
|
|
|
|
['1', '2'],
|
|
|
|
['3'],
|
|
|
|
['2'],
|
|
|
|
]);
|
|
|
|
|
|
|
|
expect(scenes).toEqual([
|
|
|
|
{
|
2016-06-27 19:03:51 +00:00
|
|
|
index: 0,
|
|
|
|
isActive: false,
|
|
|
|
isStale: true,
|
|
|
|
key: 'scene_1',
|
|
|
|
route: {
|
|
|
|
key: '1'
|
2016-03-21 18:13:59 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2016-06-27 19:03:51 +00:00
|
|
|
index: 0,
|
|
|
|
isActive: true,
|
|
|
|
isStale: false,
|
|
|
|
key: 'scene_2',
|
|
|
|
route: {
|
|
|
|
key: '2'
|
2016-03-21 18:13:59 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2016-06-27 19:03:51 +00:00
|
|
|
index: 0,
|
|
|
|
isActive: false,
|
|
|
|
isStale: true,
|
|
|
|
key: 'scene_3',
|
|
|
|
route: {
|
|
|
|
key: '3'
|
2016-03-21 18:13:59 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
});
|