<commit_before>require([
	'goo/entities/GooRunner',
	'goo/entities/EntityUtils',
	'goo/renderer/Material',
	'goo/renderer/Camera',
	'goo/entities/components/CameraComponent',
	'goo/entities/components/ScriptComponent',
	'goo/renderer/shaders/ShaderLib',
	'goo/renderer/MeshData',
	'goo/renderer/Util',
	'goo/renderer/pass/RenderPass',
	'goo/renderer/pass/BloomPass',
	'goo/renderer/pass/FullscreenPass',
	'goo/renderer/pass/Composer'
], function (GooRunner, EntityUtils, Material, Camera, CameraComponent, ScriptComponent, ShaderLib, MeshData, Util, RenderPass,	BloomPass, FullscreenPass, Composer) {
	"use strict";

    var bitmapArray = [];
    var imageArr = [];
    var LOOP = 200;
    var NUM_POINTS = LOOP * LOOP;
    var goo;
    var lastEntity;
    var xDir = 1;
    var yDir = 1;
    var xFactor = 0.005;
    var xDelta = 0;
    var yFactor = 0.008;
    var yDelta = 0;

    function loadImage(){
        for (var i = 0; i < NUM_POINTS; i++) {
            bitmapArray[i] = Array(LOOP);
        }
//        console.log(bitmapArray);

        for (var i = 0; i < LOOP; i++) {
            for (var j = 0; j < LOOP; j++) {
                bitmapArray[i][j] = "#" + (0x1000000+(Math.random())*0xffffff).toString(16).substr(1,6);
            }
        }
    }

    function initSocket(){
	    //socket IO:
	    if(!socket){
	        // socket.io initialiseren
	        socket = io.connect(window.location.hostname);
	        // some debugging statements concerning socket.io
	        socket.on('reconnecting', function(seconds){
	            console.log('reconnecting in ' + seconds + ' seconds');
	        });
	        socket.on('reconnect', function(){
	            console.log('reconnected');
	        });
	        socket.on('reconnect_failed', function(){
	            console.log('failed to reconnect');
	        });
	        socket.on('new', newContent);
	    }
	}

	function createPointCloud(){
		// Add points
		var pointsEntity = createBoxEntity(goo);
		lastEntity = pointsEntity
		xFactor = 0.003 + Math.random()*0.005;
		yFactor = 0.005 + Math.random()*0.005;
		// Add spin
		pointsEntity.setComponent(new ScriptComponent({
			run : function(entity) {
				// if(app && app.data){
				// console.log(app.data);
				var rotX = entity.transformComponent.getRotation().x;
				var rotY = entity.transformComponent.getRotation().y;

				if(rotX <= -0.8){
					xDir = 1;
					//xFactor = 0.003 + Math.random()*0.005;
				}else if(rotX >= 0.8){
					xDir = -1;
					//xFactor = 0.003 + Math.random()*0.005;
				}

				if(rotY <= -0.7){
					yDir = 1;
					//yFactor = 0.005 + Math.random()*0.005;
				}else if(rotY >= 0.7){
					yDir = -1;
					//yFactor = 0.005 + Math.random()*0.005;
				}

				if(xDir==1){
					xDelta+= 0.5+Math.random()*2.5;
				}else{
					xDelta-= 0.5+Math.random()*2.5;;
				}

				if(yDir==1){
					yDelta++;
				}else{
					yDelta--;
				}

				entity.transformComponent.transform.setRotationXYZ(
					xDelta * xFactor,
					yDelta * yFactor,
					0
				);

				// rotation between (-1,-0.7,0) and (1,0.7,0)

				entity.transformComponent.setUpdated();

				// }
                // audioData.guess
                //  Object {totalEnergy: 0.0002676707959839109, primaryNoteEnergy: 0.00005799675205730361, primaryNote: 14437.5}

                // audioData.spectrum
                //  Array[256]

                if (!audioData.spectrum) return;

                var verts = entity.meshDataComponent.meshData.getAttributeBuffer(MeshData.POSITION);
                var colors = entity.meshDataComponent.meshData.getAttributeBuffer(MeshData.COLOR);

                for (var i = 0; i < NUM_POINTS; i++) {

                    var sum = colors[i * 4 + 0] + colors[i * 4 + 1] + colors[i * 4 + 2];

                    verts[i * 3 + 2] = Math.sqrt(audioData.guess.primaryNoteEnergy * (sum * 10000000));
                }
                entity.meshDataComponent.meshData.vertexData._dataNeedsRefresh = true;
			}
		}));
		pointsEntity.addToWorld();
	}

	function newContent(data){
	    console.log(data);
	    if(lastEntity)
	    	lastEntity.removeFromWorld();
	    imageArr.push(data);
	    createPointCloud();
	}

	function init() {
		initSocket();
        loadImage();
		goo = new GooRunner({
			//showStats : true,
			//antiAlias : false
		});
		goo.renderer.domElement.id = 'goo';
		document.body.appendChild(goo.renderer.domElement);

		// createBloom(goo);

		goo.renderer.setClearColor(0,0,0,1);

		// Add camera
		var camera = new Camera(45, 1, 5, 3500);
		var cameraEntity = goo.world.createEntity("CameraEntity");
		cameraEntity.setComponent(new CameraComponent(camera));
		cameraEntity.addToWorld();
	}

    function hexToRgb(hex) {
        var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
        return result ? {
            r: parseInt(result[1], 16) / 255,
            g: parseInt(result[2], 16) / 255,
            b: parseInt(result[3], 16) / 255
        } : null;
    }

	function createBoxEntity(goo) {
		var count = 50000;
		var count = NUM_POINTS;

		var attributeMap = MeshData.defaultMap([MeshData.POSITION, MeshData.COLOR]);
		var meshData = new MeshData(attributeMap, count);
		meshData.indexModes = ['Points'];

		var verts = meshData.getAttributeBuffer(MeshData.POSITION);
		var colors = meshData.getAttributeBuffer(MeshData.COLOR);

		var n = 2000, n2 = n / 2;
        var cnt = 0;

        for (var i = LOOP; i >= 0; i--) {
            for (var j = 0; j < LOOP; j++) {
                var multX = j/LOOP;
                var multY = i/LOOP;

                var x = multX * n - n2;
			    var y = multY * n - n2;

			    var z = 1;

                verts[cnt * 3 + 0] = x;
                verts[cnt * 3 + 1] = y;
                verts[cnt * 3 + 2] = z;

                colors[cnt * 4 + 0] = imageArr[imageArr.length-1][cnt*3+0]/255;
                colors[cnt * 4 + 1] = imageArr[imageArr.length-1][cnt*3+1]/255;
                colors[cnt * 4 + 2] = imageArr[imageArr.length-1][cnt*3+2]/255;
                colors[cnt * 4 + 3] = 1.0;

                cnt++;
            }
        }

		var entity = EntityUtils.createTypicalEntity(goo.world, meshData);
		entity.transformComponent.transform.translation.z = -2750;

		var material = new Material('TestMaterial');
		material.shader = Material.createShader(Util.clone(ShaderLib.point), 'PointShader');
		entity.meshRendererComponent.materials.push(material);

		return entity;
	}

	function createBloom(goo) {
		var composer = new Composer();

		var renderPass = new RenderPass(goo.world.getSystem('RenderSystem').renderList);
		// renderPass.clearColor = (1,0,0,1);
		var bloomPass = new BloomPass();
		// Create composer with same size as screen

		var shader = Util.clone(ShaderLib.bloom);
		var outPass = new FullscreenPass(shader);

		composer.addPass(renderPass);
		composer.addPass(bloomPass);

		goo.world.getSystem('RenderSystem').composers.push(composer);
	}

	init();

});
<commit_msg>stronger effect<commit_after>require([
	'goo/entities/GooRunner',
	'goo/entities/EntityUtils',
	'goo/renderer/Material',
	'goo/renderer/Camera',
	'goo/entities/components/CameraComponent',
	'goo/entities/components/ScriptComponent',
	'goo/renderer/shaders/ShaderLib',
	'goo/renderer/MeshData',
	'goo/renderer/Util',
	'goo/renderer/pass/RenderPass',
	'goo/renderer/pass/BloomPass',
	'goo/renderer/pass/FullscreenPass',
	'goo/renderer/pass/Composer'
], function (GooRunner, EntityUtils, Material, Camera, CameraComponent, ScriptComponent, ShaderLib, MeshData, Util, RenderPass,	BloomPass, FullscreenPass, Composer) {
	"use strict";

    var bitmapArray = [];
    var imageArr = [];
    var LOOP = 200;
    var NUM_POINTS = LOOP * LOOP;
    var goo;
    var lastEntity;
    var xDir = 1;
    var yDir = 1;
    var xFactor = 0.005;
    var xDelta = 0;
    var yFactor = 0.008;
    var yDelta = 0;

    function loadImage(){
        for (var i = 0; i < NUM_POINTS; i++) {
            bitmapArray[i] = Array(LOOP);
        }
//        console.log(bitmapArray);

        for (var i = 0; i < LOOP; i++) {
            for (var j = 0; j < LOOP; j++) {
                bitmapArray[i][j] = "#" + (0x1000000+(Math.random())*0xffffff).toString(16).substr(1,6);
            }
        }
    }

    function initSocket(){
	    //socket IO:
	    if(!socket){
	        // socket.io initialiseren
	        socket = io.connect(window.location.hostname);
	        // some debugging statements concerning socket.io
	        socket.on('reconnecting', function(seconds){
	            console.log('reconnecting in ' + seconds + ' seconds');
	        });
	        socket.on('reconnect', function(){
	            console.log('reconnected');
	        });
	        socket.on('reconnect_failed', function(){
	            console.log('failed to reconnect');
	        });
	        socket.on('new', newContent);
	    }
	}

	function createPointCloud(){
		// Add points
		var pointsEntity = createBoxEntity(goo);
		lastEntity = pointsEntity
		xFactor = 0.003 + Math.random()*0.005;
		yFactor = 0.005 + Math.random()*0.005;
		// Add spin
		pointsEntity.setComponent(new ScriptComponent({
			run : function(entity) {
				// if(app && app.data){
				// console.log(app.data);
				var rotX = entity.transformComponent.getRotation().x;
				var rotY = entity.transformComponent.getRotation().y;

				if(rotX <= -0.8){
					xDir = 1;
					//xFactor = 0.003 + Math.random()*0.005;
				}else if(rotX >= 0.8){
					xDir = -1;
					//xFactor = 0.003 + Math.random()*0.005;
				}

				if(rotY <= -0.7){
					yDir = 1;
					//yFactor = 0.005 + Math.random()*0.005;
				}else if(rotY >= 0.7){
					yDir = -1;
					//yFactor = 0.005 + Math.random()*0.005;
				}

				if(xDir==1){
					xDelta+= 0.5+Math.random()*2.5;
				}else{
					xDelta-= 0.5+Math.random()*2.5;;
				}

				if(yDir==1){
					yDelta++;
				}else{
					yDelta--;
				}

				entity.transformComponent.transform.setRotationXYZ(
					xDelta * xFactor,
					yDelta * yFactor,
					0
				);

				// rotation between (-1,-0.7,0) and (1,0.7,0)

				entity.transformComponent.setUpdated();

				// }
                // audioData.guess
                //  Object {totalEnergy: 0.0002676707959839109, primaryNoteEnergy: 0.00005799675205730361, primaryNote: 14437.5}

                // audioData.spectrum
                //  Array[256]

                if (!audioData.spectrum) return;

                var verts = entity.meshDataComponent.meshData.getAttributeBuffer(MeshData.POSITION);
                var colors = entity.meshDataComponent.meshData.getAttributeBuffer(MeshData.COLOR);

                for (var i = 0; i < NUM_POINTS; i++) {

                    var sum = colors[i * 4 + 0] + colors[i * 4 + 1] + colors[i * 4 + 2];

                    verts[i * 3 + 2] = Math.sqrt(audioData.guess.primaryNoteEnergy * (sum * 10000000*10));
                }
                entity.meshDataComponent.meshData.vertexData._dataNeedsRefresh = true;
			}
		}));
		pointsEntity.addToWorld();
	}

	function newContent(data){
	    console.log(data);
	    if(lastEntity)
	    	lastEntity.removeFromWorld();
	    imageArr.push(data);
	    createPointCloud();
	}

	function init() {
		initSocket();
        loadImage();
		goo = new GooRunner({
			//showStats : true,
			//antiAlias : false
		});
		goo.renderer.domElement.id = 'goo';
		document.body.appendChild(goo.renderer.domElement);

		// createBloom(goo);

		goo.renderer.setClearColor(0,0,0,1);

		// Add camera
		var camera = new Camera(45, 1, 5, 3500);
		var cameraEntity = goo.world.createEntity("CameraEntity");
		cameraEntity.setComponent(new CameraComponent(camera));
		cameraEntity.addToWorld();
	}

    function hexToRgb(hex) {
        var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
        return result ? {
            r: parseInt(result[1], 16) / 255,
            g: parseInt(result[2], 16) / 255,
            b: parseInt(result[3], 16) / 255
        } : null;
    }

	function createBoxEntity(goo) {
		var count = 50000;
		var count = NUM_POINTS;

		var attributeMap = MeshData.defaultMap([MeshData.POSITION, MeshData.COLOR]);
		var meshData = new MeshData(attributeMap, count);
		meshData.indexModes = ['Points'];

		var verts = meshData.getAttributeBuffer(MeshData.POSITION);
		var colors = meshData.getAttributeBuffer(MeshData.COLOR);

		var n = 2000, n2 = n / 2;
        var cnt = 0;

        for (var i = LOOP; i >= 0; i--) {
            for (var j = 0; j < LOOP; j++) {
                var multX = j/LOOP;
                var multY = i/LOOP;

                var x = multX * n - n2;
			    var y = multY * n - n2;

			    var z = 1;

                verts[cnt * 3 + 0] = x;
                verts[cnt * 3 + 1] = y;
                verts[cnt * 3 + 2] = z;

                colors[cnt * 4 + 0] = imageArr[imageArr.length-1][cnt*3+0]/255;
                colors[cnt * 4 + 1] = imageArr[imageArr.length-1][cnt*3+1]/255;
                colors[cnt * 4 + 2] = imageArr[imageArr.length-1][cnt*3+2]/255;
                colors[cnt * 4 + 3] = 1.0;

                cnt++;
            }
        }

		var entity = EntityUtils.createTypicalEntity(goo.world, meshData);
		entity.transformComponent.transform.translation.z = -2750;

		var material = new Material('TestMaterial');
		material.shader = Material.createShader(Util.clone(ShaderLib.point), 'PointShader');
		entity.meshRendererComponent.materials.push(material);

		return entity;
	}

	function createBloom(goo) {
		var composer = new Composer();

		var renderPass = new RenderPass(goo.world.getSystem('RenderSystem').renderList);
		// renderPass.clearColor = (1,0,0,1);
		var bloomPass = new BloomPass();
		// Create composer with same size as screen

		var shader = Util.clone(ShaderLib.bloom);
		var outPass = new FullscreenPass(shader);

		composer.addPass(renderPass);
		composer.addPass(bloomPass);

		goo.world.getSystem('RenderSystem').composers.push(composer);
	}

	init();

});
<|endoftext|>


