<commit_before>module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    watch: {
      options: {
        livereload: true,
        spawn: false
      },

      // Styling
      scss: {
        files: 'components/**/*.scss',
        tasks: ['newer:imagemin', 'sync', 'compass:development', 'modernizr', 'newer:csslint']
      },

      // Scripting
      js: {
        files: ['components/*.js', 'components/app/**/*.js', '!components/app/_deferred/**/*.js'],
        tasks: ['requirejs:development', 'modernizr', 'newer:jshint'],
      },
      js_deferred: {
        files: ['components/app/_deferred/**/*.js'],
        tasks: ['newer:uglify:deferred_development', 'modernizr', 'newer:jshint'],
      },
      js_bower: {
        files: ['components/libs/**/*.js'],
        tasks: ['newer:uglify:external', 'requirejs:development'],
      },

      // HTML
      html: {
        files: ['*.html', 'components/app/**/*.html' , '!components/libs/**/*.html', '!build/**/*.html'],
        tasks: ['replace', 'newer:accessibility'],
      },

      // Images
      img_content: {
        files: 'img/**/*.{png,gif,jpg,svg}',
        tasks: ['newer:imagemin:content'],
      },
      img_background: {
        files: 'components/**/*.{png,gif,jpg,svg}',
        tasks: ['clean:css', 'newer:imagemin:backgrounds' , 'compass:development', 'clean:css', 'clean:svg', 'newer:csslint'],
      }
    },

    compass: {
      options: {
        asset_cache_buster: false,
        cssDir: 'build/assets/css',
        httpImagesPath: '/assets/img',
        imagesDir: 'build/assets/img',
        noLineComments: true,
        require: 'sass-css-importer',
        sassDir: 'components',
        specify: ['components/*.scss', 'components/app/_deferred/**/*.scss']
      },
      development: {
        options: {
          sourcemap: true,
          environment: 'development'
        }
      },
      production: {
        options: {
          httpPath: "/", // . = relative
          environment: 'production'
        }
      }
    },

    replace: {
      modules: {
        options: {
          patterns: [
            {
              match: /{app:{(.+)}}/g,
              replacement: function (match, placeholder) {
                return grunt.file.read('components/app/' + placeholder + '/' + placeholder + '.html');
              }
            },
            {
              match: /{deferred:{(.+)}}/g,
              replacement: function (match, placeholder) {
                return grunt.file.read('components/app/_deferred/' + placeholder + '/' + placeholder + '.html');
              }
            }
          ]
        },
        files: [
          {
            expand: true,
            flatten: true,
            src: ['*.html'],
            dest: 'build/'
          }
        ]
      }
    },

    requirejs: {
      options: {
        mainConfigFile: "components/<%= ProjectName %>.js",
        name: "<%= ProjectName %>",
        out: "build/assets/js/<%= ProjectName %>.js",
        useStrict: true
      },
      development: {
        options: {
          generateSourceMaps: true,
          optimize: 'none'
        }
      },
      production: {
        options: {
          generateSourceMaps: false,
          optimize: 'uglify'
        }
      }
    },

    uglify: {
      deferred_development: {
        options: {
          sourceMap: true
        },
        files: [{
          expand: true,
          flatten: true,
          cwd: 'components/app/_deferred',
          src: ['**/*.js', '!**/test-*.js'],
          dest: 'build/assets/js/deferred'
        }]
      },
      deferred_production: {
        files: [{
          expand: true,
          flatten: true,
          cwd: 'components/app/_deferred',
          src: ['**/*.js', '!**/test-*.js'],
          dest: 'build/assets/js/deferred'
        }]
      },
      external: {
        files: {
          'build/assets/js/libs/require.js': ['components/libs/requirejs/require.js']
        }
      }
    },

    imagemin: {
      content: {
        files: [{
          flatten: true,
          expand: true,
          cwd: 'img',
          src: ['**/*.{png,jpg,gif,svg}'],
          dest: 'build/img'
        }]
      },
      backgrounds: {
        files: [{
          flatten: true,
          expand: true,
          cwd: 'components/app',
          src: ['**/*.{jpg,gif,png,svg}'],
          dest: 'build/assets/img'
        }]
      }
    },

    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all: ['components/app/**/*.js']
    },

    csslint: {
      options: {
        csslintrc: '.csslintrc',
        import: false
      },
      lax: {
        src: ['build/assets/css/**/*.css']
      }
    },

    accessibility: {
      options : {
        accessibilityLevel: 'WCAG2<%= WCAG2 %>',
        accessibilityrc: true,
        domElement: true,
        reportLevels: {
          notice: false,
          warning: true,
          error: true
        }
      },
      development : {
        files: [{
          expand  : true,
          cwd     : 'build/',
          src     : ['*.html']
        }]
      }
    },

    clean: {
      svg: {
        src: ["build/assets/img/**/*.svg"]
      },
      css: {
        src: ["build/assets/css/**/*.css"]
      },
      build: {
        src: ["build"]
      }
    },

    qunit: {
      foo: ['qunit/qunit-test-suite.html'],
      all: {
        options: {
          urls: [
            'http://localhost:10000/qunit/qunit-test-suite.html'
          ]
        }
      }
    },

    connect: {
      server: {
        options: {
          port: 10000,
          base: '.'
        }
      }
    },

    sync: {
      webfonts: {
        files: [{
          flatten: true,
          expand: true,
          cwd: 'components/app',
          src: ['**/font/*.{ttf,eot,woff,svg}'],
          dest: 'build/assets/font'
        }],
        verbose: true
      },
      json: {
        files: [{
          flatten: true,
          expand: true,
          cwd: 'components/app',
          src: ['**/*.json'],
          dest: 'build/assets/json'
        }],
        verbose: true
      },
      favicon: {
        files: [{
          flatten: true,
          expand: true,
          cwd: '.',
          src: ['favicon.ico', 'apple-touch-icon.png'],
          dest: 'build'
        }],
        verbose: true
      }
    },

    modernizr: {
      dist: {
        "devFile" : "components/libs/modernizr/modernizr.js",
        "outputFile" : "build/assets/js/libs/modernizr.js",
        "extra" : {
          "shiv" : <% if (oldIE) { %>true<% } else { %>false<% } %>,
          "printshiv" : <% if (oldIE) { %>true<% } else { %>false<% } %>,
          "load" : false,
          "mq" : false,
          "cssclasses" : true
        },
        "files" : {
          "src": ['components/app/**/*.js', 'build/**/*.css']
        }
      }
    },

    jsdoc : {
      dist : {
        src: ['components/app/**/*.js'],
        options: {
          destination: 'documentation'
        }
      }
    },

    githooks: {
      all: {
        'pre-commit': 'csslint jshint accessibility connect qunit:all'
      }
    }

  });

  grunt.loadNpmTasks('grunt-accessibility');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-compass');
  grunt.loadNpmTasks('grunt-contrib-csslint');
  grunt.loadNpmTasks('grunt-contrib-imagemin');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks("grunt-modernizr");
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-replace');
  grunt.loadNpmTasks('grunt-sync');
  grunt.loadNpmTasks('grunt-newer');
  grunt.loadNpmTasks('grunt-jsdoc');
  grunt.loadNpmTasks('grunt-githooks');

  grunt.registerTask('default', [
    'replace',
    'imagemin',
    'sync',
    'compass:development',
    'requirejs:development',
    'uglify:deferred_development',
    'uglify:external',
    'clean:svg',
    'modernizr',
    'csslint',
    'jshint',
    'accessibility'
  ]);

  grunt.registerTask('production', [
    'clean:build',
    'replace',
    'imagemin',
    'sync',
    'compass:production',
    'requirejs:production',
    'uglify:deferred_production',
    'uglify:external',
    'clean',
    'modernizr'
   ]);

  grunt.registerTask('test', [
    'connect',
    'qunit:all'
  ]);

  grunt.registerTask('doc', [
    'jsdoc'
  ]);

};
<commit_msg>[FEATURE] prepare tasks for githooks<commit_after>module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    watch: {
      options: {
        livereload: true,
        spawn: false
      },

      // Styling
      scss: {
        files: 'components/**/*.scss',
        tasks: ['newer:imagemin', 'sync', 'compass:development', 'modernizr', 'newer:csslint']
      },

      // Scripting
      js: {
        files: ['components/*.js', 'components/app/**/*.js', '!components/app/_deferred/**/*.js'],
        tasks: ['requirejs:development', 'modernizr', 'newer:jshint'],
      },
      js_deferred: {
        files: ['components/app/_deferred/**/*.js'],
        tasks: ['newer:uglify:deferred_development', 'modernizr', 'newer:jshint'],
      },
      js_bower: {
        files: ['components/libs/**/*.js'],
        tasks: ['newer:uglify:external', 'requirejs:development'],
      },

      // HTML
      html: {
        files: ['*.html', 'components/app/**/*.html' , '!components/libs/**/*.html', '!build/**/*.html'],
        tasks: ['replace', 'newer:accessibility'],
      },

      // Images
      img_content: {
        files: 'img/**/*.{png,gif,jpg,svg}',
        tasks: ['newer:imagemin:content'],
      },
      img_background: {
        files: 'components/**/*.{png,gif,jpg,svg}',
        tasks: ['clean:css', 'newer:imagemin:backgrounds' , 'compass:development', 'clean:css', 'clean:svg', 'newer:csslint'],
      }
    },

    compass: {
      options: {
        asset_cache_buster: false,
        cssDir: 'build/assets/css',
        httpImagesPath: '/assets/img',
        imagesDir: 'build/assets/img',
        noLineComments: true,
        require: 'sass-css-importer',
        sassDir: 'components',
        specify: ['components/*.scss', 'components/app/_deferred/**/*.scss']
      },
      development: {
        options: {
          sourcemap: true,
          environment: 'development'
        }
      },
      production: {
        options: {
          httpPath: "/", // . = relative
          environment: 'production'
        }
      }
    },

    replace: {
      modules: {
        options: {
          patterns: [
            {
              match: /{app:{(.+)}}/g,
              replacement: function (match, placeholder) {
                return grunt.file.read('components/app/' + placeholder + '/' + placeholder + '.html');
              }
            },
            {
              match: /{deferred:{(.+)}}/g,
              replacement: function (match, placeholder) {
                return grunt.file.read('components/app/_deferred/' + placeholder + '/' + placeholder + '.html');
              }
            }
          ]
        },
        files: [
          {
            expand: true,
            flatten: true,
            src: ['*.html'],
            dest: 'build/'
          }
        ]
      }
    },

    requirejs: {
      options: {
        mainConfigFile: "components/<%= ProjectName %>.js",
        name: "<%= ProjectName %>",
        out: "build/assets/js/<%= ProjectName %>.js",
        useStrict: true
      },
      development: {
        options: {
          generateSourceMaps: true,
          optimize: 'none'
        }
      },
      production: {
        options: {
          generateSourceMaps: false,
          optimize: 'uglify'
        }
      }
    },

    uglify: {
      deferred_development: {
        options: {
          sourceMap: true
        },
        files: [{
          expand: true,
          flatten: true,
          cwd: 'components/app/_deferred',
          src: ['**/*.js', '!**/test-*.js'],
          dest: 'build/assets/js/deferred'
        }]
      },
      deferred_production: {
        files: [{
          expand: true,
          flatten: true,
          cwd: 'components/app/_deferred',
          src: ['**/*.js', '!**/test-*.js'],
          dest: 'build/assets/js/deferred'
        }]
      },
      external: {
        files: {
          'build/assets/js/libs/require.js': ['components/libs/requirejs/require.js']
        }
      }
    },

    imagemin: {
      content: {
        files: [{
          flatten: true,
          expand: true,
          cwd: 'img',
          src: ['**/*.{png,jpg,gif,svg}'],
          dest: 'build/img'
        }]
      },
      backgrounds: {
        files: [{
          flatten: true,
          expand: true,
          cwd: 'components/app',
          src: ['**/*.{jpg,gif,png,svg}'],
          dest: 'build/assets/img'
        }]
      }
    },

    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all: ['components/app/**/*.js']
    },

    csslint: {
      options: {
        csslintrc: '.csslintrc',
        import: false
      },
      lax: {
        src: ['build/assets/css/**/*.css']
      }
    },

    accessibility: {
      options : {
        accessibilityLevel: 'WCAG2<%= WCAG2 %>',
        accessibilityrc: true,
        domElement: true,
        reportLevels: {
          notice: false,
          warning: true,
          error: true
        }
      },
      development : {
        files: [{
          expand  : true,
          cwd     : 'build/',
          src     : ['*.html']
        }]
      }
    },

    clean: {
      svg: {
        src: ["build/assets/img/**/*.svg"]
      },
      css: {
        src: ["build/assets/css/**/*.css"]
      },
      build: {
        src: ["build"]
      }
    },

    qunit: {
      foo: ['qunit/qunit-test-suite.html'],
      all: {
        options: {
          urls: [
            'http://localhost:10000/qunit/qunit-test-suite.html'
          ]
        }
      }
    },

    connect: {
      server: {
        options: {
          port: 10000,
          base: '.'
        }
      }
    },

    sync: {
      webfonts: {
        files: [{
          flatten: true,
          expand: true,
          cwd: 'components/app',
          src: ['**/font/*.{ttf,eot,woff,svg}'],
          dest: 'build/assets/font'
        }],
        verbose: true
      },
      json: {
        files: [{
          flatten: true,
          expand: true,
          cwd: 'components/app',
          src: ['**/*.json'],
          dest: 'build/assets/json'
        }],
        verbose: true
      },
      favicon: {
        files: [{
          flatten: true,
          expand: true,
          cwd: '.',
          src: ['favicon.ico', 'apple-touch-icon.png'],
          dest: 'build'
        }],
        verbose: true
      }
    },

    modernizr: {
      dist: {
        "devFile" : "components/libs/modernizr/modernizr.js",
        "outputFile" : "build/assets/js/libs/modernizr.js",
        "extra" : {
          "shiv" : <% if (oldIE) { %>true<% } else { %>false<% } %>,
          "printshiv" : <% if (oldIE) { %>true<% } else { %>false<% } %>,
          "load" : false,
          "mq" : false,
          "cssclasses" : true
        },
        "files" : {
          "src": ['components/app/**/*.js', 'build/**/*.css']
        }
      }
    },

    jsdoc : {
      dist : {
        src: ['components/app/**/*.js'],
        options: {
          destination: 'documentation'
        }
      }
    },

    githooks: {
      all: {
        'pre-commit': 'csslint jshint accessibility connect qunit:all'
      }
    }

  });

  grunt.loadNpmTasks('grunt-accessibility');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-compass');
  grunt.loadNpmTasks('grunt-contrib-csslint');
  grunt.loadNpmTasks('grunt-contrib-imagemin');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks("grunt-modernizr");
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-replace');
  grunt.loadNpmTasks('grunt-sync');
  grunt.loadNpmTasks('grunt-newer');
  grunt.loadNpmTasks('grunt-jsdoc');
  grunt.loadNpmTasks('grunt-githooks');

  grunt.registerTask('default', [
    'replace',
    'imagemin',
    'sync',
    'compass:development',
    'requirejs:development',
    'uglify:deferred_development',
    'uglify:external',
    'clean:svg',
    'modernizr'
  ]);

  grunt.registerTask('production', [
    'clean:build',
    'replace',
    'imagemin',
    'sync',
    'compass:production',
    'requirejs:production',
    'uglify:deferred_production',
    'uglify:external',
    'clean',
    'modernizr'
   ]);

  grunt.registerTask('test', [
    'csslint',
    'jshint',
    'accessibility',
    'connect',
    'qunit:all'
  ]);

  grunt.registerTask('doc', [
    'jsdoc'
  ]);

};
<|endoftext|>


