<commit_before>'use strict';

/* eslint-disable no-inline-comments, max-len, complexity, global-require, require-jsdoc */

const Generator = require('yeoman-generator');
const chalk = require('chalk');
const yosay = require('yosay');
const path = require('path');
const gitconfig = require('git-config');
const glob = require('glob');
const _ = require('lodash');

/* this generator is used as subgenerator nitro:pattern and nitro:component */

module.exports = class extends Generator {

	constructor(args, opts) {
		// Calling the super constructor
		// eslint-disable-next-line prefer-rest-params
		super(args, opts);

		// Pattern name
		this.argument('name', { desc: 'the name of your pattern?', type: String, required: false, defaults: '' });

		// Pattern type
		this.cfg = require(this.destinationPath('config.json'));

		// Compatibility with older config and subgeneartor nitro:component
		const _patternName = this.options.namespace.split(':')[1];
		this._pattern = {
			name: _patternName,
			Name: _.upperFirst(_patternName),
			node: this.cfg.nitro.patterns || this.cfg.nitro.components,
		};

		this.types = _.map(this._pattern.node, (value, key) => {
			return key;
		});

		this.option('type', {
			desc: `your desired type [${this.types.join('|')}]`,
			type: String,
			defaults: this.types[0],
		});

		// Pattern modifier
		this.option('modifier', { desc: 'the name of your modifier', type: String });

		// Pattern decorator
		this.option('decorator', { desc: 'the name of your decorator', type: String });
	}

	initializing() {
		this.pkg = require('../../package.json');
	}

	prompting() {

		this.log(yosay(
			`Let me help you to create your ${this._pattern.name}…`
		));

		return this.prompt([
			{
				name: 'name',
				message: `What's the name of your ${this._pattern.name}?`,
				default: this.name,
				validate: function validateString(value) {
					if (!_.isString(value) || _.isEmpty(value)) {
						return `${this._pattern.Name} name has to be a valid string`;
					}
					if (/^[0-9]/.test(value)) {
						return `${this._pattern.Name} name must not start with a Number`;
					}
					return true;
				},
			},
			{
				name: 'type',
				type: 'list',
				message: 'And what\'s your desired type?',
				choices: this.types,
				default: _.indexOf(this.types, this.options.type) || 0,
			},
			{
				name: 'modifier',
				message: 'Would you like to create a CSS modifier? Type your desired name or leave empty.',
				default: this.options.modifier || '',
			},
			{
				name: 'decorator',
				message: 'Would you like to create a JS decorator? Type your desired name or leave empty.',
				default: this.options.decorator || '',
				validate: function validateString(value) {
					if (_.isString(value) && (/^[0-9]/).test(value)) {
						return `${this._pattern.Name} decorator must not start with a Number`;
					}
					return true;
				},
			},
		]).then((answers) => {
			this.name = answers.name;
			this.options.type = answers.type;
			this.options.modifier = answers.modifier;
			this.options.decorator = answers.decorator;
		});
	}

	writing() {

		const hasModifier = !_.isEmpty(this.options.modifier);
		const hasDecorator = !_.isEmpty(this.options.decorator);
		let msg = `Creating ${chalk.cyan(this.name)} ${this.options.type}`;

		if (hasModifier || hasDecorator) {
			msg += ' with ';
		}

		if (hasModifier) {
			msg += `CSS modifier ${chalk.cyan(this.options.modifier)}`;

			if (hasDecorator) {
				msg += ' and ';
			}
		}

		if (hasDecorator) {
			msg += `JS decorator ${chalk.cyan(this.options.decorator)}`;
		}

		this.log(msg);

		const pattern = this._pattern.node[this.options.type];
		const folder = this.name.replace(/[^A-Za-z0-9-]/g, '');
		const files = glob.sync('**/*', { cwd: this.destinationPath(pattern.template), nodir: true, dot: true });
		const ignores = [
			// files to ignore
			'.DS_Store',
		];
		const user = {
			name: '',
			email: '',
		};
		const gitConfig = gitconfig.sync();

		if (!_.isEmpty(gitConfig) && !_.isEmpty(gitConfig.user)) {
			user.name = gitConfig.user.name;
			user.email = gitConfig.user.email;
		}

		const patternReplacements = {
			name: this.name, // Pattern name, eg. Main Navigation
			folder, // Pattern folder, eg. MainNavigation
			js: _.upperFirst(_.camelCase(this.name.replace(/^[0-9]+/, ''))), // Pattern name for use in JS files, eg. MainNavigation
			css: _.kebabCase(this.name), // Pattern name for use in CSS files, eg. main-navigation
			prefix: pattern.pattern_prefix || pattern.component_prefix || null, // CSS class prefix, eg. m
			type: this.options.type, // Pattern type, eg. atom, molecule etc.
			file: this.name.replace(/[^A-Za-z0-9-]/g, '').toLowerCase(), // Pattern filename, eg. mainnavigation
		};
		const replacements = {
			user,
			pattern: patternReplacements,
			component: patternReplacements,
			modifier: {
				name: this.options.modifier, // Modifier name, eg. Highlight
				css: _.kebabCase(this.options.modifier), // Modifier name for use in CSS files, eg. highlight
				file: this.options.modifier.replace(/[^A-Za-z0-9-]/g, '').toLowerCase(), // Modifier filename, eg.highlight
			},
			decorator: {
				name: this.options.decorator, // Decorator name, eg. Highlight
				js: _.upperFirst(_.camelCase(this.options.decorator.replace(/^[0-9]+/, ''))), // Decorator name for use in JS files, eg. Highlight
				file: this.options.decorator.replace(/[^A-Za-z0-9-]/g, '').toLowerCase(), // Decorator filename, eg.highlight
			},
		};

		files.forEach((file) => {
			if (_.indexOf(ignores, file) !== -1) {
				return;
			}

			// exclude modifier files if modifier is not set
			if (file.indexOf('modifier') !== -1) {
				if (_.isEmpty(this.options.modifier)) {
					return;
				}
			}

			// exclude decorator files if decorator is not set
			if (file.indexOf('decorator') !== -1) {
				if (_.isEmpty(this.options.decorator)) {
					return;
				}
			}

			// filename replacements
			const fileReplacements = {
				pattern: replacements.pattern.file,
				component: replacements.pattern.file,
				modifier: replacements.modifier.file,
				decorator: replacements.decorator.file,
			};

			let filename = file;
			_.forOwn(fileReplacements, (value, key) => {
				filename = path.join(path.dirname(filename), path.basename(filename).replace(key, value));
			});

			this.fs.copyTpl(
				this.destinationPath(`${pattern.template}/${file}`),
				this.destinationPath(`${pattern.path}/${folder}/${filename}`),
				replacements);
		}, this);
	}
};
<commit_msg>generator - #102 additional validation for pattern names<commit_after>'use strict';

/* eslint-disable no-inline-comments, max-len, complexity, global-require, require-jsdoc */

const Generator = require('yeoman-generator');
const chalk = require('chalk');
const yosay = require('yosay');
const path = require('path');
const gitconfig = require('git-config');
const glob = require('glob');
const _ = require('lodash');

/* this generator is used as subgenerator nitro:pattern and nitro:component */

