<commit_before>// Copyright 2002-2015, University of Colorado Boulder

/**
 * This grunt task generates a markdown form of sherpa/third-party-licenses.json and automatically commits it.
 * The output can be observed at https://github.com/phetsims/sherpa/blob/master/third-party-licenses.md
 *
 * @author Aaron Davis
 * @author Sam Reid
 */

var child_process = require( 'child_process' );
var assert = require( 'assert' );

// constants
var SHERPA = '../sherpa';  // The relative path to sherpa, from the chipper path
var OUTPUT_FILE = 'third-party-licenses.md';
var LICENSES_DIRECTORY = '../sherpa/licenses/'; // contains third-party licenses themselves.

/**
 * @param grunt the grunt instance
 */
module.exports = function( grunt ) {
  'use strict';

  var json = grunt.file.readJSON( SHERPA + '/third-party-licenses.json' );

  var entries = [];

  for ( var library in json ) {

    // check for existence of the license file
    if ( !fs.existsSync( LICENSES_DIRECTORY + library + '.txt' ) ) {
      grunt.log.error( 'license file not found for ' + library );
    }

    var lines = [
      '**' + library + '**',
      json[ library ].text.join( '
' ),
      json[ library ].projectURL,
      json[ library ].license + '  ' + json[ library ].licenseURL,
      json[ library ].notes
    ];

    // \n worked well when viewing GitHub markdown as an issue comment, but for unknown reasons
 is necessary when
    // viewing from https://github.com/phetsims/sherpa/blob/master/third-party-licenses.md
    entries.push( lines.join( '
' ) );
  }

  var output = entries.join( '\n\n' );

  // It is sometimes convenient to iterate using GitHub issue preview rather than committing every time.
  // In this case, you may want to comment out the commit below.
  grunt.log.debug( '!!!!!! BEGIN LICENSES OUTPUT' );
  grunt.log.debug( output );
  grunt.log.debug( '!!!!!! END LICENSES OUTPUT' );

  grunt.log.writeln( 'writing file ' + OUTPUT_FILE );
  grunt.file.write( SHERPA + '/' + OUTPUT_FILE, output );

  //var done = grunt.task.current.async();

  // exec a command in the sherpa directory
  //var exec = function( command, callback ) {
  //  child_process.exec( command, { cwd: SHERPA }, function( err, stdout, stderr ) {
  //    grunt.log.writeln( stdout );
  //    grunt.log.writeln( stderr );
  //    assert( !err, 'assertion error running ' + command );
  //    callback();
  //  } );
  //};
  //
  //exec( 'git add ' + OUTPUT_FILE, function() {
  //  exec( 'git commit --message "updated info.md"', function() {
  //    exec( 'git push', function() {
  //      done();
  //    } );
  //  } );
  //} );
};<commit_msg>Uncommented code for git commits/pushes<commit_after>// Copyright 2002-2015, University of Colorado Boulder

/**
 * This grunt task generates a markdown form of sherpa/third-party-licenses.json and automatically commits it.
 * The output can be observed at https://github.com/phetsims/sherpa/blob/master/third-party-licenses.md
 *
 * @author Aaron Davis
 * @author Sam Reid
 */

var child_process = require( 'child_process' );
var assert = require( 'assert' );

// constants
var SHERPA = '../sherpa';  // The relative path to sherpa, from the chipper path
var OUTPUT_FILE = 'third-party-licenses.md';
var LICENSES_DIRECTORY = '../sherpa/licenses/'; // contains third-party licenses themselves.

/**
 * @param grunt the grunt instance
 */
module.exports = function( grunt ) {
  'use strict';

  var json = grunt.file.readJSON( SHERPA + '/third-party-licenses.json' );

  var entries = [];

  for ( var library in json ) {

    // check for existence of the license file
    if ( !fs.existsSync( LICENSES_DIRECTORY + library + '.txt' ) ) {
      grunt.log.error( 'license file not found for ' + library );
    }

    var lines = [
      '**' + library + '**',
      json[ library ].text.join( '
' ),
      json[ library ].projectURL,
      json[ library ].license + '  ' + json[ library ].licenseURL,
      json[ library ].notes
    ];

    // \n worked well when viewing GitHub markdown as an issue comment, but for unknown reasons
 is necessary when
    // viewing from https://github.com/phetsims/sherpa/blob/master/third-party-licenses.md
    entries.push( lines.join( '
' ) );
  }

  var output = entries.join( '\n\n' );

  // It is sometimes convenient to iterate using GitHub issue preview rather than committing every time.
  // In this case, you may want to comment out the commit below.
  grunt.log.debug( '!!!!!! BEGIN LICENSES OUTPUT' );
  grunt.log.debug( output );
  grunt.log.debug( '!!!!!! END LICENSES OUTPUT' );

  grunt.log.writeln( 'writing file ' + OUTPUT_FILE );
  grunt.file.write( SHERPA + '/' + OUTPUT_FILE, output );

  var done = grunt.task.current.async();

  // exec a command in the sherpa directory
  var exec = function( command, callback ) {
    child_process.exec( command, { cwd: SHERPA }, function( err, stdout, stderr ) {
      grunt.log.writeln( stdout );
      grunt.log.writeln( stderr );
      assert( !err, 'assertion error running ' + command );
      callback();
    } );
  };

  exec( 'git add ' + OUTPUT_FILE, function() {
    exec( 'git commit --message "updated info.md"', function() {
      exec( 'git push', function() {
        done();
      } );
    } );
  } );
};<|endoftext|>


<commit_before>/**
 * EditorObservable.js
 *
 * Released under LGPL License.
 * Copyright (c) 1999-2015 Ephox Corp. All rights reserved
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

/**
 * This mixin contains the event logic for the tinymce.Editor class.
 *
 * @mixin tinymce.EditorObservable
 * @extends tinymce.util.Observable
 */
define("tinymce/EditorObservable", [
	"tinymce/util/Observable",
	"tinymce/dom/DOMUtils",
	"tinymce/util/Tools"
], function(Observable, DOMUtils, Tools) {
	var DOM = DOMUtils.DOM, customEventRootDelegates;

	/**
	 * Returns the event target so for the specified event. Some events fire
	 * only on document, some fire on documentElement etc. This also handles the
	 * custom event root setting where it returns that element instead of the body.
	 *
	 * @private
	 * @param {tinymce.Editor} editor Editor instance to get event target from.
	 * @param {String} eventName Name of the event for example "click".
	 * @return {Element/Document} HTML Element or document target to bind on.
	 */
	function getEventTarget(editor, eventName) {
		if (eventName == 'selectionchange') {
			return editor.getDoc();
		}

		// Need to bind mousedown/mouseup etc to document not body in iframe mode
		// Since the user might click on the HTML element not the BODY
		if (!editor.inline && /^mouse|click|contextmenu|drop|dragover|dragend/.test(eventName)) {
			return editor.getDoc().documentElement;
		}

		// Bind to event root instead of body if it's defined
		if (editor.settings.event_root) {
			if (!editor.eventRoot) {
				editor.eventRoot = DOM.select(editor.settings.event_root)[0];
			}

			return editor.eventRoot;
		}

		return editor.getBody();
	}

	/**
	 * Binds a event delegate for the specified name this delegate will fire
	 * the event to the editor dispatcher.
	 *
	 * @private
	 * @param {tinymce.Editor} editor Editor instance to get event target from.
	 * @param {String} eventName Name of the event for example "click".
	 */
	function bindEventDelegate(editor, eventName) {
		var eventRootElm = getEventTarget(editor, eventName), delegate;

		function isListening(editor) {
			return !editor.hidden && !editor.readonly;
		}

		if (!editor.delegates) {
			editor.delegates = {};
		}

		if (editor.delegates[eventName]) {
			return;
		}

		if (editor.settings.event_root) {
			if (!customEventRootDelegates) {
				customEventRootDelegates = {};
				editor.editorManager.on('removeEditor', function() {
					var name;

					if (!editor.editorManager.activeEditor) {
						if (customEventRootDelegates) {
							for (name in customEventRootDelegates) {
								editor.dom.unbind(getEventTarget(editor, name));
							}

							customEventRootDelegates = null;
						}
					}
				});
			}

			if (customEventRootDelegates[eventName]) {
				return;
			}

			delegate = function(e) {
				var target = e.target, editors = editor.editorManager.editors, i = editors.length;

				while (i--) {
					var body = editors[i].getBody();

					if (body === target || DOM.isChildOf(target, body)) {
						if (isListening(editors[i])) {
							editors[i].fire(eventName, e);
						}
					}
				}
			};

			customEventRootDelegates[eventName] = delegate;
			DOM.bind(eventRootElm, eventName, delegate);
		} else {
			delegate = function(e) {
				if (isListening(editor)) {
					editor.fire(eventName, e);
				}
			};

			DOM.bind(eventRootElm, eventName, delegate);
			editor.delegates[eventName] = delegate;
		}
	}

	var EditorObservable = {
		/**
		 * Bind any pending event delegates. This gets executed after the target body/document is created.
		 *
		 * @private
		 */
		bindPendingEventDelegates: function() {
			var self = this;

			Tools.each(self._pendingNativeEvents, function(name) {
				bindEventDelegate(self, name);
			});
		},

		/**
		 * Toggles a native event on/off this is called by the EventDispatcher when
		 * the first native event handler is added and when the last native event handler is removed.
		 *
		 * @private
		 */
		toggleNativeEvent: function(name, state) {
			var self = this;

			// Never bind focus/blur since the FocusManager fakes those
			if (name == "focus" || name == "blur") {
				return;
			}

			if (state) {
				if (self.initialized) {
					bindEventDelegate(self, name);
				} else {
					if (!self._pendingNativeEvents) {
						self._pendingNativeEvents = [name];
					} else {
						self._pendingNativeEvents.push(name);
					}
				}
			} else if (self.initialized) {
				self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]);
				delete self.delegates[name];
			}
		},

		/**
		 * Unbinds all native event handlers that means delegates, custom events bound using the Events API etc.
		 *
		 * @private
		 */
		unbindAllNativeEvents: function() {
			var self = this, name;

			if (self.delegates) {
				for (name in self.delegates) {
					self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]);
				}

				delete self.delegates;
			}

			if (!self.inline) {
				self.getBody().onload = null;
				self.dom.unbind(self.getWin());
				self.dom.unbind(self.getDoc());
			}

			self.dom.unbind(self.getBody());
			self.dom.unbind(self.getContainer());
		}
	};

	EditorObservable = Tools.extend({}, Observable, EditorObservable);

	return EditorObservable;
});
<commit_msg>added touch events to documentElement in iframe mode<commit_after>/**
 * EditorObservable.js
 *
 * Released under LGPL License.
 * Copyright (c) 1999-2015 Ephox Corp. All rights reserved
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

/**
 * This mixin contains the event logic for the tinymce.Editor class.
 *
 * @mixin tinymce.EditorObservable
 * @extends tinymce.util.Observable
 */
define("tinymce/EditorObservable", [
	"tinymce/util/Observable",
	"tinymce/dom/DOMUtils",
	"tinymce/util/Tools"
], function(Observable, DOMUtils, Tools) {
	var DOM = DOMUtils.DOM, customEventRootDelegates;

	/**
	 * Returns the event target so for the specified event. Some events fire
	 * only on document, some fire on documentElement etc. This also handles the
	 * custom event root setting where it returns that element instead of the body.
	 *
	 * @private
	 * @param {tinymce.Editor} editor Editor instance to get event target from.
	 * @param {String} eventName Name of the event for example "click".
	 * @return {Element/Document} HTML Element or document target to bind on.
	 */
	function getEventTarget(editor, eventName) {
		if (eventName == 'selectionchange') {
			return editor.getDoc();
		}

		// Need to bind mousedown/mouseup etc to document not body in iframe mode
		// Since the user might click on the HTML element not the BODY
		if (!editor.inline && /^mouse|touch|click|contextmenu|drop|dragover|dragend/.test(eventName)) {
			return editor.getDoc().documentElement;
		}

		// Bind to event root instead of body if it's defined
		if (editor.settings.event_root) {
			if (!editor.eventRoot) {
				editor.eventRoot = DOM.select(editor.settings.event_root)[0];
			}

			return editor.eventRoot;
		}

		return editor.getBody();
	}

	/**
	 * Binds a event delegate for the specified name this delegate will fire
	 * the event to the editor dispatcher.
	 *
	 * @private
	 * @param {tinymce.Editor} editor Editor instance to get event target from.
	 * @param {String} eventName Name of the event for example "click".
	 */
	function bindEventDelegate(editor, eventName) {
		var eventRootElm = getEventTarget(editor, eventName), delegate;

		function isListening(editor) {
			return !editor.hidden && !editor.readonly;
		}

		if (!editor.delegates) {
			editor.delegates = {};
		}

		if (editor.delegates[eventName]) {
			return;
		}

		if (editor.settings.event_root) {
			if (!customEventRootDelegates) {
				customEventRootDelegates = {};
				editor.editorManager.on('removeEditor', function() {
					var name;

					if (!editor.editorManager.activeEditor) {
						if (customEventRootDelegates) {
							for (name in customEventRootDelegates) {
								editor.dom.unbind(getEventTarget(editor, name));
							}

							customEventRootDelegates = null;
						}
					}
				});
			}

			if (customEventRootDelegates[eventName]) {
				return;
			}

			delegate = function(e) {
				var target = e.target, editors = editor.editorManager.editors, i = editors.length;

				while (i--) {
					var body = editors[i].getBody();

					if (body === target || DOM.isChildOf(target, body)) {
						if (isListening(editors[i])) {
							editors[i].fire(eventName, e);
						}
					}
				}
			};

			customEventRootDelegates[eventName] = delegate;
			DOM.bind(eventRootElm, eventName, delegate);
		} else {
			delegate = function(e) {
				if (isListening(editor)) {
					editor.fire(eventName, e);
				}
			};

			DOM.bind(eventRootElm, eventName, delegate);
			editor.delegates[eventName] = delegate;
		}
	}

	var EditorObservable = {
		/**
		 * Bind any pending event delegates. This gets executed after the target body/document is created.
		 *
		 * @private
		 */
		bindPendingEventDelegates: function() {
			var self = this;

			Tools.each(self._pendingNativeEvents, function(name) {
				bindEventDelegate(self, name);
			});
		},

		/**
		 * Toggles a native event on/off this is called by the EventDispatcher when
		 * the first native event handler is added and when the last native event handler is removed.
		 *
		 * @private
		 */
		toggleNativeEvent: function(name, state) {
			var self = this;

			// Never bind focus/blur since the FocusManager fakes those
			if (name == "focus" || name == "blur") {
				return;
			}

			if (state) {
				if (self.initialized) {
					bindEventDelegate(self, name);
				} else {
					if (!self._pendingNativeEvents) {
						self._pendingNativeEvents = [name];
					} else {
						self._pendingNativeEvents.push(name);
					}
				}
			} else if (self.initialized) {
				self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]);
				delete self.delegates[name];
			}
		},

		/**
		 * Unbinds all native event handlers that means delegates, custom events bound using the Events API etc.
		 *
		 * @private
		 */
		unbindAllNativeEvents: function() {
			var self = this, name;

			if (self.delegates) {
				for (name in self.delegates) {
					self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]);
				}

				delete self.delegates;
			}

			if (!self.inline) {
				self.getBody().onload = null;
				self.dom.unbind(self.getWin());
				self.dom.unbind(self.getDoc());
			}

			self.dom.unbind(self.getBody());
			self.dom.unbind(self.getContainer());
		}
	};

	EditorObservable = Tools.extend({}, Observable, EditorObservable);

	return EditorObservable;
});
<|endoftext|>


