<commit_before>const fs = require('fs-extra');
const fileExtension = require('file-extension');
var upload = {};
var options;

upload = function (req, res, next) {
	if (!req.files[options.filefield]) next();
	var newPath = options.uploadDir + filename(req.files[options.filefield]) + '.' + fileExtension(req.files[options.filefield].name);
	fs.move(req.files[options.filefield].path,  newPath , function (err) {
		if (err) return console.error(err)
		delete req.files[options.filefield].domain;
		delete req.files[options.filefield]._writeStream;
		delete req.files[options.filefield]._events;
		delete req.files[options.filefield]._eventsCount;
		delete req.files[options.filefield]._maxListeners;
		req.files[options.filefield].path = newPath;
		next();
	})
}

upload.options = function (data) {
	options = data;
}

function filename(options){
	if (options.filename = 'random') {
		return Math.random().toString(36).substring(7);
	} else {
		Math.random().toString(36).substring(7);
	}
}
module.exports = upload;<commit_msg>if not multi part error<commit_after>const fs = require('fs-extra');
const fileExtension = require('file-extension');
var upload = {};
var options;

upload = function (req, res, next) {
	if (!req.files[options.filefield]) res.send({code: "ExternalError", messege: "Cannot read property '" + options.filefield + "' of undefined"})
	var newPath = options.uploadDir + filename(req.files[options.filefield]) + '.' + fileExtension(req.files[options.filefield].name);
	fs.move(req.files[options.filefield].path,  newPath , function (err) {
		if (err) return console.error(err)
		delete req.files[options.filefield].domain;
		delete req.files[options.filefield]._writeStream;
		delete req.files[options.filefield]._events;
		delete req.files[options.filefield]._eventsCount;
		delete req.files[options.filefield]._maxListeners;
		req.files[options.filefield].path = newPath;
		next();
	})
}

upload.options = function (data) {
	options = data;
}

function filename(options){
	if (options.filename = 'random') {
		return Math.random().toString(36).substring(7);
	} else {
		Math.random().toString(36).substring(7);
	}
}
module.exports = upload;<|endoftext|>


<commit_before>// !! Defines a parser and serializer for
// [CommonMark](http://commonmark.org/) text (registered in the
// [`format`](#format) module under `"markdown"`).

;({defaultMarkdownParser: exports.defaultMarkdownParser, MarkdownParser: exports.MarkdownParser} = require("./from_markdown"))
;({MakdownSerializer: exports.MakdownSerializer, defaultMarkdownSerializer: exports.defaultMarkdownSerializer, MarkdownSerializerState: exports.MarkdownSerializerState} = require("./to_markdown"))
<commit_msg>Fix typo in exports of markdown module<commit_after>// !! Defines a parser and serializer for
// [CommonMark](http://commonmark.org/) text (registered in the
// [`format`](#format) module under `"markdown"`).

;({defaultMarkdownParser: exports.defaultMarkdownParser, MarkdownParser: exports.MarkdownParser} = require("./from_markdown"))
;({MarkdownSerializer: exports.MarkdownSerializer, defaultMarkdownSerializer: exports.defaultMarkdownSerializer,
   MarkdownSerializerState: exports.MarkdownSerializerState} = require("./to_markdown"))
<|endoftext|>


<commit_before>const mobx = require("../../src/mobx")
const { keys, when, set, remove, values, reaction, observable, extendObservable, has, get } = mobx

test("keys should be observable when extending", () => {
    const todos = observable({})

    const todoTitles = []
    reaction(
        () => keys(todos).map(key => `${key}: ${todos[key]}`),
        titles => todoTitles.push(titles.join(","))
    )

    mobx.set(todos, {
        lewis: "Read Lewis",
        chesterton: "Be mind blown by Chesterton"
    })
    expect(todoTitles).toEqual(["lewis: Read Lewis,chesterton: Be mind blown by Chesterton"])

    mobx.set(todos, { lewis: "Read Lewis twice" })
    mobx.set(todos, { coffee: "Grab coffee" })
    expect(todoTitles).toEqual([
        "lewis: Read Lewis,chesterton: Be mind blown by Chesterton",
        "lewis: Read Lewis twice,chesterton: Be mind blown by Chesterton",
        "lewis: Read Lewis twice,chesterton: Be mind blown by Chesterton,coffee: Grab coffee"
    ])
})

test("toJS respects key changes", () => {
    const todos = observable({})

    const serialized = []
    mobx.autorun(() => {
        serialized.push(JSON.stringify(mobx.toJS(todos)))
    })

    mobx.set(todos, {
        lewis: "Read Lewis",
        chesterton: "Be mind blown by Chesterton"
    })
    mobx.set(todos, { lewis: "Read Lewis twice" })
    mobx.set(todos, { coffee: "Grab coffee" })
    expect(serialized).toEqual([
        "{}",
        '{"lewis":"Read Lewis","chesterton":"Be mind blown by Chesterton"}',
        '{"lewis":"Read Lewis twice","chesterton":"Be mind blown by Chesterton"}',
        '{"lewis":"Read Lewis twice","chesterton":"Be mind blown by Chesterton","coffee":"Grab coffee"}'
    ])
})

test("object - set, remove, values are reactive", () => {
    const todos = observable({})
    const snapshots = []

    reaction(() => values(todos), values => snapshots.push(values))

    expect(has(todos, "x")).toBe(false)
    expect(get(todos, "x")).toBe(undefined)
    set(todos, "x", 3)
    expect(has(todos, "x")).toBe(true)
    expect(get(todos, "x")).toBe(3)
    remove(todos, "y")
    set(todos, "z", 4)
    set(todos, "x", 5)
    remove(todos, "z")

    expect(snapshots).toEqual([[3], [3, 4], [5, 4], [5]])
})

test("object - set, remove, keys are reactive", () => {
    const todos = observable({ a: 3 })
    const snapshots = []

    reaction(() => keys(todos), keys => snapshots.push(keys))

    set(todos, "x", 3)
    remove(todos, "y")
    set(todos, "z", 4)
    set(todos, "x", 5)
    remove(todos, "z")
    remove(todos, "a")

    expect(snapshots).toEqual([["a", "x"], ["a", "x", "z"], ["a", "x"], ["x"]])
})

test("map - set, remove, values are reactive", () => {
    const todos = observable.map({})
    const snapshots = []

    reaction(() => values(todos), values => snapshots.push(values))

    expect(has(todos, "x")).toBe(false)
    expect(get(todos, "x")).toBe(undefined)
    set(todos, "x", 3)
    expect(has(todos, "x")).toBe(true)
    expect(get(todos, "x")).toBe(3)
    remove(todos, "y")
    set(todos, "z", 4)
    set(todos, "x", 5)
    remove(todos, "z")

    expect(snapshots).toEqual([[3], [3, 4], [5, 4], [5]])
})

test("map - set, remove, keys are reactive", () => {
    const todos = observable.map({ a: 3 })
    const snapshots = []

    reaction(() => keys(todos), keys => snapshots.push(keys))

    set(todos, "x", 3)
    remove(todos, "y")
    set(todos, "z", 4)
    set(todos, "x", 5)
    remove(todos, "z")
    remove(todos, "a")

    expect(snapshots).toEqual([["a", "x"], ["a", "x", "z"], ["a", "x"], ["x"]])
})

test("array - set, remove, values are reactive", () => {
    const todos = observable.array()
    const snapshots = []

    reaction(() => values(todos), values => snapshots.push(values))

    expect(has(todos, 0)).toBe(false)
    expect(get(todos, 0)).toBe(undefined)
    set(todos, 0, 2)
    expect(has(todos, 0)).toBe(true)
    expect(get(todos, 0)).toBe(2)

    set(todos, "1", 4)
    set(todos, 3, 4)
    set(todos, 1, 3)
    remove(todos, 2)
    remove(todos, "0")

    expect(snapshots).toEqual([
        [2],
        [2, 4],
        [2, 4, undefined, 4],
        [2, 3, undefined, 4],
        [2, 3, 4],
        [3, 4]
    ])
})

test("observe & intercept", () => {
    let events = []
    const todos = observable(
        {
            a: { title: "get coffee" }
        },
        {},
        { deep: false }
    )
    mobx.observe(todos, c => events.push({ observe: c }))
    const d = mobx.intercept(todos, c => {
        events.push({ intercept: c })
        return null // no addition!
    })

    set(todos, { b: { title: "get tea" } })
    remove(todos, "a")
    expect(events).toMatchSnapshot()
    expect(mobx.toJS(todos)).toEqual({
        a: { title: "get coffee" }
    })

    events.splice(0)
    d()
    set(todos, { b: { title: "get tea" } })
    remove(todos, "a")
    expect(events).toMatchSnapshot()
    expect(mobx.toJS(todos)).toEqual({
        b: { title: "get tea" }
    })
})

test("observe & intercept set called multiple times", () => {
    const a = mobx.observable({})
    const interceptLogs = []
    const observeLogs = []

    mobx.intercept(a, change => {
        interceptLogs.push(`${change.name}: ${change.newValue}`)
        return change
    })
    mobx.observe(a, change => observeLogs.push(`${change.name}: ${change.newValue}`))

    mobx.set(a, "x", 0)
    a.x = 1
    mobx.set(a, "x", 2)

    expect(interceptLogs).toEqual(["x: 0", "x: 1", "x: 2"])
    expect(observeLogs).toEqual(["x: 0", "x: 1", "x: 2"])
})

test("dynamically adding properties should preserve the original modifiers of an object", () => {
    const todos = observable(
        {
            a: { title: "get coffee" }
        },
        {},
        { deep: false }
    )
    expect(mobx.isObservable(todos.a)).toBe(false)
    set(todos, { b: { title: "get tea" } })
    expect(mobx.isObservable(todos.b)).toBe(false)
})

test("has and get are reactive", async () => {
    const todos = observable({})

    const p1 = when(() => has(todos, "x"))
    const p2 = when(() => get(todos, "y") === 3)

    setTimeout(() => {
        set(todos, { x: false, y: 3 })
    }, 100)

    await p1
    await p2
})

test("computed props are not considered part of collections", () => {
    const x = observable({
        get y() {
            return 3
        }
    })
    expect(mobx.isComputedProp(x, "y")).toBe(true)
    expect(x.y).toBe(3)
    expect(has(x, "y")).toBe(false)
    expect(get(x, "y")).toBe(undefined) // disputable?
    expect(keys(x)).toEqual([])
    expect(values(x)).toEqual([])
})
<commit_msg>add specs for the new entries method<commit_after>const mobx = require("../../src/mobx")
const {
    keys,
    when,
    set,
    remove,
    values,
    entries,
    reaction,
    observable,
    extendObservable,
    has,
    get
} = mobx

test("keys should be observable when extending", () => {
    const todos = observable({})

    const todoTitles = []
    reaction(
        () => keys(todos).map(key => `${key}: ${todos[key]}`),
        titles => todoTitles.push(titles.join(","))
    )

    mobx.set(todos, {
        lewis: "Read Lewis",
        chesterton: "Be mind blown by Chesterton"
    })
    expect(todoTitles).toEqual(["lewis: Read Lewis,chesterton: Be mind blown by Chesterton"])

    mobx.set(todos, { lewis: "Read Lewis twice" })
    mobx.set(todos, { coffee: "Grab coffee" })
    expect(todoTitles).toEqual([
        "lewis: Read Lewis,chesterton: Be mind blown by Chesterton",
        "lewis: Read Lewis twice,chesterton: Be mind blown by Chesterton",
        "lewis: Read Lewis twice,chesterton: Be mind blown by Chesterton,coffee: Grab coffee"
    ])
})

test("toJS respects key changes", () => {
    const todos = observable({})

    const serialized = []
    mobx.autorun(() => {
        serialized.push(JSON.stringify(mobx.toJS(todos)))
    })

    mobx.set(todos, {
        lewis: "Read Lewis",
        chesterton: "Be mind blown by Chesterton"
    })
    mobx.set(todos, { lewis: "Read Lewis twice" })
    mobx.set(todos, { coffee: "Grab coffee" })
    expect(serialized).toEqual([
        "{}",
        '{"lewis":"Read Lewis","chesterton":"Be mind blown by Chesterton"}',
        '{"lewis":"Read Lewis twice","chesterton":"Be mind blown by Chesterton"}',
        '{"lewis":"Read Lewis twice","chesterton":"Be mind blown by Chesterton","coffee":"Grab coffee"}'
    ])
})

