<commit_before>/**
 * Created by Zhengfeng.Yao on 16/9/22.
 */
import path from 'path';
import webpack from 'webpack';
import webpackMerge from 'webpack-merge';
import AssetsPlugin from 'assets-webpack-plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import ProgressBarPlugin from 'progress-bar-webpack-plugin';
import { isValid, loadAegisConfig } from './utils';

const cwd = process.cwd();

export function getBaseConfig(dev, verbose, autoprefixer) {
  autoprefixer = autoprefixer || [
      'last 2 versions',
      '> 1%',
      'Explorer >= 9',
    ];
  console.log('verbose: ' + verbose);
  return {
    cache: !!dev,
    debug: !!dev,

    stats: {
      colors: true,
      reasons: !!dev,
      hash: !!verbose,
      version: !!verbose,
      timings: true,
      chunks: !!verbose,
      chunkModules: !!verbose,
      cached: !!verbose,
      cachedAssets: !!verbose,
    },

    plugins: [
      new ProgressBarPlugin(),
      new webpack.optimize.OccurenceOrderPlugin(),
    ],

    resolve: {
      extensions: ['', '.webpack.js', '.web.js', '.json', '.json5'],
      modulesDirectories: ['node_modules', path.join(cwd, 'node_modules'), path.join(__dirname, '../node_modules')]
    },

    resolveLoader: {
      modulesDirectories: ['node_modules', path.join(cwd, 'node_modules'), path.join(__dirname, '../node_modules')]
    },

    module: {
      loaders: [
        {
          test: /\.json$/,
          loader: 'json-loader',
        }, {
          test: /\.json5$/,
          loader: 'json5-loader',
        }, {
          test: /\.txt$/,
          loader: 'raw-loader',
        }, {
          test: /\.(svg|jpe?g|png|gif)(\?.*)?$/,
          loader: 'url-loader?limit=10000',
        }, {
          test: /\.(woff\d?|ttf|eot)(\?.*)?$/,
          loader: 'file-loader',
        }, {
          test: /\.est$/,
          loader: 'babel-loader!template-string-loader'
        }
      ],
    },

    postcss: () => {
      return [
        require('postcss-nested')(),
        require('pixrem')(),
        require('autoprefixer')(autoprefixer),
        require('postcss-flexibility')(),
        require('postcss-discard-duplicates')()
      ];
    },
  }
}

function style(dev, web, loader) {
  const query = `${!!dev ? 'sourceMap&' : 'minimize&'}modules&localIdentName=[local]`;
  if (web) {
    return new ExtractTextPlugin('style', `css?${query}!${loader}`);
  } else {
    return `css/locals?${query}!${loader}`;
  }
}

export function getBabelWebpackConfig(dev, web, options, verbose) {
  return {
    entry: options.entry,
    output: options.output,
    devtool: web ? (!!dev ? 'cheap-module-eval-source-map' : false) : 'source-map',
    target: web ? 'web' : 'node',
    resolve: {
      extensions: ['', '.js', '.jsx'],
    },
    babel: {
      presets: [
        require.resolve('babel-preset-es2015-ie'),
        require.resolve('babel-preset-react'),
        require.resolve('babel-preset-stage-0'),
        require.resolve('babel-preset-stage-1'),
      ],
      plugins: [
        require.resolve('babel-plugin-transform-runtime'),
        require.resolve('babel-plugin-transform-decorators-legacy'),
      ],
    },
    externals: [
      !web && function filter(context, request, cb) {
        const isExternal =
          request.match(/^[@a-z][a-z\/\.\-0-9]*$/i);
        cb(null, Boolean(isExternal));
      },
      ...(options.externals ? options.externals : [])
    ].filter(isValid),
    module: {
      loaders: [
        {
          test: /\.js$/,
          exclude: [
            /\.es5\.js$/,
            /node_modules/
          ],
          loader: 'babel-loader',
        },
        {
          test: /\.jsx$/,
          loader: 'babel-loader',
        },
        {
          test: /\.less$/,
          loader: style(!!dev, web, 'postcss!less'),
        }, {
          test: /\.css$/,
          loader: style(!!dev, web, 'postcss'),
        }
      ]
    },
    plugins: [
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': !!dev ? '"development"' : '"production"',
        __DEV__: !!dev,
        'process.env.BROWSER': web,
        __BROWSER__: web
      }),
      ...(web ? [
        new AssetsPlugin({
          path: path.join(cwd, options.output.path),
          filename: 'assets.js',
          processOutput: x => `module.exports = ${JSON.stringify(x)};`,
        }),
        options.extractCommon && new webpack.optimize.CommonsChunkPlugin(options.extractCommon),
        new ExtractTextPlugin(!!dev ? '[name].css?[hash]' : '[name].[hash].css'),
        ...(!dev ? [
          new webpack.optimize.DedupePlugin(),
          new webpack.optimize.UglifyJsPlugin({
            compress: {
              warnings: !!verbose,
            },
          }),
          new webpack.optimize.AggressiveMergingPlugin(),
        ] : [])
      ] : [
        new webpack.BannerPlugin('require("source-map-support").install();',
          { raw: true, entryOnly: false })
      ])
    ].filter(isValid)
  };
}

export function getTSWebpackConfig(dev, web, options) {
  console.log('ts model');
}

export function getWebpackConfig(options) {
  const { dev, verbose, ts } = options;
  const aegisConfig = loadAegisConfig(dev);
  const baseConfig = getBaseConfig(dev, verbose, aegisConfig.autoprefixer);
  const { web, node } = aegisConfig;
  const clientWebpackConfig = !web ? null : webpackMerge(baseConfig, !!ts ? getTSWebpackConfig(dev, true, web, verbose) : getBabelWebpackConfig(dev, true, web, verbose));
  const serverWebpackConfig = !node ? null : webpackMerge(baseConfig, !!ts ? getTSWebpackConfig(dev, false, node) : getBabelWebpackConfig(dev, false, node));
  return [clientWebpackConfig, serverWebpackConfig].filter(isValid);
}
<commit_msg>commonchunkplugin<commit_after>/**
 * Created by Zhengfeng.Yao on 16/9/22.
 */
import path from 'path';
import webpack from 'webpack';
import webpackMerge from 'webpack-merge';
import AssetsPlugin from 'assets-webpack-plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import ProgressBarPlugin from 'progress-bar-webpack-plugin';
import { isValid, loadAegisConfig } from './utils';

const cwd = process.cwd();

export function getBaseConfig(dev, verbose, autoprefixer) {
  autoprefixer = autoprefixer || [
      'last 2 versions',
      '> 1%',
      'Explorer >= 9',
    ];
  console.log('verbose: ' + verbose);
  return {
    cache: !!dev,
    debug: !!dev,

    stats: {
      colors: true,
      reasons: !!dev,
      hash: !!verbose,
      version: !!verbose,
      timings: true,
      chunks: !!verbose,
      chunkModules: !!verbose,
      cached: !!verbose,
      cachedAssets: !!verbose,
    },

    plugins: [
      new ProgressBarPlugin(),
      new webpack.optimize.OccurenceOrderPlugin(),
    ],

    resolve: {
      extensions: ['', '.webpack.js', '.web.js', '.json', '.json5'],
      modulesDirectories: ['node_modules', path.join(cwd, 'node_modules'), path.join(__dirname, '../node_modules')]
    },

    resolveLoader: {
      modulesDirectories: ['node_modules', path.join(cwd, 'node_modules'), path.join(__dirname, '../node_modules')]
    },

    module: {
      loaders: [
        {
          test: /\.json$/,
          loader: 'json-loader',
        }, {
          test: /\.json5$/,
          loader: 'json5-loader',
        }, {
          test: /\.txt$/,
          loader: 'raw-loader',
        }, {
          test: /\.(svg|jpe?g|png|gif)(\?.*)?$/,
          loader: 'url-loader?limit=10000',
        }, {
          test: /\.(woff\d?|ttf|eot)(\?.*)?$/,
          loader: 'file-loader',
        }, {
          test: /\.est$/,
          loader: 'babel-loader!template-string-loader'
        }
      ],
    },

    postcss: () => {
      return [
        require('postcss-nested')(),
        require('pixrem')(),
        require('autoprefixer')(autoprefixer),
        require('postcss-flexibility')(),
        require('postcss-discard-duplicates')()
      ];
    },
  }
}

function style(dev, web, loader) {
  const query = `${!!dev ? 'sourceMap&' : 'minimize&'}modules&localIdentName=[local]`;
  if (web) {
    return new ExtractTextPlugin('style', `css?${query}!${loader}`);
  } else {
    return `css/locals?${query}!${loader}`;
  }
}

function spreadCommonChunk(extractCommon) {
  if (extractCommon) {
    if (extractCommon.constructor.name == 'Object') {
      return [new webpack.optimize.CommonsChunkPlugin(extractCommon)];
    }

    if (extractCommon.constructor.name == 'Array') {
      return extractCommon.filter(common => common && common.construct.name == 'Object')
        .map(common => [new webpack.optimize.CommonsChunkPlugin(common)]);
    }
  }

  return [];
}

export function getBabelWebpackConfig(dev, web, options, verbose) {
  return {
    entry: options.entry,
    output: options.output,
    devtool: web ? (!!dev ? 'cheap-module-eval-source-map' : false) : 'source-map',
    target: web ? 'web' : 'node',
    resolve: {
      extensions: ['', '.js', '.jsx'],
    },
    babel: {
      presets: [
        require.resolve('babel-preset-es2015-ie'),
        require.resolve('babel-preset-react'),
        require.resolve('babel-preset-stage-0'),
        require.resolve('babel-preset-stage-1'),
      ],
      plugins: [
        require.resolve('babel-plugin-transform-runtime'),
        require.resolve('babel-plugin-transform-decorators-legacy'),
      ],
    },
    externals: [
      !web && function filter(context, request, cb) {
        const isExternal =
          request.match(/^[@a-z][a-z\/\.\-0-9]*$/i);
        cb(null, Boolean(isExternal));
      },
      ...(options.externals ? options.externals : [])
    ].filter(isValid),
    module: {
      loaders: [
        {
          test: /\.js$/,
          exclude: [
            /\.es5\.js$/,
            /node_modules/
          ],
          loader: 'babel-loader',
        },
        {
          test: /\.jsx$/,
          loader: 'babel-loader',
        },
        {
          test: /\.less$/,
          loader: style(!!dev, web, 'postcss!less'),
        }, {
          test: /\.css$/,
          loader: style(!!dev, web, 'postcss'),
        }
      ]
    },
    plugins: [
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': !!dev ? '"development"' : '"production"',
        __DEV__: !!dev,
        'process.env.BROWSER': web,
        __BROWSER__: web
      }),
      ...(web ? [
        new AssetsPlugin({
          path: path.join(cwd, options.output.path),
          filename: 'assets.js',
          processOutput: x => `module.exports = ${JSON.stringify(x)};`,
        }),
        ...spreadCommonChunk(options.extractCommon),
        new ExtractTextPlugin(!!dev ? '[name].css?[hash]' : '[name].[hash].css'),
        ...(!dev ? [
          new webpack.optimize.DedupePlugin(),
          new webpack.optimize.UglifyJsPlugin({
            compress: {
              warnings: !!verbose,
            },
          }),
          new webpack.optimize.AggressiveMergingPlugin(),
        ] : [])
      ] : [
        new webpack.BannerPlugin('require("source-map-support").install();',
          { raw: true, entryOnly: false })
      ])
    ].filter(isValid)
  };
}

export function getTSWebpackConfig(dev, web, options) {
  console.log('ts model');
}

export function getWebpackConfig(options) {
  const { dev, verbose, ts } = options;
  const aegisConfig = loadAegisConfig(dev);
  const baseConfig = getBaseConfig(dev, verbose, aegisConfig.autoprefixer);
  const { web, node } = aegisConfig;
  const clientWebpackConfig = !web ? null : webpackMerge(baseConfig, !!ts ? getTSWebpackConfig(dev, true, web, verbose) : getBabelWebpackConfig(dev, true, web, verbose));
  const serverWebpackConfig = !node ? null : webpackMerge(baseConfig, !!ts ? getTSWebpackConfig(dev, false, node) : getBabelWebpackConfig(dev, false, node));
  return [clientWebpackConfig, serverWebpackConfig].filter(isValid);
}
<|endoftext|>


<commit_before>/**
 * postal - Pub/Sub library providing wildcard subscriptions, complex message handling, etc.  Works server and client-side.
 * Author: Jim Cowart (http://freshbrewedcode.com/jimcowart)
 * Version: v0.10.1
 * Url: http://github.com/postaljs/postal.js
 * License(s): MIT, GPL
 */
