Skip to content

Commit 4ae3fef

Browse files
authored
Merge pull request #4763 from NativeScript/fatme/migrate-unit-test-runner
feat: migrate unit test related dependencies so `tns test` command can work out of the box with CLI v6.0
2 parents 8e7ac81 + 53b360d commit 4ae3fef

File tree

4 files changed

+88
-38
lines changed

4 files changed

+88
-38
lines changed

lib/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export const PLATFORMS_DIR_NAME = "platforms";
2828
export const HOOKS_DIR_NAME = "hooks";
2929
export const WEBPACK_CONFIG_NAME = "webpack.config.js";
3030
export const TSCCONFIG_TNS_JSON_NAME = "tsconfig.tns.json";
31+
export const KARMA_CONFIG_NAME = "karma.conf.js";
3132
export const LIB_DIR_NAME = "lib";
3233
export const CODE_SIGN_ENTITLEMENTS = "CODE_SIGN_ENTITLEMENTS";
3334
export const AWAIT_NOTIFICATION_TIMEOUT_SECONDS = 9;

lib/controllers/migrate-controller.ts

Lines changed: 83 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as path from "path";
22
import * as semver from "semver";
33
import * as constants from "../constants";
44
import { UpdateControllerBase } from "./update-controller-base";
5+
import { fromWindowsRelativePathToUnix } from "../common/helpers";
56

