<commit_before>(function (window, undefined) {
"use strict";

window.Seriously = window.Seriously ||
	{ plugin: function (name, opt) { this[name] = opt; } };

Seriously.plugin('tvglitch', (function () {
	//particle parameters
	var minVelocity = 0.2,
		maxVelocity = 0.8,
		minSize = 0.02,
		maxSize = 0.3,
		lifetime = 7,
		particleCount = 20;
	return {
		initialize: function(parent) {
			var i, sizeRange, velocityRange, gl = this.gl,
				particleVertex, particleFragment, particles;

			this.lastHeight = this.height;

			//initialize particles
			particles = [];
			sizeRange = maxSize - minSize;
			velocityRange = maxVelocity - minVelocity;
			for (i = 0; i < particleCount; i++) {
				particles.push(Math.random() * 2 - 1); //position
				particles.push(Math.random() * velocityRange + minVelocity); //velocity
				particles.push(Math.random() * sizeRange + minSize); //size
				particles.push(Math.random() * 0.2); //intensity
			}

			this.particleBuffer = gl.createBuffer();
			gl.bindBuffer(gl.ARRAY_BUFFER, this.particleBuffer);
			gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(particles), gl.STATIC_DRAW);
			this.particleBuffer.itemSize = 4;
			this.particleBuffer.numItems = particleCount;

			particleVertex = '#ifdef GL_ES\n' +
			'precision mediump float;\n' +
			'#endif \n' +
			'\n' +
			'attribute vec4 particle;\n' +
			'\n' +
			'uniform float time;\n' +
			'uniform float height;\n' +
			'\n' +
			'varying float intensity;\n' +
			'\n' +
			'void main(void) {\n' +
			'	float y = particle.x + time * particle.y;\n' +
			'	y = fract((y + 1.0) / 2.0) * 4.0 - 2.0;\n' +
			'	intensity = particle.w;\n' +
			'	gl_Position = vec4(0.0, -y , 1.0, 2.0);\n' +
//			'	gl_Position = vec4(0.0, 1.0 , 1.0, 1.0);\n' +
			'	gl_PointSize = height * particle.z;\n' +
			'}\n';

			particleFragment = '#ifdef GL_ES\n\n' +
			'precision mediump float;\n\n' +
			'#endif\n\n' +
			'\n' +
			'varying float intensity;\n' +
			'\n' +
			'void main(void) {\n' +
			'	gl_FragColor = vec4(1.0);\n' +
			'	gl_FragColor.a = 2.0 * intensity * (1.0 - abs(gl_PointCoord.y - 0.5));\n' +
			'}\n';

			this.particleShader = new Seriously.util.ShaderProgram(gl, particleVertex, particleFragment);

			this.particleFrameBuffer = new Seriously.util.FrameBuffer(gl, 1, this.height/2);
			parent();
		},
		shader: function(inputs, shaderSource, utilities) {
			//baseShader = new Seriously.util.ShaderProgram(this.gl, shaderSource.vertex, shaderSource.fragment);

			shaderSource.fragment = '#ifdef GL_ES\n\n' +
				'precision mediump float;\n\n' +
				'#endif\n\n' +
				'\n' +
//				'#define HardLight(top, bottom) (top < 0.5 ? (2.0 * top * bottom) : (1.0 - 2.0 * (1.0 - top) * (1.0 - bottom)))\n' +
				'#define HardLight(top, bottom)  (1.0 - 2.0 * (1.0 - top) * (1.0 - bottom))\n' +
				'\n' +
				'varying vec2 vTexCoord;\n' +
				'varying vec4 vPosition;\n' +
				'\n' +
				'uniform sampler2D source;\n' +
				'uniform sampler2D particles;\n' +
				'uniform float time;\n' +
				'uniform float scanlines;\n' +
				'uniform float lineSync;\n' +
				'uniform float lineHeight;\n' + //for scanlines and distortion
				'uniform float distortion;\n' +
				'uniform float vsync;\n' +
				'uniform float bars;\n' +
				'\n' +
				//todo: need much better pseudo-random number generator
				(Seriously.util.shader.snoise2d || ('float snoise(vec2 v){\n' +
					'    return fract(sin(dot(v ,vec2(12.9898,78.233))) * 43758.5453);\n' +
					'}\n')) +
				'\n' +
				'void main(void) {\n' +
				'	vec2 texCoord = vTexCoord;\n' +

					//distortion
				'	float drandom = snoise(vec2(time * 50.0, texCoord.y /lineHeight));\n' +
				'	float distortAmount = distortion * (drandom - 0.25) * 0.5;\n' +
					//line sync
				'	vec4 particleOffset = texture2D(particles, vec2(0.0, texCoord.y));\n' +
				'	distortAmount -= lineSync * (2.0 * particleOffset.a - 0.5);\n' +

				'	texCoord.x -= distortAmount;\n' +
				//'	texCoord.x = max(0.0, texCoord.x);\n' +
				//'	texCoord.x = min(1.0, texCoord.x);\n' +
				'	texCoord.x = mod(texCoord.x, 1.0);\n' +

					//vertical sync
				'	float roll;\n' +
				'	if (vsync != 0.0) {\n' +
				'		roll = fract(time / vsync);\n' +
				'		texCoord.y = mod(texCoord.y - roll, 1.0);\n' +
				'	}\n' +

				'	vec4 pixel = texture2D(source, texCoord);\n' +

					//horizontal bars
				'	float barsAmount = particleOffset.r;\n' +
				'	if (barsAmount > 0.0) {\n' +
/*
				'		pixel = vec4(HardLight(pixel.r * bars, barsAmount),' +
							'HardLight(pixel.g * bars, barsAmount),' +
							'HardLight(pixel.b * bars, barsAmount),' +
							'pixel.a);\n' +
*/
				'		pixel = vec4(pixel.r + bars * barsAmount,' +
							'pixel.g + bars * barsAmount,' +
							'pixel.b + bars * barsAmount,' +
							'pixel.a);\n' +
				'	}\n' +

				'	if (mod(texCoord.y / lineHeight, 2.0) < 1.0 ) {\n' +
				'		pixel.rgb *= (1.0 - scanlines);\n' +
				'	}\n' +

				//'	gl_FragColor.r = vec4(1.0);\n' +
				'	gl_FragColor = pixel; //vec4(vec3(particleOffset), 1.0);\n' +
//				'	gl_FragColor = vec4(particleOffset);\n' +
//				'	gl_FragColor.a = 1.0;\n' +
				'}\n';

			return shaderSource;
		},
		draw: function (shader, model, uniforms, frameBuffer, parent) {
			var doParticles = (this.lastTime !== this.inputs.time),
				vsyncPeriod,
				i, particle, diff,
				gl = this.gl;

			if (this.lastHeight !== this.height) {
				this.lastHeight = this.height;
				//todo: adjust framebuffer height?
				doParticles = true;
			}

			//todo: make this configurable?
			uniforms.lineHeight = 1 / this.height;

			if (this.inputs.verticalSync) {
				vsyncPeriod = 0.2 / this.inputs.verticalSync;
				uniforms.vsync = vsyncPeriod;
			} else {
				vsyncPeriod = 1;
				uniforms.vsync = 0;
			}
			uniforms.time = (this.inputs.time % (10000 * vsyncPeriod)) / 1000;
			uniforms.distortion = Math.random() * this.inputs.distortion;

			//render particle canvas and attach uniform
			//todo: this is a good spot for parallel processing. RiverTrail maybe?
			if (doParticles && (this.inputs.lineSync || this.inputs.bars)) {
				diff = this.inputs.time - this.lastTime;

				this.particleShader.useProgram();
				gl.viewport(0, 0, 1, this.height / 2);
				gl.bindFramebuffer(gl.FRAMEBUFFER, this.particleFrameBuffer.frameBuffer);
				gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
				gl.enableVertexAttribArray(this.particleShader.location_particle);
				gl.bindBuffer(gl.ARRAY_BUFFER, this.particleBuffer);
				gl.vertexAttribPointer(this.particleShader.location_particle, this.particleBuffer.itemSize, gl.FLOAT, false, 0, 0);
				gl.enable(gl.BLEND);
				gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
				this.particleShader.set_time(uniforms.time);
				this.particleShader.set_height(this.height);
				gl.drawArrays(gl.POINTS, 0, particleCount);

				this.lastTime = this.inputs.time;
			}
			uniforms.particles = this.particleFrameBuffer.texture;

			parent(shader, model, uniforms, frameBuffer);
/*
				this.particleShader.useProgram();
				gl.viewport(0, 0, 1, 480);
				gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
//				gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
				gl.enableVertexAttribArray(this.particleShader.location_particle);
				gl.bindBuffer(gl.ARRAY_BUFFER, this.particleBuffer);
				gl.vertexAttribPointer(this.particleShader.location_particle, this.particleBuffer.itemSize, gl.FLOAT, false, 0, 0);
				gl.enable(gl.BLEND);
				gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
				this.particleShader.set_time(uniforms.time);
				this.particleShader.set_height(this.height);
				gl.drawArrays(gl.POINTS, 0, particleCount);
*/
		},
		inPlace: false,
		inputs: {
			source: {
				type: 'image',
				uniform: 'source',
				shaderDirty: false
			},
			time: {
				type: 'number',
				defaultValue: 0
			},
			distortion: {
				type: 'number',
				defaultValue: 0.1,
				min: 0,
				max: 1
			},
			verticalSync: {
				type: 'number',
				defaultValue: 0.1,
				min: 0,
				max: 1
			},
			lineSync: {
				type: 'number',
				uniform: 'lineSync',
				defaultValue: 0.2,
				min: 0,
				max: 1
			},
			scanlines: {
				type: 'number',
				uniform: 'scanlines',
				defaultValue: 0.3,
				min: 0,
				max: 1
			},
			bars: {
				type: 'number',
				uniform: 'bars',
				defaultValue: 0,
				min: 0,
				max: 1
			}
		},
		description: '',
		title: 'TV Glitch'
	};
}()) );

}(window));
<commit_msg>Fixed TV Glitch to work with new noise shader<commit_after>(function (window, undefined) {
"use strict";

window.Seriously = window.Seriously ||
	{ plugin: function (name, opt) { this[name] = opt; } };

Seriously.plugin('tvglitch', (function () {
	//particle parameters
	var minVelocity = 0.2,
		maxVelocity = 0.8,
		minSize = 0.02,
		maxSize = 0.3,
		lifetime = 7,
		particleCount = 20;
	return {
		initialize: function(parent) {
			var i, sizeRange, velocityRange, gl = this.gl,
				particleVertex, particleFragment, particles;

			this.lastHeight = this.height;

			//initialize particles
			particles = [];
			sizeRange = maxSize - minSize;
			velocityRange = maxVelocity - minVelocity;
			for (i = 0; i < particleCount; i++) {
				particles.push(Math.random() * 2 - 1); //position
				particles.push(Math.random() * velocityRange + minVelocity); //velocity
				particles.push(Math.random() * sizeRange + minSize); //size
				particles.push(Math.random() * 0.2); //intensity
			}

			this.particleBuffer = gl.createBuffer();
			gl.bindBuffer(gl.ARRAY_BUFFER, this.particleBuffer);
			gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(particles), gl.STATIC_DRAW);
			this.particleBuffer.itemSize = 4;
			this.particleBuffer.numItems = particleCount;

			particleVertex = '#ifdef GL_ES\n' +
			'precision mediump float;\n' +
			'#endif \n' +
			'\n' +
			'attribute vec4 particle;\n' +
			'\n' +
			'uniform float time;\n' +
			'uniform float height;\n' +
			'\n' +
			'varying float intensity;\n' +
			'\n' +
			'void main(void) {\n' +
			'	float y = particle.x + time * particle.y;\n' +
			'	y = fract((y + 1.0) / 2.0) * 4.0 - 2.0;\n' +
			'	intensity = particle.w;\n' +
			'	gl_Position = vec4(0.0, -y , 1.0, 2.0);\n' +
//			'	gl_Position = vec4(0.0, 1.0 , 1.0, 1.0);\n' +
			'	gl_PointSize = height * particle.z;\n' +
			'}\n';

			particleFragment = '#ifdef GL_ES\n\n' +
			'precision mediump float;\n\n' +
			'#endif\n\n' +
			'\n' +
			'varying float intensity;\n' +
			'\n' +
			'void main(void) {\n' +
			'	gl_FragColor = vec4(1.0);\n' +
			'	gl_FragColor.a = 2.0 * intensity * (1.0 - abs(gl_PointCoord.y - 0.5));\n' +
			'}\n';

			this.particleShader = new Seriously.util.ShaderProgram(gl, particleVertex, particleFragment);

			this.particleFrameBuffer = new Seriously.util.FrameBuffer(gl, 1, this.height/2);
			parent();
		},
		shader: function(inputs, shaderSource, utilities) {
			//baseShader = new Seriously.util.ShaderProgram(this.gl, shaderSource.vertex, shaderSource.fragment);

			shaderSource.fragment = '#ifdef GL_ES\n\n' +
				'precision mediump float;\n\n' +
				'#endif\n\n' +
				'\n' +
//				'#define HardLight(top, bottom) (top < 0.5 ? (2.0 * top * bottom) : (1.0 - 2.0 * (1.0 - top) * (1.0 - bottom)))\n' +
				'#define HardLight(top, bottom)  (1.0 - 2.0 * (1.0 - top) * (1.0 - bottom))\n' +
				'\n' +
				'varying vec2 vTexCoord;\n' +
				'varying vec4 vPosition;\n' +
				'\n' +
				'uniform sampler2D source;\n' +
				'uniform sampler2D particles;\n' +
				'uniform float time;\n' +
				'uniform float scanlines;\n' +
				'uniform float lineSync;\n' +
				'uniform float lineHeight;\n' + //for scanlines and distortion
				'uniform float distortion;\n' +
				'uniform float vsync;\n' +
				'uniform float bars;\n' +
				'\n' +
				//todo: need much better pseudo-random number generator
				Seriously.util.shader.noiseHelpers +
				Seriously.util.shader.snoise2d +
				'\n' +
				'void main(void) {\n' +
				'	vec2 texCoord = vTexCoord;\n' +

					//distortion
				'	float drandom = snoise(vec2(time * 50.0, texCoord.y /lineHeight));\n' +
				'	float distortAmount = distortion * (drandom - 0.25) * 0.5;\n' +
					//line sync
				'	vec4 particleOffset = texture2D(particles, vec2(0.0, texCoord.y));\n' +
				'	distortAmount -= lineSync * (2.0 * particleOffset.a - 0.5);\n' +

				'	texCoord.x -= distortAmount;\n' +
				//'	texCoord.x = max(0.0, texCoord.x);\n' +
				//'	texCoord.x = min(1.0, texCoord.x);\n' +
				'	texCoord.x = mod(texCoord.x, 1.0);\n' +

					//vertical sync
				'	float roll;\n' +
				'	if (vsync != 0.0) {\n' +
				'		roll = fract(time / vsync);\n' +
				'		texCoord.y = mod(texCoord.y - roll, 1.0);\n' +
				'	}\n' +

				'	vec4 pixel = texture2D(source, texCoord);\n' +

					//horizontal bars
				'	float barsAmount = particleOffset.r;\n' +
				'	if (barsAmount > 0.0) {\n' +
/*
				'		pixel = vec4(HardLight(pixel.r * bars, barsAmount),' +
							'HardLight(pixel.g * bars, barsAmount),' +
							'HardLight(pixel.b * bars, barsAmount),' +
							'pixel.a);\n' +
*/
				'		pixel = vec4(pixel.r + bars * barsAmount,' +
							'pixel.g + bars * barsAmount,' +
							'pixel.b + bars * barsAmount,' +
							'pixel.a);\n' +
				'	}\n' +

				'	if (mod(texCoord.y / lineHeight, 2.0) < 1.0 ) {\n' +
				'		pixel.rgb *= (1.0 - scanlines);\n' +
				'	}\n' +

				//'	gl_FragColor.r = vec4(1.0);\n' +
				'	gl_FragColor = pixel; //vec4(vec3(particleOffset), 1.0);\n' +
//				'	gl_FragColor = vec4(particleOffset);\n' +
//				'	gl_FragColor.a = 1.0;\n' +
				'}\n';

			return shaderSource;
		},
		draw: function (shader, model, uniforms, frameBuffer, parent) {
			var doParticles = (this.lastTime !== this.inputs.time),
				vsyncPeriod,
				i, particle, diff,
				gl = this.gl;

			if (this.lastHeight !== this.height) {
				this.lastHeight = this.height;
				//todo: adjust framebuffer height?
				doParticles = true;
			}

			//todo: make this configurable?
			uniforms.lineHeight = 1 / this.height;

			if (this.inputs.verticalSync) {
				vsyncPeriod = 0.2 / this.inputs.verticalSync;
				uniforms.vsync = vsyncPeriod;
			} else {
				vsyncPeriod = 1;
				uniforms.vsync = 0;
			}
			uniforms.time = (this.inputs.time % (10000 * vsyncPeriod)) / 1000;
			uniforms.distortion = Math.random() * this.inputs.distortion;

			//render particle canvas and attach uniform
			//todo: this is a good spot for parallel processing. RiverTrail maybe?
			if (doParticles && (this.inputs.lineSync || this.inputs.bars)) {
				diff = this.inputs.time - this.lastTime;

				this.particleShader.useProgram();
				gl.viewport(0, 0, 1, this.height / 2);
				gl.bindFramebuffer(gl.FRAMEBUFFER, this.particleFrameBuffer.frameBuffer);
				gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
				gl.enableVertexAttribArray(this.particleShader.location_particle);
				gl.bindBuffer(gl.ARRAY_BUFFER, this.particleBuffer);
				gl.vertexAttribPointer(this.particleShader.location_particle, this.particleBuffer.itemSize, gl.FLOAT, false, 0, 0);
				gl.enable(gl.BLEND);
				gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
				this.particleShader.set_time(uniforms.time);
				this.particleShader.set_height(this.height);
				gl.drawArrays(gl.POINTS, 0, particleCount);

				this.lastTime = this.inputs.time;
			}
			uniforms.particles = this.particleFrameBuffer.texture;

			parent(shader, model, uniforms, frameBuffer);
/*
				this.particleShader.useProgram();
				gl.viewport(0, 0, 1, 480);
				gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
//				gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
				gl.enableVertexAttribArray(this.particleShader.location_particle);
				gl.bindBuffer(gl.ARRAY_BUFFER, this.particleBuffer);
				gl.vertexAttribPointer(this.particleShader.location_particle, this.particleBuffer.itemSize, gl.FLOAT, false, 0, 0);
				gl.enable(gl.BLEND);
				gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
				this.particleShader.set_time(uniforms.time);
				this.particleShader.set_height(this.height);
				gl.drawArrays(gl.POINTS, 0, particleCount);
*/
		},
		inPlace: false,
		inputs: {
			source: {
				type: 'image',
				uniform: 'source',
				shaderDirty: false
			},
			time: {
				type: 'number',
				defaultValue: 0
			},
			distortion: {
				type: 'number',
				defaultValue: 0.1,
				min: 0,
				max: 1
			},
			verticalSync: {
				type: 'number',
				defaultValue: 0.1,
				min: 0,
				max: 1
			},
			lineSync: {
				type: 'number',
				uniform: 'lineSync',
				defaultValue: 0.2,
				min: 0,
				max: 1
			},
			scanlines: {
				type: 'number',
				uniform: 'scanlines',
				defaultValue: 0.3,
				min: 0,
				max: 1
			},
			bars: {
				type: 'number',
				uniform: 'bars',
				defaultValue: 0,
				min: 0,
				max: 1
			}
		},
		description: '',
		title: 'TV Glitch'
	};
}()) );

}(window));
<|endoftext|>


