<commit_before>/* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil; tab-width: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/*
 * Copyright 2013 Mozilla Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var DisplayListTree = (function() {

  var containerElement;
  var rootElement;
  var propertiesElement;
  var hoveredElement;
  var selectedElement;
  var selectedItem;
  var boundClickListener;
  var boundMouseOverListener;
  var boundFocusListener;
  var boundBlurListener;
  var boundKeyDownListener;
  var displayObjectStore;

  var displayObjectProps = [
    "_name",
    "alpha",
    "blendMode",
    "cacheAsBitmap",
    "height",
    "scaleX",
    "scaleY",
    "visible",
    "width"
  ];

  function findItemElement(el) {
    while (el && el !== rootElement) {
      if (el.classList.contains("item")) {
        return el;
      }
      el = el.parentElement;
    }
    return null;
  }

  function updateProperties(displayObject) {
    if (isNullOrUndefined(displayObject)) {
      containerElement.classList.remove("hasProperties");
      propertiesElement.innerHTML = "";
    } else {
      containerElement.classList.add("hasProperties");
      var innerHTML = "";
      for (var i = 0, n = displayObjectProps.length; i < n; i++) {
        innerHTML += '
' + displayObjectProps[i] + ': ' + displayObject[displayObjectProps[i]] + '
';
      }
      propertiesElement.innerHTML = innerHTML;
    }
  }

  function createLabel(displayObject) {
    var div = document.createElement("div");
    div.className = "item";
    div.textContent = displayObject.class.className + " ";
    if (!isNullOrUndefined(displayObject._name)) {
      var spanName = document.createElement("span");
      spanName.textContent = "'" + displayObject._name + "'";
      spanName.className = "doName";
      div.appendChild(spanName);
    }
    if (flash.display.MovieClip.class.isInstanceOf(displayObject)) {
      var spanFrameInfo = document.createElement("span");
      spanFrameInfo.textContent = displayObject._currentFrame + "/" + displayObject._totalFrames;
      spanFrameInfo.className = "mcFrameInfo";
      div.appendChild(spanFrameInfo);
    }
    return div;
  }

  function updateChildren(item, elItemContainer) {
    var li = document.createElement("li");

    var label = createLabel(item);
    label.dataset.dosidx = displayObjectStore.length;
    li.appendChild(label);

    displayObjectStore.push(item);

    // If item is container, iterate over its children and recurse
    if ((flash.display.DisplayObjectContainer.class.isInstanceOf(item) ||
         flash.display.SimpleButton.class.isInstanceOf(item)) &&
        item._children &&
        item._children.length > 0)
    {
      var ul = document.createElement("ul");
      var children = item._children;
      for (var i = 0, n = children.length; i < n; i++) {
        if (children[i]) {
          updateChildren(children[i], ul);
        }
      }
      li.appendChild(ul);
    }

    elItemContainer.appendChild(li);
  }

  var DisplayListTree = function() {}

  DisplayListTree.prototype = {

    update: function updateDom(stage, container) {
      displayObjectStore = [];

      containerElement = container;
      containerElement.innerHTML = "";

      var displayListRoot = document.createElement("div");
      displayListRoot.setAttribute("id", "displayListRoot");

      this._removeEventListeners(rootElement);

      rootElement = document.createElement("div");
      rootElement.setAttribute("id", "displayList");
      rootElement.setAttribute("tabindex", "6");
      rootElement.appendChild(displayListRoot);

      this._addEventListeners(rootElement);

      propertiesElement = document.createElement("div");
      propertiesElement.setAttribute("id", "displayObjectProperties");

      updateChildren(stage, displayListRoot);

      containerElement.appendChild(rootElement);
      containerElement.appendChild(propertiesElement);

      if (selectedItem) {
        var dosidx = displayObjectStore.indexOf(selectedItem);
        if (dosidx > -1) {
          selectedElement = document.querySelector("#displayListRoot .item[data-dosidx=\"" + dosidx + "\"]");
          selectedElement.classList.add("selected");
        } else {
          selectedItem = null;
          selectedElement = null;
        }
      }

      updateProperties(selectedItem);
    },

    _onClick: function _onClick(event) {
      var el = findItemElement(event.target);
      if (el) {
        // CLICK
        if (selectedElement) {
          selectedElement.classList.remove("selected");
        }
        if (el !== selectedElement || (selectedElement && !event.metaKey && !event.altKey)) {
          // SELECT
          selectedElement = el;
          selectedElement.classList.add("selected");
          selectedItem = displayObjectStore[parseInt(el.dataset.dosidx)];
          updateProperties(selectedItem);
        } else if (selectedElement) {
          // UNSELECT
          selectedElement = null;
          selectedItem = null;
          updateProperties();
        }
      }
    },

    _onMouseOver: function _onMouseOver(event) {
      var el = findItemElement(event.target);
      if (el) {
        if (el !== hoveredElement) {
          // OVER
          hoveredElement = el;
        }
      } else {
        // OUT
        hoveredElement = null;
      }
    },

    _onFocus: function _onFocus(event) {
      boundKeyDownListener = this._onKeyDown.bind(this);
      event.target.addEventListener('keydown', boundKeyDownListener, false);
    },

    _onBlur: function _onBlur(event) {
      if (boundKeyDownListener) {
        event.target.removeEventListener("keydown", boundKeyDownListener);
      }
    },

    _onKeyDown: function _onBlur(event) {
      var dir = 0;
      switch (event.keyCode) {
        case 40:
          dir = 1;
          break;
        case 38:
          dir = -1;
          break;
      }
      if (dir != 0) {
        var dosidx = clamp(selectedElement ? +selectedElement.dataset.dosidx + dir : 0, 0, displayObjectStore.length - 1);
        var newSelectedItem = displayObjectStore[dosidx];
        if (selectedItem !== newSelectedItem) {
          if (selectedElement) {
            selectedElement.classList.remove("selected");
          }
          selectedItem = newSelectedItem;
          selectedElement = document.querySelector("#displayListRoot .item[data-dosidx=\"" + dosidx + "\"]");
          selectedElement.classList.add("selected");
          updateProperties(selectedItem);
        }
        event.preventDefault();
      }
    },

    _addEventListeners: function _addEventListeners(el) {
        boundClickListener = this._onClick.bind(this);
        boundMouseOverListener = this._onMouseOver.bind(this);
        boundFocusListener = this._onFocus.bind(this);
        boundBlurListener = this._onBlur.bind(this);
        el.addEventListener("click", boundClickListener);
        el.addEventListener("mouseover", boundMouseOverListener);
        el.addEventListener("focus", boundFocusListener);
        el.addEventListener("blur", boundBlurListener);
    },

    _removeEventListeners: function _removeEventListeners(el) {
      if (el) {
        if (boundClickListener) {
          el.removeEventListener("click", boundClickListener);
        }
        if (boundMouseOverListener) {
          el.removeEventListener("mouseover", boundMouseOverListener);
        }
        if (boundFocusListener) {
          el.removeEventListener("focus", boundFocusListener);
        }
        if (boundBlurListener) {
          el.removeEventListener("blur", boundBlurListener);
        }
        if (boundKeyDownListener) {
          el.removeEventListener("keydown", boundKeyDownListener);
        }
      }
    }

  };

  return DisplayListTree;

})();
<commit_msg>restores display list scroll position<commit_after>/* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil; tab-width: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/*
 * Copyright 2013 Mozilla Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var DisplayListTree = (function() {

  var containerElement;
  var rootElement;
  var propertiesElement;
  var hoveredElement;
  var selectedElement;
  var selectedItem;
  var boundClickListener;
  var boundMouseOverListener;
  var boundFocusListener;
  var boundBlurListener;
  var boundKeyDownListener;
  var displayObjectStore;

  var displayObjectProps = [
    "_name",
    "alpha",
    "blendMode",
    "cacheAsBitmap",
    "height",
    "scaleX",
    "scaleY",
    "visible",
    "width"
  ];

  function findItemElement(el) {
    while (el && el !== rootElement) {
      if (el.classList.contains("item")) {
        return el;
      }
      el = el.parentElement;
    }
    return null;
  }

  function updateProperties(displayObject) {
    if (isNullOrUndefined(displayObject)) {
      containerElement.classList.remove("hasProperties");
      propertiesElement.innerHTML = "";
    } else {
      containerElement.classList.add("hasProperties");
      var innerHTML = "";
      for (var i = 0, n = displayObjectProps.length; i < n; i++) {
        innerHTML += '
' + displayObjectProps[i] + ': ' + displayObject[displayObjectProps[i]] + '
';
      }
      propertiesElement.innerHTML = innerHTML;
    }
  }

  function createLabel(displayObject) {
    var div = document.createElement("div");
    div.className = "item";
    div.textContent = displayObject.class.className + " ";
    if (!isNullOrUndefined(displayObject._name)) {
      var spanName = document.createElement("span");
      spanName.textContent = "'" + displayObject._name + "'";
      spanName.className = "doName";
      div.appendChild(spanName);
    }
    if (flash.display.MovieClip.class.isInstanceOf(displayObject)) {
      var spanFrameInfo = document.createElement("span");
      spanFrameInfo.textContent = displayObject._currentFrame + "/" + displayObject._totalFrames;
      spanFrameInfo.className = "mcFrameInfo";
      div.appendChild(spanFrameInfo);
    }
    return div;
  }

  function updateChildren(item, elItemContainer) {
    var li = document.createElement("li");

    var label = createLabel(item);
    label.dataset.dosidx = displayObjectStore.length;
    li.appendChild(label);

    displayObjectStore.push(item);

    // If item is container, iterate over its children and recurse
    if ((flash.display.DisplayObjectContainer.class.isInstanceOf(item) ||
         flash.display.SimpleButton.class.isInstanceOf(item)) &&
        item._children &&
        item._children.length > 0)
    {
      var ul = document.createElement("ul");
      var children = item._children;
      for (var i = 0, n = children.length; i < n; i++) {
        if (children[i]) {
          updateChildren(children[i], ul);
        }
      }
      li.appendChild(ul);
    }

    elItemContainer.appendChild(li);
  }

  var DisplayListTree = function() {}

  DisplayListTree.prototype = {

    update: function updateDom(stage, container) {
      displayObjectStore = [];

      var scrollTopOld = 0;
      if (rootElement) {
        scrollTopOld = rootElement.scrollTop;
      }

      containerElement = container;
      containerElement.innerHTML = "";

      var displayListRoot = document.createElement("div");
      displayListRoot.setAttribute("id", "displayListRoot");

      this._removeEventListeners(rootElement);

      rootElement = document.createElement("div");
      rootElement.setAttribute("id", "displayList");
      rootElement.setAttribute("tabindex", "6");
      rootElement.appendChild(displayListRoot);

      this._addEventListeners(rootElement);

      propertiesElement = document.createElement("div");
      propertiesElement.setAttribute("id", "displayObjectProperties");

      updateChildren(stage, displayListRoot);

      containerElement.appendChild(rootElement);
      containerElement.appendChild(propertiesElement);

      if (selectedItem) {
        var dosidx = displayObjectStore.indexOf(selectedItem);
        if (dosidx > -1) {
          selectedElement = document.querySelector("#displayListRoot .item[data-dosidx=\"" + dosidx + "\"]");
          selectedElement.classList.add("selected");
        } else {
          selectedItem = null;
          selectedElement = null;
        }
      }

      updateProperties(selectedItem);

      if (scrollTopOld !== 0) {
        rootElement.scrollTop = scrollTopOld;
      }
    },

    _onClick: function _onClick(event) {
      var el = findItemElement(event.target);
      if (el) {
        // CLICK
        if (selectedElement) {
          selectedElement.classList.remove("selected");
        }
        if (el !== selectedElement || (selectedElement && !event.metaKey && !event.altKey)) {
          // SELECT
          selectedElement = el;
          selectedElement.classList.add("selected");
          selectedItem = displayObjectStore[parseInt(el.dataset.dosidx)];
          updateProperties(selectedItem);
        } else if (selectedElement) {
          // UNSELECT
          selectedElement = null;
          selectedItem = null;
          updateProperties();
        }
      }
    },

    _onMouseOver: function _onMouseOver(event) {
      var el = findItemElement(event.target);
      if (el) {
        if (el !== hoveredElement) {
          // OVER
          hoveredElement = el;
        }
      } else {
        // OUT
        hoveredElement = null;
      }
    },

    _onFocus: function _onFocus(event) {
      boundKeyDownListener = this._onKeyDown.bind(this);
      event.target.addEventListener('keydown', boundKeyDownListener, false);
    },

    _onBlur: function _onBlur(event) {
      if (boundKeyDownListener) {
        event.target.removeEventListener("keydown", boundKeyDownListener);
      }
    },

    _onKeyDown: function _onBlur(event) {
      var dir = 0;
      switch (event.keyCode) {
        case 40:
          dir = 1;
          break;
        case 38:
          dir = -1;
          break;
      }
      if (dir != 0) {
        var dosidx = clamp(selectedElement ? +selectedElement.dataset.dosidx + dir : 0, 0, displayObjectStore.length - 1);
        var newSelectedItem = displayObjectStore[dosidx];
        if (selectedItem !== newSelectedItem) {
          if (selectedElement) {
            selectedElement.classList.remove("selected");
          }
          selectedItem = newSelectedItem;
          selectedElement = document.querySelector("#displayListRoot .item[data-dosidx=\"" + dosidx + "\"]");
          selectedElement.classList.add("selected");
          updateProperties(selectedItem);
        }
        event.preventDefault();
      }
    },

    _addEventListeners: function _addEventListeners(el) {
        boundClickListener = this._onClick.bind(this);
        boundMouseOverListener = this._onMouseOver.bind(this);
        boundFocusListener = this._onFocus.bind(this);
        boundBlurListener = this._onBlur.bind(this);
        el.addEventListener("click", boundClickListener);
        el.addEventListener("mouseover", boundMouseOverListener);
        el.addEventListener("focus", boundFocusListener);
        el.addEventListener("blur", boundBlurListener);
    },

    _removeEventListeners: function _removeEventListeners(el) {
      if (el) {
        if (boundClickListener) {
          el.removeEventListener("click", boundClickListener);
        }
        if (boundMouseOverListener) {
          el.removeEventListener("mouseover", boundMouseOverListener);
        }
        if (boundFocusListener) {
          el.removeEventListener("focus", boundFocusListener);
        }
        if (boundBlurListener) {
          el.removeEventListener("blur", boundBlurListener);
        }
        if (boundKeyDownListener) {
          el.removeEventListener("keydown", boundKeyDownListener);
        }
      }
    }

  };

  return DisplayListTree;

})();
<|endoftext|>


<commit_before>/* global describe, it */

