<commit_before>/**
 * @fileOverview Nukes and populates the test db.
 */
var Kansas = require('kansas');
var Promise = require('bluebird');
var kansas = new Kansas({
  prefix: 'kansas-metrics-test',
});

var log = kansas.logger.getLogger('kansas-metrics.test.initdb');

/**
 * Nukes and populates the test db.
 *
 * @constructor
 */
var Initdb = module.exports = function () {
  /** @type {Redis} Redis client */
  this.redis = kansas.conn;
};

/**
 * Start the nuking and population process.
 *
 * @return {Promise} A promise.
 */
Initdb.prototype.start = Promise.method(function() {
  log.fine('start() :: Init...');

  return this.nuke()
    .bind(this)
    .then(this.populateUsage);
});

/**
 * Nuke the keys created.
 *
 * @return {Promise} A promise.
 */
Initdb.prototype.nuke = function() {
  return kansas.db.nuke('Yes purge all records irreversably', 'kansas-metrics-test');
};

Initdb.prototype.populateUsage = function() {

};

<commit_msg>globalize db name on test initdb<commit_after>/**
 * @fileOverview Nukes and populates the test db.
 */
var Kansas = require('kansas');
var Promise = require('bluebird');

/** @const {string} The db prefix name */
var DB_NAME = 'kansas-metrics-test';

var kansas = new Kansas({
  prefix: DB_NAME,
});

var log = kansas.logger.getLogger('kansas-metrics.test.initdb');

/**
 * Nukes and populates the test db.
 *
 * @constructor
 */
var Initdb = module.exports = function () {
  /** @type {Redis} Redis client */
  this.redis = kansas.conn;

  this.kansasInitdb = new Kansas.Initdb();
  this.kansasInitdb.dbName = DB_NAME;
};

/**
 * Start the nuking and population process.
 *
 * @return {Promise} A promise.
 */
Initdb.prototype.start = Promise.method(function() {
  log.fine('start() :: Init...');

  return this.nuke()
    .bind(this)
    .then(this.populateUsage);
});

/**
 * Nuke the keys created.
 *
 * @return {Promise} A promise.
 */
Initdb.prototype.nuke = function() {
  return kansas.db.nuke('Yes purge all records irreversably', 'kansas-metrics-test');
};

Initdb.prototype.populateUsage = function() {

};

<|endoftext|>


<commit_before>import MixinTypes from '../utils/MixinTypes'

/**
 * Evaluates if a media condition is fulfilled by using window.matchMedia
 * NOTE: This won't work on server-side by default
 */
export default [{
	key: '@media',
	type: MixinTypes.BEGINWITH,
	fn: (key, styles, args) => {
		//Check if browser supports window.matchMedia
		let matchMedia = typeof window !== 'undefined' ? window.matchMedia : undefined
		if (matchMedia !== undefined) {
			if (!args.Component._mediaQueryListener) {
				args.Component._mediaQueryListener = () => {
					args.Component.forceUpdate()
				}
				window.addEventListener('resize', args.Component_mediaQueryListener)

				//Remove the listener if the component unmounts to keep things clean
				args.Component.componentWillUnmount = () => {
					args.Component.componentWillUnmount()
					window.removeEventListener(args.Component._mediauQueryListener)
				}
			}

			if (matchMedia(key.replace('@media', '').trim()).matches) {
				return styles
			} else {
				return false
			}
		} else {
			console.warn('Failed evaluating media query: ' + key + '. Your environment is not able to use window.matchMedia.');
			return false
		}
	}
}]<commit_msg>shortened media query mixin<commit_after>import MixinTypes from '../utils/MixinTypes'

/**
 * Evaluates if a media condition is fulfilled by using window.matchMedia
 * NOTE: This won't work on server-side by default
 */
export default [{
	key: '@media',
	type: MixinTypes.BEGINWITH,
	fn: (key, styles, args) => {
		//Check if browser supports window.matchMedia
		let matchMedia = typeof window !== 'undefined' ? window.matchMedia : undefined
		if (matchMedia !== undefined) {
			if (!args.Component._mediaQueryListener) {
				args.Component._mediaQueryListener = () => {
					args.Component.forceUpdate()
				}
				window.addEventListener('resize', args.Component_mediaQueryListener)

				//Remove the listener if the component unmounts to keep things clean
				args.Component.componentWillUnmount = () => {
					args.Component.componentWillUnmount()
					window.removeEventListener(args.Component._mediauQueryListener)
				}
			}
			return matchMedia(key.replace('@media', '').trim()).matches ? styles : false
		} else {
			console.warn('Failed evaluating media query: ' + key + '. Your environment is not able to use window.matchMedia.');
			return false
		}
	}
}]<|endoftext|>


<commit_before>/*
 * SystemJS Core
 * Code should be vaguely readable
 *
 */
