<commit_before>import EventDispatcher from '@vaalentin/event-dispatcher';

/**
 * @class GameLoop
 */
export default class GameLoop extends EventDispatcher {
  /**
   * @constructs GameLoop
   * @param {float} [fps = 60]
   * @param {float} [speed = 1]
   */
  constructor(fps = 60, speed = 1) {
    super();

    this._isFirstStart = true;

    this._timeStep = (1000 / fps) * speed;
    this._prevTime = null;
    this._lagTime = 0;

    this._frame = this.frame.bind(this);
    this._frameId = null;
  }

  /**
   * @method getTime
   * @private
   * @returns {float}
   */
  getTime() {
    return performance && performance.now
      ? performance.now()
      : Date.now();
  }

  /**
   * @method frame
   * @private
   */
  frame() {
    const curTime = this.getTime();
    const dt = Math.min(1000, curTime - this._prevTime);
    this._prevTime = curTime;
    this._lagTime += dt;

    while(this._lagTime > this._timeStep) {
      this._lagTime -= this._timeStep;
      this.dispatchEvent('update', this._timeStep);
    }

    this.dispatchEvent('render', dt);

    this._frameId = requestAnimationFrame(this._frame);
  }

  /**
   * @method start
   * @public
   */
  start() {
    if(this._isFirstStart) {
      this.dispatchEvent('init');
      this._isFirstStart = false;
    }

    this.dispatchEvent('start');
    this._prevTime = this.getTime();

    this.frame();
  }

  /**
   * @method stop
   * @public
   */
  stop() {
    this.dispatchEvent('stop');
    cancelRequestAnimationFrame(this._frameId);
    this._frameId = null;
  }

  /**
   * @method dispose
   * @public
   */
  dispose() {
    this.stop();
    super.dispose();
  }
}

<commit_msg>typo cancelAnimationFrame<commit_after>import EventDispatcher from '@vaalentin/event-dispatcher';

/**
 * @class GameLoop
 */
export default class GameLoop extends EventDispatcher {
  /**
   * @constructs GameLoop
   * @param {float} [fps = 60]
   * @param {float} [speed = 1]
   */
  constructor(fps = 60, speed = 1) {
    super();

    this._isFirstStart = true;

    this._timeStep = (1000 / fps) * speed;
    this._prevTime = null;
    this._lagTime = 0;

    this._frame = this.frame.bind(this);
    this._frameId = null;
  }

  /**
   * @method getTime
   * @private
   * @returns {float}
   */
  getTime() {
    return performance && performance.now
      ? performance.now()
      : Date.now();
  }

  /**
   * @method frame
   * @private
   */
  frame() {
    const curTime = this.getTime();
    const dt = Math.min(1000, curTime - this._prevTime);
    this._prevTime = curTime;
    this._lagTime += dt;

    while(this._lagTime > this._timeStep) {
      this._lagTime -= this._timeStep;
      this.dispatchEvent('update', this._timeStep);
    }

    this.dispatchEvent('render', dt);

    this._frameId = requestAnimationFrame(this._frame);
  }

  /**
   * @method start
   * @public
   */
  start() {
    if(this._isFirstStart) {
      this.dispatchEvent('init');
      this._isFirstStart = false;
    }

    this.dispatchEvent('start');
    this._prevTime = this.getTime();

    this.frame();
  }

  /**
   * @method stop
   * @public
   */
  stop() {
    this.dispatchEvent('stop');
    cancelAnimationFrame(this._frameId);
    this._frameId = null;
  }

  /**
   * @method dispose
   * @public
   */
  dispose() {
    this.stop();
    super.dispose();
  }
}

<|endoftext|>


<commit_before>// Copyright 2018 Google LLC
//
// 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
//
//     https://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.

/**
 * @namespace google
 */
/**
 * @namespace google.cloud
 */
/**
 * @namespace google.cloud.tasks
 */
/**
 * @namespace google.cloud.tasks.v2beta2
 */
/**
 * @namespace google.cloud.tasks.v2beta3
 */
/**
 * @namespace google.protobuf
 */
/**
 * @namespace google.rpc
 */
/**
 * @namespace google.type
 */

'use strict';

// Import the clients for each version supported by this package.
const gapic = Object.freeze({
  v2beta2: require('./v2beta2'),
  v2beta3: require('./v2beta3'),
});

/**
 * The `tasks` package has the following named exports:
 *
 * - `CloudTasksClient` - Reference to
 *   {@link v2beta2.CloudTasksClient}
 * - `v2beta2` - This is used for selecting or pinning a
 *   particular backend service version. It exports:
 *     - `CloudTasksClient` - Reference to
 *       {@link v2beta2.CloudTasksClient}
 *
 * @module {object} tasks
 * @alias nodejs-tasks
 *
 * @example
Install the client library with npm:

 * npm install --save tasks
 *
 * @example
Import the client library:

 * const tasks = require('@google-cloud/tasks');
 *
 * @example
Create a client that uses Application Default Credentials (ADC):

 * const client = new tasks.CloudTasksClient();
 *
 * @example
Create a client with explicit credentials:

 * const client = new tasks.CloudTasksClient({
 *   projectId: 'your-project-id',
 *   keyFilename: '/path/to/keyfile.json',
 * });
 */

/**
 * @type {object}
 * @property {constructor} CloudTasksClient
 *   Reference to {@link v2beta2.CloudTasksClient}
 */
module.exports = gapic.v2beta2;

/**
 * @type {object}
 * @property {constructor} CloudTasksClient
 *   Reference to {@link v2beta2.CloudTasksClient}
 */
module.exports.v2beta2 = gapic.v2beta2;

/**
 * @type {object}
 * @property {constructor} CloudTasksClient
 *   Reference to {@link v2beta2.CloudTasksClient}
 */
module.exports.v2beta3 = gapic.v2beta3;