require('source-map-support').install()
var _ = require('lodash')
var ap = require('any-path')
var fs = require('fs')
var enableCache = false
var _NYC

try {
  _NYC = require('../../index.covered.js')
} catch (e) {
  _NYC = require('../../')
}

function NYC (opts) {
  opts = opts || {}
  if (!opts.hasOwnProperty('enableCache')) {
    opts.enableCache = enableCache
  }
  return new _NYC(opts)
}

var path = require('path')
var existsSync = require('exists-sync')
var rimraf = require('rimraf')
var sinon = require('sinon')
var isWindows = require('is-windows')()
var spawn = require('child_process').spawn
var fixtures = path.resolve(__dirname, '../fixtures')
var projectDir = path.resolve(__dirname, '../..')
var projectTempDir = path.join(projectDir, '.nyc_output')
var projectCacheDir = path.join(projectDir, 'node_modules', '.cache', 'nyc')
var fixtureTempDir = path.join(fixtures, '.nyc_output')
var fixtureCacheDir = path.join(fixtures, 'node_modules', '.cache', 'nyc')
var bin = path.resolve(__dirname, '../../bin/nyc')

// beforeEach
rimraf.sync(projectTempDir)
rimraf.sync(fixtureTempDir)
rimraf.sync(projectCacheDir)
rimraf.sync(fixtureCacheDir)
delete process.env.NYC_CWD

require('chai').should()
require('tap').mochaGlobals()

