<commit_before>'use strict';

/* global describe, it */

var chai = require('chai');
var assert = chai.assert;
var base32 = require('base32.js');
var speakeasy = require('..');

// These tests use the information from RFC 4226's Appendix D: Test Values.
// http://tools.ietf.org/html/rfc4226#appendix-D

describe('Generator tests', function () {
  it('Normal generation with defaults', function () {
    var secret = speakeasy.generateSecret();
    assert.equal(secret.ascii.length, 32, 'Should return the correct length');

    // check returned fields
    assert.isDefined(secret.otpauth_url, 'otpauth:// URL should be returned');
    assert.isUndefined(secret.qr_code_ascii, 'QR Code ASCII should not be returned');
    assert.isUndefined(secret.qr_code_hex, 'QR Code Hex should not be returned');
    assert.isUndefined(secret.qr_code_base32, 'QR Code Base 32 should not be returned');
    assert.isUndefined(secret.google_auth_qr, 'Google Auth QR should not be returned');

    // check encodings
    assert.equal(Buffer(secret.hex, 'hex').toString('ascii'), secret.ascii, 'Should have encoded correct hex string');
    assert.equal(base32.decode(secret.base32).toString('ascii'), secret.ascii, 'Should have encoded correct base32 string');
  });

  it('Generation with custom key length', function () {
    var secret = speakeasy.generateSecret({length: 50});
    assert.equal(secret.ascii.length, 50, 'Should return the correct length');
  });

  it('Generation with symbols disabled', function () {
    var secret = speakeasy.generateSecret({symbols: false});
    assert.ok(/^[a-z0-9]+$/i.test(secret.ascii), 'Should return an alphanumeric key');
  });

  it('Generation with QR URL output enabled', function () {
    var secret = speakeasy.generateSecret({qr_codes: true});
    assert.isDefined(secret.qr_code_ascii, 'QR Code ASCII should be returned');
    assert.isDefined(secret.qr_code_hex, 'QR Code Hex should be returned');
    assert.isDefined(secret.qr_code_base32, 'QR Code Base 32 should be returned');
  });

  it('Generation with otpath:// URL output disabled', function () {
    var secret = speakeasy.generateSecret({otpauth_url: false});
    assert.isUndefined(secret.otpauth_url, 'Google Auth URL should not be returned');
  });

  it('Generation with Google Auth QR URL output enabled', function () {
    var secret = speakeasy.generateSecret({google_auth_qr: true});
    assert.isDefined(secret.google_auth_qr, 'Google Auth QR should be returned');
  });

  it('Testing generateSecretASCII with defaults', function () {
    var secret = speakeasy.generateSecretASCII();
    assert.equal(secret.length, 32, 'Should return the correct length');
    assert.ok(/^[a-z0-9]+$/i.test(secret.ascii), 'Should return an alphanumeric key');
  });

  it('Testing generateSecretASCII with custom length', function () {
    var secret = speakeasy.generateSecretASCII(20);
    assert.equal(secret.length, 20, 'Should return the correct length');
    assert.ok(/^[a-z0-9]+$/i.test(secret.ascii), 'Should return an alphanumeric key');
  });

  it('Testing backward compatibility (deprecated function) generate_key', function () {
    var secret = speakeasy.generate_key();
    assert.ok(secret, 'Should return a secret');
    assert.equal(secret.ascii.length, 32, 'Should return default secret length');
  });

  it('Testing backward compatibility (deprecated function) generate_key_ascii', function () {
    var secret = speakeasy.generate_key_ascii(20);
    assert.ok(secret, 'Should return a secret');
    assert.equal(secret.length, 20, 'Should return the correct length');
  });

  it('Testing otp URL generated by generateSecret', function () {
    var answer = speakeasy.generateSecret({
      name: 'Example:alice@google.com'
    });

    var secret = new Buffer(answer.ascii, 'ascii');
    if (Buffer.isBuffer(secret)) secret = base32.encode(secret);

    var expect = 'otpauth://totp/Example%3Aalice%40google.com?secret=' + secret + '&algorithm=SHA1&digits=6&period=30';
    assert.deepEqual(
      answer.otpauth_url,
      expect
    );
  });

  it('Testing otp URL generated by generate_key', function () {
    var answer = speakeasy.generate_key({
      name: 'Example:alice@google.com'
    });

    var secret = new Buffer(answer.ascii, 'ascii');
    if (Buffer.isBuffer(secret)) secret = base32.encode(secret);

    var expect = 'otpauth://totp/Example%3Aalice%40google.com?secret=' + secret + '&algorithm=SHA1&digits=6&period=30';
    assert.deepEqual(
      answer.otpauth_url,
      expect
    );
  });

  it('Testing google_auth_qr generated by generate_key', function () {
    var answer = speakeasy.generate_key({
      name: 'Example:alice@google.com',
      google_auth_qr: true
    });

    var secret = new Buffer(answer.base32, 'ascii');
    if (Buffer.isBuffer(secret)) secret = base32.encode(secret);

    var google_chart_url = 'https://chart.googleapis.com/chart?chs=166x166&chld=L|0&cht=qr&chl=';
    var encodedOtpUrl = encodeURIComponent('otpauth://totp/Example%3Aalice%40google.com?secret=' + secret + '&algorithm=SHA1&digits=6&period=30');
    var expect = google_chart_url + encodedOtpUrl;
    assert.deepEqual(
      answer.google_auth_qr,
      expect
    );
  });

  it('Testing otp URL generated with issuer by generateSecret', function () {
    var answer = speakeasy.generateSecret({
      name: 'Example:alice@google.com',
      issuer: 'issuer name'
    });

    var secret = new Buffer(answer.ascii, 'ascii');
    if (Buffer.isBuffer(secret)) secret = base32.encode(secret);

    var expect = 'otpauth://totp/Example%3Aalice%40google.com?secret=' + secret + '&issuer=issuer%20name';
    assert.deepEqual(
      answer.otpauth_url,
      expect
    );
  });
});
<commit_msg>Make the documentation of otpAuthURL consistent with code.<commit_after>'use strict';

/* global describe, it */

var chai = require('chai');
var assert = chai.assert;
var base32 = require('base32.js');
var speakeasy = require('..');

// These tests use the information from RFC 4226's Appendix D: Test Values.
// http://tools.ietf.org/html/rfc4226#appendix-D

describe('Generator tests', function () {
  it('Normal generation with defaults', function () {
    var secret = speakeasy.generateSecret();
    assert.equal(secret.ascii.length, 32, 'Should return the correct length');

    // check returned fields
    assert.isDefined(secret.otpauth_url, 'otpauth:// URL should be returned');
    assert.isUndefined(secret.qr_code_ascii, 'QR Code ASCII should not be returned');
    assert.isUndefined(secret.qr_code_hex, 'QR Code Hex should not be returned');
    assert.isUndefined(secret.qr_code_base32, 'QR Code Base 32 should not be returned');
    assert.isUndefined(secret.google_auth_qr, 'Google Auth QR should not be returned');

    // check encodings
    assert.equal(Buffer(secret.hex, 'hex').toString('ascii'), secret.ascii, 'Should have encoded correct hex string');
    assert.equal(base32.decode(secret.base32).toString('ascii'), secret.ascii, 'Should have encoded correct base32 string');
  });

  it('Generation with custom key length', function () {
    var secret = speakeasy.generateSecret({length: 50});
    assert.equal(secret.ascii.length, 50, 'Should return the correct length');
  });

  it('Generation with symbols disabled', function () {
    var secret = speakeasy.generateSecret({symbols: false});
    assert.ok(/^[a-z0-9]+$/i.test(secret.ascii), 'Should return an alphanumeric key');
  });

  it('Generation with QR URL output enabled', function () {
    var secret = speakeasy.generateSecret({qr_codes: true});
    assert.isDefined(secret.qr_code_ascii, 'QR Code ASCII should be returned');
    assert.isDefined(secret.qr_code_hex, 'QR Code Hex should be returned');
    assert.isDefined(secret.qr_code_base32, 'QR Code Base 32 should be returned');
  });

  it('Generation with otpath:// URL output disabled', function () {
    var secret = speakeasy.generateSecret({otpauth_url: false});
    assert.isUndefined(secret.otpauth_url, 'Google Auth URL should not be returned');
  });

  it('Generation with Google Auth QR URL output enabled', function () {
    var secret = speakeasy.generateSecret({google_auth_qr: true});
    assert.isDefined(secret.google_auth_qr, 'Google Auth QR should be returned');
  });

  it('Testing generateSecretASCII with defaults', function () {
    var secret = speakeasy.generateSecretASCII();
    assert.equal(secret.length, 32, 'Should return the correct length');
    assert.ok(/^[a-z0-9]+$/i.test(secret.ascii), 'Should return an alphanumeric key');
  });

  it('Testing generateSecretASCII with custom length', function () {
    var secret = speakeasy.generateSecretASCII(20);
    assert.equal(secret.length, 20, 'Should return the correct length');
    assert.ok(/^[a-z0-9]+$/i.test(secret.ascii), 'Should return an alphanumeric key');
  });

  it('Testing backward compatibility (deprecated function) generate_key', function () {
    var secret = speakeasy.generate_key();
    assert.ok(secret, 'Should return a secret');
    assert.equal(secret.ascii.length, 32, 'Should return default secret length');
  });

  it('Testing backward compatibility (deprecated function) generate_key_ascii', function () {
    var secret = speakeasy.generate_key_ascii(20);
    assert.ok(secret, 'Should return a secret');
    assert.equal(secret.length, 20, 'Should return the correct length');
  });

  it('Testing otp URL generated by generateSecret', function () {
    var answer = speakeasy.generateSecret({
      name: 'Example:alice@google.com'
    });

    var secret = new Buffer(answer.ascii, 'ascii');
    if (Buffer.isBuffer(secret)) secret = base32.encode(secret);

    var expect = 'otpauth://totp/Example%3Aalice%40google.com?secret=' + secret + '&algorithm=SHA1&digits=6&period=30';
    assert.deepEqual(
      answer.otpauth_url,
      expect
    );
  });

  it('Testing otp URL generated by generate_key', function () {
    var answer = speakeasy.generate_key({
      name: 'Example:alice@google.com'
    });

    var secret = new Buffer(answer.ascii, 'ascii');
    if (Buffer.isBuffer(secret)) secret = base32.encode(secret);

    var expect = 'otpauth://totp/Example%3Aalice%40google.com?secret=' + secret + '&algorithm=SHA1&digits=6&period=30';
    assert.deepEqual(
      answer.otpauth_url,
      expect
    );
  });

  it('Testing google_auth_qr generated by generate_key', function () {
    var answer = speakeasy.generate_key({
      name: 'Example:alice@google.com',
      google_auth_qr: true
    });

    var secret = new Buffer(answer.base32, 'ascii');
    if (Buffer.isBuffer(secret)) secret = base32.encode(secret);

    var google_chart_url = 'https://chart.googleapis.com/chart?chs=166x166&chld=L|0&cht=qr&chl=';
    var encodedOtpUrl = encodeURIComponent('otpauth://totp/Example%3Aalice%40google.com?secret=' + secret + '&algorithm=SHA1&digits=6&period=30');
    var expect = google_chart_url + encodedOtpUrl;
    assert.deepEqual(
      answer.google_auth_qr,
      expect
    );
  });

  it('Testing otp URL generated with issuer by generateSecret', function () {
    var answer = speakeasy.generateSecret({
      name: 'Example:alice@google.com',
      issuer: 'issuer name'
    });

    var secret = new Buffer(answer.ascii, 'ascii');
    if (Buffer.isBuffer(secret)) secret = base32.encode(secret);

    var expect = 'otpauth://totp/Example%3Aalice%40google.com?secret=' + secret + '&issuer=issuer%20name&algorithm=SHA1&digits=6&period=30';
    assert.deepEqual(
      answer.otpauth_url,
      expect
    );
  });
});
<|endoftext|>


<commit_before>import { expect } from 'chai';

