diff --git a/lib/tech/v2.js b/lib/tech/v2.js index 5851a9d8..670f4bff 100644 --- a/lib/tech/v2.js +++ b/lib/tech/v2.js @@ -192,7 +192,7 @@ var Q = require('q'), readAllContent: function(prefix) { var _this = this, res = {}; - + return Q .all(this.getCreateSuffixes().map(function(suffix) { return _this.readContent(_this.getPath(prefix, suffix), suffix) @@ -236,8 +236,8 @@ var Q = require('q'), * Return build result chunk. * * @protected - * @param {String} relPath Relative path to source object. - * @param {String} path Path to source object. + * @param {String} relPath Path to source object, relative to output directory. + * @param {String} path Absolute path to source object. * @param {String} suffix Suffix of source object. * @returns {String} Build result chunk. */ diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index c2a19c9c..5da32800 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -29,7 +29,7 @@ "from": "q-io@0.0.18" }, "fs-boot": { - "version": "0.0.9", + "version": "https://github.com/SevInf/fs-boot/archive/fix-sep.tar.gz", "from": "fs-boot@0.0.9" } } diff --git a/package.json b/package.json index 85f7c648..58f6aa95 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,10 @@ "chai": "~1.7.2", "coverjs": ">= 0.0.7-alpha", "jshint": "~2.1.4", - "sinon": "~1.7.3" + "sinon": "~1.7.3", + "chai-as-promised": "~3.3.1", + "require-mocked": "~0.2.1", + "mocha-as-promised": "~1.4.0" }, "scripts": { "test": "make test", diff --git a/test/bem-make.js b/test/bem-make.js index 71e690ea..c43610b5 100644 --- a/test/bem-make.js +++ b/test/bem-make.js @@ -41,19 +41,16 @@ describe('bem', function() { .done(); }); - it('creates proper artifacts', function(done) { - return BEM.util.exec( + it('creates proper artifacts', function() { + return assert.eventually.isNull( + BEM.util.exec( UTIL.format( 'find %s -type f -exec diff -q {} %s/{} \\; 2>&1', '.', PATH.relative(referencePath, buildPath)), {cwd: referencePath}, true) - .then(function(result) { - done(result && new Error(result)); - }) - .fail(done) - .done(); + ); }); it('does not rebuild anything on next build with no changes made to the files', function(done) { @@ -182,7 +179,7 @@ describe('bem', function() { it('invalidates deps when bemdecl is modified', function(done) { this.timeout(0); - return prepareProject() + prepareProject() .then(function() { BEM.api.make({root: buildPath, verbosity: 'error'}) .then(function() { diff --git a/test/mocha.opts b/test/mocha.opts index 620222f0..1ef8a3d3 100644 --- a/test/mocha.opts +++ b/test/mocha.opts @@ -1,3 +1,4 @@ --reporter spec +--require test/setup --timeout 0 --growl diff --git a/test/setup.js b/test/setup.js new file mode 100644 index 00000000..533dbdb5 --- /dev/null +++ b/test/setup.js @@ -0,0 +1,3 @@ +require('mocha-as-promised')(require('mocha')); +require('chai').use(require('chai-as-promised')); + diff --git a/test/tech.js b/test/tech.js index ac607814..d9400da2 100644 --- a/test/tech.js +++ b/test/tech.js @@ -2,8 +2,10 @@ 'use strict'; var Q = require('q'), - assert = require('chai').assert, SINON = require('sinon'), + requireMocked = require('require-mocked'), + assert = require('chai').assert, + mockFs = require('q-fs').Mock, BEM = require('..'), U = BEM.require('./util'), PATH = BEM.require('./path'), @@ -271,6 +273,328 @@ describe('tech', function() { }); }); + describe('v2', function() { + + function createTechObj(decl) { + decl = decl || {}; + decl.API_VER = 2; + var TechClass = getTechClass(decl); + return new TechClass(); + } + + describe('getCreateResults()', function() { + + var tech; + beforeEach(function() { + tech = createTechObj({ + API_VER: 2, + getCreateSuffixes: function() { + return ['js', 'css']; + }, + getCreateResult: function (path, suffix, vars) { + return Q.resolve(suffix + ' content'); + } + }); + }); + + it('should return one value for each suffix', function() { + var result = tech.getCreateResults('/tmp', {}); + + return assert.isFulfilled(Q.all([ + assert.eventually.property(result, 'css'), + assert.eventually.property(result, 'js'), + ])); + }); + + it('should return result of getCreateResult for each key', function() { + var result= tech.getCreateResults('/tmp', {}); + return assert.isFulfilled(Q.all([ + assert.eventually.propertyVal(result, 'css', 'css content'), + assert.eventually.propertyVal(result, 'js', 'js content') + ])); + }); + + }); + + describe('getBuildResult()', function () { + var tech; + beforeEach(function() { + tech = createTechObj({ + API_VER: 2, + + getBuildResultChunk: function(relPath, path, suffix) { + return 'relPath: ' + relPath + ' ' + + 'path: ' + path + ' ' + + 'suffix: ' + suffix; + } + }); + }); + + it('should return chunk for each file', function() { + var result = tech.getBuildResult([ + {absPath: '/test/1.js', suffix: 'js'}, + {absPath: '/test/2.css', suffix: 'css'} + ], 'out.js', '/test/result/out.js'); + + + return assert.eventually.deepEqual(result, [ + 'relPath: ../1.js path: /test/1.js suffix: js', + 'relPath: ../2.css path: /test/2.css suffix: css' + ]); + }); + }); + + function createMockedTech(fs) { + var path = (process.env.COVER? '../lib-cov/' : '../lib/') + 'tech/index.js'; + + var MOCKTECH = requireMocked(require.resolve(path), { + mocks: { + 'q-fs': mockFs(fs) + } + }); + + + var TechClass = MOCKTECH.getTechClass({API_VER: 2}); + var tech = new TechClass('techName', '/some/path'); + tech.setContext({opts:{}}); + return tech; + } + + describe('validate()', function() { + + it('should return false when meta file does not exists', function() { + var tech = createMockedTech({ + 'dest': '' + }); + + return assert.eventually.isFalse(tech.validate('dest', [ + {absPath: 'source', lastUpdated: 1374796800000} + ], {})); + }); + + it('should return false when amount of source files in cache different from current', function() { + var tech = createMockedTech({ + '.bem': { + 'cache': { + 'dest~techName.meta.js': JSON.stringify({ + buildFiles: [ + {absPath: 'source1', lastUpdated: 1374796800000}, + {absPath: 'source2', lastUpdated: 1374796800000} + ] + }) + } + }, + 'dest': '' + }); + + return assert.eventually.isFalse(tech.validate('dest', [ + {absPath: 'source1', lastUpdated: 1374796800000} + ], {})); + }); + + it('should return false when source file changed names', function() { + var tech = createMockedTech({ + '.bem': { + 'cache': { + 'dest~techName.meta.js': JSON.stringify({ + buildFiles: [ + {absPath: 'oldSource', lastUpdated: 1374710400000} + ] + }) + } + }, + 'dest': '' + }); + + return assert.eventually.isFalse(tech.validate('dest', [ + {absPath: 'newSource', lastUpdated: 1374710400000} + ], {})); + }); + + it('should return false when source file has been updated', function() { + var tech = createMockedTech({ + '.bem': { + 'cache': { + 'dest~techName.meta.js': JSON.stringify({ + buildFiles: [ + {absPath: 'source', lastUpdated: 1374710400000} + ] + }) + } + }, + 'dest': '' + }); + + return assert.eventually.isFalse(tech.validate('dest', [ + {absPath: 'source', lastUpdated: 1374796800000} + ], {})); + }); + + it('should return false when destination file does not exists', function() { + var tech = createMockedTech({ + '.bem': { + 'cache': { + 'dest~techName.meta.js': JSON.stringify({ + buildFiles: [ + {absPath: 'source', lastUpdated: 1374710400000} + ] + }) + } + } + }); + + return assert.eventually.isFalse(tech.validate('dest', [ + {absPath: 'source', lastUpdated: 1374710400000} + ], {})); + + }); + + it('should return true when all previous conditions met', function() { + var tech = createMockedTech({ + '.bem': { + 'cache': { + 'dest~techName.meta.js': JSON.stringify({ + buildFiles: [ + {absPath: 'source', lastUpdated: 1374710400000} + ] + }) + } + }, + 'dest': '' + }); + + + return assert.eventually.isTrue(tech.validate('dest', [ + {absPath: 'source', lastUpdated: 1374710400000} + ], {})); + }); + + it('should return false when opts.force is set', function() { + var tech = createMockedTech({ + '.bem': { + 'cache': { + 'dest~techName.meta.js': JSON.stringify({ + buildFiles: [ + {absPath: 'source', lastUpdated: 1374710400000} + ] + }) + } + }, + 'dest': '' + }); + + return assert.eventually.isFalse(tech.validate('dest', [ + {absPath: 'source', lastUpdated: 1374710400000} + ], {force: true})); + }); + }); + + + + describe('getSuffixes()', function () { + + it('should return each source suffix from build suffixes map', function () { + var tech = createTechObj({ + getBuildSuffixesMap: function () { + return { + 'js': ['js', 'coffee'], + 'css': ['styl', 'scss'] + }; + } + }); + + //TODO: Update chai and repalce with sameMembers + assert.deepEqual(tech.getSuffixes(), ['js', 'coffee', 'styl', 'scss']); + }); + + it('should have no duplicates', function (){ + var tech = createTechObj({ + getBuildSuffixesMap: function () { + return { + 'js': ['js', 'css'], + 'css': ['js', 'css'] + }; + } + }); + assert.deepEqual(tech.getSuffixes(), ['js', 'css']); + }); + }); + + describe.skip('matchSuffix()', function () { + }); + + describe('getPath()', function () { + + it('should return prefix and suffix concatenated', function() { + var tech = createTechObj({}); + assert.equal(tech.getPath('/test/example', 'js'), '/test/example.js'); + }); + + it('should use techName when suffix is not passed', function () { + var tech = createTechObj({ + getTechName: function() { + return 'test'; + } + }); + + assert.equal(tech.getPath('/test/example'), '/test/example.test'); + }); + }); + + describe('getPaths()', function () { + it('should return path for single suffix and prefix', function() { + var tech = createTechObj(); + assert.deepEqual(tech.getPaths('/test/example', 'js'), ['/test/example.js']); + }); + + it('should return all possible pathes for arrays of suffixes and prefixes', function () { + var paths = createTechObj().getPaths(['/test/example1', '/test/example2'], + ['js', 'css']); + + //TODO: replace with sameMembers + assert.include(paths, '/test/example1.js'); + assert.include(paths, '/test/example2.js'); + assert.include(paths, '/test/example1.css'); + assert.include(paths, '/test/example2.css'); + + }); + + it('should use getSuffixes() if suffixes has not been passed', function () { + var paths = createTechObj({ + getSuffixes: function () { + return ['html', 'less']; + } + }) + .getPaths(['/test/example1', '/test/example2']); + + assert.include(paths, '/test/example1.html'); + assert.include(paths, '/test/example2.html'); + assert.include(paths, '/test/example1.less'); + assert.include(paths, '/test/example2.less'); + }); + }); + + describe('getTechName()', function () { + var tech; + beforeEach(function () { + tech = createTechObj(); + }); + + it('should return techName if its set', function () { + tech.techName = 'SomeTech'; + + assert.equal(tech.getTechName(), 'SomeTech'); + }); + + it('should return file name if techName is not set', function () { + tech.techPath = '/test/someFile.js'; + + assert.equal(tech.getTechName(), 'someFile'); + }); + }); + + }); + }); function testBaseTech(techPath, techAlias) {