<commit_before>const path = require('path');
const test = require('tap').test;
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');

const projectUri = path.resolve(__dirname, '../fixtures/monitors.sb2');
const project = readFileToBuffer(projectUri);

const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());

// TODO figure out why running threads doesn't work in this test
// vm.start();
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);

test('Set Up - load the sb2 project', t => {
    vm.loadProject(project).then(() => {
        t.pass('Successfully Loaded!');
        t.end();
    });
});

test('saving and loading sb2 project with monitors preserves sliderMin and sliderMax', t => {

    vm.on('playgroundData', e /* eslint-disable-line no-unused-vars */ => {
        // TODO related to above TODO, comment these back in when we figure out
        // why running threads doesn't work with this test

        // const threads = JSON.parse(e.threads);
        // All monitors should create threads that finish during the step and
        // are revoved from runtime.threads.
        // t.equal(threads.length, 0);

        // we care that the last step updated the right number of monitors
        // we don't care whether the last step ran other threads or not
        // const lastStepUpdatedMonitorThreads = vm.runtime._lastStepDoneThreads.filter(thread => thread.updateMonitor);
        // t.equal(lastStepUpdatedMonitorThreads.length, 8);

        // There should be one additional hidden monitor that is in the monitorState but
        // does not start a thread.
        t.equal(vm.runtime._monitorState.size, 9);

        const stage = vm.runtime.targets[0];
        const target = vm.runtime.targets[1];

        // Global variable named "global" is a slider
        let variableId = Object.keys(stage.variables).filter(k => stage.variables[k].name === 'global')[0];
        // Used later when checking save and load of slider min/max
        let monitorRecord = vm.runtime._monitorState.get(variableId);
        t.equal(monitorRecord.opcode, 'data_variable');
        t.equal(monitorRecord.mode, 'slider');
        t.equal(monitorRecord.sliderMin, -200); // Make sure these are imported for sliders.
        t.equal(monitorRecord.sliderMax, 30);
        t.equal(monitorRecord.x, 5); // These are imported for all monitors, just check once.
        t.equal(monitorRecord.y, 59);
        t.equal(monitorRecord.visible, true);

        // Global variable named "global list" is a list
        variableId = Object.keys(stage.variables).filter(k => stage.variables[k].name === 'global list')[0];
        monitorRecord = vm.runtime._monitorState.get(variableId);
        t.equal(monitorRecord.opcode, 'data_listcontents');
        t.equal(monitorRecord.mode, 'list');
        t.equal(monitorRecord.visible, true);

        // Local variable named "local" is hidden
        variableId = Object.keys(target.variables).filter(k => target.variables[k].name === 'local')[0];
        monitorRecord = vm.runtime._monitorState.get(variableId);
        t.equal(monitorRecord.opcode, 'data_variable');
        t.equal(monitorRecord.mode, 'default');
        t.equal(monitorRecord.visible, false);

        // Local list named "local list" is visible
        variableId = Object.keys(target.variables).filter(k => target.variables[k].name === 'local list')[0];
        monitorRecord = vm.runtime._monitorState.get(variableId);
        t.equal(monitorRecord.opcode, 'data_listcontents');
        t.equal(monitorRecord.mode, 'list');
        t.equal(monitorRecord.visible, true);
        t.equal(monitorRecord.width, 104); // Make sure these are imported from lists.
        t.equal(monitorRecord.height, 204);

        // Backdrop name monitor is visible, not sprite specific
        // should get imported with id that references the name parameter
        // via '_name' at the end since the 3.0 block has a dropdown.
        monitorRecord = vm.runtime._monitorState.get('backdropnumbername_name');
        t.equal(monitorRecord.opcode, 'looks_backdropnumbername');
        t.equal(monitorRecord.mode, 'default');
        t.equal(monitorRecord.visible, true);
        t.equal(monitorRecord.spriteName, null);
        t.equal(monitorRecord.targetId, null);

        // x position monitor is in large mode, specific to sprite 1
        monitorRecord = vm.runtime._monitorState.get(`${target.id}_xposition`);
        t.equal(monitorRecord.opcode, 'motion_xposition');
        t.equal(monitorRecord.mode, 'large');
        t.equal(monitorRecord.visible, true);
        t.equal(monitorRecord.spriteName, 'Sprite1');
        t.equal(monitorRecord.targetId, target.id);

        let monitorId;
        let monitorBlock;

        // The monitor IDs for the sensing_current block should be unique
        // to the parameter that is selected on the block being monitored.
        // The paramater portion of the id should be lowercase even
        // though the field value on the block is uppercase.

        monitorId = 'current_date';
        monitorRecord = vm.runtime._monitorState.get(monitorId);
        t.equal(monitorRecord.opcode, 'sensing_current');
        monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
        t.equal(monitorBlock.fields.CURRENTMENU.value, 'DATE');
        t.equal(monitorRecord.mode, 'default');
        t.equal(monitorRecord.visible, true);
        t.equal(monitorRecord.spriteName, null);
        t.equal(monitorRecord.targetId, null);

        monitorId = 'current_minute';
        monitorRecord = vm.runtime._monitorState.get(monitorId);
        t.equal(monitorRecord.opcode, 'sensing_current');
        monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
        t.equal(monitorBlock.fields.CURRENTMENU.value, 'MINUTE');
        t.equal(monitorRecord.mode, 'default');
        t.equal(monitorRecord.visible, true);
        t.equal(monitorRecord.spriteName, null);
        t.equal(monitorRecord.targetId, null);

        monitorId = 'current_dayofweek';
        monitorRecord = vm.runtime._monitorState.get(monitorId);
        t.equal(monitorRecord.opcode, 'sensing_current');
        monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
        t.equal(monitorBlock.fields.CURRENTMENU.value, 'DAYOFWEEK');
        t.equal(monitorRecord.mode, 'default');
        t.equal(monitorRecord.visible, true);
        t.equal(monitorRecord.spriteName, null);
        t.equal(monitorRecord.targetId, null);

        t.end();
        process.nextTick(process.exit);
    });

    // Start VM, load project, and run
    t.doesNotThrow(() => {
        const sb3ProjectJson = vm.toJSON();
        return vm.loadProject(sb3ProjectJson).then(() => {
            setTimeout(() => {
                vm.getPlaygroundData();
                vm.stopAll();
            }, 100);
        });
    });
});
<commit_msg>Use beforeEach instead of a fake set up test<commit_after>const path = require('path');
const tap = require('tap');
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');

let vm;

tap.beforeEach(() => {
    const projectUri = path.resolve(__dirname, '../fixtures/monitors.sb2');
    const project = readFileToBuffer(projectUri);

    vm = new VirtualMachine();
    vm.attachStorage(makeTestStorage());

    // TODO figure out why running threads doesn't work in this test
    // vm.start();
    vm.clear();
    vm.setCompatibilityMode(false);
    vm.setTurboMode(false);

    return vm.loadProject(project);
});
const test = tap.test;

test('saving and loading sb2 project with monitors preserves sliderMin and sliderMax', t => {

    vm.on('playgroundData', e /* eslint-disable-line no-unused-vars */ => {
        // TODO related to above TODO, comment these back in when we figure out
        // why running threads doesn't work with this test

        // const threads = JSON.parse(e.threads);
        // All monitors should create threads that finish during the step and
        // are revoved from runtime.threads.
        // t.equal(threads.length, 0);

        // we care that the last step updated the right number of monitors
        // we don't care whether the last step ran other threads or not
        // const lastStepUpdatedMonitorThreads = vm.runtime._lastStepDoneThreads.filter(thread => thread.updateMonitor);
        // t.equal(lastStepUpdatedMonitorThreads.length, 8);

        // There should be one additional hidden monitor that is in the monitorState but
        // does not start a thread.
        t.equal(vm.runtime._monitorState.size, 9);

        const stage = vm.runtime.targets[0];
        const target = vm.runtime.targets[1];

        // Global variable named "global" is a slider
        let variableId = Object.keys(stage.variables).filter(k => stage.variables[k].name === 'global')[0];
        // Used later when checking save and load of slider min/max
        let monitorRecord = vm.runtime._monitorState.get(variableId);
        t.equal(monitorRecord.opcode, 'data_variable');
        t.equal(monitorRecord.mode, 'slider');
        t.equal(monitorRecord.sliderMin, -200); // Make sure these are imported for sliders.
        t.equal(monitorRecord.sliderMax, 30);
        t.equal(monitorRecord.x, 5); // These are imported for all monitors, just check once.
        t.equal(monitorRecord.y, 59);
        t.equal(monitorRecord.visible, true);

        // Global variable named "global list" is a list
        variableId = Object.keys(stage.variables).filter(k => stage.variables[k].name === 'global list')[0];
        monitorRecord = vm.runtime._monitorState.get(variableId);
        t.equal(monitorRecord.opcode, 'data_listcontents');
        t.equal(monitorRecord.mode, 'list');
        t.equal(monitorRecord.visible, true);

        // Local variable named "local" is hidden
        variableId = Object.keys(target.variables).filter(k => target.variables[k].name === 'local')[0];
        monitorRecord = vm.runtime._monitorState.get(variableId);
        t.equal(monitorRecord.opcode, 'data_variable');
        t.equal(monitorRecord.mode, 'default');
        t.equal(monitorRecord.visible, false);

        // Local list named "local list" is visible
        variableId = Object.keys(target.variables).filter(k => target.variables[k].name === 'local list')[0];
        monitorRecord = vm.runtime._monitorState.get(variableId);
        t.equal(monitorRecord.opcode, 'data_listcontents');
        t.equal(monitorRecord.mode, 'list');
        t.equal(monitorRecord.visible, true);
        t.equal(monitorRecord.width, 104); // Make sure these are imported from lists.
        t.equal(monitorRecord.height, 204);

        // Backdrop name monitor is visible, not sprite specific
        // should get imported with id that references the name parameter
        // via '_name' at the end since the 3.0 block has a dropdown.
        monitorRecord = vm.runtime._monitorState.get('backdropnumbername_name');
        t.equal(monitorRecord.opcode, 'looks_backdropnumbername');
        t.equal(monitorRecord.mode, 'default');
        t.equal(monitorRecord.visible, true);
        t.equal(monitorRecord.spriteName, null);
        t.equal(monitorRecord.targetId, null);

        // x position monitor is in large mode, specific to sprite 1
        monitorRecord = vm.runtime._monitorState.get(`${target.id}_xposition`);
        t.equal(monitorRecord.opcode, 'motion_xposition');
        t.equal(monitorRecord.mode, 'large');
        t.equal(monitorRecord.visible, true);
        t.equal(monitorRecord.spriteName, 'Sprite1');
        t.equal(monitorRecord.targetId, target.id);

        let monitorId;
        let monitorBlock;

        // The monitor IDs for the sensing_current block should be unique
        // to the parameter that is selected on the block being monitored.
        // The paramater portion of the id should be lowercase even
        // though the field value on the block is uppercase.

        monitorId = 'current_date';
        monitorRecord = vm.runtime._monitorState.get(monitorId);
        t.equal(monitorRecord.opcode, 'sensing_current');
        monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
        t.equal(monitorBlock.fields.CURRENTMENU.value, 'DATE');
        t.equal(monitorRecord.mode, 'default');
        t.equal(monitorRecord.visible, true);
        t.equal(monitorRecord.spriteName, null);
        t.equal(monitorRecord.targetId, null);

        monitorId = 'current_minute';
        monitorRecord = vm.runtime._monitorState.get(monitorId);
        t.equal(monitorRecord.opcode, 'sensing_current');
        monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
        t.equal(monitorBlock.fields.CURRENTMENU.value, 'MINUTE');
        t.equal(monitorRecord.mode, 'default');
        t.equal(monitorRecord.visible, true);
        t.equal(monitorRecord.spriteName, null);
        t.equal(monitorRecord.targetId, null);

        monitorId = 'current_dayofweek';
        monitorRecord = vm.runtime._monitorState.get(monitorId);
        t.equal(monitorRecord.opcode, 'sensing_current');
        monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
        t.equal(monitorBlock.fields.CURRENTMENU.value, 'DAYOFWEEK');
        t.equal(monitorRecord.mode, 'default');
        t.equal(monitorRecord.visible, true);
        t.equal(monitorRecord.spriteName, null);
        t.equal(monitorRecord.targetId, null);

        t.end();
        process.nextTick(process.exit);
    });

    // Start VM, load project, and run
    t.doesNotThrow(() => {
        const sb3ProjectJson = vm.toJSON();
        return vm.loadProject(sb3ProjectJson).then(() => {
            setTimeout(() => {
                vm.getPlaygroundData();
                vm.stopAll();
            }, 100);
        });
    });
});
<|endoftext|>