describe('nyc', function () {
  describe('cwd', function () {
    it('sets cwd to process.cwd() if no environment variable is set', function () {
      var nyc = new NYC()

      nyc.cwd.should.eql(process.cwd())
    })

    it('uses NYC_CWD environment variable for cwd if it is set', function () {
      process.env.NYC_CWD = path.resolve(__dirname, '../fixtures')

      var nyc = new NYC()

      nyc.cwd.should.equal(path.resolve(__dirname, '../fixtures'))
    })

    it('will look upwards for package.json from cwd', function () {
      var nyc = new NYC({cwd: __dirname})
      nyc.cwd.should.eql(path.join(__dirname, '../..'))
    })
  })

  describe('config', function () {
    it("loads 'exclude' patterns from package.json#config.nyc", function () {
      var nyc = new NYC({
        cwd: path.resolve(__dirname, '../fixtures')
      })

      nyc.exclude.length.should.eql(5)
    })

    it("loads 'exclude' patterns from package.json#nyc", function () {
      var nyc = new NYC({
        cwd: path.resolve(__dirname, '../..')
      })

      nyc.exclude.length.should.eql(19)
    })
  })

  describe('_prepGlobPatterns', function () {
    it('should adjust patterns appropriately', function () {
      var _prepGlobPatterns = new NYC()._prepGlobPatterns

      var result = _prepGlobPatterns(['./foo', 'bar/**', 'baz/'])

      result.should.deep.equal([
        './foo/**', // Appended `/**`
        './foo',
        'bar/**',
        'baz/**',  // Removed trailing slash before appending `/**`
        'baz/'
      ])
    })
  })

  describe('shouldInstrumentFile', function () {
    it('should exclude appropriately with defaults', function () {
      var nyc = new NYC()

      // Root package contains config.exclude
      // Restore exclude to default patterns
      nyc.exclude = nyc._prepGlobPatterns([
        '**/node_modules/**',
        'test/**',
        'test{,-*}.js'
      ])

      var shouldInstrumentFile = nyc.shouldInstrumentFile.bind(nyc)

      // nyc always excludes "node_modules/**"
      shouldInstrumentFile('foo', 'foo').should.equal(true)
      shouldInstrumentFile('node_modules/bar', 'node_modules/bar').should.equal(false)
      shouldInstrumentFile('foo/node_modules/bar', 'foo/node_modules/bar').should.equal(false)
      shouldInstrumentFile('test.js', 'test.js').should.equal(false)
      shouldInstrumentFile('testfoo.js', 'testfoo.js').should.equal(true)
      shouldInstrumentFile('test-foo.js', 'test-foo.js').should.equal(false)
      shouldInstrumentFile('lib/test.js', 'lib/test.js').should.equal(true)
      shouldInstrumentFile('/foo/bar/test.js', './test.js').should.equal(false)
    })

    it('should exclude appropriately with config.exclude', function () {
      var nyc = new NYC({
        cwd: fixtures
      })
      var shouldInstrumentFile = nyc.shouldInstrumentFile.bind(nyc)

      // fixtures/package.json configures excludes: "blarg", "blerg"
      shouldInstrumentFile('blarg', 'blarg').should.equal(false)
      shouldInstrumentFile('blarg/foo.js', 'blarg/foo.js').should.equal(false)
      shouldInstrumentFile('blerg', 'blerg').should.equal(false)
      shouldInstrumentFile('./blerg', './blerg').should.equal(false)
    })

    it('should handle example symlinked node_module', function () {
      var nyc = new NYC({
        cwd: fixtures
      })
      var shouldInstrumentFile = nyc.shouldInstrumentFile.bind(nyc)

      var relPath = '../../../nyc/node_modules/glob/glob.js'
      var fullPath = '/Users/user/nyc/node_modules/glob/glob.js'

      shouldInstrumentFile(fullPath, relPath).should.equal(false)

      // Full path should be excluded (node_modules)
      shouldInstrumentFile(fullPath, relPath).should.equal(false)

      // Send both relative and absolute path
      // Results in exclusion (include = false)
      shouldInstrumentFile(fullPath, relPath).should.equal(false)
    })

    it('allows a file to be included rather than excluded', function () {
      var nyc = new NYC()

      // Root package contains config.exclude
      // Restore exclude to default patterns
      nyc.include = nyc._prepGlobPatterns([
        'test.js'
      ])

      var shouldInstrumentFile = nyc.shouldInstrumentFile.bind(nyc)
      shouldInstrumentFile('test.js', 'test.js').should.equal(true)
      shouldInstrumentFile('index.js', 'index.js').should.equal(false)
    })
  })

  describe('wrap', function () {
    it('wraps modules with coverage counters when they are required', function () {
      var nyc = new NYC({
        cwd: process.cwd()
      })
      nyc.reset()
      nyc.wrap()

      var check = require('../fixtures/check-instrumented')
      check().should.be.true
    })

    describe('custom require hooks are installed', function () {
      it('wraps modules with coverage counters when the custom require hook compiles them', function () {
        var hook = sinon.spy(function (module, filename) {
          module._compile(fs.readFileSync(filename, 'utf8'), filename)
        })

        // the `require` call to istanbul is deferred, loaded here so it doesn't mess with the hooks callCount
        require('istanbul')

        var nyc = new NYC({
          cwd: process.cwd()
        })
        nyc.reset()
        nyc.wrap()

        // install the custom require hook
        require.extensions['.js'] = hook

        var check = require('../fixtures/check-instrumented')
        check().should.be.true

        // and the hook should have been called
        hook.callCount.should.equal(1)
      })
    })

    function testSignal (signal, done) {
      var nyc = (new NYC({
        cwd: fixtures
      }))

      var proc = spawn(process.execPath, [bin, './' + signal + '.js'], {
        cwd: fixtures,
        env: {},
        stdio: 'ignore'
      })

      proc.on('close', function () {
        var reports = _.filter(nyc._loadReports(), function (report) {
          return report['./' + signal + '.js']
        })
        reports.length.should.equal(1)
        return done()
      })
    }

    it('writes coverage report when process is killed with SIGTERM', function (done) {
      if (isWindows) return done()
      testSignal('sigterm', done)
    })

    it('writes coverage report when process is killed with SIGINT', function (done) {
      if (isWindows) return done()
      testSignal('sigint', done)
    })

    it('does not output coverage for files that have not been included, by default', function (done) {
      var nyc = (new NYC({
        cwd: process.cwd()
      }))
      nyc.wrap()
      nyc.reset()

      var reports = _.filter(nyc._loadReports(), function (report) {
        return report['./test/fixtures/not-loaded.js']
      })
      reports.length.should.equal(0)
      return done()
    })
  })

  describe('report', function () {
    it('runs reports for all JSON in output directory', function (done) {
      var nyc = new NYC({
        cwd: fixtures
      })

      var proc = spawn(process.execPath, [bin, './spawn.js'], {
        cwd: fixtures,
        env: {},
        stdio: 'ignore'
      })

      proc.on('close', function () {
        nyc.report(
          null,
          {
            add: function (report) {
              // the subprocess we ran should output reports
              // for files in the fixtures directory.
              Object.keys(report).should.match(/.\/(spawn|child-1|child-2)\.js/)
            }
          },
          {
            add: function (reporter) {
              // reporter defaults to 'text'/
              reporter.should.equal('text')
            },
            write: function () {
              // we should have output a report for the new subprocess.
              var stop = fs.readdirSync(nyc.tempDirectory()).length
              stop.should.be.eql(3)
              return done()
            }
          }
        )
      })
    })

    it('handles corrupt JSON files', function (done) {
      var nyc = new NYC({
        cwd: process.cwd()
      })
      nyc.reset()

      fs.writeFileSync('./.nyc_output/bad.json', '}', 'utf-8')

      nyc.report(
        null,
        {
          add: function (report) {}
        },
        {
          add: function (reporter) {},
          write: function () {
            // we should get here without exception.
            fs.unlinkSync('./.nyc_output/bad.json')
            return done()
          }
        }
      )
    })

    it('handles multiple reporters', function (done) {
      var reporters = ['text-summary', 'text-lcov']
      var incr = 0
      var nyc = new NYC({
        cwd: process.cwd(),
        reporter: reporters
      })
      nyc.reset()

      var proc = spawn(process.execPath, ['./test/fixtures/child-1.js'], {
        cwd: process.cwd(),
        env: process.env,
        stdio: 'inherit'
      })

      proc.on('close', function () {
        nyc.report(
          null,
          {
            add: function (report) {}
          },
          {
            add: function (reporter) {
              incr += !!~reporters.indexOf(reporter)
            },
            write: function () {
              incr.should.eql(reporters.length)
              return done()
            }
          }
        )
      })
    })

    it('allows coverage report to be output in an alternative directory', function (done) {
      var reporters = ['lcov']
      var nyc = new NYC({
        cwd: process.cwd(),
        reporter: reporters,
        reportDir: './alternative-report'
      })
      nyc.reset()

      var proc = spawn(process.execPath, ['./test/fixtures/child-1.js'], {
        cwd: process.cwd(),
        env: process.env,
        stdio: 'inherit'
      })

      proc.on('close', function () {
        nyc.report()
        existsSync('./alternative-report/lcov.info').should.equal(true)
        rimraf.sync('./alternative-report')
        return done()
      })
    })
  })

  describe('.istanbul.yml configuration', function () {
    var istanbul = require('istanbul')
    var configSpy = sinon.spy(istanbul.config, 'loadFile')
    var instrumenterSpy = sinon.spy(istanbul, 'Instrumenter')

    function writeConfig () {
      fs.writeFileSync('./.istanbul.yml', 'instrumentation:\n\tpreserve-comments: true', 'utf-8')
    }

    function afterEach () {
      configSpy.reset()
      instrumenterSpy.reset()
      rimraf.sync('./.istanbul.yml')
    }

    it('it handles having no .istanbul.yml in the root directory', function (done) {
      afterEach()
      var nyc = new NYC()
      nyc.wrap()
      return done()
    })

    it('uses the values in .istanbul.yml to instantiate the instrumenter', function (done) {
      writeConfig()

      var nyc = new NYC({
        istanbul: istanbul
      })
      nyc.wrap()

      nyc.instrumenter()

      istanbul.config.loadFile.calledWithMatch('.istanbul.yml').should.equal(true)
      istanbul.Instrumenter.calledWith({
        coverageVariable: '__coverage__',
        embedSource: false,
        noCompact: false,
        preserveComments: false
      }).should.equal(true)

      afterEach()
      return done()
    })

    it('loads the .istanbul.yml configuration from NYC_CWD', function (done) {
      var nyc = new NYC({
        istanbul: istanbul,
        cwd: './test/fixtures'
      })
      nyc.wrap()

      nyc.instrumenter()

      istanbul.config.loadFile.calledWithMatch(path.join('test', 'fixtures', '.istanbul.yml')).should.equal(true)
      istanbul.Instrumenter.calledWith({
        coverageVariable: '__coverage__',
        embedSource: false,
        noCompact: false,
        preserveComments: true
      }).should.equal(true)

      afterEach()
      return done()
    })
  })

  describe('mungeArgs', function () {
    it('removes dashed options that proceed bin', function () {
      process.argv = ['/Users/benjamincoe/bin/iojs',
        '/Users/benjamincoe/bin/nyc.js',
        '--reporter',
        'lcov',
        'node',
        'test/nyc-test.js'
      ]

      var yargv = require('yargs').argv

      var munged = (new NYC()).mungeArgs(yargv)

      munged.should.eql(['node', 'test/nyc-test.js'])
    })
  })

  describe('addAllFiles', function () {
    it('outputs an empty coverage report for all files that are not excluded', function (done) {
      var nyc = (new NYC())
      nyc.reset()
      nyc.addAllFiles()

      var reports = _.filter(nyc._loadReports(), function (report) {
        return ap(report)['./test/fixtures/not-loaded.js']
      })
      var report = reports[0]['./test/fixtures/not-loaded.js']

      reports.length.should.equal(1)
      report.s['1'].should.equal(0)
      report.s['2'].should.equal(0)
      return done()
    })

    it('tracks coverage appropriately once the file is required', function (done) {
      var nyc = (new NYC({
        cwd: fixtures
      }))
      nyc.reset()
      nyc.wrap()

      require('../fixtures/not-loaded')

      nyc.writeCoverageFile()
      var reports = _.filter(nyc._loadReports(), function (report) {
        return report['./not-loaded.js']
      })
      var report = reports[0]['./not-loaded.js']

      reports.length.should.equal(1)
      report.s['1'].should.equal(1)
      report.s['2'].should.equal(1)

      return done()
    })

    it('transpiles files added via addAllFiles', function (done) {
      fs.writeFileSync(
        './test/fixtures/needs-transpile.js',
        '--> pork chop sandwiches <--\nvar a = 99',
        'utf-8'
      )

      var nyc = (new NYC({
        require: './test/fixtures/transpile-hook'
      }))

      nyc.reset()
      nyc.addAllFiles()

      var reports = _.filter(nyc._loadReports(), function (report) {
        return ap(report)['./test/fixtures/needs-transpile.js']
      })
      var report = reports[0]['./test/fixtures/needs-transpile.js']

      reports.length.should.equal(1)
      report.s['1'].should.equal(0)

      fs.unlinkSync('./test/fixtures/needs-transpile.js')
      return done()
    })
  })

  describe('cache', function () {
    it('handles collisions', function (done) {
      var nyc = new NYC({cwd: fixtures})
      nyc.clearCache()

      var args = [bin, process.execPath, './cache-collision-runner.js']

      var proc = spawn(process.execPath, args, {
        cwd: fixtures,
        env: {}
      })

      proc.on('close', function (code) {
        code.should.equal(0)
        done()
      })
    })
  })
})
<commit_msg>remove bad symlink test<commit_after>/* global describe, it */

require('source-map-support').install()
var _ = require('lodash')
var ap = require('any-path')
var fs = require('fs')
var enableCache = false
var _NYC

try {
  _NYC = require('../../index.covered.js')
} catch (e) {
  _NYC = require('../../')
}

function NYC (opts) {
  opts = opts || {}
  if (!opts.hasOwnProperty('enableCache')) {
    opts.enableCache = enableCache
  }
  return new _NYC(opts)
}

var path = require('path')
var existsSync = require('exists-sync')
var rimraf = require('rimraf')
var sinon = require('sinon')
var isWindows = require('is-windows')()
var spawn = require('child_process').spawn
var fixtures = path.resolve(__dirname, '../fixtures')
var projectDir = path.resolve(__dirname, '../..')
var projectTempDir = path.join(projectDir, '.nyc_output')
var projectCacheDir = path.join(projectDir, 'node_modules', '.cache', 'nyc')
var fixtureTempDir = path.join(fixtures, '.nyc_output')
var fixtureCacheDir = path.join(fixtures, 'node_modules', '.cache', 'nyc')
var bin = path.resolve(__dirname, '../../bin/nyc')

// beforeEach
rimraf.sync(projectTempDir)
rimraf.sync(fixtureTempDir)
rimraf.sync(projectCacheDir)
rimraf.sync(fixtureCacheDir)
delete process.env.NYC_CWD

require('chai').should()
require('tap').mochaGlobals()