<commit_before>/* global describe it expect OT beforeEach */
const filters = require('../src/filters.js');
const filter = require('../src/filter.js')(filters.none);

describe('filter', () => {
  it('defines a setPublisher method', () => {
    expect(filter.setPublisher).toBeDefined();
  });

  it('defines a change method', () => {
    expect(filter.change).toBeDefined();
  });

  describe('OpenTok Publisher', () => {
    beforeEach(done => {
      const script = document.createElement('script');
      script.src = 'https://tbdev.tokbox.com/v2/js/opentok.js';
      script.type = 'text/javascript';
      script.onload = done;
      document.body.appendChild(script);
    });

    it('successfully publishes', done => {
      const publisher = OT.initPublisher(err => {
        expect(err).toBeFalsy();
        done();
      });
      filter.setPublisher(publisher);
    });

    it('lets you change the filter', done => {
      const publisher = OT.initPublisher(err => {
        expect(err).toBeFalsy();
        filter.change(filters.invert);
        done();
      });
      filter.setPublisher(publisher);
    });
  });
});
<commit_msg>Slight change to get travis to run<commit_after>/* global describe it expect OT beforeEach */
const filters = require('../src/filters.js');
const filter = require('../src/filter.js')(filters.none);

describe('filter', () => {
  it('defines a setPublisher method', () => {
    expect(filter.setPublisher).toBeDefined();
  });

  it('defines a change method', () => {
    expect(filter.change).toBeDefined();
  });

  describe('OpenTok Publisher', () => {
    beforeEach(done => {
      const script = document.createElement('script');
      script.src = 'https://tbdev.tokbox.com/v2/js/opentok.js';
      script.type = 'text/javascript';
      script.onload = done;
      document.body.appendChild(script);
    });

    it('successfully publishes', done => {
      const publisher = OT.initPublisher(err => {
        expect(err).toBeFalsy();
        done();
      });
      filter.setPublisher(publisher);
    });

    it('lets you change the filter', done => {
      const publisher = OT.initPublisher(err => {
        expect(err).toBeFalsy();
        filter.change(filters.invert);
        filter.change(filters.grayscale);
        done();
      });
      filter.setPublisher(publisher);
    });
  });
});
<|endoftext|>


<commit_before>//var L20n = process.env.L20N_COV
//  ? require('../../_build/cov/lib/l20n.js')
//  : require('../../lib/l20n.js');

var L20n = require('../../lib/l20n.js').L20n;
L20n.EventEmitter = require('../../lib/events.js').EventEmitter;
L20n.Parser = require('../../lib/parser.js').Parser;
L20n.Compiler = require('../../lib/compiler.js').Compiler;
L20n.Compiler = new L20n.Compiler(L20n.EventEmitter, L20n.Parser);
var http = require('http');
var path = require('path');
var fs = require('fs');

var env = {
  DEBUG: true,
  getURL: function getURL(url, async) {
    if (async === undefined) {
      async = true;
    }

    if (async) {
      var localhost = 'http://localhost:8357';
      if (url[0] == '/') {
        url = localhost + url;
      } else if (!/localhost:8357/.test(url)) {
        url = localhost + '/'+ url;
      }
    } else {
      if (!L20n.env.scenario) {
        throw "Define L20n.env.scenario for this scenario";
      }
      var url = 'file://'+__dirname+'/../fixtures/sets/' + L20n.env.scenario + url;
    }
    return url;
  },
  XMLHttpRequest: require("w3c-xmlhttprequest").XMLHttpRequest,
}

L20n.env = env;

// node's XHR doesn't support overrideMimeType; make it no-op for now
env.XMLHttpRequest.prototype.overrideMimeType = function() {};

