<commit_before>/* jshint node: true */
/* global it: true, describe: true, afterEach, beforeEach */

'use strict';

var fs = require('fs');
var path = require('path');
var expect = require('expect.js');
var RSVP = require('rsvp');
var rimraf = require('rimraf');
var root = process.cwd();
var broccoli = require('broccoli');
var CachingWriter = require('..');

var builder;

describe('broccoli-caching-writer', function(){
  var sourcePath = 'tests/fixtures/sample-project';
  var secondaryPath = 'tests/fixtures/other-tree';

  var existingJSFile = sourcePath + '/core.js';
  var dummyChangedFile = sourcePath + '/dummy-changed-file.txt';
  var dummyJSChangedFile = sourcePath + '/dummy-changed-file.js';

  afterEach(function() {
    if (fs.existsSync(dummyChangedFile)) {
      fs.unlinkSync(dummyChangedFile);
    }

    if (fs.existsSync(dummyJSChangedFile)) {
      fs.unlinkSync(dummyJSChangedFile);
    }

    if (builder) {
      return builder.cleanup();
    }
  });

  function build() {
    return builder.build();
  }

  function buildInSeries(count) {
    var promise = RSVP.Promise.resolve();

    for (var i = 0; i < count; i++) {
      promise = promise.then(build);
    }

    return promise;
  }

  describe('enforceSingleInputTree', function() {
    it('defaults `enforceSingleInputTree` to false', function() {
      var tree = new CachingWriter(sourcePath, {
        updateCache: function() { }
      });

      expect(tree.enforceSingleInputTree).to.not.be.ok();
    });

    it('throws an error if enforceSingleInputTree is true, and an array is passed', function() {
      expect(function() {
        var tree = new CachingWriter([sourcePath, secondaryPath], {
          enforceSingleInputTree: true,
          updateCache: function() { }
        });
      }).throwException(/You passed an array of input trees, but only a single tree is allowed./);
    });
  });

  describe('write', function() {
    it('calls updateCache when there is no cache', function(){
      var updateCacheCalled = false;
      var tree = new CachingWriter(sourcePath, {
        updateCache: function() {
          updateCacheCalled = true;
        }
      });

      builder = new broccoli.Builder(tree);

      return builder.build().finally(function() {
        expect(updateCacheCalled).to.be.ok();
      });
    });

    it('calls updateCache with a single path if enforceSingleInputTree is true', function(){
      var updateCacheCalled = false;
      var tree = new CachingWriter(sourcePath, {
        enforceSingleInputTree: true,
        updateCache: function(srcDir, destDir) {
          expect(fs.statSync(srcDir).isDirectory()).to.be.ok();
          expect(fs.statSync(destDir).isDirectory()).to.be.ok();
        }
      });

      builder = new broccoli.Builder(tree);
      return builder.build();
    });

    it('is provided a source and destination directory', function(){
      var updateCacheCalled = false;
      var tree = new CachingWriter(sourcePath, {
        updateCache: function(srcDir, destDir) {
          expect(fs.statSync(srcDir[0]).isDirectory()).to.be.ok();
          expect(fs.statSync(destDir).isDirectory()).to.be.ok();
        }
      });

      builder = new broccoli.Builder(tree);
      return builder.build();
    });

    it('only calls updateCache once if input is not changing', function(){
      var updateCacheCount = 0;
      var tree = new CachingWriter(sourcePath, {
        updateCache: function() {
          updateCacheCount++;
        }
      });

      builder = new broccoli.Builder(tree);

      return buildInSeries(3)
        .then(function() {
          expect(updateCacheCount).to.equal(1);
        });
    });

    it('calls updateCache again if input is changed', function(){
      var updateCacheCount = 0;

      var tree = new CachingWriter([sourcePath, secondaryPath], {
        updateCache: function() {
          updateCacheCount++;
        }
      });

      builder = new broccoli.Builder(tree);

      return builder.build()
        .finally(function() {
          expect(updateCacheCount).to.equal(1);
        })
        .then(function() {
          fs.writeFileSync(dummyChangedFile, 'bergh');

          return buildInSeries(3);
        })
        .finally(function() {
          expect(updateCacheCount).to.equal(2);
        })
        .then(function() {
          fs.writeFileSync(secondaryPath + '/foo-baz.js', 'bergh');

          return buildInSeries(3);
        })
        .finally(function() {
          expect(updateCacheCount).to.equal(3);
        });
    });

    it('calls updateCache again if existing file is changed', function(){
      var updateCacheCount = 0;
      var tree = new CachingWriter(sourcePath, {
        updateCache: function() {
          updateCacheCount++;
        }
      });

      builder = new broccoli.Builder(tree);

      return builder.build()
        .finally(function() {
          expect(updateCacheCount).to.equal(1);
        })
        .then(function() {
          fs.writeFileSync(existingJSFile, '"YIPPIE"\n"KI-YAY!"\n');

          return buildInSeries(3);
        })
        .finally(function() {
          fs.writeFileSync(existingJSFile, '"YIPPIE"\n');
          expect(updateCacheCount).to.equal(2);
        });
    });

    it('does not call updateCache again if input is changed but filtered from cache (via exclude)', function(){
      var updateCacheCount = 0;
      var tree = new CachingWriter(sourcePath, {
        updateCache: function() {
          updateCacheCount++;
        },
        filterFromCache: {
          exclude: [/.*\.txt$/]
        }
      });

      builder = new broccoli.Builder(tree);

      return builder.build()
        .finally(function() {
          expect(updateCacheCount).to.equal(1);
        })
        .then(function() {
          fs.writeFileSync(dummyChangedFile, 'bergh');

          return buildInSeries(3);
        })
        .finally(function() {
          expect(updateCacheCount).to.equal(1);
        });
    });

    it('does not call updateCache again if input is changed but filtered from cache (via include)', function(){
      var updateCacheCount = 0;
      var tree = new CachingWriter(sourcePath, {
        updateCache: function() {
          updateCacheCount++;
        },
        filterFromCache: {
          include: [/.*\.js$/]
        }
      });

      builder = new broccoli.Builder(tree);

      return builder.build()
        .finally(function() {
          expect(updateCacheCount).to.equal(1);
        })
        .then(function() {
          fs.writeFileSync(dummyChangedFile, 'bergh');

          return buildInSeries(3);
        })
        .finally(function() {
          expect(updateCacheCount).to.equal(1);
        });
    });

    it('does call updateCache again if input is changed is included in the cache filter', function(){
      var updateCacheCount = 0;
      var tree = new CachingWriter(sourcePath, {
        updateCache: function() {
          updateCacheCount++;
        },
        filterFromCache: {
          include: [/.*\.js$/]
        }
      });

      builder = new broccoli.Builder(tree);

      return builder.build()
        .finally(function() {
          expect(updateCacheCount).to.equal(1);
        })
        .then(function() {
          fs.writeFileSync(dummyJSChangedFile, 'bergh');

          return buildInSeries(3);
        })
        .finally(function() {
          expect(updateCacheCount).to.equal(2);
        });
    });
  });

  describe('updateCache', function() {
    it('provides array of paths if array of sourceTrees was provided', function() {
      var tree = new CachingWriter([sourcePath, secondaryPath], {
        updateCache: function(srcDirs, destDir) {
          expect(fs.readFileSync(srcDirs[0] + '/core.js', {encoding: 'utf8'})).to.eql('"YIPPIE"\n');
          expect(fs.readFileSync(srcDirs[1] + '/bar.js', {encoding: 'utf8'})).to.eql('"BLAMMO!"\n');

          fs.writeFileSync(destDir + '/something-cool.js', 'zomg blammo', {encoding: 'utf8'});
        }
      });

      builder = new broccoli.Builder(tree);
      return builder.build().then(function(result) {
        var dir = result.directory;

        expect(fs.readFileSync(dir + '/something-cool.js', {encoding: 'utf8'})).to.equal('zomg blammo');
      });
    });

    it('can write files to destDir, and they will be in the final output', function(){
      var tree = new CachingWriter(sourcePath, {
        updateCache: function(srcDir, destDir) {
          fs.writeFileSync(destDir + '/something-cool.js', 'zomg blammo', {encoding: 'utf8'});
        }
      });

      builder = new broccoli.Builder(tree);
      return builder.build().then(function(result) {
        var dir = result.directory;
        expect(fs.readFileSync(dir + '/something-cool.js', {encoding: 'utf8'})).to.equal('zomg blammo');
      });
    });

    it('throws an error if not overriden', function(){
      var tree = new CachingWriter(sourcePath);

      builder = new broccoli.Builder(tree);
      return builder.build()
        .catch(function(reason) {
          expect(reason.message).to.equal('You must implement updateCache.');
        });
    });

    it('can return a promise that is resolved', function(){
      var thenCalled = false;
      var tree = new CachingWriter(sourcePath, {
        updateCache: function(srcDir, destDir) {
          return {then: function(callback) {
            thenCalled = true;
            callback();
          }};
        }
      });

      builder = new broccoli.Builder(tree);
      return builder.build().then(function() {
        expect(thenCalled).to.be.ok();
      });
    });
  });

  describe('arguments', function() {
    it('throws exception when no input tree is provided', function() {
      expect(function() {
        new CachingWriter();
      }).to.throwException(/no inputTree was provided/);
    });
  });

  describe('shouldBeIgnored', function() {
    var tree;

    beforeEach(function() {
      tree = new CachingWriter(sourcePath);
    });

    it('returns true if the path is included in an exclude filter', function() {
      tree.filterFromCache.exclude = [ /.foo$/, /.bar$/ ];

      expect(tree.shouldBeIgnored('blah/blah/blah.foo')).to.be.ok();
      expect(tree.shouldBeIgnored('blah/blah/blah.bar')).to.be.ok();
      expect(tree.shouldBeIgnored('blah/blah/blah.baz')).to.not.be.ok();
    });

    it('returns false if the path is included in an include filter', function() {
      tree.filterFromCache.include = [ /.foo$/, /.bar$/ ];

      expect(tree.shouldBeIgnored('blah/blah/blah.foo')).to.not.be.ok();
      expect(tree.shouldBeIgnored('blah/blah/blah.bar')).to.not.be.ok();
    });

    it('returns true if the path is not included in an include filter', function() {
      tree.filterFromCache.include = [ /.foo$/, /.bar$/ ];

      expect(tree.shouldBeIgnored('blah/blah/blah.baz')).to.be.ok();
    });

    it('returns false if no patterns were used', function() {
      expect(tree.shouldBeIgnored('blah/blah/blah.baz')).to.not.be.ok();
    });

    it('uses a cache to ensure we do not recalculate the filtering on subsequent attempts', function() {
      expect(tree.shouldBeIgnored('blah/blah/blah.baz')).to.not.be.ok();

      // changing the filter mid-run should have no result on
      // previously calculated paths
      tree.filterFromCache.include = [ /.foo$/, /.bar$/ ];

      expect(tree.shouldBeIgnored('blah/blah/blah.baz')).to.not.be.ok();
    });
  });

  describe('extend', function() {
    it('sets the methods correctly', function() {
      var TestPlugin = CachingWriter.extend({
        foo: function() {}
      });

      expect(TestPlugin).to.be.a(Function);
      expect(TestPlugin.prototype.foo).to.be.a(Function);
    });

    it('calls CachingWriter constructor', function () {
      var MyPlugin = CachingWriter.extend({});
      var instance = new MyPlugin("foo");
      expect(instance.inputTrees).to.eql(["foo"]);
    });

    it('can write files to destDir, and they will be in the final output', function(){
      var TestWriter = CachingWriter.extend({
        updateCache: function(srcDir, destDir) {
          fs.writeFileSync(destDir + '/something-cooler.js', 'whoa', {encoding: 'utf8'});
        }
      });
      var tree = new TestWriter(sourcePath);

      builder = new broccoli.Builder(tree);
      return builder.build().then(function(result) {
        var dir = result.directory;
        expect(fs.readFileSync(dir + '/something-cooler.js', {encoding: 'utf8'})).to.equal('whoa');
      });
    });
  });

  describe('listFiles', function() {
    var tree, listFiles;

    beforeEach(function() {
      tree = new CachingWriter(sourcePath);
      tree.updateCache = function(srcDir, destDir){
        listFiles = this.listFiles();
      }
    });

    it('returns an array of files keyed', function() {
      builder = new broccoli.Builder(tree);
      return builder.build().then(function() {
        expect(listFiles).to.eql(['tests/fixtures/sample-project/core.js',
                                  'tests/fixtures/sample-project/main.js']);
        expect(listFiles.length).to.equal(2)
      });
    });

    it('returns an array of files keyed ignoring those in the exclude filter', function() {
      tree.filterFromCache.exclude = [ /main\.js$/ ]
      builder = new broccoli.Builder(tree);
      return builder.build().then(function() {
        expect(listFiles).to.eql(['tests/fixtures/sample-project/core.js']);
        expect(listFiles.length).to.equal(1)
      });
    });
  })
});
<commit_msg>improving test coverage<commit_after>/* jshint node: true */
/* global it: true, describe: true, afterEach, beforeEach */

