<commit_before>/* eslint-disable no-console */

const autoprefixer = require('autoprefixer');
const fs = require('fs');
const gulp = require('gulp');
const babel = require('gulp-babel');
const cleanCSS = require('gulp-clean-css');
const concat = require('gulp-concat');
const gulpCount = require('gulp-count');
const gulpErrorHandler = require('gulp-error-handle');
const filelog = require('gulp-filelog');
const header = require('gulp-header');
const gulpif = require('gulp-if');
const optimizejs = require('gulp-optimize-js');
const plumber = require('gulp-plumber');
const postcss = require('gulp-postcss');
const cssvariables = require('postcss-css-variables');
const rimraf = require('gulp-rimraf');
const sass = require('gulp-sass');
const sassGrapher = require('gulp-sass-grapher');
const sourcemaps = require('gulp-sourcemaps');
const uglify = require('gulp-uglify');
const path = require('path');
const named = require('vinyl-named');
const webpack = require('webpack');
const webpackStream = require('webpack-stream');
const nodemon = require('gulp-nodemon');
const browserSync = require('browser-sync');
const webpackConfig = require('./webpack.config');

const browserlist = ['> 0.2%', 'last 10 version', 'not dead'];

const baseScripts = [
	'./node_modules/jquery/dist/jquery.min.js',
	'./node_modules/form-serializer/dist/jquery.serialize-object.min.js',
	'./static/scripts/tether/tether.min.js',
	'./static/scripts/bootstrap/bootstrap.min.js',
	'./static/scripts/chosen/chosen.jquery.min.js',
	'./static/scripts/base.js',
	'./static/scripts/toggle/bootstrap-toggle.min.js',
	'./static/scripts/qrcode/kjua-0.1.1.min.js',
	'./static/scripts/ajaxconfig.js',
];

function themeName() {
	return process.env.SC_THEME || 'default';
}

const EXIT_ON_ERROR = process.env.GULP_EXIT_ON_ERROR
	? process.env.GULP_EXIT_ON_ERROR === 'true'
	: process.env.NODE_ENV !== 'development';

const nonBaseScripts = [
	'./static/scripts/**/*.js',
].concat(baseScripts.map((script) => `!${script}`));
// used by almost all gulp tasks instead of gulp.src(...)
// plumber prevents pipes from stopping when errors occur
// changed only passes on files that were modified since last time
// filelog logs and counts all processed files

function withTheme(src) {
	if (typeof src === 'string') {
		return [src, `./theme/${themeName()}/${src.slice(2)}`];
	}
	return src.concat(src
		.map((e) => `./theme/${themeName()}/${e.slice(2)}`));
}

const handleError = (error) => {
	console.error(error);
	process.exit(1);
};

const beginPipe = (src) => gulp
	.src(withTheme(src), { allowEmpty: true, since: gulp.lastRun('build-all') })
	.pipe(gulpif(EXIT_ON_ERROR, gulpErrorHandler(handleError), plumber()))
	.pipe(filelog());

const beginPipeAll = (src) => gulp
	.src(withTheme(src), { allowEmpty: true, since: gulp.lastRun('build-all') })
	.pipe(gulpif(EXIT_ON_ERROR, gulpErrorHandler(handleError), plumber()))
	.pipe(filelog());

// copy images
// uses gulp.src instead of beginPipe for performance reasons (logging is slow)
gulp.task('images', () => gulp
	.src(withTheme('./static/images/**/*.*'))
	.pipe(gulp.dest(`./build/${themeName()}/images`)));

// minify static/other
// uses gulp.src instead of beginPipe for performance reasons (logging is slow)
gulp.task('other', () => gulp
	.src(withTheme('./static/other/**/*.*'))
	.pipe(gulp.dest(`./build/${themeName()}/other`)));

// minify static/other
// uses gulp.src instead of beginPipe for performance reasons (logging is slow)
gulp.task('other-with-theme', gulp.series('other', () => gulp
	.src(withTheme('./static/other/**/*.*'))
	.pipe(gulp.dest(`./build/${themeName()}/other`))));

const loadPaths = path.resolve('./static/styles/');
sassGrapher.init('./static/styles/', {
	loadPaths,
});
let firstRun = true;
gulp.task('styles', () => {
	const themeFile = `./theme/${themeName()}/style.scss`;
	return beginPipe('./static/styles/**/*.{css,sass,scss}')
		.pipe(gulpif(!firstRun, sassGrapher.ancestors()))
		.pipe(header(fs.readFileSync(themeFile, 'utf8')))
		.pipe(filelog('PROCESS: '))
		.pipe(sourcemaps.init())
		.pipe(sass({
			sourceMap: true,
			includePaths: ['node_modules'],
		}).on('error', handleError))
		.pipe(postcss([
			cssvariables({
				preserve: true,
			}),
			autoprefixer({
				browsers: browserlist,
			}),
		]))
		.pipe(cleanCSS({
			compatibility: 'ie9',
		}))
		.pipe(sourcemaps.write('./sourcemaps'))
		.pipe(gulp.dest(`./build/${themeName()}/styles`))
		.pipe(browserSync.stream());
});

gulp.task('styles-done', gulp.series('styles'), () => {
	firstRun = false;
});

// copy fonts
gulp.task('fonts', () => beginPipe('./static/fonts/**/*.*')
	.pipe(gulp.dest(`./build/${themeName()}/fonts`)));

// copy static assets
gulp.task('static', () => beginPipe('./static/*')
	.pipe(gulp.dest(`./build/${themeName()}/`)));

// compile/transpile JSX and ES6 to ES5 and minify scripts
gulp.task('scripts', () => beginPipeAll(nonBaseScripts)
	.pipe(
		named((file) => {
			// As a preparation for webpack stream: Transform nonBaseScripts paths
			// e.g. '/static/scripts/schics/schicEdit.blub.min.js' -> 'schics/schicEdit.blub.min'
			const initialPath = file.history[0].split('scripts')[1];
			const pathSegments = initialPath.split('.');
			const concretePath = pathSegments
				.slice(0, pathSegments.length - 1)
				.join('.');
			const fileName = concretePath
				.split('')
				.slice(1)
				.join('');

			return fileName;
		}),
	)
	.pipe(webpackStream(webpackConfig, webpack))
	.pipe(gulp.dest(`./build/${themeName()}/scripts`))
	.pipe(browserSync.stream()));

// compile/transpile JSX and ES6 to ES5, minify and concatenate base scripts into all.js
gulp.task('base-scripts', () => beginPipeAll(baseScripts)
	.pipe(gulpCount('## js-files selected'))
	.pipe(babel({
		presets: [
			[
				'@babel/preset-env',
				{
					modules: false,
					targets: browserlist.join(', '),
				},
			],
		],
	}))
	.pipe(optimizejs())
	.pipe(uglify())
	.pipe(concat('all.js'))
	.pipe(gulp.dest(`./build/${themeName()}/scripts`)));

// compile vendor SASS/SCSS to CSS and minify it
gulp.task('vendor-styles', () => beginPipe('./static/vendor/**/*.{sass,scss}')
	.pipe(sourcemaps.init())
	.pipe(sass({
		sourceMap: true,
	}))
	.pipe(postcss([
		autoprefixer({
			browsers: browserlist,
		}),
	]))
	.pipe(cleanCSS({
		compatibility: 'ie9',
	}))
	.pipe(sourcemaps.write('./sourcemaps'))
	.pipe(gulp.dest(`./build/${themeName()}/vendor`))
	.pipe(browserSync.stream()));

// compile/transpile vendor JSX and ES6 to ES5 and minify scripts
gulp.task('vendor-scripts', () => beginPipe('./static/vendor/**/*.js')
	.pipe(babel({
		compact: false,
		presets: [
			[
				'@babel/preset-env',
				{
					modules: false,
					targets: browserlist.join(', '),
				},
			],
		],
		plugins: ['@babel/plugin-transform-react-jsx'],
	}))
	.pipe(optimizejs())
	.pipe(uglify())
	.pipe(gulp.dest(`./build/${themeName()}/vendor`)));

// copy other vendor files
gulp.task('vendor-assets', () => beginPipe([
	'./static/vendor/**/*.*',
	'!./static/vendor/**/*.js',
	'!./static/vendor/**/*.{sass,scss}',
]).pipe(gulp.dest(`./build/${themeName()}/vendor`)));

// copy node modules
const nodeModules = ['mathjax', 'font-awesome/fonts', 'video.js'];
gulp.task('node-modules', () => Promise.all(nodeModules
	// uses gulp.src instead of beginPipe for performance reasons (logging is slow)
	.map((module) => gulp.src([`./node_modules/${module}/**/*.*`])
		.pipe(gulp.dest(`./build/${themeName()}/vendor-optimized/${module}`)))));

// clear build folder + smart cache
gulp.task('clear', () => gulp
	.src(
		[
			'./build/*',
			'./.gulp-changed-smart.json',
			'./.webpack-changed-plugin-cache/*',
		],
		{
			read: false,
			allowEmpty: true,
		},
	)
	.pipe(rimraf()));

// clear gulp cache without removing current build
gulp.task('clear-cache', () => gulp
	.src(
		[
			'./.gulp-changed-smart.json',
			'./.webpack-changed-plugin-cache/*',
		],
		{
			read: false,
			allowEmpty: true,
		},
	)
	.pipe(rimraf({})));

// run all tasks, processing changed files
gulp.task('build-all', gulp.series(
	'images',
	'other',
	'other-with-theme',
	'styles',
	'styles-done',
	'fonts',
	'scripts',
	'base-scripts',
	'vendor-styles',
	'vendor-scripts',
	'vendor-assets',
	'node-modules',
	'static',
));

gulp.task('build-theme-files', gulp.series('styles', 'styles-done', 'images', 'static'));