import getType, { SelectorType } from '../src/core/selector-type';

describe('getType(selector)', function() {
    describe('Selectors', () => {
        it('Invalid selector (E E)', () => {
            expect(getType('div span')).to.equal(SelectorType.Invalid);
        });

        it('Invalid selector (E.class.class)', () => {
            expect(getType('div.class1.class2')).to.equal(SelectorType.Invalid);
        });

        it('Invalid selector (E.class#id)', () => {
            expect(getType('div.class#id')).to.equal(SelectorType.Invalid);
        });

        it('Invalid selector (E#id#id)', () => {
            expect(getType('div#id1#id2')).to.equal(SelectorType.Invalid);
        });

        it('Invalid selector (E#id.class)', () => {
            expect(getType('div#id.class')).to.equal(SelectorType.Invalid);
        });

        it('Type selector (E)', () => {
            expect(getType('div')).to.equal(SelectorType.Type);
        });

        it('Attribute selector (E[foo])', () => {
            expect(getType('div[test]')).to.equal(SelectorType.Attribute);
        });

        it('Attribute exact selector (E[foo="bar"])', () => {
            expect(getType('a[href="a"]')).to.equal(SelectorType.AttributeExact);
        });

        it('Attribute prefix selector (E[foo^="bar"])', () => {
            expect(getType('a[href^="a"]')).to.equal(SelectorType.AttributePrefix);
        });

        it('Attribute suffix selector (E[foo$="bar"])', () => {
            expect(getType('a[href$="a"]')).to.equal(SelectorType.AttributeSuffix);
        });

        it('Attribute contains selector (E[foo*="bar"])', () => {
            expect(getType('a[href*="a"]')).to.equal(SelectorType.AttributeContains);
        });

        it('Class selector (.class)', () => {
            expect(getType('.class')).to.equal(SelectorType.Class);
        });

        it('Element.Class selector (E.class)', () => {
            expect(getType('E.class')).to.equal(SelectorType.TypeClass);
        });

        it('Id selector (#id)', () => {
            expect(getType('#id')).to.equal(SelectorType.Id);
        });

        it('Element#Id selector (E#id)', () => {
            expect(getType('E#div')).to.equal(SelectorType.TypeId);
        });
    });
});<commit_msg>adds tests for more invalid selectors #2<commit_after>import { expect } from 'chai';

import getType, { SelectorType } from '../src/core/selector-type';

describe('getType(selector)', function() {
    describe('Selectors', () => {
        it('Invalid selector (E )', () => {
            expect(getType('div ')).to.equal(SelectorType.Invalid);
        });

        it('Invalid selector ( E)', () => {
            expect(getType(' div')).to.equal(SelectorType.Invalid);
        });

        it('Invalid selector (E E)', () => {
            expect(getType('div span')).to.equal(SelectorType.Invalid);
        });

        it('Invalid selector (E.class.class)', () => {
            expect(getType('div.class1.class2')).to.equal(SelectorType.Invalid);
        });

        it('Invalid selector (E.class#id)', () => {
            expect(getType('div.class#id')).to.equal(SelectorType.Invalid);
        });

        it('Invalid selector (E#id#id)', () => {
            expect(getType('div#id1#id2')).to.equal(SelectorType.Invalid);
        });

        it('Invalid selector (E#id.class)', () => {
            expect(getType('div#id.class')).to.equal(SelectorType.Invalid);
        });

        it('Type selector (E)', () => {
            expect(getType('div')).to.equal(SelectorType.Type);
        });

        it('Attribute selector (E[foo])', () => {
            expect(getType('div[test]')).to.equal(SelectorType.Attribute);
        });

        it('Attribute exact selector (E[foo="bar"])', () => {
            expect(getType('a[href="a"]')).to.equal(SelectorType.AttributeExact);
        });

        it('Attribute prefix selector (E[foo^="bar"])', () => {
            expect(getType('a[href^="a"]')).to.equal(SelectorType.AttributePrefix);
        });

        it('Attribute suffix selector (E[foo$="bar"])', () => {
            expect(getType('a[href$="a"]')).to.equal(SelectorType.AttributeSuffix);
        });

        it('Attribute contains selector (E[foo*="bar"])', () => {
            expect(getType('a[href*="a"]')).to.equal(SelectorType.AttributeContains);
        });

        it('Class selector (.class)', () => {
            expect(getType('.class')).to.equal(SelectorType.Class);
        });

        it('Element.Class selector (E.class)', () => {
            expect(getType('E.class')).to.equal(SelectorType.TypeClass);
        });

        it('Id selector (#id)', () => {
            expect(getType('#id')).to.equal(SelectorType.Id);
        });

        it('Element#Id selector (E#id)', () => {
            expect(getType('E#div')).to.equal(SelectorType.TypeId);
        });
    });
});<|endoftext|>


<commit_before>'use strict';

var assert = require('assert')
  , xmpp = require('./../lib/xmpp')

describe('JID', function() {

    describe('parsing', function() {

        it('should parse a "domain" JID', function() {
            var j = new xmpp.JID('d')
            assert.equal(j.user, null)
            assert.equal(j.domain, 'd')
            assert.equal(j.resource, null)
        })
        it('should parse a "user@domain" JID', function() {
            var j = new xmpp.JID('u@d')
            assert.equal(j.user, 'u')
            assert.equal(j.domain, 'd')
            assert.equal(j.resource, null)
        })
        it('should parse a "domain/resource" JID', function() {
            var j = new xmpp.JID('d/r')
            assert.equal(j.user, null)
            assert.equal(j.domain, 'd')
            assert.equal(j.resource, 'r')
        })
        it('should parse a "user@domain/resource" JID', function() {
            var j = new xmpp.JID('u@d/r')
            assert.equal(j.user, 'u')
            assert.equal(j.domain, 'd')
            assert.equal(j.resource, 'r')
        })
        it('should parse an internationalized domain name as unicode', function() {
            var j = new xmpp.JID('öko.de')
            assert.equal(j.domain, 'öko.de')
        })

        try {
            // HACK: these tests fail if node-stringprep is not used
            require('node-stringprep')

            it('should parse an internationalized domain name as ascii/punycode', function() {
                var j = new xmpp.JID('xn--ko-eka.de')
                assert.equal(j.domain, 'öko.de')
            })

            it('should parse a JID with punycode', function() {
                var j = new xmpp.JID('Сергей@xn--lsa92diaqnge.xn--p1ai')
                assert.equal(j.user, 'сергей')
                assert.equal(j.domain, 'приме́р.рф')
            })

        } catch (ex) {
            //ignore
        }
    })

    describe('serialization', function() {

        it('should serialize a "domain" JID', function() {
            var j = new xmpp.JID(null, 'd')
            assert.equal(j.toString(), 'd')
        })

        it('should serialize a "user@domain" JID', function() {
            var j = new xmpp.JID('u', 'd')
            assert.equal(j.toString(), 'u@d')
        })

        it('should serialize a "domain/resource" JID', function() {
            var j = new xmpp.JID(null, 'd', 'r')
            assert.equal(j.toString(), 'd/r')
        })

        it('should serialize a "user@domain/resource" JID', function() {
            var j = new xmpp.JID('u', 'd', 'r')
            assert.equal(j.toString(), 'u@d/r')
        })

    })

    describe('equality', function() {

        it('should parsed JIDs should be equal', function() {
            var j1 = new xmpp.JID('foo@bar/baz')
            var j2 = new xmpp.JID('foo@bar/baz')
            assert.equal(j1.equals(j2), true)
        })

        it('should parsed JIDs should be not equal', function() {
            var j1 = new xmpp.JID('foo@bar/baz')
            var j2 = new xmpp.JID('quux@bar/baz')
            assert.equal(j1.equals(j2), false)
        })

        it('should should ignore case in user', function() {
            var j1 = new xmpp.JID('foo@bar/baz')
            var j2 = new xmpp.JID('FOO@bar/baz')
            assert.equal(j1.equals(j2), true)
        })

        it('should should ignore case in domain', function() {
            var j1 = new xmpp.JID('foo@bar/baz')
            var j2 = new xmpp.JID('foo@BAR/baz')
            assert.equal(j1.equals(j2), true)
        })

        it('should should not ignore case in resource', function() {
            var j1 = new xmpp.JID('foo@bar/baz')
            var j2 = new xmpp.JID('foo@bar/Baz')
            assert.equal(j1.equals(j2), false)
        })

        it('should should ignore international caseness', function() {
            var j1 = new xmpp.JID('föö@bär/baß')
            var j2 = new xmpp.JID('fÖö@BÄR/baß')
            assert.equal(j1.equals(j2), true)
        })

    })

})<commit_msg>JID parsing should parse an empty domain JID<commit_after>'use strict';

var assert = require('assert')
  , xmpp = require('./../lib/xmpp')

describe('JID', function() {

    describe('parsing', function() {

        it('should parse a "domain" JID', function() {
            var j = new xmpp.JID('d')
            assert.equal(j.user, null)
            assert.equal(j.domain, 'd')
            assert.equal(j.resource, null)
        })
        it('should parse a "user@domain" JID', function() {
            var j = new xmpp.JID('u@d')
            assert.equal(j.user, 'u')
            assert.equal(j.domain, 'd')
            assert.equal(j.resource, null)
        })
        it('should parse a "domain/resource" JID', function() {
            var j = new xmpp.JID('d/r')
            assert.equal(j.user, null)
            assert.equal(j.domain, 'd')
            assert.equal(j.resource, 'r')
        })
        it('should parse a "user@domain/resource" JID', function() {
            var j = new xmpp.JID('u@d/r')
            assert.equal(j.user, 'u')
            assert.equal(j.domain, 'd')
            assert.equal(j.resource, 'r')
        })
        it('should parse an internationalized domain name as unicode', function() {
            var j = new xmpp.JID('öko.de')
            assert.equal(j.domain, 'öko.de')
        })
        it('should parse an empty domain JID (#109)', function() {
            var j = new xmpp.JID('u@d', '')
            assert.equal(j.user, 'u')
            assert.equal(j.domain, 'd')
            assert.equal(j.resource, null)
        })

        try {
            // HACK: these tests fail if node-stringprep is not used
            require('node-stringprep')

            it('should parse an internationalized domain name as ascii/punycode', function() {
                var j = new xmpp.JID('xn--ko-eka.de')
                assert.equal(j.domain, 'öko.de')
            })

            it('should parse a JID with punycode', function() {
                var j = new xmpp.JID('Сергей@xn--lsa92diaqnge.xn--p1ai')
                assert.equal(j.user, 'сергей')
                assert.equal(j.domain, 'приме́р.рф')
            })

        } catch (ex) {
            //ignore
        }
    })

    describe('serialization', function() {

        it('should serialize a "domain" JID', function() {
            var j = new xmpp.JID(null, 'd')
            assert.equal(j.toString(), 'd')
        })

        it('should serialize a "user@domain" JID', function() {
            var j = new xmpp.JID('u', 'd')
            assert.equal(j.toString(), 'u@d')
        })

        it('should serialize a "domain/resource" JID', function() {
            var j = new xmpp.JID(null, 'd', 'r')
            assert.equal(j.toString(), 'd/r')
        })

        it('should serialize a "user@domain/resource" JID', function() {
            var j = new xmpp.JID('u', 'd', 'r')
            assert.equal(j.toString(), 'u@d/r')
        })

    })

    describe('equality', function() {

        it('should parsed JIDs should be equal', function() {
            var j1 = new xmpp.JID('foo@bar/baz')
            var j2 = new xmpp.JID('foo@bar/baz')
            assert.equal(j1.equals(j2), true)
        })

        it('should parsed JIDs should be not equal', function() {
            var j1 = new xmpp.JID('foo@bar/baz')
            var j2 = new xmpp.JID('quux@bar/baz')
            assert.equal(j1.equals(j2), false)
        })

        it('should should ignore case in user', function() {
            var j1 = new xmpp.JID('foo@bar/baz')
            var j2 = new xmpp.JID('FOO@bar/baz')
            assert.equal(j1.equals(j2), true)
        })

        it('should should ignore case in domain', function() {
            var j1 = new xmpp.JID('foo@bar/baz')
            var j2 = new xmpp.JID('foo@BAR/baz')
            assert.equal(j1.equals(j2), true)
        })

        it('should should not ignore case in resource', function() {
            var j1 = new xmpp.JID('foo@bar/baz')
            var j2 = new xmpp.JID('foo@bar/Baz')
            assert.equal(j1.equals(j2), false)
        })

        it('should should ignore international caseness', function() {
            var j1 = new xmpp.JID('föö@bär/baß')
            var j2 = new xmpp.JID('fÖö@BÄR/baß')
            assert.equal(j1.equals(j2), true)
        })

    })

})<|endoftext|>


