diff --git a/addon/ng2/utilities/dynamic-path-parser.js b/addon/ng2/utilities/dynamic-path-parser.js index 13f5d2156ab5..6528c6491426 100644 --- a/addon/ng2/utilities/dynamic-path-parser.js +++ b/addon/ng2/utilities/dynamic-path-parser.js @@ -1,5 +1,6 @@ var path = require('path'); var process = require('process'); +var fs = require('fs'); module.exports = function dynamicPathParser(project, entityName) { var projectRoot = project.root; @@ -30,6 +31,27 @@ module.exports = function dynamicPathParser(project, entityName) { } } + if (!fs.existsSync(outputPath)) { + // Verify the path exists on disk. + var parsedOutputPath = path.parse(outputPath); + var parts = parsedOutputPath.dir.split(path.sep).slice(1); + var newPath = parts.reduce((tempPath, part) => { + // if (tempPath === '') { + // return part; + // } + var withoutPlus = path.join(tempPath, path.sep, part); + var withPlus = path.join(tempPath, path.sep, '+' + part); + if (fs.existsSync(withoutPlus)) { + return withoutPlus; + } else if (fs.existsSync(withPlus)) { + return withPlus; + } + + throw `Invalid path: "${withoutPlus}"" is not a valid path.` + }, parsedOutputPath.root); + outputPath = path.join(newPath, parsedOutputPath.name); + } + if (outputPath.indexOf(rootPath) < 0) { throw `Invalid path: "${entityName}" cannot be ` + `above the "${appRoot}" directory`; diff --git a/package.json b/package.json index f6a9e70c360f..eec95733ef87 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "exists-sync": "0.0.3", "minimatch": "^3.0.0", "mocha": "^2.4.5", + "mock-fs": "^3.8.0", "object-assign": "^4.0.1", "rewire": "^2.5.1", "sinon": "^1.17.3", diff --git a/tests/acceptance/dynamic-path-parser.spec.js b/tests/acceptance/dynamic-path-parser.spec.js index 76a4b418aa0d..9c2f257bfabe 100644 --- a/tests/acceptance/dynamic-path-parser.spec.js +++ b/tests/acceptance/dynamic-path-parser.spec.js @@ -3,53 +3,98 @@ var expect = require('chai').expect; var path = require('path'); var dynamicPathParser = require('../../addon/ng2/utilities/dynamic-path-parser'); +var mockFs = require('mock-fs'); var appDir = `src${path.sep}client${path.sep}app`; describe('dynamic path parser', () => { var project; var entityName = 'temp-name'; + var rootName = path.parse(process.cwd()).root + 'project'; beforeEach(() => { - project = { root: process.cwd() } + project = { root: rootName }; + var mockFolder = {}; + mockFolder[rootName] = { + src: { + client: { + app: { + 'index.html': '', + 'temp-name': {} + } + } + } + }; + mockFs(mockFolder); + }); + + afterEach(() => { + mockFs.restore(); }); it('parse from proj root dir', () => { - process.env.PWD = process.cwd(); + process.env.PWD = project.root; var result = dynamicPathParser(project, entityName); expect(result.dir).to.equal(appDir); expect(result.name).to.equal(entityName); }); it('parse from proj src dir', () => { - process.env.PWD = path.join(process.cwd(), 'src'); + process.env.PWD = path.join(project.root, 'src'); var result = dynamicPathParser(project, entityName); expect(result.dir).to.equal(appDir); expect(result.name).to.equal(entityName); }); it(`parse from proj src${path.sep}client dir`, () => { - process.env.PWD = path.join(process.cwd(), 'src', 'client'); + process.env.PWD = path.join(project.root, 'src', 'client'); var result = dynamicPathParser(project, entityName); expect(result.dir).to.equal(appDir); expect(result.name).to.equal(entityName); }); it(`parse from proj src${path.sep}client${path.sep}app dir`, () => { - process.env.PWD = path.join(process.cwd(), 'src', 'client', 'app'); + process.env.PWD = path.join(project.root, 'src', 'client', 'app'); var result = dynamicPathParser(project, entityName); expect(result.dir).to.equal(appDir); expect(result.name).to.equal(entityName); }); it(`parse from proj src${path.sep}client${path.sep}app${path.sep}child-dir`, () => { - process.env.PWD = path.join(process.cwd(), 'src', 'client', 'app', 'child-dir'); + var mockFolder = {}; + mockFolder[rootName] = { + src: { + client: { + app: { + 'index.html': '', + 'child-dir': { + 'temp-name': {} + } + } + } + } + }; + mockFs(mockFolder); + process.env.PWD = path.join(project.root, 'src', 'client', 'app', 'child-dir'); var result = dynamicPathParser(project, entityName); expect(result.dir).to.equal(`${appDir}${path.sep}child-dir`); expect(result.name).to.equal(entityName); }); it(`parse from proj src${path.sep}client${path.sep}app${path.sep}child-dir w/ ..${path.sep}`, () => { - process.env.PWD = path.join(process.cwd(), 'src', 'client', 'app', 'child-dir'); + var mockFolder = {}; + mockFolder[rootName] = { + src: { + client: { + app: { + 'index.html': '', + 'child-dir': {}, + 'temp-name': {} + } + } + } + }; + mockFs(mockFolder); + process.env.PWD = path.join(project.root, 'src', 'client', 'app', 'child-dir'); var result = dynamicPathParser(project, '..' + path.sep + entityName); expect(result.dir).to.equal(appDir); expect(result.name).to.equal(entityName); @@ -57,9 +102,42 @@ describe('dynamic path parser', () => { it(`parse from proj src${path.sep}client${path.sep}app${path.sep}child-dir${path.sep}grand-child-dir w/ ..${path.sep}`, () => { - process.env.PWD = path.join(process.cwd(), 'src', 'client', 'app', 'child-dir', 'grand-child-dir'); + var mockFolder = {}; + mockFolder[rootName] = { + src: { + client: { + app: { + 'index.html': '', + 'child-dir': { + 'grand-child-dir': {}, + 'temp-name': {} + } + } + } + } + }; + mockFs(mockFolder); + process.env.PWD = path.join(project.root, 'src', 'client', 'app', 'child-dir', 'grand-child-dir'); var result = dynamicPathParser(project, '..' + path.sep + entityName); expect(result.dir).to.equal(`${appDir}${path.sep}child-dir`); expect(result.name).to.equal(entityName); }); + + it('auto look for dirs with a "+" when not specified', () => { + var mockFolder = {}; + mockFolder[rootName] = { + src: { + client: { + app: { + '+my-route': {} + } + } + } + }; + mockFs(mockFolder); + process.env.PWD = path.join(project.root, 'src', 'client', 'app', 'my-route'); + var result = dynamicPathParser(project, entityName); + expect(result.dir).to.equal(`${appDir}${path.sep}+my-route`); + expect(result.name).to.equal(entityName); + }); }); diff --git a/tests/acceptance/generate-component.spec.js b/tests/acceptance/generate-component.spec.js index 896c4c12c713..d6217bc3a5e6 100644 --- a/tests/acceptance/generate-component.spec.js +++ b/tests/acceptance/generate-component.spec.js @@ -38,6 +38,7 @@ describe('Acceptance: ng generate component', function () { }); it('ng generate component test' + path.sep + 'my-comp', function () { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', 'test')); return ng(['generate', 'component', 'test' + path.sep + 'my-comp']).then(() => { var testPath = path.join(root, 'tmp', 'foo', 'src', 'client', 'app', 'test', 'my-comp', 'my-comp.component.ts'); expect(existsSync(testPath)).to.equal(true); @@ -53,13 +54,13 @@ describe('Acceptance: ng generate component', function () { }); it('ng generate component my-comp from a child dir', () => { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', '1')); return new Promise(function (resolve) { process.chdir('./src'); resolve(); }) .then(() => process.chdir('./client')) .then(() => process.chdir('./app')) - .then(() => fs.mkdirsSync('./1')) .then(() => process.chdir('./1')) .then(() => { return ng(['generate', 'component', 'my-comp']) @@ -71,13 +72,13 @@ describe('Acceptance: ng generate component', function () { }); it('ng generate component child-dir' + path.sep + 'my-comp from a child dir', () => { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', '1', 'child-dir')); return new Promise(function (resolve) { process.chdir('./src'); resolve(); }) .then(() => process.chdir('./client')) .then(() => process.chdir('./app')) - .then(() => fs.mkdirsSync('./1')) .then(() => process.chdir('./1')) .then(() => { return ng(['generate', 'component', 'child-dir' + path.sep + 'my-comp']) @@ -91,13 +92,13 @@ describe('Acceptance: ng generate component', function () { it('ng generate component child-dir' + path.sep + '..' + path.sep + 'my-comp from a child dir', () => { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', '1')); return new Promise(function (resolve) { process.chdir('./src'); resolve(); }) .then(() => process.chdir('./client')) .then(() => process.chdir('./app')) - .then(() => fs.mkdirsSync('./1')) .then(() => process.chdir('./1')) .then(() => { return ng([ @@ -114,13 +115,13 @@ describe('Acceptance: ng generate component', function () { it('ng generate component ' + path.sep + 'my-comp from a child dir, gens under ' + path.join('src', 'client', 'app'), () => { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', '1')); return new Promise(function (resolve) { process.chdir('./src'); resolve(); }) .then(() => process.chdir('./client')) .then(() => process.chdir('./app')) - .then(() => fs.mkdirsSync('./1')) .then(() => process.chdir('./1')) .then(() => { return ng(['generate', 'component', path.sep + 'my-comp']) diff --git a/tests/acceptance/generate-directive.spec.js b/tests/acceptance/generate-directive.spec.js index dc345e496618..1ff24f6f2e62 100644 --- a/tests/acceptance/generate-directive.spec.js +++ b/tests/acceptance/generate-directive.spec.js @@ -45,6 +45,7 @@ describe('Acceptance: ng generate directive', function () { }); it('ng generate directive test' + path.sep + 'my-dir', function () { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', 'test')); return ng(['generate', 'directive', 'test' + path.sep + 'my-dir', '--flat', 'false']).then(() => { var testPath = path.join(root, 'tmp', 'foo', 'src', 'client', 'app', 'test', 'my-dir', 'my-dir.directive.ts'); expect(existsSync(testPath)).to.equal(true); @@ -60,13 +61,13 @@ describe('Acceptance: ng generate directive', function () { }); it('ng generate directive my-dir from a child dir', () => { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', '1')); return new Promise(function (resolve) { process.chdir('./src'); resolve(); }) .then(() => process.chdir('./client')) .then(() => process.chdir('./app')) - .then(() => fs.mkdirsSync('./1')) .then(() => process.chdir('./1')) .then(() => { process.env.CWD = process.cwd(); @@ -79,13 +80,13 @@ describe('Acceptance: ng generate directive', function () { }); it('ng generate directive child-dir' + path.sep + 'my-dir from a child dir', () => { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', '1', 'child-dir')); return new Promise(function (resolve) { process.chdir('./src'); resolve(); }) .then(() => process.chdir('./client')) .then(() => process.chdir('./app')) - .then(() => fs.mkdirsSync('./1')) .then(() => process.chdir('./1')) .then(() => { process.env.CWD = process.cwd(); @@ -100,13 +101,13 @@ describe('Acceptance: ng generate directive', function () { it('ng generate directive child-dir' + path.sep + '..' + path.sep + 'my-dir from a child dir', () => { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', '1')); return new Promise(function (resolve) { process.chdir('./src'); resolve(); }) .then(() => process.chdir('./client')) .then(() => process.chdir('./app')) - .then(() => fs.mkdirsSync('./1')) .then(() => process.chdir('./1')) .then(() => { process.env.CWD = process.cwd(); @@ -123,13 +124,13 @@ describe('Acceptance: ng generate directive', function () { it('ng generate directive ' + path.sep + 'my-dir from a child dir, gens under ' + path.join('src', 'client', 'app'), () => { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', '1')); return new Promise(function (resolve) { process.chdir('./src'); resolve(); }) .then(() => process.chdir('./client')) .then(() => process.chdir('./app')) - .then(() => fs.mkdirsSync('./1')) .then(() => process.chdir('./1')) .then(() => { process.env.CWD = process.cwd(); diff --git a/tests/acceptance/generate-pipe.spec.js b/tests/acceptance/generate-pipe.spec.js index e8ea02562224..2809881e23c0 100644 --- a/tests/acceptance/generate-pipe.spec.js +++ b/tests/acceptance/generate-pipe.spec.js @@ -38,6 +38,7 @@ describe('Acceptance: ng generate pipe', function () { }); it('ng generate pipe test' + path.sep + 'my-pipe', function () { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', 'test')); return ng(['generate', 'pipe', 'test' + path.sep + 'my-pipe']).then(() => { var testPath = path.join(root, 'tmp', 'foo', 'src', 'client', 'app', 'test', 'my-pipe.pipe.ts'); expect(existsSync(testPath)).to.equal(true); @@ -52,13 +53,13 @@ describe('Acceptance: ng generate pipe', function () { }); it('ng generate pipe my-pipe from a child dir', () => { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', '1')); return new Promise(function (resolve) { process.chdir('./src'); resolve(); }) .then(() => process.chdir('./client')) .then(() => process.chdir('./app')) - .then(() => fs.mkdirsSync('./1')) .then(() => process.chdir('./1')) .then(() => { process.env.CWD = process.cwd(); @@ -71,13 +72,13 @@ describe('Acceptance: ng generate pipe', function () { }); it('ng generate pipe child-dir' + path.sep + 'my-pipe from a child dir', () => { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', '1', 'child-dir')); return new Promise(function (resolve) { process.chdir('./src'); resolve(); }) .then(() => process.chdir('./client')) .then(() => process.chdir('./app')) - .then(() => fs.mkdirsSync('./1')) .then(() => process.chdir('./1')) .then(() => { process.env.CWD = process.cwd(); @@ -91,13 +92,13 @@ describe('Acceptance: ng generate pipe', function () { }); it('ng generate pipe child-dir' + path.sep + '..' + path.sep + 'my-pipe from a child dir', () => { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', '1')); return new Promise(function (resolve) { process.chdir('./src'); resolve(); }) .then(() => process.chdir('./client')) .then(() => process.chdir('./app')) - .then(() => fs.mkdirsSync('./1')) .then(() => process.chdir('./1')) .then(() => { process.env.CWD = process.cwd(); @@ -112,13 +113,13 @@ describe('Acceptance: ng generate pipe', function () { it('ng generate pipe ' + path.sep + 'my-pipe from a child dir, gens under ' + path.join('src', 'client', 'app'), () => { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', '1')); return new Promise(function (resolve) { process.chdir('./src'); resolve(); }) .then(() => process.chdir('./client')) .then(() => process.chdir('./app')) - .then(() => fs.mkdirsSync('./1')) .then(() => process.chdir('./1')) .then(() => { process.env.CWD = process.cwd(); diff --git a/tests/acceptance/generate-service.spec.js b/tests/acceptance/generate-service.spec.js index 54fe5466cd23..e2bc9fc102ec 100644 --- a/tests/acceptance/generate-service.spec.js +++ b/tests/acceptance/generate-service.spec.js @@ -38,6 +38,7 @@ describe('Acceptance: ng generate service', function () { }); it('ng generate service test' + path.sep + 'my-svc', function () { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', 'test')); return ng(['generate', 'service', 'test' + path.sep + 'my-svc']).then(() => { var testPath = path.join(root, 'tmp', 'foo', 'src', 'client', 'app', 'test', 'my-svc.service.ts'); expect(existsSync(testPath)).to.equal(true); @@ -52,13 +53,13 @@ describe('Acceptance: ng generate service', function () { }); it('ng generate service my-svc from a child dir', () => { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', '1')); return new Promise(function (resolve) { process.chdir('./src'); resolve(); }) .then(() => process.chdir('./client')) .then(() => process.chdir('./app')) - .then(() => fs.mkdirsSync('./1')) .then(() => process.chdir('./1')) .then(() => { process.env.CWD = process.cwd(); @@ -71,13 +72,13 @@ describe('Acceptance: ng generate service', function () { }); it('ng generate service child-dir' + path.sep + 'my-svc from a child dir', () => { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', '1', 'child-dir')); return new Promise(function (resolve) { process.chdir('./src'); resolve(); }) .then(() => process.chdir('./client')) .then(() => process.chdir('./app')) - .then(() => fs.mkdirsSync('./1')) .then(() => process.chdir('./1')) .then(() => { process.env.CWD = process.cwd(); @@ -92,13 +93,13 @@ describe('Acceptance: ng generate service', function () { it('ng generate service child-dir' + path.sep + '..' + path.sep + 'my-svc from a child dir', () => { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', '1')); return new Promise(function (resolve) { process.chdir('./src'); resolve(); }) .then(() => process.chdir('./client')) .then(() => process.chdir('./app')) - .then(() => fs.mkdirsSync('./1')) .then(() => process.chdir('./1')) .then(() => { process.env.CWD = process.cwd(); @@ -115,13 +116,13 @@ describe('Acceptance: ng generate service', function () { it('ng generate service ' + path.sep + 'my-svc from a child dir, gens under ' + path.join('src', 'client', 'app'), () => { + fs.mkdirsSync(path.join(root, 'tmp', 'foo', 'src', 'client', 'app', '1')); return new Promise(function (resolve) { process.chdir('./src'); resolve(); }) .then(() => process.chdir('./client')) .then(() => process.chdir('./app')) - .then(() => fs.mkdirsSync('./1')) .then(() => process.chdir('./1')) .then(() => { process.env.CWD = process.cwd();