test("object - set, remove, values are reactive", () => {
    const todos = observable({})
    const snapshots = []

    reaction(() => values(todos), values => snapshots.push(values))

    expect(has(todos, "x")).toBe(false)
    expect(get(todos, "x")).toBe(undefined)
    set(todos, "x", 3)
    expect(has(todos, "x")).toBe(true)
    expect(get(todos, "x")).toBe(3)
    remove(todos, "y")
    set(todos, "z", 4)
    set(todos, "x", 5)
    remove(todos, "z")

    expect(snapshots).toEqual([[3], [3, 4], [5, 4], [5]])
})

test("object - set, remove, entries are reactive", () => {
    const todos = observable({})
    const snapshots = []

    reaction(() => entries(todos), entries => snapshots.push(entries))

    expect(has(todos, "x")).toBe(false)
    expect(get(todos, "x")).toBe(undefined)
    set(todos, "x", 3)
    expect(has(todos, "x")).toBe(true)
    expect(get(todos, "x")).toBe(3)
    remove(todos, "y")
    set(todos, "z", 4)
    set(todos, "x", 5)
    remove(todos, "z")

    expect(snapshots).toEqual([[["x", 3]], [["x", 3], ["z", 4]], [["x", 5], ["z", 4]], [["x", 5]]])
})

test("object - set, remove, keys are reactive", () => {
    const todos = observable({ a: 3 })
    const snapshots = []

    reaction(() => keys(todos), keys => snapshots.push(keys))

    set(todos, "x", 3)
    remove(todos, "y")
    set(todos, "z", 4)
    set(todos, "x", 5)
    remove(todos, "z")
    remove(todos, "a")

    expect(snapshots).toEqual([["a", "x"], ["a", "x", "z"], ["a", "x"], ["x"]])
})

test("map - set, remove, values are reactive", () => {
    const todos = observable.map({})
    const snapshots = []

    reaction(() => values(todos), values => snapshots.push(values))

    expect(has(todos, "x")).toBe(false)
    expect(get(todos, "x")).toBe(undefined)
    set(todos, "x", 3)
    expect(has(todos, "x")).toBe(true)
    expect(get(todos, "x")).toBe(3)
    remove(todos, "y")
    set(todos, "z", 4)
    set(todos, "x", 5)
    remove(todos, "z")

    expect(snapshots).toEqual([[3], [3, 4], [5, 4], [5]])
})

test("map - set, remove, entries are reactive", () => {
    const todos = observable.map({})
    const snapshots = []

    reaction(() => entries(todos), entries => snapshots.push(entries))

    expect(has(todos, "x")).toBe(false)
    expect(get(todos, "x")).toBe(undefined)
    set(todos, "x", 3)
    expect(has(todos, "x")).toBe(true)
    expect(get(todos, "x")).toBe(3)
    remove(todos, "y")
    set(todos, "z", 4)
    set(todos, "x", 5)
    remove(todos, "z")

    expect(snapshots).toEqual([[["x", 3]], [["x", 3], ["z", 4]], [["x", 5], ["z", 4]], [["x", 5]]])
})

test("map - set, remove, keys are reactive", () => {
    const todos = observable.map({ a: 3 })
    const snapshots = []

    reaction(() => keys(todos), keys => snapshots.push(keys))

    set(todos, "x", 3)
    remove(todos, "y")
    set(todos, "z", 4)
    set(todos, "x", 5)
    remove(todos, "z")
    remove(todos, "a")

    expect(snapshots).toEqual([["a", "x"], ["a", "x", "z"], ["a", "x"], ["x"]])
})

test("array - set, remove, values are reactive", () => {
    const todos = observable.array()
    const snapshots = []

    reaction(() => values(todos), values => snapshots.push(values))

    expect(has(todos, 0)).toBe(false)
    expect(get(todos, 0)).toBe(undefined)
    set(todos, 0, 2)
    expect(has(todos, 0)).toBe(true)
    expect(get(todos, 0)).toBe(2)

    set(todos, "1", 4)
    set(todos, 3, 4)
    set(todos, 1, 3)
    remove(todos, 2)
    remove(todos, "0")

    expect(snapshots).toEqual([
        [2],
        [2, 4],
        [2, 4, undefined, 4],
        [2, 3, undefined, 4],
        [2, 3, 4],
        [3, 4]
    ])
})

test("array - set, remove, entries are reactive", () => {
    const todos = observable.array()
    const snapshots = []

    reaction(() => entries(todos), entries => snapshots.push(entries))

    expect(has(todos, 0)).toBe(false)
    expect(get(todos, 0)).toBe(undefined)
    set(todos, 0, 2)
    expect(has(todos, 0)).toBe(true)
    expect(get(todos, 0)).toBe(2)

    set(todos, "1", 4)
    set(todos, 3, 4)
    set(todos, 1, 3)
    remove(todos, 2)
    remove(todos, "0")

    expect(snapshots).toEqual([
        [["0", 2]],
        [["0", 2], ["1", 4]],
        [["0", 2], ["1", 4], ["2", undefined], ["3", 4]],
        [["0", 2], ["1", 3], ["2", undefined], ["3", 4]],
        [["0", 2], ["1", 3], ["2", 4]],
        [["0", 3], ["1", 4]]
    ])
})

test("observe & intercept", () => {
    let events = []
    const todos = observable(
        {
            a: { title: "get coffee" }
        },
        {},
        { deep: false }
    )
    mobx.observe(todos, c => events.push({ observe: c }))
    const d = mobx.intercept(todos, c => {
        events.push({ intercept: c })
        return null // no addition!
    })

    set(todos, { b: { title: "get tea" } })
    remove(todos, "a")
    expect(events).toMatchSnapshot()
    expect(mobx.toJS(todos)).toEqual({
        a: { title: "get coffee" }
    })

    events.splice(0)
    d()
    set(todos, { b: { title: "get tea" } })
    remove(todos, "a")
    expect(events).toMatchSnapshot()
    expect(mobx.toJS(todos)).toEqual({
        b: { title: "get tea" }
    })
})

test("observe & intercept set called multiple times", () => {
    const a = mobx.observable({})
    const interceptLogs = []
    const observeLogs = []

    mobx.intercept(a, change => {
        interceptLogs.push(`${change.name}: ${change.newValue}`)
        return change
    })
    mobx.observe(a, change => observeLogs.push(`${change.name}: ${change.newValue}`))

    mobx.set(a, "x", 0)
    a.x = 1
    mobx.set(a, "x", 2)

    expect(interceptLogs).toEqual(["x: 0", "x: 1", "x: 2"])
    expect(observeLogs).toEqual(["x: 0", "x: 1", "x: 2"])
})

test("dynamically adding properties should preserve the original modifiers of an object", () => {
    const todos = observable(
        {
            a: { title: "get coffee" }
        },
        {},
        { deep: false }
    )
    expect(mobx.isObservable(todos.a)).toBe(false)
    set(todos, { b: { title: "get tea" } })
    expect(mobx.isObservable(todos.b)).toBe(false)
})

test("has and get are reactive", async () => {
    const todos = observable({})

    const p1 = when(() => has(todos, "x"))
    const p2 = when(() => get(todos, "y") === 3)

    setTimeout(() => {
        set(todos, { x: false, y: 3 })
    }, 100)

    await p1
    await p2
})

test("computed props are not considered part of collections", () => {
    const x = observable({
        get y() {
            return 3
        }
    })
    expect(mobx.isComputedProp(x, "y")).toBe(true)
    expect(x.y).toBe(3)
    expect(has(x, "y")).toBe(false)
    expect(get(x, "y")).toBe(undefined) // disputable?
    expect(keys(x)).toEqual([])
    expect(values(x)).toEqual([])
    expect(entries(x)).toEqual([])
})
<|endoftext|>


<commit_before>
"use strict";

var tls = require('tls');
var mumbleutil = require('./lib/util');

var MumbleConnection = require('./lib/MumbleConnection');
var MumbleClient = require('./lib/MumbleClient');

exports.MumbleConnection = MumbleConnection;

/**
 * @summary Connect to the Mumble server.
 *
 * @description
 * The URL specifies the Mumble server address. It can be either host with
 * optional port specified with `host:port` or then the full `mumble://`.
 *
 * @param {String} url - Mumble server address.
 * @param {Object} options - TLS options.
 * @param {function(err,client)} done - Connection callback receiving {@link MumbleClient}.
 */
exports.connect = function( url, options, done ) {

    if( typeof options === 'function' ) {
        done = options;
        options = {};
    }

    var server = mumbleutil.parseUrl( url );

    options = options || {};

    // If the options.rejectUnauthorized isn't defined default it to false.
    // We'll do this since most Mumble server certs are self signed anyway.
    //
    // The if catches null, false and other falsy values as well,
    // but this doesn't affect anything as we set it to false anyway.
    if( !options.rejectUnauthorized ) {
        options.rejectUnauthorized = false;
    }

    var socket = tls.connect( server.port, server.host, options, function ( err ) {
        if(options.key !== undefined) {
            delete options.key;
        }
        if(options.cert !== undefined) {
            delete options.cert;
        }
        var connection = new MumbleConnection( socket, options );

        done( null, new MumbleClient(connection) );
        if( !connection.authSent && server.username ) {
            connection.authenticate( server.username );
        }

        // If path was given, wait for init to be done before moving.
        if( server.path ) {
            connection.once('initialized', function () {
                connection.joinPath( server.path );
            });
        }
    });

    socket.on('error', done);
};

exports.celtVersions = mumbleutil.celtVersions;
<commit_msg>Path is always non-null, only joinPath if length is greater than 0<commit_after>
"use strict";

var tls = require('tls');
var mumbleutil = require('./lib/util');

var MumbleConnection = require('./lib/MumbleConnection');
var MumbleClient = require('./lib/MumbleClient');

exports.MumbleConnection = MumbleConnection;

/**
 * @summary Connect to the Mumble server.
 *
 * @description
 * The URL specifies the Mumble server address. It can be either host with
 * optional port specified with `host:port` or then the full `mumble://`.
 *
 * @param {String} url - Mumble server address.
 * @param {Object} options - TLS options.
 * @param {function(err,client)} done - Connection callback receiving {@link MumbleClient}.
 */
exports.connect = function( url, options, done ) {

    if( typeof options === 'function' ) {
        done = options;
        options = {};
    }

    var server = mumbleutil.parseUrl( url );

    options = options || {};

    // If the options.rejectUnauthorized isn't defined default it to false.
    // We'll do this since most Mumble server certs are self signed anyway.
    //
    // The if catches null, false and other falsy values as well,
    // but this doesn't affect anything as we set it to false anyway.
    if( !options.rejectUnauthorized ) {
        options.rejectUnauthorized = false;
    }

    var socket = tls.connect( server.port, server.host, options, function ( err ) {
        if(options.key !== undefined) {
            delete options.key;
        }
        if(options.cert !== undefined) {
            delete options.cert;
        }
        var connection = new MumbleConnection( socket, options );

        done( null, new MumbleClient(connection) );
        if( !connection.authSent && server.username ) {
            connection.authenticate( server.username );
        }

        // If path was given, wait for init to be done before moving.
        if( server.path.length ) {
            connection.once('initialized', function () {
                connection.joinPath( server.path );
            });
        }
    });

    socket.on('error', done);
};

exports.celtVersions = mumbleutil.celtVersions;
<|endoftext|>


<commit_before>'use strict';

var assert = require('assert'),
    async = require('nodee-utils').async,
    model = require('../../lib/model.js');

// load model extensions
require('../../lib/extensions/defaults.js');
require('../../lib/extensions/methods.js');
require('../../lib/extensions/queries.js');
require('../../lib/extensions/hooks.js');
require('../../lib/extensions/validations.js');

// load DataSource
require('../../lib/datasources/DataSource.js');

// load Tree behaviour
require('../../lib/behaviours/Tree.js');

// load Memory model
var Memory = require('../../lib/datasources/Memory.js');

/*
 * init test Model
 */
var PersonTree = model.define('PersonTree', ['MemoryDataSource', 'Tree'], {
    name:{ isString:true },
    surname:{ isString:true },
    isFetched:{ isBoolean:true }
});
PersonTree.extendDefaults({
    connection:{ collection:'personsTree' },
    options:{ storeChildren:true, storeChildrenCount:true } // test shildren id sync
});

