<commit_before>/*global app, me, client, URL*/
"use strict";

var _ = require('underscore');
var crypto = require('crypto');
var async = require('async');
var uuid = require('node-uuid');
var HumanModel = require('human-model');
var Resources = require('./resources');
var Messages = require('./messages');
var Message = require('./message');
var logger = require('andlog');
var fetchAvatar = require('../helpers/fetchAvatar');

module.exports = HumanModel.define({
    initialize: function (attrs) {
        if (attrs.jid) {
            this.id = attrs.jid;
        }
        this.setAvatar(attrs.avatarID);

        this.resources.bind('add remove reset', this.onResourceListChange, this);
        this.resources.bind('change', this.onResourceChange, this);

        this.bind('change:topResource change:lockedResource change:_forceUpdate', this.summarizeResources, this);
    },
    type: 'contact',
    props: {
        id: ['string', true, false],
        avatarID: ['string', false, ''],
        groups: ['array', false, []],
        inRoster: ['bool', true, false],
        jid: ['string', true],
        name: ['string', false, ''],
        owner: ['string', true, ''],
        storageId: ['string', true, ''],
        subscription: ['string', false, 'none']
    },
    session: {
        activeContact: ['bool', false, false],
        avatar: 'string',
        avatarSource: 'string',
        lastInteraction: 'date',
        lastHistoryFetch: 'date',
        lastSentMessage: 'object',
        lockedResource: 'string',
        offlineStatus: ['string', false, ''],
        topResource: 'string',
        unreadCount: ['number', false, 0],
        _forceUpdate: ['number', false, 0],
        onCall: ['boolean', false, false],
        stream: 'object'
    },
    derived: {
        streamUrl: {
            deps: ['stream'],
            cache: true,
            fn: function () {
                if (!this.stream) return '';
                return URL.createObjectURL(this.stream);
            }
        },
        displayName: {
            deps: ['name', 'jid'],
            fn: function () {
                return this.name || this.jid;
            }
        },
        displayUnreadCount: {
            deps: ['unreadCount'],
            fn: function () {
                if (this.unreadCount > 0) {
                    return this.unreadCount.toString();
                }
                return '';
            }
        },
        formattedTZO: {
            deps: ['timezoneOffset'],
            fn: function () {
                if (!this.timezoneOffset) return '';

                var localTime = new Date();
                var localTZO = localTime.getTimezoneOffset();
                var diff = Math.abs(localTZO  % (24 * 60) - this.timezoneOffset % (24 * 60));
                var remoteTime = new Date(Date.now() + diff * 60000);

                var day = remoteTime.getDate();
                var hour = remoteTime.getHours();
                var minutes = remoteTime.getMinutes();

                var days = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];

                var dow = days[remoteTime.getDay()];
                var localDow = days[localTime.getDay()];

                var m = (hour >= 12) ? ' PM' : ' AM';

                hour = hour % 12;
                if (hour === 0) {
                    hour = 12;
                }

                var strDay = (day < 10) ? '0' + day : day;
                var strHour = (hour < 10) ? '0' + hour : hour;
                var strMin = (minutes < 10) ? '0' + minutes: minutes;

                if (localDow == dow) {
                    return strHour + ':' + strMin + m;
                } else {
                    return dow + ' ' + strHour + ':' + strMin + m;
                }
            }
        },
        status: {
            deps: ['topResource', 'lockedResource', '_forceUpdate'],
            fn: function () {
                var resource = this.resources.get(this.lockedResource) || this.resources.get(this.topResource) || {};
                return resource.status || '';
            }
        },
        show: {
            deps: ['topResource', 'lockedResource', '_forceUpdate'],
            fn: function () {
                if (this.resources.length === 0) {
                    return 'offline';
                }
                var resource = this.resources.get(this.lockedResource) || this.resources.get(this.topResource) || {};
                return resource.show || 'online';
            }
        },
        timezoneOffset: {
            deps: ['topResource', 'lockedResource', '_forceUpdate'],
            fn: function () {
                var resource = this.resources.get(this.lockedResource) || this.resources.get(this.topResource) || {};
                return resource.timezoneOffset || undefined;
            }
        },
        idleSince: {
            deps: ['topResource', 'lockedResource', '_forceUpdate'],
            fn: function () {
                var resource = this.resources.get(this.lockedResource) || this.resources.get(this.topResource) || {};
                return resource.idleSince || undefined;
            }
        },
        idle: {
            deps: ['idleSince'],
            fn: function () {
                return this.idleSince && !isNaN(this.idleSince.valueOf());
            }
        },
        chatState: {
            deps: ['topResource', 'lockedResource', '_forceUpdate'],
            fn: function () {
                var states = {};
                this.resources.models.forEach(function (resource) {
                    states[resource.chatState] = true;
                });

                if (states.composing) return 'composing';
                if (states.paused) return 'paused';
                if (states.active) return 'active';
                if (states.inactive) return 'inactive';
                return 'gone';
            }
        },
        supportsReceipts: {
            deps: ['lockedResource', '_forceUpdate'],
            fn: function () {
                if (!this.lockedResource) return false;
                var res = this.resources.get(this.lockedResource);
                return res.supportsReceipts;
            }
        },
        supportsChatStates: {
            deps: ['lockedResource', '_forceUpdate'],
            fn: function () {
                if (!this.lockedResource) return false;
                var res = this.resources.get(this.lockedResource);
                return res.supportsChatStates;
            }
        },
        hasUnread: {
            deps: ['unreadCount'],
            fn: function () {
                return this.unreadCount > 0;
            }
        },
        jingleResources: {
            deps: ['_forceUpdate'],
            fn: function () {
                return this.resources.filter(function (res) {
                    return res.supportsJingleMedia;
                });
            }
        },
        callable: {
            deps: ['jingleResources'],
            fn: function () {
                return !!this.jingleResources.length;
            }
        },
        callObject: {
            fn: function () {
                return app.calls.where('contact', this);
            }
        }
    },
    collections: {
        resources: Resources,
        messages: Messages
    },
    call: function () {
        if (this.jingleResources.length) {
            var peer = this.jingleResources[0];
            this.callState = 'starting';
            app.api.call(peer.id);
        } else {
            logger.error('no jingle resources for this user');
        }
    },
    setAvatar: function (id, type, source) {
        var self = this;
        fetchAvatar(this.jid, id, type, source, function (avatar) {
            if (source == 'vcard' && self.avatarSource == 'pubsub') return;
            self.avatarID = avatar.id;
            self.avatar = avatar.uri;
            self.avaarSource = source;
            self.save();
        });
    },
    onResourceChange: function () {
        this.resources.sort();
        this.topResource = (this.resources.first() || {}).id;
        this._forceUpdate++;
    },
    onResourceListChange: function () {
        // Manually propagate change events for properties that
        // depend on the resources collection.
        this.resources.sort();

        var res = this.resources.first();
        if (res) {
            this.offlineStatus = '';
            this.topResource = res.id;
        } else {
            this.topResource = undefined;
        }

        this.lockedResource = undefined;
    },
    addMessage: function (message, notify) {
        message.owner = me.jid.bare;

        if (notify && (!this.activeContact || (this.activeContact && !app.state.focused)) && message.from.bare === this.jid) {
            this.unreadCount++;
            app.notifications.create(this.displayName, {
                body: message.body,
                icon: this.avatar,
                tag: this.jid,
                onclick: _.bind(app.navigate, app, '/chat/' + this.jid)
            });
        }

        var existing = Message.idLookup(message.from[message.type == 'groupchat' ? 'full' : 'bare'], message.mid);
        if (existing) {
            existing.set(message);
            existing.save();
        } else {
            this.messages.add(message);
            message.save();
        }

        var newInteraction = new Date(message.created);
        if (!this.lastInteraction || this.lastInteraction < newInteraction) {
            this.lastInteraction = newInteraction;
        }
    },
    fetchHistory: function () {
        var self = this;
        app.whenConnected(function () {
            var filter = {
                'with': self.jid,
                rsm: {
                    count: 20,
                    before: true
                }
            };

            var lastMessage = self.messages.last();
            if (lastMessage && lastMessage.archivedId) {
                filter.rsm.after = lastMessage.archivedId;
            }

            if (self.lastHistoryFetch && !isNaN(self.lastHistoryFetch.valueOf())) {
                if (self.lastInteraction > self.lastHistoryFetch) {
                    filter.start = self.lastInteraction;
                } else {
                    filter.start = self.lastHistoryFetch;
                }
            } else {
                filter.end = new Date(Date.now());
            }

            client.getHistory(filter, function (err, res) {
                if (err) return;

                self.lastHistoryFetch = new Date(Date.now());

                var results = res.mamQuery.results || [];
                results.reverse();
                results.forEach(function (result) {
                    result = result.toJSON();
                    var msg = result.mam.forwarded.message;

                    msg.mid = msg.id;
                    delete msg.id;

                    if (!msg.delay) {
                        msg.delay = result.mam.forwarded.delay;
                    }

                    if (msg.replace) {
                        var original = Message.idLookup(msg.from[msg.type == 'groupchat' ? 'full' : 'bare'], msg.replace);
                        // Drop the message if editing a previous, but
                        // keep it if it didn't actually change an
                        // existing message.
                        if (original && original.correct(msg)) return;
                    }

                    var message = new Message(msg);
                    message.archivedId = result.mam.id;
                    message.acked = true;

                    self.addMessage(message, false);
                });
            });
        });
    },
    save: function () {
        if (!this.inRoster) return;

        var storageId = crypto.createHash('sha1').update(this.owner + '/' + this.id).digest('hex');
        var data = {
            storageId: storageId,
            owner: this.owner,
            jid: this.jid,
            name: this.name,
            groups: this.groups,
            subscription: this.subscription,
            avatarID: this.avatarID
        };
        app.storage.roster.add(data);
    }
});
<commit_msg>typo: avaarSource<commit_after>/*global app, me, client, URL*/
"use strict";