(function(t,n){"object"==typeof module&&module.exports?module.exports=n(require("lodash"),require("conduitjs"),this):"function"==typeof define&&define.amd?define(["lodash","conduitjs"],function(i,e){return n(i,e,t)}):t.postal=n(t._,t.Conduit,t)})(this,function(t,n,i){function e(){for(;y.length;)u.unsubscribe(y.shift())}function c(t,n){return{channel:u.configuration.SYSTEM_CHANNEL,topic:"subscription."+t,data:{event:"subscription."+t,channel:n.channel,topic:n.topic}}}function r(n){return"function"==typeof n?n:n?function(i){var e=0,c=0;return t.each(n,function(t,r){e+=1,("topic"===r&&u.configuration.resolver.compare(i.topic,n.topic)||"context"===r&&n.context===(i.callback.context&&i.callback.context()||i.context)||i[r]===n[r])&&(c+=1)}),e===c}:function(){return!0}}function o(t){var n,i=new f(t.channel||this.configuration.DEFAULT_CHANNEL,t.topic,t.callback),e=this.subscriptions[i.channel];return e||(e=this.subscriptions[i.channel]={}),n=this.subscriptions[i.channel][i.topic],n||(n=this.subscriptions[i.channel][i.topic]=[]),n.push(i),i}function s(n){++m,n.channel=n.channel||this.configuration.DEFAULT_CHANNEL,n.timeStamp=new Date,t.each(this.wireTaps,function(t){t(n.data,n)}),this.subscriptions[n.channel]&&t.each(this.subscriptions[n.channel],function(t){for(var i,e=0,c=t.length;c>e;)(i=t[e++])&&w(i,n)}),0===--m&&e()}function a(){for(var t,n=0,i=Array.prototype.slice.call(arguments,0);t=i.shift();){if(m)return void y.push(t);if(this.subscriptions[t.channel]&&this.subscriptions[t.channel][t.topic]){var e=this.subscriptions[t.channel][t.topic].length;for(n=0;e>n;){if(this.subscriptions[t.channel][t.topic][n]===t){this.subscriptions[t.channel][t.topic].splice(n,1);break}n+=1}}u.publish(c("removed",t))}}var u,h=i.postal,l=function(t){this.channel=t||u.configuration.DEFAULT_CHANNEL,this.initialize()};l.prototype.initialize=function(){var t=this.publish;this.publish=new n.Async({target:t,context:this})},l.prototype.subscribe=function(){return u.subscribe({channel:this.channel,topic:1===arguments.length?arguments[0].topic:arguments[0],callback:1===arguments.length?arguments[0].callback:arguments[1]})},l.prototype.publish=function(){var t=1===arguments.length?"[object String]"===Object.prototype.toString.call(arguments[0])?{topic:arguments[0]}:arguments[0]:{topic:arguments[0],data:arguments[1]};t.channel=this.channel,u.publish(t)};var f=function(t,n,i){if(3!==arguments.length)throw new Error("You must provide a channel, topic and callback when creating a SubscriptionDefinition instance.");if(0===n.length)throw new Error("Topics cannot be empty");this.channel=t,this.topic=n,this.subscribe(i)},p=function(){var n;return function(i){var e=!1;return t.isString(i)?(e=i===n,n=i):(e=t.isEqual(i,n),n=t.clone(i)),!e}},b=function(){var n=[];return function(i){var e=!t.any(n,function(n){return t.isObject(i)||t.isArray(i)?t.isEqual(i,n):i===n});return e&&n.push(i),e}},d={withDelay:function(n){if(t.isNaN(n))throw"Milliseconds must be a number";return{name:"withDelay",fn:function(t,i,e){setTimeout(function(){t(i,e)},n)}}},defer:function(){return this.withDelay(0)},stopAfter:function(n,i){if(t.isNaN(n)||0>=n)throw"The value provided to disposeAfter (maxCalls) must be a number greater than zero.";var e=t.after(n,i);return{name:"stopAfter",fn:function(t,n,i){e(),t(n,i)}}},withThrottle:function(n){if(t.isNaN(n))throw"Milliseconds must be a number";return{name:"withThrottle",fn:t.throttle(function(t,n,i){t(n,i)},n)}},withDebounce:function(n,i){if(t.isNaN(n))throw"Milliseconds must be a number";return{name:"debounce",fn:t.debounce(function(t,n,i){t(n,i)},n,!!i)}},withConstraint:function(n){if(!t.isFunction(n))throw"Predicate constraint must be a function";return{name:"withConstraint",fn:function(t,i,e){n.call(this,i,e)&&t.call(this,i,e)}}},distinct:function(t){t=t||{};var n=function(t){return t[0]},i=t.all?new b(n):new p(n);return{name:"distinct",fn:function(t,n,e){i(n)&&t(n,e)}}}};f.prototype={after:function(){return this.callback.after.apply(this,arguments),this},before:function(){return this.callback.before.apply(this,arguments),this},"catch":function(t){var n=this.callback.target(),i=function(){try{n.apply(this,arguments)}catch(i){t(i,arguments[0])}};return this.callback.target(i),this},defer:function(){return this.callback.before(d.defer()),this},disposeAfter:function(t){var n=this;return n.callback.before(d.stopAfter(t,function(){n.unsubscribe.call(n)})),n},distinctUntilChanged:function(){return this.callback.before(d.distinct()),this},distinct:function(){return this.callback.before(d.distinct({all:!0})),this},logError:function(){if(console){var t;t=console.warn?console.warn:console.log,this["catch"](t)}return this},once:function(){return this.disposeAfter(1),this},subscribe:function(t){return this.callback=new n.Async({target:t,context:this}),this},unsubscribe:function(){this.inactive||(this.inactive=!0,u.unsubscribe(this))},withConstraint:function(t){return this.callback.before(d.withConstraint(t)),this},withConstraints:function(t){for(;t.length;)this.callback.before(d.withConstraint(t.shift()));return this},withDebounce:function(t,n){return this.callback.before(d.withDebounce(t,n)),this},withDelay:function(t){return this.callback.before(d.withDelay(t)),this},withThrottle:function(t){return this.callback.before(d.withThrottle(t)),this},withContext:function(t){return this.callback.context(t),this}};var g={cache:{},regex:{},compare:function(n,i){var e,c,r,o=this.cache[i]&&this.cache[i][n];return"undefined"!=typeof o?o:((c=this.regex[n])||(e="^"+t.map(n.split("."),function(t){var n="";return r&&(n="#"!==r?"\\.\\b":"\\b"),n+="#"===t?"[\\s\\S]*":"*"===t?"[^.]+":t,r=t,n}).join("")+"$",c=this.regex[n]=new RegExp(e)),this.cache[i]=this.cache[i]||{},this.cache[i][n]=o=c.test(i),o)},reset:function(){this.cache={},this.regex={}}},w=function(t,n){!t.inactive&&u.configuration.resolver.compare(t.topic,n.topic)&&t.callback(n.data,n)},m=0,y=[];if(u={configuration:{resolver:g,DEFAULT_CHANNEL:"/",SYSTEM_CHANNEL:"postal"},subscriptions:{},wireTaps:[],ChannelDefinition:l,SubscriptionDefinition:f,channel:function(t){return new l(t)},addWireTap:function(t){var n=this;return n.wireTaps.push(t),function(){var i=n.wireTaps.indexOf(t);-1!==i&&n.wireTaps.splice(i,1)}},noConflict:function(){if("undefined"==typeof window||"undefined"!=typeof window&&"function"==typeof define&&define.amd)throw new Error("noConflict can only be used in browser clients which aren't using AMD modules");return i.postal=h,this},getSubscribersFor:function(n){var i=[];return t.each(this.subscriptions,function(e){t.each(e,function(e){i=i.concat(t.filter(e,r(n)))})}),i},reset:function(){this.unsubscribeFor(),this.configuration.resolver.reset(),this.subscriptions={}},unsubscribeFor:function(t){var n=[];this.subscriptions&&(n=this.getSubscribersFor(t),this.unsubscribe.apply(this,n))}},u.subscribe=new n.Sync({target:o,context:u}),u.publish=n.Async({target:s,context:u}),u.unsubscribe=new n.Sync({target:a,context:u}),u.subscribe.after(function(t){u.publish(c("created",t))}),u.subscriptions[u.configuration.SYSTEM_CHANNEL]={},u.linkChannels=function(n,i){var e=[],c=this;return n=t.isArray(n)?n:[n],i=t.isArray(i)?i:[i],t.each(n,function(n){var r=n.topic||"#";t.each(i,function(i){var o=i.channel||c.configuration.DEFAULT_CHANNEL;e.push(c.subscribe({channel:n.channel||c.configuration.DEFAULT_CHANNEL,topic:r,callback:function(n,e){var r=t.clone(e);r.topic=t.isFunction(i.topic)?i.topic(e.topic):i.topic||e.topic,r.channel=o,r.data=n,c.publish(r)}}))})}),e},i&&Object.prototype.hasOwnProperty.call(i,"__postalReady__")&&t.isArray(i.__postalReady__))for(;i.__postalReady__.length;)i.__postalReady__.shift().onReady(u);return u});<commit_msg>Deleted<commit_after><|endoftext|>


<commit_before>/* eslint-env mocha */
/* eslint-disable no-undefined */
'use strict';
const {strictEqual} = require('assert');
// const {spy} = require('sinon');
const ActionsWorker = require('..');

function test_invalid_postMessage(postMessage){
	let throws = false;
	try {
		const worker = new ActionsWorker({ // eslint-disable-line no-unused-vars
			actions: {},
			serialize: () => {}, // eslint-disable-line no-empty-function
			postMessage
		});
	} catch(e){
		throws = true;
	}
	strictEqual(throws, true, 'Throws an Error');
}

function test_invalid_serialize(serialize){
	let throws = false;
	try {
		const worker = new ActionsWorker({ // eslint-disable-line no-unused-vars
			actions: {},
			serialize,
			postMessage: () => {} // eslint-disable-line no-empty-function
		});
	} catch(e){
		throws = true;
	}
	strictEqual(throws, true, 'Throws an Error');
}

function test_invalid_actions(actions){
	let throws = false;
	try {
		const worker = new ActionsWorker({ // eslint-disable-line no-unused-vars
			actions,
			serialize: () => {}, // eslint-disable-line no-empty-function
			postMessage: () => {} // eslint-disable-line no-empty-function
		});
	} catch(e){
		throws = true;
	}
	strictEqual(throws, true, 'Throws an Error');
}

function test_empty_actions(actions){
	let throws = false;
	try {
		const worker = new ActionsWorker({ // eslint-disable-line no-unused-vars
			actions,
			serialize: () => {}, // eslint-disable-line no-empty-function
			postMessage: () => {} // eslint-disable-line no-empty-function
		});
	} catch(e){
		throws = true;
	}
	strictEqual(throws, false, 'Throws an Error');
}

describe('@wildpeaks/actions-worker', /* @this */ function(){
	this.slow(500);
	this.timeout(1000);

	it('Missing postMessage', test_invalid_postMessage.bind(this, undefined));
	it('Invalid postMessage (1)', test_invalid_postMessage.bind(this, 1));
	it('Invalid postMessage (true)', test_invalid_postMessage.bind(this, true));
	it('Invalid postMessage (null)', test_invalid_postMessage.bind(this, null));
	it('Invalid postMessage ({})', test_invalid_postMessage.bind(this, {}));

	it('Missing serialize', test_invalid_serialize.bind(this, undefined));
	it('Invalid serialize (1)', test_invalid_serialize.bind(this, 1));
	it('Invalid serialize (true)', test_invalid_serialize.bind(this, true));
	it('Invalid serialize (null)', test_invalid_serialize.bind(this, null));
	it('Invalid serialize ({})', test_invalid_serialize.bind(this, {}));

	it('Missing actions', test_empty_actions.bind(this, undefined));
	it('Invalid actions (1)', test_invalid_actions.bind(this, 1));
	it('Invalid actions (true)', test_invalid_actions.bind(this, true));
	it('Invalid actions (null)', test_invalid_actions.bind(this, null));
	it('Empty actions', test_empty_actions.bind(this, {}));

	it('Invalid Action ID (1)');
	it('Invalid Action ID (true)');
	it('Invalid Action ID (null)');
	it('Invalid Action ID ("")');
	it('Invalid Action ID ("fake")');
	it('Invalid Action ID ({})');

	// and test that it calls serialize() and postMessage with the right args
	it('Valid action (single message)');
	it('Valid action (multiple messages)');

	it(`No props emitted if TestAction doesn't call setState`);
	it('No props emitter if serialize throws an exception'); // and check the ActionsWorker doesn't throw an exception too

	// Even if the properties of the props object are in a different order
	// but the state itself might be different
	it('No props if the resulting serialized props are the same');

	it('Do not store new state if serialize throws an exception');
	it('Store new state even if serialized props is the same message as last (just skip emitting props in that case)');
});
<commit_msg>More tests for invalid action messages<commit_after>/* eslint-env mocha */
/* eslint-disable no-undefined */
'use strict';
const {strictEqual} = require('assert');
// const {spy} = require('sinon');
const ActionsWorker = require('..');