<commit_before>describe('Backbone.Firebase.Model', function() {

  it('should exist', function() {
    return expect(Backbone.Firebase.Model).to.be.ok;
  });

  it('should extend', function() {
    var spy = sinon.spy();
    var Model = Backbone.Firebase.Model.extend({
      url: 'Mock://',
      autoSync: false
    });
    return expect(Model).to.be.ok;
  });

});<commit_msg>Mockfirebase<commit_after>describe('Backbone.Firebase.Model', function() {

  MockFirebase.override();

  it('should exist', function() {
    return expect(Backbone.Firebase.Model).to.be.ok;
  });

  it('should extend', function() {
    var spy = sinon.spy();
    var Model = Backbone.Firebase.Model.extend({
      url: 'Mock://',
      autoSync: false
    });
    return expect(Model).to.be.ok;
  });

});<|endoftext|>


<commit_before>const fs = require('fs');
const _ = require('lodash');
const chalk = require('chalk'); // temp

const Log = require('./log').parser;
const Config = require('./config');
const Lexer = require('./lexer');
const { ParserException, TypeException } = require('./exceptions');

const EXTENSION = '.mono';
const BLANK = '';
let ast = {
  files: [],
}

const run = () => {
  try {
    Config.getSrc().forEach((file, order) => {
      const name = _.endsWith(file, EXTENSION) ? file : `${file}${EXTENSION}`;
      const source = fs.readFileSync(`${process.cwd()}/${name}`).toString();

      ast.files.push({
        name,
        order,
        source
      });
    });
  } catch (e) {
    Log.PARSER_ERROR(e);
    throw new ParserException('Failed to run parser');
  }

  parse();
}

const parse = () => {
  ast.files.forEach(file => parseFile(file));
}

const parseFile = file => {
  const tokens = Lexer.tokenize(file);
  let output = '';
  let inferredType = false;

  console.log(chalk`\n {blue {bold Start} parsing file: ${file.name} --------------- \n}`);

  // initially generate CSS output without enforcing type-modifier system
  // todo: handle inferred types
  tokens.forEach((token, index) => {
    const prevToken = tokens[index-1]
    const nextToken = tokens[index+1];

    switch (token[0]) {
      case Lexer.BRACE_OPEN:
      case Lexer.MEDIA_QUERY:
      case Lexer.KEYFRAME:
      case Lexer.KEYFRAME_SELECTOR:
      case Lexer.FONT_FACE:
      case Lexer.CHARSET:
      case Lexer.SUPPORTS:
        output += token[1];
        break;
      case Lexer.BRACE_CLOSE:
        output += token[1];
        inferredType = false;
        break;
      case Lexer.DECLARATION:
        const explicitType = token[3] && token[3][0];
        console.log(chalk`{grey token: ${token}}`);

        if (explicitType) {
          console.log(chalk`{green declaration has explicit type: ${explicitType}}`);
        } else if (inferredType) {
          console.log(chalk`{blue declaration has inferred type: ${inferredType}}`);

          if (token[3] === null) {
            token[3] = new Array(4);
          }

          token[3][0] = `${inferredType}<Inferred>`;
        } else {
          console.log(chalk`{red declaration has NO type}`);
        }

        console.log(chalk`{grey token: ${token}}`);
        console.log('-'.repeat(100));
        break;
      case Lexer.SELECTOR:
        // either append an open brace or comma depending on whether nextToken is a SELECTOR
        const suffix = nextToken[0] === Lexer.SELECTOR ? ',' : '{';

        if (token[3]) {
          if (prevToken[0] === Lexer.SELECTOR ||
              nextToken[0] === Lexer.SELECTOR) {
            Log.CANNOT_INFER_TYPE(file, token[1], token[3][0]);
            throw new TypeException('Type cannot be inferred by grouped selector');
          } else {
            inferredType = token[3][0];
          }
        }

        output += `${shedNotionIfAny(token)}${suffix}`;
        break;
      default:
        return console.log(chalk`{red Unkown token: ${token}}`);
    }
  });

  // console.log('start OUTPUT ------------------------------------------\n');
  // console.log(chalk`{grey ${output}}`);
  // console.log('\nend OUTPUT ------------------------------------------');
  console.log(chalk`\n {red {bold End} parsing file: ${file.name} --------------- \n}`);
}

// remove notion markup & return native CSS
const shedNotionIfAny = (token) => {
  let tokenValue = token[1];

  if (token[3]) {
    // anything within crocodiles <>
    tokenValue = token[1].replace(/<.+>/, BLANK);
  }

  return tokenValue;
}

// construct CSS comment from token containing notion(s) if any
const notionToComment = (token) => {
  if (token[3]) {
    let notions = [];

    const [
      TYPE,
      MODIFIER,
      MOTIVE,
      CONTEXTUAL_DATA
    ] = token[3];

    if (TYPE) {
      notions.push(TYPE);
    }
    if (MODIFIER) {
      notions.push(MODIFIER);
    }
    if (MOTIVE) {
      notions.push(MOTIVE);
    }
    if (CONTEXTUAL_DATA) {
      notions.push(CONTEXTUAL_DATA);
    }

    return `/* ${notions.join(', ')} */`;
  }
}

module.exports = {
  run
};<commit_msg>[parser] add declaration to output<commit_after>const fs = require('fs');
const _ = require('lodash');
const chalk = require('chalk'); // temp

const Log = require('./log').parser;
const Config = require('./config');
const Lexer = require('./lexer');
const { ParserException, TypeException } = require('./exceptions');

const EXTENSION = '.mono';
const BLANK = '';
let ast = {
  files: [],
}