'use strict';

var fs = require('fs');
var path = require('path');
var expect = require('expect.js');
var RSVP = require('rsvp');
var rimraf = require('rimraf');
var root = process.cwd();
var broccoli = require('broccoli');
var CachingWriter = require('..');

var builder;

describe('broccoli-caching-writer', function(){
  var sourcePath = 'tests/fixtures/sample-project';
  var secondaryPath = 'tests/fixtures/other-tree';

  var existingJSFile = sourcePath + '/core.js';
  var dummyChangedFile = sourcePath + '/dummy-changed-file.txt';
  var dummyJSChangedFile = sourcePath + '/dummy-changed-file.js';

  afterEach(function() {
    if (fs.existsSync(dummyChangedFile)) {
      fs.unlinkSync(dummyChangedFile);
    }

    if (fs.existsSync(dummyJSChangedFile)) {
      fs.unlinkSync(dummyJSChangedFile);
    }

    if (builder) {
      return builder.cleanup();
    }
  });

  function build() {
    return builder.build();
  }

  function buildInSeries(count) {
    var promise = RSVP.Promise.resolve();

    for (var i = 0; i < count; i++) {
      promise = promise.then(build);
    }

    return promise;
  }

  describe('enforceSingleInputTree', function() {
    it('defaults `enforceSingleInputTree` to false', function() {
      var tree = new CachingWriter(sourcePath, {
        updateCache: function() { }
      });

      expect(tree.enforceSingleInputTree).to.not.be.ok();
    });

    it('throws an error if enforceSingleInputTree is true, and an array is passed', function() {
      expect(function() {
        var tree = new CachingWriter([sourcePath, secondaryPath], {
          enforceSingleInputTree: true,
          updateCache: function() { }
        });
      }).throwException(/You passed an array of input trees, but only a single tree is allowed./);
    });
  });

  describe('write', function() {
    it('calls updateCache when there is no cache', function(){
      var updateCacheCalled = false;
      var tree = new CachingWriter(sourcePath, {
        updateCache: function() {
          updateCacheCalled = true;
        }
      });

      builder = new broccoli.Builder(tree);

      return builder.build().finally(function() {
        expect(updateCacheCalled).to.be.ok();
      });
    });

    it('calls updateCache with a single path if enforceSingleInputTree is true', function(){
      var updateCacheCalled = false;
      var tree = new CachingWriter(sourcePath, {
        enforceSingleInputTree: true,
        updateCache: function(srcDir, destDir) {
          expect(fs.statSync(srcDir).isDirectory()).to.be.ok();
          expect(fs.statSync(destDir).isDirectory()).to.be.ok();
        }
      });

      builder = new broccoli.Builder(tree);
      return builder.build();
    });

    it('is provided a source and destination directory', function(){
      var updateCacheCalled = false;
      var tree = new CachingWriter(sourcePath, {
        updateCache: function(srcDir, destDir) {
          expect(fs.statSync(srcDir[0]).isDirectory()).to.be.ok();
          expect(fs.statSync(destDir).isDirectory()).to.be.ok();
        }
      });

      builder = new broccoli.Builder(tree);
      return builder.build();
    });

    it('only calls updateCache once if input is not changing', function(){
      var updateCacheCount = 0;
      var tree = new CachingWriter(sourcePath, {
        updateCache: function() {
          updateCacheCount++;
        }
      });

      builder = new broccoli.Builder(tree);

      return buildInSeries(3)
        .then(function() {
          expect(updateCacheCount).to.equal(1);
        });
    });

    it('calls updateCache again if input is changed', function(){
      var updateCacheCount = 0;

      var tree = new CachingWriter([sourcePath, secondaryPath], {
        updateCache: function() {
          updateCacheCount++;
        }
      });

      builder = new broccoli.Builder(tree);

      return builder.build()
        .finally(function() {
          expect(updateCacheCount).to.equal(1);
        })
        .then(function() {
          fs.writeFileSync(dummyChangedFile, 'bergh');

          return buildInSeries(3);
        })
        .finally(function() {
          expect(updateCacheCount).to.equal(2);
        })
        .then(function() {
          fs.writeFileSync(secondaryPath + '/foo-baz.js', 'bergh');

          return buildInSeries(3);
        })
        .finally(function() {
          expect(updateCacheCount).to.equal(3);
        });
    });

    it('calls updateCache again if existing file is changed', function(){
      var updateCacheCount = 0;
      var tree = new CachingWriter(sourcePath, {
        updateCache: function() {
          updateCacheCount++;
        }
      });

      builder = new broccoli.Builder(tree);

      return builder.build()
        .finally(function() {
          expect(updateCacheCount).to.equal(1);
        })
        .then(function() {
          fs.writeFileSync(existingJSFile, '"YIPPIE"\n"KI-YAY!"\n');

          return buildInSeries(3);
        })
        .finally(function() {
          fs.writeFileSync(existingJSFile, '"YIPPIE"\n');
          expect(updateCacheCount).to.equal(2);
        });
    });

    it('does not call updateCache again if input is changed but filtered from cache (via exclude)', function(){
      var updateCacheCount = 0;
      var tree = new CachingWriter(sourcePath, {
        updateCache: function() {
          updateCacheCount++;
        },
        filterFromCache: {
          exclude: [/.*\.txt$/]
        }
      });

      builder = new broccoli.Builder(tree);

      return builder.build()
        .finally(function() {
          expect(updateCacheCount).to.equal(1);
        })
        .then(function() {
          fs.writeFileSync(dummyChangedFile, 'bergh');

          return buildInSeries(3);
        })
        .finally(function() {
          expect(updateCacheCount).to.equal(1);
        });
    });

    it('does not call updateCache again if input is changed but filtered from cache (via include)', function(){
      var updateCacheCount = 0;
      var tree = new CachingWriter(sourcePath, {
        updateCache: function() {
          updateCacheCount++;
        },
        filterFromCache: {
          include: [/.*\.js$/]
        }
      });

      builder = new broccoli.Builder(tree);

      return builder.build()
        .finally(function() {
          expect(updateCacheCount).to.equal(1);
        })
        .then(function() {
          fs.writeFileSync(dummyChangedFile, 'bergh');

          return buildInSeries(3);
        })
        .finally(function() {
          expect(updateCacheCount).to.equal(1);
        });
    });

    it('does call updateCache again if input is changed is included in the cache filter', function(){
      var updateCacheCount = 0;
      var tree = new CachingWriter(sourcePath, {
        updateCache: function() {
          updateCacheCount++;
        },
        filterFromCache: {
          include: [/.*\.js$/]
        }
      });

      builder = new broccoli.Builder(tree);

      return builder.build()
        .finally(function() {
          expect(updateCacheCount).to.equal(1);
        })
        .then(function() {
          fs.writeFileSync(dummyJSChangedFile, 'bergh');

          return buildInSeries(3);
        })
        .finally(function() {
          expect(updateCacheCount).to.equal(2);
        });
    });
  });

  describe('updateCache', function() {
    it('provides array of paths if array of sourceTrees was provided', function() {
      var tree = new CachingWriter([sourcePath, secondaryPath], {
        updateCache: function(srcDirs, destDir) {
          expect(fs.readFileSync(srcDirs[0] + '/core.js', {encoding: 'utf8'})).to.eql('"YIPPIE"\n');
          expect(fs.readFileSync(srcDirs[1] + '/bar.js', {encoding: 'utf8'})).to.eql('"BLAMMO!"\n');

          fs.writeFileSync(destDir + '/something-cool.js', 'zomg blammo', {encoding: 'utf8'});
        }
      });

      builder = new broccoli.Builder(tree);
      return builder.build().then(function(result) {
        var dir = result.directory;

        expect(fs.readFileSync(dir + '/something-cool.js', {encoding: 'utf8'})).to.equal('zomg blammo');
      });
    });

    it('can write files to destDir, and they will be in the final output', function(){
      var tree = new CachingWriter(sourcePath, {
        updateCache: function(srcDir, destDir) {
          fs.writeFileSync(destDir + '/something-cool.js', 'zomg blammo', {encoding: 'utf8'});
        }
      });

      builder = new broccoli.Builder(tree);
      return builder.build().then(function(result) {
        var dir = result.directory;
        expect(fs.readFileSync(dir + '/something-cool.js', {encoding: 'utf8'})).to.equal('zomg blammo');
      });
    });

    it('throws an error if not overriden', function(){
      var tree = new CachingWriter(sourcePath);

      builder = new broccoli.Builder(tree);
      return builder.build()
        .catch(function(reason) {
          expect(reason.message).to.equal('You must implement updateCache.');
        });
    });

    it('can return a promise that is resolved', function(){
      var thenCalled = false;
      var tree = new CachingWriter(sourcePath, {
        updateCache: function(srcDir, destDir) {
          return {then: function(callback) {
            thenCalled = true;
            callback();
          }};
        }
      });

      builder = new broccoli.Builder(tree);
      return builder.build().then(function() {
        expect(thenCalled).to.be.ok();
      });
    });
  });

  describe('arguments', function() {
    it('throws exception when no input tree is provided', function() {
      expect(function() {
        new CachingWriter();
      }).to.throwException(/no inputTree was provided/);
    });
  });

  describe('shouldBeIgnored', function() {
    var tree;

    beforeEach(function() {
      tree = new CachingWriter(sourcePath);
    });

    it('returns true if the path is included in an exclude filter', function() {
      tree.filterFromCache.exclude = [ /.foo$/, /.bar$/ ];

      expect(tree.shouldBeIgnored('blah/blah/blah.foo')).to.be.ok();
      expect(tree.shouldBeIgnored('blah/blah/blah.bar')).to.be.ok();
      expect(tree.shouldBeIgnored('blah/blah/blah.baz')).to.not.be.ok();
    });

    it('returns false if the path is included in an include filter', function() {
      tree.filterFromCache.include = [ /.foo$/, /.bar$/ ];

      expect(tree.shouldBeIgnored('blah/blah/blah.foo')).to.not.be.ok();
      expect(tree.shouldBeIgnored('blah/blah/blah.bar')).to.not.be.ok();
    });

    it('returns true if the path is not included in an include filter', function() {
      tree.filterFromCache.include = [ /.foo$/, /.bar$/ ];

      expect(tree.shouldBeIgnored('blah/blah/blah.baz')).to.be.ok();
    });

    it('returns false if no patterns were used', function() {
      expect(tree.shouldBeIgnored('blah/blah/blah.baz')).to.not.be.ok();
    });

    it('uses a cache to ensure we do not recalculate the filtering on subsequent attempts', function() {
      expect(tree.shouldBeIgnored('blah/blah/blah.baz')).to.not.be.ok();

      // changing the filter mid-run should have no result on
      // previously calculated paths
      tree.filterFromCache.include = [ /.foo$/, /.bar$/ ];

      expect(tree.shouldBeIgnored('blah/blah/blah.baz')).to.not.be.ok();
    });
  });

  describe('extend', function() {
    it('sets the methods correctly', function() {
      var TestPlugin = CachingWriter.extend({
        foo: function() {}
      });

      expect(TestPlugin).to.be.a(Function);
      expect(TestPlugin.prototype.foo).to.be.a(Function);
    });

    it('calls CachingWriter constructor', function () {
      var MyPlugin = CachingWriter.extend({});
      var instance = new MyPlugin("foo");
      expect(instance.inputTrees).to.eql(["foo"]);
    });

    it('can write files to destDir, and they will be in the final output', function(){
      var TestWriter = CachingWriter.extend({
        updateCache: function(srcDir, destDir) {
          fs.writeFileSync(destDir + '/something-cooler.js', 'whoa', {encoding: 'utf8'});
        }
      });
      var tree = new TestWriter(sourcePath);

      builder = new broccoli.Builder(tree);
      return builder.build().then(function(result) {
        var dir = result.directory;
        expect(fs.readFileSync(dir + '/something-cooler.js', {encoding: 'utf8'})).to.equal('whoa');
      });
    });
  });

  describe('listFiles', function() {
    var tree, listFiles;

    beforeEach(function() {
      tree = new CachingWriter(sourcePath);
      tree.updateCache = function(srcDir, destDir){
        listFiles = this.listFiles();
      }
    });

    it('returns an array of files keyed', function() {
      builder = new broccoli.Builder(tree);
      return builder.build().then(function() {
        expect(listFiles).to.eql(['tests/fixtures/sample-project/core.js',
                                  'tests/fixtures/sample-project/main.js']);
        expect(listFiles.length).to.equal(2)
      });
    });

    it('returns an array of files keyed including only those in the include filter', function() {
      tree.filterFromCache.include = [ /core\.js$/ ]
      builder = new broccoli.Builder(tree);
      return builder.build().then(function() {
        expect(listFiles).to.eql(['tests/fixtures/sample-project/core.js']);
        expect(listFiles.length).to.equal(1)
      });
    });

    it('returns an array of files keyed ignoring those in the exclude filter', function() {
      tree.filterFromCache.exclude = [ /main\.js$/ ]
      builder = new broccoli.Builder(tree);
      return builder.build().then(function() {
        expect(listFiles).to.eql(['tests/fixtures/sample-project/core.js']);
        expect(listFiles.length).to.equal(1)
      });
    });

    it('returns an array of files keyed both include & exclude filters', function() {
      tree.filterFromCache.include = [ /\.js$/ ]
      tree.filterFromCache.exclude = [ /core\.js$/ ]
      builder = new broccoli.Builder(tree);
      return builder.build().then(function() {
        expect(listFiles).to.eql(['tests/fixtures/sample-project/main.js']);
        expect(listFiles.length).to.equal(1)
      });
    });
  })
});
<|endoftext|>