/*
 * helper for comparing data, because createDT and modifiedDT will be different
 */
function equalData(exclude, data, equalTo){
    var sortedData = [], sortedEqualTo = [], sortedObj;

    data = Array.isArray(data) ? data : [ data ];
    equalTo = Array.isArray(equalTo) ? equalTo : [ equalTo ];

    for(var i=0;i<data.length;i++){
        sortedObj = {};
        Object.keys(data[i]).sort().forEach(function(v) {
            if(exclude.indexOf(v)===-1) sortedObj[v] = data[i][v];
        });
        sortedData.push(sortedObj);
        sortedObj = {};
        Object.keys(equalTo[i]).sort().forEach(function(v) {
            if(exclude.indexOf(v)===-1) sortedObj[v] = equalTo[i][v];
        });
        sortedEqualTo.push(sortedObj);
    }

    return JSON.stringify(sortedData) === JSON.stringify(sortedEqualTo);
}

/*
 * run tests
 */
testHooks(testInstanceMethods);

/*
 * test Tree hooks:
 * 1. beforeCreate - validateAncestors, afterCreate - addParentRef
 * 2. beforeUpdate - disableAncestors, (test document.move)
 * 3. beforeRemove - removeChildren, removeParentRef
 */
function testHooks(cb){

    var s = new async.Series;

    var records = [
        { id:'1', name:'Duri', surname:'Kainsmetke', ancestors:[] }, // root element
        { id:'2', name:'Jozef', surname:'Kozmeker', ancestors:['1'] }, // child of '1'
        { id:'3', name:'Pista', surname:'Horvat', ancestors:['1','2'] }, // child of '2'
        { id:'4', name: 'Pista', surname: 'Lakatos', ancestors: [ '1','2','3' ] }, // child of '3'
    ];

    // 1. beforeCreate - validateAncestors, afterCreate - addParentRef
    s.add(function(next){
        PersonTree.new( records[0] ).create(function(err, record1){
            if(err) throw err;

            PersonTree.new( records[1] ).create(function(err, record2){
                if(err) throw err;

                records[2].ancestors = ['0','2']; // will return error, because ancestor with id '0' not exists
                PersonTree.new( records[2] ).create(function(err, record3){
                    assert.ok( err.message === 'PersonTree.prototype.validateAncestors: cannot find all ancestors' );

                    records[2].ancestors = ['1','2'];
                    PersonTree.new( records[2] ).create(function(err, record3){
                        if(err) throw err;

                        PersonTree.collection().all(function(err, persons){
                        if(err) throw err;
                            assert.ok(equalData(['modifiedDT', 'createdDT'], persons, [
                                { id:'1', name: 'Duri', surname: 'Kainsmetke', ancestors: [], ancestorsCount:0, children: [ '2' ], childrenCount:1 },
                                { id:'2', name: 'Jozef', surname: 'Kozmeker', ancestors: [ '1' ], ancestorsCount:1, children: [ '3' ], childrenCount:1 },
                                { id:'3', name: 'Pista', surname: 'Horvat', ancestors: [ '1', '2' ], ancestorsCount:2, children: [], childrenCount:0 }
                            ]));
                            next();
                        });
                    });
                });
            });
        });
    });

    // 2. beforeUpdate - disableAncestors, (test document.move)
    s.add(function(next){
        PersonTree.collection().findId('3').one(function(err, record3){
            if(err) throw err;

            record3.ancestors = ['999']; // trying to change ancestors from ['1','2'] to ['999'], but nothing happens, because updating ancestors is disabled
            record3.update(function(err, record3){
                if(err) throw err;
                assert.deepEqual(record3.ancestors, ['999']);
                record3.ancestors = ['1','2']; // restore ancestors, because testing vith MemoryDataSource

                // move record 3 to record id '1'
                record3.move('1', function(err){
                    if(err) throw err;
                    assert.deepEqual(record3.ancestors, ['1']);

                    records[3].ancestors = ['1','2','3']; // test inconsistent ancestors, correctly have to be ['1','3']
                    PersonTree.new( records[3] ).create(function(err, record4){
                        assert.ok(err.message === 'PersonTree.prototype.validateAncestors: inconsistent path');

                        records[3].ancestors = ['1','3'];
                        PersonTree.new( records[3] ).create(function(err, record4){
                            if(err) throw err;

                            PersonTree.collection().all(function(err, persons){
                                if(err) throw err;
                                assert.ok(equalData(['modifiedDT', 'createdDT'], persons, [
                                    { id:'1', name: 'Duri', surname: 'Kainsmetke', ancestors: [], ancestorsCount:0, children: [ '2','3' ], childrenCount:2 },
                                    { id:'2', name: 'Jozef', surname: 'Kozmeker', ancestors: [ '1' ], ancestorsCount:1, children: [], childrenCount:0 },
                                    { id:'3', name: 'Pista', surname: 'Horvat', ancestors: [ '1' ], ancestorsCount:1, children: [ '4' ], childrenCount:1 },
                                    { id:'4', name: 'Pista', surname: 'Lakatos', ancestors: [ '1','3' ], ancestorsCount:2, children: [], childrenCount:0 }
                                ]));
                                next();
                            });
                        });
                    });
                });
            });
        });
    });

    // 2. afterUpdate - updateDescendants - this will update ancestors of all descendants, when parent changes ancestors
    s.add(function(next){
        PersonTree.collection().findId('3').one(function(err, record3){
            if(err) throw err;

            // move record 3 inside record2
            record3.move('2', function(err){
                if(err) throw err;

                PersonTree.collection().all(function(err, persons){
                    if(err) throw err;

                    assert.ok(equalData(['modifiedDT', 'createdDT'], persons, [
                        { id:'1', name: 'Duri', surname: 'Kainsmetke', ancestors: [], ancestorsCount:0, children: [ '2' ], childrenCount:1 },
                        { id:'2', name: 'Jozef', surname: 'Kozmeker', ancestors: [ '1' ], ancestorsCount:1, children: [ '3' ], childrenCount:1 },
                        { id:'3', name: 'Pista', surname: 'Horvat', ancestors: [ '1','2' ], ancestorsCount:2, children: [ '4' ], childrenCount:1 },
                        { id:'4', name: 'Pista', surname: 'Lakatos', ancestors: [ '1','2','3' ], ancestorsCount:3, children: [], childrenCount:0 }
                    ]));
                    next();
                });
            });
        });
    });

    // 3. beforeRemove - removeChildren, parent removeRef
    s.add(function(next){
        PersonTree.collection().findId('2').one(function(err, record2){
            if(err) throw err;

            // remove record2, this will remove all of children, and also remove reference from parent children
            record2.remove(function(err){
                if(err) throw err;

                PersonTree.collection().all(function(err, persons){
                    if(err) throw err;

                    assert.ok(equalData(['modifiedDT', 'createdDT'], persons, [
                        { id:'1', name: 'Duri', surname: 'Kainsmetke', ancestors: [], ancestorsCount:0, children: [], childrenCount:0 }
                    ]));
                    next();
                });
            });
        });
    });

    s.execute(function(err){
        assert.ok(!err);
        console.log('Tree behaviour CRUD - OK');
        cb();
    });
}

/*
 * test tree instance methods:
 * addChild, getSiblings(sort, callback), getDescendants(sort, levels, callback)
 */
function testInstanceMethods(){
    var s = new async.Series;

    var records = [
        { id:'1', name:'Duri', surname:'Kainsmetke', ancestors:[] }, // root element
        { id:'2', name:'Jozef', surname:'Kozmeker', ancestors:['1'] }, // child of '1'
        { id:'3', name:'Pista', surname:'Horvat' }, // child of '2'
        { id:'4', name: 'Pista', surname: 'Lakatos' }, // child of '2'
    ];

    // record 0 is already in datasource, insert 1,2,3
    s.add(function(next){
        PersonTree.new( records[1] ).create(function(err, record1){
            if(err) throw err;

            // test addChild
            record1.addChild(records[2], function(err, record2){
                if(err) throw err;

                // test addChild
                record1.addChild(records[3], function(err, record3){
                    if(err) throw err;

                    PersonTree.collection().all(function(err, persons){
                        if(err) throw err;

                        assert.ok(equalData(['modifiedDT', 'createdDT'], persons, [
                            { id:'1', name: 'Duri', surname: 'Kainsmetke', ancestors: [], ancestorsCount:0, children: [ '2' ], childrenCount:1 },
                            { id:'2', name: 'Jozef', surname: 'Kozmeker', ancestors: [ '1' ], ancestorsCount:1, children: [ '3','4' ], childrenCount:2 },
                            { id:'3', name: 'Pista', surname: 'Horvat', ancestors: [ '1','2' ], ancestorsCount:2, children: [], childrenCount:0 },
                            { id:'4', name: 'Pista', surname: 'Lakatos', ancestors: [ '1','2' ], ancestorsCount:2, children: [], childrenCount:0 }
                        ]));
                        next();
                    });
                });
            });
        });
    });

    // getSiblings(sort, callback)
    s.add(function(next){
        PersonTree.collection().findId('3').one(function(err, record3){
            if(err) throw err;

            record3.getSiblings().all(function(err, siblings){
                if(err) throw err;

                assert.ok(equalData(['modifiedDT', 'createdDT'], siblings, [
                    { id:'4', name: 'Pista', surname: 'Lakatos', ancestors: [ '1','2' ], ancestorsCount:2, children: [], childrenCount:0 }
                ]));
                next();
            });
        });
    });

    // getDescendants(sort, levels, callback)
    s.add(function(next){
        PersonTree.collection().findId('1').one(function(err, record1){
            if(err) throw err;

            record1.getDescendants(2).sort({ id:-1 }).all(function(err, descendants){
                if(err) throw err;

                assert.ok(equalData(['modifiedDT', 'createdDT'], descendants, [
                    { id:'4', name: 'Pista', surname: 'Lakatos', ancestors: [ '1','2' ], ancestorsCount:2, children: [], childrenCount:0 },
                    { id:'3', name: 'Pista', surname: 'Horvat', ancestors: [ '1','2' ], ancestorsCount:2, children: [], childrenCount:0 }
                ]));
                next();
            });
        });
    });

    s.execute(function(err){
        assert.ok(!err);
        console.log('Tree behaviour instance methods - OK');
    });
}<commit_msg>fixed: tree behaviour test<commit_after>'use strict';

var assert = require('assert'),
    async = require('nodee-utils').async,
    model = require('../../lib/model.js');

// load model extensions
require('../../lib/extensions/defaults.js');
require('../../lib/extensions/methods.js');
require('../../lib/extensions/queries.js');
require('../../lib/extensions/hooks.js');
require('../../lib/extensions/validations.js');

// load DataSource
require('../../lib/datasources/DataSource.js');

// load Tree behaviour
require('../../lib/behaviours/Tree.js');

// load Memory model
var Memory = require('../../lib/datasources/Memory.js');

/*
 * init test Model
 */
var PersonTree = model.define('PersonTree', ['MemoryDataSource', 'Tree'], {
    name:{ isString:true },
    surname:{ isString:true },
    isFetched:{ isBoolean:true }
});
PersonTree.extendDefaults({
    connection:{ collection:'personsTree' },
    options:{ storeChildren:true, storeChildrenCount:true } // test shildren id sync
});

/*
 * helper for comparing data, because createDT and modifiedDT will be different
 */
function equalData(exclude, data, equalTo){
    var sortedData = [], sortedEqualTo = [], sortedObj;

    data = Array.isArray(data) ? data : [ data ];
    equalTo = Array.isArray(equalTo) ? equalTo : [ equalTo ];

    for(var i=0;i<data.length;i++){
        sortedObj = {};
        Object.keys(data[i]).sort().forEach(function(v) {
            if(exclude.indexOf(v)===-1) sortedObj[v] = data[i][v];
        });
        sortedData.push(sortedObj);
        sortedObj = {};
        Object.keys(equalTo[i]).sort().forEach(function(v) {
            if(exclude.indexOf(v)===-1) sortedObj[v] = equalTo[i][v];
        });
        sortedEqualTo.push(sortedObj);
    }

    return JSON.stringify(sortedData) === JSON.stringify(sortedEqualTo);
}

/*
 * run tests
 */