const run = () => {
  try {
    Config.getSrc().forEach((file, order) => {
      const name = _.endsWith(file, EXTENSION) ? file : `${file}${EXTENSION}`;
      const source = fs.readFileSync(`${process.cwd()}/${name}`).toString();

      ast.files.push({
        name,
        order,
        source
      });
    });
  } catch (e) {
    Log.PARSER_ERROR(e);
    throw new ParserException('Failed to run parser');
  }

  parse();
}

const parse = () => {
  ast.files.forEach(file => parseFile(file));
}

const parseFile = file => {
  const tokens = Lexer.tokenize(file);
  let output = '';
  let inferredType = false;

  console.log(chalk`\n {blue {bold Start} parsing file: ${file.name} --------------- \n}`);

  // initially generate CSS output without enforcing type-modifier system
  // todo: handle inferred types
  tokens.forEach((token, index) => {
    const prevToken = tokens[index-1]
    const nextToken = tokens[index+1];

    switch (token[0]) {
      case Lexer.BRACE_OPEN:
      case Lexer.MEDIA_QUERY:
      case Lexer.KEYFRAME:
      case Lexer.KEYFRAME_SELECTOR:
      case Lexer.FONT_FACE:
      case Lexer.CHARSET:
      case Lexer.SUPPORTS:
        output += token[1];
        break;
      case Lexer.BRACE_CLOSE:
        output += token[1];
        inferredType = false;
        break;
      case Lexer.DECLARATION:
        const explicitType = token[3] && token[3][0];
        console.log(chalk`{grey token: ${token}}`);

        if (explicitType) {
          console.log(chalk`{green declaration has explicit type: ${explicitType}}`);
        } else if (inferredType) {
          console.log(chalk`{blue declaration has inferred type: ${inferredType}}`);

          if (token[3] === null) {
            token[3] = new Array(4);
          }

          token[3][0] = `${inferredType}<Inferred>`;
        } else {
          console.log(chalk`{red declaration has NO type}`);
        }

        console.log(chalk`{grey token: ${token}}`);
        console.log('-'.repeat(100));

        output += shedNotionIfAny(token)
                    // insert notion comment before semicolon
                    .replace(/;$/, `${notionToComment(token)};`);
        break;
      case Lexer.SELECTOR:
        // either append an open brace or comma depending on whether nextToken is a SELECTOR
        const suffix = nextToken[0] === Lexer.SELECTOR ? ',' : '{';

        if (token[3]) {
          if (prevToken[0] === Lexer.SELECTOR ||
              nextToken[0] === Lexer.SELECTOR) {
            Log.CANNOT_INFER_TYPE(file, token[1], token[3][0]);
            throw new TypeException('Type cannot be inferred by grouped selector');
          } else {
            inferredType = token[3][0];
          }
        }

        output += `${shedNotionIfAny(token)}${suffix}`;
        break;
      default:
        return console.log(chalk`{red Unkown token: ${token}}`);
    }
  });

  console.log('start OUTPUT ------------------------------------------\n');
  console.log(chalk`{grey ${output}}`);
  console.log('\nend OUTPUT ------------------------------------------');
  console.log(chalk`\n {red {bold End} parsing file: ${file.name} --------------- \n}`);
}

// remove notion markup & return native CSS
const shedNotionIfAny = (token) => {
  let tokenValue = token[1];

  if (token[3]) {
    // anything within crocodiles <>
    tokenValue = token[1].replace(/<.+>/, BLANK);
  }

  return tokenValue;
}

// construct CSS comment from token containing notion(s) if any
const notionToComment = (token) => {
  let comment = BLANK;

  if (token[3]) {
    let notions = [];

    const [
      TYPE,
      MODIFIER,
      MOTIVE,
      CONTEXTUAL_DATA
    ] = token[3];

    if (TYPE) {
      notions.push(TYPE);
    }
    if (MODIFIER) {
      notions.push(MODIFIER);
    }
    if (MOTIVE) {
      notions.push(MOTIVE);
    }
    if (CONTEXTUAL_DATA) {
      notions.push(CONTEXTUAL_DATA);
    }

    comment = ` /* ${notions.join(', ')} */ `;
  }

  return comment;
}

module.exports = {
  run
};<|endoftext|>


<commit_before>/* globals module, require, Buffer */
var Picture = require('mongoose').connection.model('Picture'),
    ACCEPTABLE_IMAGE_FORMATS = [
        'png',
        'jpg',
        'jpeg',
        'gif',
        'bmp'
    ];

module.exports = {
    uploadPicture: function(req, res) {
        req.pipe(req.busboy);

        req.busboy.on('file', function(fieldName, file, fileName) {
            var fileParts = fileName.split('.'),
                filePartsLength = fileParts.length,
                fileExtension = fileParts[filePartsLength - 1],
                pictureName = fileParts.slice(0, filePartsLength - 1).join('');

            if (ACCEPTABLE_IMAGE_FORMATS.indexOf(fileExtension) < 0) {
                res.redirect('/');
                return;
            }

            file.on('data', function(data) {
                var newPicture = {
                    buffer: data,
                    name: pictureName,
                    extension: fileExtension
                };

                Picture.create(newPicture, function(err, picture) {
                    if (err) {
                        res.send(400);
                        return;
                    }
                });
            });

            file.on('end', function() {
                res.redirect('/');
            });
        });
    },
    getImageById: function(req, res) {
        var imageId = req.params.id;

        Picture.findOne({
            _id: imageId
        }).exec(function(err, image) {
            if (err) {
                res.status(404);
                return;
            }

            //image.buffer = zlib.inflateSync(image.buffer);
            image.buffer = image.buffer;

            res.contentType('image/' + image.extension);
            res.send(image.buffer);
        });
    },
    getAllPictures: function(req, res) {
        Picture.find({}).exec(function(err, pictures) {
            res.send(pictures);
        });
    }
};<commit_msg>Trying the combination of file.resume() and next for the response.<commit_after>/* globals module, require, Buffer */
var Picture = require('mongoose').connection.model('Picture'),
    ACCEPTABLE_IMAGE_FORMATS = [
        'png',
        'jpg',
        'jpeg',
        'gif',
        'bmp'
    ];

module.exports = {
    uploadPicture: function(req, res, next) {
        var newPicture;
        req.pipe(req.busboy);

        req.busboy.on('file', function(fieldName, file, fileName) {
            var fileParts = fileName.split('.'),
                filePartsLength = fileParts.length,
                fileExtension = fileParts[filePartsLength - 1],
                pictureName = fileParts.slice(0, filePartsLength - 1).join('');

            if (ACCEPTABLE_IMAGE_FORMATS.indexOf(fileExtension) < 0) {
                res.redirect('/');
                return;
            }

            file.on('data', function(data) {
                console.log('Data: ');
                newPicture = {
                    buffer: data,
                    name: pictureName,
                    extension: fileExtension
                };

                file.resume();
            });

            file.on('end', function() {
                Picture.create(newPicture, function(err, picture) {
                    if (err) {
                        res.send(400);
                        return;
                    }
                });

                next();
            });

            res.redirect('/');
        });
    },
    getImageById: function(req, res) {
        var imageId = req.params.id;

        Picture.findOne({
            _id: imageId
        }).exec(function(err, image) {
            if (err) {
                res.status(404);
                return;
            }

            image.buffer = image.buffer;

            res.contentType('image/' + image.extension);
            res.send(image.buffer);
        });
    },
    getAllPictures: function(req, res) {
        Picture.find({}).exec(function(err, pictures) {
            res.send(pictures);
        });
    }
};<|endoftext|>


<commit_before>const DrawCard = require('../../drawcard.js');

class KakitaAsami extends DrawCard {
    setupCardAbilities(ability) {
        this.action ({
            title: 'Take one honor from your opponent',
            condition: context => {
                let diff = this.game.currentConflict.attackerSkill - this.game.currentConflict.defenderSkill;
                return this.game.isDuringConflict('political') && (context.isAttackingPlayer() ? diff < 0 : diff > 0);
            },
            gameAction: ability.actions.takeHonor()
        });
    }
}

KakitaAsami.id = 'kakita-asami';

module.exports = KakitaAsami;
<commit_msg>Fix Kakita Asami bug<commit_after>const DrawCard = require('../../drawcard.js');

class KakitaAsami extends DrawCard {
    setupCardAbilities(ability) {
        this.action ({
            title: 'Take one honor from your opponent',
            condition: context => {
                let diff = this.game.currentConflict.attackerSkill - this.game.currentConflict.defenderSkill;
                return this.game.isDuringConflict('political') && (context.player.isAttackingPlayer() ? diff < 0 : diff > 0);
            },
            gameAction: ability.actions.takeHonor()
        });
    }
}

KakitaAsami.id = 'kakita-asami';

module.exports = KakitaAsami;
<|endoftext|>


<commit_before>"use strict";

if (module == require.main)
  require("test").run(exports);
<commit_msg>Porting test.<commit_after>// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

"use strict";

// test using assert
var qs = require('querystring');

// folding block, commented to pass gjslint
// {{{
// [ wonkyQS, canonicalQS, obj ]
var qsTestCases = [
  ['foo=918854443121279438895193',
   'foo=918854443121279438895193',
   {'foo': '918854443121279438895193'}],
  ['foo=bar', 'foo=bar', {'foo': 'bar'}],
  ['foo=bar&foo=quux', 'foo=bar&foo=quux', {'foo': ['bar', 'quux']}],
  ['foo=1&bar=2', 'foo=1&bar=2', {'foo': '1', 'bar': '2'}],
  ['my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F',
   'my%20weird%20field=q1!2%22\'w%245%267%2Fz8)%3F',
   {'my weird field': 'q1!2"\'w$5&7/z8)?' }],
  ['foo%3Dbaz=bar', 'foo%3Dbaz=bar', {'foo=baz': 'bar'}],
  ['foo=baz=bar', 'foo=baz%3Dbar', {'foo': 'baz=bar'}],
  ['str=foo&arr=1&arr=2&arr=3&somenull=&undef=',
   'str=foo&arr=1&arr=2&arr=3&somenull=&undef=',
   { 'str': 'foo',
     'arr': ['1', '2', '3'],
     'somenull': '',
     'undef': ''}],
  [' foo = bar ', '%20foo%20=%20bar%20', {' foo ': ' bar '}],
  ['foo=%zx', 'foo=%25zx', {'foo': '%zx'}],
  ['foo=%EF%BF%BD', 'foo=%EF%BF%BD', {'foo': '\ufffd' }]
];