module.exports = class extends Generator {

	constructor(args, opts) {
		// Calling the super constructor
		// eslint-disable-next-line prefer-rest-params
		super(args, opts);

		// Pattern name
		this.argument('name', { desc: 'the name of your pattern?', type: String, required: false, defaults: '' });

		// Pattern type
		this.cfg = require(this.destinationPath('config.json'));

		// Compatibility with older config and subgeneartor nitro:component
		const _patternName = this.options.namespace.split(':')[1];
		this._pattern = {
			name: _patternName,
			Name: _.upperFirst(_patternName),
			node: this.cfg.nitro.patterns || this.cfg.nitro.components,
		};

		this.types = _.map(this._pattern.node, (value, key) => {
			return key;
		});

		this.option('type', {
			desc: `your desired type [${this.types.join('|')}]`,
			type: String,
			defaults: this.types[0],
		});

		// Pattern modifier
		this.option('modifier', { desc: 'the name of your modifier', type: String });

		// Pattern decorator
		this.option('decorator', { desc: 'the name of your decorator', type: String });
	}

	initializing() {
		this.pkg = require('../../package.json');
	}

	prompting() {

		this.log(yosay(
			`Let me help you to create your ${this._pattern.name}…`
		));

		return this.prompt([
			{
				name: 'name',
				message: `What's the name of your ${this._pattern.name}?`,
				default: this.name,
				validate: (value) => {
					if (!_.isString(value) || _.isEmpty(value)) {
						return `${this._pattern.Name} name has to be a valid string`;
					}
					if (/^[0-9]/.test(value)) {
						return `${this._pattern.Name} name must not start with a Number`;
					}
					if (/(component|pattern|modifier|decorator)/i.test(value)) {
						return `Avoid 'pattern', 'component', 'modifier' and 'decorator' in ${this._pattern.Name} names. These have a special meaning`;
					}
					return true;
				},
			},
			{
				name: 'type',
				type: 'list',
				message: 'And what\'s your desired type?',
				choices: this.types,
				default: _.indexOf(this.types, this.options.type) || 0,
			},
			{
				name: 'modifier',
				message: 'Would you like to create a CSS modifier? Type your desired name or leave empty.',
				default: this.options.modifier || '',
				validate: (value) => {
					if (/(component|pattern|modifier|decorator)/i.test(value)) {
						return `Avoid 'pattern', 'component', 'modifier' and 'decorator' in ${this._pattern.Name} modifier names. These have a special meaning`;
					}
					return true;
				},
			},
			{
				name: 'decorator',
				message: 'Would you like to create a JS decorator? Type your desired name or leave empty.',
				default: this.options.decorator || '',
				validate: (value) => {
					if (_.isString(value) && (/^[0-9]/).test(value)) {
						return `${this._pattern.Name} decorator must not start with a Number`;
					}
					if (/(component|pattern|modifier|decorator)/i.test(value)) {
						return `Avoid 'pattern', 'component', 'modifier' and 'decorator' in ${this._pattern.Name} decorator names. These have a special meaning`;
					}
					return true;
				},
			},
		]).then((answers) => {
			this.name = answers.name;
			this.options.type = answers.type;
			this.options.modifier = answers.modifier;
			this.options.decorator = answers.decorator;
		});
	}

	writing() {

		const hasModifier = !_.isEmpty(this.options.modifier);
		const hasDecorator = !_.isEmpty(this.options.decorator);
		let msg = `Creating ${chalk.cyan(this.name)} ${this.options.type}`;

		if (hasModifier || hasDecorator) {
			msg += ' with ';
		}

		if (hasModifier) {
			msg += `CSS modifier ${chalk.cyan(this.options.modifier)}`;

			if (hasDecorator) {
				msg += ' and ';
			}
		}

		if (hasDecorator) {
			msg += `JS decorator ${chalk.cyan(this.options.decorator)}`;
		}

		this.log(msg);

		const pattern = this._pattern.node[this.options.type];
		const folder = this.name.replace(/[^A-Za-z0-9-]/g, '');
		const files = glob.sync('**/*', { cwd: this.destinationPath(pattern.template), nodir: true, dot: true });
		const ignores = [
			// files to ignore
			'.DS_Store',
		];
		const user = {
			name: '',
			email: '',
		};
		const gitConfig = gitconfig.sync();

		if (!_.isEmpty(gitConfig) && !_.isEmpty(gitConfig.user)) {
			user.name = gitConfig.user.name;
			user.email = gitConfig.user.email;
		}

		const patternReplacements = {
			name: this.name, // Pattern name, eg. Main Navigation
			folder, // Pattern folder, eg. MainNavigation
			js: _.upperFirst(_.camelCase(this.name.replace(/^[0-9]+/, ''))), // Pattern name for use in JS files, eg. MainNavigation
			css: _.kebabCase(this.name), // Pattern name for use in CSS files, eg. main-navigation
			prefix: pattern.pattern_prefix || pattern.component_prefix || null, // CSS class prefix, eg. m
			type: this.options.type, // Pattern type, eg. atom, molecule etc.
			file: this.name.replace(/[^A-Za-z0-9-]/g, '').toLowerCase(), // Pattern filename, eg. mainnavigation
		};
		const replacements = {
			user,
			pattern: patternReplacements,
			component: patternReplacements,
			modifier: {
				name: this.options.modifier, // Modifier name, eg. Highlight
				css: _.kebabCase(this.options.modifier), // Modifier name for use in CSS files, eg. highlight
				file: this.options.modifier.replace(/[^A-Za-z0-9-]/g, '').toLowerCase(), // Modifier filename, eg.highlight
			},
			decorator: {
				name: this.options.decorator, // Decorator name, eg. Highlight
				js: _.upperFirst(_.camelCase(this.options.decorator.replace(/^[0-9]+/, ''))), // Decorator name for use in JS files, eg. Highlight
				file: this.options.decorator.replace(/[^A-Za-z0-9-]/g, '').toLowerCase(), // Decorator filename, eg.highlight
			},
		};

		files.forEach((file) => {
			if (_.indexOf(ignores, file) !== -1) {
				return;
			}

			// exclude modifier files if modifier is not set
			if (file.indexOf('modifier') !== -1) {
				if (_.isEmpty(this.options.modifier)) {
					return;
				}
			}

			// exclude decorator files if decorator is not set
			if (file.indexOf('decorator') !== -1) {
				if (_.isEmpty(this.options.decorator)) {
					return;
				}
			}

			// filename replacements
			const fileReplacements = {
				pattern: replacements.pattern.file,
				component: replacements.pattern.file,
				modifier: replacements.modifier.file,
				decorator: replacements.decorator.file,
			};

			let filename = file;
			_.forOwn(fileReplacements, (value, key) => {
				filename = path.join(path.dirname(filename), path.basename(filename).split(key).join(value));
			});

			this.fs.copyTpl(
				this.destinationPath(`${pattern.template}/${file}`),
				this.destinationPath(`${pattern.path}/${folder}/${filename}`),
				replacements);
		}, this);
	}
};
<|endoftext|>


<commit_before>/**
 * @file build test file
 * @author zhoumin
 */

const san = require('../../dist/san.ssr');
const fs = require('fs');
const path = require('path');

let htmlTpl = fs.readFileSync(path.resolve(__dirname, '..', 'index-ssr.html.tpl'), 'UTF-8');
let html = '';
let specTpls = '';