<commit_before>// http.js
//
// HTTP utilities for testing
//
// Copyright 2012, StatusNet Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var http = require('http'),
    _ = require('underscore');

var options = function(host, port, path, callback) {

    var reqOpts = {
        host: host,
        port: port,
        path: path,
        method: 'OPTIONS'
    };

    var req = http.request(options, function(res) {
        var body = '';
        res.setEncoding('utf8');
        res.on('data', function(chunk) {
            body = body + chunk;
        });
        res.on('error', function(err) {
            callback(err, null, null, null);
        });
        res.on('end', function() {
            var allow = [];
            if (_(res.headers).has('allow')) {
                allow = res.headers.allow.split(',').map(function(s) { return s.trim(); });
            }
            callback(null, allow, res, body);
        });
    });

    req.on('error', function(err) {
        callback(err, null, null, null);
    });

    req.end();
};<commit_msg>add exports<commit_after>// http.js
//
// HTTP utilities for testing
//
// Copyright 2012, StatusNet Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var http = require('http'),
    _ = require('underscore');

var options = function(host, port, path, callback) {

    var reqOpts = {
        host: host,
        port: port,
        path: path,
        method: 'OPTIONS'
    };

    var req = http.request(options, function(res) {
        var body = '';
        res.setEncoding('utf8');
        res.on('data', function(chunk) {
            body = body + chunk;
        });
        res.on('error', function(err) {
            callback(err, null, null, null);
        });
        res.on('end', function() {
            var allow = [];
            if (_(res.headers).has('allow')) {
                allow = res.headers.allow.split(',').map(function(s) { return s.trim(); });
            }
            callback(null, allow, res, body);
        });
    });

    req.on('error', function(err) {
        callback(err, null, null, null);
    });

    req.end();
};

exports.options = options;
<|endoftext|>


<commit_before>import should from 'should';
import nock from 'nock';
import {Service, Characteristic} from 'HAP-NodeJS';

import { SwitchItem } from '../lib/SwitchItem.js';

process.env.NODE_ENV = 'test';

function createSwitchItem() {
  return new SwitchItem('switchItemName', 'http://openhab.test/switchItem', '1');
}

describe('SwitchItem', function () {

  it('should contain AccessoryInformation & Lightbulb services', function () {
    let switchItem = createSwitchItem();
    switchItem.should.have.property('accessory');
    switchItem.accessory.getService(Service.AccessoryInformation).should.not.be.empty;
    switchItem.accessory.getService(Service.Lightbulb).should.not.be.empty;
  });

  it('should have set the correct name', function () {
    let switchItem = createSwitchItem();
    let accessory = switchItem.accessory;
    accessory.getService(Service.AccessoryInformation)
      .getCharacteristic(Characteristic.Name).value.should.equal('switchItemName');
    accessory.getService(Service.Lightbulb)
      .getCharacteristic(Characteristic.Name).value.should.equal('switchItemName');
  });

});
<commit_msg>add websocket connection test<commit_after>import should from 'should';
import nock from 'nock';
import {Service, Characteristic} from 'HAP-NodeJS';

import { SwitchItem } from '../lib/SwitchItem.js';

process.env.NODE_ENV = 'test';

function createSwitchItem() {
  return new SwitchItem('switchItemName', 'http://openhab.test/rest/switchItem', 'ON');
}

describe('SwitchItem', function () {

  it('should contain AccessoryInformation & Lightbulb services', function () {
    let switchItem = createSwitchItem();
    switchItem.should.have.property('accessory');
    switchItem.accessory.getService(Service.AccessoryInformation).should.not.be.empty;
    switchItem.accessory.getService(Service.Lightbulb).should.not.be.empty;
  });

  it('should have set the correct name', function () {
    let switchItem = createSwitchItem();
    let accessory = switchItem.accessory;
    accessory.getService(Service.AccessoryInformation)
      .getCharacteristic(Characteristic.Name).value.should.equal('switchItemName');
    accessory.getService(Service.Lightbulb)
      .getCharacteristic(Characteristic.Name).value.should.equal('switchItemName');
  });

  it('should have set the initial value', function () {
    let switchItem = createSwitchItem();
    switchItem.accessory.getService(Service.Lightbulb)
      .getCharacteristic(Characteristic.On).value.should.be.true;
  });

  it('should make web socket connection to OpenHAB', function (done) {
    nock('http://openhab.test')
      .get('/rest/switchItem/state?type=json')
      .reply(200, function(uri, requestBody) {
        should(true).be.true;
        done();
      });
    createSwitchItem();
  });

});
<|endoftext|>


<commit_before>'use strict';

import $ from 'jquery';
import Marionette from 'backbone.marionette';
import SwipeToDeleteView from '../src/js/main';
import State from '../src/js/model';
import DelView from '../src/js/delete';

describe('The MainView', function () {
	class View extends Marionette.ItemView {
		template() {
			return '
Test
';
		}
	}

	let swipeToDeleteView;

	function renderView() {
		let cont = document.createElement('div');
		document.body.appendChild(cont);
		swipeToDeleteView = new SwipeToDeleteView({View, el: cont});
		swipeToDeleteView.render();
	}

	it('do an instance', () => {
		swipeToDeleteView = new SwipeToDeleteView({View});
		expect(typeof swipeToDeleteView).toBe('object');
	});

	it('has the "swipe-to-delete" class', () => {
		swipeToDeleteView = new SwipeToDeleteView({View});
		expect(swipeToDeleteView.$el.hasClass('swipe-to-delete')).toBe(true);
	});

	it('has "js-delete" and "js-content" elements', () => {
		swipeToDeleteView = new SwipeToDeleteView({View});
		swipeToDeleteView.render();

		expect(swipeToDeleteView.$('.js-delete').length).toBe(1);
		expect(swipeToDeleteView.$('.js-content').length).toBe(1);
	});

	describe('initializing', () => {
		it('accept options', () => {
			expect(() => {
				new SwipeToDeleteView()
			}).toThrowError('"View" can be any Backbone.View or be derived from Marionette.ItemView.');
			expect(() => {
				new SwipeToDeleteView({View: 'dummy'})
			}).toThrowError('"View" can be any Backbone.View or be derived from Marionette.ItemView.');
			expect(() => {
				new SwipeToDeleteView({View: View, DeleteView: 'dummy'})
			}).toThrowError('"DeleteView" can be any Backbone.View or be derived from Marionette.ItemView.');
		});

		it('validate the "deleteSwipe" option', () => {
			spyOn(State.prototype, 'validate');
			new SwipeToDeleteView({View: View});
			expect(State.prototype.validate).toHaveBeenCalled();
		});
	});

	it('render child views', () => {
		spyOn(DelView.prototype, 'render');
		spyOn(View.prototype, 'render');

		swipeToDeleteView = new SwipeToDeleteView({View});
		swipeToDeleteView.render();

		expect(View.prototype.render).toHaveBeenCalled();
		expect(DelView.prototype.render).toHaveBeenCalled();
	});

	describe('when start to interact', () => {
		afterEach(() => {
			swipeToDeleteView.destroy();
		});

		it('should call "interact"', () => {
			spyOn(SwipeToDeleteView.prototype, 'interact');
			renderView();

			let $el = swipeToDeleteView.$('.js-content > *');

			expect(SwipeToDeleteView.prototype.interact).not.toHaveBeenCalled();
			$el.trigger('mousedown');
			expect(SwipeToDeleteView.prototype.interact).toHaveBeenCalled();

			$el.trigger('mouseup');
		});

		it('should call "stopInteract"', () => {
			spyOn(SwipeToDeleteView.prototype, 'stopInteract').and.callThrough();
			renderView();

			let $el = swipeToDeleteView.$('.js-content > *');

			expect(SwipeToDeleteView.prototype.stopInteract).not.toHaveBeenCalled();
			$el.trigger('mousedown');
			expect(SwipeToDeleteView.prototype.stopInteract).toHaveBeenCalled();

			$el.trigger('mouseup');
		});
	});

	describe('when interact', () => {
		it('should move a view', () => {
			spyOn(SwipeToDeleteView.prototype, 'moveAt');
			renderView();

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');

			expect(SwipeToDeleteView.prototype.moveAt).not.toHaveBeenCalled();
			$(document).trigger('mousemove');
			expect(SwipeToDeleteView.prototype.moveAt).toHaveBeenCalled();

			$el.trigger('mouseup');
		});
	});

	describe('when stop interacting', () => {
		it('should call "offInteract" by "mouseup"', () => {
			spyOn(SwipeToDeleteView.prototype, 'offInteract');
			renderView();

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');
			$(document).trigger('mousemove');

			expect(SwipeToDeleteView.prototype.offInteract).not.toHaveBeenCalled();
			$el.trigger('mouseup');
			expect(SwipeToDeleteView.prototype.offInteract).toHaveBeenCalled();
		});

		it('should call "offInteract" by "mouseleave"', () => {
			spyOn(SwipeToDeleteView.prototype, 'offInteract');
			renderView();

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');
			$(document).trigger('mousemove');

			expect(SwipeToDeleteView.prototype.offInteract).not.toHaveBeenCalled();
			$el.trigger('mouseleave');
			expect(SwipeToDeleteView.prototype.offInteract).toHaveBeenCalled();
		});

		it('should call "endInteract"', () => {
			spyOn(SwipeToDeleteView.prototype, 'endInteract');
			renderView();

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');
			$(document).trigger('mousemove');

			expect(SwipeToDeleteView.prototype.endInteract).not.toHaveBeenCalled();
			$el.trigger('mouseup');
			expect(SwipeToDeleteView.prototype.endInteract).toHaveBeenCalled();
		});
	});

	describe('when is deleted', () => {
		it('should add the class "js-transition-delete-right"', () => {
			renderView();
			spyOn(swipeToDeleteView, 'getSwipePercent').and.callFake(() => .7);

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');
			$(document).trigger('mousemove');
			$el.trigger('mouseup');

			expect($el.hasClass('js-transition-delete-right')).toBe(true);
		});

		it('should add the class "js-transition-delete-left"', () => {
			renderView();
			spyOn(swipeToDeleteView, 'getSwipePercent').and.callFake(() => -.7);

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');
			$(document).trigger('mousemove');
			$el.trigger('mouseup');

			expect($el.hasClass('js-transition-delete-left')).toBe(true);
		});

		it('should call "onDelete"', () => {
			renderView();
			spyOn(swipeToDeleteView, 'getSwipePercent').and.callFake(() => .7);
			spyOn(swipeToDeleteView, 'onDelete');

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');
			$(document).trigger('mousemove');
			$el.trigger('mouseup');
			$el.trigger('transitionend');

			expect(swipeToDeleteView.onDelete).toHaveBeenCalled();
		});

		it('"onDelete" should trigger "swipe:delete" events on a content view', () => {
			renderView();
			swipeToDeleteView.getRegion('content').currentView.onSwipeDelete = () => {};

			spyOn(swipeToDeleteView, 'getSwipePercent').and.callFake(() => .7);
			spyOn(swipeToDeleteView.getRegion('content').currentView, 'onSwipeDelete');

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');
			$(document).trigger('mousemove');
			$el.trigger('mouseup');
			$el.trigger('transitionend');

			expect(swipeToDeleteView.getRegion('content').currentView.onSwipeDelete).toHaveBeenCalled();
		});
	});

	describe('when is canceled', () => {
		it('should add the class "js-transition-cancel"', () => {
			renderView();
			spyOn(swipeToDeleteView, 'getSwipePercent').and.callFake(() => .1);

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');
			$(document).trigger('mousemove');
			$el.trigger('mouseup');

			expect($el.hasClass('js-transition-cancel')).toBe(true);
		});

		it('should call "onCancel"', () => {
			renderView();
			spyOn(swipeToDeleteView, 'getSwipePercent').and.callFake(() => .1);
			spyOn(swipeToDeleteView, 'onCancel');

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');
			$(document).trigger('mousemove');
			$el.trigger('mouseup');
			$el.trigger('transitionend');

			expect(swipeToDeleteView.onCancel).toHaveBeenCalled();
		});

		it('"onCancel" should trigger "swipe:cancel" events on a content view', () => {
			renderView();
			swipeToDeleteView.getRegion('content').currentView.onSwipeCancel = () => {};

			spyOn(swipeToDeleteView, 'getSwipePercent').and.callFake(() => .1);
			spyOn(swipeToDeleteView.getRegion('content').currentView, 'onSwipeCancel');

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');
			$(document).trigger('mousemove');
			$el.trigger('mouseup');
			$el.trigger('transitionend');

			expect(swipeToDeleteView.getRegion('content').currentView.onSwipeCancel).toHaveBeenCalled();
		});

		it('"onCancel" should remove the class "js-transition-cancel"', () => {
			renderView();
			spyOn(swipeToDeleteView, 'getSwipePercent').and.callFake(() => .1);

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');
			$(document).trigger('mousemove');
			$el.trigger('mouseup');
			$el.trigger('transitionend');

			expect($el.hasClass('js-transition-cancel')).toBe(false);
		});

		it('"onCancel" should reset "startX"', () => {
			renderView();
			spyOn(swipeToDeleteView, 'getSwipePercent').and.callFake(() => .1);

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');
			$(document).trigger('mousemove');
			$el.trigger('mouseup');
			$el.trigger('transitionend');

			expect(swipeToDeleteView.state.get('startX')).toBe(0);
		});
	});
});<commit_msg>Refactoring a mainView test<commit_after>'use strict';