var _ = require('underscore');
var crypto = require('crypto');
var async = require('async');
var uuid = require('node-uuid');
var HumanModel = require('human-model');
var Resources = require('./resources');
var Messages = require('./messages');
var Message = require('./message');
var logger = require('andlog');
var fetchAvatar = require('../helpers/fetchAvatar');

module.exports = HumanModel.define({
    initialize: function (attrs) {
        if (attrs.jid) {
            this.id = attrs.jid;
        }
        this.setAvatar(attrs.avatarID);

        this.resources.bind('add remove reset', this.onResourceListChange, this);
        this.resources.bind('change', this.onResourceChange, this);

        this.bind('change:topResource change:lockedResource change:_forceUpdate', this.summarizeResources, this);
    },
    type: 'contact',
    props: {
        id: ['string', true, false],
        avatarID: ['string', false, ''],
        groups: ['array', false, []],
        inRoster: ['bool', true, false],
        jid: ['string', true],
        name: ['string', false, ''],
        owner: ['string', true, ''],
        storageId: ['string', true, ''],
        subscription: ['string', false, 'none']
    },
    session: {
        activeContact: ['bool', false, false],
        avatar: 'string',
        avatarSource: 'string',
        lastInteraction: 'date',
        lastHistoryFetch: 'date',
        lastSentMessage: 'object',
        lockedResource: 'string',
        offlineStatus: ['string', false, ''],
        topResource: 'string',
        unreadCount: ['number', false, 0],
        _forceUpdate: ['number', false, 0],
        onCall: ['boolean', false, false],
        stream: 'object'
    },
    derived: {
        streamUrl: {
            deps: ['stream'],
            cache: true,
            fn: function () {
                if (!this.stream) return '';
                return URL.createObjectURL(this.stream);
            }
        },
        displayName: {
            deps: ['name', 'jid'],
            fn: function () {
                return this.name || this.jid;
            }
        },
        displayUnreadCount: {
            deps: ['unreadCount'],
            fn: function () {
                if (this.unreadCount > 0) {
                    return this.unreadCount.toString();
                }
                return '';
            }
        },
        formattedTZO: {
            deps: ['timezoneOffset'],
            fn: function () {
                if (!this.timezoneOffset) return '';

                var localTime = new Date();
                var localTZO = localTime.getTimezoneOffset();
                var diff = Math.abs(localTZO  % (24 * 60) - this.timezoneOffset % (24 * 60));
                var remoteTime = new Date(Date.now() + diff * 60000);

                var day = remoteTime.getDate();
                var hour = remoteTime.getHours();
                var minutes = remoteTime.getMinutes();

                var days = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];

                var dow = days[remoteTime.getDay()];
                var localDow = days[localTime.getDay()];

                var m = (hour >= 12) ? ' PM' : ' AM';

                hour = hour % 12;
                if (hour === 0) {
                    hour = 12;
                }

                var strDay = (day < 10) ? '0' + day : day;
                var strHour = (hour < 10) ? '0' + hour : hour;
                var strMin = (minutes < 10) ? '0' + minutes: minutes;

                if (localDow == dow) {
                    return strHour + ':' + strMin + m;
                } else {
                    return dow + ' ' + strHour + ':' + strMin + m;
                }
            }
        },
        status: {
            deps: ['topResource', 'lockedResource', '_forceUpdate'],
            fn: function () {
                var resource = this.resources.get(this.lockedResource) || this.resources.get(this.topResource) || {};
                return resource.status || '';
            }
        },
        show: {
            deps: ['topResource', 'lockedResource', '_forceUpdate'],
            fn: function () {
                if (this.resources.length === 0) {
                    return 'offline';
                }
                var resource = this.resources.get(this.lockedResource) || this.resources.get(this.topResource) || {};
                return resource.show || 'online';
            }
        },
        timezoneOffset: {
            deps: ['topResource', 'lockedResource', '_forceUpdate'],
            fn: function () {
                var resource = this.resources.get(this.lockedResource) || this.resources.get(this.topResource) || {};
                return resource.timezoneOffset || undefined;
            }
        },
        idleSince: {
            deps: ['topResource', 'lockedResource', '_forceUpdate'],
            fn: function () {
                var resource = this.resources.get(this.lockedResource) || this.resources.get(this.topResource) || {};
                return resource.idleSince || undefined;
            }
        },
        idle: {
            deps: ['idleSince'],
            fn: function () {
                return this.idleSince && !isNaN(this.idleSince.valueOf());
            }
        },
        chatState: {
            deps: ['topResource', 'lockedResource', '_forceUpdate'],
            fn: function () {
                var states = {};
                this.resources.models.forEach(function (resource) {
                    states[resource.chatState] = true;
                });

                if (states.composing) return 'composing';
                if (states.paused) return 'paused';
                if (states.active) return 'active';
                if (states.inactive) return 'inactive';
                return 'gone';
            }
        },
        supportsReceipts: {
            deps: ['lockedResource', '_forceUpdate'],
            fn: function () {
                if (!this.lockedResource) return false;
                var res = this.resources.get(this.lockedResource);
                return res.supportsReceipts;
            }
        },
        supportsChatStates: {
            deps: ['lockedResource', '_forceUpdate'],
            fn: function () {
                if (!this.lockedResource) return false;
                var res = this.resources.get(this.lockedResource);
                return res.supportsChatStates;
            }
        },
        hasUnread: {
            deps: ['unreadCount'],
            fn: function () {
                return this.unreadCount > 0;
            }
        },
        jingleResources: {
            deps: ['_forceUpdate'],
            fn: function () {
                return this.resources.filter(function (res) {
                    return res.supportsJingleMedia;
                });
            }
        },
        callable: {
            deps: ['jingleResources'],
            fn: function () {
                return !!this.jingleResources.length;
            }
        },
        callObject: {
            fn: function () {
                return app.calls.where('contact', this);
            }
        }
    },
    collections: {
        resources: Resources,
        messages: Messages
    },
    call: function () {
        if (this.jingleResources.length) {
            var peer = this.jingleResources[0];
            this.callState = 'starting';
            app.api.call(peer.id);
        } else {
            logger.error('no jingle resources for this user');
        }
    },
    setAvatar: function (id, type, source) {
        var self = this;
        fetchAvatar(this.jid, id, type, source, function (avatar) {
            if (source == 'vcard' && self.avatarSource == 'pubsub') return;
            self.avatarID = avatar.id;
            self.avatar = avatar.uri;
            self.avatarSource = source;
            self.save();
        });
    },
    onResourceChange: function () {
        this.resources.sort();
        this.topResource = (this.resources.first() || {}).id;
        this._forceUpdate++;
    },
    onResourceListChange: function () {
        // Manually propagate change events for properties that
        // depend on the resources collection.
        this.resources.sort();

        var res = this.resources.first();
        if (res) {
            this.offlineStatus = '';
            this.topResource = res.id;
        } else {
            this.topResource = undefined;
        }

        this.lockedResource = undefined;
    },
    addMessage: function (message, notify) {
        message.owner = me.jid.bare;

        if (notify && (!this.activeContact || (this.activeContact && !app.state.focused)) && message.from.bare === this.jid) {
            this.unreadCount++;
            app.notifications.create(this.displayName, {
                body: message.body,
                icon: this.avatar,
                tag: this.jid,
                onclick: _.bind(app.navigate, app, '/chat/' + this.jid)
            });
        }

        var existing = Message.idLookup(message.from[message.type == 'groupchat' ? 'full' : 'bare'], message.mid);
        if (existing) {
            existing.set(message);
            existing.save();
        } else {
            this.messages.add(message);
            message.save();
        }

        var newInteraction = new Date(message.created);
        if (!this.lastInteraction || this.lastInteraction < newInteraction) {
            this.lastInteraction = newInteraction;
        }
    },
    fetchHistory: function () {
        var self = this;
        app.whenConnected(function () {
            var filter = {
                'with': self.jid,
                rsm: {
                    count: 20,
                    before: true
                }
            };

            var lastMessage = self.messages.last();
            if (lastMessage && lastMessage.archivedId) {
                filter.rsm.after = lastMessage.archivedId;
            }

            if (self.lastHistoryFetch && !isNaN(self.lastHistoryFetch.valueOf())) {
                if (self.lastInteraction > self.lastHistoryFetch) {
                    filter.start = self.lastInteraction;
                } else {
                    filter.start = self.lastHistoryFetch;
                }
            } else {
                filter.end = new Date(Date.now());
            }

            client.getHistory(filter, function (err, res) {
                if (err) return;

                self.lastHistoryFetch = new Date(Date.now());

                var results = res.mamQuery.results || [];
                results.reverse();
                results.forEach(function (result) {
                    result = result.toJSON();
                    var msg = result.mam.forwarded.message;

                    msg.mid = msg.id;
                    delete msg.id;

                    if (!msg.delay) {
                        msg.delay = result.mam.forwarded.delay;
                    }

                    if (msg.replace) {
                        var original = Message.idLookup(msg.from[msg.type == 'groupchat' ? 'full' : 'bare'], msg.replace);
                        // Drop the message if editing a previous, but
                        // keep it if it didn't actually change an
                        // existing message.
                        if (original && original.correct(msg)) return;
                    }

                    var message = new Message(msg);
                    message.archivedId = result.mam.id;
                    message.acked = true;

                    self.addMessage(message, false);
                });
            });
        });
    },
    save: function () {
        if (!this.inRoster) return;

        var storageId = crypto.createHash('sha1').update(this.owner + '/' + this.id).digest('hex');
        var data = {
            storageId: storageId,
            owner: this.owner,
            jid: this.jid,
            name: this.name,
            groups: this.groups,
            subscription: this.subscription,
            avatarID: this.avatarID
        };
        app.storage.roster.add(data);
    }
});
<|endoftext|>