testHooks(testInstanceMethods);

/*
 * test Tree hooks:
 * 1. beforeCreate - validateAncestors, afterCreate - addParentRef
 * 2. beforeUpdate - disableAncestors, (test document.move)
 * 3. beforeRemove - removeChildren, removeParentRef
 */
function testHooks(cb){

    var s = new async.Series;

    var records = [
        { id:'1', name:'Duri', surname:'Kainsmetke', ancestors:[] }, // root element
        { id:'2', name:'Jozef', surname:'Kozmeker', ancestors:['1'] }, // child of '1'
        { id:'3', name:'Pista', surname:'Horvat', ancestors:['1','2'] }, // child of '2'
        { id:'4', name: 'Pista', surname: 'Lakatos', ancestors: [ '1','2','3' ] }, // child of '3'
    ];

    // 1. beforeCreate - validateAncestors, afterCreate - addParentRef
    s.add(function(next){
        PersonTree.new( records[0] ).create(function(err, record1){
            if(err) throw err;

            PersonTree.new( records[1] ).create(function(err, record2){
                if(err) throw err;

                records[2].ancestors = ['0','2']; // will return error, because ancestor with id '0' not exists
                PersonTree.new( records[2] ).create(function(err, record3){
                    assert.ok( err.message === 'PersonTree.prototype.validateAncestors: cannot find all ancestors' );

                    records[2].ancestors = ['1','2'];
                    PersonTree.new( records[2] ).create(function(err, record3){
                        if(err) throw err;

                        PersonTree.collection().all(function(err, persons){
                        if(err) throw err;
                            assert.ok(equalData(['modifiedDT', 'createdDT'], persons, [
                                { id:'1', name: 'Duri', surname: 'Kainsmetke', ancestors: [], ancestorsCount:0, children: [ '2' ], childrenCount:1 },
                                { id:'2', name: 'Jozef', surname: 'Kozmeker', ancestors: [ '1' ], ancestorsCount:1, children: [ '3' ], childrenCount:1 },
                                { id:'3', name: 'Pista', surname: 'Horvat', ancestors: [ '1', '2' ], ancestorsCount:2, children: [], childrenCount:0 }
                            ]));
                            next();
                        });
                    });
                });
            });
        });
    });

    // 2. beforeUpdate - disableAncestors, (test document.move)
    s.add(function(next){
        PersonTree.collection().findId('3').one(function(err, record3){
            if(err) throw err;

            record3.ancestors = ['999']; // trying to change ancestors from ['1','2'] to ['999'], but nothing happens, because updating ancestors is disabled
            record3.update(function(err, record3){
                if(err) throw err;
                assert.deepEqual(record3.ancestors, ['999']);
                record3.ancestors = ['1','2']; // restore ancestors, because testing vith MemoryDataSource

                // move record 3 to record id '1'
                record3.move('1', function(err){
                    if(err) throw err;
                    assert.deepEqual(record3.ancestors, ['1']);

                    records[3].ancestors = ['1','2','3']; // test inconsistent ancestors, correctly have to be ['1','3']
                    PersonTree.new( records[3] ).create(function(err, record4){
                        assert.ok(err.message === 'PersonTree.prototype.validateAncestors: inconsistent tree path');

                        records[3].ancestors = ['1','3'];
                        PersonTree.new( records[3] ).create(function(err, record4){
                            if(err) throw err;

                            PersonTree.collection().all(function(err, persons){
                                if(err) throw err;
                                assert.ok(equalData(['modifiedDT', 'createdDT'], persons, [
                                    { id:'1', name: 'Duri', surname: 'Kainsmetke', ancestors: [], ancestorsCount:0, children: [ '2','3' ], childrenCount:2 },
                                    { id:'2', name: 'Jozef', surname: 'Kozmeker', ancestors: [ '1' ], ancestorsCount:1, children: [], childrenCount:0 },
                                    { id:'3', name: 'Pista', surname: 'Horvat', ancestors: [ '1' ], ancestorsCount:1, children: [ '4' ], childrenCount:1 },
                                    { id:'4', name: 'Pista', surname: 'Lakatos', ancestors: [ '1','3' ], ancestorsCount:2, children: [], childrenCount:0 }
                                ]));
                                next();
                            });
                        });
                    });
                });
            });
        });
    });

    // 2. afterUpdate - updateDescendants - this will update ancestors of all descendants, when parent changes ancestors
    s.add(function(next){
        PersonTree.collection().findId('3').one(function(err, record3){
            if(err) throw err;

            // move record 3 inside record2
            record3.move('2', function(err){
                if(err) throw err;

                PersonTree.collection().all(function(err, persons){
                    if(err) throw err;

                    assert.ok(equalData(['modifiedDT', 'createdDT'], persons, [
                        { id:'1', name: 'Duri', surname: 'Kainsmetke', ancestors: [], ancestorsCount:0, children: [ '2' ], childrenCount:1 },
                        { id:'2', name: 'Jozef', surname: 'Kozmeker', ancestors: [ '1' ], ancestorsCount:1, children: [ '3' ], childrenCount:1 },
                        { id:'3', name: 'Pista', surname: 'Horvat', ancestors: [ '1','2' ], ancestorsCount:2, children: [ '4' ], childrenCount:1 },
                        { id:'4', name: 'Pista', surname: 'Lakatos', ancestors: [ '1','2','3' ], ancestorsCount:3, children: [], childrenCount:0 }
                    ]));
                    next();
                });
            });
        });
    });

    // 3. beforeRemove - removeChildren, parent removeRef
    s.add(function(next){
        PersonTree.collection().findId('2').one(function(err, record2){
            if(err) throw err;

            // remove record2, this will remove all of children, and also remove reference from parent children
            record2.remove(function(err){
                if(err) throw err;

                PersonTree.collection().all(function(err, persons){
                    if(err) throw err;

                    assert.ok(equalData(['modifiedDT', 'createdDT'], persons, [
                        { id:'1', name: 'Duri', surname: 'Kainsmetke', ancestors: [], ancestorsCount:0, children: [], childrenCount:0 }
                    ]));
                    next();
                });
            });
        });
    });

    s.execute(function(err){
        assert.ok(!err);
        console.log('Tree behaviour CRUD - OK');
        cb();
    });
}

/*
 * test tree instance methods:
 * addChild, getSiblings(sort, callback), getDescendants(sort, levels, callback)
 */
function testInstanceMethods(){
    var s = new async.Series;

    var records = [
        { id:'1', name:'Duri', surname:'Kainsmetke', ancestors:[] }, // root element
        { id:'2', name:'Jozef', surname:'Kozmeker', ancestors:['1'] }, // child of '1'
        { id:'3', name:'Pista', surname:'Horvat' }, // child of '2'
        { id:'4', name: 'Pista', surname: 'Lakatos' }, // child of '2'
    ];

    // record 0 is already in datasource, insert 1,2,3
    s.add(function(next){
        PersonTree.new( records[1] ).create(function(err, record1){
            if(err) throw err;

            // test addChild
            record1.addChild(records[2], function(err, record2){
                if(err) throw err;

                // test addChild
                record1.addChild(records[3], function(err, record3){
                    if(err) throw err;

                    PersonTree.collection().all(function(err, persons){
                        if(err) throw err;

                        assert.ok(equalData(['modifiedDT', 'createdDT'], persons, [
                            { id:'1', name: 'Duri', surname: 'Kainsmetke', ancestors: [], ancestorsCount:0, children: [ '2' ], childrenCount:1 },
                            { id:'2', name: 'Jozef', surname: 'Kozmeker', ancestors: [ '1' ], ancestorsCount:1, children: [ '3','4' ], childrenCount:2 },
                            { id:'3', name: 'Pista', surname: 'Horvat', ancestors: [ '1','2' ], ancestorsCount:2, children: [], childrenCount:0 },
                            { id:'4', name: 'Pista', surname: 'Lakatos', ancestors: [ '1','2' ], ancestorsCount:2, children: [], childrenCount:0 }
                        ]));
                        next();
                    });
                });
            });
        });
    });

    // getSiblings(sort, callback)
    s.add(function(next){
        PersonTree.collection().findId('3').one(function(err, record3){
            if(err) throw err;

            record3.getSiblings().all(function(err, siblings){
                if(err) throw err;

                assert.ok(equalData(['modifiedDT', 'createdDT'], siblings, [
                    { id:'4', name: 'Pista', surname: 'Lakatos', ancestors: [ '1','2' ], ancestorsCount:2, children: [], childrenCount:0 }
                ]));
                next();
            });
        });
    });

    // getDescendants(sort, levels, callback)
    s.add(function(next){
        PersonTree.collection().findId('1').one(function(err, record1){
            if(err) throw err;

            record1.getDescendants(2).sort({ id:-1 }).all(function(err, descendants){
                if(err) throw err;

                assert.ok(equalData(['modifiedDT', 'createdDT'], descendants, [
                    { id:'4', name: 'Pista', surname: 'Lakatos', ancestors: [ '1','2' ], ancestorsCount:2, children: [], childrenCount:0 },
                    { id:'3', name: 'Pista', surname: 'Horvat', ancestors: [ '1','2' ], ancestorsCount:2, children: [], childrenCount:0 }
                ]));
                next();
            });
        });
    });

    s.execute(function(err){
        assert.ok(!err);
        console.log('Tree behaviour instance methods - OK');
    });
}<|endoftext|>


<commit_before>var utils     = require( 'utils' )
  , parser    = require( 'body-parser' )
  , compress  = require( 'compression' )
  , override  = require( 'method-override' )
  , resTime   = require( 'response-time' )
  , timeout   = require( 'connect-timeout' )
  , logger    = require( 'morgan' )
  , env       = utils.bootstrapEnv()
  , moduleLdr = env.moduleLoader
  , cors      = require( 'cors' )
  , chalk     = require( 'chalk' )
  , debug     = require( 'debug' )( 'Worker' )
  , app       = module.exports = env.app;

debug( 'started with pid %s', chalk.yellow( process.pid ) );

moduleLdr.on( 'preLoadModules', function() {
    debug( 'Configuring express application...' );

    app.use( resTime() );
    app.use( timeout( '30s' ) );
    app.use( parser.urlencoded( { extended: true } ) );
    app.use( parser.json() );
    app.use( logger( 'dev' ) );
    app.use( compress() );
    app.use( override() );
    app.use( cors( env.config.cors ) );
});

moduleLdr.on( 'modulesLoaded', function() {
    debug( 'Initializing routes...' );

    moduleLdr.initializeRoutes();
});

moduleLdr.on( 'routesInitialized', function() {
    debug( 'Setting up router and starting http server...' );

    app.listen( env.webPort, function() {
        debug( 'Started web server on port %s in enviromment %s', chalk.yellow( env.webPort ), chalk.yellow( process.env.NODE_ENV ? process.env.NODE_ENV : "LOCAL" ) );
    });
});

debug( 'Loading modules...' );
moduleLdr.loadModules();<commit_msg>refactor(debug): prefixing with cleverstack:<commit_after>var utils     = require( 'utils' )
  , parser    = require( 'body-parser' )
  , compress  = require( 'compression' )
  , override  = require( 'method-override' )
  , resTime   = require( 'response-time' )
  , timeout   = require( 'connect-timeout' )
  , logger    = require( 'morgan' )
  , env       = utils.bootstrapEnv()
  , moduleLdr = env.moduleLoader
  , cors      = require( 'cors' )
  , chalk     = require( 'chalk' )
  , debug     = require( 'debug' )( 'cleverstack:server' )
  , app       = module.exports = env.app;

debug( 'started with pid %s', chalk.yellow( process.pid ) );

moduleLdr.on( 'preLoadModules', function() {
    debug( 'Configuring express application...' );

    app.use( resTime() );
    // app.use( timeout( '30s' ) );
    app.use( parser.urlencoded( { extended: true } ) );
    app.use( parser.json() );
    app.use( logger( 'dev' ) );
    app.use( compress() );
    app.use( override() );
    app.use( cors( env.config.cors ) );
});

moduleLdr.on( 'modulesLoaded', function() {
    debug( 'Initializing routes...' );

    moduleLdr.initializeRoutes();
});

moduleLdr.on( 'routesInitialized', function() {
    debug( 'Setting up router and starting http server...' );

    app.listen( env.webPort, function() {
        debug( 'Started web server on port %s in enviromment %s', chalk.yellow( env.webPort ), chalk.yellow( process.env.NODE_ENV ? process.env.NODE_ENV : "LOCAL" ) );
    });
});