<commit_before>export default {
	format: 'umd',
	moduleName: 'angular-dual-listbox',
	external: [
		'@angular/core',
		'@angular/common'
	],
	onwarn: ( warning ) => {
		const skip_codes = [
			'THIS_IS_UNDEFINED',
			'MISSING_GLOBAL_NAME'
		];
		if ( skip_codes.indexOf(warning.code) != -1 )
			return;
		console.error(warning);
	}
};

<commit_msg>Add @angular/forms<commit_after>export default {
	format: 'umd',
	moduleName: 'angular-dual-listbox',
	external: [
		'@angular/core',
		'@angular/common',
		'@angular/forms'
	],
	onwarn: ( warning ) => {
		const skip_codes = [
			'THIS_IS_UNDEFINED',
			'MISSING_GLOBAL_NAME'
		];
		if ( skip_codes.indexOf(warning.code) != -1 )
			return;
		console.error(warning);
	}
};

<|endoftext|>


<commit_before>
'use strict';

var fs = require('fs');
var path = require('path');

var supertest = require('supertest');
var expect = require('thehelp-test').expect;
var util = require('./util');

var WORKER_STARTUP = 750; // milliseconds

var winston;

try {
  winston = require('winston');
}
catch (e) {}

describe('winston creates expected log files', function() {
  var agent, child, logFiles;

  before(function(done) {
    agent = supertest.agent('http://localhost:3000');

    util.emptyDir(util.logsDir, function(err) {
      if (err) {
        throw err;
      }

      child = util.startProcess(
        path.join(__dirname, '../../scenarios/end_to_end_cluster.js'));

      setTimeout(done, 1000);
    });
  });

  after(function(done) {
    this.timeout(10000);

    child.on('close', function() {

      // let's also validate that the master process logfile got everything
      var contents = fs.readFileSync(path.join(util.logsDir, logFiles[0]));
      contents = contents.toString();
      expect(contents).to.match(/Master about to exit with code 0/);

      done();
    });

    child.kill();
  });

  it('creates two log files on startup', function(done) {
    if (!winston) {
      return done();
    }

    fs.readdir(util.logsDir, function(err, files) {
      if (err) {
        throw err;
      }

      expect(files).to.have.length(2);

      files = files.sort();
      expect(files).to.have.deep.property('0').that.match(/master/);
      expect(files).to.have.deep.property('1').that.match(/worker/);

      logFiles = files;

      done();
    });
  });

  it('root returns', function(done) {
    agent
      .get('/')
      .expect('X-Worker', '1')
      .expect('Connection', 'close')
      .expect(200, done);
  });

  it('on async error, gets response with \'close connection\' header', function(done) {
    agent
      .get('/error')
      .expect('Connection', 'close')
      .expect('Content-Type', /text\/plain/)
      .expect('X-Worker', '1')
      .expect(/^error\!/)
      .expect(500, function(err) {
        if (err) {
          throw err;
        }

        setTimeout(done, WORKER_STARTUP);
      });
  });

  it('starts up another node', function(done) {
    this.timeout(5000);

    agent
      .get('/')
      .expect('X-Worker', '2')
      .expect('Connection', 'close')
      .expect(200, done);
  });

  it('three log files now in directory', function(done) {
    if (!winston) {
      return done();
    }

    fs.readdir(util.logsDir, function(err, files) {
      if (err) {
        throw err;
      }

      expect(files).to.have.length(3);

      files = files.sort();
      expect(files).to.have.deep.property('0', logFiles[0]);
      expect(files).to.have.deep.property('1', logFiles[1]);
      expect(files).to.have.deep.property('2').that.match(/worker/);

      logFiles = files;

      done();
    });
  });

});
<commit_msg>More logging test reliability changes<commit_after>
'use strict';

var fs = require('fs');
var path = require('path');

var supertest = require('supertest');
var expect = require('thehelp-test').expect;
var util = require('./util');

var WORKER_STARTUP = 750; // milliseconds

var winston;

try {
  winston = require('winston');
}
catch (e) {}

describe('winston creates expected log files', function() {
  var agent, child, logFiles;

  before(function(done) {
    agent = supertest.agent('http://localhost:3000');

    util.emptyDir(util.logsDir, function(err) {
      if (err) {
        throw err;
      }

      child = util.startProcess(
        path.join(__dirname, '../../scenarios/end_to_end_cluster.js'));

      setTimeout(done, 1000);
    });
  });

  after(function(done) {
    this.timeout(10000);

    child.on('close', function() {

      // let's also validate that the master process was logging
      var contents = fs.readFileSync(path.join(util.logsDir, logFiles[0]));
      contents = contents.toString();
      expect(contents).to.match(/Master calling all provided pre-exit check functions.../);

      done();
    });

    child.kill();
  });

  it('creates two log files on startup', function(done) {
    if (!winston) {
      return done();
    }

    fs.readdir(util.logsDir, function(err, files) {
      if (err) {
        throw err;
      }

      expect(files).to.have.length(2);

      files = files.sort();
      expect(files).to.have.deep.property('0').that.match(/master/);
      expect(files).to.have.deep.property('1').that.match(/worker/);

      logFiles = files;

      done();
    });
  });

  it('root returns', function(done) {
    agent
      .get('/')
      .expect('X-Worker', '1')
      .expect('Connection', 'close')
      .expect(200, done);
  });

  it('on async error, gets response with \'close connection\' header', function(done) {
    agent
      .get('/error')
      .expect('Connection', 'close')
      .expect('Content-Type', /text\/plain/)
      .expect('X-Worker', '1')
      .expect(/^error\!/)
      .expect(500, function(err) {
        if (err) {
          throw err;
        }

        setTimeout(done, WORKER_STARTUP);
      });
  });

  it('starts up another node', function(done) {
    this.timeout(5000);

    agent
      .get('/')
      .expect('X-Worker', '2')
      .expect('Connection', 'close')
      .expect(200, done);
  });

  it('three log files now in directory', function(done) {
    if (!winston) {
      return done();
    }

    fs.readdir(util.logsDir, function(err, files) {
      if (err) {
        throw err;
      }

      expect(files).to.have.length(3);

      files = files.sort();
      expect(files).to.have.deep.property('0', logFiles[0]);
      expect(files).to.have.deep.property('1', logFiles[1]);
      expect(files).to.have.deep.property('2').that.match(/worker/);

      logFiles = files;

      done();
    });
  });

});
<|endoftext|>


<commit_before>// add singleton to _.parse's supported event properties
_.singletonRE = /^_?\^/;
_.properties.splice(1,0, [_.singletonRE, function(){ this.singleton = true; }]);

// wrap _.fire's _.dispatch to save singletons with node and all parents
_.singleton_dispatch = _.dispatch;
_.dispatch = function(target, event) {
	_.singleton_dispatch(target, event);
	if (event.singleton) {
		do {
			var saved = target[_._sKey];
			if (saved) {
				saved.push(event);
			} else {
				Object.defineProperty(target, _._sKey, {value:[event],configurable:true});
			}
		} while (target = target.parentNode);
	}
};
_._sKey = _._key+'s.e.';