<commit_before>// Copyright 2016, University of Colorado Boulder

/**
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Andrew Adare
 */
define( function( require ) {
  'use strict';

  // modules
  var assertInstanceOf = require( 'PHET_IO/assertions/assertInstanceOf' );
  var phetioInherit = require( 'PHET_IO/phetioInherit' );
  var phetioNamespace = require( 'PHET_IO/phetioNamespace' );
  var TObject = require( 'PHET_IO/types/TObject' );
  var phetioEvents = require( 'PHET_IO/phetioEvents' );

  // Emitter for 0, 1 or 2 args
  var TTandemEmitter = function( argTypes ) {
    return phetioInherit( TObject, 'TTandemEmitter', function( tandemEmitter, phetioID ) {

      TObject.call( this, tandemEmitter, phetioID );
      assertInstanceOf( tandemEmitter, phet.tandem.TandemEmitter );

      var messageIndex = null;

      tandemEmitter.callbacksStartedEmitter.addListener( function() {
        assert && assert( arguments.length === argTypes.length, 'Wrong number of arguments, expected ' + argTypes.length + ', received ' + arguments.length );
        var p = [];
        for ( var i = 0; i < arguments.length; i++ ) {
          var a = arguments[ i ];
          p.push( a );
        }
        var parameters = { arguments: p };
        messageIndex = phetioEvents.start( 'model', phetioID, TTandemEmitter( argTypes ), 'emitted', parameters );
      } );

      tandemEmitter.callbacksEndedEmitter.addListener( function() {
        assert && assert( arguments.length === 0, 'Wrong number of arguments, expected ' + argTypes.length + ', received ' + arguments.length );
        messageIndex && phetioEvents.end( messageIndex );
      } );
    }, {}, {
      documentation: 'Emitters indicate when events have occurred, with optional arguments describing the event',
      events: [ 'emitted' ]
    } );
  };

  phetioNamespace.register( 'TTandemEmitter', TTandemEmitter );

  return TTandemEmitter;
} );