<commit_before>var Application = require('spectron').Application;
var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');
var path = require('path');

chai.should();
chai.use(chaiAsPromised);

var afterEach = global.afterEach;
var beforeEach = global.beforeEach;
var describe = global.describe;
var it = global.it;

var expect = chai.expect;

describe('demo app', function () {
  this.timeout(30000);

  beforeEach(function () {
    this.app = new Application({
      path: path.join(__dirname, '..', 'node_modules', '.bin', 'electron'),
      args: [
        path.join(__dirname, '..')
      ],
      waitTimeout: 10000
    });
    return this.app.start();
  });

  beforeEach(function () {
    chaiAsPromised.transferPromiseness = this.app.client.transferPromiseness;
  });

  afterEach(function () {
    if (this.app && this.app.isRunning()) {
      return this.app.stop();
    }
  });

  it('opens a window and lists the API sections', function () {
    return this.app.client.waitUntilWindowLoaded()
      .getWindowCount().should.eventually.equal(1)
      .isWindowMinimized().should.eventually.be.false
      .isWindowDevToolsOpened().should.eventually.be.false
      .isWindowVisible().should.eventually.be.true
      .isWindowFocused().should.eventually.be.true
      .getWindowWidth().should.eventually.equal(800)
      .getWindowHeight().should.eventually.equal(733)
      .getTitle().should.eventually.equal('Electron API Demos')
      .elements('section').then(function (response) {
        expect(response.status).to.equal(0);
        expect(response.value.length).to.equal(6);
      });
  });

  describe('when clicking on a section', function () {
    it('opens the selected section', function () {
      return this.app.client.waitUntilWindowLoaded()
        .click('a').pause(1000)
        .waitForVisible('.task-page')
        .getText('h1').should.eventually.equal('Use system dialogs');
    });
    it('all tasks are collapsed', function () {
      return this.app.client
        .isVisible('.toggle-content').should.eventually.be.false;
    });
  });
});
<commit_msg>Assert task expands when clicked<commit_after>var Application = require('spectron').Application;
var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');
var path = require('path');

chai.should();
chai.use(chaiAsPromised);

var afterEach = global.afterEach;
var beforeEach = global.beforeEach;
var describe = global.describe;
var it = global.it;

var expect = chai.expect;

