<commit_before>'use strict';

describe("New Fraction creation", function () {
  var Fraction = require('../../lib/fractions/Fraction');

  // better names!
  describe("Init with 1/2", function () {
    var f;
    beforeEach(function () {
      f = new Fraction(1, 2);
    });

    it("should return 1 as nominator", function () {
      expect(f.nominator()).toEqual(1);
    });

    it("should return 2 as denominator", function () {
      expect(f.denominator()).toEqual(2);
    });
  });

  describe("Init with 3/4", function () {
    var f;
    beforeEach(function () {
      f = new Fraction(3, 4);
    });

    it("should return 3 as nominator", function () {
      expect(f.nominator()).toEqual(3);
    });

    it("should return 4 as denominator", function () {
      expect(f.denominator()).toEqual(4);
    });
  });

  describe("Fraction Addition", function () {
    describe("Nominator is 0", function () {
      var sum;
      beforeEach(function () {
        var f = new Fraction(0, 1);
        var f2 = new Fraction(0, 1);
        sum = f.add(f2);
      });

      it("should return 0 as nominator", function () {
        expect(sum.nominator()).toEqual(0);
      });
      it("should return 1 (from first fraction) as denominator", function () {
        expect(sum.denominator()).toEqual(1);
      });
    });

    describe("Same Denominator", function () {
      var sum;
      beforeEach(function () {
        var f = new Fraction(1, 1);
        var f2 = new Fraction(1, 1);
        sum = f.add(f2);
      });

      it("should return addition", function () {
        expect(sum.nominator()).toEqual(2);
        expect(sum.denominator()).toEqual(1);
      });
    });

    describe("Same Denominator", function () {
      var sum;
      beforeEach(function () {
        var f = new Fraction(1, 4);
        var f2 = new Fraction(2, 4);
        sum = f.add(f2);
      });

      it("should return addition.", function () {
        expect(sum.nominator()).toEqual(3);
        expect(sum.denominator()).toEqual(4);
      });
    });

    describe("Expand Denominator", function () {
      it("should expand 2nd denominator.", function () {
        var sum = new Fraction(1, 6).add(new Fraction(2, 3));
        expect(sum.nominator()).toEqual(5);
        expect(sum.denominator()).toEqual(6);
      });

      it("should expand 2nd denominator.", function () {
        var sum = new Fraction(1, 8).add(new Fraction(3, 4));
        expect(sum.nominator()).toEqual(7);
        expect(sum.denominator()).toEqual(8);
      });

      it("should expand 1st denominator.", function () {
        var sum = new Fraction(2, 3).add(new Fraction(1, 6));
        expect(sum.nominator()).toEqual(5);
        expect(sum.denominator()).toEqual(6);
      });

      it("should expand 1st denominator.", function () {
        var sum = new Fraction(3, 4).add(new Fraction(1, 8));
        expect(sum.nominator()).toEqual(7);
        expect(sum.denominator()).toEqual(8);
      });

      it("should expand both denominator.", function () {
        var sum = new Fraction(1, 2).add(new Fraction(1, 3));
        expect(sum.nominator()).toEqual(5);
        expect(sum.denominator()).toEqual(6);
      });

    });

  });
});

// TODO LIST
        // 2/4 + 2/8 = 6/8 = 3/4  REDUCTION!

        // 1/0 ??             Error - 0 division
        // 2 1/2 ??           Error - not allowed

        // 3/3 + 4/4 = ??     whole numbers, expressed as fraction
        // 1/3 + 2/3 = 3/3    result full number
        // 3 + 4 = 7          whole integers

<commit_msg>added complex pinnning test 7/3 + 4/5 = 47/15<commit_after>'use strict';

describe("New Fraction creation", function () {
  var Fraction = require('../../lib/fractions/Fraction');

  // better names!
  describe("Init with 1/2", function () {
    var f;
    beforeEach(function () {
      f = new Fraction(1, 2);
    });

    it("should return 1 as nominator", function () {
      expect(f.nominator()).toEqual(1);
    });

    it("should return 2 as denominator", function () {
      expect(f.denominator()).toEqual(2);
    });
  });

  describe("Init with 3/4", function () {
    var f;
    beforeEach(function () {
      f = new Fraction(3, 4);
    });

    it("should return 3 as nominator", function () {
      expect(f.nominator()).toEqual(3);
    });

    it("should return 4 as denominator", function () {
      expect(f.denominator()).toEqual(4);
    });
  });

  describe("Fraction Addition", function () {
    describe("Nominator is 0", function () {
      var sum;
      beforeEach(function () {
        var f = new Fraction(0, 1);
        var f2 = new Fraction(0, 1);
        sum = f.add(f2);
      });

      it("should return 0 as nominator", function () {
        expect(sum.nominator()).toEqual(0);
      });
      it("should return 1 (from first fraction) as denominator", function () {
        expect(sum.denominator()).toEqual(1);
      });
    });

    describe("Same Denominator", function () {
      var sum;
      beforeEach(function () {
        var f = new Fraction(1, 1);
        var f2 = new Fraction(1, 1);
        sum = f.add(f2);
      });

      it("should return addition", function () {
        expect(sum.nominator()).toEqual(2);
        expect(sum.denominator()).toEqual(1);
      });
    });

    describe("Same Denominator", function () {
      var sum;
      beforeEach(function () {
        var f = new Fraction(1, 4);
        var f2 = new Fraction(2, 4);
        sum = f.add(f2);
      });

      it("should return addition.", function () {
        expect(sum.nominator()).toEqual(3);
        expect(sum.denominator()).toEqual(4);
      });
    });

    describe("Expand Denominator", function () {
      it("should expand 2nd denominator.", function () {
        var sum = new Fraction(1, 6).add(new Fraction(2, 3));
        expect(sum.nominator()).toEqual(5);
        expect(sum.denominator()).toEqual(6);
      });

      it("should expand 2nd denominator.", function () {
        var sum = new Fraction(1, 8).add(new Fraction(3, 4));
        expect(sum.nominator()).toEqual(7);
        expect(sum.denominator()).toEqual(8);
      });

      it("should expand 1st denominator.", function () {
        var sum = new Fraction(2, 3).add(new Fraction(1, 6));
        expect(sum.nominator()).toEqual(5);
        expect(sum.denominator()).toEqual(6);
      });

      it("should expand 1st denominator.", function () {
        var sum = new Fraction(3, 4).add(new Fraction(1, 8));
        expect(sum.nominator()).toEqual(7);
        expect(sum.denominator()).toEqual(8);
      });

      it("should expand both denominator.", function () {
        var sum = new Fraction(1, 2).add(new Fraction(1, 3));
        expect(sum.nominator()).toEqual(5);
        expect(sum.denominator()).toEqual(6);
      });

      it("should expand both denominator.", function () {
        var sum = new Fraction(7, 3).add(new Fraction(4, 5));
        expect(sum.nominator()).toEqual(47);
        expect(sum.denominator()).toEqual(15);
      });
    });

  });
});

// TODO LIST
        // 2/4 + 2/8 = 6/8 = 3/4  REDUCTION!

        // 1/0 ??             Error - 0 division
        // 2 1/2 ??           Error - not allowed

        // 3/3 + 4/4 = ??     whole numbers, expressed as fraction
        // 1/3 + 2/3 = 3/3    result full number
        // 3 + 4 = 7          whole integers

<|endoftext|>


<commit_before>#!/usr/bin/env node

/**
 * Generates metrics.json file that stores metrics metadata
 */
'use strict';

var debug = require('debug')('generate'),
	fs = require('fs'),
	glob = require('glob'),
	phantomas = require('../../'),
	yaml = require('js-yaml'),
	metadata = {
		events: {},
		extensions: {},
		modules: {},
		metrics: {},
		metricsCount: 0,
		modulesCount: 0,
		extensionsCount: 0,
		version: phantomas.version
	};

function getMetricsCoveredByTests(spec) {
	const debug = require('debug')('metricsCovered');

	var covered = {};

	spec.forEach(testCase => {
		debug(testCase.label || testCase.url);

		Object.keys(testCase.metrics || {}).forEach(metric => {
			covered[metric] = true;
		});

		Object.keys(testCase.offenders || {}).forEach(metric => {
			covered[metric] = true;
		});
	});

	return Object.keys(covered);
}

function getOptionsCoveredByTests(spec) {
	var covered = {};

	spec.forEach(testCase => {
		Object.keys(testCase.options || {}).forEach(option => {
			covered[option] = true;
		});
	});

	return Object.keys(covered).sort();
}

function getModuleMetadata(moduleFile) {
	var content = fs.readFileSync(moduleFile).toString(),
		data = {
			name: '',
			description: '',
			metrics: {},
			events: {},
		},
		matches,
		moduleName,
		metricRegEx = /(setMetric|setMetricEvaluate|incrMetric)\(['"]([^'"]+)['"](\)|,)(.*@desc.*$)?/mg,
		eventsRegEx = /emit\(['"]([^'"]+)['"]([^)]+).*@desc(.*)$/mg;

	data.name = moduleName = moduleFile.split('/').pop().replace(/\.js$/, '');

	const localPath = moduleFile.replace(fs.realpathSync(__dirname + '/../../'), '');
	data.localPath = localPath;

	//
	// scan the source code
	//

	// look for metrics metadata
	while ((matches = metricRegEx.exec(content)) !== null) {
		var entry = {},
			metricName = matches[2],
			metricComment = matches[4],
			metricUnit = 'ms',
			hasDesc = (metricComment && metricComment.indexOf('@desc') > -1);

		if (typeof data.metrics[metricName] !== 'undefined') {
			if (hasDesc) {
				debug('Found duplicated definition of %s metric in %s module', metricName, moduleName);
			}
			continue;
		}

		// parse @desc
		if (hasDesc) {
			metricComment = metricComment.split('@desc').pop().trim();
			entry.desc = '';

			['unreliable', 'optional', 'offenders', 'gecko'].forEach(function(marker) {
				if (metricComment.indexOf('@' + marker) > -1) {
					entry[marker] = true;
					metricComment = metricComment.replace('@' + marker, '').trim();
				}
			});

			// detect units (defaults to ms)
			if ((matches = metricComment.match(/\[([^\]]+)\]/)) !== null) {
				metricUnit = matches[1];
				metricComment = metricComment.replace(matches[0], '').trim();
			} else if (/^(number of|total number of|average specificity|total specificity|median of number|maximum number|maximum level)/.test(metricComment)) {
				metricUnit = 'number';
			} else if (/^(the size|size|length|total length) of/.test(metricComment)) {
				metricUnit = 'bytes';
			}

			// check if offenders are reported for this metric
			if (content.indexOf('phantomas.addOffender(\'' + metricName + "'") > -1) {
				entry.offenders = true;
			}

			entry.desc = metricComment;
			entry.unit = metricUnit;
		} else if (moduleName !== 'scope') {
			debug('Metadata missing for %s metric in %s module', metricName, moduleName);
		}

		entry.module = moduleName;

		// add a metric
		data.metrics[metricName] = entry;
	}

	// look for events metadata
	while ((matches = eventsRegEx.exec(content)) !== null) {
			// console.log([moduleName, matches[1], matches[2], matches[3]]);

			data.events[matches[1]] = {
				'file': localPath,
				'desc': matches[3].trim(),
				'arguments': matches[2].replace(/^[,\s]+/g, ''),
			};
	}

	// parse modules and extensions initial commit block
	matches = /^\/\*\*([^/]+)\*\//m.exec(content);
	if (matches) {
		var desc = matches[0].
			replace(/^[\s/]?\*+\s?/mg, ''). // remove the beginning of block comment
			replace(/\/$/mg, ''). // remove the ending of block comment
			replace(/^\s?setMetric.*$/mg, ''). // remove setMetric annotations
			trim();

		//console.log(localPath, moduleName, matches[0]);

		data.description = desc;
	}
	//console.log(data); throw new Error('foo');

	return data;
}

