<commit_before>var assert = require('assert');
var config = require("./config.json");
var graphene = require("../build/graphene");

var Module = graphene.Module;

describe("RSA", function () {
    var mod, slot, session, keys, skey;

    var MSG = "1234567890123456";
    var MSG_WRONG = MSG + "!";

    before(function () {
        mod = Module.load(config.init.lib, config.init.libName);
        mod.initialize();
        slot = mod.getSlots(0);
        session = slot.open();
        session.login(config.init.pin);
    })

    after(function () {
        if (session)
            session.logout();
        mod.finalize();
    })

    it("generate RSA", function () {
	keys = session.generateKeyPair(graphene.KeyGenMechanism.RSA, {
            keyType: graphene.KeyType.RSA,
            modulusBits: 1024,
            publicExponent: new Buffer([3]),
            token: false,
            verify: true,
            encrypt: true,
            wrap: true
        }, {
                keyType: graphene.KeyType.RSA,
                token: false,
                sign: true,
                decrypt: true,
                unwrap: true
            });
    })

    it("generate AES", function () {
        skey = session.generateKey(graphene.KeyGenMechanism.AES, {
            keyType: graphene.KeyType.AES,
            valueLen: 256 / 8
        });
    })

    function test_sign_verify(_key , alg) {
        var sign = session.createSign(alg, _key.privateKey);
        sign.update(MSG);
        var sig = sign.final();
        var verify = session.createVerify(alg, _key.publicKey);
        verify.update(MSG);
        assert.equal(verify.final(sig), true, "Correct");
        verify = session.createVerify(alg, _key.publicKey);
        verify.update(MSG_WRONG);
        assert.equal(verify.final(sig), false, "Wrong data");
    }

    function test_encrypt_decrypt(_key, alg) {
        var cipher = session.createCipher(alg, _key.publicKey);
	var enc = cipher.update(MSG);
        enc = Buffer.concat([enc, cipher.final()]);
        var decipher = session.createDecipher(alg, _key.privateKey);
        var dec = decipher.update(enc);
        assert.equal(Buffer.concat([dec, decipher.final()]).toString(), MSG, "Correct");
    }

    function test_wrap_unwrap(_key, alg, _skey) {
        _key.algorithm = alg;
        var wkey = _key.wrapKey(_skey.key);
        var ukey = _key.unwrapKey(wkey, {
            "class": graphene.ObjectClass.SECRET_KEY,
            "keyType": graphene.KeyType.AES,
            "token": false,
            "valueLen": 128 / 8,
            "encrypt": true,
            "decrypt": true
        });
        session.destroyObject(ukey);
    }

    it("sign/verify SHA-1", function () {
        test_sign_verify(keys, "SHA1_RSA_PKCS");
    });

    it("sign/verify SHA-224", function () {
        test_sign_verify(keys, "SHA224_RSA_PKCS");
    });

    it("sign/verify SHA-256", function () {
        test_sign_verify(keys, "SHA256_RSA_PKCS");
    });

    it("sign/verify SHA-384", function () {
        test_sign_verify(keys, "SHA384_RSA_PKCS");
    });

    it("sign/verify SHA-512", function () {
        test_sign_verify(keys, "SHA512_RSA_PKCS");
    });

    it("OAEP encrypt/decrypt default SHA-1", function () {
        test_encrypt_decrypt(keys, { name: "RSA_PKCS_OAEP", params: new graphene.RsaOaepParams() })
    });

    it("OAEP encrypt/decrypt SHA-1", function () {
        test_encrypt_decrypt(keys, { name: "RSA_PKCS_OAEP", params: new graphene.RsaOaepParams(graphene.MechanismEnum.SHA1, graphene.RsaMgf.MGF1_SHA1) })
    });

    it("OAEP encrypt/decrypt SHA-1 with params", function () {
        test_encrypt_decrypt(keys, { name: "RSA_PKCS_OAEP", params: new graphene.RsaOaepParams(graphene.MechanismEnum.SHA1, graphene.RsaMgf.MGF1_SHA1, new Buffer([1,2,3,4,5,6,7,8,9,0])) })
    });

    it("OAEP wrap/unwrap SHA-1", function () {
        test_wrap_unwrap(keys, { name: "RSA_PKCS_OAEP", params: new RSA.RsaOAEPParams(Enums.Mechanism.SHA1, Enums.MGF1.SHA1) }, skey);
    });

    it("RSA 1.5 sign/verify", function () {
        test_sign_verify(keys, "RSA_PKCS");
    });

    it("RSA 1.5 encrypt/decrypt", function () {
        test_encrypt_decrypt(keys, "RSA_PKCS")
    });

    it("RSA 1.5 wrap/unwrap", function () {
        test_wrap_unwrap(keys, "RSA_PKCS", skey);
    });

    it("RSA PSS sign/verify SHA1", function () {
        test_sign_verify(keys, { name: "SHA1_RSA_PKCS_PSS", params: new RSA.RsaPSSParams(Enums.Mechanism.SHA1, Enums.MGF1.SHA1) });
    });

    it("RSA PSS sign/verify SHA224", function () {
        test_sign_verify(keys, { name: "SHA224_RSA_PKCS_PSS", params: new RSA.RsaPSSParams(Enums.Mechanism.SHA224, Enums.MGF1.SHA224) });
    });

    it("RSA PSS sign/verify SHA256", function () {
        test_sign_verify(keys, { name: "SHA256_RSA_PKCS_PSS", params: new RSA.RsaPSSParams(Enums.Mechanism.SHA256, Enums.MGF1.SHA256) });
    });

    it("RSA PSS sign/verify SHA384", function () {
        test_sign_verify(keys, { name: "SHA384_RSA_PKCS_PSS", params: new RSA.RsaPSSParams(Enums.Mechanism.SHA384, Enums.MGF1.SHA384) });
    });

    it("RSA PSS sign/verify SHA512", function () {
        test_sign_verify(keys, { name: "SHA512_RSA_PKCS_PSS", params: new RSA.RsaPSSParams(Enums.Mechanism.SHA512, Enums.MGF1.SHA512) });
    });

})<commit_msg>update test<commit_after>var assert = require('assert');
var config = require("./config.json");
var graphene = require("../build/graphene");

var Module = graphene.Module;