// [ wonkyQS, canonicalQS, obj ]
var qsColonTestCases = [
  ['foo:bar', 'foo:bar', {'foo': 'bar'}],
  ['foo:bar;foo:quux', 'foo:bar;foo:quux', {'foo': ['bar', 'quux']}],
  ['foo:1&bar:2;baz:quux',
   'foo:1%26bar%3A2;baz:quux',
   {'foo': '1&bar:2', 'baz': 'quux'}],
  ['foo%3Abaz:bar', 'foo%3Abaz:bar', {'foo:baz': 'bar'}],
  ['foo:baz:bar', 'foo:baz%3Abar', {'foo': 'baz:bar'}]
];

// [wonkyObj, qs, canonicalObj]
var extendedFunction = function() {};
extendedFunction.prototype = {a: 'b'};
var qsWeirdObjects = [
  [{regexp: /./g}, 'regexp=', {'regexp': ''}],
  [{regexp: new RegExp('.', 'g')}, 'regexp=', {'regexp': ''}],
  [{fn: function() {}}, 'fn=', {'fn': ''}],
  [{fn: new Function('')}, 'fn=', {'fn': ''}],
  [{math: Math}, 'math=', {'math': ''}],
  [{e: extendedFunction}, 'e=', {'e': ''}],
  [{d: new Date()}, 'd=', {'d': ''}],
  [{d: Date}, 'd=', {'d': ''}],
  [{f: new Boolean(false), t: new Boolean(true)}, 'f=&t=', {'f': '', 't': ''}],
  [{f: false, t: true}, 'f=false&t=true', {'f': 'false', 't': 'true'}],
  [{n: null}, 'n=', {'n': ''}],
  [{nan: NaN}, 'nan=', {'nan': ''}],
  [{inf: Infinity}, 'inf=', {'inf': ''}]
];
// }}}

var qsNoMungeTestCases = [
  ['', {}],
  ['foo=bar&foo=baz', {'foo': ['bar', 'baz']}],
  ['blah=burp', {'blah': 'burp'}],
  ['gragh=1&gragh=3&goo=2', {'gragh': ['1', '3'], 'goo': '2'}],
  ['frappucino=muffin&goat%5B%5D=scone&pond=moose',
   {'frappucino': 'muffin', 'goat[]': 'scone', 'pond': 'moose'}],
  ['trololol=yes&lololo=no', {'trololol': 'yes', 'lololo': 'no'}]
];

exports['test basic'] = function(assert) {
  assert.strictEqual('918854443121279438895193',
                   qs.parse('id=918854443121279438895193').id);
};

// test that the canonical qs is parsed properly.
exports['test that the canonical qs is parsed properly'] = function(assert) {
  qsTestCases.forEach(function(testCase) {
    assert.deepEqual(testCase[2], qs.parse(testCase[0]));
  });
};

exports['test that the colon test cases can do the same'] = function(assert) {
  qsColonTestCases.forEach(function(testCase) {
    assert.deepEqual(testCase[2], qs.parse(testCase[0], ';', ':'));
  });
};

exports['test the weird objects, that they get parsed properly'] = function(assert) {
  qsWeirdObjects.forEach(function(testCase) {
    assert.deepEqual(testCase[2], qs.parse(testCase[1]));
  });
};

exports['test non munge test cases'] = function(assert) {
  qsNoMungeTestCases.forEach(function(testCase) {
    assert.deepEqual(testCase[0], qs.stringify(testCase[1], '&', '=', false));
  });
};

exports['test the nested qs-in-qs case'] = function(assert) {
  var f = qs.parse('a=b&q=x%3Dy%26y%3Dz');
  f.q = qs.parse(f.q);
  assert.deepEqual(f, { a: 'b', q: { x: 'y', y: 'z' } });
};

exports['test nested in colon'] = function(assert) {
  var f = qs.parse('a:b;q:x%3Ay%3By%3Az', ';', ':');
  f.q = qs.parse(f.q, ';', ':');
  assert.deepEqual(f, { a: 'b', q: { x: 'y', y: 'z' } });
};

exports['test stringifying'] = function(assert) {
  qsTestCases.forEach(function(testCase) {
    assert.equal(testCase[1], qs.stringify(testCase[2]));
  });

  qsColonTestCases.forEach(function(testCase) {
    assert.equal(testCase[1], qs.stringify(testCase[2], ';', ':'));
  });

  qsWeirdObjects.forEach(function(testCase) {
    assert.equal(testCase[1], qs.stringify(testCase[0]));
  });
};

exports['test stringifying nested'] = function(assert) {
  var f = qs.stringify({
    a: 'b',
    q: qs.stringify({
      x: 'y',
      y: 'z'
    })
  });
  assert.equal(f, 'a=b&q=x%3Dy%26y%3Dz');

  var threw = false;
  try { qs.parse(undefined); } catch(error) { threw = true; }
  assert.ok(!threw, "does not throws on undefined");
};

exports['test nested in colon'] = function(assert) {
  var f = qs.stringify({
    a: 'b',
    q: qs.stringify({
      x: 'y',
      y: 'z'
    }, ';', ':')
  }, ';', ':');
  assert.equal(f, 'a:b;q:x%3Ay%3By%3Az');

  assert.deepEqual({}, qs.parse());
};

exports['test unescapeBuffer'] = function(assert) {
  var b = qs.unescapeBuffer('%d3%f2Ug%1f6v%24%5e%98%cb' +
                            '%0d%ac%a2%2f%9d%eb%d8%a2%e6');
  // <Buffer d3 f2 55 67 1f 36 76 24 5e 98 cb 0d ac a2 2f 9d eb d8 a2 e6>
  assert.equal(0xd3, b[0]);
  assert.equal(0xf2, b[1]);
  assert.equal(0x55, b[2]);
  assert.equal(0x67, b[3]);
  assert.equal(0x1f, b[4]);
  assert.equal(0x36, b[5]);
  assert.equal(0x76, b[6]);
  assert.equal(0x24, b[7]);
  assert.equal(0x5e, b[8]);
  assert.equal(0x98, b[9]);
  assert.equal(0xcb, b[10]);
  assert.equal(0x0d, b[11]);
  assert.equal(0xac, b[12]);
  assert.equal(0xa2, b[13]);
  assert.equal(0x2f, b[14]);
  assert.equal(0x9d, b[15]);
  assert.equal(0xeb, b[16]);
  assert.equal(0xd8, b[17]);
  assert.equal(0xa2, b[18]);
  assert.equal(0xe6, b[19]);
};

require("test").run(exports);
<|endoftext|>


<commit_before>/* jshint -W097 */
/* jshint strict:false */
/* jslint node: true */
/* jshint expr: true */
var expect = require('chai').expect;
var fs        = require('fs');

describe('Test package.json and io-package.json', function() {
    it('Test package files', function (done) {
        console.log();

        var fileContentIOPackage = fs.readFileSync(__dirname + '/../io-package.json', 'utf8');
        var ioPackage = JSON.parse(fileContentIOPackage);

        var fileContentNPMPackage = fs.readFileSync(__dirname + '/../package.json', 'utf8');
        var npmPackage = JSON.parse(fileContentNPMPackage);

        expect(ioPackage).to.be.an('object');
        expect(npmPackage).to.be.an('object');

        expect(ioPackage.common.version, 'ERROR: Version number in io-package.json needs to exist').to.exist;
        expect(npmPackage.version, 'ERROR: Version number in package.json needs to exist').to.exist;

        expect(ioPackage.common.version, 'ERROR: Version numbers in package.json and io-package.json needs to match').to.be.equal(npmPackage.version);

        if (!ioPackage.common.news || !ioPackage.common.news[ioPackage.common.version]) {
            console.log('WARNING: No news entry for current version exists in io-package.json, no rollback in Admin possible!');
            console.log();
        }

        expect(npmPackage.author, 'ERROR: Author in package.json needs to exist').to.exist;
        expect(ioPackage.common.authors, 'ERROR: Authors in io-package.json needs to exist').to.exist;

        if (ioPackage.common.name.indexOf('template') !== 0) {
            if (Array.isArray(ioPackage.common.authors)) {
                expect(ioPackage.common.authors.length, 'ERROR: Author in io-package.json needs to be set').to.not.be.equal(0);
                if (ioPackage.common.authors.length === 1) {
                    expect(ioPackage.common.authors[0], 'ERROR: Author in io-package.json needs to be a real name').to.not.be.equal('my Name <my@email.com>');
                }
            }
            else {
                expect(ioPackage.common.authors, 'ERROR: Author in io-package.json needs to be a real name').to.not.be.equal('my Name <my@email.com>');
            }
        }
        else {
            console.log('WARNING: Testing for set authors field in io-package skipped because template adapter');
            console.log();
        }
        expect(fs.existsSync(__dirname + '/../README.md'), 'ERROR: README.md needs to exist! Please create one with description, detail information and changelog. English is mandatory.').to.be.true;
        expect(fs.existsSync(__dirname + '/../LICENSE'), 'ERROR: LICENSE needs to exist! Please create one.').to.be.true;
        if (!ioPackage.common.titleLang || typeof ioPackage.common.titleLang !== 'object') {
            console.log('WARNING: titleLang is not existing in io-package.json. Please add');
            console.log();
        }
        if (
            ioPackage.common.title.indexOf('iobroker') !== -1 ||
            ioPackage.common.title.indexOf('ioBroker') !== -1 ||
            ioPackage.common.title.indexOf('adapter') !== -1 ||
            ioPackage.common.title.indexOf('Adapter') !== -1
        ) {
            console.log('WARNING: title contains Adapter or ioBroker. It is clear anyway, that it is adapter for ioBroker.');
            console.log();
        }

        if (ioPackage.common.name.indexOf('vis-') !== 0) {
            if (!ioPackage.common.materialize || !fs.existsSync(__dirname + '/../admin/index_m.html') || !fs.existsSync(__dirname + '/../gulpfile.js')) {
                console.log('WARNING: Admin3 support is missing! Please add it');
                console.log();
            }
            if (ioPackage.common.materialize) {
                expect(fs.existsSync(__dirname + '/../admin/index_m.html'), 'Admin3 support is enabled in io-package.json, but index_m.html is missing!').to.be.true;
            }
        }

        expect(fs.existsSync(__dirname + '/../LICENSE'), 'A LICENSE must exist');
        var fileContentReadme = fs.readFileSync(__dirname + '/../README.md', 'utf8');
        expect(fileContentReadme.indexOf('## License'), 'The README.md needs to have a section ## License').not.equal(-1);
        expect(fileContentReadme.indexOf('## Changelog'), 'The README.md needs to have a section ## Changelog').not.equal(-1);
        expect(fileContentReadme.indexOf('## Changelog'), 'The README.md needs to have a section ## License').to.be.below(fileContentReadme.indexOf('## License'));
        done();
    });
});
<commit_msg>update basic package-file testing<commit_after>/* jshint -W097 */
/* jshint strict:false */
/* jslint node: true */
/* jshint expr: true */
var expect = require('chai').expect;
var fs        = require('fs');