debug( 'Loading modules...' );
moduleLdr.loadModules();<|endoftext|>


<commit_before>
var parse = require('./src/parser');
var Lexer = require('./src/lexer');

module.exports = function(input, options) {
  options = Object.assign({}, { spellcheck: false, smartquots: true }, options || {});
  var lex = Lexer();
  var lexResults = lex(input);
  var output = parse(input, lexResults.tokens, lexResults.positions, options);
  return output;
}
<commit_msg>Fix typo<commit_after>
var parse = require('./src/parser');
var Lexer = require('./src/lexer');

module.exports = function(input, options) {
  options = Object.assign({}, { spellcheck: false, smartquotes: true }, options || {});
  var lex = Lexer();
  var lexResults = lex(input);
  var output = parse(input, lexResults.tokens, lexResults.positions, options);
  return output;
}
<|endoftext|>


<commit_before>'use strict';
var childProcess = require('child_process');
var stripAnsi = require('strip-ansi');
var delimiter = require('path').delimiter;
var shell = process.env.SHELL || '/bin/sh';
var user = process.env.USER;
var opts = {encoding: 'utf8'};

module.exports = function (cb) {
	if (process.platform === 'win32') {
		setImmediate(cb, null, process.env.PATH);
		return;
	}

	var todo = [pathFromShell, pathFromSudo];
	var results = [];
	todo.forEach(function (fn) {
		fn(function (path) {
			results.push(path);
			if (results.length === todo.length) {
			  cb(null, longest(results.concat(process.env.PATH)));
			}
		});
	});
};

module.exports.sync = function () {
	if (process.platform === 'win32') {
		return process.env.PATH;
	}

	var p1 = pathFromShellSync();
	var p2 = pathFromSudoSync();
	// return the longest found path
	return longest([p1, p2, process.env.PATH]);
};

function pathFromShell(cb) {
	childProcess.execFile(shell, ['-i', '-c', 'echo "$PATH"'], opts, function (err, stdout) {
		if (err) {
			cb('');
			return;
		}

		cb(clean(stdout) || '');
	});
}

function pathFromShellSync() {
	return clean(childProcess.execFileSync(shell, ['-i', '-c', 'echo "$PATH"'], opts)) || '';
}

function pathFromSudo(cb) {
	childProcess.execFile('sudo', ['-Hiu', user, 'echo "$PATH"'], opts, function (err, stdout) {
		if (err) {
			// may fail with 'sudo: must be setuid root'
			cb('');
			return;
		}

		cb(clean(stdout) || '');
	});
}

function pathFromSudoSync() {
	try {
		return clean(childProcess.execSync('sudo -Hiu ' + user + ' echo "$PATH"', opts)) || '';
	} catch (err) {
		// may fail with 'sudo: must be setuid root'
		return '';
	}
}

function clean(str) {
	return stripAnsi(str.trim());
}

function longest(arr) {
	return arr.reduce(function (a, b) {
		return a.split(delimiter).length > b.split(delimiter).length ? a : b;
	});
}
<commit_msg>add missing comment<commit_after>'use strict';
var childProcess = require('child_process');
var stripAnsi = require('strip-ansi');
var delimiter = require('path').delimiter;
var shell = process.env.SHELL || '/bin/sh';
var user = process.env.USER;
var opts = {encoding: 'utf8'};

module.exports = function (cb) {
	if (process.platform === 'win32') {
		setImmediate(cb, null, process.env.PATH);
		return;
	}

	var todo = [pathFromShell, pathFromSudo];
	var results = [];
	todo.forEach(function (fn) {
		fn(function (path) {
			results.push(path);
			if (results.length === todo.length) {
				// return the longest found path
			  cb(null, longest(results.concat(process.env.PATH)));
			}
		});
	});
};

module.exports.sync = function () {
	if (process.platform === 'win32') {
		return process.env.PATH;
	}

	var p1 = pathFromShellSync();
	var p2 = pathFromSudoSync();
	// return the longest found path
	return longest([p1, p2, process.env.PATH]);
};

function pathFromShell(cb) {
	childProcess.execFile(shell, ['-i', '-c', 'echo "$PATH"'], opts, function (err, stdout) {
		if (err) {
			cb('');
			return;
		}

		cb(clean(stdout) || '');
	});
}

function pathFromShellSync() {
	return clean(childProcess.execFileSync(shell, ['-i', '-c', 'echo "$PATH"'], opts)) || '';
}

function pathFromSudo(cb) {
	childProcess.execFile('sudo', ['-Hiu', user, 'echo "$PATH"'], opts, function (err, stdout) {
		if (err) {
			// may fail with 'sudo: must be setuid root'
			cb('');
			return;
		}

		cb(clean(stdout) || '');
	});
}

function pathFromSudoSync() {
	try {
		return clean(childProcess.execSync('sudo -Hiu ' + user + ' echo "$PATH"', opts)) || '';
	} catch (err) {
		// may fail with 'sudo: must be setuid root'
		return '';
	}
}

function clean(str) {
	return stripAnsi(str.trim());
}

function longest(arr) {
	return arr.reduce(function (a, b) {
		return a.split(delimiter).length > b.split(delimiter).length ? a : b;
	});
}
<|endoftext|>


<commit_before>import chai from'chai'
import sinonChai from'sinon-chai'
var expect = chai.expect
chai.use(sinonChai)
import sinon from 'sinon'
import path from 'path'
import {Promise} from 'bluebird'
import fse from 'fs-extra'
import events from 'events'
import mkdirp from 'mkdirp'
import {
  config,
  cmsMedia,
  coreUtils,
  abeExtend
} from '../../../src/cli'
config.set({root: path.join(process.cwd(), 'test','fixtures')})

describe('image', function() {

  var pathToImage = path.join(config.root, config.publish.url, config.upload.image, 'chat-1.jpg');
  var imagesListInFolder = [
    path.join(config.root, config.publish.url, config.upload.image, 'img.jpg'),
    path.join(config.root, config.publish.url, config.upload.image, 'img_100x100.jpg'),
    path.join(config.root, config.publish.url, config.upload.image, 'img_10x10.jpg'),
    path.join(config.root, config.publish.url, config.upload.image, 'img_thumb.jpg')
  ];

  before(function(done) {
    fse.copySync(path.join(config.root, 'media'), config.root)
    done()
  });

  /**
   * cmsMedia.image.generateThumbnail
   * @todo : UNIT TEST this method
   *
   */
  it('cmsMedia.image.generateThumbnail()', function(done) {
    // this.sinon = sinon.sandbox.create();
    // var stub = sinon.stub(cmsMedia.image, 'smartCropAndSaveFile')
    // stub.returns(Promise.resolve(0))
    // var thumb = cmsMedia.image.generateThumbnail(pathToImage)
    // thumb.then(function (result) {
    //   done()
    //   chai.expect(result).to.not.be.undefined
    //   chai.expect(result.thumb).to.not.be.undefined
    //   chai.expect(result.thumb).to.equal('/unitimage/chat-1_thumb.jpg')
    //   sinon.assert.calledOnce(cmsMedia.image.smartCropAndSaveFile)
    //   cmsMedia.image.smartCropAndSaveFile.restore()
    // })
    done()
  });

  /**
   * cmsMedia.image.cropAndSaveFiles
   * @todo : UNIT TEST this method
   *
   */
  it('cmsMedia.image.cropAndSaveFiles()', function(done) {
    // this.sinon = sinon.sandbox.create();
    // var stub = sinon.stub(cmsMedia.image, 'smartCropAndSaveFile')
    // stub.returns(Promise.resolve({
    //   'stdout': false,
    //   'stderr': false
    // }))
    // var thumbs = cmsMedia.image.cropAndSaveFiles(['10x10'], pathToImage, {})

    // thumbs.then(function (result) {
    //   console.log("result", result)
    //   chai.expect(result).to.not.be.undefined
    //   chai.expect(result.thumbs).to.have.length(1)
    //   chai.expect(result.thumbs[0]).to.have.property('name').to.equal('/unitimage/chat-1_10x10.jpg')
    //   chai.expect(result.thumbs[0]).to.have.property('size').to.equal('10x10')
    //   sinon.assert.calledOnce(cmsMedia.image.smartCropAndSaveFile)
    //   cmsMedia.image.smartCropAndSaveFile.restore()

    //   done()
    // })
    // .catch(function (err) {
    //   console.log("catch", err)
    //   done()
    // })
    done()
  });

  /**
   * cmsMedia.image.getThumbsList
   *
   */
  it('cmsMedia.image.getThumbsList()', function() {
    this.sinon = sinon.sandbox.create();
    var stub = sinon.stub(coreUtils.file, 'getFilesSync')
    stub.returns(imagesListInFolder)
    var result = cmsMedia.image.getThumbsList()
    chai.expect(result).to.not.be.undefined
    chai.expect(result).to.have.length(1)
    chai.expect(result[0]).to.have.property('originalFile').to.equal(path.join(path.sep, 'unitimage', 'img.jpg'))
    chai.expect(result[0]).to.have.property('thumbFile').to.equal(path.join(path.sep, 'unitimage', 'img_thumb.jpg'))
    sinon.assert.calledOnce(coreUtils.file.getFilesSync)
    coreUtils.file.getFilesSync.restore()
  });

  /**
   * cmsMedia.image.createMediaFolder
   *
   */
  it('cmsMedia.image.createMediaFolder()', function() {
    this.sinon = sinon.sandbox.create();
    var stub = sinon.stub(abeExtend.hooks.instance, 'trigger')
    stub.returns('/myImageFolder')
    var stubDir = sinon.stub(mkdirp, 'sync')
    stubDir.returns({})
    var result = cmsMedia.image.createMediaFolder({})
    chai.expect(result).to.not.be.undefined
    chai.expect(result).to.be.a('string')
    chai.expect(result).to.equal(path.join(config.root, config.publish.url, '/myImageFolder'))
    sinon.assert.calledOnce(abeExtend.hooks.instance.trigger)
    abeExtend.hooks.instance.trigger.restore()
    sinon.assert.calledOnce(mkdirp.sync)
    mkdirp.sync.restore()
  });

  /**
   * cmsMedia.image.getAssociatedImageFileFromThumb
   *
   */
  it('cmsMedia.image.getAssociatedImageFileFromThumb()', function() {
    this.sinon = sinon.sandbox.create();
    var stub = sinon.stub(coreUtils.file, 'getFilesSync')
    stub.returns(imagesListInFolder)
    var result = cmsMedia.image.getAssociatedImageFileFromThumb(path.join(path.sep, 'unitimage', 'img_thumb.jpg'))
    chai.expect(result).to.not.be.undefined
    chai.expect(result).to.have.property('originalFile').to.equal(path.join(path.sep, 'unitimage', 'img.jpg'))
    chai.expect(result).to.have.property('thumbFile').to.equal(path.join(path.sep, 'unitimage', 'img_thumb.jpg'))
    chai.expect(result.thumbs).to.have.length(2)
    chai.expect(result.thumbs[0]).to.equal(path.join(path.sep, 'unitimage', 'img_100x100.jpg'))
    sinon.assert.calledOnce(coreUtils.file.getFilesSync)
    coreUtils.file.getFilesSync.restore()
  });

  /**
   * cmsMedia.image.isValidMedia
   *
   */
  it('cmsMedia.image.isValidMedia()', function() {
    var result = cmsMedia.image.isValidMedia('image/jpeg', '.jpg')
    var result2 = cmsMedia.image.isValidMedia('wrong/mimetype', '.exe')
    chai.expect(result.error).to.equal(false)
    chai.expect(result2.error).to.be.a('string')
    chai.expect(result2.error).to.equal('.exe is not an authorized extension')
  });

  /**
   * cmsMedia.image.createMediaSlug
   *
   */
  it('cmsMedia.image.createMediaSlug()', function() {
    this.sinon = sinon.sandbox.create();
    var stub = sinon.stub(coreUtils.random, 'generateUniqueIdentifier')
    stub.returns(12345)
    var result = cmsMedia.image.createMediaSlug('teSt f1le s l û g', '.jpg')
    chai.expect(result).to.not.be.undefined
    chai.expect(result).to.be.a('string')
    chai.expect(result).to.equal('test-f1le-s-l-u-g-12345.jpg')
    sinon.assert.calledOnce(coreUtils.random.generateUniqueIdentifier)
    coreUtils.random.generateUniqueIdentifier.restore()
  });

  after(function(done) {
    fse.remove(path.join(config.root, config.publish.url))
    done()
  });

});<commit_msg>qa: fix media test<commit_after>import chai from'chai'
import sinonChai from'sinon-chai'
var expect = chai.expect
chai.use(sinonChai)
import sinon from 'sinon'
import path from 'path'
import {Promise} from 'bluebird'
import fse from 'fs-extra'
import events from 'events'
import mkdirp from 'mkdirp'
import {
  config,
  cmsMedia,
  coreUtils,
  abeExtend
} from '../../../src/cli'
config.set({root: path.join(process.cwd(), 'test','fixtures')})