function handleRequest(request, response) {
  var url = request.url.split('?')[0];
  var filePath = './tests/fixtures/sets/' + this.scenario + url;

  function serve(err) {
    if (err) {
      response.writeHead(err);
      response.end();
      return;
    }
    fs.exists(filePath, function(exists) {
      if (exists) {
        fs.readFile(filePath, function(error, content) {
          if (error) {
            response.writeHead(500);
            response.end();
          } else {
            response.writeHead(200, { 'Content-Type': 'plain/text' });
            response.end(content, 'utf-8');
          }
        });
      } else {
        response.writeHead(404);
        response.end();
      }
    });
  }

  if (this.rules[url]) {
    this.rules[url](serve);
  } else {
    serve();
  }
}

// The LOL files are located in:
// /tests/fixtures/sets/SCENARIO/locales/LOCALE/
//                              ^       ^
//                              |       |
//        this is the server root       |
//                                      from here the ctx methods are called
//
// This means all of the following will work:
//
//   ctx.addResource('en-US/base.lol');
//   ctx.addResource('/locales/en-US/base.lol');
//   ctx.addResource('../locales/en-US/base.lol');
//
// With `ctx.settings.locales` set:
//
//   ctx.addResource('l10n:{{ locale }}/base.lol');
//   ctx.addResource('l10n:/locales/{{ locale }}/base.lol');
//
// With `ctx.settings.schemes` set:
//
//   ctx.settings.schemes = [
//     '/locales/{{ locale }}/{{ resource }}.lol',
//     '{{ locale }}/{{ resource }}.lol',
//     '../locales/{{ locale }}/{{ resource }}.lol',
//   ];
//   ctx.addResource('l10n:base');
//
// Or even like so:
//
//   ctx.settings.schemes = [
//     '/locales/{{ locale }}/{{ app }}/{{ resource }}.lol',
//   ];
//   ctx.addResource('l10n:browser:base');

describe('L20n context', function(){
  var server;

  before(function() {
    server = http.createServer(handleRequest);
  });

  beforeEach(function() {
    server.listen(8357);
    server.rules = {};
  });

  afterEach(function() {
    server.close();
    L20n.env.scenario = null;
  });

  xdescribe('Hardcoded URL', function(){
    before(function() {
      server.scenario = 'no_imports';
    });
    it('works for en-US', function(done) {
      var ctx = L20n.getContext();
      ctx.addResource('en-US/a.lol');
      ctx.addEventListener('ready', function() {
        var value = ctx.get('a');
        value.should.equal('A (en-US)');
        done();
      });
      ctx.freeze();
    });
    it('works for pl', function(done) {
      var ctx = L20n.getContext();
      ctx.addResource('pl/a.lol');
      ctx.addEventListener('ready', function() {
        var value = ctx.get('a');
        value.should.equal('A (pl)');
        done();
      });
      ctx.freeze();
    });
    it('works with 300ms delay', function(done) {
      server.rules['/locales/en-US/a.lol'] = function(serve) {
        setTimeout(serve, 300);
      };
      var ctx = L20n.getContext();
      ctx.addResource('en-US/a.lol');
      ctx.addEventListener('ready', function() {
        var value = ctx.get('a');
        value.should.equal('A (en-US)');
        done();
      });
      ctx.freeze();
    });
    it('uses the default value if delay is 1000ms', function(done) {
      server.rules['/locales/en-US/a.lol'] = function(serve) {
        setTimeout(serve, 1000);
      };
      var ctx = L20n.getContext();
      ctx.addResource('en-US/a.lol');
      ctx.addEventListener('ready', function() {
        var values = ctx.get('a');
        value.should.equal('A');
        done();
      });
      ctx.freeze();
      ctx.getMany(['a'], {}).then(
        function() {},
        function() {
          done();
        });
    });
  });

  xdescribe('Simple scheme URL', function(){
    before(function() {
      server.scenario = 'no_imports';
    });
    it('works for en-US for absolute URLs', function(done) {
      var ctx = L20n.getContext();
      ctx.settings.locales = ['en-US'];
      ctx.addResource('l10n:/locales/{{ locale }}/a.lol');
      ctx.addEventListener('ready', function() {
        var value = ctx.get('a');
        value.should.equal('A (en-US)');
        done();
      });
      ctx.freeze();
    });
  });

  describe('Complex scheme URL', function(){
    before(function() {
      server.scenario = 'no_imports';
    });
    it('works when the first URL is 200', function(done) {
      var ctx = L20n.getContext();
      ctx.settings.locales = ['en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:a');
      ctx.freeze();
      ctx.get('a', {}, function(value) {
        value.should.equal('A (en-US)');
        done();
      }, 'A');
    });
    it('uses the second URL if the first one cannot be fetched', function(done) {
      var ctx = L20n.getContext();
      ctx.settings.locales = ['en-US'];
      ctx.settings.schemes = [
        '/wrongdir/{{ locale }}/{{ resource }}.lol',
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:a');
      ctx.freeze();
      ctx.get('a', {}, function(value) {
        value.should.equal('A (en-US)');
        done();
      }, 'A');
    });
  });

  xdescribe('Locale fallback', function(){
    before(function() {
      server.scenario = 'no_imports';
    });
    it('uses en-US when the first locale is not integral', function(done) {
      server.rules['/locales/pl/a.lol'] = function(serve) {
        serve(404);
      };
      var ctx = L20n.getContext();
      ctx.settings.locales = ['pl', 'en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:a');
      ctx.freeze();
      ctx.get('a', {}, function(value) {
        value.should.equal('A (en-US)');
        done();
      }, 'A');
    });
    // add a testcase for when none of the locales is integral
  });

  xdescribe('Entity fallback', function(){
    before(function() {
      server.scenario = 'no_imports';
      L20n.env.scenario = 'no_imports';
    });
    it('uses en-US translation when the Polish one is missing', function(done) {
      var ctx = L20n.getContext();
      ctx.settings.locales = ['pl', 'en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:a');
      ctx.freeze();
      ctx.get('b', {}, function(value) {
        value.should.equal('B (en-US)');
        done();
      }, 'B');
    });
  });

  xdescribe('Simple import', function(){
    before(function() {
      server.scenario = 'simple_import';
    });
    it('works', function(done) {
      var ctx = L20n.getContext();
      ctx.settings.locales = ['pl', 'en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:a');
      ctx.freeze();
      ctx.get('c', {}, function(value) {
        value.should.equal('C (pl)');
        done();
      }, 'C');
    });
    it('when 404, ctx fallbacks to next locale', function(done) {
      server.rules['/locales/pl/c.lol'] = function(serve) {
        serve(404);
      };
      var ctx = L20n.getContext();
      ctx.settings.locales = ['pl', 'en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:a');
      ctx.freeze();
      ctx.get('c', {}, function(value) {
        value.should.equal('C (en-US)');
        done();
      }, 'C');
    });
  });

  xdescribe('Recursive import', function(){
    before(function() {
      server.scenario = 'recursive_imports';
    });
    it('works', function(done) {
      var ctx = L20n.getContext();
      ctx.settings.locales = ['pl', 'en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addEventListener('error', function(e) {
        e.code.should.equal(L20n.NESTED_ERROR | L20n.INTEGRITY_ERROR);
      });
      ctx.addEventListener('ready', function(e) {
        ctx.get('a').should.equal('A (en-US)')
        ctx.get('c').should.equal('C (en-US)')
        done();
      });
      ctx.addResource('l10n:a')
      ctx.freeze();
    })
  });

  xdescribe('Duplicate import', function(){
    before(function() {
      server.scenario = 'duplicate_imports';
    });
    it('works', function(done) {
      var ctx = L20n.getContext();
      ctx.settings.locales = ['pl', 'en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:a');
      ctx.freeze();
      ctx.get('c', {}, function(value) {
        value.should.equal('C (pl)');
        done();
      }, 'C');
    });
    it('when 404, fallbacks to next locale', function(done) {
      server.rules['/locales/pl/c.lol'] = function(serve) {
        serve(404);
      };
      var ctx = L20n.getContext();
      ctx.settings.locales = ['pl', 'en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:a');
      ctx.freeze();
      ctx.get('c', {}, function(value) {
        value.should.equal('C (en-US)');
        done();
      }, 'C');
    });
    it('works when the imported res is addResource\'d directly to the ctx first', function(done) {
      var ctx = L20n.getContext();
      ctx.settings.locales = ['pl', 'en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:c');
      ctx.addResource('l10n:a');
      ctx.freeze();
      ctx.get('c', {}, function(value) {
        value.should.equal('C (pl)');
        done();
      }, 'C');
    });
  });

  xdescribe('Broken lol', function(){
    before(function() {
      server.scenario = 'broken_lol';
      L20n.env.scenario = 'broken_lol';
    });
    it('works', function(done) {
      var ctx = L20n.getContext();
      ctx.settings.locales = ['pl', 'en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:a');
      ctx.freeze();
      ctx.addEventListener('error', function(e) {
        console.log(e)
      });
      ctx.addEventListener('ready', function() {
        ctx.get('a').should.equal('A (pl)')
        ctx.get('c').should.equal('C (pl)')
        ctx.get('b').should.equal('B (en-US)')
        try {
          var x = ctx.get('d');
          // that's not what should happen in this case...
          // and it'll work only once we fix the sync file loading here
        } catch (e) {
          if (e == "No valid locales were available.") {
            done();
          }
        }
      });
    })
  });

  // TODO: test fallback on parsing errors
  // TODO: test that two fallbacks invalidate ctx only once

});

<commit_msg>many changes to tests because of changes in API<commit_after>//var L20n = process.env.L20N_COV
//  ? require('../../_build/cov/lib/l20n.js')
//  : require('../../lib/l20n.js');

var L20n = require('../../lib/l20n.js').L20n;
L20n.EventEmitter = require('../../lib/events.js').EventEmitter;
L20n.Parser = require('../../lib/parser.js').Parser;
L20n.Compiler = require('../../lib/compiler.js').Compiler;
L20n.Compiler = new L20n.Compiler(L20n.EventEmitter, L20n.Parser);
var http = require('http');
var path = require('path');
var fs = require('fs');

var env = {
  DEBUG: true,
  getURL: function getURL(url, async) {
    if (async === undefined) {
      async = true;
    }

    if (async) {
      var localhost = 'http://localhost:8357';
      if (url[0] == '/') {
        url = localhost + url;
      } else if (!/localhost:8357/.test(url)) {
        url = localhost + '/'+ url;
      }
    } else {
      if (!L20n.env.scenario) {
        throw "Define L20n.env.scenario for this scenario";
      }
      var url = 'file://'+__dirname+'/../fixtures/sets/' + L20n.env.scenario + url;
    }
    return url;
  },
  XMLHttpRequest: require("xmlhttprequest").XMLHttpRequest,
}

L20n.env = env;

// node's XHR doesn't support overrideMimeType; make it no-op for now
env.XMLHttpRequest.prototype.overrideMimeType = function() {};

function handleRequest(request, response) {
  var url = request.url.split('?')[0];
  var filePath = './tests/fixtures/sets/' + this.scenario + url;

  function serve(err) {
    if (err) {
      response.writeHead(err);
      response.end();
      return;
    }
    fs.exists(filePath, function(exists) {
      if (exists) {
        fs.readFile(filePath, function(error, content) {
          if (error) {
            response.writeHead(500);
            response.end();
          } else {
            response.writeHead(200, { 'Content-Type': 'plain/text' });
            response.end(content, 'utf-8');
          }
        });
      } else {
        response.writeHead(404);
        response.end();
      }
    });
  }

  if (this.rules[url]) {
    this.rules[url](serve);
  } else {
    serve();
  }
}

