This repository has been archived by the owner on May 1, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 305
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(deep-linking): upgrade script to generate NgModules for pages with
@deeplink decorator
- Loading branch information
1 parent
08534d7
commit 2943188
Showing
3 changed files
with
201 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
import * as fs from 'fs'; | ||
import { join } from 'path'; | ||
|
||
import * as upgradeScript from './add-default-ngmodules'; | ||
import * as deeplinkUtils from '../deep-linking/util'; | ||
import { FileCache } from '../util/file-cache'; | ||
import * as globUtil from '../util/glob-util'; | ||
import * as helpers from '../util/helpers'; | ||
|
||
describe('add default ngmodules upgrade script', () => { | ||
describe('getTsFilePaths', () => { | ||
it('should return a list of absolute file paths', () => { | ||
const srcDirectory = join('Users', 'noone', 'this', 'path', 'is', 'fake', 'src'); | ||
const context = { | ||
srcDir: srcDirectory | ||
}; | ||
|
||
const knownFileOne = join(srcDirectory, 'pages', 'page-one', 'page-one.ts'); | ||
const knownFileTwo = join(srcDirectory, 'pages', 'page-two', 'page-two.ts'); | ||
const knownFileThree = join(srcDirectory, 'pages', 'page-three', 'page-three.ts'); | ||
const knownFileFour = join(srcDirectory, 'util', 'some-util.ts'); | ||
const globResults = [ | ||
{ absolutePath: knownFileOne}, | ||
{ absolutePath: knownFileTwo}, | ||
{ absolutePath: knownFileThree}, | ||
{ absolutePath: knownFileFour}, | ||
]; | ||
spyOn(globUtil, globUtil.globAll.name).and.returnValue(Promise.resolve(globResults)); | ||
const promise = upgradeScript.getTsFilePaths(context); | ||
|
||
return promise.then((filePaths: string[]) => { | ||
expect(filePaths.length).toEqual(4); | ||
expect(filePaths[0]).toEqual(knownFileOne); | ||
expect(filePaths[1]).toEqual(knownFileTwo); | ||
expect(filePaths[2]).toEqual(knownFileThree); | ||
expect(filePaths[3]).toEqual(knownFileFour); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('readTsFiles', () => { | ||
it('should read the ts files', () => { | ||
const context = { | ||
fileCache: new FileCache() | ||
}; | ||
const srcDirectory = join('Users', 'noone', 'this', 'path', 'is', 'fake', 'src'); | ||
const knownFileOne = join(srcDirectory, 'pages', 'page-one', 'page-one.ts'); | ||
const knownFileTwo = join(srcDirectory, 'pages', 'page-two', 'page-two.ts'); | ||
const knownFileThree = join(srcDirectory, 'pages', 'page-three', 'page-three.ts'); | ||
const knownFileFour = join(srcDirectory, 'util', 'some-util.ts'); | ||
|
||
const fileList = [knownFileOne, knownFileTwo, knownFileThree, knownFileFour]; | ||
|
||
spyOn(helpers, helpers.readFileAsync.name).and.callFake((filePath: string) => { | ||
// just set the file content to the path name + 'content' to keep things simple | ||
return Promise.resolve(filePath + 'content'); | ||
}); | ||
|
||
const promise = upgradeScript.readTsFiles(context, fileList); | ||
|
||
return promise.then(() => { | ||
// the files should be cached now | ||
const fileOne = context.fileCache.get(knownFileOne); | ||
expect(fileOne.content).toEqual(knownFileOne + 'content'); | ||
|
||
const fileTwo = context.fileCache.get(knownFileTwo); | ||
expect(fileTwo.content).toEqual(knownFileTwo + 'content'); | ||
|
||
const fileThree = context.fileCache.get(knownFileThree); | ||
expect(fileThree.content).toEqual(knownFileThree + 'content'); | ||
|
||
const fileFour = context.fileCache.get(knownFileFour); | ||
expect(fileFour.content).toEqual(knownFileFour + 'content'); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('generateAndWriteNgModules', () => { | ||
it('should generate NgModules for only the pages with deeplink decorator AND if the module.ts file doesnt exist', () => { | ||
const srcDirectory = join('Users', 'noone', 'this', 'path', 'is', 'fake', 'src'); | ||
const knownFileOne = join(srcDirectory, 'pages', 'page-one', 'page-one.ts'); | ||
const knownFileTwo = join(srcDirectory, 'pages', 'page-two', 'page-two.ts'); | ||
const knownFileThree = join(srcDirectory, 'pages', 'page-three', 'page-three.ts'); | ||
const knownFileThreeModule = join(srcDirectory, 'pages', 'page-three', 'page-three.module.ts'); | ||
const knownFileFour = join(srcDirectory, 'util', 'some-util.ts'); | ||
const knownFileFive = join(srcDirectory, 'pages', 'page-three', 'provider.ts'); | ||
const knownFileSix = join(srcDirectory, 'modals', 'modal-one', 'modal-one.ts'); | ||
|
||
const context = { | ||
fileCache: new FileCache() | ||
}; | ||
|
||
context.fileCache.set(knownFileOne, { path: knownFileOne, content: getClassContent('PageOne', 'page-one')}); | ||
context.fileCache.set(knownFileTwo, { path: knownFileTwo, content: getClassContent('PageTwo', 'page-two')}); | ||
context.fileCache.set(knownFileThree, { path: knownFileThree, content: getClassContent('PageThree', 'page-three')}); | ||
context.fileCache.set(knownFileThreeModule, { path: knownFileThreeModule, content: deeplinkUtils.generateDefaultDeepLinkNgModuleContent(knownFileThree, 'PageThree')}); | ||
context.fileCache.set(knownFileFour, { path: knownFileFour, content: `${knownFileFour} content`}); | ||
context.fileCache.set(knownFileFive, { path: knownFileFive, content: `${knownFileFive} content`}); | ||
context.fileCache.set(knownFileSix, { path: knownFileSix, content: getClassContent('ModalOne', 'modal-one')}); | ||
|
||
const ngModuleFileExtension = '.module.ts'; | ||
|
||
spyOn(helpers, helpers.getStringPropertyValue.name).and.returnValue(ngModuleFileExtension); | ||
const fsSpy = spyOn(fs, 'writeFileSync'); | ||
|
||
upgradeScript.generateAndWriteNgModules(context.fileCache); | ||
|
||
expect(fsSpy.calls.count()).toEqual(3); | ||
expect(fsSpy.calls.argsFor(0)[0]).toEqual(helpers.changeExtension(knownFileOne, ngModuleFileExtension)); | ||
expect(fsSpy.calls.argsFor(0)[1]).toEqual(deeplinkUtils.generateDefaultDeepLinkNgModuleContent(knownFileOne, 'PageOne')); | ||
|
||
expect(fsSpy.calls.argsFor(1)[0]).toEqual(helpers.changeExtension(knownFileTwo, ngModuleFileExtension)); | ||
expect(fsSpy.calls.argsFor(1)[1]).toEqual(deeplinkUtils.generateDefaultDeepLinkNgModuleContent(knownFileTwo, 'PageTwo')); | ||
|
||
expect(fsSpy.calls.argsFor(2)[0]).toEqual(helpers.changeExtension(knownFileSix, ngModuleFileExtension)); | ||
expect(fsSpy.calls.argsFor(2)[1]).toEqual(deeplinkUtils.generateDefaultDeepLinkNgModuleContent(knownFileSix, 'ModalOne')); | ||
}); | ||
}); | ||
}); | ||
|
||
function getClassContent(className: string, folderName: string) { | ||
return ` | ||
import { Component } from '@angular/core'; | ||
import { DeepLink, NavController } from 'ionic-angular'; | ||
@DeepLink() | ||
@Component({ | ||
selector: '${folderName}', | ||
templateUrl: './${folderName}.html' | ||
}) | ||
export class ${className} { | ||
constructor(public navCtrl: NavController) {} | ||
} | ||
`; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { writeFileSync } from 'fs'; | ||
import { join } from 'path'; | ||
|
||
import { generateDefaultDeepLinkNgModuleContent, getDeepLinkDecoratorContentForSourceFile, getNgModulePathFromCorrespondingPage } from '../deep-linking/util'; | ||
import { generateContext } from '../util/config'; | ||
import * as Constants from '../util/constants'; | ||
import { FileCache } from '../util/file-cache'; | ||
import { globAll, GlobResult } from '../util/glob-util'; | ||
import { changeExtension, getStringPropertyValue, readFileAsync } from '../util/helpers'; | ||
import { BuildContext, File } from '../util/interfaces'; | ||
|
||
import { getTypescriptSourceFile } from '../util/typescript-utils'; | ||
|
||
export function getTsFilePaths(context: BuildContext) { | ||
const tsFileGlobString = join(context.srcDir, '**', '*.ts'); | ||
return globAll([tsFileGlobString]).then((results: GlobResult[]) => { | ||
return results.map(result => result.absolutePath); | ||
}); | ||
} | ||
|
||
export function readTsFiles(context: BuildContext, tsFilePaths: string[]) { | ||
const promises = tsFilePaths.map(tsFilePath => { | ||
const promise = readFileAsync(tsFilePath); | ||
promise.then((fileContent: string) => { | ||
context.fileCache.set(tsFilePath, { path: tsFilePath, content: fileContent}); | ||
}); | ||
return promise; | ||
}); | ||
return Promise.all(promises); | ||
} | ||
|
||
export function generateAndWriteNgModules(fileCache: FileCache) { | ||
fileCache.getAll().forEach(file => { | ||
const sourceFile = getTypescriptSourceFile(file.path, file.content); | ||
const deepLinkDecoratorData = getDeepLinkDecoratorContentForSourceFile(sourceFile); | ||
if (deepLinkDecoratorData) { | ||
// we have a valid DeepLink decorator | ||
const correspondingNgModulePath = getNgModulePathFromCorrespondingPage(file.path); | ||
const ngModuleFile = fileCache.get(correspondingNgModulePath); | ||
if (!ngModuleFile) { | ||
// the ngModule file does not exist, so go ahead and create a default one | ||
const defaultNgModuleContent = generateDefaultDeepLinkNgModuleContent(file.path, deepLinkDecoratorData.className); | ||
const ngModuleFilePath = changeExtension(file.path, getStringPropertyValue(Constants.ENV_NG_MODULE_FILE_NAME_SUFFIX)); | ||
writeFileSync(ngModuleFilePath, defaultNgModuleContent); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
function run() { | ||
const context = generateContext(); | ||
|
||
// find out what files to read | ||
return getTsFilePaths(context).then((filePaths: string[]) => { | ||
// read the files | ||
return readTsFiles(context, filePaths); | ||
}).then(() => { | ||
generateAndWriteNgModules(context.fileCache); | ||
}); | ||
} | ||
|
||
run(); |