Skip to content
This repository was archived by the owner on May 1, 2020. It is now read-only.

Commit 653d9f2

Browse files
authored
fix(generators): handle no ngModule in tabs
* fix(generators): handle no ngModule in tabs Closes ionic-team/ionic-cli#2519 * chore(generators): add test for lazy loaded tabs * fix(generators): fix imports for tabs with multiple pages
1 parent 3154b73 commit 653d9f2

File tree

4 files changed

+105
-19
lines changed

4 files changed

+105
-19
lines changed

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock=false

src/generators.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ export function processTabsRequest(context: BuildContext, name: string, tabs: st
3535
});
3636

3737
return Promise.all(promises);
38-
}).then((tabs) => {
38+
})
39+
.then((tabs) => {
3940
tabsModuleManipulation(tabs, hydratedRequest, tabHydratedRequests);
4041
});
4142
}

src/generators/util.spec.ts

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { BuildContext } from '../util/interfaces';
12
import { basename, join } from 'path';
23
import * as fs from 'fs';
34
import * as Constants from '../util/constants';
@@ -30,7 +31,7 @@ describe('util', () => {
3031
const hydratedRequest = util.hydrateRequest(context, request);
3132

3233
// assert
33-
expect(hydratedRequest).toEqual({'className': 'SettingsViewComponent', 'dirToRead': join(templateDir, 'component'), 'dirToWrite': join(componentsDir, 'settings-view'), 'fileName': 'settings-view', 'includeNgModule': true, 'includeSpec': true, 'name': 'settings view', 'type': 'component'});
34+
expect(hydratedRequest).toEqual({ 'className': 'SettingsViewComponent', 'dirToRead': join(templateDir, 'component'), 'dirToWrite': join(componentsDir, 'settings-view'), 'fileName': 'settings-view', 'includeNgModule': true, 'includeSpec': true, 'name': 'settings view', 'type': 'component' });
3435
expect(hydratedRequest.type).toEqual(Constants.COMPONENT);
3536
expect(hydratedRequest.name).toEqual(request.name);
3637
expect(hydratedRequest.includeNgModule).toBeTruthy();
@@ -62,7 +63,7 @@ describe('util', () => {
6263
const hydratedRequest = util.hydrateRequest(context, request);
6364

6465
// assert
65-
expect(hydratedRequest).toEqual({'className': 'SettingsViewPage', 'dirToRead': join(templateDir, 'page'), 'dirToWrite': join(pagesDir, 'settings-view'), 'fileName': 'settings-view', 'includeNgModule': true, 'includeSpec': true, 'name': 'settings view', 'type': 'page'});
66+
expect(hydratedRequest).toEqual({ 'className': 'SettingsViewPage', 'dirToRead': join(templateDir, 'page'), 'dirToWrite': join(pagesDir, 'settings-view'), 'fileName': 'settings-view', 'includeNgModule': true, 'includeSpec': true, 'name': 'settings view', 'type': 'page' });
6667
expect(hydratedRequest.type).toEqual(Constants.PAGE);
6768
expect(hydratedRequest.name).toEqual(request.name);
6869
expect(hydratedRequest.includeNgModule).toBeTruthy();
@@ -74,6 +75,64 @@ describe('util', () => {
7475
});
7576
});
7677

78+
describe('hydrateTabRequest', () => {
79+
it('should take a lazy loaded page set the tab root to a string', () => {
80+
// arrange
81+
const baseDir = join(process.cwd(), 'someDir', 'project');
82+
const pagesDir = join(baseDir, 'src', 'pages');
83+
const templateDir = join(baseDir, 'node_modules', 'ionic-angular', 'templates');
84+
const context: BuildContext = { pagesDir };
85+
const request = {
86+
type: 'tabs',
87+
name: 'stooges',
88+
includeNgModule: true,
89+
tabs: [
90+
{
91+
includeNgModule: true,
92+
type: 'page',
93+
name: 'moe',
94+
className: 'MoePage',
95+
fileName: 'moe',
96+
'dirToRead': join(templateDir, 'page'),
97+
'dirToWrite': join(pagesDir, 'moe'),
98+
}]
99+
};
100+
spyOn(helpers, helpers.getStringPropertyValue.name).and.returnValue(templateDir);
101+
// act
102+
const hydatedTabRequest = util.hydrateTabRequest(context, request);
103+
// assert
104+
expect(hydatedTabRequest.tabVariables).toEqual(' moeRoot = \'MoePage\'\n');
105+
});
106+
107+
it('should take a page set the tab root to a component ref', () => {
108+
// arrange
109+
const baseDir = join(process.cwd(), 'someDir', 'project');
110+
const pagesDir = join(baseDir, 'src', 'pages');
111+
const templateDir = join(baseDir, 'node_modules', 'ionic-angular', 'templates');
112+
const context: BuildContext = { pagesDir };
113+
const request = {
114+
type: 'tabs',
115+
name: 'stooges',
116+
includeNgModule: false,
117+
tabs: [
118+
{
119+
includeNgModule: false,
120+
type: 'page',
121+
name: 'moe',
122+
className: 'MoePage',
123+
fileName: 'moe',
124+
'dirToRead': join(templateDir, 'page'),
125+
'dirToWrite': join(pagesDir, 'moe'),
126+
}]
127+
};
128+
spyOn(helpers, helpers.getStringPropertyValue.name).and.returnValue(templateDir);
129+
// act
130+
const hydatedTabRequest = util.hydrateTabRequest(context, request);
131+
// assert
132+
expect(hydatedTabRequest.tabVariables).toEqual(' moeRoot = MoePage\n');
133+
});
134+
});
135+
77136
describe('readTemplates', () => {
78137
it('should get a map of templates and their content back', () => {
79138
// arrange
@@ -109,7 +168,7 @@ describe('util', () => {
109168
map.set(join(templateDir, knownValues[3]), fileContent);
110169
map.set(join(templateDir, knownValues[4]), fileContent);
111170

112-
const newMap = util.filterOutTemplates({includeNgModule: true, includeSpec: true}, map);
171+
const newMap = util.filterOutTemplates({ includeNgModule: true, includeSpec: true }, map);
113172
expect(newMap.size).toEqual(knownValues.length);
114173
});
115174

@@ -124,7 +183,7 @@ describe('util', () => {
124183
map.set(join(templateDir, knownValues[3]), fileContent);
125184
map.set(join(templateDir, knownValues[4]), fileContent);
126185

127-
const newMap = util.filterOutTemplates({includeNgModule: true, includeSpec: false}, map);
186+
const newMap = util.filterOutTemplates({ includeNgModule: true, includeSpec: false }, map);
128187
expect(newMap.size).toEqual(4);
129188
expect(newMap.get(join(templateDir, knownValues[0]))).toBeTruthy();
130189
expect(newMap.get(join(templateDir, knownValues[1]))).toBeTruthy();
@@ -144,7 +203,7 @@ describe('util', () => {
144203
map.set(join(templateDir, knownValues[3]), fileContent);
145204
map.set(join(templateDir, knownValues[4]), fileContent);
146205

147-
const newMap = util.filterOutTemplates({includeNgModule: false, includeSpec: false}, map);
206+
const newMap = util.filterOutTemplates({ includeNgModule: false, includeSpec: false }, map);
148207
expect(newMap.size).toEqual(3);
149208
expect(newMap.get(join(templateDir, knownValues[0]))).toBeTruthy();
150209
expect(newMap.get(join(templateDir, knownValues[1]))).toBeTruthy();
@@ -276,7 +335,7 @@ $TAB_CONTENT
276335
const fileName = 'settings-view';
277336
const suppliedName = 'settings view';
278337

279-
const results = util.applyTemplates({ name: suppliedName, className: className, fileName: fileName}, map);
338+
const results = util.applyTemplates({ name: suppliedName, className: className, fileName: fileName }, map);
280339
const modifiedContentOne = results.get(fileOne);
281340
const modifiedContentTwo = results.get(fileTwo);
282341
const modifiedContentThree = results.get(fileThree);
@@ -404,7 +463,7 @@ $TAB_CONTENT
404463
});
405464
});
406465

407-
describe('tabsModuleManipulation' , () => {
466+
describe('tabsModuleManipulation', () => {
408467
const className = 'SettingsView';
409468
const fileName = 'settings-view';
410469
const suppliedName = 'settings view';

src/generators/util.ts

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { basename, dirname, join, relative, sep } from 'path';
1+
import { basename, dirname, extname, join, relative, sep } from 'path';
22
import { readdirSync } from 'fs';
33
import { Logger} from '../logger/logger';
44
import { toUnixPath } from '../util/helpers';
@@ -8,7 +8,7 @@ import * as GeneratorConstants from './constants';
88
import { camelCase, getStringPropertyValue, mkDirpAsync, paramCase, pascalCase, readFileAsync, replaceAll, sentenceCase, upperCaseFirst, writeFileAsync } from '../util/helpers';
99
import { BuildContext } from '../util/interfaces';
1010
import { globAll, GlobResult } from '../util/glob-util';
11-
import { ensureSuffix, removeSuffix } from '../util/helpers';
11+
import { changeExtension, ensureSuffix, removeSuffix } from '../util/helpers';
1212
import { appendNgModuleDeclaration, insertNamedImportIfNeeded } from '../util/typescript-utils';
1313

1414
export function hydrateRequest(context: BuildContext, request: GeneratorRequest) {
@@ -36,7 +36,11 @@ export function hydrateTabRequest(context: BuildContext, request: GeneratorTabRe
3636

3737
for (let i = 0; i < request.tabs.length; i++) {
3838
const tabVar = `${camelCase(request.tabs[i].name)}Root`;
39-
hydrated.tabVariables += ` ${tabVar} = '${request.tabs[i].className}'\n`;
39+
if (hydrated.includeNgModule ) {
40+
hydrated.tabVariables += ` ${tabVar} = '${request.tabs[i].className}'\n`;
41+
} else {
42+
hydrated.tabVariables += ` ${tabVar} = ${request.tabs[i].className}\n`;
43+
}
4044

4145
// If this is the last ion-tab to insert
4246
// then we do not want a new line
@@ -171,19 +175,39 @@ export function nonPageFileManipulation(context: BuildContext, name: string, ngM
171175
}
172176

173177
export function tabsModuleManipulation(tabs: string[][], hydratedRequest: HydratedGeneratorRequest, tabHydratedRequests: HydratedGeneratorRequest[]): Promise<any> {
178+
tabHydratedRequests.forEach((tabRequest, index) => {
179+
tabRequest.generatedFileNames = tabs[index];
180+
});
174181
const ngModulePath = tabs[0].find((element: any): boolean => {
175182
return element.indexOf('module') !== -1;
176183
});
177-
const tabsNgModulePath = `${hydratedRequest.dirToWrite}${sep}${hydratedRequest.fileName}.module.ts`;
178-
const importPath = toUnixPath(relative(dirname(tabsNgModulePath), ngModulePath.replace('.module.ts', '')));
184+
if (ngModulePath) {
185+
const tabsNgModulePath = `${hydratedRequest.dirToWrite}${sep}${hydratedRequest.fileName}.module.ts`;
186+
const importPath = toUnixPath(relative(dirname(tabsNgModulePath), ngModulePath.replace('.module.ts', '')));
179187

180-
return readFileAsync(tabsNgModulePath).then((content) => {
181-
let fileContent = content;
182-
fileContent = insertNamedImportIfNeeded(tabsNgModulePath, fileContent, tabHydratedRequests[0].className, importPath);
183-
fileContent = appendNgModuleDeclaration(tabsNgModulePath, fileContent, tabHydratedRequests[0].className);
188+
return readFileAsync(tabsNgModulePath).then((content) => {
189+
let fileContent = content;
190+
fileContent = insertNamedImportIfNeeded(tabsNgModulePath, fileContent, tabHydratedRequests[0].className, importPath);
191+
fileContent = appendNgModuleDeclaration(tabsNgModulePath, fileContent, tabHydratedRequests[0].className);
184192

185-
return writeFileAsync(tabsNgModulePath, fileContent);
186-
});
193+
return writeFileAsync(tabsNgModulePath, fileContent);
194+
});
195+
} else {
196+
197+
// Static imports
198+
const tabsPath = join(hydratedRequest.dirToWrite, `${hydratedRequest.fileName}.ts`);
199+
200+
let modifiedContent: string = null;
201+
return readFileAsync(tabsPath).then(content => {
202+
tabHydratedRequests.forEach((tabRequest) => {
203+
const typescriptFilePath = changeExtension(tabRequest.generatedFileNames.filter(path => extname(path) === '.ts')[0], '');
204+
const importPath = toUnixPath(relative(dirname(tabsPath), typescriptFilePath));
205+
modifiedContent = insertNamedImportIfNeeded(tabsPath, content, tabRequest.className, importPath);
206+
content = modifiedContent;
207+
});
208+
return writeFileAsync(tabsPath, modifiedContent);
209+
});
210+
}
187211
}
188212

189213
export function generateTemplates(context: BuildContext, request: HydratedGeneratorRequest): Promise<string[]> {
@@ -222,4 +246,5 @@ export interface HydratedGeneratorRequest extends GeneratorRequest {
222246
tabVariables?: string;
223247
dirToRead?: string;
224248
dirToWrite?: string;
249+
generatedFileNames?: string[];
225250
}

0 commit comments

Comments
 (0)