<commit_before>'use strict';

////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2015-2016 ArangoDB GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Alan Plum
////////////////////////////////////////////////////////////////////////////////

const fs = require('fs');
const Minimatch = require('minimatch').Minimatch;
const isWindows = require('internal').platform.substr(0, 3) === 'win';
const mocha = require('@arangodb/mocha');

const isNotPattern = (pattern) => pattern.indexOf('*') === -1;

exports.run = function runFoxxTests(app, reporterName) {
  const run = (file, context) => app.run(file, {context: context});
  return mocha.run(run, findTestFiles(app), reporterName);
};

function findTestFiles(app) {
  const patterns = app.manifest.tests || [];
  if (patterns.every(isNotPattern)) {
    return patterns.slice();
  }
  const basePath = fs.join(app.root, app.path);
  const paths = fs.listTree(basePath);
  const matchers = patterns.map((pattern) => {
    if (pattern.charAt(0) === '/') {
      pattern = pattern.slice(1);
    } else if (pattern.charAt(0) === '.' && pattern.charAt(1) === '/') {
      pattern = pattern.slice(2);
    }
    return new Minimatch(pattern);
  });
  return paths.filter(
    (path) => path && matchers.some((pattern) => pattern.match(
      isWindows ? path.replace(/\\/g, '/') : path
    )) && fs.isFile(fs.join(basePath, path))
  );
}
<commit_msg>Export foxx/mocha.findTests<commit_after>'use strict';

////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2015-2016 ArangoDB GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Alan Plum
////////////////////////////////////////////////////////////////////////////////

const fs = require('fs');
const Minimatch = require('minimatch').Minimatch;
const isWindows = require('internal').platform.substr(0, 3) === 'win';
const mocha = require('@arangodb/mocha');

const isNotPattern = (pattern) => pattern.indexOf('*') === -1;

exports.run = function runFoxxTests(service, reporterName) {
  const run = (file, context) => service.run(file, {context: context});
  return mocha.run(run, exports.findTests(service), reporterName);
};

exports.findTests = function findTestFiles(service) {
  const patterns = service.manifest.tests || [];
  if (patterns.every(isNotPattern)) {
    return patterns.slice();
  }
  const basePath = fs.join(service.root, service.path);
  const paths = fs.listTree(basePath);
  const matchers = patterns.map((pattern) => {
    if (pattern.charAt(0) === '/') {
      pattern = pattern.slice(1);
    } else if (pattern.charAt(0) === '.' && pattern.charAt(1) === '/') {
      pattern = pattern.slice(2);
    }
    return new Minimatch(pattern);
  });
  return paths.filter(
    (path) => path && matchers.some((pattern) => pattern.match(
      isWindows ? path.replace(/\\/g, '/') : path
    )) && fs.isFile(fs.join(basePath, path))
  );
};
<|endoftext|>


<commit_before>/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* globals PDFJS, expect, it, describe, Promise, combineUrl, waitsFor,
           MissingPDFException, StreamType, FontType */

'use strict';