// wrap _.on's _.handler to execute fired singletons immediately
//TODO: ensure that combo.js wraps this _.handler instead of vice versa
//      combo events should be able to include singletons, but not be singletons
_.singleton_handler = _.handler;
_.handler = function(target, text, selector, fn) {
	var handler = _.singleton_handler.apply(this, arguments);
	if (handler.singleton) {
		handler.after = function() {
			if (_.off){ _.off(target, text, fn); }
			handler.fn = _.noop;
		};
		// search target's saved singletons, execute handler upon match
		var saved = target[_._sKey];
		if (saved) {
			for (var i=0,m=saved.length; i<m; i++) {
				var event = saved[i];
				if (_.handles(event, handler)) {
					if (target = _.target(handler, event.target)) {
						_.execute(target, event, handler);
						break;
					}
				}
			}
		}
	}
	return handler;
};

HTML.addEventListener('DOMContentLoaded', function(e) {
	_.fire(HTML, '^ready', e, e);
});
<commit_msg>no more HTML.js direct usage<commit_after>// add singleton to _.parse's supported event properties
_.singletonRE = /^_?\^/;
_.properties.splice(1,0, [_.singletonRE, function(){ this.singleton = true; }]);

// wrap _.fire's _.dispatch to save singletons with node and all parents
_.singleton_dispatch = _.dispatch;
_.dispatch = function(target, event) {
	_.singleton_dispatch(target, event);
	if (event.singleton) {
		do {
			var saved = target[_._sKey];
			if (saved) {
				saved.push(event);
			} else {
				Object.defineProperty(target, _._sKey, {value:[event],configurable:true});
			}
		} while (target = target.parentNode);
	}
};
_._sKey = _._key+'s.e.';

// wrap _.on's _.handler to execute fired singletons immediately
//TODO: ensure that combo.js wraps this _.handler instead of vice versa
//      combo events should be able to include singletons, but not be singletons
_.singleton_handler = _.handler;
_.handler = function(target, text, selector, fn) {
	var handler = _.singleton_handler.apply(this, arguments);
	if (handler.singleton) {
		handler.after = function() {
			if (_.off){ _.off(target, text, fn); }
			handler.fn = _.noop;
		};
		// search target's saved singletons, execute handler upon match
		var saved = target[_._sKey];
		if (saved) {
			for (var i=0,m=saved.length; i<m; i++) {
				var event = saved[i];
				if (_.handles(event, handler)) {
					if (target = _.target(handler, event.target)) {
						_.execute(target, event, handler);
						break;
					}
				}
			}
		}
	}
	return handler;
};

document.addEventListener('DOMContentLoaded', function(e) {
	_.fire(document.documentElement, '^ready', e, e);
});
<|endoftext|>


<commit_before>const request = require('request-promise-native');

const AbstractLDAPStrategy = require('./interface.js');

/**
 * General LDAP functionality
 * @implements {AbstractLDAPStrategy}
 */
class GeneralLDAPStrategy extends AbstractLDAPStrategy {
	constructor(app, config) {
		super(app, config);
	}

	/**
     * @public
     * @see AbstractLDAPStrategy#getSchoolsQuery
     * @returns {Array} Array of Objects containing ldapOu (ldap Organization Path), displayName
     * @memberof GeneralLDAPStrategy
     */
	getSchools() {
		return Promise.resolve([{
			displayName: this.config.providerOptions.schoolName,
			ldapOu: this.config.rootPath,
		}]);
	}

	/**
     * @public
     * @see AbstractLDAPStrategy#getUsers
     * @returns {Array} Array of Objects containing email, firstName, lastName, ldapDn, ldapUUID, ldapUID,
     * (Array) roles = ['teacher', 'student', 'administrator']
     * @memberof GeneralLDAPStrategy
     */
	getUsers(school) {
		const {
			userAttributeNameMapping,
			userPathAdditions,
			roleType,
			roleAttributeNameMapping,
		} = this.config.providerOptions;

		const options = {
			filter: 'objectClass=person',
			scope: 'sub',
			attributes: [
				userAttributeNameMapping.givenName,
				userAttributeNameMapping.sn,
				userAttributeNameMapping.dn,
				userAttributeNameMapping.uuid,
				userAttributeNameMapping.uid,
				userAttributeNameMapping.mail,
				(roleType === 'group') ? 'memberOf' : userAttributeNameMapping.role,
			],
		};

		const rawAttributes = [userAttributeNameMapping.uuid];

		const searchString = (userPathAdditions === '')
			? this.config.rootPath
			: `${userPathAdditions},${this.config.rootPath}`;

		return this.app.service('ldap').searchCollection(this.config, searchString, options, rawAttributes)
			.then((data) => {
				const results = [];
				data.forEach((obj) => {
					const roles = [];
					if (roleType === 'group') {
						if (!Array.isArray(obj.memberOf)) {
							obj.memberOf = [obj.memberOf];
						}
						if (obj.memberOf.includes(roleAttributeNameMapping.roleStudent)) {
							roles.push('student');
						}
						if (obj.memberOf.includes(roleAttributeNameMapping.roleTeacher)) {
							roles.push('teacher');
						}
						if (obj.memberOf.includes(roleAttributeNameMapping.roleAdmin)) {
							roles.push('administrator');
						}
						if (obj.memberOf.includes(roleAttributeNameMapping.roleNoSc)) {
							return;
						}
					} else {
						if (obj[userAttributeNameMapping.role]
                            === roleAttributeNameMapping.roleStudent) {
							roles.push('student');
						}
						if (obj[userAttributeNameMapping.role]
                            === roleAttributeNameMapping.roleTeacher) {
							roles.push('teacher');
						}
						if (obj[userAttributeNameMapping.role]
                            === roleAttributeNameMapping.roleAdmin) {
							roles.push('administrator');
						}
						if (obj[userAttributeNameMapping.role]
                            === roleAttributeNameMapping.roleNoSc) {
							return;
						}
					}

					if (roles.length === 0) {
						return;
					}

					results.push({
						email: obj[userAttributeNameMapping.mail],
						firstName: obj[userAttributeNameMapping.givenName],
						lastName: obj[userAttributeNameMapping.sn],
						roles,
						ldapDn: obj[userAttributeNameMapping.dn],
						ldapUUID: obj[userAttributeNameMapping.uuid],
						ldapUID: obj[userAttributeNameMapping.uid],
					});
				});
				return results;
			});
	}

	/**
     * @public
     * @see AbstractLDAPStrategy#getClasses
     * @returns {Array} Array of Objects containing className, ldapDn, uniqueMember
     * @memberof GeneralLDAPStrategy
     */
	getClasses(school) {
		const {
			classAttributeNameMapping,
			classPathAdditions,
		} = this.config.providerOptions;

		if (classPathAdditions !== '') {
			const options = {
				filter: `${classAttributeNameMapping.description}=*`,
				scope: 'sub',
				attributes: [
					classAttributeNameMapping.dn,
					classAttributeNameMapping.description,
					classAttributeNameMapping.uniqueMember,
				],
			};
			const searchString = `${classPathAdditions},${this.config.rootPath}`;
			return this.app.service('ldap').searchCollection(this.config, searchString, options)
				.then(data => data.map(obj => ({
					className: obj[classAttributeNameMapping.description],
					ldapDn: obj[classAttributeNameMapping.dn],
					uniqueMembers: obj[classAttributeNameMapping.uniqueMember],
				})));
		}
	}
}

