Skip to content

Commit 2068e83

Browse files
committed
fix(schematics): use correct date adapter when using moment
Closes #1133
1 parent f447cd6 commit 2068e83

File tree

4 files changed

+109
-22
lines changed

4 files changed

+109
-22
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"build": "run-s build:copy-package-json build:lib build:date-adapters build:styles build:schematics build:copyfiles",
1616
"test:single": "cross-env TZ=UTC ng test angular-calendar --watch=false --code-coverage",
1717
"test:watch": "cross-env TZ=UTC ng test angular-calendar",
18-
"test:schematics": "cross-env TS_NODE_COMPILER_OPTIONS={\\\"module\\\":\\\"commonjs\\\"} mocha --require ts-node/register projects/angular-calendar/schematics/**/*.spec.ts",
18+
"test:schematics": "cross-env TS_NODE_COMPILER_OPTIONS={\\\"module\\\":\\\"commonjs\\\"} TS_NODE_PREFER_TS_EXTS=true mocha --require ts-node/register projects/angular-calendar/schematics/**/*.spec.ts",
1919
"test": "run-s lint test:single test:schematics build build:clean",
2020
"lint:styles": "stylelint \"{projects,src}/**/*.scss\" --fix",
2121
"lint:ts": "ng lint",

projects/angular-calendar/schematics/ng-add/index.spec.ts

+27-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ describe('angular-calendar schematics', () => {
8383

8484
const rootModule = tree.readContent(rootModulePath);
8585

86-
const calendarModuleImport = `import { CalendarModule } from 'angular-calendar'`;
86+
const calendarModuleImport = `import { CalendarModule, DateAdapter } from 'angular-calendar';`;
8787
expect(rootModule).contain(calendarModuleImport);
8888
});
8989

@@ -100,4 +100,30 @@ describe('angular-calendar schematics', () => {
100100
expect(styles[0]).to.contains(defaultAngularCalendarStylePath);
101101
expect(stylesTest[0]).to.contains(defaultAngularCalendarStylePath);
102102
});
103+
104+
it('should add the momentAdapterFactory when using moment', async () => {
105+
const rootModulePath = `/projects/${projectName}/src/app/app.module.ts`;
106+
tree = await runner
107+
.runSchematicAsync(
108+
'ng-add',
109+
{
110+
...defaultOptions,
111+
dateAdapter: 'moment'
112+
},
113+
appTree
114+
)
115+
.toPromise();
116+
expect(tree.files).contain(rootModulePath);
117+
118+
const rootModule = tree.readContent(rootModulePath);
119+
120+
expect(rootModule).contain(
121+
`import { adapterFactory } from 'angular-calendar/date-adapters/moment';`
122+
);
123+
expect(rootModule).contain(`import * as moment from 'moment';`);
124+
expect(rootModule).contain(`export function momentAdapterFactory() {
125+
return adapterFactory(moment);
126+
}`);
127+
expect(rootModule).contain(`useFactory: momentAdapterFactory`);
128+
});
103129
});

projects/angular-calendar/schematics/ng-add/index.ts

+46-19
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ import {
2121
addStyle,
2222
getSourceFile,
2323
getProjectMainFile,
24-
getProjectFromWorkspace
24+
getProjectFromWorkspace,
25+
insertWildcardImport,
26+
insertAfterImports
2527
} from '../utils';
2628