// The LOL files are located in:
// /tests/fixtures/sets/SCENARIO/locales/LOCALE/
//                              ^       ^
//                              |       |
//        this is the server root       |
//                                      from here the ctx methods are called
//
// This means all of the following will work:
//
//   ctx.addResource('en-US/base.lol');
//   ctx.addResource('/locales/en-US/base.lol');
//   ctx.addResource('../locales/en-US/base.lol');
//
// With `ctx.settings.locales` set:
//
//   ctx.addResource('l10n:{{ locale }}/base.lol');
//   ctx.addResource('l10n:/locales/{{ locale }}/base.lol');
//
// With `ctx.settings.schemes` set:
//
//   ctx.settings.schemes = [
//     '/locales/{{ locale }}/{{ resource }}.lol',
//     '{{ locale }}/{{ resource }}.lol',
//     '../locales/{{ locale }}/{{ resource }}.lol',
//   ];
//   ctx.addResource('l10n:base');
//
// Or even like so:
//
//   ctx.settings.schemes = [
//     '/locales/{{ locale }}/{{ app }}/{{ resource }}.lol',
//   ];
//   ctx.addResource('l10n:browser:base');

describe('L20n context', function(){
  var server;

  before(function() {
    server = http.createServer(handleRequest);
  });

  beforeEach(function() {
    server.listen(8357);
    server.rules = {};
  });

  afterEach(function() {
    server.close();
    L20n.env.scenario = null;
  });

  xdescribe('Hardcoded URL', function(){
    before(function() {
      server.scenario = 'no_imports';
    });
    it('works for en-US', function(done) {
      var ctx = L20n.getContext();
      ctx.addResource('locales/en-US/a.lol');
      ctx.addEventListener('ready', function() {
        var value = ctx.get('a');
        value.should.equal('A (en-US)');
        done();
      });
      ctx.freeze();
    });
    it('works for pl', function(done) {
      var ctx = L20n.getContext();
      ctx.addResource('locales/pl/a.lol');
      ctx.addEventListener('ready', function() {
        var value = ctx.get('a');
        value.should.equal('A (pl)');
        done();
      });
      ctx.freeze();
    });
    it('works with 300ms delay', function(done) {
      server.rules['/locales/en-US/a.lol'] = function(serve) {
        setTimeout(serve, 300);
      };
      var ctx = L20n.getContext();
      ctx.addResource('locales/en-US/a.lol');
      ctx.addEventListener('ready', function() {
        var value = ctx.get('a');
        value.should.equal('A (en-US)');
        done();
      });
      ctx.freeze();
    });
    it('uses the default value if delay is 1000ms', function(done) {
      server.rules['/locales/en-US/a.lol'] = function(serve) {
        setTimeout(serve, 1000);
      };
      var ctx = L20n.getContext();
      ctx.addResource('locales/en-US/a.lol');
      ctx.addEventListener('ready', function() {
        var values = ctx.get('a');
        value.should.equal('A');
        done();
      });
      ctx.freeze();
      ctx.getMany(['a'], {}).then(
        function() {},
        function() {
          done();
        });
    });
  });

  xdescribe('Simple scheme URL', function(){
    before(function() {
      server.scenario = 'no_imports';
    });
    it('works for en-US for absolute URLs', function(done) {
      var ctx = L20n.getContext();
      ctx.settings.locales = ['en-US'];
      ctx.addResource('l10n:/locales/{{ locale }}/a.lol');
      ctx.addEventListener('ready', function() {
        var value = ctx.get('a');
        value.should.equal('A (en-US)');
        done();
      });
      ctx.freeze();
    });
  });

  xdescribe('Complex scheme URL', function(){
    before(function() {
      server.scenario = 'no_imports';
    });
    it('works when the first URL is 200', function(done) {
      var ctx = L20n.getContext();
      ctx.settings.locales = ['en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:a');
      ctx.addEventListener('ready', function() {
        var value = ctx.get('a');
        value.should.equal('A (en-US)');
        done();
      });
      ctx.freeze();
    });
    it('uses the second URL if the first one cannot be fetched', function(done) {
      var ctx = L20n.getContext();
      ctx.settings.locales = ['en-US'];
      ctx.settings.schemes = [
        '/wrongdir/{{ locale }}/{{ resource }}.lol',
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:a');
      ctx.addEventListener('ready', function() {
        var value = ctx.get('a');
        value.should.equal('A (en-US)');
        done();
      });
      ctx.freeze();
    });
  });

  xdescribe('Locale fallback', function(){
    before(function() {
      server.scenario = 'no_imports';
      L20n.env.scenario = 'no_imports';
    });
    it('uses en-US when the first locale is not integral', function(done) {
      server.rules['/locales/pl/a.lol'] = function(serve) {
        serve(404);
      };
      var ctx = L20n.getContext();
      ctx.settings.locales = ['pl', 'en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:a');
      ctx.addEventListener('ready', function() {
        var value = ctx.get('a');
        value.should.equal('A (en-US)');
        done();
      });
      ctx.freeze();
    });
    // add a testcase for when none of the locales is integral
  });

  xdescribe('Entity fallback', function(){
    before(function() {
      server.scenario = 'no_imports';
      L20n.env.scenario = 'no_imports';
    });
    it('uses en-US translation when the Polish one is missing', function(done) {
      var ctx = L20n.getContext();
      ctx.settings.locales = ['pl', 'en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:a');
      ctx.addEventListener('ready', function() {
        var value = ctx.get('b');
        value.should.equal('B (en-US)');
        done();
      });
      ctx.freeze();
    });
  });

  xdescribe('Simple import', function(){
    before(function() {
      server.scenario = 'simple_import';
    });
    it('works', function(done) {
      var ctx = L20n.getContext();
      ctx.settings.locales = ['pl', 'en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:a');
      ctx.addEventListener('ready', function() {
        var value = ctx.get('c');
        value.should.equal('C (pl)');
        done();
      });
      ctx.freeze();
    });
    xit('when 404, ctx fallbacks to next locale', function(done) {
      server.rules['/locales/pl/c.lol'] = function(serve) {
        serve(404);
      };
      var ctx = L20n.getContext();
      ctx.settings.locales = ['pl', 'en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:a');
      ctx.freeze();
      ctx.get('c', {}, function(value) {
        value.should.equal('C (en-US)');
        done();
      }, 'C');
    });
  });

  xdescribe('Recursive import', function(){
    before(function() {
      server.scenario = 'recursive_imports';
    });
    it('works', function(done) {
      var ctx = L20n.getContext();
      ctx.settings.locales = ['pl', 'en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addEventListener('error', function(e) {
        e.code.should.equal(L20n.NESTED_ERROR | L20n.INTEGRITY_ERROR);
      });
      ctx.addEventListener('ready', function(e) {
        ctx.get('a').should.equal('A (pl)')
        ctx.get('c').should.equal('C (pl)')
        done();
      });
      ctx.addResource('l10n:a')
      ctx.freeze();
    })
  });

  xdescribe('Duplicate import', function(){
    before(function() {
      server.scenario = 'duplicate_imports';
    });
    it('works', function(done) {
      var ctx = L20n.getContext();
      ctx.settings.locales = ['pl', 'en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:a');
      ctx.freeze();
      ctx.get('c', {}, function(value) {
        value.should.equal('C (pl)');
        done();
      }, 'C');
    });
    it('when 404, fallbacks to next locale', function(done) {
      server.rules['/locales/pl/c.lol'] = function(serve) {
        serve(404);
      };
      var ctx = L20n.getContext();
      ctx.settings.locales = ['pl', 'en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:a');
      ctx.freeze();
      ctx.get('c', {}, function(value) {
        value.should.equal('C (en-US)');
        done();
      }, 'C');
    });
    it('works when the imported res is addResource\'d directly to the ctx first', function(done) {
      var ctx = L20n.getContext();
      ctx.settings.locales = ['pl', 'en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:c');
      ctx.addResource('l10n:a');
      ctx.freeze();
      ctx.get('c', {}, function(value) {
        value.should.equal('C (pl)');
        done();
      }, 'C');
    });
  });

  xdescribe('Broken lol', function(){
    before(function() {
      server.scenario = 'broken_lol';
      L20n.env.scenario = 'broken_lol';
    });
    it('works', function(done) {
      var ctx = L20n.getContext();
      ctx.settings.locales = ['pl', 'en-US'];
      ctx.settings.schemes = [
        '/locales/{{ locale }}/{{ resource }}.lol'
      ];
      ctx.addResource('l10n:a');
      ctx.freeze();
      ctx.addEventListener('error', function(e) {
        console.log(e)
      });
      ctx.addEventListener('ready', function() {
        ctx.get('a').should.equal('A (pl)')
        ctx.get('c').should.equal('C (pl)')
        ctx.get('b').should.equal('B (en-US)')
        try {
          var x = ctx.get('d');
          // that's not what should happen in this case...
          // and it'll work only once we fix the sync file loading here
        } catch (e) {
          if (e == "No valid locales were available.") {
            done();
          }
        }
      });
    })
  });

  // TODO: test fallback on parsing errors
  // TODO: test that two fallbacks invalidate ctx only once

});

<|endoftext|>


<commit_before>/*
 * Tests for the SystemSettingsHandler
 *
 * Copyright 2015 Raising the Floor - International
 *
 * Licensed under the New BSD license. You may not use this file except in
 * compliance with this License.
 *
 * The research leading to these results has received funding from the European Union's
 * Seventh Framework Programme (FP7/2007-2013)
 * under grant agreement no. 289016.
 *
 * You may obtain a copy of the License at
 * https://github.com/GPII/universal/blob/master/LICENSE.txt
 */

"use strict";

var fluid = require("gpii-universal");

var jqUnit = fluid.require("node-jqunit");
var gpii = fluid.registerNamespace("gpii");

fluid.require("%gpii-windows");

require("../src/systemSettingsHandler.js");

fluid.registerNamespace("gpii.tests.windows.systemSettingsHandler");

var teardowns = [];
jqUnit.module("gpii.tests.windows.systemSettingsHandler", {
    setup: function () {
    },
    teardown: function () {
        while (teardowns.length) {
            teardowns.pop()();
        }
    }
});

gpii.tests.FALSEY = fluid.makeMarker("FALSEY");

gpii.tests.windows.systemSettingsHandler.executeHelperTests = fluid.freezeRecursive([
    {
        input: [],
        expect: []
    },
    {
        input: [{}],
        expect: [{isError: true}]
    },
    {
        input: [{}, {}],
        expect: [{isError: true}, {isError: true}]
    },
    {
        input: [{"badField": "hi"}],
        expect: [{isError: true}]
    },
    {
        input: [{"settingID": null}],
        expect: [{isError: true}]
    },
    {
        input: [{"settingID": "SystemSettings_Accessibility_Keyboard_IsUnderlineShortcutEnabled"}],
        expect: [{isError: true}]
    },
    {
        input: [{"method": "unknownMethod"}],
        expect: [{isError: true}]
    },
    {
        input: [{"settingID": "unknownValue", "method": "unknownMethod"}],
        expect: [{isError: true}]
    },
    {
        input: [
            {"settingID": "SystemSettings_Accessibility_Keyboard_WarningEnabled", "method": "badMethod"}
        ],
        expect: [{isError: true}]
    },
    {
        // Get the value.
        input: [
            {
                "settingID": "SystemSettings_Accessibility_Keyboard_WarningEnabled",
                "method": "GetValue"
            }
        ],
        expect: [{returnValue: false, isError: gpii.tests.FALSEY}]
    },
    {
        // Set the value, returns the previous value.
        input: [
            {
                "settingID": "SystemSettings_Accessibility_Keyboard_WarningEnabled",
                "method": "SetValue",
                "parameters": [true]
            }
        ],
        expect: [{returnValue: false, isError: gpii.tests.FALSEY}]
    },
    {
        // Get the new value.
        input: [
            {
                "settingID": "SystemSettings_Accessibility_Keyboard_WarningEnabled",
                "method": "GetValue"
            }
        ],
        expect: [{returnValue: true, isError: gpii.tests.FALSEY}]
    },
    {
        // Set the value back.
        input: [
            {
                "settingID": "SystemSettings_Accessibility_Keyboard_WarningEnabled",
                "method": "SetValue",
                "parameters": [false]
            }
        ],
        expect: [{returnValue: true, isError: gpii.tests.FALSEY}]
    },
    {
        // Get the value.
        input: [
            {
                "settingID": "SystemSettings_Accessibility_Keyboard_WarningEnabled",
                "method": "GetValue"
            }
        ],
        expect: [{returnValue: false, isError: gpii.tests.FALSEY}]
    },
    {
        // Set it to the same value.
        input: [
            {
                "settingID": "SystemSettings_Accessibility_Keyboard_WarningEnabled",
                "method": "SetValue",
                "parameters": [false]
            }
        ],
        expect: [{returnValue: false, isError: gpii.tests.FALSEY}]
    },
    {
        // Get the value.
        input: [
            {
                "settingID": "SystemSettings_Accessibility_Keyboard_WarningEnabled",
                "method": "GetValue"
            }
        ],
        expect: [{returnValue: false, isError: gpii.tests.FALSEY}]
    }
]);