<commit_before>const path = require('path');
const _    = require('underscore');
const qforms = require('../../../qforms');
const Editor = require('../Editor');

class PageEditor extends Editor {

    constructor(appEditor, pageFile) {
        super(pageFile.data, appEditor);
        this.appEditor = appEditor;
        this.pageFile  = pageFile;
        this.name      = this.getAttr('name');
    }

    static createData(params) {
        return {
            '@class'     :'Page',
            '@attributes': {
                formatVersion: '0.1',
                name     : params['name'],
                caption  : params['caption'] ? params['caption'] : params['name']
            },
            dataSources: {},
            forms      : {},

            dataSources2: [],
            forms2      : [],
        };
    }

    async setAttr(name, value) {
        console.log('PageEditor.setAttr', name, value);
        if (name === 'name') {
            const pageLinkEditor = this.appEditor.createPageLinkEditor(this.name);
            await pageLinkEditor.setAttr(name, value);
        }
        await super.setAttr(name, value);
    }

    async moveFormUp(params) {
        this.data.forms = qforms.Helper.moveObjProp(this.data.forms, params.form, -1);
        await this.save();
        return 'ok';
    }

    async save() {
        return await this.pageFile.save();
    }

    async moveFormDown(params) {
        this.data.forms = qforms.Helper.moveObjProp(this.data.forms, params.form, 1);
        await this.save();
        return 'ok';
    }

    newFormData(params) {
        const name   = params['name'];
        const _class = params['class'];
        if (!this.data.forms) {
            this.data.forms = {};
        }
        if (!this.data.forms2) {
            this.data.forms2 = [];
        }
        if (this.data.forms[name]) {
            throw new Error(`Form ${name} already exists.`);
        }
        let data;
        switch (_class) {
            case 'TableForm':
                data = qforms.TableFormEditor.createData(params);
                break;
            case 'RowForm':
                data = qforms.RowFormEditor.createData(params);
                break;
            case 'TreeForm':
                data = qforms.TreeFormEditor.createData(params);
                break;
            default:
                throw new Error('unknown form class');
        }
        this.data.forms[name] = data;
        return data;
    }

    async createForm(params) {
        const name = params.name;
        const formData = this.newFormData(params);
        const formEditor = this.createFormEditor(name);

        // fields
        if (params.fields) {
            for (const fieldName in params.fields) {
                formEditor.newField(_.extend(
                    {form: name},
                    params.fields[fieldName]
                ));
            }
        }

        // dataSources
        if (params.dataSources) {
            for (const dataSourceName in params.dataSources) {
                const dataSource = params.dataSources[dataSourceName];
                formEditor.newDataSourceData(
                    _.extend(
                        {form:name},
                        dataSource
                    )
                );
                const dataSourceEditor = formEditor.createDataSourceEditor(dataSourceName);
                // keyColumns
                if (dataSource.keyColumns) {
                    for (const keyColumnName in dataSource.keyColumns) {
                        const keyColumn = dataSource.keyColumns[keyColumnName];
                        dataSourceEditor.newKeyColumnData(_.extend(
                            {
                                form      : name,
                                dataSource: dataSourceName
                            },
                            keyColumn
                        ));
                    }
                }
            }
        }
        await this.save();
        return formEditor;
    }

    createFormEditor(name) {
        const formData = this.data.forms[name];
        return eval(`new qforms.${formData['@class']}Editor(this, name, formData)`);
    }

    getDataSourceData(name) {
        let data = this.getModelData('dataSources', name);
        if (data) return data;
        data = this.findModelData('dataSources2', name);
        if (data) return data;
        throw new Error(`no data source: ${name}`);
    }

    createDataSourceEditor(name) {
        const dataSourceData = this.getDataSourceData(name);
        return eval(`new qforms.${dataSourceData['@class']}Editor(this, name, dataSourceData)`);
    }

    removeForm(name) {
        this.deleteForm(name);
        return this.save();
    }

    async createJs(params) {
        const templateFilePath = path.join(__dirname, 'Page.js.ejs');
        const customJsFilePath = await this.getCustomFilePath('js');
        const js = await this.createFileByParams(customJsFilePath, templateFilePath, {
            page  : this.getAttr('name'),
            _class: this.constructor.name.replace('Editor', '')
        });
        return js;
    }

    async getCustomDirPath() {
        console.log('PageEditor.getCustomDirPath');
        const customDirPath = await this.parent.getCustomDirPath();
        return path.join(customDirPath, 'pages', this.name);
    }

    newDataSourceData(params) {
        const name   = params['name'];
        const _class = params['class'];
        if (!this.data.dataSources) {
            this.data.dataSources = {};
        }
        if (!this.data.dataSources2) {
            this.data.dataSources2 = [];
        }
        if (this.data.dataSources[name] || this.findModelData('dataSources2', name)) {
            throw new Error(`DataSource ${name} already exist`);
        }
        let data;
        switch (_class) {
            case 'DataSource':
                data = qforms.DataSourceEditor.createData(params);
                break;
            case 'SqlDataSource':
                data = qforms.SqlDataSourceEditor.createData(params);
                break;
            default:
                throw new Error(`unknown data source class: ${_class}`);
        }
        // this.data.dataSources[name] = data;
        this.addModelData('dataSources2', data);
        return data;
    }

    deleteForm(name) {
        delete this.data.forms[name];
    }

    deleteDataSource(dataSource) {
        delete this.data.dataSources[dataSource];
    }

    getAppEditor() {
        return this.appEditor;
    }

}

module.exports = PageEditor;
<commit_msg>newFormData<commit_after>const path = require('path');
const _    = require('underscore');
const qforms = require('../../../qforms');
const Editor = require('../Editor');

class PageEditor extends Editor {

    constructor(appEditor, pageFile) {
        super(pageFile.data, appEditor);
        this.appEditor = appEditor;
        this.pageFile  = pageFile;
        this.name      = this.getAttr('name');
    }

    static createData(params) {
        return {
            '@class'     :'Page',
            '@attributes': {
                formatVersion: '0.1',
                name     : params['name'],
                caption  : params['caption'] ? params['caption'] : params['name']
            },
            dataSources: {},
            forms      : {},

            dataSources2: [],
            forms2      : [],
        };
    }

    async setAttr(name, value) {
        console.log('PageEditor.setAttr', name, value);
        if (name === 'name') {
            const pageLinkEditor = this.appEditor.createPageLinkEditor(this.name);
            await pageLinkEditor.setAttr(name, value);
        }
        await super.setAttr(name, value);
    }

    async moveFormUp(params) {
        this.data.forms = qforms.Helper.moveObjProp(this.data.forms, params.form, -1);
        await this.save();
        return 'ok';
    }

    async save() {
        return await this.pageFile.save();
    }

    async moveFormDown(params) {
        this.data.forms = qforms.Helper.moveObjProp(this.data.forms, params.form, 1);
        await this.save();
        return 'ok';
    }

    newFormData(params) {
        const name   = params['name'];
        const _class = params['class'];
        if (!this.data.forms) {
            this.data.forms = {};
        }
        if (!this.data.forms2) {
            this.data.forms2 = [];
        }
        if (this.data.forms[name] || this.findModelData('forms2', name)) {
            throw new Error(`Form ${name} already exists.`);
        }
        let data;
        switch (_class) {
            case 'TableForm':
                data = qforms.TableFormEditor.createData(params);
                break;
            case 'RowForm':
                data = qforms.RowFormEditor.createData(params);
                break;
            case 'TreeForm':
                data = qforms.TreeFormEditor.createData(params);
                break;
            default:
                throw new Error('unknown form class');
        }
        // this.data.forms[name] = data;
        this.addModelData('forms2', data);
        return data;
    }

    async createForm(params) {
        const name = params.name;
        const formData = this.newFormData(params);
        const formEditor = this.createFormEditor(name);

        // fields
        if (params.fields) {
            for (const fieldName in params.fields) {
                formEditor.newField(_.extend(
                    {form: name},
                    params.fields[fieldName]
                ));
            }
        }

        // dataSources
        if (params.dataSources) {
            for (const dataSourceName in params.dataSources) {
                const dataSource = params.dataSources[dataSourceName];
                formEditor.newDataSourceData(
                    _.extend(
                        {form:name},
                        dataSource
                    )
                );
                const dataSourceEditor = formEditor.createDataSourceEditor(dataSourceName);
                // keyColumns
                if (dataSource.keyColumns) {
                    for (const keyColumnName in dataSource.keyColumns) {
                        const keyColumn = dataSource.keyColumns[keyColumnName];
                        dataSourceEditor.newKeyColumnData(_.extend(
                            {
                                form      : name,
                                dataSource: dataSourceName
                            },
                            keyColumn
                        ));
                    }
                }
            }
        }
        await this.save();
        return formEditor;
    }

    getFormData(name) {
        let data = this.getModelData('forms', name);
        if (data) return data;
        data = this.findModelData('forms2', name);
        if (data) return data;
        throw new Error(`no form ${name}`);
    }

    createFormEditor(name) {
        const formData = this.getFormData(name);
        return eval(`new qforms.${formData['@class']}Editor(this, name, formData)`);
    }

    getDataSourceData(name) {
        let data = this.getModelData('dataSources', name);
        if (data) return data;
        data = this.findModelData('dataSources2', name);
        if (data) return data;
        throw new Error(`no data source: ${name}`);
    }

