Skip to content

Add 'sandbox-pod' command. Implement test. #1052

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Oct 19, 2015
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
"PROXY_HOSTNAME": "127.0.0.1",
"TYPESCRIPT_COMPILER_OPTIONS": {},
"CI_LOGGER": false,
"ANDROID_DEBUG_UI_MAC": "Google Chrome"
"ANDROID_DEBUG_UI_MAC": "Google Chrome",
"USE_POD_SANDBOX": true
}
1 change: 1 addition & 0 deletions lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export class Configuration extends configBaseLib.ConfigBase implements IConfigur
TYPESCRIPT_COMPILER_OPTIONS = {};
USE_PROXY = false;
ANDROID_DEBUG_UI: string = null;
USE_POD_SANDBOX: boolean = true;

/*don't require logger and everything that has logger as dependency in config.js due to cyclic dependency*/
constructor(protected $fs: IFileSystem) {
Expand Down
1 change: 1 addition & 0 deletions lib/declarations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ interface IStaticConfig extends Config.IStaticConfig { }

interface IConfiguration extends Config.IConfig {
ANDROID_DEBUG_UI: string;
USE_POD_SANDBOX: boolean;
}

interface IApplicationPackage {
Expand Down
6 changes: 4 additions & 2 deletions lib/services/ios-project-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
private $options: IOptions,
private $injector: IInjector,
$projectDataService: IProjectDataService,
private $prompter: IPrompter) {
private $prompter: IPrompter,
private $config: IConfiguration) {
super($fs, $projectData, $projectDataService);
}

Expand Down Expand Up @@ -495,7 +496,8 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ

private executePodInstall(): IFuture<any> {
this.$logger.info("Installing pods...");
return this.$childProcess.spawnFromEvent("pod", ["install"], "close", { cwd: this.platformData.projectRoot, stdio: 'inherit' });
let podTool = this.$config.USE_POD_SANDBOX ? "sandbox-pod" : "pod";
return this.$childProcess.spawnFromEvent(podTool, ["install"], "close", { cwd: this.platformData.projectRoot, stdio: 'inherit' });
}

private prepareFrameworks(pluginPlatformsFolderPath: string, pluginData: IPluginData): IFuture<void> {
Expand Down
91 changes: 78 additions & 13 deletions test/project-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import yok = require('../lib/common/yok');
import stubs = require('./stubs');
import * as constants from "./../lib/constants";
import * as ChildProcessLib from "../lib/common/child-process";
import {ChildProcess} from "../lib/common/child-process";
import * as ProjectServiceLib from "../lib/services/project-service";
import * as ProjectDataServiceLib from "../lib/services/project-data-service";
import * as ProjectDataLib from "../lib/project-data";
Expand All @@ -20,6 +20,7 @@ import * as helpers from "../lib/common/helpers";
import {assert} from "chai";
import * as optionsLib from "../lib/options";
import * as hostInfoLib from "../lib/common/host-info";
import iOSProjectServiceLib = require("../lib/services/ios-project-service");

let mockProjectNameValidator = {
validate: () => { return true; }
Expand All @@ -39,21 +40,20 @@ class ProjectIntegrationTest {
return projectService.createProject(projectName);
}

public getDefaultTemplatePath(): IFuture<string> {
public getDefaultTemplatePath(templateName: string): IFuture<string> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function should be renamed for example getNpmPackagePath(packageName: string)

return (() => {
let npmInstallationManager = this.testInjector.resolve("npmInstallationManager");
let fs = this.testInjector.resolve("fs");

let defaultTemplatePackageName = "tns-template-hello-world";
let cacheRoot = npmInstallationManager.getCacheRootPath();
let defaultTemplatePath = path.join(cacheRoot, defaultTemplatePackageName);
let latestVersion = npmInstallationManager.getLatestVersion(defaultTemplatePackageName).wait();
let defaultTemplatePath = path.join(cacheRoot, templateName);
let latestVersion = npmInstallationManager.getLatestVersion(templateName).wait();

if(!fs.exists(path.join(defaultTemplatePath, latestVersion)).wait()) {
npmInstallationManager.addToCache(defaultTemplatePackageName, latestVersion).wait();
npmInstallationManager.addToCache(templateName, latestVersion).wait();
}
if(!fs.exists(path.join(defaultTemplatePath, latestVersion, "package", "app")).wait()) {
npmInstallationManager.cacheUnpack(defaultTemplatePackageName, latestVersion).wait();
npmInstallationManager.cacheUnpack(templateName, latestVersion).wait();
}

return path.join(defaultTemplatePath, latestVersion, "package");
Expand Down Expand Up @@ -103,7 +103,7 @@ class ProjectIntegrationTest {

private createTestInjector(): void {
this.testInjector = new yok.Yok();
this.testInjector.register("childProcess", ChildProcessLib.ChildProcess);
this.testInjector.register("childProcess", ChildProcess);
this.testInjector.register("errors", stubs.ErrorsStub);
this.testInjector.register('logger', stubs.LoggerStub);
this.testInjector.register("projectService", ProjectServiceLib.ProjectService);
Expand All @@ -118,7 +118,6 @@ class ProjectIntegrationTest {
this.testInjector.register("npmInstallationManager", NpmInstallationManagerLib.NpmInstallationManager);
this.testInjector.register("npm", NpmLib.NodePackageManager);
this.testInjector.register("httpClient", HttpClientLib.HttpClient);
this.testInjector.register("config", {});
this.testInjector.register("lockfile", stubs.LockFile);

this.testInjector.register("options", optionsLib.Options);
Expand All @@ -135,7 +134,7 @@ describe("Project Service Tests", () => {
let options = projectIntegrationTest.testInjector.resolve("options");

options.path = tempFolder;
options.copyFrom = projectIntegrationTest.getDefaultTemplatePath().wait();
options.copyFrom = projectIntegrationTest.getDefaultTemplatePath("tns-template-hello-world").wait();

projectIntegrationTest.createProject(projectName).wait();
projectIntegrationTest.assertProject(tempFolder, projectName, "org.nativescript.myapp").wait();
Expand All @@ -147,12 +146,52 @@ describe("Project Service Tests", () => {
let options = projectIntegrationTest.testInjector.resolve("options");

options.path = tempFolder;
options.copyFrom = projectIntegrationTest.getDefaultTemplatePath().wait();
options.copyFrom = projectIntegrationTest.getDefaultTemplatePath("tns-template-hello-world").wait();
options.appid = "my.special.id";

projectIntegrationTest.createProject(projectName).wait();
projectIntegrationTest.assertProject(tempFolder, projectName, options.appid).wait();
});
it("creates ios project and tests post-install sandboxing of CocoaPods setup", () => {
if (require("os").platform() !== "darwin") {
console.log("Skipping CocoaPods sandbox test. It works only on darwin.");
return;
}

let testInjector = createInjectorForPodsTest();

let iOSProjectService: IPlatformProjectService = testInjector.resolve("iOSProjectService");
let fs: IFileSystem = testInjector.resolve("fs");
let childProcess = testInjector.resolve("childProcess");
let projectIntegrationTest = new ProjectIntegrationTest();
let workingFolderPath = temp.mkdirSync("ios_project");

let iosTemplatePath = path.join(projectIntegrationTest.getDefaultTemplatePath("tns-ios").wait(), "framework/");
childProcess.exec(`cp -R ${iosTemplatePath} ${workingFolderPath}`, { cwd: workingFolderPath }).wait();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use either $fs or shelljs

fs.writeFile("/tmp/Podfile/testFile.txt", "Test content.").wait();

let postInstallCommmand = `\`cat /tmp/Podfile/testFile.txt > ${workingFolderPath}/copyTestFile.txt && rm -rf /tmp/Podfile\``;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

magic constant used more than once - consider making it a symbol /tmp/Podfile

let podfileContent = `post_install do |installer_representation| ${postInstallCommmand} end`;
fs.writeFile(path.join(workingFolderPath, "Podfile"), podfileContent).wait();

let platformData = iOSProjectService.platformData;
Object.defineProperty(iOSProjectService, "platformData", {
get: () => {
return { projectRoot: workingFolderPath };
}
});

try {
iOSProjectService.afterPrepareAllPlugins().wait();
} catch(e) {
assert.isNotNull(e);
} finally {
Object.defineProperty(iOSProjectService, "platformData", platformData);
}

assert.isTrue(fs.exists("/tmp/Podfile").wait());
assert.isTrue(fs.exists(path.join(workingFolderPath, "copyTestFile.txt")).wait());
});
});
});

Expand All @@ -173,10 +212,9 @@ function createTestInjector() {

testInjector.register("npmInstallationManager", NpmInstallationManagerLib.NpmInstallationManager);
testInjector.register("httpClient", HttpClientLib.HttpClient);
testInjector.register("config", {});
testInjector.register("lockfile", stubs.LockFile);

testInjector.register("childProcess", ChildProcessLib.ChildProcess);
testInjector.register("childProcess", ChildProcess);

testInjector.register('projectData', ProjectDataLib.ProjectData);
testInjector.register("options", optionsLib.Options);
Expand All @@ -185,6 +223,33 @@ function createTestInjector() {
return testInjector;
}

function createInjectorForPodsTest() {
let testInjector = new yok.Yok();

testInjector.register("errors", stubs.ErrorsStub);
testInjector.register('logger', stubs.LoggerStub);
testInjector.register("projectHelper", {});
testInjector.register("projectData", {
projectName: "__PROJECT_NAME__",
platformsDir: ""
});
testInjector.register("projectDataService", {});
testInjector.register("iOSEmulatorServices", {});
testInjector.register("config", {
"USE_POD_SANDBOX": true
});
testInjector.register("prompter", {});
testInjector.register("fs", fsLib.FileSystem);
testInjector.register("staticConfig", StaticConfigLib.StaticConfig);
testInjector.register("npmInstallationManager", NpmInstallationManagerLib.NpmInstallationManager);
testInjector.register("iOSProjectService", iOSProjectServiceLib.IOSProjectService);
testInjector.register("childProcess", ChildProcess);
testInjector.register("options", optionsLib.Options);
testInjector.register("hostInfo", hostInfoLib.HostInfo);

return testInjector;
}

describe("project upgrade procedure tests", () => {
it("should throw error when no nativescript project folder specified", () => {
let testInjector = createTestInjector();
Expand Down