gpii.tests.windows.systemSettingsHandler.apiTests = fluid.freezeRecursive([
    {
        func: "get",
        input: {
            "test.windows.systemSettingsHandler": [{
                settings: {
                    "SystemSettings_Accessibility_Keyboard_WarningEnabled": {}
                }
            }]
        },
        expect: {
            "test.windows.systemSettingsHandler": [{
                settings: {
                    "SystemSettings_Accessibility_Keyboard_WarningEnabled": {
                        "value": false
                    }
                }
            }]
        }
    },
    {
        func: "set",
        input: {
            "test.windows.systemSettingsHandler": [{
                settings: {
                    "SystemSettings_Accessibility_Keyboard_WarningEnabled": {
                        "value": true
                    }
                }
            }]
        },
        expect: {
            "test.windows.systemSettingsHandler": [{
                settings: {
                    "SystemSettings_Accessibility_Keyboard_WarningEnabled": {
                        "oldValue": {
                            "value": false
                        },
                        "newValue": {
                            "value": true
                        }
                    }
                }
            }]
        }
    },
    {
        func: "get",
        input: {
            "test.windows.systemSettingsHandler": [{
                settings: {
                    "SystemSettings_Accessibility_Keyboard_WarningEnabled": {},
                    "SystemSettings_Taskbar_Location": {}
                }
            }]
        },
        expect: {
            "test.windows.systemSettingsHandler": [{
                settings: {
                    "SystemSettings_Accessibility_Keyboard_WarningEnabled": {
                        "value": true
                    },
                    "SystemSettings_Taskbar_Location": {
                        "value": 3
                    }
                }
            }]
        }
    },
    {
        func: "set",
        input: {
            "test.windows.systemSettingsHandler": [{
                settings: {
                    "SystemSettings_Accessibility_Keyboard_WarningEnabled": {
                        "value": false
                    },
                    "SystemSettings_Taskbar_Location": {
                        "value": 3
                    }
                }
            }]
        },
        expect: {
            "test.windows.systemSettingsHandler": [{
                settings: {
                    "SystemSettings_Accessibility_Keyboard_WarningEnabled": {
                        "oldValue": {
                            "value": true
                        },
                        "newValue": {
                            "value": false
                        }
                    },
                    "SystemSettings_Taskbar_Location": {
                        "oldValue": {
                            "value": 3
                        },
                        "newValue": {
                            "value": 3
                        }
                    }
                }
            }]
        }
    }
]);

/**
 * Check if all properties of expected are also in subject and are equal, ignoring any extra ones in subject.
 *
 * A property's value in the expected object can be the expected value, fluid.VALUE to match any value (just check if
 * the property exists), or fluid.NO_VALUE to check the property doesn't exist, or FALSEY marker for any false-like
 * value.
 *
 * @param {Object} subject The object to check against
 * @param {Object} expected The object containing the values to check for.
 * @param {Number} maxDepth [Optional] How deep to check.
 * @return {Boolean} true if there's a match.
 */
gpii.tests.windows.systemSettingsHandler.deepMatch = function (subject, expected, maxDepth) {
    var match = false;
    if (maxDepth < 0) {
        return false;
    } else if (!maxDepth && maxDepth !== 0) {
        maxDepth = fluid.strategyRecursionBailout;
    }

    if (!subject) {
        return subject === expected;
    }

    if (Array.isArray(subject) && Array.isArray(expected)) {
        if (subject.length !== expected.length) {
            return false;
        } else if (subject.length === 0) {
            return true;
        }
    }

    for (var prop in expected) {
        if (expected.hasOwnProperty(prop)) {
            var exp = expected[prop];
            if (fluid.isMarker(exp, fluid.VALUE)) {
                // match any value
                match = subject.hasOwnProperty(prop);
            } else if (fluid.isMarker(exp, fluid.NO_VALUE)) {
                // match no value
                match = !subject.hasOwnProperty(prop);
            } else if (fluid.isMarker(exp, gpii.tests.FALSEY)) {
                // match falsey
                match = !subject[prop];
            } else if (fluid.isPrimitive(exp)) {
                match = subject[prop] === exp;
            } else {
                match = gpii.tests.windows.systemSettingsHandler.deepMatch(subject[prop], exp, maxDepth - 1);
            }
            if (!match) {
                break;
            }
        }
    }

    return match;
};
jqUnit.asyncTest("Testing executeHelper", function () {

    var tests = gpii.tests.windows.systemSettingsHandler.executeHelperTests;

    jqUnit.expect(tests.length * 3);

    // Make sure the "SystemSettings_Accessibility_Keyboard_WarningEnabled" setting is in a known state.
    // ("Display a warning message when turning a setting on with a shortcut")
    var oldValue = gpii.windows.readRegistryKey("HKEY_CURRENT_USER", "Control Panel\\Accessibility",
        "Warning Sounds", "REG_DWORD");
    if (oldValue.statusCode === 200) {
        teardowns.push(function () {
            gpii.windows.writeRegistryKey("HKEY_CURRENT_USER", "Control Panel\\Accessibility",
                "Warning Sounds", oldValue.value, "REG_DWORD");
        });
        gpii.windows.writeRegistryKey("HKEY_CURRENT_USER", "Control Panel\\Accessibility",
            "Warning Sounds", 0, "REG_DWORD");
    }

    var runTest = function (testIndex) {
        if (testIndex >= tests.length) {
            jqUnit.start();
            return;
        }

        var test = tests[testIndex];

        fluid.log(test.input);
        var promise = gpii.windows.executeHelper(test.input);

        jqUnit.assertNotNull("executeHelper shouldn't return null", promise);
        jqUnit.assertTrue("executeHelper should return a promise", fluid.isPromise(promise));

        promise.then(function (value) {
            fluid.log(value);
            var match = gpii.tests.windows.systemSettingsHandler.deepMatch(value, test.expect);
            jqUnit.assertTrue("resolved value needs to match the expected.", match);
            runTest(testIndex + 1);
        }, fluid.fail);

    };
    runTest(0);
});

jqUnit.asyncTest("Testing system settings handler API", function () {

    var tests = gpii.tests.windows.systemSettingsHandler.apiTests;
    jqUnit.expect(tests.length * 1);

    // Make sure the "SystemSettings_Accessibility_Keyboard_WarningEnabled" setting is in a known state.
    // ("Display a warning message when turning a setting on with a shortcut")
    var oldValue = gpii.windows.readRegistryKey("HKEY_CURRENT_USER", "Control Panel\\Accessibility",
        "Warning Sounds", "REG_DWORD");
    if (oldValue.statusCode === 200) {
        teardowns.push(function () {
            gpii.windows.writeRegistryKey("HKEY_CURRENT_USER", "Control Panel\\Accessibility",
                "Warning Sounds", oldValue.value, "REG_DWORD");
        });
        gpii.windows.writeRegistryKey("HKEY_CURRENT_USER", "Control Panel\\Accessibility",
            "Warning Sounds", 0, "REG_DWORD");
    }

    var runTest = function (testIndex) {
        if (testIndex >= tests.length) {
            jqUnit.start();
            return;
        }

        var test = tests[testIndex];
        gpii.windows.systemSettingsHandler[test.func](test.input).then(function (value) {
            jqUnit.assertDeepEq("resolve", test.expect, value);
            runTest(testIndex + 1);
        });
    };
    runTest(0);

});
<commit_msg>GPII-3130: Added new needed payload options to systemSettingsHandler unit tests<commit_after>/*
 * Tests for the SystemSettingsHandler
 *
 * Copyright 2015 Raising the Floor - International
 *
 * Licensed under the New BSD license. You may not use this file except in
 * compliance with this License.
 *
 * The research leading to these results has received funding from the European Union's
 * Seventh Framework Programme (FP7/2007-2013)
 * under grant agreement no. 289016.
 *
 * You may obtain a copy of the License at
 * https://github.com/GPII/universal/blob/master/LICENSE.txt
 */

"use strict";

var fluid = require("gpii-universal");

var jqUnit = fluid.require("node-jqunit");
var gpii = fluid.registerNamespace("gpii");

fluid.require("%gpii-windows");

require("../src/systemSettingsHandler.js");

fluid.registerNamespace("gpii.tests.windows.systemSettingsHandler");

var teardowns = [];
jqUnit.module("gpii.tests.windows.systemSettingsHandler", {
    setup: function () {
    },
    teardown: function () {
        while (teardowns.length) {
            teardowns.pop()();
        }
    }
});

gpii.tests.FALSEY = fluid.makeMarker("FALSEY");

gpii.tests.windows.systemSettingsHandler.executeHelperTests = fluid.freezeRecursive([
    {
        input: [],
        expect: []
    },
    {
        input: [{}],
        expect: [{isError: true}]
    },
    {
        input: [{}, {}],
        expect: [{isError: true}, {isError: true}]
    },
    {
        input: [{"badField": "hi"}],
        expect: [{isError: true}]
    },
    {
        input: [{"settingID": null}],
        expect: [{isError: true}]
    },
    {
        input: [{"settingID": "SystemSettings_Accessibility_Keyboard_IsUnderlineShortcutEnabled"}],
        expect: [{isError: true}]
    },
    {
        input: [{"method": "unknownMethod"}],
        expect: [{isError: true}]
    },
    {
        input: [{"settingID": "unknownValue", "method": "unknownMethod"}],
        expect: [{isError: true}]
    },
    {
        input: [
            {"settingID": "SystemSettings_Accessibility_Keyboard_WarningEnabled", "method": "badMethod"}
        ],
        expect: [{isError: true}]
    },
    {
        // Get the value.
        input: [
            {
                "settingID": "SystemSettings_Accessibility_Keyboard_WarningEnabled",
                "method": "GetValue",
                "async": true
            }
        ],
        expect: [{returnValue: false, isError: gpii.tests.FALSEY}]
    },
    {
        // Set the value, returns the previous value.
        input: [
            {
                "settingID": "SystemSettings_Accessibility_Keyboard_WarningEnabled",
                "method": "SetValue",
                "parameters": [true],
                "async": true
            }
        ],
        expect: [{returnValue: false, isError: gpii.tests.FALSEY}]
    },
    {
        // Get the new value.
        input: [
            {
                "settingID": "SystemSettings_Accessibility_Keyboard_WarningEnabled",
                "method": "GetValue",
                "async": true
            }
        ],
        expect: [{returnValue: true, isError: gpii.tests.FALSEY}]
    },
    {
        // Set the value back.
        input: [
            {
                "settingID": "SystemSettings_Accessibility_Keyboard_WarningEnabled",
                "method": "SetValue",
                "parameters": [false],
                "async": true
            }
        ],
        expect: [{returnValue: true, isError: gpii.tests.FALSEY}]
    },
    {
        // Get the value.
        input: [
            {
                "settingID": "SystemSettings_Accessibility_Keyboard_WarningEnabled",
                "method": "GetValue",
                "async": true
            }
        ],
        expect: [{returnValue: false, isError: gpii.tests.FALSEY}]
    },
    {
        // Set it to the same value.
        input: [
            {
                "settingID": "SystemSettings_Accessibility_Keyboard_WarningEnabled",
                "method": "SetValue",
                "parameters": [false],
                "async": true
            }
        ],
        expect: [{returnValue: false, isError: gpii.tests.FALSEY}]
    },
    {
        // Get the value.
        input: [
            {
                "settingID": "SystemSettings_Accessibility_Keyboard_WarningEnabled",
                "method": "GetValue",
                "async": true
            }
        ],
        expect: [{returnValue: false, isError: gpii.tests.FALSEY}]
    }
]);