// read the YAML spec file
const raw = fs.readFileSync(__dirname + '/../../test/integration-spec.yaml').toString(),
		spec = yaml.safeLoad(raw);

// find all metrics covered by integration tests (take a look into integration-spec.yaml)
const coveredMetrics = getMetricsCoveredByTests(spec);

debug('Found %d metrics covered by integration-spec.yaml...', coveredMetrics.length);

// find all options covered by integration tests (take a look into integration-spec.yaml)
const coveredOptions = getOptionsCoveredByTests(spec);

debug('Found %d options covered by integration-spec.yaml: --%s', coveredOptions.length, coveredOptions.join(', --'));

// find all modules
var dir = phantomas.path;
debug('Looking for modules in %s...', dir);

[].concat(
	glob.sync(dir + '/core/modules/**/*.js'),
	glob.sync(dir + '/modules/**/*.js'),
	glob.sync(dir + '/extensions/**/*.js'),
	glob.sync(dir + '/lib/*.js')
).forEach(function(moduleFile) {
	const data = getModuleMetadata(moduleFile);

	// skip scope.js files when listing metrics
	if (moduleFile.indexOf('/scope.js') === -1 && moduleFile.indexOf('/lib/') === -1) {
		Object.keys(data.metrics).forEach(function(metricName) {
			metadata.metricsCount++;
			metadata.metrics[metricName] = data.metrics[metricName];
			metadata.metrics[metricName].testsCovered = (coveredMetrics.indexOf(metricName) > -1);
		});
	}

	// modules ...
	if (moduleFile.indexOf('/scope.js') === -1 && moduleFile.indexOf('/modules/') > -1) {
		metadata.modules[data.name] = {
			'file': data.localPath,
			'desc': data.description,
			'events': Object.keys(data.events),
			'metrics': Object.keys(data.metrics),
		}

		metadata.modulesCount++;
	}

	// ... and extensions
	if (moduleFile.indexOf('/extensions/') > -1) {
		metadata.extensions[data.name] = {
			'file': data.localPath,
			'desc': data.description,
			'options': []
		}

		metadata.extensionsCount++;
	}

	Object.keys(data.events).forEach(function(eventName) {
		metadata.events[eventName] = data.events[eventName];
	});
});

// store metadata
var filename = __dirname + '/metadata.json',
	content = JSON.stringify(metadata, null, '  ');

debug('Storing metadata in %s...', filename);
fs.writeFile(filename, content, function(err) {
	if (err) {
		debug('Storing failed: %s', err);
	} else {
		debug('Done');
	}
});

debug('Metrics found: %d (tests coverage: %s%)', metadata.metricsCount, (coveredMetrics.length / metadata.metricsCount * 100).toFixed(2));
<commit_msg>lib/metadata/generate.js: update docs<commit_after>#!/usr/bin/env node

/**
 * Generates metadata.json file that stores metadata about:
 *
 * - events
 * - metrics
 * - modules
 * - extensions
 */
'use strict';

var debug = require('debug')('generate'),
	fs = require('fs'),
	glob = require('glob'),
	phantomas = require('../../'),
	yaml = require('js-yaml'),
	metadata = {
		events: {},
		extensions: {},
		modules: {},
		metrics: {},
		metricsCount: 0,
		modulesCount: 0,
		extensionsCount: 0,
		version: phantomas.version
	};

function getMetricsCoveredByTests(spec) {
	const debug = require('debug')('metricsCovered');

	var covered = {};

	spec.forEach(testCase => {
		debug(testCase.label || testCase.url);

		Object.keys(testCase.metrics || {}).forEach(metric => {
			covered[metric] = true;
		});

		Object.keys(testCase.offenders || {}).forEach(metric => {
			covered[metric] = true;
		});
	});

	return Object.keys(covered);
}

function getOptionsCoveredByTests(spec) {
	var covered = {};

	spec.forEach(testCase => {
		Object.keys(testCase.options || {}).forEach(option => {
			covered[option] = true;
		});
	});

	return Object.keys(covered).sort();
}

function getModuleMetadata(moduleFile) {
	var content = fs.readFileSync(moduleFile).toString(),
		data = {
			name: '',
			description: '',
			metrics: {},
			events: {},
		},
		matches,
		moduleName,
		metricRegEx = /(setMetric|setMetricEvaluate|incrMetric)\(['"]([^'"]+)['"](\)|,)(.*@desc.*$)?/mg,
		eventsRegEx = /emit\(['"]([^'"]+)['"]([^)]+).*@desc(.*)$/mg;

	data.name = moduleName = moduleFile.split('/').pop().replace(/\.js$/, '');

	const localPath = moduleFile.replace(fs.realpathSync(__dirname + '/../../'), '');
	data.localPath = localPath;

	//
	// scan the source code
	//

	// look for metrics metadata
	while ((matches = metricRegEx.exec(content)) !== null) {
		var entry = {},
			metricName = matches[2],
			metricComment = matches[4],
			metricUnit = 'ms',
			hasDesc = (metricComment && metricComment.indexOf('@desc') > -1);

		if (typeof data.metrics[metricName] !== 'undefined') {
			if (hasDesc) {
				debug('Found duplicated definition of %s metric in %s module', metricName, moduleName);
			}
			continue;
		}

		// parse @desc
		if (hasDesc) {
			metricComment = metricComment.split('@desc').pop().trim();
			entry.desc = '';

			['unreliable', 'optional', 'offenders', 'gecko'].forEach(function(marker) {
				if (metricComment.indexOf('@' + marker) > -1) {
					entry[marker] = true;
					metricComment = metricComment.replace('@' + marker, '').trim();
				}
			});

			// detect units (defaults to ms)
			if ((matches = metricComment.match(/\[([^\]]+)\]/)) !== null) {
				metricUnit = matches[1];
				metricComment = metricComment.replace(matches[0], '').trim();
			} else if (/^(number of|total number of|average specificity|total specificity|median of number|maximum number|maximum level)/.test(metricComment)) {
				metricUnit = 'number';
			} else if (/^(the size|size|length|total length) of/.test(metricComment)) {
				metricUnit = 'bytes';
			}

			// check if offenders are reported for this metric
			if (content.indexOf('phantomas.addOffender(\'' + metricName + "'") > -1) {
				entry.offenders = true;
			}

			entry.desc = metricComment;
			entry.unit = metricUnit;
		} else if (moduleName !== 'scope') {
			debug('Metadata missing for %s metric in %s module', metricName, moduleName);
		}

		entry.module = moduleName;

		// add a metric
		data.metrics[metricName] = entry;
	}

	// look for events metadata
	while ((matches = eventsRegEx.exec(content)) !== null) {
			// console.log([moduleName, matches[1], matches[2], matches[3]]);

			data.events[matches[1]] = {
				'file': localPath,
				'desc': matches[3].trim(),
				'arguments': matches[2].replace(/^[,\s]+/g, ''),
			};
	}

	// parse modules and extensions initial commit block
	matches = /^\/\*\*([^/]+)\*\//m.exec(content);
	if (matches) {
		var desc = matches[0].
			replace(/^[\s/]?\*+\s?/mg, ''). // remove the beginning of block comment
			replace(/\/$/mg, ''). // remove the ending of block comment
			replace(/^\s?setMetric.*$/mg, ''). // remove setMetric annotations
			trim();

		//console.log(localPath, moduleName, matches[0]);

		data.description = desc;
	}
	//console.log(data); throw new Error('foo');

	return data;
}

// read the YAML spec file
const raw = fs.readFileSync(__dirname + '/../../test/integration-spec.yaml').toString(),
		spec = yaml.safeLoad(raw);

// find all metrics covered by integration tests (take a look into integration-spec.yaml)
const coveredMetrics = getMetricsCoveredByTests(spec);

debug('Found %d metrics covered by integration-spec.yaml...', coveredMetrics.length);

// find all options covered by integration tests (take a look into integration-spec.yaml)
const coveredOptions = getOptionsCoveredByTests(spec);

debug('Found %d options covered by integration-spec.yaml: --%s', coveredOptions.length, coveredOptions.join(', --'));

// find all modules
var dir = phantomas.path;
debug('Looking for modules in %s...', dir);

[].concat(
	glob.sync(dir + '/core/modules/**/*.js'),
	glob.sync(dir + '/modules/**/*.js'),
	glob.sync(dir + '/extensions/**/*.js'),
	glob.sync(dir + '/lib/*.js')
).forEach(function(moduleFile) {
	const data = getModuleMetadata(moduleFile);

	// skip scope.js files when listing metrics
	if (moduleFile.indexOf('/scope.js') === -1 && moduleFile.indexOf('/lib/') === -1) {
		Object.keys(data.metrics).forEach(function(metricName) {
			metadata.metricsCount++;
			metadata.metrics[metricName] = data.metrics[metricName];
			metadata.metrics[metricName].testsCovered = (coveredMetrics.indexOf(metricName) > -1);
		});
	}

	// modules ...
	if (moduleFile.indexOf('/scope.js') === -1 && moduleFile.indexOf('/modules/') > -1) {
		metadata.modules[data.name] = {
			'file': data.localPath,
			'desc': data.description,
			'events': Object.keys(data.events),
			'metrics': Object.keys(data.metrics),
		}

		metadata.modulesCount++;
	}

	// ... and extensions
	if (moduleFile.indexOf('/extensions/') > -1) {
		metadata.extensions[data.name] = {
			'file': data.localPath,
			'desc': data.description,
			'options': []
		}

		metadata.extensionsCount++;
	}

	Object.keys(data.events).forEach(function(eventName) {
		metadata.events[eventName] = data.events[eventName];
	});
});

// store metadata
var filename = __dirname + '/metadata.json',
	content = JSON.stringify(metadata, null, '  ');

debug('Storing metadata in %s...', filename);
fs.writeFile(filename, content, function(err) {
	if (err) {
		debug('Storing failed: %s', err);
	} else {
		debug('Done');
	}
});

debug('Metrics found: %d (tests coverage: %s%)', metadata.metricsCount, (coveredMetrics.length / metadata.metricsCount * 100).toFixed(2));
<|endoftext|>


