<commit_before>import animate from './animate'
import each from '../../utils/each'
import nextUniqueId from '../../utils/next-unique-id'

export default function sequence(element, pristine = this.pristine) {
	const seq = this.store.sequences[element.sequence.id]
	const i = element.sequence.index

	if (seq) {
		const visible = new SequenceModel('visible', seq, this.store)
		const revealed = new SequenceModel('revealed', seq, this.store)

		seq.models = { visible, revealed }

		/**
		 * If the sequence has no revealed members,
		 * then we reveal the first visible element
		 * within that sequence.
		 *
		 * The sequence then cues a recursive call
		 * in both directions.
		 */
		if (!revealed.body.length) {
			const nextId = seq.members[visible.body[0]]
			const nextElement = this.store.elements[nextId]

			if (nextElement) {
				cue.call(this, seq, visible.body[0], -1, pristine)
				cue.call(this, seq, visible.body[0], +1, pristine)

				seq.lastReveal = visible.body[0]
				return animate.call(this, nextElement, { reveal: true, pristine })
			} else {
				return animate.call(this, element)
			}
		}

		/**
		 * Assuming we have something visible on screen
		 * already, and we need to evaluate the element
		 * that was passed in...
		 *
		 * We first check if the element should reset.
		 */
		if (!element.visible && element.revealed && element.config.reset) {
			seq.lastReset = i
			return animate.call(this, element, { reset: true })
		}

		/**
		 * If our element isn’t resetting, we check the
		 * element sequence index against the head, and
		 * then the foot of the sequence.
		 */
		if (
			!seq.headblocked &&
			i === [...revealed.head].pop() &&
			i >= [...visible.body].shift()
		) {
			cue.call(this, seq, i, -1, pristine)
			seq.lastReveal = i
			return animate.call(this, element, { reveal: true, pristine })
		}

		if (
			!seq.footblocked &&
			i === [...revealed.foot].shift() &&
			i <= [...visible.body].pop()
		) {
			cue.call(this, seq, i, +1, pristine)
			seq.lastReveal = i
			return animate.call(this, element, { reveal: true, pristine })
		}
	}
}

export function Sequence(interval) {
	this.id = nextUniqueId()
	this.interval = interval
	this.members = []
	this.models = {}
	this.headblocked = true
	this.footblocked = true
	this.lastReveal = null
	this.lastReset = null
}

function SequenceModel(prop, sequence, store) {
	this.head = [] // Elements before the body with a falsey prop.
	this.body = [] // Elements with a truthy prop.
	this.foot = [] // Elements after the body with a falsey prop.

	each(sequence.members, (id, index) => {
		const element = store.elements[id]
		if (element && element[prop]) {
			this.body.push(index)
		}
	})

	if (this.body.length) {
		each(sequence.members, (id, index) => {
			const element = store.elements[id]
			if (element && !element[prop]) {
				if (index < this.body[0]) {
					this.head.push(index)
				} else {
					this.foot.push(index)
				}
			}
		})
	}
}

function cue(seq, i, direction, pristine) {
	const blocked = ['headblocked', null, 'footblocked'][1 + direction]
	const nextId = seq.members[i + direction]
	const nextElement = this.store.elements[nextId]

	seq[blocked] = true

	setTimeout(() => {
		seq[blocked] = false
		if (nextElement) {
			sequence.call(this, nextElement, pristine)
		}
	}, seq.interval)
}
<commit_msg>instantiate sequences unblocked<commit_after>import animate from './animate'
import each from '../../utils/each'
import nextUniqueId from '../../utils/next-unique-id'

export default function sequence(element, pristine = this.pristine) {
	const seq = this.store.sequences[element.sequence.id]
	const i = element.sequence.index

	if (seq) {
		const visible = new SequenceModel('visible', seq, this.store)
		const revealed = new SequenceModel('revealed', seq, this.store)

		seq.models = { visible, revealed }

		/**
		 * If the sequence has no revealed members,
		 * then we reveal the first visible element
		 * within that sequence.
		 *
		 * The sequence then cues a recursive call
		 * in both directions.
		 */
		if (!revealed.body.length) {
			const nextId = seq.members[visible.body[0]]
			const nextElement = this.store.elements[nextId]

			if (nextElement) {
				cue.call(this, seq, visible.body[0], -1, pristine)
				cue.call(this, seq, visible.body[0], +1, pristine)

				seq.lastReveal = visible.body[0]
				return animate.call(this, nextElement, { reveal: true, pristine })
			} else {
				return animate.call(this, element)
			}
		}

		/**
		 * Assuming we have something visible on screen
		 * already, and we need to evaluate the element
		 * that was passed in...
		 *
		 * We first check if the element should reset.
		 */
		if (!element.visible && element.revealed && element.config.reset) {
			seq.lastReset = i
			return animate.call(this, element, { reset: true })
		}

		/**
		 * If our element isn’t resetting, we check the
		 * element sequence index against the head, and
		 * then the foot of the sequence.
		 */
		if (
			!seq.headblocked &&
			i === [...revealed.head].pop() &&
			i >= [...visible.body].shift()
		) {
			cue.call(this, seq, i, -1, pristine)
			seq.lastReveal = i
			return animate.call(this, element, { reveal: true, pristine })
		}

		if (
			!seq.footblocked &&
			i === [...revealed.foot].shift() &&
			i <= [...visible.body].pop()
		) {
			cue.call(this, seq, i, +1, pristine)
			seq.lastReveal = i
			return animate.call(this, element, { reveal: true, pristine })
		}
	}
}

export function Sequence(interval) {
	this.id = nextUniqueId()
	this.interval = interval
	this.members = []
	this.models = {}
	this.headblocked = false
	this.footblocked = false
	this.lastReveal = null
	this.lastReset = null
}

function SequenceModel(prop, sequence, store) {
	this.head = [] // Elements before the body with a falsey prop.
	this.body = [] // Elements with a truthy prop.
	this.foot = [] // Elements after the body with a falsey prop.

	each(sequence.members, (id, index) => {
		const element = store.elements[id]
		if (element && element[prop]) {
			this.body.push(index)
		}
	})

	if (this.body.length) {
		each(sequence.members, (id, index) => {
			const element = store.elements[id]
			if (element && !element[prop]) {
				if (index < this.body[0]) {
					this.head.push(index)
				} else {
					this.foot.push(index)
				}
			}
		})
	}
}

function cue(seq, i, direction, pristine) {
	const blocked = ['headblocked', null, 'footblocked'][1 + direction]
	const nextId = seq.members[i + direction]
	const nextElement = this.store.elements[nextId]

	seq[blocked] = true

	setTimeout(() => {
		seq[blocked] = false
		if (nextElement) {
			sequence.call(this, nextElement, pristine)
		}
	}, seq.interval)
}
<|endoftext|>


<commit_before>if (typeof define === "function" && define.amd && typeof window.jQuery === 'function')  {
    define("jquery", [], function() {
        return window.jQuery;
    });
}

define([
    '../stream',
    'jquery'
], function(Stream, jQuery) {
    'use strict';

    jQuery.fn.streamOn = function(eventName, selector) {
        return Stream.fromEmitter($(this), selector, eventName);
    };

    return jQuery;
});

<commit_msg>move empty line on end of the file<commit_after>if (typeof define === "function" && define.amd && typeof window.jQuery === 'function')  {
    define("jquery", [], function() {
        return window.jQuery;
    });
}

define([
    '../stream',
    'jquery'
], function(Stream, jQuery) {
    'use strict';

    jQuery.fn.streamOn = function(eventName, selector) {
        return Stream.fromEmitter($(this), selector, eventName);
    };

    return jQuery;
});
<|endoftext|>


<commit_before>var expect = require('chai').expect,
    rawRequestBody = require('../fixtures').requestData,
    RequestBody = require('../../lib/index.js').RequestBody,
    QueryParam = require('../../lib/index.js').QueryParam,
    PropertyList = require('../../lib/index.js').PropertyList;