<commit_before>// Karma configuration
// Generated on Sun Mar 29 2015 10:00:42 GMT-0700 (Pacific Daylight Time)

module.exports = function(config) {
  var configuration = {

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha', 'chai', 'sinon'],

    // list of files / patterns to load in the browser
    files: [
      'client/dist/dependencies.js',
      'client/dist/debug.js',
      'client/dist/templates.js',
      'client/phoenixeye.module.js',
      'client/!(dist)/**/*.js',
      // 'client/html/**/*.html',
      'bower_components/angular-mocks/angular-mocks.js',
      'test/src/client/**/*.js'
    ],

    // list of files to exclude
    exclude: [
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      // 'client/html/**/*.html': ['ng-html2js'],
      'client/!(dist)/**/*.js': ['coverage']
    },

    // ngHtml2JsPreprocessor: {
    //   stripPrefix: 'client/',
    //   moduleName: 'phoenixeye.templates'
    // },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['mocha', 'coverage'],

    coverageReporter: {
      type : 'lcov',
      dir : 'test/coverage/client'
    },

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    // browsers: ['Chrome', 'Firefox', 'IE'],
    browsers: ['Firefox'],

    // customLaunchers: {
    //   Chrome_travis_ci: {
    //     base: 'Chrome',
    //     flags: ['--no-sandbox']
    //   }
    // },

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true
  };

  // if(process.env.TRAVIS){
  //   configuration.browsers = ['Chrome_travis_ci'];
  // }

  config.set(configuration);
};
<commit_msg>karma.conf indentation<commit_after>// Karma configuration
// Generated on Sun Mar 29 2015 10:00:42 GMT-0700 (Pacific Daylight Time)

module.exports = function(config) {
	var configuration = {

		// base path that will be used to resolve all patterns (eg. files, exclude)
		basePath: '',

		// frameworks to use
		// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
		frameworks: ['mocha', 'chai', 'sinon'],

		// list of files / patterns to load in the browser
		files: [
			'client/dist/dependencies.js',
			'client/dist/debug.js',
			'client/dist/templates.js',
			'client/phoenixeye.module.js',
			'client/!(dist)/**/*.js',
			// 'client/html/**/*.html',
			'bower_components/angular-mocks/angular-mocks.js',
			'test/src/client/**/*.js'
		],

		// list of files to exclude
		exclude: [
		],

		// preprocess matching files before serving them to the browser
		// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
		preprocessors: {
			// 'client/html/**/*.html': ['ng-html2js'],
			'client/!(dist)/**/*.js': ['coverage']
		},

		// ngHtml2JsPreprocessor: {
		//   stripPrefix: 'client/',
		//   moduleName: 'phoenixeye.templates'
		// },

		// test results reporter to use
		// possible values: 'dots', 'progress'
		// available reporters: https://npmjs.org/browse/keyword/karma-reporter
		reporters: ['mocha', 'coverage'],

		coverageReporter: {
			type : 'lcov',
			dir : 'test/coverage/client'
		},

		// web server port
		port: 9876,

		// enable / disable colors in the output (reporters and logs)
		colors: true,

		// level of logging
		// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
		logLevel: config.LOG_INFO,

		// enable / disable watching file and executing tests whenever any file changes
		autoWatch: false,

		// start these browsers
		// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
		// browsers: ['Chrome', 'Firefox', 'IE'],
		browsers: ['Firefox'],

		// customLaunchers: {
		//   Chrome_travis_ci: {
		//     base: 'Chrome',
		//     flags: ['--no-sandbox']
		//   }
		// },

		// Continuous Integration mode
		// if true, Karma captures browsers, runs the tests and exits
		singleRun: true
	};

	// if(process.env.TRAVIS){
	//   configuration.browsers = ['Chrome_travis_ci'];
	// }

	config.set(configuration);
};
<|endoftext|>


<commit_before>var pull = require('../')
var test = require('tape')

test('through - onEnd', function (t) {
  t.plan(2)
  var values = [1,2,3,4,5,6,7,8,9,10]

  //read values, and then just stop!
  //this is a subtle edge case for take!

//I did have a thing that used this edge case,
//but it broke take, actually. so removing it.
//TODO: fix that thing - was a test for some level-db stream thing....

//  pull.Source(function () {
//    return function (end, cb) {
//      if(end) cb(end)
//      else if(values.length)
//        cb(null, values.shift())
//      else console.log('drop')
//    }
//  })()

  pull(
    pull.values(values),
    pull.take(10),
    pull.through(null, function (err) {
      console.log('end')
      t.ok(true)
      process.nextTick(function () {
        t.end()
      })
    }),
    pull.collect(function (err, ary) {
      console.log(ary)
      t.ok(true)
    })
  )
})

test('take - exclude last (default)', function (t) {
  pull(
    pull.values([1,2,3,4,5,6,7,8,9,10]),
    pull.take(function(n) {return n<5}),
    pull.collect(function (err, four) {
      t.deepEqual(four, [1,2,3,4])
      t.end()
    })
  )
})
test('take - include last', function (t) {
  pull(
    pull.values([1,2,3,4,5,6,7,8,9,10]),
    pull.take(function(n) {return n<5}, {last: true}),
    pull.collect(function (err, five) {
      t.deepEqual(five, [1,2,3,4,5])
      t.end()
    })
  )
})

test('take 5 causes 5 reads upstream', function (t) {
  var reads = 0
  pull(
    pull.values([1,2,3,4,5,6,7,8,9,10]),
    function (read) {
      return function (end, cb) {
        if (end !== true) reads++
        console.log(reads, end)
        read(end, cb)
      }
    },
    pull.take(5),
    pull.collect(function (err, five) {
      t.deepEqual(five, [1,2,3,4,5])
      process.nextTick(function() {
          t.equal(reads, 5)
          t.end()
        })
    })
  )
})