<commit_before>pc.extend(pc.fw, function () {
    /**
     * @component
     * @name pc.fw.ModelComponent
     * @constructor Create a new ModelComponentSystem
     * @class Enables an Entity to render a model or a primitive shape. This Component attaches additional model geometry in to the scene graph below the Entity.
     * @param {pc.fw.ModelComponentSystem} system The ComponentSystem that created this Component
     * @param {pc.fw.Entity} entity The Entity that this Component is attached to.
     * @extends pc.fw.Component
     * @property {String} type The type of the model, which can be one of the following values:
     *

     *
asset: The component will render a model asset

     *
box: The component will render a box

     *
capsule: The component will render a capsule

     *
cone: The component will render a cone

     *
cylinder: The component will render a cylinder

     *
sphere: The component will render a sphere

     *

     * @property {String} asset The GUID of the asset for the model (only applies to models of type 'asset')
     * @property {Boolean} castShadows If true, this model will cast shadows for lights that have shadow casting enabled.
     * @property {Boolean} receiveShadows If true, shadows will be cast on this model
     * @property {String} materialAsset The material {@link pc.Asset.Asset} that will be used to render the model (not used on models of type 'asset')
     * @property {pc.scene.Model} model The model that is added to the scene graph.
     */
    var ModelComponent = function ModelComponent (system, entity)   {
        this.on("set_type", this.onSetType, this);
        this.on("set_asset", this.onSetAsset, this);
        this.on("set_castShadows", this.onSetCastShadows, this);
        this.on("set_model", this.onSetModel, this);
        this.on("set_receiveShadows", this.onSetReceiveShadows, this);

        // override materialAsset property to return a pc.Asset instead
        Object.defineProperty(this, 'materialAsset', {
            set: this.onSetMaterialAsset.bind(this),
            get: this.onGetMaterialAsset.bind(this)
        });

        this.materialLoader = new pc.resources.MaterialResourceLoader(system.context.graphicsDevice, system.context.assets);
    };
    ModelComponent = pc.inherits(ModelComponent, pc.fw.Component);

    pc.extend(ModelComponent.prototype, {
        /**
        * @function
        * @name pc.fw.ModelComponent#setVisible
        * @description Enable or disable rendering for the Model.
        * @param {Boolean} visible True to enable rendering for the model, false to disable it
        */
        setVisible: function (visible) {
            if (this.data.model) {
                var inScene = this.system.context.scene.containsModel(this.data.model);

                if (visible && !inScene) {
                    this.system.context.scene.addModel(this.data.model);
                } else if (!visible && inScene) {
                    this.system.context.scene.removeModel(this.data.model);
                }
            }
        },

        loadModelAsset: function (guid) {
            var options = {
                parent: this.entity.getRequest()
            };

            var asset = this.system.context.assets.getAssetByResourceId(guid);
            if (!asset) {
                logERROR(pc.string.format('Trying to load model before asset {0} is loaded.', guid));
                return;
            }

            this.system.context.assets.load(asset, [], options).then(function (resources) {
                var model = resources[0];

                if (this.system.context.designer) {
                    model.generateWireframe();

                    asset.on('change', this.onAssetChange, this);
                }

                if (this.data.type === 'asset') {
                    this.model = model;
                }
            }.bind(this));
        },

        /**
         * @function
         * @private
         * @name pc.fw.ModelComponent#onSetType
         * @description Handle changes to the 'type' variable
         */
        onSetType: function (name, oldValue, newValue) {
            var data = this.data;

            if (newValue) {
                var mesh = null;

                if (newValue === 'asset') {
                    if (this.data.asset) {
                        this.loadModelAsset(this.data.asset);
                    } else {
                        this.model = null;
                    }
                } else {
                    switch (newValue) {
                        case 'box':
                            mesh = this.system.box;
                            break;
                        case 'capsule':
                            mesh = this.system.capsule;
                            break;
                        case 'sphere':
                            mesh = this.system.sphere;
                            break;
                        case 'cone':
                            mesh = this.system.cone;
                            break;
                        case 'cylinder':
                            mesh = this.system.cylinder;
                            break;
                        default:
                            throw new Error("Invalid model type: " + newValue);
                    }

                    var node = new pc.scene.GraphNode();

                    var model = new pc.scene.Model();
                    model.graph = node;

                    model.meshInstances = [ new pc.scene.MeshInstance(node, mesh, data.material) ];

                    if (this.system.context.designer) {
                        model.generateWireframe();
                    }

                    this.model = model;
                }
            }
        },

        onSetAsset: function (name, oldValue, newValue) {
            if (oldValue) {
                // Remove old listener
                var asset = this.system.context.assets.getAssetByResourceId(oldValue);
                if (asset) {
                    asset.off('change', this.onAssetChange, this);
                }
            }

            if (this.data.type === 'asset') {
                if (newValue) {
                    this.loadModelAsset(newValue);
                } else {
                    this.model = null;
                }
            }
        },

        onSetCastShadows: function (name, oldValue, newValue) {
            var model = this.data.model;
            if (model) {
                var scene = this.system.context.scene;
                var inScene = scene.containsModel(model);
                if (inScene) {
                    scene.removeModel(model);
                }

                var meshInstances = model.meshInstances;
                for (var i = 0; i < meshInstances.length; i++) {
                    meshInstances[i].castShadow = newValue;
                }

                if (inScene) {
                    scene.addModel(model);
                }
            }
        },

        onSetModel: function (name, oldValue, newValue) {
            if (oldValue) {
                this.system.context.scene.removeModel(oldValue);
                this.entity.removeChild(oldValue.getGraph());
                delete oldValue._entity;
            }

            if (newValue) {
                var componentData = this.data;
                var meshInstances = newValue.meshInstances;
                for (var i = 0; i < meshInstances.length; i++) {
                    meshInstances[i].castShadow = componentData.castShadows;
                    meshInstances[i].receiveShadow = componentData.receiveShadows;
                }

                this.entity.addChild(newValue.graph);
                this.system.context.scene.addModel(newValue);

                // Store the entity that owns this model
                newValue._entity = this.entity;

                // Update any animation component
                if (this.entity.animation) {
                    this.entity.animation.setModel(newValue);
                }
            }
        },

        onSetMaterialAsset: function (newValue) {
            // if the type of the value is not a string assume it is an pc.Asset
            var guid = typeof newValue === 'string' || !newValue ? newValue : newValue.resourceId;

            material = guid ? this.materialLoader.load(guid) : this.system.defaultMaterial;
            this.data.material = material;
            if (this.data.model && this.data.type !== 'asset') {
                var meshInstances = this.data.model.meshInstances;
                for (var i=0; i<meshInstances.length; i++) {
                    meshInstances[i].material = material;
                }
            }

            this.data.materialAsset = guid;
        },

        onGetMaterialAsset: function () {
            return this.system.context.assets.getAssetByResourceId(this.data.materialAsset);
        },

        onSetReceiveShadows: function (name, oldValue, newValue) {
            if (newValue !== undefined) {
                var componentData = this.data;
                if (componentData.model) {
                    var meshInstances = componentData.model.meshInstances;
                    for (var i = 0; i < meshInstances.length; i++) {
                        meshInstances[i].receiveShadow = newValue;
                    }
                }
            }
        },

        /**
        * @private
        * @description Attached to the asset during loading (while running with the designer or over livelink), this callback
        * is used to reload the asset if it is changed.
        */
        onAssetChange: function (asset) {
            // Remove the asset from the cache and reload it
            this.system.context.loader.removeFromCache(asset.getFileUrl());
            this.asset = null;
            this.asset = asset.resourceId;
        }
    });

    return {
        ModelComponent: ModelComponent
    };
}());<commit_msg>Fire event on materialAsset setter, Changed setter / getter method names<commit_after>pc.extend(pc.fw, function () {
    /**
     * @component
     * @name pc.fw.ModelComponent
     * @constructor Create a new ModelComponentSystem
     * @class Enables an Entity to render a model or a primitive shape. This Component attaches additional model geometry in to the scene graph below the Entity.
     * @param {pc.fw.ModelComponentSystem} system The ComponentSystem that created this Component
     * @param {pc.fw.Entity} entity The Entity that this Component is attached to.
     * @extends pc.fw.Component
     * @property {String} type The type of the model, which can be one of the following values:
     *

     *
asset: The component will render a model asset

     *
box: The component will render a box

     *
capsule: The component will render a capsule

     *
cone: The component will render a cone

     *
cylinder: The component will render a cylinder

     *
sphere: The component will render a sphere

     *

     * @property {String} asset The GUID of the asset for the model (only applies to models of type 'asset')
     * @property {Boolean} castShadows If true, this model will cast shadows for lights that have shadow casting enabled.
     * @property {Boolean} receiveShadows If true, shadows will be cast on this model
     * @property {String} materialAsset The material {@link pc.Asset.Asset} that will be used to render the model (not used on models of type 'asset')
     * @property {pc.scene.Model} model The model that is added to the scene graph.
     */
    var ModelComponent = function ModelComponent (system, entity)   {
        this.on("set_type", this.onSetType, this);
        this.on("set_asset", this.onSetAsset, this);
        this.on("set_castShadows", this.onSetCastShadows, this);
        this.on("set_model", this.onSetModel, this);
        this.on("set_receiveShadows", this.onSetReceiveShadows, this);

        // override materialAsset property to return a pc.Asset instead
        Object.defineProperty(this, 'materialAsset', {
            set: this.setMaterialAsset.bind(this),
            get: this.getMaterialAsset.bind(this)
        });

        this.materialLoader = new pc.resources.MaterialResourceLoader(system.context.graphicsDevice, system.context.assets);
    };
    ModelComponent = pc.inherits(ModelComponent, pc.fw.Component);

    pc.extend(ModelComponent.prototype, {
        /**
        * @function
        * @name pc.fw.ModelComponent#setVisible
        * @description Enable or disable rendering for the Model.
        * @param {Boolean} visible True to enable rendering for the model, false to disable it
        */
        setVisible: function (visible) {
            if (this.data.model) {
                var inScene = this.system.context.scene.containsModel(this.data.model);

                if (visible && !inScene) {
                    this.system.context.scene.addModel(this.data.model);
                } else if (!visible && inScene) {
                    this.system.context.scene.removeModel(this.data.model);
                }
            }
        },

        loadModelAsset: function (guid) {
            var options = {
                parent: this.entity.getRequest()
            };

            var asset = this.system.context.assets.getAssetByResourceId(guid);
            if (!asset) {
                logERROR(pc.string.format('Trying to load model before asset {0} is loaded.', guid));
                return;
            }

            this.system.context.assets.load(asset, [], options).then(function (resources) {
                var model = resources[0];

                if (this.system.context.designer) {
                    model.generateWireframe();

                    asset.on('change', this.onAssetChange, this);
                }

                if (this.data.type === 'asset') {
                    this.model = model;
                }
            }.bind(this));
        },

        /**
         * @function
         * @private
         * @name pc.fw.ModelComponent#onSetType
         * @description Handle changes to the 'type' variable
         */
        onSetType: function (name, oldValue, newValue) {
            var data = this.data;

            if (newValue) {
                var mesh = null;

                if (newValue === 'asset') {
                    if (this.data.asset) {
                        this.loadModelAsset(this.data.asset);
                    } else {
                        this.model = null;
                    }
                } else {
                    switch (newValue) {
                        case 'box':
                            mesh = this.system.box;
                            break;
                        case 'capsule':
                            mesh = this.system.capsule;
                            break;
                        case 'sphere':
                            mesh = this.system.sphere;
                            break;
                        case 'cone':
                            mesh = this.system.cone;
                            break;
                        case 'cylinder':
                            mesh = this.system.cylinder;
                            break;
                        default:
                            throw new Error("Invalid model type: " + newValue);
                    }

                    var node = new pc.scene.GraphNode();

                    var model = new pc.scene.Model();
                    model.graph = node;

                    model.meshInstances = [ new pc.scene.MeshInstance(node, mesh, data.material) ];

                    if (this.system.context.designer) {
                        model.generateWireframe();
                    }

                    this.model = model;
                }
            }
        },

        onSetAsset: function (name, oldValue, newValue) {
            if (oldValue) {
                // Remove old listener
                var asset = this.system.context.assets.getAssetByResourceId(oldValue);
                if (asset) {
                    asset.off('change', this.onAssetChange, this);
                }
            }

            if (this.data.type === 'asset') {
                if (newValue) {
                    this.loadModelAsset(newValue);
                } else {
                    this.model = null;
                }
            }
        },

        onSetCastShadows: function (name, oldValue, newValue) {
            var model = this.data.model;
            if (model) {
                var scene = this.system.context.scene;
                var inScene = scene.containsModel(model);
                if (inScene) {
                    scene.removeModel(model);
                }

                var meshInstances = model.meshInstances;
                for (var i = 0; i < meshInstances.length; i++) {
                    meshInstances[i].castShadow = newValue;
                }

                if (inScene) {
                    scene.addModel(model);
                }
            }
        },

        onSetModel: function (name, oldValue, newValue) {
            if (oldValue) {
                this.system.context.scene.removeModel(oldValue);
                this.entity.removeChild(oldValue.getGraph());
                delete oldValue._entity;
            }

            if (newValue) {
                var componentData = this.data;
                var meshInstances = newValue.meshInstances;
                for (var i = 0; i < meshInstances.length; i++) {
                    meshInstances[i].castShadow = componentData.castShadows;
                    meshInstances[i].receiveShadow = componentData.receiveShadows;
                }

                this.entity.addChild(newValue.graph);
                this.system.context.scene.addModel(newValue);

                // Store the entity that owns this model
                newValue._entity = this.entity;

                // Update any animation component
                if (this.entity.animation) {
                    this.entity.animation.setModel(newValue);
                }
            }
        },

        setMaterialAsset: function (newValue) {
            // if the type of the value is not a string assume it is an pc.Asset
            var guid = typeof newValue === 'string' || !newValue ? newValue : newValue.resourceId;

            material = guid ? this.materialLoader.load(guid) : this.system.defaultMaterial;
            this.data.material = material;
            if (this.data.model && this.data.type !== 'asset') {
                var meshInstances = this.data.model.meshInstances;
                for (var i=0; i<meshInstances.length; i++) {
                    meshInstances[i].material = material;
                }
            }

            var oldValue = this.data.materialAsset;
            this.data.materialAsset = guid;
            this.fire('set', 'materialAsset', oldValue, guid);
        },

        getMaterialAsset: function () {
            return this.system.context.assets.getAssetByResourceId(this.data.materialAsset);
        },

        onSetReceiveShadows: function (name, oldValue, newValue) {
            if (newValue !== undefined) {
                var componentData = this.data;
                if (componentData.model) {
                    var meshInstances = componentData.model.meshInstances;
                    for (var i = 0; i < meshInstances.length; i++) {
                        meshInstances[i].receiveShadow = newValue;
                    }
                }
            }
        },

        /**
        * @private
        * @description Attached to the asset during loading (while running with the designer or over livelink), this callback
        * is used to reload the asset if it is changed.
        */
        onAssetChange: function (asset) {
            // Remove the asset from the cache and reload it
            this.system.context.loader.removeFromCache(asset.getFileUrl());
            this.asset = null;
            this.asset = asset.resourceId;
        }
    });

    return {
        ModelComponent: ModelComponent
    };
}());<|endoftext|>


