From 67b577deb3bbee27228ec0b559bca6ba90603dcc Mon Sep 17 00:00:00 2001 From: Phillip Green II Date: Sat, 14 May 2016 10:45:31 -0400 Subject: [PATCH] fix(barrel): alphabetized barrel exports Fixes #582 --- addon/ng2/utilities/barrel-management.js | 26 +++- tests/acceptance/barrel-management.spec.js | 169 +++++++++++++++++++++ 2 files changed, 191 insertions(+), 4 deletions(-) create mode 100644 tests/acceptance/barrel-management.spec.js diff --git a/addon/ng2/utilities/barrel-management.js b/addon/ng2/utilities/barrel-management.js index 0226517aa909..41c9031b4d67 100644 --- a/addon/ng2/utilities/barrel-management.js +++ b/addon/ng2/utilities/barrel-management.js @@ -1,25 +1,43 @@ var path = require('path'); +var fs = require('fs'); var EOL = require('os').EOL; module.exports = addBarrelRegistration; +function sortBarrel(contents) { + var parts = contents.split(EOL).filter(function(l){ + return l.trim().length > 0; + }); + parts.sort(); + return parts.join(EOL) + EOL; +} + function addBarrelRegistration(blueprint, installationDir, fileName) { var parts = installationDir.split(path.sep); - + var idx = parts.lastIndexOf('shared'); if (idx < parts.length -2) { return Promise.resolve(); } - + var sharedDir = parts.slice(0, idx + 1).join(path.sep); var relativeParts = parts.splice(idx + 1); if (fileName) { relativeParts.push(fileName); } var importFrom = './' + relativeParts.join('/'); - + return blueprint.insertIntoFile( sharedDir + path.sep + 'index.ts', `export * from '${importFrom}';${EOL}` - ); + ).then(function(r){ + var contents = fs.readFileSync(r.path, 'utf8'); + + contents = sortBarrel(contents); + + fs.writeFileSync(r.path, contents, 'utf8'); + + r.contents = contents; + return r; + }); } diff --git a/tests/acceptance/barrel-management.spec.js b/tests/acceptance/barrel-management.spec.js new file mode 100644 index 000000000000..4613c1466a67 --- /dev/null +++ b/tests/acceptance/barrel-management.spec.js @@ -0,0 +1,169 @@ +'use strict'; + +var expect = require('chai').expect; +var path = require('path'); +var addBarrelRegistration = require('../../addon/ng2/utilities/barrel-management'); +var mockFs = require('mock-fs'); +var existsSync = require('exists-sync'); +var EOL = require('os').EOL; + +var Blueprint = require('ember-cli/lib/models/blueprint'); + +describe('barrel-management', () => { + var blueprint; + var installationDirectory; + + beforeEach(() => { + blueprint = new Blueprint('/'); + blueprint.project = { + root: '/' + } + }); + + describe('when not shared', () => { + + + beforeEach(() => { + var mockDrive = { + '/src/app/my-component': {} + }; + mockFs(mockDrive); + + installationDirectory = path.join('src', 'app', 'my-component'); + }); + + afterEach(() => { + mockFs.restore(); + }); + + it('should do nothing', () => { + return addBarrelRegistration(blueprint, installationDirectory).then(() => { + var barrelPath = path.join(installationDirectory, 'index.ts'); + expect(existsSync(barrelPath)).to.equal(false); + }); + }); + }); + + describe('no pre-existing barrel', () => { + + beforeEach(() => { + var mockDrive = { + '/src/app/shared/my-component': {} + }; + mockFs(mockDrive); + + installationDirectory = path.join('/src/app/shared/my-component'); + }); + + afterEach(() => { + mockFs.restore(); + }); + + it('create barrel from installation dir', () => { + return addBarrelRegistration(blueprint, installationDirectory).then(() => { + var fs = require('fs'); + var barrelPath = path.join(installationDirectory, '..', 'index.ts'); + expect(existsSync(barrelPath)).to.equal(true); + var contents = fs.readFileSync(barrelPath, 'utf8'); + var expectedContents = `export * from './my-component';${EOL}`; + expect(contents).to.equal(expectedContents); + }); + }); + + it('create barrel from installation dir with file name', () => { + return addBarrelRegistration(blueprint, installationDirectory, 'my-smaller-component').then(() => { + var fs = require('fs'); + var barrelPath = path.join(installationDirectory, '..', 'index.ts'); + expect(existsSync(barrelPath)).to.equal(true); + var contents = fs.readFileSync(barrelPath, 'utf8'); + var expectedContents = `export * from './my-component/my-smaller-component';${EOL}`; + expect(contents).to.equal(expectedContents); + }); + }); + + }); + + describe('pre-existing barrel', () => { + + beforeEach(() => { + var mockDrive = { + '/src/app/shared': { + 'my-component': {}, + 'index.ts': `export * from './another-component${EOL}export * from './other-component${EOL}` + } + }; + mockFs(mockDrive); + + installationDirectory = path.join('/src/app/shared/my-component'); + }); + + afterEach(() => { + mockFs.restore(); + }); + + it('update barrel from installation dir', () => { + return addBarrelRegistration(blueprint, installationDirectory).then(() => { + var fs = require('fs'); + var barrelPath = path.join(installationDirectory, '..', 'index.ts'); + expect(existsSync(barrelPath)).to.equal(true); + var contents = fs.readFileSync(barrelPath, 'utf8'); + var expectedContents = `export * from './another-component${EOL}export * from './my-component';${EOL}export * from './other-component${EOL}`; + expect(contents).to.equal(expectedContents); + }); + }); + + it('updateA barrel from installation dir with file name', () => { + return addBarrelRegistration(blueprint, installationDirectory, 'my-smaller-component').then(() => { + var fs = require('fs'); + var barrelPath = path.join(installationDirectory, '..', 'index.ts'); + expect(existsSync(barrelPath)).to.equal(true); + var contents = fs.readFileSync(barrelPath, 'utf8'); + var expectedContents = `export * from './another-component${EOL}export * from './my-component/my-smaller-component';${EOL}export * from './other-component${EOL}`; + expect(contents).to.equal(expectedContents); + }); + }); + + }); + + describe('pre-existing barrel with export already defined', () => { + + beforeEach(() => { + var mockDrive = { + '/src/app/shared': { + 'my-component': {}, + 'index.ts': `export * from './other-component${EOL}export * from './my-component';${EOL}export * from './another-component${EOL}export * from './my-component/my-smaller-component';${EOL}` + } + }; + mockFs(mockDrive); + + installationDirectory = path.join('/src/app/shared/my-component'); + }); + + afterEach(() => { + mockFs.restore(); + }); + + it('update barrel from installation dir should add nothing', () => { + return addBarrelRegistration(blueprint, installationDirectory).then(() => { + var fs = require('fs'); + var barrelPath = path.join(installationDirectory, '..', 'index.ts'); + expect(existsSync(barrelPath)).to.equal(true); + var contents = fs.readFileSync(barrelPath, 'utf8'); + var expectedContents = `export * from './another-component${EOL}export * from './my-component';${EOL}export * from './my-component/my-smaller-component';${EOL}export * from './other-component${EOL}`; + expect(contents).to.equal(expectedContents); + }); + }); + + it('update barrel from installation dir with file name should add nothing', () => { + return addBarrelRegistration(blueprint, installationDirectory, 'my-smaller-component').then(() => { + var fs = require('fs'); + var barrelPath = path.join(installationDirectory, '..', 'index.ts'); + expect(existsSync(barrelPath)).to.equal(true); + var contents = fs.readFileSync(barrelPath, 'utf8'); + var expectedContents = `export * from './another-component${EOL}export * from './my-component';${EOL}export * from './my-component/my-smaller-component';${EOL}export * from './other-component${EOL}`; + expect(contents).to.equal(expectedContents); + }); + }); + + }); +});