// watch and run corresponding task on change, process changed files only
gulp.task('watch', gulp.series('build-all', () => {
	const watchOptions = { interval: 1000 };
	gulp.watch(baseScripts, watchOptions, gulp.series('base-scripts'));
	gulp.watch(
		withTheme('./static/styles/**/*.{css,sass,scss}'),
		watchOptions,
		gulp.series('styles', 'styles-done'),
	);
	gulp.watch(withTheme('./static/images/**/*.*'), watchOptions, gulp.series('images'))
		.on('change', browserSync.reload);
	gulp.watch(withTheme(nonBaseScripts), watchOptions, gulp.series('scripts'));

	gulp.watch(withTheme('./static/vendor/**/*.*'), watchOptions, gulp.series('vendor-styles',
		'vendor-scripts',
		'vendor-assets'));
	gulp.watch(withTheme('./static/*.*'), watchOptions, gulp.series('static'));
}));

gulp.task('nodemon', (cb) => {
	let started = false;
	return nodemon({
		ext: 'js hbs json',
		script: './bin/www',
		watch: ['views/', 'controllers/', 'helpers'],
		exec: 'node --inspect-brk=0.0.0.0:9310',
	}).on('start', () => {
		if (!started) {
			cb();
			started = true;
		}
		setTimeout(browserSync.reload, 3000); // server-start takes some time
	});
});

gulp.task('browser-sync', () => {
	browserSync.init(null, {
		proxy: 'http://localhost:3100',
		open: false,
		port: 7000,
		ghostMode: false,
		reloadOnRestart: false,
		socket: {
			clients: {
				heartbeatTimeout: 60000,
			},
		},
	});
});

gulp.task('watch-reload', gulp.parallel('watch', 'nodemon', 'browser-sync'));

// run this if only 'gulp' is run on the commandline with no task specified
gulp.task('default', gulp.series('build-all'));
<commit_msg>SC-3882 Content-Security-Policy: reverted to old gulpfile from develop branch.<commit_after>/* eslint-disable no-console */

const autoprefixer = require('autoprefixer');
const fs = require('fs');
const gulp = require('gulp');
const babel = require('gulp-babel');
const cleanCSS = require('gulp-clean-css');
const concat = require('gulp-concat');
const gulpCount = require('gulp-count');
const gulpErrorHandler = require('gulp-error-handle');
const filelog = require('gulp-filelog');
const header = require('gulp-header');
const gulpif = require('gulp-if');
const optimizejs = require('gulp-optimize-js');
const plumber = require('gulp-plumber');
const postcss = require('gulp-postcss');
const cssvariables = require('postcss-css-variables');
const rimraf = require('gulp-rimraf');
const sass = require('gulp-sass');
const sassGrapher = require('gulp-sass-grapher');
const sourcemaps = require('gulp-sourcemaps');
const uglify = require('gulp-uglify');
const path = require('path');
const named = require('vinyl-named');
const webpack = require('webpack');
const webpackStream = require('webpack-stream');
const nodemon = require('gulp-nodemon');
const browserSync = require('browser-sync');
const webpackConfig = require('./webpack.config');

const browserlist = ['> 0.2%', 'last 10 version', 'not dead'];

const baseScripts = [
	'./node_modules/jquery/dist/jquery.min.js',
	'./node_modules/form-serializer/dist/jquery.serialize-object.min.js',
	'./static/scripts/tether/tether.min.js',
	'./static/scripts/bootstrap/bootstrap.min.js',
	'./static/scripts/chosen/chosen.jquery.min.js',
	'./static/scripts/base.js',
	'./static/scripts/toggle/bootstrap-toggle.min.js',
	'./static/scripts/qrcode/kjua-0.1.1.min.js',
	'./static/scripts/ajaxconfig.js',
];

function themeName() {
	return process.env.SC_THEME || 'default';
}

const EXIT_ON_ERROR = process.env.GULP_EXIT_ON_ERROR
	? process.env.GULP_EXIT_ON_ERROR === 'true'
	: process.env.NODE_ENV !== 'development';

const nonBaseScripts = [
	'./static/scripts/**/*.js',
].concat(baseScripts.map((script) => `!${script}`));
// used by almost all gulp tasks instead of gulp.src(...)
// plumber prevents pipes from stopping when errors occur
// changed only passes on files that were modified since last time
// filelog logs and counts all processed files

function withTheme(src) {
	if (typeof src === 'string') {
		return [src, `./theme/${themeName()}/${src.slice(2)}`];
	}
	return src.concat(src
		.map((e) => `./theme/${themeName()}/${e.slice(2)}`));
}

const handleError = (error) => {
	console.error(error);
	process.exit(1);
};

const beginPipe = (src) => gulp
	.src(withTheme(src), { allowEmpty: true, since: gulp.lastRun('build-all') })
	.pipe(gulpif(EXIT_ON_ERROR, gulpErrorHandler(handleError), plumber()))
	.pipe(filelog());

const beginPipeAll = (src) => gulp
	.src(withTheme(src), { allowEmpty: true, since: gulp.lastRun('build-all') })
	.pipe(gulpif(EXIT_ON_ERROR, gulpErrorHandler(handleError), plumber()))
	.pipe(filelog());

// copy images
// uses gulp.src instead of beginPipe for performance reasons (logging is slow)
gulp.task('images', () => gulp
	.src(withTheme('./static/images/**/*.*'))
	.pipe(gulp.dest(`./build/${themeName()}/images`)));

// minify static/other
// uses gulp.src instead of beginPipe for performance reasons (logging is slow)
gulp.task('other', () => gulp
	.src(withTheme('./static/other/**/*.*'))
	.pipe(gulp.dest(`./build/${themeName()}/other`)));

// minify static/other
// uses gulp.src instead of beginPipe for performance reasons (logging is slow)
gulp.task('other-with-theme', gulp.series('other', () => gulp
	.src(withTheme('./static/other/**/*.*'))
	.pipe(gulp.dest(`./build/${themeName()}/other`))));

const loadPaths = path.resolve('./static/styles/');
sassGrapher.init('./static/styles/', {
	loadPaths,
});
let firstRun = true;
gulp.task('styles', () => {
	const themeFile = `./theme/${themeName()}/style.scss`;
	return beginPipe('./static/styles/**/*.{css,sass,scss}')
		.pipe(gulpif(!firstRun, sassGrapher.ancestors()))
		.pipe(header(fs.readFileSync(themeFile, 'utf8')))
		.pipe(filelog('PROCESS: '))
		.pipe(sourcemaps.init())
		.pipe(sass({
			sourceMap: true,
			includePaths: ['node_modules'],
		}).on('error', handleError))
		.pipe(postcss([
			cssvariables({
				preserve: true,
			}),
			autoprefixer({
				browsers: browserlist,
			}),
		]))
		.pipe(cleanCSS({
			compatibility: 'ie9',
		}))
		.pipe(sourcemaps.write('./sourcemaps'))
		.pipe(gulp.dest(`./build/${themeName()}/styles`))
		.pipe(browserSync.stream());
});

gulp.task('styles-done', gulp.series('styles'), () => {
	firstRun = false;
});

// copy fonts
gulp.task('fonts', () => beginPipe('./static/fonts/**/*.*')
	.pipe(gulp.dest(`./build/${themeName()}/fonts`)));

// copy static assets
gulp.task('static', () => beginPipe('./static/*')
	.pipe(gulp.dest(`./build/${themeName()}/`)));

// compile/transpile JSX and ES6 to ES5 and minify scripts
gulp.task('scripts', () => beginPipeAll(nonBaseScripts)
	.pipe(
		named((file) => {
			// As a preparation for webpack stream: Transform nonBaseScripts paths
			// e.g. '/static/scripts/schics/schicEdit.blub.min.js' -> 'schics/schicEdit.blub.min'
			const initialPath = file.history[0].split('scripts')[1];
			const pathSegments = initialPath.split('.');
			const concretePath = pathSegments
				.slice(0, pathSegments.length - 1)
				.join('.');
			const fileName = concretePath
				.split('')
				.slice(1)
				.join('');

			return fileName;
		}),
	)
	.pipe(webpackStream(webpackConfig, webpack))
	.pipe(gulp.dest(`./build/${themeName()}/scripts`))
	.pipe(browserSync.stream()));

// compile/transpile JSX and ES6 to ES5, minify and concatenate base scripts into all.js
gulp.task('base-scripts', () => beginPipeAll(baseScripts)
	.pipe(gulpCount('## js-files selected'))
	.pipe(babel({
		presets: [
			[
				'@babel/preset-env',
				{
					modules: false,
					targets: browserlist.join(', '),
				},
			],
		],
	}))
	.pipe(optimizejs())
	.pipe(uglify())
	.pipe(concat('all.js'))
	.pipe(gulp.dest(`./build/${themeName()}/scripts`)));

// compile vendor SASS/SCSS to CSS and minify it
gulp.task('vendor-styles', () => beginPipe('./static/vendor/**/*.{sass,scss}')
	.pipe(sourcemaps.init())
	.pipe(sass({
		sourceMap: true,
	}))
	.pipe(postcss([
		autoprefixer({
			browsers: browserlist,
		}),
	]))
	.pipe(cleanCSS({
		compatibility: 'ie9',
	}))
	.pipe(sourcemaps.write('./sourcemaps'))
	.pipe(gulp.dest(`./build/${themeName()}/vendor`))
	.pipe(browserSync.stream()));

// compile/transpile vendor JSX and ES6 to ES5 and minify scripts
gulp.task('vendor-scripts', () => beginPipe('./static/vendor/**/*.js')
	.pipe(babel({
		compact: false,
		presets: [
			[
				'@babel/preset-env',
				{
					modules: false,
					targets: browserlist.join(', '),
				},
			],
		],
		plugins: ['@babel/plugin-transform-react-jsx'],
	}))
	.pipe(optimizejs())
	.pipe(uglify())
	.pipe(gulp.dest(`./build/${themeName()}/vendor`)));

// copy other vendor files
gulp.task('vendor-assets', () => beginPipe([
	'./static/vendor/**/*.*',
	'!./static/vendor/**/*.js',
	'!./static/vendor/**/*.{sass,scss}',
]).pipe(gulp.dest(`./build/${themeName()}/vendor`)));