<commit_msg>Require argTypes to be supplied for TTandemEmitter<commit_after>// Copyright 2016, University of Colorado Boulder

/**
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Andrew Adare
 */
define( function( require ) {
  'use strict';

  // modules
  var assertInstanceOf = require( 'PHET_IO/assertions/assertInstanceOf' );
  var phetioInherit = require( 'PHET_IO/phetioInherit' );
  var phetioNamespace = require( 'PHET_IO/phetioNamespace' );
  var TObject = require( 'PHET_IO/types/TObject' );
  var phetioEvents = require( 'PHET_IO/phetioEvents' );

  // Emitter for 0, 1 or 2 args
  var TTandemEmitter = function( argTypes ) {
    assert && assert( argTypes, 'argTypes should be defined' );
    return phetioInherit( TObject, 'TTandemEmitter', function( tandemEmitter, phetioID ) {

      TObject.call( this, tandemEmitter, phetioID );
      assertInstanceOf( tandemEmitter, phet.tandem.TandemEmitter );

      var messageIndex = null;

      tandemEmitter.callbacksStartedEmitter.addListener( function() {
        assert && assert( arguments.length === argTypes.length, 'Wrong number of arguments, expected ' + argTypes.length + ', received ' + arguments.length );
        var p = [];
        for ( var i = 0; i < arguments.length; i++ ) {
          var a = arguments[ i ];
          p.push( a );
        }
        var parameters = { arguments: p };
        messageIndex = phetioEvents.start( 'model', phetioID, TTandemEmitter( argTypes ), 'emitted', parameters );
      } );

      tandemEmitter.callbacksEndedEmitter.addListener( function() {
        assert && assert( arguments.length === 0, 'Wrong number of arguments, expected ' + argTypes.length + ', received ' + arguments.length );
        messageIndex && phetioEvents.end( messageIndex );
      } );
    }, {}, {
      documentation: 'Emitters indicate when events have occurred, with optional arguments describing the event',
      events: [ 'emitted' ]
    } );
  };

  phetioNamespace.register( 'TTandemEmitter', TTandemEmitter );

  return TTandemEmitter;
} );

<|endoftext|>