test("take doesn't abort until the last read", function (t) {

  var aborted = false

  var ary = [1,2,3,4,5], i = 0

  var read = pull(
    function (abort, cb) {
      if(abort) cb(aborted = true)
      else if(i > ary.length) cb(true)
      else cb(null, ary[i++])
    },
    pull.take(function (d) {
      return d < 3
    }, {last: true})
  )

  read(null, function (_, d) {
    t.notOk(aborted, "hasn't aborted yet")
    read(null, function (_, d) {
      t.notOk(aborted, "hasn't aborted yet")
      read(null, function (_, d) {
        t.notOk(aborted, "hasn't aborted yet")
        read(null, function (end, d) {
          t.ok(end, 'stream ended')
          t.equal(d, undefined, 'data undefined')
          t.ok(aborted, "has aborted by now")
          t.end()
        })
      })
    })
  })

})

test('take should throw error on last read', function (t) {
  var i = 0
  var error = new Error('error on last call')

  pull(
    pull.values([1,2,3,4,5,6,7,8,9,10]),
    pull.take(function(n) {return n<5}, {last: true}),
    // pull.take(5),
    pull.asyncMap((data, cb) => {
      setTimeout(() => {
        if(++i < 5) cb(null, data)
        else cb(error)
      }, 100)
    }),
    pull.collect(function (err, five) {
      t.equal(err, error, 'should return err')
      t.deepEqual(five, [1,2,3,4], 'should skip failed item')
      t.end()
    })
  )
})
<commit_msg>use ES5 so that travis tests pass<commit_after>var pull = require('../')
var test = require('tape')

test('through - onEnd', function (t) {
  t.plan(2)
  var values = [1,2,3,4,5,6,7,8,9,10]

  //read values, and then just stop!
  //this is a subtle edge case for take!

//I did have a thing that used this edge case,
//but it broke take, actually. so removing it.
//TODO: fix that thing - was a test for some level-db stream thing....

//  pull.Source(function () {
//    return function (end, cb) {
//      if(end) cb(end)
//      else if(values.length)
//        cb(null, values.shift())
//      else console.log('drop')
//    }
//  })()

  pull(
    pull.values(values),
    pull.take(10),
    pull.through(null, function (err) {
      console.log('end')
      t.ok(true)
      process.nextTick(function () {
        t.end()
      })
    }),
    pull.collect(function (err, ary) {
      console.log(ary)
      t.ok(true)
    })
  )
})

test('take - exclude last (default)', function (t) {
  pull(
    pull.values([1,2,3,4,5,6,7,8,9,10]),
    pull.take(function(n) {return n<5}),
    pull.collect(function (err, four) {
      t.deepEqual(four, [1,2,3,4])
      t.end()
    })
  )
})
test('take - include last', function (t) {
  pull(
    pull.values([1,2,3,4,5,6,7,8,9,10]),
    pull.take(function(n) {return n<5}, {last: true}),
    pull.collect(function (err, five) {
      t.deepEqual(five, [1,2,3,4,5])
      t.end()
    })
  )
})

test('take 5 causes 5 reads upstream', function (t) {
  var reads = 0
  pull(
    pull.values([1,2,3,4,5,6,7,8,9,10]),
    function (read) {
      return function (end, cb) {
        if (end !== true) reads++
        console.log(reads, end)
        read(end, cb)
      }
    },
    pull.take(5),
    pull.collect(function (err, five) {
      t.deepEqual(five, [1,2,3,4,5])
      process.nextTick(function() {
          t.equal(reads, 5)
          t.end()
        })
    })
  )
})

test("take doesn't abort until the last read", function (t) {

  var aborted = false

  var ary = [1,2,3,4,5], i = 0

  var read = pull(
    function (abort, cb) {
      if(abort) cb(aborted = true)
      else if(i > ary.length) cb(true)
      else cb(null, ary[i++])
    },
    pull.take(function (d) {
      return d < 3
    }, {last: true})
  )

  read(null, function (_, d) {
    t.notOk(aborted, "hasn't aborted yet")
    read(null, function (_, d) {
      t.notOk(aborted, "hasn't aborted yet")
      read(null, function (_, d) {
        t.notOk(aborted, "hasn't aborted yet")
        read(null, function (end, d) {
          t.ok(end, 'stream ended')
          t.equal(d, undefined, 'data undefined')
          t.ok(aborted, "has aborted by now")
          t.end()
        })
      })
    })
  })

})

test('take should throw error on last read', function (t) {
  var i = 0
  var error = new Error('error on last call')

  pull(
    pull.values([1,2,3,4,5,6,7,8,9,10]),
    pull.take(function(n) {return n<5}, {last: true}),
    // pull.take(5),
    pull.asyncMap(function (data, cb) {
      setTimeout(() => {
        if(++i < 5) cb(null, data)
        else cb(error)
      }, 100)
    }),
    pull.collect(function (err, five) {
      t.equal(err, error, 'should return err')
      t.deepEqual(five, [1,2,3,4], 'should skip failed item')
      t.end()
    })
  )
})
<|endoftext|>