describe('nyc', function () {
  describe('cwd', function () {
    it('sets cwd to process.cwd() if no environment variable is set', function () {
      var nyc = new NYC()

      nyc.cwd.should.eql(process.cwd())
    })

    it('uses NYC_CWD environment variable for cwd if it is set', function () {
      process.env.NYC_CWD = path.resolve(__dirname, '../fixtures')

      var nyc = new NYC()

      nyc.cwd.should.equal(path.resolve(__dirname, '../fixtures'))
    })

    it('will look upwards for package.json from cwd', function () {
      var nyc = new NYC({cwd: __dirname})
      nyc.cwd.should.eql(path.join(__dirname, '../..'))
    })
  })

  describe('config', function () {
    it("loads 'exclude' patterns from package.json#config.nyc", function () {
      var nyc = new NYC({
        cwd: path.resolve(__dirname, '../fixtures')
      })

      nyc.exclude.length.should.eql(5)
    })

    it("loads 'exclude' patterns from package.json#nyc", function () {
      var nyc = new NYC({
        cwd: path.resolve(__dirname, '../..')
      })

      nyc.exclude.length.should.eql(19)
    })
  })

  describe('_prepGlobPatterns', function () {
    it('should adjust patterns appropriately', function () {
      var _prepGlobPatterns = new NYC()._prepGlobPatterns

      var result = _prepGlobPatterns(['./foo', 'bar/**', 'baz/'])

      result.should.deep.equal([
        './foo/**', // Appended `/**`
        './foo',
        'bar/**',
        'baz/**',  // Removed trailing slash before appending `/**`
        'baz/'
      ])
    })
  })

  describe('shouldInstrumentFile', function () {
    it('should exclude appropriately with defaults', function () {
      var nyc = new NYC()

      // Root package contains config.exclude
      // Restore exclude to default patterns
      nyc.exclude = nyc._prepGlobPatterns([
        '**/node_modules/**',
        'test/**',
        'test{,-*}.js'
      ])

      var shouldInstrumentFile = nyc.shouldInstrumentFile.bind(nyc)

      // nyc always excludes "node_modules/**"
      shouldInstrumentFile('foo', 'foo').should.equal(true)
      shouldInstrumentFile('node_modules/bar', 'node_modules/bar').should.equal(false)
      shouldInstrumentFile('foo/node_modules/bar', 'foo/node_modules/bar').should.equal(false)
      shouldInstrumentFile('test.js', 'test.js').should.equal(false)
      shouldInstrumentFile('testfoo.js', 'testfoo.js').should.equal(true)
      shouldInstrumentFile('test-foo.js', 'test-foo.js').should.equal(false)
      shouldInstrumentFile('lib/test.js', 'lib/test.js').should.equal(true)
      shouldInstrumentFile('/foo/bar/test.js', './test.js').should.equal(false)
    })

    it('should exclude appropriately with config.exclude', function () {
      var nyc = new NYC({
        cwd: fixtures
      })
      var shouldInstrumentFile = nyc.shouldInstrumentFile.bind(nyc)

      // fixtures/package.json configures excludes: "blarg", "blerg"
      shouldInstrumentFile('blarg', 'blarg').should.equal(false)
      shouldInstrumentFile('blarg/foo.js', 'blarg/foo.js').should.equal(false)
      shouldInstrumentFile('blerg', 'blerg').should.equal(false)
      shouldInstrumentFile('./blerg', './blerg').should.equal(false)
    })

    it('allows a file to be included rather than excluded', function () {
      var nyc = new NYC()

      // Root package contains config.exclude
      // Restore exclude to default patterns
      nyc.include = nyc._prepGlobPatterns([
        'test.js'
      ])

      var shouldInstrumentFile = nyc.shouldInstrumentFile.bind(nyc)
      shouldInstrumentFile('test.js', 'test.js').should.equal(true)
      shouldInstrumentFile('index.js', 'index.js').should.equal(false)
    })
  })

  describe('wrap', function () {
    it('wraps modules with coverage counters when they are required', function () {
      var nyc = new NYC({
        cwd: process.cwd()
      })
      nyc.reset()
      nyc.wrap()

      var check = require('../fixtures/check-instrumented')
      check().should.be.true
    })

    describe('custom require hooks are installed', function () {
      it('wraps modules with coverage counters when the custom require hook compiles them', function () {
        var hook = sinon.spy(function (module, filename) {
          module._compile(fs.readFileSync(filename, 'utf8'), filename)
        })

        // the `require` call to istanbul is deferred, loaded here so it doesn't mess with the hooks callCount
        require('istanbul')

        var nyc = new NYC({
          cwd: process.cwd()
        })
        nyc.reset()
        nyc.wrap()

        // install the custom require hook
        require.extensions['.js'] = hook

        var check = require('../fixtures/check-instrumented')
        check().should.be.true

        // and the hook should have been called
        hook.callCount.should.equal(1)
      })
    })

    function testSignal (signal, done) {
      var nyc = (new NYC({
        cwd: fixtures
      }))

      var proc = spawn(process.execPath, [bin, './' + signal + '.js'], {
        cwd: fixtures,
        env: {},
        stdio: 'ignore'
      })

      proc.on('close', function () {
        var reports = _.filter(nyc._loadReports(), function (report) {
          return report['./' + signal + '.js']
        })
        reports.length.should.equal(1)
        return done()
      })
    }

    it('writes coverage report when process is killed with SIGTERM', function (done) {
      if (isWindows) return done()
      testSignal('sigterm', done)
    })

    it('writes coverage report when process is killed with SIGINT', function (done) {
      if (isWindows) return done()
      testSignal('sigint', done)
    })

    it('does not output coverage for files that have not been included, by default', function (done) {
      var nyc = (new NYC({
        cwd: process.cwd()
      }))
      nyc.wrap()
      nyc.reset()

      var reports = _.filter(nyc._loadReports(), function (report) {
        return report['./test/fixtures/not-loaded.js']
      })
      reports.length.should.equal(0)
      return done()
    })
  })

  describe('report', function () {
    it('runs reports for all JSON in output directory', function (done) {
      var nyc = new NYC({
        cwd: fixtures
      })

      var proc = spawn(process.execPath, [bin, './spawn.js'], {
        cwd: fixtures,
        env: {},
        stdio: 'ignore'
      })

      proc.on('close', function () {
        nyc.report(
          null,
          {
            add: function (report) {
              // the subprocess we ran should output reports
              // for files in the fixtures directory.
              Object.keys(report).should.match(/.\/(spawn|child-1|child-2)\.js/)
            }
          },
          {
            add: function (reporter) {
              // reporter defaults to 'text'/
              reporter.should.equal('text')
            },
            write: function () {
              // we should have output a report for the new subprocess.
              var stop = fs.readdirSync(nyc.tempDirectory()).length
              stop.should.be.eql(3)
              return done()
            }
          }
        )
      })
    })

    it('handles corrupt JSON files', function (done) {
      var nyc = new NYC({
        cwd: process.cwd()
      })
      nyc.reset()

      fs.writeFileSync('./.nyc_output/bad.json', '}', 'utf-8')

      nyc.report(
        null,
        {
          add: function (report) {}
        },
        {
          add: function (reporter) {},
          write: function () {
            // we should get here without exception.
            fs.unlinkSync('./.nyc_output/bad.json')
            return done()
          }
        }
      )
    })

    it('handles multiple reporters', function (done) {
      var reporters = ['text-summary', 'text-lcov']
      var incr = 0
      var nyc = new NYC({
        cwd: process.cwd(),
        reporter: reporters
      })
      nyc.reset()

      var proc = spawn(process.execPath, ['./test/fixtures/child-1.js'], {
        cwd: process.cwd(),
        env: process.env,
        stdio: 'inherit'
      })

      proc.on('close', function () {
        nyc.report(
          null,
          {
            add: function (report) {}
          },
          {
            add: function (reporter) {
              incr += !!~reporters.indexOf(reporter)
            },
            write: function () {
              incr.should.eql(reporters.length)
              return done()
            }
          }
        )
      })
    })

    it('allows coverage report to be output in an alternative directory', function (done) {
      var reporters = ['lcov']
      var nyc = new NYC({
        cwd: process.cwd(),
        reporter: reporters,
        reportDir: './alternative-report'
      })
      nyc.reset()

      var proc = spawn(process.execPath, ['./test/fixtures/child-1.js'], {
        cwd: process.cwd(),
        env: process.env,
        stdio: 'inherit'
      })

      proc.on('close', function () {
        nyc.report()
        existsSync('./alternative-report/lcov.info').should.equal(true)
        rimraf.sync('./alternative-report')
        return done()
      })
    })
  })

  describe('.istanbul.yml configuration', function () {
    var istanbul = require('istanbul')
    var configSpy = sinon.spy(istanbul.config, 'loadFile')
    var instrumenterSpy = sinon.spy(istanbul, 'Instrumenter')

    function writeConfig () {
      fs.writeFileSync('./.istanbul.yml', 'instrumentation:\n\tpreserve-comments: true', 'utf-8')
    }

    function afterEach () {
      configSpy.reset()
      instrumenterSpy.reset()
      rimraf.sync('./.istanbul.yml')
    }

    it('it handles having no .istanbul.yml in the root directory', function (done) {
      afterEach()
      var nyc = new NYC()
      nyc.wrap()
      return done()
    })

    it('uses the values in .istanbul.yml to instantiate the instrumenter', function (done) {
      writeConfig()

      var nyc = new NYC({
        istanbul: istanbul
      })
      nyc.wrap()

      nyc.instrumenter()

      istanbul.config.loadFile.calledWithMatch('.istanbul.yml').should.equal(true)
      istanbul.Instrumenter.calledWith({
        coverageVariable: '__coverage__',
        embedSource: false,
        noCompact: false,
        preserveComments: false
      }).should.equal(true)

      afterEach()
      return done()
    })

    it('loads the .istanbul.yml configuration from NYC_CWD', function (done) {
      var nyc = new NYC({
        istanbul: istanbul,
        cwd: './test/fixtures'
      })
      nyc.wrap()

      nyc.instrumenter()

      istanbul.config.loadFile.calledWithMatch(path.join('test', 'fixtures', '.istanbul.yml')).should.equal(true)
      istanbul.Instrumenter.calledWith({
        coverageVariable: '__coverage__',
        embedSource: false,
        noCompact: false,
        preserveComments: true
      }).should.equal(true)

      afterEach()
      return done()
    })
  })

  describe('mungeArgs', function () {
    it('removes dashed options that proceed bin', function () {
      process.argv = ['/Users/benjamincoe/bin/iojs',
        '/Users/benjamincoe/bin/nyc.js',
        '--reporter',
        'lcov',
        'node',
        'test/nyc-test.js'
      ]

      var yargv = require('yargs').argv

      var munged = (new NYC()).mungeArgs(yargv)

      munged.should.eql(['node', 'test/nyc-test.js'])
    })
  })

  describe('addAllFiles', function () {
    it('outputs an empty coverage report for all files that are not excluded', function (done) {
      var nyc = (new NYC())
      nyc.reset()
      nyc.addAllFiles()

      var reports = _.filter(nyc._loadReports(), function (report) {
        return ap(report)['./test/fixtures/not-loaded.js']
      })
      var report = reports[0]['./test/fixtures/not-loaded.js']

      reports.length.should.equal(1)
      report.s['1'].should.equal(0)
      report.s['2'].should.equal(0)
      return done()
    })

    it('tracks coverage appropriately once the file is required', function (done) {
      var nyc = (new NYC({
        cwd: fixtures
      }))
      nyc.reset()
      nyc.wrap()

      require('../fixtures/not-loaded')

      nyc.writeCoverageFile()
      var reports = _.filter(nyc._loadReports(), function (report) {
        return report['./not-loaded.js']
      })
      var report = reports[0]['./not-loaded.js']

      reports.length.should.equal(1)
      report.s['1'].should.equal(1)
      report.s['2'].should.equal(1)

      return done()
    })

    it('transpiles files added via addAllFiles', function (done) {
      fs.writeFileSync(
        './test/fixtures/needs-transpile.js',
        '--> pork chop sandwiches <--\nvar a = 99',
        'utf-8'
      )

      var nyc = (new NYC({
        require: './test/fixtures/transpile-hook'
      }))

      nyc.reset()
      nyc.addAllFiles()

      var reports = _.filter(nyc._loadReports(), function (report) {
        return ap(report)['./test/fixtures/needs-transpile.js']
      })
      var report = reports[0]['./test/fixtures/needs-transpile.js']

      reports.length.should.equal(1)
      report.s['1'].should.equal(0)

      fs.unlinkSync('./test/fixtures/needs-transpile.js')
      return done()
    })
  })

  describe('cache', function () {
    it('handles collisions', function (done) {
      var nyc = new NYC({cwd: fixtures})
      nyc.clearCache()

      var args = [bin, process.execPath, './cache-collision-runner.js']

      var proc = spawn(process.execPath, args, {
        cwd: fixtures,
        env: {}
      })

      proc.on('close', function (code) {
        code.should.equal(0)
        done()
      })
    })
  })
})
<|endoftext|>


<commit_before>function WalkontableVerticalScrollbarNative(instance) {
  this.instance = instance;
  this.type = 'vertical';
  this.cellSize = 23;
  this.init();

  var that = this;

  this.clone = this.makeClone('top');
}

WalkontableVerticalScrollbarNative.prototype = new WalkontableOverlay();

//resetFixedPosition (in future merge it with this.refresh?)
WalkontableVerticalScrollbarNative.prototype.resetFixedPosition = function () {
  if (!this.instance.wtTable.holder.parentNode) {
    return; //removed from DOM
  }
  var elem = this.clone.wtTable.holder.parentNode;

  var box;
  if (this.scrollHandler === window) {
    box = this.instance.wtTable.hider.getBoundingClientRect();
    var top = Math.ceil(box.top, 10);
    var bottom = Math.ceil(box.bottom, 10);

    if (top < 0 && bottom > 0) {
      elem.style.top = '0';
    }
    else {
      elem.style.top = top + 'px';
    }
  }
  else {
    box = this.instance.wtScrollbars.horizontal.scrollHandler.getBoundingClientRect();
    elem.style.top = Math.ceil(box.top, 10) + 'px';
    elem.style.left = Math.ceil(box.left, 10) + 'px';
  }

  if (this.instance.wtScrollbars.horizontal.scrollHandler === window) {
    elem.style.width = this.instance.wtViewport.getWorkspaceActualWidth() + 'px';
  }
  else {
    elem.style.width = WalkontableDom.prototype.outerWidth(this.instance.wtTable.holder.parentNode) + 'px';
  }

  elem.style.height = WalkontableDom.prototype.outerHeight(this.clone.wtTable.TABLE) + 4 + 'px';
};