describe('RequestBody', function () {
    it('should be jsonified properly', function () {
        var reqData = new RequestBody(rawRequestBody),
            jsonified = reqData.toJSON();
        expect(jsonified).to.eql(rawRequestBody);
    });

    it('should be stringified properly', function () {
        var reqData = new RequestBody(rawRequestBody),
            expectedQueryData = QueryParam.unparse(rawRequestBody.urlencoded);

        // Set the mode to URL encoded
        reqData.mode = 'urlencoded';
        expect(reqData.toString()).to.eql(expectedQueryData);
    });

    it('should support file mode', function () {
        var rawBody = {
                mode: 'formdata',
                formdata: [
                    {
                        key: 'hiya',
                        value: 'heyo'
                    },
                    {
                        key: 'alpha',
                        value: 'beta'
                    }
                ],
                raw: 'abhijitkane',
                urlencoded: [
                    {
                        key: 'haha',
                        value: 'somevalue'
                    }
                ],
                file: {
                    src: '/somewhere/in/the/file/system'
                }
            },
            reqData = new RequestBody(rawBody);
        expect(reqData.file).to.have.property('src', rawBody.file.src);
    });

    it('should convert file reference to object, if only the reference is given', function () {
        var rawBody = {
                mode: 'file',
                file: '/omg/where/is/this/file'
            },
            reqData = new RequestBody(rawBody);
        expect(reqData.file).to.have.property('src', rawBody.file);
    });

    it('should allow converting form parameters to an object', function () {
        var rawBody = {
                mode: 'formdata',
                formdata: [
                    {
                        key: 'hiya',
                        value: 'heyo'
                    },
                    {
                        key: 'alpha',
                        value: 'beta'
                    }
                ]
            },
            reqData = new RequestBody(rawBody);
        expect(reqData.formdata.toObject()).to.eql({
            hiya: 'heyo',
            alpha: 'beta'
        });
    });

    it('should work with string bodies correctly', function () {
        var body = new RequestBody('foo');
        expect(body).to.deep.include({
            mode: 'raw',
            raw: 'foo'
        });
    });

    it('should support graphql mode', function () {
        var graphql = {
                mode: 'graphql',
                graphql: {
                    query: 'query Test { hello }',
                    operationName: 'Test',
                    variables: '{"foo":"bar"}'
                }
            },
            reqData = new RequestBody(graphql);
        expect(reqData.graphql).to.eql({
            query: 'query Test { hello }',
            operationName: 'Test',
            variables: '{"foo":"bar"}'
        });
    });

    it('should handle variables object in graphql correctly', function () {
        var reqData = new RequestBody({
            mode: 'graphql',
            graphql: {
                query: 'query Test { hello }',
                operationName: 'Test',
                variables: {
                    foo: 'bar'
                }
            }
        });

        expect(reqData.graphql).to.eql({
            query: 'query Test { hello }',
            operationName: 'Test',
            variables: {
                foo: 'bar'
            }
        });
    });

    it('should reject invalid body types', function () {
        expect(new RequestBody([])).to.be.empty;
        expect(new RequestBody(2)).to.be.empty;
    });

    it('should be able to store body options in raw mode', function () {
        var body = new RequestBody({
            mode: 'raw',
            raw: 'Hello',
            options: {
                raw: {
                    contentType: 'application/json'
                }
            }
        });
        expect(body).to.have.property('options');
        expect(body.options).to.eql({
            raw: {
                contentType: 'application/json'
            }
        });
    });

    describe('.update', function () {
        it('should use the raw request body by if an invalid mode is specified', function () {
            var reqData = new RequestBody({
                mode: 'random',
                raw: 'This is supposed to be a raw body. Do not cook it.'
            });
            expect(reqData).to.deep.include({
                mode: 'raw',
                raw: 'This is supposed to be a raw body. Do not cook it.'
            });
        });

        it('should support stringified urlencoded bodies', function () {
            var reqData = new RequestBody({
                mode: 'urlencoded',
                urlencoded: 'alpha=foo&beta=bar'
            });

            expect(reqData.urlencoded.toJSON()).to.eql([
                {
                    key: 'alpha',
                    value: 'foo'
                },
                {
                    key: 'beta',
                    value: 'bar'
                }]);
        });

        it('should handle missing formdata bodies correctly', function () {
            var reqData = new RequestBody({ mode: 'formdata' });

            expect(reqData.formdata.reference).to.be.empty;
        });

        it('should allow updating to a valid body', function () {
            var body = new RequestBody();

            body.update('foo');
            expect(body).to.deep.include({
                mode: 'raw',
                raw: 'foo'
            });

            body.update({ mode: 'formdata', formdata: [{ key: 'foo', value: 'bar' }] });
            expect(body).to.have.property('mode', 'formdata');
            expect(body.formdata.toJSON()).to.eql([{ key: 'foo', value: 'bar' }]);
        });

        it('should prohibit updates to invalid bodies', function () {
            var body = new RequestBody('foo');

            expect(body).to.deep.include({
                mode: 'raw',
                raw: 'foo'
            });

            body.update([]);
            expect(body).to.deep.include({
                mode: 'raw',
                raw: 'foo'
            });

            body.update(2);
            expect(body).to.deep.include({
                mode: 'raw',
                raw: 'foo'
            });
        });

        it('should handle disabled property (true -> false) correctly', function () {
            var body = new RequestBody({ mode: 'raw', raw: 'foo', disabled: true });

            expect(body).to.have.property('disabled', true);

            body.update({ mode: 'raw', raw: 'foo', disabled: false });
            expect(body).to.have.property('disabled', false);
        });

        it('should handle disabled property (false -> true) correctly', function () {
            var body = new RequestBody({ mode: 'raw', raw: 'foo', disabled: false });
            expect(body).to.have.property('disabled', false);

            body.update({ mode: 'raw', raw: 'foo', disabled: true });
            expect(body).to.have.property('disabled', true);
        });

        it('should handle change in body Options', function () {
            var body = new RequestBody({
                mode: 'raw',
                raw: 'Hello',
                options: {
                    raw: {
                        contentType: 'application/json'
                    }
                }
            });
            body.update({
                mode: 'raw',
                raw: 'foo',
                options: {
                    raw: {
                        contentType: 'application/xml'
                    }
                }
            });

            expect(body).to.have.property('options');
            expect(body.options).to.eql({
                raw: {
                    contentType: 'application/xml'
                }
            });
        });
    });

    describe('.toString', function () {
        it('should return an empty string for formdata or files', function () {
            var rBody = new RequestBody({ mode: 'formdata' });
            expect(rBody.toString()).to.equal('');

            rBody.update({ mode: 'file' });
            expect(rBody.toString()).to.equal('');
        });

        it('should correctly stringify urlencoded bodies', function () {
            var rBody = new RequestBody({
                mode: 'urlencoded',
                urlencoded: [{ key: 'foo', value: 'bar' }]
            });

            expect(rBody.toString()).to.equal('foo=bar');
        });

        it('should handle malformed urlencoded request bodies gracefully', function () {
            var rBody = new RequestBody({ mode: 'urlencoded' });

            rBody.urlencoded = ['a', 'b']; // This ensures that there is an inbuilt fallback to .unparse
            expect(rBody.toString()).to.equal('a,b');

            rBody.urlencoded = Object.create(null); // This ensures that there is an inbuilt fallback to .unparse
            expect(rBody.toString()).to.equal('');
        });

        it('should handle raw bodies correctly', function () {
            var rBody = new RequestBody({ mode: 'raw', raw: 'Arbitrary raw request body' });

            expect(rBody.toString()).to.equal('Arbitrary raw request body');
            rBody.update({ mode: 'raw' }); // clear the request body
            expect(rBody.toString()).to.equal('');
        });

        it('should return an empty string for arbitrary request body modes', function () {
            var rBody = new RequestBody();

            rBody.mode = 'random';
            expect(rBody.toString()).to.equal('');
        });
    });

    describe('sanity', function () {
        it('should be parsed properly', function () {
            var reqData = new RequestBody(rawRequestBody);
            expect(reqData).to.be.ok;
            expect(reqData).to.deep.include({
                mode: rawRequestBody.mode,
                disabled: undefined
            });

            // Raw Request body
            expect(reqData).to.have.property('raw', rawRequestBody.raw);

            // Form data
            expect(reqData.formdata).to.be.an.instanceOf(PropertyList);
            expect(reqData.formdata.count()).to.eql(rawRequestBody.formdata.length);

            // URL Encoded parameters
            expect(reqData.urlencoded).to.be.an.instanceOf(PropertyList);
            expect(reqData.urlencoded.count()).to.eql(rawRequestBody.urlencoded.length);
        });
    });

    describe('isEmpty', function () {
        it('should return true if no request body is set', function () {
            var body = new RequestBody();
            expect(body.isEmpty()).to.be.true;
        });

        it('should return true if mode is set to raw and no data is present', function () {
            var body = new RequestBody({ mode: 'raw', raw: '' });
            expect(body.isEmpty()).to.be.true;
        });

        it('should return true if mode is formdata and no data is present', function () {
            var body = new RequestBody({ mode: 'formdata', formdata: [], raw: 'something' });
            expect(body.isEmpty()).to.be.true;
        });

        it('should return true if mode is urlencoded and no data is present', function () {
            var body = new RequestBody({ mode: 'urlencoded', formdata: [] });
            expect(body.isEmpty()).to.be.true;
        });

        it('should return false if mode is raw and data is available', function () {
            var body = new RequestBody({ mode: 'raw', raw: 'yo' });
            expect(body.isEmpty()).to.be.false;
        });

        it('should return false if mode is file and file src is available', function () {
            var body = new RequestBody({ mode: 'file', file: { src: '/somewhere/file.txt' } });
            expect(body.isEmpty()).to.be.false;
        });

        it('should return true if mode is file and file src is not available', function () {
            var body = new RequestBody({ mode: 'file' });
            expect(body.isEmpty()).to.be.true;
        });

        it('should return true if mode is file and nothing is available', function () {
            var body = new RequestBody({ mode: 'file', file: {} });
            expect(body.isEmpty()).to.be.true;
        });

        it('should return false if mode is file and file src as well as content are available', function () {
            var body = new RequestBody({ mode: 'file', file: { src: '/somewhere/file.txt',
                content: new Buffer('omgomg') } });
            expect(body.isEmpty()).to.be.false;
        });

        it('should return false if mode is file and file content is available', function () {
            var body = new RequestBody({ mode: 'file', file: { content: 'asjdhkashd' } });
            expect(body.isEmpty()).to.be.false;
        });

        it('should return false if mode is urlencoded and data is available', function () {
            var body = new RequestBody({
                mode: 'urlencoded',
                urlencoded: [{
                    key: 'haha',
                    value: 'somevalue'
                }]
            });
            expect(body.isEmpty()).to.be.false;
        });

        it('should return false if mode is formdata and data is available', function () {
            var body = new RequestBody({
                mode: 'urlencoded',
                urlencoded: [{
                    key: 'haha',
                    value: { some: 'random', javascript: 'object' } // this functionality is used in the app
                }]
            });
            expect(body.isEmpty()).to.be.false;
        });

        it('should return true if mode is graphql and nothing is available', function () {
            var body = new RequestBody({
                mode: 'graphql'
            });

            expect(body.isEmpty()).to.be.true;
        });

        it('should return false if mode is graphql and data is available', function () {
            var body = new RequestBody({
                mode: 'graphql',
                graphql: {
                    query: '{ foo }'
                }
            });

            expect(body.isEmpty()).to.be.false;
        });
    });
});
<commit_msg>Adding test for body Options change<commit_after>var expect = require('chai').expect,
    rawRequestBody = require('../fixtures').requestData,
    RequestBody = require('../../lib/index.js').RequestBody,
    QueryParam = require('../../lib/index.js').QueryParam,
    PropertyList = require('../../lib/index.js').PropertyList;

