Skip to content

Commit 8e1342e

Browse files
author
Dimitar Tachev
authored
Merge pull request #4418 from NativeScript/tachev/fix-testing-deps
feat: keep the unit testing dependencies up-to-date and stable
2 parents 74d5bfe + 57ac858 commit 8e1342e

File tree

9 files changed

+456
-28
lines changed

9 files changed

+456
-28
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,4 @@ lib/common/xunit.xml
7979
lib/common/test-reports.xml
8080
!lib/common/test-scripts/**
8181
!lib/common/scripts/**
82+
config/test-deps-versions-generated.json

Gruntfile.js

+32-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
const childProcess = require("child_process");
22
const EOL = require("os").EOL;
3+
const path = require("path");
34
const now = new Date().toISOString();
5+
const latestVersion = require('latest-version');
46

57
const ENVIRONMENTS = {
68
live: "live",
@@ -205,9 +207,14 @@ module.exports = function (grunt) {
205207
});
206208

207209
grunt.registerTask("test", ["ts:devall", "shell:npm_test"]);
210+
211+
registerTestingDependenciesTasks(grunt);
212+
208213
grunt.registerTask("prepare", [
209214
"clean",
210215
"ts:release_build",
216+
"generate_unit_testing_dependencies",
217+
"verify_unit_testing_dependencies",
211218
"shell:npm_test",
212219

213220
"set_live_ga_id",
@@ -230,6 +237,30 @@ module.exports = function (grunt) {
230237
grunt.registerTask("lint", ["tslint:build"]);
231238
grunt.registerTask("all", ["clean", "test", "lint"]);
232239
grunt.registerTask("rebuild", ["clean", "ts:devlib"]);
233-
grunt.registerTask("default", "ts:devlib");
240+
grunt.registerTask("default", ["ts:devlib", "generate_unit_testing_dependencies"]);
234241
grunt.registerTask("docs-jekyll", ['template']);
235242
};
243+
244+
function registerTestingDependenciesTasks(grunt) {
245+
const configsBasePath = path.join(__dirname, "config");
246+
const generatedVersionFilePath = path.join(configsBasePath, "test-deps-versions-generated.json");
247+
248+
grunt.registerTask("generate_unit_testing_dependencies", async function () {
249+
var done = this.async();
250+
const dependenciesVersions = {};
251+
const testDependencies = grunt.file.readJSON(path.join(configsBasePath, "test-dependencies.json"));
252+
for (var dependency of testDependencies) {
253+
const dependencyVersion = dependency.version || await latestVersion(dependency.name);
254+
dependenciesVersions[dependency.name] = dependencyVersion;
255+
}
256+
grunt.file.write(generatedVersionFilePath, JSON.stringify(dependenciesVersions));
257+
done();
258+
});
259+
260+
grunt.registerTask("verify_unit_testing_dependencies", function () {
261+
if (!grunt.file.exists(generatedVersionFilePath)) {
262+
throw new Error("Unit testing dependencies are not configured.");
263+
}
264+
});
265+
}
266+

config/test-dependencies.json

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
[
2+
{
3+
"name": "karma"
4+
},
5+
{
6+
"name": "karma-nativescript-launcher"
7+
},
8+
{
9+
"name": "mocha",
10+
"framework": "mocha"
11+
},
12+
{
13+
"name": "karma-mocha",
14+
"framework": "mocha"
15+
},
16+
{
17+
"name": "karma-chai",
18+
"framework": "mocha"
19+
},
20+
{
21+
"name": "karma-jasmine",
22+
"framework": "jasmine"
23+
},
24+
{
25+
"name": "karma-qunit",
26+
"framework": "qunit"
27+
}
28+
]

lib/bootstrap.ts

+1
Original file line numberDiff line numberDiff line change
@@ -187,5 +187,6 @@ $injector.require("hmrStatusService", "./services/hmr-status-service");
187187

188188
$injector.require("pacoteService", "./services/pacote-service");
189189
$injector.require("qrCodeTerminalService", "./services/qr-code-terminal-service");
190+
$injector.require("testInitializationService", "./services/test-initialization-service");
190191

191192
$injector.require("networkConnectivityValidator", "./helpers/network-connectivity-validator");

lib/commands/test-init.ts

+17-23
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@ import { fromWindowsRelativePathToUnix } from '../common/helpers';
55
class TestInitCommand implements ICommand {
66
public allowedParameters: ICommandParameter[] = [];
77

8-
private frameworkDependencies: IDictionary<string[]> = {
9-
mocha: ['karma-chai', 'mocha'],
10-
};
11-
128
private karmaConfigAdditionalFrameworks: IDictionary<string[]> = {
139
mocha: ['chai']
1410
};
@@ -21,7 +17,8 @@ class TestInitCommand implements ICommand {
2117
private $fs: IFileSystem,
2218
private $resources: IResourceLoader,
2319
private $pluginsService: IPluginsService,
24-
private $logger: ILogger) {
20+
private $logger: ILogger,
21+
private $testInitializationService: ITestInitializationService) {
2522
this.$projectData.initializeProjectData();
2623
}
2724

@@ -34,28 +31,25 @@ class TestInitCommand implements ICommand {
3431
this.$errors.fail(`Unknown or unsupported unit testing framework: ${frameworkToInstall}`);
3532
}
3633

37-
const dependencies = this.frameworkDependencies[frameworkToInstall] || [];
38-
const modulesToInstall: IDependencyInformation[] = [
39-
{
40-
name: 'karma',
41-
// Hardcode the version unitl https://github.com/karma-runner/karma/issues/3052 is fixed
42-
version: "2.0.2"
43-
},
44-
{
45-
name: `karma-${frameworkToInstall}`
46-
},
47-
{
48-
name: 'karma-nativescript-launcher'
49-
}
50-
];
34+
let modulesToInstall: IDependencyInformation[] = [];
35+
try {
36+
const dependencies = this.$testInitializationService.getDependencies(frameworkToInstall);
37+
const dependenciesVersions = this.$testInitializationService.getDependenciesVersions();
38+
modulesToInstall = dependencies.map(dependency => {
39+
const dependencyVersion = dependenciesVersions[dependency];
40+
if (!dependencyVersion) {
41+
this.$errors.failWithoutHelp(`'${dependency}' is not a registered dependency.`);
42+
}
5143

52-
modulesToInstall.push(...dependencies.map(f => ({ name: f })));
44+
return { name: dependency, version: dependencyVersion };
45+
});
46+
} catch (err) {
47+
this.$errors.failWithoutHelp(`Unable to install the unit testing dependencies. Error: '${err.message}'`);
48+
}
5349

5450
for (const mod of modulesToInstall) {
5551
let moduleToInstall = mod.name;
56-
if (mod.version) {
57-
moduleToInstall += `@${mod.version}`;
58-
}
52+
moduleToInstall += `@${mod.version}`;
5953
await this.$packageManager.install(moduleToInstall, projectDir, {
6054
'save-dev': true,
6155
'save-exact': true,

lib/definitions/project.d.ts

+5
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,11 @@ interface ITestExecutionService {
475475
canStartKarmaServer(projectData: IProjectData): Promise<boolean>;
476476
}
477477

478+
interface ITestInitializationService {
479+
getDependencies(framework: string): string[];
480+
getDependenciesVersions(): IDictionary<string>;
481+
}
482+
478483
/**
479484
* Describes a service used to facilitate communication with CocoaPods
480485
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import * as path from "path";
2+
import { cache } from "../common/decorators";
3+
4+
export class TestInitializationService implements ITestInitializationService {
5+
private configsPath = path.join(__dirname, "..", "..", "config");
6+
7+
constructor(private $fs: IFileSystem) { }
8+
9+
@cache()
10+
public getDependencies(selectedFramework: string): string[] {
11+
const dependenciesPath = path.join(this.configsPath, "test-dependencies.json");
12+
const allDependencies: { name: string, framework: string }[] = this.$fs.readJson(dependenciesPath);
13+
const targetFrameworkDependencies: string[] = allDependencies
14+
.filter(dependency => !dependency.framework || dependency.framework === selectedFramework)
15+
.map(dependency => dependency.name);
16+
17+
return targetFrameworkDependencies;
18+
}
19+
20+
@cache()
21+
public getDependenciesVersions(): IDictionary<string> {
22+
const dependenciesVersionsPath = path.join(this.configsPath, "test-deps-versions-generated.json");
23+
const dependenciesVersions = this.$fs.readJson(dependenciesVersionsPath);
24+
25+
return dependenciesVersions;
26+
}
27+
}
28+
29+
$injector.register("testInitializationService", TestInitializationService);

0 commit comments

Comments
 (0)