//react on movement of the other dimension scrollbar (in future merge it with this.refresh?)
WalkontableVerticalScrollbarNative.prototype.react = function () {
  if (!this.instance.wtTable.holder.parentNode) {
    return; //removed from DOM
  }
  if (this.instance.wtScrollbars.horizontal.scrollHandler !== window) {
    var elem = this.clone.wtTable.holder.parentNode;
    elem.firstChild.style.left = -this.instance.wtScrollbars.horizontal.windowScrollPosition + 'px';
  }
};

WalkontableVerticalScrollbarNative.prototype.getScrollPosition = function () {
  if (this.scrollHandler === window) {
    return this.scrollHandler.scrollY;
  }
  else {
    return this.scrollHandler.scrollTop;
  }
};

WalkontableVerticalScrollbarNative.prototype.setScrollPosition = function (pos) {
  this.scrollHandler.scrollTop = pos;
};

WalkontableVerticalScrollbarNative.prototype.onScroll = function (forcePosition) {
  WalkontableOverlay.prototype.onScroll.apply(this, arguments);

  var scrollDelta;
  var newOffset = 0;

  if (1 == 1 || this.windowScrollPosition > this.tableParentOffset) {
    scrollDelta = this.windowScrollPosition - this.tableParentOffset;

    partialOffset = 0;
    if (scrollDelta > 0) {
      var sum = 0;
      var last;
      for (var i = 0; i < this.total; i++) {
        last = this.instance.getSetting('rowHeight', i);
        sum += last;
        if (sum > scrollDelta) {
          break;
        }
      }

      if (this.offset > 0) {
        partialOffset = (sum - scrollDelta);
      }
      newOffset = i;
      newOffset = Math.min(newOffset, this.total);
    }
  }

  this.curOuts = newOffset > this.maxOuts ? this.maxOuts : newOffset;
  newOffset -= this.curOuts;

  this.instance.update('offsetRow', newOffset);
  this.readSettings(); //read new offset
  this.instance.draw();

  this.instance.getSetting('onScrollVertically');
};

WalkontableVerticalScrollbarNative.prototype.getLastCell = function () {
  return this.instance.getSetting('offsetRow') + this.instance.wtTable.tbodyChildrenLength - 1;
};

var partialOffset = 0;

WalkontableVerticalScrollbarNative.prototype.sumCellSizes = function (from, length) {
  var sum = 0;
  while (from < length) {
    sum += this.instance.getSetting('rowHeight', from);
    from++;
  }
  return sum;
};

//applyToDOM (in future merge it with this.refresh?)
WalkontableVerticalScrollbarNative.prototype.applyToDOM = function () {
  var headerSize = this.instance.wtViewport.getColumnHeaderHeight();
  this.fixedContainer.style.height = headerSize + this.sumCellSizes(0, this.total) + 4 + 'px'; //+4 is needed, otherwise vertical scroll appears in Chrome (window scroll mode) - maybe because of fill handle in last row or because of box shadow
  this.fixed.style.top = this.measureBefore + 'px';
  this.fixed.style.bottom = '';
};

WalkontableVerticalScrollbarNative.prototype.scrollTo = function (cell) {
  var newY = this.tableParentOffset + cell * this.cellSize;
  this.$scrollHandler.scrollTop(newY);
  this.onScroll(newY);
};

//readWindowSize (in future merge it with this.prepare?)
WalkontableVerticalScrollbarNative.prototype.readWindowSize = function () {
  if (this.scrollHandler === window) {
    this.windowSize = document.documentElement.clientHeight;
    this.tableParentOffset = this.instance.wtTable.holderOffset.top;
  }
  else {
    //this.windowSize = WalkontableDom.prototype.outerHeight(this.scrollHandler);
    this.windowSize = this.scrollHandler.clientHeight; //returns height without DIV scrollbar
    this.tableParentOffset = 0;
  }
  this.windowScrollPosition = this.getScrollPosition();
};

//readSettings (in future merge it with this.prepare?)
WalkontableVerticalScrollbarNative.prototype.readSettings = function () {
  this.offset = this.instance.getSetting('offsetRow');
  this.total = this.instance.getSetting('totalRows');
};<commit_msg>native scrollbars: remove redundant variable<commit_after>function WalkontableVerticalScrollbarNative(instance) {
  this.instance = instance;
  this.type = 'vertical';
  this.cellSize = 23;
  this.init();
  this.clone = this.makeClone('top');
}

WalkontableVerticalScrollbarNative.prototype = new WalkontableOverlay();

//resetFixedPosition (in future merge it with this.refresh?)
WalkontableVerticalScrollbarNative.prototype.resetFixedPosition = function () {
  if (!this.instance.wtTable.holder.parentNode) {
    return; //removed from DOM
  }
  var elem = this.clone.wtTable.holder.parentNode;

  var box;
  if (this.scrollHandler === window) {
    box = this.instance.wtTable.hider.getBoundingClientRect();
    var top = Math.ceil(box.top, 10);
    var bottom = Math.ceil(box.bottom, 10);

    if (top < 0 && bottom > 0) {
      elem.style.top = '0';
    }
    else {
      elem.style.top = top + 'px';
    }
  }
  else {
    box = this.instance.wtScrollbars.horizontal.scrollHandler.getBoundingClientRect();
    elem.style.top = Math.ceil(box.top, 10) + 'px';
    elem.style.left = Math.ceil(box.left, 10) + 'px';
  }

  if (this.instance.wtScrollbars.horizontal.scrollHandler === window) {
    elem.style.width = this.instance.wtViewport.getWorkspaceActualWidth() + 'px';
  }
  else {
    elem.style.width = WalkontableDom.prototype.outerWidth(this.instance.wtTable.holder.parentNode) + 'px';
  }

  elem.style.height = WalkontableDom.prototype.outerHeight(this.clone.wtTable.TABLE) + 4 + 'px';
};

//react on movement of the other dimension scrollbar (in future merge it with this.refresh?)
WalkontableVerticalScrollbarNative.prototype.react = function () {
  if (!this.instance.wtTable.holder.parentNode) {
    return; //removed from DOM
  }
  if (this.instance.wtScrollbars.horizontal.scrollHandler !== window) {
    var elem = this.clone.wtTable.holder.parentNode;
    elem.firstChild.style.left = -this.instance.wtScrollbars.horizontal.windowScrollPosition + 'px';
  }
};

WalkontableVerticalScrollbarNative.prototype.getScrollPosition = function () {
  if (this.scrollHandler === window) {
    return this.scrollHandler.scrollY;
  }
  else {
    return this.scrollHandler.scrollTop;
  }
};

WalkontableVerticalScrollbarNative.prototype.setScrollPosition = function (pos) {
  this.scrollHandler.scrollTop = pos;
};

WalkontableVerticalScrollbarNative.prototype.onScroll = function (forcePosition) {
  WalkontableOverlay.prototype.onScroll.apply(this, arguments);

  var scrollDelta;
  var newOffset = 0;

  if (1 == 1 || this.windowScrollPosition > this.tableParentOffset) {
    scrollDelta = this.windowScrollPosition - this.tableParentOffset;

    partialOffset = 0;
    if (scrollDelta > 0) {
      var sum = 0;
      var last;
      for (var i = 0; i < this.total; i++) {
        last = this.instance.getSetting('rowHeight', i);
        sum += last;
        if (sum > scrollDelta) {
          break;
        }
      }

      if (this.offset > 0) {
        partialOffset = (sum - scrollDelta);
      }
      newOffset = i;
      newOffset = Math.min(newOffset, this.total);
    }
  }

  this.curOuts = newOffset > this.maxOuts ? this.maxOuts : newOffset;
  newOffset -= this.curOuts;

  this.instance.update('offsetRow', newOffset);
  this.readSettings(); //read new offset
  this.instance.draw();

  this.instance.getSetting('onScrollVertically');
};

WalkontableVerticalScrollbarNative.prototype.getLastCell = function () {
  return this.instance.getSetting('offsetRow') + this.instance.wtTable.tbodyChildrenLength - 1;
};

var partialOffset = 0;

WalkontableVerticalScrollbarNative.prototype.sumCellSizes = function (from, length) {
  var sum = 0;
  while (from < length) {
    sum += this.instance.getSetting('rowHeight', from);
    from++;
  }
  return sum;
};

//applyToDOM (in future merge it with this.refresh?)
WalkontableVerticalScrollbarNative.prototype.applyToDOM = function () {
  var headerSize = this.instance.wtViewport.getColumnHeaderHeight();
  this.fixedContainer.style.height = headerSize + this.sumCellSizes(0, this.total) + 4 + 'px'; //+4 is needed, otherwise vertical scroll appears in Chrome (window scroll mode) - maybe because of fill handle in last row or because of box shadow
  this.fixed.style.top = this.measureBefore + 'px';
  this.fixed.style.bottom = '';
};

WalkontableVerticalScrollbarNative.prototype.scrollTo = function (cell) {
  var newY = this.tableParentOffset + cell * this.cellSize;
  this.$scrollHandler.scrollTop(newY);
  this.onScroll(newY);
};

//readWindowSize (in future merge it with this.prepare?)
WalkontableVerticalScrollbarNative.prototype.readWindowSize = function () {
  if (this.scrollHandler === window) {
    this.windowSize = document.documentElement.clientHeight;
    this.tableParentOffset = this.instance.wtTable.holderOffset.top;
  }
  else {
    //this.windowSize = WalkontableDom.prototype.outerHeight(this.scrollHandler);
    this.windowSize = this.scrollHandler.clientHeight; //returns height without DIV scrollbar
    this.tableParentOffset = 0;
  }
  this.windowScrollPosition = this.getScrollPosition();
};

//readSettings (in future merge it with this.prepare?)
WalkontableVerticalScrollbarNative.prototype.readSettings = function () {
  this.offset = this.instance.getSetting('offsetRow');
  this.total = this.instance.getSetting('totalRows');
};<|endoftext|>


<commit_before>/*global window*/

import {AppKernel} from 'app/AppKernel';

$(function () {
    'use strict';

    let app = new AppKernel('development', true);

    app.init();
    app.boot();
});<commit_msg>added import of jquery<commit_after>/*global*/

import {AppKernel} from 'app/AppKernel';
import $ from 'jquery';

$(function () {
    'use strict';

    let app = new AppKernel('development', true);

    app.init();
    app.boot();
});<|endoftext|>