describe('api', function() {
  var basicApiUrl = combineUrl(window.location.href, '../pdfs/basicapi.pdf');
  var basicApiFileLength = 105779; // bytes
  function waitsForPromiseResolved(promise, successCallback) {
    var data;
    promise.then(function(val) {
      data = val;
      successCallback(data);
    },
    function(error) {
      // Shouldn't get here.
      expect(false).toEqual(true);
    });
    waitsFor(function() {
      return data !== undefined;
    }, 20000);
  }
  function waitsForPromiseRejected(promise, failureCallback) {
    var data;
    promise.then(function(val) {
      // Shouldn't get here.
      expect(false).toEqual(true);
    },
    function(error) {
      data = error;
      failureCallback(data);
    });
    waitsFor(function() {
      return data !== undefined;
    }, 20000);
  }
  describe('PDFJS', function() {
    describe('getDocument', function() {
      it('creates pdf doc from URL', function() {
        var promise = PDFJS.getDocument(basicApiUrl);
        waitsForPromiseResolved(promise, function(data) {
          expect(true).toEqual(true);
        });
      });
      it('creates pdf doc from typed array', function() {
        var nonBinaryRequest = PDFJS.disableWorker;
        var request = new XMLHttpRequest();
        request.open('GET', basicApiUrl, false);
        if (!nonBinaryRequest) {
          try {
            request.responseType = 'arraybuffer';
            nonBinaryRequest = request.responseType !== 'arraybuffer';
          } catch (e) {
            nonBinaryRequest = true;
          }
        }
        if (nonBinaryRequest && request.overrideMimeType) {
          request.overrideMimeType('text/plain; charset=x-user-defined');
        }
        request.send(null);

        var typedArrayPdf;
        if (nonBinaryRequest) {
          var data = Array.prototype.map.call(request.responseText,
              function (ch) {
            return ch.charCodeAt(0) & 0xFF;
          });
          typedArrayPdf = new Uint8Array(data);
        } else {
          typedArrayPdf = new Uint8Array(request.response);
        }
        // Sanity check to make sure that we fetched the entire PDF file.
        expect(typedArrayPdf.length).toEqual(basicApiFileLength);

        var promise = PDFJS.getDocument(typedArrayPdf);
        waitsForPromiseResolved(promise, function(data) {
          expect(true).toEqual(true);
        });
      });
      it('creates pdf doc from non-existent URL', function() {
        var nonExistentUrl = combineUrl(window.location.href,
                                        '../pdfs/non-existent.pdf');
        var promise = PDFJS.getDocument(nonExistentUrl);
        waitsForPromiseRejected(promise, function(error) {
          expect(error instanceof MissingPDFException).toEqual(true);
        });
      });
    });
  });
  describe('PDFDocument', function() {
    var promise = PDFJS.getDocument(basicApiUrl);
    var doc;
    waitsForPromiseResolved(promise, function(data) {
      doc = data;
    });
    it('gets number of pages', function() {
      expect(doc.numPages).toEqual(3);
    });
    it('gets fingerprint', function() {
      expect(typeof doc.fingerprint).toEqual('string');
    });
    it('gets page', function() {
      var promise = doc.getPage(1);
      waitsForPromiseResolved(promise, function(data) {
        expect(true).toEqual(true);
      });
    });
    it('gets page index', function() {
      // reference to second page
      var ref = {num: 17, gen: 0};
      var promise = doc.getPageIndex(ref);
      waitsForPromiseResolved(promise, function(pageIndex) {
        expect(pageIndex).toEqual(1);
      });
    });
    it('gets destinations', function() {
      var promise = doc.getDestinations();
      waitsForPromiseResolved(promise, function(data) {
        expect(data).toEqual({ chapter1: [{ gen: 0, num: 17 }, { name: 'XYZ' },
                                          0, 841.89, null] });
      });
    });
    it('gets a destination', function() {
      var promise = doc.getDestination('chapter1');
      waitsForPromiseResolved(promise, function(data) {
        expect(data).toEqual([{ gen: 0, num: 17 }, { name: 'XYZ' },
                              0, 841.89, null]);
      });
    });
    it('gets a non-existent destination', function() {
      var promise = doc.getDestination('non-existent-named-destination');
      waitsForPromiseResolved(promise, function(data) {
        expect(data).toEqual(null);
      });
    });
    it('gets attachments', function() {
      var promise = doc.getAttachments();
      waitsForPromiseResolved(promise, function (data) {
        expect(data).toEqual(null);
      });
    });
    it('gets javascript', function() {
      var promise = doc.getJavaScript();
      waitsForPromiseResolved(promise, function (data) {
        expect(data).toEqual([]);
      });
    });
    // Keep this in sync with the pattern in viewer.js. The pattern is used to
    // detect whether or not to automatically start printing.
    var viewerPrintRegExp = /\bprint\s*\(/;
    it('gets javascript with printing instructions (Print action)', function() {
      // PDF document with "Print" Named action in OpenAction
      var pdfUrl = combineUrl(window.location.href, '../pdfs/bug1001080.pdf');
      var promise = PDFJS.getDocument(pdfUrl).then(function(doc) {
        return doc.getJavaScript();
      });
      waitsForPromiseResolved(promise, function (data) {
        expect(data).toEqual(['print({});']);
        expect(data[0]).toMatch(viewerPrintRegExp);
      });
    });
    it('gets javascript with printing instructions (JS action)', function() {
      // PDF document with "JavaScript" action in OpenAction
      var pdfUrl = combineUrl(window.location.href, '../pdfs/issue6106.pdf');
      var promise = PDFJS.getDocument(pdfUrl).then(function(doc) {
        return doc.getJavaScript();
      });
      waitsForPromiseResolved(promise, function (data) {
        expect(data).toEqual(
          ['this.print({bUI:true,bSilent:false,bShrinkToFit:true});']);
        expect(data[0]).toMatch(viewerPrintRegExp);
      });
    });
    it('gets outline', function() {
      var promise = doc.getOutline();
      waitsForPromiseResolved(promise, function(outline) {
        // Two top level entries.
        expect(outline.length).toEqual(2);
        // Make sure some basic attributes are set.
        expect(outline[1].title).toEqual('Chapter 1');
        expect(outline[1].items.length).toEqual(1);
        expect(outline[1].items[0].title).toEqual('Paragraph 1.1');
      });
    });
    it('gets metadata', function() {
      var promise = doc.getMetadata();
      waitsForPromiseResolved(promise, function(metadata) {
        expect(metadata.info['Title']).toEqual('Basic API Test');
        expect(metadata.info['PDFFormatVersion']).toEqual('1.7');
        expect(metadata.metadata.get('dc:title')).toEqual('Basic API Test');
      });
    });
    it('gets data', function() {
      var promise = doc.getData();
      waitsForPromiseResolved(promise, function (data) {
        expect(data instanceof Uint8Array).toEqual(true);
        expect(data.length).toEqual(basicApiFileLength);
      });
    });
    it('gets download info', function() {
      var promise = doc.getDownloadInfo();
      waitsForPromiseResolved(promise, function (data) {
        expect(data).toEqual({ length: basicApiFileLength });
      });
    });
    it('gets stats', function() {
      var promise = doc.getStats();
      waitsForPromiseResolved(promise, function (stats) {
        expect(stats).toEqual({ streamTypes: [], fontTypes: [] });
      });
    });
  });
  describe('Page', function() {
    var resolvePromise;
    var promise = new Promise(function (resolve) {
      resolvePromise = resolve;
    });
    var pdfDocument;
    PDFJS.getDocument(basicApiUrl).then(function(doc) {
      doc.getPage(1).then(function(data) {
        resolvePromise(data);
      });
      pdfDocument = doc;
    });
    var page;
    waitsForPromiseResolved(promise, function(data) {
      page = data;
    });
    it('gets page number', function () {
      expect(page.pageNumber).toEqual(1);
    });
    it('gets rotate', function () {
      expect(page.rotate).toEqual(0);
    });
    it('gets ref', function () {
      expect(page.ref).toEqual({ num: 15, gen: 0 });
    });
    it('gets view', function () {
      expect(page.view).toEqual([0, 0, 595.28, 841.89]);
    });
    it('gets viewport', function () {
      var viewport = page.getViewport(1.5, 90);
      expect(viewport.viewBox).toEqual(page.view);
      expect(viewport.scale).toEqual(1.5);
      expect(viewport.rotation).toEqual(90);
      expect(viewport.transform).toEqual([0, 1.5, 1.5, 0, 0, 0]);
      expect(viewport.width).toEqual(1262.835);
      expect(viewport.height).toEqual(892.92);
    });
    it('gets annotations', function () {
      var promise = page.getAnnotations();
      waitsForPromiseResolved(promise, function (data) {
        expect(data.length).toEqual(4);
      });
    });
    it('gets text content', function () {
      var promise = page.getTextContent();
      waitsForPromiseResolved(promise, function (data) {
        expect(!!data.items).toEqual(true);
        expect(data.items.length).toEqual(7);
        expect(!!data.styles).toEqual(true);
      });
    });
    it('gets operator list', function() {
      var promise = page.getOperatorList();
      waitsForPromiseResolved(promise, function (oplist) {
        expect(!!oplist.fnArray).toEqual(true);
        expect(!!oplist.argsArray).toEqual(true);
        expect(oplist.lastChunk).toEqual(true);
      });
    });
    it('gets stats after parsing page', function () {
      var promise = page.getOperatorList().then(function () {
        return pdfDocument.getStats();
      });
      var expectedStreamTypes = [];
      expectedStreamTypes[StreamType.FLATE] = true;
      var expectedFontTypes = [];
      expectedFontTypes[FontType.TYPE1] = true;
      expectedFontTypes[FontType.CIDFONTTYPE2] = true;

      waitsForPromiseResolved(promise, function (stats) {
        expect(stats).toEqual({ streamTypes: expectedStreamTypes,
                                fontTypes: expectedFontTypes });
      });
    });
  });
});
<commit_msg>Slightly improved `getPage` unit-tests<commit_after>/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* globals PDFJS, expect, it, describe, Promise, combineUrl, waitsFor,
           MissingPDFException, StreamType, FontType, PDFPageProxy */

'use strict';

describe('api', function() {
  var basicApiUrl = combineUrl(window.location.href, '../pdfs/basicapi.pdf');
  var basicApiFileLength = 105779; // bytes
  function waitsForPromiseResolved(promise, successCallback) {
    var data;
    promise.then(function(val) {
      data = val;
      successCallback(data);
    },
    function(error) {
      // Shouldn't get here.
      expect(false).toEqual(true);
    });
    waitsFor(function() {
      return data !== undefined;
    }, 20000);
  }
  function waitsForPromiseRejected(promise, failureCallback) {
    var data;
    promise.then(function(val) {
      // Shouldn't get here.
      expect(false).toEqual(true);
    },
    function(error) {
      data = error;
      failureCallback(data);
    });
    waitsFor(function() {
      return data !== undefined;
    }, 20000);
  }
  describe('PDFJS', function() {
    describe('getDocument', function() {
      it('creates pdf doc from URL', function() {
        var promise = PDFJS.getDocument(basicApiUrl);
        waitsForPromiseResolved(promise, function(data) {
          expect(true).toEqual(true);
        });
      });
      it('creates pdf doc from typed array', function() {
        var nonBinaryRequest = PDFJS.disableWorker;
        var request = new XMLHttpRequest();
        request.open('GET', basicApiUrl, false);
        if (!nonBinaryRequest) {
          try {
            request.responseType = 'arraybuffer';
            nonBinaryRequest = request.responseType !== 'arraybuffer';
          } catch (e) {
            nonBinaryRequest = true;
          }
        }
        if (nonBinaryRequest && request.overrideMimeType) {
          request.overrideMimeType('text/plain; charset=x-user-defined');
        }
        request.send(null);

        var typedArrayPdf;
        if (nonBinaryRequest) {
          var data = Array.prototype.map.call(request.responseText,
              function (ch) {
            return ch.charCodeAt(0) & 0xFF;
          });
          typedArrayPdf = new Uint8Array(data);
        } else {
          typedArrayPdf = new Uint8Array(request.response);
        }
        // Sanity check to make sure that we fetched the entire PDF file.
        expect(typedArrayPdf.length).toEqual(basicApiFileLength);

        var promise = PDFJS.getDocument(typedArrayPdf);
        waitsForPromiseResolved(promise, function(data) {
          expect(true).toEqual(true);
        });
      });
      it('creates pdf doc from non-existent URL', function() {
        var nonExistentUrl = combineUrl(window.location.href,
                                        '../pdfs/non-existent.pdf');
        var promise = PDFJS.getDocument(nonExistentUrl);
        waitsForPromiseRejected(promise, function(error) {
          expect(error instanceof MissingPDFException).toEqual(true);
        });
      });
    });
  });
  describe('PDFDocument', function() {
    var promise = PDFJS.getDocument(basicApiUrl);
    var doc;
    waitsForPromiseResolved(promise, function(data) {
      doc = data;
    });
    it('gets number of pages', function() {
      expect(doc.numPages).toEqual(3);
    });
    it('gets fingerprint', function() {
      expect(typeof doc.fingerprint).toEqual('string');
    });
    it('gets page', function() {
      var promise = doc.getPage(1);
      waitsForPromiseResolved(promise, function(data) {
        expect(data instanceof PDFPageProxy).toEqual(true);
        expect(data.pageIndex).toEqual(0);
      });
    });
    it('gets non-existent page', function() {
      var promise = doc.getPage(100);
      waitsForPromiseRejected(promise, function(data) {
        expect(data instanceof Error).toEqual(true);
      });
    });
    it('gets page index', function() {
      // reference to second page
      var ref = {num: 17, gen: 0};
      var promise = doc.getPageIndex(ref);
      waitsForPromiseResolved(promise, function(pageIndex) {
        expect(pageIndex).toEqual(1);
      });
    });
    it('gets destinations', function() {
      var promise = doc.getDestinations();
      waitsForPromiseResolved(promise, function(data) {
        expect(data).toEqual({ chapter1: [{ gen: 0, num: 17 }, { name: 'XYZ' },
                                          0, 841.89, null] });
      });
    });
    it('gets a destination', function() {
      var promise = doc.getDestination('chapter1');
      waitsForPromiseResolved(promise, function(data) {
        expect(data).toEqual([{ gen: 0, num: 17 }, { name: 'XYZ' },
                              0, 841.89, null]);
      });
    });
    it('gets a non-existent destination', function() {
      var promise = doc.getDestination('non-existent-named-destination');
      waitsForPromiseResolved(promise, function(data) {
        expect(data).toEqual(null);
      });
    });
    it('gets attachments', function() {
      var promise = doc.getAttachments();
      waitsForPromiseResolved(promise, function (data) {
        expect(data).toEqual(null);
      });
    });
    it('gets javascript', function() {
      var promise = doc.getJavaScript();
      waitsForPromiseResolved(promise, function (data) {
        expect(data).toEqual([]);
      });
    });
    // Keep this in sync with the pattern in viewer.js. The pattern is used to
    // detect whether or not to automatically start printing.
    var viewerPrintRegExp = /\bprint\s*\(/;
    it('gets javascript with printing instructions (Print action)', function() {
      // PDF document with "Print" Named action in OpenAction
      var pdfUrl = combineUrl(window.location.href, '../pdfs/bug1001080.pdf');
      var promise = PDFJS.getDocument(pdfUrl).then(function(doc) {
        return doc.getJavaScript();
      });
      waitsForPromiseResolved(promise, function (data) {
        expect(data).toEqual(['print({});']);
        expect(data[0]).toMatch(viewerPrintRegExp);
      });
    });
    it('gets javascript with printing instructions (JS action)', function() {
      // PDF document with "JavaScript" action in OpenAction
      var pdfUrl = combineUrl(window.location.href, '../pdfs/issue6106.pdf');
      var promise = PDFJS.getDocument(pdfUrl).then(function(doc) {
        return doc.getJavaScript();
      });
      waitsForPromiseResolved(promise, function (data) {
        expect(data).toEqual(
          ['this.print({bUI:true,bSilent:false,bShrinkToFit:true});']);
        expect(data[0]).toMatch(viewerPrintRegExp);
      });
    });
    it('gets outline', function() {
      var promise = doc.getOutline();
      waitsForPromiseResolved(promise, function(outline) {
        // Two top level entries.
        expect(outline.length).toEqual(2);
        // Make sure some basic attributes are set.
        expect(outline[1].title).toEqual('Chapter 1');
        expect(outline[1].items.length).toEqual(1);
        expect(outline[1].items[0].title).toEqual('Paragraph 1.1');
      });
    });
    it('gets metadata', function() {
      var promise = doc.getMetadata();
      waitsForPromiseResolved(promise, function(metadata) {
        expect(metadata.info['Title']).toEqual('Basic API Test');
        expect(metadata.info['PDFFormatVersion']).toEqual('1.7');
        expect(metadata.metadata.get('dc:title')).toEqual('Basic API Test');
      });
    });
    it('gets data', function() {
      var promise = doc.getData();
      waitsForPromiseResolved(promise, function (data) {
        expect(data instanceof Uint8Array).toEqual(true);
        expect(data.length).toEqual(basicApiFileLength);
      });
    });
    it('gets download info', function() {
      var promise = doc.getDownloadInfo();
      waitsForPromiseResolved(promise, function (data) {
        expect(data).toEqual({ length: basicApiFileLength });
      });
    });
    it('gets stats', function() {
      var promise = doc.getStats();
      waitsForPromiseResolved(promise, function (stats) {
        expect(stats).toEqual({ streamTypes: [], fontTypes: [] });
      });
    });
  });
  describe('Page', function() {
    var resolvePromise;
    var promise = new Promise(function (resolve) {
      resolvePromise = resolve;
    });
    var pdfDocument;
    PDFJS.getDocument(basicApiUrl).then(function(doc) {
      doc.getPage(1).then(function(data) {
        resolvePromise(data);
      });
      pdfDocument = doc;
    });
    var page;
    waitsForPromiseResolved(promise, function(data) {
      page = data;
    });
    it('gets page number', function () {
      expect(page.pageNumber).toEqual(1);
    });
    it('gets rotate', function () {
      expect(page.rotate).toEqual(0);
    });
    it('gets ref', function () {
      expect(page.ref).toEqual({ num: 15, gen: 0 });
    });
    it('gets view', function () {
      expect(page.view).toEqual([0, 0, 595.28, 841.89]);
    });
    it('gets viewport', function () {
      var viewport = page.getViewport(1.5, 90);
      expect(viewport.viewBox).toEqual(page.view);
      expect(viewport.scale).toEqual(1.5);
      expect(viewport.rotation).toEqual(90);
      expect(viewport.transform).toEqual([0, 1.5, 1.5, 0, 0, 0]);
      expect(viewport.width).toEqual(1262.835);
      expect(viewport.height).toEqual(892.92);
    });
    it('gets annotations', function () {
      var promise = page.getAnnotations();
      waitsForPromiseResolved(promise, function (data) {
        expect(data.length).toEqual(4);
      });
    });
    it('gets text content', function () {
      var promise = page.getTextContent();
      waitsForPromiseResolved(promise, function (data) {
        expect(!!data.items).toEqual(true);
        expect(data.items.length).toEqual(7);
        expect(!!data.styles).toEqual(true);
      });
    });
    it('gets operator list', function() {
      var promise = page.getOperatorList();
      waitsForPromiseResolved(promise, function (oplist) {
        expect(!!oplist.fnArray).toEqual(true);
        expect(!!oplist.argsArray).toEqual(true);
        expect(oplist.lastChunk).toEqual(true);
      });
    });
    it('gets stats after parsing page', function () {
      var promise = page.getOperatorList().then(function () {
        return pdfDocument.getStats();
      });
      var expectedStreamTypes = [];
      expectedStreamTypes[StreamType.FLATE] = true;
      var expectedFontTypes = [];
      expectedFontTypes[FontType.TYPE1] = true;
      expectedFontTypes[FontType.CIDFONTTYPE2] = true;

      waitsForPromiseResolved(promise, function (stats) {
        expect(stats).toEqual({ streamTypes: expectedStreamTypes,
                                fontTypes: expectedFontTypes });
      });
    });
  });
});
<|endoftext|>


<commit_before>var nexpect = require('nexpect');

describe('the hound CLI', function() {

  describe('searching for a movie', function() {
    it('shows the sources when searching for a one-word movie', function(done) {
      nexpect
        .spawn('node ./hound.js gladiator', { stripColors: true })
        .sendEof()
        .run(function(err, stdout, exitcode) {
          expect(stdout[0]).toMatch(/.* \(.*\) is available on:/);
          for (var i = 1; i < stdout.length - 3; i++) {
            expect(stdout[i]).toMatch(new RegExp('^' + i + '\\) '));
          }

          expect(stdout[stdout.length - 3]).toMatch(/or/);
          expect(stdout[stdout.length - 2]).toMatch(/.\) Did you mean a different movie\?/);
          expect(stdout[stdout.length - 1]).toMatch(/\?: Which source\?:/);
          expect(exitcode).toBe(0);
          done();
        });
    });

    it('shows the sources when searching for a multi-word movie', function(done) {
      nexpect
        .spawn('node ./hound.js toy story', { stripColors: true })
        .sendEof()
        .run(function(err, stdout, exitcode) {
          expect(stdout[0]).toMatch(/.* \(.*\) is available on:/);
          for (var i = 1; i < stdout.length - 3; i++) {
            expect(stdout[i]).toMatch(new RegExp('^' + i + '\\) '));
          }

          expect(stdout[stdout.length - 3]).toMatch(/or/);
          expect(stdout[stdout.length - 2]).toMatch(/.\) Did you mean a different movie\?/);
          expect(stdout[stdout.length - 1]).toMatch(/\?: Which source\?:/);
          expect(exitcode).toBe(0);
          done();
        });
    });
  });

  describe('the utility parameters', function() {
    it('exits with failure when passing --meets and --with at the same time', function(done) {
      nexpect
        .spawn('node ./hound.js --with john --meets gladiator', { stripColors: true })
        .run(function(err, stdout, exitcode) {
          expect(stdout[0]).toBe('Invalid parameters: Cannot use --with and --meets at the same time.');
          expect(exitcode).toBe(1);
          done();
        });
    });

    it('prints version when passing --version', function(done) {
      nexpect
        .spawn('node ./hound.js --version', { stripColors: true })
        .run(function(err, stdout, exitcode) {
          expect(stdout[0]).toMatch(/\d\.\d\.\d/);
          expect(exitcode).toBe(0);
          done();
        });
    });

    it('prints help when passing --help', function(done) {
      nexpect
        .spawn('node ./hound.js --help', { stripColors: true })
        .run(function(err, stdout, exitcode) {
          expect(stdout[0]).toMatch(/Usage: hound/);
          expect(exitcode).toBe(0);
          done();
        });
    });

    it('prints help when passing no parameters at all', function(done) {
      nexpect
        .spawn('node ./hound.js', { stripColors: true })
        .run(function(err, stdout, exitcode) {
          expect(stdout[0]).toMatch(/Usage: hound/);
          expect(exitcode).toBe(0);
          done();
        });
    });
  });
});
<commit_msg>Update cli tests to point to correct file<commit_after>var nexpect = require('nexpect');