<commit_before>var twiliochat = (function() {
  var tc = {};

  var GENERAL_CHANNEL_UNIQUE_NAME = 'general';
  var GENERAL_CHANNEL_NAME = 'General Channel';
  var MESSAGES_HISTORY_LIMIT = 50;

  var $channelList;
  var $inputText;
  var $usernameInput;
  var $usernameSpan;
  var $statusRow;
  var $connectPanel;
  var $connectImage;
  var $addChannelImage;
  var $leaveSpan;
  var $newChannelInputRow;
  var $newChannelInput;
  var $deleteChannelSpan;
  var $typingRow;
  var $typingPlaceholder;

  $(document).ready(function() {
    tc.$messageList = $('#message-list');
    $channelList = $('#channel-list');
    $inputText = $('#input-text');
    $usernameInput = $('#username-input');
    $usernameSpan = $('#username-span');
    $statusRow = $('#status-row');
    $connectPanel = $('#connect-panel');
    $connectImage = $('#connect-image');
    $leaveSpan = $('#leave-span');
    $addChannelImage = $('#add-channel-image');
    $newChannelInputRow = $('#new-channel-input-row');
    $newChannelInput = $('#new-channel-input');
    $deleteChannelSpan = $('#delete-channel-span');
    $typingRow = $('#typing-row');
    $typingPlaceholder = $('#typing-placeholder');
    $usernameInput.focus();
    $usernameInput.on('keypress', handleUsernameInputKeypress);
    $inputText.on('keypress', handleInputTextKeypress);
    $newChannelInput.on('keypress', tc.handleNewChannelInputKeypress);
    $connectImage.on('click', connectClientWithUsername);
    $addChannelImage.on('click', showAddChannelInput);
    $leaveSpan.on('click', disconnectClient);
    $deleteChannelSpan.on('click', deleteCurrentChannel);
  });

  function handleUsernameInputKeypress(event) {
    if (event.keyCode === 13){
      connectClientWithUsername();
    }
  }

  function handleInputTextKeypress(event) {
    if (event.keyCode === 13) {
      tc.currentChannel.sendMessage($(this).val());
      event.preventDefault();
      $(this).val('');
    }
    else {
      notifyTyping();
    }
  }

  var notifyTyping = $.throttle(function() {
    tc.currentChannel.typing();
  }, 1000);

  tc.handleNewChannelInputKeypress = function(event) {
    if (event.keyCode === 13) {
      tc.messagingClient.createChannel({
        friendlyName: $newChannelInput.val()
      }).then(hideAddChannelInput);
      $(this).val('');
      event.preventDefault();
    }
  };

  function connectClientWithUsername() {
    var usernameText = $usernameInput.val();
    $usernameInput.val('');
    if (usernameText == '') {
      alert('Username cannot be empty');
      return;
    }
    tc.username = usernameText;
    fetchAccessToken(tc.username, connectMessagingClient);
  }

  function fetchAccessToken(username, handler) {
    $.post('/token', {
      identity: username,
      device: 'browser'
    }, function(data) {
      handler(data);
    }, 'json');
  }

  function connectMessagingClient(tokenResponse) {
    // Initialize the IP messaging client
    tc.accessManager = new Twilio.AccessManager(tokenResponse.token);
    tc.messagingClient = new Twilio.IPMessaging.Client(tc.accessManager);
    updateConnectedUI();
    tc.loadChannelList(tc.joinGeneralChannel);
    tc.messagingClient.on('channelAdded', $.throttle(tc.loadChannelList));
    tc.messagingClient.on('channelRemoved', $.throttle(tc.loadChannelList));
    tc.messagingClient.on('tokenExpired', refreshToken);
  }

  function refreshToken() {
    fetchAccessToken(username, setNewToken);
  }

  function setNewToken(tokenResponse) {
    tc.accessManager.updateToken(tokenResponse.token);
  }

  function updateConnectedUI() {
    $usernameSpan.text(tc.username);
    $statusRow.addClass('connected').removeClass('disconnected');
    tc.$messageList.addClass('connected').removeClass('disconnected');
    $connectPanel.addClass('connected').removeClass('disconnected');
    $inputText.addClass('with-shadow');
    $typingRow.addClass('connected').removeClass('disconnected');
  }

  tc.loadChannelList = function(handler) {
    if (tc.messagingClient === undefined) {
      console.log('Client is not initialized');
      return;
    }

    tc.messagingClient.getChannels().then(function(channels) {
      tc.channelArray = tc.sortChannelsByName(channels);
      $channelList.text('');
      tc.channelArray.forEach(addChannel);
      if (typeof handler === 'function') {
        handler();
      }
    });
  };

  tc.joinGeneralChannel = function() {
    console.log('Attempting to join "general" chat channel...');
    if (!tc.generalChannel) {
      // If it doesn't exist, let's create it
      tc.messagingClient.createChannel({
        uniqueName: GENERAL_CHANNEL_UNIQUE_NAME,
        friendlyName: GENERAL_CHANNEL_NAME
      }).then(function(channel) {
        console.log('Created general channel');
        tc.generalChannel = channel;
        tc.loadChannelList(tc.joinGeneralChannel);
      });
    }
    else {
      console.log('Found general channel:');
      setupChannel(tc.generalChannel);
    }
  };

  function setupChannel(channel) {
    // Join the channel
    channel.join().then(function(joinedChannel) {
      console.log('Joined channel ' + joinedChannel.friendlyName);
      leaveCurrentChannel();
      updateChannelUI(channel);
      tc.currentChannel = channel;
      tc.loadMessages();
      channel.on('messageAdded', tc.addMessageToList);
      channel.on('typingStarted', showTypingStarted);
      channel.on('typingEnded', hideTypingStarted);
      channel.on('memberJoined', notifyMemberJoined);
      channel.on('memberLeft', notifyMemberLeft);
      $inputText.prop('disabled', false).focus();
      tc.$messageList.text('');
    });
  }

  tc.loadMessages = function() {
    tc.currentChannel.getMessages(MESSAGES_HISTORY_LIMIT).then(function (messages) {
      messages.forEach(tc.addMessageToList);
    });
  };

  function leaveCurrentChannel() {
    if (tc.currentChannel) {
      tc.currentChannel.leave().then(function(leftChannel) {
        console.log('left ' + leftChannel.friendlyName);
        leftChannel.removeListener('messageAdded', tc.addMessageToList);
        leftChannel.removeListener('typingStarted', showTypingStarted);
        leftChannel.removeListener('typingEnded', hideTypingStarted);
        leftChannel.removeListener('memberJoined', notifyMemberJoined);
        leftChannel.removeListener('memberLeft', notifyMemberLeft);
      });
    }
  }

  tc.addMessageToList = function(message) {
    var rowDiv = $('<div>').addClass('row no-margin');
    rowDiv.loadTemplate($('#message-template'), {
      username: message.author,
      date: getTodayDate(message.timestamp),
      body: message.body
    });
    if (message.author === tc.username) {
      rowDiv.addClass('own-message');
    }

    tc.$messageList.append(rowDiv);
    scrollToMessageListBottom();
  };

  function notifyMemberJoined(member) {
    notify(member.identity + ' joined the channel')
  }

  function notifyMemberLeft(member) {
    notify(member.identity + ' left the channel');
  }

  function notify(message) {
    var row = $('<div>').addClass('col-md-12');
    row.loadTemplate('#member-notification-template', {
      status: message
    });
    tc.$messageList.append(row);
    scrollToMessageListBottom();
  }

  function showTypingStarted(member) {
    $typingPlaceholder.html(member.identity + ' is typing...');
  }

  function hideTypingStarted(member) {
    $typingPlaceholder.html('');
  }

  function scrollToMessageListBottom() {
    tc.$messageList.scrollTop(tc.$messageList[0].scrollHeight);
  }

  function updateChannelUI(selectedChannel) {
    var channelElements = $('.channel-element').toArray();
    var channelElement = channelElements.filter(function(element) {
      return $(element).data().sid === selectedChannel.sid;
    });
    channelElement = $(channelElement);
    if (tc.currentChannelContainer === undefined && selectedChannel.uniqueName === GENERAL_CHANNEL_UNIQUE_NAME) {
      tc.currentChannelContainer = channelElement;
    }
    tc.currentChannelContainer.removeClass('selected-channel').addClass('unselected-channel');
    channelElement.removeClass('unselected-channel').addClass('selected-channel');
    tc.currentChannelContainer = channelElement;
  }

  function showAddChannelInput() {
    if (tc.messagingClient) {
      $newChannelInputRow.addClass('showing').removeClass('not-showing');
      $channelList.addClass('showing').removeClass('not-showing');
      $newChannelInput.focus();
    }
  }

  function hideAddChannelInput() {
    $newChannelInputRow.addClass('not-showing').removeClass('showing');
    $channelList.addClass('not-showing').removeClass('showing');
    $newChannelInput.val('');
  }

  function addChannel(channel) {
    if (channel.uniqueName === GENERAL_CHANNEL_UNIQUE_NAME) {
      tc.generalChannel = channel;
    }
    var rowDiv = $('<div>').addClass('row channel-row');
    rowDiv.loadTemplate('#channel-template', {
      channelName: channel.friendlyName
    });

    var channelP = rowDiv.children().children().first();

    rowDiv.on('click', selectChannel);
    channelP.data('sid', channel.sid);
    if (tc.currentChannel && channel.sid === tc.currentChannel.sid) {
      tc.currentChannelContainer = channelP;
      channelP.addClass('selected-channel');
    }
    else {
      channelP.addClass('unselected-channel')
    }

    $channelList.append(rowDiv);
  }

  function deleteCurrentChannel() {
    if (!tc.currentChannel) {
      return;
    }
    if (tc.currentChannel.sid === tc.generalChannel.sid) {
      alert('You cannot delete the general channel');
      return;
    }
    tc.currentChannel.delete().then(function(channel) {
      console.log('channel: '+ channel.friendlyName + ' deleted');
      setupChannel(tc.generalChannel);
    });
  }

  function selectChannel(event) {
    var target = $(event.target);
    var channelSid = target.data().sid;
    var selectedChannel = tc.channelArray.filter(function(channel) {
      return channel.sid === channelSid;
    })[0];
    if (selectedChannel === tc.currentChannel) {
      return;
    }
    setupChannel(selectedChannel);
  };

  function disconnectClient() {
    leaveCurrentChannel();
    $channelList.text('');
    tc.$messageList.text('');
    channels = undefined;
    $statusRow.addClass('disconnected').removeClass('connected');
    tc.$messageList.addClass('disconnected').removeClass('connected');
    $connectPanel.addClass('disconnected').removeClass('connected');
    $inputText.removeClass('with-shadow');
    $typingRow.addClass('disconnected').removeClass('connected');
  }

  tc.sortChannelsByName = function(channels) {
    return channels.sort(function(a, b) {
      if (a.friendlyName === GENERAL_CHANNEL_NAME) {
        return -1;
      }
      if (b.friendlyName === GENERAL_CHANNEL_NAME) {
        return 1;
      }
      return a.friendlyName.localeCompare(b.friendlyName);
    });
  };

  return tc;
})();
<commit_msg>remove unnecessary jQuery objects<commit_after>var twiliochat = (function() {
  var tc = {};

  var GENERAL_CHANNEL_UNIQUE_NAME = 'general';
  var GENERAL_CHANNEL_NAME = 'General Channel';
  var MESSAGES_HISTORY_LIMIT = 50;

  var $channelList;
  var $inputText;
  var $usernameInput;
  var $statusRow;
  var $connectPanel;
  var $newChannelInputRow;
  var $newChannelInput;
  var $typingRow;
  var $typingPlaceholder;

  $(document).ready(function() {
    tc.$messageList = $('#message-list');
    $channelList = $('#channel-list');
    $inputText = $('#input-text');
    $usernameInput = $('#username-input');
    $statusRow = $('#status-row');
    $connectPanel = $('#connect-panel');
    $newChannelInputRow = $('#new-channel-input-row');
    $newChannelInput = $('#new-channel-input');
    $typingRow = $('#typing-row');
    $typingPlaceholder = $('#typing-placeholder');
    $usernameInput.focus();
    $usernameInput.on('keypress', handleUsernameInputKeypress);
    $inputText.on('keypress', handleInputTextKeypress);
    $newChannelInput.on('keypress', tc.handleNewChannelInputKeypress);
    $('#connect-image').on('click', connectClientWithUsername);
    $('#add-channel-image').on('click', showAddChannelInput);
    $('#leave-span').on('click', disconnectClient);
    $('#delete-channel-span').on('click', deleteCurrentChannel);
  });

  function handleUsernameInputKeypress(event) {
    if (event.keyCode === 13){
      connectClientWithUsername();
    }
  }

  function handleInputTextKeypress(event) {
    if (event.keyCode === 13) {
      tc.currentChannel.sendMessage($(this).val());
      event.preventDefault();
      $(this).val('');
    }
    else {
      notifyTyping();
    }
  }

  var notifyTyping = $.throttle(function() {
    tc.currentChannel.typing();
  }, 1000);

  tc.handleNewChannelInputKeypress = function(event) {
    if (event.keyCode === 13) {
      tc.messagingClient.createChannel({
        friendlyName: $newChannelInput.val()
      }).then(hideAddChannelInput);
      $(this).val('');
      event.preventDefault();
    }
  };

  function connectClientWithUsername() {
    var usernameText = $usernameInput.val();
    $usernameInput.val('');
    if (usernameText == '') {
      alert('Username cannot be empty');
      return;
    }
    tc.username = usernameText;
    fetchAccessToken(tc.username, connectMessagingClient);
  }

  function fetchAccessToken(username, handler) {
    $.post('/token', {
      identity: username,
      device: 'browser'
    }, function(data) {
      handler(data);
    }, 'json');
  }

  function connectMessagingClient(tokenResponse) {
    // Initialize the IP messaging client
    tc.accessManager = new Twilio.AccessManager(tokenResponse.token);
    tc.messagingClient = new Twilio.IPMessaging.Client(tc.accessManager);
    updateConnectedUI();
    tc.loadChannelList(tc.joinGeneralChannel);
    tc.messagingClient.on('channelAdded', $.throttle(tc.loadChannelList));
    tc.messagingClient.on('channelRemoved', $.throttle(tc.loadChannelList));
    tc.messagingClient.on('tokenExpired', refreshToken);
  }

  function refreshToken() {
    fetchAccessToken(username, setNewToken);
  }

  function setNewToken(tokenResponse) {
    tc.accessManager.updateToken(tokenResponse.token);
  }

  function updateConnectedUI() {
    $('#username-span').text(tc.username);
    $statusRow.addClass('connected').removeClass('disconnected');
    tc.$messageList.addClass('connected').removeClass('disconnected');
    $connectPanel.addClass('connected').removeClass('disconnected');
    $inputText.addClass('with-shadow');
    $typingRow.addClass('connected').removeClass('disconnected');
  }

  tc.loadChannelList = function(handler) {
    if (tc.messagingClient === undefined) {
      console.log('Client is not initialized');
      return;
    }

    tc.messagingClient.getChannels().then(function(channels) {
      tc.channelArray = tc.sortChannelsByName(channels);
      $channelList.text('');
      tc.channelArray.forEach(addChannel);
      if (typeof handler === 'function') {
        handler();
      }
    });
  };

  tc.joinGeneralChannel = function() {
    console.log('Attempting to join "general" chat channel...');
    if (!tc.generalChannel) {
      // If it doesn't exist, let's create it
      tc.messagingClient.createChannel({
        uniqueName: GENERAL_CHANNEL_UNIQUE_NAME,
        friendlyName: GENERAL_CHANNEL_NAME
      }).then(function(channel) {
        console.log('Created general channel');
        tc.generalChannel = channel;
        tc.loadChannelList(tc.joinGeneralChannel);
      });
    }
    else {
      console.log('Found general channel:');
      setupChannel(tc.generalChannel);
    }
  };

  function setupChannel(channel) {
    // Join the channel
    channel.join().then(function(joinedChannel) {
      console.log('Joined channel ' + joinedChannel.friendlyName);
      leaveCurrentChannel();
      updateChannelUI(channel);
      tc.currentChannel = channel;
      tc.loadMessages();
      channel.on('messageAdded', tc.addMessageToList);
      channel.on('typingStarted', showTypingStarted);
      channel.on('typingEnded', hideTypingStarted);
      channel.on('memberJoined', notifyMemberJoined);
      channel.on('memberLeft', notifyMemberLeft);
      $inputText.prop('disabled', false).focus();
      tc.$messageList.text('');
    });
  }

  tc.loadMessages = function() {
    tc.currentChannel.getMessages(MESSAGES_HISTORY_LIMIT).then(function (messages) {
      messages.forEach(tc.addMessageToList);
    });
  };

  function leaveCurrentChannel() {
    if (tc.currentChannel) {
      tc.currentChannel.leave().then(function(leftChannel) {
        console.log('left ' + leftChannel.friendlyName);
        leftChannel.removeListener('messageAdded', tc.addMessageToList);
        leftChannel.removeListener('typingStarted', showTypingStarted);
        leftChannel.removeListener('typingEnded', hideTypingStarted);
        leftChannel.removeListener('memberJoined', notifyMemberJoined);
        leftChannel.removeListener('memberLeft', notifyMemberLeft);
      });
    }
  }

  tc.addMessageToList = function(message) {
    var rowDiv = $('<div>').addClass('row no-margin');
    rowDiv.loadTemplate($('#message-template'), {
      username: message.author,
      date: getTodayDate(message.timestamp),
      body: message.body
    });
    if (message.author === tc.username) {
      rowDiv.addClass('own-message');
    }

    tc.$messageList.append(rowDiv);
    scrollToMessageListBottom();
  };

  function notifyMemberJoined(member) {
    notify(member.identity + ' joined the channel')
  }

  function notifyMemberLeft(member) {
    notify(member.identity + ' left the channel');
  }

  function notify(message) {
    var row = $('<div>').addClass('col-md-12');
    row.loadTemplate('#member-notification-template', {
      status: message
    });
    tc.$messageList.append(row);
    scrollToMessageListBottom();
  }

  function showTypingStarted(member) {
    $typingPlaceholder.text(member.identity + ' is typing...');
  }

  function hideTypingStarted(member) {
    $typingPlaceholder.text('');
  }

  function scrollToMessageListBottom() {
    tc.$messageList.scrollTop(tc.$messageList[0].scrollHeight);
  }

  function updateChannelUI(selectedChannel) {
    var channelElements = $('.channel-element').toArray();
    var channelElement = channelElements.filter(function(element) {
      return $(element).data().sid === selectedChannel.sid;
    });
    channelElement = $(channelElement);
    if (tc.currentChannelContainer === undefined && selectedChannel.uniqueName === GENERAL_CHANNEL_UNIQUE_NAME) {
      tc.currentChannelContainer = channelElement;
    }
    tc.currentChannelContainer.removeClass('selected-channel').addClass('unselected-channel');
    channelElement.removeClass('unselected-channel').addClass('selected-channel');
    tc.currentChannelContainer = channelElement;
  }

  function showAddChannelInput() {
    if (tc.messagingClient) {
      $newChannelInputRow.addClass('showing').removeClass('not-showing');
      $channelList.addClass('showing').removeClass('not-showing');
      $newChannelInput.focus();
    }
  }

  function hideAddChannelInput() {
    $newChannelInputRow.addClass('not-showing').removeClass('showing');
    $channelList.addClass('not-showing').removeClass('showing');
    $newChannelInput.val('');
  }

  function addChannel(channel) {
    if (channel.uniqueName === GENERAL_CHANNEL_UNIQUE_NAME) {
      tc.generalChannel = channel;
    }
    var rowDiv = $('<div>').addClass('row channel-row');
    rowDiv.loadTemplate('#channel-template', {
      channelName: channel.friendlyName
    });

    var channelP = rowDiv.children().children().first();

    rowDiv.on('click', selectChannel);
    channelP.data('sid', channel.sid);
    if (tc.currentChannel && channel.sid === tc.currentChannel.sid) {
      tc.currentChannelContainer = channelP;
      channelP.addClass('selected-channel');
    }
    else {
      channelP.addClass('unselected-channel')
    }

    $channelList.append(rowDiv);
  }

  function deleteCurrentChannel() {
    if (!tc.currentChannel) {
      return;
    }
    if (tc.currentChannel.sid === tc.generalChannel.sid) {
      alert('You cannot delete the general channel');
      return;
    }
    tc.currentChannel.delete().then(function(channel) {
      console.log('channel: '+ channel.friendlyName + ' deleted');
      setupChannel(tc.generalChannel);
    });
  }

  function selectChannel(event) {
    var target = $(event.target);
    var channelSid = target.data().sid;
    var selectedChannel = tc.channelArray.filter(function(channel) {
      return channel.sid === channelSid;
    })[0];
    if (selectedChannel === tc.currentChannel) {
      return;
    }
    setupChannel(selectedChannel);
  };

  function disconnectClient() {
    leaveCurrentChannel();
    $channelList.text('');
    tc.$messageList.text('');
    channels = undefined;
    $statusRow.addClass('disconnected').removeClass('connected');
    tc.$messageList.addClass('disconnected').removeClass('connected');
    $connectPanel.addClass('disconnected').removeClass('connected');
    $inputText.removeClass('with-shadow');
    $typingRow.addClass('disconnected').removeClass('connected');
  }

  tc.sortChannelsByName = function(channels) {
    return channels.sort(function(a, b) {
      if (a.friendlyName === GENERAL_CHANNEL_NAME) {
        return -1;
      }
      if (b.friendlyName === GENERAL_CHANNEL_NAME) {
        return 1;
      }
      return a.friendlyName.localeCompare(b.friendlyName);
    });
  };

  return tc;
})();
<|endoftext|>