function test_invalid_postMessage(postMessage){
	let throws = false;
	try {
		const worker = new ActionsWorker({ // eslint-disable-line no-unused-vars
			actions: {},
			serialize: () => {}, // eslint-disable-line no-empty-function
			postMessage
		});
	} catch(e){
		throws = true;
	}
	strictEqual(throws, true, 'Throws an Error');
}

function test_invalid_serialize(serialize){
	let throws = false;
	try {
		const worker = new ActionsWorker({ // eslint-disable-line no-unused-vars
			actions: {},
			serialize,
			postMessage: () => {} // eslint-disable-line no-empty-function
		});
	} catch(e){
		throws = true;
	}
	strictEqual(throws, true, 'Throws an Error');
}

function test_invalid_actions(actions){
	/* eslint-disable no-empty-function */
	let throws = false;
	try {
		const worker = new ActionsWorker({ // eslint-disable-line no-unused-vars
			actions,
			serialize: () => {},
			postMessage: () => {}
		});
	} catch(e){
		throws = true;
	}
	strictEqual(throws, true, 'Throws an Error');
}

function test_empty_actions(actions){
	/* eslint-disable no-empty-function */
	let throws = false;
	try {
		const worker = new ActionsWorker({ // eslint-disable-line no-unused-vars
			actions,
			serialize: () => {},
			postMessage: () => {}
		});
	} catch(e){
		throws = true;
	}
	strictEqual(throws, false, 'Throws an Error');
}

function test_invalid_message(message){
	/* eslint-disable no-empty-function */
	let worker;
	let throws = false;

	try {
		worker = new ActionsWorker({
			actions: {
				myaction: () => {}
			},
			serialize: () => {},
			postMessage: () => {}
		});
	} catch(e){
		throws = true;
	}
	strictEqual(throws, false, `Constructor doesn't throw an error`);

	try {
		worker.onmessage(message);
	} catch(e){
		throws = true;
	}
	strictEqual(throws, true, `onmessage throws an error`);
}

describe('@wildpeaks/actions-worker', /* @this */ function(){
	this.slow(500);
	this.timeout(1000);

	it('Missing postMessage', test_invalid_postMessage.bind(this, undefined));
	it('Invalid postMessage (1)', test_invalid_postMessage.bind(this, 1));
	it('Invalid postMessage (true)', test_invalid_postMessage.bind(this, true));
	it('Invalid postMessage (null)', test_invalid_postMessage.bind(this, null));
	it('Invalid postMessage ({})', test_invalid_postMessage.bind(this, {}));

	it('Missing serialize', test_invalid_serialize.bind(this, undefined));
	it('Invalid serialize (1)', test_invalid_serialize.bind(this, 1));
	it('Invalid serialize (true)', test_invalid_serialize.bind(this, true));
	it('Invalid serialize (null)', test_invalid_serialize.bind(this, null));
	it('Invalid serialize ({})', test_invalid_serialize.bind(this, {}));

	it('Missing actions', test_empty_actions.bind(this, undefined));
	it('Invalid actions (1)', test_invalid_actions.bind(this, 1));
	it('Invalid actions (true)', test_invalid_actions.bind(this, true));
	it('Invalid actions (null)', test_invalid_actions.bind(this, null));
	it('Empty actions', test_empty_actions.bind(this, {}));

	it('Invalid message (undefined)', test_invalid_message.bind(this, undefined));
	it('Invalid message (1)', test_invalid_message.bind(this, 1));
	it('Invalid message (true)', test_invalid_message.bind(this, true));
	it('Invalid message (null)', test_invalid_message.bind(this, null));
	it('Invalid message ("")', test_invalid_message.bind(this, ''));
	it('Invalid message ("fake")', test_invalid_message.bind(this, 'fake'));
	it('Invalid message ({})', test_invalid_message.bind(this, {}));

	it('Invalid Action ID (undefined)', test_invalid_message.bind(this, {action: undefined}));
	it('Invalid Action ID (1)', test_invalid_message.bind(this, {action: 1}));
	it('Invalid Action ID (true)', test_invalid_message.bind(this, {action: true}));
	it('Invalid Action ID (null)', test_invalid_message.bind(this, {action: null}));
	it('Invalid Action ID ("")', test_invalid_message.bind(this, {action: ''}));
	it('Invalid Action ID ("fake")', test_invalid_message.bind(this, {action: 'fake'}));
	it('Invalid Action ID ({})', test_invalid_message.bind(this, {action: {}}));

	// And test that it calls serialize() and postMessage with the right args.
	it('Valid action (single message)');
	it('Valid action (multiple messages)');

	it(`No props emitted if TestAction doesn't call setState`);
	it('No props emitter if serialize throws an exception'); // and check the ActionsWorker doesn't throw an exception too

	// Even if the properties of the props object are in a different order
	// but the state itself might be different
	it('No props if the resulting serialized props are the same');

	it('Do not store new state if serialize throws an exception');
	it('Store new state even if serialized props is the same message as last (just skip emitting props in that case)');
});
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014-2020 Bjoern Kimminich.
 * SPDX-License-Identifier: MIT
 */

const frisby = require('frisby')
const Joi = frisby.Joi
const insecurity = require('../../lib/insecurity')
const config = require('config')

const tamperingProductId = ((() => {
  const products = config.get('products')
  for (let i = 0; i < products.length; i++) {
    if (products[i].urlForProductTamperingChallenge) {
      return i + 1
    }
  }
})())

const API_URL = 'http://localhost:3000/api'

const authHeader = { Authorization: 'Bearer ' + insecurity.authorize(), 'content-type': 'application/json' }
const jsonHeader = { 'content-type': 'application/json' }

describe('/api/Products', () => {
  it('GET all products', () => {
    return frisby.get(API_URL + '/Products')
      .expect('status', 200)
      .expect('header', 'content-type', /application\/json/)
      .expect('jsonTypes', 'data.*', {
        id: Joi.number(),
        name: Joi.string(),
        description: Joi.string(),
        price: Joi.number(),
        deluxePrice: Joi.number(),
        image: Joi.string()
      })
  })

  it('POST new product is forbidden via public API', () => {
    return frisby.post(API_URL + '/Products', {
      name: 'Dirt Juice (1000ml)',
      description: 'Made from ugly dirt.',
      price: 0.99,
      image: 'dirt_juice.jpg'
    })
      .expect('status', 401)
  })

  if (!utils.disableOnContainerEnv()) {
    it('POST new product does not filter XSS attacks', () => {
      return frisby.post(API_URL + '/Products', {
        headers: authHeader,
        body: {
          name: 'XSS Juice (42ml)',
          description: '<iframe src="javascript:alert(`xss`)">',
          price: 9999.99,
          image: 'xss3juice.jpg'
        }
      })
        .expect('header', 'content-type', /application\/json/)
        .expect('json', 'data', { description: '<iframe src="javascript:alert(`xss`)">' })
    })
  }
})

describe('/api/Products/:id', () => {
  it('GET existing product by id', () => {
    return frisby.get(API_URL + '/Products/1')
      .expect('status', 200)
      .expect('header', 'content-type', /application\/json/)
      .expect('jsonTypes', 'data', {
        id: Joi.number(),
        name: Joi.string(),
        description: Joi.string(),
        price: Joi.number(),
        deluxePrice: Joi.number(),
        image: Joi.string(),
        createdAt: Joi.string(),
        updatedAt: Joi.string()
      })
      .expect('json', 'data', { id: 1 })
  })

  it('GET non-existing product by id', () => {
    return frisby.get(API_URL + '/Products/4711')
      .expect('status', 404)
      .expect('header', 'content-type', /application\/json/)
      .expect('json', 'message', 'Not Found')
  })

  it('PUT update existing product is possible due to Missing Function-Level Access Control vulnerability', () => {
    return frisby.put(API_URL + '/Products/' + tamperingProductId, {
      header: jsonHeader,
      body: {
        description: 'More...'
      }
    })
      .expect('status', 200)
      .expect('header', 'content-type', /application\/json/)
      .expect('json', 'data', { description: 'More...' })
  })

  it('PUT update existing product does not filter XSS attacks', () => {
    return frisby.put(API_URL + '/Products/1', {
      header: jsonHeader,
      body: {
        description: ''
      }
    })
      .expect('status', 200)
      .expect('header', 'content-type', /application\/json/)
      .expect('json', 'data', { description: '' })
  })

  it('DELETE existing product is forbidden via public API', () => {
    return frisby.del(API_URL + '/Products/1')
      .expect('status', 401)
  })

  it('DELETE existing product is forbidden via API even when authenticated', () => {
    return frisby.del(API_URL + '/Products/1', { headers: authHeader })
      .expect('status', 401)
  })
})
<commit_msg>Add missing import<commit_after>/*
 * Copyright (c) 2014-2020 Bjoern Kimminich.
 * SPDX-License-Identifier: MIT
 */

const frisby = require('frisby')
const Joi = frisby.Joi
const utils = require('../../lib/utils')
const insecurity = require('../../lib/insecurity')
const config = require('config')

const tamperingProductId = ((() => {
  const products = config.get('products')
  for (let i = 0; i < products.length; i++) {
    if (products[i].urlForProductTamperingChallenge) {
      return i + 1
    }
  }
})())

const API_URL = 'http://localhost:3000/api'

const authHeader = { Authorization: 'Bearer ' + insecurity.authorize(), 'content-type': 'application/json' }
const jsonHeader = { 'content-type': 'application/json' }

describe('/api/Products', () => {
  it('GET all products', () => {
    return frisby.get(API_URL + '/Products')
      .expect('status', 200)
      .expect('header', 'content-type', /application\/json/)
      .expect('jsonTypes', 'data.*', {
        id: Joi.number(),
        name: Joi.string(),
        description: Joi.string(),
        price: Joi.number(),
        deluxePrice: Joi.number(),
        image: Joi.string()
      })
  })

  it('POST new product is forbidden via public API', () => {
    return frisby.post(API_URL + '/Products', {
      name: 'Dirt Juice (1000ml)',
      description: 'Made from ugly dirt.',
      price: 0.99,
      image: 'dirt_juice.jpg'
    })
      .expect('status', 401)
  })

  if (!utils.disableOnContainerEnv()) {
    it('POST new product does not filter XSS attacks', () => {
      return frisby.post(API_URL + '/Products', {
        headers: authHeader,
        body: {
          name: 'XSS Juice (42ml)',
          description: '<iframe src="javascript:alert(`xss`)">',
          price: 9999.99,
          image: 'xss3juice.jpg'
        }
      })
        .expect('header', 'content-type', /application\/json/)
        .expect('json', 'data', { description: '<iframe src="javascript:alert(`xss`)">' })
    })
  }
})

describe('/api/Products/:id', () => {
  it('GET existing product by id', () => {
    return frisby.get(API_URL + '/Products/1')
      .expect('status', 200)
      .expect('header', 'content-type', /application\/json/)
      .expect('jsonTypes', 'data', {
        id: Joi.number(),
        name: Joi.string(),
        description: Joi.string(),
        price: Joi.number(),
        deluxePrice: Joi.number(),
        image: Joi.string(),
        createdAt: Joi.string(),
        updatedAt: Joi.string()
      })
      .expect('json', 'data', { id: 1 })
  })

  it('GET non-existing product by id', () => {
    return frisby.get(API_URL + '/Products/4711')
      .expect('status', 404)
      .expect('header', 'content-type', /application\/json/)
      .expect('json', 'message', 'Not Found')
  })

  it('PUT update existing product is possible due to Missing Function-Level Access Control vulnerability', () => {
    return frisby.put(API_URL + '/Products/' + tamperingProductId, {
      header: jsonHeader,
      body: {
        description: 'More...'
      }
    })
      .expect('status', 200)
      .expect('header', 'content-type', /application\/json/)
      .expect('json', 'data', { description: 'More...' })
  })

  it('PUT update existing product does not filter XSS attacks', () => {
    return frisby.put(API_URL + '/Products/1', {
      header: jsonHeader,
      body: {
        description: ''
      }
    })
      .expect('status', 200)
      .expect('header', 'content-type', /application\/json/)
      .expect('json', 'data', { description: '' })
  })

  it('DELETE existing product is forbidden via public API', () => {
    return frisby.del(API_URL + '/Products/1')
      .expect('status', 401)
  })

  it('DELETE existing product is forbidden via API even when authenticated', () => {
    return frisby.del(API_URL + '/Products/1', { headers: authHeader })
      .expect('status', 401)
  })
})
<|endoftext|>