import $ from 'jquery';
import Marionette from 'backbone.marionette';
import SwipeToDeleteView from '../src/js/main';
import State from '../src/js/model';
import DelView from '../src/js/delete';

class View extends Marionette.ItemView {
	template() {
		return '
Test
';
	}
}

let swipeToDeleteView;

function renderView() {
	let el = document.createElement('div');
	document.body.appendChild(el);
	swipeToDeleteView = new SwipeToDeleteView({View, el}).render();
}

function triggerAllSequenceEvents($el) {
	$el.trigger('mousedown');
	$(document).trigger('mousemove');
	$el.trigger('mouseup');
	$el.trigger('transitionend');
}

describe('The MainView', function () {
	afterEach(() => {
		$(document).off();
		swipeToDeleteView.destroy();
	});

	it('do an instance', () => {
		swipeToDeleteView = new SwipeToDeleteView({View});
		expect(typeof swipeToDeleteView).toBe('object');
	});

	it('has the "swipe-to-delete" class', () => {
		swipeToDeleteView = new SwipeToDeleteView({View});
		expect(swipeToDeleteView.$el.hasClass('swipe-to-delete')).toBe(true);
	});

	it('has "js-delete" and "js-content" elements', () => {
		swipeToDeleteView = new SwipeToDeleteView({View});
		swipeToDeleteView.render();

		expect(swipeToDeleteView.$('.js-delete').length).toBe(1);
		expect(swipeToDeleteView.$('.js-content').length).toBe(1);
	});

	describe('initializing', () => {
		it('accept options', () => {
			expect(() => new SwipeToDeleteView()).toThrowError('"View" can be any Backbone.View or be derived from Marionette.ItemView.');
			expect(() => new SwipeToDeleteView({View: 'dummy'})).toThrowError('"View" can be any Backbone.View or be derived from Marionette.ItemView.');
			expect(() => new SwipeToDeleteView({View: View, DeleteView: 'dummy'})).toThrowError('"DeleteView" can be any Backbone.View or be derived from Marionette.ItemView.');
		});

		it('validate the "deleteSwipe" option', () => {
			spyOn(State.prototype, 'validate');
			new SwipeToDeleteView({View: View});
			expect(State.prototype.validate).toHaveBeenCalled();
		});
	});

	it('render child views', () => {
		spyOn(DelView.prototype, 'render');
		spyOn(View.prototype, 'render');

		swipeToDeleteView = new SwipeToDeleteView({View});
		swipeToDeleteView.render();

		expect(View.prototype.render).toHaveBeenCalled();
		expect(DelView.prototype.render).toHaveBeenCalled();
	});

	describe('when start to interact', () => {
		it('should call "interact"', () => {
			spyOn(SwipeToDeleteView.prototype, 'interact');
			renderView();

			let $el = swipeToDeleteView.$('.js-content > *');

			expect(SwipeToDeleteView.prototype.interact).not.toHaveBeenCalled();
			$el.trigger('mousedown');
			expect(SwipeToDeleteView.prototype.interact).toHaveBeenCalled();

			$el.trigger('mouseup');
		});

		it('should call "stopInteract"', () => {
			spyOn(SwipeToDeleteView.prototype, 'stopInteract').and.callThrough();
			renderView();

			let $el = swipeToDeleteView.$('.js-content > *');

			expect(SwipeToDeleteView.prototype.stopInteract).not.toHaveBeenCalled();
			$el.trigger('mousedown');
			expect(SwipeToDeleteView.prototype.stopInteract).toHaveBeenCalled();

			$el.trigger('mouseup');
		});
	});

	it('when interact should move a view', () => {
		spyOn(SwipeToDeleteView.prototype, 'moveAt');
		renderView();

		let $el = swipeToDeleteView.$('.js-content > *');

		$el.trigger('mousedown');

		expect(SwipeToDeleteView.prototype.moveAt).not.toHaveBeenCalled();
		$(document).trigger('mousemove');
		expect(SwipeToDeleteView.prototype.moveAt).toHaveBeenCalled();

		$el.trigger('mouseup');
	});

	describe('when stop interacting', () => {
		it('should call "offInteract" by "mouseup"', () => {
			spyOn(SwipeToDeleteView.prototype, 'offInteract');
			renderView();

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');
			$(document).trigger('mousemove');

			expect(SwipeToDeleteView.prototype.offInteract).not.toHaveBeenCalled();
			$el.trigger('mouseup');
			expect(SwipeToDeleteView.prototype.offInteract).toHaveBeenCalled();
		});

		it('should call "offInteract" by "mouseleave"', () => {
			spyOn(SwipeToDeleteView.prototype, 'offInteract');
			renderView();

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');
			$(document).trigger('mousemove');

			expect(SwipeToDeleteView.prototype.offInteract).not.toHaveBeenCalled();
			$el.trigger('mouseleave');
			expect(SwipeToDeleteView.prototype.offInteract).toHaveBeenCalled();
			$el.trigger('mouseup');
		});

		it('should call "endInteract"', () => {
			spyOn(SwipeToDeleteView.prototype, 'endInteract');
			renderView();

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');
			$(document).trigger('mousemove');

			expect(SwipeToDeleteView.prototype.endInteract).not.toHaveBeenCalled();
			$el.trigger('mouseup');
			expect(SwipeToDeleteView.prototype.endInteract).toHaveBeenCalled();
		});
	});

	describe('when is deleted', () => {
		it('should add the class "js-transition-delete-right"', () => {
			renderView();
			spyOn(swipeToDeleteView, 'getSwipePercent').and.callFake(() => .7);

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');
			$(document).trigger('mousemove');
			$el.trigger('mouseup');

			expect($el.hasClass('js-transition-delete-right')).toBe(true);
		});

		it('should add the class "js-transition-delete-left"', () => {
			renderView();
			spyOn(swipeToDeleteView, 'getSwipePercent').and.callFake(() => -.7);

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');
			$(document).trigger('mousemove');
			$el.trigger('mouseup');

			expect($el.hasClass('js-transition-delete-left')).toBe(true);
		});

		it('should call "onDelete"', () => {
			renderView();
			spyOn(swipeToDeleteView, 'getSwipePercent').and.callFake(() => .7);
			spyOn(swipeToDeleteView, 'onDelete');

			triggerAllSequenceEvents(swipeToDeleteView.$('.js-content > *'));

			expect(swipeToDeleteView.onDelete).toHaveBeenCalled();
		});

		it('"onDelete" should trigger "swipe:delete" events on a content view', () => {
			renderView();
			swipeToDeleteView.getRegion('content').currentView.onSwipeDelete = () => {};

			spyOn(swipeToDeleteView, 'getSwipePercent').and.callFake(() => .7);
			spyOn(swipeToDeleteView.getRegion('content').currentView, 'onSwipeDelete');

			triggerAllSequenceEvents(swipeToDeleteView.$('.js-content > *'));

			expect(swipeToDeleteView.getRegion('content').currentView.onSwipeDelete).toHaveBeenCalled();
		});
	});

	describe('when is canceled', () => {
		it('should add the class "js-transition-cancel"', () => {
			renderView();
			spyOn(swipeToDeleteView, 'getSwipePercent').and.callFake(() => .1);

			let $el = swipeToDeleteView.$('.js-content > *');

			$el.trigger('mousedown');
			$(document).trigger('mousemove');
			$el.trigger('mouseup');

			expect($el.hasClass('js-transition-cancel')).toBe(true);
		});

		it('should call "onCancel"', () => {
			renderView();
			spyOn(swipeToDeleteView, 'getSwipePercent').and.callFake(() => .1);
			spyOn(swipeToDeleteView, 'onCancel');

			triggerAllSequenceEvents(swipeToDeleteView.$('.js-content > *'));

			expect(swipeToDeleteView.onCancel).toHaveBeenCalled();
		});

		it('"onCancel" should trigger "swipe:cancel" events on a content view', () => {
			renderView();
			swipeToDeleteView.getRegion('content').currentView.onSwipeCancel = () => {};

			spyOn(swipeToDeleteView, 'getSwipePercent').and.callFake(() => .1);
			spyOn(swipeToDeleteView.getRegion('content').currentView, 'onSwipeCancel');

			triggerAllSequenceEvents(swipeToDeleteView.$('.js-content > *'));

			expect(swipeToDeleteView.getRegion('content').currentView.onSwipeCancel).toHaveBeenCalled();
		});

		it('"onCancel" should remove the class "js-transition-cancel"', () => {
			renderView();
			spyOn(swipeToDeleteView, 'getSwipePercent').and.callFake(() => .1);

			let $el = swipeToDeleteView.$('.js-content > *');
			triggerAllSequenceEvents($el);

			expect($el.hasClass('js-transition-cancel')).toBe(false);
		});

		it('"onCancel" should reset "startX"', () => {
			renderView();
			spyOn(swipeToDeleteView, 'getSwipePercent').and.callFake(() => .1);

			let $el = swipeToDeleteView.$('.js-content > *');
			triggerAllSequenceEvents($el);

			expect(swipeToDeleteView.state.get('startX')).toBe(0);
		});
	});
});<|endoftext|>


<commit_before>var should = require("should");
var path = require("path");
var fs = require("fs");
var vm = require("vm");
var Test = require("mocha/lib/test");
var checkArrayExpectation = require("./checkArrayExpectation");

var Stats = require("../lib/Stats");
var webpack = require("../lib/webpack");