<commit_before>if (process.env.TRAVIS) {
  configuration.browsers = ['Chrome_travis_ci'];
}

module.exports = function (config) {
  config.set({
    frameworks: ["jasmine", "karma-typescript"],
    files: [{
        pattern: "src/**/*.ts"
      },
      {
        pattern: "test/**/*.ts"
      }
    ],
    preprocessors: {
      "src/**/*.ts": ["karma-typescript"],
      "test/**/*.ts": ["karma-typescript"]
    },
    karmaTypescriptConfig: {
      tsconfig: "./tsconfig.spec.json"
    },
    reporters: ["progress", "karma-typescript"],
    browsers: ["Chrome"],
    customLaunchers: {
      Chrome_travis_ci: {
        base: 'Chrome',
        flags: ['--no-sandbox']
      }
    }
  });
};<commit_msg>Made some changes to travis to get chrome to work hopefully<commit_after>module.exports = function (config) {
  var configuration = {
    frameworks: ["jasmine", "karma-typescript"],
    files: [{
        pattern: "src/**/*.ts"
      },
      {
        pattern: "test/**/*.ts"
      }
    ],
    preprocessors: {
      "src/**/*.ts": ["karma-typescript"],
      "test/**/*.ts": ["karma-typescript"]
    },
    karmaTypescriptConfig: {
      tsconfig: "./tsconfig.spec.json"
    },
    reporters: ["progress", "karma-typescript"],
    browsers: ["Chrome"],
    customLaunchers: {
      Chrome_travis_ci: {
        base: 'Chrome',
        flags: ['--no-sandbox']
      }
    }
  };

  if (process.env.TRAVIS) {
    configuration.browsers = ['Chrome_travis_ci'];
  }

  config.set(configuration);
};<|endoftext|>


<commit_before>// nav code
var nav = {
  bodyClass: "show-mobile-menu",
  targetEl: "#site-navigation",
  hideClass: "hide-menu",
  showClass: "show-menu",
  removeClassCheck: function() {
    if ( $( "body" ).hasClass( "show-mobile-search" ) ) {
      $( "body" ).removeClass( "show-mobile-search" );
      $( "#searchform" ).addClass( "hide-searchbox" ).removeClass( "show-searchbox" );
    }
  },
  singleRemoveClass: function() {
    $( "#searchform" ).removeClass( "hide-searchbox" );
  }
};

// search code
var search = {
  bodyClass: "show-mobile-search",
  targetEl: "#searchform",
  hideClass: "hide-searchbox",
  showClass: "show-searchbox",
  removeClassCheck: function() {
    if ( $( "body" ).hasClass( "show-mobile-menu" ) ) {
      $( "body" ).removeClass( "show-mobile-menu" );
      $( "#site-navigation" ).addClass( "hide-menu" ).removeClass( "show-menu" );
    }
  },
  singleRemoveClass: function() {
    $( "#site-navigation" ).removeClass( "hide-menu" );
  }
};

function animateNavElement( obj ) {
  if( $( "body" ).hasClass( obj.bodyClass ) ) {
    Q.fcall( function(){
      $( obj.targetEl ).addClass( obj.hideClass );
      $( "body" ).removeClass( obj.bodyClass );
      return Q.delay( 300 );
    }).then( function(){
      $( obj.targetEl ).removeClass( obj.hideClass ).removeClass( obj.showClass );
    });
  } else {
    Q.fcall( function(){
      obj.removeClassCheck();
    }).then(function(){
      $( obj.targetEl ).addClass( obj.showClass );
      $( "body" ).addClass( obj.bodyClass );
      obj.singleRemoveClass();
    });
  }
}

// Menu button
$( "#mobile-menu-button" ).click(function(){
  animateNavElement( nav );
});

// Search button
$( "#mobile-search-button" ).click( function() {
  animateNavElement( search );
});<commit_msg>increase Q.delay() to 500 milliseconds<commit_after>// nav code
var nav = {
  bodyClass: "show-mobile-menu",
  targetEl: "#site-navigation",
  hideClass: "hide-menu",
  showClass: "show-menu",
  removeClassCheck: function() {
    if ( $( "body" ).hasClass( "show-mobile-search" ) ) {
      $( "body" ).removeClass( "show-mobile-search" );
      $( "#searchform" ).addClass( "hide-searchbox" ).removeClass( "show-searchbox" );
    }
  },
  singleRemoveClass: function() {
    $( "#searchform" ).removeClass( "hide-searchbox" );
  }
};

// search code
var search = {
  bodyClass: "show-mobile-search",
  targetEl: "#searchform",
  hideClass: "hide-searchbox",
  showClass: "show-searchbox",
  removeClassCheck: function() {
    if ( $( "body" ).hasClass( "show-mobile-menu" ) ) {
      $( "body" ).removeClass( "show-mobile-menu" );
      $( "#site-navigation" ).addClass( "hide-menu" ).removeClass( "show-menu" );
    }
  },
  singleRemoveClass: function() {
    $( "#site-navigation" ).removeClass( "hide-menu" );
  }
};

function animateNavElement( obj ) {
  if( $( "body" ).hasClass( obj.bodyClass ) ) {
    Q.fcall( function(){
      $( obj.targetEl ).addClass( obj.hideClass );
      $( "body" ).removeClass( obj.bodyClass );
      return Q.delay( 500 );
    }).then( function(){
      $( obj.targetEl ).removeClass( obj.hideClass ).removeClass( obj.showClass );
    });
  } else {
    Q.fcall( function(){
      obj.removeClassCheck();
    }).then(function(){
      $( obj.targetEl ).addClass( obj.showClass );
      $( "body" ).addClass( obj.bodyClass );
      obj.singleRemoveClass();
    });
  }
}

// Menu button
$( "#mobile-menu-button" ).click(function(){
  animateNavElement( nav );
});

// Search button
$( "#mobile-search-button" ).click( function() {
  animateNavElement( search );
});<|endoftext|>


<commit_before>/*
 * This file is part of Report Portal.
 *
 * Report Portal is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Report Portal is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Report Portal.  If not, see <http://www.gnu.org/licenses/>.
 */