// generate html
let genContent = function ({componentClass, componentSource, compontentData, specTpl, dirName, result}) {
    let renderer = san.compileToRenderer(componentClass);
    let id = dirName;

    // if no inject mark, add it
    if (!/\/\/\s*\[inject\]/.test(specTpl)) {
        specTpl = specTpl.replace(/function\s*\([a-z0-9_,$\s]*\)\s*\{/, function ($0) {
            return $0 + '\n// [inject] init';
        });
    }

    let injectHtml = result ? result : renderer(compontentData);

    html += '
'
        + injectHtml
        + '
\n\n';

    let preCode = `
        ${componentSource}
        var wrap = document.getElementById('${id}');
        var myComponent = new MyComponent({
            el: wrap.firstChild
        });
    `;
    specTpl = specTpl.replace(/\/\/\s*\[inject\]\s* init/, preCode);
    specTpls += specTpl;
};

let buildFile = function (filePath) {
    let files = fs.readdirSync(filePath);
    let componentClass;
    let componentSource;
    let specTpl;
    let compontentData;
    let dirName;
    let result;
    let sourceFile = '';

    if (!files.length) {
        return;
    }

    files.forEach(filename => {
        // absolute path
        let abFilePath = path.join(filePath, filename);
        let stats = fs.statSync(abFilePath);
        let isFile = stats.isFile();
        let isDir = stats.isDirectory();

        // if it's a file, init data
        if (isFile) {
            // component file
            if (filename === 'component.js') {
                componentClass = require(abFilePath);
                componentSource = fs.readFileSync(path.resolve(abFilePath), 'UTF-8')
                    .split('\n')
                    .map(line => {
                        if (/(\.|\s)exports\s*=/.test(line)
                            || /san\s*=\s*require\(/.test(line)
                        ) {
                            return '';
                        }

                        return line;
                    })
                    .join('\n');
                sourceFile = filename;
            }
            if (filename === 'spec.js') {
                specTpl = fs.readFileSync(path.resolve(abFilePath), 'UTF-8');
            }
            if (filename === 'data.js') {
                compontentData = require(abFilePath);
            }
            if (filename === 'result.html') {
                result = fs.readFileSync(path.resolve(abFilePath), 'UTF-8').replace('\n', '');
            }
        }

        // iterate
        if (isDir) {
            console.log(`[Build SSR spec] ${filename}`);
            buildFile(abFilePath);
        }
    });

    let match = filePath.match(/[\/\\]([a-zA-Z0-9_,$\-]*)$/);
    // dirName is the identity of each component
    dirName = match[1];
    // generate html when it has source file
    if (sourceFile) {
        genContent({
            componentClass,
            componentSource,
            compontentData,
            specTpl,
            dirName,
            result
        });
    }
};

let writeIn = function ({htmlTpl, html, specTpls}) {
    let karmaHtml = fs.readFileSync(path.resolve(__dirname, '..', 'karma-context.html.tpl'), 'UTF-8');
    fs.writeFileSync(
        path.resolve(__dirname, '..', 'karma-context.html'),
        karmaHtml.replace('##ssr-elements##', html),
        'UTF-8'
    );

    fs.writeFileSync(
        path.resolve(__dirname, '..', 'index-ssr.html'),
        htmlTpl.replace('##ssr-elements##', html),
        'UTF-8'
    );

    fs.writeFileSync(
        path.resolve(__dirname, 'ssr.spec.js'),
        specTpls,
        'UTF-8'
    );
};

console.log('----- Build SSR Specs -----');

buildFile(path.resolve(__dirname, './'));
// write into file
writeIn({htmlTpl, html, specTpls});

console.log();
<commit_msg>little opti<commit_after>/**
 * @file build test file
 * @author zhoumin
 */

const san = require('../../dist/san.ssr');
const fs = require('fs');
const path = require('path');

let htmlTpl = fs.readFileSync(path.resolve(__dirname, '..', 'index-ssr.html.tpl'), 'UTF-8');
let html = '';
let specTpls = '';

// generate html
function genContent({componentClass, componentSource, compontentData, specTpl, dirName, result}) {
    let renderer = san.compileToRenderer(componentClass);
    let id = dirName;

    // if no inject mark, add it
    if (!/\/\/\s*\[inject\]/.test(specTpl)) {
        specTpl = specTpl.replace(/function\s*\([a-z0-9_,$\s]*\)\s*\{/, function ($0) {
            return $0 + '\n// [inject] init';
        });
    }

    let injectHtml = result ? result : renderer(compontentData);

    html += `<div id="${id}">${injectHtml}</div>\n\n`;

    let preCode = `
        ${componentSource}
        var wrap = document.getElementById('${id}');
        var myComponent = new MyComponent({
            el: wrap.firstChild
        });
    `;
    specTpl = specTpl.replace(/\/\/\s*\[inject\]\s* init/, preCode);
    specTpls += specTpl;
};

function buildFile(filePath) {
    let files = fs.readdirSync(filePath);
    let componentClass;
    let componentSource;
    let specTpl;
    let compontentData;
    let dirName;
    let result;
    let sourceFile = '';

    if (!files.length) {
        return;
    }

    files.forEach(filename => {
        // absolute path
        let abFilePath = path.join(filePath, filename);
        let stats = fs.statSync(abFilePath);
        let isFile = stats.isFile();
        let isDir = stats.isDirectory();

        // if it's a file, init data
        if (isFile) {
            switch (filename) {
                case 'component.js':
                    componentClass = require(abFilePath);
                    componentSource = fs.readFileSync(path.resolve(abFilePath), 'UTF-8')
                        .split('\n')
                        .map(line => {
                            if (/(\.|\s)exports\s*=/.test(line)
                                || /san\s*=\s*require\(/.test(line)
                            ) {
                                return '';
                            }

                            return line;
                        })
                        .join('\n');
                    sourceFile = filename;
                    break;

                case 'spec.js':
                    specTpl = fs.readFileSync(path.resolve(abFilePath), 'UTF-8');
                    break;

                case 'data.js':
                    compontentData = require(abFilePath);
                    break;

                case 'result.html':
                    result = fs.readFileSync(path.resolve(abFilePath), 'UTF-8').replace('\n', '');
                    break;
            }

        }

        // iterate
        if (isDir) {
            console.log(`[Build SSR spec] ${filename}`);
            buildFile(abFilePath);
        }
    });

    let match = filePath.match(/[\/\\]([a-zA-Z0-9_,$\-]*)$/);
    // dirName is the identity of each component
    dirName = match[1];
    // generate html when it has source file
    if (sourceFile) {
        genContent({
            componentClass,
            componentSource,
            compontentData,
            specTpl,
            dirName,
            result
        });
    }
};

function writeIn({htmlTpl, html, specTpls}) {
    let karmaHtml = fs.readFileSync(path.resolve(__dirname, '..', 'karma-context.html.tpl'), 'UTF-8');
    fs.writeFileSync(
        path.resolve(__dirname, '..', 'karma-context.html'),
        karmaHtml.replace('##ssr-elements##', html),
        'UTF-8'
    );

    fs.writeFileSync(
        path.resolve(__dirname, '..', 'index-ssr.html'),
        htmlTpl.replace('##ssr-elements##', html),
        'UTF-8'
    );

    fs.writeFileSync(
        path.resolve(__dirname, 'ssr.spec.js'),
        specTpls,
        'UTF-8'
    );
};

console.log();
console.log('----- Build SSR Specs -----');

buildFile(path.resolve(__dirname, './'));
// write into file
writeIn({htmlTpl, html, specTpls});

console.log();
<|endoftext|>


<commit_before>/* global describe, it */
var statement = require('../lib/statement')
var assert = require('assert')

describe('Statement', function () {
  describe('#checkWellFormed', function () {
    it('(P -> Q => unbalanced parentheses', function () {
      var error = statement.checkWellFormed('(P -> Q')
      assert.equal(error, 'unbalanced parentheses!')
    })

    it('P -> & => missing operand', function () {
      var error = statement.checkWellFormed('P -> &')
      assert.equal(error, 'missing operand!')
    })

    it('&& => double operators', function () {
      var error = statement.checkWellFormed('&&')
      assert.equal(error, 'double operators!')
    })

    it('A || (~ & B) => missing operand', function () {
      var error = statement.checkWellFormed('A || (~ & B)')
      assert.equal(error, 'missing operand!')
    })

    it('(A || (~ & B) => unbalanced parentheses', function () {
      var error = statement.checkWellFormed('(A || (~ & B)')
      assert.equal(error, 'unbalanced parentheses!')
    })
  })

  describe('#evaluate', function () {
    it('(P <-> Q) <-> ((P || R) -> (~Q -> R))', function () {
      var out = false
      var str = '(P <-> Q) <-> ((P || R) -> (~Q -> R))'

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': false})
      assert.equal(out, true)
    })

    it('(P <-> ~Q) <-> (~P <-> ~Q)', function () {
      var out = false
      var str = '(P <-> ~Q) <-> (~P <-> ~Q)'

      out = statement.evaluate(str, {'P': true, 'Q': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': true, 'Q': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': false})
      assert.equal(out, false)
    })

    it('~(P & Q) || P', function () {
      var out = false
      var str = '~(P & Q) || P'

      out = statement.evaluate(str, {'P': true, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false})
      assert.equal(out, true)
    })

    it('~(P -> Q) -> P', function () {
      var out = false
      var str = '~(P -> Q) -> P'

      out = statement.evaluate(str, {'P': true, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false})
      assert.equal(out, true)
    })

    it('(P || Q) || (~P & Q)', function () {
      var out = false
      var str = '(P || Q) || (~P & Q)'

      out = statement.evaluate(str, {'P': true, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false})
      assert.equal(out, false)
    })

    it('Q & ~Q', function () {
      var out = false
      var str = 'Q & ~Q'

      out = statement.evaluate(str, {'Q': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'Q': false})
      assert.equal(out, false)
    })

    it('(P -> Q) || (~Q & R)', function () {
      var out = false
      var str = '(P -> Q) || (~Q & R)'

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': false})
      assert.equal(out, true)
    })

    it('P || Q -> R || ~P', function () {
      var out = false
      var str = 'P || Q -> R || ~P'

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': false})
      assert.equal(out, true)
    })

    it('R <-> ~P || (R & Q)', function () {
      var out = false
      var str = 'R <-> ~P || (R & Q)'

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': false})
      assert.equal(out, false)
    })

    it('(P & Q <-> Q) -> (Q -> P)', function () {
      var out = false
      var str = '(P & Q <-> Q) -> (Q -> P)'

      out = statement.evaluate(str, {'P': true, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false})
      assert.equal(out, true)
    })

    it('P <-> Q', function () {
      var out = false
      var str = 'P <-> Q'

      out = statement.evaluate(str, {'P': true, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': false})
      assert.equal(out, true)
    })

    it('~P || ~Q', function () {
      var out = false
      var str = '~P || ~Q'

      out = statement.evaluate(str, {'P': true, 'Q': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': true, 'Q': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false})
      assert.equal(out, true)
    })

    it('P & (Q || R)', function () {
      var out = false
      var str = 'P & (Q || R)'

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': false})
      assert.equal(out, false)
    })

    it('~(~R & P)', function () {
      var out = false
      var str = '~(~R & P)'

      out = statement.evaluate(str, {'P': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'R': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'R': false})
      assert.equal(out, true)
    })

    it('(P & Q) || (R -> Q)', function () {
      var out = false
      var str = '(P & Q) || (R -> Q)'

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': false})
      assert.equal(out, true)
    })
  })
})
<commit_msg>fix: update error message for failing test<commit_after>/* global describe, it */
var statement = require('../lib/statement')
var assert = require('assert')

describe('Statement', function () {
  describe('#checkWellFormed', function () {
    it('(P -> Q => unbalanced parentheses', function () {
      var error = statement.checkWellFormed('(P -> Q')
      assert.equal(error, 'unbalanced parentheses!')
    })

    it('P -> & => missing operand', function () {
      var error = statement.checkWellFormed('P -> &')
      assert.equal(error, 'missing operand!')
    })

    it('&& => double operators', function () {
      var error = statement.checkWellFormed('&&')
      assert.equal(error, 'double operators!')
    })

    it('A | (~A & B) => unknown symbol!', function () {
      var error = statement.checkWellFormed('A | (~A & B)')
      assert.equal(error, 'unknown symbol!')
    })

    it('(A || (~ & B) => unbalanced parentheses', function () {
      var error = statement.checkWellFormed('(A || (~ & B)')
      assert.equal(error, 'unbalanced parentheses!')
    })
  })

  describe('#evaluate', function () {
    it('(P <-> Q) <-> ((P || R) -> (~Q -> R))', function () {
      var out = false
      var str = '(P <-> Q) <-> ((P || R) -> (~Q -> R))'

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': false})
      assert.equal(out, true)
    })

    it('(P <-> ~Q) <-> (~P <-> ~Q)', function () {
      var out = false
      var str = '(P <-> ~Q) <-> (~P <-> ~Q)'

      out = statement.evaluate(str, {'P': true, 'Q': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': true, 'Q': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': false})
      assert.equal(out, false)
    })

    it('~(P & Q) || P', function () {
      var out = false
      var str = '~(P & Q) || P'

      out = statement.evaluate(str, {'P': true, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false})
      assert.equal(out, true)
    })

    it('~(P -> Q) -> P', function () {
      var out = false
      var str = '~(P -> Q) -> P'

      out = statement.evaluate(str, {'P': true, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false})
      assert.equal(out, true)
    })

    it('(P || Q) || (~P & Q)', function () {
      var out = false
      var str = '(P || Q) || (~P & Q)'

      out = statement.evaluate(str, {'P': true, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false})
      assert.equal(out, false)
    })

    it('Q & ~Q', function () {
      var out = false
      var str = 'Q & ~Q'

      out = statement.evaluate(str, {'Q': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'Q': false})
      assert.equal(out, false)
    })

    it('(P -> Q) || (~Q & R)', function () {
      var out = false
      var str = '(P -> Q) || (~Q & R)'

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': false})
      assert.equal(out, true)
    })

    it('P || Q -> R || ~P', function () {
      var out = false
      var str = 'P || Q -> R || ~P'

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': false})
      assert.equal(out, true)
    })

    it('R <-> ~P || (R & Q)', function () {
      var out = false
      var str = 'R <-> ~P || (R & Q)'

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': false})
      assert.equal(out, false)
    })

    it('(P & Q <-> Q) -> (Q -> P)', function () {
      var out = false
      var str = '(P & Q <-> Q) -> (Q -> P)'

      out = statement.evaluate(str, {'P': true, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false})
      assert.equal(out, true)
    })

    it('P <-> Q', function () {
      var out = false
      var str = 'P <-> Q'

      out = statement.evaluate(str, {'P': true, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': false})
      assert.equal(out, true)
    })

    it('~P || ~Q', function () {
      var out = false
      var str = '~P || ~Q'

      out = statement.evaluate(str, {'P': true, 'Q': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': true, 'Q': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false})
      assert.equal(out, true)
    })

    it('P & (Q || R)', function () {
      var out = false
      var str = 'P & (Q || R)'

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': false})
      assert.equal(out, false)
    })

    it('~(~R & P)', function () {
      var out = false
      var str = '~(~R & P)'

      out = statement.evaluate(str, {'P': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'R': false})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'R': false})
      assert.equal(out, true)
    })

    it('(P & Q) || (R -> Q)', function () {
      var out = false
      var str = '(P & Q) || (R -> Q)'

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': true, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': true, 'Q': false, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': true})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': true, 'R': false})
      assert.equal(out, true)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': true})
      assert.equal(out, false)

      out = statement.evaluate(str, {'P': false, 'Q': false, 'R': false})
      assert.equal(out, true)
    })
  })
})
<|endoftext|>


<commit_before>/*jslint node: true */
"use strict";

var Stopwatch = require('../lib/Stopwatch');
var defaultPrecision = 15;
var assert = require('assert');
var should = require('should');

describe('stopwatch', function () {
    this.timeout(5000);

    describe('constructor', function () {
        it('w/no params', function () {
            var stopwatch = new Stopwatch();
            should.exist(stopwatch);
        });

        it('w/name as first param', function () {
            var stopwatch = new Stopwatch('metric-name');
            stopwatch.name().should.equal('metric-name');
        });

        it('w/autostart as first param', function () {
            var stopwatch = new Stopwatch(true);
            should.exist(stopwatch.name());
            stopwatch.name().should.not.equal(true);
        });

        it('w/both name and autostart', function () {
            var stopwatch = new Stopwatch('metric-name', true);
            stopwatch.name().should.equal('metric-name');
        });

        it('autocreated names are not constant', function () {
            var stopwatch1 = new Stopwatch(true);
            var stopwatch2 = new Stopwatch(true);
            stopwatch1.name().should.not.equal(stopwatch2.name());
        });
    });

    it('start and read (100ms)', function (done) {
        var testtime = 100;

        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            var delta = stopwatch.read();
            verifyDelta(testtime, delta, defaultPrecision);
            done();
        }, testtime);
    });

    it('start and read (10ms)', function (done) {
        var testtime = 10;

        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            var delta = stopwatch.read();
            verifyDelta(testtime, delta, defaultPrecision);
            done();
        }, testtime);
    });

    it('autostart set to true automatically starts stopwatch', function (done) {
        var testtime = 10;

        var stopwatch = new Stopwatch(true);
        setTimeout(function () {
            var delta = stopwatch.read();
            verifyDelta(testtime, delta, defaultPrecision);
            done();
        }, testtime);
    });

    it('autostart set to false does NOT automatically start stopwatch', function (done) {
        var testtime = 10;

        var stopwatch = new Stopwatch(false);
        setTimeout(function () {
            stopwatch.read().should.be.NaN();
            done();
        }, testtime);
    });

    it('with two stopwatches, do independent reads of each', function (done) {
        var stopwatch1 = new Stopwatch();
        var stopwatch2 = new Stopwatch();

        stopwatch1.start();

        //start first stopwatch, then do a read .3s later
        var testtimeA = 300;
        setTimeout(function () {
            var delta1 = stopwatch1.read();
            verifyDelta(testtimeA, delta1, defaultPrecision);
        }, testtimeA);

        //start second stopwatch .1s second after the first, then do a read .5s later
        var testtimeB = 500;
        setTimeout(function () {
            stopwatch2.start();
            setTimeout(function () {
                var delta2 = stopwatch2.read();
                verifyDelta(testtimeB, delta2, defaultPrecision);
                done();
            }, testtimeB);
        }, 100);
    });

    it('start, stop, and read should return the time at stop', function (done) {
        var testtime = 100;

        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            stopwatch.stop();

            setTimeout(function () {
                var delta = stopwatch.read();
                verifyDelta(testtime, delta, defaultPrecision);
                done();
            }, 500);
        }, testtime);
    });

    it('performing read without start() or stop() returns NaN', function (done) {
        var stopwatch = new Stopwatch();
        assert.ok(isNaN(stopwatch.read()));
        done();
    });

    it('performing read without start() returns NaN', function (done) {
        var stopwatch = new Stopwatch();
        stopwatch.stop();
        assert.ok(isNaN(stopwatch.read()));
        done();
    });

    it('executing stop twice should return time at second stop', function (done) {
        //start(), wait .1s, stop(), wait .2s, stop(), wait .5s, read(), ensure delta = .3s
        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            stopwatch.stop();

            setTimeout(function () {
                verifyDelta(100 + 200, stopwatch.stop(), defaultPrecision);

                setTimeout(function () {
                    var delta = stopwatch.read();
                    verifyDelta(100 + 200, delta, defaultPrecision);
                    done();
                }, 500);
            }, 200);
        }, 100);
    });

    it('ensure that stop() returns time', function (done) {
        var testtime = 100;
        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            var delta = stopwatch.stop();
            verifyDelta(testtime, delta, defaultPrecision);
            done();
        }, testtime);
    });

    describe('toString()', function () {
        it('idle', function () {
            var stopwatch = new Stopwatch('sw');
            //[sw => state:init; value:NaN]
            stopwatch.toString().should.containEql('state:init');
            stopwatch.toString().should.containEql('value:');
        });
        it('started', function () {
            var stopwatch = new Stopwatch('sw', true);
            //[sw => state:running; value:0.01]
            stopwatch.toString().should.containEql('state:running');
            stopwatch.toString().should.containEql('value:0');
        });
        it('stopped', function () {
            var stopwatch = new Stopwatch('sw', true);
            stopwatch.stop();
            //[sw => state:stopped; value:0.01]
            stopwatch.toString().should.containEql('state:stopped');
            stopwatch.toString().should.containEql('value:0');
        });
    });

    // https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/time/StopWatch.html
    describe('java stopwatch compliance', function () {
        it('time should equal read on a running stopwatch', function () {
            //TODO: list time as alias of read
            var stopwatch = new Stopwatch('sw');
            stopwatch.start();

            var readTime = stopwatch.read();
            var time = stopwatch.time();

            verifyDelta(readTime, time, 10);
        });
        it.skip('reset', function () {
            // Resets the stopwatch. Stops it if need be.
            // This method clears the internal values to allow the object to be reused.
        });
        it.skip('split/unsplit/getSplitTime', function () {
            // Split the time.  This method sets the stop time of the watch to allow a time to be extracted. The start time is unaffected, enabling unsplit() to continue the timing from the original start point.
            // Remove a split.  This method clears the stop time. The start time is unaffected, enabling timing from the original start point to continue.
            // IllegalStateException - if the StopWatch is not running. (on split)
            // IllegalStateException - if the StopWatch has not yet been split. (on unsplit)
        });
        it.skip('suspend/resume', function() {
            // This method suspends the watch until it is resumed. The watch will not include time between the suspend and resume calls in the total time.
            // IllegalStateException - if the StopWatch is not currently running.
            // IllegalStateException - if the StopWatch has not been suspended.
        });
        it.skip('start while already running', function() {
            // IllegalStateException - if the StopWatch is already running.
        });
        it.skip('stop while not running', function() {
            // IllegalStateException - if the StopWatch is not running.
        });
    });
});