describe('demo app', function () {
  this.timeout(30000);

  beforeEach(function () {
    this.app = new Application({
      path: path.join(__dirname, '..', 'node_modules', '.bin', 'electron'),
      args: [
        path.join(__dirname, '..')
      ],
      waitTimeout: 10000
    });
    return this.app.start();
  });

  beforeEach(function () {
    chaiAsPromised.transferPromiseness = this.app.client.transferPromiseness;
  });

  afterEach(function () {
    if (this.app && this.app.isRunning()) {
      return this.app.stop();
    }
  });

  it('opens a window and lists the API sections', function () {
    return this.app.client.waitUntilWindowLoaded()
      .getWindowCount().should.eventually.equal(1)
      .isWindowMinimized().should.eventually.be.false
      .isWindowDevToolsOpened().should.eventually.be.false
      .isWindowVisible().should.eventually.be.true
      .isWindowFocused().should.eventually.be.true
      .getWindowWidth().should.eventually.equal(800)
      .getWindowHeight().should.eventually.equal(733)
      .getTitle().should.eventually.equal('Electron API Demos')
      .elements('section').then(function (response) {
        expect(response.status).to.equal(0);
        expect(response.value.length).to.equal(6);
      });
  });

  describe('when clicking on a section', function () {
    it('opens the selected section', function () {
      return this.app.client.waitUntilWindowLoaded()
        .click('a').pause(1000)
        .waitForVisible('.task-page')
        .getText('h1').should.eventually.equal('Use system dialogs');
    });
    it('all tasks are collapsed', function () {
      return this.app.client
        .isVisible('.toggle-content').should.eventually.be.false;
    });
  });

  describe('when a task is clicked', function () {
    it('it expands', function () {
      return this.app.client.waitUntilWindowLoaded()
        .click('a').pause(1000)
        .waitForVisible('.task-page')
        .click('.js-container-target').pause(1000)
        .waitForVisible('.toggle-content')
        .isVisible('.toggle-content').should.eventually.deep.equal([ true, false, false, false ]);
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

var expect = require('chai').expect;
var stub = require('sinon').stub;
var Canvas = require('../lib/index.js');
var getContextStub = require('./helpers/get-context-stub');
var ImageData = require('./helpers/image-data-stub');

describe('sensible canvas', function () {

  var canvas, element;

  var specialFontTypes = [
    'caption',
    'icon',
    'menu',
    'message-box',
    'small-caption',
    'status-bar'
  ];

  var getters = {
    getOpacity: {value: 1, type: 'number'},
    getCompositeOperation: {value: 'source-over', type: 'string'},
    getFill: {value: '#000000', type: 'string'},
    getStroke: {value: '#000000', type: 'string'},
    getStrokeWidth: {value: 1, type: 'number'},
    getStrokeCap: {value: 'butt', type: 'string'},
    getStrokeJoin: {value: 'miter', type: 'string'},
    getStrokeDashOffset: {value: 0, type: 'number'},
    getMiterLimit: {value: 10, type: 'number'},
    getShadowColor: {value: 'rgba(0, 0, 0, 0)', type: 'string'},
    getShadowBlur: {value: 0, type: 'number'},
    getShadowOffsetX: {value: 0, type: 'number'},
    getShadowOffsetY: {value: 0, type: 'number'},
    getTextAlign: {value: 'start', type: 'string'},
    getTextBaseline: {value: 'alphabetic', type: 'string'}
  };

  var argumentMap = {
    setWidth: [0],
    setHeight: [0],
    setSize: [0, 0],
    scale: [1, 1],
    rotate: [0],
    translate: [0, 0],
    setTransform: [1, 0, 0, 1, 0, 0],
    transform: [1, 0, 0, 1, 0, 0],
    drawFocusIfNeeded: [element],
    clearRect: [0, 0, 0, 0],
    moveTo: [0, 0],
    lineTo: [0, 0],
    quadraticCurveTo: [0, 0, 0, 0],
    bezierCurveTo: [0, 0, 0, 0, 0, 0],
    arcTo: [0, 0, 0, 0, 0],
    fillText: ['', 0, 0],
    strokeText: ['', 0, 0],
    drawImage: [new Image(), 0, 0],
    putImageData: [new ImageData(1, 1), 0, 0],
    plotRect: [0, 0, 0, 0],
    plotArc: [0, 0, 0, 0, 0],
    plotEllipse: [0, 0, 0, 0, 0, 0, 0],
    setStrokeDash: [[]],
    isPointInPath: [0, 0]
  };

  var isGetter = /^(get|create|is)/i;

  it('should return an interface', function () {
    element = document.createElement('canvas');

    stub(element, 'getContext', getContextStub);

    canvas = new Canvas(element);

    expect(canvas).to.exist;
  });

  describe('property getters', function () {

    it('should return the correct property values from the context', function () {
      for (var key in getters) {
        var result = canvas[key]();
        expect(result).to.equal(getters[key].value);
        expect(typeof result).to.equal(getters[key].type);
      }
    });

  });

  describe('context getters', function () {

    it('should return the actual canvas context', function () {
      expect(canvas.getContext()).to.equal(element.getContext('2d'));
    });

    it('should return the context type', function () {
      expect(canvas.getContextType()).to.equal('2d');
    });

  });

  describe('get data url', function () {

    it('should return a data url of the canvas', function () {
      stub(element, 'toDataURL', function () {
        return 'url';
      });

      expect(canvas.getDataURL()).to.equal('url');
    });

  });

  describe('canvas sizes', function () {

    it('should return the canvas width and height as an integer', function () {
      element.setAttribute('width', 123);
      element.setAttribute('height', 456);

      expect(canvas.getWidth()).to.equal(123);
      expect(canvas.getHeight()).to.equal(456);

      expect(typeof canvas.getWidth()).to.equal('number');
      expect(typeof canvas.getHeight()).to.equal('number');

      element.setAttribute('width', 12.3);
      element.setAttribute('height', 45.6);

      expect(canvas.getWidth()).to.equal(12);
      expect(canvas.getHeight()).to.equal(45);

      expect(typeof canvas.getWidth()).to.equal('number');
      expect(typeof canvas.getHeight()).to.equal('number');

      expect(canvas.getSize()).to.eql({width: 12, height: 45});
    });

    it('should set the canvas width and height as integers', function () {
      canvas.setWidth(456);
      canvas.setHeight(123);

      expect(element.getAttribute('width')).to.equal('456');
      expect(element.getAttribute('height')).to.equal('123');

      canvas.setWidth(45.6);
      canvas.setHeight(12.3);

      expect(element.getAttribute('width')).to.equal('45');
      expect(element.getAttribute('height')).to.equal('12');

      canvas.setSize(32.1, 65.4);

      expect(element.getAttribute('width')).to.equal('32');
      expect(element.getAttribute('height')).to.equal('65');
    });

  });

  describe('image smoothing', function () {

    it('should return the first image smoothing value', function () {
      expect(canvas.getImageSmoothing()).to.be.true;
    });

    it('should set the first image smoothing value', function () {
      canvas.setImageSmoothing(false);

      expect(canvas.getImageSmoothing()).to.be.false;
    });

    it('should return null if no image smoothing keys present', function () {
      var context = element.getContext('2d');
      delete context.imageSmoothingEnabled;
      delete context.webkitImageSmoothingEnabled;

      expect(canvas.getImageSmoothing()).to.be.null;
    });

    it('should not set a value if no image smoothing keys present', function () {
      canvas.setImageSmoothing(true);

      expect(canvas.getImageSmoothing()).to.be.null;
    });

  });

  describe('font methods', function () {

    it('should return a formatted font value', function () {
      expect(canvas.getFont()).to.equal('normal normal normal 10px sans-serif');
    });

    it('should set the font', function () {
      canvas.setFont('small-caps normal bold 20px arial');
      expect(canvas.getFont()).to.equal('normal small-caps bold 20px arial');
    });

    it('should return individual font properties', function () {
      expect(canvas.getFontStyle()).to.equal('normal');
      expect(canvas.getFontVariant()).to.equal('small-caps');
      expect(canvas.getFontWeight()).to.equal('bold');
      expect(canvas.getFontSize()).to.equal(20);
      expect(canvas.getFontFamily()).to.equal('arial');
    });

    it('should set individual font properties', function () {
      canvas.setFontStyle('italic');
      expect(canvas.getFont()).to.equal('italic small-caps bold 20px arial');

      canvas.setFontVariant('normal');
      expect(canvas.getFont()).to.equal('italic normal bold 20px arial');

      canvas.setFontWeight('normal');
      expect(canvas.getFont()).to.equal('italic normal normal 20px arial');

      canvas.setFontSize(15);
      expect(canvas.getFont()).to.equal('italic normal normal 15px arial');

      canvas.setFontFamily('times');
      expect(canvas.getFont()).to.equal('italic normal normal 15px times');
    });

    it('should allow setting special font types', function () {
      for (var i = 0; i < specialFontTypes.length; i += 1) {
        canvas.setFont(specialFontTypes[i]);
        expect(canvas.getFont()).to.equal(specialFontTypes[i]);
      }
    });

    it('should return null for individual properties when a special font is set', function () {
      expect(canvas.getFontStyle()).to.be.null;
      expect(canvas.getFontVariant()).to.be.null;
      expect(canvas.getFontWeight()).to.be.null;
      expect(canvas.getFontSize()).to.be.null;
      expect(canvas.getFontFamily()).to.be.null;
    });

    it('should set the default font if properties are set when a special font is set', function () {
      // Set to special font type
      canvas.setFont(specialFontTypes[0]);
      expect(canvas.getFont()).to.equal(specialFontTypes[0]);

      canvas.setFontStyle();
      expect(canvas.getFont()).to.equal('normal normal normal 10px sans-serif');

      // Set to special font type
      canvas.setFont(specialFontTypes[0]);
      expect(canvas.getFont()).to.equal(specialFontTypes[0]);

      canvas.setFontVariant();
      expect(canvas.getFont()).to.equal('normal normal normal 10px sans-serif');

      // Set to special font type
      canvas.setFont(specialFontTypes[0]);
      expect(canvas.getFont()).to.equal(specialFontTypes[0]);

      canvas.setFontWeight();
      expect(canvas.getFont()).to.equal('normal normal normal 10px sans-serif');

      // Set to special font type
      canvas.setFont(specialFontTypes[0]);
      expect(canvas.getFont()).to.equal(specialFontTypes[0]);

      canvas.setFontSize();
      expect(canvas.getFont()).to.equal('normal normal normal 10px sans-serif');

      // Set to special font type
      canvas.setFont(specialFontTypes[0]);
      expect(canvas.getFont()).to.equal(specialFontTypes[0]);

      canvas.setFontFamily();
      expect(canvas.getFont()).to.equal('normal normal normal 10px sans-serif');

    });

    it('should set the default font if a font value is incorrect', function () {
      // Set to something correct
      canvas.setFont('20px times');
      expect(canvas.getFont()).to.equal('normal normal normal 20px times');

      canvas.setFont('oops');
      expect(canvas.getFont()).to.equal('normal normal normal 10px sans-serif');

      // Set to something correct
      canvas.setFont('20px times');
      expect(canvas.getFont()).to.equal('normal normal normal 20px times');

      canvas.setFont('not real values 15px arial');
      expect(canvas.getFont()).to.equal('normal normal normal 10px sans-serif');

      // Set to something correct
      canvas.setFont('20px times');
      expect(canvas.getFont()).to.equal('normal normal normal 20px times');

      canvas.setFont('italic bold');
      expect(canvas.getFont()).to.equal('normal normal normal 10px sans-serif');
    });

  });

  describe('actions and setters', function () {

    it('should return the canvas', function () {
      for (var key in canvas) {
        if (!isGetter.exec(key)) {
          expect(canvas[key].apply(null, argumentMap[key])).to.equal(canvas);
        }
      }
    });

  });

  describe('helper methods', function () {

    it('should create color values', function () {
      expect(canvas.createHSL(123, 40, 50)).to.equal('hsl(123,40%,50%)');
      expect(canvas.createHSLA(123, 40, 50, 0.5)).to.equal('hsla(123,40%,50%,0.5)');
      expect(canvas.createRGB(111, 222, 333)).to.equal('rgb(111,222,333)');
      expect(canvas.createRGBA(111, 222, 333, 0.5)).to.equal('rgba(111,222,333,0.5)');
    });

    it('should remove alpha values from colors', function () {
      expect(canvas.getHSLFromHSLA(canvas.createHSLA(123, 40, 50, 0.5))).to.equal('hsl(123,40%,50%)');
      expect(canvas.getRGBFromRGBA(canvas.createRGBA(111, 222, 333, 0.5))).to.equal('rgb(111,222,333)');
    });

    it('should convert angles', function () {
      expect(canvas.getRadiansFromDegrees(0)).to.equal(0);
      expect(canvas.getRadiansFromDegrees(180)).to.equal(Math.PI);
      expect(canvas.getRadiansFromDegrees(360)).to.equal(Math.PI * 2);

      expect(canvas.getDegreesFromRadians(0)).to.equal(0);
      expect(canvas.getDegreesFromRadians(Math.PI)).to.equal(180);
      expect(canvas.getDegreesFromRadians(Math.PI * 2)).to.equal(360);
    });

    it('should convert fractions & percentages', function () {
      expect(canvas.getPercentFromFraction(0.75)).to.equal(75);
      expect(canvas.getFractionFromPercent(25)).to.equal(0.25);
    });

    it('should get fractions & percentages of the canvas size', function () {
      canvas.setSize(400, 200);

      expect(canvas.getPercentOfWidth(75)).to.equal(300);
      expect(canvas.getFractionOfWidth(0.25)).to.equal(100);

      expect(canvas.getPercentOfHeight(75)).to.equal(150);
      expect(canvas.getFractionOfHeight(0.25)).to.equal(50);
    });

    it('should return information about a pixel', function () {
      canvas.setSize(5, 5);

      expect(canvas.getPixelData(2, 2)).to.eql([0, 0, 0, 0]);
      expect(canvas.getPixelColor(2, 2)).to.equal('rgba(0,0,0,0)');
    });

  });

});
<commit_msg>Begin testing path plotting<commit_after>'use strict';

var expect = require('chai').expect;
var sinon = require('sinon');
var spy = sinon.spy;
var stub = sinon.stub;
var Canvas = require('../lib/index.js');
var getContextStub = require('./helpers/get-context-stub');
var ImageData = require('./helpers/image-data-stub');

describe('sensible canvas', function () {

  var canvas, element;

  var specialFontTypes = [
    'caption',
    'icon',
    'menu',
    'message-box',
    'small-caption',
    'status-bar'
  ];

  var getters = {
    getOpacity: {value: 1, type: 'number'},
    getCompositeOperation: {value: 'source-over', type: 'string'},
    getFill: {value: '#000000', type: 'string'},
    getStroke: {value: '#000000', type: 'string'},
    getStrokeWidth: {value: 1, type: 'number'},
    getStrokeCap: {value: 'butt', type: 'string'},
    getStrokeJoin: {value: 'miter', type: 'string'},
    getStrokeDashOffset: {value: 0, type: 'number'},
    getMiterLimit: {value: 10, type: 'number'},
    getShadowColor: {value: 'rgba(0, 0, 0, 0)', type: 'string'},
    getShadowBlur: {value: 0, type: 'number'},
    getShadowOffsetX: {value: 0, type: 'number'},
    getShadowOffsetY: {value: 0, type: 'number'},
    getTextAlign: {value: 'start', type: 'string'},
    getTextBaseline: {value: 'alphabetic', type: 'string'}
  };

  var argumentMap = {
    setWidth: [0],
    setHeight: [0],
    setSize: [0, 0],
    scale: [1, 1],
    rotate: [0],
    translate: [0, 0],
    setTransform: [1, 0, 0, 1, 0, 0],
    transform: [1, 0, 0, 1, 0, 0],
    drawFocusIfNeeded: [element],
    clearRect: [0, 0, 0, 0],
    moveTo: [0, 0],
    lineTo: [0, 0],
    quadraticCurveTo: [0, 0, 0, 0],
    bezierCurveTo: [0, 0, 0, 0, 0, 0],
    arcTo: [0, 0, 0, 0, 0],
    fillText: ['', 0, 0],
    strokeText: ['', 0, 0],
    drawImage: [new Image(), 0, 0],
    putImageData: [new ImageData(1, 1), 0, 0],
    plotRect: [0, 0, 0, 0],
    plotArc: [0, 0, 0, 0, 0],
    plotEllipse: [0, 0, 0, 0, 0, 0, 0],
    setStrokeDash: [[]],
    isPointInPath: [0, 0]
  };

  var isGetter = /^(get|create|is)/i;

  it('should return an interface', function () {
    element = document.createElement('canvas');

    stub(element, 'getContext', getContextStub);

    canvas = new Canvas(element);

    expect(canvas).to.exist;
  });

  describe('property getters', function () {

    it('should return the correct property values from the context', function () {
      for (var key in getters) {
        var result = canvas[key]();
        expect(result).to.equal(getters[key].value);
        expect(typeof result).to.equal(getters[key].type);
      }
    });

  });

  describe('context getters', function () {

    it('should return the actual canvas context', function () {
      expect(canvas.getContext()).to.equal(element.getContext('2d'));
    });

    it('should return the context type', function () {
      expect(canvas.getContextType()).to.equal('2d');
    });

  });

  describe('get data url', function () {

    it('should return a data url of the canvas', function () {
      stub(element, 'toDataURL', function () {
        return 'url';
      });

      expect(canvas.getDataURL()).to.equal('url');
    });

  });

  describe('canvas sizes', function () {

    it('should return the canvas width and height as an integer', function () {
      element.setAttribute('width', 123);
      element.setAttribute('height', 456);

      expect(canvas.getWidth()).to.equal(123);
      expect(canvas.getHeight()).to.equal(456);

      expect(typeof canvas.getWidth()).to.equal('number');
      expect(typeof canvas.getHeight()).to.equal('number');

      element.setAttribute('width', 12.3);
      element.setAttribute('height', 45.6);

      expect(canvas.getWidth()).to.equal(12);
      expect(canvas.getHeight()).to.equal(45);

      expect(typeof canvas.getWidth()).to.equal('number');
      expect(typeof canvas.getHeight()).to.equal('number');

      expect(canvas.getSize()).to.eql({width: 12, height: 45});
    });

    it('should set the canvas width and height as integers', function () {
      canvas.setWidth(456);
      canvas.setHeight(123);

      expect(element.getAttribute('width')).to.equal('456');
      expect(element.getAttribute('height')).to.equal('123');

      canvas.setWidth(45.6);
      canvas.setHeight(12.3);

      expect(element.getAttribute('width')).to.equal('45');
      expect(element.getAttribute('height')).to.equal('12');

      canvas.setSize(32.1, 65.4);

      expect(element.getAttribute('width')).to.equal('32');
      expect(element.getAttribute('height')).to.equal('65');
    });

  });

  describe('image smoothing', function () {

    it('should return the first image smoothing value', function () {
      expect(canvas.getImageSmoothing()).to.be.true;
    });

    it('should set the first image smoothing value', function () {
      canvas.setImageSmoothing(false);

      expect(canvas.getImageSmoothing()).to.be.false;
    });

    it('should return null if no image smoothing keys present', function () {
      var context = element.getContext('2d');
      delete context.imageSmoothingEnabled;
      delete context.webkitImageSmoothingEnabled;

      expect(canvas.getImageSmoothing()).to.be.null;
    });

    it('should not set a value if no image smoothing keys present', function () {
      canvas.setImageSmoothing(true);

      expect(canvas.getImageSmoothing()).to.be.null;
    });

  });

  describe('font methods', function () {

    it('should return a formatted font value', function () {
      expect(canvas.getFont()).to.equal('normal normal normal 10px sans-serif');
    });

    it('should set the font', function () {
      canvas.setFont('small-caps normal bold 20px arial');
      expect(canvas.getFont()).to.equal('normal small-caps bold 20px arial');
    });

    it('should return individual font properties', function () {
      expect(canvas.getFontStyle()).to.equal('normal');
      expect(canvas.getFontVariant()).to.equal('small-caps');
      expect(canvas.getFontWeight()).to.equal('bold');
      expect(canvas.getFontSize()).to.equal(20);
      expect(canvas.getFontFamily()).to.equal('arial');
    });

    it('should set individual font properties', function () {
      canvas.setFontStyle('italic');
      expect(canvas.getFont()).to.equal('italic small-caps bold 20px arial');

      canvas.setFontVariant('normal');
      expect(canvas.getFont()).to.equal('italic normal bold 20px arial');

      canvas.setFontWeight('normal');
      expect(canvas.getFont()).to.equal('italic normal normal 20px arial');

      canvas.setFontSize(15);
      expect(canvas.getFont()).to.equal('italic normal normal 15px arial');

      canvas.setFontFamily('times');
      expect(canvas.getFont()).to.equal('italic normal normal 15px times');
    });

    it('should allow setting special font types', function () {
      for (var i = 0; i < specialFontTypes.length; i += 1) {
        canvas.setFont(specialFontTypes[i]);
        expect(canvas.getFont()).to.equal(specialFontTypes[i]);
      }
    });

    it('should return null for individual properties when a special font is set', function () {
      expect(canvas.getFontStyle()).to.be.null;
      expect(canvas.getFontVariant()).to.be.null;
      expect(canvas.getFontWeight()).to.be.null;
      expect(canvas.getFontSize()).to.be.null;
      expect(canvas.getFontFamily()).to.be.null;
    });

    it('should set the default font if properties are set when a special font is set', function () {
      // Set to special font type
      canvas.setFont(specialFontTypes[0]);
      expect(canvas.getFont()).to.equal(specialFontTypes[0]);

      canvas.setFontStyle();
      expect(canvas.getFont()).to.equal('normal normal normal 10px sans-serif');

      // Set to special font type
      canvas.setFont(specialFontTypes[0]);
      expect(canvas.getFont()).to.equal(specialFontTypes[0]);

      canvas.setFontVariant();
      expect(canvas.getFont()).to.equal('normal normal normal 10px sans-serif');

      // Set to special font type
      canvas.setFont(specialFontTypes[0]);
      expect(canvas.getFont()).to.equal(specialFontTypes[0]);

      canvas.setFontWeight();
      expect(canvas.getFont()).to.equal('normal normal normal 10px sans-serif');

      // Set to special font type
      canvas.setFont(specialFontTypes[0]);
      expect(canvas.getFont()).to.equal(specialFontTypes[0]);

      canvas.setFontSize();
      expect(canvas.getFont()).to.equal('normal normal normal 10px sans-serif');

      // Set to special font type
      canvas.setFont(specialFontTypes[0]);
      expect(canvas.getFont()).to.equal(specialFontTypes[0]);

      canvas.setFontFamily();
      expect(canvas.getFont()).to.equal('normal normal normal 10px sans-serif');

    });

    it('should set the default font if a font value is incorrect', function () {
      // Set to something correct
      canvas.setFont('20px times');
      expect(canvas.getFont()).to.equal('normal normal normal 20px times');

      canvas.setFont('oops');
      expect(canvas.getFont()).to.equal('normal normal normal 10px sans-serif');

      // Set to something correct
      canvas.setFont('20px times');
      expect(canvas.getFont()).to.equal('normal normal normal 20px times');

      canvas.setFont('not real values 15px arial');
      expect(canvas.getFont()).to.equal('normal normal normal 10px sans-serif');

      // Set to something correct
      canvas.setFont('20px times');
      expect(canvas.getFont()).to.equal('normal normal normal 20px times');

      canvas.setFont('italic bold');
      expect(canvas.getFont()).to.equal('normal normal normal 10px sans-serif');
    });

  });

  describe('plot path', function () {

    it('should accept and plot valid point arrays', function () {
      var context = canvas.getContext();
      var moveToSpy = spy(context, 'moveTo');
      var lineToSpy = spy(context, 'lineTo');

      canvas.plotPath([0, 1, 2, 3]);

      expect(moveToSpy).to.have.been.calledWith(0, 1);
      expect(lineToSpy).to.have.been.calledWith(2, 3);

      canvas.plotPath([[4, 5], [6, 7]]);

      expect(moveToSpy).to.have.been.calledWith(4, 5);
      expect(lineToSpy).to.have.been.calledWith(6, 7);

      canvas.plotPath([{x: 8, y: 9}, {x: 10, y: 11}]);

      expect(moveToSpy).to.have.been.calledWith(8, 9);
      expect(lineToSpy).to.have.been.calledWith(10, 11);
    });

  });

  describe('actions and setters', function () {

    it('should return the canvas', function () {
      for (var key in canvas) {
        if (!isGetter.exec(key)) {
          expect(canvas[key].apply(null, argumentMap[key])).to.equal(canvas);
        }
      }
    });

  });

  describe('helper methods', function () {

    it('should create color values', function () {
      expect(canvas.createHSL(123, 40, 50)).to.equal('hsl(123,40%,50%)');
      expect(canvas.createHSLA(123, 40, 50, 0.5)).to.equal('hsla(123,40%,50%,0.5)');
      expect(canvas.createRGB(111, 222, 333)).to.equal('rgb(111,222,333)');
      expect(canvas.createRGBA(111, 222, 333, 0.5)).to.equal('rgba(111,222,333,0.5)');
    });

    it('should remove alpha values from colors', function () {
      expect(canvas.getHSLFromHSLA(canvas.createHSLA(123, 40, 50, 0.5))).to.equal('hsl(123,40%,50%)');
      expect(canvas.getRGBFromRGBA(canvas.createRGBA(111, 222, 333, 0.5))).to.equal('rgb(111,222,333)');
    });

    it('should convert angles', function () {
      expect(canvas.getRadiansFromDegrees(0)).to.equal(0);
      expect(canvas.getRadiansFromDegrees(180)).to.equal(Math.PI);
      expect(canvas.getRadiansFromDegrees(360)).to.equal(Math.PI * 2);

      expect(canvas.getDegreesFromRadians(0)).to.equal(0);
      expect(canvas.getDegreesFromRadians(Math.PI)).to.equal(180);
      expect(canvas.getDegreesFromRadians(Math.PI * 2)).to.equal(360);
    });

    it('should convert fractions & percentages', function () {
      expect(canvas.getPercentFromFraction(0.75)).to.equal(75);
      expect(canvas.getFractionFromPercent(25)).to.equal(0.25);
    });

    it('should get fractions & percentages of the canvas size', function () {
      canvas.setSize(400, 200);

      expect(canvas.getPercentOfWidth(75)).to.equal(300);
      expect(canvas.getFractionOfWidth(0.25)).to.equal(100);

      expect(canvas.getPercentOfHeight(75)).to.equal(150);
      expect(canvas.getFractionOfHeight(0.25)).to.equal(50);
    });

    it('should return information about a pixel', function () {
      canvas.setSize(5, 5);

      expect(canvas.getPixelData(2, 2)).to.eql([0, 0, 0, 0]);
      expect(canvas.getPixelColor(2, 2)).to.equal('rgba(0,0,0,0)');
    });

  });

});
<|endoftext|>


<commit_before>'use strict'

const Application = require('spectron').Application
const chai = require('chai')
const chaiAsPromised = require('chai-as-promised')
const path = require('path')
const fs = require('fs')

chai.should()
chai.use(chaiAsPromised)

const timeout = process.env.CI ? 30000 : 10000

describe('demo app', function () {
  this.timeout(timeout)

  let app

  const removeStoredPreferences = function () {
    const productName = require('../package').productName
    const userDataPath = path.join(process.env.HOME, 'Library', 'Application Support', productName)
    try {
      fs.unlinkSync(path.join(userDataPath, 'activeDemoButtonId.json'))
    } catch (error) {
      if (error.code !== 'ENOENT') throw error
    }
    try {
      fs.unlinkSync(path.join(userDataPath, 'activeSectionButtonId.json'))
    } catch (error) {
      if (error.code !== 'ENOENT') throw error
    }
  }

  const setupApp = function (app) {
    app.client.addCommand('dismissAboutPage', function () {
      return this.isVisible('.js-nav').then(function (navVisible) {
        if (!navVisible) {
          return this.click('button[id="get-started"]').pause(500)
        }
      })
    })

    app.client.addCommand('selectSection', function (section) {
      return this.click('button[data-section="' + section + '"]').pause(100)
        .waitForVisible('#' + section + '-section')
    })

    app.client.addCommand('expandDemos', function () {
      return this.execute(function () {
        let demos = document.querySelectorAll('.demo-wrapper')
        for (let i = 0; i < demos.length; i++) {
          demos[i].classList.add('is-open')
        }
      })
    })

    app.client.addCommand('collapseDemos', function () {
      return this.execute(function () {
        let demos = document.querySelectorAll('.demo-wrapper')
        for (let i = 0; i < demos.length; i++) {
          demos[i].classList.remove('is-open')
        }
      })
    })

    app.client.addCommand('auditSectionAccessibility', function (section) {
      const options = {
        ignoreRules: ['AX_COLOR_01', 'AX_TITLE_01']
      }
      return this.selectSection(section)
        .expandDemos()
        .auditAccessibility(options).then(function (audit) {
          if (audit.failed) {
            throw Error(section + ' section failed accessibility audit\n' + audit.message)
          }
        })
    })

    chaiAsPromised.transferPromiseness = app.transferPromiseness
    return app.client.waitUntilWindowLoaded()
  }

  const startApp = function () {
    app = new Application({
      path: path.join(__dirname, '..', 'node_modules', '.bin', 'electron'),
      args: [
        path.join(__dirname, '..')
      ],
      waitTimeout: timeout
    })

    return app.start().then(setupApp)
  }

  const restartApp = function () {
    return app.restart().then(setupApp)
  }

  before(function () {
    removeStoredPreferences()
    return startApp()
  })

  after(function () {
    if (app && app.isRunning()) {
      return app.stop()
    }
  })

  it('opens a window displaying the about page', function () {
    return app.client.getWindowCount().should.eventually.equal(1)
      .browserWindow.isMinimized().should.eventually.be.false
      .browserWindow.isDevToolsOpened().should.eventually.be.false
      .browserWindow.isVisible().should.eventually.be.true
      .browserWindow.isFocused().should.eventually.be.true
      .browserWindow.getBounds().should.eventually.have.property('width').and.be.above(0)
      .browserWindow.getBounds().should.eventually.have.property('height').and.be.above(0)
      .browserWindow.getTitle().should.eventually.equal('Electron API Demos')
      .waitForVisible('#about-modal').should.eventually.be.true
      .isVisible('.js-nav').should.eventually.be.false
      .click('button[id="get-started"]').pause(500)
      .isVisible('#about-modal').should.eventually.be.false
      .isVisible('.js-nav').should.eventually.be.true
  })

  describe('when clicking on a section from the nav bar', function () {
    it('it shows the selected section in the main area', function () {
      return app.client.dismissAboutPage()
        .selectSection('windows')
        .isExisting('button.is-selected[data-section="windows"]').should.eventually.be.true
        .isVisible('#pdf-section').should.eventually.be.false
        .selectSection('pdf')
        .isVisible('#windows-section').should.eventually.be.false
        .isExisting('button.is-selected[data-section="windows"]').should.eventually.be.false
        .isExisting('button.is-selected[data-section="pdf"]').should.eventually.be.true
    })
  })

  describe('when a demo title is clicked', function () {
    it('it expands the demo content', function () {
      let onlyFirstVisible = Array(27).fill(false)
      onlyFirstVisible[0] = true

      return app.client.dismissAboutPage()
        .collapseDemos()
        .selectSection('windows')
        .click('.js-container-target')
        .waitForVisible('.demo-box')
        .isVisible('.demo-box').should.eventually.deep.equal(onlyFirstVisible)
    })
  })

  describe('when the app is restarted after use', function () {
    it('it launches at last visted section & demo', function () {
      let onlyFirstVisible = Array(27).fill(false)
      onlyFirstVisible[0] = true

      return app.client.waitForVisible('#windows-section')
        .then(restartApp)
        .then(function () {
          return app.client.waitForVisible('#windows-section')
            .isVisible('#windows-section').should.eventually.be.true
            .isVisible('.demo-box').should.eventually.deep.equal(onlyFirstVisible)
        })
    })
  })

  it('does not contain any accessibility warnings or errors', function () {
    return app.client.dismissAboutPage()
      .auditSectionAccessibility('windows')
      .auditSectionAccessibility('crash-hang')
      .auditSectionAccessibility('menus')
      .auditSectionAccessibility('shortcuts')
      .auditSectionAccessibility('ex-links-file-manager')
      .auditSectionAccessibility('dialogs')
      .auditSectionAccessibility('tray')
      .auditSectionAccessibility('ipc')
      .auditSectionAccessibility('app-sys-information')
      .auditSectionAccessibility('clipboard')
      .auditSectionAccessibility('protocol')
      .auditSectionAccessibility('pdf')
      .auditSectionAccessibility('desktop-capturer')
  })
})
<commit_msg>:art: use for/of for looping over nodes<commit_after>'use strict'

const Application = require('spectron').Application
const chai = require('chai')
const chaiAsPromised = require('chai-as-promised')
const path = require('path')
const fs = require('fs')

chai.should()
chai.use(chaiAsPromised)

const timeout = process.env.CI ? 30000 : 10000

describe('demo app', function () {
  this.timeout(timeout)

  let app

  const removeStoredPreferences = function () {
    const productName = require('../package').productName
    const userDataPath = path.join(process.env.HOME, 'Library', 'Application Support', productName)
    try {
      fs.unlinkSync(path.join(userDataPath, 'activeDemoButtonId.json'))
    } catch (error) {
      if (error.code !== 'ENOENT') throw error
    }
    try {
      fs.unlinkSync(path.join(userDataPath, 'activeSectionButtonId.json'))
    } catch (error) {
      if (error.code !== 'ENOENT') throw error
    }
  }

  const setupApp = function (app) {
    app.client.addCommand('dismissAboutPage', function () {
      return this.isVisible('.js-nav').then(function (navVisible) {
        if (!navVisible) {
          return this.click('button[id="get-started"]').pause(500)
        }
      })
    })

    app.client.addCommand('selectSection', function (section) {
      return this.click('button[data-section="' + section + '"]').pause(100)
        .waitForVisible('#' + section + '-section')
    })

    app.client.addCommand('expandDemos', function () {
      return this.execute(function () {
        for (let demo of document.querySelectorAll('.demo-wrapper')) {
          demo.classList.add('is-open')
        }
      })
    })

    app.client.addCommand('collapseDemos', function () {
      return this.execute(function () {
        for (let demo of document.querySelectorAll('.demo-wrapper')) {
          demo.classList.remove('is-open')
        }
      })
    })

    app.client.addCommand('auditSectionAccessibility', function (section) {
      const options = {
        ignoreRules: ['AX_COLOR_01', 'AX_TITLE_01']
      }
      return this.selectSection(section)
        .expandDemos()
        .auditAccessibility(options).then(function (audit) {
          if (audit.failed) {
            throw Error(section + ' section failed accessibility audit\n' + audit.message)
          }
        })
    })

    chaiAsPromised.transferPromiseness = app.transferPromiseness
    return app.client.waitUntilWindowLoaded()
  }

  const startApp = function () {
    app = new Application({
      path: path.join(__dirname, '..', 'node_modules', '.bin', 'electron'),
      args: [
        path.join(__dirname, '..')
      ],
      waitTimeout: timeout
    })

    return app.start().then(setupApp)
  }

  const restartApp = function () {
    return app.restart().then(setupApp)
  }

  before(function () {
    removeStoredPreferences()
    return startApp()
  })

  after(function () {
    if (app && app.isRunning()) {
      return app.stop()
    }
  })

  it('opens a window displaying the about page', function () {
    return app.client.getWindowCount().should.eventually.equal(1)
      .browserWindow.isMinimized().should.eventually.be.false
      .browserWindow.isDevToolsOpened().should.eventually.be.false
      .browserWindow.isVisible().should.eventually.be.true
      .browserWindow.isFocused().should.eventually.be.true
      .browserWindow.getBounds().should.eventually.have.property('width').and.be.above(0)
      .browserWindow.getBounds().should.eventually.have.property('height').and.be.above(0)
      .browserWindow.getTitle().should.eventually.equal('Electron API Demos')
      .waitForVisible('#about-modal').should.eventually.be.true
      .isVisible('.js-nav').should.eventually.be.false
      .click('button[id="get-started"]').pause(500)
      .isVisible('#about-modal').should.eventually.be.false
      .isVisible('.js-nav').should.eventually.be.true
  })

  describe('when clicking on a section from the nav bar', function () {
    it('it shows the selected section in the main area', function () {
      return app.client.dismissAboutPage()
        .selectSection('windows')
        .isExisting('button.is-selected[data-section="windows"]').should.eventually.be.true
        .isVisible('#pdf-section').should.eventually.be.false
        .selectSection('pdf')
        .isVisible('#windows-section').should.eventually.be.false
        .isExisting('button.is-selected[data-section="windows"]').should.eventually.be.false
        .isExisting('button.is-selected[data-section="pdf"]').should.eventually.be.true
    })
  })

  describe('when a demo title is clicked', function () {
    it('it expands the demo content', function () {
      let onlyFirstVisible = Array(27).fill(false)
      onlyFirstVisible[0] = true

      return app.client.dismissAboutPage()
        .collapseDemos()
        .selectSection('windows')
        .click('.js-container-target')
        .waitForVisible('.demo-box')
        .isVisible('.demo-box').should.eventually.deep.equal(onlyFirstVisible)
    })
  })

  describe('when the app is restarted after use', function () {
    it('it launches at last visted section & demo', function () {
      let onlyFirstVisible = Array(27).fill(false)
      onlyFirstVisible[0] = true

      return app.client.waitForVisible('#windows-section')
        .then(restartApp)
        .then(function () {
          return app.client.waitForVisible('#windows-section')
            .isVisible('#windows-section').should.eventually.be.true
            .isVisible('.demo-box').should.eventually.deep.equal(onlyFirstVisible)
        })
    })
  })

  it('does not contain any accessibility warnings or errors', function () {
    return app.client.dismissAboutPage()
      .auditSectionAccessibility('windows')
      .auditSectionAccessibility('crash-hang')
      .auditSectionAccessibility('menus')
      .auditSectionAccessibility('shortcuts')
      .auditSectionAccessibility('ex-links-file-manager')
      .auditSectionAccessibility('dialogs')
      .auditSectionAccessibility('tray')
      .auditSectionAccessibility('ipc')
      .auditSectionAccessibility('app-sys-information')
      .auditSectionAccessibility('clipboard')
      .auditSectionAccessibility('protocol')
      .auditSectionAccessibility('pdf')
      .auditSectionAccessibility('desktop-capturer')
  })
})
<|endoftext|>


<commit_before>/**
 * Add your test spec files to the list in order to
 * get them running by default.
 */

// Filer
require("./spec/filer.spec");

// Filer.FileSystem.*
require("./spec/fs.spec");
require("./spec/fs.stat.spec");
require("./spec/fs.lstat.spec");
require("./spec/fs.exists.spec");
require("./spec/fs.mknod.spec");
require("./spec/fs.mkdir.spec");
require("./spec/fs.readdir.spec");
require("./spec/fs.rmdir.spec");
require("./spec/fs.open.spec");
require("./spec/fs.write.spec");
require("./spec/fs.writeFile-readFile.spec");
require("./spec/fs.appendFile.spec");
require("./spec/fs.read.spec");
require("./spec/fs.close.spec");
require("./spec/fs.link.spec");
require("./spec/fs.unlink.spec");
require("./spec/fs.rename.spec");
require("./spec/fs.lseek.spec");
require("./spec/fs.symlink.spec");
require("./spec/fs.readlink.spec");
require("./spec/fs.truncate.spec");
require("./spec/fs.utimes.spec");
require("./spec/fs.xattr.spec");
require("./spec/fs.stats.spec");
require("./spec/path-resolution.spec");
require("./spec/trailing-slashes.spec");
require("./spec/times.spec");
require("./spec/time-flags.spec");
require("./spec/fs.watch.spec");
require("./spec/errors.spec");

// Filer.FileSystem.providers.*
require("./spec/providers/providers.spec");
require("./spec/providers/providers.indexeddb.spec");
require("./spec/providers/providers.websql.spec");
require("./spec/providers/providers.memory.spec");

// Filer.FileSystemShell.*
require("./spec/shell/cd.spec");
require("./spec/shell/touch.spec");
require("./spec/shell/exec.spec");
require("./spec/shell/cat.spec");
require("./spec/shell/ls.spec");
require("./spec/shell/rm.spec");
require("./spec/shell/env.spec");
require("./spec/shell/mkdirp.spec");
require("./spec/shell/wget.spec");
require("./spec/shell/zip-unzip.spec");
require("./spec/shell/network.spec");

// Ported node.js tests (filenames match names in https://github.com/joyent/node/tree/master/test)
require("./spec/node-js/simple/test-fs-mkdir");
require("./spec/node-js/simple/test-fs-null-bytes");
require("./spec/node-js/simple/test-fs-watch");
require("./spec/node-js/simple/test-fs-watch-recursive");

// Regressions, Bugs
// NOTE: bugs/issue225.js has to be run outside this step, see gruntfile.js
require("./bugs/issue105");
require("./bugs/issue106");
require("./bugs/issue239");
require("./bugs/issue249");
require("./bugs/ls-depth-bug");
require("./bugs/issue247.js");
require("./bugs/readFile-dir");
<commit_msg>Fix file name<commit_after>/**
 * Add your test spec files to the list in order to
 * get them running by default.
 */

// Filer
require("./spec/filer.spec");

// Filer.FileSystem.*
require("./spec/fs.spec");
require("./spec/fs.stat.spec");
require("./spec/fs.lstat.spec");
require("./spec/fs.exists.spec");
require("./spec/fs.mknod.spec");
require("./spec/fs.mkdir.spec");
require("./spec/fs.readdir.spec");
require("./spec/fs.rmdir.spec");
require("./spec/fs.open.spec");
require("./spec/fs.write.spec");
require("./spec/fs.writeFile-readFile.spec");
require("./spec/fs.appendFile.spec");
require("./spec/fs.read.spec");
require("./spec/fs.close.spec");
require("./spec/fs.link.spec");
require("./spec/fs.unlink.spec");
require("./spec/fs.rename.spec");
require("./spec/fs.lseek.spec");
require("./spec/fs.symlink.spec");
require("./spec/fs.readlink.spec");
require("./spec/fs.truncate.spec");
require("./spec/fs.utimes.spec");
require("./spec/fs.xattr.spec");
require("./spec/fs.stats.spec");
require("./spec/path-resolution.spec");
require("./spec/trailing-slashes.spec");
require("./spec/times.spec");
require("./spec/time-flags.spec");
require("./spec/fs.watch.spec");
require("./spec/errors.spec");

// Filer.FileSystem.providers.*
require("./spec/providers/providers.spec");
require("./spec/providers/providers.indexeddb.spec");
require("./spec/providers/providers.websql.spec");
require("./spec/providers/providers.memory.spec");

// Filer.FileSystemShell.*
require("./spec/shell/cd.spec");
require("./spec/shell/touch.spec");
require("./spec/shell/exec.spec");
require("./spec/shell/cat.spec");
require("./spec/shell/ls.spec");
require("./spec/shell/rm.spec");
require("./spec/shell/env.spec");
require("./spec/shell/mkdirp.spec");
require("./spec/shell/wget.spec");
require("./spec/shell/zip-unzip.spec");
require("./spec/shell/network.spec");

// Ported node.js tests (filenames match names in https://github.com/joyent/node/tree/master/test)
require("./spec/node-js/simple/test-fs-mkdir");
require("./spec/node-js/simple/test-fs-null-bytes");
require("./spec/node-js/simple/test-fs-watch");
require("./spec/node-js/simple/test-fs-watch-recursive");

// Regressions, Bugs
// NOTE: bugs/issue225.js has to be run outside this step, see gruntfile.js
require("./bugs/issue105");
require("./bugs/issue106");
require("./bugs/issue239");
require("./bugs/issue249");
require("./bugs/ls-depth-bug");
require("./bugs/issue247.js");
require("./bugs/issue254.js");

<|endoftext|>


<commit_before>import expect from "expect.js";
import sinon from "sinon";
import Maybe, {Just, Nothing} from "../lib/maybe";

describe("Just", function() {
	var value = 13,
		morphism = n => n * n;

	it("should satisfy the left identity law", function() {
		var m = Just(value),
			left = m.bind(morphism),
			right = morphism(value);

		expect(left.valueOf()).to.be(right);
	});

	it("should satisfy the right identity law", function() {
		var m = Just(value),
			left = m.bind(Just),
			right = m;

		expect(left.valueOf()).to.be(right.valueOf());
	});

	it("should satisfy the associativity law", function() {
		var m = Just(value),
			left = m.bind(Just).bind(morphism),
			right = m.bind(v => Just(v).bind(morphism));

		expect(left.valueOf()).to.be(right.valueOf());
	});
});

describe("Nothing", function() {
	it("should accept alternative way of computation", function() {
		var right = sinon.spy(),
			left = sinon.spy();

		Nothing().bind(right, left);

		expect(right.called).not.to.be(true);
		expect(left.called).to.be(true);
	});

	it("should use Just in alternative way", function() {
		var value = 5;

		Nothing()
			.bind(null, () => Just(value))
			.bind(wrapped => expect(wrapped).to.be(value));
	});
});

describe("Maybe", function() {
	it("should recognize nullable values", function() {
		var subscriber1 = sinon.spy(),
			subscriber2 = sinon.spy(),
			subscriber3 = sinon.spy();

		Maybe(null).bind(subscriber1, subscriber2);
		Maybe(true).bind(subscriber3);

		expect(subscriber1.called).not.to.be(true);
		expect(subscriber2.called).to.be(true);
		expect(subscriber3.called).to.be(true);
	});
});
<commit_msg>multiple vars<commit_after>import expect from "expect.js";
import sinon from "sinon";
import Maybe, {Just, Nothing} from "../lib/maybe";

describe("Just", function() {
	var value = 13;
	var morphism = n => n * n;

	it("should satisfy the left identity law", function() {
		var m = Just(value);
		var left = m.bind(morphism);
		var right = morphism(value);

		expect(left.valueOf()).to.be(right);
	});

	it("should satisfy the right identity law", function() {
		var m = Just(value);
		var left = m.bind(Just);
		var right = m;

		expect(left.valueOf()).to.be(right.valueOf());
	});

	it("should satisfy the associativity law", function() {
		var m = Just(value);
		var left = m.bind(Just).bind(morphism);
		var right = m.bind(v => Just(v).bind(morphism));

		expect(left.valueOf()).to.be(right.valueOf());
	});
});

describe("Nothing", function() {
	it("should accept alternative way of computation", function() {
		var right = sinon.spy();
		var left = sinon.spy();

		Nothing().bind(right, left);

		expect(right.called).not.to.be(true);
		expect(left.called).to.be(true);
	});

	it("should use Just in alternative way", function() {
		var value = 5;

		Nothing()
			.bind(null, () => Just(value))
			.bind(wrapped => expect(wrapped).to.be(value));
	});
});

describe("Maybe", function() {
	it("should recognize nullable values", function() {
		var subscriber1 = sinon.spy();
		var subscriber2 = sinon.spy();
		var subscriber3 = sinon.spy();

		Maybe(null).bind(subscriber1, subscriber2);
		Maybe(true).bind(subscriber3);

		expect(subscriber1.called).not.to.be(true);
		expect(subscriber2.called).to.be(true);
		expect(subscriber3.called).to.be(true);
	});
});
<|endoftext|>


<commit_before>const vdf = require('simple-vdf');
const async = require('async');
const utility = require('../util/utility');
const db = require('../store/db');
const queries = require('../store/queries');

const { invokeInterval, generateJob, getData } = utility;

function doLeagues(cb) {
  const container = generateJob('api_leagues', {
    language: 'english',
  });
  getData(container.url, (err, apiLeagues) => {
    if (err) {
      return cb(err);
    }
    return getData(
      {
        url: 'https://raw.githubusercontent.com/SteamDatabase/GameTracking-Dota2/master/game/dota/pak01_dir/scripts/items/items_game.txt',
        raw: true,
      },
      (err, body) => {
        if (err) {
          return cb(err);
        }
        const itemData = vdf.parse(body);
        const leagues = {};
        Object.keys(itemData.items_game.items).forEach((key) => {
          const item = itemData.items_game.items[key];
          if (item.prefab === 'league' && item.tool && item.tool.usage) {
            const leagueid = item.tool.usage.league_id;
            const { tier } = item.tool.usage;
            const ticket = item.image_inventory;
            const banner = item.image_banner;
            leagues[leagueid] = { tier, ticket, banner };
          }
        });
        // League tier corrections and missing data
        const leagueTiers = {
          4177: 'excluded', // CDEC Master
          94: 'amateur', // South Ural League Season 2
          216: 'amateur', // Steelseries Malaysia Cup - February
          221: 'professional', // CEVO Season 4
          99: 'professional', // SteelSeries Euro Cup Season 2
          65013: 'professional', // MLG $50,000 Dota 2 Championship
          227: 'amateur', // CFC Elite Cup
          109: 'professional', // Fragbite Masters
          112: 'professional', // ASUS ROG DreamLeague
          123: 'professional', // Yard Orange Festival
          131: 'amateur', // Gigabyte Premier League Season 1
          117: 'amateur', // South American Elite League
          134: 'professional', // Elite Southeast Asian League
          146: 'professional', // Asian Cyber Games Dota 2 Championship 2013
          160: 'professional', // Prodota Winter Cup
          174: 'professional', // Asian Cyber Games Invitational: Best of the Best
          8: 'professional', // Prodota 2 Worldwide League
          16: 'professional', // GosuLeague
          20: 'professional', // Star Series Season IV
          52: 'professional', // REDBULL Esports Champion League 2013 Bundle
          61: 'professional', // Electronic Sports World Cup 2013
          70: 'professional', // RaidCall EMS One Fall 2013
          21: 'professional', // The Defense 3
          27: 'professional', // The Premier League Season 4
          103: 'professional', // Dota 2 Champions League
          29: 'professional', // Star Series Season V
          83: 'professional', // CyberGamer Dota 2 Pro League
          33: 'professional', // DreamHack Dota2 Invitational
          48: 'professional', // RaidCall Dota 2 League Season 3
          51: 'professional', // The Defense Season 4
          65: 'professional', // SteelSeries Euro Cup
          69: 'professional', // StarSeries Season 7 - BUNDLE
          78: 'professional', // WePlay.TV Dota 2 League - Season 2
          97: 'professional', // Netolic Pro League 4
          104: 'professional', // HyperX D2L Season 4
          47: 'professional', // RaidCall EMS One Summer 2013
          53: 'professional', // DreamHack ASUS ROG Dota 2 Tournament
          161: 'professional', // SteelSeries Euro Cup Season 3
          7: 'professional', // BeyondTheSummit World Tour
          28: 'professional', // RaidCall EMS One Spring 2013
          65004: 'professional', // The International East Qualifiers
          46: 'professional', // StarSeries Season VI
          12: 'professional', // RaidCall Dota 2 League
          15: 'professional', // Premier League
          26: 'professional', // SEA League
          41: 'professional', // Curse Dota 2 Invitational
          45: 'professional', // Premier League Season 5
          50: 'professional', // American Dota League
          65005: 'professional', // The International West Qualifiers
          181: 'professional', // joinDOTA League
          4: 'professional', // The Defense
          184: 'professional', // MLG T.K.O.
          6: 'professional', // Star Series Season II Lan Final
          13: 'professional', // Star Series Season III
          65001: 'professional', // The International 2012
          24: 'professional', // G-League 2012
          176: 'professional', // Netolic Pro League 5 West
          54: 'professional', // Alienware Cup - 2013 Season 1
          135: 'professional', // Raidcall Southeast Asian Invitational League
          38: 'professional', // E2Max L33T Championship
          58: 'professional', // AMD Dota2 Premier League Season 2
          92: 'professional', // Arms of Burning Turmoil Set
          65008: 'professional', // 2013 National Electronic Sports Tournament
          235: 'professional', // The Monster Invitational
          18: 'professional', // atoD 2
          22: 'professional', // RaidCall Dota 2 League Season 2
          65002: 'professional', // DreamHack Dota 2 Corsair Vengeance Cup
          34: 'professional', // G-1 Champions League Season 5
          40: 'professional', // AMD Dota2 Premier League
          60: 'professional', // Neolution GosuCup
          0: 'amateur', // JetsetPro Amateur League 1x1 Season 1
          67: 'professional', // MLG NA League and Full Sail LAN
          71: 'professional', // The National
          80: 'professional', // Nexon Sponsorship League - ADMIN
          44: 'professional', // Rapture Gaming Network League
          76: 'professional', // Sina Cup Supernova Dota 2 Open
          81: 'professional', // WPC-ACE Dota 2 League
          114: 'professional', // G-League 2013
          177: 'professional', // Netolic Pro League 5 East
          17: 'professional', // G-1 Championship League
          23: 'professional', // Dota 2 The Asia
          37: 'professional', // AtoD 3
          42: 'professional', // Dota 2 Super League
          65007: 'professional', // Nexon Starter League
          57: 'professional', // Corsair Summer 2013
          120: 'professional', // Sina Cup Supernova Dota 2 Open Season 2
          125: 'professional', // Nexon Sponsorship League Season 2 & Gama Brothers Courier
        };
        const openQualifierTier = league => (league.name.indexOf('Open Qualifier') === -1 ? null : 'excluded');
        return async.each(apiLeagues.result.leagues, (l, cb) => {
          const itemSchemaLeague = leagues[l.leagueid] || {};
          l.tier = leagueTiers[l.leagueid] || openQualifierTier(l) || itemSchemaLeague.tier || null;
          l.ticket = itemSchemaLeague.ticket || null;
          l.banner = itemSchemaLeague.banner || null;
          queries.upsert(db, 'leagues', l, {
            leagueid: l.league_id,
          }, cb);
        }, cb);
      },
    );
  });
}
invokeInterval(doLeagues, 30 * 60 * 1000);
<commit_msg>disable tier ingestion temporarily<commit_after>const vdf = require('simple-vdf');
const async = require('async');
const utility = require('../util/utility');
const db = require('../store/db');
const queries = require('../store/queries');

const { invokeInterval, generateJob, getData } = utility;

function doLeagues(cb) {
  const container = generateJob('api_leagues', {
    language: 'english',
  });
  getData(container.url, (err, apiLeagues) => {
    if (err) {
      return cb(err);
    }
    return getData(
      {
        url: 'https://raw.githubusercontent.com/SteamDatabase/GameTracking-Dota2/master/game/dota/pak01_dir/scripts/items/items_game.txt',
        raw: true,
      },
      (err, body) => {
        if (err) {
          return cb(err);
        }
        /*
        const itemData = vdf.parse(body);
        const leagues = {};
        Object.keys(itemData.items_game.items).forEach((key) => {
          const item = itemData.items_game.items[key];
          if (item.prefab === 'league' && item.tool && item.tool.usage) {
            const leagueid = item.tool.usage.league_id;
            const { tier } = item.tool.usage;
            const ticket = item.image_inventory;
            const banner = item.image_banner;
            leagues[leagueid] = { tier, ticket, banner };
          }
        });
        */
        // League tier corrections and missing data
        const leagueTiers = {
          4177: 'excluded', // CDEC Master
          94: 'amateur', // South Ural League Season 2
          216: 'amateur', // Steelseries Malaysia Cup - February
          221: 'professional', // CEVO Season 4
          99: 'professional', // SteelSeries Euro Cup Season 2
          65013: 'professional', // MLG $50,000 Dota 2 Championship
          227: 'amateur', // CFC Elite Cup
          109: 'professional', // Fragbite Masters
          112: 'professional', // ASUS ROG DreamLeague
          123: 'professional', // Yard Orange Festival
          131: 'amateur', // Gigabyte Premier League Season 1
          117: 'amateur', // South American Elite League
          134: 'professional', // Elite Southeast Asian League
          146: 'professional', // Asian Cyber Games Dota 2 Championship 2013
          160: 'professional', // Prodota Winter Cup
          174: 'professional', // Asian Cyber Games Invitational: Best of the Best
          8: 'professional', // Prodota 2 Worldwide League
          16: 'professional', // GosuLeague
          20: 'professional', // Star Series Season IV
          52: 'professional', // REDBULL Esports Champion League 2013 Bundle
          61: 'professional', // Electronic Sports World Cup 2013
          70: 'professional', // RaidCall EMS One Fall 2013
          21: 'professional', // The Defense 3
          27: 'professional', // The Premier League Season 4
          103: 'professional', // Dota 2 Champions League
          29: 'professional', // Star Series Season V
          83: 'professional', // CyberGamer Dota 2 Pro League
          33: 'professional', // DreamHack Dota2 Invitational
          48: 'professional', // RaidCall Dota 2 League Season 3
          51: 'professional', // The Defense Season 4
          65: 'professional', // SteelSeries Euro Cup
          69: 'professional', // StarSeries Season 7 - BUNDLE
          78: 'professional', // WePlay.TV Dota 2 League - Season 2
          97: 'professional', // Netolic Pro League 4
          104: 'professional', // HyperX D2L Season 4
          47: 'professional', // RaidCall EMS One Summer 2013
          53: 'professional', // DreamHack ASUS ROG Dota 2 Tournament
          161: 'professional', // SteelSeries Euro Cup Season 3
          7: 'professional', // BeyondTheSummit World Tour
          28: 'professional', // RaidCall EMS One Spring 2013
          65004: 'professional', // The International East Qualifiers
          46: 'professional', // StarSeries Season VI
          12: 'professional', // RaidCall Dota 2 League
          15: 'professional', // Premier League
          26: 'professional', // SEA League
          41: 'professional', // Curse Dota 2 Invitational
          45: 'professional', // Premier League Season 5
          50: 'professional', // American Dota League
          65005: 'professional', // The International West Qualifiers
          181: 'professional', // joinDOTA League
          4: 'professional', // The Defense
          184: 'professional', // MLG T.K.O.
          6: 'professional', // Star Series Season II Lan Final
          13: 'professional', // Star Series Season III
          65001: 'professional', // The International 2012
          24: 'professional', // G-League 2012
          176: 'professional', // Netolic Pro League 5 West
          54: 'professional', // Alienware Cup - 2013 Season 1
          135: 'professional', // Raidcall Southeast Asian Invitational League
          38: 'professional', // E2Max L33T Championship
          58: 'professional', // AMD Dota2 Premier League Season 2
          92: 'professional', // Arms of Burning Turmoil Set
          65008: 'professional', // 2013 National Electronic Sports Tournament
          235: 'professional', // The Monster Invitational
          18: 'professional', // atoD 2
          22: 'professional', // RaidCall Dota 2 League Season 2
          65002: 'professional', // DreamHack Dota 2 Corsair Vengeance Cup
          34: 'professional', // G-1 Champions League Season 5
          40: 'professional', // AMD Dota2 Premier League
          60: 'professional', // Neolution GosuCup
          0: 'amateur', // JetsetPro Amateur League 1x1 Season 1
          67: 'professional', // MLG NA League and Full Sail LAN
          71: 'professional', // The National
          80: 'professional', // Nexon Sponsorship League - ADMIN
          44: 'professional', // Rapture Gaming Network League
          76: 'professional', // Sina Cup Supernova Dota 2 Open
          81: 'professional', // WPC-ACE Dota 2 League
          114: 'professional', // G-League 2013
          177: 'professional', // Netolic Pro League 5 East
          17: 'professional', // G-1 Championship League
          23: 'professional', // Dota 2 The Asia
          37: 'professional', // AtoD 3
          42: 'professional', // Dota 2 Super League
          65007: 'professional', // Nexon Starter League
          57: 'professional', // Corsair Summer 2013
          120: 'professional', // Sina Cup Supernova Dota 2 Open Season 2
          125: 'professional', // Nexon Sponsorship League Season 2 & Gama Brothers Courier
        };
        const openQualifierTier = league => (league.name.indexOf('Open Qualifier') === -1 ? null : 'excluded');
        return async.each(apiLeagues.result.leagues, (l, cb) => {
          const itemSchemaLeague = leagues[l.leagueid] || {};
          l.tier = leagueTiers[l.leagueid] || openQualifierTier(l) || itemSchemaLeague.tier || null;
          l.ticket = itemSchemaLeague.ticket || null;
          l.banner = itemSchemaLeague.banner || null;
          queries.upsert(db, 'leagues', l, {
            leagueid: l.league_id,
          }, cb);
        }, cb);
      },
    );
  });
}
invokeInterval(doLeagues, 30 * 60 * 1000);
<|endoftext|>


<commit_before>module("Basic Tests");

test("Controllers", function() {
    notEqual(null, Ember.Table.TableController, "Ember.Table.TableController exists");
});<commit_msg>Test views presence<commit_after>module("Basic Tests");

test("Controllers", function() {
    notEqual(null, Ember.Table.TableController, "Ember.Table.TableController exists");
});

test("Views", function() {
    notEqual(null, Ember.Table.TablesContainer, "Ember.Table.TablesContainer exists");
    notEqual(null, Ember.Table.TableContainer, "Ember.Table.TableContainer exists");
    notEqual(null, Ember.Table.TableCell, "Ember.Table.TableCell exists");
    notEqual(null, Ember.Table.HeaderRow, "Ember.Table.HeaderRow exists");
    notEqual(null, Ember.Table.HeaderCell, "Ember.Table.HeaderCell exists");
    notEqual(null, Ember.Table.ScrollContainer, "Ember.Table.ScrollContainer exists");
    notEqual(null, Ember.Table.ScrollPanel, "Ember.Table.ScrollPanel exists");
})<|endoftext|>


<commit_before>'use strict';

// idk, 109C wants me to make this.

const { run } = require('../dist/run');
const oldLog = console.log;

const test = function(code, assume) {
  const out = [];
  console.log = function(...args) {
    out.push(args);
    oldLog('\x1b[33;2m[Test Output]\x1b[39m', ...args, '\x1b[0m');
  }
  run(code);
  console.log = oldLog;
  if (!assume(out)) {
    oldLog('\x1b[31m[Errored!]\x1b[0m Assumption failed:\n\x1b[36m' + code
           + '\x1b[0m');
  }
};

const checkOut = function(compare) {
  // this should be called like this:
  // test(code, checkOut`compareThis`)

  // compare: [ compareThis ]
  return function(result) {
    // result: [ [ '{Print}', compareThis ] ]
    return result[0][1] === compare[0];
  };
};

try {
  console.log('Basic printing ---');
  test('print("hello!");', checkOut`hello!`);

  try {
    // WHY IS THIS WORKING!?!?!?!?!?!??
    test('print("hello! this should not work!")\n', checkOut`hello! this should not work!`);
  } catch(err) {
    console.log('Newline as separator doesn\'t work, but it hasn\'t been' +
                'implemented yet so that\'s okay.');
  }
  test('print("hello!")', checkOut`hello!`);
  test("print('single quoted');", checkOut`single quoted`);

  console.log('Math ---');
  test('print(+(3, 4))', checkOut`7`);
  test('print(-(3, 4))', checkOut`-1`);
  test('print(*(3, 4))', checkOut`12`);
  test('print(/(3, 4))', checkOut`0.75`);
  test('print(+(1.25, 1.755))', checkOut`3.005`);

  console.log('If/else ---');
  test(`if(true, fn() {print("good"); });`, checkOut`good`)
} catch(error) {
  console.log = oldLog;
  console.log('\x1b[31m[Errored!]\x1b[0m Error in JS:');
  console.error(error);
}
<commit_msg>last tests commit for now<commit_after>'use strict';

// idk, 109C wants me to make this.

const { run } = require('../dist/run');
const oldLog = console.log;

const test = function(code, assume) {
  const out = [];
  console.log = function(...args) {
    out.push(args);
    oldLog('\x1b[33;2m[Test Output]\x1b[39m', ...args, '\x1b[0m');
  }
  run(code);
  console.log = oldLog;
  if (!assume(out)) {
    oldLog('\x1b[31m[Errored!]\x1b[0m Assumption failed:\n\x1b[36m' + code
           + '\x1b[0m');
  }
};

const checkOut = function(compare) {
  // this should be called like this:
  // test(code, checkOut`compareThis`)

  // compare: [ compareThis ]
  return function(result) {
    // result: [ [ '{Print}', compareThis ] ]
    return result[0][1] === compare[0];
  };
};

try {
  console.log('Basic printing ---');
  test('print("hello!");', checkOut`hello!`);

  try {
    // WHY IS THIS WORKING!?!?!?!?!?!??
    test('print("hello! this should not work!")\n', checkOut`hello! this should not work!`);
  } catch(err) {
    console.log('Newline as separator doesn\'t work, but it hasn\'t been' +
                'implemented yet so that\'s okay.');
  }
  test('print("hello!")', checkOut`hello!`);
  test("print('single quoted');", checkOut`single quoted`);

  console.log('Math ---');
  test('print(+(3, 4));', checkOut`7`);
  test('print(-(3, 4));', checkOut`-1`);
  test('print(*(3, 4));', checkOut`12`);
  test('print(/(3, 4));', checkOut`0.75`);
  test('print(+(1.25, 1.755));', checkOut`3.005`);

  console.log('If/else ---');
  test(`if(true, fn() {print("good"); });`, checkOut`good`)
} catch(error) {
  console.log = oldLog;
  console.log('\x1b[31m[Errored!]\x1b[0m Error in JS:');
  console.error(error);
}
<|endoftext|>