describe('Test package.json and io-package.json', function() {
    it('Test package files', function (done) {
        console.log();

        var fileContentIOPackage = fs.readFileSync(__dirname + '/../io-package.json', 'utf8');
        var ioPackage = JSON.parse(fileContentIOPackage);

        var fileContentNPMPackage = fs.readFileSync(__dirname + '/../package.json', 'utf8');
        var npmPackage = JSON.parse(fileContentNPMPackage);

        expect(ioPackage).to.be.an('object');
        expect(npmPackage).to.be.an('object');

        expect(ioPackage.common.version, 'ERROR: Version number in io-package.json needs to exist').to.exist;
        expect(npmPackage.version, 'ERROR: Version number in package.json needs to exist').to.exist;

        expect(ioPackage.common.version, 'ERROR: Version numbers in package.json and io-package.json needs to match').to.be.equal(npmPackage.version);

        if (!ioPackage.common.news || !ioPackage.common.news[ioPackage.common.version]) {
            console.log('WARNING: No news entry for current version exists in io-package.json, no rollback in Admin possible!');
            console.log();
        }

        expect(npmPackage.author, 'ERROR: Author in package.json needs to exist').to.exist;
        expect(ioPackage.common.authors, 'ERROR: Authors in io-package.json needs to exist').to.exist;

        if (ioPackage.common.name.indexOf('template') !== 0) {
            if (Array.isArray(ioPackage.common.authors)) {
                expect(ioPackage.common.authors.length, 'ERROR: Author in io-package.json needs to be set').to.not.be.equal(0);
                if (ioPackage.common.authors.length === 1) {
                    expect(ioPackage.common.authors[0], 'ERROR: Author in io-package.json needs to be a real name').to.not.be.equal('my Name <my@email.com>');
                }
            }
            else {
                expect(ioPackage.common.authors, 'ERROR: Author in io-package.json needs to be a real name').to.not.be.equal('my Name <my@email.com>');
            }
        }
        else {
            console.log('WARNING: Testing for set authors field in io-package skipped because template adapter');
            console.log();
        }
        expect(fs.existsSync(__dirname + '/../README.md'), 'ERROR: README.md needs to exist! Please create one with description, detail information and changelog. English is mandatory.').to.be.true;
        expect(fs.existsSync(__dirname + '/../LICENSE'), 'ERROR: LICENSE needs to exist! Please create one.').to.be.true;
        if (!ioPackage.common.titleLang || typeof ioPackage.common.titleLang !== 'object') {
            console.log('WARNING: titleLang is not existing in io-package.json. Please add');
            console.log();
        }
        if (
            ioPackage.common.title.indexOf('iobroker') !== -1 ||
            ioPackage.common.title.indexOf('ioBroker') !== -1 ||
            ioPackage.common.title.indexOf('adapter') !== -1 ||
            ioPackage.common.title.indexOf('Adapter') !== -1
        ) {
            console.log('WARNING: title contains Adapter or ioBroker. It is clear anyway, that it is adapter for ioBroker.');
            console.log();
        }

        if (ioPackage.common.name.indexOf('vis-') !== 0) {
            if (!ioPackage.common.materialize || !fs.existsSync(__dirname + '/../admin/index_m.html') || !fs.existsSync(__dirname + '/../gulpfile.js')) {
                console.log('WARNING: Admin3 support is missing! Please add it');
                console.log();
            }
            if (ioPackage.common.materialize) {
                expect(fs.existsSync(__dirname + '/../admin/index_m.html'), 'Admin3 support is enabled in io-package.json, but index_m.html is missing!').to.be.true;
            }
        }

        expect(fs.existsSync(__dirname + '/../LICENSE'), 'A LICENSE must exist');
        var fileContentReadme = fs.readFileSync(__dirname + '/../README.md', 'utf8');
        if (fileContentReadme.indexOf('## License') === -1) {
            console.log('Warning: The README.md should have a section ## License');
            console.log();
        }
        if (fileContentReadme.indexOf('## Changelog') === -1) {
            console.log('Warning: The README.md should have a section ## Changelog');
            console.log();
        }
        done();
    });
});
<|endoftext|>


<commit_before><commit_msg>Moved input field interaction tests into “mouse events” block<commit_after><|endoftext|>


<commit_before>/**
 * .reel Unit Tests
 */
(function($){

  module('Annotations', reel_test_module_routine);

  test( 'One annotation DOM container (node) is rendered per each `annotations` object key/value pair', function(){
    expect(2);
    var
      selector= '#image',
      $reel= $(selector).reel({
        annotations: {
          "my_annotation_name": {}
        }
      }),
      $instance= $reel.parent()

    equal( !!$reel.siblings('.reel-annotation[id]').length, 1, 'One annotation node with `id` attribute');
    ok( !!$('#my_annotation_name').length, 'Reachable by an `id` selector equal to annotation key');
  });

  asyncTest( '`node` holds a collection of HTML attributes used for the handler\'s `div` tag', function(){
    expect(7);
    var
      selector= '#image',
      $reel= $(selector).reel({
        annotations: {
          "my_annotation": {
            node: {
              text: 'Some text',
              'class': 'some_class_name',
              title: 'Some hint',
              // Any attribute would do as it would for jQuery's `.attr()`
              'any-attribute': 'any-value'
            },
          },
          "still_node": {}
        }
      }),
      $instance= $reel.parent()

    // Positioning of annotations happens at `frameChange`
    $reel.one('frameChange.test', function(){
      ok( !!$('div#my_annotation').length, 'Node present');
      //ok( $('#my_annotation').is(':visible'), 'Node visible');
      ok( $('#my_annotation').is(':contains(Some text)'), 'Node text content');
      equal( $('#my_annotation').text(), 'Some text', 'Node text content');
      ok( !!$('#my_annotation.some_class_name').length, 'Class name applied');
      equal( $('#my_annotation[title]').attr('title'), 'Some hint', '`title` attribute applied');
      equal( $('#my_annotation[any-attribute]').attr('any-attribute'), 'any-value', 'Any attribute would do');

      ok( !!$('div#still_node').length, 'Node is always present, even when not defined');
      start();
    });
  });

  asyncTest( '`image` holds a collection of HTML attributes used for an `img` tag inside the node', function(){
    expect(5);
    var
      selector= '#image',
      $reel= $(selector).reel({
        annotations: {
          "my_annotation": {
            image: {
              src: 'samples/badge-1.gif',
              width: 120,
              height: 30
            }
          }
        }
      }),
      $instance= $reel.parent()

    // Positioning of annotations happens at `frameChange`
    $reel.one('frameChange.test', function(){
      ok( !!$('div#my_annotation').length, 'Node node present');
      ok( !!$('div#my_annotation img').length, 'Wrapping an image node');
      equal( $('#my_annotation img').attr('src'), 'samples/badge-1.gif', 'Image `src`');
      equiv( $('#my_annotation img').attr('width') || $('#my_annotation img').css('width'), 120, 'CSS width');
      equiv( $('#my_annotation img').attr('height') || $('#my_annotation img').css('height'), 30, 'CSS height');
      start();
    });
  });

  asyncTest( '`link` holds a collection of HTML attributes used for an `a` tag inside the node', function(){
    expect(8);
    var
      selector= '#image',
      $reel= $(selector).reel({
        annotations: {
          "text_link": {
            link: {
              href: 'http://some/location',
              text: 'Click to navigate away'
            }
          },
          "image_link": {
            image: {
              src: 'some/my/image.jpg'
            },
            link: {
              href: 'http://some/location'
            }
          }
        }
      })

    // Positioning of annotations happens at `frameChange`
    $reel.one('frameChange.test', function(){
      ok( !!$('div#text_link').length, 'Node node present');
      ok( !!$('div#text_link a').length, 'Wrapping a link node');
      equal( $('#text_link a').attr('href'), 'http://some/location', 'Link `href`');
      equal( $('#text_link a').text(), 'Click to navigate away', '`title`');

      ok( !!$('div#image_link').length, 'Node node present');
      ok( !!$('div#image_link > a > img').length, 'Wrapping a link node wrapping an image node');
      equal( $('#image_link a').attr('href'), 'http://some/location', 'Link `href`');
      equal( $('#image_link img').attr('src'), 'some/my/image.jpg', 'Image `src`');

      start();
    });
  });

  asyncTest( 'Frame-based visibility annotation control properties `start` and `end`', function(){
    expect(36);
    var
      selector= '#image',
      frames= 36, // Default value
      should_be= '----+++++++++-----------------------'.split(''),
      $reel= $(selector).reel({
        annotations: {
          "my_annotation": {
            node: {
              text: "aaa"
            },
            x: 1, y: 1,
            start: 5,
            end: 13
          }
        },
        // And this will autoscroll thorugh all frames once
        entry: 1,
        opening: 1
      }),
      checked= [],
      $annotation= $('#my_annotation')

    // Positioning of annotations happens at `frameChange`
    // and we test it bubbled up to instance's parent
    $reel.parent().bind('frameChange.test', function(){
      var
        frame= $reel.data('frame'),
        should= should_be[frame - 1] == '+'

      equal( $annotation.is(':visible') , should, (should ? 'On' : 'Off')+' @ frame '+frame );

      checked.push(frame);
      if (checked.length == frames){
        $reel.parent().unbind('.test');
        start();
      }
    });
  });

  asyncTest( 'GH-69 The annotations wrapper DOM element is tagged with `frame-X` class name', function(){
    expect( 2 );
    var
      $reel= $('#image').reel({ annotations: {}, speed: 1 });

    setTimeout(function(){
      var
        frame= $reel.data('frame')
      ok( frame, 'Instance stopped at frame '+frame);
      ok( $('#image-reel').attr('class').match(/frame-[0-9]+/), 'The instance wrapper carries frame-'+frame+' class name');
      start();
    }, 123);
  });

  asyncTest( 'Horizontal position of annotation is defined by `x` property relative to left top corner', function(){
    expect( 1 );
    var
      x= '120px',
      $reel= $('#image').reel({ annotations: {
        'x-positioned-annotation': {
          x: x
        }
      }})

    $reel.bind('loaded.test', function(){
      equal( $('#x-positioned-annotation').css('left'), x, '120px');
      start();
    });
  });

  asyncTest( 'Vertical position of annotation is defined by `y` property', function(){
    expect( 2 );
    var
      y= 30,
      $reel= $('#image').reel({ annotations: {
        'y-positioned-annotation': {
          y: y
        }
      }})

    $reel.bind('loaded.test', function(){
      equal( $('#y-positioned-annotation').css('top'), y + 'px', '30px');
      equiv( $('#y-positioned-annotation').css('top'), y, 'It indeed is 30px');
      start();
    });
  });

  asyncTest( 'Both `x` and `y` properties can accept an Array of positions coordinates', function(){
    expect( 12 );
    var
      frames= 6,
      xs= [ 10, 20, 30, 20, 10, 0 ],
      ys= [ 20, 10, 0 , 40, 50, 30 ],
      y= 30,
      from= 1,
      $reel= $('#image').reel({ frames: frames, speed: 1, annotations: {
        'xy-positioned-annotation': {
          x: xs,
          y: ys
        }
      }})

    $reel.parent().bind('frameChange.test', function(){
      var
        frame= $reel.data('frame'),
        index= frame - from

      if (index < 0) return;

      equiv( $('#xy-positioned-annotation').css('left'), xs[index], 'x @ frame '+frame);
      equiv( $('#xy-positioned-annotation').css('top'), ys[index], 'y @ frame '+frame);
      if (index >= xs.length-1) start();
    });
  });

  asyncTest( 'Both `x` and `y` properties can accept an Array of positions coordinates when `start` and `end` are set', function(){
    expect( 8 );
    var
      frames= 6,
      xs= [ 10, 20, 30, 20 ],
      ys= [ 20, 10, 0 , 40 ],
      y= 30,
      from= 2,
      $reel= $('#image').reel({ frames: frames, frame: 2, speed: 1, annotations: {
        'xy-positioned-annotation': {
          start: from,
          end: 5,
          x: xs,
          y: ys
        }
      }})

    $reel.parent().bind('frameChange.test', function(){
      var
        frame= $reel.data('frame'),
        index= frame - from

      if (index < 0) return;

      equiv( $('#xy-positioned-annotation').css('left'), xs[index], 'x @ frame '+frame);
      equiv( $('#xy-positioned-annotation').css('top'), ys[index], 'y @ frame '+frame);
      if (index >= xs.length-1) start();
    });
  });

  asyncTest( 'Visibility switching with `at`', function(){
    expect( 6 );
    var
      frames= 6,
      at= '-+-++-',
      x= 20,
      y= 30,
      count= 0,
      $reel= $('#image').reel({ frames: frames, frame: 1, speed: 1, annotations: {
        'at-controlled-annotation': {
          at: at,
          x: x,
          y: y
        }
      }})

    $reel.parent().bind('frameChange.test', function(){
      var
        frame= $reel.data('frame')

      equiv( $('#at-controlled-annotation').css('display'), at[frame - 1] == '+' ? 'block':'none', 'visibility @ frame '+frame);
      if (count++ >= at.length - 1) start();
    });
  });

  asyncTest( 'GH-79 `click` event on annotation is not propagated up, where it would cause Reel to advance left/right', function(){
    expect( 1 );
    var
      $reel= $('#image').reel({ annotations: {
        'annotation': {
          x: 10,
          y: 10,
          link: {
            click: function(){
              ok( true, 'Annotation `click` handler fired.');
            }
          }
        }
      }})

    $('#annotation a')
    .parent()
    .bind('click.test', function(){
      ok( false, '`click` propagated to the annotation wrapper...');
    })
    .parent()
    .bind('click.test', function(){
      ok( false, '`click` Cpropagated to the instance wrapper...');
    })
    $('#annotation a').click();
    start();
  });

})(jQuery);
<commit_msg>Added test for annotations' visibility via position skipping. #36<commit_after>/**
 * .reel Unit Tests
 */