//TODO:
//replace with: statman.TestHelper.assertCloseEnough(testtime, delta, defaultPrecision);
function verifyDelta(expected, actual, acceptedVariance) {
    var lowerThreshold = expected - acceptedVariance;
    var upperThreshold = expected + acceptedVariance;
    var message = "Expected " + expected + " ± " + acceptedVariance + ", was " + actual + ".";
    assert.ok((actual >= lowerThreshold) && (actual <= upperThreshold), message);
}<commit_msg>java compliance: read<commit_after>/*jslint node: true */
"use strict";

var Stopwatch = require('../lib/Stopwatch');
var defaultPrecision = 15;
var assert = require('assert');
var should = require('should');

describe('stopwatch', function () {
    this.timeout(5000);

    describe('constructor', function () {
        it('w/no params', function () {
            var stopwatch = new Stopwatch();
            should.exist(stopwatch);
        });

        it('w/name as first param', function () {
            var stopwatch = new Stopwatch('metric-name');
            stopwatch.name().should.equal('metric-name');
        });

        it('w/autostart as first param', function () {
            var stopwatch = new Stopwatch(true);
            should.exist(stopwatch.name());
            stopwatch.name().should.not.equal(true);
        });

        it('w/both name and autostart', function () {
            var stopwatch = new Stopwatch('metric-name', true);
            stopwatch.name().should.equal('metric-name');
        });

        it('autocreated names are not constant', function () {
            var stopwatch1 = new Stopwatch(true);
            var stopwatch2 = new Stopwatch(true);
            stopwatch1.name().should.not.equal(stopwatch2.name());
        });
    });

    it('start and read (100ms)', function (done) {
        var testtime = 100;

        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            var delta = stopwatch.read();
            verifyDelta(testtime, delta, defaultPrecision);
            done();
        }, testtime);
    });

    it('start and read (10ms)', function (done) {
        var testtime = 10;

        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            var delta = stopwatch.read();
            verifyDelta(testtime, delta, defaultPrecision);
            done();
        }, testtime);
    });

    it('autostart set to true automatically starts stopwatch', function (done) {
        var testtime = 10;

        var stopwatch = new Stopwatch(true);
        setTimeout(function () {
            var delta = stopwatch.read();
            verifyDelta(testtime, delta, defaultPrecision);
            done();
        }, testtime);
    });

    it('autostart set to false does NOT automatically start stopwatch', function (done) {
        var testtime = 10;

        var stopwatch = new Stopwatch(false);
        setTimeout(function () {
            stopwatch.read().should.be.NaN();
            done();
        }, testtime);
    });

    it('with two stopwatches, do independent reads of each', function (done) {
        var stopwatch1 = new Stopwatch();
        var stopwatch2 = new Stopwatch();

        stopwatch1.start();

        //start first stopwatch, then do a read .3s later
        var testtimeA = 300;
        setTimeout(function () {
            var delta1 = stopwatch1.read();
            verifyDelta(testtimeA, delta1, defaultPrecision);
        }, testtimeA);

        //start second stopwatch .1s second after the first, then do a read .5s later
        var testtimeB = 500;
        setTimeout(function () {
            stopwatch2.start();
            setTimeout(function () {
                var delta2 = stopwatch2.read();
                verifyDelta(testtimeB, delta2, defaultPrecision);
                done();
            }, testtimeB);
        }, 100);
    });

    it('start, stop, and read should return the time at stop', function (done) {
        var testtime = 100;

        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            stopwatch.stop();

            setTimeout(function () {
                var delta = stopwatch.read();
                verifyDelta(testtime, delta, defaultPrecision);
                done();
            }, 500);
        }, testtime);
    });

    it('performing read without start() or stop() returns NaN', function (done) {
        var stopwatch = new Stopwatch();
        assert.ok(isNaN(stopwatch.read()));
        done();
    });

    it('performing read without start() returns NaN', function (done) {
        var stopwatch = new Stopwatch();
        stopwatch.stop();
        assert.ok(isNaN(stopwatch.read()));
        done();
    });

    it('executing stop twice should return time at second stop', function (done) {
        //start(), wait .1s, stop(), wait .2s, stop(), wait .5s, read(), ensure delta = .3s
        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            stopwatch.stop();

            setTimeout(function () {
                verifyDelta(100 + 200, stopwatch.stop(), defaultPrecision);

                setTimeout(function () {
                    var delta = stopwatch.read();
                    verifyDelta(100 + 200, delta, defaultPrecision);
                    done();
                }, 500);
            }, 200);
        }, 100);
    });

    it('ensure that stop() returns time', function (done) {
        var testtime = 100;
        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            var delta = stopwatch.stop();
            verifyDelta(testtime, delta, defaultPrecision);
            done();
        }, testtime);
    });

    describe('toString()', function () {
        it('idle', function () {
            var stopwatch = new Stopwatch('sw');
            //[sw => state:init; value:NaN]
            stopwatch.toString().should.containEql('state:init');
            stopwatch.toString().should.containEql('value:');
        });
        it('started', function () {
            var stopwatch = new Stopwatch('sw', true);
            //[sw => state:running; value:0.01]
            stopwatch.toString().should.containEql('state:running');
            stopwatch.toString().should.containEql('value:0');
        });
        it('stopped', function () {
            var stopwatch = new Stopwatch('sw', true);
            stopwatch.stop();
            //[sw => state:stopped; value:0.01]
            stopwatch.toString().should.containEql('state:stopped');
            stopwatch.toString().should.containEql('value:0');
        });
    });

    // https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/time/StopWatch.html
    describe('java stopwatch compliance', function () {
        it('time should equal read on a running stopwatch', function () {
            //TODO: list time as alias of read
            var stopwatch = new Stopwatch('sw');
            stopwatch.start();

            var readTime = stopwatch.read();
            var time = stopwatch.time();

            verifyDelta(readTime, time, 10);
        });
        it('time should equal read on a stopped stopwatch', function () {
            //TODO: list time as alias of read
            var stopwatch = new Stopwatch('sw');
            stopwatch.start();
            setTimeout(  function() {
                stopwatch.read().should.be.equal(stopwatch.time());
            },10);

        });
        it.skip('reset', function () {
            // Resets the stopwatch. Stops it if need be.
            // This method clears the internal values to allow the object to be reused.
        });
        it.skip('split/unsplit/getSplitTime', function () {
            // Split the time.  This method sets the stop time of the watch to allow a time to be extracted. The start time is unaffected, enabling unsplit() to continue the timing from the original start point.
            // Remove a split.  This method clears the stop time. The start time is unaffected, enabling timing from the original start point to continue.
            // IllegalStateException - if the StopWatch is not running. (on split)
            // IllegalStateException - if the StopWatch has not yet been split. (on unsplit)
        });
        it.skip('suspend/resume', function() {
            // This method suspends the watch until it is resumed. The watch will not include time between the suspend and resume calls in the total time.
            // IllegalStateException - if the StopWatch is not currently running.
            // IllegalStateException - if the StopWatch has not been suspended.
        });
        it.skip('start while already running', function() {
            // IllegalStateException - if the StopWatch is already running.
        });
        it.skip('stop while not running', function() {
            // IllegalStateException - if the StopWatch is not running.
        });
    });
});