module.exports = GeneralLDAPStrategy;
<commit_msg>Possibility to use several user paths for general ldap (#811)<commit_after>const request = require('request-promise-native');

const AbstractLDAPStrategy = require('./interface.js');

/**
 * General LDAP functionality
 * @implements {AbstractLDAPStrategy}
 */
class GeneralLDAPStrategy extends AbstractLDAPStrategy {
	constructor(app, config) {
		super(app, config);
	}

	/**
     * @public
     * @see AbstractLDAPStrategy#getSchoolsQuery
     * @returns {Array} Array of Objects containing ldapOu (ldap Organization Path), displayName
     * @memberof GeneralLDAPStrategy
     */
	getSchools() {
		return Promise.resolve([{
			displayName: this.config.providerOptions.schoolName,
			ldapOu: this.config.rootPath,
		}]);
	}

	/**
     * @public
     * @see AbstractLDAPStrategy#getUsers
     * @returns {Array} Array of Objects containing email, firstName, lastName, ldapDn, ldapUUID, ldapUID,
     * (Array) roles = ['teacher', 'student', 'administrator']
     * @memberof GeneralLDAPStrategy
     */
	getUsers(school) {
		const {
			userAttributeNameMapping,
			userPathAdditions,
			roleType,
			roleAttributeNameMapping,
		} = this.config.providerOptions;

		const options = {
			filter: 'objectClass=person',
			scope: 'sub',
			attributes: [
				userAttributeNameMapping.givenName,
				userAttributeNameMapping.sn,
				userAttributeNameMapping.dn,
				userAttributeNameMapping.uuid,
				userAttributeNameMapping.uid,
				userAttributeNameMapping.mail,
				(roleType === 'group') ? 'memberOf' : userAttributeNameMapping.role,
			],
		};

		const rawAttributes = [userAttributeNameMapping.uuid];

		const searchArray = userPathAdditions.split(';;');

		searchArray.forEach((searchString, index) => {
			searchArray[index] = (searchString === '')
				? this.config.rootPath
				: `${searchString},${this.config.rootPath}`;
		});

		const promises = searchArray.map((searchPath) => (
			this.app.service('ldap').searchCollection(this.config, searchPath, options, rawAttributes)
		));
		return Promise.all(promises)
			.then((results) => results.reduce((all, result) => all.concat(result)), [])
			.then((data) => {
				const results = [];
				data.forEach((obj) => {
					const roles = [];
					if (roleType === 'group') {
						if (!Array.isArray(obj.memberOf)) {
							obj.memberOf = [obj.memberOf];
						}
						if (obj.memberOf.includes(roleAttributeNameMapping.roleStudent)) {
							roles.push('student');
						}
						if (obj.memberOf.includes(roleAttributeNameMapping.roleTeacher)) {
							roles.push('teacher');
						}
						if (obj.memberOf.includes(roleAttributeNameMapping.roleAdmin)) {
							roles.push('administrator');
						}
						if (obj.memberOf.includes(roleAttributeNameMapping.roleNoSc)) {
							return;
						}
					} else {
						if (obj[userAttributeNameMapping.role]
                            === roleAttributeNameMapping.roleStudent) {
							roles.push('student');
						}
						if (obj[userAttributeNameMapping.role]
                            === roleAttributeNameMapping.roleTeacher) {
							roles.push('teacher');
						}
						if (obj[userAttributeNameMapping.role]
                            === roleAttributeNameMapping.roleAdmin) {
							roles.push('administrator');
						}
						if (obj[userAttributeNameMapping.role]
                            === roleAttributeNameMapping.roleNoSc) {
							return;
						}
					}

					if (roles.length === 0) {
						return;
					}

					results.push({
						email: obj[userAttributeNameMapping.mail],
						firstName: obj[userAttributeNameMapping.givenName],
						lastName: obj[userAttributeNameMapping.sn],
						roles,
						ldapDn: obj[userAttributeNameMapping.dn],
						ldapUUID: obj[userAttributeNameMapping.uuid],
						ldapUID: obj[userAttributeNameMapping.uid],
					});
				});
				return results;
			});
	}

	/**
     * @public
     * @see AbstractLDAPStrategy#getClasses
     * @returns {Array} Array of Objects containing className, ldapDn, uniqueMember
     * @memberof GeneralLDAPStrategy
     */
	getClasses(school) {
		const {
			classAttributeNameMapping,
			classPathAdditions,
		} = this.config.providerOptions;

		if (classPathAdditions !== '') {
			const options = {
				filter: `${classAttributeNameMapping.description}=*`,
				scope: 'sub',
				attributes: [
					classAttributeNameMapping.dn,
					classAttributeNameMapping.description,
					classAttributeNameMapping.uniqueMember,
				],
			};
			const searchString = `${classPathAdditions},${this.config.rootPath}`;
			return this.app.service('ldap').searchCollection(this.config, searchString, options)
				.then(data => data.map(obj => ({
					className: obj[classAttributeNameMapping.description],
					ldapDn: obj[classAttributeNameMapping.dn],
					uniqueMembers: obj[classAttributeNameMapping.uniqueMember],
				})));
		}
	}
}

module.exports = GeneralLDAPStrategy;
<|endoftext|>


<commit_before>var soda   = require('soda'),
	assert = require('assert'),
	common = require('./common')
	;

var DOWN  = '\\40',
	UP    = '\\38',
	ESC   = '\\27',
	ENTER = '\\13'
	;

var dropdown = 'css=.text-core > .text-wrap > .text-dropdown',
	textarea = 'css=#textarea'
	;

function assertTextareaValue(browser)
{
	browser.assertValue(textarea, 'PHP');
};

function testDropdownFunctionality(finalAssert)
{
	finalAssert = finalAssert || assertTextareaValue;

	return function(browser)
	{
		browser
			.click('css=.text-wrap')

			// activate the dropdown
			.keyDown(textarea, DOWN)
			.assertVisible(dropdown)
			.assertVisible(common.suggestionsXPath(true, 0))

			// go to the second item
			.keyDown(textarea, DOWN)
			.assertElementNotPresent(common.suggestionsXPath(true, 0))
			.assertVisible(common.suggestionsXPath(true, 1))

			// go to the third item
			.keyDown(textarea, DOWN)
			.assertElementNotPresent(common.suggestionsXPath(true, 1))
			.assertVisible(common.suggestionsXPath(true, 2))

			// go back up to the second item
			.keyDown(textarea, UP)
			.assertElementNotPresent(common.suggestionsXPath(true, 2))
			.assertVisible(common.suggestionsXPath(true, 1))

			// go back up to the first item
			.keyDown(textarea, UP)
			.assertElementNotPresent(common.suggestionsXPath(true, 1))
			.assertVisible(common.suggestionsXPath(true, 0))

			.typeKeys(textarea, 'ph')
			.assertVisible(common.suggestionsXPath(true, 0))
			.keyDown(textarea, ENTER)
			.assertNotVisible(dropdown)

			.and(finalAssert)
			;
	};
};

function testAutocomplete(exampleId, finalAssert)
{
	return function(browser)
	{
		browser
			.open('/manual/plugins/autocomplete/index.html')
			.clickAndWait('css=#example-' + exampleId)

			.and(common.verifyTextExt)
			.and(testDropdownFunctionality(finalAssert))
			.and(common.screenshot('autocomplete-' + exampleId))
			;
	};
};

function run(browser)
{
	browser
		.and(testAutocomplete('basics'))
		.and(testAutocomplete('with-filter'))
		.and(testAutocomplete('with-tags', common.testTagFunctionality()))
		.and(testAutocomplete('with-tags-and-filter', common.testFilterFunctionality()))
	;
};

module.exports = run;

if(require.main == module)
	common.runModule(run);

<commit_msg>Changed autocomplete test to use OCAML in the last step.<commit_after>var soda   = require('soda'),
	assert = require('assert'),
	common = require('./common')
	;

var DOWN  = '\\40',
	UP    = '\\38',
	ESC   = '\\27',
	ENTER = '\\13'
	;

var dropdown = 'css=.text-core > .text-wrap > .text-dropdown',
	textarea = 'css=#textarea'
	;

function assertTextareaValue(browser)
{
	browser.assertValue(textarea, 'OCAML');
};

function testDropdownFunctionality(finalAssert)
{
	finalAssert = finalAssert || assertTextareaValue;

	return function(browser)
	{
		browser
			.click('css=.text-wrap')

			// activate the dropdown
			.keyDown(textarea, DOWN)
			.assertVisible(dropdown)
			.assertVisible(common.suggestionsXPath(true, 0))

			// go to the second item
			.keyDown(textarea, DOWN)
			.assertElementNotPresent(common.suggestionsXPath(true, 0))
			.assertVisible(common.suggestionsXPath(true, 1))

			// go to the third item
			.keyDown(textarea, DOWN)
			.assertElementNotPresent(common.suggestionsXPath(true, 1))
			.assertVisible(common.suggestionsXPath(true, 2))

			// go back up to the second item
			.keyDown(textarea, UP)
			.assertElementNotPresent(common.suggestionsXPath(true, 2))
			.assertVisible(common.suggestionsXPath(true, 1))

			// go back up to the first item
			.keyDown(textarea, UP)
			.assertElementNotPresent(common.suggestionsXPath(true, 1))
			.assertVisible(common.suggestionsXPath(true, 0))

			.typeKeys(textarea, 'oca')
			.assertVisible(common.suggestionsXPath(true, 0))
			.keyDown(textarea, ENTER)
			.assertNotVisible(dropdown)

			.and(finalAssert)
			;
	};
};

function testAutocomplete(exampleId, finalAssert)
{
	return function(browser)
	{
		browser
			.open('/manual/plugins/autocomplete/index.html')
			.clickAndWait('css=#example-' + exampleId)

			.and(common.verifyTextExt)
			.and(testDropdownFunctionality(finalAssert))
			.and(common.screenshot('autocomplete-' + exampleId))
			;
	};
};

function run(browser)
{
	browser
		.and(testAutocomplete('basics'))
		.and(testAutocomplete('with-filter'))
		.and(testAutocomplete('with-tags', common.testTagFunctionality()))
		.and(testAutocomplete('with-tags-and-filter', common.testFilterFunctionality()))
	;
};

module.exports = run;

if(require.main == module)
	common.runModule(run);

<|endoftext|>


<commit_before>/**
 * Description : This is a test suite that tests an LRS endpoint based on the testing requirements document
 * found at https://github.com/adlnet/xAPI_LRS_Test/blob/master/TestingRequirements.md
 *
 * https://github.com/adlnet/xAPI_LRS_Test/blob/master/TestingRequirements.md
 *
 */
(function (module) {
    "use strict";

    // defines overwriting data
    var INVALID_LANGUAGE = {a12345: 'should fail'};
    var INVALID_NUMERIC = 12345;
    var INVALID_OBJECT = {key: 'should fail'};
    var INVALID_STRING = 'should fail';
    var VALID_ACTIVITY = {
        "objectType": "Activity",
        "id": "http://www.example.com/meetings/occurances/34534"
    };

    // configures tests
    module.exports.config = function () {
        return [
            {
            /**  XAPI-00095, Data 2.4.6.2 ContextActivities Property
             * A "contextActivities" property contains one or more key/value pairs. The LRS rejects with 400 Bad Request a statement which has an empty “contextActivities” property.
             */
                name: 'A "contextActivities" property contains one or more key/value pairs (Format, Data 2.4.6.2.s4.b2, XAPI-00095)',
                config: [
                    {
                        name: 'statement context "contextActivities" is empty',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.default}}'},
                            {contextActivities: {}}
                        ],
                        expect: [400]
                    },
                    {
                        name: 'statement substatement context "contextActivities" is empty',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.default}}'},
                            {contextActivities: {}}
                        ],
                        expect: [400]
                    }
                ]
            },
            {
            /**  XAPI-00093, Data 2.4.6.2 ContextActivities Property
             * A "contextActivities" property's "key" has a value of "parent", "grouping", "category", or "other". The LRS rejects with 400 Bad Request a statement which has a key other than "parent", "grouping", "category", or "other" for the “contextActivities” property
             */
                name: 'A "contextActivities" property\'s "key" has a value of "parent", "grouping", "category", or "other" (Format, Data 2.4.6.2.s4.b1, XAPI-00093)',
                config: [
                    {
                        name: 'statement context "contextActivities" is "parent"',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.parent}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context "contextActivities" is "grouping"',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.grouping}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context "contextActivities" is "category"',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.category}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context "contextActivities" is "other"',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.other}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context "contextActivities" accepts all property keys "parent", "grouping", "category", and "other"',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.all_activities}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context "contextActivities" rejects any property key other than "parent", "grouping", "category", or "other"',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.invalid_activity}}'}
                        ],
                        expect: [400]
                    },
                    {
                        name: 'statement substatement context "contextActivities" is "parent"',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.parent}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement substatement context "contextActivities" is "grouping"',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.grouping}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement substatement context "contextActivities" is "category"',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.category}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement substatement context "contextActivities" is "other"',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.other}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context "contextActivities" accepts all property keys "parent", "grouping", "category", and "other"',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.all_activities}}'}
                        ],
                        expect: [400]
                    },
                    {
                        name: 'statement context "contextActivities" rejects any property key other than "parent", "grouping", "category", or "other"',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.invalid_activity}}'}
                        ],
                        expect: [400]
                    }
                ]
            },
            {
            /**  XAPI-00094, Data 2.4.6.2 ContextActivities Property
             * A "contextActivities" property's "value" is an Activity. The LRS rejects with 400 Bad Request a statement which has a value which is not an Activity for the “contextActivities” property.
             */
                name: 'A "contextActivities" property\'s "value" is an Activity (Format, Data 2.4.6.2.s4.b2, XAPI-00094)',
                config: [
                    {
                            name: 'statement context "contextActivities parent" value is activity array',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.parent}}'},
                            {
                                contextActivities: {
                                    parent: [VALID_ACTIVITY]
                                }
                            }
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context "contextActivities grouping" value is activity array',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.grouping}}'},
                            {
                                contextActivities: {
                                    grouping: [VALID_ACTIVITY]
                                }
                            }
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context "contextActivities category" value is activity array',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.category}}'},
                            {
                                contextActivities: {
                                    category: [VALID_ACTIVITY]
                                }
                            }
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context "contextActivities other" value is activity array',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.other}}'},
                            {
                                contextActivities: {
                                    other: [VALID_ACTIVITY]
                                }
                            }
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context contextActivities property\'s value is activity array with activities',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.other}}'},
                            {
                                contextActivities: {
                                    other: [VALID_ACTIVITY, INVALID_OBJECT]
                                }
                            }
                        ],
                        expect: [400]
                    },
                    {
                        name: 'statement substatement context "contextActivities parent" value is activity array',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.parent}}'},
                            {
                                contextActivities: {
                                    parent: [VALID_ACTIVITY]
                                }
                            }
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement substatement context "contextActivities grouping" value is activity array',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.grouping}}'},
                            {
                                contextActivities: {
                                    grouping: [VALID_ACTIVITY]
                                }
                            }
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement substatement context "contextActivities category" value is activity array',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.category}}'},
                            {
                                contextActivities: {
                                    category: [VALID_ACTIVITY]
                                }
                            }
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement substatement context "contextActivities other" value is activity array',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.other}}'},
                            {
                                contextActivities: {
                                    other: [VALID_ACTIVITY]
                                }
                            }
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement substatement context "contextActivities property\'s value is activity array',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.other}}'},
                            {
                                contextActivities: {
                                    other: [INVALID_OBJECT, VALID_ACTIVITY]
                                }
                            }
                        ],
                        expect: [400]
                    }
                ]
            }
        ];
    };
}(module));
<commit_msg>fix bad test and wording in xapi-00093<commit_after>/**
 * Description : This is a test suite that tests an LRS endpoint based on the testing requirements document
 * found at https://github.com/adlnet/xAPI_LRS_Test/blob/master/TestingRequirements.md
 *
 * https://github.com/adlnet/xAPI_LRS_Test/blob/master/TestingRequirements.md
 *
 */