    createDataSourceEditor(name) {
        const dataSourceData = this.getDataSourceData(name);
        return eval(`new qforms.${dataSourceData['@class']}Editor(this, name, dataSourceData)`);
    }

    removeForm(name) {
        this.deleteForm(name);
        return this.save();
    }

    async createJs(params) {
        const templateFilePath = path.join(__dirname, 'Page.js.ejs');
        const customJsFilePath = await this.getCustomFilePath('js');
        const js = await this.createFileByParams(customJsFilePath, templateFilePath, {
            page  : this.getAttr('name'),
            _class: this.constructor.name.replace('Editor', '')
        });
        return js;
    }

    async getCustomDirPath() {
        console.log('PageEditor.getCustomDirPath');
        const customDirPath = await this.parent.getCustomDirPath();
        return path.join(customDirPath, 'pages', this.name);
    }

    newDataSourceData(params) {
        const name   = params['name'];
        const _class = params['class'];
        if (!this.data.dataSources) {
            this.data.dataSources = {};
        }
        if (!this.data.dataSources2) {
            this.data.dataSources2 = [];
        }
        if (this.data.dataSources[name] || this.findModelData('dataSources2', name)) {
            throw new Error(`DataSource ${name} already exist`);
        }
        let data;
        switch (_class) {
            case 'DataSource':
                data = qforms.DataSourceEditor.createData(params);
                break;
            case 'SqlDataSource':
                data = qforms.SqlDataSourceEditor.createData(params);
                break;
            default:
                throw new Error(`unknown data source class: ${_class}`);
        }
        // this.data.dataSources[name] = data;
        this.addModelData('dataSources2', data);
        return data;
    }

    deleteForm(name) {
        delete this.data.forms[name];
    }

    deleteDataSource(dataSource) {
        delete this.data.dataSources[dataSource];
    }

    getAppEditor() {
        return this.appEditor;
    }

}

module.exports = PageEditor;
<|endoftext|>


<commit_before>// Looping sederhana mengalikan dengan angka sebelumnya, hingga angkat terkecil 1
// Sample
// Input totalSum(5)
// Output 5 * 4 * 3 * 2 * 1 = 120

function totalSum (number) {
  // Buat varibel sementara / temporary
  var total;
  // Lakukan perulang sebanyak jumlah angka
  for (var i = number; i >= 1; i--) {
    // Kalikan dan simpan hasilnya ke variabel total
    total *= number;
  }
  // Kembali kan hasilnya dengan melempar variabel total
  return total;
}

console.log(totalSum(5));

// Looping dengan mengalikan dengan angka sebelumnya dengan selisih paramater kedua
// Sample
// Input : totalLompat(12, 5)
// Output : 12 * 7 * 2 = 168

// function totalLompat  (number, dif) {
//   var total;
//   for (var i = 0; i < number; i++) {
//     total *= number;
//   }
//   return total;
// }
function totalLompat (number, dif) {
  // Cek apakah ini angka terakhir / terkecil yang ingin ikut dihitung
  if (number == 1) {
    // Jika kembalikan nilainya
    return 1;
  // Cek kembali, apakah 'number' lebih besar dari dif (pembeda / selisih ke angka selanjutnya)
  } else if (number > dif) {
    // Jika iya, maka terus lakukan rekrusif dengan memanggil fungsinya sendiri
    return number * totalLompat(number - dif, dif);
  } else {
    // Jika tidak, maka balikan angka tersebut, agar menjadi nilai kemabalian pada proses rekrusif terakhir
    return number;
  }
}
console.log(totalLompat(12, 5));
<commit_msg>Fixing the Monday task:<commit_after>// Looping sederhana mengalikan dengan angka sebelumnya, hingga angkat terkecil 1
// Sample
// Input totalSum(5)
// Output 5 * 4 * 3 * 2 * 1 = 120

function totalSum (number) {
  // Buat varibel sementara / temporary
  // Assign dengan nilai 1, supaya tida menjadi NaN
  var total = 1;
  // Lakukan perulang sebanyak jumlah angka
  for (var i = number; i >= 1; i--) {
    // Kalikan dan simpan hasilnya ke variabel total
    total *= i;
  }
  // Kembali kan hasilnya dengan melempar variabel total
  return total;
}

console.log(totalSum(5));

// Looping dengan mengalikan dengan angka sebelumnya dengan selisih paramater kedua
// Sample
// Input : totalLompat(12, 5)
// Output : 12 * 7 * 2 = 168

function totalLompat  (number, dif) {
  // Buat varibel sementara / temporary
  // Assign dengan nilai 1, supaya tida menjadi NaN
  var total = 1;
  // Lakukan perulang sebanyak jumlah angka dengan selisih sebanyak dif
  for (var i = number; i >= 1; i -= dif) {
    // Kalikan dan simpan hasilnya ke variabel total
    total *= i;
  }
  // Kembali kan hasilnya dengan melempar variabel total
  return total;
}
console.log(totalLompat(12, 5));
<|endoftext|>


<commit_before>// This file contains tests for the layout plugin.
// Created by Curran Kelleher Feb 2015

// Use the "expect" assert style.
// See http://chaijs.com/guide/styles/
var expect = require("chai").expect,
    Model = require("model-js"),
    Chiasm = require("../src/chiasm"),
    dummyVis = require("../src/plugins/dummyVis/dummyVis"),
    layout = require("../src/plugins/layout/layout");

// Use JSDOM for DOM manipulation in Node.
// https://github.com/tmpvar/jsdom#creating-a-browser-like-window-object
// "var" omitted intentionally to induce global variables.
document = require("jsdom").jsdom();
window = document.parentWindow;

// A utility function for asserting a group of component property values.
function expectValues(chiasm, values, callback){
  var promises = Object.keys(values).map(function(key){
    return new Promise(function(resolve, reject){
      var path = key.split("."),
          alias = path[0],
          property = path[1],
          propertyPath = path.slice(2),
          expectedValue = values[key];

      chiasm.getComponent(alias).then(function(component){
        component.when(property, function(value){
          propertyPath.forEach(function(key){
            value = value[key];
          });
          expect(value).to.equal(expectedValue);
          resolve();
        });
      }, reject);
    });
  });

  Promise.all(promises).then(function(results){
    callback();
  }, function(err){
    console.log(err);
  });
}

function initChiasm(){
  var div = document.createElement("div");
  var chiasm = Chiasm(div);

  chiasm.plugins.dummyVis = dummyVis;
  chiasm.plugins.layout = layout;

  // Set the width and height that the layout will use.
  div.clientHeight = div.clientWidth = 100;

  return chiasm;
}

describe("plugins/layout", function () {
  it("should compute size for a single dummyVis", function(done) {

    var chiasm = initChiasm();

    chiasm.setConfig({
      layout: {
        plugin: "layout",
        state: {
          layout: "a"
        }
      },
      a: {
        plugin: "dummyVis"
      }
    }).then(function(){
      chiasm.getComponent("a").then(function(a){
        a.when("box", function(box){
          expect(box.x).to.equal(0);
          expect(box.y).to.equal(0);
          expect(box.width).to.equal(100);
          expect(box.height).to.equal(100);
          done();
        });
      });

    }, function(err){
      console.log(err);
    });
  });

  it("should compute size for a 2 instances of dummyVis", function(done) {
    var chiasm = initChiasm();

    chiasm.config = {
      layout: {
        plugin: "layout",
        state: {
          layout: {
            orientation: "horizontal",
            children: ["a", "b"]
          }
        }
      },
      a: {
        plugin: "dummyVis"
      },
      b: {
        plugin: "dummyVis"
      }
    };

    expectValues(chiasm, {
      "a.box.x": 0,
      "a.box.y": 0,
      "a.box.width": 50,
      "a.box.height": 100,
      "b.box.x": 50,
      "b.box.y": 0,
      "b.box.width": 50,
      "b.box.height": 100
    }, done);
  });

  it("should compute from size specified in initial state", function(done) {

    var chiasm = initChiasm();

    chiasm.config = {
      layout: {
        plugin: "layout",
        state: {
          layout: {
            orientation: "horizontal",
            children: ["a", "b"]
          }
        }
      },
      a: {
        plugin: "dummyVis",
        state: {
          size: "40px"
        }
      },
      b: {
        plugin: "dummyVis"
      }
    };
    expectValues(chiasm, {
      "a.box.width": 40,
      "b.box.width": 60
    }, done);
  });

  // This tests that the layout plugin is listening for changes
  // in the "size" property of each component in the layout.

  // TODO refactor layout plugin to REMOVE THIS FEATURE
  // The layout should be specified purely in the layout component,
  // not spread across "size" properties in component configurations.
  it("should compute from size changed within component", function(done) {
    var chiasm = initChiasm();

    chiasm.config = {
      layout: {
        plugin: "layout",
        state: {
          layout: {
            orientation: "horizontal",
            children: ["a", "b"]
          }
        }
      },
      a: {
        plugin: "dummyVis",
        state: {
          size: "40px"
        }
      },
      b: {
        plugin: "dummyVis"
      }
    };

    chiasm.getComponent("a").then(function(a){
      chiasm.getComponent("b").then(function(b){
        a.when("box", function(box){
          if(a.size === "40px"){
            expect(box.width).to.equal(40);
            expect(b.box.width).to.equal(60);
            a.size = "55px";
          } else if(a.size === "55px"){
            expect(box.width).to.equal(55);
            expect(b.box.width).to.equal(45);
            a.size = "75px";
          } else if(a.size === "75px"){
            expect(box.width).to.equal(75);
            expect(b.box.width).to.equal(25);
            done();
          }
        });
      });
    });
  });
});
<commit_msg>Refactor layout test to use bundle with Chiasm core + plugins<commit_after>// This file contains tests for the layout plugin.
// Created by Curran Kelleher Feb 2015