describe('image', function() {

  var pathToImage = path.join(config.root, config.publish.url, config.upload.image, 'chat-1.jpg');
  var imagesListInFolder = [
    path.join(config.root, config.publish.url, config.upload.image, 'img.jpg'),
    path.join(config.root, config.publish.url, config.upload.image, 'img_100x100.jpg'),
    path.join(config.root, config.publish.url, config.upload.image, 'img_10x10.jpg'),
    path.join(config.root, config.publish.url, config.upload.image, 'img_thumb.jpg')
  ];

  before(function(done) {
    fse.copySync(path.join(config.root, 'media'), config.root)
    done()
  });

  /**
   * cmsMedia.image.generateThumbnail
   * @todo : UNIT TEST this method
   *
   */
  it('cmsMedia.image.generateThumbnail()', function(done) {
    // this.sinon = sinon.sandbox.create();
    // var stub = sinon.stub(cmsMedia.image, 'smartCropAndSaveFile')
    // stub.returns(Promise.resolve(0))
    // var thumb = cmsMedia.image.generateThumbnail(pathToImage)
    // thumb.then(function (result) {
    //   done()
    //   chai.expect(result).to.not.be.undefined
    //   chai.expect(result.thumb).to.not.be.undefined
    //   chai.expect(result.thumb).to.equal('/unitimage/chat-1_thumb.jpg')
    //   sinon.assert.calledOnce(cmsMedia.image.smartCropAndSaveFile)
    //   cmsMedia.image.smartCropAndSaveFile.restore()
    // })
    done()
  });

  /**
   * cmsMedia.image.cropAndSaveFiles
   * @todo : UNIT TEST this method
   *
   */
  it('cmsMedia.image.cropAndSaveFiles()', function(done) {
    // this.sinon = sinon.sandbox.create();
    // var stub = sinon.stub(cmsMedia.image, 'smartCropAndSaveFile')
    // stub.returns(Promise.resolve({
    //   'stdout': false,
    //   'stderr': false
    // }))
    // var thumbs = cmsMedia.image.cropAndSaveFiles(['10x10'], pathToImage, {})

    // thumbs.then(function (result) {
    //   console.log("result", result)
    //   chai.expect(result).to.not.be.undefined
    //   chai.expect(result.thumbs).to.have.length(1)
    //   chai.expect(result.thumbs[0]).to.have.property('name').to.equal('/unitimage/chat-1_10x10.jpg')
    //   chai.expect(result.thumbs[0]).to.have.property('size').to.equal('10x10')
    //   sinon.assert.calledOnce(cmsMedia.image.smartCropAndSaveFile)
    //   cmsMedia.image.smartCropAndSaveFile.restore()

    //   done()
    // })
    // .catch(function (err) {
    //   console.log("catch", err)
    //   done()
    // })
    done()
  });

  /**
   * cmsMedia.image.getThumbsList
   *
   */
  it('cmsMedia.image.getThumbsList()', function() {
    this.sinon = sinon.sandbox.create();
    var stub = sinon.stub(coreUtils.file, 'getFilesSync')
    stub.returns(imagesListInFolder)
    var result = cmsMedia.image.getThumbsList()
    chai.expect(result).to.not.be.undefined
    chai.expect(result).to.have.length(1)
    chai.expect(result[0]).to.have.property('originalFile').to.equal(path.join(path.sep, 'unitimage', 'img.jpg'))
    chai.expect(result[0]).to.have.property('thumbFile').to.equal(path.join(path.sep, 'unitimage', 'img_thumb.jpg'))
    sinon.assert.calledOnce(coreUtils.file.getFilesSync)
    coreUtils.file.getFilesSync.restore()
  });

  /**
   * cmsMedia.image.createMediaFolder
   *
   */
  it('cmsMedia.image.createMediaFolder()', function() {
    this.sinon = sinon.sandbox.create();
    var stub = sinon.stub(abeExtend.hooks.instance, 'trigger')
    stub.returns('/myImageFolder')
    var stubDir = sinon.stub(mkdirp, 'sync')
    stubDir.returns({})
    var result = cmsMedia.image.createMediaFolder({})
    chai.expect(result).to.not.be.undefined
    chai.expect(result).to.be.a('string')
    chai.expect(result).to.equal(path.join(config.root, config.publish.url, '/myImageFolder'))
    sinon.assert.calledOnce(abeExtend.hooks.instance.trigger)
    abeExtend.hooks.instance.trigger.restore()
    sinon.assert.calledOnce(mkdirp.sync)
    mkdirp.sync.restore()
  });

  /**
   * cmsMedia.image.getAssociatedImageFileFromThumb
   *
   */
  it('cmsMedia.image.getAssociatedImageFileFromThumb()', function() {
    this.sinon = sinon.sandbox.create();
    var stub = sinon.stub(coreUtils.file, 'getFilesSync')
    stub.returns(imagesListInFolder)
    var result = cmsMedia.image.getAssociatedImageFileFromThumb(path.join(path.sep, 'unitimage', 'img_thumb.jpg'))
    chai.expect(result).to.not.be.undefined
    chai.expect(result).to.have.property('originalFile').to.equal(path.join(path.sep, 'unitimage', 'img.jpg'))
    chai.expect(result).to.have.property('thumbFile').to.equal(path.join(path.sep, 'unitimage', 'img_thumb.jpg'))
    chai.expect(result.thumbs).to.have.length(2)
    chai.expect(result.thumbs[0]).to.equal(path.join(path.sep, 'unitimage', 'img_100x100.jpg'))
    sinon.assert.calledOnce(coreUtils.file.getFilesSync)
    coreUtils.file.getFilesSync.restore()
  });

  /**
   * cmsMedia.image.isValidMedia
   *
   */
  it('cmsMedia.image.isValidMedia()', function() {
    var result = cmsMedia.image.isValidMedia('image/jpeg', '.jpg')
    var result2 = cmsMedia.image.isValidMedia('wrong/mimetype', '.exe')
    chai.expect(result.error).to.equal(false)
    chai.expect(result2.error).to.be.a('string')
    chai.expect(result2.error).to.equal('.exe is not an authorized mimetype')
  });

  /**
   * cmsMedia.image.createMediaSlug
   *
   */
  it('cmsMedia.image.createMediaSlug()', function() {
    this.sinon = sinon.sandbox.create();
    var stub = sinon.stub(coreUtils.random, 'generateUniqueIdentifier')
    stub.returns(12345)
    var result = cmsMedia.image.createMediaSlug('teSt f1le s l û g', '.jpg')
    chai.expect(result).to.not.be.undefined
    chai.expect(result).to.be.a('string')
    chai.expect(result).to.equal('test-f1le-s-l-u-g-12345.jpg')
    sinon.assert.calledOnce(coreUtils.random.generateUniqueIdentifier)
    coreUtils.random.generateUniqueIdentifier.restore()
  });

  after(function(done) {
    fse.remove(path.join(config.root, config.publish.url))
    done()
  });

});<|endoftext|>


<commit_before>'use strict'

const mergeDescriptors = require('merge-descriptors')
const isObject = require('is-object')

function fill (destination, source, merge) {
  if (destination && (isObject(source) || isFunction(source))) {
    merge(destination, source, false)
    if (isFunction(destination) && isFunction(source) && source.prototype) {
      merge(destination.prototype, source.prototype, false)
    }
  }
  return destination
}

exports = module.exports = function fillKeys (destination, source) {
  return fill(destination, source, mergeDescriptors)
}

function isFunction (value) {
  return typeof value === 'function'
}
<commit_msg>rm exports assignment<commit_after>'use strict'

const mergeDescriptors = require('merge-descriptors')
const isObject = require('is-object')

function fill (destination, source, merge) {
  if (destination && (isObject(source) || isFunction(source))) {
    merge(destination, source, false)
    if (isFunction(destination) && isFunction(source) && source.prototype) {
      merge(destination.prototype, source.prototype, false)
    }
  }
  return destination
}

module.exports = function fillKeys (destination, source) {
  return fill(destination, source, mergeDescriptors)
}

function isFunction (value) {
  return typeof value === 'function'
}
<|endoftext|>


<commit_before>L.FeatureGroup.SubGroup = L.FeatureGroup.extend({

    /**
     * Instantiates a SubGroup.
     * @param parentGroup (L.LayerGroup) (optional)
     * @param layersArray (L.Layer[]) (optional)
     */
    initialize: function (parentGroup, layersArray) {
        L.FeatureGroup.prototype.initialize.call(this, layersArray);

        this.setParentGroup(parentGroup);
    },

    /**
     * Changes the parent group into which child markers are added to /
     * removed from.
     * @param parentGroup (L.LayerGroup)
     * @returns {SubGroup} this
     */
    setParentGroup: function (parentGroup) {
        var pgInstanceOfLG = parentGroup instanceof L.LayerGroup;

        this._parentGroup = parentGroup;

        // onAdd
        this.onAdd =
            pgInstanceOfLG ?
                (
                    typeof parentGroup.addLayers === "function" ?
                        this._onAddToGroupBatch :
                        this._onAddToGroup
                ) :
                this._onAddToMap;

        // onRemove
        this.onRemove =
            pgInstanceOfLG ?
                (
                    typeof parentGroup.removeLayers === "function" ?
                        this._onRemoveFromGroupBatch :
                        this._onRemoveFromGroup
                ) :
                this._onRemoveFromMap;

        // addLayer
        this.addLayer = pgInstanceOfLG ?
            this._addLayerToGroup :
            this._addLayerToMap;

        // removeLayer
        this.removeLayer = pgInstanceOfLG ?
            this._removeLayerFromGroup :
            this._removeLayerFromMap;

        return this;
    },

    /**
     * Removes the current sub-group from map before changing the parent
     * group. Re-adds the sub-group to map if it was before changing.
     * @param parentGroup (L.LayerGroup)
     * @returns {SubGroup} this
     */
    setParentGroupSafe: function (parentGroup) {
        var map = this._map;

        if (map) {
            map.removeLayer(this);
        }

        this.setParentGroup(parentGroup);

        if (map) {
            map.addLayer(this);
        }

        return this;
    },

    /**
     * Returns the current parent group.
     * @returns {*}
     */
    getParentGroup: function () {
        return this._parentGroup;
    },

    // For parent groups with batch methods (addLayers and removeLayers)
    // like MarkerCluster.
    _onAddToGroupBatch: function (map) {
        var layersArray = this.getLayers();

        this._map = map;
        this._parentGroup.addLayers(layersArray);
    },

    _onRemoveFromGroupBatch: function () {
        var layersArray = this.getLayers();

        this._parentGroup.removeLayers(layersArray);
        this._map = null;
    },

    // For other parent layer groups.
    _onAddToGroup: function (map) {
        var parentGroup = this._parentGroup;

        this._map = map;
        this.eachLayer(parentGroup.addLayer, parentGroup);
    },

    _onRemoveFromGroup: function () {
        var parentGroup = this._parentGroup;

        this.eachLayer(parentGroup.removeLayer, parentGroup);
        this._map = null;
    },

    // Defaults to standard FeatureGroup behaviour when parent group is not
    // specified or is not a type of LayerGroup.
    _onAddToMap: L.FeatureGroup.prototype.onAdd,
    _onRemoveFromMap: L.FeatureGroup.prototype.onRemove,

    _addLayerToGroup: function (layer) {
        if (this.hasLayer(layer)) {
            return this;
        }

        layer.addEventParent(this);

        var id = this.getLayerId(layer);

        this._layers[id] = layer;

        if (this._map) {
            // Add to parent group instead of directly to map.
            this._parentGroup.addLayer(layer);
        }

        return this.fire("layeradd", {layer: layer});
    },

    _removeLayerFromGroup: function (layer) {
        if (!this.hasLayer(layer)) {
            return this;
        }
        if (layer in this._layers) {
            layer = this._layers[layer];
        }

                    layer.removeEventParent(this);

        var id = layer in this._layers ? layer : this.getLayerId(layer);

        if (this._map && this._layers[id]) {
            // Remove from parent group instead of directly from map.
            this._parentGroup.removeLayer(id);
        }

        delete this._layers[id];

        return this.fire("layerremove", {layer: layer});
    },

    // Defaults to standard FeatureGroup behaviour when parent group is not
    // specified or is not a type of LayerGroup.
    _addLayerToMap: L.FeatureGroup.prototype.addLayer,
    _removeLayerFromMap: L.FeatureGroup.prototype.removeLayer

});