<commit_before>/**
 * Module dependencies
 */
var errors = require('../errors')
  , utils = require('../utils');

/**
 * Secures a route requiring a valid access_token.
 * optionally also laods the client and/or user reflected by the token.
 *
 * If a token is present the client_id and user_id are placed in req.a2
 *
 * Options:
 *  `server`            Required, the server that is used for decrypting tokens and loading clients/users.
 *  `load_client`       Load the client reflected by client_id and validates the client_id, default: false
 *  `load_user`         Loads the user reflected by user_id in access_token. Enables require_token., default: false
 *  `require_token`     Requires a valid access_token
 *  `store`             The to be used, see store dir. defalts to server's store.
 *
 * @param options {Object}
 *
 */
function secure(options) {
  var server = options.server;
  var loadClient = options.load_client || options.require_client || false;
  var loadUser = options.load_user || options.require_user || false;
  var requireToken = options.require_token || true;
  if(loadUser) {
    requireToken = true;
  }

  return function(req, res, next) {
    req.a2 = req.a2 || {};
    req.a2.server = server;
    var self = this;
    if(req.query.client_id) {
      req.a2.client_id = req.query.client_id;
    }

    if(req.query.code) {
      req.a2.code = req.query.code;
    }
    if(req.query.state || (req.body && req.body.state)) {
      req.a2.state = req.query.state;
    }
    if(req.query.response_type) {
      req.a2.response_type = req.query.response_type;
    }

    utils.getTokenFromRequest(req, res, function(err, tokenData) {
      if(err) {
        console.error("invalid token");
        return errors.resource.invalid_token(req, res);
      } else if((!err && !tokenData) && requireToken) {
        // No access_token was present, loadUser impossible.
        console.error("no token data available.");
        return errors.resource.access_denied(req, res);
      }

      if(tokenData) {
        server.tokenService.validateToken(tokenData, 'access_token', function(err, valid) {
          if(err || !valid) {
            return errors.resource.invalid_token(req, res);
          }
          req.a2.access_token = tokenData;
          req.a2.user_id = tokenData.user_id;
          req.a2.client_id = tokenData.client_id;
          var clientId = tokenData.client_id;
          var userId = tokenData.user_id;
          if(loadClient) {
            server.clientService.load(clientId, function(err, client) {
              if(err) {
                return next(err);
              }
              req.a2.client = client;
              if(!loadUser || (loadUser && req.a2.user)) {
                return next();
              }
            });
          }

          if(loadUser) {
            server.userService.load(tokenData.user_id, function(err, user) {
              if(err) {
                return next(err);
              }
              req.a2.user = user;
              if(!loadClient || (loadClient && req.a2.client)) {
                return next();
              }
            });
          }
        });
      } else {
        if(requireToken || (loadClient && !req.query.client_id)) {
          return errors.resource.access_denied(req, res);
        } else {
          if(loadClient && !req.query.client_id) {
            return errors.resource.access_denied(req, res);
          }
          return next();
        }
      }
    });
  }
}

/**
 * expose middleware
 */
module.exports = secure;<commit_msg>secure middleware fixes<commit_after>/**
 * Module dependencies
 */
var errors = require('../errors')
  , utils = require('../utils');

/**
 * Secures a route requiring a valid access_token.
 * optionally also laods the client and/or user reflected by the token.
 *
 * If a token is present the client_id and user_id are placed in req.a2
 *
 * Options:
 *  `server`            Required, the server that is used for decrypting tokens and loading clients/users.
 *  `load_client`       Load the client reflected by client_id and validates the client_id, default: false
 *  `load_user`         Loads the user reflected by user_id in access_token. Enables require_token., default: false
 *  `require_token`     Requires a valid access_token
 *  `store`             The to be used, see store dir. defalts to server's store.
 *
 * @param options {Object}
 *
 */
function secure(options) {
  var server = options.server;
  var loadClient = options.load_client || options.require_client || false;
  var loadUser = options.load_user || options.require_user || false;
  var requireToken = options.require_token || false;
  if(loadUser) {
    requireToken = true;
  }

  return function(req, res, next) {
    req.a2 = req.a2 || {};
    req.a2.server = server;
    var self = this;
    if(req.query.client_id) {
      req.a2.client_id = req.query.client_id;
    }

    if(req.query.state || (req.body && req.body.state)) {
      req.a2.state = req.query.state;
    }
    if(req.query.response_type) {
      req.a2.response_type = req.query.response_type;
    }

    utils.getTokenFromRequest(req, res, function(err, tokenData) {
      if(err) {
        console.error("invalid token");
        return errors.resource.invalid_token(req, res);
      } else if((!err && !tokenData) && requireToken) {
        // No access_token was present, loadUser impossible.
        console.error("no token data available.");
        return errors.resource.access_denied(req, res);
      }

      if(tokenData) {
        server.tokenService.validateToken(tokenData, 'access_token', function(err, valid) {
          if(err || !valid) {
            return errors.resource.invalid_token(req, res);
          }
          req.a2.access_token = tokenData;
          req.a2.user_id = tokenData.user_id;
          req.a2.client_id = tokenData.client_id;
          var clientId = tokenData.client_id;
          var userId = tokenData.user_id;
          if(loadClient) {
            server.clientService.load(clientId, function(err, client) {
              if(err) {
                return next(err);
              }
              req.a2.client = client;
              if(!loadUser || (loadUser && req.a2.user)) {
                return next();
              }
            });
          }

          if(loadUser) {
            server.userService.load(tokenData.user_id, function(err, user) {
              if(err) {
                return next(err);
              }
              req.a2.user = user;
              if(!loadClient || (loadClient && req.a2.client)) {
                return next();
              }
            });
          }
        });
      } else {
        if(loadClient && req.query.client_id) {
          server.clientService.load(req.query.client_id, function(err, client) {
            if(err || !client) {
              return errors.resource.access_denied(req, res);
            }
            req.a2.client = client;
            return next();
          });
        } else if(loadClient && !req.query.client_id) {
          return errors.resource.access_denied(req, res);
        }

        if(requireToken || (loadClient && !req.query.client_id)) {
          console.log("need token but no token or need client and no client_id");
          return errors.resource.access_denied(req, res);
        } else {
          if(loadClient && !req.query.client_id) {
            console.log("loadClient without client_id");
            return errors.resource.access_denied(req, res);
          }
          return next();
        }
      }
    });
  }
}

/**
 * expose middleware
 */
module.exports = secure;<|endoftext|>


<commit_before>/*   Copyright (c) 2010, Diaspora Inc.  This file is
 *   licensed under the Affero General Public License version 3 or later.  See
 *   the COPYRIGHT file.
 */

describe("Stream", function() {
  beforeEach(function() {
    jasmine.Clock.useMock();
    spec.loadFixture('aspects_index_with_posts');
    Diaspora.widgets.i18n.locale = { };
  });

  describe("setUpLives", function() {

    it("attaches a click event to toggle_post_comments links", function() {
      spyOn(Stream, "toggleComments");
      Stream.initializeLives();
      $('.stream a.toggle_post_comments').click();
      expect(Stream.toggleComments).toHaveBeenCalled();
    });

  });
  describe("collapseText", function() {

    it("adds a 'show more' links to long posts", function() {
      Diaspora.widgets.i18n.loadLocale(
        {show_more: 'Placeholder'}, 'en');

      stream_element = $('#main_stream .stream_element:first');
      Stream.collapseText('eventID', stream_element[0]);

      expect(stream_element.find("p .details").css('display')).toEqual('none');
      expect(stream_element.find(".read-more a").css('display')).toEqual('inline');

      stream_element.find(".read-more a").click();
      jasmine.Clock.tick(200);

      expect(stream_element.find(".read-more").css('display')).toEqual('none');
      expect(stream_element.find(".details").css('display')).toEqual('inline');
    });
  });

  describe("streamElement", function() {
    it("makes sure that ajax spinner appears when hiding a post", function() {
      Stream.bindHideIcon();
      link = $("a.stream_element_delete.vis_hide");
      spinner = link.next("img.hide_loader");
      expect(link).not.toHaveClass("hidden");
      expect(spinner).toHaveClass("hidden");
      spyOn($, "ajax");
      link.click();
      expect($.ajax).toHaveBeenCalled();
      expect(link).toHaveClass("hidden");
      expect(spinner).not.toHaveClass("hidden");
    });
  });

  describe("initialize", function() {
    it("calls collapseText",function(){
      spyOn(Stream, "collapseText");
      Stream.initialize();
      expect(Stream.collapseText).toHaveBeenCalled();
    })
  });

  describe("toggleComments", function() {
    it("toggles class hidden on the comments ul", function () {
      link = $("a.toggle_post_comments");
      expect(jQuery('ul.comments')).not.toHaveClass("hidden");
      Stream.toggleComments.call(
        link, {preventDefault: function(){} }
      );
      jasmine.Clock.tick(200);
      expect(jQuery('ul.comments')).toHaveClass("hidden");
    });

    it("changes the text on the show comments link", function() {
      link = $("a.toggle_post_comments");
      Diaspora.widgets.i18n.loadLocale(
        {'comments' : {'show': 'comments.show pl'}}, 'en');
      expect(link.text()).toEqual("Hide all comments");
      Stream.toggleComments.call(
        link, {preventDefault: function(){} }
      );
      jasmine.Clock.tick(200);
      expect(link.text()).toEqual("comments.show pl");
    });
  });

});
<commit_msg>Made toggleComments jasmine test aware that there are more posts in the fixture<commit_after>/*   Copyright (c) 2010, Diaspora Inc.  This file is
 *   licensed under the Affero General Public License version 3 or later.  See
 *   the COPYRIGHT file.
 */