gpii.tests.windows.systemSettingsHandler.apiTests = fluid.freezeRecursive([
    {
        func: "get",
        input: {
            "test.windows.systemSettingsHandler": [{
                settings: {
                    "SystemSettings_Accessibility_Keyboard_WarningEnabled": {}
                },
                options: {
                    Async: true
                }
            }]
        },
        expect: {
            "test.windows.systemSettingsHandler": [{
                settings: {
                    "SystemSettings_Accessibility_Keyboard_WarningEnabled": {
                        "value": false
                    }
                }
            }]
        }
    },
    {
        func: "set",
        input: {
            "test.windows.systemSettingsHandler": [{
                settings: {
                    "SystemSettings_Accessibility_Keyboard_WarningEnabled": {
                        "value": true
                    }
                },
                options: {
                    Async: true
                }
            }]
        },
        expect: {
            "test.windows.systemSettingsHandler": [{
                settings: {
                    "SystemSettings_Accessibility_Keyboard_WarningEnabled": {
                        "oldValue": {
                            "value": false
                        },
                        "newValue": {
                            "value": true
                        }
                    }
                }
            }]
        }
    },
    {
        func: "get",
        input: {
            "test.windows.systemSettingsHandler": [{
                settings: {
                    "SystemSettings_Accessibility_Keyboard_WarningEnabled": {},
                    "SystemSettings_Taskbar_Location": {}
                },
                options: {
                    Async: true
                }
            }]
        },
        expect: {
            "test.windows.systemSettingsHandler": [{
                settings: {
                    "SystemSettings_Accessibility_Keyboard_WarningEnabled": {
                        "value": true
                    },
                    "SystemSettings_Taskbar_Location": {
                        "value": 3
                    }
                }
            }]
        }
    },
    {
        func: "set",
        input: {
            "test.windows.systemSettingsHandler": [{
                settings: {
                    "SystemSettings_Accessibility_Keyboard_WarningEnabled": {
                        "value": false
                    },
                    "SystemSettings_Taskbar_Location": {
                        "value": 3
                    }
                },
                options: {
                    Async: true
                }
            }]
        },
        expect: {
            "test.windows.systemSettingsHandler": [{
                settings: {
                    "SystemSettings_Accessibility_Keyboard_WarningEnabled": {
                        "oldValue": {
                            "value": true
                        },
                        "newValue": {
                            "value": false
                        }
                    },
                    "SystemSettings_Taskbar_Location": {
                        "oldValue": {
                            "value": 3
                        },
                        "newValue": {
                            "value": 3
                        }
                    }
                }
            }]
        }
    }
]);

/**
 * Check if all properties of expected are also in subject and are equal, ignoring any extra ones in subject.
 *
 * A property's value in the expected object can be the expected value, fluid.VALUE to match any value (just check if
 * the property exists), or fluid.NO_VALUE to check the property doesn't exist, or FALSEY marker for any false-like
 * value.
 *
 * @param {Object} subject The object to check against
 * @param {Object} expected The object containing the values to check for.
 * @param {Number} maxDepth [Optional] How deep to check.
 * @return {Boolean} true if there's a match.
 */
gpii.tests.windows.systemSettingsHandler.deepMatch = function (subject, expected, maxDepth) {
    var match = false;
    if (maxDepth < 0) {
        return false;
    } else if (!maxDepth && maxDepth !== 0) {
        maxDepth = fluid.strategyRecursionBailout;
    }

    if (!subject) {
        return subject === expected;
    }

    if (Array.isArray(subject) && Array.isArray(expected)) {
        if (subject.length !== expected.length) {
            return false;
        } else if (subject.length === 0) {
            return true;
        }
    }

    for (var prop in expected) {
        if (expected.hasOwnProperty(prop)) {
            var exp = expected[prop];
            if (fluid.isMarker(exp, fluid.VALUE)) {
                // match any value
                match = subject.hasOwnProperty(prop);
            } else if (fluid.isMarker(exp, fluid.NO_VALUE)) {
                // match no value
                match = !subject.hasOwnProperty(prop);
            } else if (fluid.isMarker(exp, gpii.tests.FALSEY)) {
                // match falsey
                match = !subject[prop];
            } else if (fluid.isPrimitive(exp)) {
                match = subject[prop] === exp;
            } else {
                match = gpii.tests.windows.systemSettingsHandler.deepMatch(subject[prop], exp, maxDepth - 1);
            }
            if (!match) {
                break;
            }
        }
    }

    return match;
};
jqUnit.asyncTest("Testing executeHelper", function () {

    var tests = gpii.tests.windows.systemSettingsHandler.executeHelperTests;

    jqUnit.expect(tests.length * 3);

    // Make sure the "SystemSettings_Accessibility_Keyboard_WarningEnabled" setting is in a known state.
    // ("Display a warning message when turning a setting on with a shortcut")
    var oldValue = gpii.windows.readRegistryKey("HKEY_CURRENT_USER", "Control Panel\\Accessibility",
        "Warning Sounds", "REG_DWORD");
    if (oldValue.statusCode === 200) {
        teardowns.push(function () {
            gpii.windows.writeRegistryKey("HKEY_CURRENT_USER", "Control Panel\\Accessibility",
                "Warning Sounds", oldValue.value, "REG_DWORD");
        });
        gpii.windows.writeRegistryKey("HKEY_CURRENT_USER", "Control Panel\\Accessibility",
            "Warning Sounds", 0, "REG_DWORD");
    }

    var runTest = function (testIndex) {
        if (testIndex >= tests.length) {
            jqUnit.start();
            return;
        }

        var test = tests[testIndex];

        fluid.log(test.input);
        var promise = gpii.windows.executeHelper(test.input);

        jqUnit.assertNotNull("executeHelper shouldn't return null", promise);
        jqUnit.assertTrue("executeHelper should return a promise", fluid.isPromise(promise));

        promise.then(function (value) {
            fluid.log(value);
            var match = gpii.tests.windows.systemSettingsHandler.deepMatch(value, test.expect);
            jqUnit.assertTrue("resolved value needs to match the expected.", match);
            runTest(testIndex + 1);
        }, fluid.fail);

    };
    runTest(0);
});

jqUnit.asyncTest("Testing system settings handler API", function () {

    var tests = gpii.tests.windows.systemSettingsHandler.apiTests;
    jqUnit.expect(tests.length * 1);

    // Make sure the "SystemSettings_Accessibility_Keyboard_WarningEnabled" setting is in a known state.
    // ("Display a warning message when turning a setting on with a shortcut")
    var oldValue = gpii.windows.readRegistryKey("HKEY_CURRENT_USER", "Control Panel\\Accessibility",
        "Warning Sounds", "REG_DWORD");
    if (oldValue.statusCode === 200) {
        teardowns.push(function () {
            gpii.windows.writeRegistryKey("HKEY_CURRENT_USER", "Control Panel\\Accessibility",
                "Warning Sounds", oldValue.value, "REG_DWORD");
        });
        gpii.windows.writeRegistryKey("HKEY_CURRENT_USER", "Control Panel\\Accessibility",
            "Warning Sounds", 0, "REG_DWORD");
    }

    var runTest = function (testIndex) {
        if (testIndex >= tests.length) {
            jqUnit.start();
            return;
        }

        var test = tests[testIndex];
        gpii.windows.systemSettingsHandler[test.func](test.input).then(function (value) {
            jqUnit.assertDeepEq("resolve", test.expect, value);
            runTest(testIndex + 1);
        });
    };
    runTest(0);

});
<|endoftext|>


<commit_before>/*eslint-env browser*/
/*eslint no-use-before-define:0 */
/*global $*/

(function(){
  "use strict";
  $(document).ready(function(){
    setInterval(updatePage, 100);
  });

  function updatePage(){
    $.getJSON("./state.json", updateImage);
  }

  function updateLights(data){
    $.each(data, function(index, value){
      document.getElementById(value.location + "2" + value.direction).style.fill = value.state;
      document.getElementById(value.location + "2" + value.direction + "-load").innerHTML = value.load;
    });
  }

  function updateImage(data){
    updateLights(data);
    colorHighest(data);
    createStatistics(data);
  }

  function createStatistics(data){
    var totalCars = Array.reduce(data, function(total, current){
    return current.load + total;}, 0);
    document.getElementById("totalCars").innerHTML = totalCars;

  }

  function colorHighest(data){
    var carCounts = $.map(data, function(d){return d.load});
    var highestCarCount = Array.max(carCounts);
    $.each(data, function(index, value){
      var color = value.load === highestCarCount ? "yellow": "black";
      document.getElementById(value.location + "2" + value.direction + "-load").style.fill = color;
    });
  }

  Array.max = function( array ){
    return Math.max.apply( Math, array );
  };
})();

<commit_msg>Change highest color to orange<commit_after>/*eslint-env browser*/
/*eslint no-use-before-define:0 */
/*global $*/

(function(){
  "use strict";
  $(document).ready(function(){
    setInterval(updatePage, 100);
  });

  function updatePage(){
    $.getJSON("./state.json", updateImage);
  }

  function updateLights(data){
    $.each(data, function(index, value){
      document.getElementById(value.location + "2" + value.direction).style.fill = value.state;
      document.getElementById(value.location + "2" + value.direction + "-load").innerHTML = value.load;
    });
  }

  function updateImage(data){
    updateLights(data);
    colorHighest(data);
    createStatistics(data);
  }

  function createStatistics(data){
    var totalCars = Array.reduce(data, function(total, current){
    return current.load + total;}, 0);
    document.getElementById("totalCars").innerHTML = totalCars;

  }

  function colorHighest(data){
    var carCounts = $.map(data, function(d){return d.load});
    var highestCarCount = Array.max(carCounts);
    $.each(data, function(index, value){
      var color = value.load === highestCarCount ? "orange": "black";
      document.getElementById(value.location + "2" + value.direction + "-load").style.fill = color;
    });
  }

  Array.max = function( array ){
    return Math.max.apply( Math, array );
  };
})();

<|endoftext|>


<commit_before>"use strict";

var tester = require('./_lib/tester');
var Verifier = require('./_lib/lib');