<commit_before>module.exports = function() {
    'use strict';

    this.title = element(by.model('movie.title'));
    this.description = element(by.model('movie.description'));
    this.save = element(by.css('.btn-primary'));

    this.open = function() {
        browser.get('/movies/new');
    };

    this.addMovie = function(title, description) {
        this.open();
        this.title.clear();
        this.title.sendKeys(title);
        this.description.clear();
        this.description.sendKeys(description);
        this.save.click();
    };
};
<commit_msg>Trying to fix the tests<commit_after>module.exports = function() {
    'use strict';

    // this.title = element(by.model('movie.title'));
    // this.description = element(by.model('movie.description'));
    // this.save = element(by.css('.btn-primary'));

    this.open = function() {
        browser.get('/movies/new');
    };

    this.addMovie = function(title, description) {
        this.open();
        element(by.model('movie.title')).clear();
        element(by.model('movie.title')).sendKeys(title);
        element(by.model('movie.description')).clear();
        element(by.model('movie.description')).sendKeys(description);
        element(by.css('.btn-primary')).click();
    };
};
<|endoftext|>


<commit_before>// WARNING: DO NOT INSERT COMMENTS OR REFORMAT OR ANYTHING
// Line numbers matter to this test!

QUnit.module(module.id);

var nextTick = function(cb) {
	setTimeout(function(){
		cb();
	}, 0);
};

function failAsync(_, code){
	throw new Error(code);
}

function failSync(_, code){
	 // dummy to defeat CoffeeScript compat rule
	function fail(dummy){ throw new Error(code); }
	fail(0);
}

var _fail;

function A(_, code){
	if (code == 1)
		_fail(_, code);
	if (code == 2)
		_fail(_, code);
	nextTick(_);
	if (code == 3)
		_fail(_, code);
	for (var i = 0; i < 6; i++) {
		if (code == i)
			_fail(_, code);
		nextTick(_);
	}
	if (code == 6)
		_fail(_, code);
	nextTick(_);
	B(_, code);
	nextTick(_);
	return "END";
}

function B(_, code){
	if (code == 7)
		_fail(_, code);
	C(_, code);
	nextTick(_);
	C(_, code);
	D(_, code);
}

function C(_, code){
	if (code == 8)
		_fail(_, code);
}

function D(_, code){
	if (code == 9)
		_fail(_, code);
}

function E(_, code){
	try {
		_fail(_, code);
	}
	catch (ex) {
		if (code % 3 == 1)
			_fail(_, code);
		else if (code % 3 == 2)
			A(_, code);
		else
			return "OK " + code;
	}
}

function F(_, code){
	var f1 = A(!_, code);
	var f2 = A(!_, code + 1);
	return f1(_) + " & " + f2(_);
}

function G(_, code){
	if (code == 5)
		_fail(_, code);
	return "" + code;
}

function H(_, code){
	if (code % 2 == 0)
		nextTick(_);
	return G(_, code);
}

function I(_, code){
	var s = "";
	for (var i = 0; i < code; i++)
		s += H(_, i);
	return s;
}

function issue233(_, code) {
  function customThrow() {
    throw new Error("foo");
  }
  try {
    throw new Error("bar");
  } catch(e) {
    customThrow();
  }
}

// You can insert lines and/or comments after this point.