function core(loader) {

  /*
    __useDefault

    When a module object looks like:
    newModule({
      __useDefault: true,
      default: 'some-module'
    })

    Then importing that module provides the 'some-module'
    result directly instead of the full module.

    Useful for eg module.exports = function() {}
  */
  var loaderImport = loader['import'];
  loader['import'] = function(name, options) {
    return loaderImport.call(this, name, options).then(function(module) {
      return module.__useDefault ? module['default'] : module;
    });
  }

  // support the empty module, as a concept
  loader.set('@empty', loader.newModule({}));

  // include the node require since we're overriding it
  if (typeof require != 'undefined')
    loader._nodeRequire = require;

  /*
    Config
    Extends config merging one deep only

    loader.config({
      some: 'random',
      config: 'here',
      deep: {
        config: { too: 'too' }
      }
    });

    <=>

    loader.some = 'random';
    loader.config = 'here'
    loader.deep = loader.deep || {};
    loader.deep.config = { too: 'too' };
  */
  loader.config = function(cfg) {
    for (var c in cfg) {
      var v = cfg[c];
      if (typeof v == 'object' && !(v instanceof Array)) {
        this[c] = this[c] || {};
        for (var p in v)
          this[c][p] = v[p];
      }
      else
        this[c] = v;
    }
  }

  // override locate to allow baseURL to be document-relative
  var baseURI;
  if (typeof window == 'undefined' &&
      typeof WorkerGlobalScope == 'undefined') {
    baseURI = 'file:' + process.cwd() + '/';
  }
  // Inside of a Web Worker
  else if(typeof window == 'undefined') {
    baseURI = loader.global.location.href;
  }
  else {
    baseURI = document.baseURI;
    if (!baseURI) {
      var bases = document.getElementsByTagName('base');
      baseURI = bases[0] && bases[0].href || window.location.href;
    }
  }

  var loaderLocate = loader.locate;
  var normalizedBaseURL;
  loader.locate = function(load) {
    if (this.baseURL != normalizedBaseURL) {
      normalizedBaseURL = toAbsoluteURL(baseURI, this.baseURL);

      if (normalizedBaseURL.substr(normalizedBaseURL.length - 1, 1) != '/')
        normalizedBaseURL += '/';
      this.baseURL = normalizedBaseURL;
    }

    return Promise.resolve(loaderLocate.call(this, load));
  }

  // Traceur conveniences
  // good enough ES6 detection regex - format detections not designed to be accurate, but to handle the 99% use case
  var es6RegEx = /(^\s*|[}\);\n]\s*)(import\s+(['"]|(\*\s+as\s+)?[^"'\(\)\n;]+\s+from\s+['"]|\{)|export\s+\*\s+from\s+["']|export\s+(\{|default|function|class|var|const|let|async\s+function))/;

  var traceurRuntimeRegEx = /\$traceurRuntime/;

  var loaderTranslate = loader.translate;
  loader.translate = function(load) {
    var loader = this;

    if (load.name == '@traceur' || load.name == '@traceur-runtime')
      return loaderTranslate.call(loader, load);

    // detect ES6
    else if (load.metadata.format == 'es6' || !load.metadata.format && load.source.match(es6RegEx)) {
      load.metadata.format = 'es6';

      // dynamically load Traceur for ES6 if necessary
      if (!loader.global.traceur) {
        return loader['import']('@traceur').then(function() {
          return loaderTranslate.call(loader, load);
        });
      }
    }

    // dynamicallly load Traceur runtime if necessary
    if (!loader.global.$traceurRuntime && load.source.match(traceurRuntimeRegEx)) {
      return loader['import']('@traceur-runtime').then(function() {
        return loaderTranslate.call(loader, load);
      });
    }

    return loaderTranslate.call(loader, load);
  }

  // always load Traceur as a global
  var loaderInstantiate = loader.instantiate;
  loader.instantiate = function(load) {
    var loader = this;
    if (load.name == '@traceur' || load.name == '@traceur-runtime') {
      loader.__exec(load);
      return {
        deps: [],
        execute: function() {
          return loader.newModule({});
        }
      };
    }
    return loaderInstantiate.call(loader, load);
  }
}
<commit_msg>ensure Traceur runtime doesnt override System<commit_after>/*
 * SystemJS Core
 * Code should be vaguely readable
 *
 */
function core(loader) {

  /*
    __useDefault

    When a module object looks like:
    newModule({
      __useDefault: true,
      default: 'some-module'
    })

    Then importing that module provides the 'some-module'
    result directly instead of the full module.

    Useful for eg module.exports = function() {}
  */
  var loaderImport = loader['import'];
  loader['import'] = function(name, options) {
    return loaderImport.call(this, name, options).then(function(module) {
      return module.__useDefault ? module['default'] : module;
    });
  }

  // support the empty module, as a concept
  loader.set('@empty', loader.newModule({}));

  // include the node require since we're overriding it
  if (typeof require != 'undefined')
    loader._nodeRequire = require;

  /*
    Config
    Extends config merging one deep only

    loader.config({
      some: 'random',
      config: 'here',
      deep: {
        config: { too: 'too' }
      }
    });

    <=>

    loader.some = 'random';
    loader.config = 'here'
    loader.deep = loader.deep || {};
    loader.deep.config = { too: 'too' };
  */
  loader.config = function(cfg) {
    for (var c in cfg) {
      var v = cfg[c];
      if (typeof v == 'object' && !(v instanceof Array)) {
        this[c] = this[c] || {};
        for (var p in v)
          this[c][p] = v[p];
      }
      else
        this[c] = v;
    }
  }

  // override locate to allow baseURL to be document-relative
  var baseURI;
  if (typeof window == 'undefined' &&
      typeof WorkerGlobalScope == 'undefined') {
    baseURI = 'file:' + process.cwd() + '/';
  }
  // Inside of a Web Worker
  else if(typeof window == 'undefined') {
    baseURI = loader.global.location.href;
  }
  else {
    baseURI = document.baseURI;
    if (!baseURI) {
      var bases = document.getElementsByTagName('base');
      baseURI = bases[0] && bases[0].href || window.location.href;
    }
  }

  var loaderLocate = loader.locate;
  var normalizedBaseURL;
  loader.locate = function(load) {
    if (this.baseURL != normalizedBaseURL) {
      normalizedBaseURL = toAbsoluteURL(baseURI, this.baseURL);

      if (normalizedBaseURL.substr(normalizedBaseURL.length - 1, 1) != '/')
        normalizedBaseURL += '/';
      this.baseURL = normalizedBaseURL;
    }

    return Promise.resolve(loaderLocate.call(this, load));
  }

  // Traceur conveniences
  // good enough ES6 detection regex - format detections not designed to be accurate, but to handle the 99% use case
  var es6RegEx = /(^\s*|[}\);\n]\s*)(import\s+(['"]|(\*\s+as\s+)?[^"'\(\)\n;]+\s+from\s+['"]|\{)|export\s+\*\s+from\s+["']|export\s+(\{|default|function|class|var|const|let|async\s+function))/;

  var traceurRuntimeRegEx = /\$traceurRuntime/;

  var loaderTranslate = loader.translate;
  loader.translate = function(load) {
    var loader = this;

    if (load.name == '@traceur' || load.name == '@traceur-runtime')
      return loaderTranslate.call(loader, load);

    // detect ES6
    else if (load.metadata.format == 'es6' || !load.metadata.format && load.source.match(es6RegEx)) {
      load.metadata.format = 'es6';

      // dynamically load Traceur for ES6 if necessary
      if (!loader.global.traceur) {
        return loader['import']('@traceur').then(function() {
          return loaderTranslate.call(loader, load);
        });
      }
    }

    // dynamicallly load Traceur runtime if necessary
    if (!loader.global.$traceurRuntime && load.source.match(traceurRuntimeRegEx)) {
      var System = $__global.System;
      return loader['import']('@traceur-runtime').then(function() {
        // traceur runtme annihilates System global
        $__global.System = System;
        return loaderTranslate.call(loader, load);
      });
    }

    return loaderTranslate.call(loader, load);
  }

  // always load Traceur as a global
  var loaderInstantiate = loader.instantiate;
  loader.instantiate = function(load) {
    var loader = this;
    if (load.name == '@traceur' || load.name == '@traceur-runtime') {
      loader.__exec(load);
      return {
        deps: [],
        execute: function() {
          return loader.newModule({});
        }
      };
    }
    return loaderInstantiate.call(loader, load);
  }
}
<|endoftext|>


<commit_before>'use strict';
var assert = require('chai').assert;
var fs = require('fs');
var path = require('path');
var Mode = require('stat-mode');
var rm = require('rimraf').sync;
var equal = require('assert-dir-equal');
var exec = require('child_process').exec;
var fixture = path.resolve.bind(path, __dirname, 'fixtures');

var Librarian = require('../');

describe('Librarian', function(){

    var NOOP = function(){};

    it('should expose constructor', function(){
        assert.isFunction(Librarian);
    });

    it('should not require new keyword', function(){
        var l = Librarian();
        assert.instanceOf(l, Librarian);
    });

    it('should have a DEFAULTS object', function(){
        assert.isObject(Librarian.DEFAULTS);
    });

    it('should take an options object', function(){
        var options = {directory:'my-directory'};
        var l = Librarian(options);
        assert.ok(l.directory(), 'my-directory');
    });

    it('should take a single string argument that will be the working directory', function(){
        //this might change!
        var l = Librarian('my-directory');
        assert.ok(l.directory(), 'my-directory');
    });

    describe('∆ use', function(){
        it('should add plugin to stack', function(){
            var l = Librarian();
            l.use(NOOP);
            assert.equal(l._plugins.length, 1);
        });
    });

    describe('∆ directory', function(){

        it('should set a working directory by default equal to process.env.PWD', function(){
            var l = Librarian();
            assert.equal(l.directory(), process.env.PWD);
        });

        it('should set the working directory', function(){
            var l = Librarian({directory:'dir'});
            assert.ok(l.directory(), 'dir');
        });

        it('should respect absolute directories', function(){
            var l = Librarian({directory:'/dir'});
            assert.ok(l.directory(), '/dir');
        });
    });

    describe('∆ source', function(){
        it('should set a "source" directory in DEFAULTS', function(){
            var l = Librarian();
            assert.ok(l.source(), Librarian.DEFAULTS.source);
        });

        it('should set the "source" directory', function(){
            var l = Librarian({source:'dir'});
            assert.ok(l.directory(), 'dir');
        });

        it('should get full path of source directory', function(){
            var l = Librarian();
            var absoluteBuildPath = path.join(process.env.PWD, '/build');
            assert.ok(l.source(), absoluteBuildPath);
        });

        it('should respect absolute directories', function(){
            var l = Librarian({source:'/dir'});
            assert.ok(l.source(), '/dir');
        });

        it('should throw on non strings', function(){
            var l = Librarian();
            assert.throws(function(){
                l.source(23);
            });
        });
    });

    describe('∆ destination', function(){
        it('should set a destination directory in DEFAULTS', function(){
            var l = Librarian();
            assert.ok(l.destination(), Librarian.DEFAULTS.destination);
        });

        it('should get full path of destination directory', function(){
            var l = Librarian();
            var absoluteBuildPath = path.join(process.env.PWD, '/build');
            assert.ok(l.destination(), absoluteBuildPath);
        });

        it('should respect absolute directories', function(){
            var l = Librarian({destination:'/dir'});
            assert.ok(l.destination(), '/dir');
        });

        it('should throw on non strings', function(){
            var l = Librarian();
            assert.throws(function(){
                l.destination(23);
            });
        });
    });

    describe('∆ clean', function(){
        it('should set the "clean" default used in DEFAULTS', function(){
            var l = Librarian();
            assert.equal(l._clean, Librarian.DEFAULTS.clean);
        });

        it('should set the "clean" option', function(){
            var l = Librarian();
            l.clean(false);
            assert.equal(l.clean(), false);
        });

        it('should throw on on boolean', function(){
            var l = Librarian();
            assert.throws(function(){
                l.clean(23);
            });
        });
    });

    describe('∆ debug', function(){
        it('should set the "debug" default used in DEFAULTS', function(){
            var l = Librarian();
            assert.equal(l._debug, Librarian.DEFAULTS.debug);
        });

        it('should set the "clean" option', function(){
            var l = Librarian();
            l.debug(false);
            assert.equal(l.debug(), false);
        });

        it('should throw on on boolean', function(){
            var l = Librarian();
            assert.throws(function(){
                l.debug(23);
            });
        });
    });

    describe('∆ frontmatter', function(){
        it('should set the "frontmatter" default used in DEFAULTS', function(){
            var l = Librarian();
            assert.equal(l.frontmatter(), Librarian.DEFAULTS.frontmatter);
        });

        it('should initialize the "frontmatter" option', function(){
            var l = Librarian({frontmatter: true});
            assert.equal(l.frontmatter(), true)
        });

        it('should set the "frontmatter"', function(){
            var l = Librarian();
            l.frontmatter(true);
            assert.equal(l.frontmatter(), true)
        });

        it('should throw on on boolean', function(){
            var l = Librarian();
            assert.throws(function(){
                l.frontmatter(23);
            });
        });
    });

    describe('∆ metadata', function(){
        it('should set the "metadata" default used in DEFAULTS', function(){
            var l = Librarian();
            assert.deepEqual(l.metadata(), Librarian.DEFAULTS.metadata);
        });

        it('should initialize the "metadata" option', function(){
            var meta = {
                user: 'goliatone',
                url:'http://goliatone.com'
            };

            var l = Librarian({metadata: meta});
            assert.deepEqual(l.metadata(), meta);
        });

        it('should get "metadata"', function(){
            var l = Librarian();
            assert.deepEqual(l.metadata(), {});
        });

        it('should set "metadata" clone', function(){
            var meta = {
                user: 'goliatone',
                url:'http://goliatone.com'
            };
            var l = Librarian();
            l.metadata(meta);
            assert.notEqual(l.metadata(), meta);
            assert.deepEqual(l.metadata(), meta);
        });
    });

    describe('∆ attributes', function(){
        it('should set the "attributes" default used in DEFAULTS', function(){
            var l = Librarian();
            assert.deepEqual(l._attributes, Librarian.DEFAULTS.attributes);
        });

        it('should initialize the "attributes" option', function(){
            var attributes = ['stats', 'content'];
            var l = Librarian({attributes: attributes});
            assert.ok(l.attributes(), attributes);
        });

        it('should get "attributes" option', function(){
            var l = Librarian();
            assert.deepEqual(l.attributes(), Librarian.DEFAULTS.attributes);
        });

        it('should set "attributes" option', function(){
            var l = Librarian();
            var attributes = ['stats', 'content'];
            l.attributes(attributes);
            assert.ok(l.attributes(), attributes);
        });
    });

    describe('∆ path', function(){
        it('should return a path relative to the working directory', function(){
            var l = Librarian({source:'test/tmp'});
            var rel = l.path('one', 'two', 'three');
            assert.ok(rel, '/test/tmp/one/two/three');
        });
    });

    describe('∆ read', function(){
        it('should read from a source directory', function(done){
            var l = Librarian({
                directory: fixture('read')
            });
            var stats = fs.statSync(fixture('read/src/index.md'));

            l.read(function(err, files){
                if(err) return done(err);
                assert.ok(files, {
                    'index.md': {
                        title: 'A Title',
                        contents: new Buffer('body'),
                        mode: stats.mode.toString(8).slice(-4),
                        stats:stats,
                        isUtf8: true
                    }
                });
                done();
            });
        });

        it('should read from a provided directory', function(done){
            var l = Librarian({
                directory: fixture('read-dir')
            });
            var stats = fs.statSync(fixture('read-dir/dir/index.md'));
            var dir = fixture('read-dir/dir');
            l.read(dir, function(err, files){
                if(err) done(err);
                assert.ok(files, {
                    'index.md': {
                        title: 'A Title',
                        contents: new Buffer('body'),
                        mode: stats.mode.toString(8).slice(-4),
                        stats:stats,
                        isUtf8: true
                    }
                });
            });
            done();
        });

        it('should preserve an existing file mode', function(done){
            var l = Librarian({
                directory: fixture('read-mode')
            });
            var stats = fs.statSync(fixture('read-mode/src/bin'));

            l.read(function(err, files){
                if(err) done(err);
                assert.ok(files, {
                    'bin': {
                        contents: new Buffer('echo test'),
                        mode: stats.mode.toString(8).slice(-4),
                        stats: stats,
                        isUtf8: false
                    }
                });
            });
            done();
        });

        describe('should expose isUtf8 "metadata" property', function(){
            it('should be false for binary files', function(done){
                var l = Librarian({
                    directory: fixture('read-isUtf8-false')
                });

                l.read(function(err, files){
                    if(err) done(err);
                    assert.isFalse(files['image.png'].isUtf8);
                });
                done();
            });

            it('should be true for text files', function(done){
                var l = Librarian({
                    directory: fixture('read-isUtf8-true')
                });

                l.read(function(err, files){
                    if(err) done(err);
                    assert.isTrue(files['index.md'].isUtf8);
                });
                done();
            });
        });

        it('should expose attributes in each file "metadata"', function(done){
            var l = Librarian({
                directory: fixture('expose-attributes')
            });
            l.read(function(err, files){
                if(err) done(err);
                var file = files['index.md'];
                Librarian.DEFAULTS.attributes.map(function(attr){
                    assert.property(file, attr, attr);
                });
            });
            done();
        });

        it('should not parse front-matter if "frontmatter" is false', function(done){
            var l = Librarian({
                directory: fixture('read-frontmatter'),
                frontmatter: false
            });
            l.read(function(err, files){
                if(err) done(err);
                assert.isUndefined(files['index.md'].title);
            });
            done();
        });

        it('should throw if provided "source" does not exist', function(done){
            var l = Librarian({
                directory: 'this-should-never-ever-ever-exist'
            });
            l.read(function(err){
                assert(err);
                done();
            });
        });
    });

    describe('∆ write', function(){
        it('should write to a destination directory', function(done){
            var l = Librarian({
                directory: fixture('write')
            });
            var files = {'index.md':{contents: new Buffer('body')}};
            l.write(files, function(err){
                if(err) return done(err);
                equal(fixture('write/build'), fixture('write/expected'));
                done();
            });
        });

        it('should write to a provided directory', function(done){
            var l = Librarian({
                directory: fixture('write-dir')
            });
            var files = {'index.md':{contents: new Buffer('body')}};
            var dir = fixture('write-dir/out');
            l.write(files, dir, function(err){
                if(err) return done(err);
                equal(fixture('write-dir/out'), fixture('write-dir/expected'));
                done();
            });
        });

        it('should chmod an optional mode from file metadata', function(done){
            var l = Librarian({
                directory: fixture('write-mode')
            });
            var files = {
                'bin':{
                    contents: new Buffer('echo test'),
                    mode: '0777'
                }
            };

            l.write(files, function(err){
                if(err) return done(err);
                var stats = fs.statSync(fixture('write-mode/build/bin'));
                var mode = Mode(stats).toOctal();
                assert.equal(mode, '0777');
                done();
            });
        });
    });

    describe('∆ run', function(){
        it('should apply a plugin', function(done){
            var l = Librarian();
            l.use(plugin);
            l.run({one: 'one'}, function(err, files, lbr){
                assert.property(files, 'one');
                assert.property(files, 'two');
                done();
            });

            function plugin(files, lbr, next){
                assert.property(files, 'one');
                assert.equal(l, lbr);
                assert.isFunction(next);
                files.two = 'two';
                next();
            }
        });

        it('should run with a provided plugin', function(done){
            var l = Librarian();
            //TODO: Review, how does it work? run takes two args?!
            l.run({one:'one'}, [plugin], function(err, files, lbr){
                assert.property(files, 'one');
                assert.property(files, 'two');
                done();
            });

            function plugin(files, lbr, next){
                assert.property(files, 'one');
                assert.equal(l, lbr);
                assert.isFunction(next);
                files.two = 'two';
                next();
            }
        });

        it('should support synchronous plugins', function(done){
            var l = Librarian();
            l.use(plugin);
            l.run({one: 'one'}, function(err, files, lbr){
                assert.property(files, 'one');
                assert.property(files, 'two');
                done();
            });

            function plugin(files, lbr){
                assert.property(files, 'one');
                assert.equal(l, lbr);
                files.two = 'two';
            }
        });
    });

    describe('∆ build', function(){
        it('should do a basic copy with no plugins', function(done){
            Librarian({
                directory: fixture('basic')
                // ,debug:true
            }).build(function(err, files){
                if(err) return done(err);
                assert.isObject(files);
                equal(fixture('basic/build'), fixture('basic/expected'));
                done();
            });
        });
        it('should preserve binary files', function(done){
            Librarian({
                directory: fixture('basic-images')
            }).build(function(err, files){
                if(err) return done(err);
                assert.isObject(files);
                equal(fixture('basic-images/build'), fixture('basic-images/expected'));
                done();
            });
        });

        it('should apply a plugin', function(done){
            Librarian({
                directory: fixture('basic-plugin')
            }).use(function(files, lbr, next){
                Object.keys(files).forEach(function(file){
                    var data = files[file];
                    data.contents = new Buffer(data.title);
                });
                next();
            })
            .build(function(err, files){
                if(err) return done(err);
                assert.isObject(files);
                equal(fixture('basic-plugin/build'), fixture('basic-plugin/expected'));
                done();
            });
        });

        it('should remove an existing build directory', function(done){
            var l = Librarian({
                directory: fixture('build')
            });

            rm(fixture('build/build'));
            fs.mkdirSync(fixture('build/build'));

            exec('touch tests/fixtures/build/build/empty.md', function(err){
                if(err) return done(err);
                l.build(function(err){
                    if(err) return done(err);
                    equal(fixture('build/build'), fixture('build/expected'));
                    done();
                });
            });
        });

        it('should not remove an existing build directory if "clean" is false', function(done){
            var l = Librarian({
                directory: fixture('build-noclean'),
                clean: false
            });

            exec('mkdir -p tests/fixtures/build-noclean/build && \
             touch tests/fixtures/build-noclean/build/empty.md', function(err){
                if(err) return done(err);
                var files = {'index.md': {contents: new Buffer('body')}};
                l.build(function(err){
                    if(err) return done(err);
                    equal(fixture('build-noclean/build'), fixture('build-noclean/expected'));
                    done();
                });
            });
        });
    });

    describe('∆ debugBuild', function(){
        xit('should have configurable output path', function(){});
        xit('should generate metadata file', function(done){});
    });
});<commit_msg>TEST: Update references to tests<commit_after>'use strict';
var assert = require('chai').assert;
var fs = require('fs');
var path = require('path');
var Mode = require('stat-mode');
var rm = require('rimraf').sync;
var equal = require('assert-dir-equal');
var exec = require('child_process').exec;
var fixture = path.resolve.bind(path, __dirname, 'fixtures');

var Librarian = require('../');

describe('Librarian', function(){

    var NOOP = function(){};

    it('should expose constructor', function(){
        assert.isFunction(Librarian);
    });

    it('should not require new keyword', function(){
        var l = Librarian();
        assert.instanceOf(l, Librarian);
    });

    it('should have a DEFAULTS object', function(){
        assert.isObject(Librarian.DEFAULTS);
    });

    it('should take an options object', function(){
        var options = {directory:'my-directory'};
        var l = Librarian(options);
        assert.ok(l.directory(), 'my-directory');
    });

    it('should take a single string argument that will be the working directory', function(){
        //this might change!
        var l = Librarian('my-directory');
        assert.ok(l.directory(), 'my-directory');
    });

    describe('∆ use', function(){
        it('should add plugin to stack', function(){
            var l = Librarian();
            l.use(NOOP);
            assert.equal(l._plugins.length, 1);
        });
    });

    describe('∆ directory', function(){

        it('should set a working directory by default equal to process.env.PWD', function(){
            var l = Librarian();
            assert.equal(l.directory(), process.env.PWD);
        });

        it('should set the working directory', function(){
            var l = Librarian({directory:'dir'});
            assert.ok(l.directory(), 'dir');
        });

        it('should respect absolute directories', function(){
            var l = Librarian({directory:'/dir'});
            assert.ok(l.directory(), '/dir');
        });
    });

    describe('∆ source', function(){
        it('should set a "source" directory in DEFAULTS', function(){
            var l = Librarian();
            assert.ok(l.source(), Librarian.DEFAULTS.source);
        });

        it('should set the "source" directory', function(){
            var l = Librarian({source:'dir'});
            assert.ok(l.directory(), 'dir');
        });

        it('should get full path of source directory', function(){
            var l = Librarian();
            var absoluteBuildPath = path.join(process.env.PWD, '/build');
            assert.ok(l.source(), absoluteBuildPath);
        });

        it('should respect absolute directories', function(){
            var l = Librarian({source:'/dir'});
            assert.ok(l.source(), '/dir');
        });

        it('should throw on non strings', function(){
            var l = Librarian();
            assert.throws(function(){
                l.source(23);
            });
        });
    });

    describe('∆ destination', function(){
        it('should set a destination directory in DEFAULTS', function(){
            var l = Librarian();
            assert.ok(l.destination(), Librarian.DEFAULTS.destination);
        });

        it('should get full path of destination directory', function(){
            var l = Librarian();
            var absoluteBuildPath = path.join(process.env.PWD, '/build');
            assert.ok(l.destination(), absoluteBuildPath);
        });

        it('should respect absolute directories', function(){
            var l = Librarian({destination:'/dir'});
            assert.ok(l.destination(), '/dir');
        });

        it('should throw on non strings', function(){
            var l = Librarian();
            assert.throws(function(){
                l.destination(23);
            });
        });
    });

    describe('∆ clean', function(){
        it('should set the "clean" default used in DEFAULTS', function(){
            var l = Librarian();
            assert.equal(l._clean, Librarian.DEFAULTS.clean);
        });

        it('should set the "clean" option', function(){
            var l = Librarian();
            l.clean(false);
            assert.equal(l.clean(), false);
        });

        it('should throw on on boolean', function(){
            var l = Librarian();
            assert.throws(function(){
                l.clean(23);
            });
        });
    });

    describe('∆ debug', function(){
        it('should set the "debug" default used in DEFAULTS', function(){
            var l = Librarian();
            assert.equal(l._debug, Librarian.DEFAULTS.debug);
        });

        it('should set the "clean" option', function(){
            var l = Librarian();
            l.debug(false);
            assert.equal(l.debug(), false);
        });

        it('should throw on on boolean', function(){
            var l = Librarian();
            assert.throws(function(){
                l.debug(23);
            });
        });
    });

    describe('∆ frontmatter', function(){
        it('should set the "frontmatter" default used in DEFAULTS', function(){
            var l = Librarian();
            assert.equal(l.frontmatter(), Librarian.DEFAULTS.frontmatter);
        });

        it('should initialize the "frontmatter" option', function(){
            var l = Librarian({frontmatter: true});
            assert.equal(l.frontmatter(), true)
        });

        it('should set the "frontmatter"', function(){
            var l = Librarian();
            l.frontmatter(true);
            assert.equal(l.frontmatter(), true)
        });

        it('should throw on on boolean', function(){
            var l = Librarian();
            assert.throws(function(){
                l.frontmatter(23);
            });
        });
    });

    describe('∆ metadata', function(){
        it('should set the "metadata" default used in DEFAULTS', function(){
            var l = Librarian();
            assert.deepEqual(l.metadata(), Librarian.DEFAULTS.metadata);
        });

        it('should initialize the "metadata" option', function(){
            var meta = {
                user: 'goliatone',
                url:'http://goliatone.com'
            };

            var l = Librarian({metadata: meta});
            assert.deepEqual(l.metadata(), meta);
        });

        it('should get "metadata"', function(){
            var l = Librarian();
            assert.deepEqual(l.metadata(), {});
        });

        it('should set "metadata" clone', function(){
            var meta = {
                user: 'goliatone',
                url:'http://goliatone.com'
            };
            var l = Librarian();
            l.metadata(meta);
            assert.notEqual(l.metadata(), meta);
            assert.deepEqual(l.metadata(), meta);
        });
    });

    describe('∆ attributes', function(){
        it('should set the "attributes" default used in DEFAULTS', function(){
            var l = Librarian();
            assert.deepEqual(l._attributes, Librarian.DEFAULTS.attributes);
        });

        it('should initialize the "attributes" option', function(){
            var attributes = ['stats', 'content'];
            var l = Librarian({attributes: attributes});
            assert.ok(l.attributes(), attributes);
        });

        it('should get "attributes" option', function(){
            var l = Librarian();
            assert.deepEqual(l.attributes(), Librarian.DEFAULTS.attributes);
        });

        it('should set "attributes" option', function(){
            var l = Librarian();
            var attributes = ['stats', 'content'];
            l.attributes(attributes);
            assert.ok(l.attributes(), attributes);
        });
    });

    describe('∆ path', function(){
        it('should return a path relative to the working directory', function(){
            var l = Librarian({source:'test/tmp'});
            var rel = l.path('one', 'two', 'three');
            assert.ok(rel, '/test/tmp/one/two/three');
        });
    });

    describe('∆ read', function(){
        it('should read from a source directory', function(done){
            var l = Librarian({
                directory: fixture('read')
            });
            var stats = fs.statSync(fixture('read/src/index.md'));

            l.read(function(err, files){
                if(err) return done(err);
                assert.ok(files, {
                    'index.md': {
                        title: 'A Title',
                        contents: new Buffer('body'),
                        mode: stats.mode.toString(8).slice(-4),
                        stats:stats,
                        isUtf8: true
                    }
                });
                done();
            });
        });

        it('should read from a provided directory', function(done){
            var l = Librarian({
                directory: fixture('read-dir')
            });
            var stats = fs.statSync(fixture('read-dir/dir/index.md'));
            var dir = fixture('read-dir/dir');
            l.read(dir, function(err, files){
                if(err) done(err);
                assert.ok(files, {
                    'index.md': {
                        title: 'A Title',
                        contents: new Buffer('body'),
                        mode: stats.mode.toString(8).slice(-4),
                        stats:stats,
                        isUtf8: true
                    }
                });
            });
            done();
        });

        it('should preserve an existing file mode', function(done){
            var l = Librarian({
                directory: fixture('read-mode')
            });
            var stats = fs.statSync(fixture('read-mode/src/bin'));

            l.read(function(err, files){
                if(err) done(err);
                assert.ok(files, {
                    'bin': {
                        contents: new Buffer('echo test'),
                        mode: stats.mode.toString(8).slice(-4),
                        stats: stats,
                        isUtf8: false
                    }
                });
            });
            done();
        });

        describe('should expose isUtf8 "metadata" property', function(){
            it('should be false for binary files', function(done){
                var l = Librarian({
                    directory: fixture('read-isUtf8-false')
                });

                l.read(function(err, files){
                    if(err) done(err);
                    assert.isFalse(files['image.png'].isUtf8);
                });
                done();
            });

            it('should be true for text files', function(done){
                var l = Librarian({
                    directory: fixture('read-isUtf8-true')
                });

                l.read(function(err, files){
                    if(err) done(err);
                    assert.isTrue(files['index.md'].isUtf8);
                });
                done();
            });
        });

        it('should expose attributes in each file "metadata"', function(done){
            var l = Librarian({
                directory: fixture('expose-attributes')
            });
            l.read(function(err, files){
                if(err) done(err);
                var file = files['index.md'];
                Librarian.DEFAULTS.attributes.map(function(attr){
                    assert.property(file, attr, attr);
                });
            });
            done();
        });

        it('should not parse front-matter if "frontmatter" is false', function(done){
            var l = Librarian({
                directory: fixture('read-frontmatter'),
                frontmatter: false
            });
            l.read(function(err, files){
                if(err) done(err);
                assert.isUndefined(files['index.md'].title);
            });
            done();
        });

        it('should throw if provided "source" does not exist', function(done){
            var l = Librarian({
                directory: 'this-should-never-ever-ever-exist'
            });
            l.read(function(err){
                assert(err);
                done();
            });
        });
    });

    describe('∆ write', function(){
        it('should write to a destination directory', function(done){
            var l = Librarian({
                directory: fixture('write')
            });
            var files = {'index.md':{contents: new Buffer('body')}};
            l.write(files, function(err){
                if(err) return done(err);
                equal(fixture('write/build'), fixture('write/expected'));
                done();
            });
        });

        it('should write to a provided directory', function(done){
            var l = Librarian({
                directory: fixture('write-dir')
            });
            var files = {'index.md':{contents: new Buffer('body')}};
            var dir = fixture('write-dir/out');
            l.write(files, dir, function(err){
                if(err) return done(err);
                equal(fixture('write-dir/out'), fixture('write-dir/expected'));
                done();
            });
        });

        it('should chmod an optional mode from file metadata', function(done){
            var l = Librarian({
                directory: fixture('write-mode')
            });
            var files = {
                'bin':{
                    contents: new Buffer('echo test'),
                    mode: '0777'
                }
            };

            l.write(files, function(err){
                if(err) return done(err);
                var stats = fs.statSync(fixture('write-mode/build/bin'));
                var mode = Mode(stats).toOctal();
                assert.equal(mode, '0777');
                done();
            });
        });
    });

    describe('∆ run', function(){
        it('should apply a plugin', function(done){
            var l = Librarian();
            l.use(plugin);
            l.run({one: 'one'}, function(err, files, lbr){
                assert.property(files, 'one');
                assert.property(files, 'two');
                done();
            });

            function plugin(files, lbr, next){
                assert.property(files, 'one');
                assert.equal(l, lbr);
                assert.isFunction(next);
                files.two = 'two';
                next();
            }
        });

        it('should run with a provided plugin', function(done){
            var l = Librarian();
            //TODO: Review, how does it work? run takes two args?!
            l.run({one:'one'}, [plugin], function(err, files, lbr){
                assert.property(files, 'one');
                assert.property(files, 'two');
                done();
            });

            function plugin(files, lbr, next){
                assert.property(files, 'one');
                assert.equal(l, lbr);
                assert.isFunction(next);
                files.two = 'two';
                next();
            }
        });

        it('should support synchronous plugins', function(done){
            var l = Librarian();
            l.use(plugin);
            l.run({one: 'one'}, function(err, files, lbr){
                assert.property(files, 'one');
                assert.property(files, 'two');
                done();
            });

            function plugin(files, lbr){
                assert.property(files, 'one');
                assert.equal(l, lbr);
                files.two = 'two';
            }
        });
    });

    describe('∆ build', function(){
        it('should do a basic copy with no plugins', function(done){
            Librarian({
                directory: fixture('basic')
                // ,debug:true
            }).build(function(err, files){
                if(err) return done(err);
                assert.isObject(files);
                equal(fixture('basic/build'), fixture('basic/expected'));
                done();
            });
        });
        it('should preserve binary files', function(done){
            Librarian({
                directory: fixture('basic-images')
            }).build(function(err, files){
                if(err) return done(err);
                assert.isObject(files);
                equal(fixture('basic-images/build'), fixture('basic-images/expected'));
                done();
            });
        });

        it('should apply a plugin', function(done){
            Librarian({
                directory: fixture('basic-plugin')
            }).use(function(files, lbr, next){
                Object.keys(files).forEach(function(file){
                    var data = files[file];
                    data.contents = new Buffer(data.title);
                });
                next();
            })
            .build(function(err, files){
                if(err) return done(err);
                assert.isObject(files);
                equal(fixture('basic-plugin/build'), fixture('basic-plugin/expected'));
                done();
            });
        });

        it('should remove an existing build directory', function(done){
            var l = Librarian({
                directory: fixture('build')
            });

            rm(fixture('build/build'));
            fs.mkdirSync(fixture('build/build'));

            exec('touch test/fixtures/build/build/empty.md', function(err){
                if(err) return done(err);
                l.build(function(err){
                    if(err) return done(err);
                    equal(fixture('build/build'), fixture('build/expected'));
                    done();
                });
            });
        });

        it('should not remove an existing build directory if "clean" is false', function(done){
            var l = Librarian({
                directory: fixture('build-noclean'),
                clean: false
            });

            exec('mkdir -p test/fixtures/build-noclean/build && \
             touch test/fixtures/build-noclean/build/empty.md', function(err){
                if(err) return done(err);
                var files = {'index.md': {contents: new Buffer('body')}};
                l.build(function(err){
                    if(err) return done(err);
                    equal(fixture('build-noclean/build'), fixture('build-noclean/expected'));
                    done();
                });
            });
        });
    });

    describe('∆ debugBuild', function(){
        xit('should have configurable output path', function(){});
        xit('should generate metadata file', function(done){});
    });
});<|endoftext|>


<commit_before>'use strict';

const crypto = require('crypto');
const prompt = require('souffleur');
const rp = require('minimal-request-promise');
const fbReply = require('./reply');
const fbParse = require('./parse');
const validateFbRequestIntegrity = require('./validate-integrity');
const color = require('../console-colors');

module.exports = function fbSetup(api, bot, logError, optionalParser, optionalResponder) {
  let parser = optionalParser || fbParse;
  let responder = optionalResponder || fbReply;

  api.get('/facebook', request => {
    if (request.queryString['hub.verify_token'] === request.env.facebookVerifyToken)
      return request.queryString['hub.challenge'];

    logError(`Facebook can't verify the token. It expected '${request.env.facebookVerifyToken}', but got '${request.queryString['hub.verify_token']}'. Make sure you are using the same token you set in 'facebookVerifyToken' stage env variable.`);
    return 'Error';
  }, {success: {contentType: 'text/plain'}});

  api.post('/facebook', request => {
    // We are doing verification if FB Secret exist in env because we don't want to break old bots that forgot to add it
    if (request.env.facebookAppSecret && !validateFbRequestIntegrity(request))
      return Promise.reject('X-Hub-Signatures does not match');

    let arr = [].concat.apply([], request.body.entry.map(entry => entry.messaging));
    let fbHandle = parsedMessage => {
      if (parsedMessage) {
        var recipient = parsedMessage.sender;

        return Promise.resolve(parsedMessage).then(parsedMessage => bot(parsedMessage, request))
          .then(botResponse => responder(recipient, botResponse, request.env.facebookAccessToken))
          .catch(logError);
      }
    };

    return Promise.all(arr.map(message => parser(message)).map(fbHandle))
      .then(() => 'ok');
  });

  api.addPostDeployStep('facebook', (options, lambdaDetails, utils) => {
    return utils.Promise.resolve().then(() => {
      return utils.apiGatewayPromise.getStagePromise({
        restApiId: lambdaDetails.apiId,
        stageName: lambdaDetails.alias
      }).then(data => {
        if (options['configure-fb-bot']) {
          let token, pageAccessToken;

          utils.Promise.promisifyAll(crypto);

          return utils.Promise.resolve().then(() => {
            if (data.variables && data.variables.facebookVerifyToken)
              return data.variables.facebookVerifyToken;

            return crypto.randomBytesAsync(8);
          })
          .then(rawToken => {
            token = rawToken.toString('base64').replace(/[^A-Za-z0-9]/g, '');
            return utils.apiGatewayPromise.createDeploymentPromise({
              restApiId: lambdaDetails.apiId,
              stageName: lambdaDetails.alias,
              variables: {
                facebookVerifyToken: token
              }
            });
          })
          .then(() => {
            console.log(`\n\n${color.green}Facebook Messenger setup${color.reset}\n`);
            console.log(`\nFollowing info is required for the setup, for more info check the documentation.\n`);
            console.log(`\nYour webhook URL is: ${color.cyan}${lambdaDetails.apiUrl}/facebook${color.reset}\n`);
            console.log(`Your verify token is: ${color.cyan}${token}${color.reset}\n`);

            return prompt(['Facebook page access token', 'Facebook App Secret']);
          })
          .then(results => {
            console.log('\n');
            pageAccessToken = results['Facebook page access token'];
            const deployment = {
              restApiId: lambdaDetails.apiId,
              stageName: lambdaDetails.alias,
              variables: {
                facebookAccessToken: pageAccessToken,
                facebookAppSecret: results['Facebook App Secret']
              }
            };

            return utils.apiGatewayPromise.createDeploymentPromise(deployment);
          })
          .then(() => rp.post(`https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=${pageAccessToken}`));
        }

        if (!data.variables || !data.variables.facebookAppSecret)
          return console.log(`\n${color.yellow}Deprecation warning:${color.reset} your bot is not using facebook validation. Please re-run with --configure-fb to set the facebook it. This will become mandatory in the next major version. See https://github.com/claudiajs/claudia-bot-builder/blob/master/docs/API.md#message-verification for more information.\n`);
      });
    })
      .then(() => `${lambdaDetails.apiUrl}/facebook`);
  });
};
<commit_msg>Update missing Facebook payload validation deprecation notice text<commit_after>'use strict';

const crypto = require('crypto');
const prompt = require('souffleur');
const rp = require('minimal-request-promise');
const fbReply = require('./reply');
const fbParse = require('./parse');
const validateFbRequestIntegrity = require('./validate-integrity');
const color = require('../console-colors');

module.exports = function fbSetup(api, bot, logError, optionalParser, optionalResponder) {
  let parser = optionalParser || fbParse;
  let responder = optionalResponder || fbReply;

  api.get('/facebook', request => {
    if (request.queryString['hub.verify_token'] === request.env.facebookVerifyToken)
      return request.queryString['hub.challenge'];

    logError(`Facebook can't verify the token. It expected '${request.env.facebookVerifyToken}', but got '${request.queryString['hub.verify_token']}'. Make sure you are using the same token you set in 'facebookVerifyToken' stage env variable.`);
    return 'Error';
  }, {success: {contentType: 'text/plain'}});

  api.post('/facebook', request => {
    // We are doing verification if FB Secret exist in env because we don't want to break old bots that forgot to add it
    if (request.env.facebookAppSecret && !validateFbRequestIntegrity(request))
      return Promise.reject('X-Hub-Signatures does not match');

    let arr = [].concat.apply([], request.body.entry.map(entry => entry.messaging));
    let fbHandle = parsedMessage => {
      if (parsedMessage) {
        var recipient = parsedMessage.sender;

        return Promise.resolve(parsedMessage).then(parsedMessage => bot(parsedMessage, request))
          .then(botResponse => responder(recipient, botResponse, request.env.facebookAccessToken))
          .catch(logError);
      }
    };

    return Promise.all(arr.map(message => parser(message)).map(fbHandle))
      .then(() => 'ok');
  });

  api.addPostDeployStep('facebook', (options, lambdaDetails, utils) => {
    return utils.Promise.resolve().then(() => {
      return utils.apiGatewayPromise.getStagePromise({
        restApiId: lambdaDetails.apiId,
        stageName: lambdaDetails.alias
      }).then(data => {
        if (options['configure-fb-bot']) {
          let token, pageAccessToken;

          utils.Promise.promisifyAll(crypto);

          return utils.Promise.resolve().then(() => {
            if (data.variables && data.variables.facebookVerifyToken)
              return data.variables.facebookVerifyToken;

            return crypto.randomBytesAsync(8);
          })
          .then(rawToken => {
            token = rawToken.toString('base64').replace(/[^A-Za-z0-9]/g, '');
            return utils.apiGatewayPromise.createDeploymentPromise({
              restApiId: lambdaDetails.apiId,
              stageName: lambdaDetails.alias,
              variables: {
                facebookVerifyToken: token
              }
            });
          })
          .then(() => {
            console.log(`\n\n${color.green}Facebook Messenger setup${color.reset}\n`);
            console.log(`\nFollowing info is required for the setup, for more info check the documentation.\n`);
            console.log(`\nYour webhook URL is: ${color.cyan}${lambdaDetails.apiUrl}/facebook${color.reset}\n`);
            console.log(`Your verify token is: ${color.cyan}${token}${color.reset}\n`);

            return prompt(['Facebook page access token', 'Facebook App Secret']);
          })
          .then(results => {
            console.log('\n');
            pageAccessToken = results['Facebook page access token'];
            const deployment = {
              restApiId: lambdaDetails.apiId,
              stageName: lambdaDetails.alias,
              variables: {
                facebookAccessToken: pageAccessToken,
                facebookAppSecret: results['Facebook App Secret']
              }
            };

            return utils.apiGatewayPromise.createDeploymentPromise(deployment);
          })
          .then(() => rp.post(`https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=${pageAccessToken}`));
        }

        if (data.variables.facebookAccessToken && !data.variables.facebookAppSecret)
          return console.log(`\n${color.yellow}Deprecation warning:${color.reset} Your bot is not using facebook payload validation. Please re-run ${color.yellow}claudia update${color.reset} command with ${color.yellow}--configure-fb-bot${color.reset} flag to set the facebook app secret and enable payload validation. This will become mandatory in the next major version. See https://github.com/claudiajs/claudia-bot-builder/blob/master/docs/API.md#message-verification for more information.\n\n`);
      });
    })
      .then(() => `${lambdaDetails.apiUrl}/facebook`);
  });
};
<|endoftext|>


<commit_before>import { View, VARS, NO_VARS, PRE_COMPILED } from 'src/libs/view';
import Handlebars from '../../node_modules/handlebars/dist/handlebars';

describe('class View', () => {

	describe('method set/get', () => {

		it('should accept args as string and objects', () => {

			let view = new View({
				rootNode: document.createElement('div'),
			});

			view.set('foo', 1);
			view.set('bar', 2);
			view.set('baz', 3);

			// test
			view.get('foo').should.eql(1);
			view.get('bar').should.eql(2);
			view.get('baz').should.eql(3);

			// override bar
			view.set('bar', 999);

			// test again
			view.get('foo').should.eql(1);
			view.get('bar').should.eql(999);
			view.get('baz').should.eql(3);

			// test length of vars
			Object.keys(view.getVars()).should.length(3);

			view.set({
				foo: 11,
				baz: 33,
				bazinga: {
					what : { the : { f: '!' } }
				}
			});

			view.get('foo').should.eql(11);
			view.get('bar').should.eql(999);
			view.get('baz').should.eql(33);
			view.get('bazinga').should.have.propertyByPath('what', 'the', 'f').eql('!');

			// test length of vars
			Object.keys(view.getVars()).should.length(4);

		});

		it('should render passed args with right setup', () => {

			let view = new View({
				rootNode: document.createElement('p'),
				template: '
{{foo}}
{{bar}}',
				templateNode: document.createElement('div'),
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
			});

			view.set({
				foo: 'Hello',
				bar: 'Mars',
			});

			// tests
			view.render(null, { renderedFlag: false });

			view.renderedTemplate.should.equal('
Hello
Mars');
			view.el.outerHTML.should.equal('

Hello
Mars
');

		});

	});

	describe('method _getTemplateType', () => {

		it('should determine template type', () => {

			let view = new View({
				rootNode: document.createElement('div'),
			});

			view._getTemplateType("Hello World").should.be.equal(NO_VARS);
			view._getTemplateType("Hello {{foo}}").should.be.equal(VARS);
			view._getTemplateType({}).should.be.equal(PRE_COMPILED);

		});

	});

	describe('method compile', () => {

		let view = null;

		beforeEach(() => {

			view = new View({
				rootNode: document.createElement('p'),
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
			});

		});

		afterEach(() => {
			view = null;
		});

		it('should compile given NO_VARS template', () => {

			let template = view.compile(NO_VARS, 'Hello World {{ignore}}');
			template({ ignore: 'foo' }).should.be.equal('Hello World {{ignore}}');

		});

		it('should compile given VARS template', () => {

			let template = view.compile(VARS, '{{foo}} {{bar}}');
			template({ foo: 'hello', bar: 'world' }).should.be.equal('hello world');

		});

		it('should compile given PRE_COMPILED template', () => {

			let precompiled = view._precompile('{{foo}} {{bar}}');
			let template = view.compile(PRE_COMPILED, precompiled);
			template({ foo: 'hello', bar: 'world' }).should.be.equal('hello world');

		});

	});

	describe('method setTemplate', () => {

		let view = null;
		let spy_compile = null;

		beforeEach(() => {

			spy_compile = sinon.spy(View.prototype, "compile");

			view = new View({
				rootNode: document.createElement('p'),
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
			});
		});

		afterEach(() => {
			view = null;
			spy_compile.restore();
		});

		it('should call compile with with "NO_VARS" arg', () => {

			view.setTemplate('
Hello
World');
			spy_compile.args[0][0].should.be.equal('NO_VARS');
			spy_compile.args[0][2].should.be.equal('base');

		});

		it('should call compile with with "VARS" arg', () => {

			view.setTemplate('
{{foo}}
{{bar}}');
			spy_compile.args[0][0].should.be.equal('VARS');
			spy_compile.args[0][2].should.be.equal('base');

		});

		it('should call compile with with "PRE_COMPILED" arg', () => {

			let precompiled = view._precompile('{{foo}} {{bar}}');

			view.setTemplate(precompiled);
			spy_compile.args[0][0].should.be.equal('PRE_COMPILED');
			spy_compile.args[0][2].should.be.equal('base');

		});

		it('should throw error when not set template', () => {

			(() => { view.setTemplate(); }).should.throw();
			(() => { view.setTemplate(function(){}); }).should.throw();
			(() => { view.setTemplate(() => {}); }).should.throw();
			(() => { view.setTemplate(null); }).should.throw();
			(() => { view.setTemplate(undefined); }).should.throw();
			(() => { view.setTemplate(true); }).should.throw();
			(() => { view.setTemplate([]); }).should.throw();

		});

	});

	describe('initialized method', () => {

		it('should initialize view', () => {

			let view = new View({
				rootNode: document.createElement('p'),
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
			});

			view.initialized().should.be.true();

		});

	});

	describe('delete method', () => {

		it('should delete initialized view', () => {

			let view = new View({
				rootNode: document.createElement('p'),
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
			});

			view.delete();
			view.initialized().should.be.false();

		});

	});

	describe('reinit method', () => {

		it('should reinit view after deleting', () => {

			let options = {
				rootNode: document.createElement('p'),
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
			};

			let view = new View(options);

			view.delete();
			view.reinit(options);
			view.initialized().should.be.true();

		});

	});

	describe('reinit method"', () => {

		it('should throw error if reinit called without options parameter', () => {

			let view = new View({
				rootNode: document.createElement('p'),
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
			});

			view.delete();

			(() => { view.reinit(); }).should.throw();

		});

	});

	describe('method "render"', () => {

	});

	describe('method "create"', () => {

		it('should render expected template', () => {

			let view = new View({
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
				rootNode: document.createElement('p'),
				templateNode: document.createElement('div'),
				vars: {
					foo: 'Hello',
					bar: 'World!'
				},
				template: '
{{foo}}

{{bar}}
',
			});

			view.render();

			view.renderedTemplate.should.equal('
Hello

World!
');
			view.el.outerHTML.should.equal('

Hello

World!

');

		});

	});

	describe('innerHTML + slot', () => {

		it('should append innerHTML nodes to "slot" node', () => {

			let rootNode = document.createElement('p');
			rootNode.innerHTML = '

 nok nok

';

			let view = new View({
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
				rootNode: rootNode,
				templateNode: document.createElement('div'),
				vars: {
					foo: 'Thats',
					bar: 'nice'
				},
				template: '
{{foo}}
<slot></slot>
{{bar}}
',
			});

			view.render(null, { renderedFlag: false });

			view.el.outerHTML.should.equal('

Thats
<slot>

 nok nok

</slot>
nice

');

		});

	});

	describe('innerHTML + hole', () => {

		it.skip('should replace himself with given selector', () => {

			let rootNode = document.createElement('p');
			rootNode.innerHTML = 'Hello World
';

			let view = new View({
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
				rootNode: rootNode,
				templateNode: document.createElement('div'),
				vars: {
					foo: 'Thats',
					bar: 'nice'
				},
				template: '
{{foo}}
<hole></hole>
{{bar}}
',
			});

			view.render(null, { renderedFlag: false });
			view.replaceSelf('black-hole');
			view.el.outerHTML.should.equal('
Thats

Hello World

nice
');

		});

	});

	describe('render() method', () => {

		it('should not render because rendered attribute flag is set or only when explicitly wanted', () => {

			let rootNode = document.createElement('my-element');
			rootNode.setAttribute('rendered', true);
			rootNode.innerHTML = 'Should not rendered';

			let view = new View({
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
				rootNode: rootNode,
				templateNode: document.createElement('div'),
				vars: {
					foo: 'Gokcen'
				},
				template: '
{{foo}}
',
			});

			// should not render because rendered flag is set
			view.render();
			view.getRootNode().outerHTML.should.equal('<my-element rendered="true">Should not rendered</my-element>');

			// explicitly wanted to render because force = true is set
			view.render(null, { force: true });
			view.el.outerHTML.should.equal('<my-element rendered="true">
Gokcen
</my-element>');

		});

		it('should render only once if called many times or render force true', () => {

			let spy_setAttribute = sinon.spy(View.prototype, "setAttribute");
			let spy_getAttribute = sinon.spy(View.prototype, "getAttribute");

			let view = new View({
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
				rootNode: document.createElement('my-element'),
				templateNode: document.createElement('div'),
				vars: {
					foo: 'Liya'
				},
				template: '
{{foo}}
',
			});

			// first render call should render
			view.render();
			view.el.outerHTML.should.equal('<my-element rendered="true">
Liya
</my-element>');

			spy_getAttribute.callCount.should.equal(1);
			spy_getAttribute.args[0][1].should.equal('rendered');

			spy_setAttribute.callCount.should.equal(1);
			spy_setAttribute.args[0][1].should.equal('rendered');

			// second render call should not render
			view.render();
			spy_getAttribute.callCount.should.equal(2);
			spy_setAttribute.callCount.should.equal(1);

			// third render call should render due "force:true"
			view.render(null, {force: true});
			spy_getAttribute.callCount.should.equal(3);
			spy_setAttribute.callCount.should.equal(2);

			//cleanup spy
			View.prototype.getAttribute.restore();
			View.prototype.setAttribute.restore();

		});

	});

});
<commit_msg>test/libs/view.spec.js: add more tests<commit_after>import { View, VARS, NO_VARS, PRE_COMPILED } from 'src/libs/view';
import Handlebars from '../../node_modules/handlebars/dist/handlebars';

describe('class View', () => {

	describe('new View()', () => {

		it('should throw error if initialized without options', () => {

			(() => { new View(); }).should.throw();

		});

		it('should not throw error if minimum options passed', () => {

			(() => { new View({
				rootNode: document.createElement('p'),
			}); }).should.not.throw();

			(() => { new View({
				rootNode: document.createElement('p'),
				precompiler: Handlebars.precompile,
			}); }).should.not.throw();

			(() => { new View({
				rootNode: document.createElement('p'),
				prerenderer: Handlebars.template,
			}); }).should.not.throw();

		})

	});

	describe('method set/get', () => {

		it('should accept args as string and objects', () => {

			let view = new View({
				rootNode: document.createElement('div'),
			});

			view.set('foo', 1);
			view.set('bar', 2);
			view.set('baz', 3);

			// test
			view.get('foo').should.eql(1);
			view.get('bar').should.eql(2);
			view.get('baz').should.eql(3);

			// override bar
			view.set('bar', 999);

			// test again
			view.get('foo').should.eql(1);
			view.get('bar').should.eql(999);
			view.get('baz').should.eql(3);

			// test length of vars
			Object.keys(view.getVars()).should.length(3);

			view.set({
				foo: 11,
				baz: 33,
				bazinga: {
					what : { the : { f: '!' } }
				}
			});

			view.get('foo').should.eql(11);
			view.get('bar').should.eql(999);
			view.get('baz').should.eql(33);
			view.get('bazinga').should.have.propertyByPath('what', 'the', 'f').eql('!');

			// test length of vars
			Object.keys(view.getVars()).should.length(4);

		});

		it('should render passed args with right setup', () => {

			let view = new View({
				rootNode: document.createElement('p'),
				template: '
{{foo}}
{{bar}}',
				templateNode: document.createElement('div'),
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
			});

			view.set({
				foo: 'Hello',
				bar: 'Mars',
			});

			// tests
			view.render(null, { renderedFlag: false });

			view.renderedTemplate.should.equal('
Hello
Mars');
			view.el.outerHTML.should.equal('

Hello
Mars
');

		});

	});

	describe('method _getTemplateType', () => {

		it('should determine template type', () => {

			let view = new View({
				rootNode: document.createElement('div'),
			});

			view._getTemplateType("Hello World").should.be.equal(NO_VARS);
			view._getTemplateType("Hello {{foo}}").should.be.equal(VARS);
			view._getTemplateType({}).should.be.equal(PRE_COMPILED);

		});

	});

	describe('method compile', () => {

		let view = null;

		beforeEach(() => {

			view = new View({
				rootNode: document.createElement('p'),
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
			});

		});

		afterEach(() => {
			view = null;
		});

		it('should compile given NO_VARS template', () => {

			let template = view.compile(NO_VARS, 'Hello World {{ignore}}');
			template({ ignore: 'foo' }).should.be.equal('Hello World {{ignore}}');

		});

		it('should compile given VARS template', () => {

			let template = view.compile(VARS, '{{foo}} {{bar}}');
			template({ foo: 'hello', bar: 'world' }).should.be.equal('hello world');

		});

		it('should compile given PRE_COMPILED template', () => {

			let precompiled = view._precompile('{{foo}} {{bar}}');
			let template = view.compile(PRE_COMPILED, precompiled);
			template({ foo: 'hello', bar: 'world' }).should.be.equal('hello world');

		});

	});

	describe('method setTemplate', () => {

		let view = null;
		let spy_compile = null;

		beforeEach(() => {

			spy_compile = sinon.spy(View.prototype, "compile");

			view = new View({
				rootNode: document.createElement('p'),
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
			});
		});

		afterEach(() => {
			view = null;
			spy_compile.restore();
		});

		it('should call compile with with "NO_VARS" arg', () => {

			view.setTemplate('
Hello
World');
			spy_compile.args[0][0].should.be.equal('NO_VARS');
			spy_compile.args[0][2].should.be.equal('base');

		});

		it('should call compile with with "VARS" arg', () => {

			view.setTemplate('
{{foo}}
{{bar}}');
			spy_compile.args[0][0].should.be.equal('VARS');
			spy_compile.args[0][2].should.be.equal('base');

		});

		it('should call compile with with "PRE_COMPILED" arg', () => {

			let precompiled = view._precompile('{{foo}} {{bar}}');

			view.setTemplate(precompiled);
			spy_compile.args[0][0].should.be.equal('PRE_COMPILED');
			spy_compile.args[0][2].should.be.equal('base');

		});

		it('should throw error when not set template', () => {

			(() => { view.setTemplate(); }).should.throw();
			(() => { view.setTemplate(function(){}); }).should.throw();
			(() => { view.setTemplate(() => {}); }).should.throw();
			(() => { view.setTemplate(null); }).should.throw();
			(() => { view.setTemplate(undefined); }).should.throw();
			(() => { view.setTemplate(true); }).should.throw();
			(() => { view.setTemplate([]); }).should.throw();

		});

	});

	describe('initialized method', () => {

		it('should initialize view', () => {

			let view = new View({
				rootNode: document.createElement('p'),
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
			});

			view.initialized().should.be.true();

		});

	});

	describe('delete method', () => {

		it('should delete initialized view', () => {

			let view = new View({
				rootNode: document.createElement('p'),
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
			});

			view.delete();
			view.initialized().should.be.false();

		});

	});

	describe('reinit method', () => {

		it('should reinit view after deleting', () => {

			let options = {
				rootNode: document.createElement('p'),
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
			};

			let view = new View(options);

			view.delete();
			view.reinit(options);
			view.initialized().should.be.true();

		});

	});

	describe('reinit method"', () => {

		it('should throw error if reinit called without options parameter', () => {

			let view = new View({
				rootNode: document.createElement('p'),
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
			});

			view.delete();

			(() => { view.reinit(); }).should.throw();

		});

	});

	describe('method "render"', () => {

	});

	describe('method "create"', () => {

		it('should render expected template', () => {

			let view = new View({
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
				rootNode: document.createElement('p'),
				templateNode: document.createElement('div'),
				vars: {
					foo: 'Hello',
					bar: 'World!'
				},
				template: '
{{foo}}

{{bar}}
',
			});

			view.render();

			view.renderedTemplate.should.equal('
Hello

World!
');
			view.el.outerHTML.should.equal('

Hello

World!

');

		});

	});

	describe('innerHTML + slot', () => {

		it('should append innerHTML nodes to "slot" node', () => {

			let rootNode = document.createElement('p');
			rootNode.innerHTML = '

 nok nok

';

			let view = new View({
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
				rootNode: rootNode,
				templateNode: document.createElement('div'),
				vars: {
					foo: 'Thats',
					bar: 'nice'
				},
				template: '
{{foo}}
<slot></slot>
{{bar}}
',
			});

			view.render(null, { renderedFlag: false });

			view.el.outerHTML.should.equal('

Thats
<slot>

 nok nok

</slot>
nice

');

		});

	});

	describe('innerHTML + hole', () => {

		it.skip('should replace himself with given selector', () => {

			let rootNode = document.createElement('p');
			rootNode.innerHTML = 'Hello World
';

			let view = new View({
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
				rootNode: rootNode,
				templateNode: document.createElement('div'),
				vars: {
					foo: 'Thats',
					bar: 'nice'
				},
				template: '
{{foo}}
<hole></hole>
{{bar}}
',
			});

			view.render(null, { renderedFlag: false });
			view.replaceSelf('black-hole');
			view.el.outerHTML.should.equal('
Thats

Hello World

nice
');

		});

	});

	describe('render() method', () => {

		it('should not render because rendered attribute flag is set or only when explicitly wanted', () => {

			let rootNode = document.createElement('my-element');
			rootNode.setAttribute('rendered', true);
			rootNode.innerHTML = 'Should not rendered';

			let view = new View({
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
				rootNode: rootNode,
				templateNode: document.createElement('div'),
				vars: {
					foo: 'Gokcen'
				},
				template: '
{{foo}}
',
			});

			// should not render because rendered flag is set
			view.render();
			view.getRootNode().outerHTML.should.equal('<my-element rendered="true">Should not rendered</my-element>');

			// explicitly wanted to render because force = true is set
			view.render(null, { force: true });
			view.el.outerHTML.should.equal('<my-element rendered="true">
Gokcen
</my-element>');

		});

		it('should render only once if called many times or render force true', () => {

			let spy_setAttribute = sinon.spy(View.prototype, "setAttribute");
			let spy_getAttribute = sinon.spy(View.prototype, "getAttribute");

			let view = new View({
				precompiler: Handlebars.precompile,
				prerenderer: Handlebars.template,
				rootNode: document.createElement('my-element'),
				templateNode: document.createElement('div'),
				vars: {
					foo: 'Liya'
				},
				template: '
{{foo}}
',
			});

			// first render call should render
			view.render();
			view.el.outerHTML.should.equal('<my-element rendered="true">
Liya
</my-element>');

			spy_getAttribute.callCount.should.equal(1);
			spy_getAttribute.args[0][1].should.equal('rendered');

			spy_setAttribute.callCount.should.equal(1);
			spy_setAttribute.args[0][1].should.equal('rendered');

			// second render call should not render
			view.render();
			spy_getAttribute.callCount.should.equal(2);
			spy_setAttribute.callCount.should.equal(1);

			// third render call should render due "force:true"
			view.render(null, {force: true});
			spy_getAttribute.callCount.should.equal(3);
			spy_setAttribute.callCount.should.equal(2);

			//cleanup spy
			View.prototype.getAttribute.restore();
			View.prototype.setAttribute.restore();

		});

	});

});
<|endoftext|>


<commit_before>function convertDiff(name, table) {
  var inline = table.className == 'inline';
  var ths = table.tHead.rows[0].cells;
  var lines = [
    "Index: " + name,
    "===================================================================",
    "--- " + (inline ? ths[0].title : $(ths[0]).find('a').text()),
    "+++ " + (inline ? ths[1].title : $(ths[1]).find('a').text()),
  ];
  var sepIndex = 0;
  var oldOffset = 0, oldLength = 0, newOffset = 0, newLength = 0;

  for (var i = 0; i
 0) {
        if (!oldOffset && oldLength) oldOffset = 1
        if (!newOffset && newLength) newOffset = 1
        lines[sepIndex] = lines[sepIndex]
          .replace("{1}", oldOffset).replace("{2}", oldLength)
          .replace("{3}", newOffset).replace("{4}", newLength);
      }
      sepIndex = lines.length;
      lines.push("@@ -{1},{2}, +{3},{4} @@");
      oldOffset = 0, oldLength = 0, newOffset = 0, newLength = 0;
      if (tBody.className == "skipped") continue;
    }
    var tmpLines = [];
    for (var j = 0; j < tBody.rows.length; j++) {
      var cells = tBody.rows[j].cells;
      var oldLineNo = parseInt($(cells[0]).text());
      var newLineNo = parseInt($(cells[inline ? 1 : 2]).text());
      if (tBody.className == 'unmod') {
        lines.push("  " + $(cells[inline ? 2 : 1]).text());
        oldLength += 1;
        newLength += 1;
        if (!oldOffset) oldOffset = oldLineNo;
        if (!newOffset) newOffset = newLineNo;
      } else {
        var oldLine;
        var newLine;
        if (inline) {
          oldLine = newLine = $(cells[2]).text();
        } else {
          oldLine = $(cells[1]).text();
          newLine = $(cells[3]).text();
        }
        if (!isNaN(oldLineNo)) {
          lines.push("- " + oldLine);
          oldLength += 1;
        }
        if (!isNaN(newLineNo)) {
          tmpLines.push("+ " + newLine);
          newLength += 1;
        }
      }
    }
    if (tmpLines.length > 0) {
      lines = lines.concat(tmpLines);
    }
  }

  if (!oldOffset && oldLength) oldOffset = 1
  if (!newOffset && newLength) newOffset = 1
  lines[sepIndex] = lines[sepIndex]
    .replace("{1}", oldOffset).replace("{2}", oldLength)
    .replace("{3}", newOffset).replace("{4}", newLength);

  return lines.join($.browser.msie ? "\r\n" : "\n");
}

jQuery(document).ready(function($) {
  $("div.diff h2").each(function() {
    var switcher = $("").prependTo(this);
    var name = $.trim($(this).text());
    var table = $(this).siblings("table").get(0);
    if (! table) return;
    var pre = $("

").hide().insertAfter(table);
    $("Tabular").click(function() {
      $(pre).hide();
      $(table).show();
      $(this).addClass("active").siblings("span").removeClass("active");
      return false;
    }).addClass("active").appendTo(switcher);
    $("Unified").click(function() {
      $(table).hide();
      if (!pre.get(0).firstChild) pre.text(convertDiff(name, table));
      $(pre).fadeIn("fast")
      $(this).addClass("active").siblings("span").removeClass("active");
      return false;
    }).appendTo(switcher);
  });
});
<commit_msg>Another r5672 fix: the diff switcher function was not properly namespaced.<commit_after>(function($){

  function convertDiff(name, table) {
    var inline = table.className == 'inline';
    var ths = table.tHead.rows[0].cells;
    var lines = [
      "Index: " + name,
      "===================================================================",
      "--- " + (inline ? ths[0].title : $(ths[0]).find('a').text()),
      "+++ " + (inline ? ths[1].title : $(ths[1]).find('a').text()),
    ];
    var sepIndex = 0;
    var oldOffset = 0, oldLength = 0, newOffset = 0, newLength = 0;

    for (var i = 0; i
 0) {
          if (!oldOffset && oldLength) oldOffset = 1
          if (!newOffset && newLength) newOffset = 1
          lines[sepIndex] = lines[sepIndex]
            .replace("{1}", oldOffset).replace("{2}", oldLength)
            .replace("{3}", newOffset).replace("{4}", newLength);
        }
        sepIndex = lines.length;
        lines.push("@@ -{1},{2}, +{3},{4} @@");
        oldOffset = 0, oldLength = 0, newOffset = 0, newLength = 0;
        if (tBody.className == "skipped") continue;
      }
      var tmpLines = [];
      for (var j = 0; j < tBody.rows.length; j++) {
        var cells = tBody.rows[j].cells;
        var oldLineNo = parseInt($(cells[0]).text());
        var newLineNo = parseInt($(cells[inline ? 1 : 2]).text());
        if (tBody.className == 'unmod') {
          lines.push("  " + $(cells[inline ? 2 : 1]).text());
          oldLength += 1;
          newLength += 1;
          if (!oldOffset) oldOffset = oldLineNo;
          if (!newOffset) newOffset = newLineNo;
        } else {
          var oldLine;
          var newLine;
          if (inline) {
            oldLine = newLine = $(cells[2]).text();
          } else {
            oldLine = $(cells[1]).text();
            newLine = $(cells[3]).text();
          }
          if (!isNaN(oldLineNo)) {
            lines.push("- " + oldLine);
            oldLength += 1;
          }
          if (!isNaN(newLineNo)) {
            tmpLines.push("+ " + newLine);
            newLength += 1;
          }
        }
      }
      if (tmpLines.length > 0) {
        lines = lines.concat(tmpLines);
      }
    }

    if (!oldOffset && oldLength) oldOffset = 1
    if (!newOffset && newLength) newOffset = 1
    lines[sepIndex] = lines[sepIndex]
      .replace("{1}", oldOffset).replace("{2}", oldLength)
      .replace("{3}", newOffset).replace("{4}", newLength);

    return lines.join($.browser.msie ? "\r\n" : "\n");
  }

  $(document).ready(function($) {
    $("div.diff h2").each(function() {
      var switcher = $("").prependTo(this);
      var name = $.trim($(this).text());
      var table = $(this).siblings("table").get(0);
      if (! table) return;
      var pre = $("

").hide().insertAfter(table);
      $("Tabular").click(function() {
        $(pre).hide();
        $(table).show();
        $(this).addClass("active").siblings("span").removeClass("active");
        return false;
      }).addClass("active").appendTo(switcher);
      $("Unified").click(function() {
        $(table).hide();
        if (!pre.get(0).firstChild) pre.text(convertDiff(name, table));
        $(pre).fadeIn("fast")
        $(this).addClass("active").siblings("span").removeClass("active");
        return false;
      }).appendTo(switcher);
    });
  });

})(jQuery);
<|endoftext|>