2729
import { Schema } from './schema';
@@ -109,31 +111,56 @@ function addModuleToImports(options: Schema): Rule {
109111
const appModulePath = options.module
110112
? options.module
111113
: getAppModulePath(host, mainPath);
112-
const moduleSource = getSourceFile(host, appModulePath);
113-
const moduleName = `CalendarModule.forRoot({ provide: DateAdapter, useFactory: adapterFactory })`;
114+
const moduleName = `CalendarModule.forRoot({ provide: DateAdapter, useFactory: ${
115+
options.dateAdapter === 'moment'
116+
? 'momentAdapterFactory'
117+
: 'adapterFactory'
118+
} })`;
114119
const moduleCalendarSrc = 'angular-calendar';
115-
const PEER_DEPENDENCIES = ['DateAdapter', 'adapterFactory'];
116120

117121
addModuleImportToRootModule(host, moduleName, moduleCalendarSrc, project);
118122

119-
const peerDependencyChange1 = insertImport(
120-
moduleSource as ts.SourceFile,
121-
appModulePath,
122-
PEER_DEPENDENCIES[0],
123-
moduleCalendarSrc
124-
) as InsertChange;
123+
const moduleSource = getSourceFile(host, appModulePath);
125124

126-
const peerDependencyChange2 = insertImport(
127-
moduleSource as ts.SourceFile,
128-
appModulePath,
129-
PEER_DEPENDENCIES[1],
130-
`${moduleCalendarSrc}/date-adapters/${options.dateAdapter}`
131-
) as InsertChange;
125+
const updates: InsertChange[] = [
126+
insertImport(
127+
moduleSource as ts.SourceFile,
128+
appModulePath,
129+
'DateAdapter',
130+
moduleCalendarSrc
131+
) as InsertChange,
132+
insertImport(
133+
moduleSource as ts.SourceFile,
134+
appModulePath,
135+
'adapterFactory',
136+
`${moduleCalendarSrc}/date-adapters/${options.dateAdapter}`
137+
) as InsertChange
138+
];
139+
140+
if (options.dateAdapter === 'moment') {
141+
updates.push(
142+
insertWildcardImport(
143+
moduleSource as ts.SourceFile,
144+
appModulePath,
145+
'moment',
146+
'moment'
147+
) as InsertChange
148+
);
149+
updates.push(
150+
insertAfterImports(
151+
moduleSource as ts.SourceFile,
152+
appModulePath,
153+
`;\n\nexport function momentAdapterFactory() {
154+
return adapterFactory(moment);
155+
}`
156+
) as InsertChange
157+
);
158+
}
132159

133160
const recorder = host.beginUpdate(appModulePath);
134-
135-
recorder.insertLeft(peerDependencyChange1.pos, peerDependencyChange1.toAdd);
136-
recorder.insertLeft(peerDependencyChange2.pos, peerDependencyChange2.toAdd);
161+
updates.forEach(update => {
162+
recorder.insertLeft(update.pos, update.toAdd);
163+
});
137164
host.commitUpdate(recorder);
138165

139166
return host;

projects/angular-calendar/schematics/utils/ast.ts

+35-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
import { Tree, SchematicsException } from '@angular-devkit/schematics';
22
import { InsertChange, Change } from '@schematics/angular/utility/change';
3-
import { addImportToModule } from '@schematics/angular/utility/ast-utils';
3+
import {
4+
addImportToModule,
5+
findNodes,
6+
insertAfterLastOccurrence
7+
} from '@schematics/angular/utility/ast-utils';
48
import { getAppModulePath } from '@schematics/angular/utility/ng-ast-utils';
59
import { WorkspaceProject } from '@schematics/angular/utility/workspace-models';
10+
import * as ts from 'typescript';
611

712
import { getSourceFile } from './file';
813

@@ -64,3 +69,32 @@ function addModuleImportToModule(
6469

6570
host.commitUpdate(recorder);
6671
}
72+
73+
export function insertAfterImports(
74+
source: ts.SourceFile,
75+
fileToEdit: string,
76+
toInsert: string
77+
): Change {
78+
const allImports = findNodes(source, ts.SyntaxKind.ImportDeclaration);
79+
80+
return insertAfterLastOccurrence(
81+
allImports,
82+
toInsert,
83+
fileToEdit,
84+
0,
85+
ts.SyntaxKind.StringLiteral
86+
);
87+
}
88+
89+
export function insertWildcardImport(
90+
source: ts.SourceFile,
91+
fileToEdit: string,
92+
symbolName: string,
93+
fileName: string
94+
): Change {
95+
return insertAfterImports(
96+
source,
97+
fileToEdit,
98+
`;\nimport * as ${symbolName} from '${fileName}'`
99+
);
100+
}

0 commit comments

Comments
 (0)