Skip to content

Commit 0db3676

Browse files
author
Fatme
authored
Merge pull request #4437 from NativeScript/fatme/unit-testing
feat: implement unit testing with bundle
2 parents 52317d8 + aaac12f commit 0db3676

File tree

7 files changed

+72
-46
lines changed

7 files changed

+72
-46
lines changed

config/test-dependencies.json

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
{
66
"name": "karma-nativescript-launcher"
77
},
8+
{
9+
"name": "karma-webpack",
10+
"excludedPeerDependencies": ["webpack"]
11+
},
812
{
913
"name": "mocha",
1014
"framework": "mocha"

lib/commands/test-init.ts

+6-10
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,7 @@ class TestInitCommand implements ICommand {
3333

3434
let modulesToInstall: IDependencyInformation[] = [];
3535
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-
}
43-
44-
return { name: dependency, version: dependencyVersion };
45-
});
36+
modulesToInstall = this.$testInitializationService.getDependencies(frameworkToInstall);
4637
} catch (err) {
4738
this.$errors.failWithoutHelp(`Unable to install the unit testing dependencies. Error: '${err.message}'`);
4839
}
@@ -66,6 +57,11 @@ class TestInitCommand implements ICommand {
6657
const modulePeerDependencies = modulePackageJsonContent.peerDependencies || {};
6758

6859
for (const peerDependency in modulePeerDependencies) {
60+
const isPeerDependencyExcluded = _.includes(mod.excludedPeerDependencies, peerDependency);
61+
if (isPeerDependencyExcluded) {
62+
continue;
63+
}
64+
6965
const dependencyVersion = modulePeerDependencies[peerDependency] || "*";
7066

7167
// catch errors when a peerDependency is already installed

lib/common/declarations.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1466,6 +1466,7 @@ interface IProcessService {
14661466
interface IDependencyInformation {
14671467
name: string;
14681468
version?: string;
1469+
excludedPeerDependencies?: string[];
14691470
}
14701471

14711472
/**

lib/definitions/project.d.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -482,8 +482,7 @@ interface ITestExecutionService {
482482
}
483483

484484
interface ITestInitializationService {
485-
getDependencies(framework: string): string[];
486-
getDependenciesVersions(): IDictionary<string>;
485+
getDependencies(framework: string): IDependencyInformation[];
487486
}
488487

489488
/**

lib/services/test-execution-service.ts

+13-20
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ export class TestExecutionService implements ITestExecutionService {
1919
private $fs: IFileSystem,
2020
private $options: IOptions,
2121
private $pluginsService: IPluginsService,
22-
private $errors: IErrors,
2322
private $devicesService: Mobile.IDevicesService,
2423
private $childProcess: IChildProcess) {
2524
}
@@ -59,25 +58,8 @@ export class TestExecutionService implements ITestExecutionService {
5958
this.$fs.writeFile(path.join(projectDir, TestExecutionService.CONFIG_FILE_NAME), configJs);
6059
}
6160

62-
const appFilesUpdaterOptions: IAppFilesUpdaterOptions = {
63-
bundle: !!this.$options.bundle,
64-
release: this.$options.release,
65-
useHotModuleReload: this.$options.hmr
66-
};
67-
const preparePlatformInfo: IPreparePlatformInfo = {
68-
platform,
69-
appFilesUpdaterOptions,
70-
platformTemplate: this.$options.platformTemplate,
71-
projectData,
72-
config: this.$options,
73-
env: this.$options.env
74-
};
75-
7661
// Prepare the project AFTER the TestExecutionService.CONFIG_FILE_NAME file is created in node_modules
7762
// so it will be sent to device.
78-
if (!await this.$platformService.preparePlatform(preparePlatformInfo)) {
79-
this.$errors.failWithoutHelp("Verify that listed files are well-formed and try again the operation.");
80-
}
8163

8264
let devices = [];
8365
if (this.$options.debugBrk) {
@@ -125,21 +107,29 @@ export class TestExecutionService implements ITestExecutionService {
125107
return info;
126108
});
127109

110+
const env = this.$options.env || {};
111+
env.unitTesting = !!this.$options.bundle;
112+
128113
const liveSyncInfo: ILiveSyncInfo = {
129114
projectDir: projectData.projectDir,
130115
skipWatcher: !this.$options.watch || this.$options.justlaunch,
131116
watchAllFiles: this.$options.syncAllFiles,
132117
bundle: !!this.$options.bundle,
133118
release: this.$options.release,
134-
env: this.$options.env,
119+
env,
135120
timeout: this.$options.timeout,
136121
useHotModuleReload: this.$options.hmr
137122
};
138123

139124
await this.$liveSyncService.liveSync(deviceDescriptors, liveSyncInfo);
140125
};
141126

142-
karmaRunner.on("message", (karmaData: any) => {
127+
karmaRunner.on("message", (karmaData: any) => {
128+
this.$logger.trace(`The received message from karma is: `, karmaData);
129+
if (!karmaData.launcherConfig && !karmaData.url) {
130+
return;
131+
}
132+
143133
launchKarmaTests(karmaData)
144134
.catch((result) => {
145135
this.$logger.error(result);
@@ -207,6 +197,7 @@ export class TestExecutionService implements ITestExecutionService {
207197
debugTransport: this.$options.debugTransport,
208198
debugBrk: this.$options.debugBrk,
209199
watch: !!this.$options.watch,
200+
bundle: !!this.$options.bundle,
210201
appDirectoryRelativePath: projectData.getAppDirectoryRelativePath()
211202
}
212203
},
@@ -226,6 +217,8 @@ export class TestExecutionService implements ITestExecutionService {
226217
}
227218

228219
karmaConfig.projectDir = projectData.projectDir;
220+
karmaConfig.bundle = this.$options.bundle;
221+
karmaConfig.platform = platform.toLowerCase();
229222
this.$logger.debug(JSON.stringify(karmaConfig, null, 4));
230223

231224
return karmaConfig;

lib/services/test-initialization-service.ts

+15-12
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,28 @@ import { cache } from "../common/decorators";
44
export class TestInitializationService implements ITestInitializationService {
55
private configsPath = path.join(__dirname, "..", "..", "config");
66

7-
constructor(private $fs: IFileSystem) { }
7+
constructor(private $errors: IErrors,
8+
private $fs: IFileSystem) { }
89

910
@cache()
10-
public getDependencies(selectedFramework: string): string[] {
11+
public getDependencies(selectedFramework: string): IDependencyInformation[] {
1112
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-
}
13+
const allDependencies: { name: string, framework?: string, excludedPeerDependencies?: string[] }[] = this.$fs.readJson(dependenciesPath);
1914

20-
@cache()
21-
public getDependenciesVersions(): IDictionary<string> {
2215
const dependenciesVersionsPath = path.join(this.configsPath, "test-deps-versions-generated.json");
2316
const dependenciesVersions = this.$fs.readJson(dependenciesVersionsPath);
2417

25-
return dependenciesVersions;
18+
const targetFrameworkDependencies: IDependencyInformation[] = allDependencies
19+
.filter(dependency => !dependency.framework || dependency.framework === selectedFramework)
20+
.map(dependency => {
21+
const dependencyVersion = dependenciesVersions[dependency.name];
22+
if (!dependencyVersion) {
23+
this.$errors.failWithoutHelp(`'${dependency}' is not a registered dependency.`);
24+
}
25+
return { ...dependency, version: dependencyVersion };
26+
});
27+
28+
return targetFrameworkDependencies;
2629
}
2730
}
2831

resources/test/karma.conf.js

+32-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module.exports = function(config) {
2-
config.set({
2+
const options = {
33

44
// base path that will be used to resolve all patterns (eg. files, exclude)
55
basePath: '',
@@ -73,5 +73,35 @@ module.exports = function(config) {
7373
// Continuous Integration mode
7474
// if true, Karma captures browsers, runs the tests and exits
7575
singleRun: false
76-
})
76+
};
77+
78+
setWebpackPreprocessor(config, options);
79+
setWebpack(config, options);
80+
81+
config.set(options);
82+
}
83+
84+
function setWebpackPreprocessor(config, options) {
85+
if (config && config.bundle) {
86+
if (!options.preprocessors) {
87+
options.preprocessors = {};
88+
}
89+
90+
options.files.forEach(file => {
91+
if (!options.preprocessors[file]) {
92+
options.preprocessors[file] = [];
93+
}
94+
options.preprocessors[file].push('webpack');
95+
});
96+
}
97+
}
98+
99+
function setWebpack(config, options) {
100+
if (config && config.bundle) {
101+
const env = {};
102+
env[config.platform] = true;
103+
options.webpack = require('./webpack.config')(env);
104+
delete options.webpack.entry;
105+
delete options.webpack.output.libraryTarget;
106+
}
77107
}

0 commit comments

Comments
 (0)