<commit_before>// 73: Generator - `return` inside a generator is special
// To do: make all tests pass, leave the assert lines unchanged!

describe('`return` in a generator function is special', function() {
  describe('the returned value is an IteratorResult (just like any value returned via `yield`)', function() {
    it('returns an IteratorResult (an object with the properties `value` and `done`)', function() {
      function* generatorFunction() { return 1; }
      const returned = generatorFunction().next();
      //// const propertyNames = [];
      const propertyNames = ['value', 'done'];
      assert.deepEqual(Object.keys(returned), propertyNames);
    });
    it('the property `value` is the returned value', function() {
      //// function* generatorFunction() { return; }
      function* generatorFunction() { return 23; }
      const {value} = generatorFunction().next();
      assert.equal(value, 23);
    });
    it('the property `done` is true', function() {
      /// function* generatorFunction() { yield 42; }
      function* generatorFunction() { return 42; }
      const {done} = generatorFunction().next();
      assert.equal(done, true);
    });
    it('NOTE: `yield` does not return `done=true` but `done=false`!', function() {
      /// function* generatorFunction() { return 1; }
      function* generatorFunction() { yield 1; }
      const returned = generatorFunction().next();
      assert.deepEqual(returned, {value: 1, done: false});
    });
    it('a missing `return` returns `{value: undefined, done: true}`', function() {
      /// function* generatorFunction() { yield; }
      function* generatorFunction() { }
      const returned = generatorFunction().next();
      assert.deepEqual(returned, {value: void 0, done: true});
    });
  });

  describe('mixing `return` and `yield`', function() {
    function* generatorFunctionWithYieldAndReturn() {
      yield 1;
      ////
      return 2;
    }
    it('is possible', function() {
      const iterator = generatorFunctionWithYieldAndReturn();
      const values = [
        iterator.next(),
        iterator.next()
      ];
      assert.deepEqual(values, [{value: 1, done: false}, {value: 2, done: true}]);
    });
    it('the mix behaves different to two `yield`s', function() {
      const iterator = generatorFunctionWithYieldAndReturn();
      /// const values = [1, 2];
      const values = [1];
      assert.deepEqual(Array.from(iterator), values);
    });
    it('two `yield`s returning values', function() {
      function* generatorFunctionWithTwoYields() {
        ////
	yield 1;
	////
	yield 2;
      }
      assert.deepEqual(Array.from(generatorFunctionWithTwoYields()), [1, 2]);
    });
    it('return a yielded value by "chaining" `return` and `yield`', function() {
      function* generatorFunction() {
        /// return 1;
        return yield 1;
      }
      const iterator = generatorFunction();
      const values = [
        iterator.next().value,
        iterator.next(2).value
      ];
      assert.deepEqual(values, [1, 2]);
    });
  });
});
<commit_msg>Fixed the number of slashes.<commit_after>// 73: Generator - `return` inside a generator is special
// To do: make all tests pass, leave the assert lines unchanged!

describe('`return` in a generator function is special', function() {
  describe('the returned value is an IteratorResult (just like any value returned via `yield`)', function() {
    it('returns an IteratorResult (an object with the properties `value` and `done`)', function() {
      function* generatorFunction() { return 1; }
      const returned = generatorFunction().next();
      //// const propertyNames = [];
      const propertyNames = ['value', 'done'];
      assert.deepEqual(Object.keys(returned), propertyNames);
    });
    it('the property `value` is the returned value', function() {
      //// function* generatorFunction() { return; }
      function* generatorFunction() { return 23; }
      const {value} = generatorFunction().next();
      assert.equal(value, 23);
    });
    it('the property `done` is true', function() {
      //// function* generatorFunction() { yield 42; }
      function* generatorFunction() { return 42; }
      const {done} = generatorFunction().next();
      assert.equal(done, true);
    });
    it('NOTE: `yield` does not return `done=true` but `done=false`!', function() {
      //// function* generatorFunction() { return 1; }
      function* generatorFunction() { yield 1; }
      const returned = generatorFunction().next();
      assert.deepEqual(returned, {value: 1, done: false});
    });
    it('a missing `return` returns `{value: undefined, done: true}`', function() {
      //// function* generatorFunction() { yield; }
      function* generatorFunction() { }
      const returned = generatorFunction().next();
      assert.deepEqual(returned, {value: void 0, done: true});
    });
  });

  describe('mixing `return` and `yield`', function() {
    function* generatorFunctionWithYieldAndReturn() {
      yield 1;
      ////
      return 2;
    }
    it('is possible', function() {
      const iterator = generatorFunctionWithYieldAndReturn();
      const values = [
        iterator.next(),
        iterator.next()
      ];
      assert.deepEqual(values, [{value: 1, done: false}, {value: 2, done: true}]);
    });
    it('the mix behaves different to two `yield`s', function() {
      const iterator = generatorFunctionWithYieldAndReturn();
      //// const values = [1, 2];
      const values = [1];
      assert.deepEqual(Array.from(iterator), values);
    });
    it('two `yield`s returning values', function() {
      function* generatorFunctionWithTwoYields() {
        ////
	yield 1;
	////
	yield 2;
      }
      assert.deepEqual(Array.from(generatorFunctionWithTwoYields()), [1, 2]);
    });
    it('return a yielded value by "chaining" `return` and `yield`', function() {
      function* generatorFunction() {
        //// return 1;
        return yield 1;
      }
      const iterator = generatorFunction();
      const values = [
        iterator.next().value,
        iterator.next(2).value
      ];
      assert.deepEqual(values, [1, 2]);
    });
  });
});
<|endoftext|>


<commit_before>var expect = require('chai').expect,
    FILL_ME_IN;

// This section uses a functional library called Lodash...
var _ = require('lodash'); // https://lodash.com

