UNPKG

bricks-cli

Version:

Command line tool for developing ambitious ember.js apps

321 lines (266 loc) 11.3 kB
'use strict'; var tmp = require('../helpers/tmp'); var conf = require('../helpers/conf'); var Promise = require('../../lib/ext/promise'); var path = require('path'); var rimraf = Promise.denodeify(require('rimraf')); var fs = require('fs'); var crypto = require('crypto'); var assert = require('assert'); var walkSync = require('walk-sync'); var appName = 'some-cool-app'; var ncp = Promise.denodeify(require('ncp')); var runCommand = require('../helpers/run-command'); var copyFixtureFiles = require('../helpers/copy-fixture-files'); function assertTmpEmpty() { var paths = walkSync('tmp') .filter(function(path) { return !path.match(/output\//); }); assert(paths.length === 0, 'tmp/ should be empty after `ember` tasks. Contained: ' + paths.join('\n')); } function buildApp(appName) { return runCommand(path.join('..', 'bin', 'ember'), 'new', appName, { onOutput: function() { return; // no output for initial application build } }); } describe('Acceptance: smoke-test', function() { before(function() { this.timeout(360000); tmp.setup('./common-tmp'); process.chdir('./common-tmp'); conf.setup(); return buildApp(appName) .then(function() { return rimraf(path.join(appName, 'node_modules', 'ember-cli')); }); }); after(function() { tmp.teardown('./common-tmp'); conf.restore(); }); beforeEach(function() { this.timeout(10000); tmp.setup('./tmp'); return ncp('./common-tmp/' + appName, './tmp/' + appName, { clobber: true, stopOnErr: true }) .then(function() { process.chdir('./tmp'); var appsECLIPath = path.join(appName, 'node_modules', 'ember-cli'); var pwd = process.cwd(); fs.symlinkSync(path.join(pwd, '..'), appsECLIPath); process.chdir(appName); }); }); afterEach(function() { assertTmpEmpty(); tmp.teardown('./tmp'); }); it('ember new foo, clean from scratch', function() { console.log(' running the slow end-to-end it will take some time'); this.timeout(450000); return runCommand(path.join('.', 'node_modules', 'ember-cli', 'bin', 'ember'), 'test'); }); it('ember test exits with non-zero when tests fail', function() { console.log(' running the slow end-to-end it will take some time'); this.timeout(450000); return copyFixtureFiles('smoke-tests/failing-test') .then(function() { return runCommand(path.join('.', 'node_modules', 'ember-cli', 'bin', 'ember'), 'test') .then(function() { assert(false, 'should have rejected with a failing test'); }) .catch(function(result) { assert.equal(result.code, 1); }); }); }); it('ember new foo, build production and verify fingerprint', function() { console.log(' running the slow fingerprint it will take some time'); this.timeout(360000); return runCommand(path.join('.', 'node_modules', 'ember-cli', 'bin', 'ember'), 'build', '--environment=production') .then(function() { var dirPath = path.join('.', 'dist', 'assets'); var dir = fs.readdirSync(dirPath); var files = []; dir.forEach(function (filepath) { if (filepath === '.gitkeep') { return; } files.push(filepath); var file = fs.readFileSync(path.join(dirPath, filepath), { encoding: 'utf8' }); var md5 = crypto.createHash('md5'); md5.update(file); var hex = md5.digest('hex'); assert(filepath.indexOf(hex) > -1, filepath + ' contains the fingerprint (' + hex + ')'); }); var indexHtml = fs.readFileSync(path.join('.', 'dist', 'index.html'), { encoding: 'utf8' }); files.forEach(function (filename) { assert(indexHtml.indexOf(filename) > -1); }); }); }); it('ember test --environment=production', function() { console.log(' running the slow end-to-end it will take some time'); this.timeout(450000); return copyFixtureFiles('smoke-tests/passing-test') .then(function() { return runCommand(path.join('.', 'node_modules', 'ember-cli', 'bin', 'ember'), 'test', '--environment=production') .then(function(result) { var exitCode = result.code; var output = result.output.join('\n'); assert.equal(exitCode, 0, 'exit code should be 0 for passing tests'); assert(!output.match('JSHint'), 'JSHint should not be run on production assets'); assert(output.match(/fail\s+0/), 'no failures'); assert(output.match(/pass\s+1/), '1 passing'); }) .catch(function(result) { assert(false, 'failed `ember test --environment=production`. The following output was received:\n' + result.output.join('\n')); }); }); }); it('ember new foo, build development, and verify generated files', function() { console.log(' running the slow build tests'); this.timeout(360000); return runCommand(path.join('.', 'node_modules', 'ember-cli', 'bin', 'ember'), 'build') .then(function() { var dirPath = path.join('.', 'dist'); var paths = walkSync(dirPath); assert(paths.length < 20, 'expected fewer than 20 files in dist, found ' + paths.length); }); }); it('ember build exits with non-zero code when build fails', function () { console.log(' running the slow build tests'); this.timeout(360000); var appJsPath = path.join('.', 'app', 'app.js'); var ouputContainsBuildFailed = false; return runCommand(path.join('.', 'node_modules', 'ember-cli', 'bin', 'ember'), 'build') .then(function (result) { assert(result.code === 0, 'expected exit code to be zero, but got ' + result.code); // add something broken to the project to make build fail fs.appendFileSync(appJsPath, '{(syntaxError>$@}{'); return runCommand(path.join('.', 'node_modules', 'ember-cli', 'bin', 'ember'), 'build', { onOutput: function(string) { // discard output as there will be a lot of errors and a long stacktrace // just mark that the output contains expected text if (!ouputContainsBuildFailed && string.match(/Build failed/)) { ouputContainsBuildFailed = true; } } }); }).then(function () { assert(false, 'should have rejected with a failing build'); }).catch(function (result) { assert(ouputContainsBuildFailed, 'command output must contain "Build failed" text'); assert(result.code !== 0, 'expected exit code to be non-zero, but got ' + result.code); }); }); it('ember new foo, build --watch development, and verify rebuilt after change', function() { console.log(' running the slow build --watch tests'); this.timeout(360000); var touched = false; var appJsPath = path.join('.', 'app', 'app.js'); var builtJsPath = path.join('.', 'dist', 'assets', 'some-cool-app.js'); var text = 'anotuhaonteuhanothunaothanoteh'; var line = 'console.log("' + text + '");'; return runCommand(path.join('.', 'node_modules', 'ember-cli', 'bin', 'ember'), 'build', '--watch', { onOutput: function(string, process) { if (touched) { if (string.match(/Build successful/)) { // build after change to app.js var contents = fs.readFileSync(builtJsPath).toString(); assert(contents.indexOf(text) > 1, 'must contain changed line after rebuild'); process.kill('SIGINT'); } } else { if (string.match(/Build successful/)) { // first build touched = true; fs.appendFileSync(appJsPath, line); } } } }) .catch(function() { // swallowing because of SIGINT }); }); it('ember new foo, build --watch development, and verify rebuilt after multiple changes', function() { console.log(' running the slow build --watch tests'); this.timeout(360000); var buildCount = 0; var touched = false; var appJsPath = path.join('.', 'app', 'app.js'); var builtJsPath = path.join('.', 'dist', 'assets', 'some-cool-app.js'); var firstText = 'anotuhaonteuhanothunaothanoteh'; var firstLine = 'console.log("' + firstText + '");'; var secondText = 'aahsldfjlwioruoiiononociwewqwr'; var secondLine = 'console.log("' + secondText + '");'; return runCommand(path.join('.', 'node_modules', 'ember-cli', 'bin', 'ember'), 'build', '--watch', { onOutput: function(string, process) { if (buildCount === 0) { if (string.match(/Build successful/)) { // first build touched = true; buildCount = 1; fs.appendFileSync(appJsPath, firstLine); } } else if (buildCount === 1) { if (string.match(/Build successful/)) { // second build touched = true; buildCount = 2; fs.appendFileSync(appJsPath, secondLine); } } else if (touched && buildCount === 2) { if (string.match(/Build successful/)) { // build after change to app.js var contents = fs.readFileSync(builtJsPath).toString(); assert(contents.indexOf(secondText) > 1, 'must contain second changed line after rebuild'); process.kill('SIGINT'); } } } }) .catch(function() { // swallowing because of SIGINT }); }); it('ember new foo, server, SIGINT clears tmp/', function() { console.log(' running the slow build tests'); this.timeout(360000); return runCommand(path.join('.', 'node_modules', 'ember-cli', 'bin', 'ember'), 'server', { onOutput: function(string, process) { if (string.match(/Build successful/)) { process.kill('SIGINT'); } } }) .catch(function() { // just eat the rejection as we are testing what happens }); }); it('ember new foo, build production and verify css files are concatenated', function() { this.timeout(450000); return copyFixtureFiles('with-styles') .then(function() { return runCommand(path.join('.', 'node_modules', 'ember-cli', 'bin', 'ember'), 'build', '--environment=production') .then(function() { var dirPath = path.join('.', 'dist', 'assets'); var dir = fs.readdirSync(dirPath); var cssNameRE = new RegExp(appName + '-([a-f0-9]+)\\.css','i'); dir.forEach(function (filepath) { if(cssNameRE.test(filepath)) { var appCss = fs.readFileSync(path.join('.', 'dist', 'assets', filepath), { encoding: 'utf8' }); assert(appCss.indexOf('.some-weird-selector')>-1); assert(appCss.indexOf('.some-even-weirder-selector')>-1); } }); }); }); }); });