(function($){

  module('Annotations', reel_test_module_routine);

  test( 'One annotation DOM container (node) is rendered per each `annotations` object key/value pair', function(){
    expect(2);
    var
      selector= '#image',
      $reel= $(selector).reel({
        annotations: {
          "my_annotation_name": {}
        }
      }),
      $instance= $reel.parent()

    equal( !!$reel.siblings('.reel-annotation[id]').length, 1, 'One annotation node with `id` attribute');
    ok( !!$('#my_annotation_name').length, 'Reachable by an `id` selector equal to annotation key');
  });

  asyncTest( '`node` holds a collection of HTML attributes used for the handler\'s `div` tag', function(){
    expect(7);
    var
      selector= '#image',
      $reel= $(selector).reel({
        annotations: {
          "my_annotation": {
            node: {
              text: 'Some text',
              'class': 'some_class_name',
              title: 'Some hint',
              // Any attribute would do as it would for jQuery's `.attr()`
              'any-attribute': 'any-value'
            },
          },
          "still_node": {}
        }
      }),
      $instance= $reel.parent()

    // Positioning of annotations happens at `frameChange`
    $reel.one('frameChange.test', function(){
      ok( !!$('div#my_annotation').length, 'Node present');
      //ok( $('#my_annotation').is(':visible'), 'Node visible');
      ok( $('#my_annotation').is(':contains(Some text)'), 'Node text content');
      equal( $('#my_annotation').text(), 'Some text', 'Node text content');
      ok( !!$('#my_annotation.some_class_name').length, 'Class name applied');
      equal( $('#my_annotation[title]').attr('title'), 'Some hint', '`title` attribute applied');
      equal( $('#my_annotation[any-attribute]').attr('any-attribute'), 'any-value', 'Any attribute would do');

      ok( !!$('div#still_node').length, 'Node is always present, even when not defined');
      start();
    });
  });

  asyncTest( '`image` holds a collection of HTML attributes used for an `img` tag inside the node', function(){
    expect(5);
    var
      selector= '#image',
      $reel= $(selector).reel({
        annotations: {
          "my_annotation": {
            image: {
              src: 'samples/badge-1.gif',
              width: 120,
              height: 30
            }
          }
        }
      }),
      $instance= $reel.parent()

    // Positioning of annotations happens at `frameChange`
    $reel.one('frameChange.test', function(){
      ok( !!$('div#my_annotation').length, 'Node node present');
      ok( !!$('div#my_annotation img').length, 'Wrapping an image node');
      equal( $('#my_annotation img').attr('src'), 'samples/badge-1.gif', 'Image `src`');
      equiv( $('#my_annotation img').attr('width') || $('#my_annotation img').css('width'), 120, 'CSS width');
      equiv( $('#my_annotation img').attr('height') || $('#my_annotation img').css('height'), 30, 'CSS height');
      start();
    });
  });

  asyncTest( '`link` holds a collection of HTML attributes used for an `a` tag inside the node', function(){
    expect(8);
    var
      selector= '#image',
      $reel= $(selector).reel({
        annotations: {
          "text_link": {
            link: {
              href: 'http://some/location',
              text: 'Click to navigate away'
            }
          },
          "image_link": {
            image: {
              src: 'some/my/image.jpg'
            },
            link: {
              href: 'http://some/location'
            }
          }
        }
      })

    // Positioning of annotations happens at `frameChange`
    $reel.one('frameChange.test', function(){
      ok( !!$('div#text_link').length, 'Node node present');
      ok( !!$('div#text_link a').length, 'Wrapping a link node');
      equal( $('#text_link a').attr('href'), 'http://some/location', 'Link `href`');
      equal( $('#text_link a').text(), 'Click to navigate away', '`title`');

      ok( !!$('div#image_link').length, 'Node node present');
      ok( !!$('div#image_link > a > img').length, 'Wrapping a link node wrapping an image node');
      equal( $('#image_link a').attr('href'), 'http://some/location', 'Link `href`');
      equal( $('#image_link img').attr('src'), 'some/my/image.jpg', 'Image `src`');

      start();
    });
  });

  asyncTest( 'Frame-based visibility annotation control properties `start` and `end`', function(){
    expect(36);
    var
      selector= '#image',
      frames= 36, // Default value
      should_be= '----+++++++++-----------------------'.split(''),
      $reel= $(selector).reel({
        annotations: {
          "my_annotation": {
            node: {
              text: "aaa"
            },
            x: 1, y: 1,
            start: 5,
            end: 13
          }
        },
        // And this will autoscroll thorugh all frames once
        entry: 1,
        opening: 1
      }),
      checked= [],
      $annotation= $('#my_annotation')

    // Positioning of annotations happens at `frameChange`
    // and we test it bubbled up to instance's parent
    $reel.parent().bind('frameChange.test', function(){
      var
        frame= $reel.data('frame'),
        should= should_be[frame - 1] == '+'

      equal( $annotation.is(':visible') , should, (should ? 'On' : 'Off')+' @ frame '+frame );

      checked.push(frame);
      if (checked.length == frames){
        $reel.parent().unbind('.test');
        start();
      }
    });
  });

  asyncTest( 'GH-69 The annotations wrapper DOM element is tagged with `frame-X` class name', function(){
    expect( 2 );
    var
      $reel= $('#image').reel({ annotations: {}, speed: 1 });

    setTimeout(function(){
      var
        frame= $reel.data('frame')
      ok( frame, 'Instance stopped at frame '+frame);
      ok( $('#image-reel').attr('class').match(/frame-[0-9]+/), 'The instance wrapper carries frame-'+frame+' class name');
      start();
    }, 123);
  });

  asyncTest( 'Horizontal position of annotation is defined by `x` property relative to left top corner', function(){
    expect( 1 );
    var
      x= '120px',
      $reel= $('#image').reel({ annotations: {
        'x-positioned-annotation': {
          x: x
        }
      }})

    $reel.bind('loaded.test', function(){
      equal( $('#x-positioned-annotation').css('left'), x, '120px');
      start();
    });
  });

  asyncTest( 'Vertical position of annotation is defined by `y` property', function(){
    expect( 2 );
    var
      y= 30,
      $reel= $('#image').reel({ annotations: {
        'y-positioned-annotation': {
          y: y
        }
      }})

    $reel.bind('loaded.test', function(){
      equal( $('#y-positioned-annotation').css('top'), y + 'px', '30px');
      equiv( $('#y-positioned-annotation').css('top'), y, 'It indeed is 30px');
      start();
    });
  });

  asyncTest( 'Both `x` and `y` properties can accept an Array of positions coordinates', function(){
    expect( 12 );
    var
      frames= 6,
      xs= [ 10, 20, 30, 20, 10, 0 ],
      ys= [ 20, 10, 0 , 40, 50, 30 ],
      y= 30,
      from= 1,
      $reel= $('#image').reel({ frames: frames, speed: 1, annotations: {
        'xy-positioned-annotation': {
          x: xs,
          y: ys
        }
      }})

    $reel.parent().bind('frameChange.test', function(){
      var
        frame= $reel.data('frame'),
        index= frame - from

      if (index < 0) return;

      equiv( $('#xy-positioned-annotation').css('left'), xs[index], 'x @ frame '+frame);
      equiv( $('#xy-positioned-annotation').css('top'), ys[index], 'y @ frame '+frame);
      if (index >= xs.length-1) start();
    });
  });

  asyncTest( 'Both `x` and `y` properties can accept an Array of positions coordinates when `start` and `end` are set', function(){
    expect( 8 );
    var
      frames= 6,
      xs= [ 10, 20, 30, 20 ],
      ys= [ 20, 10, 0 , 40 ],
      y= 30,
      from= 2,
      $reel= $('#image').reel({ frames: frames, frame: 2, speed: 1, annotations: {
        'xy-positioned-annotation': {
          start: from,
          end: 5,
          x: xs,
          y: ys
        }
      }})

    $reel.parent().bind('frameChange.test', function(){
      var
        frame= $reel.data('frame'),
        index= frame - from

      if (index < 0) return;

      equiv( $('#xy-positioned-annotation').css('left'), xs[index], 'x @ frame '+frame);
      equiv( $('#xy-positioned-annotation').css('top'), ys[index], 'y @ frame '+frame);
      if (index >= xs.length-1) start();
    });
  });

  asyncTest( 'Visibility via position skipping', function(){
    expect( 6 );
    var
      frames= 6,
      xs= [ 10, 20, undefined, 30, , 20 ],
      ys= [ 20, undefined, 10, 0 , 40,  ],
      $reel= $('#image').reel({ frames: frames, speed: 1, annotations: {
        'xy-positioned-annotation': {
          x: xs,
          y: ys
        }
      }})

    $reel.parent().bind('frameChange.test', function(){
      var
        frame= $reel.data('frame'),
        index= frame - 1

      if (index < 0) return;

      equiv( $('#xy-positioned-annotation').css('display'), xs[index] === undefined || ys[index] === undefined ? 'none':'block', 'visibility @ frame '+frame);
      if (index >= xs.length-1) start();
    });
  });

  asyncTest( 'Visibility via position skipping with one fixed axis (works for the other too)', function(){
    expect( 8 );
    var
      frames= 6,
      xs= [ 10, 20, 30, 20 ],
      y= 30,
      $reel= $('#image').reel({ frames: frames, speed: 1, annotations: {
        'xy-positioned-annotation': {
          x: xs,
          y: y
        }
      }})

    $reel.parent().bind('frameChange.test', function(){
      var
        frame= $reel.data('frame'),
        index= frame - 1

      if (index < 0) return;

      equiv( $('#xy-positioned-annotation').css('left'), xs[index], 'x @ frame '+frame);
      equiv( $('#xy-positioned-annotation').css('top'), y, 'y @ frame '+frame);
      if (index >= xs.length-1) start();
    });
  });

  asyncTest( 'Visibility switching with `at`', function(){
    expect( 6 );
    var
      frames= 6,
      at= '-+-++-',
      x= 20,
      y= 30,
      count= 0,
      $reel= $('#image').reel({ frames: frames, frame: 1, speed: 1, annotations: {
        'at-controlled-annotation': {
          at: at,
          x: x,
          y: y
        }
      }})

    $reel.parent().bind('frameChange.test', function(){
      var
        frame= $reel.data('frame')

      equiv( $('#at-controlled-annotation').css('display'), at[frame - 1] == '+' ? 'block':'none', 'visibility @ frame '+frame);
      if (count++ >= at.length - 1) start();
    });
  });

  asyncTest( 'GH-79 `click` event on annotation is not propagated up, where it would cause Reel to advance left/right', function(){
    expect( 1 );
    var
      $reel= $('#image').reel({ annotations: {
        'annotation': {
          x: 10,
          y: 10,
          link: {
            click: function(){
              ok( true, 'Annotation `click` handler fired.');
            }
          }
        }
      }})

    $('#annotation a')
    .parent()
    .bind('click.test', function(){
      ok( false, '`click` propagated to the annotation wrapper...');
    })
    .parent()
    .bind('click.test', function(){
      ok( false, '`click` Cpropagated to the instance wrapper...');
    })
    $('#annotation a').click();
    start();
  });

})(jQuery);
<|endoftext|>