//TODO:
//replace with: statman.TestHelper.assertCloseEnough(testtime, delta, defaultPrecision);
function verifyDelta(expected, actual, acceptedVariance) {
    var lowerThreshold = expected - acceptedVariance;
    var upperThreshold = expected + acceptedVariance;
    var message = "Expected " + expected + " ± " + acceptedVariance + ", was " + actual + ".";
    assert.ok((actual >= lowerThreshold) && (actual <= upperThreshold), message);
}<|endoftext|>


<commit_before>var Checker = require('../lib/checker');
var assert = require('assert');

describe('modules/string-checker', function() {
    var checker;
    beforeEach(function() {
        checker = new Checker();
        checker.registerDefaultRules();
    });

    describe('line starting with hash, temporary, until we will have inline rules', function() {
        it('should ignore lines starting with #!', function() {
            assert(checker.checkString(
                '#! random stuff\n' +
                '#! 1234\n' +
                'var a = 5;\n'
            ).isEmpty());
        });

        it('should ignore ios instruments style import', function() {
            assert(checker.checkString(
                '#import "abc.js"\n' +
                '#import abc.js\n' +
                'var a = 5;\n'
            ).isEmpty());
        });

        it('should not replace when not beginning of line', function() {
            checker.configure({ disallowMultipleLineStrings: true });
            assert(checker.checkString(
                '#import "abc.js"\n' +
                'var b="#import \\\n abc.js";\n' +
                'var a = 5;\n'
            ).getErrorCount() === 1);
        });
    });

    it('should report parse issues as errors', function() {
        var errors = checker.checkString('this is not javascript');
        assert(errors.getErrorCount() === 1);

        var error = errors.getErrorList()[0];
        assert(error.rule === 'parseError');
        assert(error.message === 'Unexpected identifier');
        assert(error.line === 1);
        assert(error.column === 6);
    });

    it('should not process the rule if it is equals to null (#203)', function() {
        try {
            checker.configure({
                preset: 'jquery',
                requireCurlyBraces: null
            });
            assert(true);
        } catch (_) {
            assert(false);
        }
    });

    it('should throw if preset does not exist', function() {
        try {
            checker.configure({
                preset: 'not-exist'
            });

            assert(false);
        } catch (e) {
            assert(e.toString() === 'Error: Preset "not-exist" does not exist');
        }
    });

    describe('rules registration', function() {
        it('should report rules in config which don\'t match any registered rules', function() {
            var error;
            try {
                checker.configure({ disallowMulipleLineBreaks: true, disallowMultipleVarDelc: true });
            } catch (e) {
                error = e;
            }
            assert.equal(
                error.message,
                'Unsupported rules: disallowMulipleLineBreaks, disallowMultipleVarDelc'
            );
        });

        it('should not report rules in config which match registered rules', function() {
            var error;
            try {
                checker.configure({ disallowMultipleLineBreaks: true, disallowMultipleVarDecl: true });
            } catch (e) {
                error = e;
            }
            assert(error === undefined);
        });

        it('should not report "excludeFiles" rule as unregistered', function() {
            var error;
            try {
                checker.configure({ excludeFiles: [] });
            } catch (e) {
                error = e;
            }
            assert(error === undefined);
        });
    });

    describe('maxErrors', function() {
        beforeEach(function() {
            checker.configure({
                requireSpaceBeforeBinaryOperators: ['='],
                maxErrors: 1
            });
        });

        it('should allow a maximum number of reported errors to be set', function() {
            var errors = checker.checkString('var foo=1;\n var bar=2;').getErrorList();
            assert(errors.length === 1);
        });

        it('should not report more than the maximum errors across multiple checks', function() {
            var errors = checker.checkString('var foo=1;\n var bar=2;').getErrorList();
            var errors2 = checker.checkString('var baz=1;\n var qux=2;').getErrorList();
            assert(errors.length === 1);
            assert(errors2.length === 0);
        });
    });

    describe('esprima version', function() {
        var customDescription = 'in no way a real error message';
        var customEsprima = {
            parse: function() {
                var error = new Error();
                error.description = customDescription;

                throw error;
            }
        };

        it('uses a custom esprima when provided to the constructor', function() {
            checker = new Checker({ esprima: customEsprima });
            checker.registerDefaultRules();

            var errors = checker.checkString('import { foo } from "bar";');
            var error = errors.getErrorList()[0];

            assert(error.rule === 'parseError');
            assert(error.message === customDescription);
        });

        it('uses a custom esprima when both esprima and esnext are provided to the constructor', function() {
            checker = new Checker({ esprima: customEsprima, esnext: true });
            checker.registerDefaultRules();

            var errors = checker.checkString('import { foo } from "bar";');
            var error = errors.getErrorList()[0];

            assert(error.rule === 'parseError');
            assert(error.message === customDescription);
        });

        it('uses the harmony esprima when true is provided to the constructor', function() {
            checker = new Checker({ esnext: true });
            checker.registerDefaultRules();

            var errors = checker.checkString('import { foo } from "bar";');
            assert(errors.isEmpty());
        });

        it('uses the default esprima when falsely or no argument is provided to the constructor', function() {
            checker = new Checker();
            checker.registerDefaultRules();

            var errors = checker.checkString('import { foo } from "bar";');
            var error = errors.getErrorList()[0];

            assert(error.rule === 'parseError');
            assert(error.message !== customDescription);
        });
    });
});
<commit_msg>StringChecker: unit test for when maxErrors is NaN<commit_after>var Checker = require('../lib/checker');
var assert = require('assert');

