Skip to content

Commit

Permalink
Merge 46bfce6 into a281f1e
Browse files Browse the repository at this point in the history
  • Loading branch information
Vladimir Varankin committed Apr 1, 2014
2 parents a281f1e + 46bfce6 commit ebd18ed
Show file tree
Hide file tree
Showing 10 changed files with 249 additions and 18 deletions.
27 changes: 27 additions & 0 deletions .bem/borschik/istanbul.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
var path = require('path'),
environ = require('bem-environ'),
instrumenter = new (require('istanbul').Instrumenter)({ preserveComments : true }),
PRJ_ROOT = environ.PRJ_ROOT,
EXCLUDE_RE = new RegExp([
'(?:^' + environ.LIB_ROOT + ')',
'(?:\/node_modules\/)',
'(?:\.spec\.js$)'
].join('|'));

module.exports = function(borschik) {
var base = borschik.getTech('js'),
File = base.File.inherit({
processInclude : function(basePath, content) {
var filePath = this.path;
return EXCLUDE_RE.test(filePath)?
this.__base.apply(this, arguments) :
instrumenter.instrumentSync(this.__base(basePath), path.relative(PRJ_ROOT, filePath));
}
}),
Tech = base.Tech.inherit({ File : File });

return {
File : File,
Tech : Tech
};
};
30 changes: 30 additions & 0 deletions .bem/hooks/mocha-phantomjs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* An "after run" hook for [mocha-phantomjs](https://github.com/metaskills/mocha-phantomjs)
* to store instrumented code coverage results to temporary buffer,
* so they could be consumed into Istanbul#Collector for future manipulations.
* @example
* $ mocha-phantomjs \
* --hooks <path/to/hook/file.js> \
* --setting coverage-file=<path/to/coverage/buffer.json>
*/
var fs = require('fs'),
sys = require('system'),
args = sys.args;

module.exports = {
afterEnd : function(reporter) {
var covData = reporter.page.evaluate(function() {
return window.__coverage__;
});

if(!covData || args.length < 3) return;

args = JSON.parse(args[3]);

var covBufferPath = args.settings['coverage-file'];
if(!covBufferPath) return;

fs.write(covBufferPath, JSON.stringify(covData), 'w');
}
};
3 changes: 2 additions & 1 deletion .bem/levels/blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ exports.getTechs = function() {
'vanilla.js',
'browser.js',
'node.js',
'browser.js+bemhtml'
'browser.js+bemhtml',
'phantomjs'
].forEach(resolveTechs(techs, PRJ_TECHS));

return techs;
Expand Down
2 changes: 1 addition & 1 deletion .bem/levels/bundles.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ exports.baseLevelPath = require.resolve('./blocks');
exports.getTechs = function() {
var techs = this.__base();

['phantomjs', 'spec.bemjson.js'].forEach(
['spec.bemjson.js'].forEach(
this.resolveTechs(techs, BEMPR_TECHS));

return techs;
Expand Down
56 changes: 46 additions & 10 deletions .bem/make.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,14 @@ MAKE.decl('Arch', {
blocksLevelsRegexp : /^.+?\.blocks$/,
bundlesLevelsRegexp : /^.+?\.bundles$/,

libraries : [],

createCustomNodes : function(common, libs, blocks) {
createCustomNodes : function() {
var SetsNode = MAKE.getNodeClass('SetsNode');

if(typeof SetsNode.createId === 'undefined') {
return;
}

return new SetsNode({ root : this.root, arch : this.arch }).alterArch(null, libs);
return new SetsNode({ root : this.root, arch : this.arch }).alterArch();
}

});
Expand All @@ -50,7 +48,7 @@ MAKE.decl('SetsNode', {
},

getSourceTechs : function() {
return ['examples', 'specs'];
return ['examples', 'specs', 'jsdoc'];
}

});
Expand Down Expand Up @@ -120,16 +118,54 @@ MAKE.decl('ExampleNode', {
MAKE.decl('SpecNode', {

getTechs : function() {
return this.__base()
.concat([
'spec.js+browser.js+bemhtml',
'phantomjs'
]);
return [
'bemjson.js',
'bemdecl.js',
'deps.js',
'css',
'spec.js+browser.js+bemhtml',
'bemhtml',
'html',
'phantomjs'
];
},

getLevels : function() {
return this.__base.apply(this, arguments)
.concat(environ.getLibPath('bem-pr', 'spec.blocks'));
},

'create-phantomjs-node' : function() {
var arch = this.ctx.arch,
nodes = this.__base.apply(this, arguments);

function getBorchikNodeId(file) {
return PATH.join(PATH.dirname(file), '_' + PATH.basename(file));
}

['css', 'spec.js+browser.js+bemhtml'].forEach(function(tech) {
var bundlePath = this.getBundlePath(tech);
if(!arch.hasNode(bundlePath)) return;

arch
.getNode(bundlePath)
.getFiles()
.forEach(function(file) {
arch.link(getBorchikNodeId(file), nodes);
});
}, this);

return nodes;
},

'create-spec.js+browser.js+bemhtml-optimizer-node' : function(tech, sourceNode, bundleNode) {
if(process.env.ISTANBUL_COVERAGE) {
return this.createBorschikOptimizerNode(
require.resolve('./borschik/istanbul'),
sourceNode,
bundleNode);
}
return this.__base.apply(this, arguments);
}

});
Expand Down
122 changes: 122 additions & 0 deletions .bem/techs/phantomjs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
var FS = require('fs'),
PATH = require('path'),
URL = require('url'),
UTIL = require('util'),
BEM = require('bem'),
exec = require('child_process').exec,
Q = BEM.require('q'),
LOGGER = BEM.logger,
MOCHA_PHANTOM_BIN = require.resolve('../../libs/bem-pr/node_modules/mocha-phantomjs/bin/mocha-phantomjs'),
MOCHA_PHANTOM_HOOK = PATH.resolve(__dirname, '../hooks/mocha-phantomjs.js'),
MOCHA_PHANTOM_REPORTER = process.env.MOCHA_PHANTOM_REPORTER || 'spec',
MOCHA_PHANTOM_MAX_COUNT = parseInt(process.env.MOCHA_PHANTOM_MAX_COUNT, 10) || 5,
phantomCount = 0,
phantomQueue = [],
NEED_COVERAGE = process.env.ISTANBUL_COVERAGE,
covCollector,
covIdx;

if(NEED_COVERAGE) {
covCollector = new (require('istanbul').Collector)();
covIdx = 0;
}

exports.API_VER = 2;

exports.techMixin = {

getDependencies : function() {
return ['html', 'spec.js'];
},

getCoverageReportDir : function() {
return this.context.opts.dir || process.cwd();
},

createByDecl : function(item, level) {
var root = this.context.opts.dir || '',
prefix = level.getByObj(item),
relPrefix = PATH.relative(root, prefix),
path = this.getPath(prefix, 'html'),
args = '--reporter ' + MOCHA_PHANTOM_REPORTER,
url = URL.format({
protocol : 'file',
host : '/',
pathname : path
}),
defer = Q.defer(),
covBuffer;

if(NEED_COVERAGE) {
covBuffer = PATH.join(root, UTIL.format(
'__coverage-%s-%s-%s.json',
relPrefix.replace(/[^A-Za-z0-9_. ]/g, '_'),
Date.now()-0,
covIdx++));

LOGGER.fdebug('Store coverage buffer for "%s" into "%s"', relPrefix, covBuffer);

args += ' --hooks ' + MOCHA_PHANTOM_HOOK;
args += ' --setting coverage-file=' + covBuffer;
}

phantomCount < MOCHA_PHANTOM_MAX_COUNT?
runMochaPhantom() :
phantomQueue.push(runMochaPhantom);

var _this = this;

function getCovData() {
var data = {},
exists = FS.existsSync(covBuffer);

LOGGER.fdebug('Coverage buffer for "%s" %s', relPrefix, exists? 'found' : 'doesn\'t exist');

if(exists) {
data = JSON.parse(FS.readFileSync(covBuffer, 'utf8'));
FS.unlinkSync(covBuffer);
}

return data;
}

function runMochaPhantom() {
phantomCount++;

exec([MOCHA_PHANTOM_BIN, args, url].join(' '), function(err, stdout, stderr) {
var passed = err === null;

LOGGER.finfo('Tests results for "%s":\n%s',
PATH.relative(root, path), stdout, stderr? '\nStderr: ' + stderr : '');

if(passed) {
defer.resolve();
if(NEED_COVERAGE) {
LOGGER.fdebug('Going to read coverage buffer for "%s"', relPrefix);
covCollector.add(getCovData());
}
} else {
LOGGER.error('Tests failed:', err);
defer.reject(err);
}

--phantomCount;

phantomQueue.length && phantomQueue.shift()();
phantomCount ||
passed && NEED_COVERAGE && _this.storeFinalCoverage();
});
}

LOGGER.finfo('[i] Page was sent to Phantom (%s)', url);

return defer.promise;
},

storeFinalCoverage : function() {
var covFile = PATH.resolve(this.getCoverageReportDir(), 'coverage.json');
LOGGER.finfo('[i] Store final coverage "%s"', covFile);
FS.writeFileSync(covFile, JSON.stringify(covCollector.getFinalCoverage()), 'utf8');
}

};
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ node_modules
/*.specs
/*.tests

/coverage
/coverage*.json
17 changes: 14 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
language: node_js

node_js:
- "0.10"
- "0.11"
- 0.10
- 0.11

env:
global:
- GH_REF: github.com/bem/bem-core.git
- ISTANBUL_COVERAGE: yes

matrix:
allow_failures:
- node_js: "0.11"
- node_js: 0.11

branches:
only:
- v1
- v2

after_success:
- npm install coveralls
- ./node_modules/.bin/istanbul report lcovonly
- cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && echo "Coverage data was sent to coveralls!"

2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"Sergey Belov <peimei@ya.ru>"
],
"devDependencies": {
"bem-pr": "git://github.com/narqo/bem-pr.git#~0.6.1"
"bem-pr": "git://github.com/narqo/bem-pr.git#^0.7.0"
},
"license": "MIT",
"private": true,
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@
"jshint-groups": "0.6.0",
"jscs": "1.0.0",
"git-hooks": "0.0.3",
"bower-npm-install": "~0.5.4"
"bower-npm-install": "~0.5.4",
"istanbul": "^0.2.6"
},
"scripts": {
"lint": "jshint-groups && jscs .",
"libs": "bower-npm-install",
"bem-test": "npm run libs && bem make -w 5 sets",
"bem-test": "npm run libs && bem make -w 5 desktop.specs touch.specs",
"bem-coverage": "ISTANBUL_COVERAGE=yes npm run bem-test",
"test": "npm run bem-test && mocha --ui tdd --reporter spec common.blocks/i-bem/i-bem.test.bemhtml/*-test.js common.blocks/i-bem/__i18n/test/*-test.js common.blocks/i-bem/__i18n/i-bem__i18n.test.bemhtml/*-test.js"
}
}

0 comments on commit ebd18ed

Please sign in to comment.