define(function (require, exports, module) {
    'use strict';

    var SingletonLaunchFilterCollection = require('filters/SingletonLaunchFilterCollection');

    var $ = require('jquery');
    var _ = require('underscore');
    var ModalView = require('modals/_modalView');

    var Backbone = require('backbone');
    var Epoxy = require('backbone-epoxy');
    var App = require('app');
    var Util = require('util');
    var Service = require('coreService');
    var SingletonAppModel = require('model/SingletonAppModel');

    var config = App.getInstance();
    var appModel = new SingletonAppModel();

    var TicketModel = Epoxy.Model.extend({
        defaults: {
            url: '',
            ticketId: '',
        }
    });
    var TicketCollection = Backbone.Collection.extend({
        model: TicketModel,
    });
    var TicketView = Epoxy.View.extend({
       template: 'tpl-model-load-bug-item',
        className: 'ticket-row-view',
        events: {
           'click [data-js-remove-row]': 'onClickRemove',
            'blur [data-js-link-input]': 'onBlurLinkInput',
        },
        bindings: {
            '[data-js-link-input]': 'value: url',
            '[data-js-issue-input]': 'value: ticketId',
        },

        initialize: function() {
            var externalSystems = appModel.getArr('externalSystem');
            this.externalSystemType = '';
            if(externalSystems[0] && externalSystems[0].systemType) {
                this.externalSystemType = externalSystems[0].systemType;
            }
            this.render();
            this.listenTo(this.model.collection, 'add remove', this.onChangeCollection);
            this.onChangeCollection();
            Util.hintValidator($('[data-js-issue-input]', this.$el), {
                validator: 'minMaxRequired',
                type: 'issueId',
                min: 1,
                max: 128
            });
            Util.hintValidator($('[data-js-link-input]', this.$el), [{
                validator: 'matchRegex',
                type: 'issueLinkRegex',
                pattern: config.patterns.urlT,
                arg: 'i'
            }]);
        },
        onBlurLinkInput: function() {
            var $link = $('[data-js-link-input]', this.$el);
            var $issue = $('[data-js-issue-input]', this.$el);
            if (!$link.data('valid') || $.trim($issue.val())) return;
            var autoValue = '';
            if (this.externalSystemType == 'JIRA') {
                autoValue = $link.val().split('/');
                autoValue = autoValue[autoValue.length - 1];
            }
            if (this.externalSystemType == 'TFS') {
                autoValue = $link.val().split('id=')[1];
                autoValue = autoValue ? autoValue.split('&')[0] : '';
            }
            this.model.set({ticketId: autoValue});
            $issue.trigger('validate');
        },
        onChangeCollection: function() {
            if(this.model.collection.models.length <= 1) {
                $('[data-js-remove-row]', this.$el).addClass('hide');
            } else {
                $('[data-js-remove-row]', this.$el).removeClass('hide');
            }
        },
        render: function() {
            this.$el.html(Util.templates(this.template, {}));
        },
        onClickRemove: function() {
            this.model.collection.remove(this.model);
            this.destroy();
        },
        destroy: function() {
            this.$el.remove();
            this.undelegateEvents();
            this.stopListening();
            this.unbind();
            delete this;
        }
    });

    var ModalLoadBug = ModalView.extend({
        template: 'tpl-modal-load-bug',
        className: 'modal-load-bug',

        events: {
            'click [data-bts-select-item]': 'onClickBts',
            'click [data-js-add-ticket]': 'onClickAddTicket',
            'click [data-js-load]': 'onClickLoad',
        },

        initialize: function(option) {
            this.externalSystems = appModel.getArr('externalSystem');
            if(!this.externalSystems.length) {
                console.log('No bts found');
                this.hide();
                return;
            }
            this.itemModels = option.items;
            this.testItemsIds = _.map(this.itemModels, function(model) {
                return model.get('id');
            });
            this.render();
            this.selectBts(this.externalSystems[0].id);
            this.collection = new TicketCollection();
            this.listenTo(this.collection, 'add', this.onAddTicket);
            this.collection.add({});
        },
        onKeySuccess: function () {
            $('[data-js-load]', this.$el).trigger('click');
        },
        onClickAddTicket: function() {
            this.collection.add({});
        },
        onClickLoad: function() {
            var self = this;
            $('.form-control', this.$el).trigger('validate');
            if (!$('.validate-error', this.$el).length) {
                var issues = _.map(this.collection.models, function(model) {
                    return {
                        ticketId: model.get('ticketId'),
                        url: model.get('url'),
                    }
                });
                var data = {
                    systemId: this.currentBts.id,
                    issues: issues,
                    testItemIds: this.testItemsIds,
                };
                Service.loadBugs(data)
                    .done(function (response) {
                        Util.ajaxSuccessMessenger("submitKeys");
                        config.trackingDispatcher.jiraTicketLoad(data.issues.length);
                        _.each(self.itemModels, function(model) {
                            self.addIssuesToItem(model, data.issues);
                        })
                    })
                    .fail(function (error) {
                        Util.ajaxFailMessenger(error, "submitKeys");
                    })
                    .always(function () {
                        self.successClose();
                    });
            }
        },
        addIssuesToItem: function(itemModel, issues) {
            var self = this;
            var curIssue = itemModel.getIssue();
            if(!curIssue.externalSystemIssues) {
                curIssue.externalSystemIssues = [];
            }
            var newIds = _.map(issues, function(issue) {
                return issue.ticketId;
            });
            var newExternalSystemIssues = [];  // remove not unic item
            _.each(curIssue.externalSystemIssues, function(externalItem) {
                if(!_.contains(newIds, externalItem.ticketId)){
                    newExternalSystemIssues.push(externalItem);
                }
            });
            _.each(issues, function(issue) {
                newExternalSystemIssues.push({
                    systemId: self.currentBts.id,
                    ticketId: issue.ticketId,
                    url: issue.url,
                })
            })
            curIssue.externalSystemIssues = newExternalSystemIssues;
            itemModel.setIssue(curIssue);
        },
        onAddTicket: function(model) {
            $('[data-js-load-items-container]', this.$el).append((new TicketView({model: model})).$el);
        },
        onClickBts: function(e) {
            e.preventDefault();
            this.selectBts($(e.currentTarget).data('bts-select-item'));
        },
        selectBts: function(id) {
            var currentBts = null;
            _.each(this.externalSystems, function(externalSystem) {
                if(externalSystem.id == id) {
                    currentBts = externalSystem;
                    return false;
                }
            });
            if(!currentBts) {
                return;
            }
            this.currentBts = currentBts;
            $('[data-js-bts-value]', this.$el).text(currentBts.project);
            $('[data-js-bts-link]', this.$el).text(currentBts.url);
        },
        render: function() {
            this.$el.html(Util.templates(this.template, {externalSystems: this.externalSystems}))
        }
    });

    return ModalLoadBug;
});
<commit_msg>EPMRPP-23578. [MODALS] Fix for automatic adding Issue Id on a "load bug" modal.<commit_after>/*
 * This file is part of Report Portal.
 *
 * Report Portal is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Report Portal is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Report Portal.  If not, see <http://www.gnu.org/licenses/>.
 */
define(function (require, exports, module) {
    'use strict';

    var SingletonLaunchFilterCollection = require('filters/SingletonLaunchFilterCollection');

    var $ = require('jquery');
    var _ = require('underscore');
    var ModalView = require('modals/_modalView');

    var Backbone = require('backbone');
    var Epoxy = require('backbone-epoxy');
    var App = require('app');
    var Util = require('util');
    var Service = require('coreService');
    var SingletonAppModel = require('model/SingletonAppModel');

    var config = App.getInstance();
    var appModel = new SingletonAppModel();

    var TicketModel = Epoxy.Model.extend({
        defaults: {
            url: '',
            ticketId: '',
        }
    });
    var TicketCollection = Backbone.Collection.extend({
        model: TicketModel,
    });
    var TicketView = Epoxy.View.extend({
       template: 'tpl-model-load-bug-item',
        className: 'ticket-row-view',
        events: {
            'click [data-js-remove-row]': 'onClickRemove',
            'blur [data-js-link-input]': 'onBlurLinkInput',
        },
        bindings: {
            '[data-js-link-input]': 'value: url',
            '[data-js-issue-input]': 'value: ticketId',
        },

        initialize: function() {
            var externalSystems = appModel.getArr('externalSystem');
            this.externalSystemType = '';
            if(externalSystems[0] && externalSystems[0].systemType) {
                this.externalSystemType = externalSystems[0].systemType;
            }
            this.render();
            this.listenTo(this.model.collection, 'add remove', this.onChangeCollection);
            this.onChangeCollection();
            Util.hintValidator($('[data-js-issue-input]', this.$el), {
                validator: 'minMaxRequired',
                type: 'issueId',
                min: 1,
                max: 128
            });
            Util.hintValidator($('[data-js-link-input]', this.$el), [{
                validator: 'matchRegex',
                type: 'issueLinkRegex',
                pattern: config.patterns.urlT,
                arg: 'i'
            }]);
        },
        onBlurLinkInput: function() {
            var $link = $('[data-js-link-input]', this.$el);
            var $issue = $('[data-js-issue-input]', this.$el);
            if ($link.parent().hasClass('validate-error') || $.trim($issue.val())) return;
            var autoValue = '';
            if (this.externalSystemType == 'JIRA') {
                autoValue = $link.val().split('/');
                autoValue = autoValue[autoValue.length - 1];
            }
            if (this.externalSystemType == 'TFS') {
                autoValue = $link.val().split('id=')[1];
                autoValue = autoValue ? autoValue.split('&')[0] : '';
            }
            this.model.set({ticketId: autoValue});
            $issue.trigger('validate');
        },
        onChangeCollection: function() {
            if(this.model.collection.models.length <= 1) {
                $('[data-js-remove-row]', this.$el).addClass('hide');
            } else {
                $('[data-js-remove-row]', this.$el).removeClass('hide');
            }
        },
        render: function() {
            this.$el.html(Util.templates(this.template, {}));
        },
        onClickRemove: function() {
            this.model.collection.remove(this.model);
            this.destroy();
        },
        destroy: function() {
            this.$el.remove();
            this.undelegateEvents();
            this.stopListening();
            this.unbind();
            delete this;
        }
    });

    var ModalLoadBug = ModalView.extend({
        template: 'tpl-modal-load-bug',
        className: 'modal-load-bug',

        events: {
            'click [data-bts-select-item]': 'onClickBts',
            'click [data-js-add-ticket]': 'onClickAddTicket',
            'click [data-js-load]': 'onClickLoad',
        },

        initialize: function(option) {
            this.externalSystems = appModel.getArr('externalSystem');
            if(!this.externalSystems.length) {
                console.log('No bts found');
                this.hide();
                return;
            }
            this.itemModels = option.items;
            this.testItemsIds = _.map(this.itemModels, function(model) {
                return model.get('id');
            });
            this.render();
            this.selectBts(this.externalSystems[0].id);
            this.collection = new TicketCollection();
            this.listenTo(this.collection, 'add', this.onAddTicket);
            this.collection.add({});
        },
        onKeySuccess: function () {
            $('[data-js-load]', this.$el).trigger('click');
        },
        onClickAddTicket: function() {
            this.collection.add({});
        },
        onClickLoad: function() {
            var self = this;
            $('.form-control', this.$el).trigger('validate');
            if (!$('.validate-error', this.$el).length) {
                var issues = _.map(this.collection.models, function(model) {
                    return {
                        ticketId: model.get('ticketId'),
                        url: model.get('url'),
                    }
                });
                var data = {
                    systemId: this.currentBts.id,
                    issues: issues,
                    testItemIds: this.testItemsIds,
                };
                Service.loadBugs(data)
                    .done(function (response) {
                        Util.ajaxSuccessMessenger("submitKeys");
                        config.trackingDispatcher.jiraTicketLoad(data.issues.length);
                        _.each(self.itemModels, function(model) {
                            self.addIssuesToItem(model, data.issues);
                        })
                    })
                    .fail(function (error) {
                        Util.ajaxFailMessenger(error, "submitKeys");
                    })
                    .always(function () {
                        self.successClose();
                    });
            }
        },
        addIssuesToItem: function(itemModel, issues) {
            var self = this;
            var curIssue = itemModel.getIssue();
            if(!curIssue.externalSystemIssues) {
                curIssue.externalSystemIssues = [];
            }
            var newIds = _.map(issues, function(issue) {
                return issue.ticketId;
            });
            var newExternalSystemIssues = [];  // remove not unic item
            _.each(curIssue.externalSystemIssues, function(externalItem) {
                if(!_.contains(newIds, externalItem.ticketId)){
                    newExternalSystemIssues.push(externalItem);
                }
            });
            _.each(issues, function(issue) {
                newExternalSystemIssues.push({
                    systemId: self.currentBts.id,
                    ticketId: issue.ticketId,
                    url: issue.url,
                })
            })
            curIssue.externalSystemIssues = newExternalSystemIssues;
            itemModel.setIssue(curIssue);
        },
        onAddTicket: function(model) {
            $('[data-js-load-items-container]', this.$el).append((new TicketView({model: model})).$el);
        },
        onClickBts: function(e) {
            e.preventDefault();
            this.selectBts($(e.currentTarget).data('bts-select-item'));
        },
        selectBts: function(id) {
            var currentBts = null;
            _.each(this.externalSystems, function(externalSystem) {
                if(externalSystem.id == id) {
                    currentBts = externalSystem;
                    return false;
                }
            });
            if(!currentBts) {
                return;
            }
            this.currentBts = currentBts;
            $('[data-js-bts-value]', this.$el).text(currentBts.project);
            $('[data-js-bts-link]', this.$el).text(currentBts.url);
        },
        render: function() {
            this.$el.html(Util.templates(this.template, {externalSystems: this.externalSystems}))
        }
    });

    return ModalLoadBug;
});
<|endoftext|>