describe('modules/string-checker', function() {
    var checker;
    beforeEach(function() {
        checker = new Checker();
        checker.registerDefaultRules();
    });

    describe('line starting with hash, temporary, until we will have inline rules', function() {
        it('should ignore lines starting with #!', function() {
            assert(checker.checkString(
                '#! random stuff\n' +
                '#! 1234\n' +
                'var a = 5;\n'
            ).isEmpty());
        });

        it('should ignore ios instruments style import', function() {
            assert(checker.checkString(
                '#import "abc.js"\n' +
                '#import abc.js\n' +
                'var a = 5;\n'
            ).isEmpty());
        });

        it('should not replace when not beginning of line', function() {
            checker.configure({ disallowMultipleLineStrings: true });
            assert(checker.checkString(
                '#import "abc.js"\n' +
                'var b="#import \\\n abc.js";\n' +
                'var a = 5;\n'
            ).getErrorCount() === 1);
        });
    });

    it('should report parse issues as errors', function() {
        var errors = checker.checkString('this is not javascript');
        assert(errors.getErrorCount() === 1);

        var error = errors.getErrorList()[0];
        assert(error.rule === 'parseError');
        assert(error.message === 'Unexpected identifier');
        assert(error.line === 1);
        assert(error.column === 6);
    });

    it('should not process the rule if it is equals to null (#203)', function() {
        try {
            checker.configure({
                preset: 'jquery',
                requireCurlyBraces: null
            });
            assert(true);
        } catch (_) {
            assert(false);
        }
    });

    it('should throw if preset does not exist', function() {
        try {
            checker.configure({
                preset: 'not-exist'
            });

            assert(false);
        } catch (e) {
            assert(e.toString() === 'Error: Preset "not-exist" does not exist');
        }
    });

    describe('rules registration', function() {
        it('should report rules in config which don\'t match any registered rules', function() {
            var error;
            try {
                checker.configure({ disallowMulipleLineBreaks: true, disallowMultipleVarDelc: true });
            } catch (e) {
                error = e;
            }
            assert.equal(
                error.message,
                'Unsupported rules: disallowMulipleLineBreaks, disallowMultipleVarDelc'
            );
        });

        it('should not report rules in config which match registered rules', function() {
            var error;
            try {
                checker.configure({ disallowMultipleLineBreaks: true, disallowMultipleVarDecl: true });
            } catch (e) {
                error = e;
            }
            assert(error === undefined);
        });

        it('should not report "excludeFiles" rule as unregistered', function() {
            var error;
            try {
                checker.configure({ excludeFiles: [] });
            } catch (e) {
                error = e;
            }
            assert(error === undefined);
        });
    });

    describe('maxErrors', function() {
        beforeEach(function() {
            checker.configure({
                requireSpaceBeforeBinaryOperators: ['='],
                maxErrors: 1
            });
        });

        it('should allow a maximum number of reported errors to be set', function() {
            var errors = checker.checkString('var foo=1;\n var bar=2;').getErrorList();
            assert(errors.length === 1);
        });

        it('should not report more than the maximum errors across multiple checks', function() {
            var errors = checker.checkString('var foo=1;\n var bar=2;').getErrorList();
            var errors2 = checker.checkString('var baz=1;\n var qux=2;').getErrorList();
            assert(errors.length === 1);
            assert(errors2.length === 0);
        });

        it('should not be used when not a number', function() {
            var errors;
            checker.configure({
                requireSpaceBeforeBinaryOperators: ['='],
                maxErrors: NaN
            });

            errors = checker.checkString('var foo=1;\n var bar=2;').getErrorList();
            assert(errors.length > 0);
        });
    });

    describe('esprima version', function() {
        var customDescription = 'in no way a real error message';
        var customEsprima = {
            parse: function() {
                var error = new Error();
                error.description = customDescription;

                throw error;
            }
        };

        it('uses a custom esprima when provided to the constructor', function() {
            checker = new Checker({ esprima: customEsprima });
            checker.registerDefaultRules();

            var errors = checker.checkString('import { foo } from "bar";');
            var error = errors.getErrorList()[0];

            assert(error.rule === 'parseError');
            assert(error.message === customDescription);
        });

        it('uses a custom esprima when both esprima and esnext are provided to the constructor', function() {
            checker = new Checker({ esprima: customEsprima, esnext: true });
            checker.registerDefaultRules();

            var errors = checker.checkString('import { foo } from "bar";');
            var error = errors.getErrorList()[0];

            assert(error.rule === 'parseError');
            assert(error.message === customDescription);
        });

        it('uses the harmony esprima when true is provided to the constructor', function() {
            checker = new Checker({ esnext: true });
            checker.registerDefaultRules();

            var errors = checker.checkString('import { foo } from "bar";');
            assert(errors.isEmpty());
        });

        it('uses the default esprima when falsely or no argument is provided to the constructor', function() {
            checker = new Checker();
            checker.registerDefaultRules();

            var errors = checker.checkString('import { foo } from "bar";');
            var error = errors.getErrorList()[0];

            assert(error.rule === 'parseError');
            assert(error.message !== customDescription);
        });
    });
});
<|endoftext|>


