[Navigator] A method `subtract` to compute the diff between stack mutation.

Summary:
When mutation of a stack happens, we'd like to compute the diff of the stacks (before and after) so that
we can know which routes are removed in the new stack.

This diff adds a new method `substract` which does what we need.
This commit is contained in:
Hedger Wang 2015-08-04 16:01:14 -07:00
parent 274769fd8c
commit 222594cb44
2 changed files with 88 additions and 1 deletions

View File

@ -11,7 +11,7 @@ var invariant = require('invariant');
type IterationCallback = (route: any, index: number, key: string) => void; type IterationCallback = (route: any, index: number, key: string) => void;
var {List} = immutable; var {List, Set} = immutable;
function isRouteEmpty(route: any): boolean { function isRouteEmpty(route: any): boolean {
return (route === undefined || route === null || route === '') || false; return (route === undefined || route === null || route === '') || false;
@ -32,6 +32,12 @@ class RouteNode {
} }
} }
var StackDiffRecord = immutable.Record({
key: null,
route: null,
index: null,
});
/** /**
* The immutable route stack. * The immutable route stack.
*/ */
@ -201,6 +207,25 @@ class RouteStack {
} }
} }
/**
* Returns a Set excluding any routes contained within the stack given.
*/
subtract(stack: RouteStack): Set<StackDiffRecord> {
var items = [];
this._routeNodes.forEach((node: RouteNode, index: number) => {
if (!stack._routeNodes.contains(node)) {
items.push(
new StackDiffRecord({
route: node.value,
index: index,
key: node.key,
})
);
}
});
return new Set(items);
}
_update(index: number, routeNodes: List): RouteStack { _update(index: number, routeNodes: List): RouteStack {
if (this._index === index && this._routeNodes === routeNodes) { if (this._index === index && this._routeNodes === routeNodes) {
return this; return this;

View File

@ -31,6 +31,10 @@ jest
var NavigationRouteStack = require('NavigationRouteStack'); var NavigationRouteStack = require('NavigationRouteStack');
function assetStringNotEmpty(str) {
expect(!!str && typeof str === 'string').toBe(true);
}
describe('NavigationRouteStack:', () => { describe('NavigationRouteStack:', () => {
// Different types of routes. // Different types of routes.
var ROUTES = [ var ROUTES = [
@ -341,4 +345,62 @@ describe('NavigationRouteStack:', () => {
['b', 1, true], ['b', 1, true],
]); ]);
}); });
// Diff
it('subtracts stack', () => {
var stack1 = new NavigationRouteStack(2, ['a', 'b', 'c']);
var stack2 = stack1.pop().pop().push('x').push('y');
var diff = stack1.subtract(stack2);
var result = diff.toJS().map((record) => {
assetStringNotEmpty(record.key);
return {
index: record.index,
route: record.route,
};
});
// route `b` and `c` are no longer in the stack.
expect(result).toEqual([
{
index: 1,
route: 'b',
},
{
index: 2,
route: 'c',
},
]);
});
it('only subtracts the derived stack', () => {
var stack1 = new NavigationRouteStack(2, ['a', 'b', 'c']);
var stack2 = new NavigationRouteStack(0, ['a']);
var diff = stack1.subtract(stack2);
var result = diff.toJS().map((record) => {
assetStringNotEmpty(record.key);
return {
index: record.index,
route: record.route,
};
});
expect(result).toEqual([
{
index: 0,
route: 'a',
},
{
index: 1,
route: 'b',
},
{
index: 2,
route: 'c',
},
]);
});
}); });