describe("About Higher Order Functions", function () {

  it("should use filter to return array items that meet a criteria", function () {
    var numbers = [1,2,3];
    var odd = _(numbers).filter(function (x) { return x % 2 !== 0 });

    expect(odd).to.deep.equal(FILL_ME_IN);
    expect(odd.length).toBe(FILL_ME_IN);
    expect(numbers.length).toBe(FILL_ME_IN);
  });

  it("should use 'map' to transform each element", function () {
    var numbers = [1, 2, 3];
    var numbersPlus1 = _(numbers).map(function(x) { return x + 1 });

    expect(numbersPlus1).to.deep.equal(FILL_ME_IN);
    expect(numbers).to.deep.equal(FILL_ME_IN);
  });

  it("should use 'reduce' to update the same result on each iteration", function () {
    var numbers = [1, 2, 3];
    var reduction = _(numbers).reduce(
            function(/* result from last call */ memo, /* current */ x) { return memo + x }, /* initial */ 0);

    expect(reduction).toBe(FILL_ME_IN);
    expect(numbers).to.deep.equal(FILL_ME_IN);
  });

  it("should use 'forEach' for simple iteration", function () {
    var numbers = [1,2,3];
    var msg = "";
    var isEven = function (item) {
      msg += (item % 2) === 0;
    };

    _(numbers).forEach(isEven);

    expect(msg).to.deep.equal(FILL_ME_IN);
    expect(numbers).to.deep.equal(FILL_ME_IN);
  });

  it("should use 'all' to test whether all items pass condition", function () {
    var onlyEven = [2,4,6];
    var mixedBag = [2,4,5,6];

    var isEven = function(x) { return x % 2 === 0 };

    expect(_(onlyEven).all(isEven)).toBe(FILL_ME_IN);
    expect(_(mixedBag).all(isEven)).toBe(FILL_ME_IN);
  });

  it("should use 'any' to test if any items passes condition" , function () {
    var onlyEven = [2,4,6];
    var mixedBag = [2,4,5,6];

    var isEven = function(x) { return x % 2 === 0 };

    expect(_(onlyEven).any(isEven)).toBe(FILL_ME_IN);
    expect(_(mixedBag).any(isEven)).toBe(FILL_ME_IN);
  });

  it("should use range to generate an array", function() {
      expect(_.range(3)).to.deep.equal(FILL_ME_IN);
      expect(_.range(1, 4)).to.deep.equal(FILL_ME_IN);
      expect(_.range(0, -4, -1)).to.deep.equal(FILL_ME_IN);
  });

  it("should use flatten to make nested arrays easy to work with", function() {
      expect(_([ [1, 2], [3, 4] ]).flatten()).to.deep.equal(FILL_ME_IN);
  });

  it("should use chain() ... .value() to use multiple higher order functions", function() {
      var result = _([ [0, 1], 2 ]).chain()
                       .flatten()
                       .map(function(x) { return x+1 } )
                       .reduce(function (sum, x) { return sum + x })
                       .value();

      expect(result).to.deep.equal(FILL_ME_IN);
  });

});

<commit_msg>Test not passing but all should be logically correct. Suspect problem with lodash<commit_after>var expect = require('chai').expect,
    FILL_ME_IN;

// This section uses a functional library called Lodash...
var _ = require('lodash'); // https://lodash.com

describe("About Higher Order Functions", function () {

  it("should use filter to return array items that meet a criteria", function () {
    var numbers = [1,2,3];
    var odd = _(numbers).filter(function (x) { return x % 2 !== 0 });

    expect(odd).to.deep.equal([1, 3]);
    expect(odd.length).toBe(2);
    expect(numbers.length).toBe(3);
  });

  it("should use 'map' to transform each element", function () {
    var numbers = [1, 2, 3];
    var numbersPlus1 = _(numbers).map(function(x) { return x + 1 });

    expect(numbersPlus1).to.deep.equal([2, 3, 4]);
    expect(numbers).to.deep.equal([1, 2, 3]);
  });

  it("should use 'reduce' to update the same result on each iteration", function () {
    var numbers = [1, 2, 3];
    var reduction = _(numbers).reduce(
            function(/* result from last call */ memo, /* current */ x) { return memo + x }, /* initial */ 0);

    expect(reduction).toBe(6);
    expect(numbers).to.deep.equal([1, 2, 3]);
  });

  it("should use 'forEach' for simple iteration", function () {
    var numbers = [1,2,3];
    var msg = "";
    var isEven = function (item) {
      msg += (item % 2) === 0;
    };

    _(numbers).forEach(isEven);

    expect(msg).to.deep.equal("falsetruefalse");
    expect(numbers).to.deep.equal([1, 2, 3]);
  });

  it("should use 'all' to test whether all items pass condition", function () {
    var onlyEven = [2,4,6];
    var mixedBag = [2,4,5,6];

    var isEven = function(x) { return x % 2 === 0 };

    expect(_(onlyEven).all(isEven)).toBe(true);
    expect(_(mixedBag).all(isEven)).toBe(false);
  });

  it("should use 'any' to test if any items passes condition" , function () {
    var onlyEven = [2,4,6];
    var mixedBag = [2,4,5,6];

    var isEven = function(x) { return x % 2 === 0 };

    expect(_(onlyEven).any(isEven)).toBe(true);
    expect(_(mixedBag).any(isEven)).toBe(true);
  });

  it("should use range to generate an array", function() {
      expect(_.range(3)).to.deep.equal([0, 1, 2]);
      expect(_.range(1, 4)).to.deep.equal([1, 2, 3]);
      expect(_.range(0, -4, -1)).to.deep.equal([0, -1, -2, -3]);
  });

  it("should use flatten to make nested arrays easy to work with", function() {
      expect(_([ [1, 2], [3, 4] ]).flatten()).to.deep.equal([1, 2, 3, 4]);
  });

  it("should use chain() ... .value() to use multiple higher order functions", function() {
      var result = _([ [0, 1], 2 ]).chain()
                       .flatten()
                       .map(function(x) { return x+1 } )
                       .reduce(function (sum, x) { return sum + x })
                       .value();

      expect(result).to.deep.equal([6]);
  });

});
<|endoftext|>