(function (module) {
    "use strict";

    // defines overwriting data
    var INVALID_LANGUAGE = {a12345: 'should fail'};
    var INVALID_NUMERIC = 12345;
    var INVALID_OBJECT = {key: 'should fail'};
    var INVALID_STRING = 'should fail';
    var VALID_ACTIVITY = {
        "objectType": "Activity",
        "id": "http://www.example.com/meetings/occurances/34534"
    };

    // configures tests
    module.exports.config = function () {
        return [
            {
            /**  XAPI-00095, Data 2.4.6.2 ContextActivities Property
             * A "contextActivities" property contains one or more key/value pairs. The LRS rejects with 400 Bad Request a statement which has an empty “contextActivities” property.
             */
                name: 'A "contextActivities" property contains one or more key/value pairs (Format, Data 2.4.6.2.s4.b2, XAPI-00095)',
                config: [
                    {
                        name: 'statement context "contextActivities" is empty',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.default}}'},
                            {contextActivities: {}}
                        ],
                        expect: [400]
                    },
                    {
                        name: 'statement substatement context "contextActivities" is empty',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.default}}'},
                            {contextActivities: {}}
                        ],
                        expect: [400]
                    }
                ]
            },
            {
            /**  XAPI-00093, Data 2.4.6.2 ContextActivities Property
             * A "contextActivities" property's "key" has a value of "parent", "grouping", "category", or "other". The LRS rejects with 400 Bad Request a statement which has a key other than "parent", "grouping", "category", or "other" for the “contextActivities” property
             */
                name: 'A "contextActivities" property\'s "key" has a value of "parent", "grouping", "category", or "other" (Format, Data 2.4.6.2.s4.b1, XAPI-00093)',
                config: [
                    {
                        name: 'statement context "contextActivities" is "parent"',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.parent}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context "contextActivities" is "grouping"',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.grouping}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context "contextActivities" is "category"',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.category}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context "contextActivities" is "other"',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.other}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context "contextActivities" accepts all property keys "parent", "grouping", "category", and "other"',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.all_activities}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context "contextActivities" rejects any property key other than "parent", "grouping", "category", or "other"',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.invalid_activity}}'}
                        ],
                        expect: [400]
                    },
                    {
                        name: 'statement substatement context "contextActivities" is "parent"',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.parent}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement substatement context "contextActivities" is "grouping"',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.grouping}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement substatement context "contextActivities" is "category"',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.category}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement substatement context "contextActivities" is "other"',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.other}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement substatement context "contextActivities" accepts all property keys "parent", "grouping", "category", and "other"',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.all_activities}}'}
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement substatement context "contextActivities" rejects any property key other than "parent", "grouping", "category", or "other"',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.invalid_activity}}'}
                        ],
                        expect: [400]
                    }
                ]
            },
            {
            /**  XAPI-00094, Data 2.4.6.2 ContextActivities Property
             * A "contextActivities" property's "value" is an Activity. The LRS rejects with 400 Bad Request a statement which has a value which is not an Activity for the “contextActivities” property.
             */
                name: 'A "contextActivities" property\'s "value" is an Activity (Format, Data 2.4.6.2.s4.b2, XAPI-00094)',
                config: [
                    {
                            name: 'statement context "contextActivities parent" value is activity array',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.parent}}'},
                            {
                                contextActivities: {
                                    parent: [VALID_ACTIVITY]
                                }
                            }
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context "contextActivities grouping" value is activity array',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.grouping}}'},
                            {
                                contextActivities: {
                                    grouping: [VALID_ACTIVITY]
                                }
                            }
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context "contextActivities category" value is activity array',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.category}}'},
                            {
                                contextActivities: {
                                    category: [VALID_ACTIVITY]
                                }
                            }
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context "contextActivities other" value is activity array',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.other}}'},
                            {
                                contextActivities: {
                                    other: [VALID_ACTIVITY]
                                }
                            }
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement context contextActivities property\'s value is activity array with activities',
                        templates: [
                            {statement: '{{statements.context}}'},
                            {context: '{{contexts.other}}'},
                            {
                                contextActivities: {
                                    other: [VALID_ACTIVITY, INVALID_OBJECT]
                                }
                            }
                        ],
                        expect: [400]
                    },
                    {
                        name: 'statement substatement context "contextActivities parent" value is activity array',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.parent}}'},
                            {
                                contextActivities: {
                                    parent: [VALID_ACTIVITY]
                                }
                            }
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement substatement context "contextActivities grouping" value is activity array',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.grouping}}'},
                            {
                                contextActivities: {
                                    grouping: [VALID_ACTIVITY]
                                }
                            }
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement substatement context "contextActivities category" value is activity array',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.category}}'},
                            {
                                contextActivities: {
                                    category: [VALID_ACTIVITY]
                                }
                            }
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement substatement context "contextActivities other" value is activity array',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.other}}'},
                            {
                                contextActivities: {
                                    other: [VALID_ACTIVITY]
                                }
                            }
                        ],
                        expect: [200]
                    },
                    {
                        name: 'statement substatement context "contextActivities property\'s value is activity array',
                        templates: [
                            {statement: '{{statements.object_substatement}}'},
                            {object: '{{substatements.context}}'},
                            {context: '{{contexts.other}}'},
                            {
                                contextActivities: {
                                    other: [INVALID_OBJECT, VALID_ACTIVITY]
                                }
                            }
                        ],
                        expect: [400]
                    }
                ]
            }
        ];
    };
}(module));
<|endoftext|>


<commit_before>import React, {useEffect, useState, Suspense, useMemo, useRef, useReducer} from 'react'
import PropTypes from 'prop-types'
import {viewPersistor} from 'tocco-util'
import {Icon, LoadMask} from 'tocco-ui'
import {searchFormTypePropTypes} from 'tocco-entity-list/src/util/searchFormTypes'
import {selectionStylePropType} from 'tocco-entity-list/src/util/selectionStyles'

import Action from '../Action'
import FileInput from '../FileInput'
import {StyledContentWrapper, StyledIconWrapper} from './StyledComponents'
import isRootLocation from '../../utils/isRootLocation'

const ICONS = {
  Domain: 'globe',
  Folder: 'folder',
  Resource: 'file'
}

export const getParent = match => {
  if (match.params && match.params.model) {
    const model = match.params.model.charAt(0).toUpperCase() + match.params.model.slice(1)
    const key = match.params.key
    const fullKey = `${model}/${key}`
    return {
      model: 'Docs_list_item',
      key: fullKey // e.g. "Domain/118"
    }
  }
  return null
}

export const getTql = domainTypes =>
  Array.isArray(domainTypes)
    && domainTypes.length > 0
    ? `exists(relDomain_type where IN(unique_id, ${domainTypes.map(type => `"${type}"`).join(',')}))`
    : null