describe('RequestBody', function () {
    it('should be jsonified properly', function () {
        var reqData = new RequestBody(rawRequestBody),
            jsonified = reqData.toJSON();
        expect(jsonified).to.eql(rawRequestBody);
    });

    it('should be stringified properly', function () {
        var reqData = new RequestBody(rawRequestBody),
            expectedQueryData = QueryParam.unparse(rawRequestBody.urlencoded);

        // Set the mode to URL encoded
        reqData.mode = 'urlencoded';
        expect(reqData.toString()).to.eql(expectedQueryData);
    });

    it('should support file mode', function () {
        var rawBody = {
                mode: 'formdata',
                formdata: [
                    {
                        key: 'hiya',
                        value: 'heyo'
                    },
                    {
                        key: 'alpha',
                        value: 'beta'
                    }
                ],
                raw: 'abhijitkane',
                urlencoded: [
                    {
                        key: 'haha',
                        value: 'somevalue'
                    }
                ],
                file: {
                    src: '/somewhere/in/the/file/system'
                }
            },
            reqData = new RequestBody(rawBody);
        expect(reqData.file).to.have.property('src', rawBody.file.src);
    });

    it('should convert file reference to object, if only the reference is given', function () {
        var rawBody = {
                mode: 'file',
                file: '/omg/where/is/this/file'
            },
            reqData = new RequestBody(rawBody);
        expect(reqData.file).to.have.property('src', rawBody.file);
    });

    it('should allow converting form parameters to an object', function () {
        var rawBody = {
                mode: 'formdata',
                formdata: [
                    {
                        key: 'hiya',
                        value: 'heyo'
                    },
                    {
                        key: 'alpha',
                        value: 'beta'
                    }
                ]
            },
            reqData = new RequestBody(rawBody);
        expect(reqData.formdata.toObject()).to.eql({
            hiya: 'heyo',
            alpha: 'beta'
        });
    });

    it('should work with string bodies correctly', function () {
        var body = new RequestBody('foo');
        expect(body).to.deep.include({
            mode: 'raw',
            raw: 'foo'
        });
    });

    it('should support graphql mode', function () {
        var graphql = {
                mode: 'graphql',
                graphql: {
                    query: 'query Test { hello }',
                    operationName: 'Test',
                    variables: '{"foo":"bar"}'
                }
            },
            reqData = new RequestBody(graphql);
        expect(reqData.graphql).to.eql({
            query: 'query Test { hello }',
            operationName: 'Test',
            variables: '{"foo":"bar"}'
        });
    });

    it('should handle variables object in graphql correctly', function () {
        var reqData = new RequestBody({
            mode: 'graphql',
            graphql: {
                query: 'query Test { hello }',
                operationName: 'Test',
                variables: {
                    foo: 'bar'
                }
            }
        });

        expect(reqData.graphql).to.eql({
            query: 'query Test { hello }',
            operationName: 'Test',
            variables: {
                foo: 'bar'
            }
        });
    });

    it('should reject invalid body types', function () {
        expect(new RequestBody([])).to.be.empty;
        expect(new RequestBody(2)).to.be.empty;
    });

    it('should be able to store body options', function () {
        var body = new RequestBody({
            mode: 'raw',
            raw: 'Hello',
            options: {
                raw: {
                    contentType: 'application/json'
                }
            }
        });
        expect(body).to.have.property('options');
        expect(body.options).to.eql({
            raw: {
                contentType: 'application/json'
            }
        });
    });

    describe('.update', function () {
        it('should use the raw request body by if an invalid mode is specified', function () {
            var reqData = new RequestBody({
                mode: 'random',
                raw: 'This is supposed to be a raw body. Do not cook it.'
            });
            expect(reqData).to.deep.include({
                mode: 'raw',
                raw: 'This is supposed to be a raw body. Do not cook it.'
            });
        });

        it('should support stringified urlencoded bodies', function () {
            var reqData = new RequestBody({
                mode: 'urlencoded',
                urlencoded: 'alpha=foo&beta=bar'
            });

            expect(reqData.urlencoded.toJSON()).to.eql([
                {
                    key: 'alpha',
                    value: 'foo'
                },
                {
                    key: 'beta',
                    value: 'bar'
                }]);
        });

        it('should handle missing formdata bodies correctly', function () {
            var reqData = new RequestBody({ mode: 'formdata' });

            expect(reqData.formdata.reference).to.be.empty;
        });

        it('should allow updating to a valid body', function () {
            var body = new RequestBody();

            body.update('foo');
            expect(body).to.deep.include({
                mode: 'raw',
                raw: 'foo'
            });

            body.update({ mode: 'formdata', formdata: [{ key: 'foo', value: 'bar' }] });
            expect(body).to.have.property('mode', 'formdata');
            expect(body.formdata.toJSON()).to.eql([{ key: 'foo', value: 'bar' }]);
        });

        it('should prohibit updates to invalid bodies', function () {
            var body = new RequestBody('foo');

            expect(body).to.deep.include({
                mode: 'raw',
                raw: 'foo'
            });

            body.update([]);
            expect(body).to.deep.include({
                mode: 'raw',
                raw: 'foo'
            });

            body.update(2);
            expect(body).to.deep.include({
                mode: 'raw',
                raw: 'foo'
            });
        });

        it('should handle disabled property (true -> false) correctly', function () {
            var body = new RequestBody({ mode: 'raw', raw: 'foo', disabled: true });

            expect(body).to.have.property('disabled', true);

            body.update({ mode: 'raw', raw: 'foo', disabled: false });
            expect(body).to.have.property('disabled', false);
        });

        it('should handle disabled property (false -> true) correctly', function () {
            var body = new RequestBody({ mode: 'raw', raw: 'foo', disabled: false });
            expect(body).to.have.property('disabled', false);

            body.update({ mode: 'raw', raw: 'foo', disabled: true });
            expect(body).to.have.property('disabled', true);
        });

        it('should handle update in body Options', function () {
            var body = new RequestBody({
                mode: 'raw',
                raw: 'Hello',
                options: {
                    raw: {
                        contentType: 'application/json'
                    }
                }
            });
            body.update({
                mode: 'raw',
                raw: 'foo',
                options: {
                    raw: {
                        contentType: 'application/xml'
                    }
                }
            });

            expect(body).to.have.property('options');
            expect(body.options).to.eql({
                raw: {
                    contentType: 'application/xml'
                }
            });
        });

        it.only('should update the body Options to undefined', function () {
            var body = new RequestBody({
                mode: 'raw',
                raw: 'Hello',
                options: {
                    raw: {
                        contentType: 'application/json'
                    }
                }
            });
            body.update({
                mode: 'raw',
                raw: 'foo'
            });

            expect(body).to.have.property('options');
            expect(body.options).to.eql(undefined);
        });
    });

    describe('.toString', function () {
        it('should return an empty string for formdata or files', function () {
            var rBody = new RequestBody({ mode: 'formdata' });
            expect(rBody.toString()).to.equal('');

            rBody.update({ mode: 'file' });
            expect(rBody.toString()).to.equal('');
        });

        it('should correctly stringify urlencoded bodies', function () {
            var rBody = new RequestBody({
                mode: 'urlencoded',
                urlencoded: [{ key: 'foo', value: 'bar' }]
            });

            expect(rBody.toString()).to.equal('foo=bar');
        });

        it('should handle malformed urlencoded request bodies gracefully', function () {
            var rBody = new RequestBody({ mode: 'urlencoded' });

            rBody.urlencoded = ['a', 'b']; // This ensures that there is an inbuilt fallback to .unparse
            expect(rBody.toString()).to.equal('a,b');

            rBody.urlencoded = Object.create(null); // This ensures that there is an inbuilt fallback to .unparse
            expect(rBody.toString()).to.equal('');
        });

        it('should handle raw bodies correctly', function () {
            var rBody = new RequestBody({ mode: 'raw', raw: 'Arbitrary raw request body' });

            expect(rBody.toString()).to.equal('Arbitrary raw request body');
            rBody.update({ mode: 'raw' }); // clear the request body
            expect(rBody.toString()).to.equal('');
        });

        it('should return an empty string for arbitrary request body modes', function () {
            var rBody = new RequestBody();

            rBody.mode = 'random';
            expect(rBody.toString()).to.equal('');
        });
    });

    describe('sanity', function () {
        it('should be parsed properly', function () {
            var reqData = new RequestBody(rawRequestBody);
            expect(reqData).to.be.ok;
            expect(reqData).to.deep.include({
                mode: rawRequestBody.mode,
                disabled: undefined
            });

            // Raw Request body
            expect(reqData).to.have.property('raw', rawRequestBody.raw);

            // Form data
            expect(reqData.formdata).to.be.an.instanceOf(PropertyList);
            expect(reqData.formdata.count()).to.eql(rawRequestBody.formdata.length);

            // URL Encoded parameters
            expect(reqData.urlencoded).to.be.an.instanceOf(PropertyList);
            expect(reqData.urlencoded.count()).to.eql(rawRequestBody.urlencoded.length);
        });
    });

    describe('isEmpty', function () {
        it('should return true if no request body is set', function () {
            var body = new RequestBody();
            expect(body.isEmpty()).to.be.true;
        });

        it('should return true if mode is set to raw and no data is present', function () {
            var body = new RequestBody({ mode: 'raw', raw: '' });
            expect(body.isEmpty()).to.be.true;
        });

        it('should return true if mode is formdata and no data is present', function () {
            var body = new RequestBody({ mode: 'formdata', formdata: [], raw: 'something' });
            expect(body.isEmpty()).to.be.true;
        });

        it('should return true if mode is urlencoded and no data is present', function () {
            var body = new RequestBody({ mode: 'urlencoded', formdata: [] });
            expect(body.isEmpty()).to.be.true;
        });

        it('should return false if mode is raw and data is available', function () {
            var body = new RequestBody({ mode: 'raw', raw: 'yo' });
            expect(body.isEmpty()).to.be.false;
        });

        it('should return false if mode is file and file src is available', function () {
            var body = new RequestBody({ mode: 'file', file: { src: '/somewhere/file.txt' } });
            expect(body.isEmpty()).to.be.false;
        });

        it('should return true if mode is file and file src is not available', function () {
            var body = new RequestBody({ mode: 'file' });
            expect(body.isEmpty()).to.be.true;
        });

        it('should return true if mode is file and nothing is available', function () {
            var body = new RequestBody({ mode: 'file', file: {} });
            expect(body.isEmpty()).to.be.true;
        });

        it('should return false if mode is file and file src as well as content are available', function () {
            var body = new RequestBody({ mode: 'file', file: { src: '/somewhere/file.txt',
                content: new Buffer('omgomg') } });
            expect(body.isEmpty()).to.be.false;
        });

        it('should return false if mode is file and file content is available', function () {
            var body = new RequestBody({ mode: 'file', file: { content: 'asjdhkashd' } });
            expect(body.isEmpty()).to.be.false;
        });

        it('should return false if mode is urlencoded and data is available', function () {
            var body = new RequestBody({
                mode: 'urlencoded',
                urlencoded: [{
                    key: 'haha',
                    value: 'somevalue'
                }]
            });
            expect(body.isEmpty()).to.be.false;
        });

        it('should return false if mode is formdata and data is available', function () {
            var body = new RequestBody({
                mode: 'urlencoded',
                urlencoded: [{
                    key: 'haha',
                    value: { some: 'random', javascript: 'object' } // this functionality is used in the app
                }]
            });
            expect(body.isEmpty()).to.be.false;
        });

        it('should return true if mode is graphql and nothing is available', function () {
            var body = new RequestBody({
                mode: 'graphql'
            });

            expect(body.isEmpty()).to.be.true;
        });

        it('should return false if mode is graphql and data is available', function () {
            var body = new RequestBody({
                mode: 'graphql',
                graphql: {
                    query: '{ foo }'
                }
            });

            expect(body.isEmpty()).to.be.false;
        });
    });
});
<|endoftext|>