<commit_before>const marked = require('../../src/marked.js');

describe('Test heading ID functionality', () => {
  it('should add id attribute by default', () => {
    const renderer = new marked.Renderer();
    const slugger = new marked.Slugger();
    const header = renderer.heading('test', 1, 'test', slugger);
    expect(header).toBe('
test
\n');
  });

  it('should NOT add id attribute when options set false', () => {
    const renderer = new marked.Renderer({ headerIds: false });
    const header = renderer.heading('test', 1, 'test');
    expect(header).toBe('
test
\n');
  });
});

describe('Test slugger functionality', () => {
  it('should use lowercase slug', () => {
    const slugger = new marked.Slugger();
    expect(slugger.slug('Test')).toBe('test');
  });

  it('should be unique to avoid collisions 1280', () => {
    const slugger = new marked.Slugger();
    expect(slugger.slug('test')).toBe('test');
    expect(slugger.slug('test')).toBe('test-1');
    expect(slugger.slug('test')).toBe('test-2');
  });

  it('should be unique when slug ends with number', () => {
    const slugger = new marked.Slugger();
    expect(slugger.slug('test 1')).toBe('test-1');
    expect(slugger.slug('test')).toBe('test');
    expect(slugger.slug('test')).toBe('test-2');
  });

  it('should be unique when slug ends with hyphen number', () => {
    const slugger = new marked.Slugger();
    expect(slugger.slug('foo')).toBe('foo');
    expect(slugger.slug('foo')).toBe('foo-1');
    expect(slugger.slug('foo 1')).toBe('foo-1-1');
    expect(slugger.slug('foo-1')).toBe('foo-1-2');
    expect(slugger.slug('foo')).toBe('foo-2');
  });

  it('should allow non-latin chars', () => {
    const slugger = new marked.Slugger();
    expect(slugger.slug('привет')).toBe('привет');
  });

  it('should remove ampersands 857', () => {
    const slugger = new marked.Slugger();
    expect(slugger.slug('This & That Section')).toBe('this--that-section');
  });

  it('should remove periods', () => {
    const slugger = new marked.Slugger();
    expect(slugger.slug('file.txt')).toBe('filetxt');
  });
});

describe('Test paragraph token type', () => {
  it('should use the "paragraph" type on top level', () => {
    const md = 'A Paragraph.\n\n> A blockquote\n\n- list item\n';

    const tokens = marked.lexer(md);

    expect(tokens[0].type).toBe('paragraph');
    expect(tokens[3].type).toBe('paragraph');
    expect(tokens[7].type).toBe('text');
  });
});

describe('changeDefaults', () => {
  it('should change global defaults', () => {
    const { defaults, changeDefaults } = require('../../src/defaults');
    expect(defaults.test).toBeUndefined();
    changeDefaults({ test: true });
    expect(require('../../src/defaults').defaults.test).toBe(true);
  });
});
<commit_msg>add inline html test<commit_after>const marked = require('../../src/marked.js');

describe('Test heading ID functionality', () => {
  it('should add id attribute by default', () => {
    const renderer = new marked.Renderer();
    const slugger = new marked.Slugger();
    const header = renderer.heading('test', 1, 'test', slugger);
    expect(header).toBe('
test
\n');
  });

  it('should NOT add id attribute when options set false', () => {
    const renderer = new marked.Renderer({ headerIds: false });
    const header = renderer.heading('test', 1, 'test');
    expect(header).toBe('
test
\n');
  });
});

describe('Test slugger functionality', () => {
  it('should use lowercase slug', () => {
    const slugger = new marked.Slugger();
    expect(slugger.slug('Test')).toBe('test');
  });

  it('should be unique to avoid collisions 1280', () => {
    const slugger = new marked.Slugger();
    expect(slugger.slug('test')).toBe('test');
    expect(slugger.slug('test')).toBe('test-1');
    expect(slugger.slug('test')).toBe('test-2');
  });

  it('should be unique when slug ends with number', () => {
    const slugger = new marked.Slugger();
    expect(slugger.slug('test 1')).toBe('test-1');
    expect(slugger.slug('test')).toBe('test');
    expect(slugger.slug('test')).toBe('test-2');
  });

  it('should be unique when slug ends with hyphen number', () => {
    const slugger = new marked.Slugger();
    expect(slugger.slug('foo')).toBe('foo');
    expect(slugger.slug('foo')).toBe('foo-1');
    expect(slugger.slug('foo 1')).toBe('foo-1-1');
    expect(slugger.slug('foo-1')).toBe('foo-1-2');
    expect(slugger.slug('foo')).toBe('foo-2');
  });

  it('should allow non-latin chars', () => {
    const slugger = new marked.Slugger();
    expect(slugger.slug('привет')).toBe('привет');
  });

  it('should remove ampersands 857', () => {
    const slugger = new marked.Slugger();
    expect(slugger.slug('This & That Section')).toBe('this--that-section');
  });

  it('should remove periods', () => {
    const slugger = new marked.Slugger();
    expect(slugger.slug('file.txt')).toBe('filetxt');
  });
});

describe('Test paragraph token type', () => {
  it('should use the "paragraph" type on top level', () => {
    const md = 'A Paragraph.\n\n> A blockquote\n\n- list item\n';

    const tokens = marked.lexer(md);

    expect(tokens[0].type).toBe('paragraph');
    expect(tokens[3].type).toBe('paragraph');
    expect(tokens[7].type).toBe('text');
  });
});

describe('changeDefaults', () => {
  it('should change global defaults', () => {
    const { defaults, changeDefaults } = require('../../src/defaults');
    expect(defaults.test).toBeUndefined();
    changeDefaults({ test: true });
    expect(require('../../src/defaults').defaults.test).toBe(true);
  });
});

describe('inlineLexer', () => {
  it('should send html to renderer.html', () => {
    const renderer = new marked.Renderer();
    spyOn(renderer, 'html').and.callThrough();
    const md = 'HTML Image: ';
    marked(md, { renderer });

    expect(renderer.html).toHaveBeenCalledWith('');
  });
});
<|endoftext|>


<commit_before>define([
	'dojo/_base/declare',
	'dojo/_base/array',
	'dojo/store/util/QueryResults'
	/*=====, "dstore/api/Store" =====*/
], function (declare, arrayUtil, QueryResults /*=====, Store =====*/) {
// module:
//		An adapter mixin that makes a dstore store object look like a legacy Dojo object store.

	function passthrough(data) {
		return data;
	}

	// No base class, but for purposes of documentation, the base class is dstore/api/Store
	var base = null;
	/*===== base = Store; =====*/

	var adapterPrototype = {

		// store:
		//		The dstore store that is wrapped as a Dojo object store
		store: null,

		constructor: function (store) {
			this.store = store;

			if (this.store.queryEngine) {
				var queryEngine = this.store.queryEngine;
				this.queryEngine = function (query, options) {
					options = options || {};

					var filter = queryEngine.filter(query);
					var sort = passthrough;
					var range = passthrough;

					if (queryEngine.sort && options.sort) {
						sort = queryEngine.sort(arrayUtil.map(options.sort, function (criteria) {
							return {
								property: criteria.attribute,
								descending: criteria.descending
							};
						}));
					}

					if (!isNaN(options.start) || !isNaN(options.count)) {
						range = queryEngine.range({
							start: options.start,
							end: (options.start || 0) + (isNaN(options.count) ? Infinity : options.count)
						});
					}

					return function (data) {
						return range(sort(filter(data)));
					};
				};
			}
			var objectStore = this;
			// we call notify on events to mimic the old dojo/store/Trackable
			store.on('add,update,remove', function (event) {
				var type = event.type;
				var target = event.target;
				objectStore.notify(
					(type === 'add' || type === 'update') ? target : undefined,
					(type === 'remove' || type === 'update') ?
						('id' in event ? event.id : store.getIdentity(target)) : undefined);
			});
		},

		query: function (query, options) {
			// summary:
			//		Queries the store for objects. This does not alter the store, but returns a
			//		set of data from the store.
			// query: String|Object|Function
			//		The query to use for retrieving objects from the store.
			// options: dstore/api/Store.QueryOptions
			//		The optional arguments to apply to the resultset.
			// returns: dstore/api/Store.QueryResults
			//		The results of the query, extended with iterative methods.
			//
			// example:
			//		Given the following store:
			//
			//	...find all items where "prime" is true:
			//
			//	|	store.query({ prime: true }).forEach(function(object){
			//	|		// handle each object
			//	|	});
			var results = this.store.filter(query);

			if (options) {
				// Apply sorting
				var sort = options.sort;
				if (sort) {
					if (Object.prototype.toString.call(sort) === '[object Array]') {
						var sortOptions;
						while ((sortOptions = sort.pop())) {
							results = results.sort(sortOptions.attribute, sortOptions.descending);
						}
					} else {
						results = results.sort(sort);
					}
				}
				// Apply a range
				if ('start' in options) {
					var start = options.start || 0;
					// object stores support sync results, so try that if available
					var queryResults = results[results.fetchRangeSync ? 'fetchRangeSync' : 'fetchRange']({
						start: start,
						end: options.count ? (start + options.count) : Infinity
					});
					queryResults.total = queryResults.totalLength;
					return new QueryResults(queryResults);
				}
 			}
 			var tracked;
			if (results.track) {
				// if it is trackable, always track, so that observe can
				// work properly.
				results = results.track();
				tracked = true;
			}
			var queryResults = new QueryResults(results[results.fetchSync ? 'fetchSync' : 'fetch']());
			queryResults.observe = function (callback, includeObjectUpdates) {
				// translate observe to event listeners
				function convertUndefined(value) {
					if (value === undefined && tracked) {
						return -1;
					}
					return value;
				}
				var addHandle = results.on('add', function (event) {
					callback(event.target, -1, convertUndefined(event.index));
				});
				var updateHandle = results.on('update', function (event) {
					if (includeObjectUpdates || event.previousIndex !== event.index || !isFinite(event.index)) {
						callback(event.target, convertUndefined(event.previousIndex), convertUndefined(event.index));
					}
				});
				var removeHandle = results.on('remove', function (event) {
					callback(event.target, convertUndefined(event.previousIndex), -1);
				});
				var handle = {
					remove: function () {
						addHandle.remove();
						updateHandle.remove();
						removeHandle.remove();
					}
				};
				handle.cancel = handle.remove;
				return handle;
			};
			return queryResults;
		},
		notify: function () {

		}
	};

	var delegatedMethods = [ 'get', 'put', 'add', 'remove', 'getIdentity' ];
	arrayUtil.forEach(delegatedMethods, function (methodName) {
		adapterPrototype[methodName] = function () {
			var store = this.store;
			// try sync first, since dojo object stores support that directly
			return (store[methodName + 'Sync'] || store[methodName]).apply(store, arguments);
		};
	});

	return declare(base, adapterPrototype);
});
<commit_msg>Ensure that observe is added to all query result sets returned from DstoreAdapter<commit_after>define([
	'dojo/_base/declare',
	'dojo/_base/array',
	'dojo/store/util/QueryResults'
	/*=====, "dstore/api/Store" =====*/
], function (declare, arrayUtil, QueryResults /*=====, Store =====*/) {
// module:
//		An adapter mixin that makes a dstore store object look like a legacy Dojo object store.

	function passthrough(data) {
		return data;
	}

	// No base class, but for purposes of documentation, the base class is dstore/api/Store
	var base = null;
	/*===== base = Store; =====*/

	var adapterPrototype = {

		// store:
		//		The dstore store that is wrapped as a Dojo object store
		store: null,

		constructor: function (store) {
			this.store = store;

			if (this.store.queryEngine) {
				var queryEngine = this.store.queryEngine;
				this.queryEngine = function (query, options) {
					options = options || {};

					var filter = queryEngine.filter(query);
					var sort = passthrough;
					var range = passthrough;

					if (queryEngine.sort && options.sort) {
						sort = queryEngine.sort(arrayUtil.map(options.sort, function (criteria) {
							return {
								property: criteria.attribute,
								descending: criteria.descending
							};
						}));
					}

					if (!isNaN(options.start) || !isNaN(options.count)) {
						range = queryEngine.range({
							start: options.start,
							end: (options.start || 0) + (isNaN(options.count) ? Infinity : options.count)
						});
					}

					return function (data) {
						return range(sort(filter(data)));
					};
				};
			}
			var objectStore = this;
			// we call notify on events to mimic the old dojo/store/Trackable
			store.on('add,update,remove', function (event) {
				var type = event.type;
				var target = event.target;
				objectStore.notify(
					(type === 'add' || type === 'update') ? target : undefined,
					(type === 'remove' || type === 'update') ?
						('id' in event ? event.id : store.getIdentity(target)) : undefined);
			});
		},

		query: function (query, options) {
			// summary:
			//		Queries the store for objects. This does not alter the store, but returns a
			//		set of data from the store.
			// query: String|Object|Function
			//		The query to use for retrieving objects from the store.
			// options: dstore/api/Store.QueryOptions
			//		The optional arguments to apply to the resultset.
			// returns: dstore/api/Store.QueryResults
			//		The results of the query, extended with iterative methods.
			//
			// example:
			//		Given the following store:
			//
			//	...find all items where "prime" is true:
			//
			//	|	store.query({ prime: true }).forEach(function(object){
			//	|		// handle each object
			//	|	});
			var results = this.store.filter(query);
			var queryResults;

			if (options) {
				// Apply sorting
				var sort = options.sort;
				if (sort) {
					if (Object.prototype.toString.call(sort) === '[object Array]') {
						var sortOptions;
						while ((sortOptions = sort.pop())) {
							results = results.sort(sortOptions.attribute, sortOptions.descending);
						}
					} else {
						results = results.sort(sort);
					}
				}
			}
 			var tracked;
			if (results.track) {
				// if it is trackable, always track, so that observe can
				// work properly.
				results = results.track();
				tracked = true;
			}
			if (options && 'start' in options) {
				// Apply a range
				var start = options.start || 0;
				// object stores support sync results, so try that if available
				queryResults = results[results.fetchRangeSync ? 'fetchRangeSync' : 'fetchRange']({
					start: start,
					end: options.count ? (start + options.count) : Infinity
				});
				queryResults.total = queryResults.totalLength;
			}
			queryResults = queryResults || new QueryResults(results[results.fetchSync ? 'fetchSync' : 'fetch']());
			queryResults.observe = function (callback, includeObjectUpdates) {
				// translate observe to event listeners
				function convertUndefined(value) {
					if (value === undefined && tracked) {
						return -1;
					}
					return value;
				}
				var addHandle = results.on('add', function (event) {
					callback(event.target, -1, convertUndefined(event.index));
				});
				var updateHandle = results.on('update', function (event) {
					if (includeObjectUpdates || event.previousIndex !== event.index || !isFinite(event.index)) {
						callback(event.target, convertUndefined(event.previousIndex), convertUndefined(event.index));
					}
				});
				var removeHandle = results.on('remove', function (event) {
					callback(event.target, convertUndefined(event.previousIndex), -1);
				});
				var handle = {
					remove: function () {
						addHandle.remove();
						updateHandle.remove();
						removeHandle.remove();
					}
				};
				handle.cancel = handle.remove;
				return handle;
			};
			return queryResults;
		},
		notify: function () {

		}
	};

	var delegatedMethods = [ 'get', 'put', 'add', 'remove', 'getIdentity' ];
	arrayUtil.forEach(delegatedMethods, function (methodName) {
		adapterPrototype[methodName] = function () {
			var store = this.store;
			// try sync first, since dojo object stores support that directly
			return (store[methodName + 'Sync'] || store[methodName]).apply(store, arguments);
		};
	});

	return declare(base, adapterPrototype);
});
<|endoftext|>