Merged master
diff --git a/views/ngXosLib/bower.json b/views/ngXosLib/bower.json
index 228a082..08a02e3 100644
--- a/views/ngXosLib/bower.json
+++ b/views/ngXosLib/bower.json
@@ -17,7 +17,6 @@
"angular": "1.4.7",
"angular-ui-router": "0.2.15",
"angular-resource": "1.4.7",
- "ng-lodash": "0.3.0",
"angular-cookies": "1.4.7",
"angular-animate": "1.4.7",
"lodash": "~4.11.1",
diff --git a/views/ngXosLib/generator-xos/app/templates/gulp/build.js b/views/ngXosLib/generator-xos/app/templates/gulp/build.js
index 663a4cf..b66cdbc 100644
--- a/views/ngXosLib/generator-xos/app/templates/gulp/build.js
+++ b/views/ngXosLib/generator-xos/app/templates/gulp/build.js
@@ -98,8 +98,8 @@
gulp.task('copyHtml', function(){
return gulp.src(options.src + 'index.html')
// remove dev dependencies from html
- .pipe(replace(/<!-- bower:css -->(\n.*)*\n<!-- endbower --><!-- endcss -->/, ''))
- .pipe(replace(/<!-- bower:js -->(\n.*)*\n<!-- endbower --><!-- endjs -->/, ''))
+ .pipe(replace(/<!-- bower:css -->(\n^<link.*)*\n<!-- endbower -->/gmi, ''))
+ .pipe(replace(/<!-- bower:js -->(\n^<script.*)*\n<!-- endbower -->/gmi, ''))
// injecting minified files
.pipe(
inject(
@@ -150,6 +150,7 @@
gulp.task('build', function() {
runSequence(
'clean',
+ 'sass',
'templates',
'babel',
'scripts',
diff --git a/views/ngXosLib/generator-xos/package.json b/views/ngXosLib/generator-xos/package.json
old mode 100755
new mode 100644
index 58b5a33..0098496
--- a/views/ngXosLib/generator-xos/package.json
+++ b/views/ngXosLib/generator-xos/package.json
@@ -4,7 +4,7 @@
"description": "View generator for XOS",
"main": "index.js",
"scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
+ "test": "mocha test"
},
"author": "Matteo Scandolo",
"license": "ISC",
@@ -13,5 +13,13 @@
},
"files": [
"app"
- ]
+ ],
+ "devDependencies": {
+ "mocha": "^2.4.5",
+ "mockery": "^1.7.0",
+ "rimraf": "^2.5.2",
+ "wiredep": "^4.0.0",
+ "yeoman-assert": "^2.2.1",
+ "yeoman-test": "^1.4.0"
+ }
}
diff --git a/views/ngXosLib/generator-xos/test/build.spec.js b/views/ngXosLib/generator-xos/test/build.spec.js
new file mode 100644
index 0000000..dd49b03
--- /dev/null
+++ b/views/ngXosLib/generator-xos/test/build.spec.js
@@ -0,0 +1,182 @@
+'use strict';
+var path = require('path');
+var helpers = require('yeoman-test');
+var assert = require('yeoman-assert');
+var exec = require('child_process').exec;
+var fs = require('fs');
+const rimraf = require('rimraf');
+
+const getMillisec = min => min * 60 * 1000;
+const deleteFile = file => {
+ if(fs.existsSync(file)){
+ // console.log(`deleting: ${file}`);
+ fs.unlinkSync(file);
+ }
+}
+
+// source files
+const viewName = 'testDashboard';
+const fileName = viewName.replace(/^./, viewName[0].toUpperCase());
+const sourcePath = path.join(__dirname, `../../../ngXosViews/${viewName}/`);
+
+// dest files
+const basePath = '../../../../xos/core/xoslib';
+const destHtml = path.join(__dirname, basePath + '/dashboards/xosTestDashboard.html');
+const destJs = path.join(__dirname, basePath + '/static/js/xosTestDashboard.js');
+const destVendor = path.join(__dirname, basePath + '/static/js/vendor/xosTestDashboardVendor.js');
+const destCss = path.join(__dirname, basePath + '/static/css/xosTestDashboard.css');
+
+describe('The XOS Build script', function(){
+ const buildCmd = 'gulp build';
+
+ this.timeout(getMillisec(5));
+
+ before(done => {
+ console.log('Running generator');
+ this.generator = helpers
+ .run(require.resolve('../app'))
+ .inDir(sourcePath)
+ .withOptions({ 'skip-install': false })
+ .withPrompts({
+ name: viewName,
+ host: 'test-host',
+ token: 'test-token',
+ session: 'test-session'
+ })
+ .on('end', () => {
+ process.stdout.write('Installing Node Modules');
+ let npmInstall = setInterval(() => {
+ process.stdout.write('.');
+ }, 1000);
+ exec('npm install', {
+ cwd: sourcePath
+ }, (err) => {
+ clearInterval(npmInstall);
+ process.stdout.write('\nInstalling Bower Components');
+ let bowerInstall = setInterval(() => {
+ process.stdout.write('.');
+ }, 1000);
+ exec('bower install', {
+ cwd: sourcePath
+ }, (err) => {
+ clearInterval(bowerInstall);
+ done(err);
+ });
+ });
+ });
+ });
+
+ describe('when no styles or vendors are added', () => {
+
+ before((done) => {
+ process.stdout.write('\nBuilding App');
+ let appBuild = setInterval(() => {
+ process.stdout.write('.');
+ }, 1000);
+ exec(buildCmd, {
+ cwd: sourcePath
+ }, (err) => {
+ console.log(err);
+ clearInterval(appBuild);
+ done(err);
+ });
+ });
+
+ it('should have build the app', () => {
+ assert.file([destHtml, destJs]);
+ });
+
+ it('should include only minified files in the index', () => {
+ assert.fileContent(destHtml, `<script src="/static/js/xos${fileName}.js"></script>`);
+ assert.noFileContent(destHtml, `<!-- bower:css -->`);
+ assert.noFileContent(destHtml, `<!-- bower:js -->`);
+ });
+ });
+
+ describe('when a third party library is added', () => {
+ before((done) => {
+ process.stdout.write('\nInstalling 3rd party library');
+ let bowerInstall = setInterval(() => {
+ process.stdout.write('.');
+ }, 1000);
+ exec('bower install d3 --save', {
+ cwd: sourcePath
+ }, (err, out) => {
+ clearInterval(bowerInstall);
+ process.stdout.write('\nBuilding App');
+ let appBuild = setInterval(() => {
+ process.stdout.write('.');
+ }, 1000);
+ exec(buildCmd, {
+ cwd: sourcePath
+ }, (err) => {
+ console.log(err);
+ clearInterval(appBuild);
+ done(err);
+ });
+ });
+ });
+
+ it('should have build the app with a vendor file', () => {
+ assert.file([destHtml, destJs, destVendor]);
+ });
+
+ it('should include only minified files and minified deps in the index', () => {
+ assert.fileContent(destHtml, `<script src="/static/js/xos${fileName}.js"></script>`);
+ assert.fileContent(destHtml, `<script src="/static/js/vendor/xos${fileName}Vendor.js"></script>`);
+ assert.noFileContent(destHtml, `<!-- bower:css -->`);
+ assert.noFileContent(destHtml, `<!-- bower:js -->`);
+ });
+ });
+
+ describe('when some styles are added', () => {
+ before((done) => {
+ let styleContent = `
+ @import '../../../../style/sass/lib/_variables.scss';
+
+ #xosTestDashboard {
+ background: $brand-primary;
+ }
+ `;
+
+ fs.writeFile(`${sourcePath}src/sass/main.scss`, styleContent, function(err) {
+ process.stdout.write('\nBuilding the Application');
+ let appBuild = setInterval(() => {
+ process.stdout.write('.');
+ }, 1000);
+ exec('bower uninstall d3 --save', {
+ cwd: sourcePath
+ }, (err, out) => {
+ exec(buildCmd, {
+ cwd: sourcePath
+ }, (err, out) => {
+ clearInterval(appBuild);
+ done();
+ })
+ })
+ });
+ });
+
+ it('should have build the app with a css file', () => {
+ assert.file([destHtml, destJs, destCss]);
+ });
+
+ it('should include only minified files and minified deps in the index', () => {
+ assert.fileContent(destHtml, `<script src="/static/js/xos${fileName}.js"></script>`);
+ assert.fileContent(destHtml, `<link rel="stylesheet" href="/static/css/xos${fileName}.css">`);
+ assert.noFileContent(destHtml, `<!-- bower:css -->`);
+ assert.noFileContent(destHtml, `<!-- bower:js -->`);
+
+ assert.fileContent(destCss, `background:#337ab7`);
+ });
+ });
+
+ after(done => {
+ // deleting the folder used for test
+ deleteFile(destHtml);
+ deleteFile(destJs);
+ deleteFile(destVendor);
+ deleteFile(destCss);
+ rimraf(sourcePath, {}, done);
+ });
+});
\ No newline at end of file
diff --git a/views/ngXosLib/generator-xos/test/generator.spec.js b/views/ngXosLib/generator-xos/test/generator.spec.js
new file mode 100644
index 0000000..f75f444
--- /dev/null
+++ b/views/ngXosLib/generator-xos/test/generator.spec.js
@@ -0,0 +1,117 @@
+'use strict';
+
+const path = require('path');
+const helpers = require('yeoman-test');
+const assert = require('yeoman-assert');
+const rimraf = require('rimraf');
+const mockery = require('mockery');
+const wiredep = require('wiredep');
+
+const firstCharTouppercase = string => string.replace(/^./, string[0].toUpperCase())
+
+// get bower deps installed in ngXosLib
+let bowerDeps = wiredep({
+ cwd: path.join(__dirname, '../../'), // pretending to be in the ngXosLib root
+ exclude: ['Chart.js']
+});
+bowerDeps = bowerDeps.js.map(d => d.match(/bower_components\/([a-zA-Z\-`.]+)\//)[1]);
+
+// test values
+const viewName = 'testDashboard';
+const fileName = firstCharTouppercase(viewName);
+const testPath = path.join(__dirname, `../../../ngXosViews/${viewName}/`);
+
+const getDefaultFiles = () => {
+ return [
+ '.bowerrc',
+ '.eslintrc',
+ '.gitignore',
+ 'bower.json',
+ 'gulpfile.js',
+ 'karma.conf.js',
+ 'package.json',
+ 'src/index.html',
+ ].map(i => `${testPath}${i}`);
+};
+
+const yeomanUserMock = {
+ git: {
+ name: () => 'Test User',
+ email: () => 'test@mail.org'
+ }
+}
+
+mockery.enable({
+ warnOnReplace: false,
+ warnOnUnregistered: false,
+ useCleanCache: true,
+});
+mockery.resetCache();
+mockery.registerMock('../node_modules/yeoman-generator/lib/actions/user', yeomanUserMock);
+
+describe('Yeoman XOS generator', function () {
+
+ beforeEach(() => {
+ });
+
+ before(done => {
+ this.generator = helpers
+ .run(require.resolve('../app'))
+ .inDir(testPath)
+ .withOptions({ 'skip-install': true })
+ .withPrompts({
+ name: viewName,
+ host: 'test-host',
+ token: 'test-token',
+ session: 'test-session'
+ })
+ .on('end', done);
+ });
+
+
+ it('should generate base files in the correct directory', () => {
+ assert.file(getDefaultFiles());
+ });
+
+ it('should create the env file with correct params', () => {
+ assert.fileContent(`${testPath}env/default.js`, 'host: \'test-host\'');
+ assert.fileContent(`${testPath}env/default.js`, 'xoscsrftoken: \'test-token\'');
+ assert.fileContent(`${testPath}env/default.js`, 'xossessionid: \'test-session\'');
+ });
+
+ it('should write username in package & bower json', () => {
+ assert.fileContent(`${testPath}package.json`, '"author": "Test User"');
+ assert.fileContent(`${testPath}bower.json`, '"Test User <test@mail.org>"')
+ });
+
+ it('should add all xosLib dependencies in the dev section of bower.json', () => {
+ bowerDeps.forEach(d => {
+ assert.fileContent(`${testPath}bower.json`, d);
+ });
+ });
+
+ it('should set the right module name in all the files', () => {
+ assert.fileContent(`${testPath}src/index.html`, `ng-app="xos.${viewName}"`)
+ assert.fileContent(`${testPath}src/index.html`, `id="xos${fileName}"`)
+ assert.fileContent(`${testPath}src/js/main.js`, `angular.module('xos.${viewName}', [`)
+ assert.fileContent(`${testPath}src/sass/main.scss`, `#xos${fileName}`)
+ });
+
+ it('should set correct paths in build file', () => {
+ assert.fileContent(`${testPath}gulp/build.js`, `angular.module('xos.${viewName}')`)
+ assert.fileContent(`${testPath}gulp/build.js`, `options.dashboards + 'xos${fileName}.html'`)
+ assert.fileContent(`${testPath}gulp/build.js`, `options.static + 'css/xos${fileName}.css'`)
+ assert.fileContent(`${testPath}gulp/build.js`, `.pipe(concat('xos${fileName}.css'))`)
+ assert.fileContent(`${testPath}gulp/build.js`, `.pipe(concat('xos${fileName}.js'))`)
+ assert.fileContent(`${testPath}gulp/build.js`, `module: 'xos.${viewName}'`)
+ assert.fileContent(`${testPath}gulp/build.js`, `options.static + 'js/vendor/xos${fileName}Vendor.js'`)
+ assert.fileContent(`${testPath}gulp/build.js`, `options.static + 'js/xos${fileName}.js'`)
+ assert.fileContent(`${testPath}gulp/build.js`, `options.static + 'css/xos${fileName}.css'`)
+ assert.fileContent(`${testPath}gulp/build.js`, `.pipe(concat('xos${fileName}Vendor.js'))`)
+ });
+
+ after(done => {
+ // deleting the folder used for test
+ rimraf(testPath, {}, done)
+ });
+});
\ No newline at end of file
diff --git a/views/ngXosViews/serviceGrid/src/js/main.js b/views/ngXosViews/serviceGrid/src/js/main.js
index 5c41bd4..c52ef9f 100644
--- a/views/ngXosViews/serviceGrid/src/js/main.js
+++ b/views/ngXosViews/serviceGrid/src/js/main.js
@@ -60,6 +60,10 @@
.then((services) => {
this.services = _.map(services, s => {
// parse backend_status string in a boolean for display
+ // NOTE they are not boolean:
+ // - start with 0 = provisioning
+ // - start with 1 = good
+ // - start with 2 = error
s.status = parseInt(s.backend_status.match(/^[0-9]/)[0]) === 0 ? false : true;
return s;
})