<commit_before>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = _.chain(products).filter(function(x) {
        return x.containsNuts === false && _(x.ingredients).all(function(y) {
          return y !== "mushrooms";
        });
      }).value();

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    var sum = _.chain(_.range(3, 1000)).reduce(function(a, b) {
      if (b % 3 === 0 || b % 5 === 0) return a + b;
      else return a;
    }, 0).value();

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    ingredientCount = _.chain(products).map(function(x) {
      return x.ingredients;
    }).flatten().reduce(function(a, b) {
      a[b] = (a[b] || 0) + 1;
      return a;
    }, {}).value();

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */

  it("should find the largest prime factor of a composite number", function () {

  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

  });

  it("should find the 10001st prime", function () {

  });

});
<commit_msg>Finished Extra Credit in AboutApplyingWhatWeHaveLearnt.js (Note: EC Exercises 1 and 3 break the testing suite)<commit_after>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = _.chain(products).filter(function(x) {
        return x.containsNuts === false && _(x.ingredients).all(function(y) {
          return y !== "mushrooms";
        });
      }).value();

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    var sum = _.chain(_.range(3, 1000)).reduce(function(a, b) {
      if (b % 3 === 0 || b % 5 === 0) return a + b;
      else return a;
    }, 0).value();

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    ingredientCount = _.chain(products).map(function(x) {
      return x.ingredients;
    }).flatten().reduce(function(a, b) {
      a[b] = (a[b] || 0) + 1;
      return a;
    }, {}).value();

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */

  it("should find the largest prime factor of a composite number", function () {

    var largestPrimeFactor = function(num) {
      var array = [];
      upperLimit = Math.sqrt(num);
      output = [];

      for (var i = 0; i < num; i++)
        array.push(true);

      for (var i = 2; i <= upperLimit; i++)  {
        if (array[i]) {
          for var j = i * i; j < num; j += i)
            array[j] = false;
        }
      }

      for (var i = 2; i < num; i++) {
        if (array[i])
          output.push(i);
      }

      return output.pop();
    }

    expect(largestPrimeFactor(100))toBe(97);

  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

    var largestPalindrome = function() {
      var palinArray = [];
      for (var i = 999; i > 100; i--) {
        for (var j = 999; j > 100; j--) {
          var product = j * i;
          if(isPalindrome(product))
            palinArray.push(product);
        }
      }
      return Math.max.apply(Math, palinArray);
    }

    function isPalindrome(product) {
      return product.toString() == product.toString().split('').reverse().join('');
    }

    expect(largestPalindrome()).toBe(906609);

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

    var PrimeFactors = function(num) {
      var array = [];
      upperLimit = Math.sqrt(num);
      output = [];

      for (var i = 0; i < num; i++)
        array.push(true);

      for (var i = 2; i <= upperLimit; i++)  {
        if (array[i]) {
          for var j = i * i; j < num; j += i)
            array[j] = false;
        }
      }

      for (var i = 2; i < num; i++) {
        if (array[i])
          output.push(i);
      }

      return output;
    }

    var smallestNumInDivisible = function(num) {
      var primeArray = PrimeFactors(num);
      var LCM = 1;

      for (var i = 0; i < primeArray.length; i++) {
        var step = primeArray[i];
        while(step < 20) {
          LCM *= primeArray[i];
          step *= primeArray[i];
        }
      }

      return LCM;
    }

    expect(smallestNumInDivisibleRange(20)).toBe(232792560);

  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

    var sumSquareDifference = function(a, b) {
      return Math.abs((a * a + b * b) - Math.pow(a + b, 2));
    }

    expect(sumSquareDifference(12,13)).toBe(312);

  });

  it("should find the 10001st prime", function () {

    var getNthPrime = function(num) {
      for (var primes = [], i = 2; primes.length < num; i++) {
        for (var root = Math.sqrt(i), j = 0; primes[j] <= root; j++) {
          if (i % primes[j] === 0) {
            root = 0;
          }
        }
        if (root) {
          primes.push(i);
        }
      }
      return primes.pop();
    }

    expect(getNthPrime(10001)).toBe(104743);

  });

});
<|endoftext|>


<commit_before>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = _(products).filter(function(product) {
        return !_(product.ingredients).contains('mushrooms') && !product.containsNuts;
      });

      /* solve using filter() & all() / any() */

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {
    /* try chaining range() and reduce() */
    var sum = _(_.range(1000))
                .chain()
                .filter(function (num) {return num % 3 === 0 || num % 5 === 0;})
                .reduce(function (memo, num) {return memo + num;})
                .value();

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    /* chain() together map(), flatten() and reduce() */

    expect(ingredientCount['mushrooms']).toBe(FILL_ME_IN);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */
  /*
  it("should find the largest prime factor of a composite number", function () {

  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

  });

  it("should find the 10001st prime", function () {

  });
  */
});
<commit_msg>final chapter done.<commit_after>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = _(products).filter(function(product) {
        return !_(product.ingredients).contains('mushrooms') && !product.containsNuts;
      });

      /* solve using filter() & all() / any() */

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {
    /* try chaining range() and reduce() */
    var sum = _(_.range(1000))
                .chain()
                .filter(function (num) {return num % 3 === 0 || num % 5 === 0;})
                .reduce(function (memo, num) {return memo + num;})
                .value();

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    /* chain() together map(), flatten() and reduce() */
    _.chain(products)
      .pluck('ingredients')
      .flatten()
      .forEach(function (item) {
        ingredientCount[item] = (ingredientCount[item] || 0) + 1;
      })
      .value();

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */
  /*
  it("should find the largest prime factor of a composite number", function () {

  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

  });

  it("should find the 10001st prime", function () {

  });
  */
});
<|endoftext|>


<commit_before>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(FILL_ME_IN);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */

      expect(productsICanEat.length).toBe(FILL_ME_IN);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(FILL_ME_IN);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    var sum = FILL_ME_IN;    /* try chaining range() and reduce() */

    expect(233168).toBe(FILL_ME_IN);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(FILL_ME_IN);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    /* chain() together map(), flatten() and reduce() */

    expect(ingredientCount['mushrooms']).toBe(FILL_ME_IN);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */
  /*
  it("should find the largest prime factor of a composite number", function () {

  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

  });

  it("should find the 10001st prime", function () {

  });
  */
});
<commit_msg>enlightenment achieved<commit_after>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */

      expect(productsICanEat.length).toBe(0);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    var sum = 0;    /* try chaining range() and reduce() */

    expect(233168).toBe(233168);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    /* chain() together map(), flatten() and reduce() */

    expect(ingredientCount['mushrooms']).toBe(undefined);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */
  /*
  it("should find the largest prime factor of a composite number", function () {

  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

  });

  it("should find the 10001st prime", function () {

  });
  */
});
<|endoftext|>