<commit_before>const routeHelper = require('../../helpers/routes/route-helper')
const supertest = require('supertest')
const expect = require('chai').expect
const proxyquire = require('proxyquire')
const claimStatusEnum = require('../../../app/constants/claim-status-enum')
const sinon = require('sinon')
require('sinon-bluebird')

var getClaimsListAndCount
var displayHelperStub
var authorisation
var isCaseworkerStub

const RETURNED_CLAIM = {
  Reference: 'A123456',
  FirstName: 'Joe',
  LastName: 'Bloggs',
  DateSubmitted: '2016-11-29T00:00:00.000Z',
  ClaimType: 'first-time',
  ClaimId: 1,
  DateSubmittedFormatted: '28-11-2016 00:00',
  Name: 'Joe Bloggs'
}

describe('routes/index', function () {
  var app

  beforeEach(function () {
    isCaseworkerStub = sinon.stub()
    authorisation = { isCaseworker: isCaseworkerStub }
    getClaimsListAndCount = sinon.stub()
    displayHelperStub = sinon.stub({ 'getClaimTypeDisplayName': function () {} })
    displayHelperStub.getClaimTypeDisplayName.returns('First time')

    var route = proxyquire('../../../app/routes/index', {
      '../services/authorisation': authorisation,
      '../services/data/get-claim-list-and-count': getClaimsListAndCount,
      '../views/helpers/display-helper': displayHelperStub
    })

    app = routeHelper.buildApp(route)
  })

  describe('GET /', function () {
    it('should respond with a 200', function () {
      return supertest(app)
        .get('/')
        .expect(200)
        .expect(function () {
          expect(isCaseworkerStub.calledOnce).to.be.true
        })
    })
  })

  describe('GET /claims/:status', function () {
    it('should respond with a 200', function () {
      getClaimsListAndCount.resolves({claims: [RETURNED_CLAIM], total: {Count: 0}})

      return supertest(app)
        .get('/claims/TEST?draw=1&start=0&length=10')
        .expect(200)
        .expect(function (response) {
          expect(isCaseworkerStub.calledOnce).to.be.true
          expect(getClaimsListAndCount.calledWith('TEST', false, 0, 10)).to.be.true
          expect(response.body.recordsTotal).to.equal(0)
          expect(response.body.claims[0].ClaimTypeDisplayName).to.equal('First time')
        })
    })

    it('should call for advance claims when status is ADVANCE', function () {
      getClaimsListAndCount.resolves({claims: [RETURNED_CLAIM], total: {Count: 0}})

      return supertest(app)
        .get('/claims/ADVANCE?draw=1&start=0&length=10')
        .expect(200)
        .expect(function (response) {
          expect(getClaimsListAndCount.calledWith(claimStatusEnum.NEW.value, true, 0, 10)).to.be.true
        })
    })

    it('should call for approved advance claims when status is ADVANCE-APPROVED', function () {
      getClaimsListAndCount.resolves({claims: [RETURNED_CLAIM], total: {Count: 0}})

      return supertest(app)
        .get('/claims/ADVANCE-APPROVED?draw=1&start=0&length=10')
        .expect(200)
        .expect(function (response) {
          expect(getClaimsListAndCount.calledWith(claimStatusEnum.APPROVED.value, true, 0, 10)).to.be.true
        })
    })

    it('should call for updated advance claims when status is ADVANCE-UPDATED', function () {
      getClaimsListAndCount.resolves({claims: [RETURNED_CLAIM], total: {Count: 0}})

      return supertest(app)
        .get('/claims/ADVANCE-UPDATED?draw=1&start=0&length=10')
        .expect(200)
        .expect(function (response) {
          expect(getClaimsListAndCount.calledWith(claimStatusEnum.UPDATED.value, true, 0, 10)).to.be.true
        })
    })

    it('should respond with a 500 promise rejects', function () {
      getClaimsListAndCount.rejects()
      return supertest(app)
        .get('/claims/TEST?draw=1&start=0&length=10')
        .expect(500)
    })
  })
})
<commit_msg>APVS0229: Fixing unit tests<commit_after>const routeHelper = require('../../helpers/routes/route-helper')
const supertest = require('supertest')
const expect = require('chai').expect
const proxyquire = require('proxyquire')
const claimStatusEnum = require('../../../app/constants/claim-status-enum')
const sinon = require('sinon')
require('sinon-bluebird')

var getClaimsListAndCount
var displayHelperStub
var authorisation
var isCaseworkerStub

const RETURNED_CLAIM = {
  Reference: 'A123456',
  FirstName: 'Joe',
  LastName: 'Bloggs',
  DateSubmitted: '2016-11-29T00:00:00.000Z',
  ClaimType: 'first-time',
  ClaimId: 1,
  DateSubmittedFormatted: '28-11-2016 00:00',
  Name: 'Joe Bloggs'
}