// Supply with a factory for consistency with Leaflet.
L.featureGroup.subGroup = function (parentGroup, options) {
    return new L.FeatureGroup.SubGroup(parentGroup, options);
};
<commit_msg>Fix(#11): Merge pull request #12 from computerminds/bug/remove-layers-markercluster<commit_after>L.FeatureGroup.SubGroup = L.FeatureGroup.extend({

    /**
     * Instantiates a SubGroup.
     * @param parentGroup (L.LayerGroup) (optional)
     * @param layersArray (L.Layer[]) (optional)
     */
    initialize: function (parentGroup, layersArray) {
        L.FeatureGroup.prototype.initialize.call(this, layersArray);

        this.setParentGroup(parentGroup);
    },

    /**
     * Changes the parent group into which child markers are added to /
     * removed from.
     * @param parentGroup (L.LayerGroup)
     * @returns {SubGroup} this
     */
    setParentGroup: function (parentGroup) {
        var pgInstanceOfLG = parentGroup instanceof L.LayerGroup;

        this._parentGroup = parentGroup;

        // onAdd
        this.onAdd =
            pgInstanceOfLG ?
                (
                    typeof parentGroup.addLayers === "function" ?
                        this._onAddToGroupBatch :
                        this._onAddToGroup
                ) :
                this._onAddToMap;

        // onRemove
        this.onRemove =
            pgInstanceOfLG ?
                (
                    typeof parentGroup.removeLayers === "function" ?
                        this._onRemoveFromGroupBatch :
                        this._onRemoveFromGroup
                ) :
                this._onRemoveFromMap;

        // addLayer
        this.addLayer = pgInstanceOfLG ?
            this._addLayerToGroup :
            this._addLayerToMap;

        // removeLayer
        this.removeLayer = pgInstanceOfLG ?
            this._removeLayerFromGroup :
            this._removeLayerFromMap;

        return this;
    },

    /**
     * Removes the current sub-group from map before changing the parent
     * group. Re-adds the sub-group to map if it was before changing.
     * @param parentGroup (L.LayerGroup)
     * @returns {SubGroup} this
     */
    setParentGroupSafe: function (parentGroup) {
        var map = this._map;

        if (map) {
            map.removeLayer(this);
        }

        this.setParentGroup(parentGroup);

        if (map) {
            map.addLayer(this);
        }

        return this;
    },

    /**
     * Returns the current parent group.
     * @returns {*}
     */
    getParentGroup: function () {
        return this._parentGroup;
    },

    // For parent groups with batch methods (addLayers and removeLayers)
    // like MarkerCluster.
    _onAddToGroupBatch: function (map) {
        var layersArray = this.getLayers();

        this._map = map;
        this._parentGroup.addLayers(layersArray);
    },

    _onRemoveFromGroupBatch: function () {
        var layersArray = this.getLayers();

        this._parentGroup.removeLayers(layersArray);
        this._map = null;
    },

    // For other parent layer groups.
    _onAddToGroup: function (map) {
        var parentGroup = this._parentGroup;

        this._map = map;
        this.eachLayer(parentGroup.addLayer, parentGroup);
    },

    _onRemoveFromGroup: function () {
        var parentGroup = this._parentGroup;

        this.eachLayer(parentGroup.removeLayer, parentGroup);
        this._map = null;
    },

    // Defaults to standard FeatureGroup behaviour when parent group is not
    // specified or is not a type of LayerGroup.
    _onAddToMap: L.FeatureGroup.prototype.onAdd,
    _onRemoveFromMap: L.FeatureGroup.prototype.onRemove,

    _addLayerToGroup: function (layer) {
        if (this.hasLayer(layer)) {
            return this;
        }

        layer.addEventParent(this);

        var id = this.getLayerId(layer);

        this._layers[id] = layer;

        if (this._map) {
            // Add to parent group instead of directly to map.
            this._parentGroup.addLayer(layer);
        }

        return this.fire("layeradd", {layer: layer});
    },

    _removeLayerFromGroup: function (layer) {
        if (!this.hasLayer(layer)) {
            return this;
        }
        if (layer in this._layers) {
            layer = this._layers[layer];
        }

                    layer.removeEventParent(this);

        var id = layer in this._layers ? layer : this.getLayerId(layer);

        if (this._map && this._layers[id]) {
            // Remove from parent group instead of directly from map.
            this._parentGroup.removeLayer(this._layers[id]);
        }

        delete this._layers[id];

        return this.fire("layerremove", {layer: layer});
    },

    // Defaults to standard FeatureGroup behaviour when parent group is not
    // specified or is not a type of LayerGroup.
    _addLayerToMap: L.FeatureGroup.prototype.addLayer,
    _removeLayerFromMap: L.FeatureGroup.prototype.removeLayer

});

// Supply with a factory for consistency with Leaflet.
L.featureGroup.subGroup = function (parentGroup, options) {
    return new L.FeatureGroup.SubGroup(parentGroup, options);
};
<|endoftext|>


<commit_before>/*global beforeEach, afterEach, describe, it, inject, expect, module, spyOn, CodeMirror, angular, $*/
/**
 * TODO Test all the CodeMirror events : cursorActivity viewportChange gutterClick focus blur scroll update.
 *      with  <textarea ui-codemirror="{onChange: doChange ,onCursorActivity: doSomething}" ng-model="foo">
 *
 */