<commit_before>'use strict';

const {customLaunchers} = require('./browsers.conf.js');

module.exports = config => {
  config.set({
    frameworks: ['jasmine'],

    files: [
      './bin/test.min.js',
      {
        pattern: 'test-assets/json/*.json',
        watched: false,
        included: false,
        served: true,
        nocache: false
      }
    ],

    customLaunchers,

    preprocessors: {
      './bin/test.min.js': ['sourcemap']
    },

    reporters: ['spec', 'saucelabs'],

    specReporter: {
      suppressErrorSummary: false,
      suppressFailed: false,
      suppressPassed: process.env.TRAVIS,
      suppressSkipped: process.env.TRAVIS,
      showSpecTiming: true,
      failFast: false
    },

    sauceLabs: {
      testName: 'clulib',
      retryLimit: 2,
      recordScreenshots: false,
      options: {
        'command-timeout': 600,
        'idle-timeout': 600,
        'max-duration': 5400
      }
    },

    browserDisconnectTimeout: 10 * 1000, // 10s - default 2s
    browserDisconnectTolerance: 1, // default 0
    browserNoActivityTimeout: 4 * 60 * 1000, // 4 min - default 10s
    captureTimeout: 5 * 60 * 1000, // 5 min default 60s
    port: 9876,
    autoWatch: false,
    browsers: ['Chrome'],
    singleRun: true,
    concurrency: 5
  });

  if (process.env.TRAVIS) {
    config.sauceLabs.build = `TRAVIS #${process.env.TRAVIS_BUILD_NUMBER} (${process.env.TRAVIS_BUILD_ID})`;
    config.sauceLabs.tunnelIdentifier = process.env.TRAVIS_JOB_NUMBER;
    config.transports = ['polling'];
    config.browsers = Object.keys(customLaunchers);
  }
};
<commit_msg>fix karma assets serving<commit_after>'use strict';

const {customLaunchers} = require('./browsers.conf.js');

module.exports = config => {
  config.set({
    frameworks: ['jasmine'],

    files: [
      './bin/test.min.js',
      {
        pattern: 'test-assets/json/*.json',
        watched: false,
        included: false,
        served: true,
        nocache: false
      },
      {
        pattern: 'test-assets/l10n/de-DE/*.json',
        watched: false,
        included: false,
        served: true,
        nocache: false
      }
    ],

    customLaunchers,

    preprocessors: {
      './bin/test.min.js': ['sourcemap']
    },

    reporters: ['spec', 'saucelabs'],

    specReporter: {
      suppressErrorSummary: false,
      suppressFailed: false,
      suppressPassed: process.env.TRAVIS,
      suppressSkipped: process.env.TRAVIS,
      showSpecTiming: true,
      failFast: false
    },

    sauceLabs: {
      testName: 'clulib',
      retryLimit: 2,
      recordScreenshots: false,
      options: {
        'command-timeout': 600,
        'idle-timeout': 600,
        'max-duration': 5400
      }
    },

    browserDisconnectTimeout: 10 * 1000, // 10s - default 2s
    browserDisconnectTolerance: 1, // default 0
    browserNoActivityTimeout: 4 * 60 * 1000, // 4 min - default 10s
    captureTimeout: 5 * 60 * 1000, // 5 min default 60s
    port: 9876,
    autoWatch: false,
    browsers: ['Chrome'],
    singleRun: true,
    concurrency: 5
  });

  if (process.env.TRAVIS) {
    config.sauceLabs.build = `TRAVIS #${process.env.TRAVIS_BUILD_NUMBER} (${process.env.TRAVIS_BUILD_ID})`;
    config.sauceLabs.tunnelIdentifier = process.env.TRAVIS_JOB_NUMBER;
    config.transports = ['polling'];
    config.browsers = Object.keys(customLaunchers);
  }
};
<|endoftext|>


<commit_before>'use strict';
var test = require('../');
var ava = require('../lib/test');

test('run test', function (t) {
	ava('foo', function (a) {
		a.true(false);
		a.end();
	}).run(function (err) {
		t.true(err);
		t.end();
	});
});

test('test title is optional', function (t) {
	ava(function (a) {
		a.end();
	}).run(function () {
		t.is(this.title, '[anonymous]');
		t.end();
	});
});

test('infer test name from function', function (t) {
	ava(function foo(a) {
		a.end();
	}).run(function () {
		t.is(this.title, 'foo');
		t.end();
	});
});

test('multiple asserts', function (t) {
	ava(function (a) {
		a.true(true);
		a.true(true);
		a.true(true);
		a.end();
	}).run(function () {
		t.is(this._assertCount, 3);
		t.end();
	});
});

test('plan assertions', function (t) {
	ava(function (a) {
		a.plan(2);
		a.true(true);
		a.true(true);
	}).run(function () {
		t.is(this._planCount, 2);
		t.is(this._assertCount, 2);
		t.end();
	});
});

test('run more assertions than planned', function (t) {
	ava(function (a) {
		a.plan(2);
		a.true(true);
		a.true(true);
		a.true(true);
	}).run(function (err) {
		t.true(err);
		t.is(err.name, 'AssertionError');
		t.end();
	});
});

test('handle non-assertion errors', function (t) {
	ava(function () {
		throw new Error();
	}).run(function (err) {
		t.is(err.name, 'AssertionError');
		t.true(err.actual instanceof Error);
		t.end();
	});
});

test('handle testing of arrays', function (t) {
	ava(function (a) {
		a.same(['foo', 'bar'], ['foo', 'bar']);
		a.end();
	}).run(function (err) {
		t.false(err);
		t.end();
	});
});

test('handle falsy testing of arrays', function (t) {
	ava(function (a) {
		a.notSame(['foo', 'bar'], ['foo', 'bar', 'cat']);
		a.end();
	}).run(function (err) {
		t.false(err);
		t.end();
	});
});

test('handle testing of objects', function (t) {
	ava(function (a) {
		a.same({foo: 'foo', bar: 'bar'}, {foo: 'foo', bar: 'bar'});
		a.end();
	}).run(function (err) {
		t.false(err);
		t.end();
	});
});

test('handle falsy testing of objects', function (t) {
	ava(function (a) {
		a.notSame({foo: 'foo', bar: 'bar'}, {foo: 'foo', bar: 'bar', cat: 'cake'});
		a.end();
	}).run(function (err) {
		t.false(err);
		t.end();
	});
});

test('handle throws', function (t) {
	ava(function (a) {
		a.throws(function () {
			throw new Error('foo');
		});

		a.end();
	}).run(function (err) {
		t.false(err);
		t.end();
	});
});

test('handle throws with error', function (t) {
	ava(function (a) {
		a.doesNotThrow(function () {
			throw new Error('foo');
		});

		a.end();
	}).run(function (err) {
		t.true(err);
		t.end();
	});
});

test('handle falsy throws', function (t) {
	ava(function (a) {
		a.doesNotThrow(function () {
			return;
		});

		a.end();
	}).run(function (err) {
		t.false(err);
		t.end();
	});
});

test('handle falsy throws with error', function (t) {
	ava(function (a) {
		a.throws(function () {
			return;
		});

		a.end();
	}).run(function (err) {
		t.true(err);
		t.end();
	});
});

test('run functions after last planned assertion', function (t) {
	var i = 0;

	ava('foo', function (a) {
		a.plan(1);
		a.true(true);
		i++;
	}).run(function () {
		t.is(i, 1);
		t.end();
	});
});

test('run async functions after last planned assertion', function (t) {
	var i = 0;

	ava('foo', function (a) {
		a.plan(1);

		function foo(cb) {
			a.true(true);
			cb();
		}

		foo(function () {
			i++;
		});
	}).run(function () {
		t.is(i, 1);
		t.end();
	});
});
<commit_msg>add a test for planned async assertion<commit_after>'use strict';
var test = require('../');
var ava = require('../lib/test');