describe('routes/index', function () {
  var app

  beforeEach(function () {
    isCaseworkerStub = sinon.stub()
    authorisation = { isCaseworker: isCaseworkerStub }
    getClaimsListAndCount = sinon.stub()
    displayHelperStub = sinon.stub({ 'getClaimTypeDisplayName': function () {} })
    displayHelperStub.getClaimTypeDisplayName.returns('First time')

    var route = proxyquire('../../../app/routes/index', {
      '../services/authorisation': authorisation,
      '../services/data/get-claim-list-and-count': getClaimsListAndCount,
      '../views/helpers/display-helper': displayHelperStub
    })

    app = routeHelper.buildApp(route)
  })

  describe('GET /', function () {
    it('should respond with a 200', function () {
      return supertest(app)
        .get('/')
        .expect(200)
        .expect(function () {
          expect(isCaseworkerStub.calledOnce).to.be.true
        })
    })
  })

  describe('GET /claims/:status', function () {
    it('should respond with a 200', function () {
      getClaimsListAndCount.resolves({claims: [RETURNED_CLAIM], total: {Count: 0}})

      return supertest(app)
        .get('/claims/TEST?draw=1&start=0&length=10')
        .expect(200)
        .expect(function (response) {
          expect(isCaseworkerStub.calledOnce).to.be.true
          expect(getClaimsListAndCount.calledWith('TEST', false, 0, 10)).to.be.true
          expect(response.body.recordsTotal).to.equal(0)
          expect(response.body.claims[0].ClaimTypeDisplayName).to.equal('First time')
        })
    })

    it('should call for advance claims when status is ADVANCE', function () {
      getClaimsListAndCount.resolves({claims: [RETURNED_CLAIM], total: {Count: 0}})

      return supertest(app)
        .get('/claims/ADVANCE?draw=1&start=0&length=10')
        .expect(200)
        .expect(function (response) {
          expect(getClaimsListAndCount.calledWith(claimStatusEnum.NEW.value, true, 0, 10)).to.be.true
        })
    })

    it('should call for approved advance claims when status is ADVANCE-APPROVED', function () {
      getClaimsListAndCount.resolves({claims: [RETURNED_CLAIM], total: {Count: 0}})

      return supertest(app)
        .get('/claims/ADVANCE-APPROVED?draw=1&start=0&length=10')
        .expect(200)
        .expect(function (response) {
          expect(getClaimsListAndCount.calledWith([claimStatusEnum.APPROVED.value, claimStatusEnum.REQUEST_INFORMATION.value], true, 0, 10)).to.be.true
        })
    })

    it('should call for updated advance claims when status is ADVANCE-UPDATED', function () {
      getClaimsListAndCount.resolves({claims: [RETURNED_CLAIM], total: {Count: 0}})

      return supertest(app)
        .get('/claims/ADVANCE-UPDATED?draw=1&start=0&length=10')
        .expect(200)
        .expect(function (response) {
          expect(getClaimsListAndCount.calledWith(claimStatusEnum.UPDATED.value, true, 0, 10)).to.be.true
        })
    })

    it('should respond with a 500 promise rejects', function () {
      getClaimsListAndCount.rejects()
      return supertest(app)
        .get('/claims/TEST?draw=1&start=0&length=10')
        .expect(500)
    })
  })
})
<|endoftext|>


<commit_before><commit_msg>Delete eventParser.js<commit_after><|endoftext|>


<commit_before>function fuzzySearch(names,query){
    var rQuery = "";
    var retArray = [];

    //Prepare regex and keys from query string
    rQuery = "\\b"; //"pineapple","custard apple","apsple","apple"  not taken into account
    for(var i=0;i<query.length;i++){
        rQuery += "(.*)" + query[i].replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
    }
    rQuery+="(.*)";

    //Prepare regex...
    var regex = new RegExp(rQuery,"i");

    //Loop through names in dictionary
    for(var nameIndex in names){
        var name = names[nameIndex];
        var match;
        if((match = regex.exec(name)) != null){
            var firstMatch = match[1];
            var lastMatch = match[match.length-1];

            //nScore: inverted score
            //If query is the first part of name then nScore = 0 else nScore = 0.1
            //nScore == 0.1 to distinguish between "apsple" and "pineapple" while searching for "apple".
            //In this case we decided that "pineapple" should be a better match.
            var nScore = firstMatch.length>0?0.1:0;
            if(lastMatch.length>0) nScore+=0.1;

            //Add to inverted score if character before match is a letter/digit.
            //Because we decided that "pineapple" should score worse than "custard apple"
            //Ignore if firstCharacter is start of string. Otherwise this applies to "apple" inadvertantly.
            // 2nd line of code is the same but for "applepine" (word after first word)
            if(firstMatch.length>0 && /\w/.exec(firstMatch[firstMatch.length-1])) nScore+=0.2;
            if(lastMatch.length>0 && /\w/.exec(lastMatch[0])) nScore+=0.1;

            //Loop through remaining submatches and add length of submatches to inverted score.
            //These are characters in between the query characters I.E.
            //a(.*)p(.*)p(.*)l(.*)e

            //Search "test" matches "tempest" more than "troubleshoot"
            for(i=2; i<match.length-1; i++){
                var length = match[i].length;
                if(length>0)
                    nScore += 2+length;
            }

            //Score inversely proportional to nScore of gaps between letters
            var score = 1 / (1+nScore);

            //If name matches regex, push it to the return array
            //Default score of 1 for ease of multiplying score to
            // promote frequently matched names.
            retArray.push({name:name,score:score});
        }
    }

    //Return fuzzy results
    return sortMatches(retArray);
}

function sortMatches(matches){
    return matches.sort(function(a,b){
        return b.score-a.score;
    });
}

function searchTree(tree,query){
    var rQuery = "";
    var retArray = [];

    rQuery = "\\b";
    for(var i=0;i<query.length;i++){
        rQuery += "(.*)" + query[i].replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
    }
    rQuery+="(.*)";

    //Prepare regex...
    var regex = new RegExp(rQuery,"i");

    //Loop through files in tree
    tree.each(function(file){
        var name = file.n;
        var match;
        if((match = regex.exec(name)) != null){
            var firstMatch = match[1];
            var lastMatch = match[match.length-1];

            //nScore: inverted score
            //If query is the first part of name then nScore = 0 else nScore = 0.1
            //nScore == 0.1 to distinguish between "apple" and "pineapple" while searching for "apple".
            //In this case we decided that "pineapple" should be a better match.
            var nScore = firstMatch.length>0?0.1:0;
            if(lastMatch.length>0) nScore+=0.1;

            //Add to inverted score if character before match is a letter/digit.
            //Because we decided that "pineapple" should score worse than "custard apple"
            //Ignore if firstCharacter is start of string. Otherwise this applies to "apple" inadvertantly.
            if(firstMatch.length>0 && /\w/.exec(firstMatch[firstMatch.length-1])) nScore+=0.1;
            if(lastMatch.length>0 && /\w/.exec(lastMatch[0])) nScore+=0.1;

            //Loop through remaining submatches and add length of submatches to inverted score.
            //These are characters in between the query characters I.E.
            //a(.*)p(.*)p(.*)l(.*)e
            for(i=2; i<match.length-1; i++){
                console.log(match);
                var length = match[i].length;
                if(length>0)
                    nScore += 2+length;
            }

            //Score inversely proportional to nScore of gaps between letters
            var score = 1 / (1+nScore);

            //If name matches regex, push it to the return array
            //Default score of 1 for ease of multiplying score to
            // promote frequently matched names.
            retArray.push({name:name,score:score});
        }
    });

    //Return fuzzy results
    return sortMatches(retArray);
}

function sortMatches(matches){
    return matches.sort(function(a,b){
        return b.score-a.score;
    });
}<commit_msg>Readme sturf<commit_after>function fuzzySearch(names,query){
    var rQuery = "";
    var retArray = [];

    //Prepare regex and keys from query string
    rQuery = "\\b"; //"pineapple","custard apple","apsple","apple"  not taken into account
    for(var i=0;i<query.length;i++){
        rQuery += "(.*)" + query[i].replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
    }
    rQuery+="(.*)";

    //Prepare regex...
    var regex = new RegExp(rQuery,"i");

    //Loop through names in dictionary
    for(var nameIndex in names){
        var name = names[nameIndex];
        var match;
        if((match = regex.exec(name)) != null){
            var firstMatch = match[1];
            var lastMatch = match[match.length-1];

            //nScore: inverted score
            //If query is the first part of name then nScore = 0 else nScore = 0.1
            //nScore == 0.1 to distinguish between "apsple" and "pineapple" while searching for "apple".
            //In this case we decided that "pineapple" should be a better match.
            var nScore = firstMatch.length>0?0.1:0;
            if(lastMatch.length>0) nScore+=0.1;

            //Add to inverted score if character before match is a letter/digit.
            //Because we decided that "pineapple" should score worse than "custard apple"
            //Ignore if firstCharacter is start of string. Otherwise this applies to "apple" inadvertantly.
            // 2nd line of code is the same but for "applepine" (word after first word)
            if(firstMatch.length>0 && /\w/.exec(firstMatch[firstMatch.length-1])) nScore+=0.2;
            if(lastMatch.length>0 && /\w/.exec(lastMatch[0])) nScore+=0.1;

            //Loop through remaining submatches and add length of submatches to inverted score.
            //These are characters in between the query characters I.E.
            //a(.*)p(.*)p(.*)l(.*)e

            //Search "test" matches "tempest" more than "troubleshoot"
            for(i=2; i<match.length-1; i++){
                var length = match[i].length;
                if(length>0)
                    nScore += 2+length;
            }

            //Score inversely proportional to nScore of gaps between letters
            var score = 1 / (1+nScore);

            //If name matches regex, push it to the return array
            //Default score of 1 for ease of multiplying score to
            // promote frequently matched names.
            retArray.push({name:name,score:score});
        }
    }

    //Return fuzzy results
    return sortMatches(retArray);
}