export const getFormName = (parent, keys) => parent
  ? 'Docs_list_item'
  : keys
    ? 'Root_docs_list_item_specific'
    : 'Root_docs_list_item'

export const getDefaultLocation = (model, key) => {
  switch (model) {
    case 'Domain':
      return `/docs/domain/${key}/list`
    case 'Folder':
      return `/docs/folder/${key}/list`
    case 'Resource':
      return `/docs/doc/${key}/detail`
    default:
      throw new Error(`Unexpected model: ${model}`)
  }
}

const LazyListApp = React.lazy(() => import('./LazyListApp'))

const DocsView = props => {
  const {
    history,
    match,
    domainTypes,
    rootNodes,
    navigationStrategy,
    changeListParent,
    onSearchChange,
    emitAction,
    openFileDialog,
    limit,
    searchFormType,
    selectionStyle,
    getCustomLocation,
    disableViewPersistor,
    getListFormName,
    domainDetailFormName,
    folderDetailFormName,
    showActions,
    sortable,
    searchMode,
    openResource
  } = props
  // eslint-disable-next-line no-unused-vars
  const [entityListNumber, forceEntityListUpdate] = useReducer(x => x + 1, 0)

  const entityListKey = `entity-list-${entityListNumber}`

  const [selection, setSelection] = useState([])
  const parent = useMemo(() => getParent(match), [match.params])

  const keys = !parent && rootNodes ? rootNodes.map(node => `${node.entityName}/${node.key}`) : null
  const formName = useMemo(() => getListFormName
    ? getListFormName(parent, keys)
    : getFormName(parent, keys)
  , [match.params, getListFormName])

  const mounted = useRef(false)
  const searchModeRef = useRef(searchMode)

  searchModeRef.current = searchMode

  useEffect(() => {
    mounted.current = true
    return () => (mounted.current = false)
  })

  useEffect(() => {
    changeListParent(parent)
    setSelection([])
  }, [parent])

  const handleRowClick = ({id}) => {
    if (searchModeRef.current && isRootLocation(history.location.pathname)) {
      if (!viewPersistor.viewInfoSelector('search').store) {
        // persist search store to allow a "go back to search"
        const searchStore = viewPersistor.viewInfoSelector(entityListKey).store
        viewPersistor.persistViewInfo('search', {store: searchStore})
      }
      forceEntityListUpdate()
    }

    const [model, key] = id.split('/')
    const location = getCustomLocation ? getCustomLocation(model, key) : getDefaultLocation(model, key)

    if (location) {
      if (openResource && model === 'Resource') {
        openResource(location)
      } else {
        history.push(location)
      }
    }
  }

  const tql = !parent && !keys ? getTql(domainTypes) : null

  const handleUploadDocument = function* (definition, selection, parent, params, config, onSuccess, onError) {
    const directory = false
    openFileDialog(history.location.pathname, directory, onSuccess, onError)
  }

  const handleUploadDirectory = function* (definition, selection, parent, params, config, onSuccess, onError) {
    const directory = true
    openFileDialog(history.location.pathname, directory, onSuccess, onError)
  }

  const handleSearch = e => {
    if (mounted.current) {
      onSearchChange(e)
    }
  }

  const store = disableViewPersistor
    ? undefined
    : isRootLocation(history.location.pathname)
      ? viewPersistor.viewInfoSelector('search').store
      : null

  return (
    <>
      <Suspense fallback={<LoadMask/>}>
        <LazyListApp
          key={entityListKey}
          id="documents"
          entityName="Docs_list_item"
          formName={formName}
          limit={limit || 25}
          onRowClick={handleRowClick}
          searchFormPosition="left"
          searchFormType={searchFormType || 'admin'}
          parent={parent}
          onSearchChange={handleSearch}
          store={store}
          onStoreCreate={store => {
            if (!disableViewPersistor) {
              viewPersistor.persistViewInfo(entityListKey, {store})
            }
          }}
          cellRenderers={{
            'dms-label-with-icon': (rowData, column, cellRenderer) => (

                {cellRenderer(column.children[0])}
              </StyledContentWrapper>
            )
          }}
          emitAction={emitAction}
          actionAppComponent={Action}
          contextParams={{
            history,
            detailFormNames: {
              Domain: domainDetailFormName,
              Folder: folderDetailFormName
            }
          }}
          customActions={{
            'upload-document': handleUploadDocument,
            'upload-directory': handleUploadDirectory
          }}
          navigationStrategy={navigationStrategy}
          tql={tql}
          keys={keys}
          selectionStyle={selectionStyle || 'multi_explicit'}
          onSelectChange={setSelection}
          selection={selection}
          showActions={showActions}
          sortable={sortable}
        />
      </Suspense>
      <FileInput/>
    </>
  )
}

DocsView.propTypes = {
  match: PropTypes.object.isRequired,
  history: PropTypes.object.isRequired,
  navigationStrategy: PropTypes.object,
  domainTypes: PropTypes.arrayOf(PropTypes.string),
  rootNodes: PropTypes.arrayOf(PropTypes.shape({
    entityName: PropTypes.string,
    key: PropTypes.string
  })),
  changeListParent: PropTypes.func.isRequired,
  onSearchChange: PropTypes.func.isRequired,
  emitAction: PropTypes.func.isRequired,
  openFileDialog: PropTypes.func.isRequired,
  limit: PropTypes.number,
  searchFormType: searchFormTypePropTypes,
  selectionStyle: selectionStylePropType,
  getCustomLocation: PropTypes.func,
  disableViewPersistor: PropTypes.bool,
  getListFormName: PropTypes.func,
  domainDetailFormName: PropTypes.string,
  folderDetailFormName: PropTypes.string,
  showActions: PropTypes.bool,
  sortable: PropTypes.bool,
  searchMode: PropTypes.bool,
  openResource: PropTypes.func
}

export default DocsView
<commit_msg>feat(docs-browser): icons are now sent as part of the rest response<commit_after>import React, {useEffect, useState, Suspense, useMemo, useRef, useReducer} from 'react'
import PropTypes from 'prop-types'
import {viewPersistor} from 'tocco-util'
import {Icon, LoadMask} from 'tocco-ui'
import {searchFormTypePropTypes} from 'tocco-entity-list/src/util/searchFormTypes'
import {selectionStylePropType} from 'tocco-entity-list/src/util/selectionStyles'

import Action from '../Action'
import FileInput from '../FileInput'
import {StyledContentWrapper, StyledIconWrapper} from './StyledComponents'
import isRootLocation from '../../utils/isRootLocation'

export const getParent = match => {
  if (match.params && match.params.model) {
    const model = match.params.model.charAt(0).toUpperCase() + match.params.model.slice(1)
    const key = match.params.key
    const fullKey = `${model}/${key}`
    return {
      model: 'Docs_list_item',
      key: fullKey // e.g. "Domain/118"
    }
  }
  return null
}

export const getTql = domainTypes =>
  Array.isArray(domainTypes)
    && domainTypes.length > 0
    ? `exists(relDomain_type where IN(unique_id, ${domainTypes.map(type => `"${type}"`).join(',')}))`
    : null

export const getFormName = (parent, keys) => parent
  ? 'Docs_list_item'
  : keys
    ? 'Root_docs_list_item_specific'
    : 'Root_docs_list_item'

export const getDefaultLocation = (model, key) => {
  switch (model) {
    case 'Domain':
      return `/docs/domain/${key}/list`
    case 'Folder':
      return `/docs/folder/${key}/list`
    case 'Resource':
      return `/docs/doc/${key}/detail`
    default:
      throw new Error(`Unexpected model: ${model}`)
  }
}

const LazyListApp = React.lazy(() => import('./LazyListApp'))

const DocsView = props => {
  const {
    history,
    match,
    domainTypes,
    rootNodes,
    navigationStrategy,
    changeListParent,
    onSearchChange,
    emitAction,
    openFileDialog,
    limit,
    searchFormType,
    selectionStyle,
    getCustomLocation,
    disableViewPersistor,
    getListFormName,
    domainDetailFormName,
    folderDetailFormName,
    showActions,
    sortable,
    searchMode,
    openResource
  } = props
  // eslint-disable-next-line no-unused-vars
  const [entityListNumber, forceEntityListUpdate] = useReducer(x => x + 1, 0)

  const entityListKey = `entity-list-${entityListNumber}`

  const [selection, setSelection] = useState([])
  const parent = useMemo(() => getParent(match), [match.params])

  const keys = !parent && rootNodes ? rootNodes.map(node => `${node.entityName}/${node.key}`) : null
  const formName = useMemo(() => getListFormName
    ? getListFormName(parent, keys)
    : getFormName(parent, keys)
  , [match.params, getListFormName])

  const mounted = useRef(false)
  const searchModeRef = useRef(searchMode)

  searchModeRef.current = searchMode

  useEffect(() => {
    mounted.current = true
    return () => (mounted.current = false)
  })

  useEffect(() => {
    changeListParent(parent)
    setSelection([])
  }, [parent])

  const handleRowClick = ({id}) => {
    if (searchModeRef.current && isRootLocation(history.location.pathname)) {
      if (!viewPersistor.viewInfoSelector('search').store) {
        // persist search store to allow a "go back to search"
        const searchStore = viewPersistor.viewInfoSelector(entityListKey).store
        viewPersistor.persistViewInfo('search', {store: searchStore})
      }
      forceEntityListUpdate()
    }

    const [model, key] = id.split('/')
    const location = getCustomLocation ? getCustomLocation(model, key) : getDefaultLocation(model, key)

    if (location) {
      if (openResource && model === 'Resource') {
        openResource(location)
      } else {
        history.push(location)
      }
    }
  }

  const tql = !parent && !keys ? getTql(domainTypes) : null

  const handleUploadDocument = function* (definition, selection, parent, params, config, onSuccess, onError) {
    const directory = false
    openFileDialog(history.location.pathname, directory, onSuccess, onError)
  }

  const handleUploadDirectory = function* (definition, selection, parent, params, config, onSuccess, onError) {
    const directory = true
    openFileDialog(history.location.pathname, directory, onSuccess, onError)
  }

  const handleSearch = e => {
    if (mounted.current) {
      onSearchChange(e)
    }
  }

  const store = disableViewPersistor
    ? undefined
    : isRootLocation(history.location.pathname)
      ? viewPersistor.viewInfoSelector('search').store
      : null

  return (
    <>
      <Suspense fallback={<LoadMask/>}>
        <LazyListApp
          key={entityListKey}
          id="documents"
          entityName="Docs_list_item"
          formName={formName}
          limit={limit || 25}
          onRowClick={handleRowClick}
          searchFormPosition="left"
          searchFormType={searchFormType || 'admin'}
          parent={parent}
          onSearchChange={handleSearch}
          store={store}
          onStoreCreate={store => {
            if (!disableViewPersistor) {
              viewPersistor.persistViewInfo(entityListKey, {store})
            }
          }}
          cellRenderers={{
            'dms-label-with-icon': (rowData, column, cellRenderer) => (

                {cellRenderer(column.children[0])}
              </StyledContentWrapper>
            )
          }}
          emitAction={emitAction}
          actionAppComponent={Action}
          contextParams={{
            history,
            detailFormNames: {
              Domain: domainDetailFormName,
              Folder: folderDetailFormName
            }
          }}
          customActions={{
            'upload-document': handleUploadDocument,
            'upload-directory': handleUploadDirectory
          }}
          navigationStrategy={navigationStrategy}
          tql={tql}
          keys={keys}
          selectionStyle={selectionStyle || 'multi_explicit'}
          onSelectChange={setSelection}
          selection={selection}
          showActions={showActions}
          sortable={sortable}
        />
      </Suspense>
      <FileInput/>
    </>
  )
}