function T(_, fn, code, failFn){
	_fail = failFn;
	var s = "{";
	try {
		return fn(_, code);
	}
	catch (ex) {
		var s = ex.stack;
		s = s.split('\n').filter(function(l) {
			return l.indexOf('<<<') < 0 && !/\bstreamline-runtime.lib/.test(l);
		}).map(function(l){
			l = l.replace(/\bFunction\.(\w+) \[as fiberized-\d+\]/, '$1');
			// We get Object.A in futures test because of a bind call. Ignore this difference.
			var m = /^\s+at (?:Object\.)?(\w+)[^(]+\((?:[A-Z]:)?[^:]*:(\d+)/.exec(l);
			if (m)
				return m[1] + ":" + m[2];
			return l;
		}).join('/');
		var end = s.indexOf('/T:');
		return end < 0 ? s + "-- end frame missing" : s.substring(0, end);
	}
}

var browser = typeof process === 'undefined' || process.browser;

function stackEqual(got, expect) {
	if (browser) {
		got = got.replace(/(Error: \d+)\/.*?\/([A-Z]:)/, "$1/**ignored**/$2");
		expect = expect.replace(/(Error: \d+)\/.*?\/([A-Z]:)/, "$1/**ignored**/$2");
	}
	strictEqual(got, expect, expect);
}
// safari hack
var rawStack = new Error().stack ? function(raw) {
	return raw;
} : function() {
	return "raw stack unavailable";
}

asyncTest("stacks", 20, function(_) {
	stackEqual(T(_, A, 1, failAsync), rawStack("Error: 1/failAsync:15") + "/A:28");
	stackEqual(T(_, A, 1, failSync), rawStack("Error: 1/fail:20/failSync:21") + "/A:28");
	stackEqual(T(_, A, 2, failAsync), rawStack("Error: 2/failAsync:15") + "/A:30");
	stackEqual(T(_, A, 2, failSync), rawStack("Error: 2/fail:20/failSync:21") + "/A:30");
	stackEqual(T(_, A, 3, failAsync), rawStack("Error: 3/failAsync:15") + "/A:33");
	stackEqual(T(_, A, 3, failSync), rawStack("Error: 3/fail:20/failSync:21") + "/A:33");
	stackEqual(T(_, A, 4, failAsync), rawStack("Error: 4/failAsync:15") + "/A:36");
	stackEqual(T(_, A, 4, failSync), rawStack("Error: 4/fail:20/failSync:21") + "/A:36");
	stackEqual(T(_, A, 5, failAsync), rawStack("Error: 5/failAsync:15") + "/A:36");
	stackEqual(T(_, A, 5, failSync), rawStack("Error: 5/fail:20/failSync:21") + "/A:36");
	stackEqual(T(_, A, 6, failAsync), rawStack("Error: 6/failAsync:15") + "/A:40");
	stackEqual(T(_, A, 6, failSync), rawStack("Error: 6/fail:20/failSync:21") + "/A:40");
	stackEqual(T(_, A, 7, failAsync), rawStack("Error: 7/failAsync:15") + "/B:49/A:42");
	stackEqual(T(_, A, 7, failSync), rawStack("Error: 7/fail:20/failSync:21") + "/B:49/A:42");
	stackEqual(T(_, A, 8, failAsync), rawStack("Error: 8/failAsync:15") + "/C:58/B:50/A:42");
	stackEqual(T(_, A, 8, failSync), rawStack("Error: 8/fail:20/failSync:21") + "/C:58/B:50/A:42");
	stackEqual(T(_, A, 9, failAsync), rawStack("Error: 9/failAsync:15") + "/D:63/B:53/A:42");
	stackEqual(T(_, A, 9, failSync), rawStack("Error: 9/fail:20/failSync:21") + "/D:63/B:53/A:42");
	stackEqual(T(_, A, 10, failAsync), "END");
	stackEqual(T(_, A, 10, failSync), "END");
	start();
})

asyncTest("catch", 20, function(_) {
	stackEqual(T(_, E, 1, failAsync), rawStack("Error: 1/failAsync:15") + "/E:72");
	stackEqual(T(_, E, 1, failSync), rawStack("Error: 1/fail:20/failSync:21") + "/E:72");
	stackEqual(T(_, E, 2, failAsync), rawStack("Error: 2/failAsync:15") + "/A:30/E:74");
	stackEqual(T(_, E, 2, failSync), rawStack("Error: 2/fail:20/failSync:21") + "/A:30/E:74");
	stackEqual(T(_, E, 3, failAsync), "OK 3");
	stackEqual(T(_, E, 3, failSync), "OK 3");
	stackEqual(T(_, E, 4, failAsync), rawStack("Error: 4/failAsync:15") + "/E:72");
	stackEqual(T(_, E, 4, failSync), rawStack("Error: 4/fail:20/failSync:21") + "/E:72");
	stackEqual(T(_, E, 5, failAsync), rawStack("Error: 5/failAsync:15") + "/A:36/E:74");
	stackEqual(T(_, E, 5, failSync), rawStack("Error: 5/fail:20/failSync:21") + "/A:36/E:74");
	stackEqual(T(_, E, 6, failAsync), "OK 6");
	stackEqual(T(_, E, 6, failSync), "OK 6");
	stackEqual(T(_, E, 7, failAsync), rawStack("Error: 7/failAsync:15") + "/E:72");
	stackEqual(T(_, E, 7, failSync), rawStack("Error: 7/fail:20/failSync:21") + "/E:72");
	stackEqual(T(_, E, 8, failAsync), rawStack("Error: 8/failAsync:15") + "/C:58/B:50/A:42/E:74");
	stackEqual(T(_, E, 8, failSync), rawStack("Error: 8/fail:20/failSync:21") + "/C:58/B:50/A:42/E:74");
	stackEqual(T(_, E, 9, failAsync), "OK 9");
	stackEqual(T(_, E, 9, failSync), "OK 9");
	stackEqual(T(_, E, 10, failAsync), rawStack("Error: 10/failAsync:15") + "/E:72");
	stackEqual(T(_, E, 10, failSync), rawStack("Error: 10/fail:20/failSync:21") + "/E:72");
	start();
})

asyncTest("futures", 20, function(_) {
	stackEqual(T(_, F, 1, failAsync), rawStack("Error: 1/failAsync:15") + "/A:28/F:83");
	stackEqual(T(_, F, 1, failSync), rawStack("Error: 1/fail:20/failSync:21") + "/A:28/F:83");
	stackEqual(T(_, F, 2, failAsync), rawStack("Error: 2/failAsync:15") + "/A:30/F:83");
	stackEqual(T(_, F, 2, failSync), rawStack("Error: 2/fail:20/failSync:21") + "/A:30/F:83");
	stackEqual(T(_, F, 3, failAsync), rawStack("Error: 3/failAsync:15") + "/A:33/F:83");
	stackEqual(T(_, F, 3, failSync), rawStack("Error: 3/fail:20/failSync:21") + "/A:33/F:83");
	stackEqual(T(_, F, 4, failAsync), rawStack("Error: 4/failAsync:15") + "/A:36/F:83");
	stackEqual(T(_, F, 4, failSync), rawStack("Error: 4/fail:20/failSync:21") + "/A:36/F:83");
	stackEqual(T(_, F, 5, failAsync), rawStack("Error: 5/failAsync:15") + "/A:36/F:83");
	stackEqual(T(_, F, 5, failSync), rawStack("Error: 5/fail:20/failSync:21") + "/A:36/F:83");
	stackEqual(T(_, F, 6, failAsync), rawStack("Error: 6/failAsync:15") + "/A:40/F:83");
	stackEqual(T(_, F, 6, failSync), rawStack("Error: 6/fail:20/failSync:21") + "/A:40/F:83");
	stackEqual(T(_, F, 7, failAsync), rawStack("Error: 7/failAsync:15") + "/B:49/A:42/F:83");
	stackEqual(T(_, F, 7, failSync), rawStack("Error: 7/fail:20/failSync:21") + "/B:49/A:42/F:83");
	stackEqual(T(_, F, 8, failAsync), rawStack("Error: 8/failAsync:15") + "/C:58/B:50/A:42/F:83");
	stackEqual(T(_, F, 8, failSync), rawStack("Error: 8/fail:20/failSync:21") + "/C:58/B:50/A:42/F:83");
	stackEqual(T(_, F, 9, failAsync), rawStack("Error: 9/failAsync:15") + "/D:63/B:53/A:42/F:83");
	stackEqual(T(_, F, 9, failSync), rawStack("Error: 9/fail:20/failSync:21") + "/D:63/B:53/A:42/F:83");
	stackEqual(T(_, F, 10, failAsync), "END & END");
	stackEqual(T(_, F, 10, failSync), "END & END");
	start();
})

asyncTest("loop", 8, function(_) {
	stackEqual(T(_, I, 4, failAsync), "0123");
	stackEqual(T(_, I, 4, failSync), "0123");
	stackEqual(T(_, I, 5, failAsync), "01234");
	stackEqual(T(_, I, 5, failSync), "01234");
	stackEqual(T(_, I, 6, failAsync), rawStack("Error: 5/failAsync:15") + "/G:88/H:95/I:101");
	stackEqual(T(_, I, 6, failSync), rawStack("Error: 5/fail:20/failSync:21") + "/G:88/H:95/I:101");
	stackEqual(T(_, I, 7, failAsync), rawStack("Error: 5/failAsync:15") + "/G:88/H:95/I:101");
	stackEqual(T(_, I, 7, failSync), rawStack("Error: 5/fail:20/failSync:21") + "/G:88/H:95/I:101");
	start();
})

if (!browser) asyncTest("issue233", 1, function(_) {
	stackEqual(T(_, issue233, 0, failSync), "Error: foo/customThrow:107/issue233:112");
	start();
});
<commit_msg>issue #323 - fix stack trace unit test for node 0.12<commit_after>// WARNING: DO NOT INSERT COMMENTS OR REFORMAT OR ANYTHING
// Line numbers matter to this test!

QUnit.module(module.id);

var nextTick = function(cb) {
	setTimeout(function(){
		cb();
	}, 0);
};

function failAsync(_, code){
	throw new Error(code);
}

function failSync(_, code){
	 // dummy to defeat CoffeeScript compat rule
	function fail(dummy){ throw new Error(code); }
	fail(0);
}

var _fail;

function A(_, code){
	if (code == 1)
		_fail(_, code);
	if (code == 2)
		_fail(_, code);
	nextTick(_);
	if (code == 3)
		_fail(_, code);
	for (var i = 0; i < 6; i++) {
		if (code == i)
			_fail(_, code);
		nextTick(_);
	}
	if (code == 6)
		_fail(_, code);
	nextTick(_);
	B(_, code);
	nextTick(_);
	return "END";
}

function B(_, code){
	if (code == 7)
		_fail(_, code);
	C(_, code);
	nextTick(_);
	C(_, code);
	D(_, code);
}

function C(_, code){
	if (code == 8)
		_fail(_, code);
}

function D(_, code){
	if (code == 9)
		_fail(_, code);
}

function E(_, code){
	try {
		_fail(_, code);
	}
	catch (ex) {
		if (code % 3 == 1)
			_fail(_, code);
		else if (code % 3 == 2)
			A(_, code);
		else
			return "OK " + code;
	}
}

function F(_, code){
	var f1 = A(!_, code);
	var f2 = A(!_, code + 1);
	return f1(_) + " & " + f2(_);
}

function G(_, code){
	if (code == 5)
		_fail(_, code);
	return "" + code;
}

function H(_, code){
	if (code % 2 == 0)
		nextTick(_);
	return G(_, code);
}

function I(_, code){
	var s = "";
	for (var i = 0; i < code; i++)
		s += H(_, i);
	return s;
}

function issue233(_, code) {
  function customThrow() {
    throw new Error("foo");
  }
  try {
    throw new Error("bar");
  } catch(e) {
    customThrow();
  }
}

// You can insert lines and/or comments after this point.

function T(_, fn, code, failFn){
	_fail = failFn;
	var s = "{";
	try {
		return fn(_, code);
	}
	catch (ex) {
		var s = ex.stack;
		s = s.split('\n').filter(function(l) {
			return l.indexOf('<<<') < 0 && !/\bstreamline-runtime.lib/.test(l);
		}).map(function(l){
			l = l.replace(/\bFunction\.(\w+) \[as fiberized-\d+\]/, '$1');
			// We get Object.A in futures test because of a bind call. Ignore this difference.
			var m = /^\s+at (?:(?:Function|Object)\.)?(\w+)[^(]+\((?:[A-Z]:)?[^:]*:(\d+)/.exec(l);
			if (m)
				return m[1] + ":" + m[2];
			return l;
		}).join('/');
		var end = s.indexOf('/T:');
		return end < 0 ? s + "-- end frame missing" : s.substring(0, end);
	}
}

var browser = typeof process === 'undefined' || process.browser;

function stackEqual(got, expect) {
	if (browser) {
		got = got.replace(/(Error: \d+)\/.*?\/([A-Z]:)/, "$1/**ignored**/$2");
		expect = expect.replace(/(Error: \d+)\/.*?\/([A-Z]:)/, "$1/**ignored**/$2");
	}
	strictEqual(got, expect, expect);
}
// safari hack
var rawStack = new Error().stack ? function(raw) {
	return raw;
} : function() {
	return "raw stack unavailable";
}

asyncTest("stacks", 20, function(_) {
	stackEqual(T(_, A, 1, failAsync), rawStack("Error: 1/failAsync:15") + "/A:28");
	stackEqual(T(_, A, 1, failSync), rawStack("Error: 1/fail:20/failSync:21") + "/A:28");
	stackEqual(T(_, A, 2, failAsync), rawStack("Error: 2/failAsync:15") + "/A:30");
	stackEqual(T(_, A, 2, failSync), rawStack("Error: 2/fail:20/failSync:21") + "/A:30");
	stackEqual(T(_, A, 3, failAsync), rawStack("Error: 3/failAsync:15") + "/A:33");
	stackEqual(T(_, A, 3, failSync), rawStack("Error: 3/fail:20/failSync:21") + "/A:33");
	stackEqual(T(_, A, 4, failAsync), rawStack("Error: 4/failAsync:15") + "/A:36");
	stackEqual(T(_, A, 4, failSync), rawStack("Error: 4/fail:20/failSync:21") + "/A:36");
	stackEqual(T(_, A, 5, failAsync), rawStack("Error: 5/failAsync:15") + "/A:36");
	stackEqual(T(_, A, 5, failSync), rawStack("Error: 5/fail:20/failSync:21") + "/A:36");
	stackEqual(T(_, A, 6, failAsync), rawStack("Error: 6/failAsync:15") + "/A:40");
	stackEqual(T(_, A, 6, failSync), rawStack("Error: 6/fail:20/failSync:21") + "/A:40");
	stackEqual(T(_, A, 7, failAsync), rawStack("Error: 7/failAsync:15") + "/B:49/A:42");
	stackEqual(T(_, A, 7, failSync), rawStack("Error: 7/fail:20/failSync:21") + "/B:49/A:42");
	stackEqual(T(_, A, 8, failAsync), rawStack("Error: 8/failAsync:15") + "/C:58/B:50/A:42");
	stackEqual(T(_, A, 8, failSync), rawStack("Error: 8/fail:20/failSync:21") + "/C:58/B:50/A:42");
	stackEqual(T(_, A, 9, failAsync), rawStack("Error: 9/failAsync:15") + "/D:63/B:53/A:42");
	stackEqual(T(_, A, 9, failSync), rawStack("Error: 9/fail:20/failSync:21") + "/D:63/B:53/A:42");
	stackEqual(T(_, A, 10, failAsync), "END");
	stackEqual(T(_, A, 10, failSync), "END");
	start();
})

asyncTest("catch", 20, function(_) {
	stackEqual(T(_, E, 1, failAsync), rawStack("Error: 1/failAsync:15") + "/E:72");
	stackEqual(T(_, E, 1, failSync), rawStack("Error: 1/fail:20/failSync:21") + "/E:72");
	stackEqual(T(_, E, 2, failAsync), rawStack("Error: 2/failAsync:15") + "/A:30/E:74");
	stackEqual(T(_, E, 2, failSync), rawStack("Error: 2/fail:20/failSync:21") + "/A:30/E:74");
	stackEqual(T(_, E, 3, failAsync), "OK 3");
	stackEqual(T(_, E, 3, failSync), "OK 3");
	stackEqual(T(_, E, 4, failAsync), rawStack("Error: 4/failAsync:15") + "/E:72");
	stackEqual(T(_, E, 4, failSync), rawStack("Error: 4/fail:20/failSync:21") + "/E:72");
	stackEqual(T(_, E, 5, failAsync), rawStack("Error: 5/failAsync:15") + "/A:36/E:74");
	stackEqual(T(_, E, 5, failSync), rawStack("Error: 5/fail:20/failSync:21") + "/A:36/E:74");
	stackEqual(T(_, E, 6, failAsync), "OK 6");
	stackEqual(T(_, E, 6, failSync), "OK 6");
	stackEqual(T(_, E, 7, failAsync), rawStack("Error: 7/failAsync:15") + "/E:72");
	stackEqual(T(_, E, 7, failSync), rawStack("Error: 7/fail:20/failSync:21") + "/E:72");
	stackEqual(T(_, E, 8, failAsync), rawStack("Error: 8/failAsync:15") + "/C:58/B:50/A:42/E:74");
	stackEqual(T(_, E, 8, failSync), rawStack("Error: 8/fail:20/failSync:21") + "/C:58/B:50/A:42/E:74");
	stackEqual(T(_, E, 9, failAsync), "OK 9");
	stackEqual(T(_, E, 9, failSync), "OK 9");
	stackEqual(T(_, E, 10, failAsync), rawStack("Error: 10/failAsync:15") + "/E:72");
	stackEqual(T(_, E, 10, failSync), rawStack("Error: 10/fail:20/failSync:21") + "/E:72");
	start();
})

asyncTest("futures", 20, function(_) {
	stackEqual(T(_, F, 1, failAsync), rawStack("Error: 1/failAsync:15") + "/A:28/F:83");
	stackEqual(T(_, F, 1, failSync), rawStack("Error: 1/fail:20/failSync:21") + "/A:28/F:83");
	stackEqual(T(_, F, 2, failAsync), rawStack("Error: 2/failAsync:15") + "/A:30/F:83");
	stackEqual(T(_, F, 2, failSync), rawStack("Error: 2/fail:20/failSync:21") + "/A:30/F:83");
	stackEqual(T(_, F, 3, failAsync), rawStack("Error: 3/failAsync:15") + "/A:33/F:83");
	stackEqual(T(_, F, 3, failSync), rawStack("Error: 3/fail:20/failSync:21") + "/A:33/F:83");
	stackEqual(T(_, F, 4, failAsync), rawStack("Error: 4/failAsync:15") + "/A:36/F:83");
	stackEqual(T(_, F, 4, failSync), rawStack("Error: 4/fail:20/failSync:21") + "/A:36/F:83");
	stackEqual(T(_, F, 5, failAsync), rawStack("Error: 5/failAsync:15") + "/A:36/F:83");
	stackEqual(T(_, F, 5, failSync), rawStack("Error: 5/fail:20/failSync:21") + "/A:36/F:83");
	stackEqual(T(_, F, 6, failAsync), rawStack("Error: 6/failAsync:15") + "/A:40/F:83");
	stackEqual(T(_, F, 6, failSync), rawStack("Error: 6/fail:20/failSync:21") + "/A:40/F:83");
	stackEqual(T(_, F, 7, failAsync), rawStack("Error: 7/failAsync:15") + "/B:49/A:42/F:83");
	stackEqual(T(_, F, 7, failSync), rawStack("Error: 7/fail:20/failSync:21") + "/B:49/A:42/F:83");
	stackEqual(T(_, F, 8, failAsync), rawStack("Error: 8/failAsync:15") + "/C:58/B:50/A:42/F:83");
	stackEqual(T(_, F, 8, failSync), rawStack("Error: 8/fail:20/failSync:21") + "/C:58/B:50/A:42/F:83");
	stackEqual(T(_, F, 9, failAsync), rawStack("Error: 9/failAsync:15") + "/D:63/B:53/A:42/F:83");
	stackEqual(T(_, F, 9, failSync), rawStack("Error: 9/fail:20/failSync:21") + "/D:63/B:53/A:42/F:83");
	stackEqual(T(_, F, 10, failAsync), "END & END");
	stackEqual(T(_, F, 10, failSync), "END & END");
	start();
})

asyncTest("loop", 8, function(_) {
	stackEqual(T(_, I, 4, failAsync), "0123");
	stackEqual(T(_, I, 4, failSync), "0123");
	stackEqual(T(_, I, 5, failAsync), "01234");
	stackEqual(T(_, I, 5, failSync), "01234");
	stackEqual(T(_, I, 6, failAsync), rawStack("Error: 5/failAsync:15") + "/G:88/H:95/I:101");
	stackEqual(T(_, I, 6, failSync), rawStack("Error: 5/fail:20/failSync:21") + "/G:88/H:95/I:101");
	stackEqual(T(_, I, 7, failAsync), rawStack("Error: 5/failAsync:15") + "/G:88/H:95/I:101");
	stackEqual(T(_, I, 7, failSync), rawStack("Error: 5/fail:20/failSync:21") + "/G:88/H:95/I:101");
	start();
})

if (!browser) asyncTest("issue233", 1, function(_) {
	stackEqual(T(_, issue233, 0, failSync), "Error: foo/customThrow:107/issue233:112");
	start();
});
<|endoftext|>


<commit_before>var git = require('../');
var rimraf = require('rimraf');
var fs = require( 'fs' );

// Helper functions
var helper = {
  // Test if obj is a true function
  testFunction: function(test, obj, label) {
    // The object reports itself as a function
    test(typeof obj, 'function', label + ' reports as a function.');
    // This ensures the repo is actually a derivative of the Function [[Class]]
    test(toString.call(obj), '[object Function]', label + ' [[Class]] is of type function.');
  },
  // Test code and handle exception thrown
  testException: function(test, fun, label) {
    try {
      fun();
      test(false, label);
    }
    catch (ex) {
      test(true, label);
    }
  }
};

/**
 * Test that the commit object is present.
 */
exports.method = function(test){
  test.expect(2);
  helper.testFunction(test.equals, git.commit, 'Commmit');
  test.done();
};

/**
 * Test that improper commit ID's result in an error message
 */
exports.improperCommitId = function(test) {
  test.expect(1);
  git.repo('../.git', function(error, repository) {
    repository.commit('not a proper commit sha', function(error, commit) {
      test.notEqual(error, null, 'Error should occur');
      test.done();
    });
  });
};

var historyCountKnownSHA = 'fce88902e66c72b5b93e75bdb5ae717038b221f6';

/**
 * Test that retreiving walking a given commit's history works as expected.
 *
 * @param  {Object} test
 */
exports.history = function(test) {
  test.expect(368);
  git.repo('../.git', function(error, repository) {
    repository.commit(historyCountKnownSHA, function(error, commit) {
      test.equals(null, error, 'Getting latest branch commit should not error');
      var historyCount = 0;
      var expectedHistoryCount = 364;
      commit.history().on('commit', function(error, commit) {
        test.equals(null, error, 'There should be no errors');
        historyCount++;
      }).on('end', function(error, commits) {
        test.equals(null, error, 'There should be no errors');
        test.equals(historyCount, expectedHistoryCount, 'Manual count does not match expected');
        test.equals(commits.length, expectedHistoryCount, '"end" count does not match expected');

        test.done();
      });
    });
  });
};

/**
 * Test that retreiving master branch's HEAD commit works as expected.
 */
exports.masterHead = function(test) {
  test.expect(2);
  git.repo('../.git', function(error, repository) {
    repository.branch('master', function(error, branch) {

      test.equals(error, null, 'Getting branch should not error');

      repository.commit(branch.sha, function(error, commit) {

        test.equals(error, null, 'Getting latest branch commit should not error');

        test.done();
      });
    });
  });
};

/**
 * Test that retreiving parent works as expected.
 *
 * @param  {Object} test
 */
exports.parentSync = function(test) {
  test.expect(2);
  git.repo('../.git', function(error, repository) {
    repository.commit('2d71044741412280370cb0326c96d3a5a7b5dca1', function(error, commit) {
      test.equals(commit.parentCount, 1, 'Commit has exactly one parent');
      var parent = commit.parentSync(0);
      test.equals(parent.sha, 'e8876707938abf94d5cc02b0c4017c4fec2aa44e', 'Parent SHA should match expected value');
      test.done();
    });
  });
};

/**
 * Test that retreiving parent works as expected.
 *
 * @param  {Object} test
 */
exports.parent = function(test) {
  test.expect(2);
  git.repo('../.git', function(error, repository) {
    repository.commit('2d71044741412280370cb0326c96d3a5a7b5dca1', function(error, commit) {
      test.equals(commit.parentCount, 1, 'Commit has exactly one parent');
      commit.parent(0, function(error, parent) {
        if (error) throw error;
        test.equals(parent.sha, 'e8876707938abf94d5cc02b0c4017c4fec2aa44e', 'Parent SHA should match expected value');
        test.done();
      });

    });
  });
};

/**
 * Test that retrieving and walking a commit's tree works as expected.
 */
exports.tree = function(test) {
  test.expect(2);
  git.repo('../.git', function(error, repository) {

    repository.commit(historyCountKnownSHA, function(error, commit) {

      test.equals(error, null, 'Getting latest branch commit should not error');

      var commitTreeEntryCount = 0;
      var expectedCommitTreeEntryCount = 200;

      commit.tree().walk().on('entry', function(commit) {
        commitTreeEntryCount++;
      }).on('end', function(commits) {

        test.equals(commitTreeEntryCount, expectedCommitTreeEntryCount, 'Commit tree entry count does not match expected');

        test.done();
      });
    });
  });
};

/**
 * Test that parentsDiffTrees works as expected.
 */
exports.parentsDiffTrees = function(test) {
  test.expect(1);
  git.repo('../.git', function(error, repository) {
    repository.commit(historyCountKnownSHA, function(error, commit) {
      commit.parentsDiffTrees(function(error, parentsDiffTrees) {
        console.log(arguments);
        process.exit();
      });
    });
  });
};
<commit_msg>Very basic diffTrees test<commit_after>var git = require('../');
var rimraf = require('rimraf');
var fs = require( 'fs' );

// Helper functions
var helper = {
  // Test if obj is a true function
  testFunction: function(test, obj, label) {
    // The object reports itself as a function
    test(typeof obj, 'function', label + ' reports as a function.');
    // This ensures the repo is actually a derivative of the Function [[Class]]
    test(toString.call(obj), '[object Function]', label + ' [[Class]] is of type function.');
  },
  // Test code and handle exception thrown
  testException: function(test, fun, label) {
    try {
      fun();
      test(false, label);
    }
    catch (ex) {
      test(true, label);
    }
  }
};

/**
 * Test that the commit object is present.
 */
exports.method = function(test){
  test.expect(2);
  helper.testFunction(test.equals, git.commit, 'Commmit');
  test.done();
};

/**
 * Test that improper commit ID's result in an error message
 */
exports.improperCommitId = function(test) {
  test.expect(1);
  git.repo('../.git', function(error, repository) {
    repository.commit('not a proper commit sha', function(error, commit) {
      test.notEqual(error, null, 'Error should occur');
      test.done();
    });
  });
};

var historyCountKnownSHA = 'fce88902e66c72b5b93e75bdb5ae717038b221f6';

/**
 * Test that retreiving walking a given commit's history works as expected.
 *
 * @param  {Object} test
 */
exports.history = function(test) {
  test.expect(368);
  git.repo('../.git', function(error, repository) {
    repository.commit(historyCountKnownSHA, function(error, commit) {
      test.equals(null, error, 'Getting latest branch commit should not error');
      var historyCount = 0;
      var expectedHistoryCount = 364;
      commit.history().on('commit', function(error, commit) {
        test.equals(null, error, 'There should be no errors');
        historyCount++;
      }).on('end', function(error, commits) {
        test.equals(null, error, 'There should be no errors');
        test.equals(historyCount, expectedHistoryCount, 'Manual count does not match expected');
        test.equals(commits.length, expectedHistoryCount, '"end" count does not match expected');

        test.done();
      });
    });
  });
};

/**
 * Test that retreiving master branch's HEAD commit works as expected.
 */
exports.masterHead = function(test) {
  test.expect(2);
  git.repo('../.git', function(error, repository) {
    repository.branch('master', function(error, branch) {

      test.equals(error, null, 'Getting branch should not error');

      repository.commit(branch.sha, function(error, commit) {

        test.equals(error, null, 'Getting latest branch commit should not error');

        test.done();
      });
    });
  });
};

/**
 * Test that retreiving parent works as expected.
 *
 * @param  {Object} test
 */
exports.parentSync = function(test) {
  test.expect(2);
  git.repo('../.git', function(error, repository) {
    repository.commit('2d71044741412280370cb0326c96d3a5a7b5dca1', function(error, commit) {
      test.equals(commit.parentCount, 1, 'Commit has exactly one parent');
      var parent = commit.parentSync(0);
      test.equals(parent.sha, 'e8876707938abf94d5cc02b0c4017c4fec2aa44e', 'Parent SHA should match expected value');
      test.done();
    });
  });
};

/**
 * Test that retreiving parent works as expected.
 *
 * @param  {Object} test
 */
exports.parent = function(test) {
  test.expect(2);
  git.repo('../.git', function(error, repository) {
    repository.commit('2d71044741412280370cb0326c96d3a5a7b5dca1', function(error, commit) {
      test.equals(commit.parentCount, 1, 'Commit has exactly one parent');
      commit.parent(0, function(error, parent) {
        if (error) throw error;
        test.equals(parent.sha, 'e8876707938abf94d5cc02b0c4017c4fec2aa44e', 'Parent SHA should match expected value');
        test.done();
      });

    });
  });
};

/**
 * Test that retrieving and walking a commit's tree works as expected.
 */
exports.tree = function(test) {
  test.expect(2);
  git.repo('../.git', function(error, repository) {

    repository.commit(historyCountKnownSHA, function(error, commit) {

      test.equals(error, null, 'Getting latest branch commit should not error');

      var commitTreeEntryCount = 0;
      var expectedCommitTreeEntryCount = 200;

      commit.tree().walk().on('entry', function(commit) {
        commitTreeEntryCount++;
      }).on('end', function(commits) {

        test.equals(commitTreeEntryCount, expectedCommitTreeEntryCount, 'Commit tree entry count does not match expected');

        test.done();
      });
    });
  });
};

/**
 * Test that parentsDiffTrees works as expected.
 */
exports.parentsDiffTrees = function(test) {
  test.expect(1);
  git.repo('../.git', function(error, repository) {
    repository.commit(historyCountKnownSHA, function(error, commit) {
      commit.parentsDiffTrees(function(error, parentsDiffTrees) {
        test.equals(parentsDiffTrees.length, 1, 'Should be one item in parents diff trees');
        test.done();
      });
    });
  });
};
<|endoftext|>


<commit_before>"use strict";

describe("define/class/check", function () {

    if (gpf.internals) {

        describe("(internal) _GpfClassDefinition", function () {

            var _GpfClassDefinition = gpf.internals._GpfClassDefinition,
                _gpfDefineBuildTypedEntity = gpf.internals._gpfDefineBuildTypedEntity;

            it("is used for class definition", function () {
                var definition = _gpfDefineBuildTypedEntity({
                    $class: "Test"
                });
                assert(definition instanceof _GpfClassDefinition);
            });

            it("accepts a valid class definition", function () {
                _gpfDefineBuildTypedEntity({
                    $class: "Test",
                    member: function () {}
                });
            });

            [
                "startingWithLowercaseLetterIsNotOK",
                "The$signIsForbbidenIfNotAtTheBeginning",
                "The_signIsForbbidenIfNotAtTheBeginning"
            ].forEach(function (invalidClassName) {
                it("rejects invalid class name (" + invalidClassName + ")", function () {
                    var exceptionCaught;
                    try {
                        _gpfDefineBuildTypedEntity({
                            $class: invalidClassName
                        });
                    } catch (e) {
                        exceptionCaught = e;
                    }
                    assert(exceptionCaught instanceof gpf.Error.InvalidClassName);
                });

            });

            [
                "StartingWithUppercaseLetterIsNotOK",
                "the$signIsForbbidenIfNotAtTheBeginning",
                "the_signIsForbbidenIfNotAtTheBeginning",
                "class"
            ].forEach(function (invalidPropertyName) {
                it("rejects invalid property name (" + invalidPropertyName + ")", function () {
                    var rawDefinition = {
                            $class: "Test"
                        },
                        exceptionCaught;
                    rawDefinition[invalidPropertyName] = true;
                    try {

                        _gpfDefineBuildTypedEntity(rawDefinition);
                    } catch (e) {
                        exceptionCaught = e;
                    }
                    assert(exceptionCaught instanceof gpf.Error.InvalidClassProperty);
                });

            });

        });

    }

});
<commit_msg>Tests $extend<commit_after>"use strict";

describe("define/class/check", function () {

    if (gpf.internals) {

        describe("(internal) _GpfClassDefinition", function () {

            var _GpfClassDefinition = gpf.internals._GpfClassDefinition,
                _gpfDefineBuildTypedEntity = gpf.internals._gpfDefineBuildTypedEntity;

            it("is used for class definition", function () {
                var definition = _gpfDefineBuildTypedEntity({
                    $class: "Test"
                });
                assert(definition instanceof _GpfClassDefinition);
            });

            it("accepts a valid class definition", function () {
                _gpfDefineBuildTypedEntity({
                    $class: "Test",
                    member: function () {}
                });
            });

            [
                "startingWithLowercaseLetterIsNotOK",
                "The$signIsForbbidenIfNotAtTheBeginning",
                "The_signIsForbbidenIfNotAtTheBeginning"
            ].forEach(function (invalidClassName) {
                it("rejects invalid class name (" + invalidClassName + ")", function () {
                    var exceptionCaught;
                    try {
                        _gpfDefineBuildTypedEntity({
                            $class: invalidClassName
                        });
                    } catch (e) {
                        exceptionCaught = e;
                    }
                    assert(exceptionCaught instanceof gpf.Error.InvalidClassName);
                });

            });

            [
                "StartingWithUppercaseLetterIsNotOK",
                "the$signIsForbbidenIfNotAtTheBeginning",
                "the_signIsForbbidenIfNotAtTheBeginning",
                "class"
            ].forEach(function (invalidPropertyName) {
                it("rejects invalid property name (" + invalidPropertyName + ")", function () {
                    var rawDefinition = {
                            $class: "Test"
                        },
                        exceptionCaught;
                    rawDefinition[invalidPropertyName] = true;
                    try {

                        _gpfDefineBuildTypedEntity(rawDefinition);
                    } catch (e) {
                        exceptionCaught = e;
                    }
                    assert(exceptionCaught instanceof gpf.Error.InvalidClassProperty);
                });

            });

            it("rejects invalid $extend", function () {
                var exceptionCaught;
                try {
                    _gpfDefineBuildTypedEntity({
                        $class: "Test",
                        $extend: 12
                    });
                } catch (e) {
                    exceptionCaught = e;
                }
                assert(exceptionCaught instanceof gpf.Error.InvalidClassExtend);
            });

            it("accepts native $extend", function () {
                _gpfDefineBuildTypedEntity({
                    $class: "Test",
                    $extend: String
                });
            });

            it("accepts contextual $extend", function () {
                _gpfDefineBuildTypedEntity({
                    $class: "Test",
                    $extend: "String"
                });
            });

        });

    }

});
<|endoftext|>


<commit_before>'use strict';
let bt = require('../../help/browsertimeSingleScript');
let assert = require('assert');

let path = 'http://0.0.0.0:8282/info/';

let BROWSERS = ['chrome', 'firefox'];

describe('Info', function() {

  BROWSERS.forEach(function(browser) {

    describe('browser:' + browser, function() {
      before(() => bt.start(browser));

      after(() => bt.stop());

      it('Should be able to find the assets inside the head tag', function() {
        return bt.run(path + 'head.html', 'lib/dom/info/head.js')
          .then((result) => {
            assert.strictEqual(result.jssync.length, 1);
            assert.strictEqual(result.jsasync.length, 1);
            assert.strictEqual(result.css.length, 2);
          });
      });

      it('We should be able to identify a AMP page', function() {
        return bt.run(path + 'amp.html', 'lib/dom/info/amp.js')
          .then((result) => {
            assert.strictEqual(result, '1450396666888');
          });
      });

      it('We should be able to identify the connection type', function() {
        return bt.run(path + 'connectionType.html', 'lib/dom/info/connectionType.js')
          .then((result) => {
            if (browser === 'chrome') {
              assert.strictEqual(result !== 'unknown', true);
            }
          });
      });

      it('We should be able to find iframes', function() {
        return bt.run(path + 'iframes.html', 'lib/dom/info/iframes.js')
          .then((result) => {
            assert.strictEqual(result, 2);
          });
      });

      it('We should be able to get the title', function() {
        return bt.run(path + 'documentTitle.html', 'lib/dom/info/documentTitle.js')
          .then((result) => {
            assert.strictEqual(result, 'Document title');
          });
      });

      it('We should be able to get the document height', function() {
        return bt.run(path + 'documentHeight.html', 'lib/dom/info/documentHeight.js')
          .then((result) => {
            assert.strictEqual(result > 0, true);
          });
      });

      it('We should be able to get the document width', function() {
        return bt.run(path + 'documentWidth.html', 'lib/dom/info/documentWidth.js')
          .then((result) => {
            assert.strictEqual(result> 0, true);
          });
      });

      it('We should be able to count the DOM depth', function() {
        return bt.run(path + 'domDepth.html', 'lib/dom/info/domDepth.js')
          .then((result) => {
            assert.strictEqual(result.avg, 3);
            assert.strictEqual(result.max, 4);
          });
      });

      it('We should be able to get the DOM elements', function() {
        return bt.run(path + 'domElements.html', 'lib/dom/info/domElements.js')
          .then((result) => {
            assert.strictEqual(result, 26);
          });
      });

      it('We should be able to get the local storage size', function() {
        return bt.run(path + 'localStorageSize.html', 'lib/dom/info/localStorageSize.js')
          .then((result) => {
            assert.strictEqual(result > 0, true);
          });
      });

      it('We should be able to get the session storage size', function() {
        return bt.run(path + 'sessionStorageSize.html', 'lib/dom/info/sessionStorageSize.js')
          .then((result) => {
            assert.strictEqual(result > 0, true);
          });
      });

      it('We should be able to get the window size', function() {
        return bt.run(path + 'windowSize.html', 'lib/dom/info/windowSize.js')
          .then((result) => {
            assert.strictEqual(result != undefined, true);
          });
      });

      it('We should be able to get resource hints', function() {
        return bt.run(path + 'resourceHints.html', 'lib/dom/info/resourceHints.js')
          .then((result) => {
            assert.strictEqual(result.prerender[0], 'http://0.0.0.0:8282/info/amp.html','Could not fetch prerender');
            assert.strictEqual(result.preconnect[0], 'http://example.com/','Could not fetch preconnect');
            assert.strictEqual(result.prefetch[0], 'http://0.0.0.0:8282/info/js/body.js','Could not fetch prefetch');
            assert.strictEqual(result["dns-prefetch"][0], 'http://example.com/','Could not fetch dns-prefetch');
          });
      });
    });
  });
});
<commit_msg>test connection type both for chrome & ff (since ff 45)<commit_after>'use strict';
let bt = require('../../help/browsertimeSingleScript');
let assert = require('assert');

let path = 'http://0.0.0.0:8282/info/';

let BROWSERS = ['chrome', 'firefox'];

describe('Info', function() {

  BROWSERS.forEach(function(browser) {

    describe('browser:' + browser, function() {
      before(() => bt.start(browser));

      after(() => bt.stop());

      it('Should be able to find the assets inside the head tag', function() {
        return bt.run(path + 'head.html', 'lib/dom/info/head.js')
          .then((result) => {
            assert.strictEqual(result.jssync.length, 1);
            assert.strictEqual(result.jsasync.length, 1);
            assert.strictEqual(result.css.length, 2);
          });
      });

      it('We should be able to identify a AMP page', function() {
        return bt.run(path + 'amp.html', 'lib/dom/info/amp.js')
          .then((result) => {
            assert.strictEqual(result, '1450396666888');
          });
      });

      it('We should be able to identify the connection type', function() {
        return bt.run(path + 'connectionType.html', 'lib/dom/info/connectionType.js')
          .then((result) => {
              assert.strictEqual(result !== 'unknown', true);
          });
      });

      it('We should be able to find iframes', function() {
        return bt.run(path + 'iframes.html', 'lib/dom/info/iframes.js')
          .then((result) => {
            assert.strictEqual(result, 2);
          });
      });

      it('We should be able to get the title', function() {
        return bt.run(path + 'documentTitle.html', 'lib/dom/info/documentTitle.js')
          .then((result) => {
            assert.strictEqual(result, 'Document title');
          });
      });

      it('We should be able to get the document height', function() {
        return bt.run(path + 'documentHeight.html', 'lib/dom/info/documentHeight.js')
          .then((result) => {
            assert.strictEqual(result > 0, true);
          });
      });

      it('We should be able to get the document width', function() {
        return bt.run(path + 'documentWidth.html', 'lib/dom/info/documentWidth.js')
          .then((result) => {
            assert.strictEqual(result> 0, true);
          });
      });

      it('We should be able to count the DOM depth', function() {
        return bt.run(path + 'domDepth.html', 'lib/dom/info/domDepth.js')
          .then((result) => {
            assert.strictEqual(result.avg, 3);
            assert.strictEqual(result.max, 4);
          });
      });

      it('We should be able to get the DOM elements', function() {
        return bt.run(path + 'domElements.html', 'lib/dom/info/domElements.js')
          .then((result) => {
            assert.strictEqual(result, 26);
          });
      });

      it('We should be able to get the local storage size', function() {
        return bt.run(path + 'localStorageSize.html', 'lib/dom/info/localStorageSize.js')
          .then((result) => {
            assert.strictEqual(result > 0, true);
          });
      });

      it('We should be able to get the session storage size', function() {
        return bt.run(path + 'sessionStorageSize.html', 'lib/dom/info/sessionStorageSize.js')
          .then((result) => {
            assert.strictEqual(result > 0, true);
          });
      });

      it('We should be able to get the window size', function() {
        return bt.run(path + 'windowSize.html', 'lib/dom/info/windowSize.js')
          .then((result) => {
            assert.strictEqual(result != undefined, true);
          });
      });

      it('We should be able to get resource hints', function() {
        return bt.run(path + 'resourceHints.html', 'lib/dom/info/resourceHints.js')
          .then((result) => {
            assert.strictEqual(result.prerender[0], 'http://0.0.0.0:8282/info/amp.html','Could not fetch prerender');
            assert.strictEqual(result.preconnect[0], 'http://example.com/','Could not fetch preconnect');
            assert.strictEqual(result.prefetch[0], 'http://0.0.0.0:8282/info/js/body.js','Could not fetch prefetch');
            assert.strictEqual(result["dns-prefetch"][0], 'http://example.com/','Could not fetch dns-prefetch');
          });
      });
    });
  });
});
<|endoftext|>


<commit_before>import check from './support/check.js';

describe('function calls', () => {
  it('inserts commas after arguments if they are not there', () => {
    check(`
      a(
        1
        2
      )
    `, `
      a(
        1,
        2
      );
    `);
  });

  it('does not insert commas in single-line calls', () => {
    check(`a(1, 2)`, `a(1, 2);`);
  });

  it('inserts commas only for arguments that end a line', () => {
    check(`
      a(
        1, 2
        3, 4)
    `, `
      a(
        1, 2,
        3, 4);
    `);
  });

  it('inserts commas immediately after the element if followed by a comment', () => {
    check(`
      a(
        1 # hi
        2
      )
    `, `
      a(
        1, // hi
        2
      );
    `);
  });

  it.skip('inserts commas on the same line when the property value is an interpolated string', () => {
    check(`
      a
        b: "#{c}"
        d: e
    `, `
      a({
        b: \`\${c}\`,
        d: e
      });
    `);
  });

  it('works when the first argument is parenthesized', () => {
    check(`
      f (1+1),2+2
    `, `
      f((1+1),2+2);
    `);
  });

  it('works when the last argument is parenthesized', () => {
    check(`
      f 1+1,(2+2)
    `, `
      f(1+1,(2+2));
    `);
  });

  it('works with `new` when the first argument is parenthesized', () => {
    check(`
      a= new c ([b()])
    `, `
      var a= new c(([b()]));
    `);
  });

  it.skip('places parentheses in calls with multi-line function arguments after the closing brace', () => {
    check(`
      promise.then ->
        b # c
      d
    `, `
      promise.then(function() {
        return b; // c
      });
      d;
    `);
  });

  it('replaces the space between the callee and the first argument for first arg on same line', () => {
    check(`a 1, 2`, `a(1, 2);`);
  });

  it('does not add anything if there are already parens', () => {
    check(`a()`, `a();`);
    check(`a(1, 2)`, `a(1, 2);`);
  });

  it('does not add them when present and the callee is surrounded by parentheses', () => {
    check(`(a)()`, `(a)();`);
  });

  it('adds parens for nested function calls', () => {
    check(`a   b  c d     e`, `a(b(c(d(e))));`);
  });

  it('adds parens for a new expression with args', () => {
    check(`new Foo 1`, `new Foo(1);`);
  });

  it('adds parens for a new expression without args', () => {
    check(`new Foo`, `new Foo();`);
  });

  it('adds parens after the properties of a member expression', () => {
    check(`a.b c`, `a.b(c);`);
  });

  it('adds parens after the brackets on a computed member expression', () => {
    check(`a b[c]`, `a(b[c]);`);
  });

  it.skip('adds parens without messing up multi-line calls', () => {
    check(`
      a
        b: c
    `, `
      a({
        b: c
      });
    `);
  });

  it.skip('adds parens to multi-line calls with the right indentation', () => {
    check(`
      ->
        a
          b: c
    `, `
      (function() {
        return a({
          b: c
        });
      });
    `);
  });

  it('converts rest params in function calls', () => {
    check(`(a,b...)->b[0]`, `(function(a,...b){return b[0]; });`);
  });
});
<commit_msg>Add a test which doesn't yet work.<commit_after>import check from './support/check.js';

describe('function calls', () => {
  it('inserts commas after arguments if they are not there', () => {
    check(`
      a(
        1
        2
      )
    `, `
      a(
        1,
        2
      );
    `);
  });

  it('does not insert commas in single-line calls', () => {
    check(`a(1, 2)`, `a(1, 2);`);
  });

  it('inserts commas only for arguments that end a line', () => {
    check(`
      a(
        1, 2
        3, 4)
    `, `
      a(
        1, 2,
        3, 4);
    `);
  });

  it('inserts commas immediately after the element if followed by a comment', () => {
    check(`
      a(
        1 # hi
        2
      )
    `, `
      a(
        1, // hi
        2
      );
    `);
  });

  it.skip('inserts commas on the same line when the property value is an interpolated string', () => {
    check(`
      a
        b: "#{c}"
        d: e
    `, `
      a({
        b: \`\${c}\`,
        d: e
      });
    `);
  });

  it('works when the first argument is parenthesized', () => {
    check(`
      f (1+1),2+2
    `, `
      f((1+1),2+2);
    `);
  });

  it('works when the last argument is parenthesized', () => {
    check(`
      f 1+1,(2+2)
    `, `
      f(1+1,(2+2));
    `);
  });

  it('works with `new` when the first argument is parenthesized', () => {
    check(`
      a= new c ([b()])
    `, `
      var a= new c(([b()]));
    `);
  });

  it.skip('places parentheses in calls with multi-line function arguments after the closing brace', () => {
    check(`
      promise.then ->
        b # c
      d
    `, `
      promise.then(function() {
        return b; // c
      });
      d;
    `);
  });

  it('replaces the space between the callee and the first argument for first arg on same line', () => {
    check(`a 1, 2`, `a(1, 2);`);
  });

  it('does not add anything if there are already parens', () => {
    check(`a()`, `a();`);
    check(`a(1, 2)`, `a(1, 2);`);
  });

  it('does not add them when present and the callee is surrounded by parentheses', () => {
    check(`(a)()`, `(a)();`);
  });

  it.skip('works with a multi-line callee', () => {
    // FIXME: This doesn't work because FunctionApplicationPatcher thinks it is
    // an implicit call (i.e. no parens), since the token after the function is
    // a newline and not a CALL_START (i.e. ')'). We should switch to coffee-lex
    // tokens and skip past any NEWLINE, COMMENT, or HERECOMMENT tokens.
    check(`
      (->
        1
      )()
    `, `
      (function() {
        return 1;
      )();
    `);
  });

  it('adds parens for nested function calls', () => {
    check(`a   b  c d     e`, `a(b(c(d(e))));`);
  });

  it('adds parens for a new expression with args', () => {
    check(`new Foo 1`, `new Foo(1);`);
  });

  it('adds parens for a new expression without args', () => {
    check(`new Foo`, `new Foo();`);
  });

  it('adds parens after the properties of a member expression', () => {
    check(`a.b c`, `a.b(c);`);
  });

  it('adds parens after the brackets on a computed member expression', () => {
    check(`a b[c]`, `a(b[c]);`);
  });

  it.skip('adds parens without messing up multi-line calls', () => {
    check(`
      a
        b: c
    `, `
      a({
        b: c
      });
    `);
  });

  it.skip('adds parens to multi-line calls with the right indentation', () => {
    check(`
      ->
        a
          b: c
    `, `
      (function() {
        return a({
          b: c
        });
      });
    `);
  });

  it('converts rest params in function calls', () => {
    check(`(a,b...)->b[0]`, `(function(a,...b){return b[0]; });`);
  });
});
<|endoftext|>


<commit_before>var parser = require("../../lib/parser2/parser.js"),
expect     = require("expect.js");

describe("parser/script#", function () {

  describe("references", function () {

  });

  describe("scripts", function () {
    it("automatically assigns value script", function () {
        var ast = parser.parse("{{ a }}")[0];
        expect(ast.scripts.value.value).to.be("a");
    });

    it("properly parses scripts", function () {
        var ast = parser.parse("{{ a:b, c:d, e:f}}")[0];
        expect(ast.scripts.a.value.value).to.be("b");
        expect(ast.scripts.c.value.value).to.be("d");
        expect(ast.scripts.e.value.value).to.be("f");
    });
  });

  describe("objects", function () {
    it("can have different types of keys", function () {
        var ast = parser.parse("{{{ a:b, 'c':d, \"e\":'f'} }}")[0];
        expect(ast.scripts.value.value[0].key).to.be("a");
        expect(ast.scripts.value.value[1].key).to.be("c");
        expect(ast.scripts.value.value[2].key).to.be("e");
    });
  });

  describe("numbers", function () {
    it("can parse an integer", function () {
      expect((parser.parse("{{ 55 }}")[0].scripts.value.value)).to.be(55);
    });

    it("can parse a floating point", function () {
      expect((parser.parse("{{ .5 }}")[0].scripts.value.value)).to.be(.5);
      expect((parser.parse("{{ 333.509 }}")[0].scripts.value.value)).to.be(333.509);
    });

    it("can parse a negative values", function () {
      expect((parser.parse("{{ -.5 }}")[0].scripts.value.value)).to.be(-.5);
      expect((parser.parse("{{ -333.509 }}")[0].scripts.value.value)).to.be(-333.509);
    });

  });

  describe("reserved words", function () {
    it("can parse boolean values", function () {
      expect(parser.parse("{{ true }}")[0].scripts.value.value).to.be(true);
      expect(parser.parse("{{ false }}")[0].scripts.value.value).to.be(false);
    });
    it("can parse undefined values", function () {
      expect(parser.parse("{{ undefined }}")[0].scripts.value.value).to.be(void 0);
    });
    it("can parse null values", function () {
      expect(parser.parse("{{ null }}")[0].scripts.value.value).to.be(null);
    });
  });

  describe("operations", function () {

    describe("ternery", function () {
      it("parses properly", function () {
        var ast = parser.parse("{{a?b:c}}")[0].scripts.value;

      });
      it("can nest ternery operations", function () {
        var ast = parser.parse("{{a ? b ? c ? d : e : f : g }}")[0].scripts.value;

        expect(ast.condition.value).to.be("a");
        expect(ast.right.value).to.be("g");
        expect(ast.left.condition.value).to.be("b");
        expect(ast.left.right.value).to.be("f");
        expect(ast.left.left.condition.value).to.be("c");
        expect(ast.left.left.right.value).to.be("e");
      });
    });

    describe("equations", function () {
      it("can add / subtract two numbers together", function () {
        var ast = parser.parse("{{ 5+6 }}")[0].scripts.value;
        expect(ast.left.value).to.be(5);
        expect(ast.right.value).to.be(6);
        ast = parser.parse("{{ 5-6 }}")[0].scripts.value;
        expect(ast.left.value).to.be(5);
        expect(ast.right.value).to.be(6);
      });

      it("gets the order of operations correct", function () {
        var ast = parser.parse("{{ 3+4*5/(6+7) }}")[0].scripts.value;
        expect(ast.left.value).to.be(3);
        expect(ast.right.left.value).to.be(4);
        expect(ast.right.right.left.value).to.be(5);
        expect(ast.right.right.right.left.value).to.be(6);
        expect(ast.right.right.right.right.value).to.be(7);
      });

      it("works with modulus", function () {
        var ast = parser.parse("{{ 3*4%5 }}")[0].scripts.value;
        expect(ast.left.left.value).to.be(3);
        expect(ast.left.right.value).to.be(4);
        expect(ast.right.value).to.be(5);

        var ast = parser.parse("{{ 3+4%5 }}")[0].scripts.value;
        expect(ast.left.value).to.be(3);
        expect(ast.right.left.value).to.be(4);
        expect(ast.right.right.value).to.be(5);
      });
    });

    describe("comparisons", function () {

      ["&&", "||", "==", "===", ">", ">=", ">==", "<", "<=", "<=="].forEach(function (op) {
         it("can parse " + op, function () {
          var ast = parser.parse("{{ true "+op+" false }}")[0].scripts.value;
          expect(ast.left.value).to.be(true);
          expect(ast.right.value).to.be(false);
        });
      });

      it("can parse multiple comparisons", function () {
        var ast = parser.parse("{{true && false >= true || undefined < null}}");
      });

      it("puts equations at a higher priority than comparisons", function () {
        var ast = parser.parse("{{scriptA:1>2+3}}")[0].scripts.scriptA;
        expect(ast.key).to.be("scriptA");
        expect(ast.value.type).to.be(">");
        expect(ast.value.left.value).to.be(1);
        expect(ast.value.right.left.value).to.be(2);
        expect(ast.value.right.right.value).to.be(3);
      });
    });
  });
});
<commit_msg>start on other operators<commit_after>var parser = require("../../lib/parser2/parser.js"),
expect     = require("expect.js");

describe("parser/script#", function () {

  describe("references", function () {

  });

  describe("scripts", function () {
    it("automatically assigns value script", function () {
        var ast = parser.parse("{{ a }}")[0];
        expect(ast.scripts.value.value).to.be("a");
    });

    it("properly parses scripts", function () {
        var ast = parser.parse("{{ a:b, c:d, e:f}}")[0];
        expect(ast.scripts.a.value.value).to.be("b");
        expect(ast.scripts.c.value.value).to.be("d");
        expect(ast.scripts.e.value.value).to.be("f");
    });
  });

  describe("objects", function () {
    it("can have different types of keys", function () {
        var ast = parser.parse("{{{ a:b, 'c':d, \"e\":'f'} }}")[0];
        expect(ast.scripts.value.value[0].key).to.be("a");
        expect(ast.scripts.value.value[1].key).to.be("c");
        expect(ast.scripts.value.value[2].key).to.be("e");
    });
  });

  describe("numbers", function () {
    it("can parse an integer", function () {
      expect((parser.parse("{{ 55 }}")[0].scripts.value.value)).to.be(55);
    });

    it("can parse a floating point", function () {
      expect((parser.parse("{{ .5 }}")[0].scripts.value.value)).to.be(.5);
      expect((parser.parse("{{ 333.509 }}")[0].scripts.value.value)).to.be(333.509);
    });

    it("can parse a negative values", function () {
      expect((parser.parse("{{ -.5 }}")[0].scripts.value.value)).to.be(-.5);
      expect((parser.parse("{{ -333.509 }}")[0].scripts.value.value)).to.be(-333.509);
    });

  });

  describe("reserved words", function () {
    it("can parse boolean values", function () {
      expect(parser.parse("{{ true }}")[0].scripts.value.value).to.be(true);
      expect(parser.parse("{{ false }}")[0].scripts.value.value).to.be(false);
    });
    it("can parse undefined values", function () {
      expect(parser.parse("{{ undefined }}")[0].scripts.value.value).to.be(void 0);
    });
    it("can parse null values", function () {
      expect(parser.parse("{{ null }}")[0].scripts.value.value).to.be(null);
    });
  });

  describe("operations", function () {

    describe("ternery", function () {
      it("parses properly", function () {
        var ast = parser.parse("{{a?b:c}}")[0].scripts.value;

      });
      it("can nest ternery operations", function () {
        var ast = parser.parse("{{a ? b ? c ? d : e : f : g }}")[0].scripts.value;

        expect(ast.condition.value).to.be("a");
        expect(ast.right.value).to.be("g");
        expect(ast.left.condition.value).to.be("b");
        expect(ast.left.right.value).to.be("f");
        expect(ast.left.left.condition.value).to.be("c");
        expect(ast.left.left.right.value).to.be("e");
      });
    });

    describe("equations", function () {
      it("can add / subtract two numbers together", function () {
        var ast = parser.parse("{{ 5+6 }}")[0].scripts.value;
        expect(ast.left.value).to.be(5);
        expect(ast.right.value).to.be(6);
        ast = parser.parse("{{ 5-6 }}")[0].scripts.value;
        expect(ast.left.value).to.be(5);
        expect(ast.right.value).to.be(6);
      });

      it("gets the order of operations correct", function () {
        var ast = parser.parse("{{ 3+4*5/(6+7) }}")[0].scripts.value;
        expect(ast.left.value).to.be(3);
        expect(ast.right.left.value).to.be(4);
        expect(ast.right.right.left.value).to.be(5);
        expect(ast.right.right.right.left.value).to.be(6);
        expect(ast.right.right.right.right.value).to.be(7);
      });

      it("works with modulus", function () {
        var ast = parser.parse("{{ 3*4%5 }}")[0].scripts.value;
        expect(ast.left.left.value).to.be(3);
        expect(ast.left.right.value).to.be(4);
        expect(ast.right.value).to.be(5);

        var ast = parser.parse("{{ 3+4%5 }}")[0].scripts.value;
        expect(ast.left.value).to.be(3);
        expect(ast.right.left.value).to.be(4);
        expect(ast.right.right.value).to.be(5);
      });
    });

    describe("comparisons", function () {

      ["&&", "||", "==", "===", ">", ">=", ">==", "<", "<=", "<=="].forEach(function (op) {
         it("can parse " + op, function () {
          var ast = parser.parse("{{ true "+op+" false }}")[0].scripts.value;
          expect(ast.left.value).to.be(true);
          expect(ast.right.value).to.be(false);
        });
      });

      it("can parse multiple comparisons", function () {
        var ast = parser.parse("{{true && false >= true || undefined < null}}");
      });

      it("puts equations at a higher priority than comparisons", function () {
        var ast = parser.parse("{{scriptA:1>2+3}}")[0].scripts.scriptA;
        expect(ast.key).to.be("scriptA");
        expect(ast.value.type).to.be(">");
        expect(ast.value.left.value).to.be(1);
        expect(ast.value.right.left.value).to.be(2);
        expect(ast.value.right.right.value).to.be(3);
      });
    });

    describe("assigning", function () {

    });

    describe("bindings", function () {

    });

    describe("modifiers", function () {

    });
  });
});
<|endoftext|>