<commit_before>/**
 * Crypto utilities.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2010 Digital Bazaar, Inc. All rights reserved.
 */
(function($)
{
   /**
    * The crypto namespace and utils API.
    */
   window.krypto = window.krypto || {};
   window.krypto.utils =
   {
      /**
       * Creates a buffer that stores bytes.
       *
       * @param b the bytes to wrap (as a string) (optional).
       */
      createBuffer: function(b)
      {
         var buf =
         {
            /**
             * The data in this buffer.
             */
            data: b || new String(),

            /**
             * The pointer for reading from this buffer.
             */
            read: 0,

            /**
             * Gets the number of bytes in this buffer.
             *
             * @return the number of bytes in this buffer.
             */
            length: function()
            {
               return buf.data.length - buf.read;
            },

            /**
             * Puts a byte in this buffer.
             *
             * @param b the byte to put.
             */
            putByte: function(b)
            {
               buf.data += String.fromCharCode(b);
            },

            /**
             * Puts bytes in this buffer.
             *
             * @param bytes the bytes (as a string) to put.
             */
            putBytes: function(bytes)
            {
               buf.data += bytes;
            },

            /**
             * Puts a 16-bit integer in this buffer.
             *
             * @param i the 16-bit integer.
             */
            putInt16: function(i)
            {
               buf.data +=
                  String.fromCharCode(s >> 8 & 0xFF) +
                  String.fromCharCode(s & 0xFF);
            },

            /**
             * Puts a 24-bit integer in this buffer.
             *
             * @param i the 24-bit integer.
             */
            putInt24: function(s)
            {
               buf.data +=
                  String.fromCharCode(s >> 16 & 0xFF) +
                  String.fromCharCode(s >> 8 & 0xFF) +
                  String.fromCharCode(s & 0xFF);
            },

            /**
             * Puts a 32-bit integer in this buffer.
             *
             * @param i the 32-bit integer.
             */
            putInt32: function(i)
            {
               buf.data +=
                  String.fromCharCode(i >> 24 & 0xFF) +
                  String.fromCharCode(i >> 16 & 0xFF) +
                  String.fromCharCode(i >> 8 & 0xFF) +
                  String.fromCharCode(i & 0xFF);
            },

            /**
             * Puts an n-bit integer in this buffer.
             *
             * @param i the n-bit integer.
             * @param n the number of bits in the integer.
             */
            putInt: function(i, n)
            {
               do
               {
                  n -= 8;
                  buf.data += String.fromCharCode((i >> n) & 0xFF);
               }
               while(bits > 0);
            },

            /**
             * Puts the given buffer into this buffer.
             *
             * @param buffer the buffer to put into this one.
             */
            putBuffer: function(buffer)
            {
               buf.data += buffer.getBytes();
            },

            /**
             * Gets a byte from this buffer and advances the read pointer by 1.
             *
             * @return the byte.
             */
            getByte: function()
            {
               return buf.data.charCodeAt(buf.read++);
            },

            /**
             * Gets a uint16 from this buffer and advances the read pointer
             * by 2.
             *
             * @return the uint16.
             */
            getInt16: function()
            {
               return (
                  buf.data.charCodeAt(buf.read++) << 8 ^
                  buf.data.charCodeAt(buf.read++));
            },

            /**
             * Gets a uint24 from this buffer and advances the read pointer
             * by 3.
             *
             * @return the uint24.
             */
            getInt24: function()
            {
               return (
                  buf.data.charCodeAt(buf.read++) << 16 ^
                  buf.data.charCodeAt(buf.read++) << 8 ^
                  buf.data.charCodeAt(buf.read++));
            },

            /**
             * Gets a uint32 from this buffer and advances the read pointer
             * by 4.
             *
             * @return the word.
             */
            getInt32: function()
            {
               return (
                  buf.data.charCodeAt(buf.read++) << 24 ^
                  buf.data.charCodeAt(buf.read++) << 16 ^
                  buf.data.charCodeAt(buf.read++) << 8 ^
                  buf.data.charCodeAt(buf.read++));
            },

            /**
             * Reads bytes out into a string and clears them from the buffer.
             *
             * @param count the number of bytes to read, undefined, null or 0
             *           for all.
             *
             * @return a string of bytes.
             */
            getBytes: function(count)
            {
               var rval;
               if(count)
               {
                  // read count bytes
                  rval = buf.data.slice(buf.read, buf.read + count);
                  buf.read += count;
               }
               else
               {
                  // read all bytes
                  rval = buf.data.slice(buf.read);
                  buf.clear();
               }
               return rval;
            },

            /**
             * Gets a string of all the bytes without modifying the read
             * pointer.
             *
             * @return an array of bytes.
             */
            bytes: function()
            {
               return buf.data.slice(buf.read);
            },

            /**
             * Gets a byte at the given index without modifying the read
             * pointer.
             *
             * @param i the byte index.
             *
             * @return the byte.
             */
            at: function(i)
            {
               return buf.data.charCodeAt(buf.read + i);
            },

            /**
             * Gets the last byte without modifying the read pointer.
             *
             * @return the last byte.
             */
            last: function()
            {
               return buf.data.charCodeAt(buf.data.length - 1);
            },

            /**
             * Creates a copy of this buffer.
             *
             * @return the copy.
             */
            copy: function()
            {
               var c = window.krypto.utils.createBuffer(buf.data);
               c.read = buf.read;
               return c;
            },

            /**
             * Compacts this buffer.
             */
            compact: function()
            {
               if(buf.read > 0)
               {
                  buf.data = buf.data.slice(buf.read);
                  buf.read = 0;
               }
            },

            /**
             * Clears this buffer.
             */
            clear: function()
            {
               buf.data = new String();
               buf.read = 0;
            },

            /**
             * Shortens this buffer by triming bytes off of the end of this
             * buffer.
             *
             * @param count the number of bytes to trim off.
             */
            truncate: function(count)
            {
               var len = Math.max(0, buf.length() - count);
               buf.data = buf.data.substr(buf.read, len);
               buf.read = 0;
            }
         };
         return buf;
      }
   };
})(jQuery);
<commit_msg>Limited count in getBytes() to length of buffer.<commit_after>/**
 * Crypto utilities.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2010 Digital Bazaar, Inc. All rights reserved.
 */