DocsView.propTypes = {
  match: PropTypes.object.isRequired,
  history: PropTypes.object.isRequired,
  navigationStrategy: PropTypes.object,
  domainTypes: PropTypes.arrayOf(PropTypes.string),
  rootNodes: PropTypes.arrayOf(PropTypes.shape({
    entityName: PropTypes.string,
    key: PropTypes.string
  })),
  changeListParent: PropTypes.func.isRequired,
  onSearchChange: PropTypes.func.isRequired,
  emitAction: PropTypes.func.isRequired,
  openFileDialog: PropTypes.func.isRequired,
  limit: PropTypes.number,
  searchFormType: searchFormTypePropTypes,
  selectionStyle: selectionStylePropType,
  getCustomLocation: PropTypes.func,
  disableViewPersistor: PropTypes.bool,
  getListFormName: PropTypes.func,
  domainDetailFormName: PropTypes.string,
  folderDetailFormName: PropTypes.string,
  showActions: PropTypes.bool,
  sortable: PropTypes.bool,
  searchMode: PropTypes.bool,
  openResource: PropTypes.func
}

export default DocsView
<|endoftext|>


<commit_before>var Window = require('./sys/Window');
var Mat4   = require('./math/Mat4');

Window.create({
    settings : {
        width  : 800,
        height : 600,
        type   : '3d'
    },
    init : function(){
        var ctx = this.getContext();

        this._matrixProjection = Mat4.create();
        this._matrixView       = Mat4.create();

    },
    draw : function(){
        var ctx = this.getContext();

        var windowWidth_2 = this.getWidth() * 0.5;
        var windowHeight  = this.getHeight();

        //
        ctx.pushState();
            ctx.setViewport(0,0,windowWidth_2,windowHeight);
            //ctx.setProjectionMatrix(
            //    Mat4.perspective(this._matrixProjection,45,windowWidth_2 / windowHeight, 0.001,10.0)
            //);
            ctx.setScissorTest(true);
            ctx.setScissor(0,0,windowWidth_2,windowHeight);

            ctx.setClearColor(1,0,0,1);
            ctx.clear(ctx.COLOR_BIT);

            //ctx.setClearColor(1,0,0,1);
            //ctx.setScissor(0,0,windowWidth_2,windowHeight);
        ctx.popState();
        ctx.pushState();
            ctx.setViewport(0,0,windowWidth_2,windowHeight);
            ctx.setScissorTest(true);
            ctx.setScissor(windowWidth_2,0,windowWidth_2,windowHeight);
            ctx.setClearColor(0,1,0,1);
            ctx.clear(ctx.COLOR_BIT);
        ctx.popState();
        //ctx.push();
        //  //  ctx.setViewport(windowWidth_2,0,windowWidth_2,windowHeight);
        //    //ctx.setProjectionMatrix(
        //    //    Mat4.ortho(this._matrixProjection,0,windowWidth_2,windowHeight,0,0.001,10.0)
        //    //);
        //    ////ctx.setClearColor(0,0,0,1);
        //ctx.pop();
    }
});
<commit_msg>06-pex-ctx-00 removed unused main.js<commit_after><|endoftext|>


<commit_before>/* eslint-disable flowtype/require-valid-file-annotation, no-console, import/extensions */
import nodeResolve from 'rollup-plugin-node-resolve'
import replace from 'rollup-plugin-replace'
import commonjs from 'rollup-plugin-commonjs'
import babel from 'rollup-plugin-babel'
import json from 'rollup-plugin-json'
import flow from 'rollup-plugin-flow'
import { terser } from 'rollup-plugin-terser'
import sourceMaps from 'rollup-plugin-sourcemaps'

// rollup-plugin-ignore stopped working, so we'll just remove the import line 😐
const streamIgnore = { "import stream from 'stream';": "'';" }

const cjs = {
  exports: 'named',
  format: 'cjs',
  sourcemap: true,
}

const esm = {
  format: 'esm',
  sourcemap: true,
}

const getCJS = override => Object.assign({}, cjs, override)
const getESM = override => Object.assign({}, esm, override)

const commonPlugins = [
  flow({
    // needed for sourcemaps to be properly generated
    pretty: true,
  }),
  sourceMaps(),
  json(),
  nodeResolve(),
  babel({
    exclude: 'node_modules/**',
    plugins: ['external-helpers'],
  }),
  commonjs({
    ignoreGlobal: true,
    namedExports: {
      'react-is': ['isValidElementType'],
    },
  }),
  replace({
    __DEV__: JSON.stringify(false), // disable flag indicating a Jest run
  }),
]

const configBase = {
  input: './src/index.js',

  // \0 is rollup convention for generated in memory modules
  external: id =>
    !id.startsWith('\0') && !id.startsWith('.') && !id.startsWith('/'),
  plugins: commonPlugins,
}

const globals = { react: 'React' }

const umdBaseConfig = Object.assign({}, configBase, {
  output: {
    exports: 'named',
    file: 'dist/styled-components.js',
    format: 'umd',
    globals,
    name: 'styled',
    sourcemap: true,
  },
  external: Object.keys(globals),
  plugins: configBase.plugins.concat(
    replace({
      ...streamIgnore,
      __SERVER__: JSON.stringify(false),
    })
  ),
})

const umdConfig = Object.assign({}, umdBaseConfig, {
  plugins: umdBaseConfig.plugins.concat(
    replace({
      'process.env.NODE_ENV': JSON.stringify('development'),
    })
  ),
})

const umdProdConfig = Object.assign({}, umdBaseConfig, {
  output: Object.assign({}, umdBaseConfig.output, {
    file: 'dist/styled-components.min.js',
  }),
  plugins: umdBaseConfig.plugins.concat([
    replace({
      'process.env.NODE_ENV': JSON.stringify('production'),
    }),
    terser({
      sourceMap: true,
    }),
  ]),
})

const serverConfig = Object.assign({}, configBase, {
  output: [
    getESM({ file: 'dist/styled-components.esm.js' }),
    getCJS({ file: 'dist/styled-components.cjs.js' }),
  ],
  plugins: configBase.plugins.concat(
    replace({
      __SERVER__: JSON.stringify(true),
    })
  ),
})

const serverProdConfig = Object.assign({}, configBase, serverConfig, {
  output: [
    getESM({ file: 'dist/styled-components.esm.min.js' }),
    getCJS({ file: 'dist/styled-components.cjs.min.js' }),
  ],
  plugins: serverConfig.plugins.concat(
    replace({
      'process.env.NODE_ENV': JSON.stringify('production'),
    }),
    terser({
      sourceMap: true,
    })
  ),
})

const browserConfig = Object.assign({}, configBase, {
  output: [
    getESM({ file: 'dist/styled-components.browser.esm.js' }),
    getCJS({ file: 'dist/styled-components.browser.cjs.js' }),
  ],
  plugins: configBase.plugins.concat(
    replace({
      ...streamIgnore,
      __SERVER__: JSON.stringify(false),
    })
  ),
})

const browserProdConfig = Object.assign({}, configBase, browserConfig, {
  output: [
    getESM({
      file: 'dist/styled-components.browser.esm.min.js',
    }),
    getCJS({
      file: 'dist/styled-components.browser.cjs.min.js',
    }),
  ],
  plugins: browserConfig.plugins.concat(
    replace({
      'process.env.NODE_ENV': JSON.stringify('production'),
    }),
    terser({
      sourceMap: true,
    })
  ),
})

const nativeConfig = Object.assign({}, configBase, {
  input: './src/native/index.js',
  output: getCJS({
    file: 'dist/styled-components.native.cjs.js',
  }),
})

const primitivesConfig = Object.assign({}, configBase, {
  input: './src/primitives/index.js',
  output: [
    getESM({ file: 'dist/styled-components-primitivesm.esm.js' }),
    getCJS({
      file: 'dist/styled-components-primitivesm.cjs.js',
    }),
  ],
  plugins: configBase.plugins.concat(
    replace({
      __SERVER__: JSON.stringify(true),
    })
  ),
})

const noParserConfig = Object.assign({}, configBase, {
  input: './src/no-parser/index.js',
  output: [
    getESM({ file: 'dist/styled-components-no-parser.esm.js' }),
    getCJS({ file: 'dist/styled-components-no-parser.cjs.js' }),
  ],
  plugins: configBase.plugins.concat(
    replace({
      __SERVER__: JSON.stringify(true),
    })
  ),
})