describe('uiCodemirror', function () {
	'use strict';

	// declare these up here to be global to all tests
	var scope, $compile, $timeout, uiConfig;

	beforeEach(module('ui.codemirror'));
	beforeEach(inject(function (uiCodemirrorConfig) {
    uiConfig = uiCodemirrorConfig;
    uiConfig.codemirror = {bar: 'baz'};

	}));

	// inject in angular constructs. Injector knows about leading/trailing underscores and does the right thing
	// otherwise, you would need to inject these into each test
	beforeEach(inject(function (_$rootScope_, _$compile_, _$timeout_) {
		scope = _$rootScope_.$new();
		$compile = _$compile_;
		$timeout = _$timeout_;
	}));

	afterEach(function () {
		uiConfig = {};
	});

	describe('compiling this directive', function () {
		it('should throw an error if used against a non-textarea', function () {
			function compile() {
				$compile('

')(scope);
			}

			expect(compile).toThrow();
		});

		it('should not throw an error when used against a textarea', function () {
			function compile() {
				$compile('<textarea ui-codemirror ng-model="foo"></textarea>')(scope);
			}

			expect(compile).not.toThrow();
		});

		it('should throw an error when no ngModel attribute defined', function () {
			function compile() {
				$compile('<textarea ui-codemirror></textarea>')(scope);
			}

			expect(compile).toThrow();
		});

		it('should watch the uiCodemirror attribute', function () {
			spyOn(scope, '$watch');
      // Must have a parentNode for insertBefore (see https://github.com/marijnh/CodeMirror/blob/v3.11/lib/codemirror.js#L3390)
			$compile('
<textarea ui-codemirror ng-model="foo" uiRefresh="sdf"></textarea>
')(scope);
			$timeout.flush();
			expect(scope.$watch).toHaveBeenCalled();
		});
	});

	describe('while spying on the CodeMirror instance', function () {

		var codemirror;

		beforeEach(function () {
			var fromTextArea = CodeMirror.fromTextArea;
			spyOn(CodeMirror, 'fromTextArea').andCallFake(function () {
				codemirror = fromTextArea.apply(this, arguments);
				return codemirror;
			});
		});

		describe('verify the directive options', function () {
			it('should include the passed options', function () {
        // Must have a parentNode for insertBefore (see https://github.com/marijnh/CodeMirror/blob/v3.11/lib/codemirror.js#L3390)
				$compile('
<textarea ui-codemirror="{oof: \'baar\'}" ng-model="foo"></textarea>
')(scope);
				$timeout.flush();
				expect(CodeMirror.fromTextArea.mostRecentCall.args[1].oof).toEqual("baar");
			});

			it('should include the default options', function () {
        // Must have a parentNode for insertBefore (see https://github.com/marijnh/CodeMirror/blob/v3.11/lib/codemirror.js#L3390)
				$compile('
<textarea ui-codemirror ng-model="foo"></textarea>
')(scope);
				$timeout.flush();
				expect(CodeMirror.fromTextArea.mostRecentCall.args[1].bar).toEqual('baz');
			});
		});

		describe('when uiRefresh is added', function () {
			it('should trigger the CodeMirror.refresh() method', function () {
        // Must have a parentNode for insertBefore (see https://github.com/marijnh/CodeMirror/blob/v3.11/lib/codemirror.js#L3390)
				$compile('
<textarea ui-codemirror ng-model="foo" ui-refresh="bar"></textarea>
')(scope);
				$timeout.flush();
				var spy = spyOn(codemirror, 'refresh');
				scope.$apply('bar = true');
				$timeout.flush();
				expect(codemirror.refresh).toHaveBeenCalled();
        scope.$apply('bar = false');
        $timeout.flush();
        expect(spy.callCount).toEqual(2);
			});
		});

		describe('when the IDE changes', function () {
			it('should update the model', function () {
        // Must have a parentNode for insertBefore (see https://github.com/marijnh/CodeMirror/blob/v3.11/lib/codemirror.js#L3390)
				$compile('
<textarea ui-codemirror ng-model="foo"></textarea>
')(scope);
				scope.$apply("foo = 'bar'");
				$timeout.flush();
				var value = 'baz';
				codemirror.setValue(value);
				expect(scope.foo).toBe(value);
			});
		});

		describe('when the model changes', function () {
			it('should update the IDE', function () {
        // Must have a parentNode for insertBefore (see https://github.com/marijnh/CodeMirror/blob/v3.11/lib/codemirror.js#L3390)
				var element = $compile('
<textarea ui-codemirror ng-model="foo"></textarea>
')(scope);
				scope.foo = 'bar';
				scope.$apply();
				$timeout.flush();
				expect(codemirror.getValue()).toBe(scope.foo);
			});
		});

		describe('when the model is undefined/null', function () {
			it('should update the IDE with an empty string', function () {
        // Must have a parentNode for insertBefore (see https://github.com/marijnh/CodeMirror/blob/v3.11/lib/codemirror.js#L3390)
				var element = $compile('
<textarea ui-codemirror ng-model="foo"></textarea>
')(scope);
				scope.$apply();
				$timeout.flush();
				expect(scope.foo).toBe(undefined);
				expect(codemirror.getValue()).toBe('');
				scope.$apply('foo = "bar"');
				expect(scope.foo).toBe('bar');
				expect(codemirror.getValue()).toBe('bar');
				scope.$apply('foo = null');
				expect(scope.foo).toBe(null);
				expect(codemirror.getValue()).toBe('');
			});
		});

    it('should runs the onLoad callback', function () {
      scope.codemirrorLoaded = function () {};
      spyOn(scope, "codemirrorLoaded");
      // Must have a parentNode for insertBefore (see https://github.com/marijnh/CodeMirror/blob/v3.11/lib/codemirror.js#L3390)
      $compile('
<textarea ui-codemirror="{onLoad: codemirrorLoaded}" ng-model="foo"></textarea>
')(scope);
      $timeout.flush();
      expect(scope.codemirrorLoaded).toHaveBeenCalled();
      expect(scope.codemirrorLoaded).toHaveBeenCalledWith(codemirror);
    });
	});

	describe('when the model is an object or an array', function () {
		it('should throw an error', function () {
			function compileWithObject() {
				$compile('<textarea ui-codemirror ng-model="foo"></textarea>')(scope);
				$timeout.flush();
				scope.foo = {};
				scope.$apply();
			}

			function compileWithArray() {
				$compile('<textarea ui-codemirror ng-model="foo"></textarea>')(scope);
				$timeout.flush();
				scope.foo = [];
				scope.$apply();
			}

			expect(compileWithObject).toThrow();
			expect(compileWithArray).toThrow();
		});
	});
});<commit_msg>[M] Add test : should watch ui-codemirror options. Close #7.<commit_after>/*global beforeEach, afterEach, describe, it, inject, expect, module, spyOn, CodeMirror, angular, $*/
/**
 * TODO Test all the CodeMirror events : cursorActivity viewportChange gutterClick focus blur scroll update.
 *      with  <textarea ui-codemirror="{onChange: doChange ,onCursorActivity: doSomething}" ng-model="foo">
 *
 */
describe('uiCodemirror', function () {
	'use strict';

	// declare these up here to be global to all tests
	var scope, $compile, $timeout, uiConfig;

	beforeEach(module('ui.codemirror'));
	beforeEach(inject(function (uiCodemirrorConfig) {
    uiConfig = uiCodemirrorConfig;
    uiConfig.codemirror = {bar: 'baz'};

	}));

	// inject in angular constructs. Injector knows about leading/trailing underscores and does the right thing
	// otherwise, you would need to inject these into each test
	beforeEach(inject(function (_$rootScope_, _$compile_, _$timeout_) {
		scope = _$rootScope_.$new();
		$compile = _$compile_;
		$timeout = _$timeout_;
	}));

	afterEach(function () {
		uiConfig = {};
	});

	describe('compiling this directive', function () {
		it('should throw an error if used against a non-textarea', function () {
			function compile() {
				$compile('

')(scope);
			}

			expect(compile).toThrow();
		});

		it('should not throw an error when used against a textarea', function () {
			function compile() {
				$compile('<textarea ui-codemirror ng-model="foo"></textarea>')(scope);
			}

			expect(compile).not.toThrow();
		});

		it('should throw an error when no ngModel attribute defined', function () {
			function compile() {
				$compile('<textarea ui-codemirror></textarea>')(scope);
			}

			expect(compile).toThrow();
		});

		it('should watch the uiCodemirror attribute', function () {
			spyOn(scope, '$watch');
      // Must have a parentNode for insertBefore (see https://github.com/marijnh/CodeMirror/blob/v3.11/lib/codemirror.js#L3390)
			$compile('
<textarea ui-codemirror ng-model="foo" uiRefresh="sdf"></textarea>
')(scope);
			$timeout.flush();
			expect(scope.$watch).toHaveBeenCalled();
		});
	});

	describe('while spying on the CodeMirror instance', function () {

		var codemirror;

		beforeEach(function () {
			var fromTextArea = CodeMirror.fromTextArea;
			spyOn(CodeMirror, 'fromTextArea').andCallFake(function () {
				codemirror = fromTextArea.apply(this, arguments);
				return codemirror;
			});
		});

		describe('verify the directive options', function () {
			it('should include the passed options', function () {
        // Must have a parentNode for insertBefore (see https://github.com/marijnh/CodeMirror/blob/v3.11/lib/codemirror.js#L3390)
				$compile('
<textarea ui-codemirror="{oof: \'baar\'}" ng-model="foo"></textarea>
')(scope);
				$timeout.flush();
				expect(CodeMirror.fromTextArea.mostRecentCall.args[1].oof).toEqual("baar");
			});

			it('should include the default options', function () {
        // Must have a parentNode for insertBefore (see https://github.com/marijnh/CodeMirror/blob/v3.11/lib/codemirror.js#L3390)
				$compile('
<textarea ui-codemirror ng-model="foo"></textarea>
')(scope);
				$timeout.flush();
				expect(CodeMirror.fromTextArea.mostRecentCall.args[1].bar).toEqual('baz');
			});
		});

		describe('when uiRefresh is added', function () {
			it('should trigger the CodeMirror.refresh() method', function () {
        // Must have a parentNode for insertBefore (see https://github.com/marijnh/CodeMirror/blob/v3.11/lib/codemirror.js#L3390)
				$compile('
<textarea ui-codemirror ng-model="foo" ui-refresh="bar"></textarea>
')(scope);
				$timeout.flush();
				var spy = spyOn(codemirror, 'refresh');
				scope.$apply('bar = true');
				$timeout.flush();
				expect(codemirror.refresh).toHaveBeenCalled();
        scope.$apply('bar = false');
        $timeout.flush();
        expect(spy.callCount).toEqual(2);
			});
		});

		describe('when the IDE changes', function () {
			it('should update the model', function () {
        // Must have a parentNode for insertBefore (see https://github.com/marijnh/CodeMirror/blob/v3.11/lib/codemirror.js#L3390)
				$compile('
<textarea ui-codemirror ng-model="foo"></textarea>
')(scope);
				scope.$apply("foo = 'bar'");
				$timeout.flush();
				var value = 'baz';
				codemirror.setValue(value);
				expect(scope.foo).toBe(value);
			});
		});

		describe('when the model changes', function () {
			it('should update the IDE', function () {
        // Must have a parentNode for insertBefore (see https://github.com/marijnh/CodeMirror/blob/v3.11/lib/codemirror.js#L3390)
				var element = $compile('
<textarea ui-codemirror ng-model="foo"></textarea>
')(scope);
				scope.foo = 'bar';
				scope.$apply();
				$timeout.flush();
				expect(codemirror.getValue()).toBe(scope.foo);
			});
		});

		describe('when the model is undefined/null', function () {
			it('should update the IDE with an empty string', function () {
        // Must have a parentNode for insertBefore (see https://github.com/marijnh/CodeMirror/blob/v3.11/lib/codemirror.js#L3390)
				var element = $compile('
<textarea ui-codemirror ng-model="foo"></textarea>
')(scope);
				scope.$apply();
				$timeout.flush();
				expect(scope.foo).toBe(undefined);
				expect(codemirror.getValue()).toBe('');
				scope.$apply('foo = "bar"');
				expect(scope.foo).toBe('bar');
				expect(codemirror.getValue()).toBe('bar');
				scope.$apply('foo = null');
				expect(scope.foo).toBe(null);
				expect(codemirror.getValue()).toBe('');
			});
		});

    it('should runs the onLoad callback', function () {
      scope.codemirrorLoaded = function () {};
      spyOn(scope, "codemirrorLoaded");
      // Must have a parentNode for insertBefore (see https://github.com/marijnh/CodeMirror/blob/v3.11/lib/codemirror.js#L3390)
      $compile('
<textarea ui-codemirror="{onLoad: codemirrorLoaded}" ng-model="foo"></textarea>
')(scope);
      $timeout.flush();
      expect(scope.codemirrorLoaded).toHaveBeenCalled();
      expect(scope.codemirrorLoaded).toHaveBeenCalledWith(codemirror);
    });

    it('should watch the options', function () {
      var __watcher = scope.$watch;
      spyOn(scope, '$watch').andCallFake(__watcher);

      // Must have a parentNode for insertBefore (see https://github.com/marijnh/CodeMirror/blob/v3.11/lib/codemirror.js#L3390)
      $compile('
<textarea ui-codemirror="cmOption" ng-model="foo"></textarea>
')(scope);
      scope.cmOption = { readOnly : true };
      $timeout.flush();

      expect(scope.$watch.callCount).toEqual(2); // The ngModel + the uiCodemirror
      expect(scope.$watch).toHaveBeenCalledWith('cmOption', jasmine.any(Function), true);
      expect(codemirror.getOption('readOnly')).toBeTruthy();

      scope.cmOption.readOnly = false;
      scope.$digest();
      expect(codemirror.getOption('readOnly')).toBeFalsy();
    });
	});

	describe('when the model is an object or an array', function () {
		it('should throw an error', function () {
			function compileWithObject() {
				$compile('<textarea ui-codemirror ng-model="foo"></textarea>')(scope);
				$timeout.flush();
				scope.foo = {};
				scope.$apply();
			}

			function compileWithArray() {
				$compile('<textarea ui-codemirror ng-model="foo"></textarea>')(scope);
				$timeout.flush();
				scope.foo = [];
				scope.$apply();
			}

			expect(compileWithObject).toThrow();
			expect(compileWithArray).toThrow();
		});
	});
});<|endoftext|>


<commit_before>// Dependencies
var path = require('path')

// Generate absolute paths
// to styles packages
function pathToModule (style) {
  return path.join(__dirname,
    '..',
    'node_modules',
    style,
    'bin'
  )
}

module.exports = {
  standard: pathToModule('standard'),
  semiStandard: pathToModule('semistandard'),
  happiness: pathToModule('happiness')
}
<commit_msg>add complete path to bin<commit_after>// Dependencies
var path = require('path')

// Generate absolute paths
// to styles packages
function pathToModule (style) {
  return path.join(__dirname,
    '..',
    'node_modules',
    style,
    'bin',
    'cmd.js'
  )
}

module.exports = {
  standard: pathToModule('standard'),
  semiStandard: pathToModule('semistandard'),
  happiness: pathToModule('happiness')
}
<|endoftext|>


<commit_before>'use strict';

var url = require('url');
var getProxy = require('get-proxy');
var got = require('got');

module.exports = function (items, cb) {
	var opts = {};
	var proxy = getProxy();

	if (typeof items === 'function' && !cb) {
		cb = items;
		items = [];
	}

	if (proxy) {
		opts.host = url.parse(proxy).hostname;
		opts.port = url.parse(proxy).port;
		opts.path = 'http://viewportsizes.com/devices.json';
		opts.headers = {Host: 'http://viewportsizes.com/devices.json'};
	}

	if (items.length) {
		items = items.map(function (item) {
			return item.split(' ').join('').toLowerCase();
		});
	}

	got('http://viewportsizes.com/devices.json', opts, function (err, res) {
		if (err) {
			cb(err);
			return;
		}

		var ret = [];
		var sizes = JSON.parse(res).map(function (size) {
			return {
				name: size['Device Name'].toLowerCase(),
				platform: size.Platform.toLowerCase(),
				os: size['OS Version'].toLowerCase(),
				size: size['Portrait Width'] + 'x' + size['Landscape Width'],
				release: size['Release Date']
			};
		});

		if (!items.length) {
			cb(null, sizes);
			return;
		}

		items.forEach(function (item) {
			sizes.filter(function (size) {
				return size.name.split(' ').join('').indexOf(item) !== -1;
			}).forEach(function (size) {
				ret.push(size);
			});
		});

		if (!ret.length) {
			cb(new Error('Couldn\'t get any items'));
			return;
		}

		cb(null, ret);
	});
};
<commit_msg>Use `json` option in `got`<commit_after>'use strict';

var url = require('url');
var getProxy = require('get-proxy');
var got = require('got');

module.exports = function (items, cb) {
	var opts = {json: true};
	var proxy = getProxy();

	if (typeof items === 'function' && !cb) {
		cb = items;
		items = [];
	}

	if (proxy) {
		opts.host = url.parse(proxy).hostname;
		opts.port = url.parse(proxy).port;
		opts.path = 'http://viewportsizes.com/devices.json';
		opts.headers = {Host: 'http://viewportsizes.com/devices.json'};
	}

	if (items.length) {
		items = items.map(function (item) {
			return item.split(' ').join('').toLowerCase();
		});
	}

	got('http://viewportsizes.com/devices.json', opts, function (err, res) {
		if (err) {
			cb(err);
			return;
		}

		var ret = [];
		var sizes = res.map(function (size) {
			return {
				name: size['Device Name'].toLowerCase(),
				platform: size.Platform.toLowerCase(),
				os: size['OS Version'].toLowerCase(),
				size: size['Portrait Width'] + 'x' + size['Landscape Width'],
				release: size['Release Date']
			};
		});

		if (!items.length) {
			cb(null, sizes);
			return;
		}

		items.forEach(function (item) {
			sizes.filter(function (size) {
				return size.name.split(' ').join('').indexOf(item) !== -1;
			}).forEach(function (size) {
				ret.push(size);
			});
		});

		if (!ret.length) {
			cb(new Error('Couldn\'t get any items'));
			return;
		}

		cb(null, ret);
	});
};
<|endoftext|>