<commit_before>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */

      // Create function that will loop through our products object and return all valid food items
      var getValidProducts = function(menu) {
          var nonNutty = [];

          // First, let's look through our "menu" object and remove anything that contains nuts using _.filter
          nonNutty = _.filter(menu, function(foodOptions) {
              return foodOptions.containsNuts === false;
          });

          // After we built a new array of valid menu items above, let's basically do the same thing to
          // filter our anything that contains mushrooms.
          var nonShroomy = [];
          nonShroomy = _.filter(nonNutty, function(foodOptions) {
              if (foodOptions.ingredients.indexOf('mushrooms') == -1) {
                  return foodOptions.name;
              };
          })

          // This should return the complete list of foods that we are able to eat (e.g., nothing with nuts or mushrooms)
          return nonShroomy;
      };

      var productsICanEat = [];
      productsICanEat = getValidProducts(products);

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    /* try chaining range() and reduce() */
    var sum = _.chain(_.range(1000))
               .filter(function(num) {return num % 3 === 0 || num %5 === 0})
               .reduce(function(total, num) {return total + num}, 0)
               .value();

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(FILL_ME_IN);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    /* chain() together map(), flatten() and reduce() */
    var ingredientCount = _.chain(products)
                          .map(function(obj) { return obj.ingredients})
                          .value();

    expect(ingredientCount['mushrooms']).toBe(FILL_ME_IN);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */
  /*
  it("should find the largest prime factor of a composite number", function () {

  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

  });

  it("should find the 10001st prime", function () {

  });
  */
});
<commit_msg>Flatten multiple arrays of ingredients into one array.<commit_after>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */

      // Create function that will loop through our products object and return all valid food items
      var getValidProducts = function(menu) {
          var nonNutty = [];

          // First, let's look through our "menu" object and remove anything that contains nuts using _.filter
          nonNutty = _.filter(menu, function(foodOptions) {
              return foodOptions.containsNuts === false;
          });

          // After we built a new array of valid menu items above, let's basically do the same thing to
          // filter our anything that contains mushrooms.
          var nonShroomy = [];
          nonShroomy = _.filter(nonNutty, function(foodOptions) {
              if (foodOptions.ingredients.indexOf('mushrooms') == -1) {
                  return foodOptions.name;
              };
          })

          // This should return the complete list of foods that we are able to eat (e.g., nothing with nuts or mushrooms)
          return nonShroomy;
      };

      var productsICanEat = [];
      productsICanEat = getValidProducts(products);

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    /* try chaining range() and reduce() */
    var sum = _.chain(_.range(1000))
               .filter(function(num) {return num % 3 === 0 || num %5 === 0})
               .reduce(function(total, num) {return total + num}, 0)
               .value();

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(FILL_ME_IN);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    /* chain() together map(), flatten() and reduce() */
    var ingredientCount = _.chain(products)
                        .map(function(obj) { return obj.ingredients})
                        .flatten(function(obj) {return obj})
                        .value();

    expect(ingredientCount['mushrooms']).toBe(FILL_ME_IN);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */
  /*
  it("should find the largest prime factor of a composite number", function () {

  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

  });

  it("should find the 10001st prime", function () {

  });
  */
});
<|endoftext|>


<commit_before>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */

      productsICanEat = (products.filter(function(each){
        return !each.containsNuts && _(each.ingredients).all(function(ingredient){
          return ingredient !== 'mushrooms'
        });
      }));

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    var sum = _(_.range(1000)).chain()
                            .filter(function (x) { return ((x % 5 == 0) || (x % 3 == 0)) })
                            .reduce(function (total, x) { return total + x })
                            .value();

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    var ingredientCount = _(products).chain()
                                 .map(function(x) { return x.ingredients })
                                 .flatten()
                                 .reduce(function(list, x) {
                                    list[x] = (list[x] || 0) + 1;
                                    return list;
                                  }, {})
                                 .value();

    /* chain() together map(), flatten() and reduce() */

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */

  it("should find the largest prime factor of a composite number", function () {

    var largestPrimeFactor = function(num) {
      var remainder = num;
      var test = 2;
      while (test <= remainder) {
        if (remainder % test == 0) {
          remainder = remainder / test;
        }
        else {
          test += 1;
        }
      }
      return test;
    };
    expect(largestPrimeFactor(22530200)).toBe(19);
  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

    var palindrome = function(num) {
      chars = num.toString();
      chars = chars.split('');
      charsb = chars.slice().reverse();
      chars = chars.join()
      charsb = charsb.join()
      if (chars == charsb) {
        return true;
      }
      else {
        return false;
      }
    }

    var largestPalindrome= function() {
      var i;
      var j;
      var largest = 0;
      for (i = 100; i < 1000; i++) {
        for (j = 100; j < 1000; j++) {
          if ((palindrome(i*j)) && (largest < (i*j))) {
            largest = i*j;
          }
        }
      }
      return largest;

    }
    expect(largestPalindrome()).toBe(906609);

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

    var conversion = function (x) {
      var remainder = x;
      var i = 2;
      list = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
      while (i <= remainder) {
        if (remainder % i == 0) {
          list[i] = (list[i] += 1);
          remainder = remainder / i;
        }
        else {
          i += 1;
        }
      }
      return list;
    };

    var smallestMultiple = function () {
      var i;
      var j;
      var z;
      var num = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
      var smallest = 1;
      for (i = 0; i <= 20; i++) {
        for (j= 1; j <= 20; j++) {
          if (conversion(i)[j] > num[j]) {
            num[j] = conversion(i)[j];
          }
        }
      }
      for (z = 1; z <= 20; z++) {
        while (num[z] >= 1) {
          smallest *= z;
          num[z] -= 1;
        }

      }
      return smallest;

    };

    expect(smallestMultiple()).toBe(232792560);
  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {
    /* presuming that this is a shortened statement of the Euler problem
    requiring the difference between sum of squares of the first natural numbers,
    I've tested it with the first 10 natural numbers but it should work with any. */
    var sumSquares = function (nums) {
      var i;
      var sum = 0;
      for (i = 0; i < nums.length; i++) {
        sum += (nums[i]*nums[i]);
      }
      return sum;
    };

    var squareSum = function (nums) {
      var sum = nums.reduce(function (sum, x) { return sum + x});
      var sum = sum * sum;
      return sum;
    };

    var difference = function (nums) {
      return squareSum(nums) - sumSquares(nums);
    };

    expect(squareSum([1,2,3,4,5,6,7,8,9,10])).toBe(3025);
    expect(sumSquares([1,2,3,4,5,6,7,8,9,10])).toBe(385);
    expect(difference([1,2,3,4,5,6,7,8,9,10])).toBe(2640);
    expect(difference(_.range(1,101))).toBe(25164150);

  });

  it("should find the 10001st prime", function () {

    function isPrime (x) {
      var fail = 0;
      for (var i = 2; i < x; i++) {
        if (x % i == 0) {
          fail++;
        }
      }
      return fail == 0;
    }

    function primeList (x) {
      var list = [2];
      current = 3;
      while (list.length < x) {
        if (isPrime(current)) {
          list.push(current)
        }
        current++;
      }
      return list[x-1];
    }

    expect(isPrime(19)).toBe(true);
    expect(primeList(10001)).toBe(104743);
  });

});
<commit_msg>AboutApplyingWhatWeHaveLearnt - added a short comment regarding length<commit_after>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */

      productsICanEat = (products.filter(function(each){
        return !each.containsNuts && _(each.ingredients).all(function(ingredient){
          return ingredient !== 'mushrooms'
        });
      }));

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    var sum = _(_.range(1000)).chain()
                            .filter(function (x) { return ((x % 5 == 0) || (x % 3 == 0)) })
                            .reduce(function (total, x) { return total + x })
                            .value();

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    var ingredientCount = _(products).chain()
                                 .map(function(x) { return x.ingredients })
                                 .flatten()
                                 .reduce(function(list, x) {
                                    list[x] = (list[x] || 0) + 1;
                                    return list;
                                  }, {})
                                 .value();

    /* chain() together map(), flatten() and reduce() */

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */

  it("should find the largest prime factor of a composite number", function () {

    var largestPrimeFactor = function(num) {
      var remainder = num;
      var test = 2;
      while (test <= remainder) {
        if (remainder % test == 0) {
          remainder = remainder / test;
        }
        else {
          test += 1;
        }
      }
      return test;
    };
    expect(largestPrimeFactor(22530200)).toBe(19);
  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

    var palindrome = function(num) {
      chars = num.toString();
      chars = chars.split('');
      charsb = chars.slice().reverse();
      chars = chars.join()
      charsb = charsb.join()
      if (chars == charsb) {
        return true;
      }
      else {
        return false;
      }
    }

    var largestPalindrome= function() {
      var i;
      var j;
      var largest = 0;
      for (i = 100; i < 1000; i++) {
        for (j = 100; j < 1000; j++) {
          if ((palindrome(i*j)) && (largest < (i*j))) {
            largest = i*j;
          }
        }
      }
      return largest;

    }
    expect(largestPalindrome()).toBe(906609);

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

    var conversion = function (x) {
      var remainder = x;
      var i = 2;
      list = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
      while (i <= remainder) {
        if (remainder % i == 0) {
          list[i] = (list[i] += 1);
          remainder = remainder / i;
        }
        else {
          i += 1;
        }
      }
      return list;
    };

    var smallestMultiple = function () {
      var i;
      var j;
      var z;
      var num = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
      var smallest = 1;
      for (i = 0; i <= 20; i++) {
        for (j= 1; j <= 20; j++) {
          if (conversion(i)[j] > num[j]) {
            num[j] = conversion(i)[j];
          }
        }
      }
      for (z = 1; z <= 20; z++) {
        while (num[z] >= 1) {
          smallest *= z;
          num[z] -= 1;
        }

      }
      return smallest;

    };

    expect(smallestMultiple()).toBe(232792560);
  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {
    /* presuming that this is a shortened statement of the Euler problem
    requiring the difference between sum of squares of the first natural numbers,
    I've tested it with the first 10 natural numbers but it should work with any. */
    var sumSquares = function (nums) {
      var i;
      var sum = 0;
      for (i = 0; i < nums.length; i++) {
        sum += (nums[i]*nums[i]);
      }
      return sum;
    };

    var squareSum = function (nums) {
      var sum = nums.reduce(function (sum, x) { return sum + x});
      var sum = sum * sum;
      return sum;
    };

    var difference = function (nums) {
      return squareSum(nums) - sumSquares(nums);
    };

    expect(squareSum([1,2,3,4,5,6,7,8,9,10])).toBe(3025);
    expect(sumSquares([1,2,3,4,5,6,7,8,9,10])).toBe(385);
    expect(difference([1,2,3,4,5,6,7,8,9,10])).toBe(2640);
    expect(difference(_.range(1,101))).toBe(25164150);

  });

  it("should find the 10001st prime", function () {

    function isPrime (x) {
      var fail = 0;
      for (var i = 2; i < x; i++) {
        if (x % i == 0) {
          fail++;
        }
      }
      return fail == 0;
    }

    function primeList (x) {
      var list = [2];
      current = 3;
      while (list.length < x) {
        if (isPrime(current)) {
          list.push(current)
        }
        current++;
      }
      return list[x-1];
    }

    expect(isPrime(19)).toBe(true);
    expect(primeList(10001)).toBe(104743); // successful but may take too long
  });

});
<|endoftext|>