67
export class MigrateController extends UpdateControllerBase implements IMigrateController {
78
constructor(
@@ -15,20 +16,26 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC
1516
private $errors: IErrors,
1617
private $addPlatformService: IAddPlatformService,
1718
private $pluginsService: IPluginsService,
18-
private $projectDataService: IProjectDataService) {
19+
private $projectDataService: IProjectDataService,
20+
private $resources: IResourceLoader) {
1921
super($fs, $platformCommandHelper, $platformsDataService, $packageInstallationManager, $packageManager);
2022
}
2123

24+
static readonly backupFolder: string = ".migration_backup";
25+
static readonly migrateFailMessage: string = "Could not migrate the project!";
26+
static readonly backupFailMessage: string = "Could not backup project folders!";
27+
2228
static readonly folders: string[] = [
2329
constants.LIB_DIR_NAME,
2430
constants.HOOKS_DIR_NAME,
2531
constants.WEBPACK_CONFIG_NAME,
2632
constants.PACKAGE_JSON_FILE_NAME,
2733
constants.PACKAGE_LOCK_JSON_FILE_NAME,
28-
constants.TSCCONFIG_TNS_JSON_NAME
34+
constants.TSCCONFIG_TNS_JSON_NAME,
35+
constants.KARMA_CONFIG_NAME
2936
];
3037

31-
static readonly migrationDependencies: IMigrationDependency[] = [
38+
private migrationDependencies: IMigrationDependency[] = [
3239
{ packageName: constants.TNS_CORE_MODULES_NAME, verifiedVersion: "6.0.0-next-2019-06-20-155941-01" },
3340
{ packageName: constants.TNS_CORE_MODULES_WIDGETS_NAME, verifiedVersion: "6.0.0-next-2019-06-20-155941-01" },
3441
{ packageName: "node-sass", isDev: true, verifiedVersion: "4.12.0" },
@@ -57,13 +64,13 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC
5764
//TODO update with no prerelease version compatible with webpack only hooks
5865
{ packageName: "nativescript-vue", verifiedVersion: "2.3.0-rc.0" },
5966
{ packageName: "nativescript-permissions", verifiedVersion: "1.3.0" },
60-
{ packageName: "nativescript-cardview", verifiedVersion: "3.2.0" }
67+
{ packageName: "nativescript-cardview", verifiedVersion: "3.2.0" },
68+
{ packageName: "nativescript-unit-test-runner", verifiedVersion: "0.6.3",
69+
shouldMigrateAction: (projectData: IProjectData) => this.hasDependency({ packageName: "nativescript-unit-test-runner", isDev: false }, projectData),
70+
migrateAction: this.migrateUnitTestRunner.bind(this)
71+
}
6172
];
6273

63-
static readonly backupFolder: string = ".migration_backup";
64-
static readonly migrateFailMessage: string = "Could not migrate the project!";
65-
static readonly backupFailMessage: string = "Could not backup project folders!";
66-
6774
get verifiedPlatformVersions(): IDictionary<string> {
6875
return {
6976
[this.$devicePlatformsConstants.Android.toLowerCase()]: "6.0.0-2019-06-11-172137-01",
@@ -97,10 +104,14 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC
97104
public async shouldMigrate({ projectDir }: IProjectDir): Promise<boolean> {
98105
const projectData = this.$projectDataService.getProjectData(projectDir);
99106

100-
for (let i = 0; i < MigrateController.migrationDependencies.length; i++) {
101-
const dependency = MigrateController.migrationDependencies[i];
107+
for (let i = 0; i < this.migrationDependencies.length; i++) {
108+
const dependency = this.migrationDependencies[i];
102109
const hasDependency = this.hasDependency(dependency, projectData);
103110

111+
if (hasDependency && dependency.shouldMigrateAction && dependency.shouldMigrateAction(projectData)) {
112+
return true;
113+
}
114+
104115
if (hasDependency && dependency.replaceWith) {
105116
return true;
106117
}
@@ -138,32 +149,18 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC
138149

139150
private async migrateDependencies(projectData: IProjectData): Promise<void> {
140151
this.$logger.info("Start dependencies migration.");
141-
for (let i = 0; i < MigrateController.migrationDependencies.length; i++) {
142-
const dependency = MigrateController.migrationDependencies[i];
152+
for (let i = 0; i < this.migrationDependencies.length; i++) {
153+
const dependency = this.migrationDependencies[i];
143154
const hasDependency = this.hasDependency(dependency, projectData);
144155

145-
if (hasDependency && dependency.replaceWith) {
146-
this.$pluginsService.removeFromPackageJson(dependency.packageName, dependency.isDev, projectData.projectDir);
147-
const replacementDep = _.find(MigrateController.migrationDependencies, migrationPackage => migrationPackage.packageName === dependency.replaceWith);
148-
if (!replacementDep) {
149-
this.$errors.failWithoutHelp("Failed to find replacement dependency.");
156+
if (hasDependency && dependency.migrateAction && dependency.shouldMigrateAction(projectData)) {
157+
const newDependencies = await dependency.migrateAction(projectData, path.join(projectData.projectDir, MigrateController.backupFolder));
158+
for (const newDependency of newDependencies) {
159+
await this.migrateDependency(newDependency, projectData);
150160
}
151-
this.$logger.info(`Replacing '${dependency.packageName}' with '${replacementDep.packageName}'.`);
152-
this.$pluginsService.addToPackageJson(replacementDep.packageName, replacementDep.verifiedVersion, replacementDep.isDev, projectData.projectDir);
153-
continue;
154161
}
155162

156-
if (hasDependency && await this.shouldMigrateDependencyVersion(dependency, projectData)) {
157-
this.$logger.info(`Updating '${dependency.packageName}' to compatible version '${dependency.verifiedVersion}'`);
158-
this.$pluginsService.addToPackageJson(dependency.packageName, dependency.verifiedVersion, dependency.isDev, projectData.projectDir);
159-
continue;
160-
}
161-
162-
if (!hasDependency && dependency.shouldAddIfMissing) {
163-
this.$logger.info(`Adding '${dependency.packageName}' with version '${dependency.verifiedVersion}'`);
164-
this.$pluginsService.addToPackageJson(dependency.packageName, dependency.verifiedVersion, dependency.isDev, projectData.projectDir);
165-
continue;
166-
}
163+
await this.migrateDependency(dependency, projectData);
167164
}
168165

169166
for (const platform in this.$devicePlatformsConstants) {
@@ -188,6 +185,32 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC
188185
this.$logger.info("Migration complete.");
189186
}
190187

188+
private async migrateDependency(dependency: IMigrationDependency, projectData: IProjectData): Promise<void> {
189+
const hasDependency = this.hasDependency(dependency, projectData);
190+
191+
if (hasDependency && dependency.replaceWith) {
192+
this.$pluginsService.removeFromPackageJson(dependency.packageName, dependency.isDev, projectData.projectDir);
193+
const replacementDep = _.find(this.migrationDependencies, migrationPackage => migrationPackage.packageName === dependency.replaceWith);
194+
if (!replacementDep) {
195+
this.$errors.failWithoutHelp("Failed to find replacement dependency.");
196+
}
197+
this.$logger.info(`Replacing '${dependency.packageName}' with '${replacementDep.packageName}'.`);
198+
this.$pluginsService.addToPackageJson(replacementDep.packageName, replacementDep.verifiedVersion, replacementDep.isDev, projectData.projectDir);
199+
return;
200+
}
201+
202+
if (hasDependency && await this.shouldMigrateDependencyVersion(dependency, projectData)) {
203+
this.$logger.info(`Updating '${dependency.packageName}' to compatible version '${dependency.verifiedVersion}'`);
204+
this.$pluginsService.addToPackageJson(dependency.packageName, dependency.verifiedVersion, dependency.isDev, projectData.projectDir);
205+
return;
206+
}
207+
208+
if (!hasDependency && dependency.shouldAddIfMissing) {
209+
this.$logger.info(`Adding '${dependency.packageName}' with version '${dependency.verifiedVersion}'`);
210+
this.$pluginsService.addToPackageJson(dependency.packageName, dependency.verifiedVersion, dependency.isDev, projectData.projectDir);
211+
}
212+
}
213+
191214
private async shouldMigrateDependencyVersion(dependency: IMigrationDependency, projectData: IProjectData): Promise<boolean> {
192215
const collection = dependency.isDev ? projectData.devDependencies : projectData.dependencies;
193216
const maxSatisfyingVersion = await this.getMaxDependencyVersion(dependency.packageName, collection[dependency.packageName]);
@@ -200,6 +223,35 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC
200223

201224
return !(maxRuntimeVersion && semver.gte(maxRuntimeVersion, targetVersion));
202225
}
226+
227+
private async migrateUnitTestRunner(projectData: IProjectData, migrationBackupDirPath: string): Promise<IMigrationDependency[]> {
228+
// Migrate karma.conf.js
229+
const oldKarmaContent = this.$fs.readText(path.join(migrationBackupDirPath, constants.KARMA_CONFIG_NAME));
230+
231+
const regExp = /frameworks:\s+\[([\S\s]*?)\]/g;
232+
const matches = regExp.exec(oldKarmaContent);
233+
const frameworks = (matches && matches[1] && matches[1].trim()) || '["jasmine"]';
234+
235+
const testsDir = path.join(projectData.appDirectoryPath, 'tests');
236+
const relativeTestsDir = path.relative(projectData.projectDir, testsDir);
237+
const testFiles = `'${fromWindowsRelativePathToUnix(relativeTestsDir)}/**/*.*'`;
238+
239+
const karmaConfTemplate = this.$resources.readText('test/karma.conf.js');
240+
const karmaConf = _.template(karmaConfTemplate)({ frameworks, testFiles });
241+
this.$fs.writeFile(path.join(projectData.projectDir, constants.KARMA_CONFIG_NAME), karmaConf);
242+
243+
// Dependencies to migrate
244+
const dependencies = [
245+
{ packageName: "karma-webpack", verifiedVersion: "3.0.5", isDev: true, shouldAddIfMissing: !this.hasDependency({ packageName: "karma-webpack", isDev: true }, projectData) },
246+
{ packageName: "karma-jasmine", verifiedVersion: "2.0.1", isDev: true },
247+
{ packageName: "karma-mocha", verifiedVersion: "1.3.0", isDev: true },
248+
{ packageName: "karma-chai", verifiedVersion: "0.1.0", isDev: true },
249+
{ packageName: "karma-qunit", verifiedVersion: "3.1.2", isDev: true },
250+
{ packageName: "karma", verifiedVersion: "4.1.0", isDev: true },
251+
];
252+
253+
return dependencies;
254+
}
203255
}
204256

205257
$injector.register("migrateController", MigrateController);

lib/controllers/update-controller-base.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,13 @@ export class UpdateControllerBase {
3434

3535
protected hasDependency(dependency: IDependency, projectData: IProjectData): boolean {
3636
const collection = dependency.isDev ? projectData.devDependencies : projectData.dependencies;
37-
if (collection && collection[dependency.packageName]) {
38-
return true;
39-
}
37+
return collection && collection[dependency.packageName];
4038
}
4139

4240
protected hasRuntimeDependency({platform, projectData}: {platform: string, projectData: IProjectData}): boolean {
4341
const lowercasePlatform = platform.toLowerCase();
4442
const currentPlatformVersion = this.$platformCommandHelper.getCurrentPlatformVersion(lowercasePlatform, projectData);
45-
46-
if (currentPlatformVersion) {
47-
return true;
48-
}
43+
return !!currentPlatformVersion;
4944
}
5045

5146
protected async getMaxRuntimeVersion({platform, projectData}: {platform: string, projectData: IProjectData}) {

lib/definitions/migrate.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,6 @@ interface IMigrationDependency extends IDependency {
1313
replaceWith?: string;
1414
verifiedVersion?: string;
1515
shouldAddIfMissing?: boolean;
16+
shouldMigrateAction?: (projectData: IProjectData) => boolean;
17+
migrateAction?: (projectData: IProjectData, migrationBackupDirPath: string) => Promise<IMigrationDependency[]>;
1618
}

0 commit comments

Comments
 (0)