Skip to content

Commit 48c299a

Browse files
Fatme Havaluovarosen-vladimirov
Fatme Havaluova
authored andcommitted
Fix unit tests
1 parent 4c115e6 commit 48c299a

7 files changed

+307
-70
lines changed

lib/definitions/project.d.ts

+6
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,9 @@ interface IPlatformProjectService {
3434
preparePluginNativeCode(pluginData: IPluginData): IFuture<void>;
3535
removePluginNativeCode(pluginData: IPluginData): IFuture<void>;
3636
}
37+
38+
interface IAndroidProjectPropertiesManager {
39+
getProjectReferences(): IFuture<ILibRef[]>;
40+
addProjectReference(referencePath: string): IFuture<void>;
41+
removeProjectReference(referencePath: string): IFuture<void>;
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
///<reference path="../.d.ts"/>
2+
"use strict";
3+
4+
import path = require("path");
5+
6+
export class AndroidProjectPropertiesManager implements IAndroidProjectPropertiesManager {
7+
private static LIBRARY_REFERENCE_KEY_PREFIX = "android.library.reference.";
8+
9+
private _editor: IPropertiesParserEditor = null;
10+
private filePath: string = null;
11+
private projectReferences: ILibRef[];
12+
private dirty = false;
13+
14+
constructor(private $propertiesParser: IPropertiesParser,
15+
private $fs: IFileSystem,
16+
directoryPath: string) {
17+
this.filePath = path.join(directoryPath, "project.properties");
18+
}
19+
20+
public addToPropertyList(key: string, value: string): IFuture<void> {
21+
return (() => {
22+
let editor = this.createEditor().wait();
23+
let i = 1;
24+
while (editor.get(this.buildKeyName(key, i))) {
25+
i++;
26+
}
27+
28+
editor.set(this.buildKeyName(key, i), value);
29+
this.$propertiesParser.saveEditor().wait();
30+
this.dirty = true;
31+
}).future<void>()();
32+
}
33+
34+
public removeFromPropertyList(key: string, value: string): IFuture<void> {
35+
return (() => {
36+
let editor = this.createEditor().wait();
37+
let valueLowerCase = value.toLowerCase();
38+
let i = 1;
39+
let currentValue: any;
40+
while (currentValue = editor.get(this.buildKeyName(key, i))) {
41+
if (currentValue.toLowerCase() === valueLowerCase) {
42+
while (currentValue = editor.get(this.buildKeyName(key, i+1))) {
43+
editor.set(this.buildKeyName(key, i), currentValue);
44+
i++;
45+
}
46+
editor.set(this.buildKeyName(key, i));
47+
break;
48+
}
49+
i++;
50+
}
51+
this.$propertiesParser.saveEditor().wait();
52+
this.dirty = true;
53+
}).future<void>()();
54+
}
55+
56+
public getProjectReferences(): IFuture<ILibRef[]> {
57+
return (() => {
58+
if(!this.projectReferences || this.dirty) {
59+
let allProjectProperties = this.getAllProjectProperties().wait();
60+
this.projectReferences = _(_.keys(allProjectProperties))
61+
.filter(key => _.startsWith(key, "android.library.reference."))
62+
.map(key => this.createLibraryReference(key, allProjectProperties[key]))
63+
.value();
64+
}
65+
66+
return this.projectReferences;
67+
}).future<ILibRef[]>()();
68+
}
69+
70+
public addProjectReference(referencePath: string): IFuture<void> {
71+
return (() => {
72+
let references = this.getProjectReferences().wait();
73+
let libRefExists = _.any(references, r => path.normalize(r.path) === path.normalize(referencePath));
74+
if(!libRefExists) {
75+
this.addToPropertyList("android.library.reference", referencePath).wait();
76+
}
77+
}).future<void>()();
78+
}
79+
80+
public removeProjectReference(referencePath: string): IFuture<void> {
81+
return (() => {
82+
let references = this.getProjectReferences().wait();
83+
let libRefExists = _.any(references, r => path.normalize(r.path) === path.normalize(referencePath));
84+
if(libRefExists) {
85+
this.removeFromPropertyList("android.library.reference", referencePath).wait();
86+
}
87+
}).future<void>()();
88+
}
89+
90+
private createEditor(): IFuture<any> {
91+
return (() => {
92+
if(!this._editor) {
93+
this._editor = this.$propertiesParser.createEditor(this.filePath).wait();
94+
}
95+
96+
return this._editor;
97+
}).future<any>()();
98+
}
99+
100+
private buildKeyName(key: string, index: number): string {
101+
return `${key}.${index}`;
102+
}
103+
104+
private getAllProjectProperties(): IFuture<IStringDictionary> {
105+
return this.$propertiesParser.read(this.filePath);
106+
}
107+
108+
private createLibraryReference(referenceName: string, referencePath: string): ILibRef {
109+
return {
110+
idx: parseInt(referenceName.split("android.library.reference.")[1]),
111+
key: referenceName,
112+
path: referencePath,
113+
adjustedPath: path.join(path.dirname(this.filePath), referencePath)
114+
}
115+
}
116+
}

lib/services/android-project-service.ts

+33-67
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import helpers = require("../common/helpers");
99
import fs = require("fs");
1010
import os = require("os");
1111

12+
import androidProjectPropertiesManagerLib = require("./android-project-properties-manager");
13+
1214
class AndroidProjectService implements IPlatformProjectService {
1315
private static MIN_SUPPORTED_VERSION = 17;
1416
private SUPPORTED_TARGETS = ["android-17", "android-18", "android-19", "android-21", "android-22"]; // forbidden for now: "android-MNC"
@@ -21,6 +23,7 @@ class AndroidProjectService implements IPlatformProjectService {
2123

2224

2325
private targetApi: string;
26+
private _androidProjectPropertiesManagers: IDictionary<IAndroidProjectPropertiesManager>;
2427

2528
constructor(private $androidEmulatorServices: Mobile.IEmulatorPlatformServices,
2629
private $childProcess: IChildProcess,
@@ -30,7 +33,9 @@ class AndroidProjectService implements IPlatformProjectService {
3033
private $projectData: IProjectData,
3134
private $propertiesParser: IPropertiesParser,
3235
private $options: IOptions,
33-
private $hostInfo: IHostInfo) {
36+
private $hostInfo: IHostInfo,
37+
private $injector: IInjector) {
38+
this._androidProjectPropertiesManagers = Object.create(null);
3439
}
3540

3641
private _platformData: IPlatformData = null;
@@ -185,72 +190,44 @@ class AndroidProjectService implements IPlatformProjectService {
185190
return this.$fs.exists(path.join(projectRoot, "assets", constants.APP_FOLDER_NAME));
186191
}
187192

188-
private parseProjectProperties(projDir: string, destDir: string): IFuture<void> {
193+
private getProjectPropertiesManager(filePath: string): IAndroidProjectPropertiesManager {
194+
if(!this._androidProjectPropertiesManagers[filePath]) {
195+
this._androidProjectPropertiesManagers[filePath] = this.$injector.resolve(androidProjectPropertiesManagerLib.AndroidProjectPropertiesManager, { directoryPath: filePath });
196+
}
197+
198+
return this._androidProjectPropertiesManagers[filePath];
199+
}
200+
201+
private parseProjectProperties(projDir: string, destDir: string): IFuture<void> { // projDir is libraryPath, targetPath is the path to lib folder
189202
return (() => {
190203
let projProp = path.join(projDir, "project.properties");
191-
192204
if (!this.$fs.exists(projProp).wait()) {
193205
this.$logger.warn("Warning: File %s does not exist", projProp);
194206
return;
195207
}
196-
197-
let lines = this.$fs.readText(projProp, "utf-8").wait().split(os.EOL);
198-
199-
let regEx = /android\.library\.reference\.(\d+)=(.*)/;
200-
lines.forEach(elem => {
201-
let match = elem.match(regEx);
202-
if (match) {
203-
let libRef: ILibRef = { idx: parseInt(match[1]), path: match[2].trim() };
204-
libRef.adjustedPath = this.$fs.isRelativePath(libRef.path) ? path.join(projDir, libRef.path) : libRef.path;
205-
this.parseProjectProperties(libRef.adjustedPath, destDir).wait();
206-
}
208+
209+
let projectPropertiesManager = this.getProjectPropertiesManager(projDir);
210+
let references = projectPropertiesManager.getProjectReferences().wait();
211+
_.each(references, reference => {
212+
let adjustedPath = this.$fs.isRelativePath(reference.path) ? path.join(projDir, reference.path) : reference.path;
213+
this.parseProjectProperties(adjustedPath, destDir).wait();
207214
});
208215

209216
this.$logger.info("Copying %s", projDir);
210217
shell.cp("-Rf", projDir, destDir);
211218

212219
let targetDir = path.join(destDir, path.basename(projDir));
213-
// TODO: parametrize targetSdk
214-
let targetSdk = "android-17";
220+
let targetSdk = `android-${this.$options.sdk || 17}`;
215221
this.$logger.info("Generate build.xml for %s", targetDir);
216222
this.runAndroidUpdate(targetDir, targetSdk).wait();
217223
}).future<void>()();
218224
}
219225

220-
private getProjectReferences(projDir: string): ILibRef[]{
221-
let projProp = path.join(projDir, "project.properties");
222-
223-
let lines = this.$fs.readText(projProp, "utf-8").wait().split(os.EOL);
224-
225-
let refs: ILibRef[] = [];
226-
227-
let regEx = /android\.library\.reference\.(\d+)=(.*)/;
228-
lines.forEach(elem => {
229-
let match = elem.match(regEx);
230-
if (match) {
231-
let libRef: ILibRef = { idx: parseInt(match[1]), path: match[2] };
232-
libRef.adjustedPath = path.join(projDir, libRef.path);
233-
libRef.key = match[0].split("=")[0];
234-
refs.push(libRef);
235-
}
236-
});
237-
238-
return refs;
239-
}
240-
241-
private updateProjectReferences(projDir: string, libraryPath: string): void {
242-
let refs = this.getProjectReferences(projDir);
243-
let maxIdx = refs.length > 0 ? _.max(refs, r => r.idx).idx : 0;
244-
245-
let relLibDir = path.relative(projDir, libraryPath).split("\\").join("/");
246-
247-
let libRefExists = _.any(refs, r => path.normalize(r.path) === path.normalize(relLibDir));
248-
249-
if (!libRefExists) {
250-
let projRef = util.format("%sandroid.library.reference.%d=%s", os.EOL, maxIdx + 1, relLibDir);
251-
let projProp = path.join(projDir, "project.properties");
252-
fs.appendFileSync(projProp, projRef, { encoding: "utf-8" });
253-
}
226+
private updateProjectReferences(projDir: string, libraryPath: string): IFuture<void> {
227+
let relLibDir = path.relative(projDir, libraryPath).split("\\").join("/");
228+
229+
let projectPropertiesManager = this.getProjectPropertiesManager(projDir);
230+
return projectPropertiesManager.addProjectReference(relLibDir);
254231
}
255232

256233
public addLibrary(platformData: IPlatformData, libraryPath: string): IFuture<void> {
@@ -271,7 +248,7 @@ class AndroidProjectService implements IPlatformProjectService {
271248

272249
let libProjProp = path.join(libraryPath, "project.properties");
273250
if (this.$fs.exists(libProjProp).wait()) {
274-
this.updateProjectReferences(platformData.projectRoot, targetLibPath);
251+
this.updateProjectReferences(platformData.projectRoot, targetLibPath).wait();
275252
}
276253
}).future<void>()();
277254
}
@@ -302,26 +279,15 @@ class AndroidProjectService implements IPlatformProjectService {
302279

303280
public removePluginNativeCode(pluginData: IPluginData): IFuture<void> {
304281
return (() => {
305-
let projectReferences = this.getProjectReferences(this.platformData.projectRoot);
306-
let androidLibraries = this.getAllAndroidLibrariesForPlugin(pluginData).wait();
307-
308-
let file = path.join(this.platformData.projectRoot, "project.properties");
309-
let editor = this.$propertiesParser.createEditor(file).wait();
282+
let projectPropertiesManager = this.getProjectPropertiesManager(this.platformData.projectRoot);
310283

284+
let androidLibraries = this.getAllAndroidLibrariesForPlugin(pluginData).wait();
311285
_.each(androidLibraries, androidLibraryName => {
312-
// Remove library from project.properties
313-
let androidLibraryNameLowerCase = androidLibraryName.toLowerCase();
314-
let projectReference = _.find(projectReferences, projectReference => _.last(projectReference.adjustedPath.split(path.sep)).toLowerCase() === androidLibraryNameLowerCase);
315-
if(projectReference && projectReference.key) {
316-
editor.unset(projectReference.key);
317-
}
318-
319-
// Remove library from lib folder
320-
this.$fs.deleteDirectory(path.join(this.$projectData.projectDir, "lib", this.platformData.normalizedPlatformName, androidLibraryName)).wait();
286+
let libPath = path.join(this.$projectData.projectDir, "lib", this.platformData.normalizedPlatformName, androidLibraryName);
287+
projectPropertiesManager.removeProjectReference(path.relative(this.platformData.projectRoot, libPath)).wait(); // TODO: Compose the reference path
288+
this.$fs.deleteDirectory(libPath).wait();
321289
});
322290

323-
this.$propertiesParser.saveEditor().wait();
324-
325291
}).future<void>()();
326292
}
327293

0 commit comments

Comments
 (0)