function sortMatches(matches){
    return matches.sort(function(a,b){
        return b.score-a.score;
    });
}

function searchTree(tree,query){
    var rQuery = "";
    var retArray = [];

    rQuery = "\\b";
    for(var i=0;i<query.length;i++){
        var escChar = query[i].replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
        rQuery += "([^"+escChar+"]*)" + escChar;
    }
    rQuery+="(.*)";

    //Prepare regex...
    var regex = new RegExp(rQuery,"i");

    //Loop through files in tree
    tree.each(function(file){
        var name = file.n;
        var match;
        if((match = regex.exec(name)) != null){
            var firstMatch = match[1];
            var lastMatch = match[match.length-1];

            //nScore: inverted score
            //If query is the first part of name then nScore = 0 else nScore = 0.1
            //nScore == 0.1 to distinguish between "apple" and "pineapple" while searching for "apple".
            //In this case we decided that "pineapple" should be a better match.
            var nScore = firstMatch.length>0?0.1:0;
            if(lastMatch.length>0) nScore+=0.1;

            //Add to inverted score if character before match is a letter/digit.
            //Because we decided that "pineapple" should score worse than "custard apple"
            //Ignore if firstCharacter is start of string. Otherwise this applies to "apple" inadvertantly.
            if(firstMatch.length>0 && /\w/.exec(firstMatch[firstMatch.length-1])) nScore+=0.1;
            if(lastMatch.length>0 && /\w/.exec(lastMatch[0])) nScore+=0.1;

            //Loop through remaining submatches and add length of submatches to inverted score.
            //These are characters in between the query characters I.E.
            //a(.*)p(.*)p(.*)l(.*)e
            for(i=2; i<match.length-1; i++){
                var length = match[i].length;
                if(length>0)
                    nScore += 2+length;
            }

            nScore += (name.length-query.length)/1000;

            //Score inversely proportional to nScore of gaps between letters
            var score = 1 / (1+nScore);

            //If name matches regex, push it to the return array
            //Default score of 1 for ease of multiplying score to
            // promote frequently matched names.
            retArray.push({name:name,score:score});
        }
    });

    //Return fuzzy results
    return sortMatches(retArray);
}

function sortMatches(matches){
    return matches.sort(function(a,b){
        return b.score-a.score;
    });
}

function searchTreeAdvanced(tree,query){
    var rQuery = "";
    var retArray = [];

    rQuery = "\\b";
    for(var i=0;i<query.length;i++){
        var escChar = query[i].replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
        rQuery += "([^"+escChar+"]*)" + escChar;
    }
    rQuery+="(.*)";

    //Prepare regex...
    var regex = new RegExp(rQuery,"i");

    //Loop through files in tree
    tree.each(function(file){
        var name = file.n;
        var match;
        if((match = regex.exec(name)) != null){
            var firstMatch = match[1];
            var lastMatch = match[match.length-1];

            //nScore: inverted score
            //If query is the first part of name then nScore = 0 else nScore = 0.1
            //nScore == 0.1 to distinguish between "apple" and "pineapple" while searching for "apple".
            //In this case we decided that "pineapple" should be a better match.
            var nScore = firstMatch.length>0?0.1:0;
            if(lastMatch.length>0) nScore+=0.1;

            //Add to inverted score if character before match is a letter/digit.
            //Because we decided that "pineapple" should score worse than "custard apple"
            //Ignore if firstCharacter is start of string. Otherwise this applies to "apple" inadvertantly.
            if(firstMatch.length>0 && /\w/.exec(firstMatch[firstMatch.length-1])) nScore+=0.1;
            if(lastMatch.length>0 && /\w/.exec(lastMatch[0])) nScore+=0.1;

            //Loop through remaining submatches and add length of submatches to inverted score.
            //These are characters in between the query characters I.E.
            //a(.*)p(.*)p(.*)l(.*)e
            for(i=2; i<match.length-1; i++){
                var length = match[i].length;
                if(length>0)
                    nScore += 2+length;
            }

            nScore += (name.length-query.length)/1000;

            //Score inversely proportional to nScore of gaps between letters
            var score = 1 / (1+nScore);

            //If name matches regex, push it to the return array
            //Default score of 1 for ease of multiplying score to
            // promote frequently matched names.
            retArray.push({name:name,score:score});
        }
    });

    //Return fuzzy results
    return sortMatches(retArray);
}<|endoftext|>


<commit_before>var expect = require('expect.js');
var mockSpawn = require('mock-spawn');
var sinon = require('sinon');

var mockery = require('mockery');

describe('executeCredential', function () {
    var mySpawn;
    var feed;

    var executeCredential;
    var libPath = '../../lib/util/executeCredential';

    beforeEach(function () {
        mySpawn = mockSpawn(false);
        feed = sinon.stub();

        mockery.enable({
            useCleanCache: true,
            warnOnUnregistered: false
        });
        mockery.registerMock('child_process', { spawn: mySpawn });
        mockery.registerMock('../util/feed', feed);
        mockery.registerAllowable(libPath, true);
        executeCredential = require(libPath);
    });

    afterEach(function() {
        mockery.deregisterAll();
        mockery.resetCache();
        mockery.disable();
    });

    it('should call git credential when called', function (done) {
        mySpawn.sequence.add(mySpawn.simple(0, '\n'));

        executeCredential(['bar1', 'bar2'], function(err, data) {
            expect(err).to.be(null);
            expect(data).to.eql({});

            var call = mySpawn.calls[0];
            expect(call.command).to.be('git');
            expect(call.args).to.eql(['credential', 'bar1', 'bar2']);

            done();
        }, '');
    });

    it('should call git credential when called with input data', function (done) {
        var testObject = {
            foo: 'bar',
            foo2: 'bar2',
            foo3: 'bar3',
            foo4: ''
        };

        var testFeed = 'foo=bar\n\
foo2=bar2\n\
foo3=bar3\n\
\n';

        mySpawn.sequence.add(mySpawn.simple(0, '\n'));
        feed.returns(testFeed);

        executeCredential(['bar1', 'bar2'], function(err, data) {
            expect(err).to.be(null);
            expect(data).to.eql({});

            // No way to verify the stdin part of the spawn call.
            var call = mySpawn.calls[0];
            expect(call.command).to.be('git');
            expect(call.args).to.eql(['credential', 'bar1', 'bar2']);

            expect(feed.called).to.be(true);
            expect(feed.args[0][0]).to.be(testObject);

            done();
        }, testObject);
    });
});
<commit_msg>Added test for silent/detached option.<commit_after>var expect = require('expect.js');
var mockSpawn = require('mock-spawn');
var sinon = require('sinon');

var mockery = require('mockery');

describe('executeCredential', function () {
    var mySpawn;
    var feed;

    var executeCredential;
    var libPath = '../../lib/util/executeCredential';

    beforeEach(function () {
        mySpawn = mockSpawn(false);
        feed = sinon.stub();

        mockery.enable({
            useCleanCache: true,
            warnOnUnregistered: false
        });
        mockery.registerMock('child_process', { spawn: mySpawn });
        mockery.registerMock('../util/feed', feed);
        mockery.registerAllowable(libPath, true);
        executeCredential = require(libPath);
    });

    afterEach(function() {
        mockery.deregisterAll();
        mockery.resetCache();
        mockery.disable();
    });

    it('should call git credential when called', function (done) {
        mySpawn.sequence.add(mySpawn.simple(0, '\n'));

        executeCredential(['bar1', 'bar2'], function(err, data) {
            expect(err).to.be(null);
            expect(data).to.eql({});

            var call = mySpawn.calls[0];
            expect(call.command).to.be('git');
            expect(call.args).to.eql(['credential', 'bar1', 'bar2']);
            expect(call.opts.detached).to.be(false);

            done();
        }, '');
    });

    it('should use the silent option true', function (done) {
        mySpawn.sequence.add(mySpawn.simple(0, '\n'));

        executeCredential(['bar1', 'bar2'], function(err, data) {
            expect(err).to.be(null);
            expect(data).to.eql({});

            var call = mySpawn.calls[0];
            expect(call.command).to.be('git');
            expect(call.args).to.eql(['credential', 'bar1', 'bar2']);
            expect(call.opts.detached).to.be(true);

            done();
        }, '', {
            silent: true
        });
    });

    it('should use the silent option false', function (done) {
        mySpawn.sequence.add(mySpawn.simple(0, '\n'));

        executeCredential(['bar1', 'bar2'], function(err, data) {
            expect(err).to.be(null);
            expect(data).to.eql({});

            var call = mySpawn.calls[0];
            expect(call.command).to.be('git');
            expect(call.args).to.eql(['credential', 'bar1', 'bar2']);
            expect(call.opts.detached).to.be(false);

            done();
        }, '', {
            silent: false
        });
    });

    it('should call git credential when called with input data', function (done) {
        var testObject = {
            foo: 'bar',
            foo2: 'bar2',
            foo3: 'bar3',
            foo4: ''
        };

        var testFeed = 'foo=bar\n\
foo2=bar2\n\
foo3=bar3\n\
\n';

        mySpawn.sequence.add(mySpawn.simple(0, '\n'));
        feed.returns(testFeed);

        executeCredential(['bar1', 'bar2'], function(err, data) {
            expect(err).to.be(null);
            expect(data).to.eql({});

            // No way to verify the stdin part of the spawn call.
            var call = mySpawn.calls[0];
            expect(call.command).to.be('git');
            expect(call.args).to.eql(['credential', 'bar1', 'bar2']);

            expect(feed.called).to.be(true);
            expect(feed.args[0][0]).to.be(testObject);

            done();
        }, testObject);
    });
});
<|endoftext|>