test('run test', function (t) {
	ava('foo', function (a) {
		a.true(false);
		a.end();
	}).run(function (err) {
		t.true(err);
		t.end();
	});
});

test('test title is optional', function (t) {
	ava(function (a) {
		a.end();
	}).run(function () {
		t.is(this.title, '[anonymous]');
		t.end();
	});
});

test('infer test name from function', function (t) {
	ava(function foo(a) {
		a.end();
	}).run(function () {
		t.is(this.title, 'foo');
		t.end();
	});
});

test('multiple asserts', function (t) {
	ava(function (a) {
		a.true(true);
		a.true(true);
		a.true(true);
		a.end();
	}).run(function () {
		t.is(this._assertCount, 3);
		t.end();
	});
});

test('plan assertions', function (t) {
	ava(function (a) {
		a.plan(2);
		a.true(true);
		a.true(true);
	}).run(function () {
		t.is(this._planCount, 2);
		t.is(this._assertCount, 2);
		t.end();
	});
});

test('run more assertions than planned', function (t) {
	ava(function (a) {
		a.plan(2);
		a.true(true);
		a.true(true);
		a.true(true);
	}).run(function (err) {
		t.true(err);
		t.is(err.name, 'AssertionError');
		t.end();
	});
});

test('handle non-assertion errors', function (t) {
	ava(function () {
		throw new Error();
	}).run(function (err) {
		t.is(err.name, 'AssertionError');
		t.true(err.actual instanceof Error);
		t.end();
	});
});

test('handle testing of arrays', function (t) {
	ava(function (a) {
		a.same(['foo', 'bar'], ['foo', 'bar']);
		a.end();
	}).run(function (err) {
		t.false(err);
		t.end();
	});
});

test('handle falsy testing of arrays', function (t) {
	ava(function (a) {
		a.notSame(['foo', 'bar'], ['foo', 'bar', 'cat']);
		a.end();
	}).run(function (err) {
		t.false(err);
		t.end();
	});
});

test('handle testing of objects', function (t) {
	ava(function (a) {
		a.same({foo: 'foo', bar: 'bar'}, {foo: 'foo', bar: 'bar'});
		a.end();
	}).run(function (err) {
		t.false(err);
		t.end();
	});
});

test('handle falsy testing of objects', function (t) {
	ava(function (a) {
		a.notSame({foo: 'foo', bar: 'bar'}, {foo: 'foo', bar: 'bar', cat: 'cake'});
		a.end();
	}).run(function (err) {
		t.false(err);
		t.end();
	});
});

test('handle throws', function (t) {
	ava(function (a) {
		a.throws(function () {
			throw new Error('foo');
		});

		a.end();
	}).run(function (err) {
		t.false(err);
		t.end();
	});
});

test('handle throws with error', function (t) {
	ava(function (a) {
		a.doesNotThrow(function () {
			throw new Error('foo');
		});

		a.end();
	}).run(function (err) {
		t.true(err);
		t.end();
	});
});

test('handle falsy throws', function (t) {
	ava(function (a) {
		a.doesNotThrow(function () {
			return;
		});

		a.end();
	}).run(function (err) {
		t.false(err);
		t.end();
	});
});

test('handle falsy throws with error', function (t) {
	ava(function (a) {
		a.throws(function () {
			return;
		});

		a.end();
	}).run(function (err) {
		t.true(err);
		t.end();
	});
});

test('run functions after last planned assertion', function (t) {
	var i = 0;

	ava(function (a) {
		a.plan(1);
		a.true(true);
		i++;
	}).run(function () {
		t.is(i, 1);
		t.end();
	});
});

test('run async functions after last planned assertion', function (t) {
	var i = 0;

	ava(function (a) {
		a.plan(1);

		function foo(cb) {
			a.true(true);
			cb();
		}

		foo(function () {
			i++;
		});
	}).run(function () {
		t.is(i, 1);
		t.end();
	});
});

test('planned async assertion', function (t) {
	ava(function (a) {
		a.plan(1);

		setTimeout(function () {
			a.pass();
		}, 100);
	}).run(function (err) {
		t.error(err);
		t.end();
	});
});
<|endoftext|>


<commit_before>// Karma configuration
// Generated on Sun Apr 24 2016 02:13:14 GMT+0000 (UTC)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files: [
      'node_modules/jquery/dist/jquery.js',
      'bower_components/angular/angular.js',
      'node_modules/angular-mocks/angular-mocks.js',
      'bower_components/angular-websocket/angular-websocket.js',
      'src/ngActionCable.js',
      'src/services/actionCableConfig.js',
      'src/services/actionCableController.js',
      'src/services/actionCableWebsocket.js',
      'src/services/actionCableSocketWrangler.js',
      'src/services/actionCableChannel.js',

      'test/**/*.spec.js'
    ],

    // list of files to exclude
    exclude: [
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Firefox', 'Chrome', 'PhantomJS'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
}
<commit_msg>include all files with wildcard<commit_after>// Karma configuration
// Generated on Sun Apr 24 2016 02:13:14 GMT+0000 (UTC)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files: [
      'node_modules/jquery/dist/jquery.js',
      'bower_components/angular/angular.js',
      'node_modules/angular-mocks/angular-mocks.js',
      'bower_components/angular-websocket/angular-websocket.js',
      'src/**/*.js',
      'test/**/*.spec.js'
    ],

    // list of files to exclude
    exclude: [
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Firefox', 'Chrome', 'PhantomJS'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
}
<|endoftext|>


<commit_before>"use strict";

var _ = require('lodash');
var stream = require('stream');
var expect = require('expect.js');
var execToHtml = require('..');

var fixtures = require('./fixtures.js');

var stream = require('stream');
var util = require('util');
var os = require('os');

describe('exec-to-html', function(){
    describe('internal streams', function(){
        it('first simple test', function(done){
            var lineCount=0;
            var obtainedLines=[];
            execToHtml.run('!echo hi5',{echo:false}).onLine(function(lineInfo){
                obtainedLines.push(lineInfo);
            }).then(function(exitCode){
                expect(obtainedLines).to.eql([{origin:'stdout', text:'hi5'+os.EOL}]);
                expect(exitCode).to.be(0);
                done();
            }).catch(done);
        });
        _.forEach(fixtures,function(fixture){
            if(fixture.skipped){
                it.skip('run fixture with stream. For fixutreName='+fixture.name+', skipped:'+fixture.skipped,function(){
                });
                return;
            }
            it('run fixture with stream. For fixutreName='+fixture.name,function(done){
                if(fixture.timeout){
                    this.timeout(fixture.timeout*(process.env.APPVEYOR?3:1));
                }
                if(fixture.slice){
                    var expectedLines=fixture.expected.slice(fixture.slice[0],fixture.slice[1]);
                }else{
                    var expectedLines=fixture.expected.slice(0);
                }
                var obtainedLines=[];
                execToHtml.run(fixture.commands,fixture.opts).onLine(function(lineInfo){
                    // console.log('expect(',lineInfo,expectedLines.shift()); return;
                    obtainedLines.push(lineInfo);
                }).then(function(exitCode){
                    if(fixture.slice) {
                        obtainedLines = obtainedLines.slice(fixture.slice[0], fixture.slice[1]);
                    }
                    //console.log("OL", obtainedLines); console.log("EX", fixture.expected);
                    expect(obtainedLines).to.eql(fixture.expected);
                    //console.log("exitCode",exitCode);
                    expect(exitCode).to.eql(fixture.exit||0);
                    done();
                }).catch(done);
            });
            if(fixture.collect){
                it('run fixture with collect. For fixutreName='+fixture.name,function(done){
                    var opts=_.clone(fixture.opts||{});
                    opts.collect=true;
                    execToHtml.run(fixture.commands,opts).then(function(result){
                        expect(result).to.eql(fixture.collect);
                        done();
                    }).catch(done);
                });
            };
        });
    });
    describe('internal streams error control', function(){
        it('must pass opts',function(done){
            execToHtml.run('!echo 1').onLine(function(){
                throw new Error('Unexpected data');
            }).then(function(){
                throw new Error('Reject expected');
            }).catch(function(err){
                expect(err).to.be.a(Error);
                expect(err.message).to.match(/option echo is mandatory/);
                done();
            }).catch(done);
        });
    });
});
<commit_msg>estaba mal ubicado el slice<commit_after>"use strict";

var _ = require('lodash');
var stream = require('stream');
var expect = require('expect.js');
var execToHtml = require('..');

var fixtures = require('./fixtures.js');

var stream = require('stream');
var util = require('util');
var os = require('os');

describe('exec-to-html', function(){
    describe('internal streams', function(){
        it('first simple test', function(done){
            var lineCount=0;
            var obtainedLines=[];
            execToHtml.run('!echo hi5',{echo:false}).onLine(function(lineInfo){
                obtainedLines.push(lineInfo);
            }).then(function(exitCode){
                expect(obtainedLines).to.eql([{origin:'stdout', text:'hi5'+os.EOL}]);
                expect(exitCode).to.be(0);
                done();
            }).catch(done);
        });
        _.forEach(fixtures,function(fixture){
            if(fixture.skipped){
                it.skip('run fixture with stream. For fixutreName='+fixture.name+', skipped:'+fixture.skipped,function(){
                });
                return;
            }
            it('run fixture with stream. For fixutreName='+fixture.name,function(done){
                if(fixture.timeout){
                    this.timeout(fixture.timeout*(process.env.APPVEYOR?3:1));
                }
                var expectedLines=fixture.expected.slice(0);
                var obtainedLines=[];
                execToHtml.run(fixture.commands,fixture.opts).onLine(function(lineInfo){
                    // console.log('expect(',lineInfo,expectedLines.shift()); return;
                    obtainedLines.push(lineInfo);
                }).then(function(exitCode){
                    if(fixture.slice) {
                        obtainedLines = obtainedLines.slice(fixture.slice[0], fixture.slice[1]);
                    }
                    //console.log("OL", obtainedLines); console.log("EX", fixture.expected);
                    expect(obtainedLines).to.eql(fixture.expected);
                    //console.log("exitCode",exitCode);
                    expect(exitCode).to.eql(fixture.exit||0);
                    done();
                }).catch(done);
            });
            if(fixture.collect){
                it('run fixture with collect. For fixutreName='+fixture.name,function(done){
                    var opts=_.clone(fixture.opts||{});
                    opts.collect=true;
                    execToHtml.run(fixture.commands,opts).then(function(result){
                        expect(result).to.eql(fixture.collect);
                        done();
                    }).catch(done);
                });
            };
        });
    });
    describe('internal streams error control', function(){
        it('must pass opts',function(done){
            execToHtml.run('!echo 1').onLine(function(){
                throw new Error('Unexpected data');
            }).then(function(){
                throw new Error('Reject expected');
            }).catch(function(err){
                expect(err).to.be.a(Error);
                expect(err.message).to.match(/option echo is mandatory/);
                done();
            }).catch(done);
        });
    });
});
<|endoftext|>