const noParserBrowserConfig = Object.assign({}, configBase, {
  output: [
    getESM({
      file: 'dist/styled-components-no-parser.browser.esm.js',
    }),
    getCJS({
      file: 'dist/styled-components-no-parser.browser.cjs.js',
    }),
  ],
  plugins: configBase.plugins.concat(
    replace({
      ...streamIgnore,
      __SERVER__: JSON.stringify(false),
    })
  ),
})

export default [
  umdConfig,
  umdProdConfig,
  serverConfig,
  serverProdConfig,
  browserConfig,
  browserProdConfig,
  nativeConfig,
  primitivesConfig,
  noParserConfig,
  noParserBrowserConfig,
]
<commit_msg>make node 6 happy<commit_after>/* eslint-disable flowtype/require-valid-file-annotation, no-console, import/extensions */
import nodeResolve from 'rollup-plugin-node-resolve'
import replace from 'rollup-plugin-replace'
import commonjs from 'rollup-plugin-commonjs'
import babel from 'rollup-plugin-babel'
import json from 'rollup-plugin-json'
import flow from 'rollup-plugin-flow'
import { terser } from 'rollup-plugin-terser'
import sourceMaps from 'rollup-plugin-sourcemaps'

// rollup-plugin-ignore stopped working, so we'll just remove the import line 😐
const ignore = { "import stream from 'stream';": "'';" }

const cjs = {
  exports: 'named',
  format: 'cjs',
  sourcemap: true,
}

const esm = {
  format: 'esm',
  sourcemap: true,
}

const getCJS = override => Object.assign({}, cjs, override)
const getESM = override => Object.assign({}, esm, override)

const commonPlugins = [
  flow({
    // needed for sourcemaps to be properly generated
    pretty: true,
  }),
  sourceMaps(),
  json(),
  nodeResolve(),
  babel({
    exclude: 'node_modules/**',
    plugins: ['external-helpers'],
  }),
  commonjs({
    ignoreGlobal: true,
    namedExports: {
      'react-is': ['isValidElementType'],
    },
  }),
  replace({
    __DEV__: JSON.stringify(false), // disable flag indicating a Jest run
  }),
]

const configBase = {
  input: './src/index.js',

  // \0 is rollup convention for generated in memory modules
  external: id =>
    !id.startsWith('\0') && !id.startsWith('.') && !id.startsWith('/'),
  plugins: commonPlugins,
}

const globals = { react: 'React' }

const umdBaseConfig = Object.assign({}, configBase, {
  output: {
    exports: 'named',
    file: 'dist/styled-components.js',
    format: 'umd',
    globals,
    name: 'styled',
    sourcemap: true,
  },
  external: Object.keys(globals),
  plugins: configBase.plugins.concat(
    replace(
      Object.assign({}, ignore, {
        __SERVER__: JSON.stringify(false),
      })
    )
  ),
})

const umdConfig = Object.assign({}, umdBaseConfig, {
  plugins: umdBaseConfig.plugins.concat(
    replace({
      'process.env.NODE_ENV': JSON.stringify('development'),
    })
  ),
})

const umdProdConfig = Object.assign({}, umdBaseConfig, {
  output: Object.assign({}, umdBaseConfig.output, {
    file: 'dist/styled-components.min.js',
  }),
  plugins: umdBaseConfig.plugins.concat([
    replace({
      'process.env.NODE_ENV': JSON.stringify('production'),
    }),
    terser({
      sourceMap: true,
    }),
  ]),
})

const serverConfig = Object.assign({}, configBase, {
  output: [
    getESM({ file: 'dist/styled-components.esm.js' }),
    getCJS({ file: 'dist/styled-components.cjs.js' }),
  ],
  plugins: configBase.plugins.concat(
    replace({
      __SERVER__: JSON.stringify(true),
    })
  ),
})

const serverProdConfig = Object.assign({}, configBase, serverConfig, {
  output: [
    getESM({ file: 'dist/styled-components.esm.min.js' }),
    getCJS({ file: 'dist/styled-components.cjs.min.js' }),
  ],
  plugins: serverConfig.plugins.concat(
    replace({
      'process.env.NODE_ENV': JSON.stringify('production'),
    }),
    terser({
      sourceMap: true,
    })
  ),
})

const browserConfig = Object.assign({}, configBase, {
  output: [
    getESM({ file: 'dist/styled-components.browser.esm.js' }),
    getCJS({ file: 'dist/styled-components.browser.cjs.js' }),
  ],
  plugins: configBase.plugins.concat(
    replace(
      Object.assign({}, ignore, {
        __SERVER__: JSON.stringify(false),
      })
    )
  ),
})

const browserProdConfig = Object.assign({}, configBase, browserConfig, {
  output: [
    getESM({
      file: 'dist/styled-components.browser.esm.min.js',
    }),
    getCJS({
      file: 'dist/styled-components.browser.cjs.min.js',
    }),
  ],
  plugins: browserConfig.plugins.concat(
    replace({
      'process.env.NODE_ENV': JSON.stringify('production'),
    }),
    terser({
      sourceMap: true,
    })
  ),
})

const nativeConfig = Object.assign({}, configBase, {
  input: './src/native/index.js',
  output: getCJS({
    file: 'dist/styled-components.native.cjs.js',
  }),
})

const primitivesConfig = Object.assign({}, configBase, {
  input: './src/primitives/index.js',
  output: [
    getESM({ file: 'dist/styled-components-primitivesm.esm.js' }),
    getCJS({
      file: 'dist/styled-components-primitivesm.cjs.js',
    }),
  ],
  plugins: configBase.plugins.concat(
    replace({
      __SERVER__: JSON.stringify(true),
    })
  ),
})

const noParserConfig = Object.assign({}, configBase, {
  input: './src/no-parser/index.js',
  output: [
    getESM({ file: 'dist/styled-components-no-parser.esm.js' }),
    getCJS({ file: 'dist/styled-components-no-parser.cjs.js' }),
  ],
  plugins: configBase.plugins.concat(
    replace({
      __SERVER__: JSON.stringify(true),
    })
  ),
})

const noParserBrowserConfig = Object.assign({}, configBase, {
  output: [
    getESM({
      file: 'dist/styled-components-no-parser.browser.esm.js',
    }),
    getCJS({
      file: 'dist/styled-components-no-parser.browser.cjs.js',
    }),
  ],
  plugins: configBase.plugins.concat(
    replace(
      Object.assign({}, ignore, {
        __SERVER__: JSON.stringify(false),
      })
    )
  ),
})

export default [
  umdConfig,
  umdProdConfig,
  serverConfig,
  serverProdConfig,
  browserConfig,
  browserProdConfig,
  nativeConfig,
  primitivesConfig,
  noParserConfig,
  noParserBrowserConfig,
]
<|endoftext|>


<commit_before>// add singleton to _.parse's supported event properties
_.properties.unshift([/^\^/, function singleton(){ this.singleton = true; }]);

// _.fire's _.dispatch will call this when appropriate
_.singleton = function(target, event) {
	_.remember(target, event);
	if (event.bubbles && !event.propagationStopped && target !== _.global) {
		_.singleton(target.parentNode || target.parentObject || _.global, event);
	}
};
var _skey = _._skey = '^'+_key;
_.remember = function remember(target, event) {
	var saved = target[_skey] || [];
	if (!saved.length) {
		Object.defineProperty(target, _skey, {value:saved,configurable:true});
	}
	event[_skey] = true;
	saved.push(event);
};

Eventi.on(_, 'handler#new', function singletonHandler(e, handler) {
	if (handler.match.singleton) {
		delete handler.match.singleton;// singleton never needs matching
		var fn = handler._fn = handler.fn,
			target = handler.target;
		handler.fn = function single(e) {
			_.unhandle(handler);
			if (!e[_skey]) {// remember this non-singleton as singleton for handler's sake
				_.remember(target, e);
			}
			fn.apply(this, arguments);
		};

		// search target's saved singletons, execute handler upon match
		var saved = target[_skey]||[];
		for (var i=0,m=saved.length; i<m; i++) {
			var event = saved[i];
			if (_.matches(event, handler.match)) {
				var etarget = _.target(handler, event.target);
				if (etarget) {
					return _.execute(etarget, event, handler);
				}
			}
		}
	}
});

if (document) {
	Eventi.on('DOMContentLoaded', function ready(e) {
		_.fire(document.documentElement, ['^ready'], undefined, [e]);
	});
}<commit_msg>better var/fn names<commit_after>// add singleton to _.parse's supported event properties
_.properties.unshift([/^\^/, function singleton(){ this.singleton = true; }]);

// _.fire's _.dispatch will call this when appropriate
_.singleton = function(target, event) {
	_.remember(target, event);
	if (event.bubbles && !event.propagationStopped && target !== _.global) {
		_.singleton(target.parentNode || target.parentObject || _.global, event);
	}
};
var _skey = _._skey = '^'+_key;
_.remember = function remember(target, event) {
	var saved = target[_skey] || [];
	if (!saved.length) {
		Object.defineProperty(target, _skey, {value:saved,configurable:true});
	}
	event[_skey] = true;
	saved.push(event);
};

Eventi.on(_, 'handler#new', function singleton(e, handler) {
	if (handler.match.singleton) {
		delete handler.match.singleton;// singleton never needs matching
		var fn = handler._fn = handler.fn;
		handler.fn = function singleton(e) {
			_.unhandle(handler);
			if (!e[_skey]) {// remember this non-singleton as singleton for handler's sake
				_.remember(handler.target, e);
			}
			fn.apply(this, arguments);
		};

		// search target's saved singletons, execute handler upon match
		var saved = handler.target[_skey]||[];
		for (var i=0,m=saved.length; i<m; i++) {
			var event = saved[i];
			if (_.matches(event, handler.match)) {
				var target = _.target(handler, event.target);
				if (target) {
					return _.execute(target, event, handler);
				}
			}
		}
	}
});

if (document) {
	Eventi.on('DOMContentLoaded', function ready(e) {
		_.fire(document.documentElement, ['^ready'], undefined, [e]);
	});
}<|endoftext|>