// Use the "expect" assert style.
// See http://chaijs.com/guide/styles/
var expect = require("chai").expect,
    Model = require("model-js"),
    Chiasm = require("../index");

// Use JSDOM for DOM manipulation in Node.
// https://github.com/tmpvar/jsdom#creating-a-browser-like-window-object
// "var" omitted intentionally to induce global variables.
document = require("jsdom").jsdom();
window = document.parentWindow;

// A utility function for asserting a group of component property values.
function expectValues(chiasm, values, callback){
  var promises = Object.keys(values).map(function(key){
    return new Promise(function(resolve, reject){
      var path = key.split("."),
          alias = path[0],
          property = path[1],
          propertyPath = path.slice(2),
          expectedValue = values[key];

      chiasm.getComponent(alias).then(function(component){
        component.when(property, function(value){
          propertyPath.forEach(function(key){
            value = value[key];
          });
          expect(value).to.equal(expectedValue);
          resolve();
        });
      }, reject);
    });
  });

  Promise.all(promises).then(function(results){
    callback();
  }, function(err){
    console.log(err);
  });
}

function initChiasm(){
  var div = document.createElement("div");
  var chiasm = Chiasm(div);

  // Set the width and height that the layout will use.
  div.clientHeight = div.clientWidth = 100;

  return chiasm;
}