describe("Stream", function() {
  beforeEach(function() {
    jasmine.Clock.useMock();
    spec.loadFixture('aspects_index_with_posts');
    Diaspora.widgets.i18n.locale = { };
  });

  describe("setUpLives", function() {

    it("attaches a click event to toggle_post_comments links", function() {
      spyOn(Stream, "toggleComments");
      Stream.initializeLives();
      $('.stream a.toggle_post_comments').click();
      expect(Stream.toggleComments).toHaveBeenCalled();
    });

  });
  describe("collapseText", function() {

    it("adds a 'show more' links to long posts", function() {
      Diaspora.widgets.i18n.loadLocale(
        {show_more: 'Placeholder'}, 'en');

      stream_element = $('#main_stream .stream_element:first');
      Stream.collapseText('eventID', stream_element[0]);

      expect(stream_element.find("p .details").css('display')).toEqual('none');
      expect(stream_element.find(".read-more a").css('display')).toEqual('inline');

      stream_element.find(".read-more a").click();
      jasmine.Clock.tick(200);

      expect(stream_element.find(".read-more").css('display')).toEqual('none');
      expect(stream_element.find(".details").css('display')).toEqual('inline');
    });
  });

  describe("streamElement", function() {
    it("makes sure that ajax spinner appears when hiding a post", function() {
      Stream.bindHideIcon();
      link = $("a.stream_element_delete.vis_hide");
      spinner = link.next("img.hide_loader");
      expect(link).not.toHaveClass("hidden");
      expect(spinner).toHaveClass("hidden");
      spyOn($, "ajax");
      link.click();
      expect($.ajax).toHaveBeenCalled();
      expect(link).toHaveClass("hidden");
      expect(spinner).not.toHaveClass("hidden");
    });
  });

  describe("initialize", function() {
    it("calls collapseText",function(){
      spyOn(Stream, "collapseText");
      Stream.initialize();
      expect(Stream.collapseText).toHaveBeenCalled();
    })
  });

  describe("toggleComments", function() {
    it("toggles class hidden on the comments ul", function () {
      link = $("a.toggle_post_comments").first();
      expect(jQuery('ul.comments')).not.toHaveClass("hidden");
      Stream.toggleComments.call(
        link, {preventDefault: function(){} }
      );
      jasmine.Clock.tick(200);
      expect(jQuery('ul.comments')).toHaveClass("hidden");
    });

    it("changes the text on the show comments link", function() {
      link = $("a.toggle_post_comments").first();
      Diaspora.widgets.i18n.loadLocale(
        {'comments' : {'show': 'comments.show pl'}}, 'en');
      expect(link.text()).toEqual("Hide all comments");
      Stream.toggleComments.call(
        link, {preventDefault: function(){} }
      );
      jasmine.Clock.tick(200);
      expect(link.text()).toEqual("comments.show pl");
    });
  });

});
<|endoftext|>


<commit_before>/* eslint-disable
  jasmine/no-global-setup, jasmine/no-unsafe-spy, no-underscore-dangle, no-console
*/

import $ from 'jquery';
import 'vendor/jasmine-jquery';
import '~/commons';
import Vue from 'vue';
import VueResource from 'vue-resource';
import Translate from '~/vue_shared/translate';
import CheckEE from '~/vue_shared/mixins/is_ee';
import jasmineDiff from 'jasmine-diff';

import { getDefaultAdapter } from '~/lib/utils/axios_utils';
import { FIXTURES_PATH, TEST_HOST } from './test_constants';

import customMatchers from './matchers';

const isHeadlessChrome = /\bHeadlessChrome\//.test(navigator.userAgent);
Vue.config.devtools = !isHeadlessChrome;
Vue.config.productionTip = false;

let hasVueWarnings = false;
Vue.config.warnHandler = (msg, vm, trace) => {
  // The following workaround is necessary, so we are able to use setProps from Vue test utils
  // see https://github.com/vuejs/vue-test-utils/issues/631#issuecomment-421108344
  const currentStack = new Error().stack;
  const isInVueTestUtils = currentStack
    .split('\n')
    .some(line => line.startsWith('    at VueWrapper.setProps ('));
  if (isInVueTestUtils) {
    return;
  }

  hasVueWarnings = true;
  fail(`${msg}${trace}`);
};

let hasVueErrors = false;
Vue.config.errorHandler = function(err) {
  hasVueErrors = true;
  fail(err);
};

Vue.use(VueResource);
Vue.use(Translate);
Vue.use(CheckEE);

// enable test fixtures
jasmine.getFixtures().fixturesPath = FIXTURES_PATH;
jasmine.getJSONFixtures().fixturesPath = FIXTURES_PATH;

beforeAll(() => {
  jasmine.addMatchers(
    jasmineDiff(jasmine, {
      colors: window.__karma__.config.color,
      inline: window.__karma__.config.color,
    }),
  );
  jasmine.addMatchers(customMatchers);
});

// globalize common libraries
window.$ = $;
window.jQuery = window.$;

// stub expected globals
window.gl = window.gl || {};
window.gl.TEST_HOST = TEST_HOST;
window.gon = window.gon || {};
window.gon.test_env = true;
window.gon.ee = false;
gon.relative_url_root = '';

let hasUnhandledPromiseRejections = false;

window.addEventListener('unhandledrejection', event => {
  hasUnhandledPromiseRejections = true;
  console.error('Unhandled promise rejection:');
  console.error(event.reason.stack || event.reason);
});

// Add global function to spy on a module's dependencies via rewire
window.spyOnDependency = (module, name) => {
  const dependency = module.__GetDependency__(name);
  const spy = jasmine.createSpy(name, dependency);
  module.__Rewire__(name, spy);
  return spy;
};

// Reset any rewired modules after each test (see babel-plugin-rewire)
afterEach(__rewire_reset_all__); // eslint-disable-line

// HACK: Chrome 59 disconnects if there are too many synchronous tests in a row
// because it appears to lock up the thread that communicates to Karma's socket
// This async beforeEach gets called on every spec and releases the JS thread long
// enough for the socket to continue to communicate.
// The downside is that it creates a minor performance penalty in the time it takes
// to run our unit tests.
beforeEach(done => done());

const builtinVueHttpInterceptors = Vue.http.interceptors.slice();

beforeEach(() => {
  // restore interceptors so we have no remaining ones from previous tests
  Vue.http.interceptors = builtinVueHttpInterceptors.slice();
});

let longRunningTestTimeoutHandle;

beforeEach(done => {
  longRunningTestTimeoutHandle = setTimeout(() => {
    done.fail('Test is running too long!');
  }, 2000);
  done();
});

afterEach(() => {
  clearTimeout(longRunningTestTimeoutHandle);
});

const axiosDefaultAdapter = getDefaultAdapter();

// render all of our tests
const testContexts = [require.context('spec', true, /_spec$/)];

if (process.env.EE) {
  testContexts.push(require.context('ee_spec', true, /_spec$/));
}

testContexts.forEach(context => {
  context.keys().forEach(path => {
    try {
      context(path);
    } catch (err) {
      console.log(err);
      console.error('[GL SPEC RUNNER ERROR] Unable to load spec: ', path);
      describe('Test bundle', function() {
        it(`includes '${path}'`, function() {
          expect(err).toBeNull();
        });
      });
    }
  });
});

describe('test errors', () => {
  beforeAll(done => {
    if (hasUnhandledPromiseRejections || hasVueWarnings || hasVueErrors) {
      setTimeout(done, 1000);
    } else {
      done();
    }
  });

  it('has no unhandled Promise rejections', () => {
    expect(hasUnhandledPromiseRejections).toBe(false);
  });

  it('has no Vue warnings', () => {
    expect(hasVueWarnings).toBe(false);
  });

  it('has no Vue error', () => {
    expect(hasVueErrors).toBe(false);
  });

  it('restores axios adapter after mocking', () => {
    if (getDefaultAdapter() !== axiosDefaultAdapter) {
      fail('axios adapter is not restored! Did you forget a restore() on MockAdapter?');
    }
  });
});

// if we're generating coverage reports, make sure to include all files so
// that we can catch files with 0% coverage
// see: https://github.com/deepsweet/istanbul-instrumenter-loader/issues/15
if (process.env.BABEL_ENV === 'coverage') {
  // exempt these files from the coverage report
  const troubleMakers = [
    './blob_edit/blob_bundle.js',
    './boards/components/modal/empty_state.vue',
    './boards/components/modal/footer.js',
    './boards/components/modal/header.js',
    './cycle_analytics/cycle_analytics_bundle.js',
    './cycle_analytics/components/stage_plan_component.js',
    './cycle_analytics/components/stage_staging_component.js',
    './cycle_analytics/components/stage_test_component.js',
    './commit/pipelines/pipelines_bundle.js',
    './diff_notes/diff_notes_bundle.js',
    './diff_notes/components/jump_to_discussion.js',
    './diff_notes/components/resolve_count.js',
    './dispatcher.js',
    './environments/environments_bundle.js',
    './graphs/graphs_bundle.js',
    './issuable/time_tracking/time_tracking_bundle.js',
    './main.js',
    './merge_conflicts/merge_conflicts_bundle.js',
    './merge_conflicts/components/inline_conflict_lines.js',
    './merge_conflicts/components/parallel_conflict_lines.js',
    './monitoring/monitoring_bundle.js',
    './network/network_bundle.js',
    './network/branch_graph.js',
    './profile/profile_bundle.js',
    './protected_branches/protected_branches_bundle.js',
    './snippet/snippet_bundle.js',
    './terminal/terminal_bundle.js',
    './users/users_bundle.js',
    './issue_show/index.js',
    './pages/admin/application_settings/show/index.js',
  ];

  describe('Uncovered files', function() {
    const sourceFilesContexts = [require.context('~', true, /\.(js|vue)$/)];

    if (process.env.EE) {
      sourceFilesContexts.push(require.context('ee', true, /\.(js|vue)$/));
    }

    const allTestFiles = testContexts.reduce(
      (accumulator, context) => accumulator.concat(context.keys()),
      [],
    );

    $.holdReady(true);

    sourceFilesContexts.forEach(context => {
      context.keys().forEach(path => {
        // ignore if there is a matching spec file
        if (allTestFiles.indexOf(`${path.replace(/\.(js|vue)$/, '')}_spec`) > -1) {
          return;
        }

        it(`includes '${path}'`, function() {
          try {
            context(path);
          } catch (err) {
            if (troubleMakers.indexOf(path) === -1) {
              expect(err).toBeNull();
            }
          }
        });
      });
    });
  });
}
<commit_msg>Use flag provided from Webpack to mock gon.ee<commit_after>/* eslint-disable
  jasmine/no-global-setup, jasmine/no-unsafe-spy, no-underscore-dangle, no-console
*/

