Skip to content

fix: Plugin remove command fails in case plugin name has dot #3459

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 1 commit into from
Mar 15, 2018
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,8 @@ export const enum BuildStates {
}

export const NATIVESCRIPT_CLOUD_EXTENSION_NAME = "nativescript-cloud";

/**
* Used in ProjectDataService to concatenate the names of the properties inside nativescript key of package.json.
*/
export const NATIVESCRIPT_PROPS_INTERNAL_DELIMITER = "**|__**";
9 changes: 5 additions & 4 deletions lib/services/project-data-service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as path from "path";
import { ProjectData } from "../project-data";
import { exported } from "../common/decorators";
import { NATIVESCRIPT_PROPS_INTERNAL_DELIMITER } from "../constants";

interface IProjectFileData {
projectData: any;
Expand Down Expand Up @@ -65,11 +66,11 @@ export class ProjectDataService implements IProjectDataService {
}

private getNativeScriptPropertyName(propertyName: string) {
return `${this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE}.${propertyName}`;
return `${this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE}${NATIVESCRIPT_PROPS_INTERNAL_DELIMITER}${propertyName}`;
}

private getPropertyValueFromJson(jsonData: any, dottedPropertyName: string): any {
const props = dottedPropertyName.split(".");
const props = dottedPropertyName.split(NATIVESCRIPT_PROPS_INTERNAL_DELIMITER);
let result = jsonData[props.shift()];

for (const prop of props) {
Expand All @@ -82,7 +83,7 @@ export class ProjectDataService implements IProjectDataService {
private setValue(projectDir: string, key: string, value: any): void {
const projectFileInfo = this.getProjectFileData(projectDir);

const props = key.split(".");
const props = key.split(NATIVESCRIPT_PROPS_INTERNAL_DELIMITER);
const data: any = projectFileInfo.projectData;
let currentData = data;

Expand All @@ -103,7 +104,7 @@ export class ProjectDataService implements IProjectDataService {
const projectFileInfo = this.getProjectFileData(projectDir);
const data: any = projectFileInfo.projectData;
let currentData = data;
const props = propertyName.split(".");
const props = propertyName.split(NATIVESCRIPT_PROPS_INTERNAL_DELIMITER);
const propertyToDelete = props.splice(props.length - 1, 1)[0];

_.each(props, (prop) => {
Expand Down
66 changes: 36 additions & 30 deletions test/services/project-data-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,40 @@ import { Yok } from "../../lib/common/yok";
import { assert } from "chai";
import { ProjectDataService } from "../../lib/services/project-data-service";
import { LoggerStub } from "../stubs";
import { NATIVESCRIPT_PROPS_INTERNAL_DELIMITER } from '../../lib/constants';

const CLIENT_NAME_KEY_IN_PROJECT_FILE = "nativescript";

const testData: any = [{
"propertyValue": 1,
"propertyName": "root",
"description": "returns correct result when a single propertyName is passed and the value of it is number"
},
{
"propertyValue": "expectedData",
"propertyName": "root",
"description": "returns correct result when a single propertyName is passed and the value of it is string"
},
{
"propertyValue": "expectedData",
"propertyName": "root.prop1",
"description": "returns correct result when inner propertyName is passed and the value of it is string"
},
{
"propertyValue": 1234,
"propertyName": "root.prop1",
"description": "returns correct result when inner propertyName is passed and the value of it is number"
},
{
"propertyValue": "expectedData",
"propertyName": "root.prop1.prop2.prop3.prop4",
"description": "returns correct result when really inner propertyName is passed and the value of it is string"
}
const getPropertyName = (props: string[]): string => {
return props.join(NATIVESCRIPT_PROPS_INTERNAL_DELIMITER);
};

const testData: any = [
{
"propertyValue": 1,
"propertyName": "root",
"description": "returns correct result when a single propertyName is passed and the value of it is number"
},
{
"propertyValue": "expectedData",
"propertyName": "root",
"description": "returns correct result when a single propertyName is passed and the value of it is string"
},
{
"propertyValue": "expectedData",
"propertyName": getPropertyName(["root", "prop1"]),
"description": "returns correct result when inner propertyName is passed and the value of it is string"
},
{
"propertyValue": 1234,
"propertyName": getPropertyName(["root", "prop1"]),
"description": "returns correct result when inner propertyName is passed and the value of it is number"
},
{
"propertyValue": "expectedData",
"propertyName": getPropertyName(["root", "prop1", "prop2", "prop3", "prop4"]),
"description": "returns correct result when really inner propertyName is passed and the value of it is string"
}
];

const createTestInjector = (readTextData?: string): IInjector => {
Expand Down Expand Up @@ -60,7 +66,7 @@ const createTestInjector = (readTextData?: string): IInjector => {

describe("projectDataService", () => {
const generateJsonDataFromTestData = (currentTestData: any, skipNativeScriptKey?: boolean) => {
const props = currentTestData.propertyName.split(".");
const props = currentTestData.propertyName.split(NATIVESCRIPT_PROPS_INTERNAL_DELIMITER);
const data: any = {};
let currentData: any = skipNativeScriptKey ? data : (data[CLIENT_NAME_KEY_IN_PROJECT_FILE] = {});

Expand Down Expand Up @@ -140,7 +146,7 @@ describe("projectDataService", () => {
};

const projectDataService: IProjectDataService = testInjector.resolve("projectDataService");
projectDataService.setNSValue("projectDir", "root.id", "2");
projectDataService.setNSValue("projectDir", getPropertyName(["root", "id"]), "2");
const expectedData = _.cloneDeep(initialData);
expectedData[CLIENT_NAME_KEY_IN_PROJECT_FILE].root.id = "2";
assert.isTrue(!!dataPassedToWriteJson[CLIENT_NAME_KEY_IN_PROJECT_FILE], "Data passed to write JSON must contain nativescript key.");
Expand All @@ -154,7 +160,7 @@ describe("projectDataService", () => {
describe("removeNSProperty", () => {

const generateExpectedDataFromTestData = (currentTestData: any) => {
const props = currentTestData.propertyName.split(".");
const props = currentTestData.propertyName.split(NATIVESCRIPT_PROPS_INTERNAL_DELIMITER);
props.splice(props.length - 1, 1);

const data: any = {};
Expand Down Expand Up @@ -207,15 +213,15 @@ describe("projectDataService", () => {
};

const projectDataService: IProjectDataService = testInjector.resolve("projectDataService");
projectDataService.removeNSProperty("projectDir", "root.id");
projectDataService.removeNSProperty("projectDir", getPropertyName(["root", "id"]));
assert.deepEqual(dataPassedToWriteJson, { nativescript: { root: { constantItem: "myValue" } } });
});
});

describe("removeDependency", () => {
it("removes specified dependency from project file", () => {
const currentTestData = {
propertyName: "dependencies.myDeps",
propertyName: getPropertyName(["dependencies", "myDeps"]),
propertyValue: "1.0.0"
};

Expand Down