describe("RSA", function () {
    var mod, slot, session, keys, skey;

    var MSG = "1234567890123456";
    var MSG_WRONG = MSG + "!";

    before(function () {
        mod = Module.load(config.init.lib, config.init.libName);
        mod.initialize();
        slot = mod.getSlots(0);
        session = slot.open();
        session.login(config.init.pin);
    })

    after(function () {
        if (session)
            session.logout();
        mod.finalize();
    })

    it("generate RSA", function () {
	keys = session.generateKeyPair(graphene.KeyGenMechanism.RSA, {
            keyType: graphene.KeyType.RSA,
            modulusBits: 1024,
            publicExponent: new Buffer([3]),
            token: false,
            verify: true,
            encrypt: true,
            wrap: true
        }, {
                keyType: graphene.KeyType.RSA,
                token: false,
                sign: true,
                decrypt: true,
                unwrap: true
            });
    })

    it("generate AES", function () {
        skey = session.generateKey(graphene.KeyGenMechanism.AES, {
            keyType: graphene.KeyType.AES,
            valueLen: 256 / 8
        });
    })

    function test_sign_verify(_key , alg) {
        var sign = session.createSign(alg, _key.privateKey);
        sign.update(MSG);
        var sig = sign.final();
        var verify = session.createVerify(alg, _key.publicKey);
        verify.update(MSG);
        assert.equal(verify.final(sig), true, "Correct");
        verify = session.createVerify(alg, _key.publicKey);
        verify.update(MSG_WRONG);
        assert.equal(verify.final(sig), false, "Wrong data");
    }

    function test_encrypt_decrypt(_key, alg) {
        var cipher = session.createCipher(alg, _key.publicKey);
	var enc = cipher.update(MSG);
        enc = Buffer.concat([enc, cipher.final()]);
        var decipher = session.createDecipher(alg, _key.privateKey);
        var dec = decipher.update(enc);
        assert.equal(Buffer.concat([dec, decipher.final()]).toString(), MSG, "Correct");
    }

    function test_wrap_unwrap(_key, alg, _skey) {
        var wkey = session.wrapKey(alg, _key.publicKey, _skey);
        var ukey = session.unwrapKey(alg, _key.privateKey, wkey, {
            "class": graphene.ObjectClass.SECRET_KEY,
            "keyType": graphene.KeyType.AES,
            "token": false,
            "valueLen": 256 / 8,
            "encrypt": true,
            "decrypt": true
        });
	assert.equal(!!ukey.handle, true);
    }

    it("sign/verify SHA-1", function () {
        test_sign_verify(keys, "SHA1_RSA_PKCS");
    });

    it("sign/verify SHA-224", function () {
        test_sign_verify(keys, "SHA224_RSA_PKCS");
    });

    it("sign/verify SHA-256", function () {
        test_sign_verify(keys, "SHA256_RSA_PKCS");
    });

    it("sign/verify SHA-384", function () {
        test_sign_verify(keys, "SHA384_RSA_PKCS");
    });

    it("sign/verify SHA-512", function () {
        test_sign_verify(keys, "SHA512_RSA_PKCS");
    });

    it("OAEP encrypt/decrypt default SHA-1", function () {
        test_encrypt_decrypt(keys, { name: "RSA_PKCS_OAEP", params: new graphene.RsaOaepParams() })
    });

    it("OAEP encrypt/decrypt SHA-1", function () {
        test_encrypt_decrypt(keys, { name: "RSA_PKCS_OAEP", params: new graphene.RsaOaepParams(graphene.MechanismEnum.SHA1, graphene.RsaMgf.MGF1_SHA1) })
    });

    it("OAEP encrypt/decrypt SHA-1 with params", function () {
        test_encrypt_decrypt(keys, { name: "RSA_PKCS_OAEP", params: new graphene.RsaOaepParams(graphene.MechanismEnum.SHA1, graphene.RsaMgf.MGF1_SHA1, new Buffer([1,2,3,4,5,6,7,8,9,0])) })
    });

    it("OAEP wrap/unwrap SHA-1", function () {
        test_wrap_unwrap(keys, { name: "RSA_PKCS_OAEP", params: new graphene.RsaOaepParams() }, skey);
    });

    it("RSA 1.5 sign/verify", function () {
        test_sign_verify(keys, "RSA_PKCS");
    });

    it("RSA 1.5 encrypt/decrypt", function () {
        test_encrypt_decrypt(keys, "RSA_PKCS")
    });

    it("RSA 1.5 wrap/unwrap", function () {
        test_wrap_unwrap(keys, "RSA_PKCS", skey);
    });

    it("RSA PSS sign/verify SHA1", function () {
        test_sign_verify(keys, { name: "SHA1_RSA_PKCS_PSS", params: new RSA.RsaPSSParams(Enums.Mechanism.SHA1, Enums.MGF1.SHA1) });
    });

    it("RSA PSS sign/verify SHA224", function () {
        test_sign_verify(keys, { name: "SHA224_RSA_PKCS_PSS", params: new RSA.RsaPSSParams(Enums.Mechanism.SHA224, Enums.MGF1.SHA224) });
    });

    it("RSA PSS sign/verify SHA256", function () {
        test_sign_verify(keys, { name: "SHA256_RSA_PKCS_PSS", params: new RSA.RsaPSSParams(Enums.Mechanism.SHA256, Enums.MGF1.SHA256) });
    });

    it("RSA PSS sign/verify SHA384", function () {
        test_sign_verify(keys, { name: "SHA384_RSA_PKCS_PSS", params: new RSA.RsaPSSParams(Enums.Mechanism.SHA384, Enums.MGF1.SHA384) });
    });

    it("RSA PSS sign/verify SHA512", function () {
        test_sign_verify(keys, { name: "SHA512_RSA_PKCS_PSS", params: new RSA.RsaPSSParams(Enums.Mechanism.SHA512, Enums.MGF1.SHA512) });
    });

})<|endoftext|>