import $ from 'jquery';
import 'vendor/jasmine-jquery';
import '~/commons';
import Vue from 'vue';
import VueResource from 'vue-resource';
import Translate from '~/vue_shared/translate';
import CheckEE from '~/vue_shared/mixins/is_ee';
import jasmineDiff from 'jasmine-diff';

import { getDefaultAdapter } from '~/lib/utils/axios_utils';
import { FIXTURES_PATH, TEST_HOST } from './test_constants';

import customMatchers from './matchers';

const isHeadlessChrome = /\bHeadlessChrome\//.test(navigator.userAgent);
Vue.config.devtools = !isHeadlessChrome;
Vue.config.productionTip = false;

let hasVueWarnings = false;
Vue.config.warnHandler = (msg, vm, trace) => {
  // The following workaround is necessary, so we are able to use setProps from Vue test utils
  // see https://github.com/vuejs/vue-test-utils/issues/631#issuecomment-421108344
  const currentStack = new Error().stack;
  const isInVueTestUtils = currentStack
    .split('\n')
    .some(line => line.startsWith('    at VueWrapper.setProps ('));
  if (isInVueTestUtils) {
    return;
  }

  hasVueWarnings = true;
  fail(`${msg}${trace}`);
};

let hasVueErrors = false;
Vue.config.errorHandler = function(err) {
  hasVueErrors = true;
  fail(err);
};

Vue.use(VueResource);
Vue.use(Translate);
Vue.use(CheckEE);

// enable test fixtures
jasmine.getFixtures().fixturesPath = FIXTURES_PATH;
jasmine.getJSONFixtures().fixturesPath = FIXTURES_PATH;

beforeAll(() => {
  jasmine.addMatchers(
    jasmineDiff(jasmine, {
      colors: window.__karma__.config.color,
      inline: window.__karma__.config.color,
    }),
  );
  jasmine.addMatchers(customMatchers);
});

// globalize common libraries
window.$ = $;
window.jQuery = window.$;

// stub expected globals
window.gl = window.gl || {};
window.gl.TEST_HOST = TEST_HOST;
window.gon = window.gon || {};
window.gon.test_env = true;
window.gon.ee = process.env.EE;
gon.relative_url_root = '';

let hasUnhandledPromiseRejections = false;

window.addEventListener('unhandledrejection', event => {
  hasUnhandledPromiseRejections = true;
  console.error('Unhandled promise rejection:');
  console.error(event.reason.stack || event.reason);
});

// Add global function to spy on a module's dependencies via rewire
window.spyOnDependency = (module, name) => {
  const dependency = module.__GetDependency__(name);
  const spy = jasmine.createSpy(name, dependency);
  module.__Rewire__(name, spy);
  return spy;
};

// Reset any rewired modules after each test (see babel-plugin-rewire)
afterEach(__rewire_reset_all__); // eslint-disable-line

// HACK: Chrome 59 disconnects if there are too many synchronous tests in a row
// because it appears to lock up the thread that communicates to Karma's socket
// This async beforeEach gets called on every spec and releases the JS thread long
// enough for the socket to continue to communicate.
// The downside is that it creates a minor performance penalty in the time it takes
// to run our unit tests.
beforeEach(done => done());

const builtinVueHttpInterceptors = Vue.http.interceptors.slice();

beforeEach(() => {
  // restore interceptors so we have no remaining ones from previous tests
  Vue.http.interceptors = builtinVueHttpInterceptors.slice();
});

let longRunningTestTimeoutHandle;

beforeEach(done => {
  longRunningTestTimeoutHandle = setTimeout(() => {
    done.fail('Test is running too long!');
  }, 2000);
  done();
});

afterEach(() => {
  clearTimeout(longRunningTestTimeoutHandle);
});

const axiosDefaultAdapter = getDefaultAdapter();

// render all of our tests
const testContexts = [require.context('spec', true, /_spec$/)];

if (process.env.EE) {
  testContexts.push(require.context('ee_spec', true, /_spec$/));
}

testContexts.forEach(context => {
  context.keys().forEach(path => {
    try {
      context(path);
    } catch (err) {
      console.log(err);
      console.error('[GL SPEC RUNNER ERROR] Unable to load spec: ', path);
      describe('Test bundle', function() {
        it(`includes '${path}'`, function() {
          expect(err).toBeNull();
        });
      });
    }
  });
});

describe('test errors', () => {
  beforeAll(done => {
    if (hasUnhandledPromiseRejections || hasVueWarnings || hasVueErrors) {
      setTimeout(done, 1000);
    } else {
      done();
    }
  });

  it('has no unhandled Promise rejections', () => {
    expect(hasUnhandledPromiseRejections).toBe(false);
  });

  it('has no Vue warnings', () => {
    expect(hasVueWarnings).toBe(false);
  });

  it('has no Vue error', () => {
    expect(hasVueErrors).toBe(false);
  });

  it('restores axios adapter after mocking', () => {
    if (getDefaultAdapter() !== axiosDefaultAdapter) {
      fail('axios adapter is not restored! Did you forget a restore() on MockAdapter?');
    }
  });
});

// if we're generating coverage reports, make sure to include all files so
// that we can catch files with 0% coverage
// see: https://github.com/deepsweet/istanbul-instrumenter-loader/issues/15
if (process.env.BABEL_ENV === 'coverage') {
  // exempt these files from the coverage report
  const troubleMakers = [
    './blob_edit/blob_bundle.js',
    './boards/components/modal/empty_state.vue',
    './boards/components/modal/footer.js',
    './boards/components/modal/header.js',
    './cycle_analytics/cycle_analytics_bundle.js',
    './cycle_analytics/components/stage_plan_component.js',
    './cycle_analytics/components/stage_staging_component.js',
    './cycle_analytics/components/stage_test_component.js',
    './commit/pipelines/pipelines_bundle.js',
    './diff_notes/diff_notes_bundle.js',
    './diff_notes/components/jump_to_discussion.js',
    './diff_notes/components/resolve_count.js',
    './dispatcher.js',
    './environments/environments_bundle.js',
    './graphs/graphs_bundle.js',
    './issuable/time_tracking/time_tracking_bundle.js',
    './main.js',
    './merge_conflicts/merge_conflicts_bundle.js',
    './merge_conflicts/components/inline_conflict_lines.js',
    './merge_conflicts/components/parallel_conflict_lines.js',
    './monitoring/monitoring_bundle.js',
    './network/network_bundle.js',
    './network/branch_graph.js',
    './profile/profile_bundle.js',
    './protected_branches/protected_branches_bundle.js',
    './snippet/snippet_bundle.js',
    './terminal/terminal_bundle.js',
    './users/users_bundle.js',
    './issue_show/index.js',
    './pages/admin/application_settings/show/index.js',
  ];

  describe('Uncovered files', function() {
    const sourceFilesContexts = [require.context('~', true, /\.(js|vue)$/)];

    if (process.env.EE) {
      sourceFilesContexts.push(require.context('ee', true, /\.(js|vue)$/));
    }

    const allTestFiles = testContexts.reduce(
      (accumulator, context) => accumulator.concat(context.keys()),
      [],
    );

    $.holdReady(true);

    sourceFilesContexts.forEach(context => {
      context.keys().forEach(path => {
        // ignore if there is a matching spec file
        if (allTestFiles.indexOf(`${path.replace(/\.(js|vue)$/, '')}_spec`) > -1) {
          return;
        }

        it(`includes '${path}'`, function() {
          try {
            context(path);
          } catch (err) {
            if (troubleMakers.indexOf(path) === -1) {
              expect(err).toBeNull();
            }
          }
        });
      });
    });
  });
}
<|endoftext|>