describe('the hound CLI', function() {

  describe('searching for a movie', function() {
    it('shows the sources when searching for a one-word movie', function(done) {
      nexpect
        .spawn('node ./houndcli.js gladiator', { stripColors: true })
        .sendEof()
        .run(function(err, stdout, exitcode) {
          expect(stdout[0]).toMatch(/.* \(.*\) is available on:/);
          for (var i = 1; i < stdout.length - 3; i++) {
            expect(stdout[i]).toMatch(new RegExp('^' + i + '\\) '));
          }

          expect(stdout[stdout.length - 3]).toMatch(/or/);
          expect(stdout[stdout.length - 2]).toMatch(/.\) Did you mean a different movie\?/);
          expect(stdout[stdout.length - 1]).toMatch(/\?: Which source\?:/);
          expect(exitcode).toBe(0);
          done();
        });
    });

    it('shows the sources when searching for a multi-word movie', function(done) {
      nexpect
        .spawn('node ./houndcli.js toy story', { stripColors: true })
        .sendEof()
        .run(function(err, stdout, exitcode) {
          expect(stdout[0]).toMatch(/.* \(.*\) is available on:/);
          for (var i = 1; i < stdout.length - 3; i++) {
            expect(stdout[i]).toMatch(new RegExp('^' + i + '\\) '));
          }

          expect(stdout[stdout.length - 3]).toMatch(/or/);
          expect(stdout[stdout.length - 2]).toMatch(/.\) Did you mean a different movie\?/);
          expect(stdout[stdout.length - 1]).toMatch(/\?: Which source\?:/);
          expect(exitcode).toBe(0);
          done();
        });
    });
  });

  describe('the utility parameters', function() {
    it('exits with failure when passing --meets and --with at the same time', function(done) {
      nexpect
        .spawn('node ./houndcli.js --with john --meets gladiator', { stripColors: true })
        .run(function(err, stdout, exitcode) {
          expect(stdout[0]).toBe('Invalid parameters: Cannot use --with and --meets at the same time.');
          expect(exitcode).toBe(1);
          done();
        });
    });

    it('prints version when passing --version', function(done) {
      nexpect
        .spawn('node ./houndcli.js --version', { stripColors: true })
        .run(function(err, stdout, exitcode) {
          expect(stdout[0]).toMatch(/\d\.\d\.\d/);
          expect(exitcode).toBe(0);
          done();
        });
    });

    it('prints help when passing --help', function(done) {
      nexpect
        .spawn('node ./houndcli.js --help', { stripColors: true })
        .run(function(err, stdout, exitcode) {
          expect(stdout[0]).toMatch(/Usage: hound/);
          expect(exitcode).toBe(0);
          done();
        });
    });

    it('prints help when passing no parameters at all', function(done) {
      nexpect
        .spawn('node ./houndcli.js', { stripColors: true })
        .run(function(err, stdout, exitcode) {
          expect(stdout[0]).toMatch(/Usage: hound/);
          expect(exitcode).toBe(0);
          done();
        });
    });
  });
});
<|endoftext|>


<commit_before>function intval( mixed_var, base ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // *     example 1: intval('Kevin van Zonneveld');
    // *     returns 1: 0
    // *     example 2: intval(4.2);
    // *     returns 2: 4
    // *     example 3: intval(42, 8);
    // *     returns 3: 42

    var tmp;

    if( typeof( mixed_var ) == 'string' ){
        tmp = parseInt(mixed_var);
        if(isNaN(tmp)){
            return 0;
        } else{
            return tmp.toString(base || 10);
        }
    } else if( typeof( mixed_var ) == 'number' ){
        return Math.floor(mixed_var);
    } else{
        return 0;
    }
}<commit_msg>Improved intval to handle JavaScripts "Infinity"<commit_after>function intval( mixed_var, base ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: stensi
    // *     example 1: intval('Kevin van Zonneveld');
    // *     returns 1: 0
    // *     example 2: intval(4.2);
    // *     returns 2: 4
    // *     example 3: intval(42, 8);
    // *     returns 3: 42

    var tmp;

    if( typeof( mixed_var ) == 'string' ){
        tmp = parseInt(mixed_var);
        if(isNaN(tmp) || !isFinite(tmp)){
            return 0;
        } else{
            return tmp.toString(base || 10);
        }
    } else if( typeof( mixed_var ) == 'number' && isFinite(mixed_var) ){
        return Math.floor(mixed_var);
    } else{
        return 0;
    }
}<|endoftext|>