(function($)
{
   /**
    * The crypto namespace and utils API.
    */
   window.krypto = window.krypto || {};
   window.krypto.utils =
   {
      /**
       * Creates a buffer that stores bytes.
       *
       * @param b the bytes to wrap (as a string) (optional).
       */
      createBuffer: function(b)
      {
         var buf =
         {
            /**
             * The data in this buffer.
             */
            data: b || new String(),

            /**
             * The pointer for reading from this buffer.
             */
            read: 0,

            /**
             * Gets the number of bytes in this buffer.
             *
             * @return the number of bytes in this buffer.
             */
            length: function()
            {
               return buf.data.length - buf.read;
            },

            /**
             * Puts a byte in this buffer.
             *
             * @param b the byte to put.
             */
            putByte: function(b)
            {
               buf.data += String.fromCharCode(b);
            },

            /**
             * Puts bytes in this buffer.
             *
             * @param bytes the bytes (as a string) to put.
             */
            putBytes: function(bytes)
            {
               buf.data += bytes;
            },

            /**
             * Puts a 16-bit integer in this buffer.
             *
             * @param i the 16-bit integer.
             */
            putInt16: function(i)
            {
               buf.data +=
                  String.fromCharCode(s >> 8 & 0xFF) +
                  String.fromCharCode(s & 0xFF);
            },

            /**
             * Puts a 24-bit integer in this buffer.
             *
             * @param i the 24-bit integer.
             */
            putInt24: function(s)
            {
               buf.data +=
                  String.fromCharCode(s >> 16 & 0xFF) +
                  String.fromCharCode(s >> 8 & 0xFF) +
                  String.fromCharCode(s & 0xFF);
            },

            /**
             * Puts a 32-bit integer in this buffer.
             *
             * @param i the 32-bit integer.
             */
            putInt32: function(i)
            {
               buf.data +=
                  String.fromCharCode(i >> 24 & 0xFF) +
                  String.fromCharCode(i >> 16 & 0xFF) +
                  String.fromCharCode(i >> 8 & 0xFF) +
                  String.fromCharCode(i & 0xFF);
            },

            /**
             * Puts an n-bit integer in this buffer.
             *
             * @param i the n-bit integer.
             * @param n the number of bits in the integer.
             */
            putInt: function(i, n)
            {
               do
               {
                  n -= 8;
                  buf.data += String.fromCharCode((i >> n) & 0xFF);
               }
               while(bits > 0);
            },

            /**
             * Puts the given buffer into this buffer.
             *
             * @param buffer the buffer to put into this one.
             */
            putBuffer: function(buffer)
            {
               buf.data += buffer.getBytes();
            },

            /**
             * Gets a byte from this buffer and advances the read pointer by 1.
             *
             * @return the byte.
             */
            getByte: function()
            {
               return buf.data.charCodeAt(buf.read++);
            },

            /**
             * Gets a uint16 from this buffer and advances the read pointer
             * by 2.
             *
             * @return the uint16.
             */
            getInt16: function()
            {
               return (
                  buf.data.charCodeAt(buf.read++) << 8 ^
                  buf.data.charCodeAt(buf.read++));
            },

            /**
             * Gets a uint24 from this buffer and advances the read pointer
             * by 3.
             *
             * @return the uint24.
             */
            getInt24: function()
            {
               return (
                  buf.data.charCodeAt(buf.read++) << 16 ^
                  buf.data.charCodeAt(buf.read++) << 8 ^
                  buf.data.charCodeAt(buf.read++));
            },

            /**
             * Gets a uint32 from this buffer and advances the read pointer
             * by 4.
             *
             * @return the word.
             */
            getInt32: function()
            {
               return (
                  buf.data.charCodeAt(buf.read++) << 24 ^
                  buf.data.charCodeAt(buf.read++) << 16 ^
                  buf.data.charCodeAt(buf.read++) << 8 ^
                  buf.data.charCodeAt(buf.read++));
            },

            /**
             * Reads bytes out into a string and clears them from the buffer.
             *
             * @param count the number of bytes to read, undefined, null or 0
             *           for all.
             *
             * @return a string of bytes.
             */
            getBytes: function(count)
            {
               var rval;
               if(count)
               {
                  // read count bytes
                  count = Math.min(buf.length(), count);
                  rval = buf.data.slice(buf.read, buf.read + count);
                  buf.read += count;
               }
               else
               {
                  // read all bytes
                  rval = buf.data.slice(buf.read);
                  buf.clear();
               }
               return rval;
            },

            /**
             * Gets a string of all the bytes without modifying the read
             * pointer.
             *
             * @return an array of bytes.
             */
            bytes: function()
            {
               return buf.data.slice(buf.read);
            },

            /**
             * Gets a byte at the given index without modifying the read
             * pointer.
             *
             * @param i the byte index.
             *
             * @return the byte.
             */
            at: function(i)
            {
               return buf.data.charCodeAt(buf.read + i);
            },

            /**
             * Gets the last byte without modifying the read pointer.
             *
             * @return the last byte.
             */
            last: function()
            {
               return buf.data.charCodeAt(buf.data.length - 1);
            },

            /**
             * Creates a copy of this buffer.
             *
             * @return the copy.
             */
            copy: function()
            {
               var c = window.krypto.utils.createBuffer(buf.data);
               c.read = buf.read;
               return c;
            },

            /**
             * Compacts this buffer.
             */
            compact: function()
            {
               if(buf.read > 0)
               {
                  buf.data = buf.data.slice(buf.read);
                  buf.read = 0;
               }
            },

            /**
             * Clears this buffer.
             */
            clear: function()
            {
               buf.data = new String();
               buf.read = 0;
            },

            /**
             * Shortens this buffer by triming bytes off of the end of this
             * buffer.
             *
             * @param count the number of bytes to trim off.
             */
            truncate: function(count)
            {
               var len = Math.max(0, buf.length() - count);
               buf.data = buf.data.substr(buf.read, len);
               buf.read = 0;
            }
         };
         return buf;
      }
   };
})(jQuery);
<|endoftext|>


<commit_before>/* eslint-env mocha */

"use strict";

var assert = require("chai").assert;
var rpc = require("../src");

describe("sync", function () {
  beforeEach(function () {
    rpc.connect({
      httpAddresses: ["https://eth3.augur.net"],
      wsAddresses: [],
      ipcAddresses: [],
      errorHandler: function (error) { throw error; }
    });
  });
  afterEach(function () {
    rpc.resetState();
  });
  it("returns result synchronously", function (done) {
    var resultOrError = rpc.raw("net_version", null);
    assert.typeOf(resultOrError, "string");
    done();
  });
  it("ensureLatestBlock", function (done) {
    assert.isNull(rpc.getCurrentBlock());
    rpc.ensureLatestBlock();
    assert.isNotNull(rpc.getCurrentBlock());
    require("../").resetState();
    done();
  });
});
<commit_msg>Updated network ID in sync tests<commit_after>/* eslint-env mocha */

"use strict";

var assert = require("chai").assert;
var rpc = require("../src");

describe("sync", function () {
  beforeEach(function () {
    rpc.connect({
      httpAddresses: ["https://eth9000.augur.net"],
      wsAddresses: [],
      ipcAddresses: [],
      errorHandler: function (error) { throw error; }
    });
  });
  afterEach(function () {
    rpc.resetState();
  });
  it("returns result synchronously", function (done) {
    var resultOrError = rpc.raw("net_version", null);
    assert.typeOf(resultOrError, "string");
    done();
  });
  it("ensureLatestBlock", function (done) {
    assert.isNull(rpc.getCurrentBlock());
    rpc.ensureLatestBlock();
    assert.isNotNull(rpc.getCurrentBlock());
    require("../").resetState();
    done();
  });
});
<|endoftext|>


<commit_before>"use strict"

var assert = require('chai').assert

var templates = require('../lib/templates')

function returnsADeviceObject(devices, name) {
    assert.property(devices, name);
    assert.isFunction(devices[name]);

    assert.property(devices[name](), 'name');
    assert.isString(templates.devices[name]().name);

    assert.property(devices[name](), 'type');
    assert.isString(devices[name]().type);

    assert.property(devices[name](), 'size');
    assert.isString(devices[name]().type);

    assert.property(devices[name](), 'width');
    assert.isNumber(devices[name]().width);

    assert.property(devices[name](), 'height');
    assert.isNumber(devices[name]().height);
}

describe('require("lib/template")', function() {
    describe('.devices', function() {

        describe('.chrome()', function() {
            it('returns an Device object', function() {
                returnsADeviceObject(templates.devices, 'chrome')
            })
            it('.type is "desktop"', function() {
                assert.equal(templates.devices.chrome().type, 'desktop')
            })
        })
        describe('.nexus4()', function() {
            it('returns an Device object', () => { returnsADeviceObject(templates.devices, 'nexus4') })
        })
        describe('.nexus5()', function() {
            it('returns an Device object', () => { returnsADeviceObject(templates.devices, 'nexus5') })
        })
        describe('.nexus7()', function() {
            it('returns an Device object', () => { returnsADeviceObject(templates.devices, 'nexus7') })
        })
        describe('.nexus10()', function() {
            it('returns an Device object', () => { returnsADeviceObject(templates.devices, 'nexus10') })
        })
    })
})
<commit_msg>Extend library tests<commit_after>"use strict"

var assert = require('chai').assert

var templates = require('../lib/templates')

function returnsADeviceObject(devices, name) {
    assert.property(devices, name);
    assert.isFunction(devices[name]);

    assert.property(devices[name](), 'name');
    assert.isString(templates.devices[name]().name);

    assert.property(devices[name](), 'type');
    assert.isString(devices[name]().type);

    assert.property(devices[name](), 'size');
    assert.isString(devices[name]().type);

    assert.property(devices[name](), 'width');
    assert.isNumber(devices[name]().width);

    assert.property(devices[name](), 'height');
    assert.isNumber(devices[name]().height);
}

describe('require("lib/template")', function() {
    describe('.devices', function() {
        var deviceFunction = name => templates.devices[name]

        describe('.chrome()', function() {
            var name = 'chrome'
            it('returns an Device object',function() { returnsADeviceObject(templates.devices, name) })
            it('.type is "desktop"', function() { assert.equal(deviceFunction(name)().type, 'desktop') })
        })
        describe('.nexus4()', function() {
            var name = 'nexus4'
            it('returns an Device object', () => { returnsADeviceObject(templates.devices, name) })
            it('.type is "phone"', function() { assert.equal(deviceFunction(name)().type, 'phone') })
        })
        describe('.nexus5()', function() {
            var name = 'nexus5'
            it('returns an Device object', () => { returnsADeviceObject(templates.devices, name) })
            it('.type is "phone"', function() { assert.equal(deviceFunction(name)().type, 'phone') })
        })
        describe('.nexus7()', function() {
            var name = 'nexus7'
            it('returns an Device object', () => { returnsADeviceObject(templates.devices, name) })
            it('.type is "tablet"', function() { assert.equal(deviceFunction(name)().type, 'tablet') })
        })
        describe('.nexus10()', function() {
            var name = 'nexus10'
            it('returns an Device object', () => { returnsADeviceObject(templates.devices, name) })
            it('.type is "tablet"', function() { assert.equal(deviceFunction(name)().type, 'tablet') })
        })
    })
})
<|endoftext|>