<commit_before>module.exports = function(crowi) {
  var debug = require('debug')('crowi:models:attachment')
    , mongoose = require('mongoose')
    , ObjectId = mongoose.Schema.Types.ObjectId
    , fileUploader = require('../util/fileUploader')(crowi)
  ;

  function generateFileHash (fileName) {
    var hasher = require('crypto').createHash('md5');
    hasher.update(fileName);

    return hasher.digest('hex');
  }

  attachmentSchema = new mongoose.Schema({
    page: { type: ObjectId, ref: 'Page', index: true },
    creator: { type: ObjectId, ref: 'User', index: true  },
    filePath: { type: String, required: true },
    fileName: { type: String, required: true },
    originalName: { type: String },
    fileFormat: { type: String, required: true },
    fileSize: { type: Number, default: 0 },
    createdAt: { type: Date, default: Date.now }
  }, {
    toJSON: {
      virtuals: true
    },
  });

  attachmentSchema.virtual('fileUrl').get(function() {
    return `/files/${this._id}`;
  });

  attachmentSchema.statics.findById = function(id) {
    var Attachment = this;

    return new Promise(function(resolve, reject) {
      Attachment.findOne({_id: id}, function(err, data) {
        if (err) {
          return reject(err);
        }

        if (data === null) {
          return reject(new Error('Attachment not found'));
        }
        return resolve(data);
      });

    });
  };

  attachmentSchema.statics.getListByPageId = function(id) {
    var self = this;

    return new Promise(function(resolve, reject) {

      self
        .find({page: id})
        .sort({'updatedAt': 1})
        .populate('creator')
        .exec(function(err, data) {
          if (err) {
            return reject(err);
          }

          if (data.length < 1) {
            return resolve([]);
          }

          debug(data);
          return resolve(data);
        });
    });
  };

  attachmentSchema.statics.create = function(pageId, creator, filePath, originalName, fileName, fileFormat, fileSize) {
    var Attachment = this;

    return new Promise(function(resolve, reject) {
      var newAttachment = new Attachment();

      newAttachment.page = pageId;
      newAttachment.creator = creator._id;
      newAttachment.filePath = filePath;
      newAttachment.originalName = originalName;
      newAttachment.fileName = fileName;
      newAttachment.fileFormat = fileFormat;
      newAttachment.fileSize = fileSize;
      newAttachment.createdAt = Date.now();

      newAttachment.save(function(err, data) {
        if (err) {
          debug('Error on saving attachment.', err);
          return reject(err);
        }
        debug('Attachment saved.', data);
        return resolve(data);
      });
    });
  };

  attachmentSchema.statics.createAttachmentFilePath = function (pageId, fileName, fileType) {
    var ext = '.' + fileName.match(/(.*)(?:\.([^.]+$))/)[2] || '';

    return 'attachment/' + pageId + '/' + generateFileHash(fileName) + ext;
  };

  attachmentSchema.statics.removeAttachmentsByPageId = function(pageId) {
    var Attachment = this;

    return new Promise((resolve, reject) => {
      Attachment.getListByPageId(pageId)
      .then((attachments) => {
        for (attachment of attachments) {
          Attachment.removeAttachment(attachment).then((res) => {
            // do nothing
          }).catch((err) => {
            debug('Attachment remove error', err);
          });
        }

        resolve(attachments);
      }).catch((err) => {
        reject(err);
      });
    });

  };

  attachmentSchema.statics.findDeliveryFile = function(attachment, forceUpdate) {
    var Attachment = this;

    // TODO
    var forceUpdate = forceUpdate || false;

    return fileUploader.findDeliveryFile(attachment._id, attachment.filePath);
  };

  attachmentSchema.statics.removeAttachment = function(attachment) {
    const Attachment = this;
    const filePath = attachment.filePath;

    return new Promise((resolve, reject) => {
      Attachment.remove({_id: attachment._id}, (err, data) => {
        if (err) {
          return reject(err);
        }

        fileUploader.deleteFile(attachment._id, filePath)
        .then(data => {
          resolve(data); // this may null
        }).catch(err => {
          reject(err);
        });
      });
    });
  };

  return mongoose.model('Attachment', attachmentSchema);
};
<commit_msg>Fix error when tmpfile doesnt include ext in its original name<commit_after>module.exports = function(crowi) {
  var debug = require('debug')('crowi:models:attachment')
    , mongoose = require('mongoose')
    , ObjectId = mongoose.Schema.Types.ObjectId
    , fileUploader = require('../util/fileUploader')(crowi)
  ;

  function generateFileHash (fileName) {
    var hasher = require('crypto').createHash('md5');
    hasher.update(fileName);

    return hasher.digest('hex');
  }

  attachmentSchema = new mongoose.Schema({
    page: { type: ObjectId, ref: 'Page', index: true },
    creator: { type: ObjectId, ref: 'User', index: true  },
    filePath: { type: String, required: true },
    fileName: { type: String, required: true },
    originalName: { type: String },
    fileFormat: { type: String, required: true },
    fileSize: { type: Number, default: 0 },
    createdAt: { type: Date, default: Date.now }
  }, {
    toJSON: {
      virtuals: true
    },
  });

  attachmentSchema.virtual('fileUrl').get(function() {
    return `/files/${this._id}`;
  });

  attachmentSchema.statics.findById = function(id) {
    var Attachment = this;

    return new Promise(function(resolve, reject) {
      Attachment.findOne({_id: id}, function(err, data) {
        if (err) {
          return reject(err);
        }

        if (data === null) {
          return reject(new Error('Attachment not found'));
        }
        return resolve(data);
      });

    });
  };

  attachmentSchema.statics.getListByPageId = function(id) {
    var self = this;

    return new Promise(function(resolve, reject) {

      self
        .find({page: id})
        .sort({'updatedAt': 1})
        .populate('creator')
        .exec(function(err, data) {
          if (err) {
            return reject(err);
          }

          if (data.length < 1) {
            return resolve([]);
          }

          debug(data);
          return resolve(data);
        });
    });
  };

  attachmentSchema.statics.create = function(pageId, creator, filePath, originalName, fileName, fileFormat, fileSize) {
    var Attachment = this;

    return new Promise(function(resolve, reject) {
      var newAttachment = new Attachment();

      newAttachment.page = pageId;
      newAttachment.creator = creator._id;
      newAttachment.filePath = filePath;
      newAttachment.originalName = originalName;
      newAttachment.fileName = fileName;
      newAttachment.fileFormat = fileFormat;
      newAttachment.fileSize = fileSize;
      newAttachment.createdAt = Date.now();

      newAttachment.save(function(err, data) {
        if (err) {
          debug('Error on saving attachment.', err);
          return reject(err);
        }
        debug('Attachment saved.', data);
        return resolve(data);
      });
    });
  };

  attachmentSchema.statics.guessExtByFileType = function (fileType) {
    let ext = '';
    const isImage = fileType.match(/^image\/(.+)/i);

    if (isImage) {
      ext = isImage[1].toLowerCase();
    }

    return ext;
  };

  attachmentSchema.statics.createAttachmentFilePath = function (pageId, fileName, fileType) {
    const Attachment = this;
    let ext = '';
    const fnExt = fileName.match(/(.*)(?:\.([^.]+$))/);

    if (fnExt) {
      ext = '.' + fnExt[2];
    } else {
      ext = Attachment.guessExtByFileType(fileType);
      if (ext !== '') {
        ext = '.' + ext;
      }
    }

    return 'attachment/' + pageId + '/' + generateFileHash(fileName) + ext;
  };

  attachmentSchema.statics.removeAttachmentsByPageId = function(pageId) {
    var Attachment = this;

    return new Promise((resolve, reject) => {
      Attachment.getListByPageId(pageId)
      .then((attachments) => {
        for (attachment of attachments) {
          Attachment.removeAttachment(attachment).then((res) => {
            // do nothing
          }).catch((err) => {
            debug('Attachment remove error', err);
          });
        }

        resolve(attachments);
      }).catch((err) => {
        reject(err);
      });
    });

  };

  attachmentSchema.statics.findDeliveryFile = function(attachment, forceUpdate) {
    var Attachment = this;

    // TODO
    var forceUpdate = forceUpdate || false;

    return fileUploader.findDeliveryFile(attachment._id, attachment.filePath);
  };

  attachmentSchema.statics.removeAttachment = function(attachment) {
    const Attachment = this;
    const filePath = attachment.filePath;

    return new Promise((resolve, reject) => {
      Attachment.remove({_id: attachment._id}, (err, data) => {
        if (err) {
          return reject(err);
        }

        fileUploader.deleteFile(attachment._id, filePath)
        .then(data => {
          resolve(data); // this may null
        }).catch(err => {
          reject(err);
        });
      });
    });
  };

  return mongoose.model('Attachment', attachmentSchema);
};
<|endoftext|>


<commit_before>var NodeListPrototype = Y.NodeList.prototype,
    _selectorFilter = NodeListPrototype.filter;

/**
 * Filters the NodeList instance to only the matching nodes
 * @method Y.NodeList.filter
 * @param {string|function} filter A CSS selector string to apply to the list,
 * or a boolean function to apply to each element in the list. The function
 * will be passed three arguments, a Y.Node instance of the current node, the
 * current index in the list, and the NodeList instance.
 * @return {NodeList} NodeList containing the updated collection
 */
NodeListPrototype.filter = function(filter) {
    var newList;
    if (typeof(filter) === "string") {
        return _selectorFilter.apply(this, arguments);
    }
    if (typeof(filter) === 'function') {
        newList = new Y.NodeList([]);
        this.each(function(node, index, list) {
            if (filter(node, index, list)) {
                newList.push(node);
            }
        });
        return newList;
    }

    Y.log("Unrecognized filter type, returning list");
    return this;
};
/**
 * This inverse of filter. Applies :not to a selector, or builds a NodeList
 * consisting of all the nodes for which the argument is false
 * @param {string|function} filter A CSS selector string to apply to the list,
 * or a boolean function to apply to each element in the list. The function
 * will be passed three arguments, a Y.Node instance of the current node, the
 * current index in the list, and the NodeList instance.
 * @return {NodeList} NodeList containing the updated collection
 */
NodeListPrototype.reject = function(filter) {
    if (typeof(filter) === "string") {
        return this.filter(function(item) {
                    return !item.test(filter);
                });
    }
    if (typeof(filter) === "function") {
        return this.filter(function(item, i, a) {
                    return !filter.call(null, item, i, a);
                });
    }

    Y.log("Unrecognized filter type, returning list");
    return this;
};
<commit_msg>Cache reference to NodeList<commit_after>var NodeList = Y.NodeList,
    NodeListPrototype = NodeList.prototype,
    _selectorFilter = NodeListPrototype.filter;

/**
 * Filters the NodeList instance to only the matching nodes
 * @method Y.NodeList.filter
 * @param {string|function} filter A CSS selector string to apply to the list,
 * or a boolean function to apply to each element in the list. The function
 * will be passed three arguments, a Y.Node instance of the current node, the
 * current index in the list, and the NodeList instance.
 * @return {NodeList} NodeList containing the updated collection
 */
NodeListPrototype.filter = function(filter) {
    var newList;
    if (typeof(filter) === "string") {
        return _selectorFilter.apply(this, arguments);
    }
    if (typeof(filter) === 'function') {
        newList = new NodeList([]);
        this.each(function(node, index, list) {
            if (filter(node, index, list)) {
                newList.push(node);
            }
        });
        return newList;
    }

    Y.log("Unrecognized filter type, returning list");
    return this;
};
/**
 * This inverse of filter. Applies :not to a selector, or builds a NodeList
 * consisting of all the nodes for which the argument is false
 * @param {string|function} filter A CSS selector string to apply to the list,
 * or a boolean function to apply to each element in the list. The function
 * will be passed three arguments, a Y.Node instance of the current node, the
 * current index in the list, and the NodeList instance.
 * @return {NodeList} NodeList containing the updated collection
 */
NodeListPrototype.reject = function(filter) {
    if (typeof(filter) === "string") {
        return this.filter(function(item) {
                    return !item.test(filter);
                });
    }
    if (typeof(filter) === "function") {
        return this.filter(function(item, i, a) {
                    return !filter.call(null, item, i, a);
                });
    }

    Y.log("Unrecognized filter type, returning list");
    return this;
};
<|endoftext|>


<commit_before>/**
 * Core dependencies.
 */

var fs = require('fs');

/**
 * External dependencies.
 */

var AssertionError = require('assertion-error');

/**
 * Return an exit code expectation.
 *
 * @param {Number} expected exit code.
 * @returns {Function}
 * @api public
 */

exports.code = function(code) {
  return function(result) {
    if (code !== result.code) {
      return error(result, 'Expected exit code: "' + code + '", actual: "' + result.code + '"');
    }
  };
};

/**
 * Return no timeout expectation.
 *
 * @returns {Function}
 * @api public
 */

exports.time = function() {
  return function(result) {
    if (result.killed) {
      return error(result, 'Command execution terminated (timeout)');
    }
  };
};

/**
 * Return a stderr expectation.
 *
 * @param {String|RegExp} expected string or regular express to match
 * @returns {Function}
 * @api public
 */

exports.stderr = function(expected) {
  return function(result) {
    return assertOut('stderr', expected, result);
  };
};

/**
 * Return a stdout expectation.
 *
 * @param {String|RegExp} expected string or regular express to match
 * @returns {Function}
 * @api public
 */

exports.stdout = function(expected) {
  return function(result) {
    return assertOut('stdout', expected, result);
  };
};

/**
 * Verify that a `path` exists.
 *
 * @param {String} path
 * @returns {Function}
 * @api public
 */

exports.exists = function(path) {
  return function(result) {
    if (fs.existsSync(path) !== true) {
      return error(result, 'Expected "' + path + '" to exist.');
    }
  };
};

/**
 * Verify that `path`'s data matches `data`.
 *
 * @param {String} path
 * @param {String|RegExp} data
 * @returns {Function}
 * @api public
 */

exports.match = function(path, data) {
  return function(result) {
    var contents = fs.readFileSync(path, { encoding: 'utf8' });
    var statement = data instanceof RegExp
      ? data.test(contents)
      : data === contents;

    if (statement !== true) {
      return error(result, 'Expected "' + path + '" to match "' + data + '", but it was: "' + contents + '"');
    }
  };
};

/**
 * Assert stdout or stderr.
 *
 * @param {String} stdout/stderr
 * @param {Mixed} expected
 * @param {Result} result
 * @returns {AssertionError|null}
 * @api private
 */

function assertOut(key, expected, result) {
  var actual = result[key];
  var statement = expected instanceof RegExp
    ? expected.test(actual)
    : expected === actual;

  if (statement !== true) {
    var message = 'Expected ' + key +' to match "' + expected + '". Actual: "' + actual + '"';
    return error(result, message);
  }
}

/**
 * Create and return a new `AssertionError`.
 * It will assign the given `result` to it, it will also prepend the executed command
 * to the error message.
 *
 * Assertion error is a constructor for test and validation frameworks that implements
 * standardized Assertion Error specification.
 *
 * For more info go visit https://github.com/chaijs/assertion-error
 *
 * @param {Result} result
 * @param {String} error message
 * @returns {AssertionError}
 * @api private
 */