<commit_before>
// UI Definition
var GuacamoleUI = {

    "viewport"    : document.getElementById("viewportClone"),
    "display"     : document.getElementById("display"),
    "menu"        : document.getElementById("menu"),
    "menuControl" : document.getElementById("menuControl"),
    "touchMenu"   : document.getElementById("touchMenu"),
    "logo"        : document.getElementById("status-logo"),

    "buttons": {

        "showClipboard": document.getElementById("showClipboard"),
        "showKeyboard" : document.getElementById("showKeyboard"),
        "ctrlAltDelete": document.getElementById("ctrlAltDelete"),
        "reconnect"    : document.getElementById("reconnect"),
        "logout"       : document.getElementById("logout")

    },

    "containers": {
        "state"    : document.getElementById("statusDialog"),
        "clipboard": document.getElementById("clipboardDiv"),
        "keyboard" : document.getElementById("keyboardContainer")
    },

    "state"     : document.getElementById("statusText"),
    "clipboard" : document.getElementById("clipboard")

};

// Constant UI initialization and behavior
(function() {

    var menu_shaded = false;

    var shade_interval = null;
    var show_interval = null;

    // Cache error image (might not be available when error occurs)
    var guacErrorImage = new Image();
    guacErrorImage.src = "images/noguacamole-logo-24.png";

    GuacamoleUI.hideStatus = function() {
        document.body.classList.remove("guac-error");
        GuacamoleUI.containers.state.style.visibility = "hidden";
    };

    GuacamoleUI.showStatus = function(text) {
        document.body.classList.remove("guac-error");
        GuacamoleUI.containers.state.style.visibility = "visible";
        GuacamoleUI.state.textContent = text;
    };

    GuacamoleUI.showError = function(error) {
        document.body.classList.add("guac-error");
        GuacamoleUI.state.textContent = error;
    };

    GuacamoleUI.shadeMenu = function() {

        if (!menu_shaded) {

            var step = Math.floor(GuacamoleUI.menu.offsetHeight / 10) + 1;
            var offset = 0;
            menu_shaded = true;

            window.clearInterval(show_interval);
            shade_interval = window.setInterval(function() {

                offset -= step;
                GuacamoleUI.menu.style.top = offset + "px";

                if (offset <= -GuacamoleUI.menu.offsetHeight) {
                    window.clearInterval(shade_interval);
                    GuacamoleUI.menu.style.visiblity = "hidden";
                }

            }, 30);
        }

    };

    GuacamoleUI.showMenu = function() {

        if (menu_shaded) {

            var step = Math.floor(GuacamoleUI.menu.offsetHeight / 5) + 1;
            var offset = -GuacamoleUI.menu.offsetHeight;
            menu_shaded = false;
            GuacamoleUI.menu.style.visiblity = "";

            window.clearInterval(shade_interval);
            show_interval = window.setInterval(function() {

                offset += step;

                if (offset >= 0) {
                    offset = 0;
                    window.clearInterval(show_interval);
                }

                GuacamoleUI.menu.style.top = offset + "px";

            }, 30);
        }

    };

    // Show/Hide clipboard
    GuacamoleUI.buttons.showClipboard.onclick = function() {

        var displayed = GuacamoleUI.containers.clipboard.style.display;
        if (displayed != "block") {
            GuacamoleUI.containers.clipboard.style.display = "block";
            GuacamoleUI.buttons.showClipboard.innerHTML = "Hide Clipboard";
        }
        else {
            GuacamoleUI.containers.clipboard.style.display = "none";
            GuacamoleUI.buttons.showClipboard.innerHTML = "Show Clipboard";
            GuacamoleUI.clipboard.onchange();
        }

    };

    // Show/Hide keyboard
    var keyboardResizeInterval = null;
    GuacamoleUI.buttons.showKeyboard.onclick = function() {

        var displayed = GuacamoleUI.containers.keyboard.style.display;
        if (displayed != "block") {
            GuacamoleUI.containers.keyboard.style.display = "block";
            GuacamoleUI.buttons.showKeyboard.textContent = "Hide Keyboard";

            // Automatically update size
            window.onresize = updateKeyboardSize;
            keyboardResizeInterval = window.setInterval(updateKeyboardSize, 30);

            updateKeyboardSize();
        }
        else {
            GuacamoleUI.containers.keyboard.style.display = "none";
            GuacamoleUI.buttons.showKeyboard.textContent = "Show Keyboard";

            window.onresize = null;
            window.clearInterval(keyboardResizeInterval);
        }

    };

    // Logout
    GuacamoleUI.buttons.logout.onclick = function() {
        window.location.href = "logout";
    };

    // Timeouts for detecting if users wants menu to open or close
    var detectMenuOpenTimeout = null;
    var detectMenuCloseTimeout = null;

    // Clear detection timeouts
    GuacamoleUI.resetMenuDetect = function() {

        if (detectMenuOpenTimeout != null) {
            window.clearTimeout(detectMenuOpenTimeout);
            detectMenuOpenTimeout = null;
        }

        if (detectMenuCloseTimeout != null) {
            window.clearTimeout(detectMenuCloseTimeout);
            detectMenuCloseTimeout = null;
        }

    };

    // Initiate detection of menu open action. If not canceled through some
    // user event, menu will open.
    GuacamoleUI.startMenuOpenDetect = function() {

        if (!detectMenuOpenTimeout) {

            // Clear detection state
            GuacamoleUI.resetMenuDetect();

            // Wait and then show menu
            detectMenuOpenTimeout = window.setTimeout(function() {
                GuacamoleUI.showMenu();
                detectMenuOpenTimeout = null;
            }, 325);

        }

    };

    // Initiate detection of menu close action. If not canceled through some
    // user event, menu will close.
    GuacamoleUI.startMenuCloseDetect = function() {

        if (!detectMenuCloseTimeout) {

            // Clear detection state
            GuacamoleUI.resetMenuDetect();

            // Wait and then shade menu
            detectMenuCloseTimeout = window.setTimeout(function() {
                GuacamoleUI.shadeMenu();
                detectMenuCloseTimeout = null;
            }, 500);

        }

    };

    // Show menu if mouseover any part of menu
    GuacamoleUI.menu.addEventListener('mouseover', GuacamoleUI.showMenu, true);

    // Stop detecting menu state change intents if mouse is over menu
    GuacamoleUI.menu.addEventListener('mouseover', GuacamoleUI.resetMenuDetect, true);

    // When mouse hovers over top of screen, start detection of intent to open menu
    GuacamoleUI.menuControl.addEventListener('mousemove', GuacamoleUI.startMenuOpenDetect, true);

    var menuShowLongPressTimeout = null;

    GuacamoleUI.startLongPressDetect = function() {

        if (!menuShowLongPressTimeout) {

            menuShowLongPressTimeout = window.setTimeout(function() {

                menuShowLongPressTimeout = null;
                GuacamoleUI.showMenu();

            }, 800);

        }
    };

    GuacamoleUI.stopLongPressDetect = function() {
        window.clearTimeout(menuShowLongPressTimeout);
        menuShowLongPressTimeout = null;
    };

    // Detect long-press at bottom of screen
    document.body.addEventListener('touchstart', GuacamoleUI.startLongPressDetect, true);

    // Reconnect button
    GuacamoleUI.buttons.reconnect.onclick = function() {
        window.location.reload();
    };

    // On-screen keyboard
    GuacamoleUI.keyboard = new Guacamole.OnScreenKeyboard("layouts/en-us-qwerty-mobile.xml");
    GuacamoleUI.containers.keyboard.appendChild(GuacamoleUI.keyboard.getElement());

    // Function for automatically updating keyboard size
    var lastKeyboardWidth;
    function updateKeyboardSize() {
        var currentSize = GuacamoleUI.keyboard.getElement().offsetWidth;
        if (lastKeyboardWidth != currentSize) {
            GuacamoleUI.keyboard.resize(currentSize);
            lastKeyboardWidth = currentSize;
        }
    };

})();