describe("plugins/layout", function () {
  it("should compute size for a single dummyVis", function(done) {

    var chiasm = initChiasm();

    chiasm.setConfig({
      layout: {
        plugin: "layout",
        state: {
          layout: "a"
        }
      },
      a: {
        plugin: "dummyVis"
      }
    }).then(function(){
      chiasm.getComponent("a").then(function(a){
        a.when("box", function(box){
          expect(box.x).to.equal(0);
          expect(box.y).to.equal(0);
          expect(box.width).to.equal(100);
          expect(box.height).to.equal(100);
          done();
        });
      });

    }, function(err){
      console.log(err);
    });
  });

  it("should compute size for a 2 instances of dummyVis", function(done) {
    var chiasm = initChiasm();

    chiasm.config = {
      layout: {
        plugin: "layout",
        state: {
          layout: {
            orientation: "horizontal",
            children: ["a", "b"]
          }
        }
      },
      a: {
        plugin: "dummyVis"
      },
      b: {
        plugin: "dummyVis"
      }
    };

    expectValues(chiasm, {
      "a.box.x": 0,
      "a.box.y": 0,
      "a.box.width": 50,
      "a.box.height": 100,
      "b.box.x": 50,
      "b.box.y": 0,
      "b.box.width": 50,
      "b.box.height": 100
    }, done);
  });

  it("should compute from size specified in initial state", function(done) {

    var chiasm = initChiasm();

    chiasm.config = {
      layout: {
        plugin: "layout",
        state: {
          layout: {
            orientation: "horizontal",
            children: ["a", "b"]
          }
        }
      },
      a: {
        plugin: "dummyVis",
        state: {
          size: "40px"
        }
      },
      b: {
        plugin: "dummyVis"
      }
    };
    expectValues(chiasm, {
      "a.box.width": 40,
      "b.box.width": 60
    }, done);
  });

  // This tests that the layout plugin is listening for changes
  // in the "size" property of each component in the layout.

  // TODO refactor layout plugin to REMOVE THIS FEATURE
  // The layout should be specified purely in the layout component,
  // not spread across "size" properties in component configurations.
  it("should compute from size changed within component", function(done) {
    var chiasm = initChiasm();

    chiasm.config = {
      layout: {
        plugin: "layout",
        state: {
          layout: {
            orientation: "horizontal",
            children: ["a", "b"]
          }
        }
      },
      a: {
        plugin: "dummyVis",
        state: {
          size: "40px"
        }
      },
      b: {
        plugin: "dummyVis"
      }
    };

    chiasm.getComponent("a").then(function(a){
      chiasm.getComponent("b").then(function(b){
        a.when("box", function(box){
          if(a.size === "40px"){
            expect(box.width).to.equal(40);
            expect(b.box.width).to.equal(60);
            a.size = "55px";
          } else if(a.size === "55px"){
            expect(box.width).to.equal(55);
            expect(b.box.width).to.equal(45);
            a.size = "75px";
          } else if(a.size === "75px"){
            expect(box.width).to.equal(75);
            expect(b.box.width).to.equal(25);
            done();
          }
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>var user = function(uuid, socket, mode, description) {
   this.uuid = uuid;
   this.socket = socket;
   this.mode = mode;
   this.description = description;
   this.MTSubscription = [];
};

user.prototype.equals = function(user) {
   return (this.uuid === user.uuid);
};

user.prototype.subscribe = function(event) {
   this.MTSubscription.push(event);
};

user.prototype.copy = function() {
   var result = {};

   result.uuid = this.uuid;
   result.description = this.description;

   return result;
};

module.exports = user;<commit_msg>feat(equals): can pass uuid or user object as parameter to function<commit_after>var user = function(uuid, socket, mode, description) {
   this.uuid = uuid;
   this.socket = socket;
   this.mode = mode;
   this.description = description;
   this.MTSubscription = [];
};

user.prototype.equals = function(user) {
   if (typeof user === 'string')
      return (this.uuid === user);
   else
      return (this.uuid === user.uuid);
};

user.prototype.subscribe = function(event) {
   this.MTSubscription.push(event);
};

user.prototype.copy = function() {
   var result = {};

   result.uuid = this.uuid;
   result.description = this.description;

   return result;
};

module.exports = user;<|endoftext|>


<commit_before>/*
 * External Dependencies
 */
var Promise 	  = require('bluebird'),
	//failed to promisify xml2js (not sure if by own error or by bug in either lib)
	parseXML 	  = require('xml2js').parseString,
	validator 	  = require('validator'),
	request 	  = require('request'),
	whois 		  = require('whois'),
	async		  = require('async');

var domains = {
    isDomainAvailable : function(domain) {
    return new Promise(function(resolve, reject) {
        whois.lookup(domain, {follow: 0/*, verbose: true*/}, function(err, data) {
            if(err) {
                console.log(err);
                reject({domain: domain, error: err, response: data});
            } else {
                var availableRegex = /No match for domain "(.*)"/g,
                    unavailableRegex = /Domain Name: (.*)\n/g,
                    unavailableRegexAlt = /Domain Name: (.*)\r\n/g,
                    unavailableRegexAlt2 = /Domain Name:(.*)\r\n/g;

                var domainResponse = {
                    domain : domain
                };
                if(data.search(availableRegex) > -1) {
                    domainResponse.status = "available";
                } else if(
                        data.search(unavailableRegex) > -1 ||
                        data.search(unavailableRegexAlt) > -1 ||
                        data.search(unavailableRegexAlt2) > -1
                    ) {
                    domainResponse.status = "registered";
                } else {
                    domainResponse.status = "error";
                }

                resolve(domainResponse);
            }
        });
    });
}
};

module.exports = domains;<commit_msg>Add regex for new TLDs<commit_after>/*
 * External Dependencies
 */
var Promise 	  = require('bluebird'),
	//failed to promisify xml2js (not sure if by own error or by bug in either lib)
	parseXML 	  = require('xml2js').parseString,
	validator 	  = require('validator'),
	request 	  = require('request'),
	whois 		  = require('whois'),
	async		  = require('async');

var domains = {
    isDomainAvailable : function(domain) {
    return new Promise(function(resolve, reject) {
        whois.lookup(domain, {follow: 0/*, verbose: true*/}, function(err, data) {
            if(err) {
                console.log(err);
                reject({domain: domain, error: err, response: data});
            } else {
                var availableRegex = /No match for domain "(.*)"/g,
                    availableRegex = /NOT FOUND/g,
                    unavailableRegex = /Domain Name: (.*)\n/g,
                    unavailableRegexAlt = /Domain Name: (.*)\r\n/g,
                    unavailableRegexAlt2 = /Domain Name:(.*)\r\n/g;

                var domainResponse = {
                    domain : domain
                };
                if(
                    data.search(availableRegex) > -1 ||
                    data.search(availableRegex2) > -1
                ) {
                    domainResponse.status = "available";
                } else if(
                        data.search(unavailableRegex) > -1 ||
                        data.search(unavailableRegexAlt) > -1 ||
                        data.search(unavailableRegexAlt2) > -1
                    ) {
                    domainResponse.status = "registered";
                } else {
                    domainResponse.status = "error";
                }

                resolve(domainResponse);
            }
        });
    });
}
};

module.exports = domains;<|endoftext|>


<commit_before>exports.config = {
	specs:['env_vars.js', 'navigation.js', 'user_navigation.js', 'index.js'],
	baseUrl: 'http://localhost:5000',
	framework:'mocha',
	mochaOpts: {
		reporter:'spec',
		slow: 3000,
		enableTimeouts: false
	},
	capabilities: {
		'browserName':'chrome'
	}
};

if (process.env.TRAVIS_BUILD_NUMBER) {
    exports.config.seleniumAddress = 'http://localhost:4445/wd/hub';
    exports.config.capabilities = {
        'name': 'Travis + Protractor Tests',
        'browserName': 'chrome',
        'username': process.env.SAUCE_USERNAME,
        'accessKey': process.env.SAUCE_ACCESS_KEY,
        'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER,
        'build': process.env.TRAVIS_BUILD_NUMBER,
        'tags': [process.env.TRAVIS_BRANCH, process.env.TRAVIS_BUILD_NUMBER]
    };
}<commit_msg>Removed user_navigation.js from test files since we deleted it.<commit_after>exports.config = {
	specs:['env_vars.js', 'navigation.js', 'index.js'],
	baseUrl: 'http://localhost:5000',
	framework:'mocha',
	mochaOpts: {
		reporter:'spec',
		slow: 3000,
		enableTimeouts: false
	},
	capabilities: {
		'browserName':'chrome'
	}
};

if (process.env.TRAVIS_BUILD_NUMBER) {
    exports.config.seleniumAddress = 'http://localhost:4445/wd/hub';
    exports.config.capabilities = {
        'name': 'Travis + Protractor Tests',
        'browserName': 'chrome',
        'username': process.env.SAUCE_USERNAME,
        'accessKey': process.env.SAUCE_ACCESS_KEY,
        'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER,
        'build': process.env.TRAVIS_BUILD_NUMBER,
        'tags': [process.env.TRAVIS_BRANCH, process.env.TRAVIS_BUILD_NUMBER]
    };
}<|endoftext|>


<commit_before>//
// Copyright (c) Microsoft and contributors.  All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//

var _ = require('underscore');
var should = require('should');
var sinon = require('sinon');
var util = require('util');
var applicationInsights = require('applicationinsights');
var fs = require('fs');

describe('cli', function() {
  describe('telemetry', function() {
    var sandbox = sinon.sandbox.create();
    var telemetry = require('../../lib/util/telemetry');
    var testInstrumentationKey = "1234";

    beforeEach(function (done) {
      var client = applicationInsights.setup(testInstrumentationKey).client;

      // stub AppInsights functions.
      sandbox.stub(applicationInsights, 'setup', function(ikey) {
        return applicationInsights;
      });

      sandbox.stub(applicationInsights, 'start', function() {
        return applicationInsights;
      });

      sandbox.stub(applicationInsights, 'setAutoCollectExceptions', function(enabled) {
        return applicationInsights;
      });

      sandbox.stub(applicationInsights, 'setAutoCollectPerformance', function(enabled) {
        return applicationInsights;
      });

      sandbox.stub(applicationInsights, 'setAutoCollectRequests', function(enabled) {
        return applicationInsights;
      });

      sandbox.stub(client, 'sendPendingData', function(callback) {
        if (typeof callback === 'function') {
          callback();
        }
      });

      done();
    });

    afterEach(function (done) {
      sandbox.restore();
      done();
    });

    it('should not send out event if data-collection is not enabled', function(done){
      var track = sandbox.spy(applicationInsights.client, 'track');

      telemetry.init(false)
      telemetry.start(['foo', 'bar', 'azure', 'login']);
      telemetry.currentCommand({
        fullName: function() {
          return 'azure login';
        }
      });
      telemetry.onFinish(function() {});

      (track.called).should.be.false;
      done();
    });

    it('should encrypt user sensitive data', function(done) {
      var eventData;
      sandbox.stub(applicationInsights.client, 'track', function(data) {
        eventData = data;
      });

      telemetry.setAppInsights(applicationInsights);
      telemetry.init(true);
      telemetry.start(['foo', 'bar', 'azure', 'login', '-u', 'foo', '-p', 'bar']);
      telemetry.currentCommand({
        fullName: function() {
          return 'azure login';
        }
      });
      telemetry.onFinish(function() {});

      (eventData.baseData.properties.command === 'azure login -u *** -p ***').should.be.true;
      done();
    });

    it('should catch exception and encrypt exception data', function(done) {
      var eventData;
      sandbox.stub(applicationInsights.client, 'track', function(data) {
        eventData = data;
      });

      telemetry.setAppInsights(applicationInsights);
      telemetry.init(true)
      telemetry.start(['foo', 'bar', 'azure', 'login', '-u', 'foo', '-p', 'bar']);
      telemetry.currentCommand({
        fullName: function() {
          return 'azure login';
        }
      });
      var err = new Error('error');
      telemetry.onError(err, function() {});
      (eventData.baseData.properties.isSuccess).should.be.false;
      //(eventData.baseData.properties.stacktrace).should.be.true;
      (eventData.baseData.properties.command === 'azure login -u *** -p ***').should.be.true;
      done();
    });

    it('should filter username from the stacktrace', function(done) {
      var eventData;
      sandbox.stub(applicationInsights.client, 'track', function(data) {
        eventData = data;
      });

      telemetry.setAppInsights(applicationInsights);
      telemetry.init(true)
      telemetry.start(['foo', 'bar', 'azure', 'login', '-u', 'foo', '-p', 'bar']);
      telemetry.currentCommand({
        fullName: function() {
          return 'azure login';
        }
      });
      var err = new Error('error');
      err.stack = fs.readFileSync(__dirname + '/../data/error.txt', 'utf8');
      var filteredError = fs.readFileSync(__dirname + '/../data/filtered_error.txt', 'utf8');
      telemetry.onError(err, function() {});
      (eventData.baseData.properties.isSuccess).should.be.false;
      eventData.baseData.properties.stacktrace.should.equal(filteredError);
      (eventData.baseData.properties.command === 'azure login -u *** -p ***').should.be.true;
      done();
    });
  })
});
<commit_msg>tests for user agent header construction<commit_after>//
// Copyright (c) Microsoft and contributors.  All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//

var _ = require('underscore');
var should = require('should');
var sinon = require('sinon');
var util = require('util');
var applicationInsights = require('applicationinsights');
var fs = require('fs');

describe('cli', function() {
  describe('telemetry', function() {
    var sandbox = sinon.sandbox.create();
    var telemetry = require('../../lib/util/telemetry');
    var testInstrumentationKey = "1234";

    beforeEach(function (done) {
      var client = applicationInsights.setup(testInstrumentationKey).client;

      // stub AppInsights functions.
      sandbox.stub(applicationInsights, 'setup', function(ikey) {
        return applicationInsights;
      });

      sandbox.stub(applicationInsights, 'start', function() {
        return applicationInsights;
      });

      sandbox.stub(applicationInsights, 'setAutoCollectExceptions', function(enabled) {
        return applicationInsights;
      });

      sandbox.stub(applicationInsights, 'setAutoCollectPerformance', function(enabled) {
        return applicationInsights;
      });

      sandbox.stub(applicationInsights, 'setAutoCollectRequests', function(enabled) {
        return applicationInsights;
      });

      sandbox.stub(client, 'sendPendingData', function(callback) {
        if (typeof callback === 'function') {
          callback();
        }
      });

      done();
    });

    afterEach(function (done) {
      sandbox.restore();
      done();
    });

    it('should not send out event if data-collection is not enabled', function(done){
      var track = sandbox.spy(applicationInsights.client, 'track');

      telemetry.init(false)
      telemetry.start(['foo', 'bar', 'azure', 'login']);
      telemetry.currentCommand({
        fullName: function() {
          return 'azure login';
        }
      });
      telemetry.onFinish(function() {});

      (track.called).should.be.false;
      done();
    });

    it('should construct user agent info object with some data', function (done) {

      sandbox.stub(telemetry, 'getUserAgentInfo', function () {
        return {
          osType: 'WindowsNT',
          osVersion: '2.0',
          mode: 'baz',
          commandName: 'group',
          rawCommand: 'azure group list'
        };
      });

      telemetry.init(true)
      telemetry.start(['foo', 'bar', 'azure', 'group', 'list']);
      telemetry.currentCommand({
        fullName: function () {
          return 'azure group list';
        }
      });

      telemetry.onFinish(function () { });

      var userAgentInfo = telemetry.getUserAgentInfo();
      should(userAgentInfo).have.property('osType', 'WindowsNT');
      should(userAgentInfo).have.property('osVersion', '2.0');
      should(userAgentInfo).have.property('mode', 'baz');
      should(userAgentInfo).have.property('commandName', 'group');
      should(userAgentInfo).have.property('rawCommand', 'azure group list');

      sandbox.restore();
      done();
    });

    it('should construct user agent info object with some properties', function (done) {

      var command = 'azure group list';
      telemetry.init(true)
      telemetry.start(['foo', 'bar', 'azure', 'group', 'list']);
      telemetry.currentCommand({
        fullName: function () {
          return command;
        }
      });

      telemetry.setMode('arm');
      telemetry.onFinish(function () { });

      var userAgentInfo = telemetry.getUserAgentInfo();

      // assert properties
      should(userAgentInfo).have.property('osType').with.type('string');
      should(userAgentInfo).have.property('osVersion').with.type('string');
      should(userAgentInfo).have.property('nodeVersion').with.type('string');
      should(userAgentInfo).have.property('installationType').with.type('string');
      should(userAgentInfo).have.property('userId').with.type('string');
      should(userAgentInfo).have.property('subscriptionId').with.type('string');
      should(userAgentInfo).have.property('userType').with.type('string');

      // assert properties, with values.
      should(userAgentInfo).have.property('mode').with.type('string').be.equal('arm');
      should(userAgentInfo).have.property('commandName').with.type('string').be.equal(command);
      should(userAgentInfo).have.property('rawCommand').with.type('string').be.equal(command);

      done();
    });

    it('should construct user agent info object with command and its parameters', function (done) {

      var givenCommand = 'keyvault create --vault-name \"testvault007\" --resource-group \"testrg007\" --location \"westus\"';
      var expectedRawCommand = 'azure keyvault create --vault-name testvault007 --resource-group testrg007 --location westus';

      telemetry.init(true)
      telemetry.start(['foo', 'bar', 'azure', 'keyvault', 'create', '--vault-name', 'testvault007', '--resource-group', 'testrg007', '--location', 'westus']);
      telemetry.currentCommand({
        fullName: function () {
          return givenCommand;
        }
      });

      telemetry.setMode('arm');
      telemetry.onFinish(function () { });

      var userAgentInfo = telemetry.getUserAgentInfo();

      // assert command name and parameters.
      should(userAgentInfo).have.property('commandName').with.type('string').be.equal(givenCommand);
      should(userAgentInfo).have.property('rawCommand').with.type('string').be.equal(expectedRawCommand);

      done();
    });

    it('should construct user agent info object when telemetry is not enabled', function (done) {
      var track = sandbox.spy(applicationInsights.client, 'track');

      var givenCommand = 'azure group list';

      // disable telemetry
      telemetry.init(false)
      telemetry.start(['foo', 'bar', 'azure', 'group', 'list']);
      telemetry.currentCommand({
        fullName: function () {
          return givenCommand;
        }
      });

      telemetry.setMode('arm');
      telemetry.onFinish(function () { });

      // assert telemetry is not enabled.
      (track.called).should.be.false;

      // verify userAgent is properly constructed
      var userAgentInfo = telemetry.getUserAgentInfo();

      (userAgentInfo).should.be.ok;
      (userAgentInfo.osType).should.be.ok;
      (userAgentInfo.osVersion).should.be.ok;
      (userAgentInfo.nodeVersion).should.be.ok;
      (userAgentInfo.installationType).should.be.ok;
      (userAgentInfo.userId).should.be.ok;
      (userAgentInfo.subscriptionId).should.be.ok;
      (userAgentInfo.userType).should.be.ok;
      (userAgentInfo.mode).should.be.ok;
      (userAgentInfo.commandName).should.be.ok;
      (userAgentInfo.rawCommand).should.be.ok;

      // verify values
      (userAgentInfo.mode).should.be.equal('arm');
      (userAgentInfo.commandName).should.be.equal(givenCommand);
      (userAgentInfo.rawCommand).should.be.equal(givenCommand);

      done();
    });

    it('should encrypt user sensitive data', function(done) {
      var eventData;
      sandbox.stub(applicationInsights.client, 'track', function(data) {
        eventData = data;
      });

      telemetry.setAppInsights(applicationInsights);
      telemetry.init(true);
      telemetry.start(['foo', 'bar', 'azure', 'login', '-u', 'foo', '-p', 'bar']);
      telemetry.currentCommand({
        fullName: function() {
          return 'azure login';
        }
      });
      telemetry.onFinish(function() {});

      (eventData.baseData.properties.command === 'azure login -u *** -p ***').should.be.true;
      done();
    });

    it('should catch exception and encrypt exception data', function(done) {
      var eventData;
      sandbox.stub(applicationInsights.client, 'track', function(data) {
        eventData = data;
      });

      telemetry.setAppInsights(applicationInsights);
      telemetry.init(true)
      telemetry.start(['foo', 'bar', 'azure', 'login', '-u', 'foo', '-p', 'bar']);
      telemetry.currentCommand({
        fullName: function() {
          return 'azure login';
        }
      });
      var err = new Error('error');
      telemetry.onError(err, function() {});
      (eventData.baseData.properties.isSuccess).should.be.false;
      //(eventData.baseData.properties.stacktrace).should.be.true;
      (eventData.baseData.properties.command === 'azure login -u *** -p ***').should.be.true;
      done();
    });

    it('should filter username from the stacktrace', function(done) {
      var eventData;
      sandbox.stub(applicationInsights.client, 'track', function(data) {
        eventData = data;
      });

      telemetry.setAppInsights(applicationInsights);
      telemetry.init(true)
      telemetry.start(['foo', 'bar', 'azure', 'login', '-u', 'foo', '-p', 'bar']);
      telemetry.currentCommand({
        fullName: function() {
          return 'azure login';
        }
      });
      var err = new Error('error');
      err.stack = fs.readFileSync(__dirname + '/../data/error.txt', 'utf8');
      var filteredError = fs.readFileSync(__dirname + '/../data/filtered_error.txt', 'utf8');
      telemetry.onError(err, function() {});
      (eventData.baseData.properties.isSuccess).should.be.false;
      eventData.baseData.properties.stacktrace.should.equal(filteredError);
      (eventData.baseData.properties.command === 'azure login -u *** -p ***').should.be.true;
      done();
    });
  })
});
<|endoftext|>


<commit_before>import React from 'react';
import { expect } from 'chai';
import { spy } from 'sinon';
import { shallow } from 'enzyme';
import { JSDOM } from 'jsdom';

import Field from '../../../src/components/Admin/Field';

const window = (new JSDOM('<!doctype html>')).window;
global.window = window;
global.document = window.document;
global.navigator = {
  userAgent: 'node.js',
};

function copyProps(src, target) {
  const props = Object.getOwnPropertyNames(src)
    .filter(prop => typeof target[prop] === 'undefined')
    .map(prop => Object.getOwnPropertyDescriptor(src, prop));
  Object.defineProperties(target, props);
}
copyProps(window, global);

describe('<Field />', () => {
  it('renders a div with props and text', () => {
    const onClick = spy();
    const wrapper = shallow(<Field name='test' />);
    expect(wrapper.find('div')).to.have.length(1);
    expect(wrapper.find('div').prop('name')).to.equal('test');
    expect(wrapper.find('div').text()).to.equal('test');
    wrapper.setProps({name: 'testing', id: 42, text: 'meaning', onClick: onClick});
    expect(wrapper.find('div').prop('name')).to.equal('testing');
    expect(wrapper.find('div').prop('id')).to.equal(42);
    expect(wrapper.find('div').text()).to.equal('meaning');
    expect(wrapper.find('div').prop('onClick')).to.equal(onClick);
  });
});
<commit_msg>added missing expect for placeholder className<commit_after>import React from 'react';
import { expect } from 'chai';
import { spy } from 'sinon';
import { shallow } from 'enzyme';
import { JSDOM } from 'jsdom';

import Field from '../../../src/components/Admin/Field';

const window = (new JSDOM('<!doctype html>')).window;
global.window = window;
global.document = window.document;
global.navigator = {
  userAgent: 'node.js',
};

function copyProps(src, target) {
  const props = Object.getOwnPropertyNames(src)
    .filter(prop => typeof target[prop] === 'undefined')
    .map(prop => Object.getOwnPropertyDescriptor(src, prop));
  Object.defineProperties(target, props);
}
copyProps(window, global);

describe('<Field />', () => {
  it('renders a div with props and text', () => {
    const onClick = spy();
    const wrapper = shallow(<Field name='test' />);
    expect(wrapper.find('div')).to.have.length(1);
    expect(wrapper.find('div').prop('name')).to.equal('test');
    expect(wrapper.find('div').prop('className')).to.equal('placeholder');
    expect(wrapper.find('div').text()).to.equal('test');
    wrapper.setProps({name: 'testing', id: 42, text: 'meaning', onClick: onClick});
    expect(wrapper.find('div').prop('name')).to.equal('testing');
    expect(wrapper.find('div').prop('className')).to.equal(undefined);
    expect(wrapper.find('div').prop('id')).to.equal(42);
    expect(wrapper.find('div').text()).to.equal('meaning');
    expect(wrapper.find('div').prop('onClick')).to.equal(onClick);
  });
});
<|endoftext|>


<commit_before>require('proof')(23, require('cadence')(prove))

function prove (async, okay) {
    var send = require('./fixtures/send')
    var optional = require('./fixtures/optional')
    var args = require('./fixtures/arguments')
    var main = require('./fixtures/main')
    var stream = require('stream')
    var events = require('events')
    var stdout
    var chunks
    var ee
    async(function () {
        var events = require('events')
        var identified = require('./fixtures/identified')
        async(function () {
            identified({}, async())
        }, function (identifier) {
            okay(identifier, [ 1 ], 'set identifier')
        })
    }, function () {
        var events = require('events')
        var errored = require('./fixtures/errored')
        async([function () {
            errored({}, async())
        }, function (error) {
            okay(/^destructible#error$/m.test(error.message), 'error from constructor')
        }])
    }, function () {
        var stream = require('stream')
        var echo = require('./fixtures/echo')
        async(function () {
            echo([ 'a', 'b' ], {
                $stdout: new stream.PassThrough
            }, async())
        }, function (child) {
            async(function () {
                child.exit(async())
            }, function () {
                okay(child.options.$stdout.read().toString(), 'a b\n', 'echo')
            })
        })
    }, function () {
        var messaged = require('./fixtures/messaged')
        var Messenger = require('../messenger')
        var stream = require('stream')
        async(function () {
            messaged({}, { $stdout: new stream.PassThrough, messenger: new Messenger }, async())
        }, function (child) {
            child.options.messenger.emit('message', { method: 'shutdown' })
            async(function () {
                child.exit(async())
            }, function () {
                okay(child.options.$stdout.read().toString(), 'shutdown\n', 'send')
            })
        })
    }, function () {
        var language = require('./fixtures/language')
        var LANG = process.env.LANG
        async(function () {
            process.env.LANG = 'fr_FR'
            console.log(process.env.LANG)
            language({}, {}, async())
        }, function (lang, child) {
            if (LANG != null) {
                process.env.LANG = LANG
            } else {
                delete process.env.LANG
            }
            okay(lang, 'fr_FR', 'language from environment')
            child.exit(async())
        })
    }, function () {
        okay(true, 'direct ee called back')
    }, function () {
        var optional = require('./fixtures/optional')
        async(function () {
            optional({}, async())
        }, function (pid, child) {
            okay(pid, process.pid, 'default property return')
            async(function () {
                child.exit(async())
                child.destroy()
            }, function (exitCode, pid) {
                okay({
                    exitCode: exitCode,
                    pid: pid
                }, {
                    exitCode: 0,
                    pid: process.pid
                },  'default property exit')
            })
        })
    }, function () {
        var optional = require('./fixtures/optional')
        async(function () {
            optional({}, { pid: 2 },  async())
        }, function (pid, child) {
            okay(pid, 2, 'override default property return')
            async(function () {
                child.exit(async())
                child.destroy()
            }, function (exitCode, pid) {
                okay({
                    exitCode: exitCode,
                    pid: pid
                }, {
                    exitCode: 0,
                    pid: 2
                },  'override default pid exit')
            })
        })
    }, function () {
        var events = require('events')
        var signaled = require('./fixtures/signaled')
        async(function () {
            signaled({}, {
                $signals: new events.EventEmitter
            }, async())
        }, function (destructed, child) {
            child.options.$signals.once('SIGINT', function () {
                okay('SIGINT swallowed')
            })
            okay(!destructed[0], 'SIGINT did not destroy')
            child.options.$signals.emit('SIGHUP') // Should do nothing.
            okay(!destructed[0], 'SIGHUP did not destroy')
            async(function () {
                child.exit(async())
                child.options.$signals.emit('SIGTERM')
            }, function (exitCode) {
                okay({
                    exitCode: exitCode,
                    destructed: destructed[0]
                }, {
                    exitCode: 0,
                    destructed: true
                },  'SIGTERM did destroy')
            })
        })
    }, function () {
        var events = require('events')
        var signaled = require('./fixtures/signaled')
        async(function () {
            signaled({}, {
                $signals: new events.EventEmitter,
                $trap: false
            }, async())
        }, function (destructed, child) {
            okay(child.options.$signals.listenerCount('SIGINT'), 0, 'no traps')
            child.options.$signals.emit('SIGINT')
            okay(!destructed[0], 'SIGINT did not destroy')
            child.destroy()
            child.exit(async())
        })
    }, function () {
        var events = require('events')
        var signaled = require('./fixtures/signaled')
        async(function () {
            signaled({}, {
                $signals: new events.EventEmitter,
                $trap: true
            }, async())
        }, function (destructed, child) {
            okay(child.options.$signals.listenerCount('SIGINT'), 1, 'has a SIGINT trap')
            child.options.$signals.emit('SIGINT')
            okay(destructed[0], 'SIGINT destroyed')
            child.destroy()
            child.exit(async())
        })
    }, function () {
        // Also tests untrap as false.
        var main = require('./fixtures/main')
        var events = require('events')
        async(function () {
            main({}, {
                $signals: new events.EventEmitter,
                $isMainModule: true
            }, async())
        }, function (isMainModule, child) {
            okay(isMainModule, 'is main module')
            okay(child.options.$signals.listenerCount('SIGINT'), 1, 'main module still trapped')
            child.exit(async())
        })
    }, function () {
        // Also tests untrap as false.
        var main = require('./fixtures/main')
        var events = require('events')
        async(function () {
            main({}, {
                $signals: new events.EventEmitter,
                $isMainModule: true,
                $untrap: true
            }, async())
        }, function (isMainModule, child) {
            okay(isMainModule, 'is still main module')
            okay(child.options.$signals.listenerCount('SIGINT'), 0, 'main module untrapped')
            child.exit(async())
        })
    }, function () {
        // Also tests untrap as false.
        var abend = require('./fixtures/abend')
        var events = require('events')
        async([function () {
            abend({}, async())
        }, function (error) {
            okay(error.exitCode, 1, 'abend exit code')
            return [ async.return ]
        }], function () {
            throw new Error('abend expected')
        })
    }, function () {
        var args = require('./fixtures/arguments')
        async(function () {
            args([{ name: 'value' }], {}, async())
        }, function (name, child) {
            okay(name, 'value', 'disconected')
            child.exit(async())
        })
    })
}
<commit_msg>Remove unused test.<commit_after>require('proof')(22, require('cadence')(prove))

function prove (async, okay) {
    var send = require('./fixtures/send')
    var optional = require('./fixtures/optional')
    var args = require('./fixtures/arguments')
    var main = require('./fixtures/main')
    var stream = require('stream')
    var events = require('events')
    var stdout
    var chunks
    var ee
    async(function () {
        var events = require('events')
        var identified = require('./fixtures/identified')
        async(function () {
            identified({}, async())
        }, function (identifier) {
            okay(identifier, [ 1 ], 'set identifier')
        })
    }, function () {
        var events = require('events')
        var errored = require('./fixtures/errored')
        async([function () {
            errored({}, async())
        }, function (error) {
            okay(/^destructible#error$/m.test(error.message), 'error from constructor')
        }])
    }, function () {
        var stream = require('stream')
        var echo = require('./fixtures/echo')
        async(function () {
            echo([ 'a', 'b' ], {
                $stdout: new stream.PassThrough
            }, async())
        }, function (child) {
            async(function () {
                child.exit(async())
            }, function () {
                okay(child.options.$stdout.read().toString(), 'a b\n', 'echo')
            })
        })
    }, function () {
        var messaged = require('./fixtures/messaged')
        var Messenger = require('../messenger')
        var stream = require('stream')
        async(function () {
            messaged({}, { $stdout: new stream.PassThrough, messenger: new Messenger }, async())
        }, function (child) {
            child.options.messenger.emit('message', { method: 'shutdown' })
            async(function () {
                child.exit(async())
            }, function () {
                okay(child.options.$stdout.read().toString(), 'shutdown\n', 'send')
            })
        })
    }, function () {
        var language = require('./fixtures/language')
        var LANG = process.env.LANG
        async(function () {
            process.env.LANG = 'fr_FR'
            console.log(process.env.LANG)
            language({}, {}, async())
        }, function (lang, child) {
            if (LANG != null) {
                process.env.LANG = LANG
            } else {
                delete process.env.LANG
            }
            okay(lang, 'fr_FR', 'language from environment')
            child.exit(async())
        })
    }, function () {
        var optional = require('./fixtures/optional')
        async(function () {
            optional({}, async())
        }, function (pid, child) {
            okay(pid, process.pid, 'default property return')
            async(function () {
                child.exit(async())
                child.destroy()
            }, function (exitCode, pid) {
                okay({
                    exitCode: exitCode,
                    pid: pid
                }, {
                    exitCode: 0,
                    pid: process.pid
                },  'default property exit')
            })
        })
    }, function () {
        var optional = require('./fixtures/optional')
        async(function () {
            optional({}, { pid: 2 },  async())
        }, function (pid, child) {
            okay(pid, 2, 'override default property return')
            async(function () {
                child.exit(async())
                child.destroy()
            }, function (exitCode, pid) {
                okay({
                    exitCode: exitCode,
                    pid: pid
                }, {
                    exitCode: 0,
                    pid: 2
                },  'override default pid exit')
            })
        })
    }, function () {
        var events = require('events')
        var signaled = require('./fixtures/signaled')
        async(function () {
            signaled({}, {
                $signals: new events.EventEmitter
            }, async())
        }, function (destructed, child) {
            child.options.$signals.once('SIGINT', function () {
                okay('SIGINT swallowed')
            })
            okay(!destructed[0], 'SIGINT did not destroy')
            child.options.$signals.emit('SIGHUP') // Should do nothing.
            okay(!destructed[0], 'SIGHUP did not destroy')
            async(function () {
                child.exit(async())
                child.options.$signals.emit('SIGTERM')
            }, function (exitCode) {
                okay({
                    exitCode: exitCode,
                    destructed: destructed[0]
                }, {
                    exitCode: 0,
                    destructed: true
                },  'SIGTERM did destroy')
            })
        })
    }, function () {
        var events = require('events')
        var signaled = require('./fixtures/signaled')
        async(function () {
            signaled({}, {
                $signals: new events.EventEmitter,
                $trap: false
            }, async())
        }, function (destructed, child) {
            okay(child.options.$signals.listenerCount('SIGINT'), 0, 'no traps')
            child.options.$signals.emit('SIGINT')
            okay(!destructed[0], 'SIGINT did not destroy')
            child.destroy()
            child.exit(async())
        })
    }, function () {
        var events = require('events')
        var signaled = require('./fixtures/signaled')
        async(function () {
            signaled({}, {
                $signals: new events.EventEmitter,
                $trap: true
            }, async())
        }, function (destructed, child) {
            okay(child.options.$signals.listenerCount('SIGINT'), 1, 'has a SIGINT trap')
            child.options.$signals.emit('SIGINT')
            okay(destructed[0], 'SIGINT destroyed')
            child.destroy()
            child.exit(async())
        })
    }, function () {
        // Also tests untrap as false.
        var main = require('./fixtures/main')
        var events = require('events')
        async(function () {
            main({}, {
                $signals: new events.EventEmitter,
                $isMainModule: true
            }, async())
        }, function (isMainModule, child) {
            okay(isMainModule, 'is main module')
            okay(child.options.$signals.listenerCount('SIGINT'), 1, 'main module still trapped')
            child.exit(async())
        })
    }, function () {
        // Also tests untrap as false.
        var main = require('./fixtures/main')
        var events = require('events')
        async(function () {
            main({}, {
                $signals: new events.EventEmitter,
                $isMainModule: true,
                $untrap: true
            }, async())
        }, function (isMainModule, child) {
            okay(isMainModule, 'is still main module')
            okay(child.options.$signals.listenerCount('SIGINT'), 0, 'main module untrapped')
            child.exit(async())
        })
    }, function () {
        // Also tests untrap as false.
        var abend = require('./fixtures/abend')
        var events = require('events')
        async([function () {
            abend({}, async())
        }, function (error) {
            okay(error.exitCode, 1, 'abend exit code')
            return [ async.return ]
        }], function () {
            throw new Error('abend expected')
        })
    }, function () {
        var args = require('./fixtures/arguments')
        async(function () {
            args([{ name: 'value' }], {}, async())
        }, function (name, child) {
            okay(name, 'value', 'disconected')
            child.exit(async())
        })
    })
}
<|endoftext|>