exports.examples = tester([
	{
		rules: 'format 3',
		value: 4,
		expect: false
	},
	{
		rules: 'format 3',
		value: 3,
		expect: true
	},
	{
		rules: 'format 3',
		value: 433,
		expect: true
	},
	{
		rules: 'format ^3',
		value: 433,
		expect: false
	},
	{
		rules: 'format ^3',
		value: 33,
		expect: true
	},
	{
		rules: 'format ^3$',
		value: 3,
		expect: true
	},
	{
		rules: 'format ^3$',
		value: 33,
		expect: false
	},
	{
		rules: 'format ^[a-zA-Z][a-zA-Z0-9_.-]*@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+$',
		value: 33,
		expect: false
	},
	{
		rules: 'format ^[a-zA-Z][a-zA-Z0-9_.-]*@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+$',
		value: "asdasdasd",
		expect: false
	},
	{
		rules: 'format ^[a-zA-Z][a-zA-Z0-9_.-]*@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+$',
		value: "asdasdasd@asd.com",
		expect: true
	}
]);

exports['check params'] = function (test) {

	test.throws(function () {
		var verifier = new Verifier({format: null});
	});

	test.throws(function () {
		var verifier = new Verifier({format: {}});
	});

	test.throws(function () {
		var verifier = new Verifier({format: parseInt("asdasd")});
	});

	test.done();
};<commit_msg>add error check for rule-format test<commit_after>"use strict";

var tester = require('./_lib/tester');
var Verifier = require('./_lib/lib');

exports.examples = tester([
	{
		rules: 'format 3',
		value: 4,
		verr: {
			rule: 'format',
			params: '3',
			index: null
		}
	},
	{
		rules: 'format 3',
		value: 3,
		expect: true
	},
	{
		rules: 'format 3',
		value: 433,
		expect: true
	},
	{
		rules: 'format ^3',
		value: 433,
		verr: {
			rule: 'format',
			params: '^3',
			index: null
		}
	},
	{
		rules: 'format ^3',
		value: 33,
		expect: true
	},
	{
		rules: 'format ^3$',
		value: 3,
		expect: true
	},
	{
		rules: 'format ^3$',
		value: 33,
		verr: {
			rule: 'format',
			params: '^3$',
			index: null
		}
	},
	{
		rules: 'format ^[a-zA-Z][a-zA-Z0-9_.-]*@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+$',
		value: 33,
		verr: {
			rule: 'format',
			params: '^[a-zA-Z][a-zA-Z0-9_.-]*@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+$',
			index: null
		}
	},
	{
		rules: 'format ^[a-zA-Z][a-zA-Z0-9_.-]*@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+$',
		value: "asdasdasd",
		verr: {
			rule: 'format',
			params: '^[a-zA-Z][a-zA-Z0-9_.-]*@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+$',
			index: null
		}
	},
	{
		rules: 'format ^[a-zA-Z][a-zA-Z0-9_.-]*@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+$',
		value: "asdasdasd@asd.com",
		expect: true
	}
]);

exports['check params'] = function (test) {

	test.throws(function () {
		var verifier = new Verifier({format: null});
	});

	test.throws(function () {
		var verifier = new Verifier({format: {}});
	});

	test.throws(function () {
		var verifier = new Verifier({format: parseInt("asdasd")});
	});

	test.done();
};<|endoftext|>


<commit_before>/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */

/**
 * Blocklist of unit tests from angular/material2 with ivy that are skipped when running on
 * angular/angular. As bugs are resolved, items should be removed from this blocklist.
 *
 * The `notes` section should be used to keep track of specific issues associated with the failures.
 */

// clang-format off
// tslint:disable

