Skip to content
4 changes: 4 additions & 0 deletions config/test-dependencies.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
{
"name": "karma-nativescript-launcher"
},
{
"name": "karma-webpack",
"excludedPeerDependencies": ["webpack"]
},
{
"name": "mocha",
"framework": "mocha"
Expand Down
16 changes: 6 additions & 10 deletions lib/commands/test-init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,7 @@ class TestInitCommand implements ICommand {

let modulesToInstall: IDependencyInformation[] = [];
try {
const dependencies = this.$testInitializationService.getDependencies(frameworkToInstall);
const dependenciesVersions = this.$testInitializationService.getDependenciesVersions();
modulesToInstall = dependencies.map(dependency => {
const dependencyVersion = dependenciesVersions[dependency];
if (!dependencyVersion) {
this.$errors.failWithoutHelp(`'${dependency}' is not a registered dependency.`);
}

return { name: dependency, version: dependencyVersion };
});
modulesToInstall = this.$testInitializationService.getDependencies(frameworkToInstall);
} catch (err) {
this.$errors.failWithoutHelp(`Unable to install the unit testing dependencies. Error: '${err.message}'`);
}
Expand All @@ -66,6 +57,11 @@ class TestInitCommand implements ICommand {
const modulePeerDependencies = modulePackageJsonContent.peerDependencies || {};

for (const peerDependency in modulePeerDependencies) {
const isPeerDependencyExcluded = _.includes(mod.excludedPeerDependencies, peerDependency);
if (isPeerDependencyExcluded) {
continue;
}

const dependencyVersion = modulePeerDependencies[peerDependency] || "*";

// catch errors when a peerDependency is already installed
Expand Down
1 change: 1 addition & 0 deletions lib/common/declarations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1466,6 +1466,7 @@ interface IProcessService {
interface IDependencyInformation {
name: string;
version?: string;
excludedPeerDependencies?: string[];
}

/**
Expand Down
3 changes: 1 addition & 2 deletions lib/definitions/project.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -482,8 +482,7 @@ interface ITestExecutionService {
}

interface ITestInitializationService {
getDependencies(framework: string): string[];
getDependenciesVersions(): IDictionary<string>;
getDependencies(framework: string): IDependencyInformation[];
}

/**
Expand Down
33 changes: 13 additions & 20 deletions lib/services/test-execution-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export class TestExecutionService implements ITestExecutionService {
private $fs: IFileSystem,
private $options: IOptions,
private $pluginsService: IPluginsService,
private $errors: IErrors,
private $devicesService: Mobile.IDevicesService,
private $childProcess: IChildProcess) {
}
Expand Down Expand Up @@ -59,25 +58,8 @@ export class TestExecutionService implements ITestExecutionService {
this.$fs.writeFile(path.join(projectDir, TestExecutionService.CONFIG_FILE_NAME), configJs);
}

const appFilesUpdaterOptions: IAppFilesUpdaterOptions = {
bundle: !!this.$options.bundle,
release: this.$options.release,
useHotModuleReload: this.$options.hmr
};
const preparePlatformInfo: IPreparePlatformInfo = {
platform,
appFilesUpdaterOptions,
platformTemplate: this.$options.platformTemplate,
projectData,
config: this.$options,
env: this.$options.env
};

// Prepare the project AFTER the TestExecutionService.CONFIG_FILE_NAME file is created in node_modules
// so it will be sent to device.
if (!await this.$platformService.preparePlatform(preparePlatformInfo)) {
this.$errors.failWithoutHelp("Verify that listed files are well-formed and try again the operation.");
}

let devices = [];
if (this.$options.debugBrk) {
Expand Down Expand Up @@ -125,21 +107,29 @@ export class TestExecutionService implements ITestExecutionService {
return info;
});

const env = this.$options.env || {};
env.unitTesting = !!this.$options.bundle;

const liveSyncInfo: ILiveSyncInfo = {
projectDir: projectData.projectDir,
skipWatcher: !this.$options.watch || this.$options.justlaunch,
watchAllFiles: this.$options.syncAllFiles,
bundle: !!this.$options.bundle,
release: this.$options.release,
env: this.$options.env,
env,
timeout: this.$options.timeout,
useHotModuleReload: this.$options.hmr
};

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

karmaRunner.on("message", (karmaData: any) => {
karmaRunner.on("message", (karmaData: any) => {
this.$logger.trace(`The received message from karma is: `, karmaData);
if (!karmaData.launcherConfig && !karmaData.url) {
return;
}

launchKarmaTests(karmaData)
.catch((result) => {
this.$logger.error(result);
Expand Down Expand Up @@ -207,6 +197,7 @@ export class TestExecutionService implements ITestExecutionService {
debugTransport: this.$options.debugTransport,
debugBrk: this.$options.debugBrk,
watch: !!this.$options.watch,
bundle: !!this.$options.bundle,
appDirectoryRelativePath: projectData.getAppDirectoryRelativePath()
}
},
Expand All @@ -226,6 +217,8 @@ export class TestExecutionService implements ITestExecutionService {
}

karmaConfig.projectDir = projectData.projectDir;
karmaConfig.bundle = this.$options.bundle;
karmaConfig.platform = platform.toLowerCase();
this.$logger.debug(JSON.stringify(karmaConfig, null, 4));

return karmaConfig;
Expand Down
27 changes: 15 additions & 12 deletions lib/services/test-initialization-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,28 @@ import { cache } from "../common/decorators";
export class TestInitializationService implements ITestInitializationService {
private configsPath = path.join(__dirname, "..", "..", "config");

constructor(private $fs: IFileSystem) { }
constructor(private $errors: IErrors,
private $fs: IFileSystem) { }

@cache()
public getDependencies(selectedFramework: string): string[] {
public getDependencies(selectedFramework: string): IDependencyInformation[] {
const dependenciesPath = path.join(this.configsPath, "test-dependencies.json");
const allDependencies: { name: string, framework: string }[] = this.$fs.readJson(dependenciesPath);
const targetFrameworkDependencies: string[] = allDependencies
.filter(dependency => !dependency.framework || dependency.framework === selectedFramework)
.map(dependency => dependency.name);

return targetFrameworkDependencies;
}
const allDependencies: { name: string, framework?: string, excludedPeerDependencies?: string[] }[] = this.$fs.readJson(dependenciesPath);

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

return dependenciesVersions;
const targetFrameworkDependencies: IDependencyInformation[] = allDependencies
.filter(dependency => !dependency.framework || dependency.framework === selectedFramework)
.map(dependency => {
const dependencyVersion = dependenciesVersions[dependency.name];
if (!dependencyVersion) {
this.$errors.failWithoutHelp(`'${dependency}' is not a registered dependency.`);
}
return { ...dependency, version: dependencyVersion };
});

return targetFrameworkDependencies;
}
}

Expand Down
34 changes: 32 additions & 2 deletions resources/test/karma.conf.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = function(config) {
config.set({
const options = {

// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
Expand Down Expand Up @@ -73,5 +73,35 @@ module.exports = function(config) {
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false
})
};

setWebpackPreprocessor(config, options);
setWebpack(config, options);

config.set(options);
}

function setWebpackPreprocessor(config, options) {
if (config && config.bundle) {
if (!options.preprocessors) {
options.preprocessors = {};
}

options.files.forEach(file => {
if (!options.preprocessors[file]) {
options.preprocessors[file] = [];
}
options.preprocessors[file].push('webpack');
});
}
}

function setWebpack(config, options) {
if (config && config.bundle) {
const env = {};
env[config.platform] = true;
options.webpack = require('./webpack.config')(env);
delete options.webpack.entry;
delete options.webpack.output.libraryTarget;
}
}