describe("TestCases", function() {
	var casesPath = path.join(__dirname, "cases");
	var categories = fs.readdirSync(casesPath);
	categories = categories.map(function(cat) {
		return {
			name: cat,
			tests: fs.readdirSync(path.join(casesPath, cat)).filter(function(folder) {
				return folder.indexOf("_") < 0;
			})
		};
	});
	[{
		name: "normal"
	}, {
		name: "hot",
		plugins: [
			new webpack.HotModuleReplacementPlugin()
		]
	}, {
		name: "hot-multi-step",
		plugins: [
			new webpack.HotModuleReplacementPlugin({
				multiStep: true
			})
		]
	}, {
		name: "devtool-eval",
		devtool: "eval"
	}, {
		name: "devtool-eval-named-modules",
		devtool: "eval",
		plugins: [
			new webpack.NamedModulesPlugin()
		]
	}, {
		name: "devtool-eval-source-map",
		devtool: "#eval-source-map"
	}, {
		name: "devtool-inline-source-map",
		devtool: "inline-source-map"
	}, {
		name: "devtool-source-map",
		devtool: "#@source-map"
	}, {
		name: "devtool-cheap-inline-source-map",
		devtool: "cheap-inline-source-map"
	}, {
		name: "devtool-cheap-eval-source-map",
		devtool: "cheap-eval-source-map"
	}, {
		name: "devtool-cheap-eval-module-source-map",
		devtool: "cheap-eval-module-source-map"
	}, {
		name: "devtool-cheap-source-map",
		devtool: "cheap-source-map"
	}, {
		name: "minimized",
		minimize: true,
		plugins: [
			new webpack.optimize.UglifyJsPlugin({
				sourceMap: false
			})
		]
	}, {
		name: "minimized-source-map",
		minimize: true,
		plugins: [
			new webpack.optimize.UglifyJsPlugin()
		]
	}, {
		name: "deduped",
		plugins: [
			new webpack.optimize.DedupePlugin(),
			new webpack.NamedModulesPlugin()
		]
	}, {
		name: "minimized-deduped",
		minimize: true,
		plugins: [
			new webpack.optimize.DedupePlugin(),
			new webpack.optimize.UglifyJsPlugin()
		]
	}, {
		name: "optimized",
		minimize: true,
		plugins: [
			new webpack.optimize.DedupePlugin(),
			new webpack.optimize.OccurrenceOrderPlugin(),
			new webpack.optimize.UglifyJsPlugin()
		]
	}, {
		name: "all-combined",
		devtool: "#@source-map",
		minimize: true,
		plugins: [
			new webpack.HotModuleReplacementPlugin(),
			new webpack.optimize.DedupePlugin(),
			new webpack.optimize.OccurrenceOrderPlugin(),
			new webpack.optimize.UglifyJsPlugin(),
			new webpack.NamedModulesPlugin()
		]
	}].forEach(function(config) {
		describe(config.name, function() {
			categories.forEach(function(category) {
				describe(category.name, function() {
					this.timeout(20000);
					category.tests.filter(function(test) {
						var testDirectory = path.join(casesPath, category.name, test);
						var filterPath = path.join(testDirectory, "test.filter.js");
						if(fs.existsSync(filterPath) && !require(filterPath)(config)) {
							describe.skip(test, function() { it('filtered')});
							return false;
						}
						return true;
					}).forEach(function(testName) {
						var suite = describe(testName, function() {});
						it(testName + " should compile", function(done) {
							var testDirectory = path.join(casesPath, category.name, testName);
							var outputDirectory = path.join(__dirname, "js", config.name, category.name, testName);
							var options = {
								context: casesPath,
								entry: "./" + category.name + "/" + testName + "/index",
								target: "async-node",
								devtool: config.devtool,
								output: {
									pathinfo: true,
									path: outputDirectory,
									filename: "bundle.js"
								},
								resolve: {
									modules: ["web_modules", "node_modules"],
									mainFields: ["webpack", "browser", "web", "browserify", ["jam", "main"], "main"],
									aliasFields: ["browser"],
									extensions: [".webpack.js", ".web.js", ".js"]
								},
								resolveLoader: {
									modules: ["web_loaders", "web_modules", "node_loaders", "node_modules"],
									mainFields: ["webpackLoader", "webLoader", "loader", "main"],
									extensions: [".webpack-loader.js", ".web-loader.js", ".loader.js", ".js"]
								},
								module: {
									loaders: [{
										test: /\.json$/,
										loader: "json-loader"
									}, {
										test: /\.coffee$/,
										loader: "coffee-loader"
									}, {
										test: /\.jade$/,
										loader: "jade-loader"
									}]
								},
								plugins: (config.plugins || []).concat(
									function() {
										this.plugin("compilation", function(compilation) {
											["optimize", "optimize-modules-basic", "optimize-chunks-basic", "after-optimize-tree", "after-optimize-assets"].forEach(function(hook) {
												compilation.plugin(hook, function() {
													compilation.checkConstraints();
												});
											});
										});
									}
								)
							};
							webpack(options, function(err, stats) {
								if(err) return done(err);
								var statOptions = Stats.presetToOptions("verbose");
								statOptions.colors = false;
								fs.writeFileSync(path.join(outputDirectory, "stats.txt"), stats.toString(statOptions), "utf-8");
								var jsonStats = stats.toJson({
									errorDetails: true
								});
								if(checkArrayExpectation(testDirectory, jsonStats, "error", "Error", done)) return;
								if(checkArrayExpectation(testDirectory, jsonStats, "warning", "Warning", done)) return;
								var exportedTest = 0;

								function _it(title, fn) {
									var test = new Test(title, fn);
									suite.addTest(test);
									exportedTest++;
									return test;
								}

								function _require(module) {
									if(module.substr(0, 2) === "./") {
										var p = path.join(outputDirectory, module);
										var fn = vm.runInThisContext("(function(require, module, exports, __dirname, it) {" + fs.readFileSync(p, "utf-8") + "\n})", p);
										var module = {
											exports: {}
										};
										fn.call(module.exports, _require, module, module.exports, outputDirectory, _it);
										return module.exports;
									} else return require(module);
								}
								_require("./bundle.js");
								if(exportedTest === 0) return done(new Error("No tests exported by test case"));
								done();
							});
						});
					});
				});
			});
		});
	});
});
<commit_msg>Fix lint error<commit_after>var should = require("should");
var path = require("path");
var fs = require("fs");
var vm = require("vm");
var Test = require("mocha/lib/test");
var checkArrayExpectation = require("./checkArrayExpectation");

var Stats = require("../lib/Stats");
var webpack = require("../lib/webpack");

describe("TestCases", function() {
	var casesPath = path.join(__dirname, "cases");
	var categories = fs.readdirSync(casesPath);
	categories = categories.map(function(cat) {
		return {
			name: cat,
			tests: fs.readdirSync(path.join(casesPath, cat)).filter(function(folder) {
				return folder.indexOf("_") < 0;
			})
		};
	});
	[{
		name: "normal"
	}, {
		name: "hot",
		plugins: [
			new webpack.HotModuleReplacementPlugin()
		]
	}, {
		name: "hot-multi-step",
		plugins: [
			new webpack.HotModuleReplacementPlugin({
				multiStep: true
			})
		]
	}, {
		name: "devtool-eval",
		devtool: "eval"
	}, {
		name: "devtool-eval-named-modules",
		devtool: "eval",
		plugins: [
			new webpack.NamedModulesPlugin()
		]
	}, {
		name: "devtool-eval-source-map",
		devtool: "#eval-source-map"
	}, {
		name: "devtool-inline-source-map",
		devtool: "inline-source-map"
	}, {
		name: "devtool-source-map",
		devtool: "#@source-map"
	}, {
		name: "devtool-cheap-inline-source-map",
		devtool: "cheap-inline-source-map"
	}, {
		name: "devtool-cheap-eval-source-map",
		devtool: "cheap-eval-source-map"
	}, {
		name: "devtool-cheap-eval-module-source-map",
		devtool: "cheap-eval-module-source-map"
	}, {
		name: "devtool-cheap-source-map",
		devtool: "cheap-source-map"
	}, {
		name: "minimized",
		minimize: true,
		plugins: [
			new webpack.optimize.UglifyJsPlugin({
				sourceMap: false
			})
		]
	}, {
		name: "minimized-source-map",
		minimize: true,
		plugins: [
			new webpack.optimize.UglifyJsPlugin()
		]
	}, {
		name: "deduped",
		plugins: [
			new webpack.optimize.DedupePlugin(),
			new webpack.NamedModulesPlugin()
		]
	}, {
		name: "minimized-deduped",
		minimize: true,
		plugins: [
			new webpack.optimize.DedupePlugin(),
			new webpack.optimize.UglifyJsPlugin()
		]
	}, {
		name: "optimized",
		minimize: true,
		plugins: [
			new webpack.optimize.DedupePlugin(),
			new webpack.optimize.OccurrenceOrderPlugin(),
			new webpack.optimize.UglifyJsPlugin()
		]
	}, {
		name: "all-combined",
		devtool: "#@source-map",
		minimize: true,
		plugins: [
			new webpack.HotModuleReplacementPlugin(),
			new webpack.optimize.DedupePlugin(),
			new webpack.optimize.OccurrenceOrderPlugin(),
			new webpack.optimize.UglifyJsPlugin(),
			new webpack.NamedModulesPlugin()
		]
	}].forEach(function(config) {
		describe(config.name, function() {
			categories.forEach(function(category) {
				describe(category.name, function() {
					this.timeout(20000);
					category.tests.filter(function(test) {
						var testDirectory = path.join(casesPath, category.name, test);
						var filterPath = path.join(testDirectory, "test.filter.js");
						if(fs.existsSync(filterPath) && !require(filterPath)(config)) {
							describe.skip(test, function() {
								it('filtered')
							});
							return false;
						}
						return true;
					}).forEach(function(testName) {
						var suite = describe(testName, function() {});
						it(testName + " should compile", function(done) {
							var testDirectory = path.join(casesPath, category.name, testName);
							var outputDirectory = path.join(__dirname, "js", config.name, category.name, testName);
							var options = {
								context: casesPath,
								entry: "./" + category.name + "/" + testName + "/index",
								target: "async-node",
								devtool: config.devtool,
								output: {
									pathinfo: true,
									path: outputDirectory,
									filename: "bundle.js"
								},
								resolve: {
									modules: ["web_modules", "node_modules"],
									mainFields: ["webpack", "browser", "web", "browserify", ["jam", "main"], "main"],
									aliasFields: ["browser"],
									extensions: [".webpack.js", ".web.js", ".js"]
								},
								resolveLoader: {
									modules: ["web_loaders", "web_modules", "node_loaders", "node_modules"],
									mainFields: ["webpackLoader", "webLoader", "loader", "main"],
									extensions: [".webpack-loader.js", ".web-loader.js", ".loader.js", ".js"]
								},
								module: {
									loaders: [{
										test: /\.json$/,
										loader: "json-loader"
									}, {
										test: /\.coffee$/,
										loader: "coffee-loader"
									}, {
										test: /\.jade$/,
										loader: "jade-loader"
									}]
								},
								plugins: (config.plugins || []).concat(
									function() {
										this.plugin("compilation", function(compilation) {
											["optimize", "optimize-modules-basic", "optimize-chunks-basic", "after-optimize-tree", "after-optimize-assets"].forEach(function(hook) {
												compilation.plugin(hook, function() {
													compilation.checkConstraints();
												});
											});
										});
									}
								)
							};
							webpack(options, function(err, stats) {
								if(err) return done(err);
								var statOptions = Stats.presetToOptions("verbose");
								statOptions.colors = false;
								fs.writeFileSync(path.join(outputDirectory, "stats.txt"), stats.toString(statOptions), "utf-8");
								var jsonStats = stats.toJson({
									errorDetails: true
								});
								if(checkArrayExpectation(testDirectory, jsonStats, "error", "Error", done)) return;
								if(checkArrayExpectation(testDirectory, jsonStats, "warning", "Warning", done)) return;
								var exportedTest = 0;

								function _it(title, fn) {
									var test = new Test(title, fn);
									suite.addTest(test);
									exportedTest++;
									return test;
								}

								function _require(module) {
									if(module.substr(0, 2) === "./") {
										var p = path.join(outputDirectory, module);
										var fn = vm.runInThisContext("(function(require, module, exports, __dirname, it) {" + fs.readFileSync(p, "utf-8") + "\n})", p);
										var module = {
											exports: {}
										};
										fn.call(module.exports, _require, module, module.exports, outputDirectory, _it);
										return module.exports;
									} else return require(module);
								}
								_require("./bundle.js");
								if(exportedTest === 0) return done(new Error("No tests exported by test case"));
								done();
							});
						});
					});
				});
			});
		});
	});
});
<|endoftext|>