// Tie UI events / behavior to a specific Guacamole client
GuacamoleUI.attach = function(guac) {

    var guac_display = guac.getDisplay();

    // When mouse enters display, start detection of intent to close menu
    guac_display.addEventListener('mouseover', GuacamoleUI.startMenuCloseDetect, true);

    guac_display.onclick = function(e) {
        e.preventDefault();
        return false;
    };

    // Mouse
    var mouse = new Guacamole.Mouse(guac_display);
    mouse.onmousedown = mouse.onmouseup = mouse.onmousemove =
        function(mouseState) {

            // Determine mouse position within view
            var mouse_view_x = mouseState.x + guac_display.offsetLeft - window.pageXOffset;
            var mouse_view_y = mouseState.y + guac_display.offsetTop  - window.pageYOffset;

            // Determine viewport dimensioins
            var view_width  = GuacamoleUI.viewport.offsetWidth;
            var view_height = GuacamoleUI.viewport.offsetHeight;

            // Determine scroll amounts based on mouse position relative to document

            var scroll_amount_x;
            if (mouse_view_x > view_width)
                scroll_amount_x = mouse_view_x - view_width;
            else if (mouse_view_x < 0)
                scroll_amount_x = mouse_view_x;
            else
                scroll_amount_x = 0;

            var scroll_amount_y;
            if (mouse_view_y > view_height)
                scroll_amount_y = mouse_view_y - view_height;
            else if (mouse_view_y < 0)
                scroll_amount_y = mouse_view_y;
            else
                scroll_amount_y = 0;

            // Scroll (if necessary) to keep mouse on screen.
            window.scrollBy(scroll_amount_x, scroll_amount_y);

            // Hide menu on movement
            GuacamoleUI.startMenuCloseDetect();

            // Stop detecting long presses if mouse is being used
            GuacamoleUI.stopLongPressDetect();

            // Send mouse event
            guac.sendMouseState(mouseState);

        };

    // Keyboard
    var keyboard = new Guacamole.Keyboard(document);

    function disableKeyboard() {
        keyboard.onkeydown = null;
        keyboard.onkeyup = null;
    }

    function enableKeyboard() {
        keyboard.onkeydown =
            function (keysym) {
                guac.sendKeyEvent(1, keysym);
            };

        keyboard.onkeyup =
            function (keysym) {
                guac.sendKeyEvent(0, keysym);
            };
    }

    // Enable keyboard by default
    enableKeyboard();

    // Handle client state change
    guac.onstatechange = function(clientState) {
        switch (clientState) {

            // Idle
            case 0:
                GuacamoleUI.showStatus("Idle.");
                break;

            // Connecting
            case 1:
                GuacamoleUI.shadeMenu();
                GuacamoleUI.showStatus("Connecting...");
                break;

            // Connected + waiting
            case 2:
                GuacamoleUI.showStatus("Connected, waiting for first update...");
                break;

            // Connected
            case 3:

                GuacamoleUI.hideStatus();
                GuacamoleUI.display.className =
                    GuacamoleUI.display.className.replace(/guac-loading/, '');

                GuacamoleUI.menu.className = "connected";
                break;

            // Disconnecting
            case 4:
                GuacamoleUI.showStatus("Disconnecting...");
                break;

            // Disconnected
            case 5:
                GuacamoleUI.showStatus("Disconnected.");
                break;

            // Unknown status code
            default:
                GuacamoleUI.showStatus("[UNKNOWN STATUS]");

        }
    };

    // Name instruction handler
    guac.onname = function(name) {
        document.title = name;
    };

    // Error handler
    guac.onerror = function(error) {

        // Disconnect, if connected
        guac.disconnect();

        // Display error message
        GuacamoleUI.showError(error);

    };

    // Disconnect on close
    window.onunload = function() {
        guac.disconnect();
    };

    // Handle clipboard events
    GuacamoleUI.clipboard.onchange = function() {

        var text = GuacamoleUI.clipboard.value;
        guac.setClipboard(text);

    };

    // Ignore keypresses when clipboard is focused
    GuacamoleUI.clipboard.onfocus = function() {
        disableKeyboard();
    };

    // Capture keypresses when clipboard is not focused
    GuacamoleUI.clipboard.onblur = function() {
        enableKeyboard();
    };

    // Server copy handler
    guac.onclipboard = function(data) {
        GuacamoleUI.clipboard.value = data;
    };

    GuacamoleUI.keyboard.onkeydown = function(keysym) {
        guac.sendKeyEvent(1, keysym);
    };

    GuacamoleUI.keyboard.onkeyup = function(keysym) {
        guac.sendKeyEvent(0, keysym);
    };

    // Send Ctrl-Alt-Delete
    GuacamoleUI.buttons.ctrlAltDelete.onclick = function() {

        var KEYSYM_CTRL   = 0xFFE3;
        var KEYSYM_ALT    = 0xFFE9;
        var KEYSYM_DELETE = 0xFFFF;

        guac.sendKeyEvent(1, KEYSYM_CTRL);
        guac.sendKeyEvent(1, KEYSYM_ALT);
        guac.sendKeyEvent(1, KEYSYM_DELETE);
        guac.sendKeyEvent(0, KEYSYM_DELETE);
        guac.sendKeyEvent(0, KEYSYM_ALT);
        guac.sendKeyEvent(0, KEYSYM_CTRL);
    };

};<commit_msg>Do not require classList.<commit_after>
// UI Definition
var GuacamoleUI = {

    "viewport"    : document.getElementById("viewportClone"),
    "display"     : document.getElementById("display"),
    "menu"        : document.getElementById("menu"),
    "menuControl" : document.getElementById("menuControl"),
    "touchMenu"   : document.getElementById("touchMenu"),
    "logo"        : document.getElementById("status-logo"),

    "buttons": {

        "showClipboard": document.getElementById("showClipboard"),
        "showKeyboard" : document.getElementById("showKeyboard"),
        "ctrlAltDelete": document.getElementById("ctrlAltDelete"),
        "reconnect"    : document.getElementById("reconnect"),
        "logout"       : document.getElementById("logout")

    },

    "containers": {
        "state"    : document.getElementById("statusDialog"),
        "clipboard": document.getElementById("clipboardDiv"),
        "keyboard" : document.getElementById("keyboardContainer")
    },

    "state"     : document.getElementById("statusText"),
    "clipboard" : document.getElementById("clipboard")

};

// Constant UI initialization and behavior
(function() {

    var menu_shaded = false;

    var shade_interval = null;
    var show_interval = null;

    // Cache error image (might not be available when error occurs)
    var guacErrorImage = new Image();
    guacErrorImage.src = "images/noguacamole-logo-24.png";

    // Function for adding a class to an element
    var addClass;

    // Function for removing a class from an element
    var removeClass;

    // If Node.classList is supported, implement addClass/removeClass using that
    if (Node.classList) {

        addClass = function(element, classname) {
            element.classList.add(classname);
        };

        removeClass = function(element, classname) {
            element.classList.remove(classname);
        };

    }

    // Otherwise, implement own
    else {

        addClass = function(element, classname) {

            // Simply add new class
            element.className += " " + classname;

        };

        removeClass = function(element, classname) {

            // Filter out classes with given name
            element.className = element.className.replace(/([^ ]+)[ ]*/g,
                function(match, testClassname, spaces, offset, string) {

                    // If same class, remove
                    if (testClassname == classname)
                        return "";

                    // Otherwise, allow
                    return match;

                }
            );

        };

    }

    GuacamoleUI.hideStatus = function() {
        removeClass(document.body, "guac-error");
        GuacamoleUI.containers.state.style.visibility = "hidden";
    };

    GuacamoleUI.showStatus = function(text) {
        removeClass(document.body, "guac-error");
        GuacamoleUI.containers.state.style.visibility = "visible";
        GuacamoleUI.state.textContent = text;
    };

    GuacamoleUI.showError = function(error) {
        addClass(document.body, "guac-error");
        GuacamoleUI.state.textContent = error;
    };

    GuacamoleUI.shadeMenu = function() {

        if (!menu_shaded) {

            var step = Math.floor(GuacamoleUI.menu.offsetHeight / 10) + 1;
            var offset = 0;
            menu_shaded = true;

            window.clearInterval(show_interval);
            shade_interval = window.setInterval(function() {

                offset -= step;
                GuacamoleUI.menu.style.top = offset + "px";

                if (offset <= -GuacamoleUI.menu.offsetHeight) {
                    window.clearInterval(shade_interval);
                    GuacamoleUI.menu.style.visiblity = "hidden";
                }

            }, 30);
        }

    };

    GuacamoleUI.showMenu = function() {

        if (menu_shaded) {

            var step = Math.floor(GuacamoleUI.menu.offsetHeight / 5) + 1;
            var offset = -GuacamoleUI.menu.offsetHeight;
            menu_shaded = false;
            GuacamoleUI.menu.style.visiblity = "";

            window.clearInterval(shade_interval);
            show_interval = window.setInterval(function() {

                offset += step;

                if (offset >= 0) {
                    offset = 0;
                    window.clearInterval(show_interval);
                }

                GuacamoleUI.menu.style.top = offset + "px";

            }, 30);
        }

    };

    // Show/Hide clipboard
    GuacamoleUI.buttons.showClipboard.onclick = function() {

        var displayed = GuacamoleUI.containers.clipboard.style.display;
        if (displayed != "block") {
            GuacamoleUI.containers.clipboard.style.display = "block";
            GuacamoleUI.buttons.showClipboard.innerHTML = "Hide Clipboard";
        }
        else {
            GuacamoleUI.containers.clipboard.style.display = "none";
            GuacamoleUI.buttons.showClipboard.innerHTML = "Show Clipboard";
            GuacamoleUI.clipboard.onchange();
        }

    };

    // Show/Hide keyboard
    var keyboardResizeInterval = null;
    GuacamoleUI.buttons.showKeyboard.onclick = function() {

        var displayed = GuacamoleUI.containers.keyboard.style.display;
        if (displayed != "block") {
            GuacamoleUI.containers.keyboard.style.display = "block";
            GuacamoleUI.buttons.showKeyboard.textContent = "Hide Keyboard";

            // Automatically update size
            window.onresize = updateKeyboardSize;
            keyboardResizeInterval = window.setInterval(updateKeyboardSize, 30);

            updateKeyboardSize();
        }
        else {
            GuacamoleUI.containers.keyboard.style.display = "none";
            GuacamoleUI.buttons.showKeyboard.textContent = "Show Keyboard";

            window.onresize = null;
            window.clearInterval(keyboardResizeInterval);
        }

    };

    // Logout
    GuacamoleUI.buttons.logout.onclick = function() {
        window.location.href = "logout";
    };

    // Timeouts for detecting if users wants menu to open or close
    var detectMenuOpenTimeout = null;
    var detectMenuCloseTimeout = null;

    // Clear detection timeouts
    GuacamoleUI.resetMenuDetect = function() {

        if (detectMenuOpenTimeout != null) {
            window.clearTimeout(detectMenuOpenTimeout);
            detectMenuOpenTimeout = null;
        }

        if (detectMenuCloseTimeout != null) {
            window.clearTimeout(detectMenuCloseTimeout);
            detectMenuCloseTimeout = null;
        }

    };

    // Initiate detection of menu open action. If not canceled through some
    // user event, menu will open.
    GuacamoleUI.startMenuOpenDetect = function() {

        if (!detectMenuOpenTimeout) {

            // Clear detection state
            GuacamoleUI.resetMenuDetect();

            // Wait and then show menu
            detectMenuOpenTimeout = window.setTimeout(function() {
                GuacamoleUI.showMenu();
                detectMenuOpenTimeout = null;
            }, 325);

        }

    };

    // Initiate detection of menu close action. If not canceled through some
    // user event, menu will close.
    GuacamoleUI.startMenuCloseDetect = function() {

        if (!detectMenuCloseTimeout) {

            // Clear detection state
            GuacamoleUI.resetMenuDetect();

            // Wait and then shade menu
            detectMenuCloseTimeout = window.setTimeout(function() {
                GuacamoleUI.shadeMenu();
                detectMenuCloseTimeout = null;
            }, 500);

        }

    };

    // Show menu if mouseover any part of menu
    GuacamoleUI.menu.addEventListener('mouseover', GuacamoleUI.showMenu, true);

    // Stop detecting menu state change intents if mouse is over menu
    GuacamoleUI.menu.addEventListener('mouseover', GuacamoleUI.resetMenuDetect, true);

    // When mouse hovers over top of screen, start detection of intent to open menu
    GuacamoleUI.menuControl.addEventListener('mousemove', GuacamoleUI.startMenuOpenDetect, true);

    var menuShowLongPressTimeout = null;

    GuacamoleUI.startLongPressDetect = function() {

        if (!menuShowLongPressTimeout) {

            menuShowLongPressTimeout = window.setTimeout(function() {

                menuShowLongPressTimeout = null;
                GuacamoleUI.showMenu();

            }, 800);

        }
    };

    GuacamoleUI.stopLongPressDetect = function() {
        window.clearTimeout(menuShowLongPressTimeout);
        menuShowLongPressTimeout = null;
    };

    // Detect long-press at bottom of screen
    document.body.addEventListener('touchstart', GuacamoleUI.startLongPressDetect, true);

    // Reconnect button
    GuacamoleUI.buttons.reconnect.onclick = function() {
        window.location.reload();
    };

    // On-screen keyboard
    GuacamoleUI.keyboard = new Guacamole.OnScreenKeyboard("layouts/en-us-qwerty-mobile.xml");
    GuacamoleUI.containers.keyboard.appendChild(GuacamoleUI.keyboard.getElement());

    // Function for automatically updating keyboard size
    var lastKeyboardWidth;
    function updateKeyboardSize() {
        var currentSize = GuacamoleUI.keyboard.getElement().offsetWidth;
        if (lastKeyboardWidth != currentSize) {
            GuacamoleUI.keyboard.resize(currentSize);
            lastKeyboardWidth = currentSize;
        }
    };

})();