// Alias `module.exports` as `module.exports.default`, for future-proofing.
module.exports.default = Object.assign({}, module.exports);
<commit_msg>feat: make v2beta3 the default version (#70)<commit_after>// Copyright 2018 Google LLC
//
// 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
//
//     https://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.

/**
 * @namespace google
 */
/**
 * @namespace google.cloud
 */
/**
 * @namespace google.cloud.tasks
 */
/**
 * @namespace google.cloud.tasks.v2beta2
 */
/**
 * @namespace google.cloud.tasks.v2beta3
 */
/**
 * @namespace google.protobuf
 */
/**
 * @namespace google.rpc
 */
/**
 * @namespace google.type
 */

'use strict';

// Import the clients for each version supported by this package.
const gapic = Object.freeze({
  v2beta2: require('./v2beta2'),
  v2beta3: require('./v2beta3'),
});

/**
 * The `tasks` package has the following named exports:
 *
 * - `CloudTasksClient` - Reference to
 *   {@link v2beta2.CloudTasksClient}
 * - `v2beta2` - This is used for selecting or pinning a
 *   particular backend service version. It exports:
 *     - `CloudTasksClient` - Reference to
 *       {@link v2beta2.CloudTasksClient}
 *
 * @module {object} tasks
 * @alias nodejs-tasks
 *
 * @example
Install the client library with npm:

 * npm install --save tasks
 *
 * @example
Import the client library:

 * const tasks = require('@google-cloud/tasks');
 *
 * @example
Create a client that uses Application Default Credentials (ADC):

 * const client = new tasks.CloudTasksClient();
 *
 * @example
Create a client with explicit credentials:

 * const client = new tasks.CloudTasksClient({
 *   projectId: 'your-project-id',
 *   keyFilename: '/path/to/keyfile.json',
 * });
 */

/**
 * @type {object}
 * @property {constructor} CloudTasksClient
 *   Reference to {@link v2beta3.CloudTasksClient}
 */
module.exports = gapic.v2beta3;

/**
 * @type {object}
 * @property {constructor} CloudTasksClient
 *   Reference to {@link v2beta2.CloudTasksClient}
 */
module.exports.v2beta2 = gapic.v2beta2;

/**
 * @type {object}
 * @property {constructor} CloudTasksClient
 *   Reference to {@link v2beta2.CloudTasksClient}
 */
module.exports.v2beta3 = gapic.v2beta3;

// Alias `module.exports` as `module.exports.default`, for future-proofing.
module.exports.default = Object.assign({}, module.exports);
<|endoftext|>


<commit_before>var Promise = require('promise');
var shexjs = require("shex");
var n3 = require("n3");

var DefaultBase = "";

function Validator(schemaText, dataText, callbacks, options) {
    this.callbacks = callbacks;
    this.options = options;

    this.updateSchema(location.origin + '/schema.shex', schemaText);
    this.updateData(dataText);

    // console.log("validator has instantiated");
    // console.log("callbacks:\n",callbacks);
    // console.log("options:\n",options);

}

Validator.prototype = {
    updateSchema: function (base, schemaText) {
        this.schema = parseSchema(base ,schemaText);
        // this.schema = schemaParser.parseSchema(schemaText);
        this.schema.done(this.callbacks.schemaParsed, this.callbacks.schemaParseError);
        // var _schema = shexjs.Parser.construct(DefaultBase).parse(schemaText);
        // console.log('UPDATING THE FUCKIGN Schema',this.schema, _schema);
    },
    updateData: function (dataText) {
        this.data = parseData(dataText);
        // this.data = dataParser.parseData(dataText);
        this.data.done(this.callbacks.dataParsed, this.callbacks.dataParseError);
    },
    findShapes: function () {
        var _this = this;
        return Promise.all([this.schema, this.data]).then(function (a) {
            console.log('showing shapes');
            console.log(this.schema);
            console.log(this.data);
        });
    },
    validate: function(startingNodes) {
        var _this = this;
        console.log('validate function',_this);
        return Promise.all([this.schema, this.data, this.options]).then(function (a) {
            console.log(a);
            var node = Object.keys(a[2].resourceShapeMap)[0];
            var result = shexjs.Validator.construct(a[0].schema).validate(a[1].db, node, a[2].resourceShapeMap[node]);
            console.log('callbacks in validator',_this.callbacks);
            // console.log('validation results:',result);
            // return validator.validate(
            //     a[0].schema,                       // Schema
            //     a[0].resolver,
            //     startingNodes,      // Starting Node
            //     a[1].db,                       // db
            //     a[1].resolver,
            //     _this.options.closedShapes,
            //     _this.callbacks.validationResult);
            return cleanResult(result, _this.callbacks.validationResult)
        });
    }
};

module.exports.Validator = Validator;

function parseData(dataText){
    console.log('split data');
    console.log(dataText.split("\n"));
    return new Promise(function (resolve, reject) {

        var db = n3.Store();
        n3.Parser({documentIRI: DefaultBase}).parse(dataText, function (error, triple, prefixes) {
            // console.log('db', db);
            // console.log('DB');
            console.log('triple callback')
            if (error) {
                // throw Error("error parsing " + data + ": " + error);
                reject(parseN3Error(error));
            } else if (triple) {
                console.log("N3triple",triple);
                // triple.line = N3triple.line;
                db.addTriple(triple);
            // console.log(triple.subject, triple.predicate, triple.object, '.');
            } else {
                resolve({db: db, triples:db.getTriples()});
            }
        });

    });
}

function parseSchema(base, schemaText) {
    return new Promise(function (resolve, reject) {
        var schema;
        try {
            schema = shexjs.Parser.construct(base).parse(schemaText);
        }
        catch (e) {
            reject(e);
        }
        resolve({schema: schema, shapes: schema.shapes});

    });
};

function cleanResult(result, callback){
    console.log('validation result', result);
    var errors = [];
    var solutions = [];
    if (result.type == 'Failure'){
        errors = result.errors;
    } else {
        solutions = result.solution.solutions;
    }
    console.log('errors',errors,'passed',errors.length === 0);
    var clean_result = {
            errors: errors,
            matches: solutions,
            startingResource: 'startingResource',
            passed: errors.length === 0,
            full_result:result
        };
    console.log('clean_result',clean_result);
    return callback(clean_result);
}

function parseN3Error(error) {
    var line = error.message.match(/line [0-9]*/g);

    line = (line && line.length > 0 && line[0].length > 5)?Number(line[0].substr(5)):null;

    return {
        message: error.message,
        line: line,
        column: 0
    }
}
<commit_msg>testing changes<commit_after>var Promise = require('promise');
var shexjs = require("shex");
var n3 = require("n3");

var DefaultBase = "";

function Validator(schemaText, dataText, callbacks, options) {
    this.callbacks = callbacks;
    this.options = options;

    this.updateSchema(location.origin + '/schema.shex', schemaText);
    this.updateData(dataText);

    // console.log("validator has instantiated");
    // console.log("callbacks:\n",callbacks);
    // console.log("options:\n",options);

}

Validator.prototype = {
    updateSchema: function (base, schemaText) {
        this.schema = parseSchema(base ,schemaText);
        // this.schema = schemaParser.parseSchema(schemaText);
        this.schema.done(this.callbacks.schemaParsed, this.callbacks.schemaParseError);
        // var _schema = shexjs.Parser.construct(DefaultBase).parse(schemaText);
        // console.log('UPDATING THE FUCKIGN Schema',this.schema, _schema);
    },
    updateData: function (dataText) {
        this.data = parseData(dataText);
        // this.data = dataParser.parseData(dataText);
        this.data.done(this.callbacks.dataParsed, this.callbacks.dataParseError);
    },
    findShapes: function () {
        var _this = this;
        return Promise.all([this.schema, this.data]).then(function (a) {
            console.log('showing shapes');
            console.log(this.schema);
            console.log(this.data);
        });
    },
    validate: function(startingNodes) {
        var _this = this;
        console.log('validate function',_this);
        return Promise.all([this.schema, this.data, this.options]).then(function (a) {
            console.log(a);
            var node = Object.keys(a[2].resourceShapeMap)[0];
            var result = shexjs.Validator.construct(a[0].schema).validate(a[1].db, node, a[2].resourceShapeMap[node]);
            console.log('callbacks in validator',_this.callbacks);
            console.log('db to validate',a[1].db)
            // console.log('validation results:',result);
            // return validator.validate(
            //     a[0].schema,                       // Schema
            //     a[0].resolver,
            //     startingNodes,      // Starting Node
            //     a[1].db,                       // db
            //     a[1].resolver,
            //     _this.options.closedShapes,
            //     _this.callbacks.validationResult);
            return cleanResult(result, _this.callbacks.validationResult)
        });
    }
};

module.exports.Validator = Validator;

function parseData(dataText){
    console.log('split data');
    console.log(dataText.split("\n"));
    return new Promise(function (resolve, reject) {

        var db = n3.Store();
        n3.Parser({documentIRI: DefaultBase}).parse(dataText, function (error, triple, prefixes) {
            // console.log('db', db);
            // console.log('DB');
            console.log('triple callback')
            if (error) {
                // throw Error("error parsing " + data + ": " + error);
                reject(parseN3Error(error));
            } else if (triple) {
                console.log("N3triple",triple);
                // triple.line = N3triple.line;
                db.addTriple(triple);
            // console.log(triple.subject, triple.predicate, triple.object, '.');
            } else {
                resolve({db: db, triples:db.getTriples()});
            }
        });

    });
}

function parseSchema(base, schemaText) {
    return new Promise(function (resolve, reject) {
        var schema;
        try {
            schema = shexjs.Parser.construct(base).parse(schemaText);
        }
        catch (e) {
            reject(e);
        }
        resolve({schema: schema, shapes: schema.shapes});

    });
};

function cleanResult(result, callback){
    console.log('validation result', result);
    var errors = [];
    var solutions = [];
    if (result.type == 'Failure'){
        errors = result.errors;
    } else {
        solutions = result.solution.solutions;
    }
    console.log('errors',errors,'passed',errors.length === 0);
    var clean_result = {
            errors: errors,
            matches: solutions,
            startingResource: 'startingResource',
            passed: errors.length === 0,
            full_result:result
        };
    console.log('clean_result',clean_result);
    return callback(clean_result);
}

function parseN3Error(error) {
    var line = error.message.match(/line [0-9]*/g);

    line = (line && line.length > 0 && line[0].length > 5)?Number(line[0].substr(5)):null;

    return {
        message: error.message,
        line: line,
        column: 0
    }
}
<|endoftext|>


<commit_before>import _ from 'underscore';
import { requestPromise } from './utils';
import * as acts from './acts';
import * as crawlers from './crawlers';
import keyValueStores from './key-value-stores';

export const getDefaultOptions = () => ({
    protocol: 'https',
    host: 'api.apifier.com',
    basePath: '',
    storeId: process.env.APIFY_ACT_RUN_ID, // When used inside of Act we set default storeId to act's run ID.
});

/**
 * Each property is a plain object of methods.
 *
 * Method must have 2 parameters "options" and "requestPromise" where:
 * - requestPromise is utils.requestPromise with Promise parameter set based on
 *   user's choice of Promises dependency.
 * - options
 *
 * Method must return promise.
 */
const methodGroups = {
    acts,
    crawlers,
    keyValueStores,
};

const ApifyClient = function (options = {}) {
    // This allows to initiate ApifyClient both ways - with and without "new".
    if (!this || this.constructor !== ApifyClient) return new ApifyClient(options);

    // This is used only internally for unit testing of ApifyClient.
    const undecoratedMethodGroups = options._overrideMethodGroups || methodGroups;
    delete options._overrideMethodGroups;

    const instanceOpts = Object.assign({}, getDefaultOptions(), options);

    // Choose Promises dependency and throw if no one is set.
    if (!instanceOpts.promise) {
        if (typeof Promise === 'function') {
            instanceOpts.promise = Promise;
        } else {
            throw new Error('The "options.promise" parameter is required when native Promise is not available.');
        }
    }

    const preconfiguredRequest = _.partial(requestPromise, instanceOpts.promise);

    /**
     * This decorator does:
     * - extends "options" parameter with values from default options and from ApifyClient instance options
     * - adds options.baseUrl
     * - passes preconfigured utils.requestPromise with Promises dependency set
     * - allows to use method with both callbacks and promises
     */
    const methodDecorator = (method) => {
        return (callOpts, callback) => {
            const mergedOpts = Object.assign({}, instanceOpts, callOpts);

            // Check that all required parameters are set.
            ['protocol', 'host', 'promise'].forEach((key) => {
                if (!instanceOpts[key]) throw new Error(`"options.${key}" parameter is required`);
            });

            // TODO: what's the point of having separate protocol/host/port/basePath?
            //       IMHO it's too complicated. The only relevant use case is it to enable testing on dev/staging,
            //       but this complicates config files or I need to parse the base URL before passing it to ApifyClient.
            //       please use simple 'baseUrl' in options, that's it
            // eslint-disable-next-line prefer-template
            mergedOpts.baseUrl = mergedOpts.protocol
                               + '://'
                               + mergedOpts.host
                               + (mergedOpts.port ? `:${mergedOpts.port}` : '')
                               + mergedOpts.basePath;

            const promise = method(preconfiguredRequest, mergedOpts);

            if (!callback) return promise;

            promise.then(
                result => callback(null, result),
                error => callback(error),
            );
        };
    };

    // Decorate methods and bind them to this object.
    _.forEach(undecoratedMethodGroups, (methodGroup, name) => {
        this[name] = _.mapObject(methodGroup, methodDecorator);
    });

    // Add setOptions(options) method to allow setOptions overriding.
    this.setOptions = (newOptions) => {
        _.forEach(newOptions, (val, key) => {
            instanceOpts[key] = val;
        });
    };
};

export default ApifyClient;
<commit_msg>Added new TODO<commit_after>import _ from 'underscore';
import { requestPromise } from './utils';
import * as acts from './acts';
import * as crawlers from './crawlers';
import keyValueStores from './key-value-stores';

export const getDefaultOptions = () => ({
    protocol: 'https',
    host: 'api.apifier.com',
    basePath: '',
    storeId: process.env.APIFY_ACT_RUN_ID, // When used inside of Act we set default storeId to act's run ID.
});

/**
 * Each property is a plain object of methods.
 *
 * Method must have 2 parameters "options" and "requestPromise" where:
 * - requestPromise is utils.requestPromise with Promise parameter set based on
 *   user's choice of Promises dependency.
 * - options
 *
 * Method must return promise.
 */
const methodGroups = {
    acts,
    crawlers,
    keyValueStores,
};

const ApifyClient = function (options = {}) {
    // This allows to initiate ApifyClient both ways - with and without "new".
    if (!this || this.constructor !== ApifyClient) return new ApifyClient(options);

    // This is used only internally for unit testing of ApifyClient.
    const undecoratedMethodGroups = options._overrideMethodGroups || methodGroups;
    delete options._overrideMethodGroups;

    const instanceOpts = Object.assign({}, getDefaultOptions(), options);

    // Choose Promises dependency and throw if no one is set.
    if (!instanceOpts.promise) {
        if (typeof Promise === 'function') {
            instanceOpts.promise = Promise;
        } else {
            throw new Error('The "options.promise" parameter is required when native Promise is not available.');
        }
    }

    const preconfiguredRequest = _.partial(requestPromise, instanceOpts.promise);

    /**
     * This decorator does:
     * - extends "options" parameter with values from default options and from ApifyClient instance options
     * - adds options.baseUrl
     * - passes preconfigured utils.requestPromise with Promises dependency set
     * - allows to use method with both callbacks and promises
     */
    const methodDecorator = (method) => {
        return (callOpts, callback) => {
            const mergedOpts = Object.assign({}, instanceOpts, callOpts);

            // Check that all required parameters are set.
            ['protocol', 'host', 'promise'].forEach((key) => {
                if (!instanceOpts[key]) throw new Error(`"options.${key}" parameter is required`);
            });

            // TODO: what's the point of having separate protocol/host/port/basePath?
            //       IMHO it's too complicated. The only relevant use case is it to enable testing on dev/staging,
            //       but this complicates config files or I need to parse the base URL before passing it to ApifyClient.
            //       please use simple 'baseUrl' in options, that's it
            //       (see https://github.com/Apifier/apifier-sdk-js/commit/b5d7db11954207c0f0adbfa668488312a44398a2)
            // eslint-disable-next-line prefer-template
            mergedOpts.baseUrl = mergedOpts.protocol
                               + '://'
                               + mergedOpts.host
                               + (mergedOpts.port ? `:${mergedOpts.port}` : '')
                               + mergedOpts.basePath;

            const promise = method(preconfiguredRequest, mergedOpts);

            if (!callback) return promise;

            promise.then(
                result => callback(null, result),
                error => callback(error),
            );
        };
    };

    // Decorate methods and bind them to this object.
    _.forEach(undecoratedMethodGroups, (methodGroup, name) => {
        this[name] = _.mapObject(methodGroup, methodDecorator);
    });

    // Add setOptions(options) method to allow setOptions overriding.
    this.setOptions = (newOptions) => {
        _.forEach(newOptions, (val, key) => {
            instanceOpts[key] = val;
        });
    };
};

export default ApifyClient;
<|endoftext|>


<commit_before>'use strict';

var Promise = require('native-promise-only');
var debug = require('debug');

var Github = require('./github');
var generatePlan = require('./generate-plan');
var Action = require('./models/action');
var GithubMessage = require('./models/messages/github');
var HubotMessage = require('./models/messages/hubot');

var log = debug('pull-review');

var defaultNotifyFn = function defaultNotifyFn(message) {
  log(message);
};

/**
 * Generate a plan of actions and execute it
 * @param  {Object} options
 * @param  {Boolean} options.dryRun - do not assign or notify reviewers
 * @param  {Function} options.notifyFn - custom notifying function
 * @param  {String} options.githubToken - GitHub token with user and repo scopes
 * @return {[type]}
 */
module.exports = function PullReview(options) {
  var actions;
  var loggedEvents = [];
  var dryRun = Boolean(options.dryRun);
  var notifyFn = options.notifyFn || defaultNotifyFn;
  var github = Github(options.githubToken);
  options.github = github;

  log('started on ' + options.pullRequestURL);

  return generatePlan(options)
    .then(function(res) {
      actions = res;

      var transaction = [];

      actions = actions.map(Action);
      actions.forEach(function(action) {
        switch (action.type) {
          case 'ASSIGN_USERS_TO_PULL_REQUEST':
            transaction.push(function() {
              return github.assignUsersToPullRequest(
                action.payload.pullRequest,
                action.payload.assignees
              );
            });
            loggedEvents.push(
              'assigned ' + action.payload.assignees.join(', ')
            );
            break;
          case 'UNASSIGN_USERS_FROM_PULL_REQUEST':
            transaction.push(function() {
              return github.unassignUsersFromPullRequest(
                action.payload.pullRequest,
                action.payload.assignees
              );
            });
            loggedEvents.push(
              'unassigned ' + action.payload.assignees.join(', ')
            );
            break;
          case 'CREATE_REVIEW_REQUEST':
            transaction.push(function() {
              return github.createReviewRequest(
                action.payload.pullRequest,
                action.payload.assignees
              );
            });
            if (action.payload.assignees.length) {
              loggedEvents.push(
                'requested a review from ' + action.payload.assignees.join(', ')
              );
            }
            break;
          case 'DELETE_REVIEW_REQUESTS':
            transaction.push(function() {
              return github.deleteReviewRequest(
                action.payload.pullRequest,
                action.payload.assignees
              );
            });

            if (action.payload.assignees.length) {
              loggedEvents.push(
                'removed review request' + (action.payload.assignees.length > 1 ? 's' : '') + ' from ' + action.payload.assignees.join(', ')
              );
            }
            break;
          case 'NOTIFY':
            if (action.payload.channel === 'github') {
              transaction.push(function() {
                return github.postPullRequestComment(
                  action.payload.pullRequest,
                  GithubMessage(action.payload)
                );
              });
              loggedEvents.push('posted GitHub comment');
            } else {
              transaction.push(function() {
                return new Promise(function(resolve) {
                  try {
                    var notification = HubotMessage(action.payload);
                    resolve(notifyFn(notification));
                  } catch (e) {
                    log(e);
                    resolve();
                  }
                });
              });
            }
            break;
        }
      });

      return Promise.resolve().then(function() {
        return transaction.reduce(function(promise, fn) {
          return promise.then(function () {
            return dryRun ? null : fn();
          });
        }, Promise.resolve());
      });
    })
    .then(function () {
      /**
       * GitHub API calls for a PR with two files:
       * getPullRequest: 1
       * getPullRequestFiles: 1
       * getPullRequestCommits: 1
       * getPullRequestLabels: 1
       * getReviewRequests: 1
       * getRepoFile: 1 (.pull-review)
       * getBlameForCommitFile: 2
       * assignUsersToPullRequest: 1
       * postPullRequestComment: 1
       */
      log(
        (dryRun ? 'would have ' : '') +
          loggedEvents.join(', ') +
          ' on ' +
          options.pullRequestURL
      );
      return actions;
    });
};
<commit_msg>log planned actions before plan is executed<commit_after>'use strict';

var Promise = require('native-promise-only');
var debug = require('debug');

var Github = require('./github');
var generatePlan = require('./generate-plan');
var Action = require('./models/action');
var GithubMessage = require('./models/messages/github');
var HubotMessage = require('./models/messages/hubot');

var log = debug('pull-review');

var defaultNotifyFn = function defaultNotifyFn(message) {
  log(message);
};

/**
 * Generate a plan of actions and execute it
 * @param  {Object} options
 * @param  {Boolean} options.dryRun - do not assign or notify reviewers
 * @param  {Function} options.notifyFn - custom notifying function
 * @param  {String} options.githubToken - GitHub token with user and repo scopes
 * @return {[type]}
 */
module.exports = function PullReview(options) {
  var actions;
  var plannedEvents = [];
  var dryRun = Boolean(options.dryRun);
  var notifyFn = options.notifyFn || defaultNotifyFn;
  var github = Github(options.githubToken);
  options.github = github;

  log('started on ' + options.pullRequestURL);

  return generatePlan(options)
    .then(function(res) {
      actions = res;

      var transaction = [];

      actions = actions.map(Action);
      actions.forEach(function(action) {
        switch (action.type) {
          case 'ASSIGN_USERS_TO_PULL_REQUEST':
            transaction.push(function() {
              return github.assignUsersToPullRequest(
                action.payload.pullRequest,
                action.payload.assignees
              );
            });
            plannedEvents.push(
              'assign ' + action.payload.assignees.join(', ')
            );
            break;
          case 'UNASSIGN_USERS_FROM_PULL_REQUEST':
            transaction.push(function() {
              return github.unassignUsersFromPullRequest(
                action.payload.pullRequest,
                action.payload.assignees
              );
            });
            plannedEvents.push(
              'unassign ' + action.payload.assignees.join(', ')
            );
            break;
          case 'CREATE_REVIEW_REQUEST':
            transaction.push(function() {
              return github.createReviewRequest(
                action.payload.pullRequest,
                action.payload.assignees
              );
            });
            if (action.payload.assignees.length) {
              plannedEvents.push(
                'request a review from ' + action.payload.assignees.join(', ')
              );
            }
            break;
          case 'DELETE_REVIEW_REQUESTS':
            transaction.push(function() {
              return github.deleteReviewRequest(
                action.payload.pullRequest,
                action.payload.assignees
              );
            });

            if (action.payload.assignees.length) {
              plannedEvents.push(
                'remove review request' + (action.payload.assignees.length > 1 ? 's' : '') + ' from ' + action.payload.assignees.join(', ')
              );
            }
            break;
          case 'NOTIFY':
            if (action.payload.channel === 'github') {
              transaction.push(function() {
                return github.postPullRequestComment(
                  action.payload.pullRequest,
                  GithubMessage(action.payload)
                );
              });
              plannedEvents.push('post GitHub comment');
            } else {
              transaction.push(function() {
                return new Promise(function(resolve) {
                  try {
                    var notification = HubotMessage(action.payload);
                    resolve(notifyFn(notification));
                  } catch (e) {
                    log(e);
                    resolve();
                  }
                });
              });
            }
            break;
        }
      });

      log('will ' + plannedEvents.join(', ') + ' on ' +
      options.pullRequestURL);

      return Promise.resolve().then(function() {
        return transaction.reduce(function(promise, fn) {
          return promise.then(function () {
            return dryRun ? null : fn();
          });
        }, Promise.resolve());
      });
    })
    .then(function () {
      /**
       * GitHub API calls for a PR with two files:
       * getPullRequest: 1
       * getPullRequestFiles: 1
       * getPullRequestCommits: 1
       * getPullRequestLabels: 1
       * getReviewRequests: 1
       * getRepoFile: 1 (.pull-review)
       * getBlameForCommitFile: 2
       * assignUsersToPullRequest: 1
       * postPullRequestComment: 1
       */
      if (!dryRun) {
        log('did ' + plannedEvents.join(', ') + ' on ' +
      options.pullRequestURL);
      }
      return actions;
    });
};
<|endoftext|>


<commit_before>import apiCreate from './api/create';
import apiEmit from './api/emit';
import apiFragment from './api/fragment';
import apiInit from './api/init';
import apiVersion from './api/version';
import assign from './util/assign';
import assignSafe from './util/assign-safe';
import attached from './lifecycle/attached';
import attribute from './lifecycle/attribute';
import created from './lifecycle/created';
import debounce from './util/debounce';
import defaults from './defaults';
import detached from './lifecycle/detached';
import documentObserver from './global/document-observer';
import elementConstructor from './util/element-constructor';
import registry from './global/registry';
import supportsCustomElements from './support/custom-elements';
import typeElement from './type/element';
import utilWalkTree from './util/walk-tree';
import validCustomElement from './support/valid-custom-element';

function makeOptions (userOptions) {
  var options = assignSafe({}, defaults);

  // Copy over all standard options if the user has defined them.
  for (let name in defaults) {
    if (userOptions[name] !== undefined) {
      options[name] = userOptions[name];
    }
  }

  // Copy over non-standard options.
  for (let name in userOptions) {
    options[name] = userOptions[name];
  }

  return options;
}

function makeNonNewableWrapper (Ctor) {
  var CtorWrapper = function (props = {}) {
    return assign(new Ctor(), props);
  };
  CtorWrapper.prototype = Ctor.prototype;
  return CtorWrapper;
}

var HTMLElement = window.HTMLElement;
var initDocument = debounce(function () {
  utilWalkTree(document.documentElement.childNodes, function (element) {
    var components = registry.find(element);
    var componentsLength = components.length;

    for (let a = 0; a < componentsLength; a++) {
      created(components[a]).call(element);
    }

    for (let a = 0; a < componentsLength; a++) {
      attached(components[a]).call(element);
    }
  });
});

function skate (id, userOptions) {
  let Ctor, CtorParent;
  let opts = makeOptions(userOptions);

  opts.id = id;
  opts.isNative = opts.type === typeElement && supportsCustomElements() && validCustomElement(id);
  CtorParent = opts.extends ? document.createElement(opts.extends).constructor : HTMLElement;

  // Inherit from parent prototype.
  if (!CtorParent.prototype.isPrototypeOf(opts.prototype)) {
    opts.prototype = assignSafe(Object.create(CtorParent.prototype), opts.prototype);
  }

  // Extend behaviour of existing callbacks.
  opts.prototype.createdCallback = created(opts);
  opts.prototype.attachedCallback = attached(opts);
  opts.prototype.detachedCallback = detached(opts);
  opts.prototype.attributeChangedCallback = attribute(opts);

  // Make a constructor for the definition.
  if (opts.isNative) {
    Ctor = document.registerElement(id, {
      extends: opts.extends || undefined,
      prototype: opts.prototype
    });
  } else {
    Ctor = elementConstructor(opts);
    initDocument();
    documentObserver.register();
  }

  Ctor = makeNonNewableWrapper(Ctor);
  assignSafe(Ctor, opts);
  registry.set(id, Ctor);

  return Ctor;
}

skate.create = apiCreate;
skate.emit = apiEmit;
skate.fragment = apiFragment;
skate.init = apiInit;
skate.version = apiVersion;

// ES6
export default skate;
<commit_msg>var -> let<commit_after>import apiCreate from './api/create';
import apiEmit from './api/emit';
import apiFragment from './api/fragment';
import apiInit from './api/init';
import apiVersion from './api/version';
import assign from './util/assign';
import assignSafe from './util/assign-safe';
import attached from './lifecycle/attached';
import attribute from './lifecycle/attribute';
import created from './lifecycle/created';
import debounce from './util/debounce';
import defaults from './defaults';
import detached from './lifecycle/detached';
import documentObserver from './global/document-observer';
import elementConstructor from './util/element-constructor';
import registry from './global/registry';
import supportsCustomElements from './support/custom-elements';
import typeElement from './type/element';
import utilWalkTree from './util/walk-tree';
import validCustomElement from './support/valid-custom-element';

function makeOptions (userOptions) {
  let options = assignSafe({}, defaults);

  // Copy over all standard options if the user has defined them.
  for (let name in defaults) {
    if (userOptions[name] !== undefined) {
      options[name] = userOptions[name];
    }
  }

  // Copy over non-standard options.
  for (let name in userOptions) {
    options[name] = userOptions[name];
  }

  return options;
}

function makeNonNewableWrapper (Ctor) {
  let CtorWrapper = function (props = {}) {
    return assign(new Ctor(), props);
  };
  CtorWrapper.prototype = Ctor.prototype;
  return CtorWrapper;
}

let HTMLElement = window.HTMLElement;
let initDocument = debounce(function () {
  utilWalkTree(document.documentElement.childNodes, function (element) {
    let components = registry.find(element);
    let componentsLength = components.length;

    for (let a = 0; a < componentsLength; a++) {
      created(components[a]).call(element);
    }

    for (let a = 0; a < componentsLength; a++) {
      attached(components[a]).call(element);
    }
  });
});

function skate (id, userOptions) {
  let Ctor, CtorParent;
  let opts = makeOptions(userOptions);

  opts.id = id;
  opts.isNative = opts.type === typeElement && supportsCustomElements() && validCustomElement(id);
  CtorParent = opts.extends ? document.createElement(opts.extends).constructor : HTMLElement;

  // Inherit from parent prototype.
  if (!CtorParent.prototype.isPrototypeOf(opts.prototype)) {
    opts.prototype = assignSafe(Object.create(CtorParent.prototype), opts.prototype);
  }

  // Extend behaviour of existing callbacks.
  opts.prototype.createdCallback = created(opts);
  opts.prototype.attachedCallback = attached(opts);
  opts.prototype.detachedCallback = detached(opts);
  opts.prototype.attributeChangedCallback = attribute(opts);

  // Make a constructor for the definition.
  if (opts.isNative) {
    Ctor = document.registerElement(id, {
      extends: opts.extends || undefined,
      prototype: opts.prototype
    });
  } else {
    Ctor = elementConstructor(opts);
    initDocument();
    documentObserver.register();
  }

  Ctor = makeNonNewableWrapper(Ctor);
  assignSafe(Ctor, opts);
  registry.set(id, Ctor);

  return Ctor;
}

skate.create = apiCreate;
skate.emit = apiEmit;
skate.fragment = apiFragment;
skate.init = apiInit;
skate.version = apiVersion;

// ES6
export default skate;
<|endoftext|>


<commit_before>import parse_css from './parser/parse-css';
import parse_grid from './parser/parse-grid';
import parse_shaders from './parser/parse-shaders';
import generator from './generator';
import seedrandom from './lib/seedrandom';
import { svg_to_png } from './svg';
import { draw_shader } from './shader.js';
import { uniform_time } from './uniform';

import get_props from './utils/get-props';
import { get_variable, get_all_variables } from './utils/variables';

import {
  cell_id, is_nil,
  normalize_png_name, cache_image,
  is_safari, un_entity,
  maybe, maybenot
} from './utils/index';

class Doodle extends HTMLElement {
  constructor() {
    super();
    this.doodle = this.attachShadow({ mode: 'open' });
    this.extra = {
      get_variable: name => get_variable(this, name)
    };
  }

  connectedCallback(again) {
    if (/^(complete|interactive|loaded)$/.test(document.readyState)) {
      this.load(again);
    } else {
      setTimeout(() => this.load(again));
    }
  }

  update(styles) {
    let use = this.get_use();
    if (!styles) styles = this.innerHTML;
    this.innerHTML = styles;

    if (!this.grid_size) {
      this.grid_size = this.get_grid();
    }

    let { x: gx, y: gy, z: gz } = this.grid_size;

    const compiled = this.generate(
      parse_css(use + styles, this.extra)
    );

    if (compiled.grid) {
      let { x, y, z } = compiled.grid;
      if (gx !== x || gy !== y || gz !== z) {
        Object.assign(this.grid_size, compiled.grid);
        return this.build_grid(compiled, compiled.grid);
      }
      Object.assign(this.grid_size, compiled.grid);
    }

    else {
      let grid = this.get_grid();
      let { x, y, z } = grid;
      if (gx !== x || gy !== y || gz !== z) {
        Object.assign(this.grid_size, grid);
        return this.build_grid(
          this.generate(parse_css(use + styles, this.extra)),
          grid
        );
      }
    }

    let replace = this.replace(compiled.doodles, compiled.shaders);

    this.set_content('.style-keyframes', replace(compiled.styles.keyframes));

    if (compiled.props.has_animation) {
      this.set_content('.style-cells', '');
      this.set_content('.style-container', '');
    }

    setTimeout(() => {
      this.set_content('.style-container', replace(
          get_grid_styles(this.grid_size)
        + compiled.styles.host
        + compiled.styles.container
      ));
      this.set_content('.style-cells', replace(compiled.styles.cells));
    });
  }

  get grid() {
    return Object.assign({}, this.grid_size);
  }

  set grid(grid) {
    this.attr('grid', grid);
    this.connectedCallback(true);
  }

  get seed() {
    return this._seed_value;
  }

  set seed(seed) {
    this.attr('seed', seed);
    this.connectedCallback(true);
  }

  get use() {
    return this.attr('use');
  }

  set use(use) {
    this.attr('use', use);
    this.connectedCallback(true);
  }

  static get observedAttributes() {
    return ['grid', 'use', 'seed'];
  }

  attributeChangedCallback(name, old_val, new_val) {
    if (old_val == new_val) {
      return false;
    }
    let observed = ['grid', 'use', 'seed'].includes(name);
    if (observed && !is_nil(old_val)) {
      this[name] = new_val;
    }
  }

  get_grid() {
    return parse_grid(this.attr('grid'));
  }

  get_use() {
    let use = this.attr('use') || '';
    if (use) use = `@use:${ use };`;
    return use;
  }

  attr(name, value) {
    if (arguments.length === 1) {
      return this.getAttribute(name);
    }
    if (arguments.length === 2) {
      this.setAttribute(name, value);
      return value;
    }
  }

  generate(parsed) {
    let grid = this.get_grid();
    let seed = this.attr('seed') || this.attr('data-seed');

    if (is_nil(seed)) {
      seed = Date.now();
    }

    seed = String(seed);
    this._seed_value = seed;

    let random = this.random = seedrandom(seed);
    let compiled = this.compiled = generator(parsed, grid, random);
    return compiled;
  }

  doodle_to_image(code, options, fn) {
    if (typeof options === 'function') {
      fn = options;
      options = null;
    }
    let parsed = parse_css(code, this.extra);
    let _grid = parse_grid({});
    let compiled = generator(parsed, _grid, this.random);
    let grid = compiled.grid ? compiled.grid : _grid;
    const { keyframes, host, container, cells } = compiled.styles;

    let replace = this.replace(compiled.doodles, compiled.shaders);
    let grid_container = create_grid(grid);

    let size = (options && options.width && options.height)
      ? `width="${ options.width }" height="${ options.height }"`
      : '';

    replace(`
      <svg ${ size } xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none">
        <foreignObject width="100%" height="100%">

            ${ grid_container }

        </foreignObject>
      </svg>
    `).then(result => {
      let source =`data:image/svg+xml;base64,${ window.btoa(unescape(encodeURIComponent(result))) }`;
      if (is_safari()) {
        cache_image(source);
      }
      fn(source);
    });
  }

  shader_to_image({ shader, cell }, fn) {
    let parsed = parse_shaders(shader);
    let element = this.doodle.getElementById(cell);
    let { width, height } = element.getBoundingClientRect();
    let ratio = window.devicePixelRatio || 1;

    if (!parsed.textures.length) {
      draw_shader(parsed, width, height).then(fn);
    }
    // Need to bind textures first
    else {
      let transforms = parsed.textures.map(texture => {
        return new Promise(resolve => {
          this.doodle_to_image(texture.value, { width, height }, src => {
            let img = new Image();
            img.width = width * ratio;
            img.height = height * ratio;
            img.onload = () => resolve({ name: texture.name, value: img });
            img.src = src;
          });
        });
      });
      Promise.all(transforms).then(textures => {
        parsed.textures = textures;
        draw_shader(parsed, width, height).then(fn);
      });
    }
  }

  load(again) {
    let use = this.get_use();
    if (!this.innerHTML.trim() && !use) {
      return false;
    }

    let parsed = parse_css(use + un_entity(this.innerHTML), this.extra);
    let compiled = this.generate(parsed);

    this.grid_size = compiled.grid
      ? compiled.grid
      : this.get_grid();

    this.build_grid(compiled, this.grid_size);

    if (!again) {
      if (this.hasAttribute('click-to-update')) {
        this.addEventListener('click', e => this.update());
      }
    }
  }

  replace(doodles, shaders) {
    let doodle_ids = Object.keys(doodles);
    let shader_ids = Object.keys(shaders);
    return input => {
      if (!doodle_ids.length && !shader_ids.length) {
        return Promise.resolve(input);
      }

      let mappings = [].concat(
        doodle_ids.map(id => {
          if (input.includes(id)) {
            return new Promise(resolve => {
              this.doodle_to_image(doodles[id], value => resolve({ id, value }));
            });
          } else {
            return Promise.resolve('');
          }
        }),
        shader_ids.map(id => {
          if (input.includes(id)) {
            return new Promise(resolve => {
              this.shader_to_image(shaders[id], value => resolve({ id, value }));
            });
          } else {
            return Promise.resolve('');
          }
        })
      );

      return Promise.all(mappings).then(mapping => {
        if (input.replaceAll) {
          mapping.forEach(({ id, value }) => {
            input = input.replaceAll('${' + id + '}', `url(${value})`);
          });
        } else {
          mapping.forEach(({ id, value }) => {
            input = input.replace('${' + id + '}', `url(${value})`);
          });
        }
        return input;
      });
    }
  }

  build_grid(compiled, grid) {
    const { has_transition, has_animation } = compiled.props;
    let has_delay = (has_transition || has_animation);

    const { keyframes, host, container, cells } = compiled.styles;
    let style_container = get_grid_styles(grid) + host + container;
    let style_cells = has_delay ? '' : cells;

    const { uniforms } = compiled;

    let replace = this.replace(compiled.doodles, compiled.shaders);

    this.doodle.innerHTML = `

      ${ create_grid(grid) }
    `;

    this.set_content('.style-container', replace(style_container));

    if (has_delay) {
      setTimeout(() => {
        this.set_content('.style-cells', replace(cells));
      }, 50);
    } else {
      this.set_content('.style-cells', replace(cells));
    }

    // might be removed in the future
    const definitions = compiled.definitions;
    if (window.CSS && window.CSS.registerProperty) {
      try {
        if (uniforms.time) {
          CSS.registerProperty({
            name: '--' + uniform_time.name,
            syntax: '<number>',
            initialValue: 0,
            inherits: true
          });
        }
        definitions.forEach(CSS.registerProperty);
      } catch (e) { }
    }
  }

  export({ scale, name, download, detail } = {}) {
    return new Promise((resolve, reject) => {
      let variables = get_all_variables(this);
      let html = this.doodle.innerHTML;

      let { width, height } = this.getBoundingClientRect();
      scale = parseInt(scale) || 1;

      let w = width * scale;
      let h = height * scale;

      let svg = minify(`
        <svg xmlns="http://www.w3.org/2000/svg"
          preserveAspectRatio="none"
          viewBox="0 0 ${ width } ${ height }"
          ${ maybenot(is_safari(), `width="${ w }px" height="${ h }px"`)}
        >
          <foreignObject width="100%" height="100%">

              ${ html }

          </foreignObject>
        </svg>
      `);

      if (download || detail) {
        svg_to_png(svg, w, h, scale)
          .then(({ source, url, blob }) => {
            resolve({
              width: w, height: h, svg, blob, source
            });
            if (download) {
              let a = document.createElement('a');
              a.download = normalize_png_name(name);
              a.href = url;
              a.click();
            }
          })
          .catch(error => {
            reject(error);
          });
      } else {
        resolve({
          width: w, height: h, svg: svg
        });
      }
    });
  }

  set_content(selector, styles) {
    if (styles instanceof Promise) {
      styles.then(value => {
        this.set_content(selector, value);
      });
    } else {
      const el = this.shadowRoot.querySelector(selector);
      el && (el.styleSheet
        ? (el.styleSheet.cssText = styles )
        : (el.innerHTML = styles));
    }
  }
}

if (!customElements.get('css-doodle')) {
  customElements.define('css-doodle', Doodle);
}

function get_basic_styles(uniforms = {}) {
  const inherited_grid_props = get_props(/grid/)
    .map(n => `${ n }: inherit;`)
    .join('');
  return `
    * {
      box-sizing: border-box
    }
    *::after, *::before {
      box-sizing: inherit
    }
    :host, .host {
      display: block;
      visibility: visible;
      width: auto;
      height: auto;
      --cssd-time-uniform: 0;
    }
    :host([hidden]), .host[hidden] {
      display: none
    }
    .container {
      position: relative;
      width: 100%;
      height: 100%;
      display: grid;
      ${ inherited_grid_props }
    }
    cell:empty {
      position: relative;
      line-height: 1;
      display: grid;
      place-items: center
    }
  `;
}

function get_grid_styles({x, y}) {
  return `
    :host, .host {
      grid-template-rows: repeat(${ y }, 1fr);
      grid-template-columns: repeat(${ x }, 1fr);
    }
  `;
}

function minify(input) {
  return input
    .replace(/\n\s+|^\s+|\n+/g, ' ')
    .trim();
}

function create_cell(x, y, z) {
  let cell = document.createElement('cell');
  cell.id = cell_id(x, y, z);
  return cell;
}

function create_grid({ x, y, z }) {
  let grid = document.createElement('grid');
  let root = document.createDocumentFragment();
  if (z == 1) {
    for (let j = 1; j <= y; ++j) {
      for (let i = 1; i <= x; ++i) {
        root.appendChild(create_cell(i, j, 1));
      }
    }
  }
  else {
    let temp = null;
    for (let i = 1; i <= z; ++i) {
      let cell = create_cell(1, 1, i);
      (temp || root).appendChild(cell);
      temp = cell;
    }
    temp = null;
  }
  grid.className = 'container';
  grid.appendChild(root);
  return grid.outerHTML;
}

function CSSDoodle(input, ...vars) {
  let get_value = v => is_nil(v) ? '' : v;
  let rules = input.reduce((s, c, i) => s + c + get_value(vars[i]), '');
  let doodle = document.createElement('css-doodle');
  if (doodle.update) {
    doodle.update(rules);
  }
  return doodle;
}

export default CSSDoodle;
<commit_msg>Fix initial time uniform name<commit_after>import parse_css from './parser/parse-css';
import parse_grid from './parser/parse-grid';
import parse_shaders from './parser/parse-shaders';
import generator from './generator';
import seedrandom from './lib/seedrandom';
import { svg_to_png } from './svg';
import { draw_shader } from './shader.js';
import { uniform_time } from './uniform';

import get_props from './utils/get-props';
import { get_variable, get_all_variables } from './utils/variables';

import {
  cell_id, is_nil,
  normalize_png_name, cache_image,
  is_safari, un_entity,
  maybe, maybenot
} from './utils/index';

class Doodle extends HTMLElement {
  constructor() {
    super();
    this.doodle = this.attachShadow({ mode: 'open' });
    this.extra = {
      get_variable: name => get_variable(this, name)
    };
  }

  connectedCallback(again) {
    if (/^(complete|interactive|loaded)$/.test(document.readyState)) {
      this.load(again);
    } else {
      setTimeout(() => this.load(again));
    }
  }

  update(styles) {
    let use = this.get_use();
    if (!styles) styles = this.innerHTML;
    this.innerHTML = styles;

    if (!this.grid_size) {
      this.grid_size = this.get_grid();
    }

    let { x: gx, y: gy, z: gz } = this.grid_size;

    const compiled = this.generate(
      parse_css(use + styles, this.extra)
    );

    if (compiled.grid) {
      let { x, y, z } = compiled.grid;
      if (gx !== x || gy !== y || gz !== z) {
        Object.assign(this.grid_size, compiled.grid);
        return this.build_grid(compiled, compiled.grid);
      }
      Object.assign(this.grid_size, compiled.grid);
    }

    else {
      let grid = this.get_grid();
      let { x, y, z } = grid;
      if (gx !== x || gy !== y || gz !== z) {
        Object.assign(this.grid_size, grid);
        return this.build_grid(
          this.generate(parse_css(use + styles, this.extra)),
          grid
        );
      }
    }

    let replace = this.replace(compiled.doodles, compiled.shaders);

    this.set_content('.style-keyframes', replace(compiled.styles.keyframes));

    if (compiled.props.has_animation) {
      this.set_content('.style-cells', '');
      this.set_content('.style-container', '');
    }

    setTimeout(() => {
      this.set_content('.style-container', replace(
          get_grid_styles(this.grid_size)
        + compiled.styles.host
        + compiled.styles.container
      ));
      this.set_content('.style-cells', replace(compiled.styles.cells));
    });
  }

  get grid() {
    return Object.assign({}, this.grid_size);
  }

  set grid(grid) {
    this.attr('grid', grid);
    this.connectedCallback(true);
  }

  get seed() {
    return this._seed_value;
  }

  set seed(seed) {
    this.attr('seed', seed);
    this.connectedCallback(true);
  }

  get use() {
    return this.attr('use');
  }

  set use(use) {
    this.attr('use', use);
    this.connectedCallback(true);
  }

  static get observedAttributes() {
    return ['grid', 'use', 'seed'];
  }

  attributeChangedCallback(name, old_val, new_val) {
    if (old_val == new_val) {
      return false;
    }
    let observed = ['grid', 'use', 'seed'].includes(name);
    if (observed && !is_nil(old_val)) {
      this[name] = new_val;
    }
  }

  get_grid() {
    return parse_grid(this.attr('grid'));
  }

  get_use() {
    let use = this.attr('use') || '';
    if (use) use = `@use:${ use };`;
    return use;
  }

  attr(name, value) {
    if (arguments.length === 1) {
      return this.getAttribute(name);
    }
    if (arguments.length === 2) {
      this.setAttribute(name, value);
      return value;
    }
  }

  generate(parsed) {
    let grid = this.get_grid();
    let seed = this.attr('seed') || this.attr('data-seed');

    if (is_nil(seed)) {
      seed = Date.now();
    }

    seed = String(seed);
    this._seed_value = seed;

    let random = this.random = seedrandom(seed);
    let compiled = this.compiled = generator(parsed, grid, random);
    return compiled;
  }

  doodle_to_image(code, options, fn) {
    if (typeof options === 'function') {
      fn = options;
      options = null;
    }
    let parsed = parse_css(code, this.extra);
    let _grid = parse_grid({});
    let compiled = generator(parsed, _grid, this.random);
    let grid = compiled.grid ? compiled.grid : _grid;
    const { keyframes, host, container, cells } = compiled.styles;

    let replace = this.replace(compiled.doodles, compiled.shaders);
    let grid_container = create_grid(grid);

    let size = (options && options.width && options.height)
      ? `width="${ options.width }" height="${ options.height }"`
      : '';

    replace(`
      <svg ${ size } xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none">
        <foreignObject width="100%" height="100%">

            ${ grid_container }

        </foreignObject>
      </svg>
    `).then(result => {
      let source =`data:image/svg+xml;base64,${ window.btoa(unescape(encodeURIComponent(result))) }`;
      if (is_safari()) {
        cache_image(source);
      }
      fn(source);
    });
  }

  shader_to_image({ shader, cell }, fn) {
    let parsed = parse_shaders(shader);
    let element = this.doodle.getElementById(cell);
    let { width, height } = element.getBoundingClientRect();
    let ratio = window.devicePixelRatio || 1;

    if (!parsed.textures.length) {
      draw_shader(parsed, width, height).then(fn);
    }
    // Need to bind textures first
    else {
      let transforms = parsed.textures.map(texture => {
        return new Promise(resolve => {
          this.doodle_to_image(texture.value, { width, height }, src => {
            let img = new Image();
            img.width = width * ratio;
            img.height = height * ratio;
            img.onload = () => resolve({ name: texture.name, value: img });
            img.src = src;
          });
        });
      });
      Promise.all(transforms).then(textures => {
        parsed.textures = textures;
        draw_shader(parsed, width, height).then(fn);
      });
    }
  }

  load(again) {
    let use = this.get_use();
    if (!this.innerHTML.trim() && !use) {
      return false;
    }

    let parsed = parse_css(use + un_entity(this.innerHTML), this.extra);
    let compiled = this.generate(parsed);

    this.grid_size = compiled.grid
      ? compiled.grid
      : this.get_grid();

    this.build_grid(compiled, this.grid_size);

    if (!again) {
      if (this.hasAttribute('click-to-update')) {
        this.addEventListener('click', e => this.update());
      }
    }
  }

  replace(doodles, shaders) {
    let doodle_ids = Object.keys(doodles);
    let shader_ids = Object.keys(shaders);
    return input => {
      if (!doodle_ids.length && !shader_ids.length) {
        return Promise.resolve(input);
      }

      let mappings = [].concat(
        doodle_ids.map(id => {
          if (input.includes(id)) {
            return new Promise(resolve => {
              this.doodle_to_image(doodles[id], value => resolve({ id, value }));
            });
          } else {
            return Promise.resolve('');
          }
        }),
        shader_ids.map(id => {
          if (input.includes(id)) {
            return new Promise(resolve => {
              this.shader_to_image(shaders[id], value => resolve({ id, value }));
            });
          } else {
            return Promise.resolve('');
          }
        })
      );

      return Promise.all(mappings).then(mapping => {
        if (input.replaceAll) {
          mapping.forEach(({ id, value }) => {
            input = input.replaceAll('${' + id + '}', `url(${value})`);
          });
        } else {
          mapping.forEach(({ id, value }) => {
            input = input.replace('${' + id + '}', `url(${value})`);
          });
        }
        return input;
      });
    }
  }

  build_grid(compiled, grid) {
    const { has_transition, has_animation } = compiled.props;
    let has_delay = (has_transition || has_animation);

    const { keyframes, host, container, cells } = compiled.styles;
    let style_container = get_grid_styles(grid) + host + container;
    let style_cells = has_delay ? '' : cells;

    const { uniforms } = compiled;

    let replace = this.replace(compiled.doodles, compiled.shaders);

    this.doodle.innerHTML = `

      ${ create_grid(grid) }
    `;

    this.set_content('.style-container', replace(style_container));

    if (has_delay) {
      setTimeout(() => {
        this.set_content('.style-cells', replace(cells));
      }, 50);
    } else {
      this.set_content('.style-cells', replace(cells));
    }

    // might be removed in the future
    const definitions = compiled.definitions;
    if (window.CSS && window.CSS.registerProperty) {
      try {
        if (uniforms.time) {
          CSS.registerProperty({
            name: '--' + uniform_time.name,
            syntax: '<number>',
            initialValue: 0,
            inherits: true
          });
        }
        definitions.forEach(CSS.registerProperty);
      } catch (e) { }
    }
  }

  export({ scale, name, download, detail } = {}) {
    return new Promise((resolve, reject) => {
      let variables = get_all_variables(this);
      let html = this.doodle.innerHTML;

      let { width, height } = this.getBoundingClientRect();
      scale = parseInt(scale) || 1;

      let w = width * scale;
      let h = height * scale;

      let svg = minify(`
        <svg xmlns="http://www.w3.org/2000/svg"
          preserveAspectRatio="none"
          viewBox="0 0 ${ width } ${ height }"
          ${ maybenot(is_safari(), `width="${ w }px" height="${ h }px"`)}
        >
          <foreignObject width="100%" height="100%">

              ${ html }

          </foreignObject>
        </svg>
      `);

      if (download || detail) {
        svg_to_png(svg, w, h, scale)
          .then(({ source, url, blob }) => {
            resolve({
              width: w, height: h, svg, blob, source
            });
            if (download) {
              let a = document.createElement('a');
              a.download = normalize_png_name(name);
              a.href = url;
              a.click();
            }
          })
          .catch(error => {
            reject(error);
          });
      } else {
        resolve({
          width: w, height: h, svg: svg
        });
      }
    });
  }

  set_content(selector, styles) {
    if (styles instanceof Promise) {
      styles.then(value => {
        this.set_content(selector, value);
      });
    } else {
      const el = this.shadowRoot.querySelector(selector);
      el && (el.styleSheet
        ? (el.styleSheet.cssText = styles )
        : (el.innerHTML = styles));
    }
  }
}

if (!customElements.get('css-doodle')) {
  customElements.define('css-doodle', Doodle);
}

function get_basic_styles(uniforms = {}) {
  const inherited_grid_props = get_props(/grid/)
    .map(n => `${ n }: inherit;`)
    .join('');
  return `
    * {
      box-sizing: border-box
    }
    *::after, *::before {
      box-sizing: inherit
    }
    :host, .host {
      display: block;
      visibility: visible;
      width: auto;
      height: auto;
      --${ uniform_time.name }: 0
    }
    :host([hidden]), .host[hidden] {
      display: none
    }
    .container {
      position: relative;
      width: 100%;
      height: 100%;
      display: grid;
      ${ inherited_grid_props }
    }
    cell:empty {
      position: relative;
      line-height: 1;
      display: grid;
      place-items: center
    }
  `;
}

function get_grid_styles({x, y}) {
  return `
    :host, .host {
      grid-template-rows: repeat(${ y }, 1fr);
      grid-template-columns: repeat(${ x }, 1fr);
    }
  `;
}

function minify(input) {
  return input
    .replace(/\n\s+|^\s+|\n+/g, ' ')
    .trim();
}

function create_cell(x, y, z) {
  let cell = document.createElement('cell');
  cell.id = cell_id(x, y, z);
  return cell;
}

function create_grid({ x, y, z }) {
  let grid = document.createElement('grid');
  let root = document.createDocumentFragment();
  if (z == 1) {
    for (let j = 1; j <= y; ++j) {
      for (let i = 1; i <= x; ++i) {
        root.appendChild(create_cell(i, j, 1));
      }
    }
  }
  else {
    let temp = null;
    for (let i = 1; i <= z; ++i) {
      let cell = create_cell(1, 1, i);
      (temp || root).appendChild(cell);
      temp = cell;
    }
    temp = null;
  }
  grid.className = 'container';
  grid.appendChild(root);
  return grid.outerHTML;
}

function CSSDoodle(input, ...vars) {
  let get_value = v => is_nil(v) ? '' : v;
  let rules = input.reduce((s, c, i) => s + c + get_value(vars[i]), '');
  let doodle = document.createElement('css-doodle');
  if (doodle.update) {
    doodle.update(rules);
  }
  return doodle;
}

export default CSSDoodle;
<|endoftext|>


<commit_before>import jQuery from 'jquery';

import 'bootstrap';
import 'bootstrap/less/bootstrap.less';

import 'jquery-ui';
import 'jquery-ui/ui/widgets/sortable';
import 'jquery-ui/themes/base/all.css';

import 'select2';
import 'select2/dist/css/select2.css';
import Chart from 'chart.js';

import 'gentelella/production/less/custom.css';
import 'font-awesome/css/font-awesome.css';

import '../libs/jquery.clonePosition';

import Epesi from './epesi';

window.Chart = Chart;
window.EpesiClass = Epesi;

window.focus_by_id = (id) => {
  const element = document.getElementById(id);
  if (element) setTimeout(() => element.focus(), 200);
};

window.addslashes = x => x.replace(/('|"|\\)/g, '\\$1');
<commit_msg>[Fix] Load jqueryUI disable selection<commit_after>import jQuery from 'jquery';

import 'bootstrap';
import 'bootstrap/less/bootstrap.less';

import 'jquery-ui';
import 'jquery-ui/ui/widgets/sortable';
import 'jquery-ui/ui/disable-selection';
import 'jquery-ui/themes/base/all.css';

import 'select2';
import 'select2/dist/css/select2.css';
import Chart from 'chart.js';

import 'gentelella/production/less/custom.css';
import 'font-awesome/css/font-awesome.css';

import '../libs/jquery.clonePosition';

import Epesi from './epesi';

window.Chart = Chart;
window.EpesiClass = Epesi;

window.focus_by_id = (id) => {
  const element = document.getElementById(id);
  if (element) setTimeout(() => element.focus(), 200);
};

window.addslashes = x => x.replace(/('|"|\\)/g, '\\$1');
<|endoftext|>


<commit_before>import _ from 'lodash';
import Chalk from 'chalk';

// Need to explicitly enable colors, probably for the same reason as:
// https://github.com/bcaudan/jasmine-spec-reporter/issues/36
var chalk = new Chalk.constructor({
  enabled: true
});

const LEVELS = {
 debug: {
  name: 'debug',
  color: 'cyan'
 },
 info: {
  name: 'info',
  color: 'magenta'
 },
 warning: {
  name: 'warning',
  color: 'yellow'
 },
 severe: {
  name: 'severe',
  color: 'red'
 }
};

const DEFAULT_LOG_LEVELS = [
  LEVELS.warning.name,
  LEVELS.severe.name
];

// http://stackoverflow.com/questions/1879860/most-reliable-split-character
const SPLIT_CHAR = '\u0007';

export default {
  postTest: function() {
    let config = this.config;

    return browser.manage().logs().get('browser')
      .then(result => {
        if(result.length === 0) {
          return;
        }

        printHeader.call(config);

        _(result)
          .chain()
          .filter(byLogLevel, config)
          .reduce(group, {})
          .forEach(printLog, config)
          .value();
      });
  }
};

function getLogLevels() {
  return this.logLevels || DEFAULT_LOG_LEVELS;
}

function byLogLevel(log) {
  return getLogLevels.call(this)
    .map(name => name.toLowerCase())
    .indexOf(log.level.name.toLowerCase()) !== -1;
}

function group(result, log) {
  let message = log.message;
  let id = [message, log.level.name].join(SPLIT_CHAR);
  result[id] = result[id] ? ++result[id] : 1;
  return result;
}

function printHeader() {
  (this.headerPrinter || headerPrinter).call(this);
}

function headerPrinter() {
  let header = `Test console output (log levels: ${getLogLevels.call(this).join(', ')})`;
  console.log(chalk.underline(header));
}

function printLog(count, log) {
  let split = log.split(SPLIT_CHAR);
  let options = {
    message: split[0],
    level: split[1],
    count
  };
  let printer = this.logPrinter || logPrinter;
  printer.call(printer, options);
}

function logPrinter({message, level, count}) {
  let color = chalk[LEVELS[level.toLowerCase()].color];
  let args = [color(message)];

  if (count > 1) {
    args.push(`(${count})`);
  }

  console.log.apply(console, args);
}
<commit_msg>Auto-format source<commit_after>import _ from 'lodash';
import Chalk from 'chalk';

// Need to explicitly enable colors, probably for the same reason as:
// https://github.com/bcaudan/jasmine-spec-reporter/issues/36
var chalk = new Chalk.constructor({
  enabled: true
});

const LEVELS = {
  debug: {
    name: 'debug',
    color: 'cyan'
  },
  info: {
    name: 'info',
    color: 'magenta'
  },
  warning: {
    name: 'warning',
    color: 'yellow'
  },
  severe: {
    name: 'severe',
    color: 'red'
  }
};

const DEFAULT_LOG_LEVELS = [
  LEVELS.warning.name,
  LEVELS.severe.name
];

// http://stackoverflow.com/questions/1879860/most-reliable-split-character
const SPLIT_CHAR = '\u0007';

export default {
  postTest: function() {
    let config = this.config;

    return browser.manage().logs().get('browser')
      .then(result => {
        if (result.length === 0) {
          return;
        }

        printHeader.call(config);

        _(result)
          .chain()
          .filter(byLogLevel, config)
          .reduce(group, {})
          .forEach(printLog, config)
          .value();
      });
  }
};

function getLogLevels() {
  return this.logLevels || DEFAULT_LOG_LEVELS;
}

function byLogLevel(log) {
  return getLogLevels.call(this)
    .map(name => name.toLowerCase())
    .indexOf(log.level.name.toLowerCase()) !== -1;
}

function group(result, log) {
  let message = log.message;
  let id = [message, log.level.name].join(SPLIT_CHAR);
  result[id] = result[id] ? ++result[id] : 1;
  return result;
}

function printHeader() {
  (this.headerPrinter || headerPrinter).call(this);
}

function headerPrinter() {
  let header = `Test console output (log levels: ${getLogLevels.call(this).join(', ')})`;
  console.log(chalk.underline(header));
}

function printLog(count, log) {
  let split = log.split(SPLIT_CHAR);
  let options = {
    message: split[0],
    level: split[1],
    count
  };
  let printer = this.logPrinter || logPrinter;
  printer.call(printer, options);
}

function logPrinter({message, level, count}) {
  let color = chalk[LEVELS[level.toLowerCase()].color];
  let args = [color(message)];

  if (count > 1) {
    args.push(`(${count})`);
  }

  console.log.apply(console, args);
}
<|endoftext|>


<commit_before>describe('Datagrid column service', function () {
    'use strict';

    var gridMock, columnsMetadata;

    beforeEach(module('data-prep.datagrid'));

    beforeEach(inject(function () {
        columnsMetadata = [
            {id: '0000', name: 'col0', type: 'string'},
            {id: '0001', name: 'col1', type: 'integer'},
            {id: '0002', name: 'col2', type: 'string', domain: 'salary'}
        ];

        /*global SlickGridMock:false */
        gridMock = new SlickGridMock();
    }));

    describe('on creation', function () {
        it('should add SlickGrid header destroy handler', inject(function (DatagridColumnService) {
            //given
            spyOn(gridMock.onBeforeHeaderCellDestroy, 'subscribe').and.returnValue();

            //when
            DatagridColumnService.init(gridMock);

            //then
            expect(gridMock.onBeforeHeaderCellDestroy.subscribe).toHaveBeenCalled();
        }));

        it('should add SlickGrid header creation handler', inject(function (DatagridColumnService) {
            //given
            spyOn(gridMock.onHeaderCellRendered, 'subscribe').and.returnValue();

            //when
            DatagridColumnService.init(gridMock);

            //then
            expect(gridMock.onHeaderCellRendered.subscribe).toHaveBeenCalled();
        }));
    });

    describe('create columns', function() {
        var headers = [
            {element: {detach: function() {}}},
            {element: {detach: function() {}}},
            {element: {detach: function() {}}}];
        var formatter = function() {};

        beforeEach(inject(function(DatagridColumnService, DatagridStyleService) {
            DatagridColumnService.init(gridMock);
            headers.forEach(function(header) {
                spyOn(header.element, 'detach').and.returnValue();
            });

            spyOn(DatagridStyleService, 'getColumnPreviewStyle').and.returnValue('');
            spyOn(DatagridStyleService, 'columnFormatter').and.returnValue(formatter);
        }));

        it('should create new preview grid columns', inject(function(DatagridColumnService) {
            //when
            var createdColumns = DatagridColumnService.createColumns(columnsMetadata, true, false);

            //then
            expect(createdColumns[0].id).toEqual('0000');
            expect(createdColumns[0].field).toEqual('0000');
            expect(createdColumns[0].name).toEqual('

col0

text

');
            expect(createdColumns[0].formatter).toEqual(formatter);
            expect(createdColumns[0].minWidth).toEqual(80);
            expect(createdColumns[0].tdpColMetadata).toEqual({ id: '0000', name: 'col0', type: 'string' } );

            expect(createdColumns[1].id).toEqual('0001');
            expect(createdColumns[1].field).toEqual('0001');
            expect(createdColumns[1].name).toEqual('

col1

number

');
            expect(createdColumns[1].formatter).toEqual(formatter);
            expect(createdColumns[1].minWidth).toEqual(80);
            expect(createdColumns[1].tdpColMetadata).toEqual({ id: '0001', name: 'col1', type: 'integer' } );

            expect(createdColumns[2].id).toEqual('0002');
            expect(createdColumns[2].field).toEqual('0002');
            expect(createdColumns[2].name).toEqual('

col2

salary

');
            expect(createdColumns[2].formatter).toEqual(formatter);
            expect(createdColumns[2].minWidth).toEqual(80);
            expect(createdColumns[2].tdpColMetadata).toEqual({ id: '0002', name: 'col2', type: 'string', domain: 'salary' } );
        }));

        it('should create new grid columns', inject(function(DatagridColumnService) {
            //when
            var createdColumns = DatagridColumnService.createColumns(columnsMetadata, false, false);

            //then
            expect(createdColumns[0].id).toEqual('0000');
            expect(createdColumns[0].field).toEqual('0000');
            expect(createdColumns[0].name).toEqual('');
            expect(createdColumns[0].formatter).toEqual(formatter);
            expect(createdColumns[0].minWidth).toEqual(80);
            expect(createdColumns[0].tdpColMetadata).toEqual({ id: '0000', name: 'col0', type: 'string' } );

            expect(createdColumns[1].id).toEqual('0001');
            expect(createdColumns[1].field).toEqual('0001');
            expect(createdColumns[1].name).toEqual('');
            expect(createdColumns[1].formatter).toEqual(formatter);
            expect(createdColumns[1].minWidth).toEqual(80);
            expect(createdColumns[1].tdpColMetadata).toEqual({ id: '0001', name: 'col1', type: 'integer' } );

            expect(createdColumns[2].id).toEqual('0002');
            expect(createdColumns[2].field).toEqual('0002');
            expect(createdColumns[2].name).toEqual('');
            expect(createdColumns[2].formatter).toEqual(formatter);
            expect(createdColumns[2].minWidth).toEqual(80);
            expect(createdColumns[2].tdpColMetadata).toEqual({ id: '0002', name: 'col2', type: 'string', domain: 'salary' });
        }));
    });

    describe('on column header destroy event', function() {
        var columnDef;

        beforeEach(inject(function(DatagridColumnService) {
            spyOn(gridMock.onBeforeHeaderCellDestroy, 'subscribe').and.returnValue();

            columnDef = {
                header: {remove: function() {}, detach: function() {}},
                scope: {$destroy: function() {}}
            };

            spyOn(columnDef.header, 'detach').and.returnValue();
            spyOn(columnDef.header, 'remove').and.returnValue();
            spyOn(columnDef.scope, '$destroy').and.returnValue();

            DatagridColumnService.init(gridMock);
        }));

        it('should do nothing when column is part of a preview', inject(function(DatagridColumnService) {
            //given
            columnDef.preview = true;
            var columnsArgs = {
                id: '0001',
                column: columnDef
            };
            DatagridColumnService.renewAllColumns(true);

            //when
            var onBeforeHeaderCellDestroy = gridMock.onBeforeHeaderCellDestroy.subscribe.calls.argsFor(0)[0];
            onBeforeHeaderCellDestroy(null, columnsArgs);

            //then
            expect(columnDef.header.detach).not.toHaveBeenCalled();
            expect(columnDef.header.remove).not.toHaveBeenCalled();
            expect(columnDef.scope.$destroy).not.toHaveBeenCalled();
        }));

        it('should destroy header when renewAllFlag is set to true', inject(function(DatagridColumnService) {
            //given
            columnDef.preview = false;
            var columnsArgs = {
                id: '0001',
                column: columnDef
            };
            DatagridColumnService.renewAllColumns(true);

            //when
            var onBeforeHeaderCellDestroy = gridMock.onBeforeHeaderCellDestroy.subscribe.calls.argsFor(0)[0];
            onBeforeHeaderCellDestroy(null, columnsArgs);

            //then
            expect(columnDef.header.detach).not.toHaveBeenCalled();
            expect(columnDef.header.remove).toHaveBeenCalled();
            expect(columnDef.scope.$destroy).toHaveBeenCalled();
        }));

        it('should detach header when renewAllFlag is set to false', inject(function(DatagridColumnService) {
            //given
            columnDef.preview = false;
            var columnsArgs = {
                id: '0001',
                column: columnDef
            };
            DatagridColumnService.renewAllColumns(false);

            //when
            var onBeforeHeaderCellDestroy = gridMock.onBeforeHeaderCellDestroy.subscribe.calls.argsFor(0)[0];
            onBeforeHeaderCellDestroy(null, columnsArgs);

            //then
            expect(columnDef.header.detach).toHaveBeenCalled();
            expect(columnDef.header.remove).not.toHaveBeenCalled();
            expect(columnDef.scope.$destroy).not.toHaveBeenCalled();
        }));
    });

    describe('on column header rendered event', function() {
        var availableScope;
        var availableHeader;

        function saveHeader(id, scope, header) {
            var columnsToDestroy = {
                id: id,
                scope: scope,
                header: header,
                preview: false
            };
            var headerToDetach = {
                column: columnsToDestroy
            };

            //destroy to save header in the available headers
            var onBeforeHeaderCellDestroy = gridMock.onBeforeHeaderCellDestroy.subscribe.calls.argsFor(0)[0];
            onBeforeHeaderCellDestroy(null, headerToDetach);
        }

        beforeEach(inject(function(DatagridColumnService) {
            spyOn(gridMock.onBeforeHeaderCellDestroy, 'subscribe').and.returnValue();
            spyOn(gridMock.onHeaderCellRendered, 'subscribe').and.returnValue();

            DatagridColumnService.init(gridMock);

            //save header in available headers list
            availableScope = {$destroy: function() {}, $digest: function() {}};
            availableHeader = angular.element('

')
            saveHeader('0001', availableScope, availableHeader);

            spyOn(availableScope, '$digest').and.returnValue();
        }));

        it('should attach and update available header that has the same id', inject(function() {
            //given
            var columnsArgs = {
                column:  {
                    id: '0001',
                    tdpColMetadata: {}
                },
                node: angular.element('

')[0]
            };

            //when
            var onHeaderCellRendered = gridMock.onHeaderCellRendered.subscribe.calls.argsFor(0)[0];
            onHeaderCellRendered(null, columnsArgs);

            //then
            expect(availableScope.column).toBe(columnsArgs.column.tdpColMetadata);
            expect(availableScope.$digest).toHaveBeenCalled();

            expect(columnsArgs.column.header).toBe(availableHeader);
            expect(columnsArgs.column.scope).toBe(availableScope);

            expect(angular.element(columnsArgs.node).find('#availableHeader').length).toBe(1);
        }));

        it('should create and attach a new header', inject(function() {
            //given
            var columnsArgs = {
                column:  {
                    id: '0002',
                    tdpColMetadata: {}
                },
                node: angular.element('

')[0]
            };

            //when
            var onHeaderCellRendered = gridMock.onHeaderCellRendered.subscribe.calls.argsFor(0)[0];
            onHeaderCellRendered(null, columnsArgs);

            //then
            expect(columnsArgs.column.scope).toBeDefined();
            expect(columnsArgs.column.header).toBeDefined();

            expect(columnsArgs.column.header).not.toBe(availableHeader);
            expect(columnsArgs.column.scope).not.toBe(availableScope);

            expect(angular.element(columnsArgs.node).find('datagrid-header').length).toBe(1);
        }));

        it('should do nothing if column is from preview', inject(function() {
            //given
            var columnsArgs = {
                column:  {
                    id: '0002',
                    tdpColMetadata: {},
                    preview: true
                },
                node: angular.element('

')[0]
            };

            //when
            var onHeaderCellRendered = gridMock.onHeaderCellRendered.subscribe.calls.argsFor(0)[0];
            onHeaderCellRendered(null, columnsArgs);

            //then
            expect(columnsArgs.column.scope).not.toBeDefined();
            expect(columnsArgs.column.header).not.toBeDefined();

            expect(angular.element(columnsArgs.node).find('datagrid-header').length).toBe(0);
        }));
    });
});
<commit_msg>TDP-382 : jshint fix<commit_after>describe('Datagrid column service', function () {
    'use strict';

    var gridMock, columnsMetadata;

    beforeEach(module('data-prep.datagrid'));

    beforeEach(inject(function () {
        columnsMetadata = [
            {id: '0000', name: 'col0', type: 'string'},
            {id: '0001', name: 'col1', type: 'integer'},
            {id: '0002', name: 'col2', type: 'string', domain: 'salary'}
        ];

        /*global SlickGridMock:false */
        gridMock = new SlickGridMock();
    }));

    describe('on creation', function () {
        it('should add SlickGrid header destroy handler', inject(function (DatagridColumnService) {
            //given
            spyOn(gridMock.onBeforeHeaderCellDestroy, 'subscribe').and.returnValue();

            //when
            DatagridColumnService.init(gridMock);

            //then
            expect(gridMock.onBeforeHeaderCellDestroy.subscribe).toHaveBeenCalled();
        }));

        it('should add SlickGrid header creation handler', inject(function (DatagridColumnService) {
            //given
            spyOn(gridMock.onHeaderCellRendered, 'subscribe').and.returnValue();

            //when
            DatagridColumnService.init(gridMock);

            //then
            expect(gridMock.onHeaderCellRendered.subscribe).toHaveBeenCalled();
        }));
    });

    describe('create columns', function() {
        var headers = [
            {element: {detach: function() {}}},
            {element: {detach: function() {}}},
            {element: {detach: function() {}}}];
        var formatter = function() {};

        beforeEach(inject(function(DatagridColumnService, DatagridStyleService) {
            DatagridColumnService.init(gridMock);
            headers.forEach(function(header) {
                spyOn(header.element, 'detach').and.returnValue();
            });

            spyOn(DatagridStyleService, 'getColumnPreviewStyle').and.returnValue('');
            spyOn(DatagridStyleService, 'columnFormatter').and.returnValue(formatter);
        }));

        it('should create new preview grid columns', inject(function(DatagridColumnService) {
            //when
            var createdColumns = DatagridColumnService.createColumns(columnsMetadata, true, false);

            //then
            expect(createdColumns[0].id).toEqual('0000');
            expect(createdColumns[0].field).toEqual('0000');
            expect(createdColumns[0].name).toEqual('

col0

text

');
            expect(createdColumns[0].formatter).toEqual(formatter);
            expect(createdColumns[0].minWidth).toEqual(80);
            expect(createdColumns[0].tdpColMetadata).toEqual({ id: '0000', name: 'col0', type: 'string' } );

            expect(createdColumns[1].id).toEqual('0001');
            expect(createdColumns[1].field).toEqual('0001');
            expect(createdColumns[1].name).toEqual('

col1

number

');
            expect(createdColumns[1].formatter).toEqual(formatter);
            expect(createdColumns[1].minWidth).toEqual(80);
            expect(createdColumns[1].tdpColMetadata).toEqual({ id: '0001', name: 'col1', type: 'integer' } );

            expect(createdColumns[2].id).toEqual('0002');
            expect(createdColumns[2].field).toEqual('0002');
            expect(createdColumns[2].name).toEqual('

col2

salary

');
            expect(createdColumns[2].formatter).toEqual(formatter);
            expect(createdColumns[2].minWidth).toEqual(80);
            expect(createdColumns[2].tdpColMetadata).toEqual({ id: '0002', name: 'col2', type: 'string', domain: 'salary' } );
        }));

        it('should create new grid columns', inject(function(DatagridColumnService) {
            //when
            var createdColumns = DatagridColumnService.createColumns(columnsMetadata, false, false);

            //then
            expect(createdColumns[0].id).toEqual('0000');
            expect(createdColumns[0].field).toEqual('0000');
            expect(createdColumns[0].name).toEqual('');
            expect(createdColumns[0].formatter).toEqual(formatter);
            expect(createdColumns[0].minWidth).toEqual(80);
            expect(createdColumns[0].tdpColMetadata).toEqual({ id: '0000', name: 'col0', type: 'string' } );

            expect(createdColumns[1].id).toEqual('0001');
            expect(createdColumns[1].field).toEqual('0001');
            expect(createdColumns[1].name).toEqual('');
            expect(createdColumns[1].formatter).toEqual(formatter);
            expect(createdColumns[1].minWidth).toEqual(80);
            expect(createdColumns[1].tdpColMetadata).toEqual({ id: '0001', name: 'col1', type: 'integer' } );

            expect(createdColumns[2].id).toEqual('0002');
            expect(createdColumns[2].field).toEqual('0002');
            expect(createdColumns[2].name).toEqual('');
            expect(createdColumns[2].formatter).toEqual(formatter);
            expect(createdColumns[2].minWidth).toEqual(80);
            expect(createdColumns[2].tdpColMetadata).toEqual({ id: '0002', name: 'col2', type: 'string', domain: 'salary' });
        }));
    });

    describe('on column header destroy event', function() {
        var columnDef;

        beforeEach(inject(function(DatagridColumnService) {
            spyOn(gridMock.onBeforeHeaderCellDestroy, 'subscribe').and.returnValue();

            columnDef = {
                header: {remove: function() {}, detach: function() {}},
                scope: {$destroy: function() {}}
            };

            spyOn(columnDef.header, 'detach').and.returnValue();
            spyOn(columnDef.header, 'remove').and.returnValue();
            spyOn(columnDef.scope, '$destroy').and.returnValue();

            DatagridColumnService.init(gridMock);
        }));

        it('should do nothing when column is part of a preview', inject(function(DatagridColumnService) {
            //given
            columnDef.preview = true;
            var columnsArgs = {
                id: '0001',
                column: columnDef
            };
            DatagridColumnService.renewAllColumns(true);

            //when
            var onBeforeHeaderCellDestroy = gridMock.onBeforeHeaderCellDestroy.subscribe.calls.argsFor(0)[0];
            onBeforeHeaderCellDestroy(null, columnsArgs);

            //then
            expect(columnDef.header.detach).not.toHaveBeenCalled();
            expect(columnDef.header.remove).not.toHaveBeenCalled();
            expect(columnDef.scope.$destroy).not.toHaveBeenCalled();
        }));

        it('should destroy header when renewAllFlag is set to true', inject(function(DatagridColumnService) {
            //given
            columnDef.preview = false;
            var columnsArgs = {
                id: '0001',
                column: columnDef
            };
            DatagridColumnService.renewAllColumns(true);

            //when
            var onBeforeHeaderCellDestroy = gridMock.onBeforeHeaderCellDestroy.subscribe.calls.argsFor(0)[0];
            onBeforeHeaderCellDestroy(null, columnsArgs);

            //then
            expect(columnDef.header.detach).not.toHaveBeenCalled();
            expect(columnDef.header.remove).toHaveBeenCalled();
            expect(columnDef.scope.$destroy).toHaveBeenCalled();
        }));

        it('should detach header when renewAllFlag is set to false', inject(function(DatagridColumnService) {
            //given
            columnDef.preview = false;
            var columnsArgs = {
                id: '0001',
                column: columnDef
            };
            DatagridColumnService.renewAllColumns(false);

            //when
            var onBeforeHeaderCellDestroy = gridMock.onBeforeHeaderCellDestroy.subscribe.calls.argsFor(0)[0];
            onBeforeHeaderCellDestroy(null, columnsArgs);

            //then
            expect(columnDef.header.detach).toHaveBeenCalled();
            expect(columnDef.header.remove).not.toHaveBeenCalled();
            expect(columnDef.scope.$destroy).not.toHaveBeenCalled();
        }));
    });

    describe('on column header rendered event', function() {
        var availableScope;
        var availableHeader;

        function saveHeader(id, scope, header) {
            var columnsToDestroy = {
                id: id,
                scope: scope,
                header: header,
                preview: false
            };
            var headerToDetach = {
                column: columnsToDestroy
            };

            //destroy to save header in the available headers
            var onBeforeHeaderCellDestroy = gridMock.onBeforeHeaderCellDestroy.subscribe.calls.argsFor(0)[0];
            onBeforeHeaderCellDestroy(null, headerToDetach);
        }

        beforeEach(inject(function(DatagridColumnService) {
            spyOn(gridMock.onBeforeHeaderCellDestroy, 'subscribe').and.returnValue();
            spyOn(gridMock.onHeaderCellRendered, 'subscribe').and.returnValue();

            DatagridColumnService.init(gridMock);

            //save header in available headers list
            availableScope = {$destroy: function() {}, $digest: function() {}};
            availableHeader = angular.element('

');
            saveHeader('0001', availableScope, availableHeader);

            spyOn(availableScope, '$digest').and.returnValue();
        }));

        it('should attach and update available header that has the same id', inject(function() {
            //given
            var columnsArgs = {
                column:  {
                    id: '0001',
                    tdpColMetadata: {}
                },
                node: angular.element('

')[0]
            };

            //when
            var onHeaderCellRendered = gridMock.onHeaderCellRendered.subscribe.calls.argsFor(0)[0];
            onHeaderCellRendered(null, columnsArgs);

            //then
            expect(availableScope.column).toBe(columnsArgs.column.tdpColMetadata);
            expect(availableScope.$digest).toHaveBeenCalled();

            expect(columnsArgs.column.header).toBe(availableHeader);
            expect(columnsArgs.column.scope).toBe(availableScope);

            expect(angular.element(columnsArgs.node).find('#availableHeader').length).toBe(1);
        }));

        it('should create and attach a new header', inject(function() {
            //given
            var columnsArgs = {
                column:  {
                    id: '0002',
                    tdpColMetadata: {}
                },
                node: angular.element('

')[0]
            };

            //when
            var onHeaderCellRendered = gridMock.onHeaderCellRendered.subscribe.calls.argsFor(0)[0];
            onHeaderCellRendered(null, columnsArgs);

            //then
            expect(columnsArgs.column.scope).toBeDefined();
            expect(columnsArgs.column.header).toBeDefined();

            expect(columnsArgs.column.header).not.toBe(availableHeader);
            expect(columnsArgs.column.scope).not.toBe(availableScope);

            expect(angular.element(columnsArgs.node).find('datagrid-header').length).toBe(1);
        }));

        it('should do nothing if column is from preview', inject(function() {
            //given
            var columnsArgs = {
                column:  {
                    id: '0002',
                    tdpColMetadata: {},
                    preview: true
                },
                node: angular.element('

')[0]
            };

            //when
            var onHeaderCellRendered = gridMock.onHeaderCellRendered.subscribe.calls.argsFor(0)[0];
            onHeaderCellRendered(null, columnsArgs);

            //then
            expect(columnsArgs.column.scope).not.toBeDefined();
            expect(columnsArgs.column.header).not.toBeDefined();

            expect(angular.element(columnsArgs.node).find('datagrid-header').length).toBe(0);
        }));
    });
});
<|endoftext|>