<commit_before>/* vuex-i18n defines the Vuexi18nPlugin to enable localization using a vuex
** module to store the translation information. Make sure to also include the
** file vuex-i18n-store.js to include a respective vuex module.
*/

import module from './vuex-i18n-store';
import plurals from './vuex-i18n-plurals';

// initialize the plugin object
let VuexI18nPlugin = {};

// internationalization plugin for vue js using vuex
VuexI18nPlugin.install = function install(Vue, store, config) {

	// TODO: remove this block for next major update (API break)
	if (typeof arguments[2] === 'string' || typeof arguments[3] === 'string') {
		console.warn('i18n: Registering the plugin vuex-i18n with a string for `moduleName` or `identifiers` is deprecated. Use a configuration object instead.', 'https://github.com/dkfbasel/vuex-i18n#setup');
		config = {
			moduleName: arguments[2],
			identifiers: arguments[3]
		};
	}

	// merge default options with user supplied options
	let mergedConfig = Object.assign({
		moduleName: 'i18n',
		identifiers: ['{', '}'],
		onTranslationNotFound: function() {}
	}, config);

	// define module name and identifiers as constants to prevent any changes
	const moduleName = mergedConfig.moduleName;
	const identifiers = mergedConfig.identifiers;

	// initialize the onTranslationNotFound function and make sure it is actually
	// a function
	let onTranslationNotFound = mergedConfig.onTranslationNotFound;
	if (typeof onTranslationNotFound !== 'function') {
		console.error('i18n: i18n config option onTranslationNotFound must be a function');
		onTranslationNotFound = function() {};
	}

	// register the i18n module in the vuex store
	store.registerModule(moduleName, module, {preserveState: true});

	// check if the plugin was correctly initialized
	if (store.state.hasOwnProperty(moduleName) === false) {
		console.error('i18n: i18n vuex module is not correctly initialized. Please check the module name:', moduleName);

		// always return the key if module is not initialized correctly
		Vue.prototype.$i18n = function(key) {
			return key;
		};

		Vue.prototype.$getLanguage = function() {
			return null;
		};

		Vue.prototype.$setLanguage = function() {
			console.error('i18n: i18n vuex module is not correctly initialized');
		};

		return;
	};

	// initialize the replacement function
	let render = renderFn(identifiers);

	// get localized string from store. note that we pass the arguments passed
	// to the function directly to the translateInLanguage function
	let translate = function $t() {

		// get the current language from the store
		let locale = store.state[moduleName].locale;

		return translateInLanguage(locale, ...arguments);
	};

	// get localized string from store in a given language if available.
	// there are two possible signatures for the function.
	// we will check the arguments to make up the options passed.
	// 1: locale, key, options, pluralization
	// 2: locale, key, defaultValue, options, pluralization
	let translateInLanguage = function translateInLanguage(locale) {

		// read the function arguments
		let args = arguments;

		// initialize options
		let key = '';
		let defaultValue = '';
		let options = {};
		let pluralization = null;

		let count = args.length;

		// check if a default value was specified and fill options accordingly
		if (count >= 3 && typeof args[2] === 'string') {

			key = args[1];
			defaultValue = args[2];

			if (count > 3) {
				options = args[3];
			}

			if (count > 4) {
				pluralization = args[4];
			}

		} else {

			key = args[1];

			// default value was not specified and is therefore the same as the key
			defaultValue = key;

			if (count > 2) {
				options = args[2];
			}

			if (count > 3) {
				pluralization = args[3];
			}

		}

		// return the default value if the locale is not set (could happen on initialization)
		if (!locale) {
			console.warn('i18n: i18n locale is not set when trying to access translations:', key);
			return defaultValue;
		}

		// get the translations from the store
		let translations = store.state[moduleName].translations;

		// get the last resort fallback from the store
		let fallback = store.state[moduleName].fallback;

		// split locale by - to support partial fallback for regional locales
		// like de-CH, en-UK
		let localeRegional = locale.split('-');

		// flag for translation to exist or not
		let translationExists = true;

		// check if the language exists in the store. return the key if not
		if (translations.hasOwnProperty(locale) === false ) {
			translationExists = false;

		// check if the key exists in the store. return the key if not
		} else if (translations[locale].hasOwnProperty(key) === false) {
			translationExists = false;
		}

		// return the value from the store
		if (translationExists === true) {
			return render(locale, translations[locale][key], options, pluralization);
		}

		// check if a regional locale translation would be available for the key
		// i.e. de for de-CH
		if (localeRegional.length > 1 &&
			translations.hasOwnProperty(localeRegional[0]) === true &&
			translations[localeRegional[0]].hasOwnProperty(key) === true) {
			return render(localeRegional[0], translations[localeRegional[0]][key], options, pluralization);
		}

		// invoke a method if a translation is not found
		let asyncTranslation = onTranslationNotFound(locale, key, defaultValue);

		// resolve async translations by updating the store
		if (asyncTranslation) {
			Promise.resolve(asyncTranslation).then((value) => {
				let additionalTranslations = {};
				additionalTranslations[key] = value;
				addLocale(locale, additionalTranslations);
			});
		}

		// check if a vaild fallback exists in the store.
		// return the default value if not
		if (translations.hasOwnProperty(fallback) === false ) {
			return render(locale, defaultValue, options, pluralization);
		}

		// check if the key exists in the fallback locale in the store.
		// return the default value if not
		if (translations[fallback].hasOwnProperty(key) === false) {
			return render(fallback, defaultValue, options, pluralization);
		}

		return render(locale, translations[fallback][key], options, pluralization);

	};

	// check if the given key exists in the current locale
	let checkKeyExists = function checkKeyExists(key, scope = 'fallback') {

		// get the current language from the store
		let locale = store.state[moduleName].locale;
		let fallback = store.state[moduleName].fallback;
		let translations = store.state[moduleName].translations;

		// check the current translation
		if (translations.hasOwnProperty(locale) && translations[locale].hasOwnProperty(key)) {
			return true;
		}

		if (scope == 'strict') {
			return false;
		}

		// check any localized translations
		let localeRegional = locale.split('-');

		if (localeRegional.length > 1 &&
			translations.hasOwnProperty(localeRegional[0]) &&
			translations[localeRegional[0]].hasOwnProperty(key)) {
			return true;
		}

		if (scope == 'locale') {
			return false;
		}

		// check if a fallback locale exists
		if (translations.hasOwnProperty(fallback) && translations[fallback].hasOwnProperty(key)) {
			return true;
		}

		// key does not exist in the store
		return false;
	};

	// set fallback locale
	let setFallbackLocale = function setFallbackLocale(locale) {
		store.dispatch({
			type: `${moduleName}/setFallbackLocale`,
			locale: locale
		});
	};

	// set the current locale
	let setLocale = function setLocale(locale) {
		store.dispatch({
			type: `${moduleName}/setLocale`,
			locale: locale
		});
	};

	// get the current locale
	let getLocale = function getLocale() {
		return store.state[moduleName].locale;
	};

	// add predefined translations to the store (keeping existing information)
	let addLocale = function addLocale(locale, translations) {
		return store.dispatch({
			type: `${moduleName}/addLocale`,
			locale: locale,
			translations: translations
		});
	};

	// replace all locale information in the store
	let replaceLocale = function replaceLocale(locale, translations) {
		return store.dispatch({
			type: `${moduleName}/replaceLocale`,
			locale: locale,
			translations: translations
		});
	};

	// remove the givne locale from the store
	let removeLocale = function removeLocale(locale) {
		if (store.state[moduleName].translations.hasOwnProperty(locale)) {
			store.dispatch({
				type: `${moduleName}/removeLocale`,
				locale: locale
			});
		}
	};

	// we are phasing out the exists function
	let phaseOutExistsFn = function phaseOutExistsFn(locale) {
		console.warn('i18n: $i18n.exists is depreceated. Please use $i18n.localeExists instead. It provides exatly the same functionality.');
		return checkLocaleExists(locale);
	};

	// check if the given locale is already loaded
	let checkLocaleExists = function checkLocaleExists(locale) {
		return store.state[moduleName].translations.hasOwnProperty(locale);
	};

	// register vue prototype methods
	Vue.prototype.$i18n = {
		locale: getLocale,
		set: setLocale,
		add: addLocale,
		replace: replaceLocale,
		remove: removeLocale,
		fallback: setFallbackLocale,
		localeExists: checkLocaleExists,
		keyExists: checkKeyExists,

		exists: phaseOutExistsFn
	};

	// register global methods
	Vue.i18n = {
		locale: getLocale,
		set: setLocale,
		add: addLocale,
		replace: replaceLocale,
		remove: removeLocale,
		fallback: setFallbackLocale,
		translate: translate,
		translateIn: translateInLanguage,
		localeExists: checkLocaleExists,
		keyExists: checkKeyExists,

		exists: phaseOutExistsFn
	};

	// register the translation function on the vue instance
	Vue.prototype.$t = translate;

	// register the specific language translation function on the vue instance
	Vue.prototype.$tlang = translateInLanguage;

	// register a filter function for translations
	Vue.filter('translate', translate);

};

// renderFn will initialize a function to render the variable substitutions in
// the translation string. identifiers specify the tags will be used to find
// variable substitutions, i.e. {test} or {{test}}, note that we are using a
// closure to avoid recompilation of the regular expression to match tags on
// every render cycle.
let renderFn = function(identifiers) {

	if (identifiers == null || identifiers.length != 2) {
		console.warn('i18n: You must specify the start and end character identifying variable substitutions');
	}

	// construct a regular expression ot find variable substitutions, i.e. {test}
	let matcher = new RegExp('' + identifiers[0] + '\\w+' + identifiers[1], 'g');

	// define the replacement function
	let replace = function replace(translation, replacements, warn = true) {

		// check if the object has a replace property
		if (!translation.replace) {
			return translation;
		}

		return translation.replace(matcher, function(placeholder) {

			// remove the identifiers (can be set on the module level)
			let key = placeholder.replace(identifiers[0], '').replace(identifiers[1], '');

			if (replacements[key] !== undefined) {
				return replacements[key];
			}

			// warn user that the placeholder has not been found
			if (warn === true) {
				console.group ? console.group('i18n: Not all placeholders found') : console.warn('i18n: Not all placeholders found');
				console.warn('Text:', translation);
				console.warn('Placeholder:', placeholder);
				if(console.groupEnd) {
					console.groupEnd();
				}
			}

			// return the original placeholder
			return placeholder;
		});
	};

	// the render function will replace variable substitutions and prepare the
	// translations for rendering
	let render = function render(locale, translation, replacements = {}, pluralization = null) {
		// get the type of the property
		let objType = typeof translation;
		let pluralizationType = typeof pluralization;

		let resolvePlaceholders = function() {

			if (isArray(translation)) {

				// replace the placeholder elements in all sub-items
				return translation.map((item) => {
					return replace(item, replacements, false);
				});

			} else if (objType === 'string') {
				return replace(translation, replacements, true);
			}

		};

			// return translation item directly
		if (pluralization === null) {
			return resolvePlaceholders();
		}

		// check if pluralization value is countable
		if (pluralizationType !== 'number') {
			console.warn('i18n: pluralization is not a number');
			return resolvePlaceholders();
		}

		// --- handle pluralizations ---

		// replace all placeholders
		let resolvedTranslation = resolvePlaceholders();

		// initialize pluralizations
		let pluralizations = null;

		// if translations are already an array and have more than one entry,
		// we will not perform a split operation on :::
		if (isArray(resolvedTranslation) && resolvedTranslation.length > 0) {
			pluralizations = resolvedTranslation;

		} else {
			// split translation strings by ::: to find create the pluralization array
			pluralizations = resolvedTranslation.split(':::');
		}

		// determine the pluralization version to use by locale
		let index = plurals.getTranslationIndex(locale, pluralization);

		// check if the specified index is present in the pluralization
		if(typeof pluralizations[index] === 'undefined') {
			console.warn('i18n: pluralization not provided in locale', translation, locale, index);

			// return the first element of the pluralization by default
			return pluralizations[0].trim();
		}

		// return the requested item from the pluralizations
		return pluralizations[index].trim();

	};

	// return the render function to the caller
	return render;

};

