Skip to content

Commit 62334f9

Browse files
feat(store): add createFeatureSelector migration (#3214)
* feat(store): add createFeatureSelector migration * chore: update test
1 parent ba86496 commit 62334f9

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { Tree } from '@angular-devkit/schematics';
2+
import {
3+
SchematicTestRunner,
4+
UnitTestTree,
5+
} from '@angular-devkit/schematics/testing';
6+
import * as path from 'path';
7+
8+
describe('Store Migration 13_0_0 beta', () => {
9+
const collectionPath = path.join(__dirname, '../migration.json');
10+
const pkgName = 'store';
11+
12+
it(`should replace createFeatureSelector usages with 2 generics`, async () => {
13+
const contents = `
14+
import {createFeatureSelector} from '@ngrx/store'
15+
16+
// untouched
17+
const featureSelector1 = createFeatureSelector('feature1');
18+
const featureSelector2 = createFeatureSelector<Feature>(feature2);
19+
const featureSelector3 = createFeatureSelector<State,Feature,SomethingElse>(feature3);
20+
const featureSelector4 = createFeatureSelector<fromFeat.State>('feature4');
21+
22+
// modified
23+
const featureSelector5 = createFeatureSelector<State, Feature>('feature5');
24+
const featureSelector6 = createFeatureSelector<State,Feature>(feature6);
25+
const featureSelector7 = createFeatureSelector<fromRoot.State, fromFeat.State>('feature7');
26+
`;
27+
28+
const expected = `
29+
import {createFeatureSelector} from '@ngrx/store'
30+
31+
// untouched
32+
const featureSelector1 = createFeatureSelector('feature1');
33+
const featureSelector2 = createFeatureSelector<Feature>(feature2);
34+
const featureSelector3 = createFeatureSelector<State,Feature,SomethingElse>(feature3);
35+
const featureSelector4 = createFeatureSelector<fromFeat.State>('feature4');
36+
37+
// modified
38+
const featureSelector5 = createFeatureSelector< Feature>('feature5');
39+
const featureSelector6 = createFeatureSelector<Feature>(feature6);
40+
const featureSelector7 = createFeatureSelector< fromFeat.State>('feature7');
41+
`;
42+
43+
const appTree = new UnitTestTree(Tree.empty());
44+
appTree.create('./fixture.ts', contents);
45+
const runner = new SchematicTestRunner('schematics', collectionPath);
46+
47+
const newTree = await runner
48+
.runSchematicAsync(`ngrx-${pkgName}-migration-13-beta`, {}, appTree)
49+
.toPromise();
50+
const file = newTree.readContent('fixture.ts');
51+
52+
expect(file).toBe(expected);
53+
});
54+
});
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import * as ts from 'typescript';
2+
import { Rule, chain, Tree } from '@angular-devkit/schematics';
3+
import {
4+
visitTSSourceFiles,
5+
RemoveChange,
6+
commitChanges,
7+
} from '../../schematics-core';
8+
9+
function updateCreateFeatureSelectorGenerics(): Rule {
10+
return (tree: Tree) => {
11+
visitTSSourceFiles(tree, (sourceFile) => {
12+
const runMigration = sourceFile.statements
13+
.filter(ts.isImportDeclaration)
14+
.filter(
15+
(importDeclaration) =>
16+
importDeclaration.moduleSpecifier.getText(sourceFile) ===
17+
"'@ngrx/store'" ||
18+
importDeclaration.moduleSpecifier.getText(sourceFile) ===
19+
'"@ngrx/store"'
20+
)
21+
.some((importDeclaration) => {
22+
return importDeclaration.importClause?.namedBindings
23+
?.getText(sourceFile)
24+
.includes('createFeatureSelector');
25+
});
26+
27+
if (!runMigration) return;
28+
29+
const changes: RemoveChange[] = [];
30+
ts.forEachChild(sourceFile, crawl);
31+
return commitChanges(tree, sourceFile.fileName, changes);
32+
33+
function crawl(node: ts.Node) {
34+
ts.forEachChild(node, crawl);
35+
36+
if (!ts.isCallExpression(node)) return;
37+
if (node.typeArguments?.length !== 2) return;
38+
if (!ts.isIdentifier(node.expression)) return;
39+
if (node.expression.text !== 'createFeatureSelector') return;
40+
41+
changes.push(
42+
new RemoveChange(
43+
sourceFile.fileName,
44+
node.typeArguments[0].pos,
45+
node.typeArguments[1].pos
46+
)
47+
);
48+
}
49+
});
50+
};
51+
}
52+
53+
export default function (): Rule {
54+
return chain([updateCreateFeatureSelectorGenerics()]);
55+
}

modules/store/migrations/migration.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515
"description": "The road to v8 RC",
1616
"version": "8-rc.1",
1717
"factory": "./8_0_0-rc/index"
18+
},
19+
"ngrx-store-migration-13-beta": {
20+
"description": "The road to v13 beta",
21+
"version": "13-beta",
22+
"factory": "./13_0_0-beta/index"
1823
}
1924
}
2025
}

0 commit comments

Comments
 (0)