Skip to content

Commit 5ebebb4

Browse files
committed
Merge pull request #1052 from NativeScript/tpopov/sandbox-pods
Add 'sandbox-pod' command. Implement test.
2 parents 4e667af + 20f4b26 commit 5ebebb4

File tree

6 files changed

+110
-32
lines changed

6 files changed

+110
-32
lines changed

config/config.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
"PROXY_HOSTNAME": "127.0.0.1",
66
"TYPESCRIPT_COMPILER_OPTIONS": {},
77
"CI_LOGGER": false,
8-
"ANDROID_DEBUG_UI_MAC": "Google Chrome"
8+
"ANDROID_DEBUG_UI_MAC": "Google Chrome",
9+
"USE_POD_SANDBOX": true
910
}

lib/config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export class Configuration extends configBaseLib.ConfigBase implements IConfigur
1111
TYPESCRIPT_COMPILER_OPTIONS = {};
1212
USE_PROXY = false;
1313
ANDROID_DEBUG_UI: string = null;
14+
USE_POD_SANDBOX: boolean = true;
1415

1516
/*don't require logger and everything that has logger as dependency in config.js due to cyclic dependency*/
1617
constructor(protected $fs: IFileSystem) {

lib/declarations.ts

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ interface IStaticConfig extends Config.IStaticConfig { }
3737

3838
interface IConfiguration extends Config.IConfig {
3939
ANDROID_DEBUG_UI: string;
40+
USE_POD_SANDBOX: boolean;
4041
}
4142

4243
interface IApplicationPackage {

lib/services/ios-project-service.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
3232
private $options: IOptions,
3333
private $injector: IInjector,
3434
$projectDataService: IProjectDataService,
35-
private $prompter: IPrompter) {
35+
private $prompter: IPrompter,
36+
private $config: IConfiguration) {
3637
super($fs, $projectData, $projectDataService);
3738
}
3839

@@ -499,7 +500,8 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
499500

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

505507
private prepareFrameworks(pluginPlatformsFolderPath: string, pluginData: IPluginData): IFuture<void> {

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
},
1111
"main": "./lib/nativescript-cli.js",
1212
"scripts": {
13-
"test": "node_modules/.bin/istanbul cover node_modules/mocha/bin/_mocha -- --ui mocha-fibers --recursive --reporter spec --require test/test-bootstrap.js --timeout 60000 test/ lib/common/test/unit-tests",
13+
"test": "node_modules/.bin/istanbul cover node_modules/mocha/bin/_mocha -- --ui mocha-fibers --recursive --reporter spec --require test/test-bootstrap.js --timeout 150000 test/ lib/common/test/unit-tests",
1414
"postinstall": "node postinstall.js",
1515
"preuninstall": "node preuninstall.js"
1616
},

test/project-service.ts

+101-28
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,24 @@
44
import yok = require('../lib/common/yok');
55
import stubs = require('./stubs');
66
import * as constants from "./../lib/constants";
7-
import * as ChildProcessLib from "../lib/common/child-process";
7+
import {ChildProcess} from "../lib/common/child-process";
88
import * as ProjectServiceLib from "../lib/services/project-service";
99
import * as ProjectDataServiceLib from "../lib/services/project-data-service";
1010
import * as ProjectDataLib from "../lib/project-data";
1111
import * as ProjectHelperLib from "../lib/common/project-helper";
12-
import * as StaticConfigLib from "../lib/config";
12+
import {StaticConfig} from "../lib/config";
1313
import * as NpmLib from "../lib/node-package-manager";
14-
import * as NpmInstallationManagerLib from "../lib/npm-installation-manager";
14+
import {NpmInstallationManager} from "../lib/npm-installation-manager";
1515
import * as HttpClientLib from "../lib/common/http-client";
16-
import * as fsLib from "../lib/common/file-system";
16+
import {FileSystem} from "../lib/common/file-system";
1717
import * as path from "path";
1818
import temp = require("temp");
1919
import * as helpers from "../lib/common/helpers";
2020
import {assert} from "chai";
21-
import * as optionsLib from "../lib/options";
22-
import * as hostInfoLib from "../lib/common/host-info";
21+
import {Options} from "../lib/options";
22+
import {HostInfo} from "../lib/common/host-info";
23+
import {IOSProjectService} from "../lib/services/ios-project-service";
24+
import * as shell from "shelljs";
2325

2426
let mockProjectNameValidator = {
2527
validate: () => { return true; }
@@ -39,21 +41,20 @@ class ProjectIntegrationTest {
3941
return projectService.createProject(projectName);
4042
}
4143

42-
public getDefaultTemplatePath(): IFuture<string> {
44+
public getNpmPackagePath(packageName: string): IFuture<string> {
4345
return (() => {
4446
let npmInstallationManager = this.testInjector.resolve("npmInstallationManager");
4547
let fs = this.testInjector.resolve("fs");
4648

47-
let defaultTemplatePackageName = "tns-template-hello-world";
4849
let cacheRoot = npmInstallationManager.getCacheRootPath();
49-
let defaultTemplatePath = path.join(cacheRoot, defaultTemplatePackageName);
50-
let latestVersion = npmInstallationManager.getLatestVersion(defaultTemplatePackageName).wait();
50+
let defaultTemplatePath = path.join(cacheRoot, packageName);
51+
let latestVersion = npmInstallationManager.getLatestVersion(packageName).wait();
5152

5253
if(!fs.exists(path.join(defaultTemplatePath, latestVersion)).wait()) {
53-
npmInstallationManager.addToCache(defaultTemplatePackageName, latestVersion).wait();
54+
npmInstallationManager.addToCache(packageName, latestVersion).wait();
5455
}
5556
if(!fs.exists(path.join(defaultTemplatePath, latestVersion, "package", "app")).wait()) {
56-
npmInstallationManager.cacheUnpack(defaultTemplatePackageName, latestVersion).wait();
57+
npmInstallationManager.cacheUnpack(packageName, latestVersion).wait();
5758
}
5859

5960
return path.join(defaultTemplatePath, latestVersion, "package");
@@ -103,26 +104,25 @@ class ProjectIntegrationTest {
103104

104105
private createTestInjector(): void {
105106
this.testInjector = new yok.Yok();
106-
this.testInjector.register("childProcess", ChildProcessLib.ChildProcess);
107+
this.testInjector.register("childProcess", ChildProcess);
107108
this.testInjector.register("errors", stubs.ErrorsStub);
108109
this.testInjector.register('logger', stubs.LoggerStub);
109110
this.testInjector.register("projectService", ProjectServiceLib.ProjectService);
110111
this.testInjector.register("projectHelper", ProjectHelperLib.ProjectHelper);
111112
this.testInjector.register("projectTemplatesService", stubs.ProjectTemplatesService);
112113
this.testInjector.register("projectNameValidator", mockProjectNameValidator);
113114

114-
this.testInjector.register("fs", fsLib.FileSystem);
115+
this.testInjector.register("fs", FileSystem);
115116
this.testInjector.register("projectDataService", ProjectDataServiceLib.ProjectDataService);
116-
this.testInjector.register("staticConfig", StaticConfigLib.StaticConfig);
117+
this.testInjector.register("staticConfig", StaticConfig);
117118

118-
this.testInjector.register("npmInstallationManager", NpmInstallationManagerLib.NpmInstallationManager);
119+
this.testInjector.register("npmInstallationManager", NpmInstallationManager);
119120
this.testInjector.register("npm", NpmLib.NodePackageManager);
120121
this.testInjector.register("httpClient", HttpClientLib.HttpClient);
121-
this.testInjector.register("config", {});
122122
this.testInjector.register("lockfile", stubs.LockFile);
123123

124-
this.testInjector.register("options", optionsLib.Options);
125-
this.testInjector.register("hostInfo", hostInfoLib.HostInfo);
124+
this.testInjector.register("options", Options);
125+
this.testInjector.register("hostInfo", HostInfo);
126126
}
127127
}
128128

@@ -135,7 +135,7 @@ describe("Project Service Tests", () => {
135135
let options = projectIntegrationTest.testInjector.resolve("options");
136136

137137
options.path = tempFolder;
138-
options.copyFrom = projectIntegrationTest.getDefaultTemplatePath().wait();
138+
options.copyFrom = projectIntegrationTest.getNpmPackagePath("tns-template-hello-world").wait();
139139

140140
projectIntegrationTest.createProject(projectName).wait();
141141
projectIntegrationTest.assertProject(tempFolder, projectName, "org.nativescript.myapp").wait();
@@ -147,12 +147,50 @@ describe("Project Service Tests", () => {
147147
let options = projectIntegrationTest.testInjector.resolve("options");
148148

149149
options.path = tempFolder;
150-
options.copyFrom = projectIntegrationTest.getDefaultTemplatePath().wait();
150+
options.copyFrom = projectIntegrationTest.getNpmPackagePath("tns-template-hello-world").wait();
151151
options.appid = "my.special.id";
152152

153153
projectIntegrationTest.createProject(projectName).wait();
154154
projectIntegrationTest.assertProject(tempFolder, projectName, options.appid).wait();
155155
});
156+
it("creates ios project and tests post-install sandboxing of CocoaPods setup", () => {
157+
if (require("os").platform() !== "darwin") {
158+
console.log("Skipping CocoaPods sandbox test. It works only on darwin.");
159+
return;
160+
}
161+
162+
let testDirectoryPath = "/tmp/Podfile";
163+
let testInjector = createInjectorForPodsTest();
164+
let iOSProjectService: IPlatformProjectService = testInjector.resolve("iOSProjectService");
165+
let fs: IFileSystem = testInjector.resolve("fs");
166+
let projectIntegrationTest = new ProjectIntegrationTest();
167+
let workingFolderPath = temp.mkdirSync("ios_project");
168+
let iosTemplatePath = path.join(projectIntegrationTest.getNpmPackagePath("tns-ios").wait(), "framework/");
169+
let postInstallCommmand = `\`cat ${testDirectoryPath}/testFile.txt > ${workingFolderPath}/copyTestFile.txt && rm -rf ${testDirectoryPath}\``;
170+
let podfileContent = `post_install do |installer_representation| ${postInstallCommmand} end`;
171+
let platformData = iOSProjectService.platformData;
172+
173+
shell.cp("-R", iosTemplatePath, workingFolderPath);
174+
175+
fs.writeFile(`${testDirectoryPath}/testFile.txt`, "Test content.").wait();
176+
fs.writeFile(path.join(workingFolderPath, "Podfile"), podfileContent).wait();
177+
178+
Object.defineProperty(iOSProjectService, "platformData", {
179+
get: () => {
180+
return { projectRoot: workingFolderPath };
181+
}
182+
});
183+
184+
try {
185+
iOSProjectService.afterPrepareAllPlugins().wait();
186+
} finally {
187+
Object.defineProperty(iOSProjectService, "platformData", platformData);
188+
}
189+
190+
assert.isTrue(fs.exists(testDirectoryPath).wait());
191+
assert.isTrue(fs.exists(path.join(workingFolderPath, "copyTestFile.txt")).wait());
192+
fs.deleteDirectory(testDirectoryPath).wait(); // Clean up 'tmp' after test ends.
193+
});
156194
});
157195
});
158196

@@ -166,21 +204,56 @@ function createTestInjector() {
166204
testInjector.register("projectTemplatesService", stubs.ProjectTemplatesService);
167205
testInjector.register("projectNameValidator", mockProjectNameValidator);
168206

169-
testInjector.register("fs", fsLib.FileSystem);
207+
testInjector.register("fs", FileSystem);
170208
testInjector.register("projectDataService", ProjectDataServiceLib.ProjectDataService);
171209

172-
testInjector.register("staticConfig", StaticConfigLib.StaticConfig);
210+
testInjector.register("staticConfig", StaticConfig);
173211

174-
testInjector.register("npmInstallationManager", NpmInstallationManagerLib.NpmInstallationManager);
212+
testInjector.register("npmInstallationManager", NpmInstallationManager);
175213
testInjector.register("httpClient", HttpClientLib.HttpClient);
176-
testInjector.register("config", {});
177214
testInjector.register("lockfile", stubs.LockFile);
178215

179-
testInjector.register("childProcess", ChildProcessLib.ChildProcess);
216+
testInjector.register("childProcess", ChildProcess);
180217

181218
testInjector.register('projectData', ProjectDataLib.ProjectData);
182-
testInjector.register("options", optionsLib.Options);
183-
testInjector.register("hostInfo", hostInfoLib.HostInfo);
219+
testInjector.register("options", Options);
220+
testInjector.register("hostInfo", HostInfo);
221+
222+
return testInjector;
223+
}
224+
225+
function createInjectorForPodsTest() {
226+
let testInjector = new yok.Yok();
227+
228+
testInjector.register("errors", stubs.ErrorsStub);
229+
testInjector.register('logger', stubs.LoggerStub);
230+
testInjector.register("projectHelper", {});
231+
testInjector.register("projectData", {
232+
projectName: "__PROJECT_NAME__",
233+
platformsDir: ""
234+
});
235+
testInjector.register("iOSEmulatorServices", {});
236+
testInjector.register("config", {
237+
"USE_POD_SANDBOX": true
238+
});
239+
testInjector.register("prompter", {});
240+
testInjector.register("fs", FileSystem);
241+
testInjector.register("staticConfig", StaticConfig);
242+
testInjector.register("npmInstallationManager", NpmInstallationManager);
243+
testInjector.register("iOSProjectService", IOSProjectService);
244+
testInjector.register("projectService", ProjectServiceLib.ProjectService);
245+
testInjector.register("pluginsService", {
246+
getAllInstalledPlugins: () => {
247+
return (() => {
248+
return <any>[];
249+
}).future<IPluginData[]>()();
250+
}
251+
});
252+
testInjector.register("fs", FileSystem);
253+
testInjector.register("projectDataService", ProjectDataServiceLib.ProjectDataService);
254+
testInjector.register("options", Options);
255+
testInjector.register("hostInfo", HostInfo);
256+
testInjector.register("childProcess", ChildProcess);
184257

185258
return testInjector;
186259
}

0 commit comments

Comments
 (0)