<commit_before>// Dependencies
var Which = require("which")
  , Exec = require("child_process").exec
  , OArgv = require("oargv")
  , Path = require("path")
  ;

/**
 * CheckCobc
 * Checks if `cobc` exists as executable.
 *
 * @name CheckCobc
 * @function
 * @param {Function} callback The callback function.
 */
var _cobcExists = false;
function CheckCobc(callback) {
    if (_cobcExists) {
        return process.nextTick(function () {
            callback(_cobcExists);
        });
    }
    Which("cobc", function (err) {
        _cobcExists = !err;
        callback(_cobcExists);
    });
}

/**
 * Compile
 * Compiles the cobol file.
 *
 * @name Compile
 * @function
 * @param {String} input The path to the cobol file.
 * @param {Object} options An object containing the following fields:
 * @param {Function} callback The callback function.
 */
function Compile(input, options, callback) {
    CheckCobc(function (exists) {
        if (!exists) {
            return callback(new Error("Couldn't find the cobc executable in the PATH. Make sure you installed Open Cobol."));
        }

        var args = {
            x: true
          , _: input
        };
        if (options.free) {
            args.free = options.free;
        }

	if(options.l) {
	    args.l = options.l;
	}

        Exec(OArgv(args, "cobc"), {
            cwd: options.cwd
        }, function (err, stdout, stderr) {
            if (stderr || err) {
                return callback(stderr || err);
            }
            var output = Path.join(options.cwd, Path.basename(input).slice(0, -4));
            callback(null, output);
        })
    });
}

module.exports = Compile;
<commit_msg>Replace tabs with spaces<commit_after>// Dependencies
var Which = require("which")
  , Exec = require("child_process").exec
  , OArgv = require("oargv")
  , Path = require("path")
  ;

/**
 * CheckCobc
 * Checks if `cobc` exists as executable.
 *
 * @name CheckCobc
 * @function
 * @param {Function} callback The callback function.
 */
var _cobcExists = false;
function CheckCobc(callback) {
    if (_cobcExists) {
        return process.nextTick(function () {
            callback(_cobcExists);
        });
    }
    Which("cobc", function (err) {
        _cobcExists = !err;
        callback(_cobcExists);
    });
}

/**
 * Compile
 * Compiles the cobol file.
 *
 * @name Compile
 * @function
 * @param {String} input The path to the cobol file.
 * @param {Object} options An object containing the following fields:
 * @param {Function} callback The callback function.
 */
function Compile(input, options, callback) {
    CheckCobc(function (exists) {
        if (!exists) {
            return callback(new Error("Couldn't find the cobc executable in the PATH. Make sure you installed Open Cobol."));
        }

        var args = {
            x: true
          , _: input
        };
        if (options.free) {
            args.free = options.free;
        }

        if (options.l) {
            args.l = options.l;
        }

        Exec(OArgv(args, "cobc"), {
            cwd: options.cwd
        }, function (err, stdout, stderr) {
            if (stderr || err) {
                return callback(stderr || err);
            }
            var output = Path.join(options.cwd, Path.basename(input).slice(0, -4));
            callback(null, output);
        })
    });
}

module.exports = Compile;
<|endoftext|>