// check if the given object is an array
function isArray(obj) {
	return !!obj && Array === obj.constructor;
}

export default VuexI18nPlugin;
<commit_msg>Fix issue with preserveState<commit_after>/* vuex-i18n defines the Vuexi18nPlugin to enable localization using a vuex
** module to store the translation information. Make sure to also include the
** file vuex-i18n-store.js to include a respective vuex module.
*/

import module from './vuex-i18n-store';
import plurals from './vuex-i18n-plurals';

// initialize the plugin object
let VuexI18nPlugin = {};

// internationalization plugin for vue js using vuex
VuexI18nPlugin.install = function install(Vue, store, config) {

	// TODO: remove this block for next major update (API break)
	if (typeof arguments[2] === 'string' || typeof arguments[3] === 'string') {
		console.warn('i18n: Registering the plugin vuex-i18n with a string for `moduleName` or `identifiers` is deprecated. Use a configuration object instead.', 'https://github.com/dkfbasel/vuex-i18n#setup');
		config = {
			moduleName: arguments[2],
			identifiers: arguments[3]
		};
	}

	// merge default options with user supplied options
	let mergedConfig = Object.assign({
		moduleName: 'i18n',
		identifiers: ['{', '}'],
		preserveState: false,
		onTranslationNotFound: function() {}
	}, config);

	// define module name and identifiers as constants to prevent any changes
	const moduleName = mergedConfig.moduleName;
	const identifiers = mergedConfig.identifiers;

	// initialize the onTranslationNotFound function and make sure it is actually
	// a function
	let onTranslationNotFound = mergedConfig.onTranslationNotFound;
	if (typeof onTranslationNotFound !== 'function') {
		console.error('i18n: i18n config option onTranslationNotFound must be a function');
		onTranslationNotFound = function() {};
	}

	// register the i18n module in the vuex store
	// preserveState can be used via configuration if server side rendering is used
	store.registerModule(moduleName, module, {preserveState: preserveState});

	// check if the plugin was correctly initialized
	if (store.state.hasOwnProperty(moduleName) === false) {
		console.error('i18n: i18n vuex module is not correctly initialized. Please check the module name:', moduleName);

		// always return the key if module is not initialized correctly
		Vue.prototype.$i18n = function(key) {
			return key;
		};

		Vue.prototype.$getLanguage = function() {
			return null;
		};

		Vue.prototype.$setLanguage = function() {
			console.error('i18n: i18n vuex module is not correctly initialized');
		};

		return;
	};

	// initialize the replacement function
	let render = renderFn(identifiers);

	// get localized string from store. note that we pass the arguments passed
	// to the function directly to the translateInLanguage function
	let translate = function $t() {

		// get the current language from the store
		let locale = store.state[moduleName].locale;

		return translateInLanguage(locale, ...arguments);
	};

	// get localized string from store in a given language if available.
	// there are two possible signatures for the function.
	// we will check the arguments to make up the options passed.
	// 1: locale, key, options, pluralization
	// 2: locale, key, defaultValue, options, pluralization
	let translateInLanguage = function translateInLanguage(locale) {

		// read the function arguments
		let args = arguments;

		// initialize options
		let key = '';
		let defaultValue = '';
		let options = {};
		let pluralization = null;

		let count = args.length;

		// check if a default value was specified and fill options accordingly
		if (count >= 3 && typeof args[2] === 'string') {

			key = args[1];
			defaultValue = args[2];

			if (count > 3) {
				options = args[3];
			}

			if (count > 4) {
				pluralization = args[4];
			}

		} else {

			key = args[1];

			// default value was not specified and is therefore the same as the key
			defaultValue = key;

			if (count > 2) {
				options = args[2];
			}

			if (count > 3) {
				pluralization = args[3];
			}

		}

		// return the default value if the locale is not set (could happen on initialization)
		if (!locale) {
			console.warn('i18n: i18n locale is not set when trying to access translations:', key);
			return defaultValue;
		}

		// get the translations from the store
		let translations = store.state[moduleName].translations;

		// get the last resort fallback from the store
		let fallback = store.state[moduleName].fallback;

		// split locale by - to support partial fallback for regional locales
		// like de-CH, en-UK
		let localeRegional = locale.split('-');

		// flag for translation to exist or not
		let translationExists = true;

		// check if the language exists in the store. return the key if not
		if (translations.hasOwnProperty(locale) === false ) {
			translationExists = false;

		// check if the key exists in the store. return the key if not
		} else if (translations[locale].hasOwnProperty(key) === false) {
			translationExists = false;
		}

		// return the value from the store
		if (translationExists === true) {
			return render(locale, translations[locale][key], options, pluralization);
		}

		// check if a regional locale translation would be available for the key
		// i.e. de for de-CH
		if (localeRegional.length > 1 &&
			translations.hasOwnProperty(localeRegional[0]) === true &&
			translations[localeRegional[0]].hasOwnProperty(key) === true) {
			return render(localeRegional[0], translations[localeRegional[0]][key], options, pluralization);
		}

		// invoke a method if a translation is not found
		let asyncTranslation = onTranslationNotFound(locale, key, defaultValue);

		// resolve async translations by updating the store
		if (asyncTranslation) {
			Promise.resolve(asyncTranslation).then((value) => {
				let additionalTranslations = {};
				additionalTranslations[key] = value;
				addLocale(locale, additionalTranslations);
			});
		}

		// check if a vaild fallback exists in the store.
		// return the default value if not
		if (translations.hasOwnProperty(fallback) === false ) {
			return render(locale, defaultValue, options, pluralization);
		}

		// check if the key exists in the fallback locale in the store.
		// return the default value if not
		if (translations[fallback].hasOwnProperty(key) === false) {
			return render(fallback, defaultValue, options, pluralization);
		}

		return render(locale, translations[fallback][key], options, pluralization);

	};

	// check if the given key exists in the current locale
	let checkKeyExists = function checkKeyExists(key, scope = 'fallback') {

		// get the current language from the store
		let locale = store.state[moduleName].locale;
		let fallback = store.state[moduleName].fallback;
		let translations = store.state[moduleName].translations;

		// check the current translation
		if (translations.hasOwnProperty(locale) && translations[locale].hasOwnProperty(key)) {
			return true;
		}

		if (scope == 'strict') {
			return false;
		}

		// check any localized translations
		let localeRegional = locale.split('-');

		if (localeRegional.length > 1 &&
			translations.hasOwnProperty(localeRegional[0]) &&
			translations[localeRegional[0]].hasOwnProperty(key)) {
			return true;
		}

		if (scope == 'locale') {
			return false;
		}

		// check if a fallback locale exists
		if (translations.hasOwnProperty(fallback) && translations[fallback].hasOwnProperty(key)) {
			return true;
		}

		// key does not exist in the store
		return false;
	};

	// set fallback locale
	let setFallbackLocale = function setFallbackLocale(locale) {
		store.dispatch({
			type: `${moduleName}/setFallbackLocale`,
			locale: locale
		});
	};

	// set the current locale
	let setLocale = function setLocale(locale) {
		store.dispatch({
			type: `${moduleName}/setLocale`,
			locale: locale
		});
	};

	// get the current locale
	let getLocale = function getLocale() {
		return store.state[moduleName].locale;
	};

	// add predefined translations to the store (keeping existing information)
	let addLocale = function addLocale(locale, translations) {
		return store.dispatch({
			type: `${moduleName}/addLocale`,
			locale: locale,
			translations: translations
		});
	};

	// replace all locale information in the store
	let replaceLocale = function replaceLocale(locale, translations) {
		return store.dispatch({
			type: `${moduleName}/replaceLocale`,
			locale: locale,
			translations: translations
		});
	};

	// remove the givne locale from the store
	let removeLocale = function removeLocale(locale) {
		if (store.state[moduleName].translations.hasOwnProperty(locale)) {
			store.dispatch({
				type: `${moduleName}/removeLocale`,
				locale: locale
			});
		}
	};

	// we are phasing out the exists function
	let phaseOutExistsFn = function phaseOutExistsFn(locale) {
		console.warn('i18n: $i18n.exists is depreceated. Please use $i18n.localeExists instead. It provides exatly the same functionality.');
		return checkLocaleExists(locale);
	};

	// check if the given locale is already loaded
	let checkLocaleExists = function checkLocaleExists(locale) {
		return store.state[moduleName].translations.hasOwnProperty(locale);
	};

	// register vue prototype methods
	Vue.prototype.$i18n = {
		locale: getLocale,
		set: setLocale,
		add: addLocale,
		replace: replaceLocale,
		remove: removeLocale,
		fallback: setFallbackLocale,
		localeExists: checkLocaleExists,
		keyExists: checkKeyExists,

		exists: phaseOutExistsFn
	};

	// register global methods
	Vue.i18n = {
		locale: getLocale,
		set: setLocale,
		add: addLocale,
		replace: replaceLocale,
		remove: removeLocale,
		fallback: setFallbackLocale,
		translate: translate,
		translateIn: translateInLanguage,
		localeExists: checkLocaleExists,
		keyExists: checkKeyExists,

		exists: phaseOutExistsFn
	};

	// register the translation function on the vue instance
	Vue.prototype.$t = translate;

	// register the specific language translation function on the vue instance
	Vue.prototype.$tlang = translateInLanguage;

	// register a filter function for translations
	Vue.filter('translate', translate);

};

// renderFn will initialize a function to render the variable substitutions in
// the translation string. identifiers specify the tags will be used to find
// variable substitutions, i.e. {test} or {{test}}, note that we are using a
// closure to avoid recompilation of the regular expression to match tags on
// every render cycle.
let renderFn = function(identifiers) {

	if (identifiers == null || identifiers.length != 2) {
		console.warn('i18n: You must specify the start and end character identifying variable substitutions');
	}

	// construct a regular expression ot find variable substitutions, i.e. {test}
	let matcher = new RegExp('' + identifiers[0] + '\\w+' + identifiers[1], 'g');

	// define the replacement function
	let replace = function replace(translation, replacements, warn = true) {

		// check if the object has a replace property
		if (!translation.replace) {
			return translation;
		}

		return translation.replace(matcher, function(placeholder) {

			// remove the identifiers (can be set on the module level)
			let key = placeholder.replace(identifiers[0], '').replace(identifiers[1], '');

			if (replacements[key] !== undefined) {
				return replacements[key];
			}

			// warn user that the placeholder has not been found
			if (warn === true) {
				console.group ? console.group('i18n: Not all placeholders found') : console.warn('i18n: Not all placeholders found');
				console.warn('Text:', translation);
				console.warn('Placeholder:', placeholder);
				if(console.groupEnd) {
					console.groupEnd();
				}
			}

			// return the original placeholder
			return placeholder;
		});
	};

	// the render function will replace variable substitutions and prepare the
	// translations for rendering
	let render = function render(locale, translation, replacements = {}, pluralization = null) {
		// get the type of the property
		let objType = typeof translation;
		let pluralizationType = typeof pluralization;

		let resolvePlaceholders = function() {

			if (isArray(translation)) {

				// replace the placeholder elements in all sub-items
				return translation.map((item) => {
					return replace(item, replacements, false);
				});

			} else if (objType === 'string') {
				return replace(translation, replacements, true);
			}

		};

			// return translation item directly
		if (pluralization === null) {
			return resolvePlaceholders();
		}

		// check if pluralization value is countable
		if (pluralizationType !== 'number') {
			console.warn('i18n: pluralization is not a number');
			return resolvePlaceholders();
		}

		// --- handle pluralizations ---

		// replace all placeholders
		let resolvedTranslation = resolvePlaceholders();

		// initialize pluralizations
		let pluralizations = null;

		// if translations are already an array and have more than one entry,
		// we will not perform a split operation on :::
		if (isArray(resolvedTranslation) && resolvedTranslation.length > 0) {
			pluralizations = resolvedTranslation;

		} else {
			// split translation strings by ::: to find create the pluralization array
			pluralizations = resolvedTranslation.split(':::');
		}

		// determine the pluralization version to use by locale
		let index = plurals.getTranslationIndex(locale, pluralization);

		// check if the specified index is present in the pluralization
		if(typeof pluralizations[index] === 'undefined') {
			console.warn('i18n: pluralization not provided in locale', translation, locale, index);

			// return the first element of the pluralization by default
			return pluralizations[0].trim();
		}

		// return the requested item from the pluralizations
		return pluralizations[index].trim();

	};

	// return the render function to the caller
	return render;

};