<commit_before>(function() {
  var driver;

  if (typeof require !== "undefined") {
    driver = require("./driver.js");
    require("./tests.js");
    require("./tests-harmony.js");
    require("./tests-jsx.js");
  } else {
    driver = window;
  }

  var htmlLog = typeof document === "object" && document.getElementById('log');
  var htmlGroup = htmlLog;

  function group(name) {
    if (htmlGroup) {
      var parentGroup = htmlGroup;
      htmlGroup = document.createElement("ul");
      var item = document.createElement("li");
      item.textContent = name;
      item.appendChild(htmlGroup);
      parentGroup.appendChild(item);
    }
    if (typeof console === "object" && console.group) {
      console.group(name);
    }
  }

  function groupEnd() {
    if (htmlGroup) {
      htmlGroup = htmlGroup.parentElement.parentElement;
    }
    if (typeof console === "object" && console.groupEnd) {
      console.groupEnd(name);
    }
  }

  function log(title, message) {
    if (htmlGroup) {
      var elem = document.createElement("li");
      elem.innerHTML = "" + title + " " + message;
      htmlGroup.appendChild(elem);
    }
    if (typeof console === "object") console.log(title, message);
  }

  var stats, modes = {
    Normal: {
      config: {
        parse: (typeof require === "undefined" ? window.acorn : require("../acorn.js")).parse
      }
    },
    Loose: {
      config: {
        parse: (typeof require === "undefined" ? window.acorn : require("../acorn_loose")).parse_dammit,
        loose: true,
        filter: function (test) {
          if (/`/.test(test.code)) return false; // FIXME remove this when the loose parse supports template strings
          var opts = test.options || {};
          if (opts.loose === false) return false;
          return (opts.ecmaVersion || 5) <= 6;
        }
      }
    }
  };

function report(state, code, message) {
    if (state != "ok") {++stats.failed; log(code, message);}
    ++stats.testsRun;
}

  group("Errors");

  for (var name in modes) {
    group(name);
    var mode = modes[name];
    stats = mode.stats = {testsRun: 0, failed: 0};
var t0 = +new Date;
    driver.runTests(mode.config, report);
    mode.stats.duration = +new Date - t0;
    groupEnd();
  }

  groupEnd();

  function outputStats(name, stats) {
    log(name + ":", stats.testsRun + " tests run in " + stats.duration + "ms; " +
      (stats.failed ? stats.failed + " failures." : "all passed."));
  }

  var total = {testsRun: 0, failed: 0, duration: 0};

  group("Stats");

  for (var name in modes) {
    var stats = modes[name].stats;
    outputStats(name + " parser", stats);
    for (var key in stats) total[key] += stats[key];
  }

  outputStats("Total", total);

  groupEnd();

  if (total.failed && typeof process === "object") {
  process.stdout.write("", function() {
    process.exit(1);
  });
  }
})();
<commit_msg>disable loose test runner<commit_after>(function() {
  var driver;

  if (typeof require !== "undefined") {
    driver = require("./driver.js");
    require("./tests.js");
    require("./tests-harmony.js");
    require("./tests-jsx.js");
  } else {
    driver = window;
  }

  var htmlLog = typeof document === "object" && document.getElementById('log');
  var htmlGroup = htmlLog;

  function group(name) {
    if (htmlGroup) {
      var parentGroup = htmlGroup;
      htmlGroup = document.createElement("ul");
      var item = document.createElement("li");
      item.textContent = name;
      item.appendChild(htmlGroup);
      parentGroup.appendChild(item);
    }
    if (typeof console === "object" && console.group) {
      console.group(name);
    }
  }

  function groupEnd() {
    if (htmlGroup) {
      htmlGroup = htmlGroup.parentElement.parentElement;
    }
    if (typeof console === "object" && console.groupEnd) {
      console.groupEnd(name);
    }
  }

  function log(title, message) {
    if (htmlGroup) {
      var elem = document.createElement("li");
      elem.innerHTML = "" + title + " " + message;
      htmlGroup.appendChild(elem);
    }
    if (typeof console === "object") console.log(title, message);
  }

  var stats, modes = {
    Normal: {
      config: {
        parse: (typeof require === "undefined" ? window.acorn : require("../acorn.js")).parse
      }
    }
  };

function report(state, code, message) {
    if (state != "ok") {++stats.failed; log(code, message);}
    ++stats.testsRun;
}

  group("Errors");

  for (var name in modes) {
    group(name);
    var mode = modes[name];
    stats = mode.stats = {testsRun: 0, failed: 0};
var t0 = +new Date;
    driver.runTests(mode.config, report);
    mode.stats.duration = +new Date - t0;
    groupEnd();
  }

  groupEnd();

  function outputStats(name, stats) {
    log(name + ":", stats.testsRun + " tests run in " + stats.duration + "ms; " +
      (stats.failed ? stats.failed + " failures." : "all passed."));
  }

  var total = {testsRun: 0, failed: 0, duration: 0};

  group("Stats");

  for (var name in modes) {
    var stats = modes[name].stats;
    outputStats(name + " parser", stats);
    for (var key in stats) total[key] += stats[key];
  }

  outputStats("Total", total);

  groupEnd();

  if (total.failed && typeof process === "object") {
  process.stdout.write("", function() {
    process.exit(1);
  });
  }
})();
<|endoftext|>


<commit_before>var assert = require("assert")
var fs = require('fs');
var path = require('path');
var newLine = require('os').EOL;
var tsLoader = require('../index');
var webpack = require('webpack');

function handleErrors(err, stats, done) {
    if (err) {
        done(err)
        return true;
    }

    if (stats.hasErrors()) {
        done(new Error(stats.toString({errorDetails: true})))
        return true;
    }
    return false;
}

function assertSourceContains(stats, moduleRegExp, content) {
    var statsJson = stats.toJson();
    var module = statsJson.modules.filter(function(m) { return m.name.match(moduleRegExp) })[0];
    assert.ok(module, 'module not found matching ' + moduleRegExp)
    assert.ok(module.source.indexOf(content) != -1, 'module doe not have matching content');
}

function assertModuleCount(stats, expectedNumberOfModules) {
    var statsJson = stats.toJson();
    assert.equal(statsJson.modules.length, expectedNumberOfModules, 'wrong number of modules found')
}

describe('files', function() {
    it('should not error', function(done) {
        webpack(require('./files/webpack.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                done()
            }
        })
    })
})

describe('basic', function() {

    it('should have the correct output', function(done) {
        webpack(require('./basic/webpack.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                var statsJson = stats.toJson();

                var appModule = statsJson.modules.filter(function(m) { return m.name == './test/basic/app.ts' })[0];
                var subModule = statsJson.modules.filter(function(m) { return m.name == './test/basic/submodule/submodule.ts' })[0];
                var externalLib = statsJson.modules.filter(function(m) { return m.name == './test/basic/lib/externalLib.js' })[0];

                assert.equal(appModule.source,
                    '///<reference path="_references.d.ts" />' + newLine +
                    "var submodule = require('./submodule/submodule');" + newLine +
                    "var externalLib = require('externalLib');" + newLine +
                    "externalLib.doSomething(submodule);" + newLine);

                assert.equal(subModule.source,
                    'var message = "Hello from submodule";' + newLine +
                    'module.exports = message;' + newLine);

                assert.ok(externalLib, 'External lib exists');

                done()
            }
        })
    })
})

describe('externals', function() {
    it('should not error', function(done) {
        webpack(require('./externals/webpack.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                done()
            }
        })
    })
})

describe('instance', function() {
    it('should error when incorrectly configured', function(done) {
        webpack(require('./instance/bad.config')).run(function(err, stats) {
            if (err) return done(err)

            var errors = stats.toJson().errors;

            assert.equal(errors.length, 1, 'Exactly one error should be reported');
            assert.ok(errors[0].indexOf("Subsequent variable declarations must have the same type") != -1, 'The error reported was the wrong error');

            done();
        })
    })

    it('should not error when correctly configured', function(done) {
        webpack(require('./instance/good.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                done();
            }
        })
    })
})

describe('jsx', function() {
    it('should not error', function(done) {
        webpack(require('./jsx/webpack.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                done()
            }
        })
    })
})

describe('node', function() {
    it('should not error', function(done) {
        webpack(require('./node/webpack.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                done()
            }
        })
    })
})

describe('noImplicitAny', function() {
    it('should fail when turned on', function(done) {
        webpack(require('./noImplicitAny/on.config')).run(function(err, stats) {
            if (err) return done(err)

            var errors = stats.toJson().errors;

            assert.equal(errors.length, 1, 'Exactly one errors should be reported');
            assert.ok(errors[0].indexOf("Parameter 'a' implicitly has an 'any' type.") != -1, 'The error reported was the wrong error');

            done();
        })
    })

    it('should not fail when turned off', function(done) {
        webpack(require('./noImplicitAny/off.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                done();
            }
        })
    })

})

describe('replacement', function() {
    it('should have the correct output', function(done) {
        webpack(require('./replacement/webpack.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {

                assertModuleCount(stats, 3);
                assertSourceContains(stats, /a\.ts$/, "var dep = require('./dep')")
                assertSourceContains(stats, /dep\.ts$/, "var dep = 'replacement'")

                done();
            }
        })
    })
})

// Disabling the source maps unit tests until a better way can be implemented to actually check for their presence
/*
describe('sourceMaps', function() {
    it('should be present when turned on', function(done) {
        webpack(require('./sourceMaps/on.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                var statsJson = stats.toJson();

                var module = statsJson.modules.filter(function(m) { return m.name == './test/sourceMaps/a.ts' })[0];

                assert.equal(module.source, "console.log('Hello world');" + newLine + "//# sourceMappingURL=a.js.map");

                done();
            }
        })
    })

    it('should not be present when turned off', function(done) {
        webpack(require('./sourceMaps/off.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                var statsJson = stats.toJson();

                var module = statsJson.modules.filter(function(m) { return m.name == './test/sourceMaps/a.ts' })[0];

                assert.equal(module.source, "console.log('Hello world');" + newLine);

                done();
            }
        })
    })

})
*/

describe('targets', function() {
    it('es3', function(done) {
        webpack(require('./targets/es3.config')).run(function(err, stats) {
            if (err) return done(err)

            var errors = stats.toJson().errors;

            assert.equal(errors.length, 1, 'Exactly one error should be reported');
            assert.ok(errors[0].indexOf("Accessors are only available when targeting ECMAScript 5 and higher") != -1, 'The error reported was the wrong error');

            done();
        })
    })

    it('es5', function(done) {
        webpack(require('./targets/es5.config')).run(function(err, stats) {
            if (err) return done(err)

            var statsJson = stats.toJson(),
                errors = statsJson.errors;

            assert.equal(errors.length, 1, 'Exactly one error should be reported');
            assert.ok(errors[0].indexOf("Cannot find name 'Symbol'.") != -1, 'The error reported was the wrong error');

            done();
        })
    })

    it('es6', function(done) {
        webpack(require('./targets/es6.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                done();
            }
        })
    })

})

describe('module', function() {

    it('commonjs', function(done) {
        webpack(require('./module/commonjs.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                var statsJson = stats.toJson();

                var module = statsJson.modules.filter(function(m) { return m.name == './test/module/a.ts' })[0];

                assert.ok(!module.source.match(/^define/));

                done();
            }
        })
    })

    it('amd', function(done) {
        webpack(require('./module/amd.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                var statsJson = stats.toJson();

                var module = statsJson.modules.filter(function(m) { return m.name == './test/module/a.ts' })[0];

                assert.ok(module.source.match(/^define/));

                done();
            }
        })
    })

})

describe('tsconfig', function() {
    it('should not error', function(done) {
        webpack(require('./tsconfig/webpack.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                done()
            }
        })
    })

    it('should not error when using parent dir', function(done) {
        webpack(require('./tsconfig/parentDir.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                done()
            }
        })
    })
})<commit_msg>Disable jsx-typescript unit test temporarily<commit_after>var assert = require("assert")
var fs = require('fs');
var path = require('path');
var newLine = require('os').EOL;
var tsLoader = require('../index');
var webpack = require('webpack');

function handleErrors(err, stats, done) {
    if (err) {
        done(err)
        return true;
    }

    if (stats.hasErrors()) {
        done(new Error(stats.toString({errorDetails: true})))
        return true;
    }
    return false;
}

function assertSourceContains(stats, moduleRegExp, content) {
    var statsJson = stats.toJson();
    var module = statsJson.modules.filter(function(m) { return m.name.match(moduleRegExp) })[0];
    assert.ok(module, 'module not found matching ' + moduleRegExp)
    assert.ok(module.source.indexOf(content) != -1, 'module doe not have matching content');
}

function assertModuleCount(stats, expectedNumberOfModules) {
    var statsJson = stats.toJson();
    assert.equal(statsJson.modules.length, expectedNumberOfModules, 'wrong number of modules found')
}

describe('files', function() {
    it('should not error', function(done) {
        webpack(require('./files/webpack.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                done()
            }
        })
    })
})

describe('basic', function() {

    it('should have the correct output', function(done) {
        webpack(require('./basic/webpack.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                var statsJson = stats.toJson();

                var appModule = statsJson.modules.filter(function(m) { return m.name == './test/basic/app.ts' })[0];
                var subModule = statsJson.modules.filter(function(m) { return m.name == './test/basic/submodule/submodule.ts' })[0];
                var externalLib = statsJson.modules.filter(function(m) { return m.name == './test/basic/lib/externalLib.js' })[0];

                assert.equal(appModule.source,
                    '///<reference path="_references.d.ts" />' + newLine +
                    "var submodule = require('./submodule/submodule');" + newLine +
                    "var externalLib = require('externalLib');" + newLine +
                    "externalLib.doSomething(submodule);" + newLine);

                assert.equal(subModule.source,
                    'var message = "Hello from submodule";' + newLine +
                    'module.exports = message;' + newLine);

                assert.ok(externalLib, 'External lib exists');

                done()
            }
        })
    })
})

describe('externals', function() {
    it('should not error', function(done) {
        webpack(require('./externals/webpack.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                done()
            }
        })
    })
})

describe('instance', function() {
    it('should error when incorrectly configured', function(done) {
        webpack(require('./instance/bad.config')).run(function(err, stats) {
            if (err) return done(err)

            var errors = stats.toJson().errors;

            assert.equal(errors.length, 1, 'Exactly one error should be reported');
            assert.ok(errors[0].indexOf("Subsequent variable declarations must have the same type") != -1, 'The error reported was the wrong error');

            done();
        })
    })

    it('should not error when correctly configured', function(done) {
        webpack(require('./instance/good.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                done();
            }
        })
    })
})
// Disabling the jsx unit tests until jsx-typescript is updated to TS 1.5
/*
describe('jsx', function() {
    it('should not error', function(done) {
        webpack(require('./jsx/webpack.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                done()
            }
        })
    })
})
*/
describe('node', function() {
    it('should not error', function(done) {
        webpack(require('./node/webpack.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                done()
            }
        })
    })
})

describe('noImplicitAny', function() {
    it('should fail when turned on', function(done) {
        webpack(require('./noImplicitAny/on.config')).run(function(err, stats) {
            if (err) return done(err)

            var errors = stats.toJson().errors;

            assert.equal(errors.length, 1, 'Exactly one errors should be reported');
            assert.ok(errors[0].indexOf("Parameter 'a' implicitly has an 'any' type.") != -1, 'The error reported was the wrong error');

            done();
        })
    })

    it('should not fail when turned off', function(done) {
        webpack(require('./noImplicitAny/off.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                done();
            }
        })
    })

})

describe('replacement', function() {
    it('should have the correct output', function(done) {
        webpack(require('./replacement/webpack.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {

                assertModuleCount(stats, 3);
                assertSourceContains(stats, /a\.ts$/, "var dep = require('./dep')")
                assertSourceContains(stats, /dep\.ts$/, "var dep = 'replacement'")

                done();
            }
        })
    })
})

// Disabling the source maps unit tests until a better way can be implemented to actually check for their presence
/*
describe('sourceMaps', function() {
    it('should be present when turned on', function(done) {
        webpack(require('./sourceMaps/on.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                var statsJson = stats.toJson();

                var module = statsJson.modules.filter(function(m) { return m.name == './test/sourceMaps/a.ts' })[0];

                assert.equal(module.source, "console.log('Hello world');" + newLine + "//# sourceMappingURL=a.js.map");

                done();
            }
        })
    })

    it('should not be present when turned off', function(done) {
        webpack(require('./sourceMaps/off.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                var statsJson = stats.toJson();

                var module = statsJson.modules.filter(function(m) { return m.name == './test/sourceMaps/a.ts' })[0];

                assert.equal(module.source, "console.log('Hello world');" + newLine);

                done();
            }
        })
    })

})
*/

describe('targets', function() {
    it('es3', function(done) {
        webpack(require('./targets/es3.config')).run(function(err, stats) {
            if (err) return done(err)

            var errors = stats.toJson().errors;

            assert.equal(errors.length, 1, 'Exactly one error should be reported');
            assert.ok(errors[0].indexOf("Accessors are only available when targeting ECMAScript 5 and higher") != -1, 'The error reported was the wrong error');

            done();
        })
    })

    it('es5', function(done) {
        webpack(require('./targets/es5.config')).run(function(err, stats) {
            if (err) return done(err)

            var statsJson = stats.toJson(),
                errors = statsJson.errors;

            assert.equal(errors.length, 1, 'Exactly one error should be reported');
            assert.ok(errors[0].indexOf("Cannot find name 'Symbol'.") != -1, 'The error reported was the wrong error');

            done();
        })
    })

    it('es6', function(done) {
        webpack(require('./targets/es6.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                done();
            }
        })
    })

})

describe('module', function() {

    it('commonjs', function(done) {
        webpack(require('./module/commonjs.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                var statsJson = stats.toJson();

                var module = statsJson.modules.filter(function(m) { return m.name == './test/module/a.ts' })[0];

                assert.ok(!module.source.match(/^define/));

                done();
            }
        })
    })

    it('amd', function(done) {
        webpack(require('./module/amd.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                var statsJson = stats.toJson();

                var module = statsJson.modules.filter(function(m) { return m.name == './test/module/a.ts' })[0];

                assert.ok(module.source.match(/^define/));

                done();
            }
        })
    })

})

describe('tsconfig', function() {
    it('should not error', function(done) {
        webpack(require('./tsconfig/webpack.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                done()
            }
        })
    })

    it('should not error when using parent dir', function(done) {
        webpack(require('./tsconfig/parentDir.config')).run(function(err, stats) {
            if (!handleErrors(err, stats, done)) {
                done()
            }
        })
    })
})<|endoftext|>


<commit_before>var options = {};

if (process.env.filter) {
  options.include = new RegExp(process.env.filter + '.*\\.js$');
}

require('urun')(__dirname, options);
<commit_msg>env variables are all uppercase<commit_after>var options = {};

if (process.env.FILTER) {
  options.include = new RegExp(process.env.FILTER + '.*\\.js$');
}

require('urun')(__dirname, options);
<|endoftext|>


<commit_before>import React from 'react'
import sinon from 'sinon'
import { expect } from 'chai'
import { render, mount, shallow } from 'enzyme'
import { DraftWidget, Loading } from './../../components'
import * as Paths from './../../Paths'

let wrapper

describe('DraftWidget', () => {
  let props = {
    dispatch     : () => {},
    auth         : {},
    mobilization : {},
    widget       : {},
    editable     : true
  }

  context('when it is editable', () => {
    before(() => {
      sinon.spy(DraftWidget.prototype, 'updateKind')
    })

    beforeEach(() => {
      wrapper = shallow(<DraftWidget {...props} />)
    })

    after(() => {
      DraftWidget.prototype.updateKind.restore()
    })

    describe('#render', () => {
      it('should render a draft widget containing html elements passing editable prop enabled', () => {
        expect(wrapper.find('div.widget').length).to.equal(1)
        expect(wrapper.find('div.widget h4').length).to.equal(1)
        expect(wrapper.find('div.widget button').length).to.equal(3)
        expect(wrapper.state().loading).to.equal(false)
      })
    })

    describe('#handleContentClick', () => {
      it('should call updateKind with `content` parameter', () => {
        wrapper.find('button').at(0).simulate('click', { preventDefault() {} })

        const updateKind = DraftWidget.prototype.updateKind
        expect(updateKind.called).to.equal(true)
        expect(updateKind.calledWith('content')).to.equal(true)
        expect(wrapper.state().loading).to.equal(true)
      })
    })

    describe('#handleFormClick', () => {
      it('should call updateKind with `form` parameter', () => {
        wrapper.find('button').at(1).simulate('click', { preventDefault() {} })

        const updateKind = DraftWidget.prototype.updateKind
        expect(updateKind.called).to.equal(true)
        expect(updateKind.calledWith('form')).to.equal(true)
        expect(wrapper.state().loading).to.equal(true)
      })
    })

    describe('#handleDonationClick', () => {
      it('should call updateKind with `donation` parameter', () => {
        wrapper.find('button').at(2).simulate('click', { preventDefault() {} })

        const updateKind = DraftWidget.prototype.updateKind
        expect(updateKind.called).to.equal(true)
        expect(updateKind.calledWith('donation')).to.equal(true)
        expect(wrapper.state().loading).to.equal(true)
      })
    })

    describe('#renderLoading', () => {
      it('should return rendered Loading component if `state.loading` is true', () => {
        wrapper.setState({ loading: true })
        expect(wrapper.contains(<Loading />)).to.be.true
      })
    })
  })

  context('when it isn\'t editable', () => {
    before(() => {
      wrapper = shallow(<DraftWidget {...props} editable={false} />)
    })

    describe('#render', () => {
      it('should render an empty div', () => {
        expect(wrapper.contains(

)).to.be.true
        expect(wrapper.find('div.widget').length).to.equal(0)
        expect(wrapper.find('div.widget h4').length).to.equal(0)
        expect(wrapper.find('div.widget button').length).to.equal(0)
      })
    })
  })
})
<commit_msg>Fix DraftWidget component tests imports.<commit_after>import React from 'react'
import sinon from 'sinon'
import { expect } from 'chai'
import { render, mount, shallow } from 'enzyme'
import { DraftWidget, Loading } from './'
import * as Paths from './../Paths'

let wrapper

describe('DraftWidget', () => {
  let props = {
    dispatch     : () => {},
    auth         : {},
    mobilization : {},
    widget       : {},
    editable     : true
  }

  context('when it is editable', () => {
    before(() => {
      sinon.spy(DraftWidget.prototype, 'updateKind')
    })

    beforeEach(() => {
      wrapper = shallow(<DraftWidget {...props} />)
    })

    after(() => {
      DraftWidget.prototype.updateKind.restore()
    })

    describe('#render', () => {
      it('should render a draft widget containing html elements passing editable prop enabled', () => {
        expect(wrapper.find('div.widget').length).to.equal(1)
        expect(wrapper.find('div.widget h4').length).to.equal(1)
        expect(wrapper.find('div.widget button').length).to.equal(3)
        expect(wrapper.state().loading).to.equal(false)
      })
    })

    describe('#handleContentClick', () => {
      it('should call updateKind with `content` parameter', () => {
        wrapper.find('button').at(0).simulate('click', { preventDefault() {} })

        const updateKind = DraftWidget.prototype.updateKind
        expect(updateKind.called).to.equal(true)
        expect(updateKind.calledWith('content')).to.equal(true)
        expect(wrapper.state().loading).to.equal(true)
      })
    })

    describe('#handleFormClick', () => {
      it('should call updateKind with `form` parameter', () => {
        wrapper.find('button').at(1).simulate('click', { preventDefault() {} })

        const updateKind = DraftWidget.prototype.updateKind
        expect(updateKind.called).to.equal(true)
        expect(updateKind.calledWith('form')).to.equal(true)
        expect(wrapper.state().loading).to.equal(true)
      })
    })

    describe('#handleDonationClick', () => {
      it('should call updateKind with `donation` parameter', () => {
        wrapper.find('button').at(2).simulate('click', { preventDefault() {} })

        const updateKind = DraftWidget.prototype.updateKind
        expect(updateKind.called).to.equal(true)
        expect(updateKind.calledWith('donation')).to.equal(true)
        expect(wrapper.state().loading).to.equal(true)
      })
    })

    describe('#renderLoading', () => {
      it('should return rendered Loading component if `state.loading` is true', () => {
        wrapper.setState({ loading: true })
        expect(wrapper.contains(<Loading />)).to.be.true
      })
    })
  })

  context('when it isn\'t editable', () => {
    before(() => {
      wrapper = shallow(<DraftWidget {...props} editable={false} />)
    })

    describe('#render', () => {
      it('should render an empty div', () => {
        expect(wrapper.contains(

)).to.be.true
        expect(wrapper.find('div.widget').length).to.equal(0)
        expect(wrapper.find('div.widget h4').length).to.equal(0)
        expect(wrapper.find('div.widget button').length).to.equal(0)
      })
    })
  })
})
<|endoftext|>


<commit_before>/**
 * flexselect: a jQuery plugin, version: %RELEASE_VERSION% (%RELEASE_DATE%)
 * @requires jQuery v1.3 or later
 *
 * FlexSelect is a jQuery plugin that makes it easy to convert a select box into
 * a Quicksilver-style, autocompleting, flex matching selection tool.
 *
 * For usage and examples, visit:
 * http://rmm5t.github.io/jquery-flexselect/
 *
 * Licensed under the MIT:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright (c) 2009-2015, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
 */
(function($) {
  $.flexselect = function(select, options) { this.init(select, options); };

  $.extend($.flexselect.prototype, {
    settings: {
      allowMismatch: false,
      allowMismatchBlank: true, // If "true" a user can backspace such that the value is nothing (even if no blank value was provided in the original criteria)
      sortBy: 'score', // 'score' || 'name'
      preSelection: true,
      hideDropdownOnEmptyInput: false,
      selectedClass: "flexselect_selected",
      dropdownClass: "flexselect_dropdown",
      showDisabledOptions: false,
      inputIdTransform:    function(id)   { return id + "_flexselect"; },
      inputNameTransform:  function(name) { return; },
      dropdownIdTransform: function(id)   { return id + "_flexselect_dropdown"; }
    },
    select: null,
    input: null,
    dropdown: null,
    dropdownList: null,
    cache: [],
    results: [],
    lastAbbreviation: null,
    abbreviationBeforeFocus: null,
    selectedIndex: 0,
    picked: false,
    allowMouseMove: true,
    dropdownMouseover: false, // Workaround for poor IE behaviors
    indexOptgroupLabels: false,

    init: function(select, options) {
      this.settings = $.extend({}, this.settings, options);
      this.select = $(select);
      this.reloadCache();
      this.renderControls();
      this.wire();
    },

    reloadCache: function() {
      var name, group, text, disabled;
      var indexGroup = this.settings.indexOptgroupLabels;
      this.cache = this.select.find("option").map(function() {
        name = $(this).text();
        group = $(this).parent("optgroup").attr("label");
        text = indexGroup ? [name, group].join(" ") : name;
        disabled = $(this).parent("optgroup").attr("disabled") || $(this).attr('disabled');
        return { text: $.trim(text), name: $.trim(name), value: $(this).val(), disabled: disabled, score: 0.0 };
      });
    },

    renderControls: function() {
      var selected = this.settings.preSelection ? this.select.find("option:selected") : null;

      this.input = $("<input type='text' autocomplete='off' />").attr({
        id: this.settings.inputIdTransform(this.select.attr("id")),
        name: this.settings.inputNameTransform(this.select.attr("name")),
        accesskey: this.select.attr("accesskey"),
        tabindex: this.select.attr("tabindex"),
        style: this.select.attr("style"),
        placeholder: this.select.attr("data-placeholder")
      }).addClass(this.select.attr("class")).val($.trim(selected ? selected.text():  '')).css({
        visibility: 'visible'
      });

      this.dropdown = $("

").attr({
        id: this.settings.dropdownIdTransform(this.select.attr("id"))
      }).addClass(this.settings.dropdownClass);
      this.dropdownList = $("

");
      this.dropdown.append(this.dropdownList);

      this.select.after(this.input).hide();
      $("body").append(this.dropdown);
    },

    wire: function() {
      var self = this;

      this.input.click(function() {
        self.lastAbbreviation = null;
        self.focus();
      });

      this.input.mouseup(function(event) {
        // This is so Safari selection actually occurs.
        event.preventDefault();
      });

      this.input.focus(function() {
        self.abbreviationBeforeFocus = self.input.val();
        self.input.select();
        if (!self.picked) self.filterResults();
      });

      this.input.blur(function() {
        if (!self.dropdownMouseover) {
          self.hide();
          if (self.settings.allowMismatchBlank && $.trim($(this).val()) == '')
            self.setValue('');
          if (!self.settings.allowMismatch && !self.picked)
            self.reset();
        }
        if (self.settings.hideDropdownOnEmptyInput)
          self.dropdownList.show();
      });

      this.dropdownList.mouseover(function(event) {
        if (!self.allowMouseMove) {
          self.allowMouseMove = true;
          return;
        }

        if (event.target.tagName == "LI") {
          var rows = self.dropdown.find("li");
          self.markSelected(rows.index($(event.target)));
        }
      });
      this.dropdownList.mouseleave(function() {
        self.markSelected(-1);
      });
      this.dropdownList.mouseup(function(event) {
        self.pickSelected();
        self.focusAndHide();
      });
      this.dropdown.mouseover(function(event) {
        self.dropdownMouseover = true;
      });
      this.dropdown.mouseleave(function(event) {
        self.dropdownMouseover = false;
      });
      this.dropdown.mousedown(function(event) {
        event.preventDefault();
      });

      this.input.keyup(function(event) {
        switch (event.keyCode) {
          case 13: // return
            event.preventDefault();
            self.pickSelected();
            self.focusAndHide();
            break;
          case 27: // esc
            event.preventDefault();
            self.reset();
            self.focusAndHide();
            break;
          default:
            self.filterResults();
            break;
        }
        if (self.settings.hideDropdownOnEmptyInput){
          if(self.input.val() == "")
            self.dropdownList.hide();
          else
            self.dropdownList.show();
        }
      });

      this.input.keydown(function(event) {
        switch (event.keyCode) {
          case 9:  // tab
            self.pickSelected();
            self.hide();
            break;
          case 33: // pgup
            event.preventDefault();
            self.markFirst();
            break;
          case 34: // pgedown
            event.preventDefault();
            self.markLast();
            break;
          case 38: // up
            event.preventDefault();
            self.moveSelected(-1);
            break;
          case 40: // down
            event.preventDefault();
            self.moveSelected(1);
            break;
          case 13: // return
          case 27: // esc
            event.preventDefault();
            event.stopPropagation();
            break;
        }
      });

      var input = this.input;
      this.select.change(function () {
        input.val($.trim($(this).find('option:selected').text()));
      });
    },

    filterResults: function() {
      var showDisabled = this.settings.showDisabledOptions;
      var abbreviation = this.input.val();
      if (abbreviation == this.lastAbbreviation) return;

      var results = [];
      $.each(this.cache, function() {
        if (this.disabled && !showDisabled) return;
        this.score = LiquidMetal.score(this.text, abbreviation);
        if (this.score > 0.0) results.push(this);
      });
      this.results = results;

      if (this.settings.sortBy == 'score')
        this.sortResultsByScore();
      else if (this.settings.sortBy == 'name')
        this.sortResultsByName();

      this.renderDropdown();
      this.markFirst();
      this.lastAbbreviation = abbreviation;
      this.picked = false;
      this.allowMouseMove = false;
    },

    sortResultsByScore: function() {
      this.results.sort(function(a, b) { return b.score - a.score; });
    },

    sortResultsByName: function() {
      this.results.sort(function(a, b) { return a.name  b.name ? 1 : 0); });
    },

    renderDropdown: function() {
      var showDisabled = this.settings.showDisabledOptions;
      var dropdownBorderWidth = this.dropdown.outerWidth() - this.dropdown.innerWidth();
      var inputOffset = this.input.offset();
      this.dropdown.css({
        width: (this.input.outerWidth() - dropdownBorderWidth) + "px",
        top: (inputOffset.top + this.input.outerHeight()) + "px",
        left: inputOffset.left + "px",
        maxHeight: ''
      });

      var html = '';
      var disabledAttribute = '';
      $.each(this.results, function() {
        if (this.disabled && !showDisabled) return;
        disabledAttribute = this.disabled ? ' class="disabled"' : '';
        html += '
' + this.name + '
';
      });
      this.dropdownList.html(html);
      this.adjustMaxHeight();
      this.dropdown.show();
    },

    adjustMaxHeight: function() {
      var maxTop = $(window).height() + $(window).scrollTop() - this.dropdown.outerHeight();
      var top = parseInt(this.dropdown.css('top'), 10);
      this.dropdown.css('max-height', top > maxTop ? (Math.max(0, maxTop - top + this.dropdown.innerHeight()) + 'px') : '');
    },

    markSelected: function(n) {
      if (n < 0 || n >= this.results.length) return;

      var rows = this.dropdown.find("li");
      rows.removeClass(this.settings.selectedClass);

      var row = $(rows[n]);
      if (row.hasClass('disabled')) {
        this.selectedIndex = null;
        return;
      }

      this.selectedIndex = n;
      row.addClass(this.settings.selectedClass);
      var top = row.position().top;
      var delta = top + row.outerHeight() - this.dropdown.height();
      if (delta > 0) {
        this.allowMouseMove = false;
        this.dropdown.scrollTop(this.dropdown.scrollTop() + delta);
      } else if (top < 0) {
        this.allowMouseMove = false;
        this.dropdown.scrollTop(Math.max(0, this.dropdown.scrollTop() + top));
      }
    },

    pickSelected: function() {
      var selected = this.results[this.selectedIndex];
      if (selected && !selected.disabled) {
        this.input.val(selected.name);
        this.setValue(selected.value);
        this.picked = true;
      } else if (this.settings.allowMismatch) {
        this.setValue.val("");
      } else {
        this.reset();
      }
    },

    setValue: function(val) {
      if (this.select.val() === val) return;
      this.select.val(val).change();
    },

    hide: function() {
      this.dropdown.hide();
      this.lastAbbreviation = null;
    },

    moveSelected: function(n) { this.markSelected(this.selectedIndex+n); },
    markFirst:    function()  { this.markSelected(0); },
    markLast:     function()  { this.markSelected(this.results.length - 1); },
    reset:        function()  { this.input.val(this.abbreviationBeforeFocus); },
    focus:        function()  { this.input.focus(); },
    focusAndHide: function()  { this.focus(); this.hide(); }
  });

  $.fn.flexselect = function(options) {
    this.each(function() {
      if ($(this).data("flexselect")) {
        $(this).data("flexselect").reloadCache();
      } else if (this.tagName == "SELECT") {
        $(this).data("flexselect", new $.flexselect(this, options));
      }
    });
    return this;
  };
})(jQuery);
<commit_msg>Selection range all on mobile<commit_after>/**
 * flexselect: a jQuery plugin, version: %RELEASE_VERSION% (%RELEASE_DATE%)
 * @requires jQuery v1.3 or later
 *
 * FlexSelect is a jQuery plugin that makes it easy to convert a select box into
 * a Quicksilver-style, autocompleting, flex matching selection tool.
 *
 * For usage and examples, visit:
 * http://rmm5t.github.io/jquery-flexselect/
 *
 * Licensed under the MIT:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright (c) 2009-2015, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
 */
(function($) {
  $.flexselect = function(select, options) { this.init(select, options); };

  $.extend($.flexselect.prototype, {
    settings: {
      allowMismatch: false,
      allowMismatchBlank: true, // If "true" a user can backspace such that the value is nothing (even if no blank value was provided in the original criteria)
      sortBy: 'score', // 'score' || 'name'
      preSelection: true,
      hideDropdownOnEmptyInput: false,
      selectedClass: "flexselect_selected",
      dropdownClass: "flexselect_dropdown",
      showDisabledOptions: false,
      inputIdTransform:    function(id)   { return id + "_flexselect"; },
      inputNameTransform:  function(name) { return; },
      dropdownIdTransform: function(id)   { return id + "_flexselect_dropdown"; }
    },
    select: null,
    input: null,
    dropdown: null,
    dropdownList: null,
    cache: [],
    results: [],
    lastAbbreviation: null,
    abbreviationBeforeFocus: null,
    selectedIndex: 0,
    picked: false,
    allowMouseMove: true,
    dropdownMouseover: false, // Workaround for poor IE behaviors
    indexOptgroupLabels: false,

    init: function(select, options) {
      this.settings = $.extend({}, this.settings, options);
      this.select = $(select);
      this.reloadCache();
      this.renderControls();
      this.wire();
    },

    reloadCache: function() {
      var name, group, text, disabled;
      var indexGroup = this.settings.indexOptgroupLabels;
      this.cache = this.select.find("option").map(function() {
        name = $(this).text();
        group = $(this).parent("optgroup").attr("label");
        text = indexGroup ? [name, group].join(" ") : name;
        disabled = $(this).parent("optgroup").attr("disabled") || $(this).attr('disabled');
        return { text: $.trim(text), name: $.trim(name), value: $(this).val(), disabled: disabled, score: 0.0 };
      });
    },

    renderControls: function() {
      var selected = this.settings.preSelection ? this.select.find("option:selected") : null;

      this.input = $("<input type='text' autocomplete='off' />").attr({
        id: this.settings.inputIdTransform(this.select.attr("id")),
        name: this.settings.inputNameTransform(this.select.attr("name")),
        accesskey: this.select.attr("accesskey"),
        tabindex: this.select.attr("tabindex"),
        style: this.select.attr("style"),
        placeholder: this.select.attr("data-placeholder")
      }).addClass(this.select.attr("class")).val($.trim(selected ? selected.text():  '')).css({
        visibility: 'visible'
      });

      this.dropdown = $("

").attr({
        id: this.settings.dropdownIdTransform(this.select.attr("id"))
      }).addClass(this.settings.dropdownClass);
      this.dropdownList = $("

");
      this.dropdown.append(this.dropdownList);

      this.select.after(this.input).hide();
      $("body").append(this.dropdown);
    },

    wire: function() {
      var self = this;

      this.input.click(function() {
        self.lastAbbreviation = null;
        self.focus();
      });

      this.input.mouseup(function(event) {
        // This is so Safari selection actually occurs.
        event.preventDefault();
      });

      this.input.focus(function() {
        self.abbreviationBeforeFocus = self.input.val();
        self.input[0].setSelectionRange(0, 999);
        if (!self.picked) self.filterResults();
      });

      this.input.blur(function() {
        if (!self.dropdownMouseover) {
          self.hide();
          if (self.settings.allowMismatchBlank && $.trim($(this).val()) == '')
            self.setValue('');
          if (!self.settings.allowMismatch && !self.picked)
            self.reset();
        }
        if (self.settings.hideDropdownOnEmptyInput)
          self.dropdownList.show();
      });

      this.dropdownList.mouseover(function(event) {
        if (!self.allowMouseMove) {
          self.allowMouseMove = true;
          return;
        }

        if (event.target.tagName == "LI") {
          var rows = self.dropdown.find("li");
          self.markSelected(rows.index($(event.target)));
        }
      });
      this.dropdownList.mouseleave(function() {
        self.markSelected(-1);
      });
      this.dropdownList.mouseup(function(event) {
        self.pickSelected();
        self.focusAndHide();
      });
      this.dropdown.mouseover(function(event) {
        self.dropdownMouseover = true;
      });
      this.dropdown.mouseleave(function(event) {
        self.dropdownMouseover = false;
      });
      this.dropdown.mousedown(function(event) {
        event.preventDefault();
      });

      this.input.keyup(function(event) {
        switch (event.keyCode) {
          case 13: // return
            event.preventDefault();
            self.pickSelected();
            self.focusAndHide();
            break;
          case 27: // esc
            event.preventDefault();
            self.reset();
            self.focusAndHide();
            break;
          default:
            self.filterResults();
            break;
        }
        if (self.settings.hideDropdownOnEmptyInput){
          if(self.input.val() == "")
            self.dropdownList.hide();
          else
            self.dropdownList.show();
        }
      });

      this.input.keydown(function(event) {
        switch (event.keyCode) {
          case 9:  // tab
            self.pickSelected();
            self.hide();
            break;
          case 33: // pgup
            event.preventDefault();
            self.markFirst();
            break;
          case 34: // pgedown
            event.preventDefault();
            self.markLast();
            break;
          case 38: // up
            event.preventDefault();
            self.moveSelected(-1);
            break;
          case 40: // down
            event.preventDefault();
            self.moveSelected(1);
            break;
          case 13: // return
          case 27: // esc
            event.preventDefault();
            event.stopPropagation();
            break;
        }
      });

      var input = this.input;
      this.select.change(function () {
        input.val($.trim($(this).find('option:selected').text()));
      });
    },

    filterResults: function() {
      var showDisabled = this.settings.showDisabledOptions;
      var abbreviation = this.input.val();
      if (abbreviation == this.lastAbbreviation) return;

      var results = [];
      $.each(this.cache, function() {
        if (this.disabled && !showDisabled) return;
        this.score = LiquidMetal.score(this.text, abbreviation);
        if (this.score > 0.0) results.push(this);
      });
      this.results = results;

      if (this.settings.sortBy == 'score')
        this.sortResultsByScore();
      else if (this.settings.sortBy == 'name')
        this.sortResultsByName();

      this.renderDropdown();
      this.markFirst();
      this.lastAbbreviation = abbreviation;
      this.picked = false;
      this.allowMouseMove = false;
    },

    sortResultsByScore: function() {
      this.results.sort(function(a, b) { return b.score - a.score; });
    },

    sortResultsByName: function() {
      this.results.sort(function(a, b) { return a.name  b.name ? 1 : 0); });
    },

    renderDropdown: function() {
      var showDisabled = this.settings.showDisabledOptions;
      var dropdownBorderWidth = this.dropdown.outerWidth() - this.dropdown.innerWidth();
      var inputOffset = this.input.offset();
      this.dropdown.css({
        width: (this.input.outerWidth() - dropdownBorderWidth) + "px",
        top: (inputOffset.top + this.input.outerHeight()) + "px",
        left: inputOffset.left + "px",
        maxHeight: ''
      });

      var html = '';
      var disabledAttribute = '';
      $.each(this.results, function() {
        if (this.disabled && !showDisabled) return;
        disabledAttribute = this.disabled ? ' class="disabled"' : '';
        html += '
' + this.name + '
';
      });
      this.dropdownList.html(html);
      this.adjustMaxHeight();
      this.dropdown.show();
    },

    adjustMaxHeight: function() {
      var maxTop = $(window).height() + $(window).scrollTop() - this.dropdown.outerHeight();
      var top = parseInt(this.dropdown.css('top'), 10);
      this.dropdown.css('max-height', top > maxTop ? (Math.max(0, maxTop - top + this.dropdown.innerHeight()) + 'px') : '');
    },

    markSelected: function(n) {
      if (n < 0 || n >= this.results.length) return;

      var rows = this.dropdown.find("li");
      rows.removeClass(this.settings.selectedClass);

      var row = $(rows[n]);
      if (row.hasClass('disabled')) {
        this.selectedIndex = null;
        return;
      }

      this.selectedIndex = n;
      row.addClass(this.settings.selectedClass);
      var top = row.position().top;
      var delta = top + row.outerHeight() - this.dropdown.height();
      if (delta > 0) {
        this.allowMouseMove = false;
        this.dropdown.scrollTop(this.dropdown.scrollTop() + delta);
      } else if (top < 0) {
        this.allowMouseMove = false;
        this.dropdown.scrollTop(Math.max(0, this.dropdown.scrollTop() + top));
      }
    },

    pickSelected: function() {
      var selected = this.results[this.selectedIndex];
      if (selected && !selected.disabled) {
        this.input.val(selected.name);
        this.setValue(selected.value);
        this.picked = true;
      } else if (this.settings.allowMismatch) {
        this.setValue.val("");
      } else {
        this.reset();
      }
    },

    setValue: function(val) {
      if (this.select.val() === val) return;
      this.select.val(val).change();
    },

    hide: function() {
      this.dropdown.hide();
      this.lastAbbreviation = null;
    },

    moveSelected: function(n) { this.markSelected(this.selectedIndex+n); },
    markFirst:    function()  { this.markSelected(0); },
    markLast:     function()  { this.markSelected(this.results.length - 1); },
    reset:        function()  { this.input.val(this.abbreviationBeforeFocus); },
    focus:        function()  { this.input.focus(); },
    focusAndHide: function()  { this.focus(); this.hide(); }
  });

  $.fn.flexselect = function(options) {
    this.each(function() {
      if ($(this).data("flexselect")) {
        $(this).data("flexselect").reloadCache();
      } else if (this.tagName == "SELECT") {
        $(this).data("flexselect", new $.flexselect(this, options));
      }
    });
    return this;
  };
})(jQuery);
<|endoftext|>


<commit_before>// @link https://github.com/adampietrasiak/jquery.initialize
// @author Adam Pietrasiak
// @author Damien Bezborodov
;(function($) {
    var seen = []; // Tracks elements that have previously been initialized.

    // MutationSelectorObserver represents a selector and it's associated initialization callback.
    var MutationSelectorObserver = function(selector, callback) {
        this.selector = selector;
        this.callback = callback;
    }

    // List of MutationSelectorObservers.
    var msobservers = [];

    // Handle .initialize() calls.
    msobservers.initialize = function(selector, callback) {

        // Wrap the callback so that we can ensure that it is only
        // called once per element.
        callbackOnce = function() {
            if (seen.indexOf(this) == -1) {
                seen.push(this);
                $(this).each(callback);
            }
        }

        // See if the selector matches any elements already on the page.
        $(selector).each(callbackOnce);

        // Then, add it to the list of selector observers.
        this.push(new MutationSelectorObserver(selector, callbackOnce));
    };

    // The MutationObserver watches for when new elements are added to the DOM.
    var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {

            // For each MutationSelectorObserver currently registered.
            for (var j = 0; j < msobservers.length; j++) {

                // Handle DOM node being added.
                if (mutation.type == 'childList') {
                    $(mutation.addedNodes)
                        .find(msobservers[j].selector)
                        .addBack(msobservers[j].selector)
                        .each(msobservers[j].callback);
                }

                // Handle attribute being changed.
                if (mutation.type == 'attributes') {
                    $(mutation.target)
                        .filter(msobservers[j].selector)
                        .each(msobservers[j].callback);
                }
            }
        });
    });

    // Observe the entire document.
    observer.observe(document.documentElement, {childList: true, subtree: true, attributes: true});

    // Handle .initialize() calls.
    $.fn.initialize = function(callback) {
        msobservers.initialize(this.selector, callback);
    };
})(jQuery);
<commit_msg>Make it even simpler, by searching the entire document.<commit_after>// @link https://github.com/adampietrasiak/jquery.initialize
// @author Adam Pietrasiak
// @author Damien Bezborodov
;(function($) {
    var seen = []; // Tracks elements that have previously been initialized.

    // MutationSelectorObserver represents a selector and it's associated initialization callback.
    var MutationSelectorObserver = function(selector, callback) {
        this.selector = selector;
        this.callback = callback;
    }

    // List of MutationSelectorObservers.
    var msobservers = [];
    msobservers.initialize = function(selector, callback) {

        // Wrap the callback so that we can ensure that it is only
        // called once per element.
        callbackOnce = function() {
            if (seen.indexOf(this) == -1) {
                seen.push(this);
                $(this).each(callback);
            }
        }

        // See if the selector matches any elements already on the page.
        $(selector).each(callbackOnce);

        // Then, add it to the list of selector observers.
        this.push(new MutationSelectorObserver(selector, callbackOnce));
    };

    // The MutationObserver watches for when new elements are added to the DOM.
    var observer = new MutationObserver(function(mutations) {

        // For each MutationSelectorObserver currently registered.
        for (var j = 0; j < msobservers.length; j++) {
            $(msobservers[j].selector).each(msobservers[j].callback);
        }
    });

    // Observe the entire document.
    observer.observe(document.documentElement, {childList: true, subtree: true, attributes: true});

    // Handle .initialize() calls.
    $.fn.initialize = function(callback) {
        msobservers.initialize(this.selector, callback);
    };
})(jQuery);
<|endoftext|>