function error(result, message) {
  var err = new AssertionError('`' + result.cmd + '`: ' + message);
  err.result = result;
  return err;
}
<commit_msg>Provide extra assertion properties<commit_after>/**
 * Core dependencies.
 */

var fs = require('fs');

/**
 * External dependencies.
 */

var AssertionError = require('assertion-error');

/**
 * Return an exit code expectation.
 *
 * @param {Number} expected exit code.
 * @returns {Function}
 * @api public
 */

exports.code = function(code) {
  return function(result) {
    if (code !== result.code) {
      return error(result, 'Expected exit code: "' + code + '", actual: "' + result.code + '"');
    }
  };
};

/**
 * Return no timeout expectation.
 *
 * @returns {Function}
 * @api public
 */

exports.time = function() {
  return function(result) {
    if (result.killed) {
      return error(result, 'Command execution terminated (timeout)');
    }
  };
};

/**
 * Return a stderr expectation.
 *
 * @param {String|RegExp} expected string or regular express to match
 * @returns {Function}
 * @api public
 */

exports.stderr = function(expected) {
  return function(result) {
    return assertOut('stderr', expected, result);
  };
};

/**
 * Return a stdout expectation.
 *
 * @param {String|RegExp} expected string or regular express to match
 * @returns {Function}
 * @api public
 */

exports.stdout = function(expected) {
  return function(result) {
    return assertOut('stdout', expected, result);
  };
};

/**
 * Verify that a `path` exists.
 *
 * @param {String} path
 * @returns {Function}
 * @api public
 */

exports.exists = function(path) {
  return function(result) {
    if (fs.existsSync(path) !== true) {
      return error(result, 'Expected "' + path + '" to exist.');
    }
  };
};

/**
 * Verify that `path`'s data matches `data`.
 *
 * @param {String} path
 * @param {String|RegExp} data
 * @returns {Function}
 * @api public
 */

exports.match = function(path, data) {
  return function(result) {
    var contents = fs.readFileSync(path, { encoding: 'utf8' });
    var statement = data instanceof RegExp
      ? data.test(contents)
      : data === contents;

    if (statement !== true) {
      var message = 'Expected "' + path + '" to match "' + data + '", but it was: "' + contents + '"';
      return error(result, message, data, contents);
    }
  };
};

/**
 * Assert stdout or stderr.
 *
 * @param {String} stdout/stderr
 * @param {Mixed} expected
 * @param {Result} result
 * @returns {AssertionError|null}
 * @api private
 */

function assertOut(key, expected, result) {
  var actual = result[key];
  var statement = expected instanceof RegExp
    ? expected.test(actual)
    : expected === actual;

  if (statement !== true) {
    var message = 'Expected ' + key +' to match "' + expected + '". Actual: "' + actual + '"';
    return error(result, message, expected, actual);
  }
}

/**
 * Create and return a new `AssertionError`.
 * It will assign the given `result` to it, it will also prepend the executed command
 * to the error message.
 *
 * Assertion error is a constructor for test and validation frameworks that implements
 * standardized Assertion Error specification.
 *
 * For more info go visit https://github.com/chaijs/assertion-error
 *
 * @param {Result} result
 * @param {String} error message
 * @returns {AssertionError}
 * @api private
 */

function error(result, message, expected, actual) {
  var err = new AssertionError('`' + result.cmd + '`: ' + message);
  err.result = result;
  if (expected) {
    err.expected = expected;
  }
  if (actual) {
    err.actual = actual;
  }
  return err;
}
<|endoftext|>


<commit_before>const util = require('./util')

const getAttr = util.getAttr
const getText = util.getText
const getData = util.getData
const toNum = util.toNum
const parseSlug = util.parseSlug

module.exports = {
  /**
   * Answers.
   */
  answers($) {
    var eles = $('.zm-item[data-type="Answer"]')
    return util.map(eles, ele => _parseAnswer($, ele))
  }
}

/**
 * @private
 */
function _parseAnswer($, ele) {
  var questionEle = $('.zm-item-title a', ele)
  var answerEle = $('.zm-item-answer', ele)
  var voteupEle = $('.zm-votebar .count', ele)
  var authorEle = $('.zm-item-answer-author-info .author-link', ele)
  var contentEle = $('.zm-item-rich-text textarea', ele)
  var commentsEle = $('.zm-item-meta .toggle-comment')

  var answer = {
    id: getData(answerEle, 'atoken'),
    type: 'answer',
    aid: getData(answerEle, 'aid'),
    voteup_count: toNum(getText(voteupEle)),
    comment_count: toNum(getText(commentsEle).split(' ')[0]),
    content: getText(contentEle),
    created_time: getData(answerEle, 'created'),
    author: {
      name: getText(authorEle)
    },
    question: {
      id: toNum(getAttr(questionEle, 'href').substring('/question/'.length)),
      type: 'question',
      title: getText(questionEle)
    }
  }
  Object.assign(answer.author, parseSlug(getAttr(authorEle, 'href')))

  return answer
}
<commit_msg>comments bug for collection answers<commit_after>const util = require('./util')

const getAttr = util.getAttr
const getText = util.getText
const getData = util.getData
const toNum = util.toNum
const parseSlug = util.parseSlug

module.exports = {
  /**
   * Answers.
   */
  answers($) {
    var eles = $('.zm-item[data-type="Answer"]')
    return util.map(eles, ele => _parseAnswer($, ele))
  }
}

/**
 * @private
 */
function _parseAnswer($, ele) {
  var questionEle = $('.zm-item-title a', ele)
  var answerEle = $('.zm-item-answer', ele)
  var voteupEle = $('.zm-votebar .count', ele)
  var authorEle = $('.zm-item-answer-author-info .author-link', ele)
  var contentEle = $('.zm-item-rich-text textarea', ele)
  var commentsEle = $('.zm-item-meta .toggle-comment', ele)

  var answer = {
    id: getData(answerEle, 'atoken'),
    type: 'answer',
    aid: getData(answerEle, 'aid'),
    voteup_count: toNum(getText(voteupEle)),
    comment_count: toNum(getText(commentsEle).split(' ')[0]),
    content: getText(contentEle),
    created_time: getData(answerEle, 'created'),
    author: {
      name: getText(authorEle)
    },
    question: {
      id: toNum(getAttr(questionEle, 'href').substring('/question/'.length)),
      type: 'question',
      title: getText(questionEle)
    }
  }
  Object.assign(answer.author, parseSlug(getAttr(authorEle, 'href')))

  return answer
}
<|endoftext|>


<commit_before>(function () {
    'use strict';

    angular.module('app.core').config(config);

    /**
     * Route configuration
     *
     * @memberof module:core
     *
     * @param {object} $routeProvider
     * The route provider (ngRoute)
     */
    function config($routeProvider) {
        $routeProvider.
            when('/books', {
                controller: 'BookController',
                templateUrl: 'partials/book-list.html'
            }).
            when('/book/:bookId', {
                controller: 'BookDetailController',
                templateUrl: 'partials/book-detail.html'
            }).
            when('/books/new', {
                controller: 'BookController',
                templateUrl: 'partials/book-detail.html',
                resolve: {
                    factory: checkRouting
                }
            }).
            when('/login', {
                controller: 'LoginController',
                templateUrl: 'partials/login.html'
            }).
            when('/author/:authorId', {
                controller: 'AuthorDetailController',
                templateUrl: 'partials/author-detail.html'
            }).
            when('/author', {
                controller: 'AuthorController',
                templateUrl: 'partials/author-list.html'
            }).
            when('/author/new', {
                controller: 'AuthorController',
                templateUrl: 'partials/author-detail.html',
                resolve: {
                    factory: checkRouting
                }
            }).
            when('/user/:userId', {
                controller: 'UserDetailController',
                templateUrl: 'partials/user-detail.html',
                 resolve: {
                    factory: checkRouting
                }
            }).
            when('/users', {
                controller: 'UserController',
                templateUrl: 'partials/user-list.html',
                 resolve: {
                    factory: checkRouting
                }
            }).
            when('/users/new', {
                controller: 'UserController',
                templateUrl: 'partials/user-detail.html',
                resolve: {
                    factory: checkRouting
                }
            }).
            otherwise({
                redirectTo: '/books'
            });
    }
}());

var checkRouting= function ($q, $rootScope, $location) {
    if ($rootScope.isAuthenticated && $rootScope.userName) {
        return true;
    } else {
        $location.path("/login");
    }
};<commit_msg>fixing jshint and jscs errors<commit_after>(function () {
    'use strict';

    var checkRouting = function ($q, $rootScope, $location) {
        if ($rootScope.isAuthenticated && $rootScope.userName) {
            return true;
        } else {
            $location.path('/login');
        }
    };

    angular.module('app.core').config(config);

    /**
     * Route configuration
     *
     * @memberof module:core
     *
     * @param {object} $routeProvider
     * The route provider (ngRoute)
     */
    function config($routeProvider) {
        $routeProvider.
            when('/books', {
                controller: 'BookController',
                templateUrl: 'partials/book-list.html'
            }).
            when('/book/:bookId', {
                controller: 'BookDetailController',
                templateUrl: 'partials/book-detail.html'
            }).
            when('/books/new', {
                controller: 'BookController',
                templateUrl: 'partials/book-detail.html',
                resolve: {
                    factory: checkRouting
                }
            }).
            when('/login', {
                controller: 'LoginController',
                templateUrl: 'partials/login.html'
            }).
            when('/author/:authorId', {
                controller: 'AuthorDetailController',
                templateUrl: 'partials/author-detail.html'
            }).
            when('/author', {
                controller: 'AuthorController',
                templateUrl: 'partials/author-list.html'
            }).
            when('/author/new', {
                controller: 'AuthorController',
                templateUrl: 'partials/author-detail.html',
                resolve: {
                    factory: checkRouting
                }
            }).
            when('/user/:userId', {
                controller: 'UserDetailController',
                templateUrl: 'partials/user-detail.html',
                resolve: {
                    factory: checkRouting
                }
            }).
            when('/users', {
                controller: 'UserController',
                templateUrl: 'partials/user-list.html',
                resolve: {
                    factory: checkRouting
                }
            }).
            when('/users/new', {
                controller: 'UserController',
                templateUrl: 'partials/user-detail.html',
                resolve: {
                    factory: checkRouting
                }
            }).
            otherwise({
                redirectTo: '/books'
            });
    }
}());
<|endoftext|>


<commit_before>function checkDuplicateUser(playQueue, video, config) {
  if (config.userQueueLimit <= -1) return false;

  var count = 0;
  for (element of playQueue) {
    if (element.userId === video.userId) count++;
  }

  return (count >= config.userQueueLimit);
}

function checkDuplicateVideo(playQueue, video, config) {
  for (element of playQueue) {
    if (element.vid === video.vid) return true;
  }

  return false;
}

function checkVideoLength(playQueue, video, config) {
  if (config.maxLength > -1) {
    if (video.length_seconds > config.maxLength) {
      return true;
    }
  }

  return false;
}

var checks = [
  [checkDuplicateVideo, 'That video is already in the queue!'],
  [checkDuplicateUser, 'You already have too many videos in the queue!'],
  [checkVideoLength, 'That video is too long!'],
];

function shouldDisallowQueue(playQueue, video, config) {
  for (check of checks) {
    if (config.checksEnabled[check[0].name]) {
      result = check[0](playQueue, video, config);
      if (result) return check[1];
    }
  }

  return false;
}

module.exports = shouldDisallowQueue;
<commit_msg>Delete permission-checks.js<commit_after><|endoftext|>