// copy node modules
const nodeModules = ['mathjax', 'font-awesome/fonts', 'video.js'];
gulp.task('node-modules', () => Promise.all(nodeModules
	// uses gulp.src instead of beginPipe for performance reasons (logging is slow)
	.map((module) => gulp.src([`./node_modules/${module}/**/*.*`])
		.pipe(gulp.dest(`./build/${themeName()}/vendor-optimized/${module}`)))));

// clear build folder + smart cache
gulp.task('clear', () => gulp
	.src(
		[
			'./build/*',
			'./.gulp-changed-smart.json',
			'./.webpack-changed-plugin-cache/*',
		],
		{
			read: false,
			allowEmpty: true,
		},
	)
	.pipe(rimraf()));

// clear gulp cache without removing current build
gulp.task('clear-cache', () => gulp
	.src(
		[
			'./.gulp-changed-smart.json',
			'./.webpack-changed-plugin-cache/*',
		],
		{
			read: false,
			allowEmpty: true,
		},
	)
	.pipe(rimraf({})));

// run all tasks, processing changed files
gulp.task('build-all', gulp.series(
	'images',
	'other',
	'other-with-theme',
	'styles',
	'styles-done',
	'fonts',
	'scripts',
	'base-scripts',
	'vendor-styles',
	'vendor-scripts',
	'vendor-assets',
	'node-modules',
	'static',
));

gulp.task('build-theme-files', gulp.series('styles', 'styles-done', 'images', 'static'));

// watch and run corresponding task on change, process changed files only
gulp.task('watch', gulp.series('build-all', () => {
	const watchOptions = { interval: 1000 };
	gulp.watch(baseScripts, watchOptions, gulp.series('base-scripts'));
	gulp.watch(
		withTheme('./static/styles/**/*.{css,sass,scss}'),
		watchOptions,
		gulp.series('styles', 'styles-done'),
	);
	gulp.watch(withTheme('./static/images/**/*.*'), watchOptions, gulp.series('images'))
		.on('change', browserSync.reload);
	gulp.watch(withTheme(nonBaseScripts), watchOptions, gulp.series('scripts'));

	gulp.watch(withTheme('./static/vendor/**/*.*'), watchOptions, gulp.series('vendor-styles',
		'vendor-scripts',
		'vendor-assets'));
	gulp.watch(withTheme('./static/*.*'), watchOptions, gulp.series('static'));
}));

gulp.task('nodemon', (cb) => {
	let started = false;
	return nodemon({
		ext: 'js hbs json',
		script: './bin/www',
		watch: ['views/', 'controllers/', 'helpers'],
		exec: 'node --inspect=9310',
	}).on('start', () => {
		if (!started) {
			cb();
			started = true;
		}
		setTimeout(browserSync.reload, 3000); // server-start takes some time
	});
});

gulp.task('browser-sync', () => {
	browserSync.init(null, {
		proxy: 'http://localhost:3100',
		open: false,
		port: 7000,
		ghostMode: false,
		reloadOnRestart: false,
		socket: {
			clients: {
				heartbeatTimeout: 60000,
			},
		},
	});
});

gulp.task('watch-reload', gulp.parallel('watch', 'nodemon', 'browser-sync'));

// run this if only 'gulp' is run on the commandline with no task specified
gulp.task('default', gulp.series('build-all'));
<|endoftext|>


<commit_before>function data(){
    return {
        "bookName": "bookName-" + parseInt(Math.random() * 100),
        "price": parseInt(Math.random() * 1000),
        "checkedOut": new Date()
    }
};

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction;