<commit_before>describe('Javabuzz', function() {

  var javabuzz;

  beforeEach(function(){
    javabuzz = new Javabuzz();
  });

  describe('knows when a number is', function() {

    it('divisble by three', function(){
      expect(javabuzz.isDivisableByThree(3)).toEqual(true);
    });

    it('divisable by five', function(){
      expect(javabuzz.isDivisableByFive(5)).toEqual(true);
    });

    it('divisable by three and five', function(){
      expect(javabuzz.isDivisableByFifteen(15)).toEqual(true);
    });

  });

  describe('knows when a number is not', function(){

    it('not divisable by three', function(){
      expect(javabuzz.isDivisableByThree(1)).toEqual(false);
    });

    it('not divisable by five', function(){
      expect(javabuzz.isDivisableByFive(1)).toEqual(false);
    });

    it('not divisable by fifteen', function(){
      expect(javabuzz.isDivisableByFifteen(1)).toEqual(false);
    });

  });

  describe('prints fizz, buzz, fizzbuzz or number', function(){

    it('prints fizz when divisable by 3', function(){
      expect(javabuzz.prints(6)).toEqual('fizz');
    });

  });

});
<commit_msg>returns buzz test passed<commit_after>describe('Javabuzz', function() {

  var javabuzz;

  beforeEach(function(){
    javabuzz = new Javabuzz();
  });

  describe('knows when a number is', function() {

    it('divisble by three', function(){
      expect(javabuzz.isDivisableByThree(3)).toEqual(true);
    });

    it('divisable by five', function(){
      expect(javabuzz.isDivisableByFive(5)).toEqual(true);
    });

    it('divisable by three and five', function(){
      expect(javabuzz.isDivisableByFifteen(15)).toEqual(true);
    });

  });

  describe('knows when a number is not', function(){

    it('not divisable by three', function(){
      expect(javabuzz.isDivisableByThree(1)).toEqual(false);
    });

    it('not divisable by five', function(){
      expect(javabuzz.isDivisableByFive(1)).toEqual(false);
    });

    it('not divisable by fifteen', function(){
      expect(javabuzz.isDivisableByFifteen(1)).toEqual(false);
    });

  });

  describe('prints fizz, buzz, fizzbuzz or number', function(){

    it('prints fizz when divisable by 3', function(){
      expect(javabuzz.prints(6)).toEqual('fizz');
    });

    it('prints buzz when divisable by 5', function(){
      expect(javabuzz.prints(10)).toEqual('buzz');
    })

  });

});
<|endoftext|>


<commit_before>'use strict';

var assert = require('chai').assert,
    testlib = require('../lib/test'),
    context = require('../lib/context.js');

describe('context', function () {
    it('.query should be a subtask creator', function (done) {
        assert.equal(true, testlib.isSubtaskCreator(testlib.getMockContext().query));
        done();
    });

    it('.param should be a subtask creator', function (done) {
        assert.equal(true, testlib.isSubtaskCreator(testlib.getMockContext().param));
        done();
    });

    it('.cookie should be a subtask creator', function (done) {
        assert.equal(true, testlib.isSubtaskCreator(testlib.getMockContext().cookie));
        done();
    });

    it('.data should be a subtask creator locator', function (done) {
        assert.equal(true, testlib.isSubtaskCreatorFinder(testlib.getMockContext().data));
        done();
    });

    it('.data("getProdcut") should be a subtask creator', function (done) {
        assert.equal(true, testlib.isSubtaskCreator(testlib.getMockContext().data('getProduct')));
        done();
    });

    it('.module should be a subtask creator locator', function (done) {
        assert.equal(true, testlib.isSubtaskCreatorFinder(testlib.getMockContext().module));
        done();
    });

    it('.module("header") should be a subtask creator', function (done) {
        assert.equal(true, testlib.isSubtaskCreator(testlib.getMockContext().module('header')));
        done();
    });

    it('.module("not_found") should be a subtask creator', function (done) {
        assert.equal(true, testlib.isSubtaskCreator(testlib.getMockContext().module('not_found')));
        done();
    });

    it('.page should be a subtask creator locator', function (done) {
        assert.equal(true, testlib.isSubtaskCreatorFinder(testlib.getMockContext().page));
        done();
    });

    it('.react should be a subtask creator locator', function (done) {
        assert.equal(true, testlib.isSubtaskCreatorFinder(testlib.getMockContext().react));
        done();
    });

    it('.dreact should be a subtask creator locator', function (done) {
        assert.equal(true, testlib.isSubtaskCreatorFinder(testlib.getMockContext().dreact));
        done();
    });

    it('.task should be a subtask creator', function (done) {
        assert.equal(true, testlib.isSubtaskCreator(testlib.getMockContext().task));
        done();
    });

    it('.input should be a subtask creator', function (done) {
        assert.equal(true, testlib.isSubtaskCreator(testlib.getMockContext().input));
        done();
    });

    it('.input("getSomeParams") should be a subtask', function (done) {
        assert.equal(true, testlib.isSubtask(testlib.getMockContext().input('getSomeParams')));
        done();
    });
});
<commit_msg>test more (these should be real case)<commit_after>'use strict';

var assert = require('chai').assert,
    testlib = require('../lib/test'),
    context = require('../lib/context.js');

describe('context', function () {
    it('.query should be a subtask creator', function (done) {
        assert.equal(true, testlib.isSubtaskCreator(testlib.getMockContext().query));
        done();
    });

    it('.param should be a subtask creator', function (done) {
        assert.equal(true, testlib.isSubtaskCreator(testlib.getMockContext().param));
        done();
    });

    it('.cookie should be a subtask creator', function (done) {
        assert.equal(true, testlib.isSubtaskCreator(testlib.getMockContext().cookie));
        done();
    });

    it('.data should be a subtask creator locator', function (done) {
        assert.equal(true, testlib.isSubtaskCreatorFinder(testlib.getMockContext().data));
        done();
    });

    it('.data("getProdcut") should be a subtask creator', function (done) {
        assert.equal(true, testlib.isSubtaskCreator(testlib.getMockContext().data('getProduct')));
        done();
    });

    it('.module should be a subtask creator locator', function (done) {
        assert.equal(true, testlib.isSubtaskCreatorFinder(testlib.getMockContext().module));
        done();
    });

    it('.module("header") should be a subtask creator', function (done) {
        assert.equal(true, testlib.isSubtaskCreator(testlib.getMockContext().module('header')));
        done();
    });

    it('.module("not_found") should be a subtask creator', function (done) {
        assert.equal(true, testlib.isSubtaskCreator(testlib.getMockContext().module('not_found')));
        done();
    });

    it('.page should be a subtask creator locator', function (done) {
        assert.equal(true, testlib.isSubtaskCreatorFinder(testlib.getMockContext().page));
        done();
    });

    it('.react should be a subtask creator locator', function (done) {
        assert.equal(true, testlib.isSubtaskCreatorFinder(testlib.getMockContext().react));
        done();
    });

    it('.dreact should be a subtask creator locator', function (done) {
        assert.equal(true, testlib.isSubtaskCreatorFinder(testlib.getMockContext().dreact));
        done();
    });

    it('.task should be a subtask creator', function (done) {
        assert.equal(true, testlib.isSubtaskCreator(testlib.getMockContext().task));
        done();
    });

    it('.input should be a subtask creator', function (done) {
        assert.equal(true, testlib.isSubtaskCreator(testlib.getMockContext().input));
        done();
    });

    it('.input("getSomeParams") should be a subtask', function (done) {
        assert.equal(true, testlib.isSubtask(testlib.getMockContext().input('getSomeParams')));
        done();
    });
});