// Tie UI events / behavior to a specific Guacamole client
GuacamoleUI.attach = function(guac) {

    var guac_display = guac.getDisplay();

    // When mouse enters display, start detection of intent to close menu
    guac_display.addEventListener('mouseover', GuacamoleUI.startMenuCloseDetect, true);

    guac_display.onclick = function(e) {
        e.preventDefault();
        return false;
    };

    // Mouse
    var mouse = new Guacamole.Mouse(guac_display);
    mouse.onmousedown = mouse.onmouseup = mouse.onmousemove =
        function(mouseState) {

            // Determine mouse position within view
            var mouse_view_x = mouseState.x + guac_display.offsetLeft - window.pageXOffset;
            var mouse_view_y = mouseState.y + guac_display.offsetTop  - window.pageYOffset;

            // Determine viewport dimensioins
            var view_width  = GuacamoleUI.viewport.offsetWidth;
            var view_height = GuacamoleUI.viewport.offsetHeight;

            // Determine scroll amounts based on mouse position relative to document

            var scroll_amount_x;
            if (mouse_view_x > view_width)
                scroll_amount_x = mouse_view_x - view_width;
            else if (mouse_view_x < 0)
                scroll_amount_x = mouse_view_x;
            else
                scroll_amount_x = 0;

            var scroll_amount_y;
            if (mouse_view_y > view_height)
                scroll_amount_y = mouse_view_y - view_height;
            else if (mouse_view_y < 0)
                scroll_amount_y = mouse_view_y;
            else
                scroll_amount_y = 0;

            // Scroll (if necessary) to keep mouse on screen.
            window.scrollBy(scroll_amount_x, scroll_amount_y);

            // Hide menu on movement
            GuacamoleUI.startMenuCloseDetect();

            // Stop detecting long presses if mouse is being used
            GuacamoleUI.stopLongPressDetect();

            // Send mouse event
            guac.sendMouseState(mouseState);

        };

    // Keyboard
    var keyboard = new Guacamole.Keyboard(document);

    function disableKeyboard() {
        keyboard.onkeydown = null;
        keyboard.onkeyup = null;
    }

    function enableKeyboard() {
        keyboard.onkeydown =
            function (keysym) {
                guac.sendKeyEvent(1, keysym);
            };

        keyboard.onkeyup =
            function (keysym) {
                guac.sendKeyEvent(0, keysym);
            };
    }

    // Enable keyboard by default
    enableKeyboard();

    // Handle client state change
    guac.onstatechange = function(clientState) {
        switch (clientState) {

            // Idle
            case 0:
                GuacamoleUI.showStatus("Idle.");
                break;

            // Connecting
            case 1:
                GuacamoleUI.shadeMenu();
                GuacamoleUI.showStatus("Connecting...");
                break;

            // Connected + waiting
            case 2:
                GuacamoleUI.showStatus("Connected, waiting for first update...");
                break;

            // Connected
            case 3:

                GuacamoleUI.hideStatus();
                GuacamoleUI.display.className =
                    GuacamoleUI.display.className.replace(/guac-loading/, '');

                GuacamoleUI.menu.className = "connected";
                break;

            // Disconnecting
            case 4:
                GuacamoleUI.showStatus("Disconnecting...");
                break;

            // Disconnected
            case 5:
                GuacamoleUI.showStatus("Disconnected.");
                break;

            // Unknown status code
            default:
                GuacamoleUI.showStatus("[UNKNOWN STATUS]");

        }
    };

    // Name instruction handler
    guac.onname = function(name) {
        document.title = name;
    };

    // Error handler
    guac.onerror = function(error) {

        // Disconnect, if connected
        guac.disconnect();

        // Display error message
        GuacamoleUI.showError(error);

    };

    // Disconnect on close
    window.onunload = function() {
        guac.disconnect();
    };

    // Handle clipboard events
    GuacamoleUI.clipboard.onchange = function() {

        var text = GuacamoleUI.clipboard.value;
        guac.setClipboard(text);

    };

    // Ignore keypresses when clipboard is focused
    GuacamoleUI.clipboard.onfocus = function() {
        disableKeyboard();
    };

    // Capture keypresses when clipboard is not focused
    GuacamoleUI.clipboard.onblur = function() {
        enableKeyboard();
    };

    // Server copy handler
    guac.onclipboard = function(data) {
        GuacamoleUI.clipboard.value = data;
    };

    GuacamoleUI.keyboard.onkeydown = function(keysym) {
        guac.sendKeyEvent(1, keysym);
    };

    GuacamoleUI.keyboard.onkeyup = function(keysym) {
        guac.sendKeyEvent(0, keysym);
    };

    // Send Ctrl-Alt-Delete
    GuacamoleUI.buttons.ctrlAltDelete.onclick = function() {

        var KEYSYM_CTRL   = 0xFFE3;
        var KEYSYM_ALT    = 0xFFE9;
        var KEYSYM_DELETE = 0xFFFF;

        guac.sendKeyEvent(1, KEYSYM_CTRL);
        guac.sendKeyEvent(1, KEYSYM_ALT);
        guac.sendKeyEvent(1, KEYSYM_DELETE);
        guac.sendKeyEvent(0, KEYSYM_DELETE);
        guac.sendKeyEvent(0, KEYSYM_ALT);
        guac.sendKeyEvent(0, KEYSYM_CTRL);
    };

};<|endoftext|>


<commit_before>var resourceMethods = require('./resource');

var resources = {};
module.exports.addResource = function addResource(resourceName, endpoints){
    resources[resourceName] = endpoints;
};

var filterChain = [];
module.exports.filterChain = filterChain;

//Parse the URL and use the resources to select a resource.
module.exports.handleRequest = function handleRequest(httpRequest, httpResponse){
    try {
        console.log('Handling ' + httpRequest.method + ' postRequest for ' + httpRequest.url);
        //Run the filter chain. Very "java" way of doing it.
        //TODO I think this would be better handled as "middleware"... It's a term that keeps coming up in googles.
        filterChain.forEach(function (filter) {
            filter(httpRequest, httpResponse);
        });

        // Since most of the APIs I build tend to deal strictly with the media application/json, even in production,
        // I am going to make an assumption and kick out anything that isn't json. Leaving undefined to make testing easier for now
        var contentType = httpRequest.headers['content-type'];
        if ((httpRequest.method != 'GET') && (contentType != 'application/json') && (contentType != undefined)) {
            console.log('Unsupported media type from postRequest: ' + contentType);
            httpResponse.writeHead(415, 'Resource only supports application/json');
            httpResponse.end();
        }
        dispatch(httpRequest, httpResponse);
    //Node likes to die at the slightest error. I don't want it to die at the slightest error.
    } catch(err){
        console.log(err.stack);
        httpResponse.writeHead(500);
        httpResponse.end("There was a Server Error while processing your request");
    }
};

function dispatch(clientRequest, serverResponse){
    //Look Up Resource by the first URL token, error if not found.
    var urlTokens = clientRequest.url.trim().split('/');
    var Service = resources[urlTokens[1].toLowerCase()];

    if(Service == undefined){
        serverResponse.writeHead(404);
        serverResponse.end('Not Found: ' + serverResponse.url);
    } else {
       var service = new Service();
    }

    switch(clientRequest.method){
        case 'POST':
            if(typeof service.save === 'function'){
                readBodyEventHandling(clientRequest, serverResponse, resourceMethods.POST, service, undefined);
            } else {
                serverResponse.writeHead(405);
                serverResponse.end('Not Supported: ' + method);
            }
            break;
        case 'PUT':
            if(typeof service.update === 'function'){
                readBodyEventHandling(clientRequest, serverResponse, resourceMethods.PUT, service, urlTokens);
            } else {
                serverResponse.writeHead(405);
                serverResponse.end('Not Supported: ' + method);
            }
            break;
        case 'GET':
            if(typeof service.getById === 'function' && typeof service.getAll === 'function') {
                resourceMethods.GET(clientRequest, serverResponse, urlTokens[2], service);
            }
            break;
        case 'DELETE':
            if(typeof service.del === 'function') {
                resourceMethods.DELETE(clientRequest, serverResponse, urlTokens[2], service);
            }
            break;
        default:
            serverResponse.writeHead(405);
            serverResponse.end('Not Supported: ' + method);
    }
}
function readBodyEventHandling(clientRequest, serverResponse, httpMethod, service, urlTokens) {
    var body, methodCalled = false;
    clientRequest.on('data', function (data) {
        body = data.toString();
    });
    clientRequest.on('end', function () {
        methodCalled = true;
        if(urlTokens == undefined){
            httpMethod(clientRequest, serverResponse, body, service);
        } else {
            httpMethod(clientRequest, serverResponse, body, urlTokens[2], service);
        }
    });
}

<commit_msg>Fixed the way filters were being called to block... Probably will change it back to callback based later.<commit_after>var resourceMethods = require('./resource');

var resources = {};
module.exports.addResource = function addResource(resourceName, endpoints){
    resources[resourceName] = endpoints;
};

var filterChain = [];
module.exports.filterChain = filterChain;