var jqueryIndexedDB_Test = {
    "Set Version": {
        "code": function(){
            $.indexeddb("BookShop1").setVersion(10).then(console.info, console.error);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var req = db.setVersion(isNaN(parseInt(db.version, 10)) ? 0 : parseInt(db.version, 10) + 1);
                req.onsuccess = function(){
                    console.info(req.result);
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
        }
    },

    "Transaction": {
        "code": function(){
            var transaction = $.indexeddb("BookShop1").transaction([], IDBTransaction.READ_WRITE);
            transaction.then(console.info, console.error);
            transaction.objectStore("BookList").add(data()).then(console.info, console.error);
            transaction.objectStore("OldBookList").add(data(), new Date().getTime()).then(console.info, console.error);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                console.info(transaction);
                var bookList = transaction.objectStore("BookList");
                var oldBookList = transaction.objectStore("OldBookList");
                var req1 = bookList.add(data());
                var req2 = oldBookList.add(data(), new Date().getTime());
                req1.onsuccess = function(){
                    console.info(req1.result);
                };
                req1.onerror = function(e){
                    console.error(e, req1);
                };
                req2.onsuccess = function(){
                    console.info(req2.result);
                };
                req2.onerror = function(e){
                    console.error(e, req2);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Create Object Store": {
        "code": function(){
            $.indexeddb("BookShop1").createObjectStore("BookList", {
                "keyPath": "id",
                "autoIncrement": true
            }).then(console.info, console.error);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var req = db.setVersion((isNaN(parseInt(db.version, 10)) ? 0 : parseInt(db.version, 10) + 1));
                req.onsuccess = function(){
                    var transaction = req.result;
                    var objectStore = transaction.db.createObjectStore("BookList", {
                        "keyPath": "id",
                        "autoIncrement": true
                    });
                    console.info(objectStore);
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Delete Object Store": {
        "code": function(){
            $.indexeddb("BookShop1").deleteObjectStore("BookList", false).then(console.info, console.error);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var req = db.setVersion((isNaN(parseInt(db.version, 10)) ? 0 : parseInt(db.version, 10) + 1));
                req.onsuccess = function(){
                    var transaction = req.result;
                    transaction.db.deleteObjectStore("BookList");
                    console.info(transaction.db);
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Open Object Store, but dont create if does not exist": {
        "code": function(){
            $.indexeddb("BookShop1").objectStore("BookList", false).then(console.info, console.error);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                try {
                    var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                    var objectStore = transaction.objectStore("BookList");
                    console.info(objectStore);
                }
                catch (e) {
                    console.error(e, request);
                }
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Open Object Store, or create if does not exist": {
        "code": function(){
            $.indexeddb("BookShop1").objectStore("BookList", {
                "keyPath": "id",
                "autoIncrement": true
            }).then(console.info, console.error);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                try {
                    var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                    var objectStore = transaction.objectStore("BookList");
                    console.info(objectStore);
                }
                catch (e) {
                    var req = db.setVersion((isNaN(parseInt(db.version, 10)) ? 0 : parseInt(db.version, 10) + 1));
                    req.onsuccess = function(){
                        var transaction = req.result;
                        var objectStore = transaction.db.createObjectStore("BookList", {
                            "autoIncrement": true
                        });
                        console.info(objectStore);
                    };
                    req.onerror = function(e){
                        console.error(e, req);
                    };
                }

            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Add Data to Object Store": {
        "code": function(){
            window.book = data();
            $.indexeddb("BookShop1").objectStore("BookList").add(book).then(function(val){
                book.id = val;
                console.info(val);
            }, console.error);
        },
        "alternate": function(){
            window.book = data();
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                var bookList = transaction.objectStore("BookList");
                var req = bookList.add(data());
                req.onsuccess = function(){
                    book.id = req.result;
                    console.info(req.result);
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Get data": {
        "code": function(){
            $.indexeddb("BookShop1").objectStore("BookList").get(book.id).then(console.info, console.error);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                var bookList = transaction.objectStore("BookList");
                var req = bookList.get(book.id);
                req.onsuccess = function(){
                    console.info(req.result);
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Modify Data in Object Store": {
        "code": function(){
            book["modified" + Math.random()] = true;
            $.indexeddb("BookShop1").objectStore("BookList").update(book, new Date().getTime()).then(console.info, console.error);
        },
        "alternate": function(){
            book["modified" + Math.random()] = true;
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                var bookList = transaction.objectStore("BookList");
                var req = bookList.put(data(), new Date().getTime());
                req.onsuccess = function(){
                    console.info(req.result);
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Cursor and list all items in the object store": {
        "code": function(){
            $.indexeddb("BookShop1").objectStore("BookList").openCursor().each(console.info);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                var bookList = transaction.objectStore("BookList");
                var req = bookList.openCursor();
                req.onsuccess = function(){
                    var cursor = req.result;
                    if (cursor) {
                        console.info(req.result.value);
                        cursor["continue"]();
                    }
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Cursor and delete items with price that is an odd number": {
        "code": function(){
            $.indexeddb("BookShop1").objectStore("BookList").openCursor().deleteEach(function(value, key){
                if (value && value.price % 2) {
                    console.info("Deleting", value);
                    return true;
                }
            });
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                var bookList = transaction.objectStore("BookList");
                var req = bookList.openCursor();
                req.onsuccess = function(){
                    var cursor = req.result;
                    if (cursor) {
                        if (cursor.value && cursor.value.price % 2) {
                            console.info("Deleting", cursor.value);
                            cursor["delete"]();
                        }
                        cursor["continue"]();
                    }
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Cursor and update items with price that is an odd number": {
        "code": function(){
            $.indexeddb("BookShop1").objectStore("BookList").openCursor().updateEach(function(value){
                if (value && value.price % 2) {
                    value["modified-" + Math.random()] = true;
                    console.info("Updating", value);
                    return value;
                }
            });
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                var bookList = transaction.objectStore("BookList");
                var req = bookList.openCursor();
                req.onsuccess = function(){
                    var cursor = req.result;
                    if (cursor) {
                        if (cursor.value && cursor.value.price % 2) {
                            cursor.value["modified-" + Math.random()] = true;
                            console.info("Updating", cursor.value);
                            cursor.update(cursor.value);
                        }
                        cursor["continue"]();
                    }
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },
    "Open an Index and iterate over its objects": {
        "code": function(){
            $.indexeddb("BookShop1").objectStore("BookList").index("price").openCursor().each(console.info);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                var bookList = transaction.objectStore("BookList");
                // Assuming that index exists
                var index = bookList.index("price-index");
                var req = index.openCursor();
                req.onsuccess = function(){
                    var cursor = req.result;
                    if (cursor) {
                        console.info(cursor.value);
                        cursor["continue"]();
                    }
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Open a key cursor on an Index and iterate over its objects": {
        "code": function(){
            $.indexeddb("BookShop1").objectStore("BookList").index("price").openKeyCursor([200, 500]).each(console.info);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                var bookList = transaction.objectStore("BookList");
                var index = bookList.index("price-index");
                var range = new IDBKeyRange.bound(200, 500, true, true);
                var req = index.openKeyCursor(range);
                req.onsuccess = function(){
                    var cursor = req.result;
                    if (cursor) {
                        console.info(cursor.value, cursor.key);
                        cursor["continue"]();
                    }

                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    }
};
<commit_msg>Changed the casing for IndexedDB<commit_after>function data(){
    return {
        "bookName": "bookName-" + parseInt(Math.random() * 100),
        "price": parseInt(Math.random() * 1000),
        "checkedOut": new Date()
    }
};

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction;

var jqueryIndexedDB_Test = {
    "Set Version": {
        "code": function(){
            $.indexedDB("BookShop1").setVersion(10).then(console.info, console.error);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var req = db.setVersion(isNaN(parseInt(db.version, 10)) ? 0 : parseInt(db.version, 10) + 1);
                req.onsuccess = function(){
                    console.info(req.result);
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
        }
    },

    "Transaction": {
        "code": function(){
            var transaction = $.indexedDB("BookShop1").transaction([], IDBTransaction.READ_WRITE);
            transaction.then(console.info, console.error);
            transaction.objectStore("BookList").add(data()).then(console.info, console.error);
            transaction.objectStore("OldBookList").add(data(), new Date().getTime()).then(console.info, console.error);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                console.info(transaction);
                var bookList = transaction.objectStore("BookList");
                var oldBookList = transaction.objectStore("OldBookList");
                var req1 = bookList.add(data());
                var req2 = oldBookList.add(data(), new Date().getTime());
                req1.onsuccess = function(){
                    console.info(req1.result);
                };
                req1.onerror = function(e){
                    console.error(e, req1);
                };
                req2.onsuccess = function(){
                    console.info(req2.result);
                };
                req2.onerror = function(e){
                    console.error(e, req2);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Create Object Store": {
        "code": function(){
            $.indexedDB("BookShop1").createObjectStore("BookList", {
                "keyPath": "id",
                "autoIncrement": true
            }).then(console.info, console.error);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var req = db.setVersion((isNaN(parseInt(db.version, 10)) ? 0 : parseInt(db.version, 10) + 1));
                req.onsuccess = function(){
                    var transaction = req.result;
                    var objectStore = transaction.db.createObjectStore("BookList", {
                        "keyPath": "id",
                        "autoIncrement": true
                    });
                    console.info(objectStore);
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Delete Object Store": {
        "code": function(){
            $.indexedDB("BookShop1").deleteObjectStore("BookList", false).then(console.info, console.error);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var req = db.setVersion((isNaN(parseInt(db.version, 10)) ? 0 : parseInt(db.version, 10) + 1));
                req.onsuccess = function(){
                    var transaction = req.result;
                    transaction.db.deleteObjectStore("BookList");
                    console.info(transaction.db);
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Open Object Store, but dont create if does not exist": {
        "code": function(){
            $.indexedDB("BookShop1").objectStore("BookList", false).then(console.info, console.error);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                try {
                    var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                    var objectStore = transaction.objectStore("BookList");
                    console.info(objectStore);
                }
                catch (e) {
                    console.error(e, request);
                }
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Open Object Store, or create if does not exist": {
        "code": function(){
            $.indexedDB("BookShop1").objectStore("BookList", {
                "keyPath": "id",
                "autoIncrement": true
            }).then(console.info, console.error);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                try {
                    var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                    var objectStore = transaction.objectStore("BookList");
                    console.info(objectStore);
                }
                catch (e) {
                    var req = db.setVersion((isNaN(parseInt(db.version, 10)) ? 0 : parseInt(db.version, 10) + 1));
                    req.onsuccess = function(){
                        var transaction = req.result;
                        var objectStore = transaction.db.createObjectStore("BookList", {
                            "autoIncrement": true
                        });
                        console.info(objectStore);
                    };
                    req.onerror = function(e){
                        console.error(e, req);
                    };
                }

            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Add Data to Object Store": {
        "code": function(){
            window.book = data();
            $.indexedDB("BookShop1").objectStore("BookList").add(book).then(function(val){
                book.id = val;
                console.info(val);
            }, console.error);
        },
        "alternate": function(){
            window.book = data();
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                var bookList = transaction.objectStore("BookList");
                var req = bookList.add(data());
                req.onsuccess = function(){
                    book.id = req.result;
                    console.info(req.result);
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Get data": {
        "code": function(){
            $.indexedDB("BookShop1").objectStore("BookList").get(book.id).then(console.info, console.error);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                var bookList = transaction.objectStore("BookList");
                var req = bookList.get(book.id);
                req.onsuccess = function(){
                    console.info(req.result);
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Modify Data in Object Store": {
        "code": function(){
            book["modified" + Math.random()] = true;
            $.indexedDB("BookShop1").objectStore("BookList").update(book, new Date().getTime()).then(console.info, console.error);
        },
        "alternate": function(){
            book["modified" + Math.random()] = true;
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                var bookList = transaction.objectStore("BookList");
                var req = bookList.put(data(), new Date().getTime());
                req.onsuccess = function(){
                    console.info(req.result);
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Cursor and list all items in the object store": {
        "code": function(){
            $.indexedDB("BookShop1").objectStore("BookList").openCursor().each(console.info);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                var bookList = transaction.objectStore("BookList");
                var req = bookList.openCursor();
                req.onsuccess = function(){
                    var cursor = req.result;
                    if (cursor) {
                        console.info(req.result.value);
                        cursor["continue"]();
                    }
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Cursor and delete items with price that is an odd number": {
        "code": function(){
            $.indexedDB("BookShop1").objectStore("BookList").openCursor().deleteEach(function(value, key){
                if (value && value.price % 2) {
                    console.info("Deleting", value);
                    return true;
                }
            });
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                var bookList = transaction.objectStore("BookList");
                var req = bookList.openCursor();
                req.onsuccess = function(){
                    var cursor = req.result;
                    if (cursor) {
                        if (cursor.value && cursor.value.price % 2) {
                            console.info("Deleting", cursor.value);
                            cursor["delete"]();
                        }
                        cursor["continue"]();
                    }
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Cursor and update items with price that is an odd number": {
        "code": function(){
            $.indexedDB("BookShop1").objectStore("BookList").openCursor().updateEach(function(value){
                if (value && value.price % 2) {
                    value["modified-" + Math.random()] = true;
                    console.info("Updating", value);
                    return value;
                }
            });
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                var bookList = transaction.objectStore("BookList");
                var req = bookList.openCursor();
                req.onsuccess = function(){
                    var cursor = req.result;
                    if (cursor) {
                        if (cursor.value && cursor.value.price % 2) {
                            cursor.value["modified-" + Math.random()] = true;
                            console.info("Updating", cursor.value);
                            cursor.update(cursor.value);
                        }
                        cursor["continue"]();
                    }
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },
    "Open an Index and iterate over its objects": {
        "code": function(){
            $.indexedDB("BookShop1").objectStore("BookList").index("price").openCursor().each(console.info);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                var bookList = transaction.objectStore("BookList");
                // Assuming that index exists
                var index = bookList.index("price-index");
                var req = index.openCursor();
                req.onsuccess = function(){
                    var cursor = req.result;
                    if (cursor) {
                        console.info(cursor.value);
                        cursor["continue"]();
                    }
                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    },

    "Open a key cursor on an Index and iterate over its objects": {
        "code": function(){
            $.indexedDB("BookShop1").objectStore("BookList").index("price").openKeyCursor([200, 500]).each(console.info);
        },
        "alternate": function(){
            var request = window.indexedDB.open("BookShop1");
            request.onsuccess = function(event){
                var db = request.result;
                var transaction = db.transaction([], IDBTransaction.READ_WRITE);
                var bookList = transaction.objectStore("BookList");
                var index = bookList.index("price-index");
                var range = new IDBKeyRange.bound(200, 500, true, true);
                var req = index.openKeyCursor(range);
                req.onsuccess = function(){
                    var cursor = req.result;
                    if (cursor) {
                        console.info(cursor.value, cursor.key);
                        cursor["continue"]();
                    }

                };
                req.onerror = function(e){
                    console.error(e, req);
                };
            };
            request.onerror = function(e){
                console.error(e, request);
            };
        }
    }
};
<|endoftext|>


<commit_before>'use strict'

const fs = require('fs')
const path = require('path')

const del = require('del')
const gitRevSync = require('git-rev-sync')
const ghpages = require('gh-pages')
const gulp = require('gulp')
const $ = require('gulp-load-plugins')()

const pkg = require('./package.json')

const paths = {
  dist: 'public',
  html: 'public/**/.html',
  images: 'public/**/*',
  scripts: 'app/**/*.js',
  styles: 'app/**/*.scss'
}

gulp.task('default', ['lint', 'watch'])
gulp.task('lint', ['standard', 'sass-lint'])
gulp.task('minify', ['htmlmin', 'imagemin'])
gulp.task('watch', ['watch:html', 'watch:scripts', 'watch:styles'])

gulp.task('clean', () => (del(paths.dist)))

gulp.task('htmlhint', () => {
  return gulp.src(paths.html)
    .pipe($.htmlhint())
    .pipe($.htmlhint.failReporter())
})

gulp.task('standard', () => {
  return gulp.src(paths.scripts)
    .pipe($.standard())
    .pipe($.standard.reporter('default', {
      breakOnError: true
    }))
})

gulp.task('sass-lint', () => {
  return gulp.src(paths.styles)
    .pipe($.sassLint())
    .pipe($.sassLint.format())
    .pipe($.sassLint.failOnError())
})

gulp.task('watch:html', () => {
  return gulp.src(paths.html)
    .pipe($.watch(paths.html))
    .pipe($.plumber())
    .pipe($.htmlhint())
    .pipe($.htmlhint.reporter())
})

gulp.task('watch:scripts', () => {
  return gulp.src(paths.scripts)
    .pipe($.watch(paths.scripts))
    .pipe($.plumber())
    .pipe($.standard())
    .pipe($.standard.reporter('default'))
})

gulp.task('watch:styles', () => {
  return gulp.src(paths.styles)
    .pipe($.watch(paths.styles))
    .pipe($.plumber())
    .pipe($.sassLint())
    .pipe($.sassLint.format())
})

gulp.task('imagemin', () => {
  return gulp.src(paths.images)
    .pipe($.imagemin())
    .pipe(gulp.dest(paths.dist))
})

gulp.task('htmlmin', () => {
  return gulp.src(paths.html)
    .pipe($.htmlmin({
      collapseBooleanAttributes: true,
      collapseWhitespace: true,
      preserveLineBreaks: true,
      removeComments: true,
      removeScriptTypeAttributes: true,
      removeStyleLinkTypeAttributes: true,
      minifyCSS: true,
      minifyJS: true
    }))
    .pipe(gulp.dest(paths.dist))
})

gulp.task('deploy', (done) => {
  fs.openSync(path.join(paths.dist, '.nojekyll'), 'w')

  return ghpages.publish(paths.dist, {
    clone: '.deploy',
    depth: 2,
    dotfiles: true,
    message: `Deploy ${gitRevSync.short()} from v${pkg.version} [ci skip]`,
    repo: process.env.DEPLOY_REPO || `git@github.com:${pkg.repository}.git`,
    branch: process.env.DEPLOY_BRANCH || 'gh-pages',
    logger: (message) => { console.log(`[ deploy ] ${message}`) },
    user: {
      name: process.env.DEPLOY_NAME || pkg.author.name,
      email: process.env.DEPLOY_EMAIL || pkg.author.email
    }
  }, done)
})
<commit_msg>Fix html path in gulpfile<commit_after>'use strict'

const fs = require('fs')
const path = require('path')

const del = require('del')
const gitRevSync = require('git-rev-sync')
const ghpages = require('gh-pages')
const gulp = require('gulp')
const $ = require('gulp-load-plugins')()

const pkg = require('./package.json')

const paths = {
  dist: 'public',
  html: 'public/**/*.html',
  images: 'public/**/*',
  scripts: 'app/**/*.js',
  styles: 'app/**/*.scss'
}

gulp.task('default', ['lint', 'watch'])
gulp.task('lint', ['standard', 'sass-lint'])
gulp.task('minify', ['htmlmin', 'imagemin'])
gulp.task('watch', ['watch:html', 'watch:scripts', 'watch:styles'])

gulp.task('clean', () => (del(paths.dist)))

gulp.task('htmlhint', () => {
  return gulp.src(paths.html)
    .pipe($.htmlhint())
    .pipe($.htmlhint.failReporter())
})

gulp.task('standard', () => {
  return gulp.src(paths.scripts)
    .pipe($.standard())
    .pipe($.standard.reporter('default', {
      breakOnError: true
    }))
})

gulp.task('sass-lint', () => {
  return gulp.src(paths.styles)
    .pipe($.sassLint())
    .pipe($.sassLint.format())
    .pipe($.sassLint.failOnError())
})

gulp.task('watch:html', () => {
  return gulp.src(paths.html)
    .pipe($.watch(paths.html))
    .pipe($.plumber())
    .pipe($.htmlhint())
    .pipe($.htmlhint.reporter())
})

gulp.task('watch:scripts', () => {
  return gulp.src(paths.scripts)
    .pipe($.watch(paths.scripts))
    .pipe($.plumber())
    .pipe($.standard())
    .pipe($.standard.reporter('default'))
})

gulp.task('watch:styles', () => {
  return gulp.src(paths.styles)
    .pipe($.watch(paths.styles))
    .pipe($.plumber())
    .pipe($.sassLint())
    .pipe($.sassLint.format())
})

gulp.task('imagemin', () => {
  return gulp.src(paths.images)
    .pipe($.imagemin())
    .pipe(gulp.dest(paths.dist))
})

gulp.task('htmlmin', () => {
  return gulp.src(paths.html)
    .pipe($.htmlmin({
      collapseBooleanAttributes: true,
      collapseWhitespace: true,
      preserveLineBreaks: true,
      removeComments: true,
      removeScriptTypeAttributes: true,
      removeStyleLinkTypeAttributes: true,
      minifyCSS: true,
      minifyJS: true
    }))
    .pipe(gulp.dest(paths.dist))
})

gulp.task('deploy', (done) => {
  fs.openSync(path.join(paths.dist, '.nojekyll'), 'w')

  return ghpages.publish(paths.dist, {
    clone: '.deploy',
    depth: 2,
    dotfiles: true,
    message: `Deploy ${gitRevSync.short()} from v${pkg.version} [ci skip]`,
    repo: process.env.DEPLOY_REPO || `git@github.com:${pkg.repository}.git`,
    branch: process.env.DEPLOY_BRANCH || 'gh-pages',
    logger: (message) => { console.log(`[ deploy ] ${message}`) },
    user: {
      name: process.env.DEPLOY_NAME || pkg.author.name,
      email: process.env.DEPLOY_EMAIL || pkg.author.email
    }
  }, done)
})
<|endoftext|>


<commit_before>'use strict';

describe('directives', function () {
  var $compile;
  var $rootScope;
  var element;
  var scope;
  var mockConfig;

  beforeEach(module('uchiwa'));
  beforeEach(module('partials'));

  beforeEach(function() {
    mockConfig = jasmine.createSpyObj('mockConfig', ['dateFormat', 'defaultTheme', 'logoURL']);
    mockConfig.dateFormat.and.callFake(function() {return 'YYYY-MM-DD HH:mm:ss'});
    mockConfig.defaultTheme.and.callFake(function() {return 'uchiwa-default'});
    mockConfig.logoURL.and.callFake(function() {return 'http://127.0.0.1/foo.png'});
    module(function($provide) {
      $provide.value('Config', mockConfig);
    });
  });

  beforeEach(inject(function (_$compile_, _$rootScope_, $httpBackend) {
    $compile = _$compile_;
    $httpBackend.whenGET('config').respond([]);
    //$httpBackend.whenGET('partials/directives/client-summary.html?v=0.23.0').respond([]);
    $rootScope = _$rootScope_;
    $rootScope.partialsPath = 'partials';
    $rootScope.versionParam = '';
    element = jasmine.createSpyObj('element', ['tooltip', 'attr', 'removeAttr', 'addClass']);
    scope = jasmine.createSpyObj('scope', ['$on', '$watch']);
  }));

  describe('clientSummary', function() {
    it('ignores redundant keys in the client data and handles images', function(){
      scope = $rootScope.$new();
      element = $compile('<client-summary client="{{client}}"></client-summary>')(scope);
      scope.client = {dc: 'foo', image: 'https://uchiwa.io/dashboard.jpg', version: '0.20.4'};
      scope.$digest();

      expect(scope.clientSummary).toEqual({version: '0.20.4'});
      expect(scope.clientImages[0].value).toBe('');
      expect(element.find('img').eq(0).attr('src')).toBe('https://uchiwa.io/dashboard.jpg');
    });
  });

  describe('logoUrl', function() {
    it('returns the default logo', function(){
      scope = $rootScope.$new();
      element = $compile('<logo-url></logo-url>')(scope);
      scope.$digest();

      expect(element.find('img').eq(0).attr('src')).toBe('http://127.0.0.1/foo.png');
    });
  });

  describe('siteTheme', function () {
    it('should be restricted to elements and attributes', inject(function (siteThemeDirective) {
      expect(siteThemeDirective[0].restrict).toBe('EA');
    }));

    it('should have a link method', inject(function (siteThemeDirective) {
      expect(siteThemeDirective[0].link).toBeDefined();
    }));

    it('should define themes', inject(function (siteThemeDirective) {
      siteThemeDirective[0].link(scope, element);
      expect(scope.currentTheme).toBeDefined();
    }));

    it('should listen for theme:changed event', inject(function (siteThemeDirective) {
      siteThemeDirective[0].link(scope, element);
      expect(scope.$on).toHaveBeenCalledWith('theme:changed', jasmine.any(Function));
    }));
  });

  describe('statusGlyph', function () {
    it('should be restricted to elements and attributes', inject(function (statusGlyphDirective) {
      expect(statusGlyphDirective[0].restrict).toBe('EA');
    }));

    it('should have a link method', inject(function (statusGlyphDirective) {
      expect(statusGlyphDirective[0].link).toBeDefined();
    }));
  });
});
<commit_msg>Cleanup<commit_after>'use strict';

describe('directives', function () {
  var $compile;
  var $rootScope;
  var element;
  var scope;
  var mockConfig;

  beforeEach(module('uchiwa'));
  beforeEach(module('partials'));

  beforeEach(function() {
    mockConfig = jasmine.createSpyObj('mockConfig', ['dateFormat', 'defaultTheme', 'logoURL']);
    mockConfig.dateFormat.and.callFake(function() {return 'YYYY-MM-DD HH:mm:ss'});
    mockConfig.defaultTheme.and.callFake(function() {return 'uchiwa-default'});
    mockConfig.logoURL.and.callFake(function() {return 'http://127.0.0.1/foo.png'});
    module(function($provide) {
      $provide.value('Config', mockConfig);
    });
  });

  beforeEach(inject(function (_$compile_, _$rootScope_, $httpBackend) {
    $compile = _$compile_;
    $httpBackend.whenGET('config').respond([]);
    $rootScope = _$rootScope_;
    $rootScope.partialsPath = 'partials';
    $rootScope.versionParam = '';
    element = jasmine.createSpyObj('element', ['tooltip', 'attr', 'removeAttr', 'addClass']);
    scope = jasmine.createSpyObj('scope', ['$on', '$watch']);
  }));

  describe('clientSummary', function() {
    it('ignores redundant keys in the client data and handles images', function(){
      scope = $rootScope.$new();
      element = $compile('<client-summary client="{{client}}"></client-summary>')(scope);
      scope.client = {dc: 'foo', image: 'https://uchiwa.io/dashboard.jpg', version: '0.20.4'};
      scope.$digest();

      expect(scope.clientSummary).toEqual({version: '0.20.4'});
      expect(scope.clientImages[0].value).toBe('');
      expect(element.find('img').eq(0).attr('src')).toBe('https://uchiwa.io/dashboard.jpg');
    });
  });

  describe('logoUrl', function() {
    it('returns the default logo', function(){
      scope = $rootScope.$new();
      element = $compile('<logo-url></logo-url>')(scope);
      scope.$digest();

      expect(element.find('img').eq(0).attr('src')).toBe('http://127.0.0.1/foo.png');
    });
  });

  describe('siteTheme', function () {
    it('should be restricted to elements and attributes', inject(function (siteThemeDirective) {
      expect(siteThemeDirective[0].restrict).toBe('EA');
    }));

    it('should have a link method', inject(function (siteThemeDirective) {
      expect(siteThemeDirective[0].link).toBeDefined();
    }));

    it('should define themes', inject(function (siteThemeDirective) {
      siteThemeDirective[0].link(scope, element);
      expect(scope.currentTheme).toBeDefined();
    }));

    it('should listen for theme:changed event', inject(function (siteThemeDirective) {
      siteThemeDirective[0].link(scope, element);
      expect(scope.$on).toHaveBeenCalledWith('theme:changed', jasmine.any(Function));
    }));
  });

  describe('statusGlyph', function () {
    it('should be restricted to elements and attributes', inject(function (statusGlyphDirective) {
      expect(statusGlyphDirective[0].restrict).toBe('EA');
    }));

    it('should have a link method', inject(function (statusGlyphDirective) {
      expect(statusGlyphDirective[0].link).toBeDefined();
    }));
  });
});
<|endoftext|>


<commit_before>const gulp = require('gulp');
const replace = require('gulp-replace');
const yaml = require('gulp-yaml');
const del = require('del');
const connect = require('gulp-connect');
const shell = require('gulp-shell')

const swaggerRoot = 'specs/maas-v1.json'

// Wait for clean:docs to finish to avoid filesystem errors
gulp.task('copy-swagger-ui', ['clean:docs'], function() {
  // Copies everything
  return gulp.src(['node_modules/swagger-ui-dist/*', '!node_modules/swagger-ui-dist/index.html'])
    .pipe(gulp.dest('docs'));
});

// Wait for clean:docs to finish to avoid filesystem errors
gulp.task('copy-specs', ['clean:docs'], function() {
  return gulp.src(['specs/**/*.json', 'specs/**/*.png', 'specs/**/*.svg'])
    .pipe(gulp.dest('docs/specs'));
});

gulp.task('watch-specs', function() {
  gulp.watch(['specs/**/*.yml'], ['clean:docs', 'transform-yaml', 'copy-swagger-ui', 'copy-specs']);
})

gulp.task('transform-yaml', function() {
  return gulp.src('./specs/*.yml')
    .pipe(yaml({ safe: true, space: 2 }))
    .pipe(gulp.dest('./specs/'))
});

gulp.task('clean:docs', function () {
  return del(['docs/*', '!docs/index.html']);
});

gulp.task('serve', function() {
  return connect.server({
    root: 'docs',
    livereload: true
  });
});

gulp.task(
  'create-temp-gh-pages-deployment-branch',
  shell.task(
    [
      'git checkout -b gh-pages-tmp',
      'rm .gitignore'
    ]
  )
)

gulp.task(
  'deploy-temp-gh-pages-deployment-branch',
  shell.task(
    [
      'git checkout -b gh-pages-tmp',
      'mv .gitignore .gitignore.backup',
      'git add .',
      'git commit -am "Remove gitignore; add built docs"',
      // Push the docs folder to the Github Pages branch
      'git subtree push --prefix docs upstream gh-pages',
    ]
  )
)

gulp.task(
  'delete-temp-gh-pages-deployment-branch',
  shell.task(
    [
      // TODO: change the following line to 'git checkout master' after test
      'git checkout gh-pages-deploy-script',
      'git branch --delete gh-pages-tmp',
      'mv .gitignore.backup .gitignore'
    ]
  )
)

// Aliases

gulp.task('docs', ['copy-swagger-ui', 'copy-specs']);
gulp.task('build', ['transform-yaml']);
gulp.task('clean', ['clean:docs']);
gulp.task('watch', ['watch-specs']);
gulp.task('deploy', [
  'create-temp-gh-pages-deployment-branch',
  'deploy-temp-gh-pages-deployment-branch',
  'delete-temp-gh-pages-deployment-branch',
])
<commit_msg>Move .gitignore rather than delete<commit_after>const gulp = require('gulp');
const replace = require('gulp-replace');
const yaml = require('gulp-yaml');
const del = require('del');
const connect = require('gulp-connect');
const shell = require('gulp-shell')

const swaggerRoot = 'specs/maas-v1.json'

// Wait for clean:docs to finish to avoid filesystem errors
gulp.task('copy-swagger-ui', ['clean:docs'], function() {
  // Copies everything
  return gulp.src(['node_modules/swagger-ui-dist/*', '!node_modules/swagger-ui-dist/index.html'])
    .pipe(gulp.dest('docs'));
});

// Wait for clean:docs to finish to avoid filesystem errors
gulp.task('copy-specs', ['clean:docs'], function() {
  return gulp.src(['specs/**/*.json', 'specs/**/*.png', 'specs/**/*.svg'])
    .pipe(gulp.dest('docs/specs'));
});

gulp.task('watch-specs', function() {
  gulp.watch(['specs/**/*.yml'], ['clean:docs', 'transform-yaml', 'copy-swagger-ui', 'copy-specs']);
})

gulp.task('transform-yaml', function() {
  return gulp.src('./specs/*.yml')
    .pipe(yaml({ safe: true, space: 2 }))
    .pipe(gulp.dest('./specs/'))
});

gulp.task('clean:docs', function () {
  return del(['docs/*', '!docs/index.html']);
});

gulp.task('serve', function() {
  return connect.server({
    root: 'docs',
    livereload: true
  });
});

gulp.task(
  'create-temp-gh-pages-deployment-branch',
  shell.task(
    [
      'git checkout -b gh-pages-tmp',
      'mv .gitignore .gitignore.backup'
    ]
  )
)

gulp.task(
  'deploy-temp-gh-pages-deployment-branch',
  shell.task(
    [
      'git checkout -b gh-pages-tmp',
      'mv .gitignore .gitignore.backup',
      'git add .',
      'git commit -am "Remove gitignore; add built docs"',
      // Push the docs folder to the Github Pages branch
      'git subtree push --prefix docs upstream gh-pages',
    ]
  )
)

gulp.task(
  'delete-temp-gh-pages-deployment-branch',
  shell.task(
    [
      // TODO: change the following line to 'git checkout master' after test
      'git checkout gh-pages-deploy-script',
      'git branch --delete gh-pages-tmp',
      'mv .gitignore.backup .gitignore'
    ]
  )
)

// Aliases

gulp.task('docs', ['copy-swagger-ui', 'copy-specs']);
gulp.task('build', ['transform-yaml']);
gulp.task('clean', ['clean:docs']);
gulp.task('watch', ['watch-specs']);
gulp.task('deploy', [
  'create-temp-gh-pages-deployment-branch',
  'deploy-temp-gh-pages-deployment-branch',
  'delete-temp-gh-pages-deployment-branch',
])
<|endoftext|>


<commit_before>import React from 'react';
import {
  Switch,
  Route
} from 'react-router-dom';
import MixpanelUtils from '../app/assets/javascripts/helpers/mixpanel_utils.jsx';
import HomePage from '../app/assets/javascripts/home/HomePage';
import EducatorPage from '../app/assets/javascripts/educator/EducatorPage';
import TieringPage from '../app/assets/javascripts/tiering/TieringPage';
import SchoolCoursesPage from '../app/assets/javascripts/school_courses/SchoolCoursesPage';>>>>>>> origin/master

// This is the top-level component, only handling routing.
// The core model is still "new page, new load," this just
// handles routing on initial page load for JS code.
class App extends React.Component {
  // This is mostly for testing, and provides a fn to read the time
  // in any deeply nested component.
  // Note that `context` should be avoided in general, and that the API
  // is changing in upcoming React releases: https://reactjs.org/docs/context.html
  getChildContext() {
    return {
      nowFn() { return moment.utc(); }
    };
  }

  // Read which educator Rails wrote inline in the HTML page,
  // and report routing activity for analytics (eg, MixPanel)
  // TODO(kr) could do this as a higher-order component
  // to remove having to do this manually for each route.
  trackVisit(routeProps, pageKey) {
    const {currentEducator} = this.props;
    MixpanelUtils.registerUser(currentEducator);
    MixpanelUtils.track('PAGE_VISIT', { page_key: pageKey });
  }

  // Expects serializedData and navbar, see `ui#ui` on the server
  // side.
  render() {
    return (
      <Switch>
        <Route exact path="/schools/:id/courses" render={this.renderSchoolCoursesPage.bind(this)}/>
        <Route exact path="/educators/view/:id" render={this.renderEducatorPage.bind(this)}/>
        <Route exact path="/home" render={this.renderHomePage.bind(this)}/>
        <Route exact path="/tiering/:school_id" render={this.renderTieringPage.bind(this)}/>
        <Route render={() => this.renderNotFound()} />
      </Switch>
    );
  }

  renderHomePage(routeProps) {
    const {currentEducator} = this.props;
    this.trackVisit(routeProps, 'HOME_PAGE');
    return <HomePage educatorId={currentEducator.id} />;
  }

  renderSchoolCoursesPage(routeProps) {
    const schoolId = routeProps.match.params.id;
    this.trackVisit(routeProps, 'SCHOOL_COURSES_PAGE');
    return <SchoolCoursesPage schoolId={schoolId} />;
  }

  renderEducatorPage(routeProps) {
    const educatorId = parseInt(routeProps.match.params.id, 10);
    this.trackVisit(routeProps, 'EDUCATOR_PAGE');
    return <EducatorPage educatorId={educatorId} />;
  }

  renderTieringPage(routeProps) {
    const schoolId = routeProps.match.params.school_id;
    this.trackVisit(routeProps, 'TIERING_PAGE');
    return <TieringPage schoolId={schoolId} />;
  }

  // Ignore this, since we're hybrid client/server and perhaps the
  // server has rendered something and the client-side app just doesn't
  // know about it.
  renderNotFound() {
    console.warn('App: 404'); // eslint-disable-line no-console
    return null;
  }
}
App.childContextTypes = {
  nowFn: React.PropTypes.func
};
App.propTypes = {
  currentEducator: React.PropTypes.shape({
    id: React.PropTypes.number.isRequired,
    school_id: React.PropTypes.number.isRequired,
    admin: React.PropTypes.bool.isRequired
  }).isRequired
};

export default App;<commit_msg>Fix bad merge<commit_after>import React from 'react';
import {
  Switch,
  Route
} from 'react-router-dom';
import MixpanelUtils from '../app/assets/javascripts/helpers/mixpanel_utils.jsx';
import HomePage from '../app/assets/javascripts/home/HomePage';
import EducatorPage from '../app/assets/javascripts/educator/EducatorPage';
import TieringPage from '../app/assets/javascripts/tiering/TieringPage';
import SchoolCoursesPage from '../app/assets/javascripts/school_courses/SchoolCoursesPage';

// This is the top-level component, only handling routing.
// The core model is still "new page, new load," this just
// handles routing on initial page load for JS code.
class App extends React.Component {
  // This is mostly for testing, and provides a fn to read the time
  // in any deeply nested component.
  // Note that `context` should be avoided in general, and that the API
  // is changing in upcoming React releases: https://reactjs.org/docs/context.html
  getChildContext() {
    return {
      nowFn() { return moment.utc(); }
    };
  }

  // Read which educator Rails wrote inline in the HTML page,
  // and report routing activity for analytics (eg, MixPanel)
  // TODO(kr) could do this as a higher-order component
  // to remove having to do this manually for each route.
  trackVisit(routeProps, pageKey) {
    const {currentEducator} = this.props;
    MixpanelUtils.registerUser(currentEducator);
    MixpanelUtils.track('PAGE_VISIT', { page_key: pageKey });
  }

  // Expects serializedData and navbar, see `ui#ui` on the server
  // side.
  render() {
    return (
      <Switch>
        <Route exact path="/schools/:id/courses" render={this.renderSchoolCoursesPage.bind(this)}/>
        <Route exact path="/educators/view/:id" render={this.renderEducatorPage.bind(this)}/>
        <Route exact path="/home" render={this.renderHomePage.bind(this)}/>
        <Route exact path="/tiering/:school_id" render={this.renderTieringPage.bind(this)}/>
        <Route render={() => this.renderNotFound()} />
      </Switch>
    );
  }

  renderHomePage(routeProps) {
    const {currentEducator} = this.props;
    this.trackVisit(routeProps, 'HOME_PAGE');
    return <HomePage educatorId={currentEducator.id} />;
  }

  renderSchoolCoursesPage(routeProps) {
    const schoolId = routeProps.match.params.id;
    this.trackVisit(routeProps, 'SCHOOL_COURSES_PAGE');
    return <SchoolCoursesPage schoolId={schoolId} />;
  }

  renderEducatorPage(routeProps) {
    const educatorId = parseInt(routeProps.match.params.id, 10);
    this.trackVisit(routeProps, 'EDUCATOR_PAGE');
    return <EducatorPage educatorId={educatorId} />;
  }

  renderTieringPage(routeProps) {
    const schoolId = routeProps.match.params.school_id;
    this.trackVisit(routeProps, 'TIERING_PAGE');
    return <TieringPage schoolId={schoolId} />;
  }

  // Ignore this, since we're hybrid client/server and perhaps the
  // server has rendered something and the client-side app just doesn't
  // know about it.
  renderNotFound() {
    console.warn('App: 404'); // eslint-disable-line no-console
    return null;
  }
}
App.childContextTypes = {
  nowFn: React.PropTypes.func
};
App.propTypes = {
  currentEducator: React.PropTypes.shape({
    id: React.PropTypes.number.isRequired,
    school_id: React.PropTypes.number.isRequired,
    admin: React.PropTypes.bool.isRequired
  }).isRequired
};

export default App;<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var tape = require('tape');
var tapeCluster = require('tape-cluster');

var RelayNetwork = require('./relay_network.js');

HyperbahnCluster.test = tapeCluster(tape, HyperbahnCluster);

// TODO merge RelayNetwork into this
module.exports = HyperbahnCluster;

/*  This class is just to have the same interface as the
    hyperbahn cluster for sharing tests between tchannel
    and hyperbahn.

    cluster: {
        remotes: {
            steve: TChannel,
            bob: TChannel
        },
        logger: Logger,
        hostPortList: Array<String>
    }

*/
function HyperbahnCluster(options) {
    if (!(this instanceof HyperbahnCluster)) {
        return new HyperbahnCluster(options);
    }

    var self = this;

    self.size = options.size;

    self.relayNetwork = RelayNetwork({
        numRelays: self.size,
        numInstancesPerService: self.size,
        kValue: 5,
        serviceNames: ['bob', 'steve', 'mary'],
        cluster: options.cluster
    });

    self.remotes = {};
    self.logger = null;
    self.hostPortList = null;
}

HyperbahnCluster.prototype.bootstrap = function bootstrap(cb) {
    var self = this;

    self.relayNetwork.bootstrap(onBootstrap);

    function onBootstrap(err) {
        if (err) {
            return cb(err);
        }

        var relayNetwork = self.relayNetwork;
        self.logger = self.relayNetwork.cluster.logger;

        self.remotes.steve = HyperbahnRemote({
            subChannel: relayNetwork.subChannelsByName.steve[0]
        });
        self.remotes.bob = HyperbahnRemote({
            subChannel: relayNetwork.subChannelsByName.bob[0]
        });
        self.hostPortList = relayNetwork.relayChannels.map(function p(c) {
            return c.hostPort;
        });

        cb();
    }
};

HyperbahnCluster.prototype.checkExitPeers =
function checkExitPeers(assert, options) {
    // TODO implement
};

HyperbahnCluster.prototype.close = function close(cb) {
    var self = this;

    self.relayNetwork.close(cb);
};

function HyperbahnRemote(opts) {
    if (!(this instanceof HyperbahnRemote)) {
        return new HyperbahnRemote(opts);
    }

    var self = this;

    self.serviceName = opts.subChannel.serviceName;
    self.channel = opts.subChannel.topChannel;
    self.clientChannel = opts.subChannel;
}
<commit_msg>test/hyperbahn-cluster: use only one remote for determism<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var tape = require('tape');
var tapeCluster = require('tape-cluster');

var RelayNetwork = require('./relay_network.js');

HyperbahnCluster.test = tapeCluster(tape, HyperbahnCluster);

// TODO merge RelayNetwork into this
module.exports = HyperbahnCluster;

/*  This class is just to have the same interface as the
    hyperbahn cluster for sharing tests between tchannel
    and hyperbahn.

    cluster: {
        remotes: {
            steve: TChannel,
            bob: TChannel
        },
        logger: Logger,
        hostPortList: Array<String>
    }

*/
function HyperbahnCluster(options) {
    if (!(this instanceof HyperbahnCluster)) {
        return new HyperbahnCluster(options);
    }

    var self = this;

    self.size = options.size;

    self.relayNetwork = RelayNetwork({
        numRelays: self.size,
        numInstancesPerService: 1,
        kValue: 5,
        serviceNames: ['bob', 'steve', 'mary'],
        cluster: options.cluster
    });

    self.remotes = {};
    self.logger = null;
    self.hostPortList = null;
}

HyperbahnCluster.prototype.bootstrap = function bootstrap(cb) {
    var self = this;

    self.relayNetwork.bootstrap(onBootstrap);

    function onBootstrap(err) {
        if (err) {
            return cb(err);
        }

        var relayNetwork = self.relayNetwork;
        self.logger = self.relayNetwork.cluster.logger;

        self.remotes.steve = HyperbahnRemote({
            subChannel: relayNetwork.subChannelsByName.steve[0]
        });
        self.remotes.bob = HyperbahnRemote({
            subChannel: relayNetwork.subChannelsByName.bob[0]
        });
        self.hostPortList = relayNetwork.relayChannels.map(function p(c) {
            return c.hostPort;
        });

        cb();
    }
};

HyperbahnCluster.prototype.checkExitPeers =
function checkExitPeers(assert, options) {
    // TODO implement
};

HyperbahnCluster.prototype.close = function close(cb) {
    var self = this;

    self.relayNetwork.close(cb);
};

function HyperbahnRemote(opts) {
    if (!(this instanceof HyperbahnRemote)) {
        return new HyperbahnRemote(opts);
    }

    var self = this;

    self.serviceName = opts.subChannel.serviceName;
    self.channel = opts.subChannel.topChannel;
    self.clientChannel = opts.subChannel;
}
<|endoftext|>


<commit_before>var del = require('del');
var gulp = require('gulp');
var concat = require('gulp-concat');
var jshint = require('gulp-jshint');
var uglify = require('gulp-uglify');
var zip = require('gulp-zip');
var pkg = require('./package.json');
var Server = require('karma').Server;

var app = {
    html: [
        'app/*.html'
    ],
    css: [
        'app/*.css'
    ],
    js: [
        'app/app.js',
        'app/**/*.js'
    ]
};

var vendor = {
    css: [
        'node_modules/bootstrap/dist/css/bootstrap.min.css'
    ],
    js: [
        'node_modules/angular/angular.min.js',
        'node_modules/jquery/dist/jquery.min.js',
        'node_modules/bootstrap/dist/js/bootstrap.min.js'
    ],
    fonts: [
        'node_modules/bootstrap/dist/fonts/*'
    ]
};

var dist = {
    html: 'public/',
    css: 'public/css/',
    js: 'public/js/',
    fonts: 'public/fonts/'
};

gulp.task('clean', (done) => {
    del('public/');
    done();
});

gulp.task('vendor', (done) => {
    gulp.src(vendor.js)
        .pipe(gulp.dest(dist.js));

    gulp.src(vendor.css)
        .pipe(gulp.dest(dist.css));

    gulp.src(vendor.fonts)
        .pipe(gulp.dest(dist.fonts));

    done();
});

gulp.task('app', (done) => {
    gulp.src(app.html)
        .pipe(gulp.dest(dist.html));

    gulp.src(app.js)
        .pipe(jshint())
        .pipe(jshint.reporter('default'))
        .pipe(concat('app.min.js'))
        .pipe(uglify())
        .pipe(gulp.dest(dist.js));

    gulp.src(app.css)
        .pipe(gulp.dest(dist.css));

    done();
});

gulp.task('compress', gulp.series('app', 'vendor', (done) => {
    gulp.src('public/**/*')
        .pipe(zip('asmsimulator-' + pkg.version + '.zip'))
        .pipe(gulp.dest('dist/'));

    done();
}));

gulp.task('test', (done) => {
    new Server({
      configFile: __dirname + '/karma.conf.js',
      singleRun: true
    }, done).start();
});

gulp.task('default', gulp.series('app', 'vendor'));
<commit_msg>Improve gulpfile.js<commit_after>var del = require('del');
var gulp = require('gulp');
var concat = require('gulp-concat');
var jshint = require('gulp-jshint');
var uglify = require('gulp-uglify');
var zip = require('gulp-zip');
var pkg = require('./package.json');
var Server = require('karma').Server;

var app = {
    html: [
        'app/*.html'
    ],
    css: [
        'app/*.css'
    ],
    js: [
        'app/app.js',
        'app/**/*.js'
    ]
};

var vendor = {
    css: [
        'node_modules/bootstrap/dist/css/bootstrap.min.css'
    ],
    js: [
        'node_modules/angular/angular.min.js',
        'node_modules/jquery/dist/jquery.min.js',
        'node_modules/bootstrap/dist/js/bootstrap.min.js'
    ],
    fonts: [
        'node_modules/bootstrap/dist/fonts/*'
    ]
};

var dist = {
    html: 'public/',
    css: 'public/css/',
    js: 'public/js/',
    fonts: 'public/fonts/'
};

gulp.task('clean', () => {
    return del('public/');
});

gulp.task('build:vendor:js', () => {
    return gulp.src(vendor.js)
        .pipe(gulp.dest(dist.js));
});

gulp.task('build:vendor:css', () => {
    return gulp.src(vendor.css)
        .pipe(gulp.dest(dist.css));
});

gulp.task('build:vendor:fonts', () => {
    return gulp.src(vendor.fonts)
        .pipe(gulp.dest(dist.fonts));
});

gulp.task('build:vendor', gulp.parallel(
    'build:vendor:js',
    'build:vendor:css',
    'build:vendor:fonts'
));

gulp.task('build:app:html', () => {
    return gulp.src(app.html)
        .pipe(gulp.dest(dist.html));
});

gulp.task('build:app:js', () => {
    return gulp.src(app.js)
        .pipe(jshint())
        .pipe(jshint.reporter('default'))
        .pipe(concat('app.min.js'))
        .pipe(uglify())
        .pipe(gulp.dest(dist.js));
});

gulp.task('build:app:css', () => {
    return gulp.src(app.css)
        .pipe(gulp.dest(dist.css));
});

gulp.task('build:app', gulp.parallel(
    'build:app:html',
    'build:app:js',
    'build:app:css'
));

gulp.task('default', gulp.parallel('build:vendor', 'build:app'));

gulp.task('compress', gulp.series('default', () => {
    return gulp.src('public/**/*')
        .pipe(zip('asmsimulator-' + pkg.version + '.zip'))
        .pipe(gulp.dest('./dist/'));
}));

gulp.task('test', (done) => {
    new Server({
      configFile: __dirname + '/karma.conf.js',
      singleRun: true
    }, done).start();
});
<|endoftext|>


<commit_before>/*global beforeEach describe it*/
import { expect } from "chai";
import sinon from "sinon";
import addProxies from "../../../src/lib/server/addProxies";

describe("lib/server/addProxies", function () {
  let mockApp;
  beforeEach(() => {
    mockApp = {
      use: sinon.spy()
    };
  });

  it("should add proxies to express app", () => {
    const proxies = [
      {
        path: "/api",
        destination: "http://www.test.com/api",
        options: {
          test: "yes"
        }
      },
      {
        path: "/api2",
        destination: "http://www.test2.com/api",
        options: {
          test: "yes"
        }
      }
    ];
    addProxies(mockApp, proxies);
    expect(mockApp.use.calledWith("/api")).to.equal(true);
    expect(mockApp.use.calledWith("/api2")).to.equal(true);
    expect(mockApp.use.calledWith("/not")).to.equal(false);
  });

  it("should pass the correct proxy arguments when creating a proxy", () => {
    const mockExpressHttpProxy = sinon.spy();
    const proxyConfig = {
      path: "/api",
      destination: "http://www.test.com/api",
      options: {
        test: "yes"
      }
    };
    addProxies(mockApp, [proxyConfig], mockExpressHttpProxy);
    expect(mockExpressHttpProxy.called).to.equal(true);
    console.log("### # ## ###", mockExpressHttpProxy.lastCall.args);
    expect(mockExpressHttpProxy.lastCall.args[0].test).to.equal(proxyConfig.options.test);
  });

  it("should use the default forwardPath option for you when creating the proxy", () => {
    const mockExpressHttpProxy = sinon.spy();
    const mockRequest = sinon.stub();
    mockRequest.url = "/todos";
    const proxyConfig = {
      path: "/api",
      destination: "http://www.test.com/api",
      options: {
        test: "yes"
      }
    };
    addProxies(mockApp, [proxyConfig], mockExpressHttpProxy);
    expect(mockExpressHttpProxy.lastCall.args[0].pathRewrite).to.deep.equal({[`^${proxyConfig.path}`]: ""});
  });

  it("should allow you to override pathRewrite", () => {
    const mockExpressHttpProxy = sinon.spy();
    const pathRewrite = {"^/api": "/API"};
    const proxyConfig = {
      path: "/api",
      destination: "http://www.test.com/api",
      options: {
        test: "yes",
        pathRewrite
      }
    };
    addProxies(mockApp, [proxyConfig], mockExpressHttpProxy);
    expect(mockExpressHttpProxy.lastCall.args[0].pathRewrite).to.equal(pathRewrite);
  });
});

<commit_msg>remove log<commit_after>/*global beforeEach describe it*/
import { expect } from "chai";
import sinon from "sinon";
import addProxies from "../../../src/lib/server/addProxies";

describe("lib/server/addProxies", function () {
  let mockApp;
  beforeEach(() => {
    mockApp = {
      use: sinon.spy()
    };
  });

  it("should add proxies to express app", () => {
    const proxies = [
      {
        path: "/api",
        destination: "http://www.test.com/api",
        options: {
          test: "yes"
        }
      },
      {
        path: "/api2",
        destination: "http://www.test2.com/api",
        options: {
          test: "yes"
        }
      }
    ];
    addProxies(mockApp, proxies);
    expect(mockApp.use.calledWith("/api")).to.equal(true);
    expect(mockApp.use.calledWith("/api2")).to.equal(true);
    expect(mockApp.use.calledWith("/not")).to.equal(false);
  });

  it("should pass the correct proxy arguments when creating a proxy", () => {
    const mockExpressHttpProxy = sinon.spy();
    const proxyConfig = {
      path: "/api",
      destination: "http://www.test.com/api",
      options: {
        test: "yes"
      }
    };
    addProxies(mockApp, [proxyConfig], mockExpressHttpProxy);
    expect(mockExpressHttpProxy.called).to.equal(true);
    expect(mockExpressHttpProxy.lastCall.args[0].test).to.equal(proxyConfig.options.test);
  });

  it("should use the default forwardPath option for you when creating the proxy", () => {
    const mockExpressHttpProxy = sinon.spy();
    const mockRequest = sinon.stub();
    mockRequest.url = "/todos";
    const proxyConfig = {
      path: "/api",
      destination: "http://www.test.com/api",
      options: {
        test: "yes"
      }
    };
    addProxies(mockApp, [proxyConfig], mockExpressHttpProxy);
    expect(mockExpressHttpProxy.lastCall.args[0].pathRewrite).to.deep.equal({[`^${proxyConfig.path}`]: ""});
  });

  it("should allow you to override pathRewrite", () => {
    const mockExpressHttpProxy = sinon.spy();
    const pathRewrite = {"^/api": "/API"};
    const proxyConfig = {
      path: "/api",
      destination: "http://www.test.com/api",
      options: {
        test: "yes",
        pathRewrite
      }
    };
    addProxies(mockApp, [proxyConfig], mockExpressHttpProxy);
    expect(mockExpressHttpProxy.lastCall.args[0].pathRewrite).to.equal(pathRewrite);
  });
});

<|endoftext|>