window.testBlocklist = {
  "CdkTable should be able to render multiple header and footer rows": {
    "error": "Error: Missing definitions for header, footer, and row; cannot determine which columns should be rendered.",
    "notes": "FW-1141: Direct ContentChildren not found for <tr> tags without a <tbody>"
  },
  "CdkTable should render correctly when using native HTML tags": {
    "error": "Error: Missing definitions for header, footer, and row; cannot determine which columns should be rendered.",
    "notes": "FW-1141: Direct ContentChildren not found for <tr> tags without a <tbody>"
  },
  "CdkTable with sticky positioning on native table layout should stick and unstick headers": {
    "error": "Error: Missing definitions for header, footer, and row; cannot determine which columns should be rendered.",
    "notes": "FW-1141: Direct ContentChildren not found for <tr> tags without a <tbody>"
  },
  "CdkTable with sticky positioning on native table layout should stick and unstick footers": {
    "error": "Error: Missing definitions for header, footer, and row; cannot determine which columns should be rendered.",
    "notes": "FW-1141: Direct ContentChildren not found for <tr> tags without a <tbody>"
  },
  "CdkTable with sticky positioning on native table layout should stick tfoot when all rows are stuck": {
    "error": "Error: Missing definitions for header, footer, and row; cannot determine which columns should be rendered.",
    "notes": "FW-1141: Direct ContentChildren not found for <tr> tags without a <tbody>"
  },
  "CdkTable with sticky positioning on native table layout should stick and unstick left columns": {
    "error": "Error: Missing definitions for header, footer, and row; cannot determine which columns should be rendered.",
    "notes": "FW-1141: Direct ContentChildren not found for <tr> tags without a <tbody>"
  },
  "CdkTable with sticky positioning on native table layout should stick and unstick right columns": {
    "error": "Error: Missing definitions for header, footer, and row; cannot determine which columns should be rendered.",
    "notes": "FW-1141: Direct ContentChildren not found for <tr> tags without a <tbody>"
  },
  "CdkTable with sticky positioning on native table layout should stick and unstick combination of sticky header, footer, and columns": {
    "error": "Error: Missing definitions for header, footer, and row; cannot determine which columns should be rendered.",
    "notes": "FW-1141: Direct ContentChildren not found for <tr> tags without a <tbody>"
  },
  "CdkTree flat tree should initialize should be able to use units different from px for the indentation": {
    "error": "Error: Failed: Expected node level to be 15rem but was 28px",
    "notes": "Breaking change: Change detection follows insertion tree only, not declaration tree (CdkTree is OnPush)"
  },
  "CdkTree flat tree should initialize should default to px if no unit is set for string value indentation": {
    "error": "Error: Failed: Expected node level to be 17px but was 28px",
    "notes": "Breaking change: Change detection follows insertion tree only, not declaration tree (CdkTree is OnPush)"
  },
  "CdkTree flat tree with toggle should expand/collapse the node": {
    "error": "Error: Failed: Expected node level to be 40px but was ",
    "notes": "Breaking change: Static directive inputs evaluated in creation mode (CdkTreeNode.mostRecentTreeNode.data is set after inputs)"
  },
  "CdkTree flat tree with toggle should expand/collapse the node recursively": {
    "error": "Error: Failed: Expected node level to be 40px but was ",
    "notes": "Breaking change: Static directive inputs evaluated in creation mode (CdkTreeNode.mostRecentTreeNode.data is set after inputs)"
  },
  "CdkTree nested tree with toggle should expand/collapse the node multiple times": {
    "error": "Error: Expected 3 to be 1, 'Expect node expanded'.",
    "notes": "1) Breaking change: Change detection follows insertion tree only, not declaration tree (CdkTree is OnPush) - 2) Breaking change: Content queries and descendants flag (fix test by removing <div> in NestedCdkTreeAppWithToggle)"
  },
  "CdkTree nested tree with toggle should expand/collapse the node recursively": {
    "error": "Error: Failed: Expected node descendant num to be 2 but was 0",
    "notes": "Breaking change: Content queries and descendants flag (fix test by removing <div> in NestedCdkTreeAppWithToggle)"
  },
  "MatStepper basic stepper should go to next available step when the next button is clicked": {
    "error": "Error: Expected 2 to be 1.",
    "notes": "Unknown"
  },
  "MatStepper basic stepper should go to previous available step when the previous button is clicked": {
    "error": "TypeError: Cannot read property 'nativeElement' of undefined",
    "notes": "Unknown"
  },
  "MatStepper basic stepper should not set focus on header of selected step if header is not clicked": {
    "error": "Error: Expected 2 to be 1.",
    "notes": "Unknown"
  },
  "MatStepper basic stepper should focus next step header if focus is inside the stepper": {
    "error": "Error: Expected 2 to be 1.",
    "notes": "Unknown"
  },
  "MatStepper basic stepper should only be able to return to a previous step if it is editable": {
    "error": "TypeError: Cannot read property 'nativeElement' of undefined",
    "notes": "Unknown"
  },
  "MatStepper basic stepper should not do anything when pressing the ENTER key with a modifier": {
    "error": "Error: Expected 0 to be 1, 'Expected index of focused step to increase by 1 after pressing the next key.'.",
    "notes": "FW-1146: Components should be able to inherit view queries from directives"
  },
  "MatStepper basic stepper should not do anything when pressing the SPACE key with a modifier": {
    "error": "Error: Expected 0 to be 1, 'Expected index of focused step to increase by 1 after pressing the next key.'.",
    "notes": "FW-1146: Components should be able to inherit view queries from directives"
  },
  "MatStepper linear stepper should not move to next step if current step is pending": {
    "error": "TypeError: Cannot read property 'nativeElement' of undefined",
    "notes": "Unknown"
  },
  "MatStepper vertical stepper should support using the left/right arrows to move focus": {
    "error": "Error: Expected 0 to be 1, 'Expected index of focused step to increase by 1 after pressing the next key.'.",
    "notes": "FW-1146: Components should be able to inherit view queries from directives"
  },
  "MatStepper vertical stepper should support using the up/down arrows to move focus": {
    "error": "Error: Expected 0 to be 1, 'Expected index of focused step to increase by 1 after pressing the next key.'.",
    "notes": "FW-1146: Components should be able to inherit view queries from directives"
  },
  "MatStepper vertical stepper should reverse arrow key focus in RTL mode": {
    "error": "Error: Expected 0 to be 1.",
    "notes": "FW-1146: Components should be able to inherit view queries from directives"
  },
  "MatStepper stepper with error state should show error state": {
    "error": "TypeError: Cannot read property 'nativeElement' of undefined",
    "notes": "Unknown"
  },
  "MatStepper stepper with error state should respect a custom falsy hasError value": {
    "error": "TypeError: Cannot read property 'nativeElement' of undefined",
    "notes": "Unknown"
  },
  "MatStepper stepper using Material UI Guideline logic should show done state when step is completed and its not the current step": {
    "error": "TypeError: Cannot read property 'nativeElement' of undefined",
    "notes": "Unknown"
  },
  "MatSidenav should be fixed position when in fixed mode": {
    "error": "Error: Expected ng-tns-c23383-0 ng-trigger ng-trigger-transform mat-drawer mat-sidenav mat-drawer-over ng-star-inserted to contain 'mat-sidenav-fixed'.",
    "notes": "FW-1132: Host class bindings don't work if super class has host class bindings"
  },
  "MatSidenav should set fixed bottom and top when in fixed mode": {
    "error": "Error: Expected '' to be '20px'.",
    "notes": "FW-1132: Host class bindings don't work if super class has host class bindings"
  },
  "MatTree flat tree with toggle should expand/collapse the node": {
    "error": "Error: Expected 0 to be 1, 'Expect node expanded one level'.",
    "notes": "Breaking change: Static directive inputs evaluated in creation mode (CdkTreeNode.mostRecentTreeNode.data is set after inputs)"
  },
  "MatTree flat tree with toggle should expand/collapse the node recursively": {
    "error": "Error: Expected 0 to be 3, 'Expect nodes expanded'.",
    "notes": "Breaking change: Static directive inputs evaluated in creation mode (CdkTreeNode.mostRecentTreeNode.data is set after inputs)"
  },
  "MatTree nested tree with toggle should expand/collapse the node": {
    "error": "Error: Expected 0 to be 1, 'Expect node expanded'.",
    "notes": "1) Breaking change: Content queries and descendants flag (fix test by removing <div> in NestedMatTreeAppWithToggle) - 2) Breaking change: Ivy inherits metadata from superclasses (remove (click) in MatTreeNodeToggle)"
  },
  "MatTree nested tree with toggle should expand/collapse the node recursively": {
    "error": "Error: Expected 0 to be 3, 'Expect node expanded'.",
    "notes": "1) Breaking change: Content queries and descendants flag (fix test by removing <div> in NestedMatTreeAppWithToggle) - 2) Breaking change: Ivy inherits metadata from superclasses (remove (click) in MatTreeNodeToggle)"
  },
  "MatInput without forms validates the type": {
    "error": "Error: Input type \"file\" isn't supported by matInput.",
    "notes": "Breaking change: Static directive inputs evaluated in creation mode - material test to be updated"
  },
  "MatInput with textarea autosize should work in a step": {
    "error": "TypeError: Cannot read property 'getBoundingClientRect' of null",
    "notes": "Unknown"
  },
  "Dialog should set the proper animation states": {
    "error": "TypeError: Cannot read property 'componentInstance' of null",
    "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
  },
  "MatAutocomplete aria should set role of autocomplete panel to listbox": {
    "error": "TypeError: Cannot read property 'nativeElement' of null",
    "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
  },
  "MatAutocomplete aria should set aria-owns based on the attached autocomplete": {
    "error": "TypeError: Cannot read property 'nativeElement' of null",
    "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
  },
  "MatDialog should set the proper animation states": {
    "error": "TypeError: Cannot read property 'componentInstance' of null",
    "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
  },
  "MatMenu animations should enable ripples on items by default": {
    "error": "TypeError: Cannot read property 'query' of null",
    "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
  },
  "MatMenu animations should disable ripples on disabled items": {
    "error": "TypeError: Cannot read property 'query' of undefined",
    "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
  },
  "MatMenu animations should disable ripples if disableRipple is set": {
    "error": "TypeError: Cannot read property 'query' of undefined",
    "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
  },
  "MatMenu nested menu should close submenu when hovering over disabled sibling item": {
    "error": "TypeError: Cannot read property 'nativeElement' of undefined",
    "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
  },
  "MatMenu nested menu should not open submenu when hovering over disabled trigger": {
    "error": "TypeError: Cannot read property 'componentInstance' of null",
    "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
  },
  "MatSnackBar with TemplateRef should be able to open a snack bar using a TemplateRef": {
    "error": "Error: Expected ' Fries Pizza  ' to contain 'Pasta'.",
    "notes": "Breaking change: Change detection follows insertion tree only, not declaration tree (MatSnackBarContainer is OnPush)"
  },
  "MatTooltip special cases should clear the `user-select` when a tooltip is set on a text field": {
    "error": "Error: Expected 'none' to be falsy.",
    "notes": "FW-1133: Inline styles are not applied before constructor is run"
  },
  "MatTooltip special cases should clear the `-webkit-user-drag` on draggable elements": {
    "error": "Error: Expected 'none' to be falsy.",
    "notes": "FW-1133: Inline styles are not applied before constructor is run"
  },
  "MatTable should be able to render a table correctly with native elements": {
    "error": "Error: Missing definitions for header, footer, and row; cannot determine which columns should be rendered.",
    "notes": "FW-1141: Direct ContentChildren not found for <tr> tags without a <tbody>"
  },
  "MatTable should apply custom sticky CSS class to sticky cells": {
    "error": "Error: Missing definitions for header, footer, and row; cannot determine which columns should be rendered.",
    "notes": "FW-1141: Direct ContentChildren not found for <tr> tags without a <tbody>"
  }
};
// clang-format on
<commit_msg>test(ivy): enable passing Material tests (#29219)<commit_after>/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */

/**
 * Blocklist of unit tests from angular/material2 with ivy that are skipped when running on
 * angular/angular. As bugs are resolved, items should be removed from this blocklist.
 *
 * The `notes` section should be used to keep track of specific issues associated with the failures.
 */

// clang-format off
// tslint:disable

window.testBlocklist = {
  "CdkTree flat tree should initialize should be able to use units different from px for the indentation": {
    "error": "Error: Failed: Expected node level to be 15rem but was 28px",
    "notes": "Breaking change: Change detection follows insertion tree only, not declaration tree (CdkTree is OnPush)"
  },
  "CdkTree flat tree should initialize should default to px if no unit is set for string value indentation": {
    "error": "Error: Failed: Expected node level to be 17px but was 28px",
    "notes": "Breaking change: Change detection follows insertion tree only, not declaration tree (CdkTree is OnPush)"
  },
  "CdkTree flat tree with toggle should expand/collapse the node": {
    "error": "Error: Failed: Expected node level to be 40px but was ",
    "notes": "Breaking change: Static directive inputs evaluated in creation mode (CdkTreeNode.mostRecentTreeNode.data is set after inputs)"
  },
  "CdkTree flat tree with toggle should expand/collapse the node recursively": {
    "error": "Error: Failed: Expected node level to be 40px but was ",
    "notes": "Breaking change: Static directive inputs evaluated in creation mode (CdkTreeNode.mostRecentTreeNode.data is set after inputs)"
  },
  "CdkTree nested tree with toggle should expand/collapse the node multiple times": {
    "error": "Error: Expected 3 to be 1, 'Expect node expanded'.",
    "notes": "1) Breaking change: Change detection follows insertion tree only, not declaration tree (CdkTree is OnPush) - 2) Breaking change: Content queries and descendants flag (fix test by removing <div> in NestedCdkTreeAppWithToggle)"
  },
  "CdkTree nested tree with toggle should expand/collapse the node recursively": {
    "error": "Error: Failed: Expected node descendant num to be 2 but was 0",
    "notes": "Breaking change: Content queries and descendants flag (fix test by removing <div> in NestedCdkTreeAppWithToggle)"
  },
  "MatStepper basic stepper should go to next available step when the next button is clicked": {
    "error": "Error: Expected 2 to be 1.",
    "notes": "Unknown"
  },
  "MatStepper basic stepper should go to previous available step when the previous button is clicked": {
    "error": "TypeError: Cannot read property 'nativeElement' of undefined",
    "notes": "Unknown"
  },
  "MatStepper basic stepper should not set focus on header of selected step if header is not clicked": {
    "error": "Error: Expected 2 to be 1.",
    "notes": "Unknown"
  },
  "MatStepper basic stepper should focus next step header if focus is inside the stepper": {
    "error": "Error: Expected 2 to be 1.",
    "notes": "Unknown"
  },
  "MatStepper basic stepper should only be able to return to a previous step if it is editable": {
    "error": "TypeError: Cannot read property 'nativeElement' of undefined",
    "notes": "Unknown"
  },
  "MatStepper linear stepper should not move to next step if current step is pending": {
    "error": "TypeError: Cannot read property 'nativeElement' of undefined",
    "notes": "Unknown"
  },
  "MatStepper stepper with error state should show error state": {
    "error": "TypeError: Cannot read property 'nativeElement' of undefined",
    "notes": "Unknown"
  },
  "MatStepper stepper with error state should respect a custom falsy hasError value": {
    "error": "TypeError: Cannot read property 'nativeElement' of undefined",
    "notes": "Unknown"
  },
  "MatStepper stepper using Material UI Guideline logic should show done state when step is completed and its not the current step": {
    "error": "TypeError: Cannot read property 'nativeElement' of undefined",
    "notes": "Unknown"
  },
  "MatSidenav should be fixed position when in fixed mode": {
    "error": "Error: Expected ng-tns-c22979-0 ng-trigger ng-trigger-transform mat-drawer mat-sidenav mat-drawer-over ng-star-inserted to contain 'mat-sidenav-fixed'.",
    "notes": "FW-1132: Host class bindings don't work if super class has host class bindings"
  },
  "MatSidenav should set fixed bottom and top when in fixed mode": {
    "error": "Error: Expected '' to be '20px'.",
    "notes": "FW-1132: Host class bindings don't work if super class has host class bindings"
  },
  "MatTree flat tree with toggle should expand/collapse the node": {
    "error": "Error: Expected 0 to be 1, 'Expect node expanded one level'.",
    "notes": "Breaking change: Static directive inputs evaluated in creation mode (CdkTreeNode.mostRecentTreeNode.data is set after inputs)"
  },
  "MatTree flat tree with toggle should expand/collapse the node recursively": {
    "error": "Error: Expected 0 to be 3, 'Expect nodes expanded'.",
    "notes": "Breaking change: Static directive inputs evaluated in creation mode (CdkTreeNode.mostRecentTreeNode.data is set after inputs)"
  },
  "MatTree nested tree with toggle should expand/collapse the node": {
    "error": "Error: Expected 0 to be 1, 'Expect node expanded'.",
    "notes": "1) Breaking change: Content queries and descendants flag (fix test by removing <div> in NestedMatTreeAppWithToggle) - 2) Breaking change: Ivy inherits metadata from superclasses (remove (click) in MatTreeNodeToggle)"
  },
  "MatTree nested tree with toggle should expand/collapse the node recursively": {
    "error": "Error: Expected 0 to be 3, 'Expect node expanded'.",
    "notes": "1) Breaking change: Content queries and descendants flag (fix test by removing <div> in NestedMatTreeAppWithToggle) - 2) Breaking change: Ivy inherits metadata from superclasses (remove (click) in MatTreeNodeToggle)"
  },
  "MatInput without forms validates the type": {
    "error": "Error: Input type \"file\" isn't supported by matInput.",
    "notes": "Breaking change: Static directive inputs evaluated in creation mode - material test to be updated"
  },
  "MatInput with textarea autosize should work in a step": {
    "error": "TypeError: Cannot read property 'getBoundingClientRect' of null",
    "notes": "Unknown"
  },
  "Dialog should set the proper animation states": {
    "error": "TypeError: Cannot read property 'componentInstance' of null",
    "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
  },
  "MatAutocomplete aria should set role of autocomplete panel to listbox": {
    "error": "TypeError: Cannot read property 'nativeElement' of null",
    "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
  },
  "MatAutocomplete aria should set aria-owns based on the attached autocomplete": {
    "error": "TypeError: Cannot read property 'nativeElement' of null",
    "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
  },
  "MatDialog should set the proper animation states": {
    "error": "TypeError: Cannot read property 'componentInstance' of null",
    "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
  },
  "MatMenu animations should enable ripples on items by default": {
    "error": "TypeError: Cannot read property 'query' of null",
    "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
  },
  "MatMenu animations should disable ripples on disabled items": {
    "error": "TypeError: Cannot read property 'query' of undefined",
    "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
  },
  "MatMenu animations should disable ripples if disableRipple is set": {
    "error": "TypeError: Cannot read property 'query' of undefined",
    "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
  },
  "MatMenu nested menu should close submenu when hovering over disabled sibling item": {
    "error": "TypeError: Cannot read property 'nativeElement' of undefined",
    "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
  },
  "MatMenu nested menu should not open submenu when hovering over disabled trigger": {
    "error": "TypeError: Cannot read property 'componentInstance' of null",
    "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
  },
  "MatSnackBar with TemplateRef should be able to open a snack bar using a TemplateRef": {
    "error": "Error: Expected ' Fries Pizza  ' to contain 'Pasta'.",
    "notes": "Breaking change: Change detection follows insertion tree only, not declaration tree (MatSnackBarContainer is OnPush)"
  },
  "MatTooltip special cases should clear the `user-select` when a tooltip is set on a text field": {
    "error": "Error: Expected 'none' to be falsy.",
    "notes": "FW-1133: Inline styles are not applied before constructor is run"
  },
  "MatTooltip special cases should clear the `-webkit-user-drag` on draggable elements": {
    "error": "Error: Expected 'none' to be falsy.",
    "notes": "FW-1133: Inline styles are not applied before constructor is run"
  }
};
// clang-format on
<|endoftext|>