<commit_before>import classNames from 'classnames';
import {Link} from 'react-router';
var React = require('react');

import Cluster from '../utils/Cluster';
var EventTypes = require('../constants/EventTypes');
import Framework from '../structs/Framework';
import HealthBar from './HealthBar';
import Icon from './Icon';
var MarathonStore = require('../stores/MarathonStore');
import NestedServiceLinks from '../components/NestedServiceLinks';
var ResourceTableUtil = require('../utils/ResourceTableUtil');
var ServiceTableHeaderLabels = require('../constants/ServiceTableHeaderLabels');
import ServiceTableUtil from '../utils/ServiceTableUtil';
import ServiceTree from '../structs/ServiceTree';
import StringUtil from '../utils/StringUtil';
import {Table} from 'reactjs-components';
import TableUtil from '../utils/TableUtil';
var Units = require('../utils/Units');

const StatusMapping = {
  'Running': 'running-state'
};

var ServicesTable = React.createClass({

  displayName: 'ServicesTable',

  defaultProps: {
    isFiltered: false
  },

  propTypes: {
    isFiltered: React.PropTypes.bool,
    services: React.PropTypes.array.isRequired
  },

  componentDidMount: function () {
    MarathonStore.addChangeListener(
      EventTypes.MARATHON_APPS_CHANGE,
      this.onMarathonAppsChange
    );
  },

  componentWillUnmount: function () {
    MarathonStore.removeChangeListener(
      EventTypes.MARATHON_APPS_CHANGE,
      this.onMarathonAppsChange
    );
  },

  getDefaultProps: function () {
    return {
      services: []
    };
  },

  getOpenInNewWindowLink(service) {
    if (!(service instanceof Framework) || !service.getWebURL()) {
      return null;
    }

    return (

        <Icon
          color="white"
          className="icon-margin-left icon-margin-left-wide"
          family="mini"
          id="open-external"
          size="mini" />

    );
  },

  onMarathonAppsChange: function () {
    this.forceUpdate();
  },

  getServiceLink: function (service) {
    const id = encodeURIComponent(service.getId());

    if (this.props.isFiltered) {
      return (
        <NestedServiceLinks
          serviceID={id}
          className="service-breadcrumb"
          majorLinkClassName="service-breadcrumb-service-id"
          minorLinkWrapperClassName="service-breadcrumb-crumb" />
      );
    }

    return (
      <Link to="services-detail"
        className="headline table-cell-value flex-box flex-box-col"
        params={{id}}>

          {service.getName()}

      </Link>
    );
  },

  renderHeadline: function (prop, service) {
    const id = encodeURIComponent(service.getId());
    let itemImage = null;

    if (service instanceof ServiceTree) {
      // Get serviceTree image/icon
      itemImage = (
        <Icon
          className="icon-margin-right inverse"
          color="grey"
          id="folder"
          size="small"
          family="small" />
      );
    }

    if (service instanceof Framework) {
      // Get framework image/icon
      itemImage = (

      );
    }

    return (

        <Link to="services-detail"
          className="table-cell-icon"
          params={{id}}>
          {itemImage}
        </Link>
        {this.getServiceLink(service)}
        {this.getOpenInNewWindowLink(service)}

    );
  },

  renderStatus: function (prop, service) {
    let instanceCount = service.getInstancesCount();
    let serviceStatus = service.getStatus();
    let serviceStatusClassSet = StatusMapping[serviceStatus] || '';
    let taskSummary = service.getTasksSummary();
    let {tasksRunning} = taskSummary;

    let text = ` (${tasksRunning} ${StringUtil.pluralize('Task', tasksRunning)})`;
    if (tasksRunning !== instanceCount) {
      text = ` (${tasksRunning} of ${instanceCount} Tasks)`;
    }

    return (

          <HealthBar tasksSummary={taskSummary} instancesCount={instanceCount} />

          {serviceStatus}
          {text}

    );
  },

  renderStats: function (prop, service) {
    return (

        {Units.formatResource(prop, service.getResources()[prop])}

    );
  },

  renderStatsHeading: function (prop, sortBy, row) {
    let isHeader = row == null;

    return classNames('flush-left text-align-right hidden-mini hidden-small', {
      'highlight': prop === sortBy.prop,
      'clickable': isHeader
    });
  },

  getColumns: function () {
    let className = ResourceTableUtil.getClassName;
    let heading = ResourceTableUtil.renderHeading(ServiceTableHeaderLabels);

    return [
      {
        className,
        headerClassName: className,
        prop: 'name',
        render: this.renderHeadline,
        sortable: true,
        sortFunction: ServiceTableUtil.propCompareFunctionFactory,
        heading
      },
      {
        className,
        headerClassName: className,
        prop: 'status',
        render: this.renderStatus,
        sortable: true,
        sortFunction: ServiceTableUtil.propCompareFunctionFactory,
        heading
      },
      {
        className: this.renderStatsHeading,
        headerClassName: this.renderStatsHeading,
        prop: 'cpus',
        render: this.renderStats,
        sortable: true,
        sortFunction: ServiceTableUtil.propCompareFunctionFactory,
        heading
      },
      {
        className: this.renderStatsHeading,
        headerClassName: this.renderStatsHeading,
        prop: 'mem',
        render: this.renderStats,
        sortable: true,
        sortFunction: ServiceTableUtil.propCompareFunctionFactory,
        heading
      },
      {
        className: this.renderStatsHeading,
        headerClassName: this.renderStatsHeading,
        prop: 'disk',
        render: this.renderStats,
        sortable: true,
        sortFunction: ServiceTableUtil.propCompareFunctionFactory,
        heading
      }
    ];
  },

  getColGroup: function () {
    return (
      <colgroup>
        <col />
        <col className="status-bar-column"/>
        <col className="hidden-mini hidden-small" style={{width: '85px'}} />
        <col className="hidden-mini hidden-small" style={{width: '75px'}} />
        <col className="hidden-mini hidden-small" style={{width: '85px'}} />
      </colgroup>
    );
  },

  render: function () {
    return (

    );
  }
});

module.exports = ServicesTable;
<commit_msg>Shorten headline table cell on filter<commit_after>import classNames from 'classnames';
import {Link} from 'react-router';
var React = require('react');

import Cluster from '../utils/Cluster';
var EventTypes = require('../constants/EventTypes');
import Framework from '../structs/Framework';
import HealthBar from './HealthBar';
import Icon from './Icon';
var MarathonStore = require('../stores/MarathonStore');
import NestedServiceLinks from '../components/NestedServiceLinks';
var ResourceTableUtil = require('../utils/ResourceTableUtil');
var ServiceTableHeaderLabels = require('../constants/ServiceTableHeaderLabels');
import ServiceTableUtil from '../utils/ServiceTableUtil';
import ServiceTree from '../structs/ServiceTree';
import StringUtil from '../utils/StringUtil';
import {Table} from 'reactjs-components';
import TableUtil from '../utils/TableUtil';
var Units = require('../utils/Units');

const StatusMapping = {
  'Running': 'running-state'
};