describe('context tasks', function () {
    it('module("header")() should be a success task', function (done) {
        testlib.getMockContext().module('header')().execute(function (D) {
            assert.equal(true, D !== undefined);
            done();
        });
    });

    it('react("path")(productData) should be a success task', function (done) {
        testlib.getMockContext().react('Path')({
            path: [
                {id: 1, title: 'root'},
                {id: 3, title: 'second'},
                {id: 321, title: 'final'}
            ]
        }).execute(function (D) {
            assert.equal('

root

second

final

', D);
            done();
        });
    });
});
<|endoftext|>


<commit_before>/*
 * Integration tests for caching
 */

/* eslint-env jest */
'use strict';

const path = require('path');
const webpack = require('webpack');
const rimraf = require('rimraf');
const WebpackRecompilationSimulator = require('webpack-recompilation-simulator');
const HtmlWebpackPlugin = require('../index.js');

const OUTPUT_DIR = path.join(__dirname, '../dist/caching-spec');

jest.setTimeout(30000);
process.on('unhandledRejection', r => console.log(r));
process.traceDeprecation = true;

function setUpCompiler (htmlWebpackPlugin) {
  jest.spyOn(htmlWebpackPlugin, 'evaluateCompilationResult');
  const webpackConfig = {
    stats: { all: true },
    // Caching works only in development
    mode: 'development',
    entry: path.join(__dirname, 'fixtures/index.js'),
    module: {
      rules: [
        {
          test: /\.html$/,
          loader: require.resolve('../lib/loader.js'),
          options: {
            force: true
          }
        }
      ]
    },
    output: {
      path: OUTPUT_DIR,
      filename: 'index_bundle.js'
    },
    plugins: Array.from(arguments)
  };
  const compiler = new WebpackRecompilationSimulator(webpack(webpackConfig));
  return compiler;
}

function getCompiledModules (statsJson) {
  const builtModules = statsJson.modules.filter(webpackModule => webpackModule.built).map((webpackModule) => {
    return module.userRequest;
  });
  statsJson.children.forEach((childCompilationStats) => {
    const builtChildModules = getCompiledModules(childCompilationStats);
    Array.prototype.push.apply(builtModules, builtChildModules);
  });
  return builtModules;
}

function getCompiledModuleCount (statsJson) {
  return getCompiledModules(statsJson).length;
}

function expectNoErrors (stats) {
  const errors = {
    main: stats.compilation.errors,
    childCompilation: []
  };
  stats.compilation.children.forEach((child) => {
    Array.prototype.push.apply(errors.childCompilation, child.errors);
  });
  if (errors.main.length) {
    errors.main.forEach((error) => {
      console.log('Error => ', error);
    });
    console.dir(stats.toJson({ errorDetails: true, moduleTrace: true }), { depth: 5 });
  }
  expect(errors.main).toEqual([]);
  expect(errors.childCompilation).toEqual([]);
}

describe('HtmlWebpackPluginCaching', () => {
  beforeEach(done => {
    rimraf(OUTPUT_DIR, done);
  });

  it('should compile nothing if no file was changed', done => {
    const template = path.join(__dirname, 'fixtures/plain.html');
    const htmlWebpackPlugin = new HtmlWebpackPlugin({
      template: template
    });
    let childCompilerHash;
    const compiler = setUpCompiler(htmlWebpackPlugin);
    compiler.addTestFile(path.join(__dirname, 'fixtures/index.js'));
    compiler.run()
      // Change the template file and compile again
      .then(() => {
        childCompilerHash = htmlWebpackPlugin.childCompilerHash;
        return compiler.run();
      })
      .then(stats => {
        // Expect no errors:
        expectNoErrors(stats);
        // Verify that no file was built
        expect(getCompiledModules(stats.toJson()))
          .toEqual([]);
        // Verify that the html was processed only during the inital build
        expect(htmlWebpackPlugin.evaluateCompilationResult.mock.calls.length)
          .toBe(1);
        // Verify that the child compilation was executed twice
        expect(htmlWebpackPlugin.childCompilerHash)
          .toBe(childCompilerHash);
      })
      .then(done);
  });

  it('should not compile the webpack html file if only a javascript file was changed', done => {
    const htmlWebpackPlugin = new HtmlWebpackPlugin();
    const compiler = setUpCompiler(htmlWebpackPlugin);
    let childCompilerHash;
    compiler.addTestFile(path.join(__dirname, 'fixtures/index.js'));
    compiler.run()
      // Change a js file and compile again
      .then(() => {
        childCompilerHash = htmlWebpackPlugin.childCompilerHash;
        compiler.simulateFileChange(path.join(__dirname, 'fixtures/index.js'), { footer: '//1' });
        return compiler.run();
      })
      .then(stats => {
        // Expect no errors:
        expectNoErrors(stats);
        // Verify that only one file was built
        expect(getCompiledModuleCount(stats.toJson()))
          .toBe(1);
        // Verify that the html was processed only during the inital build
        expect(htmlWebpackPlugin.evaluateCompilationResult.mock.calls.length)
          .toBe(1);
        // Verify that the child compilation was executed only once
        expect(htmlWebpackPlugin.childCompilerHash)
          .toBe(childCompilerHash);
      })
      .then(done);
  });

  it('should compile the webpack html file even if only a javascript file was changed if caching is disabled', done => {
    const htmlWebpackPlugin = new HtmlWebpackPlugin({
      cache: false
    });
    let childCompilerHash;
    const compiler = setUpCompiler(htmlWebpackPlugin);
    compiler.addTestFile(path.join(__dirname, 'fixtures/index.js'));
    compiler.run()
      // Change a js file and compile again
      .then(() => {
        childCompilerHash = htmlWebpackPlugin.childCompilerHash;
        compiler.simulateFileChange(path.join(__dirname, 'fixtures/index.js'), { footer: '//1' });
        return compiler.run();
      })
      .then(stats => {
        // Expect no errors:
        expectNoErrors(stats);
        // Verify that only one file was built
        expect(getCompiledModuleCount(stats.toJson()))
          .toBe(1);
        // Verify that the html was processed on every run
        expect(htmlWebpackPlugin.evaluateCompilationResult.mock.calls.length)
          .toBe(2);
        // Verify that the child compilation was executed only once
        expect(htmlWebpackPlugin.childCompilerHash)
          .toBe(childCompilerHash);
      })
      .then(done);
  });

  it('should compile the webpack html if the template file was changed', done => {
    const template = path.join(__dirname, 'fixtures/plain.html');
    const htmlWebpackPlugin = new HtmlWebpackPlugin({
      template: template
    });
    let childCompilerHash;
    const compiler = setUpCompiler(htmlWebpackPlugin);
    compiler.addTestFile(template);
    compiler.run()
      // Change the template file and compile again
      .then(() => {
        childCompilerHash = htmlWebpackPlugin.childCompilerHash;
        compiler.simulateFileChange(template, { footer: '<!-- 1 -->' });
        return compiler.run();
      })
      .then(stats => {
        // Expect no errors:
        expectNoErrors(stats);
        // Verify that only one file was built
        expect(getCompiledModuleCount(stats.toJson()))
          .toBe(1);
        // Verify that the html was processed twice
        expect(htmlWebpackPlugin.evaluateCompilationResult.mock.calls.length)
          .toBe(2);
        // Verify that the child compilation was executed twice
        expect(htmlWebpackPlugin.childCompilerHash)
          .not.toBe(childCompilerHash);
      })
      .then(done);
  });

  it('should not slow down linear (15 plugins should not take twice as much time as a 1 plugin)', done => {
    const template = path.join(__dirname, 'fixtures/plain.html');
    const createHtmlWebpackPlugin = () => new HtmlWebpackPlugin({
      template: template
    });
    let singlePluginCompileStart;
    let singleCompileRunDuration;
    let multiPluginComileStart;
    let multiCompileRunDuration;

    let singleCompiler = setUpCompiler(createHtmlWebpackPlugin());
    let multiCompiler = setUpCompiler.apply(null, Array(15).fill(0).map(() => createHtmlWebpackPlugin()));

    Promise.resolve()
      .then(function singleCompileRun () {
        singlePluginCompileStart = process.hrtime();
        return singleCompiler.run()
          // Change the template file and compile again
          .then(() => {
            singleCompileRunDuration = process.hrtime(singlePluginCompileStart);
          });
      })
      .then(function multiCompileRun () {
        multiPluginComileStart = process.hrtime();
        return multiCompiler.run()
          // Change the template file and compile again
          .then(() => {
            multiCompileRunDuration = process.hrtime(multiPluginComileStart);
          });
      }).then(function meassureTime () {
        const singleCompileRunDurationInNs = singleCompileRunDuration[0] * 1e9 + singleCompileRunDuration[1];
        const multiCompileRunDurationInNs = multiCompileRunDuration[0] * 1e9 + multiCompileRunDuration[1];
        const speedComarision = multiCompileRunDurationInNs / singleCompileRunDurationInNs * 100;

        expect(speedComarision).toBeLessThan(200);
        done();
      });
  });

  it('should keep watching the webpack html if only a js file was changed', done => {
    const template = path.join(__dirname, 'fixtures/plain.html');
    const jsFile = path.join(__dirname, 'fixtures/index.js');
    const htmlWebpackPlugin = new HtmlWebpackPlugin({
      template: template
    });
    const compiler = setUpCompiler(htmlWebpackPlugin);
    compiler.addTestFile(template);
    compiler.addTestFile(jsFile);
    // Build the template file for the first time
    compiler.startWatching()
      // Change the template file (second build)
      .then(() => {
        compiler.simulateFileChange(template, { footer: '<!-- 1 -->' });
        return compiler.waitForWatchRunComplete();
      })
      // Change js
      .then(() => {
        compiler.simulateFileChange(jsFile, { footer: '// 1' });
        return compiler.waitForWatchRunComplete();
      })
      // Change js
      .then(() => {
        compiler.simulateFileChange(jsFile, { footer: '// 2' });
        return compiler.waitForWatchRunComplete();
      })
      // Change js
      .then(() => {
        compiler.simulateFileChange(jsFile, { footer: '// 3' });
        return compiler.waitForWatchRunComplete();
      })
      // Change the template file (third build)
      .then(() => {
        compiler.simulateFileChange(template, { footer: '<!-- 2 -->' });
        return compiler.waitForWatchRunComplete();
      })
      .then(() => {
        // Verify that the html was processed trice
        expect(htmlWebpackPlugin.evaluateCompilationResult.mock.calls.length)
          .toBe(3);
      })
      .then(() => compiler.stopWatching())
      .then(done);
  });
});
<commit_msg>chore: Adjust speed limit<commit_after>/*
 * Integration tests for caching
 */

/* eslint-env jest */
'use strict';

const path = require('path');
const webpack = require('webpack');
const rimraf = require('rimraf');
const WebpackRecompilationSimulator = require('webpack-recompilation-simulator');
const HtmlWebpackPlugin = require('../index.js');

const OUTPUT_DIR = path.join(__dirname, '../dist/caching-spec');

jest.setTimeout(30000);
process.on('unhandledRejection', r => console.log(r));
process.traceDeprecation = true;

function setUpCompiler (htmlWebpackPlugin) {
  jest.spyOn(htmlWebpackPlugin, 'evaluateCompilationResult');
  const webpackConfig = {
    stats: { all: true },
    // Caching works only in development
    mode: 'development',
    entry: path.join(__dirname, 'fixtures/index.js'),
    module: {
      rules: [
        {
          test: /\.html$/,
          loader: require.resolve('../lib/loader.js'),
          options: {
            force: true
          }
        }
      ]
    },
    output: {
      path: OUTPUT_DIR,
      filename: 'index_bundle.js'
    },
    plugins: Array.from(arguments)
  };
  const compiler = new WebpackRecompilationSimulator(webpack(webpackConfig));
  return compiler;
}

function getCompiledModules (statsJson) {
  const builtModules = statsJson.modules.filter(webpackModule => webpackModule.built).map((webpackModule) => {
    return module.userRequest;
  });
  statsJson.children.forEach((childCompilationStats) => {
    const builtChildModules = getCompiledModules(childCompilationStats);
    Array.prototype.push.apply(builtModules, builtChildModules);
  });
  return builtModules;
}

function getCompiledModuleCount (statsJson) {
  return getCompiledModules(statsJson).length;
}

function expectNoErrors (stats) {
  const errors = {
    main: stats.compilation.errors,
    childCompilation: []
  };
  stats.compilation.children.forEach((child) => {
    Array.prototype.push.apply(errors.childCompilation, child.errors);
  });
  if (errors.main.length) {
    errors.main.forEach((error) => {
      console.log('Error => ', error);
    });
    console.dir(stats.toJson({ errorDetails: true, moduleTrace: true }), { depth: 5 });
  }
  expect(errors.main).toEqual([]);
  expect(errors.childCompilation).toEqual([]);
}

describe('HtmlWebpackPluginCaching', () => {
  beforeEach(done => {
    rimraf(OUTPUT_DIR, done);
  });

  it('should compile nothing if no file was changed', done => {
    const template = path.join(__dirname, 'fixtures/plain.html');
    const htmlWebpackPlugin = new HtmlWebpackPlugin({
      template: template
    });
    let childCompilerHash;
    const compiler = setUpCompiler(htmlWebpackPlugin);
    compiler.addTestFile(path.join(__dirname, 'fixtures/index.js'));
    compiler.run()
      // Change the template file and compile again
      .then(() => {
        childCompilerHash = htmlWebpackPlugin.childCompilerHash;
        return compiler.run();
      })
      .then(stats => {
        // Expect no errors:
        expectNoErrors(stats);
        // Verify that no file was built
        expect(getCompiledModules(stats.toJson()))
          .toEqual([]);
        // Verify that the html was processed only during the inital build
        expect(htmlWebpackPlugin.evaluateCompilationResult.mock.calls.length)
          .toBe(1);
        // Verify that the child compilation was executed twice
        expect(htmlWebpackPlugin.childCompilerHash)
          .toBe(childCompilerHash);
      })
      .then(done);
  });

  it('should not compile the webpack html file if only a javascript file was changed', done => {
    const htmlWebpackPlugin = new HtmlWebpackPlugin();
    const compiler = setUpCompiler(htmlWebpackPlugin);
    let childCompilerHash;
    compiler.addTestFile(path.join(__dirname, 'fixtures/index.js'));
    compiler.run()
      // Change a js file and compile again
      .then(() => {
        childCompilerHash = htmlWebpackPlugin.childCompilerHash;
        compiler.simulateFileChange(path.join(__dirname, 'fixtures/index.js'), { footer: '//1' });
        return compiler.run();
      })
      .then(stats => {
        // Expect no errors:
        expectNoErrors(stats);
        // Verify that only one file was built
        expect(getCompiledModuleCount(stats.toJson()))
          .toBe(1);
        // Verify that the html was processed only during the inital build
        expect(htmlWebpackPlugin.evaluateCompilationResult.mock.calls.length)
          .toBe(1);
        // Verify that the child compilation was executed only once
        expect(htmlWebpackPlugin.childCompilerHash)
          .toBe(childCompilerHash);
      })
      .then(done);
  });

  it('should compile the webpack html file even if only a javascript file was changed if caching is disabled', done => {
    const htmlWebpackPlugin = new HtmlWebpackPlugin({
      cache: false
    });
    let childCompilerHash;
    const compiler = setUpCompiler(htmlWebpackPlugin);
    compiler.addTestFile(path.join(__dirname, 'fixtures/index.js'));
    compiler.run()
      // Change a js file and compile again
      .then(() => {
        childCompilerHash = htmlWebpackPlugin.childCompilerHash;
        compiler.simulateFileChange(path.join(__dirname, 'fixtures/index.js'), { footer: '//1' });
        return compiler.run();
      })
      .then(stats => {
        // Expect no errors:
        expectNoErrors(stats);
        // Verify that only one file was built
        expect(getCompiledModuleCount(stats.toJson()))
          .toBe(1);
        // Verify that the html was processed on every run
        expect(htmlWebpackPlugin.evaluateCompilationResult.mock.calls.length)
          .toBe(2);
        // Verify that the child compilation was executed only once
        expect(htmlWebpackPlugin.childCompilerHash)
          .toBe(childCompilerHash);
      })
      .then(done);
  });

  it('should compile the webpack html if the template file was changed', done => {
    const template = path.join(__dirname, 'fixtures/plain.html');
    const htmlWebpackPlugin = new HtmlWebpackPlugin({
      template: template
    });
    let childCompilerHash;
    const compiler = setUpCompiler(htmlWebpackPlugin);
    compiler.addTestFile(template);
    compiler.run()
      // Change the template file and compile again
      .then(() => {
        childCompilerHash = htmlWebpackPlugin.childCompilerHash;
        compiler.simulateFileChange(template, { footer: '<!-- 1 -->' });
        return compiler.run();
      })
      .then(stats => {
        // Expect no errors:
        expectNoErrors(stats);
        // Verify that only one file was built
        expect(getCompiledModuleCount(stats.toJson()))
          .toBe(1);
        // Verify that the html was processed twice
        expect(htmlWebpackPlugin.evaluateCompilationResult.mock.calls.length)
          .toBe(2);
        // Verify that the child compilation was executed twice
        expect(htmlWebpackPlugin.childCompilerHash)
          .not.toBe(childCompilerHash);
      })
      .then(done);
  });

  it('should not slow down linear (10 plugins should not take twice as much time as a 1 plugin)', done => {
    const template = path.join(__dirname, 'fixtures/plain.html');
    const createHtmlWebpackPlugin = () => new HtmlWebpackPlugin({
      template: template
    });
    let singlePluginCompileStart;
    let singleCompileRunDuration;
    let multiPluginComileStart;
    let multiCompileRunDuration;

    let singleCompiler = setUpCompiler(createHtmlWebpackPlugin());
    let multiCompiler = setUpCompiler.apply(null, Array(10).fill(0).map(() => createHtmlWebpackPlugin()));

    Promise.resolve()
      .then(function singleCompileRun () {
        singlePluginCompileStart = process.hrtime();
        return singleCompiler.run()
          // Change the template file and compile again
          .then(() => {
            singleCompileRunDuration = process.hrtime(singlePluginCompileStart);
          });
      })
      .then(function multiCompileRun () {
        multiPluginComileStart = process.hrtime();
        return multiCompiler.run()
          // Change the template file and compile again
          .then(() => {
            multiCompileRunDuration = process.hrtime(multiPluginComileStart);
          });
      }).then(function meassureTime () {
        const singleCompileRunDurationInNs = singleCompileRunDuration[0] * 1e9 + singleCompileRunDuration[1];
        const multiCompileRunDurationInNs = multiCompileRunDuration[0] * 1e9 + multiCompileRunDuration[1];
        const speedComarision = multiCompileRunDurationInNs / singleCompileRunDurationInNs * 100;

        expect(speedComarision).toBeLessThan(200);
        done();
      });
  });

  it('should keep watching the webpack html if only a js file was changed', done => {
    const template = path.join(__dirname, 'fixtures/plain.html');
    const jsFile = path.join(__dirname, 'fixtures/index.js');
    const htmlWebpackPlugin = new HtmlWebpackPlugin({
      template: template
    });
    const compiler = setUpCompiler(htmlWebpackPlugin);
    compiler.addTestFile(template);
    compiler.addTestFile(jsFile);
    // Build the template file for the first time
    compiler.startWatching()
      // Change the template file (second build)
      .then(() => {
        compiler.simulateFileChange(template, { footer: '<!-- 1 -->' });
        return compiler.waitForWatchRunComplete();
      })
      // Change js
      .then(() => {
        compiler.simulateFileChange(jsFile, { footer: '// 1' });
        return compiler.waitForWatchRunComplete();
      })
      // Change js
      .then(() => {
        compiler.simulateFileChange(jsFile, { footer: '// 2' });
        return compiler.waitForWatchRunComplete();
      })
      // Change js
      .then(() => {
        compiler.simulateFileChange(jsFile, { footer: '// 3' });
        return compiler.waitForWatchRunComplete();
      })
      // Change the template file (third build)
      .then(() => {
        compiler.simulateFileChange(template, { footer: '<!-- 2 -->' });
        return compiler.waitForWatchRunComplete();
      })
      .then(() => {
        // Verify that the html was processed trice
        expect(htmlWebpackPlugin.evaluateCompilationResult.mock.calls.length)
          .toBe(3);
      })
      .then(() => compiler.stopWatching())
      .then(done);
  });
});
<|endoftext|>


<commit_before>openerp.account = function(instance) {
var _t = instance.web._t,
   _lt = instance.web._lt;
instance.web.views.add('form_clone', 'instance.account.extend_form_view');

instance.account.extend_viewmanager = instance.web.ViewManagerAction.include({
    start : function(){
        this._super()
        if(this.action.context && this.action.context.extended_view_id && this.action.context.extended_model)
            this.setup_exended_form_view(this.action.context.extended_model, this.action.context.extended_view_id);
    },
    setup_exended_form_view: function(view_model, view_id){
        var self = this;
        from_view = this.registry.get_object('form_clone');
        this.dataset_form = new instance.web.DataSetSearch(this, view_model, this.action.context, this.action.domain);
        this.dataset_loaded  = this.dataset_form.read_slice();
        obj_from_view = new from_view(self, self.dataset_form, view_id, options={});
        obj_from_view.template = 'ExtendedFormView';
        view_form = obj_from_view.appendTo(self.$el.find('.oe_extended_form_view'));
        $.when(view_form, this.dataset_loaded).then(function() {
                obj_from_view.post_action();
        });
    }

})
instance.account.extend_form_view = instance.web.FormView.extend({
    on_loaded: function(data) {
         this._super.apply(this,arguments);
         var self = this
         this.$el.find(".oe_reconcile").on('click', this.do_reconcilation)
         this.$el.find(".oe_nothing_to_reconcile").on('click', this.do_nothing_to_reconcile)
         this.$el.on('click','a[data-pager-action]',function() {
            var action = $(this).data('pager-action');
            self.on_pager_action(action);
        });
    },
    do_reconcilation:function(event){
        var self = this
        var list_view = this.getParent().views['list'].controller
        ids = list_view.get_selected_ids()
        if (ids.length == 0) {
            instance.web.dialog($("<div />").text(_t("You must choose at least one record.")), { title: _t("Warning"), modal: true });
            return false;
        }
        var additional_context = _.extend({
            active_id: ids[0],
            active_ids: ids,
            active_model: list_view.dataset.model
        });
        self.rpc("/web/action/load", {
            action_id: py.eval(event.target.name),
            context: additional_context
            }, function(result) {
                result.result.context = _.extend(result.result.context || {},
                    additional_context);
                result.result.flags = result.result.flags || {};
                result.result.flags.new_window = true;
                self.do_action(result.result, function () {
                    self.post_action();
            });
        });
    },

    post_action: function(){
        // hide if not records otherwise go next record
        var self = this;
        var viewmanager = this.getParent();
        this.dataset.read_slice().done(function(){
            if (_.isEmpty(self.dataset.ids)){
                viewmanager.action.context.next_partner_only = true;
                /*self.$el.hide();
                viewmanager.action.context.next_partner_only = false;
                viewmanager.searchview.do_search();*/
            }
            else{
                self.on_pager_action('first');
            }
        });
    },

    do_nothing_to_reconcile:function(){
        var self = this;
        this.dataset.call(event.target.name, [[self.datarecord.id], self.dataset.context]).then(function() {
            self.post_action();
        });
    },

    do_update_pager: function(hide_index) {
        var index = this.dataset.index + 1
        if (this.dataset.ids.length == 0)
            index = 0;
        index = hide_index ? '-' : index;
        this.$el.find('span.oe_pager_index_extend').html(index).end()
                   .find('span.oe_pager_count_extend').html(this.dataset.ids.length);
    },

    on_pager_action: function(action) {
        var self = this
        var viewmanager = self.getParent();
        $.when(this._super(action)).then(function() {
            var id = self.get_fields_values().partner_id;
            viewmanager.action.context.next_partner_only = true;
            viewmanager.action.context.partner_id = [id];
            viewmanager.searchview.do_search();
        })
    },
  })

}
<commit_msg>[FIX] account: rector js of account reconcilation<commit_after>openerp.account = function(instance) {
var _t = instance.web._t,
   _lt = instance.web._lt;
instance.web.views.add('form_clone', 'instance.account.extend_form_view');

instance.account.extend_viewmanager = instance.web.ViewManagerAction.include({
    start : function(){
        this._super()
        if(this.action.context && this.action.context.extended_view_id && this.action.context.extended_model)
            this.setup_exended_form_view(this.action.context.extended_model, this.action.context.extended_view_id);
    },
    setup_exended_form_view: function(view_model, view_id){
        var self = this;
        from_view = this.registry.get_object('form_clone');
        this.dataset_form = new instance.web.DataSetSearch(this, view_model, this.action.context, this.action.domain);
        this.dataset_loaded  = this.dataset_form.read_slice();
        obj_from_view = new from_view(self, self.dataset_form, view_id, options={});
        obj_from_view.template = 'ExtendedFormView';
        view_form = obj_from_view.appendTo(self.$el.find('.oe_extended_form_view'));
        $.when(view_form, this.dataset_loaded).then(function() {
                obj_from_view.on_pager_action('first');
        });
    }

})
instance.account.extend_form_view = instance.web.FormView.extend({
    on_loaded: function(data) {
         this._super.apply(this,arguments);
         var self = this
         this.$el.find(".oe_reconcile").on('click', this.do_reconcilation)
         this.$el.find(".oe_nothing_to_reconcile").on('click', this.do_nothing_to_reconcile)
         this.$el.on('click','a[data-pager-action]',function() {
            var action = $(this).data('pager-action');
            self.on_pager_action(action);
        });
    },
    do_reconcilation:function(event){
        var self = this
        var list_view = this.getParent().views['list'].controller
        ids = list_view.get_selected_ids()
        if (ids.length == 0) {
            instance.web.dialog($("<div />").text(_t("You must choose at least one record.")), { title: _t("Warning"), modal: true });
            return false;
        }
        var additional_context = _.extend({
            active_id: ids[0],
            active_ids: ids,
            active_model: list_view.dataset.model
        });
        self.rpc("/web/action/load", {
            action_id: py.eval(event.target.name),
            context: additional_context
            }, function(result) {
                result.result.context = _.extend(result.result.context || {},
                    additional_context);
                result.result.flags = result.result.flags || {};
                result.result.flags.new_window = true;
                self.do_action(result.result, function () {
                    self.dataset.read_slice().done(function(){
                        self.on_pager_action('next');
                    });
            });
        });
    },

    do_nothing_to_reconcile:function(){
        var self = this;
        this.dataset.call(event.target.name, [[self.datarecord.id], self.dataset.context]).then(function() {
            self.dataset.read_slice().done(function(){
                self.on_pager_action('next');
            });
        });
    },

    do_update_pager: function(hide_index) {
        var index = this.dataset.index + 1
        if (this.dataset.ids.length == 0)
            index = 0;
        index = hide_index ? '-' : index;
        this.$el.find('span.oe_pager_index_extend').html(index).end()
                   .find('span.oe_pager_count_extend').html(this.dataset.ids.length);
    },

    on_pager_action: function(action) {
        var self = this
        var viewmanager = self.getParent();
        viewmanager.action.context.next_partner_only = true;
        //TODO: if no records, than it's not working, it giving error
        if (this.dataset.ids.length == 0){
            self.dataset.index = null;
            viewmanager.action.context.partner_id = [];
            viewmanager.searchview.do_search();
            self.reload();
            return
        }

        $.when(this._super(action)).then(function() {
            var id = self.get_fields_values().partner_id;
            viewmanager.action.context.partner_id = [id];
            viewmanager.searchview.do_search();
        });
    },
  })

}
<|endoftext|>