// check if the given object is an array
function isArray(obj) {
	return !!obj && Array === obj.constructor;
}

export default VuexI18nPlugin;
<|endoftext|>


<commit_before>/* Dependency */
var mdns = null;
try {
  mdns = require('mdns');
} catch(e) {
  mdns = null;
}

function mDNSAdvertiser(name, port) {
  this._mdnsIsInstalled = !!mdns;
  /**
   * The Bonjour/MDNS Server Advertisement
   * */
  this.ad = null;

  this.isInstalled = function(callback) {
    callback = callback || function() {};
    return callback(null, this._mdnsIsInstalled);
  };

  this.init = function(callback) {
    callback = callback || function() {};

    if ( !this._mdnsIsInstalled ) {
      if ( process.env.NODE_ENV !== 'test' && process.env.NODE_ENV !== 'production' ) {
        console.log("mDNS module is not installed.");
      }
      return callback(null);
    }

    var options = {};
    this.ad = mdns.createAdvertisement(mdns.tcp(name), port, options);
    // error handler
    this.ad.on('error', function(error) {
      if ( error.errorCode ) {
        // dns_sd lib error
        if ( error.errorCode === mdns.kDNSServiceErr_Unknown ) {
          console.log("Unknown mDNS error.");
        }
      } else {
        throw error; // TODO: handle gracefully
      }
    });

    callback(null);
  };

  var _changeAdvertising = function(type, callback) {
    callback = callback || function() {};

    if ( !this.ad ) {
      if ( this._mdnsIsInstalled ) {
        return callback(new Error('Advertisement is not initialized.'));
      }
      // mdns is not installed, ad cannot be initialized. The user should be aware of it
      return callback(null, null);
    }

    if ( type === 'start' ) {
      this.ad.start();
    } else if ( type === 'stop' ) {
      this.ad.stop();
    }

    callback(null);
  };

  this.startAdvertising = function(callback) {
    _changeAdvertising('start', callback);
  };
  this.stopAdvertising = function(callback) {
    _changeAdvertising('stop', callback);
  };
}

module.exports = {
  mDNSAdvertiser: mDNSAdvertiser,
};
<commit_msg>Fixed mdns scope.<commit_after>/* Dependency */
var mdns = null;
try {
  mdns = require('mdns');
} catch(e) {
  mdns = null;
}

function mDNSAdvertiser(name, port) {
  this._mdnsIsInstalled = !!mdns;
  /**
   * The Bonjour/MDNS Server Advertisement
   * */
  this.ad = null;

  this.isInstalled = function(callback) {
    callback = callback || function() {};
    return callback(null, this._mdnsIsInstalled);
  };

  this.init = function(callback) {
    callback = callback || function() {};

    if ( !this._mdnsIsInstalled ) {
      if ( process.env.NODE_ENV !== 'test' && process.env.NODE_ENV !== 'production' ) {
        console.log("mDNS module is not installed.");
      }
      return callback(null);
    }

    var options = {};
    this.ad = mdns.createAdvertisement(mdns.tcp(name), port, options);
    // error handler
    this.ad.on('error', function(error) {
      if ( error.errorCode ) {
        // dns_sd lib error
        if ( error.errorCode === mdns.kDNSServiceErr_Unknown ) {
          console.log("Unknown mDNS error.");
        }
      } else {
        throw error; // TODO: handle gracefully
      }
    });

    callback(null);
  };

  var _changeAdvertising = function(type, callback) {
    callback = callback || function() {};

    if ( !this.ad ) {
      if ( this._mdnsIsInstalled ) {
        return callback(new Error('Advertisement is not initialized.'));
      }
      // mdns is not installed, ad cannot be initialized. The user should be aware of it
      return callback(null, null);
    }

    if ( type === 'start' ) {
      this.ad.start();
    } else if ( type === 'stop' ) {
      this.ad.stop();
    }

    callback(null);
  };

  this.startAdvertising = function(callback) {
    _changeAdvertising.call(this, 'start', callback);
  };
  this.stopAdvertising = function(callback) {
    _changeAdvertising.call(this, 'stop', callback);
  };
}

module.exports = {
  mDNSAdvertiser: mDNSAdvertiser,
};
<|endoftext|>


<commit_before>/* eslint react/no-multi-comp: 0, max-len: 0 */
import 'rc-slider/assets/index.less';

import React from 'react';
import ReactDOM from 'react-dom';
import Slider from 'rc-slider';

const style = { width: 600, margin: 50 };

function log(value) {
  console.log(value); //eslint-disable-line
}

function percentFormatter(v) {
  return `${v} %`;
}

class CustomizedSlider extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 50,
    };
  }
  onSliderChange = (value) => {
    log(value);
    this.setState({
      value,
    });
  }
  onAfterChange = (value) => {
    console.log(value); //eslint-disable-line
  }
  render() {
    return (
      <Slider value={this.state.value}
        onChange={this.onSliderChange} onAfterChange={this.onAfterChange}
      />
    );
  }
}

class DynamicBounds extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      min: 0,
      max: 100,
    };
  }
  onSliderChange = (value) => {
    log(value);
  }
  onMinChange = (e) => {
    this.setState({
      min: +e.target.value || 0,
    });
  }
  onMaxChange = (e) => {
    this.setState({
      max: +e.target.value || 100,
    });
  }
  render() {
    return (

        Min:
        <input type="number" value={this.state.min} onChange={this.onMinChange} />

        Max:
        <input type="number" value={this.state.max} onChange={this.onMaxChange} />

        <Slider defaultValue={50} min={this.state.min} max={this.state.max}
          onChange={this.onSliderChange}
        />

    );
  }
}

ReactDOM.render(

Basic Slider

      <Slider tipTransitionName="rc-slider-tooltip-zoom-down" onChange={log} />

Basic Slider，`step=20`

      <Slider step={20} defaultValue={50} onBeforeChange={log} />

Basic Slider，`step=20, dots`

      <Slider dots step={20} defaultValue={100} onAfterChange={log} />

Basic Slider with `tipFormatter`

      <Slider tipFormatter={percentFormatter}
        tipTransitionName="rc-slider-tooltip-zoom-down" onChange={log}
      />

Basic Slider without tooltip

      <Slider tipFormatter={null} onChange={log} />

Slider with custom handle and track style.(old api, will be deperacete)

      <Slider
        defaultValue={30}
        maximumTrackStyle={{ backgroundColor: 'red', height: 10 }}
        minimumTrackStyle={{ backgroundColor: 'blue', height: 10 }}
        handleStyle={{
          borderColor: 'blue',
          height: 28,
          width: 28,
          marginLeft: -14,
          marginTop: -9,
          backgroundColor: 'black',
        }}
      />

Slider with custom handle and track style.(The recommended new api)

      <Slider
        defaultValue={30}
        trackStyle={{ backgroundColor: 'blue', height: 10 }}
        handleStyle={{
          borderColor: 'blue',
          height: 28,
          width: 28,
          marginLeft: -14,
          marginTop: -9,
          backgroundColor: 'black',
        }}
        railStyle={{ backgroundColor: 'red', height: 10 }}
      />

Basic Slider, disabled

      <Slider tipTransitionName="rc-slider-tooltip-zoom-down" onChange={log} disabled />

Controlled Slider

      <Slider value={50} />

Customized Slider

      <CustomizedSlider />

Slider with dynamic `min` `max`

      <DynamicBounds />

  , document.getElementById('__react-content'));
<commit_msg>docs: update demo<commit_after>/* eslint react/no-multi-comp: 0, max-len: 0 */
import 'rc-slider/assets/index.less';

import React from 'react';
import ReactDOM from 'react-dom';
import Slider, { createSliderWithTooltip } from 'rc-slider';

const style = { width: 600, margin: 50 };

function log(value) {
  console.log(value); //eslint-disable-line
}

function percentFormatter(v) {
  return `${v} %`;
}

const SliderWithTooltip = createSliderWithTooltip(Slider);

class CustomizedSlider extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 50,
    };
  }
  onSliderChange = (value) => {
    log(value);
    this.setState({
      value,
    });
  }
  onAfterChange = (value) => {
    console.log(value); //eslint-disable-line
  }
  render() {
    return (
      <Slider value={this.state.value}
        onChange={this.onSliderChange} onAfterChange={this.onAfterChange}
      />
    );
  }
}

class DynamicBounds extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      min: 0,
      max: 100,
    };
  }
  onSliderChange = (value) => {
    log(value);
  }
  onMinChange = (e) => {
    this.setState({
      min: +e.target.value || 0,
    });
  }
  onMaxChange = (e) => {
    this.setState({
      max: +e.target.value || 100,
    });
  }
  render() {
    return (

        Min:
        <input type="number" value={this.state.min} onChange={this.onMinChange} />

        Max:
        <input type="number" value={this.state.max} onChange={this.onMaxChange} />

        <Slider defaultValue={50} min={this.state.min} max={this.state.max}
          onChange={this.onSliderChange}
        />

    );
  }
}

ReactDOM.render(

Basic Slider

      <Slider onChange={log} />

Basic Slider，`step=20`

      <Slider step={20} defaultValue={50} onBeforeChange={log} />

Basic Slider，`step=20, dots`

      <Slider dots step={20} defaultValue={100} onAfterChange={log} />

Slider with tooltip, with custom `tipFormatter`

      <SliderWithTooltip
        tipFormatter={percentFormatter}
        tipProps={{ overlayClassName: 'foo' }}
        onChange={log}
      />

Slider with custom handle and track style.(old api, will be deperacete)

      <Slider
        defaultValue={30}
        maximumTrackStyle={{ backgroundColor: 'red', height: 10 }}
        minimumTrackStyle={{ backgroundColor: 'blue', height: 10 }}
        handleStyle={{
          borderColor: 'blue',
          height: 28,
          width: 28,
          marginLeft: -14,
          marginTop: -9,
          backgroundColor: 'black',
        }}
      />

Slider with custom handle and track style.(The recommended new api)

      <Slider
        defaultValue={30}
        trackStyle={{ backgroundColor: 'blue', height: 10 }}
        handleStyle={{
          borderColor: 'blue',
          height: 28,
          width: 28,
          marginLeft: -14,
          marginTop: -9,
          backgroundColor: 'black',
        }}
        railStyle={{ backgroundColor: 'red', height: 10 }}
      />

Basic Slider, disabled

      <Slider onChange={log} disabled />

Controlled Slider

      <Slider value={50} />

Customized Slider

      <CustomizedSlider />

Slider with dynamic `min` `max`

      <DynamicBounds />

  , document.getElementById('__react-content'));
<|endoftext|>