var ServicesTable = React.createClass({

  displayName: 'ServicesTable',

  defaultProps: {
    isFiltered: false
  },

  propTypes: {
    isFiltered: React.PropTypes.bool,
    services: React.PropTypes.array.isRequired
  },

  componentDidMount: function () {
    MarathonStore.addChangeListener(
      EventTypes.MARATHON_APPS_CHANGE,
      this.onMarathonAppsChange
    );
  },

  componentWillUnmount: function () {
    MarathonStore.removeChangeListener(
      EventTypes.MARATHON_APPS_CHANGE,
      this.onMarathonAppsChange
    );
  },

  getDefaultProps: function () {
    return {
      services: []
    };
  },

  getOpenInNewWindowLink(service) {
    if (!(service instanceof Framework) || !service.getWebURL()) {
      return null;
    }

    return (

        <Icon
          color="white"
          className="icon-margin-left icon-margin-left-wide"
          family="mini"
          id="open-external"
          size="mini" />

    );
  },

  onMarathonAppsChange: function () {
    this.forceUpdate();
  },

  getServiceLink: function (service) {
    const id = encodeURIComponent(service.getId());

    if (this.props.isFiltered) {
      return (
        <NestedServiceLinks
          serviceID={id}
          className="service-breadcrumb"
          majorLinkClassName="service-breadcrumb-service-id"
          minorLinkWrapperClassName="service-breadcrumb-crumb" />
      );
    }

    return (
      <Link to="services-detail"
        className="headline table-cell-value flex-box flex-box-col"
        params={{id}}>

          {service.getName()}

      </Link>
    );
  },

  renderHeadline: function (prop, service) {
    const id = encodeURIComponent(service.getId());
    let itemImage = null;

    if (service instanceof ServiceTree) {
      // Get serviceTree image/icon
      itemImage = (
        <Icon
          className="icon-margin-right inverse"
          color="grey"
          id="folder"
          size="small"
          family="small" />
      );
    }

    if (service instanceof Framework) {
      // Get framework image/icon
      itemImage = (

      );
    }

    return (

        <Link to="services-detail"
          className="table-cell-icon"
          params={{id}}>
          {itemImage}
        </Link>
        {this.getServiceLink(service)}
        {this.getOpenInNewWindowLink(service)}

    );
  },

  renderStatus: function (prop, service) {
    let instanceCount = service.getInstancesCount();
    let serviceStatus = service.getStatus();
    let serviceStatusClassSet = StatusMapping[serviceStatus] || '';
    let taskSummary = service.getTasksSummary();
    let {tasksRunning} = taskSummary;

    let text = ` (${tasksRunning} ${StringUtil.pluralize('Task', tasksRunning)})`;
    if (tasksRunning !== instanceCount) {
      text = ` (${tasksRunning} of ${instanceCount} Tasks)`;
    }

    return (

          <HealthBar tasksSummary={taskSummary} instancesCount={instanceCount} />

          {serviceStatus}
          {text}

    );
  },

  renderStats: function (prop, service) {
    return (

        {Units.formatResource(prop, service.getResources()[prop])}

    );
  },

  renderStatsHeading: function (prop, sortBy, row) {
    let isHeader = row == null;

    return classNames('flush-left text-align-right hidden-mini hidden-small', {
      'highlight': prop === sortBy.prop,
      'clickable': isHeader
    });
  },

  getColumns: function () {
    let className = ResourceTableUtil.getClassName;
    let heading = ResourceTableUtil.renderHeading(ServiceTableHeaderLabels);
    let {isFiltered} = this.props;

    return [
      {
        className: function () {
          return classNames([
            className.apply(this, arguments),
            {'table-cell-short': isFiltered}
          ]);
        },
        headerClassName: className,
        prop: 'name',
        render: this.renderHeadline,
        sortable: true,
        sortFunction: ServiceTableUtil.propCompareFunctionFactory,
        heading
      },
      {
        className,
        headerClassName: className,
        prop: 'status',
        render: this.renderStatus,
        sortable: true,
        sortFunction: ServiceTableUtil.propCompareFunctionFactory,
        heading
      },
      {
        className: this.renderStatsHeading,
        headerClassName: this.renderStatsHeading,
        prop: 'cpus',
        render: this.renderStats,
        sortable: true,
        sortFunction: ServiceTableUtil.propCompareFunctionFactory,
        heading
      },
      {
        className: this.renderStatsHeading,
        headerClassName: this.renderStatsHeading,
        prop: 'mem',
        render: this.renderStats,
        sortable: true,
        sortFunction: ServiceTableUtil.propCompareFunctionFactory,
        heading
      },
      {
        className: this.renderStatsHeading,
        headerClassName: this.renderStatsHeading,
        prop: 'disk',
        render: this.renderStats,
        sortable: true,
        sortFunction: ServiceTableUtil.propCompareFunctionFactory,
        heading
      }
    ];
  },

  getColGroup: function () {
    return (
      <colgroup>
        <col />
        <col className="status-bar-column"/>
        <col className="hidden-mini hidden-small" style={{width: '85px'}} />
        <col className="hidden-mini hidden-small" style={{width: '75px'}} />
        <col className="hidden-mini hidden-small" style={{width: '85px'}} />
      </colgroup>
    );
  },

  render: function () {
    return (

    );
  }
});

module.exports = ServicesTable;
<|endoftext|>


<commit_before>/*
 * Audero Context Menu is a cross-browser jQuery plugin that allows
 * you to show a custom context menu on one or more specified elements.
 *
 * @author  Aurelio De Rosa <aurelioderosa@gmail.com>
 * @version 2.2.1
 * @link    https://github.com/AurelioDeRosa/Audero-Context-Menu
 * @license Dual licensed under MIT (http://www.opensource.org/licenses/MIT)
 * and GPL-3.0 (http://opensource.org/licenses/GPL-3.0)
 */
(function($) {
   'use strict';

   var namespace = 'audero-context-menu';
   var localeNamespace = function(idMenu) {
      return namespace + '-' + idMenu;
   };

   var methods = {
      init: function(options) {
         if (typeof options === 'string') {
            options = {
               idMenu: options
            };
         }
         options = $.extend(true, {}, $.fn.auderoContextMenu.defaults, options);

         if (!options.idMenu) {
            $.error('No menu specified');
            return;
         } else if (document.getElementById(options.idMenu) === null) {
            $.error('The menu specified does not exist');
            return;
         }

         methods.destroy.call(this);
         this.data(namespace, options);
         var currentNamespace = localeNamespace(options.idMenu);

         // Hide the menu if the user clicks outside the elements specified
         $('html').on(
            'contextmenu.' + currentNamespace + ' click.' + currentNamespace,
            function() {
               $('#' + options.idMenu).hide();
            }
         );

         this.on(
            'contextmenu.' + currentNamespace + (options.bindLeftClick ? ' click.' + currentNamespace : ''),
            function(event) {
               event.preventDefault();
               event.stopPropagation();

               var posX = (options.posX === null) ? event.pageX : options.posX;
               var posY = (options.posY === null) ? event.pageY : options.posY;
               $('#' + options.idMenu)
                  .css({
                     top: posY + 'px',
                     left: posX + 'px'
                  })
                  .show();
            }
         );

         return this;
      },
      destroy: function() {
         var options = this.data(namespace);
         if (options !== undefined) {
            // Hide the menu if it's currently visible
            $('#' + options.idMenu).hide();

            // Remove the handlers and the data from the elements
            this
               .removeData(namespace)
               .add('html')
               .off('.' + localeNamespace(options.idMenu));
         }

         return this;
      }
   };

   $.fn.auderoContextMenu = function(method) {
      if (methods[method]) {
         return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
      } else if (typeof method === 'object' || typeof method === 'string' || !method) {
         return methods.init.apply(this, arguments);
      } else {
         $.error('Method ' + method + ' does not exist on jQuery.auderoContextMenu');
      }
   };

   $.fn.auderoContextMenu.defaults = {
      idMenu: null,        // string (required). The id of the menu that has to be shown
      posX: null,          // number (optional). The X coordinate used to show the menu
      posY: null,          // number (optional). The Y coordinate used to show the menu
      bindLeftClick: false // boolean (optional). If the menu has to be shown also on mouse left button click
   };
})(jQuery);<commit_msg>Removed useless returns<commit_after>/*
 * Audero Context Menu is a cross-browser jQuery plugin that allows
 * you to show a custom context menu on one or more specified elements.
 *
 * @author  Aurelio De Rosa <aurelioderosa@gmail.com>
 * @version 2.2.1
 * @link    https://github.com/AurelioDeRosa/Audero-Context-Menu
 * @license Dual licensed under MIT (http://www.opensource.org/licenses/MIT)
 * and GPL-3.0 (http://opensource.org/licenses/GPL-3.0)
 */
(function($) {
   'use strict';

   var namespace = 'audero-context-menu';
   var localeNamespace = function(idMenu) {
      return namespace + '-' + idMenu;
   };

   var methods = {
      init: function(options) {
         if (typeof options === 'string') {
            options = {
               idMenu: options
            };
         }
         options = $.extend(true, {}, $.fn.auderoContextMenu.defaults, options);

         if (!options.idMenu) {
            $.error('No menu specified');
         } else if (document.getElementById(options.idMenu) === null) {
            $.error('The menu specified does not exist');
         }

         methods.destroy.call(this);
         this.data(namespace, options);
         var currentNamespace = localeNamespace(options.idMenu);

         // Hide the menu if the user clicks outside the elements specified
         $('html').on(
            'contextmenu.' + currentNamespace + ' click.' + currentNamespace,
            function() {
               $('#' + options.idMenu).hide();
            }
         );

         this.on(
            'contextmenu.' + currentNamespace + (options.bindLeftClick ? ' click.' + currentNamespace : ''),
            function(event) {
               event.preventDefault();
               event.stopPropagation();

               var posX = (options.posX === null) ? event.pageX : options.posX;
               var posY = (options.posY === null) ? event.pageY : options.posY;
               $('#' + options.idMenu)
                  .css({
                     top: posY + 'px',
                     left: posX + 'px'
                  })
                  .show();
            }
         );

         return this;
      },
      destroy: function() {
         var options = this.data(namespace);
         if (options !== undefined) {
            // Hide the menu if it's currently visible
            $('#' + options.idMenu).hide();

            // Remove the handlers and the data from the elements
            this
               .removeData(namespace)
               .add('html')
               .off('.' + localeNamespace(options.idMenu));
         }

         return this;
      }
   };

   $.fn.auderoContextMenu = function(method) {
      if (methods[method]) {
         return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
      } else if (typeof method === 'object' || typeof method === 'string' || !method) {
         return methods.init.apply(this, arguments);
      } else {
         $.error('Method ' + method + ' does not exist on jQuery.auderoContextMenu');
      }
   };

   $.fn.auderoContextMenu.defaults = {
      idMenu: null,        // string (required). The id of the menu that has to be shown
      posX: null,          // number (optional). The X coordinate used to show the menu
      posY: null,          // number (optional). The Y coordinate used to show the menu
      bindLeftClick: false // boolean (optional). If the menu has to be shown also on mouse left button click
   };
})(jQuery);<|endoftext|>