//Parse the URL and use the resources to select a resource.
module.exports.handleRequest = function handleRequest(httpRequest, httpResponse){
    try {
        console.log('Handling ' + httpRequest.method + ' postRequest for ' + httpRequest.url);
        //Run the filter chain. Very "java" way of doing it.
        //TODO I think this would be better handled as "middleware"... It's a term that keeps coming up in googles.
        for(var current in filterChain){
            var filter = filterChain[current]
            filter(httpRequest, httpResponse);
        }

        // Since most of the APIs I build tend to deal strictly with the media application/json, even in production,
        // I am going to make an assumption and kick out anything that isn't json. Leaving undefined to make testing easier for now
        var contentType = httpRequest.headers['content-type'];
        if ((httpRequest.method != 'GET') && (contentType != 'application/json') && (contentType != undefined)) {
            console.log('Unsupported media type from postRequest: ' + contentType);
            httpResponse.writeHead(415, 'Resource only supports application/json');
            httpResponse.end();
        }
        dispatch(httpRequest, httpResponse);
    //Node likes to die at the slightest error. I don't want it to die at the slightest error.
    } catch(err){
        console.log(err.stack);
        httpResponse.writeHead(500);
        httpResponse.end("There was a Server Error while processing your request");
    }
};

function dispatch(clientRequest, serverResponse){
    //Look Up Resource by the first URL token, error if not found.
    var urlTokens = clientRequest.url.trim().split('/');
    var Service = resources[urlTokens[1].toLowerCase()];

    if(Service == undefined){
        serverResponse.writeHead(404);
        serverResponse.end('Not Found: ' + serverResponse.url);
    } else {
       var service = new Service();
    }

    switch(clientRequest.method){
        case 'POST':
            if(typeof service.save === 'function'){
                readBodyEventHandling(clientRequest, serverResponse, resourceMethods.POST, service, undefined);
            } else {
                serverResponse.writeHead(405);
                serverResponse.end('Not Supported: ' + method);
            }
            break;
        case 'PUT':
            if(typeof service.update === 'function'){
                readBodyEventHandling(clientRequest, serverResponse, resourceMethods.PUT, service, urlTokens);
            } else {
                serverResponse.writeHead(405);
                serverResponse.end('Not Supported: ' + method);
            }
            break;
        case 'GET':
            if(typeof service.getById === 'function' && typeof service.getAll === 'function') {
                resourceMethods.GET(clientRequest, serverResponse, urlTokens[2], service);
            }
            break;
        case 'DELETE':
            if(typeof service.del === 'function') {
                resourceMethods.DELETE(clientRequest, serverResponse, urlTokens[2], service);
            }
            break;
        default:
            serverResponse.writeHead(405);
            serverResponse.end('Not Supported: ' + method);
    }
}
function readBodyEventHandling(clientRequest, serverResponse, httpMethod, service, urlTokens) {
    var body, methodCalled = false;
    clientRequest.on('data', function (data) {
        body = data.toString();
    });
    clientRequest.on('end', function () {
        methodCalled = true;
        if(urlTokens == undefined){
            httpMethod(clientRequest, serverResponse, body, service);
        } else {
            httpMethod(clientRequest, serverResponse, body, urlTokens[2], service);
        }
    });
}

<|endoftext|>


<commit_before>import Ember from 'ember';
import Move from 'ember-animated/motions/move';
import Scale from 'ember-animated/motions/scale';

export function * transition() {
  this.insertedSprites.forEach(sprite => {
    sprite.reveal();
  });

  this.keptSprites.forEach(sprite => {
    sprite.scale(sprite.initialBounds.width / sprite.finalBounds.width, sprite.initialBounds.height / sprite.finalBounds.height);
    this.animate(new Move(sprite));
    this.animate(new Scale(sprite));
  });
}

export default Ember.Controller.extend({
  transition
});
<commit_msg>Update Hero demo to support Opacity transition<commit_after>import Ember from 'ember';
import Move from 'ember-animated/motions/move';
import Scale from 'ember-animated/motions/scale';
import Opacity from 'ember-animated/motions/opacity';

export function * transition() {
  this.insertedSprites.forEach(sprite => {
    this.animate(new Opacity(sprite));
  });

  this.keptSprites.forEach(sprite => {
    sprite.scale(sprite.initialBounds.width / sprite.finalBounds.width, sprite.initialBounds.height / sprite.finalBounds.height);
    sprite.applyStyles({
      'z-index': 1
    });
    this.animate(new Move(sprite));
    this.animate(new Scale(sprite));
  });
}

export default Ember.Controller.extend({
  transition
});
<|endoftext|>


<commit_before>var Promise   = testPromise;
var _         = require('lodash');

module.exports = function() {

  // This module is included into the `bookshelf` repository,
  // and run from the root of the directory.
  var path     = require('path');
  var basePath = process.cwd();

  var Sync = require(path.resolve(basePath + '/lib/sync'));

  describe('Sync', function() {

    var stubSync = function() {
      var qd = [];
      var stubQuery = function() {
        qd.push(_.toArray(arguments));
        return this;
      };
      return {
        tableName: 'testtable',
        isNew: function() {
          return true
        },
        queryData: qd,
        query: function() {
          return {
            where: stubQuery,
            limit: stubQuery
          };
        },
        resetQuery: function () {
          return this;
        }
      };
    };

    describe('prefixFields', function () {

      it('should prefix all keys of the passed in object with the tablename', function () {

        var sync = new Sync(stubSync());

        var attributes = {
          'some': 'column',
          'another': 'column'
        };

        expect(sync.prefixFields(attributes)).to.eql({
          'testtable.some':'column',
          'testtable.another':'column'
        });

      });

      it('should run after format', function() {

        var attributes = {
          'Some': 'column',
          'Another': 'column'
        };
        var sync = new Sync(_.extend(stubSync(), {
          format: function(attrs) {
            var data = {};
            for (var key in attrs) {
              data[key.toLowerCase()] = attrs[key];
            }
            return data;
          }
        }));
        sync.select = function() {
          expect(this.syncing.queryData[0]).to.eql([{
            "testtable.some": "column",
            "testtable.another": "column"
          }]);
        };
        return sync.first(attributes);

      });

    });

  });

};
<commit_msg>Add test to check id isn't updated if unchanged<commit_after>var _ = require('lodash');

module.exports = function() {
  // This module is included into the `bookshelf` repository,
  // and run from the root of the directory.
  var path     = require('path');
  var basePath = process.cwd();
  var Sync = require(path.resolve(basePath + '/lib/sync'));

  describe('Sync', function() {
    var stubSync = function() {
      var qd = [];
      var stubQuery = function() {
        qd.push(_.toArray(arguments));
        return this;
      };
      return {
        id: 1,
        idAttribute: 'id',
        tableName: 'testtable',
        format: _.identity,
        isNew: function() {
          return true
        },
        queryData: qd,
        query: function() {
          return {
            where: stubQuery,
            limit: stubQuery
          };
        },
        resetQuery: function() {
          return this;
        }
      };
    };

    describe('prefixFields', function() {
      it('should prefix all keys of the passed in object with the tablename', function () {
        var sync = new Sync(stubSync());
        var attributes = {
          'some': 'column',
          'another': 'column'
        };

        expect(sync.prefixFields(attributes)).to.eql({
          'testtable.some':'column',
          'testtable.another':'column'
        });
      });

      it('should run after format', function() {
        var attributes = {
          'Some': 'column',
          'Another': 'column'
        };
        var sync = new Sync(_.extend(stubSync(), {
          format: function(attrs) {
            var data = {};
            for (var key in attrs) {
              data[key.toLowerCase()] = attrs[key];
            }
            return data;
          }
        }));

        sync.select = function() {
          expect(this.syncing.queryData[0]).to.eql([{
            "testtable.some": "column",
            "testtable.another": "column"
          }]);
        };

        return sync.first(attributes);
      });
    });

    describe('update', function() {
      it('doesn\'t try to update the primary key if it hasn\'t changed', function() {
        var sync = new Sync(stubSync())
        _.extend(sync.query, {
          update: function(attrs) {
            expect(attrs).to.not.have.property('id');
          },
          where: function() {
            this._statements = [{grouping: 'where'}]
          }
        })

        return sync.update({id: 1, name: 'something'})
      })
    })
  });
};
<|endoftext|>


<commit_before>exports['Should correctly timeout socket operation and then correctly re-execute'] = {
  metadata: {
    requires: {
      generators: true,
      topology: "single"
    }
  },

  test: function(configuration, test) {
    var Server = configuration.require.Server,
      ObjectId = configuration.require.BSON.ObjectId,
      co = require('co'),
      mockupdb = require('../../../mock');

    // Contain mock server
    var server = null;
    var running = true;
    // Current index for the ismaster
    var currentStep = 0;
    // Primary stop responding
    var stopRespondingPrimary = false;

    // Extend the object
    var extend = function(template, fields) {
      for(var name in template) fields[name] = template[name];
      return fields;
    }

    // Default message fields
    var defaultFields = {
      "ismaster" : true,
      "maxBsonObjectSize" : 16777216,
      "maxMessageSizeBytes" : 48000000,
      "maxWriteBatchSize" : 1000,
      "localTime" : new Date(),
      "maxWireVersion" : 3,
      "minWireVersion" : 0,
      "ok" : 1
    }

    // Primary server states
    var serverIsMaster = [extend(defaultFields, {})];
    var timeoutPromise = function(timeout) {
      return new Promise(function(resolve, reject) {
        setTimeout(function() {
          resolve();
        }, timeout);
      });
    }

    // Boot the mock
    co(function*() {
      server = yield mockupdb.createServer(37019, 'localhost');

      // Primary state machine
      co(function*() {
        while(running) {
          var request = yield server.receive();

          // Get the document
          var doc = request.document;
          if(doc.ismaster && currentStep == 0) {
            request.reply(serverIsMaster[0]);
            currentStep += 1;
          } else if(doc.insert && currentStep == 1) {
            // Stop responding to any calls (emulate dropping packets on the floor)
            if(stopRespondingPrimary) {
              yield timeoutPromise(3000);
              continue;
            }

            currentStep += 1;
          } else if(doc.ismaster && currentStep == 2) {
            request.reply(serverIsMaster[0]);
          } else if(doc.insert && currentStep == 2) {
            request.reply({ok:1, n:doc.documents, lastOp: new Date()});
          }
        }
      });

      // Start dropping the packets
      setTimeout(function() {
        stopRespondingPrimary = true;
        currentIsMasterState = 1;
      }, 5000);
    });

    // Attempt to connect
    var replset = new Server({
      host: 'localhost',
      port: '37019',
      connectionTimeout: 5000,
      socketTimeout: 1000,
      size: 1
    });

    // Not done
    var done = false;

    // Add event listeners
    replset.once('connect', function(_server) {
      // console.log("======= 0")
      _server.insert('test.test', [{created:new Date()}], function(err, r) {
        // console.log("======= 1")
        test.ok(err != null);
        // console.dir(err)

        function wait() {
          setTimeout(function() {
            _server.insert('test.test', [{created:new Date()}], function(err, r) {
              if(r && !done) {
                // console.log("======= 3")
                done = true;
                test.equal(37019, r.connection.port);
                replset.destroy();
                running = false;
                test.done();
              } else {
                wait();
              }
            });
          }, 500);
        }

        wait();
      });
    });

    replset.on('error', function(){});
    replset.connect();
  }
}

