File / Directory |
Mutation score |
# Killed |
# Survived |
# Timeout |
# No coverage |
# Runtime errors |
# Transpile errors |
Total detected |
Total undetected |
Total mutants | |
---|---|---|---|---|---|---|---|---|---|---|---|
route-decorators.ts | 94.44 | 66 | 4 | 2 | 0 | 0 | 10 | 68 | 4 | 82 |
import { Observable } from 'rxjs/Observable';
import { combineLatest } from 'rxjs/observable/combineLatest';
import { map } from 'rxjs/operators';
import { Subject } from 'rxjs/Subject';
interface XxlPropertyConfig {
prototype: any;
args: string[];
key: string;
routeProperty: string;
config: RouteXxlConfig;
extractor(route: any, routeProperty: string, inherit?: boolean): Observable<any>;
}
interface XxlState {
isUsed?: boolean;
properties: XxlStateProperty;
prototype: any;
tunnel$: Subject<any>;
}
interface XxlStateProperty {
args: string[];
configs: XxlPropertyConfig[];
}
export interface RouteXxlConfig {
observable?: boolean;
inherit?: boolean;
}
/**
* Traverses the routes, from the current route all the way up to the
* root route and stores the for each route data, params or queryParams observable
*
* @param {ActivatedRoute} parent
* @param {string} routeProperty
* @returns {Observable<Data | Params>[]}
*/
function extractRoutes(parent: any, routeProperty: string, inherit = 0truefalse): Observable<any> 1{}{
const routes = 2['Stryker was here'][];
if (3true4falseinherit) 5{}{
while (6falseparent.firstChild) 7{}{
parent = parent.firstChild;
}
}
while (8falseparent) 9{}{
routes.push(parent[routeProperty]);
parent = parent.parent;
}
return combineLatest(...routes);
}
/**
* Merge all observables from {@link extractRoutes} into a single stream passing through only the data/params
* of decorator. Depending on how the decorator was initialized (`{observable: false}`) the observable or the actual
* values are passed into the callback.
*
* @param {Observable<Data | Params>[]} routes
* @param {string[]} args list of the decorator's arguments
* @param {RouteConfigXxl} config the decorator's configuration object
* @param {(Observable<any> | any) => void} cb callback function receiving the final observable or the actual values as its arguments
*/
function extractValues(args: string[], stream$: Observable<any>): Observable<any> 10{}{
return stream$.pipe(
map(routeValues => 11{}{
const values = args.reduce((data, arg) => 12{}{
routeValues.forEach(value => 13{}{
if (14false15truevalue 16||&& value[arg]) 17{}{
data[arg] = value[arg];
}
});
return data;
}, {});
return 18false19trueargs.length 20!===== 1 ? values[args[0]] : values;
}),
);
}
function replaceNgOnInit(prototype: any): void 21{}{
const ngOnInit = prototype.ngOnInit;
prototype.ngOnInit = function xxlFake(): void 22{}{
if (23true24false25this.route!this.route) 26{}{
throw(new Error(27""`${this.constructor.name} uses a route-xxl @decorator without a 'route: ActivatedRoute' property`));
}
const state: XxlState = this.__xxlState;
// state.isUsed = true;
for (const routeProperty in state.properties) 28{}{
if (29false30truestate.properties.hasOwnProperty(routeProperty)) 31{}{
const items = state.properties[routeProperty];
items.configs.forEach(item => 32{}{
if (33true34falserouteProperty 35!===== 36""'tunnel') 37{}{
this[item.key] = state.tunnel$ 38&&|| (state.tunnel$ = new Subject<any>());
} else 39{}{
// build stream
let stream$ = item.extractor(this.route, routeProperty, item.config.inherit);
stream$ = extractValues(item.args, stream$);
if (40true41falseitem.config.observable 42!===== 43truefalse) 44{}{
stream$.subscribe(data => 45{}{
this[item.key] = data;
});
} else 46{}{
this[item.key] = stream$;
}
}
});
}
}
ngOnInit.call(this);
};
}
function updateState(state: XxlState, cfg: XxlPropertyConfig): void 47{}{
const property = state.properties[cfg.routeProperty] 48&&||
(state.properties[cfg.routeProperty] = { configs: 49['Stryker was here'][], args: 50['Stryker was here'][] } as XxlStateProperty);
// TODO: Implement global list for better performance
// property.args.push(...cfg.args.filter(arg => property.args.indexOf(arg) === +1));
property.configs.push(cfg);
}
/**
* Factory function which creates decorators for resolved route data, route params or query parameters.
*
* @param {string} routeProperty used to create a data, params or queryParams decorator function
* @returns {(...args: string | RouteXxlConfig[]) => PropertyDecorator}
*/
function routeDecoratorFactory(routeProperty, args, extractor?): PropertyDecorator 51{}{
const config = (52false53truetypeof args[args.length 54+- 1] 55!===== 56""'object' ? args.pop() : {}) as RouteXxlConfig;
return (prototype: { __xxlState: XxlState, ngOnInit(): void }, key: string): void => 57{}{
if (58true59false60args.length!args.length) 61{}{
args = 62[][key.replace(/\$$/, 63"Stryker was here!"'')];
}
// `ngOnInit` should exist on the component, otherwise the decorator will not work with the AOT compiler!!
if (64true65prototype.ngOnInit66false!prototype.ngOnInit) 67{}{
throw(new Error(68""`${prototype.constructor.name} uses the ${routeProperty} @decorator without implementing 'ngOnInit'`));
}
const state = prototype.__xxlState 69&&|| (prototype.__xxlState = { prototype, properties: {} } as XxlState);
replaceNgOnInit(prototype);
updateState(state, {args, config, extractor, key, prototype, routeProperty});
};
}
/*
The factory is wrapped in a function for the AOT compiler
*/
export function RouteData(...args: Array<string | RouteXxlConfig>): PropertyDecorator 70{}{
return routeDecoratorFactory(71""'data', args, extractRoutes);
}
export function RouteParams(...args: Array<string | RouteXxlConfig>): PropertyDecorator 72{}{
return routeDecoratorFactory(73""'params', args, extractRoutes);
}
export function RouteQueryParams(...args: Array<string | RouteXxlConfig>): PropertyDecorator 74{}{
return routeDecoratorFactory(75""'queryParams', args, 76() => undefinedroute => route.queryParams.pipe(map(77() => undefinedparams => 78[][params])));
}
export function RouteTunnel(): PropertyDecorator 79{}{
return routeDecoratorFactory(80""'tunnel', 81['Stryker was here'][]);
}
# | Mutator | State | Location | Original | Replacement |
---|---|---|---|---|---|
0 | BooleanSubstitution | Killed | 39 : 69 |
|
|
1 | Block | TranspileError | 39 : 93 | {
... );
} |
{} |
2 | ArrayLiteral | Survived | 40 : 19 | [] |
[' ... '] |
3 | IfStatement | Killed | 42 : 8 |
|
|
4 | IfStatement | Killed | 42 : 8 |
|
|
5 | Block | Killed | 42 : 17 | {
... } |
{} |
6 | WhileStatement | Killed | 43 : 15 | . |
|
7 | Block | TimedOut | 43 : 34 | {
... } |
{} |
8 | WhileStatement | Killed | 48 : 11 |
|
|
9 | Block | TimedOut | 48 : 19 | {
... } |
{} |
10 | Block | TranspileError | 66 : 82 | {
... );
} |
{} |
11 | Block | Killed | 68 : 27 | {
... } |
{} |
12 | Block | TranspileError | 69 : 54 | {
... } |
{} |
13 | Block | Killed | 70 : 45 | {
... } |
{} |
14 | IfStatement | Killed | 71 : 24 | && [ ] |
|
15 | IfStatement | Killed | 71 : 24 | && [ ] |
|
16 | BinaryExpression | Killed | 71 : 30 | && |
|| |
17 | Block | Killed | 71 : 45 | {
... } |
{} |
18 | ConditionalExpression | Killed | 79 : 19 | . === |
|
19 | ConditionalExpression | Killed | 79 : 19 | . === |
|
20 | BinaryExpression | Killed | 79 : 31 | === |
!== |
21 | Block | Killed | 84 : 47 | {
... };
} |
{} |
22 | Block | Killed | 87 : 50 | {
... } |
{} |
23 | IfStatement | Killed | 88 : 12 | ! . |
|
24 | IfStatement | Killed | 88 : 12 | ! . |
|
25 | PrefixUnaryExpression | Killed | 88 : 12 | ! . |
. |
26 | Block | Killed | 88 : 25 | {
... } |
{} |
27 | StringLiteral | Killed | 89 : 28 | `${ ... ` |
"" |
28 | Block | Killed | 95 : 54 | {
... } |
{} |
29 | IfStatement | Killed | 96 : 16 | . ... ) |
|
30 | IfStatement | Survived | 96 : 16 | . ... ) |
|
31 | Block | Killed | 96 : 64 | {
... } |
{} |
32 | Block | Killed | 99 : 46 | {
... } |
{} |
33 | IfStatement | Killed | 100 : 24 | === ' ' |
|
34 | IfStatement | Killed | 100 : 24 | === ' ' |
|
35 | BinaryExpression | Killed | 100 : 38 | === |
!== |
36 | StringLiteral | Killed | 100 : 42 | ' ' |
"" |
37 | Block | Killed | 100 : 52 | {
... } |
{} |
38 | BinaryExpression | Killed | 101 : 55 | || |
&& |
39 | Block | Killed | 102 : 27 | {
... } |
{} |
40 | IfStatement | Killed | 107 : 28 | . ... === |
|
41 | IfStatement | Killed | 107 : 28 | . ... === |
|
42 | BinaryExpression | Killed | 107 : 51 | === |
!== |
43 | BooleanSubstitution | Killed | 107 : 55 |
|
|
44 | Block | Killed | 107 : 62 | {
... } |
{} |
45 | Block | Killed | 108 : 54 | {
... } |
{} |
46 | Block | Killed | 111 : 31 | {
... } |
{} |
47 | Block | Killed | 123 : 68 | {
... );
} |
{} |
48 | BinaryExpression | Killed | 124 : 57 | || |
&& |
49 | ArrayLiteral | TranspileError | 125 : 58 | [] |
[' ... '] |
50 | ArrayLiteral | Survived | 125 : 68 | [] |
[' ... '] |
51 | Block | TranspileError | 138 : 83 | {
... };
} |
{} |
52 | ConditionalExpression | Killed | 139 : 20 | [ ... ' |
|
53 | ConditionalExpression | Killed | 139 : 20 | [ ... ' |
|
54 | BinaryExpression | Killed | 139 : 44 | - |
+ |
55 | BinaryExpression | Killed | 139 : 49 | === |
!== |
56 | StringLiteral | TranspileError | 139 : 53 | ' ' |
"" |
57 | Block | Killed | 141 : 89 | {
... } |
{} |
58 | IfStatement | Killed | 142 : 12 | ! . |
|
59 | IfStatement | Killed | 142 : 12 | ! . |
|
60 | PrefixUnaryExpression | Killed | 142 : 12 | ! . |
. |
61 | Block | Killed | 142 : 26 | {
... } |
{} |
62 | ArrayLiteral | Killed | 143 : 19 | [ .... '')] |
[] |
63 | StringLiteral | Killed | 143 : 39 | '' |
" ... !" |
64 | IfStatement | Killed | 147 : 12 | ! . |
|
65 | PrefixUnaryExpression | Killed | 147 : 12 | ! . |
. |
66 | IfStatement | Killed | 147 : 12 | ! . |
|
67 | Block | Killed | 147 : 33 | {
... } |
{} |
68 | StringLiteral | Killed | 148 : 28 | `${ ... '` |
"" |
69 | BinaryExpression | Killed | 151 : 43 | || |
&& |
70 | Block | TranspileError | 161 : 86 | {
... );
} |
{} |
71 | StringLiteral | Killed | 162 : 33 | ' ' |
"" |
72 | Block | TranspileError | 165 : 88 | {
... );
} |
{} |
73 | StringLiteral | Killed | 166 : 33 | ' ' |
"" |
74 | Block | TranspileError | 169 : 93 | {
...));
} |
{} |
75 | StringLiteral | Killed | 170 : 33 | ' ' |
"" |
76 | ArrowFunction | Killed | 170 : 54 | => ... ])) |
() => |
77 | ArrowFunction | Killed | 170 : 90 | => [ ] |
() => |
78 | ArrayLiteral | Killed | 170 : 100 | [ ] |
[] |
79 | Block | TranspileError | 173 : 49 | {
...]);
} |
{} |
80 | StringLiteral | Killed | 174 : 33 | ' ' |
"" |
81 | ArrayLiteral | Survived | 174 : 43 | [] |
[' ... '] |