exports['Should correctly recover from an immediate shutdown mid insert'] = {
  metadata: {
    requires: {
      generators: true,
      topology: "single"
    }
  },

  test: function(configuration, test) {
    var Server = configuration.require.Server,
      ObjectId = configuration.require.BSON.ObjectId,
      co = require('co'),
      mockupdb = require('../../../mock');

    // Contain mock server
    var server = null;
    var running = true;
    // Current index for the ismaster
    var currentStep = 0;
    // Should fail due to broken pipe
    var brokenPipe = false;

    // Extend the object
    var extend = function(template, fields) {
      for(var name in template) fields[name] = template[name];
      return fields;
    }

    // Default message fields
    var defaultFields = {
      "ismaster" : true,
      "maxBsonObjectSize" : 16777216,
      "maxMessageSizeBytes" : 48000000,
      "maxWriteBatchSize" : 1000,
      "localTime" : new Date(),
      "maxWireVersion" : 3,
      "minWireVersion" : 0,
      "ok" : 1
    }

    // Primary server states
    var serverIsMaster = [extend(defaultFields, {})];
    var timeoutPromise = function(timeout) {
      return new Promise(function(resolve, reject) {
        setTimeout(function() {
          resolve();
        }, timeout);
      });
    }

    // Boot the mock
    co(function*() {
      server = yield mockupdb.createServer(37017, 'localhost', {
        onRead: function(server, connection, buffer, bytesRead) {
          // Force EPIPE error
          if(currentStep == 1)  {
            // Destroy connection mid write
            connection.destroy();
            // Reset the mock to accept ismasters
            currentStep += 1;
            // Return connection was destroyed
            return true;
          }
        }
      });

      // Primary state machine
      co(function*() {
        while(running) {
          var request = yield server.receive();
          // Get the document
          var doc = request.document;
          if(doc.ismaster && currentStep == 0) {
            currentStep += 1;
            request.reply(serverIsMaster[0]);
          } else if(doc.insert && currentStep == 2) {
            currentStep += 1;
            request.reply({ok:1, n:doc.documents, lastOp: new Date()});
          } else if(doc.ismaster) {
            request.reply(serverIsMaster[0]);
          }
        }
      });
    });

    // Attempt to connect
    var server = new Server({
      host: 'localhost',
      port: '37017',
      connectionTimeout: 3000,
      socketTimeout: 2000,
      size: 1
    });

    // Add event listeners
    server.once('connect', function(_server) {
      // console.log("!!!! server connect")
      var docs = [];
      // Create big insert message
      for(var i = 0; i < 1000; i++) {
        docs.push({
          a:i,
          string: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string1: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string2: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string3: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string4: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string5: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string6: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string7: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string8: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string9: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string10: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string11: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string12: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string13: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string14: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string15: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string16: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string17: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string18: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string19: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string20: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string21: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string22: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string23: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string24: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string25: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string26: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string27: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string28: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
        });
      }

      _server.insert('test.test', docs, function(err, r) {
        test.ok(err != null);
        brokenPipe = true;
      });
    });

    server.once('reconnect', function(_server) {
      // console.log("!!!! server reconnect")
      // console.dir(_server)
      _server.insert('test.test', [{created:new Date()}], function(err, r) {
        test.ok(brokenPipe);
        _server.destroy();
        running = false;
        test.done();
      });
    });

    server.on('error', function(){});
    // console.log("!!! connect")
    server.connect();
  }
}
<commit_msg>NODE-758 NODE-753 NODE-759 Added warning about seedlist name not matching it's ismaster me field and thus being removed<commit_after>exports['Should correctly timeout socket operation and then correctly re-execute'] = {
  metadata: {
    requires: {
      generators: true,
      topology: "single"
    }
  },

  test: function(configuration, test) {
    var Server = configuration.require.Server,
      ObjectId = configuration.require.BSON.ObjectId,
      co = require('co'),
      mockupdb = require('../../../mock');

    // Contain mock server
    var server = null;
    var running = true;
    // Current index for the ismaster
    var currentStep = 0;
    // Primary stop responding
    var stopRespondingPrimary = false;

    // Extend the object
    var extend = function(template, fields) {
      for(var name in template) fields[name] = template[name];
      return fields;
    }

    // Default message fields
    var defaultFields = {
      "ismaster" : true,
      "maxBsonObjectSize" : 16777216,
      "maxMessageSizeBytes" : 48000000,
      "maxWriteBatchSize" : 1000,
      "localTime" : new Date(),
      "maxWireVersion" : 3,
      "minWireVersion" : 0,
      "ok" : 1
    }

    // Primary server states
    var serverIsMaster = [extend(defaultFields, {})];
    var timeoutPromise = function(timeout) {
      return new Promise(function(resolve, reject) {
        setTimeout(function() {
          resolve();
        }, timeout);
      });
    }

    // Boot the mock
    co(function*() {
      server = yield mockupdb.createServer(37019, 'localhost');

      // Primary state machine
      co(function*() {
        while(running) {
          var request = yield server.receive();

          // Get the document
          var doc = request.document;
          if(doc.ismaster && currentStep == 0) {
            request.reply(serverIsMaster[0]);
            currentStep += 1;
          } else if(doc.insert && currentStep == 1) {
            // Stop responding to any calls (emulate dropping packets on the floor)
            if(stopRespondingPrimary) {
              yield timeoutPromise(3000);
              continue;
            }

            currentStep += 1;
          } else if(doc.ismaster && currentStep == 2) {
            request.reply(serverIsMaster[0]);
          } else if(doc.insert && currentStep == 2) {
            request.reply({ok:1, n:doc.documents, lastOp: new Date()});
          }
        }
      });

      // Start dropping the packets
      setTimeout(function() {
        stopRespondingPrimary = true;
        currentIsMasterState = 1;
      }, 5000);
    });

    // Attempt to connect
    var replset = new Server({
      host: 'localhost',
      port: '37019',
      connectionTimeout: 5000,
      socketTimeout: 1000,
      size: 1
    });

    // Not done
    var done = false;

    // Add event listeners
    replset.once('connect', function(_server) {
      _server.insert('test.test', [{created:new Date()}], function(err, r) {
        test.ok(err != null);
        // console.dir(err)

        function wait() {
          setTimeout(function() {
            _server.insert('test.test', [{created:new Date()}], function(err, r) {
              if(r && !done) {
                done = true;
                test.equal(37019, r.connection.port);
                replset.destroy();
                running = false;
                test.done();
              } else {
                wait();
              }
            });
          }, 500);
        }

        wait();
      });
    });

    replset.on('error', function(){});
    replset.connect();
  }
}

exports['Should correctly recover from an immediate shutdown mid insert'] = {
  metadata: {
    requires: {
      generators: true,
      topology: "single"
    }
  },

  test: function(configuration, test) {
    var Server = configuration.require.Server,
      ObjectId = configuration.require.BSON.ObjectId,
      co = require('co'),
      mockupdb = require('../../../mock');

    // Contain mock server
    var server = null;
    var running = true;
    // Current index for the ismaster
    var currentStep = 0;
    // Should fail due to broken pipe
    var brokenPipe = false;

    // Extend the object
    var extend = function(template, fields) {
      for(var name in template) fields[name] = template[name];
      return fields;
    }

    // Default message fields
    var defaultFields = {
      "ismaster" : true,
      "maxBsonObjectSize" : 16777216,
      "maxMessageSizeBytes" : 48000000,
      "maxWriteBatchSize" : 1000,
      "localTime" : new Date(),
      "maxWireVersion" : 3,
      "minWireVersion" : 0,
      "ok" : 1
    }

    // Primary server states
    var serverIsMaster = [extend(defaultFields, {})];
    var timeoutPromise = function(timeout) {
      return new Promise(function(resolve, reject) {
        setTimeout(function() {
          resolve();
        }, timeout);
      });
    }

    // Boot the mock
    co(function*() {
      server = yield mockupdb.createServer(37017, 'localhost', {
        onRead: function(server, connection, buffer, bytesRead) {
          // Force EPIPE error
          if(currentStep == 1)  {
            // Destroy connection mid write
            connection.destroy();
            // Reset the mock to accept ismasters
            currentStep += 1;
            // Return connection was destroyed
            return true;
          }
        }
      });

      // Primary state machine
      co(function*() {
        while(running) {
          var request = yield server.receive();
          // Get the document
          var doc = request.document;
          if(doc.ismaster && currentStep == 0) {
            currentStep += 1;
            request.reply(serverIsMaster[0]);
          } else if(doc.insert && currentStep == 2) {
            currentStep += 1;
            request.reply({ok:1, n:doc.documents, lastOp: new Date()});
          } else if(doc.ismaster) {
            request.reply(serverIsMaster[0]);
          }
        }
      });
    });

    // Attempt to connect
    var server = new Server({
      host: 'localhost',
      port: '37017',
      connectionTimeout: 3000,
      socketTimeout: 2000,
      size: 1
    });

    // Add event listeners
    server.once('connect', function(_server) {
      // console.log("!!!! server connect")
      var docs = [];
      // Create big insert message
      for(var i = 0; i < 1000; i++) {
        docs.push({
          a:i,
          string: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string1: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string2: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string3: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string4: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string5: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string6: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string7: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string8: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string9: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string10: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string11: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string12: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string13: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string14: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string15: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string16: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string17: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string18: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string19: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string20: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string21: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string22: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string23: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string24: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string25: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string26: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string27: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
          string28: 'hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world',
        });
      }

      _server.insert('test.test', docs, function(err, r) {
        test.ok(err != null);
        brokenPipe = true;
      });
    });

    server.once('reconnect', function(_server) {
      // console.log("!!!! server reconnect")
      // console.dir(_server)
      _server.insert('test.test', [{created:new Date()}], function(err, r) {
        test.ok(brokenPipe);
        _server.destroy();
        running = false;
        test.done();
      });
    });

    server.on('error', function(){});
    // console.log("!!! connect")
    server.connect();
  }
}
<|endoftext|>